Skip to content

Commit

Permalink
drm/amd/display: get refclk from MICROSECOND_TIME_BASE_DIV HW register
Browse files Browse the repository at this point in the history
[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 <[email protected]>
Reviewed-by: Chris Park <[email protected]>
Reviewed-by: Nicholas Kazlauskas <[email protected]>
Acked-by: Bindu Ramamurthy <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
  • Loading branch information
Charlene Liu authored and valpackett committed Feb 26, 2022
1 parent 474b7ab commit e55f295
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,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)\
Expand Down Expand Up @@ -177,6 +178,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;
};
Expand Down Expand Up @@ -218,6 +220,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;
};
Expand Down

0 comments on commit e55f295

Please sign in to comment.