Commit 9eeec26a authored by Lewis Huang's avatar Lewis Huang Committed by Alex Deucher

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: default avatarLewis Huang <Lewis.Huang@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 887ff121
...@@ -100,20 +100,6 @@ static uint32_t get_hw_buffer_available_size( ...@@ -100,20 +100,6 @@ static uint32_t get_hw_buffer_available_size(
dce_i2c_hw->buffer_used_bytes; 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( static void process_channel_reply(
struct dce_i2c_hw *dce_i2c_hw, struct dce_i2c_hw *dce_i2c_hw,
struct i2c_payload *reply) struct i2c_payload *reply)
...@@ -278,16 +264,25 @@ static void set_speed( ...@@ -278,16 +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 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 (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,
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_THRESHOLD), 2,
FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1); FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
else else
REG_UPDATE_N(SPEED, 2, 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); FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
} }
} }
...@@ -344,9 +339,7 @@ static void release_engine( ...@@ -344,9 +339,7 @@ static void release_engine(
bool safe_to_reset; bool safe_to_reset;
/* Restore original HW engine speed */ /* Restore original HW engine speed */
REG_WRITE(SPEED, dce_i2c_hw->original_speed);
set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);
/* Reset HW engine */ /* Reset HW engine */
{ {
...@@ -416,7 +409,7 @@ struct dce_i2c_hw *acquire_i2c_hw_engine( ...@@ -416,7 +409,7 @@ struct dce_i2c_hw *acquire_i2c_hw_engine(
dce_i2c_hw->ddc = ddc; dce_i2c_hw->ddc = ddc;
current_speed = get_speed(dce_i2c_hw); current_speed = REG_READ(SPEED);
if (current_speed) if (current_speed)
dce_i2c_hw->original_speed = current_speed; dce_i2c_hw->original_speed = current_speed;
...@@ -478,13 +471,9 @@ static void submit_channel_request_hw( ...@@ -478,13 +471,9 @@ static void submit_channel_request_hw(
static uint32_t get_transaction_timeout_hw( static uint32_t get_transaction_timeout_hw(
const struct dce_i2c_hw *dce_i2c_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 period_timeout;
uint32_t num_of_clock_stretches; uint32_t num_of_clock_stretches;
...@@ -504,7 +493,8 @@ static uint32_t get_transaction_timeout_hw( ...@@ -504,7 +493,8 @@ static uint32_t get_transaction_timeout_hw(
bool dce_i2c_hw_engine_submit_payload( bool dce_i2c_hw_engine_submit_payload(
struct dce_i2c_hw *dce_i2c_hw, struct dce_i2c_hw *dce_i2c_hw,
struct i2c_payload *payload, struct i2c_payload *payload,
bool middle_of_transaction) bool middle_of_transaction,
uint32_t speed)
{ {
struct i2c_request_transaction_data request; struct i2c_request_transaction_data request;
...@@ -542,7 +532,7 @@ bool dce_i2c_hw_engine_submit_payload( ...@@ -542,7 +532,7 @@ bool dce_i2c_hw_engine_submit_payload(
/* obtain timeout value before submitting request */ /* obtain timeout value before submitting request */
transaction_timeout = get_transaction_timeout_hw( transaction_timeout = get_transaction_timeout_hw(
dce_i2c_hw, payload->length + 1); dce_i2c_hw, payload->length + 1, speed);
submit_channel_request_hw( submit_channel_request_hw(
dce_i2c_hw, &request); dce_i2c_hw, &request);
...@@ -588,13 +578,11 @@ bool dce_i2c_submit_command_hw( ...@@ -588,13 +578,11 @@ bool dce_i2c_submit_command_hw(
struct i2c_payload *payload = cmd->payloads + index_of_payload; struct i2c_payload *payload = cmd->payloads + index_of_payload;
if (!dce_i2c_hw_engine_submit_payload( if (!dce_i2c_hw_engine_submit_payload(
dce_i2c_hw, payload, mot)) { dce_i2c_hw, payload, mot, cmd->speed)) {
result = false; result = false;
break; break;
} }
++index_of_payload; ++index_of_payload;
} }
...@@ -640,9 +628,6 @@ void dce100_i2c_hw_construct( ...@@ -640,9 +628,6 @@ void dce100_i2c_hw_construct(
const struct dce_i2c_shift *shifts, const struct dce_i2c_shift *shifts,
const struct dce_i2c_mask *masks) const struct dce_i2c_mask *masks)
{ {
uint32_t xtal_ref_div = 0;
dce_i2c_hw_construct(dce_i2c_hw, dce_i2c_hw_construct(dce_i2c_hw,
ctx, ctx,
engine_id, engine_id,
...@@ -650,21 +635,6 @@ void dce100_i2c_hw_construct( ...@@ -650,21 +635,6 @@ void dce100_i2c_hw_construct(
shifts, shifts,
masks); masks);
dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100; 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( void dce112_i2c_hw_construct(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment