Skip to content

Commit 452c76d

Browse files
charliu-AMDENGalexdeucher
authored andcommitted
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>
1 parent 1a36568 commit 452c76d

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,18 +264,25 @@ static void set_speed(
264264
struct dce_i2c_hw *dce_i2c_hw,
265265
uint32_t speed)
266266
{
267-
uint32_t xtal_ref_div = 0;
267+
uint32_t xtal_ref_div = 0, ref_base_div = 0;
268268
uint32_t prescale = 0;
269+
uint32_t i2c_ref_clock = 0;
269270

270271
if (speed == 0)
271272
return;
272273

273-
REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
274+
REG_GET_2(MICROSECOND_TIME_BASE_DIV, MICROSECOND_TIME_BASE_DIV, &ref_base_div,
275+
XTAL_REF_DIV, &xtal_ref_div);
274276

275277
if (xtal_ref_div == 0)
276278
xtal_ref_div = 2;
277279

278-
prescale = ((dce_i2c_hw->reference_frequency * 2) / xtal_ref_div) / speed;
280+
if (ref_base_div == 0)
281+
i2c_ref_clock = (dce_i2c_hw->reference_frequency * 2);
282+
else
283+
i2c_ref_clock = ref_base_div * 1000;
284+
285+
prescale = (i2c_ref_clock / xtal_ref_div) / speed;
279286

280287
if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
281288
REG_UPDATE_N(SPEED, 3,

drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ enum {
139139
I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\
140140
I2C_SF(DC_I2C_DATA, DC_I2C_INDEX_WRITE, mask_sh),\
141141
I2C_SF(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, mask_sh),\
142+
I2C_SF(MICROSECOND_TIME_BASE_DIV, MICROSECOND_TIME_BASE_DIV, mask_sh),\
142143
I2C_SF(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, mask_sh)
143144

144145
#define I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh)\
@@ -182,6 +183,7 @@ struct dce_i2c_shift {
182183
uint8_t DC_I2C_INDEX;
183184
uint8_t DC_I2C_INDEX_WRITE;
184185
uint8_t XTAL_REF_DIV;
186+
uint8_t MICROSECOND_TIME_BASE_DIV;
185187
uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH;
186188
uint8_t DC_I2C_REG_RW_CNTL_STATUS;
187189
uint8_t I2C_LIGHT_SLEEP_FORCE;
@@ -225,6 +227,7 @@ struct dce_i2c_mask {
225227
uint32_t DC_I2C_INDEX;
226228
uint32_t DC_I2C_INDEX_WRITE;
227229
uint32_t XTAL_REF_DIV;
230+
uint32_t MICROSECOND_TIME_BASE_DIV;
228231
uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH;
229232
uint32_t DC_I2C_REG_RW_CNTL_STATUS;
230233
uint32_t I2C_LIGHT_SLEEP_FORCE;

0 commit comments

Comments
 (0)