Commit 452c76df authored by Charlene Liu's avatar Charlene Liu Committed by Alex Deucher
Browse files

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: default avatarCharlene Liu <Charlene.Liu@amd.com>
Reviewed-by: default avatarChris Park <Chris.Park@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarBindu Ramamurthy <bindu.r@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1a365683
Loading
Loading
Loading
Loading
+10 −3
Original line number Original line Diff line number Diff line
@@ -264,18 +264,25 @@ static void set_speed(
	struct dce_i2c_hw *dce_i2c_hw,
	struct dce_i2c_hw *dce_i2c_hw,
	uint32_t speed)
	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 prescale = 0;
	uint32_t i2c_ref_clock = 0;


	if (speed == 0)
	if (speed == 0)
		return;
		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)
	if (xtal_ref_div == 0)
		xtal_ref_div = 2;
		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)
	if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
		REG_UPDATE_N(SPEED, 3,
		REG_UPDATE_N(SPEED, 3,
+3 −0
Original line number Original line Diff line number Diff line
@@ -139,6 +139,7 @@ enum {
	I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\
	I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\
	I2C_SF(DC_I2C_DATA, DC_I2C_INDEX_WRITE, 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, 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)
	I2C_SF(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, mask_sh)


#define I2C_COMMON_MASK_SH_LIST_DCE110(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;
	uint8_t DC_I2C_INDEX_WRITE;
	uint8_t DC_I2C_INDEX_WRITE;
	uint8_t XTAL_REF_DIV;
	uint8_t XTAL_REF_DIV;
	uint8_t MICROSECOND_TIME_BASE_DIV;
	uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH;
	uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH;
	uint8_t DC_I2C_REG_RW_CNTL_STATUS;
	uint8_t DC_I2C_REG_RW_CNTL_STATUS;
	uint8_t I2C_LIGHT_SLEEP_FORCE;
	uint8_t I2C_LIGHT_SLEEP_FORCE;
@@ -225,6 +227,7 @@ struct dce_i2c_mask {
	uint32_t DC_I2C_INDEX;
	uint32_t DC_I2C_INDEX;
	uint32_t DC_I2C_INDEX_WRITE;
	uint32_t DC_I2C_INDEX_WRITE;
	uint32_t XTAL_REF_DIV;
	uint32_t XTAL_REF_DIV;
	uint32_t MICROSECOND_TIME_BASE_DIV;
	uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH;
	uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH;
	uint32_t DC_I2C_REG_RW_CNTL_STATUS;
	uint32_t DC_I2C_REG_RW_CNTL_STATUS;
	uint32_t I2C_LIGHT_SLEEP_FORCE;
	uint32_t I2C_LIGHT_SLEEP_FORCE;