diff options
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.patch | 413 |
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 + |