drm/amd/display: Add dependant changes for DCN32/321
authorAurabindo Pillai <aurabindo.pillai@amd.com>
Wed, 23 Feb 2022 22:48:45 +0000 (17:48 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 3 Jun 2022 20:43:38 +0000 (16:43 -0400)
[Why&How]
This patch adds necessary changes needed in DC files outside DCN32/321
specific tree

v2: squash in updates (Alex)

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
49 files changed:
drivers/gpu/drm/amd/display/dc/Makefile
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h
drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_bios_types.h
drivers/gpu/drm/amd/display/dc/dc_hw_types.h
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dce/dce_abm.h
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.h
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_stream_encoder.h
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
drivers/gpu/drm/amd/display/dc/inc/core_types.h
drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h
drivers/gpu/drm/amd/display/dc/inc/resource.h
drivers/gpu/drm/amd/display/include/bios_parser_types.h

index b4eca02..4de8e18 100644 (file)
@@ -38,6 +38,8 @@ DC_LIBS += dcn303
 DC_LIBS += dcn31
 DC_LIBS += dcn315
 DC_LIBS += dcn316
+DC_LIBS += dcn32
+DC_LIBS += dcn321
 endif
 
 DC_LIBS += dce120
index 23a3b64..bbc0a57 100644 (file)
@@ -165,9 +165,21 @@ static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
        unsigned int count = 0;
        unsigned int i;
 
-       for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
-               if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
-                       count++;
+       switch (bp->object_info_tbl.revision.minor) {
+       default:
+       case 4:
+               for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++)
+                       if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
+                               count++;
+
+               break;
+
+       case 5:
+               for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++)
+                       if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0)
+                               count++;
+
+               break;
        }
        return count;
 }
@@ -182,16 +194,34 @@ static struct graphics_object_id bios_parser_get_connector_id(
        struct object_info_table *tbl = &bp->object_info_tbl;
        struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
 
-       if (v1_4->number_of_path > i) {
-               /* If display_objid is generic object id,  the encoderObj
-                * /extencoderobjId should be 0
-                */
-               if (v1_4->display_path[i].encoderobjid != 0 &&
-                               v1_4->display_path[i].display_objid != 0)
-                       object_id = object_id_from_bios_object_id(
+       struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5;
+
+       switch (bp->object_info_tbl.revision.minor) {
+       default:
+       case 4:
+               if (v1_4->number_of_path > i) {
+                       /* If display_objid is generic object id,  the encoderObj
+                        * /extencoderobjId should be 0
+                        */
+                       if (v1_4->display_path[i].encoderobjid != 0 &&
+                           v1_4->display_path[i].display_objid != 0)
+                               object_id = object_id_from_bios_object_id(
                                        v1_4->display_path[i].display_objid);
-       }
+               }
+               break;
 
+       case 5:
+               if (v1_5->number_of_path > i) {
+                       /* If display_objid is generic object id,  the encoderObjId
+                * should be 0
+                */
+                       if (v1_5->display_path[i].encoderobjid != 0 &&
+                           v1_5->display_path[i].display_objid != 0)
+                               object_id = object_id_from_bios_object_id(
+                                       v1_5->display_path[i].display_objid);
+               }
+               break;
+       }
        return object_id;
 }
 
@@ -201,8 +231,8 @@ static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
        unsigned int i;
-       enum bp_result  bp_result = BP_RESULT_BADINPUT;
-       struct graphics_object_id obj_id = {0};
+       enum bp_result bp_result = BP_RESULT_BADINPUT;
+       struct graphics_object_id obj_id = { 0 };
        struct object_info_table *tbl = &bp->object_info_tbl;
 
        if (!src_object_id)
@@ -217,37 +247,84 @@ static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
                 * If found in for loop, should break.
                 * DAL2 implementation may be changed too
                 */
-               for (i = 0; i < tbl->v1_4->number_of_path; i++) {
-                       obj_id = object_id_from_bios_object_id(
-                       tbl->v1_4->display_path[i].encoderobjid);
-                       if (object_id.type == obj_id.type &&
-                                       object_id.id == obj_id.id &&
-                                               object_id.enum_id ==
-                                                       obj_id.enum_id) {
-                               *src_object_id =
-                               object_id_from_bios_object_id(0x1100);
-                               /* break; */
+               switch (bp->object_info_tbl.revision.minor) {
+               default:
+               case 4:
+                       for (i = 0; i < tbl->v1_4->number_of_path; i++) {
+                               obj_id = object_id_from_bios_object_id(
+                                       tbl->v1_4->display_path[i].encoderobjid);
+                               if (object_id.type == obj_id.type &&
+                                   object_id.id == obj_id.id &&
+                                   object_id.enum_id == obj_id.enum_id) {
+                                       *src_object_id =
+                                               object_id_from_bios_object_id(
+                                                       0x1100);
+                                       /* break; */
+                               }
+                       }
+                       bp_result = BP_RESULT_OK;
+                       break;
+
+               case 5:
+                       for (i = 0; i < tbl->v1_5->number_of_path; i++) {
+                               obj_id = object_id_from_bios_object_id(
+                                       tbl->v1_5->display_path[i].encoderobjid);
+                               if (object_id.type == obj_id.type &&
+                                   object_id.id == obj_id.id &&
+                                   object_id.enum_id == obj_id.enum_id) {
+                                       *src_object_id =
+                                               object_id_from_bios_object_id(
+                                                       0x1100);
+                                       /* break; */
+                               }
                        }
+                       bp_result = BP_RESULT_OK;
+                       break;
                }
-               bp_result = BP_RESULT_OK;
                break;
        case OBJECT_TYPE_CONNECTOR:
-               for (i = 0; i < tbl->v1_4->number_of_path; i++) {
-                       obj_id = object_id_from_bios_object_id(
-                               tbl->v1_4->display_path[i].display_objid);
-
-                       if (object_id.type == obj_id.type &&
-                               object_id.id == obj_id.id &&
-                                       object_id.enum_id == obj_id.enum_id) {
-                               *src_object_id =
-                               object_id_from_bios_object_id(
-                               tbl->v1_4->display_path[i].encoderobjid);
-                               /* break; */
+               switch (bp->object_info_tbl.revision.minor) {
+               default:
+               case 4:
+                       for (i = 0; i < tbl->v1_4->number_of_path; i++) {
+                               obj_id = object_id_from_bios_object_id(
+                                       tbl->v1_4->display_path[i]
+                                               .display_objid);
+
+                               if (object_id.type == obj_id.type &&
+                                   object_id.id == obj_id.id &&
+                                   object_id.enum_id == obj_id.enum_id) {
+                                       *src_object_id =
+                                               object_id_from_bios_object_id(
+                                                       tbl->v1_4
+                                                               ->display_path[i]
+                                                               .encoderobjid);
+                                       /* break; */
+                               }
                        }
+                       bp_result = BP_RESULT_OK;
+                       break;
                }
                bp_result = BP_RESULT_OK;
                break;
+               case 5:
+                       for (i = 0; i < tbl->v1_5->number_of_path; i++) {
+                               obj_id = object_id_from_bios_object_id(
+                                                                      tbl->v1_5->display_path[i].display_objid);
+
+                               if (object_id.type == obj_id.type &&
+                                   object_id.id == obj_id.id &&
+                                   object_id.enum_id == obj_id.enum_id) {
+                                       *src_object_id = object_id_from_bios_object_id(
+                                                                                      tbl->v1_5->display_path[i].encoderobjid);
+                                       /* break; */
+                               }
+                       }
+               bp_result = BP_RESULT_OK;
+               break;
+
        default:
+               bp_result = BP_RESULT_OK;
                break;
        }
 
@@ -290,12 +367,55 @@ static struct atom_display_object_path_v2 *get_bios_object(
        }
 }
 
+/* from graphics_object_id, find display path which includes the object_id */
+static struct atom_display_object_path_v3 *get_bios_object_from_path_v3(
+       struct bios_parser *bp,
+       struct graphics_object_id id)
+{
+       unsigned int i;
+       struct graphics_object_id obj_id = {0};
+
+       switch (id.type) {
+       case OBJECT_TYPE_ENCODER:
+               for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
+                       obj_id = object_id_from_bios_object_id(
+                                       bp->object_info_tbl.v1_5->display_path[i].encoderobjid);
+                       if (id.type == obj_id.type && id.id == obj_id.id
+                                       && id.enum_id == obj_id.enum_id)
+                               return &bp->object_info_tbl.v1_5->display_path[i];
+               }
+        break;
+
+       case OBJECT_TYPE_CONNECTOR:
+       case OBJECT_TYPE_GENERIC:
+               /* Both Generic and Connector Object ID
+                * will be stored on display_objid
+                */
+               for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
+                       obj_id = object_id_from_bios_object_id(
+                                       bp->object_info_tbl.v1_5->display_path[i].display_objid);
+                       if (id.type == obj_id.type && id.id == obj_id.id
+                                       && id.enum_id == obj_id.enum_id)
+                               return &bp->object_info_tbl.v1_5->display_path[i];
+               }
+        break;
+
+       default:
+               return NULL;
+       }
+
+    return NULL;
+}
+
 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
        struct graphics_object_id id,
        struct graphics_object_i2c_info *info)
 {
        uint32_t offset;
        struct atom_display_object_path_v2 *object;
+
+       struct atom_display_object_path_v3 *object_path_v3;
+
        struct atom_common_record_header *header;
        struct atom_i2c_record *record;
        struct atom_i2c_record dummy_record = {0};
@@ -313,12 +433,25 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
                        return BP_RESULT_NORECORD;
        }
 
