Skip to content

Commit

Permalink
drm/amd/display: Change the DMCUB mailbox memory location from FB to …
Browse files Browse the repository at this point in the history
…inbox

commit 5911d02 upstream.

[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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Lewis Huang authored and gregkh committed Nov 28, 2023
1 parent 353bc38 commit 7aded92
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 22 deletions.
13 changes: 7 additions & 6 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
struct dmub_srv_create_params create_params;
struct dmub_srv_region_params region_params;
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 *dmub_srv;
const struct dmcub_firmware_header_v1_0 *hdr;
Expand Down Expand Up @@ -2177,6 +2177,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
adev->dm.dmub_fw->data +
le32_to_cpu(hdr->header.ucode_array_offset_bytes) +
PSP_HEADER_BYTES;
region_params.is_mailbox_in_inbox = false;

status = dmub_srv_calc_region_info(dmub_srv, &region_params,
&region_info);
Expand All @@ -2200,10 +2201,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
return r;

/* Rebase the regions on the framebuffer address. */
memset(&fb_params, 0, sizeof(fb_params));
fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr;
fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr;
fb_params.region_info = &region_info;
memset(&memory_params, 0, sizeof(memory_params));
memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
memory_params.region_info = &region_info;

adev->dm.dmub_fb_info =
kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
Expand All @@ -2215,7 +2216,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
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) {
DRM_ERROR("Error calculating DMUB FB info: %d\n", status);
return -EINVAL;
Expand Down
22 changes: 14 additions & 8 deletions drivers/gpu/drm/amd/display/dmub/dmub_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ struct dmub_srv_region_params {
uint32_t vbios_size;
const uint8_t *fw_inst_const;
const uint8_t *fw_bss_data;
bool is_mailbox_in_inbox;
};

/**
Expand All @@ -205,20 +206,25 @@ struct dmub_srv_region_params {
*/
struct dmub_srv_region_info {
uint32_t fb_size;
uint32_t inbox_size;
uint8_t num_regions;
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
* @cpu_addr: base cpu address for the framebuffer
* @gpu_addr: base gpu virtual address for the framebuffer
* @cpu_fb_addr: base cpu 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;
void *cpu_addr;
uint64_t gpu_addr;
void *cpu_fb_addr;
void *cpu_inbox_addr;
uint64_t gpu_fb_addr;
uint64_t gpu_inbox_addr;
};

/**
Expand Down Expand Up @@ -545,8 +551,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
* DMUB_STATUS_OK - success
* DMUB_STATUS_INVALID - unspecified error
*/
enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
const struct dmub_srv_fb_params *params,
enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
const struct dmub_srv_memory_params *params,
struct dmub_srv_fb_info *out);

/**
Expand Down
32 changes: 24 additions & 8 deletions drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
uint32_t fw_state_size = DMUB_FW_STATE_SIZE;
uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE;
uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE;

uint32_t previous_top = 0;
if (!dmub->sw_init)
return DMUB_STATUS_INVALID;

Expand All @@ -410,8 +410,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
bios->base = dmub_align(stack->top, 256);
bios->top = bios->base + params->vbios_size;

mail->base = dmub_align(bios->top, 256);
mail->top = mail->base + DMUB_MAILBOX_SIZE;
if (params->is_mailbox_in_inbox) {
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);

Expand All @@ -430,7 +437,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
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);

fw_state->base = dmub_align(trace_buff->top, 256);
Expand All @@ -441,11 +448,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,

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;
}

enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
const struct dmub_srv_fb_params *params,
enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
const struct dmub_srv_memory_params *params,
struct dmub_srv_fb_info *out)
{
uint8_t *cpu_base;
Expand All @@ -460,15 +470,21 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
return DMUB_STATUS_INVALID;

cpu_base = (uint8_t *)params->cpu_addr;
gpu_base = params->gpu_addr;
cpu_base = (uint8_t *)params->cpu_fb_addr;
gpu_base = params->gpu_fb_addr;

for (i = 0; i < DMUB_NUM_WINDOWS; ++i) {
const struct dmub_region *reg =
&params->region_info->regions[i];

out->fb[i].cpu_addr = cpu_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;
}

Expand Down

0 comments on commit 7aded92

Please sign in to comment.