DF-4047 / fix.diff
--- a/sys/dev/drm/amd/display/dc/bios/command_table.c +++ b/sys/dev/drm/amd/display/dc/bios/command_table.c @@ -364,8 +364,13 @@ static enum bp_result transmitter_control_v1_6( static void init_transmitter_control(struct bios_parser *bp) { - uint8_t frev; - uint8_t crev; + uint8_t frev = 0; + uint8_t crev = 0; if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl, frev, crev) == false) BREAK_TO_DEBUGGER(); + + /* + * amdgpu_atom_parse_cmd_header() does not write frev/crev when the + * command is absent (atom.c:1412-1413); never switch on uninit + * stack, and never select a handler whose helper entry is NULL + * in the DCE110/DCE112 command_table_helper tables (DF-4047). + */ switch (crev) { case 2: + if (bp->cmd_helper->transmitter_bp_to_atom == NULL) + break; bp->cmd_tbl.transmitter_control = transmitter_control_v2; break; @@ -369,6 +374,8 @@ static void init_transmitter_control(struct bios_parser *bp) case 4: + if (bp->cmd_helper->clock_source_id_to_ref_clk_src == NULL) + break; bp->cmd_tbl.transmitter_control = transmitter_control_v4; break; @@ -160,12 +167,16 @@ static void init_encoder_control_dig_v1(struct bios_parser *bp) { struct cmd_tbl *cmd_tbl = &bp->cmd_tbl; - if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl)) + if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl) && + bp->cmd_helper->assign_control_parameter != NULL) cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1; else cmd_tbl->encoder_control_dig1 = NULL; - if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl)) + if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl) && + bp->cmd_helper->assign_control_parameter != NULL) cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1; else cmd_tbl->encoder_control_dig2 = NULL; |