Commit 2847642a authored by Jake Wang's avatar Jake Wang Committed by Alex Deucher

drm/amd/display: vbios data table packing

[WHY]
Currently we're copying the entire bios image into vbios.  Loading time
for FW with entire bios(54272 bytes) is 105138us.  By copying only the
sections of bios we're using(4436 bytes), loading time drops to 104326us
which saves us 812us.

[HOW]
ROM header, master data table, and all data tables will be packed in
contiguous manner. The offsets for the data tables are remapped to their
newly packed location.
Signed-off-by: default avatarJake Wang <haonan.wang2@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fb8cf277
...@@ -1877,6 +1877,103 @@ static enum bp_result bios_get_board_layout_info( ...@@ -1877,6 +1877,103 @@ static enum bp_result bios_get_board_layout_info(
return BP_RESULT_OK; return BP_RESULT_OK;
} }
static uint16_t bios_parser_pack_data_tables(
struct dc_bios *dcb,
void *dst)
{
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;
}
static const struct dc_vbios_funcs vbios_funcs = { static const struct dc_vbios_funcs vbios_funcs = {
.get_connectors_number = bios_parser_get_connectors_number, .get_connectors_number = bios_parser_get_connectors_number,
...@@ -1925,6 +2022,7 @@ static const struct dc_vbios_funcs vbios_funcs = { ...@@ -1925,6 +2022,7 @@ static const struct dc_vbios_funcs vbios_funcs = {
.bios_parser_destroy = firmware_parser_destroy, .bios_parser_destroy = firmware_parser_destroy,
.get_board_layout_info = bios_get_board_layout_info, .get_board_layout_info = bios_get_board_layout_info,
.pack_data_tables = bios_parser_pack_data_tables,
}; };
static bool bios_parser2_construct( static bool bios_parser2_construct(
......
...@@ -89,7 +89,6 @@ struct dc_vbios_funcs { ...@@ -89,7 +89,6 @@ struct dc_vbios_funcs {
bool (*is_device_id_supported)( bool (*is_device_id_supported)(
struct dc_bios *bios, struct dc_bios *bios,
struct device_id id); struct device_id id);
/* COMMANDS */ /* COMMANDS */
enum bp_result (*encoder_control)( enum bp_result (*encoder_control)(
...@@ -131,6 +130,9 @@ struct dc_vbios_funcs { ...@@ -131,6 +130,9 @@ struct dc_vbios_funcs {
enum bp_result (*get_board_layout_info)( enum bp_result (*get_board_layout_info)(
struct dc_bios *dcb, struct dc_bios *dcb,
struct board_layout_info *board_layout_info); struct board_layout_info *board_layout_info);
uint16_t (*pack_data_tables)(
struct dc_bios *dcb,
void *dst);
}; };
struct bios_registers { struct bios_registers {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment