mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-05 06:08:22 +00:00
drm/amd/display: Make DMCUB bss/data firmware blob optional
[Why] By moving everything out of .data into the other regions we can drop the requirement for the second blob and unify it all into the inst/const blob. [How] We need to still support the blob being there and not being there for backwards compatibility. Look for the DMCUB metadata section in the end of the inst/const blob instead of bss/data is missing. Clear CW2 if we don't have the data blob so we don't hang when transitioning between data blob/blobless firmwares. Don't memcpy the blob into CW2 region if it doesn't exist. Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@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
8ccf0e2076
commit
a576b345f9
4 changed files with 40 additions and 15 deletions
|
@ -825,8 +825,9 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
|
|||
fw_inst_const_size);
|
||||
}
|
||||
|
||||
memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr, fw_bss_data,
|
||||
fw_bss_data_size);
|
||||
if (fw_bss_data_size)
|
||||
memcpy(fb_info->fb[DMUB_WINDOW_2_BSS_DATA].cpu_addr,
|
||||
fw_bss_data, fw_bss_data_size);
|
||||
|
||||
/* Copy firmware bios info into FB memory. */
|
||||
memcpy(fb_info->fb[DMUB_WINDOW_3_VBIOS].cpu_addr, adev->bios,
|
||||
|
@ -1265,6 +1266,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
|
|||
adev->dm.dmub_fw->data +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
|
||||
le32_to_cpu(hdr->inst_const_bytes);
|
||||
region_params.fw_inst_const =
|
||||
adev->dm.dmub_fw->data +
|
||||
le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
|
||||
PSP_HEADER_BYTES;
|
||||
|
||||
status = dmub_srv_calc_region_info(dmub_srv, ®ion_params,
|
||||
®ion_info);
|
||||
|
|
|
@ -151,6 +151,7 @@ struct dmub_srv_region_params {
|
|||
uint32_t inst_const_size;
|
||||
uint32_t bss_data_size;
|
||||
uint32_t vbios_size;
|
||||
const uint8_t *fw_inst_const;
|
||||
const uint8_t *fw_bss_data;
|
||||
};
|
||||
|
||||
|
|
|
@ -186,14 +186,22 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub,
|
|||
|
||||
dmub_dcn20_get_fb_base_offset(dmub, &fb_base, &fb_offset);
|
||||
|
||||
dmub_dcn20_translate_addr(&cw2->offset, fb_base, fb_offset, &offset);
|
||||
if (cw2->region.base != cw2->region.top) {
|
||||
dmub_dcn20_translate_addr(&cw2->offset, fb_base, fb_offset,
|
||||
&offset);
|
||||
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET, offset.u.low_part);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, offset.u.high_part);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, cw2->region.base);
|
||||
REG_SET_2(DMCUB_REGION3_CW2_TOP_ADDRESS, 0,
|
||||
DMCUB_REGION3_CW2_TOP_ADDRESS, cw2->region.top,
|
||||
DMCUB_REGION3_CW2_ENABLE, 1);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET, offset.u.low_part);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, offset.u.high_part);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, cw2->region.base);
|
||||
REG_SET_2(DMCUB_REGION3_CW2_TOP_ADDRESS, 0,
|
||||
DMCUB_REGION3_CW2_TOP_ADDRESS, cw2->region.top,
|
||||
DMCUB_REGION3_CW2_ENABLE, 1);
|
||||
} else {
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET, 0);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_OFFSET_HIGH, 0);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_BASE_ADDRESS, 0);
|
||||
REG_WRITE(DMCUB_REGION3_CW2_TOP_ADDRESS, 0);
|
||||
}
|
||||
|
||||
dmub_dcn20_translate_addr(&cw3->offset, fb_base, fb_offset, &offset);
|
||||
|
||||
|
|
|
@ -91,17 +91,29 @@ void dmub_flush_buffer_mem(const struct dmub_fb *fb)
|
|||
}
|
||||
|
||||
static const struct dmub_fw_meta_info *
|
||||
dmub_get_fw_meta_info(const uint8_t *fw_bss_data, uint32_t fw_bss_data_size)
|
||||
dmub_get_fw_meta_info(const struct dmub_srv_region_params *params)
|
||||
{
|
||||
const union dmub_fw_meta *meta;
|
||||
const uint8_t *blob = NULL;
|
||||
uint32_t blob_size = 0;
|
||||
|
||||
if (fw_bss_data == NULL)
|
||||
if (params->fw_bss_data) {
|
||||
/* Legacy metadata region. */
|
||||
blob = params->fw_bss_data;
|
||||
blob_size = params->bss_data_size;
|
||||
} else if (params->fw_inst_const) {
|
||||
/* Combined metadata region. */
|
||||
blob = params->fw_inst_const;
|
||||
blob_size = params->inst_const_size;
|
||||
}
|
||||
|
||||
if (!blob || !blob_size)
|
||||
return NULL;
|
||||
|
||||
if (fw_bss_data_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET)
|
||||
if (blob_size < sizeof(union dmub_fw_meta) + DMUB_FW_META_OFFSET)
|
||||
return NULL;
|
||||
|
||||
meta = (const union dmub_fw_meta *)(fw_bss_data + fw_bss_data_size -
|
||||
meta = (const union dmub_fw_meta *)(blob + blob_size -
|
||||
DMUB_FW_META_OFFSET -
|
||||
sizeof(union dmub_fw_meta));
|
||||
|
||||
|
@ -247,8 +259,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
|
|||
mail->base = dmub_align(bios->top, 256);
|
||||
mail->top = mail->base + DMUB_MAILBOX_SIZE;
|
||||
|
||||
fw_info = dmub_get_fw_meta_info(params->fw_bss_data,
|
||||
params->bss_data_size);
|
||||
fw_info = dmub_get_fw_meta_info(params);
|
||||
|
||||
if (fw_info) {
|
||||
fw_state_size = fw_info->fw_region_size;
|
||||
|
|
Loading…
Add table
Reference in a new issue