drm/amd/display: Implement HDMI retimer settings for RV AM4 support.
Signed-off-by: Zeyu Fan <Zeyu.Fan@amd.com> Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
0cb8a88122
commit
1e8635ea0e
|
@ -993,6 +993,8 @@ static struct device_id device_type_from_device_id(uint16_t device_id)
|
|||
|
||||
struct device_id result_device_id;
|
||||
|
||||
result_device_id.raw_device_tag = device_id;
|
||||
|
||||
switch (device_id) {
|
||||
case ATOM_DISPLAY_LCD1_SUPPORT:
|
||||
result_device_id.device_type = DEVICE_TYPE_LCD;
|
||||
|
@ -1812,10 +1814,77 @@ static enum bp_result get_integrated_info_v11(
|
|||
info_v11->extdispconninfo.path[i].hpdlut_index;
|
||||
info->ext_disp_conn_info.path[i].channel_mapping.raw =
|
||||
info_v11->extdispconninfo.path[i].channelmapping;
|
||||
info->ext_disp_conn_info.path[i].caps =
|
||||
le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
|
||||
}
|
||||
info->ext_disp_conn_info.checksum =
|
||||
info_v11->extdispconninfo.checksum;
|
||||
|
||||
info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
|
||||
info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
|
||||
for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
|
||||
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
|
||||
info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
|
||||
for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
|
||||
info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
|
||||
info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
|
||||
info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
|
||||
info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
|
||||
for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
|
||||
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
|
||||
info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
|
||||
for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
|
||||
info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
|
||||
info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
|
||||
info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
|
||||
info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
|
||||
for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
|
||||
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
|
||||
info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
|
||||
for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
|
||||
info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
|
||||
info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
|
||||
info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
|
||||
info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
|
||||
for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
|
||||
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
|
||||
info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
|
||||
for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
|
||||
info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
|
||||
info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
|
||||
info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
|
||||
info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
|
||||
}
|
||||
|
||||
|
||||
/** TODO - review **/
|
||||
#if 0
|
||||
info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
|
||||
|
|
|
@ -1044,10 +1044,17 @@ static bool construct(
|
|||
&info.ext_disp_conn_info.path[i];
|
||||
if (path->device_connector_id.enum_id == link->link_id.enum_id
|
||||
&& path->device_connector_id.id == link->link_id.id
|
||||
&& path->device_connector_id.type == link->link_id.type
|
||||
&& path->device_acpi_enum
|
||||
== link->device_tag.acpi_device) {
|
||||
link->ddi_channel_mapping = path->channel_mapping;
|
||||
&& path->device_connector_id.type == link->link_id.type) {
|
||||
|
||||
if (link->device_tag.acpi_device != 0
|
||||
&& path->device_acpi_enum == link->device_tag.acpi_device) {
|
||||
link->ddi_channel_mapping = path->channel_mapping;
|
||||
link->chip_caps = path->caps;
|
||||
} else if (path->device_tag ==
|
||||
link->device_tag.dev_id.raw_device_tag) {
|
||||
link->ddi_channel_mapping = path->channel_mapping;
|
||||
link->chip_caps = path->caps;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1263,11 +1270,416 @@ static enum dc_status enable_link_dp_mst(struct pipe_ctx *pipe_ctx)
|
|||
return enable_link_dp(pipe_ctx);
|
||||
}
|
||||
|
||||
static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx,
|
||||
enum engine_id eng_id,
|
||||
struct ext_hdmi_settings *settings)
|
||||
{
|
||||
bool result = false;
|
||||
int i = 0;
|
||||
struct integrated_info *integrated_info =
|
||||
pipe_ctx->stream->ctx->dc_bios->integrated_info;
|
||||
|
||||
if (integrated_info == NULL)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Get retimer settings from sbios for passing SI eye test for DCE11
|
||||
* The setting values are varied based on board revision and port id
|
||||
* Therefore the setting values of each ports is passed by sbios.
|
||||
*/
|
||||
|
||||
// Check if current bios contains ext Hdmi settings
|
||||
if (integrated_info->gpu_cap_info & 0x20) {
|
||||
switch (eng_id) {
|
||||
case ENGINE_ID_DIGA:
|
||||
settings->slv_addr = integrated_info->dp0_ext_hdmi_slv_addr;
|
||||
settings->reg_num = integrated_info->dp0_ext_hdmi_6g_reg_num;
|
||||
settings->reg_num_6g = integrated_info->dp0_ext_hdmi_6g_reg_num;
|
||||
memmove(settings->reg_settings,
|
||||
integrated_info->dp0_ext_hdmi_reg_settings,
|
||||
sizeof(integrated_info->dp0_ext_hdmi_reg_settings));
|
||||
memmove(settings->reg_settings_6g,
|
||||
integrated_info->dp0_ext_hdmi_6g_reg_settings,
|
||||
sizeof(integrated_info->dp0_ext_hdmi_6g_reg_settings));
|
||||
result = true;
|
||||
break;
|
||||
case ENGINE_ID_DIGB:
|
||||
settings->slv_addr = integrated_info->dp1_ext_hdmi_slv_addr;
|
||||
settings->reg_num = integrated_info->dp1_ext_hdmi_6g_reg_num;
|
||||
settings->reg_num_6g = integrated_info->dp1_ext_hdmi_6g_reg_num;
|
||||
memmove(settings->reg_settings,
|
||||
integrated_info->dp1_ext_hdmi_reg_settings,
|
||||
sizeof(integrated_info->dp1_ext_hdmi_reg_settings));
|
||||
memmove(settings->reg_settings_6g,
|
||||
integrated_info->dp1_ext_hdmi_6g_reg_settings,
|
||||
sizeof(integrated_info->dp1_ext_hdmi_6g_reg_settings));
|
||||
result = true;
|
||||
break;
|
||||
case ENGINE_ID_DIGC:
|
||||
settings->slv_addr = integrated_info->dp2_ext_hdmi_slv_addr;
|
||||
settings->reg_num = integrated_info->dp2_ext_hdmi_6g_reg_num;
|
||||
settings->reg_num_6g = integrated_info->dp2_ext_hdmi_6g_reg_num;
|
||||
memmove(settings->reg_settings,
|
||||
integrated_info->dp2_ext_hdmi_reg_settings,
|
||||
sizeof(integrated_info->dp2_ext_hdmi_reg_settings));
|
||||
memmove(settings->reg_settings_6g,
|
||||
integrated_info->dp2_ext_hdmi_6g_reg_settings,
|
||||
sizeof(integrated_info->dp2_ext_hdmi_6g_reg_settings));
|
||||
result = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
// Validate settings from bios integrated info table
|
||||
if (settings->slv_addr == 0)
|
||||
return false;
|
||||
if (settings->reg_num > 9)
|
||||
return false;
|
||||
if (settings->reg_num_6g > 3)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < settings->reg_num; i++) {
|
||||
if (settings->reg_settings[i].i2c_reg_index > 0x20)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < settings->reg_num_6g; i++) {
|
||||
if (settings->reg_settings_6g[i].i2c_reg_index > 0x20)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool i2c_write(struct pipe_ctx *pipe_ctx,
|
||||
uint8_t address, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
struct i2c_command cmd = {0};
|
||||
struct i2c_payload payload = {0};
|
||||
|
||||
memset(&payload, 0, sizeof(payload));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.number_of_payloads = 1;
|
||||
cmd.engine = I2C_COMMAND_ENGINE_DEFAULT;
|
||||
cmd.speed = pipe_ctx->stream->ctx->dc->caps.i2c_speed_in_khz;
|
||||
|
||||
payload.address = address;
|
||||
payload.data = buffer;
|
||||
payload.length = length;
|
||||
payload.write = true;
|
||||
cmd.payloads = &payload;
|
||||
|
||||
if (dc_submit_i2c(pipe_ctx->stream->ctx->dc,
|
||||
pipe_ctx->stream->sink->link->link_index, &cmd))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void write_i2c_retimer_setting(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
bool is_vga_mode,
|
||||
bool is_over_340mhz,
|
||||
struct ext_hdmi_settings *settings)
|
||||
{
|
||||
uint8_t slave_address = (settings->slv_addr >> 1);
|
||||
uint8_t buffer[2];
|
||||
const uint8_t apply_rx_tx_change = 0x4;
|
||||
uint8_t offset = 0xA;
|
||||
uint8_t value = 0;
|
||||
int i = 0;
|
||||
bool i2c_success = false;
|
||||
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
|
||||
/* Start Ext-Hdmi programming*/
|
||||
|
||||
for (i = 0; i < settings->reg_num; i++) {
|
||||
/* Apply 3G settings */
|
||||
if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
|
||||
|
||||
buffer[0] = settings->reg_settings[i].i2c_reg_index;
|
||||
buffer[1] = settings->reg_settings[i].i2c_reg_val;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
|
||||
* needs to be set to 1 on every 0xA-0xC write.
|
||||
*/
|
||||
if (settings->reg_settings[i].i2c_reg_index == 0xA ||
|
||||
settings->reg_settings[i].i2c_reg_index == 0xB ||
|
||||
settings->reg_settings[i].i2c_reg_index == 0xC) {
|
||||
|
||||
/* Query current value from offset 0xA */
|
||||
if (settings->reg_settings[i].i2c_reg_index == 0xA)
|
||||
value = settings->reg_settings[i].i2c_reg_val;
|
||||
else {
|
||||
i2c_success =
|
||||
dal_ddc_service_query_ddc_data(
|
||||
pipe_ctx->stream->sink->link->ddc,
|
||||
slave_address, &offset, 1, &value, 1);
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
|
||||
buffer[0] = offset;
|
||||
/* Set APPLY_RX_TX_CHANGE bit to 1 */
|
||||
buffer[1] = value | apply_rx_tx_change;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply 3G settings */
|
||||
if (is_over_340mhz) {
|
||||
for (i = 0; i < settings->reg_num_6g; i++) {
|
||||
/* Apply 3G settings */
|
||||
if (settings->reg_settings[i].i2c_reg_index <= 0x20) {
|
||||
|
||||
buffer[0] = settings->reg_settings_6g[i].i2c_reg_index;
|
||||
buffer[1] = settings->reg_settings_6g[i].i2c_reg_val;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A
|
||||
* needs to be set to 1 on every 0xA-0xC write.
|
||||
*/
|
||||
if (settings->reg_settings_6g[i].i2c_reg_index == 0xA ||
|
||||
settings->reg_settings_6g[i].i2c_reg_index == 0xB ||
|
||||
settings->reg_settings_6g[i].i2c_reg_index == 0xC) {
|
||||
|
||||
/* Query current value from offset 0xA */
|
||||
if (settings->reg_settings_6g[i].i2c_reg_index == 0xA)
|
||||
value = settings->reg_settings_6g[i].i2c_reg_val;
|
||||
else {
|
||||
i2c_success =
|
||||
dal_ddc_service_query_ddc_data(
|
||||
pipe_ctx->stream->sink->link->ddc,
|
||||
slave_address, &offset, 1, &value, 1);
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
|
||||
buffer[0] = offset;
|
||||
/* Set APPLY_RX_TX_CHANGE bit to 1 */
|
||||
buffer[1] = value | apply_rx_tx_change;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_vga_mode) {
|
||||
/* Program additional settings if using 640x480 resolution */
|
||||
|
||||
/* Write offset 0xFF to 0x01 */
|
||||
buffer[0] = 0xff;
|
||||
buffer[1] = 0x01;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x00 to 0x23 */
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x23;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0xff to 0x00 */
|
||||
buffer[0] = 0xff;
|
||||
buffer[1] = 0x00;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void write_i2c_default_retimer_setting(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
bool is_vga_mode,
|
||||
bool is_over_340mhz)
|
||||
{
|
||||
uint8_t slave_address = (0xBA >> 1);
|
||||
uint8_t buffer[2];
|
||||
bool i2c_success = false;
|
||||
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
|
||||
/* Program Slave Address for tuning single integrity */
|
||||
/* Write offset 0x0A to 0x13 */
|
||||
buffer[0] = 0x0A;
|
||||
buffer[1] = 0x13;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x0A to 0x17 */
|
||||
buffer[0] = 0x0A;
|
||||
buffer[1] = 0x17;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x0B to 0xDA or 0xD8 */
|
||||
buffer[0] = 0x0B;
|
||||
buffer[1] = is_over_340mhz ? 0xDA : 0xD8;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x0A to 0x17 */
|
||||
buffer[0] = 0x0A;
|
||||
buffer[1] = 0x17;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x0C to 0x1D or 0x91 */
|
||||
buffer[0] = 0x0C;
|
||||
buffer[1] = is_over_340mhz ? 0x1D : 0x91;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x0A to 0x17 */
|
||||
buffer[0] = 0x0A;
|
||||
buffer[1] = 0x17;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
|
||||
if (is_vga_mode) {
|
||||
/* Program additional settings if using 640x480 resolution */
|
||||
|
||||
/* Write offset 0xFF to 0x01 */
|
||||
buffer[0] = 0xff;
|
||||
buffer[1] = 0x01;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0x00 to 0x23 */
|
||||
buffer[0] = 0x00;
|
||||
buffer[1] = 0x23;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
|
||||
/* Write offset 0xff to 0x00 */
|
||||
buffer[0] = 0xff;
|
||||
buffer[1] = 0x00;
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_i2c_redriver_setting(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
bool is_over_340mhz)
|
||||
{
|
||||
uint8_t slave_address = (0xF0 >> 1);
|
||||
uint8_t buffer[16];
|
||||
bool i2c_success = false;
|
||||
|
||||
memset(&buffer, 0, sizeof(buffer));
|
||||
|
||||
// Program Slave Address for tuning single integrity
|
||||
buffer[3] = 0x4E;
|
||||
buffer[4] = 0x4E;
|
||||
buffer[5] = 0x4E;
|
||||
buffer[6] = is_over_340mhz ? 0x4E : 0x4A;
|
||||
|
||||
i2c_success = i2c_write(pipe_ctx, slave_address,
|
||||
buffer, sizeof(buffer));
|
||||
|
||||
if (!i2c_success)
|
||||
/* Write failure */
|
||||
ASSERT(i2c_success);
|
||||
}
|
||||
|
||||
static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct dc_link *link = stream->sink->link;
|
||||
enum dc_color_depth display_color_depth;
|
||||
enum engine_id eng_id;
|
||||
struct ext_hdmi_settings settings = {0};
|
||||
bool is_over_340mhz = false;
|
||||
bool is_vga_mode = (stream->timing.h_addressable == 640)
|
||||
&& (stream->timing.v_addressable == 480);
|
||||
|
||||
if (stream->phy_pix_clk > 340000)
|
||||
is_over_340mhz = true;
|
||||
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) {
|
||||
if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x2) {
|
||||
/* DP159, Retimer settings */
|
||||
eng_id = pipe_ctx->stream_res.stream_enc->id;
|
||||
|
||||
if (get_ext_hdmi_settings(pipe_ctx, eng_id, &settings)) {
|
||||
write_i2c_retimer_setting(pipe_ctx,
|
||||
is_vga_mode, is_over_340mhz, &settings);
|
||||
} else {
|
||||
write_i2c_default_retimer_setting(pipe_ctx,
|
||||
is_vga_mode, is_over_340mhz);
|
||||
}
|
||||
} else if ((pipe_ctx->stream->sink->link->chip_caps >> 2) == 0x1) {
|
||||
/* PI3EQX1204, Redriver settings */
|
||||
write_i2c_redriver_setting(pipe_ctx, is_over_340mhz);
|
||||
}
|
||||
}
|
||||
|
||||
if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
|
||||
dal_ddc_service_write_scdc_data(
|
||||
|
|
|
@ -815,6 +815,7 @@ struct dc_link {
|
|||
union ddi_channel_mapping ddi_channel_mapping;
|
||||
struct connector_device_tag_info device_tag;
|
||||
struct dpcd_caps dpcd_caps;
|
||||
unsigned short chip_caps;
|
||||
unsigned int dpcd_sink_count;
|
||||
|
||||
enum edp_revision edp_revision;
|
||||
|
|
|
@ -96,11 +96,6 @@ bool dm_helpers_submit_i2c(
|
|||
const struct dc_link *link,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum dc_edid_status dm_helpers_read_local_edid(
|
||||
struct dc_context *ctx,
|
||||
struct dc_link *link,
|
||||
|
|
|
@ -65,6 +65,7 @@ enum dal_device_type {
|
|||
struct device_id {
|
||||
enum dal_device_type device_type:16;
|
||||
uint32_t enum_id:16; /* 1 based enum */
|
||||
uint16_t raw_device_tag;
|
||||
};
|
||||
|
||||
struct graphics_object_i2c_info {
|
||||
|
@ -264,6 +265,20 @@ struct transmitter_configuration {
|
|||
#define NUMBER_OF_DISP_CLK_VOLTAGE 4
|
||||
#define NUMBER_OF_AVAILABLE_SCLK 5
|
||||
|
||||
struct i2c_reg_info {
|
||||
unsigned char i2c_reg_index;
|
||||
unsigned char i2c_reg_val;
|
||||
};
|
||||
|
||||
struct ext_hdmi_settings {
|
||||
unsigned char slv_addr;
|
||||
unsigned char reg_num;
|
||||
struct i2c_reg_info reg_settings[9];
|
||||
unsigned char reg_num_6g;
|
||||
struct i2c_reg_info reg_settings_6g[3];
|
||||
};
|
||||
|
||||
|
||||
/* V6 */
|
||||
struct integrated_info {
|
||||
struct clock_voltage_caps {
|
||||
|
@ -291,6 +306,8 @@ struct integrated_info {
|
|||
struct graphics_object_id ext_encoder_obj_id;
|
||||
/* XBAR mapping of the PHY channels */
|
||||
union ddi_channel_mapping channel_mapping;
|
||||
|
||||
unsigned short caps;
|
||||
} path[MAX_NUMBER_OF_EXT_DISPLAY_PATH];
|
||||
|
||||
uint8_t gu_id[NUMBER_OF_UCHAR_FOR_GUID];
|
||||
|
@ -357,6 +374,27 @@ struct integrated_info {
|
|||
uint32_t lvds_pwr_off_seq_blon_to_vary_bl_in_4ms;
|
||||
uint32_t lvds_reserved1;
|
||||
uint32_t lvds_bit_depth_control_val;
|
||||
//Start from V9
|
||||
unsigned char dp0_ext_hdmi_slv_addr;
|
||||
unsigned char dp0_ext_hdmi_reg_num;
|
||||
struct i2c_reg_info dp0_ext_hdmi_reg_settings[9];
|
||||
unsigned char dp0_ext_hdmi_6g_reg_num;
|
||||
struct i2c_reg_info dp0_ext_hdmi_6g_reg_settings[3];
|
||||
unsigned char dp1_ext_hdmi_slv_addr;
|
||||
unsigned char dp1_ext_hdmi_reg_num;
|
||||
struct i2c_reg_info dp1_ext_hdmi_reg_settings[9];
|
||||
unsigned char dp1_ext_hdmi_6g_reg_num;
|
||||
struct i2c_reg_info dp1_ext_hdmi_6g_reg_settings[3];
|
||||
unsigned char dp2_ext_hdmi_slv_addr;
|
||||
unsigned char dp2_ext_hdmi_reg_num;
|
||||
struct i2c_reg_info dp2_ext_hdmi_reg_settings[9];
|
||||
unsigned char dp2_ext_hdmi_6g_reg_num;
|
||||
struct i2c_reg_info dp2_ext_hdmi_6g_reg_settings[3];
|
||||
unsigned char dp3_ext_hdmi_slv_addr;
|
||||
unsigned char dp3_ext_hdmi_reg_num;
|
||||
struct i2c_reg_info dp3_ext_hdmi_reg_settings[9];
|
||||
unsigned char dp3_ext_hdmi_6g_reg_num;
|
||||
struct i2c_reg_info dp3_ext_hdmi_6g_reg_settings[3];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue