[PATCH 07/12] drm/amd/display: get refclk from MICROSECOND_TIME_BASE_DIV HW register

Bindu Ramamurthy bindu.r at amd.com
Fri Jun 18 17:35:09 UTC 2021


From: Charlene Liu <Charlene.Liu at 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.Liu at amd.com>
Reviewed-by: Chris Park <Chris.Park at amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas at amd.com>
Acked-by: Bindu Ramamurthy <bindu.r at 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



More information about the amd-gfx mailing list