⬢ DragonFlyBSD Kernel Audit
DF-4947 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
+++ b/sys/dev/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
@@ -210,7 +210,6 @@
 	switch (id) {
 	case GPIO_ID_DDC_DATA:
-		info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		switch (en) {
 		case GPIO_DDC_LINE_DDC1:
 			info->offset = REG(DC_GPIO_DDC1_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC2:
 			info->offset = REG(DC_GPIO_DDC2_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC3:
 			info->offset = REG(DC_GPIO_DDC3_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC4:
 			info->offset = REG(DC_GPIO_DDC4_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC5:
 			info->offset = REG(DC_GPIO_DDC5_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC6:
 			info->offset = REG(DC_GPIO_DDC6_A);
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_DDC_VGA:
 			info->offset = REG(DC_GPIO_DDCVGA_A);
+			/* DDCVGADATA_A_MASK == DDC6DATA_A_MASK == 0x100 (same layout) */
+			info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
 		break;
 		case GPIO_DDC_LINE_I2C_PAD:
 			info->offset = REG(DC_GPIO_I2CPAD_A);
+			/* FIX: the I2C pad's data (SDA) field is bit 1, NOT the DDC
+			 * bit-8 layout — must match the factory table (ddc_regs.h
+			 * ddc_i2c_data_regs uses DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK) */
+			info->mask = DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK;
 		break;
 		default:
 			ASSERT_CRITICAL(false);
 			result = false;
 		}