diff options
author | Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> | 2020-04-05 16:41:14 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-04-09 10:43:17 -0400 |
commit | a576b345f94ff9ab9c4006bf8317c1fbc3dee867 (patch) | |
tree | 1a9c47236f224a0413dfb0d41cf9ce2eb9da83f2 /drivers/gpu/drm/amd/display/dmub | |
parent | 8ccf0e20769d96b8d0ccbfcb56bc7ca7874154a4 (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dmub')
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c | 23 |
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h index af678462f0e6..e40d1cdbcfaa 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h @@ -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; }; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index 63bb9e2c81de..45638d61b73d 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -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); - - 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); + 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); + } 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); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 0be8a54cc475..0a1a851741c5 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -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 (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 (fw_bss_data == NULL) + 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; |