diff options
author | Charlene Liu <Charlene.Liu@amd.com> | 2021-05-25 14:06:37 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2021-06-21 17:45:14 -0400 |
commit | 452c76dfd24f799677d7ea4735daf89f479128f2 (patch) | |
tree | fd6dab12da933727b1514f43710b56b3cb61d954 | |
parent | 1a365683d6df1bf22d248fe62d227867793a58f1 (diff) | |
download | linux-452c76dfd24f799677d7ea4735daf89f479128f2.tar.gz linux-452c76dfd24f799677d7ea4735daf89f479128f2.tar.bz2 linux-452c76dfd24f799677d7ea4735daf89f479128f2.zip |
drm/amd/display: get refclk from MICROSECOND_TIME_BASE_DIV HW register
[why]
recent VBIOS dce_infotable reference clock change caused a I2c regression.
instead of relying on vbios, let's get it from HW directly.
Signed-off-by: Charlene Liu <Charlene.Liu@amd.com>
Reviewed-by: Chris Park <Chris.Park@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Bindu Ramamurthy <bindu.r@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h | 3 |
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c index a524f471e0d7..6d1b01c267b7 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c @@ -264,18 +264,25 @@ static void set_speed( struct dce_i2c_hw *dce_i2c_hw, uint32_t speed) { - uint32_t xtal_ref_div = 0; + uint32_t xtal_ref_div = 0, ref_base_div = 0; uint32_t prescale = 0; + uint32_t i2c_ref_clock = 0; if (speed == 0) return; - REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div); + REG_GET_2(MICROSECOND_TIME_BASE_DIV, MICROSECOND_TIME_BASE_DIV, &ref_base_div, + XTAL_REF_DIV, &xtal_ref_div); if (xtal_ref_div == 0) xtal_ref_div = 2; - prescale = ((dce_i2c_hw->reference_frequency * 2) / xtal_ref_div) / speed; + if (ref_base_div == 0) + i2c_ref_clock = (dce_i2c_hw->reference_frequency * 2); + else + i2c_ref_clock = ref_base_div * 1000; + + prescale = (i2c_ref_clock / xtal_ref_div) / speed; if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL) REG_UPDATE_N(SPEED, 3, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h index 2309f2bb162c..3f45ecd189a2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h @@ -139,6 +139,7 @@ enum { I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\ I2C_SF(DC_I2C_DATA, DC_I2C_INDEX_WRITE, mask_sh),\ I2C_SF(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, mask_sh),\ + I2C_SF(MICROSECOND_TIME_BASE_DIV, MICROSECOND_TIME_BASE_DIV, mask_sh),\ I2C_SF(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, mask_sh) #define I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ @@ -182,6 +183,7 @@ struct dce_i2c_shift { uint8_t DC_I2C_INDEX; uint8_t DC_I2C_INDEX_WRITE; uint8_t XTAL_REF_DIV; + uint8_t MICROSECOND_TIME_BASE_DIV; uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH; uint8_t DC_I2C_REG_RW_CNTL_STATUS; uint8_t I2C_LIGHT_SLEEP_FORCE; @@ -225,6 +227,7 @@ struct dce_i2c_mask { uint32_t DC_I2C_INDEX; uint32_t DC_I2C_INDEX_WRITE; uint32_t XTAL_REF_DIV; + uint32_t MICROSECOND_TIME_BASE_DIV; uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH; uint32_t DC_I2C_REG_RW_CNTL_STATUS; uint32_t I2C_LIGHT_SLEEP_FORCE; |