[PATCH 08/12] drm/amd/display: Add GART memory support for dmcub

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Fudongwang <fudong.wang@xxxxxxx>

[Why]
In dump file, GART memory can be accessed while frame buffer cannot.

[How]
Add GART memory support for dmcub.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@xxxxxxx>
Acked-by: Roman Li <roman.li@xxxxxxx>
Signed-off-by: Fudongwang <fudong.wang@xxxxxxx>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  13 ++-
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h   |  19 +++-
 .../gpu/drm/amd/display/dmub/src/dmub_srv.c   | 106 ++++++++----------
 3 files changed, 71 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index a9a57ba2b256..7905f5e2da05 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2120,6 +2120,16 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 	const struct dmcub_firmware_header_v1_0 *hdr;
 	enum dmub_asic dmub_asic;
 	enum dmub_status status;
+	static enum dmub_window_memory_type window_memory_type[DMUB_WINDOW_TOTAL] = {
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_0_INST_CONST
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_1_STACK
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_2_BSS_DATA
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_3_VBIOS
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_4_MAILBOX
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_5_TRACEBUFF
+		DMUB_WINDOW_MEMORY_TYPE_FB,		//DMUB_WINDOW_6_FW_STATE
+		DMUB_WINDOW_MEMORY_TYPE_FB		//DMUB_WINDOW_7_SCRATCH_MEM
+	};
 	int r;
 
 	switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
@@ -2217,7 +2227,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;
+	region_params.window_memory_type = window_memory_type;
 
 	status = dmub_srv_calc_region_info(dmub_srv, &region_params,
 					   &region_info);
@@ -2245,6 +2255,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
 	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;
+	memory_params.window_memory_type = window_memory_type;
 
 	adev->dm.dmub_fb_info =
 		kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL);
diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
index c78c9224ab60..410420683f31 100644
--- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
+++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h
@@ -78,6 +78,16 @@ struct dmub_srv_dcn31_regs;
 
 struct dmcub_trace_buf_entry;
 
+struct dmcub_inbox1_buf {
+	union dmub_rb_cmd cmd[DMUB_RB_MAX_ENTRY];
+};
+
+/* enum dmub_window_memory_type - memory location type specification for windows */
+enum dmub_window_memory_type {
+	DMUB_WINDOW_MEMORY_TYPE_FB = 0,
+	DMUB_WINDOW_MEMORY_TYPE_GART
+};
+
 /* enum dmub_status - return code for dmcub functions */
 enum dmub_status {
 	DMUB_STATUS_OK = 0,
@@ -203,7 +213,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;
+	const enum dmub_window_memory_type *window_memory_type;
 };
 
 /**
@@ -223,7 +233,7 @@ struct dmub_srv_region_params {
  */
 struct dmub_srv_region_info {
 	uint32_t fb_size;
-	uint32_t inbox_size;
+	uint32_t gart_size;
 	uint8_t num_regions;
 	struct dmub_region regions[DMUB_WINDOW_TOTAL];
 };
@@ -239,9 +249,10 @@ struct dmub_srv_region_info {
 struct dmub_srv_memory_params {
 	const struct dmub_srv_region_info *region_info;
 	void *cpu_fb_addr;
-	void *cpu_inbox_addr;
+	void *cpu_gart_addr;
 	uint64_t gpu_fb_addr;
-	uint64_t gpu_inbox_addr;
+	uint64_t gpu_gart_addr;
+	const enum dmub_window_memory_type *window_memory_type;
 };
 
 /**
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 9ad738805320..71eee58d86a1 100644
--- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
@@ -417,58 +417,44 @@ void dmub_srv_destroy(struct dmub_srv *dmub)
 	dmub_memset(dmub, 0, sizeof(*dmub));
 }
 
+static uint32_t dmub_srv_calc_regions_for_memory_type(const struct dmub_srv_region_params *params,
+	struct dmub_srv_region_info *out,
+	const uint32_t *window_sizes,
+	enum dmub_window_memory_type memory_type)
+{
+	uint32_t i, top = 0;
+
+	for (i = 0; i < DMUB_WINDOW_TOTAL; ++i) {
+		if (params->window_memory_type[i] == memory_type) {
+			struct dmub_region *region = &out->regions[i];
+
+			region->base = dmub_align(top, 256);
+			region->top = region->base + dmub_align(window_sizes[i], 64);
+			top = region->top;
+		}
+	}
+
+	return dmub_align(top, 4096);
+}
+
 enum dmub_status
-dmub_srv_calc_region_info(struct dmub_srv *dmub,
-			  const struct dmub_srv_region_params *params,
-			  struct dmub_srv_region_info *out)
+	dmub_srv_calc_region_info(struct dmub_srv *dmub,
+		const struct dmub_srv_region_params *params,
+		struct dmub_srv_region_info *out)
 {
-	struct dmub_region *inst = &out->regions[DMUB_WINDOW_0_INST_CONST];
-	struct dmub_region *stack = &out->regions[DMUB_WINDOW_1_STACK];
-	struct dmub_region *data = &out->regions[DMUB_WINDOW_2_BSS_DATA];
-	struct dmub_region *bios = &out->regions[DMUB_WINDOW_3_VBIOS];
-	struct dmub_region *mail = &out->regions[DMUB_WINDOW_4_MAILBOX];
-	struct dmub_region *trace_buff = &out->regions[DMUB_WINDOW_5_TRACEBUFF];
-	struct dmub_region *fw_state = &out->regions[DMUB_WINDOW_6_FW_STATE];
-	struct dmub_region *scratch_mem = &out->regions[DMUB_WINDOW_7_SCRATCH_MEM];
 	const struct dmub_fw_meta_info *fw_info;
 	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;
+	uint32_t window_sizes[DMUB_WINDOW_TOTAL] = { 0 };
+
 	if (!dmub->sw_init)
 		return DMUB_STATUS_INVALID;
 
 	memset(out, 0, sizeof(*out));
+	memset(window_sizes, 0, sizeof(window_sizes));
 
 	out->num_regions = DMUB_NUM_WINDOWS;
 
-	inst->base = 0x0;
-	inst->top = inst->base + params->inst_const_size;
-
-	data->base = dmub_align(inst->top, 256);
-	data->top = data->base + params->bss_data_size;
-
-	/*
-	 * All cache windows below should be aligned to the size
-	 * of the DMCUB cache line, 64 bytes.
-	 */
-
-	stack->base = dmub_align(data->top, 256);
-	stack->top = stack->base + DMUB_STACK_SIZE + DMUB_CONTEXT_SIZE;
-
-	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);
 
 	if (fw_info) {
@@ -486,19 +472,20 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub,
 			dmub->fw_version = fw_info->fw_version;
 	}
 
-	trace_buff->base = dmub_align(previous_top, 256);
-	trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64);
+	window_sizes[DMUB_WINDOW_0_INST_CONST] = params->inst_const_size;
+	window_sizes[DMUB_WINDOW_1_STACK] = DMUB_STACK_SIZE + DMUB_CONTEXT_SIZE;
+	window_sizes[DMUB_WINDOW_2_BSS_DATA] = params->bss_data_size;
+	window_sizes[DMUB_WINDOW_3_VBIOS] = params->vbios_size;
+	window_sizes[DMUB_WINDOW_4_MAILBOX] = DMUB_MAILBOX_SIZE;
+	window_sizes[DMUB_WINDOW_5_TRACEBUFF] = trace_buffer_size;
+	window_sizes[DMUB_WINDOW_6_FW_STATE] = fw_state_size;
+	window_sizes[DMUB_WINDOW_7_SCRATCH_MEM] = DMUB_SCRATCH_MEM_SIZE;
 
-	fw_state->base = dmub_align(trace_buff->top, 256);
-	fw_state->top = fw_state->base + dmub_align(fw_state_size, 64);
+	out->fb_size =
+		dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_FB);
 
-	scratch_mem->base = dmub_align(fw_state->top, 256);
-	scratch_mem->top = scratch_mem->base + dmub_align(scratch_mem_size, 64);
-
-	out->fb_size = dmub_align(scratch_mem->top, 4096);
-
-	if (params->is_mailbox_in_inbox)
-		out->inbox_size = dmub_align(mail->top, 4096);
+	out->gart_size =
+		dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_GART);
 
 	return DMUB_STATUS_OK;
 }
@@ -507,8 +494,6 @@ 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;
-	uint64_t gpu_base;
 	uint32_t i;
 
 	if (!dmub->sw_init)
@@ -519,19 +504,16 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
 	if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
 		return DMUB_STATUS_INVALID;
 
-	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;
+		if (params->window_memory_type[i] == DMUB_WINDOW_MEMORY_TYPE_GART) {
+			out->fb[i].cpu_addr = (uint8_t *)params->cpu_gart_addr + reg->base;
+			out->fb[i].gpu_addr = params->gpu_gart_addr + reg->base;
+		} else {
+			out->fb[i].cpu_addr = (uint8_t *)params->cpu_fb_addr + reg->base;
+			out->fb[i].gpu_addr = params->gpu_fb_addr + reg->base;
 		}
 
 		out->fb[i].size = reg->top - reg->base;
-- 
2.34.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux