diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c')
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c index 310f48965b27..d9e6e70dc394 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c @@ -25,6 +25,7 @@ #include "dm_services.h" +#include "include/gpio_interface.h" #include "include/gpio_types.h" #include "hw_gpio.h" #include "hw_ddc.h" @@ -42,18 +43,20 @@ #define REG(reg)\ (ddc->regs->reg) -static void destruct( +struct gpio; + +static void dal_hw_ddc_destruct( struct hw_ddc *pin) { dal_hw_gpio_destruct(&pin->base); } -static void destroy( +static void dal_hw_ddc_destroy( struct hw_gpio_pin **ptr) { struct hw_ddc *pin = HW_DDC_FROM_BASE(*ptr); - destruct(pin); + dal_hw_ddc_destruct(pin); kfree(pin); @@ -91,23 +94,25 @@ 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) { - - REG_SET_2(gpio.MASK_reg, regval, + if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) { + // bit 4 of mask has different usage in some cases + REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1); + } else { + 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) msleep(3); } } else { - uint32_t reg2; uint32_t sda_pd_dis = 0; uint32_t scl_pd_dis = 0; - reg2 = REG_GET_2(gpio.MASK_reg, - DC_GPIO_SDA_PD_DIS, &sda_pd_dis, - DC_GPIO_SCL_PD_DIS, &scl_pd_dis); + REG_GET_2(gpio.MASK_reg, + DC_GPIO_SDA_PD_DIS, &sda_pd_dis, + DC_GPIO_SCL_PD_DIS, &scl_pd_dis); if (sda_pd_dis) { REG_SET(gpio.MASK_reg, regval, @@ -144,6 +149,13 @@ static enum gpio_result set_config( AUX_PAD1_MODE, 0); } + if (ddc->regs->dc_gpio_aux_ctrl_5 != 0) { + REG_UPDATE(dc_gpio_aux_ctrl_5, DDC_PAD_I2CMODE, 1); + } + //set DC_IO_aux_rxsel = 2'b01 + if (ddc->regs->phy_aux_cntl != 0) { + REG_UPDATE(phy_aux_cntl, AUX_PAD_RXSEL, 1); + } return GPIO_RESULT_OK; case GPIO_DDC_CONFIG_TYPE_MODE_AUX: /* set the AUX pad mode */ @@ -151,11 +163,14 @@ static enum gpio_result set_config( REG_SET(gpio.MASK_reg, regval, AUX_PAD1_MODE, 1); } + if (ddc->regs->dc_gpio_aux_ctrl_5 != 0) { + REG_UPDATE(dc_gpio_aux_ctrl_5, + DDC_PAD_I2CMODE, 0); + } return GPIO_RESULT_OK; case GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT: - if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) && - (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) { + if (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA) { REG_UPDATE_3(ddc_setup, DC_I2C_DDC1_ENABLE, 1, DC_I2C_DDC1_EDID_DETECT_ENABLE, 1, @@ -164,8 +179,7 @@ static enum gpio_result set_config( } break; case GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT: - if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) && - (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) { + if (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA) { REG_UPDATE_3(ddc_setup, DC_I2C_DDC1_ENABLE, 1, DC_I2C_DDC1_EDID_DETECT_ENABLE, 1, @@ -174,8 +188,7 @@ static enum gpio_result set_config( } break; case GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING: - if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) && - (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) { + if (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA) { REG_UPDATE_2(ddc_setup, DC_I2C_DDC1_ENABLE, 0, DC_I2C_DDC1_EDID_DETECT_ENABLE, 0); @@ -190,7 +203,7 @@ static enum gpio_result set_config( } static const struct hw_gpio_pin_funcs funcs = { - .destroy = destroy, + .destroy = dal_hw_ddc_destroy, .open = dal_hw_gpio_open, .get_value = dal_hw_gpio_get_value, .set_value = dal_hw_gpio_set_value, @@ -199,7 +212,7 @@ static const struct hw_gpio_pin_funcs funcs = { .close = dal_hw_gpio_close, }; -static void construct( +static void dal_hw_ddc_construct( struct hw_ddc *ddc, enum gpio_id id, uint32_t en, @@ -209,24 +222,29 @@ static void construct( ddc->base.base.funcs = &funcs; } -struct hw_gpio_pin *dal_hw_ddc_create( +void dal_hw_ddc_init( + struct hw_ddc **hw_ddc, struct dc_context *ctx, enum gpio_id id, uint32_t en) { - struct hw_ddc *pin; - - if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { + if (en > GPIO_DDC_LINE_MAX) { ASSERT_CRITICAL(false); - return NULL; + *hw_ddc = NULL; } - pin = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); - if (!pin) { + *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); + if (!*hw_ddc) { ASSERT_CRITICAL(false); - return NULL; + return; } - construct(pin, id, en, ctx); - return &pin->base.base; + dal_hw_ddc_construct(*hw_ddc, id, en, ctx); +} + +struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio) +{ + struct hw_ddc *hw_ddc = dal_gpio_get_ddc(gpio); + + return &hw_ddc->base.base; } |
