[PATCH 25/76] drm/amd/dal: fix DDC pad mode detection logic

Harry Wentland harry.wentland at amd.com
Mon Nov 21 23:00:45 UTC 2016


From: Tony Cheng <tony.cheng at amd.com>

- use reg_helper macro for all register field access
- revise logic following golden CZ dal2 logic

Signed-off-by: Tony Cheng <tony.cheng at amd.com>
Acked-by: Harry Wentland <harry.wentland at amd.com>
---
 drivers/gpu/drm/amd/dal/dc/dc_helper.c      | 12 +++++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c    | 78 ++++++++++-------------------
 drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h | 11 ++++
 3 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helper.c b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
index 841d58b8cd7c..6ac801422c63 100644
--- a/drivers/gpu/drm/amd/dal/dc/dc_helper.c
+++ b/drivers/gpu/drm/amd/dal/dc/dc_helper.c
@@ -49,6 +49,18 @@ uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
 	return reg_val;
 }
 
+uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
+		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
+		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
+		uint8_t shift3, uint32_t mask3, uint32_t *field_value3)
+{
+	uint32_t reg_val = dm_read_reg(ctx, addr);
+	*field_value1 = get_reg_field_value_ex(reg_val, mask1, shift1);
+	*field_value2 = get_reg_field_value_ex(reg_val, mask2, shift2);
+	*field_value3 = get_reg_field_value_ex(reg_val, mask3, shift3);
+	return reg_val;
+}
+
 /* note:  va version of this is pretty bad idea, since there is a output parameter pass by pointer
  * compiler won't be able to check for size match and is prone to stack corruption type of bugs
 
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
index e02843d32735..47e0f8f24a86 100644
--- a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
@@ -66,7 +66,6 @@ static enum gpio_result set_config(
 {
 	struct hw_ddc *ddc = HW_DDC_FROM_BASE(ptr);
 	struct hw_gpio *hw_gpio = NULL;
-	uint32_t addr;
 	uint32_t regval;
 	uint32_t ddc_data_pd_en = 0;
 	uint32_t ddc_clk_pd_en = 0;
@@ -79,22 +78,10 @@ static enum gpio_result set_config(
 		return GPIO_RESULT_NULL_HANDLE;
 	}
 
-	/* switch dual mode GPIO to I2C/AUX mode */
-	addr = ddc->base.regs->MASK_reg;
-
-	regval = REG_READ(gpio.MASK_reg);
-
-	ddc_data_pd_en = get_reg_field_value_ex(
-			regval,
-			FN(,DC_GPIO_DDC1DATA_PD_EN));
-
-	ddc_clk_pd_en = get_reg_field_value_ex(
-			regval,
-			FN(,DC_GPIO_DDC1CLK_PD_EN));
-
-	aux_pad_mode = get_reg_field_value_ex(
-			regval,
-			FN(,AUX_PAD1_MODE));
+	regval = REG_GET_3(gpio.MASK_reg,
+			DC_GPIO_DDC1DATA_PD_EN, &ddc_data_pd_en,
+			DC_GPIO_DDC1CLK_PD_EN, &ddc_clk_pd_en,
+			AUX_PAD1_MODE, &aux_pad_mode);
 
 	switch (config_data->config.ddc.type) {
 	case GPIO_DDC_CONFIG_TYPE_MODE_I2C:
@@ -104,52 +91,39 @@ static enum gpio_result set_config(
 		 * is required for detection of AUX mode */
 		if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
 			if (!ddc_data_pd_en || !ddc_clk_pd_en) {
-				set_reg_field_value_ex(
-					regval,
-					1,
-					FN(,DC_GPIO_DDC1DATA_PD_EN));
-
-				set_reg_field_value_ex(
-					regval,
-					1,
-					FN(,DC_GPIO_DDC1CLK_PD_EN));
 
-				REG_WRITE(gpio.MASK_reg, regval);
+				REG_SET_2(gpio.MASK_reg, regval,
+						DC_GPIO_DDC1DATA_PD_EN, 1,
+						DC_GPIO_DDC1CLK_PD_EN, 1);
 
 				if (config_data->type ==
-					GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
-					/* should not affect normal I2C R/W */
-					/* [anaumov] in DAL2, there was
-					 * dc_service_delay_in_microseconds(2500); */
+						GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
 					msleep(3);
 			}
 		} else {
-			uint32_t reg2 = regval;
+			uint32_t reg2;
 			uint32_t sda_pd_dis = 0;
 			uint32_t scl_pd_dis = 0;
 
-			sda_pd_dis = get_reg_field_value_ex(
-					reg2,
-					FN(,DC_GPIO_SDA_PD_DIS));
+			reg2 = REG_GET_2(gpio.MASK_reg,
+					DC_GPIO_SDA_PD_DIS, &sda_pd_dis,
+					DC_GPIO_SCL_PD_DIS, &scl_pd_dis);
 
-			scl_pd_dis = get_reg_field_value_ex(
-					reg2,
-					FN(,DC_GPIO_SCL_PD_DIS));
+			if (sda_pd_dis) {
+				REG_SET(gpio.MASK_reg, regval,
+						DC_GPIO_SDA_PD_DIS, 0);
 
-			if (sda_pd_dis)
-				sda_pd_dis = 0;
-
-			if (!scl_pd_dis)
-				scl_pd_dis = 1;
+				if (config_data->type ==
+						GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+					msleep(3);
+			}
 
-			if (sda_pd_dis || !scl_pd_dis) {
-				REG_WRITE(gpio.MASK_reg, reg2);
+			if (!scl_pd_dis) {
+				REG_SET(gpio.MASK_reg, regval,
+						DC_GPIO_SCL_PD_DIS, 1);
 
 				if (config_data->type ==
-					GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
-					/* should not affect normal I2C R/W */
-					/* [anaumov] in DAL2, there was
-					 * dc_service_delay_in_microseconds(2500); */
+						GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
 					msleep(3);
 			}
 		}
@@ -166,14 +140,16 @@ static enum gpio_result set_config(
 			/* set the I2C pad mode */
 			/* read the register again,
 			 * some bits may have been changed */
-			REG_UPDATE(gpio.MASK_reg, AUX_PAD1_MODE, 1);
+			REG_UPDATE(gpio.MASK_reg,
+					AUX_PAD1_MODE, 0);
 		}
 
 		return GPIO_RESULT_OK;
 	case GPIO_DDC_CONFIG_TYPE_MODE_AUX:
 		/* set the AUX pad mode */
 		if (!aux_pad_mode) {
-			REG_UPDATE(gpio.MASK_reg, AUX_PAD1_MODE, 1);
+			REG_SET(gpio.MASK_reg, regval,
+					AUX_PAD1_MODE, 1);
 		}
 
 		return GPIO_RESULT_OK;
diff --git a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
index 1e3308dfb64a..ef652abcd276 100644
--- a/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
+++ b/drivers/gpu/drm/amd/dal/dc/inc/reg_helper.h
@@ -113,6 +113,12 @@
 				FN(reg_name, f1), v1, \
 				FN(reg_name, f2), v2)
 
+#define REG_GET_3(reg_name, f1, v1, f2, v2, f3, v3)	\
+		generic_reg_get3(CTX, REG(reg_name), \
+				FN(reg_name, f1), v1, \
+				FN(reg_name, f2), v2, \
+				FN(reg_name, f3), v3)
+
 /* macro to poll and wait for a register field to read back given value */
 
 #define REG_WAIT(reg_name, field, val, delay, max_try)	\
@@ -224,4 +230,9 @@ uint32_t generic_reg_get2(const struct dc_context *ctx, uint32_t addr,
 		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
 		uint8_t shift2, uint32_t mask2, uint32_t *field_value2);
 
+uint32_t generic_reg_get3(const struct dc_context *ctx, uint32_t addr,
+		uint8_t shift1, uint32_t mask1, uint32_t *field_value1,
+		uint8_t shift2, uint32_t mask2, uint32_t *field_value2,
+		uint8_t shift3, uint32_t mask3, uint32_t *field_value3);
+
 #endif /* DRIVERS_GPU_DRM_AMD_DAL_DEV_DC_INC_REG_HELPER_H_ */
-- 
2.10.1



More information about the amd-gfx mailing list