aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch413
1 files changed, 413 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch
new file mode 100644
index 00000000..0c38cf27
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4357-drm-amd-display-add-oem-i2c-implemenation-in-dc.patch
@@ -0,0 +1,413 @@
+From 58809698c7d678019f04e162634cf3750c3cb60b Mon Sep 17 00:00:00 2001
+From: Jun Lei <Jun.Lei@amd.com>
+Date: Fri, 2 Aug 2019 17:22:57 -0400
+Subject: [PATCH 4357/4736] drm/amd/display: add oem i2c implemenation in dc
+
+[why]
+Need it for some OEM I2C devices in Nv10
+
+[how]
+Link up code to parse OEM table and expose DC interface
+to access the pins
+
+Signed-off-by: Jun Lei <Jun.Lei@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
+---
+ .../drm/amd/display/dc/bios/bios_parser2.c | 63 ++++++++++++-------
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 11 ++++
+ .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 5 +-
+ drivers/gpu/drm/amd/display/dc/dc_link.h | 4 ++
+ drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c | 19 +++---
+ .../gpu/drm/amd/display/dc/dce/dce_i2c_sw.c | 43 -------------
+ .../gpu/drm/amd/display/dc/dce/dce_i2c_sw.h | 6 +-
+ .../drm/amd/display/dc/dcn20/dcn20_resource.c | 15 +++++
+ .../display/dc/gpio/dcn20/hw_factory_dcn20.c | 12 ++++
+ .../gpu/drm/amd/display/dc/inc/core_types.h | 2 +
+ .../display/include/grph_object_ctrl_defs.h | 3 +-
+ 11 files changed, 100 insertions(+), 83 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 b4bbfb7bde12..3e2f21af2be7 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -292,11 +292,21 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
+ struct atom_display_object_path_v2 *object;
+ struct atom_common_record_header *header;
+ struct atom_i2c_record *record;
++ struct atom_i2c_record dummy_record = {0};
+ struct bios_parser *bp = BP_FROM_DCB(dcb);
+
+ if (!info)
+ return BP_RESULT_BADINPUT;
+
++ if (id.type == OBJECT_TYPE_GENERIC) {
++ dummy_record.i2c_id = id.id;
++
++ if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
++ return BP_RESULT_OK;
++ else
++ return BP_RESULT_NORECORD;
++ }
++
+ object = get_bios_object(bp, id);
+
+ if (!object)
+@@ -339,6 +349,7 @@ static enum bp_result get_gpio_i2c_info(
+ struct atom_gpio_pin_lut_v2_1 *header;
+ uint32_t count = 0;
+ unsigned int table_index = 0;
++ bool find_valid = false;
+
+ if (!info)
+ return BP_RESULT_BADINPUT;
+@@ -366,33 +377,28 @@ static enum bp_result get_gpio_i2c_info(
+ - sizeof(struct atom_common_table_header))
+ / sizeof(struct atom_gpio_pin_assignment);
+
+- table_index = record->i2c_id & I2C_HW_LANE_MUX;
+-
+- if (count < table_index) {
+- bool find_valid = false;
+-
+- for (table_index = 0; table_index < count; table_index++) {
+- if (((record->i2c_id & I2C_HW_CAP) == (
+- header->gpio_pin[table_index].gpio_id &
+- I2C_HW_CAP)) &&
+- ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
+- (header->gpio_pin[table_index].gpio_id &
+- I2C_HW_ENGINE_ID_MASK)) &&
+- ((record->i2c_id & I2C_HW_LANE_MUX) ==
+- (header->gpio_pin[table_index].gpio_id &
+- I2C_HW_LANE_MUX))) {
+- /* still valid */
+- find_valid = true;
+- break;
+- }
++ for (table_index = 0; table_index < count; table_index++) {
++ if (((record->i2c_id & I2C_HW_CAP) == (
++ header->gpio_pin[table_index].gpio_id &
++ I2C_HW_CAP)) &&
++ ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
++ (header->gpio_pin[table_index].gpio_id &
++ I2C_HW_ENGINE_ID_MASK)) &&
++ ((record->i2c_id & I2C_HW_LANE_MUX) ==
++ (header->gpio_pin[table_index].gpio_id &
++ I2C_HW_LANE_MUX))) {
++ /* still valid */
++ find_valid = true;
++ break;
+ }
+- /* If we don't find the entry that we are looking for then
+- * we will return BP_Result_BadBiosTable.
+- */
+- if (find_valid == false)
+- return BP_RESULT_BADBIOSTABLE;
+ }
+
++ /* If we don't find the entry that we are looking for then
++ * we will return BP_Result_BadBiosTable.
++ */
++ if (find_valid == false)
++ return BP_RESULT_BADBIOSTABLE;
++
+ /* get the GPIO_I2C_INFO */
+ info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
+ info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
+@@ -1203,6 +1209,8 @@ static enum bp_result get_firmware_info_v3_1(
+ bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
+ }
+
++ info->oem_i2c_present = false;
++
+ return BP_RESULT_OK;
+ }
+
+@@ -1281,6 +1289,13 @@ static enum bp_result get_firmware_info_v3_2(
+ bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
+ }
+
++ if (firmware_info->board_i2c_feature_id == 0x2) {
++ info->oem_i2c_present = true;
++ info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
++ } else {
++ info->oem_i2c_present = false;
++ }
++
+ return BP_RESULT_OK;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 0c7925c2faf2..a652ebd77f7a 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2495,6 +2495,17 @@ bool dc_submit_i2c(
+ cmd);
+ }
+
++bool dc_submit_i2c_oem(
++ struct dc *dc,
++ struct i2c_command *cmd)
++{
++ struct ddc_service *ddc = dc->res_pool->oem_device;
++ return dce_i2c_submit_command(
++ dc->res_pool,
++ ddc->ddc_pin,
++ cmd);
++}
++
+ static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
+ {
+ if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+index d98640f49874..747cd0fbe571 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+@@ -204,7 +204,10 @@ static void construct(
+ ddc_service->ddc_pin = NULL;
+ } else {
+ hw_info.ddc_channel = i2c_info.i2c_line;
+- hw_info.hw_supported = i2c_info.i2c_hw_assist;
++ if (ddc_service->link != NULL)
++ hw_info.hw_supported = i2c_info.i2c_hw_assist;
++ else
++ hw_info.hw_supported = false;
+
+ ddc_service->ddc_pin = dal_gpio_create_ddc(
+ gpio_service,
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
+index f24fd19ed93d..9270e43cd5bb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
+@@ -305,6 +305,10 @@ bool dc_submit_i2c(
+ uint32_t link_index,
+ struct i2c_command *cmd);
+
++bool dc_submit_i2c_oem(
++ struct dc *dc,
++ struct i2c_command *cmd);
++
+ uint32_t dc_bandwidth_in_kbps_from_timing(
+ const struct dc_crtc_timing *timing);
+ #endif /* DC_LINK_H_ */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
+index 35a75398fcb4..dd41736bb5c4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c.c
+@@ -31,7 +31,7 @@ bool dce_i2c_submit_command(
+ struct i2c_command *cmd)
+ {
+ struct dce_i2c_hw *dce_i2c_hw;
+- struct dce_i2c_sw *dce_i2c_sw;
++ struct dce_i2c_sw dce_i2c_sw = {0};
+
+ if (!ddc) {
+ BREAK_TO_DEBUGGER();
+@@ -43,18 +43,15 @@ bool dce_i2c_submit_command(
+ return false;
+ }
+
+- /* The software engine is only available on dce8 */
+- dce_i2c_sw = dce_i2c_acquire_i2c_sw_engine(pool, ddc);
+-
+- if (!dce_i2c_sw) {
+- dce_i2c_hw = acquire_i2c_hw_engine(pool, ddc);
+-
+- if (!dce_i2c_hw)
+- return false;
++ dce_i2c_hw = acquire_i2c_hw_engine(pool, ddc);
+
++ if (dce_i2c_hw)
+ return dce_i2c_submit_command_hw(pool, ddc, cmd, dce_i2c_hw);
+- }
+
+- return dce_i2c_submit_command_sw(pool, ddc, cmd, dce_i2c_sw);
++ dce_i2c_sw.ctx = ddc->ctx;
++ if (dce_i2c_engine_acquire_sw(&dce_i2c_sw, ddc)) {
++ return dce_i2c_submit_command_sw(pool, ddc, cmd, &dce_i2c_sw);
++ }
+
++ return false;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c
+index f0266694cb56..f48dbeb75e80 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.c
+@@ -70,31 +70,6 @@ static void release_engine_dce_sw(
+ dce_i2c_sw->ddc = NULL;
+ }
+
+-static bool get_hw_supported_ddc_line(
+- struct ddc *ddc,
+- enum gpio_ddc_line *line)
+-{
+- enum gpio_ddc_line line_found;
+-
+- *line = GPIO_DDC_LINE_UNKNOWN;
+-
+- if (!ddc) {
+- BREAK_TO_DEBUGGER();
+- return false;
+- }
+-
+- if (!ddc->hw_info.hw_supported)
+- return false;
+-
+- line_found = dal_ddc_get_line(ddc);
+-
+- if (line_found >= GPIO_DDC_LINE_COUNT)
+- return false;
+-
+- *line = line_found;
+-
+- return true;
+-}
+ static bool wait_for_scl_high_sw(
+ struct dc_context *ctx,
+ struct ddc *ddc,
+@@ -521,21 +496,3 @@ bool dce_i2c_submit_command_sw(
+
+ return result;
+ }
+-struct dce_i2c_sw *dce_i2c_acquire_i2c_sw_engine(
+- struct resource_pool *pool,
+- struct ddc *ddc)
+-{
+- enum gpio_ddc_line line;
+- struct dce_i2c_sw *engine = NULL;
+-
+- if (get_hw_supported_ddc_line(ddc, &line))
+- engine = pool->sw_i2cs[line];
+-
+- if (!engine)
+- return NULL;
+-
+- if (!dce_i2c_engine_acquire_sw(engine, ddc))
+- return NULL;
+-
+- return engine;
+-}
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.h b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.h
+index 5bbcdd455614..019fc47bb767 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_i2c_sw.h
+@@ -49,9 +49,9 @@ bool dce_i2c_submit_command_sw(
+ struct i2c_command *cmd,
+ struct dce_i2c_sw *dce_i2c_sw);
+
+-struct dce_i2c_sw *dce_i2c_acquire_i2c_sw_engine(
+- struct resource_pool *pool,
+- struct ddc *ddc);
++bool dce_i2c_engine_acquire_sw(
++ struct dce_i2c_sw *dce_i2c_sw,
++ struct ddc *ddc_handle);
+
+ #endif
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+index 19a4838b1ac2..454d30bbfd20 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -57,6 +57,7 @@
+ #include "dml/display_mode_vba.h"
+ #include "dcn20_dccg.h"
+ #include "dcn20_vmid.h"
++#include "dc_link_ddc.h"
+
+ #include "navi10_ip_offset.h"
+
+@@ -1344,6 +1345,8 @@ static void destruct(struct dcn20_resource_pool *pool)
+ if (pool->base.pp_smu != NULL)
+ dcn20_pp_smu_destroy(&pool->base.pp_smu);
+
++ if (pool->base.oem_device != NULL)
++ dal_ddc_service_destroy(&pool->base.oem_device);
+ }
+
+ struct hubp *dcn20_hubp_create(
+@@ -3389,6 +3392,7 @@ static bool construct(
+ int i;
+ struct dc_context *ctx = dc->ctx;
+ struct irq_service_init_data init_data;
++ struct ddc_service_init_data ddc_init_data;
+ struct _vcs_dpi_soc_bounding_box_st *loaded_bb =
+ get_asic_rev_soc_bb(ctx->asic_id.hw_internal_rev);
+ struct _vcs_dpi_ip_params_st *loaded_ip =
+@@ -3684,6 +3688,17 @@ static bool construct(
+
+ dc->cap_funcs = cap_funcs;
+
++ if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
++ ddc_init_data.ctx = dc->ctx;
++ ddc_init_data.link = NULL;
++ ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
++ ddc_init_data.id.enum_id = 0;
++ ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
++ pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
++ } else {
++ pool->base.oem_device = NULL;
++ }
++
+ return true;
+
+ create_fail:
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
+index 43a440385b43..2664cb22dfe7 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c
+@@ -110,6 +110,12 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
+ ddc_data_regs_dcn2(4),
+ ddc_data_regs_dcn2(5),
+ ddc_data_regs_dcn2(6),
++ {
++ DDC_GPIO_VGA_REG_LIST(DATA),
++ .ddc_setup = 0,
++ .phy_aux_cntl = 0,
++ .dc_gpio_aux_ctrl_5 = 0
++ }
+ };
+
+ static const struct ddc_registers ddc_clk_regs_dcn[] = {
+@@ -119,6 +125,12 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
+ ddc_clk_regs_dcn2(4),
+ ddc_clk_regs_dcn2(5),
+ ddc_clk_regs_dcn2(6),
++ {
++ DDC_GPIO_VGA_REG_LIST(CLK),
++ .ddc_setup = 0,
++ .phy_aux_cntl = 0,
++ .dc_gpio_aux_ctrl_5 = 0
++ }
+ };
+
+ static const struct ddc_sh_mask ddc_shift[] = {
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+index a831079607cd..fc9decc0a8fc 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+@@ -229,6 +229,8 @@ struct resource_pool {
+
+ const struct resource_funcs *funcs;
+ const struct resource_caps *res_cap;
++
++ struct ddc_service *oem_device;
+ };
+
+ struct dcn_fe_bandwidth {
+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 f312834fef50..d51de94e4bc3 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
+@@ -178,7 +178,8 @@ struct dc_firmware_info {
+ uint32_t default_engine_clk; /* in KHz */
+ uint32_t dp_phy_ref_clk; /* in KHz - DCE12 only */
+ uint32_t i2c_engine_ref_clk; /* in KHz - DCE12 only */
+-
++ bool oem_i2c_present;
++ uint8_t oem_i2c_obj_id;
+
+ };
+
+--
+2.17.1
+