summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDillon Varone <Dillon.Varone@amd.com>2026-06-23 15:42:34 -0400
committerAlex Deucher <alexander.deucher@amd.com>2026-07-14 19:12:34 -0400
commit5b69770e945caa1bef6c4848bb279ec09d3e9d4f (patch)
treed5df456321fecdb5e760cf9bb77dd63fe9a22a32
parentb48b1cad84609ed422f8d4086205cc06d425487e (diff)
drm/amd/display: Generalize DMUB memory flushes from host
[WHY&HOW] Add DMUB service context to aid in platform abstraction when flushing memory from the host. Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Signed-off-by: Dillon Varone <Dillon.Varone@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c4
-rw-r--r--drivers/gpu/drm/amd/display/dmub/dmub_srv.h9
-rw-r--r--drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c55
5 files changed, 46 insertions, 31 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c
index 2692d1890ba2..00ea0dbd0f3f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_dmub.c
@@ -147,7 +147,7 @@ int dm_dmub_hw_init(struct amdgpu_device *adev)
struct dmub_srv_hw_params hw_params;
enum dmub_status status;
const unsigned char *fw_inst_const, *fw_bss_data;
- u32 i, fw_inst_const_size, fw_bss_data_size;
+ u32 fw_inst_const_size, fw_bss_data_size;
bool has_hw_support;
if (!dmub_srv)
@@ -243,8 +243,7 @@ int dm_dmub_hw_init(struct amdgpu_device *adev)
if (dmcu)
hw_params.psp_version = dmcu->psp_version;
- for (i = 0; i < fb_info->num_fb; ++i)
- hw_params.fb[i] = &fb_info->fb[i];
+ hw_params.fb_info = fb_info;
/* Enable usb4 dpia in the FW APU */
if (dc->caps.is_apu &&
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 68ed0e16639d..80a21d7cae90 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -1908,6 +1908,8 @@ static void dc_dmub_srv_ib_based_fams2_update_config(struct dc *dc,
config->global.features.bits.enable = enable && context->bw_ctx.bw.dcn.fams2_global_config.features.bits.enable;
config->global.features.bits.enable_ppt_check = dc->debug.fams2_config.bits.enable_ppt_check;
+ dmub_srv_flush_buffer_mem(dc->ctx->dmub_srv->dmub, &dc->ctx->dmub_srv->dmub->ib_mem_gart);
+
dm_execute_dmub_cmd_list(dc->ctx, 1, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
@@ -2073,7 +2075,7 @@ bool dc_dmub_srv_ips_query_residency_info(const struct dc_context *ctx, uint8_t
union dmub_rb_cmd cmd;
uint32_t bytes = sizeof(struct dmub_ips_residency_info);
- dmub_flush_buffer_mem(&ctx->dmub_srv->dmub->scratch_mem_fb);
+ dmub_srv_flush_buffer_mem(ctx->dmub_srv->dmub, &ctx->dmub_srv->dmub->scratch_mem_fb);
memset(&cmd, 0, sizeof(cmd));
cmd.ips_query_residency_info.header.type = DMUB_CMD__IPS;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
index 2f4d368bd3fd..f60e43ba6060 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
@@ -166,7 +166,7 @@ void dmub_abm_init_config(struct abm *abm,
uint8_t panel_mask = 0x01 << inst;
// TODO: Optimize by only reading back final 4 bytes
- dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
+ dmub_srv_flush_buffer_mem(dc->dmub_srv->dmub, &dc->dmub_srv->dmub->scratch_mem_fb);
// Copy iramtable into cw7
memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
@@ -227,7 +227,7 @@ bool dmub_abm_save_restore(
unsigned int bytes = sizeof(struct abm_save_restore);
// TODO: Optimize by only reading back final 4 bytes
- dmub_flush_buffer_mem(&dc->dmub_srv->dmub->scratch_mem_fb);
+ dmub_srv_flush_buffer_mem(dc->dmub_srv->dmub, &dc->dmub_srv->dmub->scratch_mem_fb);
// Copy iramtable into cw7
memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)pData, bytes);
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index f4d05dcfef29..94d4b40ee16a 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -329,7 +329,7 @@ struct dmub_soc_fb_info {
* @load_inst_const: true if DMUB should load inst const fw
*/
struct dmub_srv_hw_params {
- struct dmub_fb *fb[DMUB_WINDOW_TOTAL];
+ struct dmub_srv_fb_info *fb_info;
struct dmub_soc_fb_info soc_fb_info;
uint32_t psp_version;
bool load_inst_const;
@@ -592,9 +592,11 @@ struct dmub_srv {
void *user_ctx;
uint32_t fw_version;
bool is_virtual;
+ bool no_ext_reg_access;
struct dmub_fb scratch_mem_fb;
struct dmub_fb ib_mem_gart;
struct dmub_fb cursor_offload_fb;
+ const struct dmub_srv_fb_info *fb_info;
volatile struct dmub_shared_state_feature_block *shared_state;
volatile struct dmub_cursor_offload_v1 *cursor_offload_v1;
volatile const struct dmub_fw_state *fw_state;
@@ -954,14 +956,15 @@ enum dmub_status dmub_srv_get_gpint_dataout(struct dmub_srv *dmub,
uint32_t *dataout);
/**
- * dmub_flush_buffer_mem() - Read back entire frame buffer region.
+ * dmub_srv_flush_buffer_mem() - Read back entire frame buffer region.
* This ensures that the write from x86 has been flushed and will not
* hang the DMCUB.
+ * @dmub: the dmub service
* @fb: frame buffer to flush
*
* Can be called after software initialization.
*/
-void dmub_flush_buffer_mem(const struct dmub_fb *fb);
+void dmub_srv_flush_buffer_mem(struct dmub_srv *dmub, const struct dmub_fb *fb);
/**
* dmub_srv_get_fw_boot_status() - Returns the DMUB boot status bits.
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 7463d2ae5055..5a1a2276c432 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -96,7 +96,7 @@ static inline uint32_t dmub_align(uint32_t val, uint32_t factor)
return (val + factor - 1) / factor * factor;
}
-void dmub_flush_buffer_mem(const struct dmub_fb *fb)
+void dmub_srv_flush_buffer_mem(struct dmub_srv *dmub, const struct dmub_fb *fb)
{
const uint8_t *base = (const uint8_t *)fb->cpu_addr;
uint8_t buf[64];
@@ -114,6 +114,8 @@ void dmub_flush_buffer_mem(const struct dmub_fb *fb)
/* Read anything leftover into the buffer. */
if (end < fb->size)
dmub_memcpy(buf, base + pos, fb->size - end);
+
+ (void)dmub;
}
static const struct dmub_fw_meta_info *
@@ -748,31 +750,38 @@ enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init)
enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
const struct dmub_srv_hw_params *params)
{
- struct dmub_fb *inst_fb = params->fb[DMUB_WINDOW_0_INST_CONST];
- struct dmub_fb *stack_fb = params->fb[DMUB_WINDOW_1_STACK];
- struct dmub_fb *data_fb = params->fb[DMUB_WINDOW_2_BSS_DATA];
- struct dmub_fb *bios_fb = params->fb[DMUB_WINDOW_3_VBIOS];
- struct dmub_fb *mail_fb = params->fb[DMUB_WINDOW_4_MAILBOX];
- struct dmub_fb *tracebuff_fb = params->fb[DMUB_WINDOW_5_TRACEBUFF];
- struct dmub_fb *fw_state_fb = params->fb[DMUB_WINDOW_6_FW_STATE];
- struct dmub_fb *shared_state_fb = params->fb[DMUB_WINDOW_SHARED_STATE];
+ struct dmub_fb *inst_fb;
+ struct dmub_fb *stack_fb;
+ struct dmub_fb *data_fb;
+ struct dmub_fb *bios_fb;
+ struct dmub_fb *mail_fb;
+ struct dmub_fb *tracebuff_fb;
+ struct dmub_fb *fw_state_fb;
+ struct dmub_fb *shared_state_fb;
struct dmub_rb_init_params rb_params, outbox0_rb_params;
struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6, region6;
struct dmub_region inbox1, outbox1, outbox0;
- uint32_t i;
-
if (!dmub->sw_init)
return DMUB_STATUS_INVALID;
- for (i = 0; i < DMUB_WINDOW_TOTAL; ++i) {
- if (!params->fb[i]) {
- ASSERT(0);
- return DMUB_STATUS_INVALID;
- }
+ if (!params->fb_info || params->fb_info->num_fb < DMUB_WINDOW_TOTAL) {
+ ASSERT(0);
+ return DMUB_STATUS_INVALID;
}
+ inst_fb = &params->fb_info->fb[DMUB_WINDOW_0_INST_CONST];
+ stack_fb = &params->fb_info->fb[DMUB_WINDOW_1_STACK];
+ data_fb = &params->fb_info->fb[DMUB_WINDOW_2_BSS_DATA];
+ bios_fb = &params->fb_info->fb[DMUB_WINDOW_3_VBIOS];
+ mail_fb = &params->fb_info->fb[DMUB_WINDOW_4_MAILBOX];
+ tracebuff_fb = &params->fb_info->fb[DMUB_WINDOW_5_TRACEBUFF];
+ fw_state_fb = &params->fb_info->fb[DMUB_WINDOW_6_FW_STATE];
+ shared_state_fb = &params->fb_info->fb[DMUB_WINDOW_SHARED_STATE];
+
+ dmub->fb_info = params->fb_info;
+
memcpy(&dmub->soc_fb_info, &params->soc_fb_info, sizeof(params->soc_fb_info));
dmub->psp_version = params->psp_version;
@@ -800,7 +809,7 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
* flushed yet. This only occurs in backdoor loading.
*/
if (params->mem_access_type == DMUB_MEMORY_ACCESS_CPU)
- dmub_flush_buffer_mem(inst_fb);
+ dmub_srv_flush_buffer_mem(dmub, inst_fb);
if (params->fw_in_system_memory && dmub->hw_funcs.backdoor_load_zfb_mode)
dmub->hw_funcs.backdoor_load_zfb_mode(dmub, &cw0, &cw1);
@@ -851,10 +860,10 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
dmub->shared_state = shared_state_fb->cpu_addr;
- dmub->scratch_mem_fb = *params->fb[DMUB_WINDOW_7_SCRATCH_MEM];
- dmub->ib_mem_gart = *params->fb[DMUB_WINDOW_IB_MEM];
+ dmub->scratch_mem_fb = params->fb_info->fb[DMUB_WINDOW_7_SCRATCH_MEM];
+ dmub->ib_mem_gart = params->fb_info->fb[DMUB_WINDOW_IB_MEM];
- dmub->cursor_offload_fb = *params->fb[DMUB_WINDOW_CURSOR_OFFLOAD];
+ dmub->cursor_offload_fb = params->fb_info->fb[DMUB_WINDOW_CURSOR_OFFLOAD];
dmub->cursor_offload_v1 = (struct dmub_cursor_offload_v1 *)dmub->cursor_offload_fb.cpu_addr;
if (dmub->hw_funcs.setup_windows)
@@ -1014,13 +1023,14 @@ enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub,
enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
uint32_t timeout_us)
{
+ const uint32_t delay_us = 100;
uint32_t i;
bool hw_on = true;
if (!dmub->hw_init)
return DMUB_STATUS_INVALID;
- for (i = 0; i <= timeout_us; i += 100) {
+ for (i = 0; i <= timeout_us; i += delay_us) {
union dmub_fw_boot_status status = dmub->hw_funcs.get_fw_status(dmub);
if (dmub->hw_funcs.is_hw_powered_up)
@@ -1029,7 +1039,7 @@ enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
if (status.bits.dal_fw && status.bits.mailbox_rdy && hw_on)
return DMUB_STATUS_OK;
- udelay(100);
+ udelay(delay_us);
}
return DMUB_STATUS_TIMEOUT;
@@ -1258,6 +1268,7 @@ bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub)
if (!dmub || !dmub->hw_funcs.get_diagnostic_data)
return false;
dmub->hw_funcs.get_diagnostic_data(dmub);
+
return true;
}