From: Charlene Liu <charlene....@amd.com>

[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....@amd.com>
Reviewed-by: Chris Park <chris.p...@amd.com>
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlaus...@amd.com>
Acked-by: Bindu Ramamurthy <bind...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c | 13 ++++++++++---
 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;
-- 
2.25.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to