drm/amd/display: Change the DMCUB mailbox memory location from FB to inbox

[WHY]
Flush command sent to DMCUB spends more time for execution on
a dGPU than on an APU. This causes cursor lag when using high
refresh rate mouses.

[HOW]
1. Change the DMCUB mailbox memory location from FB to inbox.
2. Only change windows memory to inbox.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Lewis Huang <lewis.huang@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Lewis Huang 2023-10-19 17:22:21 +08:00 committed by Alex Deucher
parent 9ddea8c977
commit 5911d02cac
3 changed files with 45 additions and 22 deletions

View File

@ -2079,7 +2079,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
struct dmub_srv_create_params create_params; struct dmub_srv_create_params create_params;
struct dmub_srv_region_params region_params; struct dmub_srv_region_params region_params;
struct dmub_srv_region_info region_info; struct dmub_srv_region_info region_info;
struct dmub_srv_fb_params fb_params; struct dmub_srv_memory_params memory_params;
struct dmub_srv_fb_info *fb_info; struct dmub_srv_fb_info *fb_info;
struct dmub_srv *dmub_srv; struct dmub_srv *dmub_srv;
const struct dmcub_firmware_header_v1_0 *hdr; const struct dmcub_firmware_header_v1_0 *hdr;
@ -2182,6 +2182,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
adev->dm.dmub_fw->data + adev->dm.dmub_fw->data +
le32_to_cpu(hdr->header.ucode_array_offset_bytes) + le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
PSP_HEADER_BYTES; PSP_HEADER_BYTES;
region_params.is_mailbox_in_inbox = false;
status = dmub_srv_calc_region_info(dmub_srv, &region_params, status = dmub_srv_calc_region_info(dmub_srv, &region_params,
&region_info); &region_info);
@ -2205,10 +2206,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
return r; return r;
/* Rebase the regions on the framebuffer address. */ /* Rebase the regions on the framebuffer address. */
memset(&fb_params, 0, sizeof(fb_params)); memset(&memory_params, 0, sizeof(memory_params));
fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr; memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr; memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
fb_params.region_info = &region_info; memory_params.region_info = &region_info;
adev->dm.dmub_fb_info = adev->dm.dmub_fb_info =
kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL); kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
@ -2220,7 +2221,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
return -ENOMEM; return -ENOMEM;
} }
status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info); status = dmub_srv_calc_mem_info(dmub_srv, &memory_params, fb_info);
if (status != DMUB_STATUS_OK) { if (status != DMUB_STATUS_OK) {
DRM_ERROR("Error calculating DMUB FB info: %d\n", status); DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
return -EINVAL; return -EINVAL;

View File

@ -195,6 +195,7 @@ struct dmub_srv_region_params {
uint32_t vbios_size; uint32_t vbios_size;
const uint8_t *fw_inst_const; const uint8_t *fw_inst_const;
const uint8_t *fw_bss_data; const uint8_t *fw_bss_data;
bool is_mailbox_in_inbox;
}; };
/** /**
@ -214,20 +215,25 @@ struct dmub_srv_region_params {
*/ */
struct dmub_srv_region_info { struct dmub_srv_region_info {
uint32_t fb_size; uint32_t fb_size;
uint32_t inbox_size;
uint8_t num_regions; uint8_t num_regions;
struct dmub_region regions[DMUB_WINDOW_TOTAL]; struct dmub_region regions[DMUB_WINDOW_TOTAL];
}; };
/** /**
* struct dmub_srv_fb_params - parameters used for driver fb setup * struct dmub_srv_memory_params - parameters used for driver fb setup
* @region_info: region info calculated by dmub service * @region_info: region info calculated by dmub service
* @cpu_addr: base cpu address for the framebuffer * @cpu_fb_addr: base cpu address for the framebuffer
* @gpu_addr: base gpu virtual address for the framebuffer * @cpu_inbox_addr: base cpu address for the gart
* @gpu_fb_addr: base gpu virtual address for the framebuffer
* @gpu_inbox_addr: base gpu virtual address for the gart
*/ */
struct dmub_srv_fb_params { struct dmub_srv_memory_params {
const struct dmub_srv_region_info *region_info; const struct dmub_srv_region_info *region_info;
void *cpu_addr; void *cpu_fb_addr;
uint64_t gpu_addr; void *cpu_inbox_addr;
uint64_t gpu_fb_addr;
uint64_t gpu_inbox_addr;
}; };
/** /**
@ -563,8 +569,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
* DMUB_STATUS_OK - success * DMUB_STATUS_OK - success
* DMUB_STATUS_INVALID - unspecified error * DMUB_STATUS_INVALID - unspecified error
*/ */
enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
const struct dmub_srv_fb_params *params, const struct dmub_srv_memory_params *params,
struct dmub_srv_fb_info *out); struct dmub_srv_fb_info *out);
/** /**

View File

@ -434,7 +434,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
uint32_t fw_state_size = DMUB_FW_STATE_SIZE; uint32_t fw_state_size = DMUB_FW_STATE_SIZE;
uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE; uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE;
uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE; uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE;
uint32_t previous_top = 0;
if (!dmub->sw_init) if (!dmub->sw_init)
return DMUB_STATUS_INVALID; return DMUB_STATUS_INVALID;
@ -459,8 +459,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
bios->base = dmub_align(stack->top, 256); bios->base = dmub_align(stack->top, 256);
bios->top = bios->base + params->vbios_size; bios->top = bios->base + params->vbios_size;
mail->base = dmub_align(bios->top, 256); if (params->is_mailbox_in_inbox) {
mail->top = mail->base + DMUB_MAILBOX_SIZE; mail->base = 0;
mail->top = mail->base + DMUB_MAILBOX_SIZE;
previous_top = bios->top;
} else {
mail->base = dmub_align(bios->top, 256);
mail->top = mail->base + DMUB_MAILBOX_SIZE;
previous_top = mail->top;
}
fw_info = dmub_get_fw_meta_info(params); fw_info = dmub_get_fw_meta_info(params);
@ -479,7 +486,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
dmub->fw_version = fw_info->fw_version; dmub->fw_version = fw_info->fw_version;
} }
trace_buff->base = dmub_align(mail->top, 256); trace_buff->base = dmub_align(previous_top, 256);
trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64); trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64);
fw_state->base = dmub_align(trace_buff->top, 256); fw_state->base = dmub_align(trace_buff->top, 256);
@ -490,11 +497,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
out->fb_size = dmub_align(scratch_mem->top, 4096); out->fb_size = dmub_align(scratch_mem->top, 4096);
if (params->is_mailbox_in_inbox)
out->inbox_size = dmub_align(mail->top, 4096);
return DMUB_STATUS_OK; return DMUB_STATUS_OK;
} }
enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
const struct dmub_srv_fb_params *params, const struct dmub_srv_memory_params *params,
struct dmub_srv_fb_info *out) struct dmub_srv_fb_info *out)
{ {
uint8_t *cpu_base; uint8_t *cpu_base;
@ -509,8 +519,8 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
if (params->region_info->num_regions != DMUB_NUM_WINDOWS) if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
return DMUB_STATUS_INVALID; return DMUB_STATUS_INVALID;
cpu_base = (uint8_t *)params->cpu_addr; cpu_base = (uint8_t *)params->cpu_fb_addr;
gpu_base = params->gpu_addr; gpu_base = params->gpu_fb_addr;
for (i = 0; i < DMUB_NUM_WINDOWS; ++i) { for (i = 0; i < DMUB_NUM_WINDOWS; ++i) {
const struct dmub_region *reg = const struct dmub_region *reg =
@ -518,6 +528,12 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
out->fb[i].cpu_addr = cpu_base + reg->base; out->fb[i].cpu_addr = cpu_base + reg->base;
out->fb[i].gpu_addr = gpu_base + reg->base; out->fb[i].gpu_addr = gpu_base + reg->base;
if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) {
out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base;
out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base;
}
out->fb[i].size = reg->top - reg->base; out->fb[i].size = reg->top - reg->base;
} }