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:
parent
9ddea8c977
commit
5911d02cac
@ -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, ®ion_params,
|
status = dmub_srv_calc_region_info(dmub_srv, ®ion_params,
|
||||||
®ion_info);
|
®ion_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 = ®ion_info;
|
memory_params.region_info = ®ion_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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user