⬢ DragonFlyBSD Kernel Audit
DF-5000 / fix.diff
← back to finding ↓ download raw
fix.diff for DF-5000 — command_table_helper_dce80.c
Complete the dce80 vtable: implement and bind the two members left NULL
(dc_clock_type_to_atom, transmitter_color_depth_to_atom) so that the
unguarded consumer call sites (command_table.c:1188, command_table2.c:308-311,
command_table.c:2437, command_table2.c:722) can never call through NULL,
even under a generation-mismatched (SetPixelClock-V7-era) ROM on DCE8 silicon.

Implementation notes:
- transmitter_color_depth_to_atom mirrors the dce112 implementation
  (command_table_helper_dce112.c:358-376), using dce80's BREAK_TO_DEBUGGER
  style for the default branch.
- dc_clock_type_to_atom mirrors dce112 (command_table_helper_dce112.c:333-355)
  but with the DF-4935 defect fixed in the copy: the default branch writes the
  output and returns false instead of returning true with the caller's
  uninitialized stack (the DF-4935/DF-4937 family fix).
--- sys/dev/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c
+++ sys/dev/drm/amd/display/dc/bios/dce80/command_table_helper_dce80.c
@@ -326,6 +326,58 @@ (after disp_power_gating_action_to_atom)
 	return atom_pipe_action;
 }
 
+static uint8_t transmitter_color_depth_to_atom(
+		enum transmitter_color_depth id)
+{
+	uint8_t atom_color_depth = 0;
+
+	switch (id) {
+	case TRANSMITTER_COLOR_DEPTH_24:
+		atom_color_depth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
+		break;
+	case TRANSMITTER_COLOR_DEPTH_30:
+		atom_color_depth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
+		break;
+	case TRANSMITTER_COLOR_DEPTH_36:
+		atom_color_depth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
+		break;
+	case TRANSMITTER_COLOR_DEPTH_48:
+		atom_color_depth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
+		break;
+	default:
+		BREAK_TO_DEBUGGER(); /* Unhandle action in driver! */
+		break;
+	}
+
+	return atom_color_depth;
+}
+
+static bool dc_clock_type_to_atom(
+		enum bp_dce_clock_type id,
+		uint32_t *atom_clock_type)
+{
+	bool ret_code = false;
+
+	if (atom_clock_type == NULL)
+		return false;
+
+	switch (id) {
+	case DCECLOCK_TYPE_DISPLAY_CLOCK:
+		*atom_clock_type = DCE_CLOCK_TYPE_DISPCLK;
+		ret_code = true;
+		break;
+	case DCECLOCK_TYPE_DPREFCLK:
+		*atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK;
+		ret_code = true;
+		break;
+	default:
+		BREAK_TO_DEBUGGER(); /* Unhandle action in driver! */
+		break;
+	}
+
+	return ret_code;
+}
+
 static const struct command_table_helper command_table_helper_funcs = {
 	.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
 	.encoder_action_to_atom = encoder_action_to_atom,
@@ -346,6 +398,8 @@
 	.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
 	.encoder_mode_bp_to_atom =
 		dal_cmd_table_helper_encoder_mode_bp_to_atom,
+	.dc_clock_type_to_atom = dc_clock_type_to_atom,
+	.transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
 };
 
 const struct command_table_helper *dal_cmd_tbl_helper_dce80_get_table(void)