-       object = get_bios_object(bp, id);
+       switch (bp->object_info_tbl.revision.minor) {
+           case 4:
+           default:
+               object = get_bios_object(bp, id);
 
-       if (!object)
-               return BP_RESULT_BADINPUT;
+               if (!object)
+                               return BP_RESULT_BADINPUT;
 
-       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+               offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+               break;
+           case 5:
+               object_path_v3 = get_bios_object_from_path_v3(bp, id);
+
+               if (!object_path_v3)
+                       return BP_RESULT_BADINPUT;
+
+               offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset;
+               break;
+       }
 
        for (;;) {
                header = GET_IMAGE(struct atom_common_record_header, offset);
@@ -421,6 +554,41 @@ static enum bp_result get_gpio_i2c_info(
        return BP_RESULT_OK;
 }
 
+static struct atom_hpd_int_record *get_hpd_record_for_path_v3(
+       struct bios_parser *bp,
+       struct atom_display_object_path_v3 *object)
+{
+       struct atom_common_record_header *header;
+       uint32_t offset;
+
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+               return NULL;
+       }
+
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+
+       for (;;) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+
+               if (!header)
+                       return NULL;
+
+               if (header->record_type == ATOM_RECORD_END_TYPE ||
+                       !header->record_size)
+                       break;
+
+               if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
+                       && sizeof(struct atom_hpd_int_record) <=
+                                                       header->record_size)
+                       return (struct atom_hpd_int_record *) header;
+
+               offset += header->record_size;
+       }
+
+       return NULL;
+}
+
 static enum bp_result bios_parser_get_hpd_info(
        struct dc_bios *dcb,
        struct graphics_object_id id,
@@ -428,17 +596,32 @@ static enum bp_result bios_parser_get_hpd_info(
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
        struct atom_display_object_path_v2 *object;
+       struct atom_display_object_path_v3 *object_path_v3;
        struct atom_hpd_int_record *record = NULL;
 
        if (!info)
                return BP_RESULT_BADINPUT;
 
-       object = get_bios_object(bp, id);
+       switch (bp->object_info_tbl.revision.minor) {
+           case 4:
+           default:
+               object = get_bios_object(bp, id);
 
-       if (!object)
-               return BP_RESULT_BADINPUT;
+                       if (!object)
+                               return BP_RESULT_BADINPUT;
+
+               record = get_hpd_record(bp, object);
+
+               break;
+           case 5:
+               object_path_v3 = get_bios_object_from_path_v3(bp, id);
 
-       record = get_hpd_record(bp, object);
+               if (!object_path_v3)
+                       return BP_RESULT_BADINPUT;
+
+               record = get_hpd_record_for_path_v3(bp, object_path_v3);
+               break;
+       }
 
        if (record != NULL) {
                info->hpd_int_gpio_uid = record->pin_id;
@@ -526,25 +709,9 @@ static enum bp_result bios_parser_get_gpio_pin_info(
                return BP_RESULT_UNSUPPORTED;
 
        /* Temporary hard code gpio pin info */
-#if defined(FOR_SIMNOW_BOOT)
-       {
-               struct  atom_gpio_pin_assignment  gpio_pin[8] = {
-                               {0x5db5, 0, 0, 1, 0},
-                               {0x5db5, 8, 8, 2, 0},
-                               {0x5db5, 0x10, 0x10, 3, 0},
-                               {0x5db5, 0x18, 0x14, 4, 0},
-                               {0x5db5, 0x1A, 0x18, 5, 0},
-                               {0x5db5, 0x1C, 0x1C, 6, 0},
-               };
-
-               count = 6;
-               memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
-       }
-#else
        count = (le16_to_cpu(header->table_header.structuresize)
                        - sizeof(struct atom_common_table_header))
                                / sizeof(struct atom_gpio_pin_assignment);
-#endif
        for (i = 0; i < count; ++i) {
                if (header->gpio_pin[i].gpio_id != gpio_id)
                        continue;
@@ -633,19 +800,37 @@ static enum bp_result bios_parser_get_device_tag(
        struct bios_parser *bp = BP_FROM_DCB(dcb);
        struct atom_display_object_path_v2 *object;
 
+       struct atom_display_object_path_v3 *object_path_v3;
+
+
        if (!info)
                return BP_RESULT_BADINPUT;
 
-       /* getBiosObject will return MXM object */
-       object = get_bios_object(bp, connector_object_id);
+       switch (bp->object_info_tbl.revision.minor) {
+           case 4:
+           default:
+               /* getBiosObject will return MXM object */
+               object = get_bios_object(bp, connector_object_id);
 
-       if (!object) {
-               BREAK_TO_DEBUGGER(); /* Invalid object id */
-               return BP_RESULT_BADINPUT;
-       }
+                       if (!object) {
+                               BREAK_TO_DEBUGGER(); /* Invalid object id */
+                               return BP_RESULT_BADINPUT;
+                       }
 
-       info->acpi_device = 0; /* BIOS no longer provides this */
-       info->dev_id = device_type_from_device_id(object->device_tag);
+               info->acpi_device = 0; /* BIOS no longer provides this */
+               info->dev_id = device_type_from_device_id(object->device_tag);
+               break;
+           case 5:
+               object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id);
+
+               if (!object_path_v3) {
+                       BREAK_TO_DEBUGGER(); /* Invalid object id */
+                       return BP_RESULT_BADINPUT;
+               }
+               info->acpi_device = 0; /* BIOS no longer provides this */
+               info->dev_id = device_type_from_device_id(object_path_v3->device_tag);
+               break;
+       }
 
        return BP_RESULT_OK;
 }
@@ -803,6 +988,71 @@ static enum bp_result get_ss_info_v4_2(
        return result;
 }
 
+static enum bp_result get_ss_info_v4_5(
+       struct bios_parser *bp,
+       uint32_t id,
+       uint32_t index,
+       struct spread_spectrum_info *ss_info)
+{
+       enum bp_result result = BP_RESULT_OK;
+       struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
+
+       if (!ss_info)
+               return BP_RESULT_BADINPUT;
+
+       if (!DATA_TABLES(dce_info))
+               return BP_RESULT_BADBIOSTABLE;
+
+       disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_5,
+                                                       DATA_TABLES(dce_info));
+       if (!disp_cntl_tbl)
+               return BP_RESULT_BADBIOSTABLE;
+
+       ss_info->type.STEP_AND_DELAY_INFO = false;
+       ss_info->spread_percentage_divider = 1000;
+       /* BIOS no longer uses target clock.  Always enable for now */
+       ss_info->target_clock_range = 0xffffffff;
+
+       switch (id) {
+       case AS_SIGNAL_TYPE_DVI:
+               ss_info->spread_spectrum_percentage =
+                               disp_cntl_tbl->dvi_ss_percentage;
+               ss_info->spread_spectrum_range =
+                               disp_cntl_tbl->dvi_ss_rate_10hz * 10;
+               if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
+                       ss_info->type.CENTER_MODE = true;
+               break;
+       case AS_SIGNAL_TYPE_HDMI:
+               ss_info->spread_spectrum_percentage =
+                               disp_cntl_tbl->hdmi_ss_percentage;
+               ss_info->spread_spectrum_range =
+                               disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
+               if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
+                       ss_info->type.CENTER_MODE = true;
+               break;
+       case AS_SIGNAL_TYPE_DISPLAY_PORT:
+               ss_info->spread_spectrum_percentage =
+                               disp_cntl_tbl->dp_ss_percentage;
+               ss_info->spread_spectrum_range =
+                               disp_cntl_tbl->dp_ss_rate_10hz * 10;
+               if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
+                       ss_info->type.CENTER_MODE = true;
+               break;
+       case AS_SIGNAL_TYPE_GPU_PLL:
+               /* atom_smu_info_v4_0 does not have fields for SS for SMU Display PLL anymore.
+                * SMU Display PLL supposed to be without spread.
+                * Better place for it would be in atom_display_controller_info_v4_5 table.
+                */
+               result = BP_RESULT_UNSUPPORTED;
+               break;
+       default:
+               result = BP_RESULT_UNSUPPORTED;
+               break;
+       }
+
+       return result;
+}
+
 /**
  * bios_parser_get_spread_spectrum_info
  * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
@@ -847,6 +1097,9 @@ static enum bp_result bios_parser_get_spread_spectrum_info(
                case 3:
                case 4:
                        return get_ss_info_v4_2(bp, signal, index, ss_info);
+               case 5:
+                       return get_ss_info_v4_5(bp, signal, index, ss_info);
+
                default:
                        ASSERT(0);
                        break;
@@ -887,6 +1140,31 @@ static enum bp_result get_soc_bb_info_v4_4(
        return result;
 }
 
+static enum bp_result get_soc_bb_info_v4_5(
+       struct bios_parser *bp,
+       struct bp_soc_bb_info *soc_bb_info)
+{
+       enum bp_result result = BP_RESULT_OK;
+       struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
+
+       if (!soc_bb_info)
+               return BP_RESULT_BADINPUT;
+
+       if (!DATA_TABLES(dce_info))
+               return BP_RESULT_BADBIOSTABLE;
+
+       disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_5,
+                                                       DATA_TABLES(dce_info));
+       if (!disp_cntl_tbl)
+               return BP_RESULT_BADBIOSTABLE;
+
+       soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
+       soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
+       soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
+
+       return result;
+}
+
 static enum bp_result bios_parser_get_soc_bb_info(
        struct dc_bios *dcb,
        struct bp_soc_bb_info *soc_bb_info)
@@ -916,6 +1194,9 @@ static enum bp_result bios_parser_get_soc_bb_info(
                case 4:
                        result = get_soc_bb_info_v4_4(bp, soc_bb_info);
                        break;
+               case 5:
+                       result = get_soc_bb_info_v4_5(bp, soc_bb_info);
+                       break;
                default:
                        break;
                }
@@ -1023,6 +1304,30 @@ static enum bp_result get_disp_caps_v4_4(
        return result;
 }
 
+static enum bp_result get_disp_caps_v4_5(
+       struct bios_parser *bp,
+       uint8_t *dce_caps)
+{
+       enum bp_result result = BP_RESULT_OK;
+       struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
+
+       if (!dce_caps)
+               return BP_RESULT_BADINPUT;
+
+       if (!DATA_TABLES(dce_info))
+               return BP_RESULT_BADBIOSTABLE;
+
+       disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
+                                                       DATA_TABLES(dce_info));
+
+       if (!disp_cntl_tbl)
+               return BP_RESULT_BADBIOSTABLE;
+
+       *dce_caps = disp_cntl_tbl->display_caps;
+
+       return result;
+}
+
 static enum bp_result bios_parser_get_lttpr_interop(
        struct dc_bios *dcb,
        uint8_t *dce_caps)
@@ -1057,6 +1362,11 @@ static enum bp_result bios_parser_get_lttpr_interop(
                        result = get_disp_caps_v4_4(bp, dce_caps);
                        *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
                        break;
+               case 5:
+                       result = get_disp_caps_v4_5(bp, dce_caps);
+                       *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
+                       break;
+
                default:
                        break;
                }
@@ -1102,6 +1412,10 @@ static enum bp_result bios_parser_get_lttpr_caps(
                        result = get_disp_caps_v4_4(bp, dce_caps);
                        *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
                        break;
+               case 5:
+                       result = get_disp_caps_v4_5(bp, dce_caps);
+                       *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
+
                default:
                        break;
                }
@@ -1218,7 +1532,6 @@ static enum bp_result bios_parser_get_embedded_panel_info(
                default:
                        break;
                }
-               break;
        default:
                break;
        }
@@ -1274,8 +1587,17 @@ static bool bios_parser_is_device_id_supported(
 
        uint32_t mask = get_support_mask_for_device_id(id);
 
-       return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
-                                                               mask) != 0;
+       switch (bp->object_info_tbl.revision.minor) {
+           case 4:
+           default:
+               return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0;
+                       break;
+           case 5:
+                       return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0;
+                       break;
+       }
+
+    return false;
 }
 
 static uint32_t bios_parser_get_ss_entry_number(
@@ -1408,12 +1730,21 @@ static void bios_parser_set_scratch_critical_state(
        bios_set_scratch_critical_state(dcb, state);
 }
 
+struct atom_dig_transmitter_info_header_v5_3 {
+    struct atom_common_table_header table_header;
+    uint16_t dpphy_hdmi_settings_offset;
+    uint16_t dpphy_dvi_settings_offset;
+    uint16_t dpphy_dp_setting_table_offset;
+    uint16_t uniphy_xbar_settings_v2_table_offset;
+    uint16_t dpphy_internal_reg_overide_offset;
+};
+
 static enum bp_result bios_parser_get_firmware_info(
        struct dc_bios *dcb,
        struct dc_firmware_info *info)
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
-       enum bp_result result = BP_RESULT_BADBIOSTABLE;
+       static enum bp_result result = BP_RESULT_BADBIOSTABLE;
        struct atom_common_table_header *header;
 
        struct atom_data_revision revision;
@@ -1590,6 +1921,11 @@ static enum bp_result get_firmware_info_v3_4(
        struct atom_data_revision revision;
        struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL;
        struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL;
+
+       struct atom_smu_info_v3_5 *smu_info_v3_5 = NULL;
+       struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL;
+       struct atom_smu_info_v4_0 *smu_info_v4_0 = NULL;
+
        if (!info)
                return BP_RESULT_BADINPUT;
 
@@ -1609,6 +1945,22 @@ static enum bp_result get_firmware_info_v3_4(
        switch (revision.major) {
        case 4:
                switch (revision.minor) {
+               case 5:
+                       dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
+                                                       DATA_TABLES(dce_info));
+
+                       if (!dce_info_v4_5)
+                               return BP_RESULT_BADBIOSTABLE;
+
+                        /* 100MHz expected */
+                       info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10;
+                       info->dp_phy_ref_clk             = dce_info_v4_5->dpphy_refclk_10khz * 10;
+                        /* 50MHz expected */
+                       info->i2c_engine_ref_clk         = dce_info_v4_5->i2c_engine_refclk_10khz * 10;
+
+                       /* For DCN32/321 Display PLL VCO Frequency from dce_info_v4_5 may not be reliable */
+                       break;
+
                case 4:
                        dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
                                                        DATA_TABLES(dce_info));
@@ -1650,6 +2002,45 @@ static enum bp_result get_firmware_info_v3_4(
                                        DATA_TABLES(smu_info));
        get_atom_data_table_revision(header, &revision);
 
+       switch (revision.major) {
+       case 3:
+               switch (revision.minor) {
+               case 5:
+                       smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5,
+                                                       DATA_TABLES(smu_info));
+
+                       if (!smu_info_v3_5)
+                               return BP_RESULT_BADBIOSTABLE;
+
+                       info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10;
+                       break;
+
+               default:
+                       break;
+               }
+               break;
+
+       case 4:
+               switch (revision.minor) {
+               case 0:
+                       smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0,
+                                                       DATA_TABLES(smu_info));
+
+                       if (!smu_info_v4_0)
+                               return BP_RESULT_BADBIOSTABLE;
+
+                       /* For DCN32/321 bootup DCFCLK from smu_info_v4_0 may not be reliable */
+                       break;
+
+               default:
+                       break;
+               }
+               break;
+
+       default:
+               break;
+       }
+
         // We need to convert from 10KHz units into KHz units.
        info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
 
@@ -1675,6 +2066,12 @@ static enum bp_result bios_parser_get_encoder_cap_info(
        if (!info)
                return BP_RESULT_BADINPUT;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       /* encoder cap record not available in v1_5 */
+       if (bp->object_info_tbl.revision.minor == 5)
+               return BP_RESULT_NORECORD;
+#endif
+
        object = get_bios_object(bp, object_id);
 
        if (!object)
@@ -1781,6 +2178,42 @@ static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
        return NULL;
 }
 
+static struct atom_connector_caps_record *get_connector_caps_record(
+       struct bios_parser *bp,
+       struct atom_display_object_path_v3 *object)
+{
+       struct atom_common_record_header *header;
+       uint32_t offset;
+
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+               return NULL;
+       }
+
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+
+       for (;;) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+
+               if (!header)
+                       return NULL;
+
+               offset += header->record_size;
+
+               if (header->record_type == ATOM_RECORD_END_TYPE ||
+                               !header->record_size)
+                       break;
+
+               if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE)
+                       continue;
+
+               if (sizeof(struct atom_connector_caps_record) <= header->record_size)
+                       return (struct atom_connector_caps_record *)header;
+       }
+
+       return NULL;
+}
+
 static enum bp_result bios_parser_get_disp_connector_caps_info(
        struct dc_bios *dcb,
        struct graphics_object_id object_id,
@@ -1788,25 +2221,116 @@ static enum bp_result bios_parser_get_disp_connector_caps_info(
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
        struct atom_display_object_path_v2 *object;
+
+       struct atom_display_object_path_v3 *object_path_v3;
+       struct atom_connector_caps_record *record_path_v3;
+
        struct atom_disp_connector_caps_record *record = NULL;
 
        if (!info)
                return BP_RESULT_BADINPUT;
 
-       object = get_bios_object(bp, object_id);
+       switch (bp->object_info_tbl.revision.minor) {
+           case 4:
+           default:
+                   object = get_bios_object(bp, object_id);
 
-       if (!object)
+                   if (!object)
+                           return BP_RESULT_BADINPUT;
+
+                   record = get_disp_connector_caps_record(bp, object);
+                   if (!record)
+                           return BP_RESULT_NORECORD;
+
+                   info->INTERNAL_DISPLAY =
+                           (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) ? 1 : 0;
+                   info->INTERNAL_DISPLAY_BL =
+                           (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) ? 1 : 0;
+                   break;
+           case 5:
+               object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
+
+               if (!object_path_v3)
+                       return BP_RESULT_BADINPUT;
+
+               record_path_v3 = get_connector_caps_record(bp, object_path_v3);
+               if (!record_path_v3)
+                       return BP_RESULT_NORECORD;
+
+               info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
+                                                                       ? 1 : 0;
+               info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
+                                                                               ? 1 : 0;
+               break;
+       }
+
+       return BP_RESULT_OK;
+}
+
+static struct atom_connector_speed_record *get_connector_speed_cap_record(
+       struct bios_parser *bp,
+       struct atom_display_object_path_v3 *object)
+{
+       struct atom_common_record_header *header;
+       uint32_t offset;
+
+       if (!object) {
+               BREAK_TO_DEBUGGER(); /* Invalid object */
+               return NULL;
+       }
+
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;
+
+       for (;;) {
+               header = GET_IMAGE(struct atom_common_record_header, offset);
+
+               if (!header)
+                       return NULL;
+
+               offset += header->record_size;
+
+               if (header->record_type == ATOM_RECORD_END_TYPE ||
+                               !header->record_size)
+                       break;
+
+               if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO)
+                       continue;
+
+               if (sizeof(struct atom_connector_speed_record) <= header->record_size)
+                       return (struct atom_connector_speed_record *)header;
+       }
+
+       return NULL;
+}
+
+static enum bp_result bios_parser_get_connector_speed_cap_info(
+       struct dc_bios *dcb,
+       struct graphics_object_id object_id,
+       struct bp_connector_speed_cap_info *info)
+{
+       struct bios_parser *bp = BP_FROM_DCB(dcb);
+       struct atom_display_object_path_v3 *object_path_v3;
+       //struct atom_connector_speed_record *record = NULL;
+       struct atom_connector_speed_record *record;
+
+       if (!info)
+               return BP_RESULT_BADINPUT;
+
+       object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
+
+       if (!object_path_v3)
                return BP_RESULT_BADINPUT;
 
-       record = get_disp_connector_caps_record(bp, object);
+       record = get_connector_speed_cap_record(bp, object_path_v3);
        if (!record)
                return BP_RESULT_NORECORD;
 
-       info->INTERNAL_DISPLAY = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
-                                                                       ? 1 : 0;
-       info->INTERNAL_DISPLAY_BL = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
-                                                                                       ? 1 : 0;
-
+       info->DP_HBR2_EN = (record->connector_max_speed >= 5400) ? 1 : 0;
+       info->DP_HBR3_EN = (record->connector_max_speed >= 8100) ? 1 : 0;
+       info->HDMI_6GB_EN = (record->connector_max_speed >= 5940) ? 1 : 0;
+       info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0;
+       info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0;
+       info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0;
        return BP_RESULT_OK;
 }
 
