[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