From: Tony Cheng <tony.cheng@xxxxxxx> - 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