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: Jake Wang <haonan.wang2@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
fb8cf277b1
commit
2847642a18
|
@ -1877,6 +1877,103 @@ 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)
|
||||
{
|
||||
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 = {
|
||||
.get_connectors_number = bios_parser_get_connectors_number,
|
||||
|
||||
|
@ -1925,6 +2022,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(
|
||||
|
|
|
@ -89,7 +89,6 @@ struct dc_vbios_funcs {
|
|||
bool (*is_device_id_supported)(
|
||||
struct dc_bios *bios,
|
||||
struct device_id id);
|
||||
|
||||
/* COMMANDS */
|
||||
|
||||
enum bp_result (*encoder_control)(
|
||||
|
@ -131,6 +130,9 @@ struct dc_vbios_funcs {
|
|||
enum bp_result (*get_board_layout_info)(
|
||||
struct dc_bios *dcb,
|
||||
struct board_layout_info *board_layout_info);
|
||||
uint16_t (*pack_data_tables)(
|
||||
struct dc_bios *dcb,
|
||||
void *dst);
|
||||
};
|
||||
|
||||
struct bios_registers {
|
||||
|
|
Loading…
Reference in New Issue