static enum dm_pp_clocks_state dce_get_required_clocks_state( struct display_clock *clk, struct state_dependent_clocks *req_clocks) { struct dce_disp_clk *clk_dce = TO_DCE_CLOCKS(clk); int i; enum dm_pp_clocks_state low_req_clk; /* Iterate from highest supported to lowest valid state, and update * lowest RequiredState with the lowest state that satisfies * all required clocks */ for (i = clk->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) if (req_clocks->display_clk_khz > clk_dce->max_clks_by_state[i].display_clk_khz || req_clocks->pixel_clk_khz > clk_dce->max_clks_by_state[i].pixel_clk_khz) break; low_req_clk = i + 1; if (low_req_clk > clk->max_clks_state) { dm_logger_write(clk->ctx->logger, LOG_WARNING, "%s: clocks unsupported", __func__); low_req_clk = DM_PP_CLOCKS_STATE_INVALID; } return low_req_clk; }
bool dal_irq_service_dummy_ack( struct irq_service *irq_service, const struct irq_source_info *info) { dm_logger_write( irq_service->ctx->logger, LOG_ERROR, "%s: called for non-implemented irq source\n", __func__); return false; }
struct dc *dc_create(const struct dc_init_data *init_params) { struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL); unsigned int full_pipe_count; if (NULL == dc) goto alloc_fail; if (false == construct(dc, init_params)) goto construct_fail; /*TODO: separate HW and SW initialization*/ dc->hwss.init_hw(dc); full_pipe_count = dc->res_pool->pipe_count; if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE) full_pipe_count--; dc->caps.max_streams = min( full_pipe_count, dc->res_pool->stream_enc_count); dc->caps.max_links = dc->link_count; dc->caps.max_audios = dc->res_pool->audio_count; dc->config = init_params->flags; dm_logger_write(dc->ctx->logger, LOG_DC, "Display Core initialized\n"); /* TODO: missing feature to be enabled */ dc->debug.disable_dfs_bypass = true; return dc; construct_fail: kfree(dc); alloc_fail: return NULL; }
bool dc_commit_state(struct dc *dc, struct dc_state *context) { enum dc_status result = DC_ERROR_UNEXPECTED; int i; if (false == context_changed(dc, context)) return DC_OK; dm_logger_write(dc->ctx->logger, LOG_DC, "%s: %d streams\n", __func__, context->stream_count); for (i = 0; i < context->stream_count; i++) { struct dc_stream_state *stream = context->streams[i]; dc_stream_log(stream, dc->ctx->logger, LOG_DC); } result = dc_commit_state_no_check(dc, context); return (result == DC_OK); }
static bool dce_clock_set_min_clocks_state( struct display_clock *clk, enum dm_pp_clocks_state clocks_state) { struct dm_pp_power_level_change_request level_change_req = { clocks_state }; if (clocks_state > clk->max_clks_state) { /*Requested state exceeds max supported state.*/ dm_logger_write(clk->ctx->logger, LOG_WARNING, "Requested state exceeds max supported state"); return false; } else if (clocks_state == clk->cur_min_clks_state) { /*if we're trying to set the same state, we can just return * since nothing needs to be done*/ return true; } /* get max clock state from PPLIB */ if (dm_pp_apply_power_level_change_request(clk->ctx, &level_change_req)) clk->cur_min_clks_state = clocks_state; return true; }
static void dce110_update_hdmi_info_packet( struct dce110_stream_encoder *enc110, uint32_t packet_index, const struct encoder_info_packet *info_packet) { struct dc_context *ctx = enc110->base.ctx; uint32_t cont, send, line; if (info_packet->valid) { dce110_update_generic_info_packet( enc110, packet_index, info_packet); /* enable transmission of packet(s) - * packet transmission begins on the next frame */ cont = 1; /* send packet(s) every frame */ send = 1; /* select line number to send packets on */ line = 2; } else { cont = 0; send = 0; line = 0; } /* choose which generic packet control to use */ switch (packet_index) { case 0: REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC0_CONT, cont, HDMI_GENERIC0_SEND, send, HDMI_GENERIC0_LINE, line); break; case 1: REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0, HDMI_GENERIC1_CONT, cont, HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; case 2: REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC0_CONT, cont, HDMI_GENERIC0_SEND, send, HDMI_GENERIC0_LINE, line); break; case 3: REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1, HDMI_GENERIC1_CONT, cont, HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; #if defined(CONFIG_DRM_AMD_DC_DCN1_0) case 4: if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC0_CONT, cont, HDMI_GENERIC0_SEND, send, HDMI_GENERIC0_LINE, line); break; case 5: if (REG(HDMI_GENERIC_PACKET_CONTROL2)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2, HDMI_GENERIC1_CONT, cont, HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; case 6: if (REG(HDMI_GENERIC_PACKET_CONTROL3)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC0_CONT, cont, HDMI_GENERIC0_SEND, send, HDMI_GENERIC0_LINE, line); break; case 7: if (REG(HDMI_GENERIC_PACKET_CONTROL3)) REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3, HDMI_GENERIC1_CONT, cont, HDMI_GENERIC1_SEND, send, HDMI_GENERIC1_LINE, line); break; #endif default: /* invalid HW packet index */ dm_logger_write( ctx->logger, LOG_WARNING, "Invalid HW packet index: %s()\n", __func__); return; } }
static void dce110_se_setup_hdmi_audio( struct stream_encoder *enc, const struct audio_crtc_info *crtc_info) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); struct audio_clock_info audio_clock_info = {0}; uint32_t max_packets_per_line; /* For now still do calculation, although this field is ignored when above HDMI_PACKET_GEN_VERSION set to 1 */ max_packets_per_line = calc_max_audio_packets_per_line(crtc_info); /* HDMI_AUDIO_PACKET_CONTROL */ REG_UPDATE_2(HDMI_AUDIO_PACKET_CONTROL, HDMI_AUDIO_PACKETS_PER_LINE, max_packets_per_line, HDMI_AUDIO_DELAY_EN, 1); /* AFMT_AUDIO_PACKET_CONTROL */ REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); /* AFMT_AUDIO_PACKET_CONTROL2 */ REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_LAYOUT_OVRD, 0, AFMT_60958_OSF_OVRD, 0); /* HDMI_ACR_PACKET_CONTROL */ REG_UPDATE_3(HDMI_ACR_PACKET_CONTROL, HDMI_ACR_AUTO_SEND, 1, HDMI_ACR_SOURCE, 0, HDMI_ACR_AUDIO_PRIORITY, 0); /* Program audio clock sample/regeneration parameters */ get_audio_clock_info(crtc_info->color_depth, crtc_info->requested_pixel_clock, crtc_info->calculated_pixel_clock, &audio_clock_info); dm_logger_write(enc->ctx->logger, LOG_HW_AUDIO, "\n%s:Input::requested_pixel_clock = %d" \ "calculated_pixel_clock = %d \n", __func__, \ crtc_info->requested_pixel_clock, \ crtc_info->calculated_pixel_clock); /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */ REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz); /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */ REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz); /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */ REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz); /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */ REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz); /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */ REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz); /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */ REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz); /* Video driver cannot know in advance which sample rate will be used by HD Audio driver HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is programmed below in interruppt callback */ /* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK & AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */ REG_UPDATE_2(AFMT_60958_0, AFMT_60958_CS_CHANNEL_NUMBER_L, 1, AFMT_60958_CS_CLOCK_ACCURACY, 0); /* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */ REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2); /*AFMT_60958_2 now keep this settings until * Programming guide comes out*/ REG_UPDATE_6(AFMT_60958_2, AFMT_60958_CS_CHANNEL_NUMBER_2, 3, AFMT_60958_CS_CHANNEL_NUMBER_3, 4, AFMT_60958_CS_CHANNEL_NUMBER_4, 5, AFMT_60958_CS_CHANNEL_NUMBER_5, 6, AFMT_60958_CS_CHANNEL_NUMBER_6, 7, AFMT_60958_CS_CHANNEL_NUMBER_7, 8); }