From 1e8635ea0ea370bf4f0f2b2f1b3eb61474dd962a Mon Sep 17 00:00:00 2001 From: Zeyu Fan Date: Mon, 14 Aug 2017 18:43:11 -0400 Subject: [PATCH] drm/amd/display: Implement HDMI retimer settings for RV AM4 support. Signed-off-by: Zeyu Fan Reviewed-by: Charlene Liu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/bios/bios_parser2.c | 69 +++ drivers/gpu/drm/amd/display/dc/core/dc_link.c | 420 +++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dm_helpers.h | 5 - .../display/include/grph_object_ctrl_defs.h | 38 ++ 5 files changed, 524 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 86fce5ae5856..f8d4f08bf985 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -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) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 1888bf4d2c3f..d77f0de0f2bf 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -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( diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 1210fdd48c56..629aa3c323ca 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -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; diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 39010325cef9..ab88f07772a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -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, diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h index 6cdbf84f34e6..92fe00fab87c 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h @@ -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]; }; /** -- 2.30.2