mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-02 04:54:44 -05:00
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>
This commit is contained in:
committed by
Alex Deucher
parent
1a365683d6
commit
452c76dfd2
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user