@@ -1815,7 +2339,7 @@ static enum bp_result get_vram_info_v23(
        struct dc_vram_info *info)
 {
        struct atom_vram_info_header_v2_3 *info_v23;
-       enum bp_result result = BP_RESULT_OK;
+       static enum bp_result result = BP_RESULT_OK;
 
        info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
                                                DATA_TABLES(vram_info));
@@ -1834,7 +2358,7 @@ static enum bp_result get_vram_info_v24(
        struct dc_vram_info *info)
 {
        struct atom_vram_info_header_v2_4 *info_v24;
-       enum bp_result result = BP_RESULT_OK;
+       static enum bp_result result = BP_RESULT_OK;
 
        info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
                                                DATA_TABLES(vram_info));
@@ -1853,7 +2377,7 @@ static enum bp_result get_vram_info_v25(
        struct dc_vram_info *info)
 {
        struct atom_vram_info_header_v2_5 *info_v25;
-       enum bp_result result = BP_RESULT_OK;
+       static enum bp_result result = BP_RESULT_OK;
 
        info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
                                                DATA_TABLES(vram_info));
@@ -1878,7 +2402,7 @@ static enum bp_result get_vram_info_v25(
  * integrated_info *info - [out] store and output integrated info
  *
  * @return
- * enum bp_result - BP_RESULT_OK if information is available,
+ * static enum bp_result - BP_RESULT_OK if information is available,
  *                  BP_RESULT_BADBIOSTABLE otherwise.
  */
 static enum bp_result get_integrated_info_v11(
@@ -2369,17 +2893,19 @@ static enum bp_result get_integrated_info_v2_2(
  * integrated_info *info - [out] store and output integrated info
  *
  * @return
- * enum bp_result - BP_RESULT_OK if information is available,
+ * static enum bp_result - BP_RESULT_OK if information is available,
  *                  BP_RESULT_BADBIOSTABLE otherwise.
  */
 static enum bp_result construct_integrated_info(
        struct bios_parser *bp,
        struct integrated_info *info)
 {
-       enum bp_result result = BP_RESULT_BADBIOSTABLE;
+       static enum bp_result result = BP_RESULT_BADBIOSTABLE;
 
        struct atom_common_table_header *header;
        struct atom_data_revision revision;
+
+       struct clock_voltage_caps temp = {0, 0};
        uint32_t i;
        uint32_t j;
 
@@ -2427,8 +2953,10 @@ static enum bp_result construct_integrated_info(
                                info->disp_clk_voltage[j-1].max_supported_clk
                                ) {
                                /* swap j and j - 1*/
-                               swap(info->disp_clk_voltage[j - 1],
-                                    info->disp_clk_voltage[j]);
+                               temp = info->disp_clk_voltage[j-1];
+                               info->disp_clk_voltage[j-1] =
+                                       info->disp_clk_voltage[j];
+                               info->disp_clk_voltage[j] = temp;
                        }
                }
        }
@@ -2441,7 +2969,7 @@ static enum bp_result bios_parser_get_vram_info(
                struct dc_vram_info *info)
 {
        struct bios_parser *bp = BP_FROM_DCB(dcb);
-       enum bp_result result = BP_RESULT_BADBIOSTABLE;
+       static enum bp_result result = BP_RESULT_BADBIOSTABLE;
        struct atom_common_table_header *header;
        struct atom_data_revision revision;
 
@@ -2507,7 +3035,7 @@ static enum bp_result update_slot_layout_info(
        struct atom_display_object_path_v2 *object;
        struct atom_bracket_layout_record *record;
        struct atom_common_record_header *record_header;
-       enum bp_result result;
+       static enum bp_result result;
        struct bios_parser *bp;
        struct object_info_table *tbl;
        struct display_object_info_table_v1_4 *v1_4;
@@ -2613,6 +3141,104 @@ static enum bp_result update_slot_layout_info(
        return result;
 }
 
+static enum bp_result update_slot_layout_info_v2(
+       struct dc_bios *dcb,
+       unsigned int i,
+       struct slot_layout_info *slot_layout_info)
+{
+       unsigned int record_offset;
+       struct atom_display_object_path_v3 *object;
+       struct atom_bracket_layout_record_v2 *record;
+       struct atom_common_record_header *record_header;
+       static enum bp_result result;
+       struct bios_parser *bp;
+       struct object_info_table *tbl;
+       struct display_object_info_table_v1_5 *v1_5;
+       struct graphics_object_id connector_id;
+
+       record = NULL;
+       record_header = NULL;
+       result = BP_RESULT_NORECORD;
+
+       bp = BP_FROM_DCB(dcb);
+       tbl = &bp->object_info_tbl;
+       v1_5 = tbl->v1_5;
+
+       object = &v1_5->display_path[i];
+       record_offset = (unsigned int)
+               (object->disp_recordoffset) +
+               (unsigned int)(bp->object_info_tbl_offset);
+
+       for (;;) {
+
+               record_header = (struct atom_common_record_header *)
+                       GET_IMAGE(struct atom_common_record_header,
+                       record_offset);
+               if (record_header == NULL) {
+                       result = BP_RESULT_BADBIOSTABLE;
+                       break;
+               }
+
+               /* the end of the list */
+               if (record_header->record_type == ATOM_RECORD_END_TYPE ||
+                       record_header->record_size == 0)        {
+                       break;
+               }
+
+               if (record_header->record_type ==
+                       ATOM_BRACKET_LAYOUT_V2_RECORD_TYPE &&
+                       sizeof(struct atom_bracket_layout_record_v2)
+                       <= record_header->record_size) {
+                       record = (struct atom_bracket_layout_record_v2 *)
+                               (record_header);
+                       result = BP_RESULT_OK;
+                       break;
+               }
+
+               record_offset += record_header->record_size;
+       }
+
+       /* return if the record not found */
+       if (result != BP_RESULT_OK)
+               return result;
+
+       /* get slot sizes */
+       connector_id = object_id_from_bios_object_id(object->display_objid);
+
+       slot_layout_info->length = record->bracketlen;
+       slot_layout_info->width = record->bracketwidth;
+       slot_layout_info->num_of_connectors = v1_5->number_of_path;
+       slot_layout_info->connectors[i].position = record->conn_num;
+       slot_layout_info->connectors[i].connector_id = connector_id;
+
+       switch (connector_id.id) {
+       case CONNECTOR_ID_SINGLE_LINK_DVID:
+       case CONNECTOR_ID_DUAL_LINK_DVID:
+               slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DVI_D;
+               slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DVI;
+               break;
+
+       case CONNECTOR_ID_HDMI_TYPE_A:
+               slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_HDMI;
+               slot_layout_info->connectors[i].length = CONNECTOR_SIZE_HDMI;
+               break;
+
+       case CONNECTOR_ID_DISPLAY_PORT:
+               if (record->mini_type == MINI_TYPE_NORMAL) {
+                       slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DP;
+                       slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DP;
+               } else {
+                       slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP;
+                       slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP;
+               }
+               break;
+
+       default:
+               slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN;
+               slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN;
+       }
+       return result;
+}
 
 static enum bp_result get_bracket_layout_record(
        struct dc_bios *dcb,
@@ -2621,9 +3247,10 @@ static enum bp_result get_bracket_layout_record(
 {
        unsigned int i;
        struct bios_parser *bp = BP_FROM_DCB(dcb);
-       enum bp_result result;
+       static enum bp_result result;
        struct object_info_table *tbl;
        struct display_object_info_table_v1_4 *v1_4;
+    struct display_object_info_table_v1_5 *v1_5;
 
        if (slot_layout_info == NULL) {
                DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
@@ -2633,14 +3260,21 @@ static enum bp_result get_bracket_layout_record(
        v1_4 = tbl->v1_4;
 
        result = BP_RESULT_NORECORD;
-       for (i = 0; i < v1_4->number_of_path; ++i)      {
-
-               if (bracket_layout_id ==
-                       v1_4->display_path[i].display_objid) {
-                       result = update_slot_layout_info(dcb, i,
-                               slot_layout_info);
+       switch (bp->object_info_tbl.revision.minor) {
+               case 4:
+               default:
+                       for (i = 0; i < v1_4->number_of_path; ++i)      {
+                               if (bracket_layout_id ==
+                                       v1_4->display_path[i].display_objid) {
+                                       result = update_slot_layout_info(dcb, i, slot_layout_info);
+                                       break;
+                               }
+                       }
+                   break;
+               case 5:
+                       for (i = 0; i < v1_5->number_of_path; ++i)
+                               result = update_slot_layout_info_v2(dcb, i, slot_layout_info);
                        break;
-               }
        }
        return result;
 }
@@ -2650,7 +3284,10 @@ static enum bp_result bios_get_board_layout_info(
        struct board_layout_info *board_layout_info)
 {
        unsigned int i;
-       enum bp_result record_result;
+
+       struct bios_parser *bp;
+
+       static enum bp_result record_result;
 
        const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
                GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
@@ -2658,6 +3295,9 @@ static enum bp_result bios_get_board_layout_info(
                0, 0
        };
 
+
+       bp = BP_FROM_DCB(dcb);
+
        if (board_layout_info == NULL) {
                DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
                return BP_RESULT_BADINPUT;
@@ -2692,99 +3332,6 @@ static uint16_t bios_parser_pack_data_tables(
        struct dc_bios *dcb,
        void *dst)
 {
-#ifdef PACK_BIOS_DATA
-       struct bios_parser *bp = BP_FROM_DCB(dcb);
-       struct atom_rom_header_v2_2 *rom_header = NULL;
-       struct atom_rom_header_v2_2 *packed_rom_header = NULL;
-       struct atom_common_table_header *data_tbl_header = NULL;
-       struct atom_master_list_of_data_tables_v2_1 *data_tbl_list = NULL;
-       struct atom_master_data_table_v2_1 *packed_master_data_tbl = NULL;
-       struct atom_data_revision tbl_rev = {0};
-       uint16_t *rom_header_offset = NULL;
-       const uint8_t *bios = bp->base.bios;
-       uint8_t *bios_dst = (uint8_t *)dst;
-       uint16_t packed_rom_header_offset;
-       uint16_t packed_masterdatatable_offset;
-       uint16_t packed_data_tbl_offset;
-       uint16_t data_tbl_offset;
-       unsigned int i;
-
-       rom_header_offset =
-               GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
-
-       if (!rom_header_offset)
-               return 0;
-
-       rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
-
-       if (!rom_header)
-               return 0;
-
-       get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
-       if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
-               return 0;
-
-       get_atom_data_table_revision(&bp->master_data_tbl->table_header, &tbl_rev);
-       if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 1))
-               return 0;
-
-       packed_rom_header_offset =
-               OFFSET_TO_ATOM_ROM_HEADER_POINTER + sizeof(*rom_header_offset);
-
-       packed_masterdatatable_offset =
-               packed_rom_header_offset + rom_header->table_header.structuresize;
-
-       packed_data_tbl_offset =
-               packed_masterdatatable_offset +
-               bp->master_data_tbl->table_header.structuresize;
-
-       packed_rom_header =
-               (struct atom_rom_header_v2_2 *)(bios_dst + packed_rom_header_offset);
-
-       packed_master_data_tbl =
-               (struct atom_master_data_table_v2_1 *)(bios_dst +
-               packed_masterdatatable_offset);
-
-       memcpy(bios_dst, bios, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
-
-       *((uint16_t *)(bios_dst + OFFSET_TO_ATOM_ROM_HEADER_POINTER)) =
-               packed_rom_header_offset;
-
-       memcpy(bios_dst + packed_rom_header_offset, rom_header,
-               rom_header->table_header.structuresize);
-
-       packed_rom_header->masterdatatable_offset = packed_masterdatatable_offset;
-
-       memcpy(&packed_master_data_tbl->table_header,
-               &bp->master_data_tbl->table_header,
-               sizeof(bp->master_data_tbl->table_header));
-
-       data_tbl_list = &bp->master_data_tbl->listOfdatatables;
-
-       /* Each data table offset in data table list is 2 bytes,
-        * we can use that to iterate through listOfdatatables
-        * without knowing the name of each member.
-        */
-       for (i = 0; i < sizeof(*data_tbl_list)/sizeof(uint16_t); i++) {
-               data_tbl_offset = *((uint16_t *)data_tbl_list + i);
-
-               if (data_tbl_offset) {
-                       data_tbl_header =
-                               (struct atom_common_table_header *)(bios + data_tbl_offset);
-
-                       memcpy(bios_dst + packed_data_tbl_offset, data_tbl_header,
-                               data_tbl_header->structuresize);
-
-                       *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) =
-                               packed_data_tbl_offset;
-
-                       packed_data_tbl_offset += data_tbl_header->structuresize;
-               } else {
-                       *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) = 0;
-               }
-       }
-       return packed_data_tbl_offset;
-#endif
        // TODO: There is data bytes alignment issue, disable it for now.
        return 0;
 }
@@ -2814,6 +3361,13 @@ static struct atom_dc_golden_table_v1 *bios_get_golden_table(
                        dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset;
                        *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
                        break;
+               case 5:
+               default:
+                       /* For atom_display_controller_info_v4_5 there is no need to get golden table from
+                        * dc_golden_table_offset as all these fields previously in golden table used for AUX
+                        * pre-charge settings are now available directly in atom_display_controller_info_v4_5.
+                        */
+                       break;
                }
                break;
        }
@@ -2916,6 +3470,7 @@ static const struct dc_vbios_funcs vbios_funcs = {
        .bios_parser_destroy = firmware_parser_destroy,
 
        .get_board_layout_info = bios_get_board_layout_info,
+       /* TODO: use this fn in hw init?*/
        .pack_data_tables = bios_parser_pack_data_tables,
 
        .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
@@ -2929,6 +3484,8 @@ static const struct dc_vbios_funcs vbios_funcs = {
        .get_lttpr_caps = bios_parser_get_lttpr_caps,
 
        .get_lttpr_interop = bios_parser_get_lttpr_interop,
+
+       .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info,
 };
 
 static bool bios_parser2_construct(
@@ -3002,6 +3559,16 @@ static bool bios_parser2_construct(
                        return false;
 
                bp->object_info_tbl.v1_4 = tbl_v1_4;
+       } else if (bp->object_info_tbl.revision.major == 1
+               && bp->object_info_tbl.revision.minor == 5) {
+               struct display_object_info_table_v1_5 *tbl_v1_5;
+
+               tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5,
+                       bp->object_info_tbl_offset);
+               if (!tbl_v1_5)
+                       return false;
+
+               bp->object_info_tbl.v1_5 = tbl_v1_5;
        } else {
                ASSERT(0);
                return false;
index bf1f5c8..41d02d4 100644 (file)
@@ -40,6 +40,7 @@ struct object_info_table {
        struct atom_data_revision revision;
        union {
                struct display_object_info_table_v1_4 *v1_4;
+               struct display_object_info_table_v1_5 *v1_5;
        };
 };
 
index f379228..f22593b 100644 (file)
@@ -77,6 +77,8 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
        case DCN_VERSION_3_1:
        case DCN_VERSION_3_15:
        case DCN_VERSION_3_16:
+       case DCN_VERSION_3_2:
+       case DCN_VERSION_3_21:
                *h = dal_cmd_tbl_helper_dce112_get_table2();
                return true;
 
index e803e59..d145dcb 100644 (file)
@@ -328,8 +328,8 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
            dcn32_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg);
            return &clk_mgr->base;
            break;
-#endif
        }
+#endif
        default:
                ASSERT(0); /* Unknown Asic */
                break;
index f144494..e3e3b27 100644 (file)
@@ -3054,11 +3054,15 @@ static void commit_planes_for_stream(struct dc *dc,
 
        }
 
-       if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) {
-               dc->hwss.interdependent_update_lock(dc, context, false);
-       } else {
-               dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
-       }
+#ifdef CONFIG_DRM_AMD_DC_DCN
+               if (update_type != UPDATE_TYPE_FAST)
+                       if (dc->hwss.commit_subvp_config)
+                               dc->hwss.commit_subvp_config(dc, context);
+#endif
+               if (should_lock_all_pipes && dc->hwss.interdependent_update_lock)
+                       dc->hwss.interdependent_update_lock(dc, context, false);
+               else
+                       dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false);
 
        if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
                if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
index 6774dd8..b087452 100644 (file)
@@ -67,6 +67,8 @@
 #include "dcn31/dcn31_resource.h"
 #include "dcn315/dcn315_resource.h"
 #include "dcn316/dcn316_resource.h"
+#include "../dcn32/dcn32_resource.h"
+#include "../dcn321/dcn321_resource.h"
 
 #define DC_LOGGER_INIT(logger)
 
@@ -162,7 +164,11 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
                if (ASICREV_IS_GC_10_3_7(asic_id.hw_internal_rev))
                        dc_version = DCN_VERSION_3_16;
                break;
-
+       case AMDGPU_FAMILY_GC_11_0_0:
+               dc_version = DCN_VERSION_3_2;
+               if (ASICREV_IS_GC_11_0_2(asic_id.hw_internal_rev))
+                       dc_version = DCN_VERSION_3_21;
+               break;
        default:
                dc_version = DCE_VERSION_UNKNOWN;
                break;
@@ -258,6 +264,12 @@ struct resource_pool *dc_create_resource_pool(struct dc  *dc,
        case DCN_VERSION_3_16:
                res_pool = dcn316_create_resource_pool(init_data, dc);
                break;
+       case DCN_VERSION_3_2:
+               res_pool = dcn32_create_resource_pool(init_data, dc);
+               break;
+       case DCN_VERSION_3_21:
+               res_pool = dcn321_create_resource_pool(init_data, dc);
+               break;
 #endif
        default:
                break;
@@ -1982,6 +1994,11 @@ enum dc_status dc_remove_stream_from_ctx(
                                dc->res_pool,
                        del_pipe->stream_res.stream_enc,
                        false);
+       /* Release link encoder from stream in new dc_state. */
+       if (dc->res_pool->funcs->link_enc_unassign)
+               dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream);
+
+#if defined(CONFIG_DRM_AMD_DC_DCN)
        if (is_dp_128b_132b_signal(del_pipe)) {
                update_hpo_dp_stream_engine_usage(
                        &new_ctx->res_ctx, dc->res_pool,
@@ -1989,6 +2006,7 @@ enum dc_status dc_remove_stream_from_ctx(
                        false);
                remove_hpo_dp_link_enc_from_ctx(&new_ctx->res_ctx, del_pipe, del_pipe->stream);
        }
+#endif
 
        if (del_pipe->stream_res.audio)
                update_audio_usage(
index 52d6da5..6916546 100644 (file)
@@ -162,6 +162,10 @@ struct dc_color_caps {
        struct mpc_color_caps mpc;
 };
 
+struct dc_dmub_caps {
+    bool psr;
+};
+
 struct dc_caps {
        uint32_t max_streams;
        uint32_t max_links;
@@ -196,12 +200,22 @@ struct dc_caps {
        unsigned int cursor_cache_size;
        struct dc_plane_cap planes[MAX_PLANES];
        struct dc_color_caps color;
+       struct dc_dmub_caps dmub_caps;
        bool dp_hpo;
        bool hdmi_frl_pcon_support;
        bool edp_dsc_support;
        bool vbios_lttpr_aware;
        bool vbios_lttpr_enable;
        uint32_t max_otg_num;
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       uint32_t max_cab_allocation_bytes;
+       uint32_t cache_line_size;
+       uint32_t cache_num_ways;
+       uint16_t subvp_fw_processing_delay_us;
+       uint16_t subvp_prefetch_end_to_mall_start_us;
+       uint16_t subvp_pstate_allow_width_us;
+       uint16_t subvp_vertical_int_margin_us;
+#endif
 };
 
 struct dc_bug_wa {
@@ -427,6 +441,8 @@ struct dc_clocks {
         */
        bool prev_p_state_change_support;
        bool fclk_prev_p_state_change_support;
+       int num_ways;
+       int prev_num_ways;
        enum dtm_pstate dtm_level;
        int max_supported_dppclk_khz;
        int max_supported_dispclk_khz;
@@ -721,6 +737,9 @@ struct dc_debug_options {
        bool enable_z9_disable_interface;
        bool enable_sw_cntl_psr;
        union dpia_debug_options dpia_debug;
+       bool force_disable_subvp;
+       bool force_subvp_mclk_switch;
+       bool force_usr_allow;
        bool apply_vendor_specific_lttpr_wa;
        bool extended_blank_optimization;
        union aux_wake_wa_options aux_wake_wa;
index 67abda4..260ac44 100644 (file)
@@ -156,6 +156,11 @@ struct dc_vbios_funcs {
        enum bp_result (*get_lttpr_interop)(
                        struct dc_bios *dcb,
                        uint8_t *dce_caps);
+
+       enum bp_result (*get_connector_speed_cap_info)(
+               struct dc_bios *bios,
+               struct graphics_object_id object_id,
+               struct bp_connector_speed_cap_info *info);
 };
 
 struct bios_registers {
index aa7e3a0..d75416d 100644 (file)
@@ -780,6 +780,7 @@ struct dc_crtc_timing {
        uint32_t v_sync_width;
 
        uint32_t pix_clk_100hz;
+       uint32_t min_refresh_in_uhz;
 
        uint32_t vic;
        uint32_t hdmi_vic;
index 58941f4..772b4a6 100644 (file)
@@ -145,6 +145,24 @@ struct test_pattern {
        unsigned int cust_pattern_size;
 };
 
+#ifdef CONFIG_DRM_AMD_DC_DCN
+#define SUBVP_DRR_MARGIN_US 500 // 500us for DRR margin (SubVP + DRR)
+
+enum mall_stream_type {
+       SUBVP_NONE, // subvp not in use
+       SUBVP_MAIN, // subvp in use, this stream is main stream
+       SUBVP_PHANTOM, // subvp in use, this stream is a phantom stream
+};
+
+struct mall_stream_config {
+       /* MALL stream config to indicate if the stream is phantom or not.
+        * We will use a phantom stream to indicate that the pipe is phantom.
+        */
+       enum mall_stream_type type;
+       struct dc_stream_state *paired_stream;  // master / slave stream
+};
+#endif
+
 struct dc_stream_state {
        // sink is deprecated, new code should not reference
        // this pointer
@@ -255,6 +273,9 @@ struct dc_stream_state {
 
        bool has_non_synchronizable_pclk;
        bool vblank_synchronized;
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       struct mall_stream_config mall_stream_config;
+#endif
 };
 
 #define ABM_LEVEL_IMMEDIATE_DISABLE 255
index b699d1b..e6c0632 100644 (file)
        SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
        NBIO_SR(BIOS_SCRATCH_2)
 
+#define ABM_DCN32_REG_LIST(id)\
+       SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \
+       SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \
+       SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \
+       SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \
+       SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \
+       SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \
+       SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \
+       SRI(BL1_PWM_USER_LEVEL, ABM, id), \
+       SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \
+       SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \
+       SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \
+       SRI(DC_ABM1_ACE_THRES_12, ABM, id), \
+       NBIO_SR(BIOS_SCRATCH_2)
+
 #define ABM_SF(reg_name, field_name, post_fix)\
        .field_name = reg_name ## __ ## field_name ## post_fix
 
 
 #define ABM_MASK_SH_LIST_DCN30(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh)
 
+#define ABM_MASK_SH_LIST_DCN32(mask_sh) \
+       ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
+                       ABM1_HG_NUM_OF_BINS_SEL, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
+                       ABM1_HG_VMAX_SEL, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_HG_MISC_CTRL, \
+                       ABM1_HG_BIN_BITWIDTH_SIZE_SEL, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
+                       ABM1_IPCSC_COEFF_SEL_R, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
+                       ABM1_IPCSC_COEFF_SEL_G, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_IPCSC_COEFF_SEL, \
+                       ABM1_IPCSC_COEFF_SEL_B, mask_sh), \
+       ABM_SF(ABM0_BL1_PWM_CURRENT_ABM_LEVEL, \
+                       BL1_PWM_CURRENT_ABM_LEVEL, mask_sh), \
+       ABM_SF(ABM0_BL1_PWM_TARGET_ABM_LEVEL, \
+                       BL1_PWM_TARGET_ABM_LEVEL, mask_sh), \
+       ABM_SF(ABM0_BL1_PWM_USER_LEVEL, \
+                       BL1_PWM_USER_LEVEL, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
+                       ABM1_LS_MIN_PIXEL_VALUE_THRES, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, \
+                       ABM1_LS_MAX_PIXEL_VALUE_THRES, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
+                       ABM1_HG_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
+                       ABM1_LS_REG_READ_MISSED_FRAME_CLEAR, mask_sh), \
+       ABM_SF(ABM0_DC_ABM1_HGLS_REG_READ_PROGRESS, \
+                       ABM1_BL_REG_READ_MISSED_FRAME_CLEAR, mask_sh)
+
 #define ABM_REG_FIELD_LIST(type) \
        type ABM1_HG_NUM_OF_BINS_SEL; \
        type ABM1_HG_VMAX_SEL; \
index 9eec352..e0c390f 100644 (file)
        CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\
        CS_SF(OTG0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE, mask_sh)
 
+#define CS_COMMON_MASK_SH_LIST_DCN3_2(mask_sh)\
+       CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh),\
+       CS_SF(OTG0_PIXEL_RATE_CNTL, PIPE0_DTO_SRC_SEL, mask_sh)
+
 #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \
                SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\
                SRII(PHASE, DP_DTO, 0),\
        type DP_DTO0_MODULO; \
        type DP_DTO0_ENABLE;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+#define CS_REG_FIELD_LIST_DCN32(type) \
+       type PIPE0_DTO_SRC_SEL;
+#endif
+
 struct dce110_clk_src_shift {
        CS_REG_FIELD_LIST(uint8_t)
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       CS_REG_FIELD_LIST_DCN32(uint8_t)
+#endif
 };
 
 struct dce110_clk_src_mask{
        CS_REG_FIELD_LIST(uint32_t)
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+       CS_REG_FIELD_LIST_DCN32(uint32_t)
+#endif
 };
 
 struct dce110_clk_src_regs {
index 39485bd..e48fd04 100644 (file)
@@ -158,8 +158,39 @@ struct dcn_hubbub_registers {
        uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C;
        uint32_t DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D;
        uint32_t DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D;
+       uint32_t DCHUBBUB_ARB_USR_RETRAINING_CNTL;
+       uint32_t DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A;
+       uint32_t DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B;
+       uint32_t DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C;
+       uint32_t DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D;
+       uint32_t DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A;
+       uint32_t DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B;
+       uint32_t DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C;
+       uint32_t DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D;
+       uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A;
+       uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B;
+       uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C;
+       uint32_t DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D;
 };
 
+#define HUBBUB_REG_FIELD_LIST_DCN32(type) \
+               type DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_VALUE;\
+               type DCHUBBUB_ARB_ALLOW_USR_RETRAINING_FORCE_ENABLE;\
+               type DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PSTATE_CHANGE_REQUEST;\
+               type DCHUBBUB_ARB_DO_NOT_FORCE_ALLOW_USR_RETRAINING_DURING_PRE_CSTATE;\
+               type DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_A;\
+               type DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_B;\
+               type DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_C;\
+               type DCHUBBUB_ARB_USR_RETRAINING_WATERMARK_D;\
+               type DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_A;\
+               type DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_B;\
+               type DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_C;\
+               type DCHUBBUB_ARB_UCLK_PSTATE_CHANGE_WATERMARK_D;\
+               type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_A;\
+               type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_B;\
+               type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_C;\
+               type DCHUBBUB_ARB_FCLK_PSTATE_CHANGE_WATERMARK_D
+
 /* set field name */
 #define HUBBUB_SF(reg_name, field_name, post_fix)\
        .field_name = reg_name ## __ ## field_name ## post_fix
@@ -337,6 +368,7 @@ struct dcn_hubbub_shift {
        HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t);
        HUBBUB_HVM_REG_FIELD_LIST(uint8_t);
        HUBBUB_RET_REG_FIELD_LIST(uint8_t);
+       HUBBUB_REG_FIELD_LIST_DCN32(uint8_t);
 };
 
 struct dcn_hubbub_mask {
@@ -344,6 +376,7 @@ struct dcn_hubbub_mask {
        HUBBUB_STUTTER_REG_FIELD_LIST(uint32_t);
        HUBBUB_HVM_REG_FIELD_LIST(uint32_t);
        HUBBUB_RET_REG_FIELD_LIST(uint32_t);
+       HUBBUB_REG_FIELD_LIST_DCN32(uint32_t);
 };
 
 struct dc;
index e3a6287..1cb206d 100644 (file)
@@ -1375,11 +1375,6 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
                pipe_ctx->stream_res.tg = NULL;
                pipe_ctx->plane_res.hubp = NULL;
 
-               if (tg->funcs->is_tg_enabled(tg)) {
-                       if (tg->funcs->init_odm)
-                               tg->funcs->init_odm(tg);
-               }
-
                tg->funcs->tg_init(tg);
        }
 
index c50c299..df155cc 100644 (file)
@@ -514,6 +514,7 @@ struct dcn_optc_registers {
        type DIG_UPDATE_POSITION_X;\
        type DIG_UPDATE_POSITION_Y;\
        type OTG_H_TIMING_DIV_MODE;\
+       type OTG_H_TIMING_DIV_MODE_MANUAL;\
        type OTG_DRR_TIMING_DBUF_UPDATE_MODE;\
        type OTG_CRC_DSC_MODE;\
        type OTG_CRC_DATA_STREAM_COMBINE_MODE;\
@@ -553,6 +554,7 @@ struct optc {
        int vupdate_offset;
        int vupdate_width;
        int vready_offset;
+       struct dc_crtc_timing orginal_patched_timing;
        enum signal_type signal;
 };
 
index 293595a..02c7707 100644 (file)
@@ -73,6 +73,7 @@
        SRI(HDMI_ACR_48_1, DIG, id),\
        SRI(DP_DB_CNTL, DP, id), \
        SRI(DP_MSA_MISC, DP, id), \
+       SRI(DP_MSA_VBID_MISC, DP, id), \
        SRI(DP_MSA_COLORIMETRY, DP, id), \
        SRI(DP_MSA_TIMING_PARAM1, DP, id), \
        SRI(DP_MSA_TIMING_PARAM2, DP, id), \
@@ -186,6 +187,7 @@ struct dcn10_stream_enc_registers {
        uint32_t HDMI_GENERIC_PACKET_CONTROL9;
        uint32_t HDMI_GENERIC_PACKET_CONTROL10;
        uint32_t DIG_CLOCK_PATTERN;
+       uint32_t DIG_FIFO_CTRL0;
 };
 
 
@@ -337,8 +339,14 @@ struct dcn10_stream_enc_registers {
        SE_SF(DIG0_DIG_FE_CNTL, DIG_SOURCE_SELECT, mask_sh),\
        SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+#define SE_COMMON_MASK_SH_LIST_SOC(mask_sh)\
+       SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh),\
+       SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh)
+#else
 #define SE_COMMON_MASK_SH_LIST_SOC(mask_sh)\
        SE_COMMON_MASK_SH_LIST_SOC_BASE(mask_sh)
+#endif
 
 #define SE_COMMON_MASK_SH_LIST_DCN10(mask_sh)\
        SE_COMMON_MASK_SH_LIST_SOC(mask_sh),\
@@ -567,16 +575,33 @@ struct dcn10_stream_enc_registers {
        type DP_SEC_GSP11_ENABLE;\
        type DP_SEC_GSP11_LINE_NUM
 
+#define SE_REG_FIELD_LIST_DCN3_2(type) \
+       type DIG_SYMCLK_FE_ON;\
+       type DIG_FIFO_READ_START_LEVEL;\
+       type DIG_FIFO_ENABLE;\
+       type DIG_FIFO_RESET;\
+       type DIG_FIFO_RESET_DONE
+
 struct dcn10_stream_encoder_shift {
        SE_REG_FIELD_LIST_DCN1_0(uint8_t);
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+       uint8_t HDMI_ACP_SEND;
+#endif
        SE_REG_FIELD_LIST_DCN2_0(uint8_t);
        SE_REG_FIELD_LIST_DCN3_0(uint8_t);
+       SE_REG_FIELD_LIST_DCN3_2(uint8_t);
+
 };
 
 struct dcn10_stream_encoder_mask {
        SE_REG_FIELD_LIST_DCN1_0(uint32_t);
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
+       uint32_t HDMI_ACP_SEND;
+#endif
        SE_REG_FIELD_LIST_DCN2_0(uint32_t);
        SE_REG_FIELD_LIST_DCN3_0(uint32_t);
+       SE_REG_FIELD_LIST_DCN3_2(uint32_t);
+
 };
 
 struct dcn10_stream_encoder {
index b3c9a97..2b9d3e6 100644 (file)
        type OTG_DROP_PIXEL[MAX_PIPES];
 
 #define DCCG3_REG_FIELD_LIST(type) \
+       type HDMICHARCLK0_EN;\
+       type HDMICHARCLK0_SRC_SEL;\
        type PHYASYMCLK_FORCE_EN;\
        type PHYASYMCLK_FORCE_SRC_SEL;\
        type PHYBSYMCLK_FORCE_EN;\
        type PHYDSYMCLK_GATE_DISABLE; \
        type PHYESYMCLK_GATE_DISABLE;
 
+#define DCCG32_REG_FIELD_LIST(type) \
+       type DPSTREAMCLK0_EN;\
+       type DPSTREAMCLK1_EN;\
+       type DPSTREAMCLK2_EN;\
+       type DPSTREAMCLK3_EN;\
+       type DPSTREAMCLK0_SRC_SEL;\
+       type DPSTREAMCLK1_SRC_SEL;\
+       type DPSTREAMCLK2_SRC_SEL;\
+       type DPSTREAMCLK3_SRC_SEL;\
+       type HDMISTREAMCLK0_EN;\
+       type OTG0_PIXEL_RATE_DIVK1;\
+       type OTG0_PIXEL_RATE_DIVK2;\
+       type OTG1_PIXEL_RATE_DIVK1;\
+       type OTG1_PIXEL_RATE_DIVK2;\
+       type OTG2_PIXEL_RATE_DIVK1;\
+       type OTG2_PIXEL_RATE_DIVK2;\
+       type OTG3_PIXEL_RATE_DIVK1;\
+       type OTG3_PIXEL_RATE_DIVK2;\
+       type DTBCLK_P0_SRC_SEL;\
+       type DTBCLK_P0_EN;\
+       type DTBCLK_P1_SRC_SEL;\
+       type DTBCLK_P1_EN;\
+       type DTBCLK_P2_SRC_SEL;\
+       type DTBCLK_P2_EN;\
+       type DTBCLK_P3_SRC_SEL;\
+       type DTBCLK_P3_EN;
+
 struct dccg_shift {
        DCCG_REG_FIELD_LIST(uint8_t)
        DCCG3_REG_FIELD_LIST(uint8_t)
        DCCG31_REG_FIELD_LIST(uint8_t)
+       DCCG32_REG_FIELD_LIST(uint8_t)
 };
 
 struct dccg_mask {
        DCCG_REG_FIELD_LIST(uint32_t)
        DCCG3_REG_FIELD_LIST(uint32_t)
        DCCG31_REG_FIELD_LIST(uint32_t)
+       DCCG32_REG_FIELD_LIST(uint32_t)
 };
 
 struct dccg_registers {
@@ -247,7 +278,8 @@ struct dccg_registers {
        uint32_t DCCG_GATE_DISABLE_CNTL3;
        uint32_t HDMISTREAMCLK0_DTO_PARAM;
        uint32_t DCCG_GATE_DISABLE_CNTL4;
-
+       uint32_t OTG_PIXEL_RATE_DIV;
+       uint32_t DTBCLK_P_CNTL;
 };
 
 struct dcn_dccg {
index 9204c3e..efa2adf 100644 (file)
        DCN21_HUBP_REG_COMMON_VARIABLE_LIST;\
        uint32_t DCN_DMDATA_VM_CNTL
 
+#define DCN32_HUBP_REG_COMMON_VARIABLE_LIST \
+       DCN30_HUBP_REG_COMMON_VARIABLE_LIST;\
+       uint32_t DCHUBP_MALL_CONFIG;\
+       uint32_t DCHUBP_VMPG_CONFIG;\
+       uint32_t UCLK_PSTATE_FORCE
+
 #define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \
        DCN_HUBP_REG_FIELD_BASE_LIST(type); \
        type DMDATA_ADDRESS_HIGH;\
        type CURSOR_REQ_MODE;\
        type HUBP_SOFT_RESET
 
+#define DCN32_HUBP_REG_FIELD_VARIABLE_LIST(type) \
+       DCN31_HUBP_REG_FIELD_VARIABLE_LIST(type);\
+       type USE_MALL_SEL; \
+       type USE_MALL_FOR_CURSOR;\
+       type VMPG_SIZE; \
+       type PTE_BUFFER_MODE; \
+       type BIGK_FRAGMENT_SIZE; \
+       type FORCE_ONE_ROW_FOR_FRAME; \
+       type DATA_UCLK_PSTATE_FORCE_EN; \
+       type DATA_UCLK_PSTATE_FORCE_VALUE; \
+       type CURSOR_UCLK_PSTATE_FORCE_EN; \
+       type CURSOR_UCLK_PSTATE_FORCE_VALUE
+
 struct dcn_hubp2_registers {
-       DCN30_HUBP_REG_COMMON_VARIABLE_LIST;
+       DCN32_HUBP_REG_COMMON_VARIABLE_LIST;
 };
 
 struct dcn_hubp2_shift {
-       DCN31_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
+       DCN32_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t);
 };
 
 struct dcn_hubp2_mask {
-       DCN31_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
+       DCN32_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t);
 };
 
 struct dcn20_hubp {
index ec6aa8d..d00a278 100644 (file)
@@ -768,6 +768,10 @@ enum dc_status dcn20_enable_stream_timing(
        /* TODO enable stream if timing changed */
        /* TODO unblank stream if DP */
 
+       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+               if (pipe_ctx->stream_res.tg && pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable)
+                       pipe_ctx->stream_res.tg->funcs->phantom_crtc_post_enable(pipe_ctx->stream_res.tg);
+       }
        return DC_OK;
 }
 
@@ -1247,6 +1251,16 @@ void dcn20_pipe_control_lock(
                                        lock,
                                        &hw_locks,
                                        &inst_flags);
+       } else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+               hw_lock_cmd.bits.lock_pipe = 1;
+               hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
+               hw_lock_cmd.bits.lock = lock;
+               if (!lock)
+                       hw_lock_cmd.bits.should_release = 1;
+               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
        } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
                if (lock)
                        pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
@@ -1564,10 +1578,12 @@ static void dcn20_update_dchubp_dpp(
                plane_state->update_flags.bits.addr_update)
                hws->funcs.update_plane_addr(dc, pipe_ctx);
 
-
-
        if (pipe_ctx->update_flags.bits.enable)
                hubp->funcs->set_blank(hubp, false);
+       /* If the stream paired with this plane is phantom, the plane is also phantom */
+       if (pipe_ctx->stream && pipe_ctx->stream->mall_stream_config.type == SUBVP_PHANTOM
+                       && hubp->funcs->phantom_hubp_post_enable)
+               hubp->funcs->phantom_hubp_post_enable(hubp);
 }
 
 
@@ -1578,6 +1594,7 @@ static void dcn20_program_pipe(
 {
        struct dce_hwseq *hws = dc->hwseq;
        /* Only need to unblank on top pipe */
+
        if ((pipe_ctx->update_flags.bits.enable || pipe_ctx->stream->update_flags.bits.abm_level)
                        && !pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe)
                hws->funcs.blank_pixel_data(dc, pipe_ctx, !pipe_ctx->plane_state->visible);
@@ -1585,7 +1602,6 @@ static void dcn20_program_pipe(
        /* Only update TG on top pipe */
        if (pipe_ctx->update_flags.bits.global_sync && !pipe_ctx->top_pipe
                        && !pipe_ctx->prev_odm_pipe) {
-
                pipe_ctx->stream_res.tg->funcs->program_global_sync(
                                pipe_ctx->stream_res.tg,
                                pipe_ctx->pipe_dlg_param.vready_offset,
@@ -1593,7 +1609,12 @@ static void dcn20_program_pipe(
                                pipe_ctx->pipe_dlg_param.vupdate_offset,
                                pipe_ctx->pipe_dlg_param.vupdate_width);
 
-               pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+               if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                       pipe_ctx->stream_res.tg->funcs->wait_for_state(
+                               pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+                       pipe_ctx->stream_res.tg->funcs->wait_for_state(
+                               pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+               }
 
                pipe_ctx->stream_res.tg->funcs->set_vtg_params(
                                pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
@@ -1749,6 +1770,8 @@ void dcn20_program_front_end_for_ctx(
                        pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
                }
        }
+       if (hws->funcs.program_mall_pipe_config)
+               hws->funcs.program_mall_pipe_config(dc, context);
 }
 
 void dcn20_post_unlock_program_front_end(
@@ -2409,6 +2432,7 @@ void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)
                        NULL,
                        hubp->inst,
                        mpcc_id);
+
        dc->hwss.update_visual_confirm_color(dc, pipe_ctx, &blnd_cfg.black_color, mpcc_id);
 
        ASSERT(new_mpcc != NULL);
index a04ca4a..b683ad8 100644 (file)
@@ -195,7 +195,7 @@ static void enc3_update_hdmi_info_packet(
        }
 }
 
-static void enc3_stream_encoder_update_hdmi_info_packets(
+void enc3_stream_encoder_update_hdmi_info_packets(
        struct stream_encoder *enc,
        const struct encoder_info_frame *info_frame)
 {
@@ -214,7 +214,7 @@ static void enc3_stream_encoder_update_hdmi_info_packets(
        enc3_update_hdmi_info_packet(enc1, 4, &info_frame->hdrsmd);
 }
 
-static void enc3_stream_encoder_stop_hdmi_info_packets(
+void enc3_stream_encoder_stop_hdmi_info_packets(
        struct stream_encoder *enc)
 {
        struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
@@ -318,7 +318,7 @@ static void enc3_dp_set_dsc_config(struct stream_encoder *enc,
 }
 
 
-static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
+void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
                                        bool enable,
                                        uint8_t *dsc_packed_pps,
                                        bool immediate_update)
@@ -404,7 +404,7 @@ static void enc3_read_state(struct stream_encoder *enc, struct enc_state *s)
        }
 }
 
-static void enc3_stream_encoder_update_dp_info_packets(
+void enc3_stream_encoder_update_dp_info_packets(
        struct stream_encoder *enc,
        const struct encoder_info_frame *info_frame)
 {
@@ -652,7 +652,7 @@ static void enc3_stream_encoder_hdmi_set_stream_attribute(
        REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
 }
 
-static void enc3_audio_mute_control(
+void enc3_audio_mute_control(
        struct stream_encoder *enc,
        bool mute)
 {
@@ -660,7 +660,7 @@ static void enc3_audio_mute_control(
        enc->afmt->funcs->audio_mute_control(enc->afmt, mute);
 }
 
-static void enc3_se_dp_audio_setup(
+void enc3_se_dp_audio_setup(
        struct stream_encoder *enc,
        unsigned int az_inst,
        struct audio_info *info)
@@ -691,7 +691,7 @@ static void enc3_se_setup_dp_audio(
        enc->afmt->funcs->setup_dp_audio(enc->afmt);
 }
 
-static void enc3_se_dp_audio_enable(
+void enc3_se_dp_audio_enable(
        struct stream_encoder *enc)
 {
        enc1_se_enable_audio_clock(enc, true);
@@ -757,7 +757,7 @@ static void enc3_se_setup_hdmi_audio(
         */
 }
 
-static void enc3_se_hdmi_audio_setup(
+void enc3_se_hdmi_audio_setup(
        struct stream_encoder *enc,
        unsigned int az_inst,
        struct audio_info *info,
index 42140e7..d2207b3 100644 (file)
@@ -287,4 +287,39 @@ void dcn30_dio_stream_encoder_construct(
        const struct dcn10_stream_encoder_shift *se_shift,
        const struct dcn10_stream_encoder_mask *se_mask);
 
+void enc3_stream_encoder_update_hdmi_info_packets(
+       struct stream_encoder *enc,
+       const struct encoder_info_frame *info_frame);
+
+void enc3_stream_encoder_stop_hdmi_info_packets(
+       struct stream_encoder *enc);
+
+void enc3_stream_encoder_update_dp_info_packets(
+       struct stream_encoder *enc,
+       const struct encoder_info_frame *info_frame);
+
+void enc3_audio_mute_control(
+       struct stream_encoder *enc,
+       bool mute);
+
+void enc3_se_dp_audio_setup(
+       struct stream_encoder *enc,
+       unsigned int az_inst,
+       struct audio_info *info);
+
+void enc3_se_dp_audio_enable(
+       struct stream_encoder *enc);
+
+void enc3_se_hdmi_audio_setup(
+       struct stream_encoder *enc,
+       unsigned int az_inst,
+       struct audio_info *info,
+       struct audio_crtc_info *audio_crtc_info);
+
+void enc3_dp_set_dsc_pps_info_packet(
+       struct stream_encoder *enc,
+       bool enable,
+       uint8_t *dsc_packed_pps,
+    bool immediate_update);
+
 #endif /* __DC_DIO_STREAM_ENCODER_DCN30_H__ */
index ab3918c..9cca59b 100644 (file)
@@ -41,9 +41,9 @@
        dpp->tf_shift->field_name, dpp->tf_mask->field_name
 
 
-static void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s)
+void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s)
 {
-       struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
+       struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
        REG_GET(DPP_CONTROL,
                        DPP_CLOCK_ENABLE, &s->is_enabled);
@@ -167,7 +167,7 @@ void dpp3_set_pre_degam(struct dpp *dpp_base, enum dc_transfer_func_predefined t
                        PRE_DEGAM_SELECT, degamma_lut_selection);
 }
 
-static void dpp3_cnv_setup (
+void dpp3_cnv_setup (
                struct dpp *dpp_base,
                enum surface_pixel_format format,
                enum expansion_mode mode,
@@ -372,7 +372,7 @@ void dpp3_set_cursor_attributes(
 }
 
 
-static bool dpp3_get_optimal_number_of_taps(
+bool dpp3_get_optimal_number_of_taps(
                struct dpp *dpp,
                struct scaler_data *scl_data,
                const struct scaling_taps *in_taps)
index ac644ae..6263408 100644 (file)
@@ -588,6 +588,22 @@ void dpp3_program_CM_dealpha(
                struct dpp *dpp_base,
                uint32_t enable, uint32_t additive_blending);
 
+void dpp30_read_state(struct dpp *dpp_base,
+               struct dcn_dpp_state *s);
+
+bool dpp3_get_optimal_number_of_taps(
+               struct dpp *dpp,
+               struct scaler_data *scl_data,
+               const struct scaling_taps *in_taps);
+
+void dpp3_cnv_setup (
+               struct dpp *dpp_base,
+               enum surface_pixel_format format,
+               enum expansion_mode mode,
+               struct dc_csc_transform input_csc_color_matrix,
+               enum dc_color_space input_color_space,
+               struct cnv_alpha_2bit_lut *alpha_2bit_lut);
+
 void dpp3_program_CM_bias(
                struct dpp *dpp_base,
                struct CM_bias_params *bias_params);
index 0ce0d61..1981a71 100644 (file)
@@ -44,7 +44,7 @@
 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
 
 
-static bool mpc3_is_dwb_idle(
+bool mpc3_is_dwb_idle(
        struct mpc *mpc,
        int dwb_id)
 {
@@ -59,7 +59,7 @@ static bool mpc3_is_dwb_idle(
                return false;
 }
 
-static void mpc3_set_dwb_mux(
+void mpc3_set_dwb_mux(
        struct mpc *mpc,
        int dwb_id,
        int mpcc_id)
@@ -70,7 +70,7 @@ static void mpc3_set_dwb_mux(
                MPC_DWB0_MUX, mpcc_id);
 }
 
-static void mpc3_disable_dwb_mux(
+void mpc3_disable_dwb_mux(
        struct mpc *mpc,
        int dwb_id)
 {
@@ -80,7 +80,7 @@ static void mpc3_disable_dwb_mux(
                MPC_DWB0_MUX, 0xf);
 }
 
-static void mpc3_set_out_rate_control(
+void mpc3_set_out_rate_control(
        struct mpc *mpc,
        int opp_id,
        bool enable,
@@ -99,7 +99,7 @@ static void mpc3_set_out_rate_control(
                        MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1);
 }
 
-static enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
+enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
 {
        /*Contrary to DCN2 and DCN1 wherein a single status register field holds this info;
         *in DCN3/3AG, we need to read two separate fields to retrieve the same info
@@ -137,7 +137,7 @@ static enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
                return mode;
 }
 
-static void mpc3_power_on_ogam_lut(
+void mpc3_power_on_ogam_lut(
                struct mpc *mpc, int mpcc_id,
                bool power_on)
 {
@@ -1035,7 +1035,7 @@ static void mpc3_set3dlut_ram10(
 }
 
 
-static void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
+void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
 {
        mpcc->mpcc_id = mpcc_inst;
        mpcc->dpp_id = 0xf;
index 34b9ced..a4d8f77 100644 (file)
        uint32_t MPCC_OGAM_RAMB_START_BASE_CNTL_R[MAX_MPCC]; \
        uint32_t MPC_OUT_CSC_COEF_FORMAT
 
+#define MPC_REG_VARIABLE_LIST_DCN32 \
+       uint32_t MPCC_MCM_SHAPER_CONTROL[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_OFFSET_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_OFFSET_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_OFFSET_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_SCALE_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_SCALE_G_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_LUT_INDEX[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_LUT_DATA[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_START_CNTL_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_START_CNTL_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_START_CNTL_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_END_CNTL_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_END_CNTL_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_END_CNTL_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_0_1[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_2_3[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_4_5[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_6_7[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_8_9[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_10_11[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_12_13[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_14_15[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_16_17[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_18_19[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_20_21[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_22_23[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_24_25[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_26_27[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_28_29[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_30_31[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMA_REGION_32_33[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_START_CNTL_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_START_CNTL_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_START_CNTL_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_END_CNTL_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_END_CNTL_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_END_CNTL_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_0_1[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_2_3[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_4_5[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_6_7[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_8_9[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_10_11[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_12_13[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_14_15[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_16_17[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_18_19[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_20_21[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_22_23[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_24_25[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_26_27[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_28_29[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_30_31[MAX_MPCC]; \
+       uint32_t MPCC_MCM_SHAPER_RAMB_REGION_32_33[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_MODE[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_INDEX[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_DATA[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_DATA_30BIT[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_READ_WRITE_CONTROL[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_OUT_NORM_FACTOR[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_OUT_OFFSET_R[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_OUT_OFFSET_G[MAX_MPCC]; \
+       uint32_t MPCC_MCM_3DLUT_OUT_OFFSET_B[MAX_MPCC]; \
+       uint32_t MPCC_MCM_MEM_PWR_CTRL[MAX_MPCC]
+
 #define MPC_COMMON_MASK_SH_LIST_DCN3_0(mask_sh) \
        MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh),\
        SF(MPCC0_MPCC_CONTROL, MPCC_BG_BPC, mask_sh),\
        type MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS;\
        type MPC_RMU_SHAPER_MODE_CURRENT
 
+#define MPC_REG_FIELD_LIST_DCN32(type) \
+       type MPCC_MCM_SHAPER_MEM_PWR_FORCE;\
+       type MPCC_MCM_SHAPER_MEM_PWR_DIS;\
+       type MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE;\
+       type MPCC_MCM_3DLUT_MEM_PWR_FORCE;\
+       type MPCC_MCM_3DLUT_MEM_PWR_DIS;\
+       type MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE;\
+       type MPCC_MCM_1DLUT_MEM_PWR_FORCE;\
+       type MPCC_MCM_1DLUT_MEM_PWR_DIS;\
+       type MPCC_MCM_1DLUT_MEM_LOW_PWR_MODE;\
+       type MPCC_MCM_SHAPER_MEM_PWR_STATE;\
+       type MPCC_MCM_3DLUT_MEM_PWR_STATE;\
+       type MPCC_MCM_1DLUT_MEM_PWR_STATE;\
+       type MPCC_MCM_3DLUT_MODE; \
+       type MPCC_MCM_3DLUT_SIZE; \
+       type MPCC_MCM_3DLUT_MODE_CURRENT; \
+       type MPCC_MCM_3DLUT_WRITE_EN_MASK;\
+       type MPCC_MCM_3DLUT_RAM_SEL;\
+       type MPCC_MCM_3DLUT_30BIT_EN;\
+       type MPCC_MCM_3DLUT_CONFIG_STATUS;\
+       type MPCC_MCM_3DLUT_READ_SEL;\
+       type MPCC_MCM_3DLUT_INDEX;\
+       type MPCC_MCM_3DLUT_DATA0;\
+       type MPCC_MCM_3DLUT_DATA1;\
+       type MPCC_MCM_3DLUT_DATA_30BIT;\
+       type MPCC_MCM_SHAPER_LUT_MODE;\
+       type MPCC_MCM_SHAPER_MODE_CURRENT;\
+       type MPCC_MCM_SHAPER_OFFSET_R;\
+       type MPCC_MCM_SHAPER_OFFSET_G;\
+       type MPCC_MCM_SHAPER_OFFSET_B;\
+       type MPCC_MCM_SHAPER_SCALE_R;\
+       type MPCC_MCM_SHAPER_SCALE_G;\
+       type MPCC_MCM_SHAPER_SCALE_B;\
+       type MPCC_MCM_SHAPER_LUT_INDEX;\
+       type MPCC_MCM_SHAPER_LUT_DATA;\
+       type MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK;\
+       type MPCC_MCM_SHAPER_LUT_WRITE_SEL;\
+       type MPCC_MCM_SHAPER_CONFIG_STATUS;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET;\
+       type MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS
+
 #define MPC_COMMON_MASK_SH_LIST_DCN303(mask_sh) \
        MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh),\
        SF(MPCC0_MPCC_CONTROL, MPCC_BG_BPC, mask_sh),\
 
 struct dcn30_mpc_registers {
        MPC_REG_VARIABLE_LIST_DCN3_0;
+       MPC_REG_VARIABLE_LIST_DCN32;
 };
 
 struct dcn30_mpc_shift {
        MPC_REG_FIELD_LIST_DCN3_0(uint8_t);
+       MPC_REG_FIELD_LIST_DCN32(uint8_t);
 };
 
 struct dcn30_mpc_mask {
        MPC_REG_FIELD_LIST_DCN3_0(uint32_t);
+       MPC_REG_FIELD_LIST_DCN32(uint32_t);
 };
 
 struct dcn30_mpc {
@@ -841,4 +958,34 @@ void mpc3_set_rmu_mux(
        int rmu_idx,
        int value);
 
+void mpc3_set_dwb_mux(
+       struct mpc *mpc,
+       int dwb_id,
+       int mpcc_id);
+
+void mpc3_disable_dwb_mux(
+       struct mpc *mpc,
+       int dwb_id);
+
+bool mpc3_is_dwb_idle(
+       struct mpc *mpc,
+       int dwb_id);
+
+void mpc3_set_out_rate_control(
+       struct mpc *mpc,
+       int opp_id,
+       bool enable,
+       bool rate_2x_mode,
+       struct mpc_dwb_flow_control *flow_control);
+
+void mpc3_power_on_ogam_lut(
+       struct mpc *mpc, int mpcc_id,
+       bool power_on);
+
+void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst);
+
+enum dc_lut_mode mpc3_get_ogam_current(
+       struct mpc *mpc,
+       int mpcc_id);
+
 #endif
index 97f11ef..33bd12f 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "dcn20/dcn20_optc.h"
 
+#define V_TOTAL_REGS_DCN30_SRI(inst)
 
 #define OPTC_COMMON_REG_LIST_DCN3_BASE(inst) \
        SRI(OTG_VSTARTUP_PARAM, OTG, inst),\
@@ -55,6 +56,7 @@
        SRI(OTG_V_TOTAL_MAX, OTG, inst),\
        SRI(OTG_V_TOTAL_MIN, OTG, inst),\
        SRI(OTG_V_TOTAL_CONTROL, OTG, inst),\
+       V_TOTAL_REGS_DCN30_SRI(inst)\
        SRI(OTG_TRIGA_CNTL, OTG, inst),\
        SRI(OTG_FORCE_COUNT_NOW_CNTL, OTG, inst),\
        SRI(OTG_STATIC_SCREEN_CONTROL, OTG, inst),\
@@ -80,6 +82,7 @@
        SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\
        SRI(OTG_GSL_CONTROL, OTG, inst),\
        SRI(OTG_CRC_CNTL, OTG, inst),\
+       SRI(OTG_CRC_CNTL2, OTG, inst),\
        SRI(OTG_CRC0_DATA_RG, OTG, inst),\
        SRI(OTG_CRC0_DATA_B, OTG, inst),\
        SRI(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst),\
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
        SR(DWB_SOURCE_SELECT)
 
+#define DCN30_VTOTAL_REGS_SF(mask_sh)
 
 #define OPTC_COMMON_MASK_SH_LIST_DCN3_BASE(mask_sh)\
        SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
        SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_SET_V_TOTAL_MIN_MASK, mask_sh),\
        SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_REPLACING_MIN_EN, mask_sh),\
        SF(OTG0_OTG_V_TOTAL_CONTROL, OTG_VTOTAL_MID_REPLACING_MAX_EN, mask_sh),\
+       DCN30_VTOTAL_REGS_SF(mask_sh)\
        SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_CLEAR, mask_sh),\
        SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_MODE, mask_sh),\
        SF(OTG0_OTG_FORCE_COUNT_NOW_CNTL, OTG_FORCE_COUNT_NOW_OCCURRED, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
+       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DSC_MODE, mask_sh),\
+       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_COMBINE_MODE, mask_sh),\
+       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_SPLIT_MODE, mask_sh),\
+       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_FORMAT, mask_sh),\
        SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
        SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\
        SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\
index 4519ece..13dbf99 100644 (file)
@@ -158,10 +158,9 @@ static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst)
        }
 }
 
-void dccg31_set_dpstreamclk(
-               struct dccg *dccg,
-               enum hdmistreamclk_source src,
-               int otg_inst)
+void dccg31_set_dpstreamclk(struct dccg *dccg,
+                           enum streamclk_source src,
+                           int otg_inst)
 {
        if (src == REFCLK)
                dccg31_disable_dpstreamclk(dccg, otg_inst);
@@ -662,6 +661,24 @@ void dccg31_init(struct dccg *dccg)
        }
 }
 
+void dccg31_otg_add_pixel(struct dccg *dccg,
+               uint32_t otg_inst)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
+                       OTG_ADD_PIXEL[otg_inst], 1);
+}
+
+void dccg31_otg_drop_pixel(struct dccg *dccg,
+               uint32_t otg_inst)
+{
+       struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+
+       REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
+                       OTG_DROP_PIXEL[otg_inst], 1);
+}
+
 static const struct dccg_funcs dccg31_funcs = {
        .update_dpp_dto = dccg31_update_dpp_dto,
        .get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
@@ -674,6 +691,9 @@ static const struct dccg_funcs dccg31_funcs = {
        .set_physymclk = dccg31_set_physymclk,
        .set_dtbclk_dto = dccg31_set_dtbclk_dto,
        .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto,
+       .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en,
+       .otg_add_pixel = dccg31_otg_add_pixel,
+       .otg_drop_pixel = dccg31_otg_drop_pixel,
        .set_dispclk_change_mode = dccg31_set_dispclk_change_mode,
        .disable_dsc = dccg31_disable_dscclk,
        .enable_dsc = dccg31_enable_dscclk,
index f158c1e..80bd807 100644 (file)
 
 #include "dcn30/dcn30_dccg.h"
 
-#define DCCG_SFII(block, reg_name, field_prefix, field_name, inst, post_fix)\
-       .field_prefix ## _ ## field_name[inst] = block ## inst ## _ ## reg_name ## __ ## field_prefix ## inst ## _ ## field_name ## post_fix
-
-
 #define DCCG_REG_LIST_DCN31() \
        SR(DPPCLK_DTO_CTRL),\
        DCCG_SRII(DTO_PARAM, DPPCLK, 0),\
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 1, mask_sh),\
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 2, mask_sh),\
        DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 3, mask_sh),\
+       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\
+       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\
+       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 2, mask_sh),\
+       DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 3, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
        DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
        DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh), \
@@ -163,7 +163,7 @@ void dccg31_init(struct dccg *dccg);
 
 void dccg31_set_dpstreamclk(
                struct dccg *dccg,
-               enum hdmistreamclk_source src,
+               enum streamclk_source src,
                int otg_inst);
 
 void dccg31_enable_symclk32_se(
@@ -194,8 +194,4 @@ void dccg31_set_audio_dtbclk_dto(
                struct dccg *dccg,
                const struct dtbclk_dto_params *params);
 
-void dccg31_set_hdmistreamclk(
-               struct dccg *dccg,
-               enum hdmistreamclk_source src);
-
 #endif //__DCN31_DCCG_H__
index c51f7dc..96fac71 100644 (file)
@@ -213,26 +213,6 @@ void optc31_set_drr(
        }
 }
 
-void optc3_init_odm(struct timing_generator *optc)
-{
-       struct optc *optc1 = DCN10TG_FROM_TG(optc);
-
-       REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0,
-                       OPTC_NUM_OF_INPUT_SEGMENT, 0,
-                       OPTC_SEG0_SRC_SEL, optc->inst,
-                       OPTC_SEG1_SRC_SEL, 0xf,
-                       OPTC_SEG2_SRC_SEL, 0xf,
-                       OPTC_SEG3_SRC_SEL, 0xf
-                       );
-
-       REG_SET(OTG_H_TIMING_CNTL, 0,
-                       OTG_H_TIMING_DIV_MODE, 0);
-
-       REG_SET(OPTC_MEMORY_CONFIG, 0,
-                       OPTC_MEM_SEL, 0);
-       optc1->opp_count = 1;
-}
-
 static struct timing_generator_funcs dcn31_tg_funcs = {
                .validate_timing = optc1_validate_timing,
                .program_timing = optc1_program_timing,
@@ -266,6 +246,7 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
                .lock_doublebuffer_disable = optc3_lock_doublebuffer_disable,
                .enable_optc_clock = optc1_enable_optc_clock,
                .set_drr = optc31_set_drr,
+               .get_last_used_drr_vtotal = optc2_get_last_used_drr_vtotal,
                .set_vtotal_min_max = optc1_set_vtotal_min_max,
                .set_static_screen_control = optc1_set_static_screen_control,
                .program_stereo = optc1_program_stereo,
@@ -292,7 +273,6 @@ static struct timing_generator_funcs dcn31_tg_funcs = {
                .program_manual_trigger = optc2_program_manual_trigger,
                .setup_manual_trigger = optc2_setup_manual_trigger,
                .get_hw_timing = optc1_get_hw_timing,
-               .init_odm = optc3_init_odm,
 };
 
 void dcn31_timing_generator_init(struct optc *optc1)
index 9e881f2..3706e6f 100644 (file)
@@ -98,7 +98,8 @@
        SRI(OPTC_WIDTH_CONTROL, ODM, inst),\
        SRI(OPTC_MEMORY_CONFIG, ODM, inst),\
        SRI(OTG_CRC_CNTL2, OTG, inst),\
-       SR(DWB_SOURCE_SELECT)
+       SR(DWB_SOURCE_SELECT),\
+       SRI(OTG_DRR_CONTROL, OTG, inst)
 
 #define OPTC_COMMON_MASK_SH_LIST_DCN3_1(mask_sh)\
        SF(OTG0_OTG_VSTARTUP_PARAM, VSTARTUP_START, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DSC_MODE, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_COMBINE_MODE, mask_sh),\
        SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_SPLIT_MODE, mask_sh),\
-       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_FORMAT, mask_sh)
+       SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_FORMAT, mask_sh),\
+       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
 
 void dcn31_timing_generator_init(struct optc *optc1);
 
index 1263356..5609ac6 100644 (file)
@@ -141,52 +141,45 @@ static void dccg32_set_dtbclk_p_src(
 /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */
 void dccg32_set_dtbclk_dto(
                struct dccg *dccg,
-               int otg_inst,
-               int pixclk_khz,
-               int num_odm_segments,
-               const struct dc_crtc_timing *timing)
+               const struct dtbclk_dto_params *params)
 {
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
        /* DTO Output Rate / Pixel Rate = 1/4 */
-       int req_dtbclk_khz = pixclk_khz / 4;
+       int req_dtbclk_khz = params->pixclk_khz / 4;
 
-       if (dccg->ref_dtbclk_khz && req_dtbclk_khz) {
+       if (params->ref_dtbclk_khz && req_dtbclk_khz) {
                uint32_t modulo, phase;
 
                // phase / modulo = dtbclk / dtbclk ref
-               modulo = 0xffffffff;
-               phase = (((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1) / dccg->ref_dtbclk_khz;
+               modulo = params->ref_dtbclk_khz * 1000;
+               phase = req_dtbclk_khz * 1000;
 
-               REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], modulo);
-               REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], phase);
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase);
 
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
-                               DTBCLK_DTO_ENABLE[otg_inst], 1);
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 1);
 
-               REG_WAIT(OTG_PIXEL_RATE_CNTL[otg_inst],
-                               DTBCLKDTO_ENABLE_STATUS[otg_inst], 1,
+               REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1,
                                1, 100);
 
                /* program OTG_PIXEL_RATE_DIV for DIVK1 and DIVK2 fields */
-               dccg32_set_pixel_rate_div(dccg, otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
+               dccg32_set_pixel_rate_div(dccg, params->otg_inst, PIXEL_RATE_DIV_BY_1, PIXEL_RATE_DIV_BY_1);
 
                /* The recommended programming sequence to enable DTBCLK DTO to generate
                 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
                 * be set only after DTO is enabled
                 */
-               REG_UPDATE(OTG_PIXEL_RATE_CNTL[otg_inst],
-                               PIPE_DTO_SRC_SEL[otg_inst], 2);
-
-               dccg->dtbclk_khz[otg_inst] = req_dtbclk_khz;
+               REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 2);
        } else {
-               REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[otg_inst],
-                               DTBCLK_DTO_ENABLE[otg_inst], 0,
-                               PIPE_DTO_SRC_SEL[otg_inst], 1);
-
-               REG_WRITE(DTBCLK_DTO_MODULO[otg_inst], 0);
-               REG_WRITE(DTBCLK_DTO_PHASE[otg_inst], 0);
+               REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+                               DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+                               PIPE_DTO_SRC_SEL[params->otg_inst], 1);
 
-               dccg->dtbclk_khz[otg_inst] = 0;
+               REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+               REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
        }
 }
 
index 62532da..4d7588f 100644 (file)
@@ -211,8 +211,10 @@ static void enc32_stream_encoder_hdmi_set_stream_attribute(
                HDMI_GC_SEND, 1,
                HDMI_NULL_SEND, 1);
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
        /* Disable Audio Content Protection packet transmission */
        REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
+#endif
 
        /* following belongs to audio */
        /* Enable Audio InfoFrame packet transmission. */
@@ -301,6 +303,21 @@ static void enc32_stream_encoder_dp_unblank(
 
        REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
 
+       /* DIG Resync FIFO now needs to be explicitly enabled
+        */
+       // TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON
+       REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
+
+       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+
+       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
+
+       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+
+       REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
+
+       REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+
        /* wait 100us for DIG/DP logic to prime
         * (i.e. a few video lines)
         */
@@ -354,6 +371,23 @@ static void enc32_read_state(struct stream_encoder *enc, struct enc_state *s)
        }
 }
 
+static void enc32_stream_encoder_reset_fifo(struct stream_encoder *enc)
+{
+       struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+       uint32_t fifo_enabled;
+
+       REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &fifo_enabled);
+
+       if (fifo_enabled == 0) {
+               /* reset DIG resync FIFO */
+               REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+               /* TODO: fix timeout when wait for DIG_FIFO_RESET_DONE */
+               //REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 1, 100);
+               udelay(1);
+               REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+               REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 1, 100);
+       }
+}
 
 static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
        .dp_set_odm_combine =
@@ -375,7 +409,7 @@ static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
        .stop_dp_info_packets =
                enc1_stream_encoder_stop_dp_info_packets,
        .reset_fifo =
-               enc1_stream_encoder_reset_fifo,
+               enc32_stream_encoder_reset_fifo,
        .dp_blank =
                enc1_stream_encoder_dp_blank,
        .dp_unblank =
index 7241080..77da0a1 100644 (file)
@@ -89,7 +89,8 @@
        SRI(DP_SEC_METADATA_TRANSMISSION, DP, id), \
        SRI(HDMI_METADATA_PACKET_CONTROL, DIG, id), \
        SRI(DIG_FE_CNTL, DIG, id), \
-       SRI(DIG_CLOCK_PATTERN, DIG, id)
+       SRI(DIG_CLOCK_PATTERN, DIG, id), \
+       SRI(DIG_FIFO_CTRL0, DIG, id)
 
 
 #define SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)\
        SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE_REFERENCE, mask_sh),\
        SE_SF(DIG0_HDMI_METADATA_PACKET_CONTROL, HDMI_METADATA_PACKET_LINE, mask_sh),\
        SE_SF(DIG0_DIG_FE_CNTL, DOLBY_VISION_EN, mask_sh),\
+       SE_SF(DIG0_DIG_FE_CNTL, DIG_SYMCLK_FE_ON, mask_sh),\
        SE_SF(DP0_DP_SEC_FRAMING4, DP_SST_SDP_SPLITTING, mask_sh),\
-       SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh)
+       SE_SF(DIG0_DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, mask_sh),\
+       SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, mask_sh),\
+       SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, mask_sh),\
+       SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET, mask_sh),\
+       SE_SF(DIG0_DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, mask_sh)
 
+#if defined(CONFIG_DRM_AMD_DC_HDCP)
 #define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
        SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh),\
        SE_SF(DIG0_HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, mask_sh)
+#else
+#define SE_COMMON_MASK_SH_LIST_DCN32(mask_sh)\
+       SE_COMMON_MASK_SH_LIST_DCN32_BASE(mask_sh)
+#endif
 
 void dcn32_dio_stream_encoder_construct(
        struct dcn10_stream_encoder *enc1,
index d0a222f..40afd33 100644 (file)
@@ -649,7 +649,7 @@ void dcn32_init_hw(struct dc *dc)
         * Otherwise, if taking control is not possible, we need to power
         * everything down.
         */
-       if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) {
+       if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.seamless_boot_edp_requested) {
                hws->funcs.init_pipes(dc, dc->current_state);
                if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
                        dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
@@ -661,7 +661,7 @@ void dcn32_init_hw(struct dc *dc)
         * To avoid this, power down hardware on boot
         * if DIG is turned on and seamless boot not enabled
         */
-       if (dc->config.power_down_display_on_boot) {
+       if (dc->config.seamless_boot_edp_requested) {
                struct dc_link *edp_links[MAX_NUM_EDP];
                struct dc_link *edp_link;
 
index f1ed25e..88275ea 100644 (file)
@@ -91,10 +91,18 @@ static void optc32_set_odm_combine(struct timing_generator *optc, int *opp_id, i
        REG_UPDATE(OPTC_WIDTH_CONTROL,
                        OPTC_SEGMENT_WIDTH, mpcc_hactive);
 
-       REG_SET(OTG_H_TIMING_CNTL, 0, OTG_H_TIMING_DIV_MODE, opp_cnt - 1);
+       REG_UPDATE(OTG_H_TIMING_CNTL,
+                       OTG_H_TIMING_DIV_MODE, opp_cnt - 1);
        optc1->opp_count = opp_cnt;
 }
 
+static void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+       REG_UPDATE(OTG_H_TIMING_CNTL,
+                       OTG_H_TIMING_DIV_MODE_MANUAL, manual_mode ? 1 : 0);
+}
 /**
  * Enable CRTC
  * Enable CRTC - call ASIC Control Object to enable Timing generator.
@@ -157,6 +165,29 @@ void optc32_phantom_crtc_post_enable(struct timing_generator *optc)
        REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000);
 }
 
+static void optc32_set_odm_bypass(struct timing_generator *optc,
+               const struct dc_crtc_timing *dc_crtc_timing)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+       enum h_timing_div_mode h_div = H_TIMING_NO_DIV;
+
+       REG_SET_5(OPTC_DATA_SOURCE_SELECT, 0,
+                       OPTC_NUM_OF_INPUT_SEGMENT, 0,
+                       OPTC_SEG0_SRC_SEL, optc->inst,
+                       OPTC_SEG1_SRC_SEL, 0xf,
+                       OPTC_SEG2_SRC_SEL, 0xf,
+                       OPTC_SEG3_SRC_SEL, 0xf
+                       );
+
+       h_div = optc1_is_two_pixels_per_containter(dc_crtc_timing);
+       REG_UPDATE(OTG_H_TIMING_CNTL,
+                       OTG_H_TIMING_DIV_MODE, h_div);
+
+       REG_SET(OPTC_MEMORY_CONFIG, 0,
+                       OPTC_MEM_SEL, 0);
+       optc1->opp_count = 1;
+}
+
 
 static struct timing_generator_funcs dcn32_tg_funcs = {
                .validate_timing = optc1_validate_timing,
@@ -206,8 +237,9 @@ static struct timing_generator_funcs dcn32_tg_funcs = {
                .set_dsc_config = optc3_set_dsc_config,
                .get_dsc_status = optc2_get_dsc_status,
                .set_dwb_source = NULL,
-               .set_odm_bypass = optc3_set_odm_bypass,
+               .set_odm_bypass = optc32_set_odm_bypass,
                .set_odm_combine = optc32_set_odm_combine,
+               .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode,
                .get_optc_source = optc2_get_optc_source,
                .set_out_mux = optc3_set_out_mux,
                .set_drr_trigger_window = optc3_set_drr_trigger_window,
index 17a287b..7ac6428 100644 (file)
@@ -77,7 +77,7 @@
 
 #include "dcn/dcn_3_2_0_offset.h"
 #include "dcn/dcn_3_2_0_sh_mask.h"
-#include "dcn/nbio_4_3_0_offset.h"
+#include "nbio/nbio_4_3_0_offset.h"
 
 #include "reg_helper.h"
 #include "dce/dmub_abm.h"
index f79dd40..8d4c74b 100644 (file)
@@ -811,9 +811,14 @@ void dcn20_calculate_dlg_params(
                pipes[pipe_idx].pipe.dest.vupdate_offset = get_vupdate_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
                pipes[pipe_idx].pipe.dest.vupdate_width = get_vupdate_width(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
                pipes[pipe_idx].pipe.dest.vready_offset = get_vready_offset(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
-               context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
-               context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
-
+               if (context->res_ctx.pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM) {
+                       // Phantom pipe requires that DET_SIZE = 0 and no unbounded requests
+                       context->res_ctx.pipe_ctx[i].det_buffer_size_kb = 0;
+                       context->res_ctx.pipe_ctx[i].unbounded_req = false;
+               } else {
+                       context->res_ctx.pipe_ctx[i].det_buffer_size_kb = context->bw_ctx.dml.ip.det_buffer_size_kbytes;
+                       context->res_ctx.pipe_ctx[i].unbounded_req = pipes[pipe_idx].pipe.src.unbounded_req_mode;
+               }
                if (context->bw_ctx.bw.dcn.clk.dppclk_khz < pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
                        context->bw_ctx.bw.dcn.clk.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000;
                context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz =
@@ -1013,6 +1018,31 @@ int dcn20_populate_dml_pipes_from_context(
                        pipes[pipe_cnt].pipe.dest.pixel_rate_mhz *= 2;
                pipes[pipe_cnt].pipe.dest.otg_inst = res_ctx->pipe_ctx[i].stream_res.tg->inst;
                pipes[pipe_cnt].dout.dp_lanes = 4;
+               if (res_ctx->pipe_ctx[i].stream->link) {
+                       switch (res_ctx->pipe_ctx[i].stream->link->cur_link_settings.link_rate) {
+                       case LINK_RATE_HIGH:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr;
+                               break;
+                       case LINK_RATE_HIGH2:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr2;
+                               break;
+                       case LINK_RATE_HIGH3:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr3;
+                               break;
+                       case LINK_RATE_UHBR10:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_uhbr10;
+                               break;
+                       case LINK_RATE_UHBR13_5:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_uhbr13p5;
+                               break;
+                       case LINK_RATE_UHBR20:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_uhbr20;
+                               break;
+                       default:
+                               pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_na;
+                               break;
+                       }
+               }
                pipes[pipe_cnt].dout.is_virtual = 0;
                pipes[pipe_cnt].pipe.dest.vtotal_min = res_ctx->pipe_ctx[i].stream->adjust.v_total_min;
                pipes[pipe_cnt].pipe.dest.vtotal_max = res_ctx->pipe_ctx[i].stream->adjust.v_total_max;
@@ -1070,6 +1100,7 @@ int dcn20_populate_dml_pipes_from_context(
                        pipes[pipe_cnt].dout.is_virtual = 1;
                        pipes[pipe_cnt].dout.output_type = dm_dp;
                        pipes[pipe_cnt].dout.dp_lanes = 4;
+                       pipes[pipe_cnt].dout.dp_rate = dm_dp_rate_hbr2;
                }
 
                switch (res_ctx->pipe_ctx[i].stream->timing.display_color_depth) {
@@ -1138,7 +1169,8 @@ int dcn20_populate_dml_pipes_from_context(
                 * bw calculations due to cursor on/off
                 */
                if (res_ctx->pipe_ctx[i].plane_state &&
-                               res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
+                               (res_ctx->pipe_ctx[i].plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE ||
+                                res_ctx->pipe_ctx[i].stream->mall_stream_config.type == SUBVP_PHANTOM))
                        pipes[pipe_cnt].pipe.src.num_cursors = 0;
                else
                        pipes[pipe_cnt].pipe.src.num_cursors = dc->dml.ip.number_of_cursors;
@@ -1149,6 +1181,7 @@ int dcn20_populate_dml_pipes_from_context(
                if (!res_ctx->pipe_ctx[i].plane_state) {
                        pipes[pipe_cnt].pipe.src.is_hsplit = pipes[pipe_cnt].pipe.dest.odm_combine != dm_odm_combine_mode_disabled;
                        pipes[pipe_cnt].pipe.src.source_scan = dm_horz;
+                       pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
                        pipes[pipe_cnt].pipe.src.sw_mode = dm_sw_4kb_s;
                        pipes[pipe_cnt].pipe.src.macro_tile_size = dm_64k_tile;
                        pipes[pipe_cnt].pipe.src.viewport_width = timing->h_addressable;
@@ -1201,8 +1234,26 @@ int dcn20_populate_dml_pipes_from_context(
 
                        pipes[pipe_cnt].pipe.src.source_scan = pln->rotation == ROTATION_ANGLE_90
                                        || pln->rotation == ROTATION_ANGLE_270 ? dm_vert : dm_horz;
+                       switch (pln->rotation) {
+                       case ROTATION_ANGLE_0:
+                               pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_0;
+                               break;
+                       case ROTATION_ANGLE_90:
+                               pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_90;
+                               break;
+                       case ROTATION_ANGLE_180:
+                               pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_180;
+                               break;
+                       case ROTATION_ANGLE_270:
+                               pipes[pipe_cnt].pipe.src.source_rotation = dm_rotation_270;
+                               break;
+                       default:
+                               break;
+                       }
                        pipes[pipe_cnt].pipe.src.viewport_y_y = scl->viewport.y;
                        pipes[pipe_cnt].pipe.src.viewport_y_c = scl->viewport_c.y;
+                       pipes[pipe_cnt].pipe.src.viewport_x_y = scl->viewport.x;
+                       pipes[pipe_cnt].pipe.src.viewport_x_c = scl->viewport_c.x;
                        pipes[pipe_cnt].pipe.src.viewport_width = scl->viewport.width;
                        pipes[pipe_cnt].pipe.src.viewport_width_c = scl->viewport_c.width;
                        pipes[pipe_cnt].pipe.src.viewport_height = scl->viewport.height;
index 555d4d9..0317af5 100644 (file)
@@ -195,6 +195,16 @@ struct resource_funcs {
        enum dc_status (*add_dsc_to_stream_resource)(
                        struct dc *dc, struct dc_state *state,
                        struct dc_stream_state *stream);
+
+       void (*add_phantom_pipes)(
+            struct dc *dc,
+            struct dc_state *context,
+            display_e2e_pipe_params_st *pipes,
+                       unsigned int pipe_cnt,
+            unsigned int index);
+       void (*remove_phantom_pipes)(
+            struct dc *dc,
+            struct dc_state *context);
 };
 
 struct audio_support{
index c1023cc..b5acc6b 100644 (file)
@@ -45,9 +45,10 @@ enum physymclk_clock_source {
        PHYSYMCLK_FORCE_SRC_PHYD32CLK, // Select phyd32clk as the source of clock which is output to PHY through DCIO.
 };
 
-enum hdmistreamclk_source {
+enum streamclk_source {
        REFCLK,                   // Selects REFCLK as source for hdmistreamclk.
        DTBCLK0,                  // Selects DTBCLK0 as source for hdmistreamclk.
+       DPREFCLK,                 // Selects DPREFCLK as source for hdmistreamclk
 };
 
 enum dentist_dispclk_change_mode {
@@ -91,7 +92,7 @@ struct dccg_funcs {
 
        void (*set_dpstreamclk)(
                        struct dccg *dccg,
-                       enum hdmistreamclk_source src,
+                       enum streamclk_source src,
                        int otg_inst);
 
        void (*enable_symclk32_se)(
index 9195dec..e7571c6 100644 (file)
@@ -47,6 +47,8 @@ struct dcn_hubbub_wm_set {
        uint32_t sr_enter;
        uint32_t sr_exit;
        uint32_t dram_clk_chanage;
+       uint32_t usr_retrain;
+       uint32_t fclk_pstate_change;
 };
 
 struct dcn_hubbub_wm {
@@ -168,6 +170,7 @@ struct hubbub_funcs {
        void (*program_det_size)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_in_kbyte);
        void (*program_compbuf_size)(struct hubbub *hubbub, unsigned compbuf_size_kb, bool safe_to_increase);
        void (*init_crb)(struct hubbub *hubbub);
+       void (*force_usr_retraining_allow)(struct hubbub *hubbub, bool allow);
 };
 
 struct hubbub {
index ad69d78..b2cdb6b 100644 (file)
@@ -140,6 +140,9 @@ struct hubp_funcs {
 
        void (*set_blank)(struct hubp *hubp, bool blank);
        void (*set_blank_regs)(struct hubp *hubp, bool blank);
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       void (*phantom_hubp_post_enable)(struct hubp *hubp);
+#endif
        void (*set_hubp_blank_en)(struct hubp *hubp, bool blank);
 
        void (*set_cursor_attributes)(
@@ -193,6 +196,10 @@ struct hubp_funcs {
        bool (*hubp_in_blank)(struct hubp *hubp);
        void (*hubp_soft_reset)(struct hubp *hubp, bool reset);
 
+       void (*hubp_update_force_pstate_disallow)(struct hubp *hubp, bool allow);
+       void (*hubp_update_mall_sel)(struct hubp *hubp, uint32_t mall_sel);
+       void (*hubp_prepare_subvp_buffering)(struct hubp *hubp, bool enable);
+
        void (*hubp_set_flip_int)(struct hubp *hubp);
 
        void (*program_extended_blank)(struct hubp *hubp,
index 8798cfa..b72fb31 100644 (file)
@@ -37,6 +37,7 @@ struct cstate_pstate_watermarks_st {
        uint32_t cstate_enter_plus_exit_z8_ns;
        uint32_t cstate_enter_plus_exit_ns;
        uint32_t pstate_change_ns;
+       uint32_t fclk_pstate_change_ns;
 };
 
 struct dcn_watermarks {
@@ -46,6 +47,7 @@ struct dcn_watermarks {
        uint32_t frac_urg_bw_flip;
        int32_t urgent_latency_ns;
        struct cstate_pstate_watermarks_st cstate_pstate;
+       uint32_t usr_retraining_ns;
 };
 
 struct dcn_watermark_set {
index 678c206..36ec565 100644 (file)
@@ -164,6 +164,10 @@ struct stream_encoder_funcs {
        void (*stop_dp_info_packets)(
                struct stream_encoder *enc);
 
+       void (*reset_fifo)(
+               struct stream_encoder *enc
+       );
+
        void (*dp_blank)(
                struct dc_link *link,
                struct stream_encoder *enc);
index 554d2e3..a89b223 100644 (file)
@@ -174,6 +174,9 @@ struct timing_generator_funcs {
 
        bool (*enable_crtc)(struct timing_generator *tg);
        bool (*disable_crtc)(struct timing_generator *tg);
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       void (*phantom_crtc_post_enable)(struct timing_generator *tg);
+#endif
        bool (*immediate_disable_crtc)(struct timing_generator *tg);
        bool (*is_counter_moving)(struct timing_generator *tg);
        void (*get_position)(struct timing_generator *tg,
@@ -293,6 +296,7 @@ struct timing_generator_funcs {
        void (*set_odm_bypass)(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing);
        void (*set_odm_combine)(struct timing_generator *optc, int *opp_id, int opp_cnt,
                        struct dc_crtc_timing *timing);
+       void (*set_h_timing_div_manual_mode)(struct timing_generator *optc, bool manual_mode);
        void (*set_gsl)(struct timing_generator *optc, const struct gsl_params *params);
        void (*set_gsl_source_select)(struct timing_generator *optc,
                        int group_idx,
@@ -310,8 +314,10 @@ struct timing_generator_funcs {
                        uint32_t slave_pixel_clock_100Hz,
                        uint8_t master_clock_divider,
                        uint8_t slave_clock_divider);
-
-       void (*init_odm)(struct timing_generator *tg);
+       bool (*validate_vmin_vmax)(struct timing_generator *optc,
+                       int vmin, int vmax);
+       bool (*validate_vtotal_change_limit)(struct timing_generator *optc,
+                       uint32_t vtotal_change_limit);
 };
 
 #endif
index 05053f3..eb616a4 100644 (file)
@@ -244,6 +244,8 @@ struct hw_sequencer_funcs {
                        struct pipe_ctx *pipe_ctx,
                        struct tg_color *color,
                        int mpcc_id);
+
+       void (*commit_subvp_config)(struct dc *dc, struct dc_state *context);
 };
 
 void color_space_to_black_color(
index d2cb0e7..fd869e9 100644 (file)
@@ -145,6 +145,11 @@ struct hwseq_private_funcs {
        void (*PLAT_58856_wa)(struct dc_state *context,
                        struct pipe_ctx *pipe_ctx);
        void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable);
+#ifdef CONFIG_DRM_AMD_DC_DCN
+       void (*program_mall_pipe_config)(struct dc *dc, struct dc_state *context);
+       void (*subvp_update_force_pstate)(struct dc *dc, struct dc_state *context);
+       void (*update_mall_sel)(struct dc *dc, struct dc_state *context);
+#endif
 };
 
 struct dce_hwseq {
index 2369f38..5815876 100644 (file)
@@ -205,6 +205,13 @@ bool get_temp_dp_link_res(struct dc_link *link,
                struct link_resource *link_res,
                struct dc_link_settings *link_settings);
 
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt(
+               const struct resource_context *res_ctx,
+               const struct resource_pool *pool,
+               const struct dc_link *link);
+#endif
+
 void reset_syncd_pipes_from_disabled_pipes(struct dc *dc,
        struct dc_state *context);
 
index cf4027c..83058bc 100644 (file)
@@ -335,4 +335,14 @@ struct bp_soc_bb_info {
        uint32_t dram_sr_enter_exit_latency_100ns;
 };
 
+struct bp_connector_speed_cap_info {
+       uint32_t DP_HBR2_EN:1;
+       uint32_t DP_HBR3_EN:1;
+       uint32_t HDMI_6GB_EN:1;
+       uint32_t DP_UHBR10_EN:1;
+       uint32_t DP_UHBR13_5_EN:1;
+       uint32_t DP_UHBR20_EN:1;
+       uint32_t RESERVED:29;
+};
+
 #endif /*__DAL_BIOS_PARSER_TYPES_H__ */