summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/bios
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/bios')
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c204
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c40
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h3
4 files changed, 252 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
index 37fa7b48250e..b8684131151d 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -1154,6 +1154,9 @@ static enum bp_result bios_parser_get_firmware_info(
result = get_firmware_info_v3_2(bp, info);
break;
case 3:
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+ case 4:
+#endif
result = get_firmware_info_v3_2(bp, info);
break;
default:
@@ -1375,6 +1378,63 @@ static struct atom_encoder_caps_record *get_encoder_cap_record(
return NULL;
}
+static enum bp_result get_vram_info_v23(
+ struct bios_parser *bp,
+ struct dc_vram_info *info)
+{
+ struct atom_vram_info_header_v2_3 *info_v23;
+ enum bp_result result = BP_RESULT_OK;
+
+ info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
+ DATA_TABLES(vram_info));
+
+ if (info_v23 == NULL)
+ return BP_RESULT_BADBIOSTABLE;
+
+ info->num_chans = info_v23->vram_module[0].channel_num;
+ info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8;
+
+ return result;
+}
+
+static enum bp_result get_vram_info_v24(
+ struct bios_parser *bp,
+ struct dc_vram_info *info)
+{
+ struct atom_vram_info_header_v2_4 *info_v24;
+ enum bp_result result = BP_RESULT_OK;
+
+ info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
+ DATA_TABLES(vram_info));
+
+ if (info_v24 == NULL)
+ return BP_RESULT_BADBIOSTABLE;
+
+ info->num_chans = info_v24->vram_module[0].channel_num;
+ info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8;
+
+ return result;
+}
+
+static enum bp_result get_vram_info_v25(
+ struct bios_parser *bp,
+ struct dc_vram_info *info)
+{
+ struct atom_vram_info_header_v2_5 *info_v25;
+ enum bp_result result = BP_RESULT_OK;
+
+ info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
+ DATA_TABLES(vram_info));
+
+ if (info_v25 == NULL)
+ return BP_RESULT_BADBIOSTABLE;
+
+ info->num_chans = info_v25->vram_module[0].channel_num;
+ info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8;
+
+ return result;
+}
+
/*
* get_integrated_info_v11
*
@@ -1666,6 +1726,46 @@ static enum bp_result construct_integrated_info(
return result;
}
+static enum bp_result bios_parser_get_vram_info(
+ struct dc_bios *dcb,
+ struct dc_vram_info *info)
+{
+ struct bios_parser *bp = BP_FROM_DCB(dcb);
+ enum bp_result result = BP_RESULT_BADBIOSTABLE;
+ struct atom_common_table_header *header;
+ struct atom_data_revision revision;
+
+ if (info && DATA_TABLES(vram_info)) {
+ header = GET_IMAGE(struct atom_common_table_header,
+ DATA_TABLES(vram_info));
+
+ get_atom_data_table_revision(header, &revision);
+
+ switch (revision.major) {
+ case 2:
+ switch (revision.minor) {
+ case 3:
+ result = get_vram_info_v23(bp, info);
+ break;
+ case 4:
+ result = get_vram_info_v24(bp, info);
+ break;
+ case 5:
+ result = get_vram_info_v25(bp, info);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ return result;
+ }
+
+ }
+ return result;
+}
+
static struct integrated_info *bios_parser_create_integrated_info(
struct dc_bios *dcb)
{
@@ -1877,6 +1977,108 @@ static enum bp_result bios_get_board_layout_info(
return BP_RESULT_OK;
}
+
+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;
+}
+
static const struct dc_vbios_funcs vbios_funcs = {
.get_connectors_number = bios_parser_get_connectors_number,
@@ -1925,6 +2127,7 @@ static const struct dc_vbios_funcs vbios_funcs = {
.bios_parser_destroy = firmware_parser_destroy,
.get_board_layout_info = bios_get_board_layout_info,
+ .pack_data_tables = bios_parser_pack_data_tables,
};
static bool bios_parser2_construct(
@@ -2006,6 +2209,7 @@ static bool bios_parser2_construct(
bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
+ bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);
return true;
}
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
index 204d7942a6e5..21ff6b686f5f 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
@@ -65,6 +65,11 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
*h = dal_cmd_tbl_helper_dce112_get_table2();
return true;
#endif
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+ case DCN_VERSION_3_0:
+ *h = dal_cmd_tbl_helper_dce112_get_table2();
+ return true;
+#endif
default:
/* Unsupported DCE */
diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
index 755b6e33140a..bf0affef893f 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c
@@ -388,3 +388,43 @@ const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void)
{
return &command_table_helper_funcs;
}
+
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+/* function table */
+static const struct command_table_helper command_table_helper_funcs_dcn2x = {
+ .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom2,
+ .encoder_action_to_atom = encoder_action_to_atom,
+ .engine_bp_to_atom = engine_bp_to_atom,
+ .clock_source_id_to_atom = clock_source_id_to_atom,
+ .clock_source_id_to_atom_phy_clk_src_id =
+ clock_source_id_to_atom_phy_clk_src_id,
+ .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
+ .hpd_sel_to_atom = hpd_sel_to_atom,
+ .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
+ .phy_id_to_atom = phy_id_to_atom,
+ .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
+ .clock_source_id_to_ref_clk_src = NULL,
+ .transmitter_bp_to_atom = NULL,
+ .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom2,
+ .encoder_mode_bp_to_atom =
+ dal_cmd_table_helper_encoder_mode_bp_to_atom2,
+ .dc_clock_type_to_atom = dc_clock_type_to_atom,
+ .transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
+
+};
+
+/*
+ * dal_cmd_tbl_helper_dce110_get_table
+ *
+ * @brief
+ * Initialize command table helper functions
+ *
+ * @param
+ * const struct command_table_helper **h - [out] struct of functions
+ *
+ */
+const struct command_table_helper *dal_cmd_tbl_helper_dcn2_get_table2(void)
+{
+ return &command_table_helper_funcs_dcn2x;
+}
+#endif
diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h
index abf28a06f5bc..2d9e9f3c579d 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h
+++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h
@@ -30,5 +30,8 @@ struct command_table_helper;
/* Initialize command table helper functions */
const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void);
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+const struct command_table_helper *dal_cmd_tbl_helper_dcn2_get_table2(void);
+#endif
#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */