Commit 2991f298 authored by Lewis Huang's avatar Lewis Huang Committed by Zheng Zengkai
Browse files

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

stable inclusion
from stable-v6.6.3
commit 17661e606e6d643e2e39af9470064c3d50da9834
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8LBQP

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=17661e606e6d643e2e39af9470064c3d50da9834



--------------------------------

commit 5911d02cac70d7fb52009fbd37423e63f8f6f9bc 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: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarLewis Huang <lewis.huang@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 44f5fe6f
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -2084,7 +2084,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;
@@ -2184,6 +2184,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);
@@ -2207,10 +2208,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);
@@ -2222,7 +2223,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;
+14 −8
Original line number Diff line number Diff line
@@ -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;
};

/**
@@ -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;
};

/**
@@ -546,8 +552,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);

/**
+24 −8
Original line number Diff line number Diff line
@@ -386,7 +386,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;

@@ -411,8 +411,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
	bios->base = dmub_align(stack->top, 256);
	bios->top = bios->base + params->vbios_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);

@@ -431,7 +438,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);
@@ -442,11 +449,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;
@@ -461,8 +471,8 @@ 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 =
@@ -470,6 +480,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].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;
	}