From: Jun Lei <jun....@amd.com>

[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....@amd.com>
Reviewed-by: Aric Cyr <aric....@amd.com>
Acked-by: Bhawanpreet Lakha <bhawanpreet.la...@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 7873abea4112..05be2c0c25d1 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -294,11 +294,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)
@@ -341,6 +351,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;
@@ -368,33 +379,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;
@@ -1205,6 +1211,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;
 }
 
@@ -1283,6 +1291,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 b26ed07c2d2c..b3366ccc29c3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2498,6 +2498,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 7f904d55c1bc..a2e6adacaff6 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
@@ -206,7 +206,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 a5a11c251e25..87d8428df6c4 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
@@ -73,31 +73,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,
@@ -524,21 +499,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 1862d8a192bc..a6dfa716ba97 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -59,6 +59,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"
 
@@ -1341,6 +1342,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(
@@ -3386,6 +3389,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 =
@@ -3681,6 +3685,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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to