diff options
author | Maxime Ripard <maxime@cerno.tech> | 2021-04-26 14:03:09 +0200 |
---|---|---|
committer | Maxime Ripard <maxime@cerno.tech> | 2021-04-26 14:03:09 +0200 |
commit | 355b60296143a090039211c5f0e1463f84aab65a (patch) | |
tree | b74d4ef2aea66252ea9cf77c847de6c6e72a02b7 /drivers/gpu/drm/amd/display/dc/bios | |
parent | 91185d55b32e7e377f15fb46a62b216f8d3038d4 (diff) | |
parent | a1a1ca70deb3ec600eeabb21de7f3f48aaae5695 (diff) |
Merge drm/drm-next into drm-misc-next
Christian needs some patches from drm/next
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/bios')
6 files changed, 304 insertions, 15 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 9f9fda3118d1..d79f4fe06c47 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -916,6 +916,192 @@ static enum bp_result bios_parser_get_soc_bb_info( return result; } +static enum bp_result get_disp_caps_v4_1( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_2( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_3( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result get_disp_caps_v4_4( + struct bios_parser *bp, + uint8_t *dce_caps) +{ + enum bp_result result = BP_RESULT_OK; + struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; + + if (!dce_caps) + return BP_RESULT_BADINPUT; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_BADBIOSTABLE; + + disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, + DATA_TABLES(dce_info)); + + if (!disp_cntl_tbl) + return BP_RESULT_BADBIOSTABLE; + + *dce_caps = disp_cntl_tbl->display_caps; + + return result; +} + +static enum bp_result bios_parser_get_lttpr_interop( + struct dc_bios *dcb, + uint8_t *dce_caps) +{ + struct bios_parser *bp = BP_FROM_DCB(dcb); + enum bp_result result = BP_RESULT_UNSUPPORTED; + struct atom_common_table_header *header; + struct atom_data_revision tbl_revision; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_UNSUPPORTED; + + header = GET_IMAGE(struct atom_common_table_header, + DATA_TABLES(dce_info)); + get_atom_data_table_revision(header, &tbl_revision); + switch (tbl_revision.major) { + case 4: + switch (tbl_revision.minor) { + case 1: + result = get_disp_caps_v4_1(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 2: + result = get_disp_caps_v4_2(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 3: + result = get_disp_caps_v4_3(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + case 4: + result = get_disp_caps_v4_4(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); + break; + default: + break; + } + break; + default: + break; + } + + return result; +} + +static enum bp_result bios_parser_get_lttpr_caps( + struct dc_bios *dcb, + uint8_t *dce_caps) +{ + struct bios_parser *bp = BP_FROM_DCB(dcb); + enum bp_result result = BP_RESULT_UNSUPPORTED; + struct atom_common_table_header *header; + struct atom_data_revision tbl_revision; + + if (!DATA_TABLES(dce_info)) + return BP_RESULT_UNSUPPORTED; + + header = GET_IMAGE(struct atom_common_table_header, + DATA_TABLES(dce_info)); + get_atom_data_table_revision(header, &tbl_revision); + switch (tbl_revision.major) { + case 4: + switch (tbl_revision.minor) { + case 1: + result = get_disp_caps_v4_1(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 2: + result = get_disp_caps_v4_2(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 3: + result = get_disp_caps_v4_3(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + case 4: + result = get_disp_caps_v4_4(bp, dce_caps); + *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); + break; + default: + break; + } + break; + default: + break; + } + + return result; +} + static enum bp_result get_embedded_panel_info_v2_1( struct bios_parser *bp, struct embedded_panel_info *info) @@ -1180,14 +1366,15 @@ static enum bp_result bios_parser_enable_disp_power_gating( static enum bp_result bios_parser_enable_lvtma_control( struct dc_bios *dcb, - uint8_t uc_pwr_on) + uint8_t uc_pwr_on, + uint8_t panel_instance) { struct bios_parser *bp = BP_FROM_DCB(dcb); if (!bp->cmd_tbl.enable_lvtma_control) return BP_RESULT_FAILURE; - return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on); + return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance); } static bool bios_parser_is_accelerated_mode( @@ -2530,6 +2717,10 @@ static const struct dc_vbios_funcs vbios_funcs = { .get_soc_bb_info = bios_parser_get_soc_bb_info, .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info, + + .get_lttpr_caps = bios_parser_get_lttpr_caps, + + .get_lttpr_interop = bios_parser_get_lttpr_interop, }; static bool bios_parser2_construct( diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c index fce46ab54c54..53d7513b5083 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.c @@ -64,9 +64,10 @@ bool bios_is_accelerated_mode( void bios_set_scratch_acc_mode_change( - struct dc_bios *bios) + struct dc_bios *bios, + uint32_t state) { - REG_UPDATE(BIOS_SCRATCH_6, S6_ACC_MODE, 1); + REG_UPDATE(BIOS_SCRATCH_6, S6_ACC_MODE, state); } diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h index 75a29e68fb27..e1b4a40a353d 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h @@ -32,7 +32,7 @@ uint8_t *bios_get_image(struct dc_bios *bp, uint32_t offset, uint32_t size); bool bios_is_accelerated_mode(struct dc_bios *bios); -void bios_set_scratch_acc_mode_change(struct dc_bios *bios); +void bios_set_scratch_acc_mode_change(struct dc_bios *bios, uint32_t state); void bios_set_scratch_critical_state(struct dc_bios *bios, bool state); uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios); diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index afc10b954ffa..ad13e4e36d77 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -1531,6 +1531,27 @@ static enum bp_result adjust_display_pll_v2( params.ucEncodeMode = (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom( bp_params->signal_type, false); + + if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) { + /* Convert output pixel clock back 10KHz-->KHz: multiply + * original pixel clock in KHz by ratio + * [output pxlClk/input pxlClk] */ + uint64_t pixel_clk_10_khz_out = + (uint64_t)le16_to_cpu(params.usPixelClock); + uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock; + + if (pixel_clock_10KHz_in != 0) { + bp_params->adjusted_pixel_clock = + div_u64(pixel_clk * pixel_clk_10_khz_out, + pixel_clock_10KHz_in); + } else { + bp_params->adjusted_pixel_clock = 0; + BREAK_TO_DEBUGGER(); + } + + result = BP_RESULT_OK; + } + return result; } diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index 25bdf1c38e0a..f1f672a997d7 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -218,6 +218,10 @@ static enum bp_result transmitter_control_v1_6( struct bios_parser *bp, struct bp_transmitter_control *cntl); +static enum bp_result transmitter_control_v1_7( + struct bios_parser *bp, + struct bp_transmitter_control *cntl); + static enum bp_result transmitter_control_fallback( struct bios_parser *bp, struct bp_transmitter_control *cntl); @@ -233,6 +237,9 @@ static void init_transmitter_control(struct bios_parser *bp) case 6: bp->cmd_tbl.transmitter_control = transmitter_control_v1_6; break; + case 7: + bp->cmd_tbl.transmitter_control = transmitter_control_v1_7; + break; default: dm_output_to_console("Don't have transmitter_control for v%d\n", crev); bp->cmd_tbl.transmitter_control = transmitter_control_fallback; @@ -304,13 +311,76 @@ static enum bp_result transmitter_control_v1_6( return result; } +static void transmitter_control_dmcub_v1_7( + struct dc_dmub_srv *dmcub, + struct dmub_dig_transmitter_control_data_v1_7 *dig) +{ + union dmub_rb_cmd cmd; + + memset(&cmd, 0, sizeof(cmd)); + + cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS; + cmd.dig1_transmitter_control.header.sub_type = + DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL; + cmd.dig1_transmitter_control.header.payload_bytes = + sizeof(cmd.dig1_transmitter_control) - + sizeof(cmd.dig1_transmitter_control.header); + cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig; + + dc_dmub_srv_cmd_queue(dmcub, &cmd); + dc_dmub_srv_cmd_execute(dmcub); + dc_dmub_srv_wait_idle(dmcub); +} + +static enum bp_result transmitter_control_v1_7( + struct bios_parser *bp, + struct bp_transmitter_control *cntl) +{ + enum bp_result result = BP_RESULT_FAILURE; + const struct command_table_helper *cmd = bp->cmd_helper; + struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0}; + + dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter); + dig_v1_7.action = (uint8_t)cntl->action; + + if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) + dig_v1_7.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings; + else + dig_v1_7.mode_laneset.digmode = + cmd->signal_type_to_atom_dig_mode(cntl->signal); + + dig_v1_7.lanenum = (uint8_t)cntl->lanes_number; + dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); + dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); + dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id; + dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10; + + if (cntl->action == TRANSMITTER_CONTROL_ENABLE || + cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || + cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { + DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n", + __func__, dig_v1_7.symclk_units.symclk_10khz); + } + + if (bp->base.ctx->dc->ctx->dmub_srv && + bp->base.ctx->dc->debug.dmub_command_table) { + transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7); + return BP_RESULT_OK; + } + +/*color_depth not used any more, driver has deep color factor in the Phyclk*/ + if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7)) + result = BP_RESULT_OK; + return result; +} + static enum bp_result transmitter_control_fallback( struct bios_parser *bp, struct bp_transmitter_control *cntl) { if (bp->base.ctx->dc->ctx->dmub_srv && bp->base.ctx->dc->debug.dmub_command_table) { - return transmitter_control_v1_6(bp, cntl); + return transmitter_control_v1_7(bp, cntl); } return BP_RESULT_FAILURE; @@ -911,7 +981,8 @@ static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) static enum bp_result enable_lvtma_control( struct bios_parser *bp, - uint8_t uc_pwr_on); + uint8_t uc_pwr_on, + uint8_t panel_instance); static void init_enable_lvtma_control(struct bios_parser *bp) { @@ -922,19 +993,21 @@ static void init_enable_lvtma_control(struct bios_parser *bp) static void enable_lvtma_control_dmcub( struct dc_dmub_srv *dmcub, - uint8_t uc_pwr_on) + uint8_t uc_pwr_on, + uint8_t panel_instance) { union dmub_rb_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.cmd_common.header.type = DMUB_CMD__VBIOS; - cmd.cmd_common.header.sub_type = + cmd.lvtma_control.header.type = DMUB_CMD__VBIOS; + cmd.lvtma_control.header.sub_type = DMUB_CMD__VBIOS_LVTMA_CONTROL; - cmd.cmd_common.cmd_buffer[0] = + cmd.lvtma_control.data.uc_pwr_action = uc_pwr_on; - + cmd.lvtma_control.data.panel_inst = + panel_instance; dc_dmub_srv_cmd_queue(dmcub, &cmd); dc_dmub_srv_cmd_execute(dmcub); dc_dmub_srv_wait_idle(dmcub); @@ -943,14 +1016,16 @@ static void enable_lvtma_control_dmcub( static enum bp_result enable_lvtma_control( struct bios_parser *bp, - uint8_t uc_pwr_on) + uint8_t uc_pwr_on, + uint8_t panel_instance) { enum bp_result result = BP_RESULT_FAILURE; if (bp->base.ctx->dc->ctx->dmub_srv && bp->base.ctx->dc->debug.dmub_command_table) { enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv, - uc_pwr_on); + uc_pwr_on, + panel_instance); return BP_RESULT_OK; } return result; diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.h b/drivers/gpu/drm/amd/display/dc/bios/command_table2.h index 7bdce013cde5..be060b4b87db 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.h +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.h @@ -95,7 +95,8 @@ struct cmd_tbl { unsigned int (*get_smu_clock_info)( struct bios_parser *bp, uint8_t id); enum bp_result (*enable_lvtma_control)(struct bios_parser *bp, - uint8_t uc_pwr_on); + uint8_t uc_pwr_on, + uint8_t panel_instance); }; void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp); |