drm/amd/display: Refine i2c frequency calculating sequence
[Why] In HG mode, vbios didn't call DispController_Init to program NV1x XTAL_REF_DIV value when ASIC_INIT, but driver read XTAL_REF_DIV to calculate i2c reference frequency. it cause i2c frequency change from 100kHz to 200kHz. [How] remove get_speed function and calculate reference frequency at set_speed functiton. Signed-off-by: Lewis Huang <Lewis.Huang@amd.com> Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
887ff12198
commit
9eeec26a13
|
@ -100,20 +100,6 @@ static uint32_t get_hw_buffer_available_size(
|
|||
dce_i2c_hw->buffer_used_bytes;
|
||||
}
|
||||
|
||||
static uint32_t get_speed(
|
||||
const struct dce_i2c_hw *dce_i2c_hw)
|
||||
{
|
||||
uint32_t pre_scale = 0;
|
||||
|
||||
REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale);
|
||||
|
||||
/* [anaumov] it seems following is unnecessary */
|
||||
/*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
|
||||
return pre_scale ?
|
||||
dce_i2c_hw->reference_frequency / pre_scale :
|
||||
dce_i2c_hw->default_speed;
|
||||
}
|
||||
|
||||
static void process_channel_reply(
|
||||
struct dce_i2c_hw *dce_i2c_hw,
|
||||
struct i2c_payload *reply)
|
||||
|
@ -278,16 +264,25 @@ static void set_speed(
|
|||
struct dce_i2c_hw *dce_i2c_hw,
|
||||
uint32_t speed)
|
||||
{
|
||||
uint32_t xtal_ref_div = 0;
|
||||
uint32_t prescale = 0;
|
||||
|
||||
REG_GET(MICROSECOND_TIME_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 (speed) {
|
||||
if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
|
||||
REG_UPDATE_N(SPEED, 3,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
|
||||
else
|
||||
REG_UPDATE_N(SPEED, 2,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
|
||||
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
|
||||
}
|
||||
}
|
||||
|
@ -344,9 +339,7 @@ static void release_engine(
|
|||
bool safe_to_reset;
|
||||
|
||||
/* Restore original HW engine speed */
|
||||
|
||||
set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);
|
||||
|
||||
REG_WRITE(SPEED, dce_i2c_hw->original_speed);
|
||||
|
||||
/* Reset HW engine */
|
||||
{
|
||||
|
@ -416,7 +409,7 @@ struct dce_i2c_hw *acquire_i2c_hw_engine(
|
|||
|
||||
dce_i2c_hw->ddc = ddc;
|
||||
|
||||
current_speed = get_speed(dce_i2c_hw);
|
||||
current_speed = REG_READ(SPEED);
|
||||
|
||||
if (current_speed)
|
||||
dce_i2c_hw->original_speed = current_speed;
|
||||
|
@ -478,13 +471,9 @@ static void submit_channel_request_hw(
|
|||
|
||||
static uint32_t get_transaction_timeout_hw(
|
||||
const struct dce_i2c_hw *dce_i2c_hw,
|
||||
uint32_t length)
|
||||
uint32_t length,
|
||||
uint32_t speed)
|
||||
{
|
||||
|
||||
uint32_t speed = get_speed(dce_i2c_hw);
|
||||
|
||||
|
||||
|
||||
uint32_t period_timeout;
|
||||
uint32_t num_of_clock_stretches;
|
||||
|
||||
|
@ -504,7 +493,8 @@ static uint32_t get_transaction_timeout_hw(
|
|||
bool dce_i2c_hw_engine_submit_payload(
|
||||
struct dce_i2c_hw *dce_i2c_hw,
|
||||
struct i2c_payload *payload,
|
||||
bool middle_of_transaction)
|
||||
bool middle_of_transaction,
|
||||
uint32_t speed)
|
||||
{
|
||||
|
||||
struct i2c_request_transaction_data request;
|
||||
|
@ -542,7 +532,7 @@ bool dce_i2c_hw_engine_submit_payload(
|
|||
/* obtain timeout value before submitting request */
|
||||
|
||||
transaction_timeout = get_transaction_timeout_hw(
|
||||
dce_i2c_hw, payload->length + 1);
|
||||
dce_i2c_hw, payload->length + 1, speed);
|
||||
|
||||
submit_channel_request_hw(
|
||||
dce_i2c_hw, &request);
|
||||
|
@ -588,13 +578,11 @@ bool dce_i2c_submit_command_hw(
|
|||
struct i2c_payload *payload = cmd->payloads + index_of_payload;
|
||||
|
||||
if (!dce_i2c_hw_engine_submit_payload(
|
||||
dce_i2c_hw, payload, mot)) {
|
||||
dce_i2c_hw, payload, mot, cmd->speed)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
++index_of_payload;
|
||||
}
|
||||
|
||||
|
@ -640,9 +628,6 @@ void dce100_i2c_hw_construct(
|
|||
const struct dce_i2c_shift *shifts,
|
||||
const struct dce_i2c_mask *masks)
|
||||
{
|
||||
|
||||
uint32_t xtal_ref_div = 0;
|
||||
|
||||
dce_i2c_hw_construct(dce_i2c_hw,
|
||||
ctx,
|
||||
engine_id,
|
||||
|
@ -650,21 +635,6 @@ void dce100_i2c_hw_construct(
|
|||
shifts,
|
||||
masks);
|
||||
dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;
|
||||
|
||||
REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
|
||||
|
||||
if (xtal_ref_div == 0)
|
||||
xtal_ref_div = 2;
|
||||
|
||||
/*Calculating Reference Clock by divding original frequency by
|
||||
* XTAL_REF_DIV.
|
||||
* At upper level, uint32_t reference_frequency =
|
||||
* dal_dce_i2c_get_reference_clock(as) >> 1
|
||||
* which already divided by 2. So we need x2 to get original
|
||||
* reference clock from ppll_info
|
||||
*/
|
||||
dce_i2c_hw->reference_frequency =
|
||||
(dce_i2c_hw->reference_frequency * 2) / xtal_ref_div;
|
||||
}
|
||||
|
||||
void dce112_i2c_hw_construct(
|
||||
|
|
Loading…
Reference in New Issue