Commit 624e0d7f authored by Fudongwang's avatar Fudongwang Committed by Alex Deucher

drm/amd/display: Add GART memory support for dmcub

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

[How]
Add GART memory support for dmcub.
Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: default avatarRoman Li <roman.li@amd.com>
Signed-off-by: default avatarFudongwang <fudong.wang@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8457bddc
...@@ -2121,6 +2121,16 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) ...@@ -2121,6 +2121,16 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
const struct dmcub_firmware_header_v1_0 *hdr; const struct dmcub_firmware_header_v1_0 *hdr;
enum dmub_asic dmub_asic; enum dmub_asic dmub_asic;
enum dmub_status status; 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; int r;
switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) { switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
...@@ -2218,7 +2228,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) ...@@ -2218,7 +2228,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; region_params.window_memory_type = window_memory_type;
status = dmub_srv_calc_region_info(dmub_srv, &region_params, status = dmub_srv_calc_region_info(dmub_srv, &region_params,
&region_info); &region_info);
...@@ -2246,6 +2256,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) ...@@ -2246,6 +2256,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr; memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr;
memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr; memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr;
memory_params.region_info = &region_info; memory_params.region_info = &region_info;
memory_params.window_memory_type = window_memory_type;
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);
......
...@@ -78,6 +78,16 @@ struct dmub_srv_dcn31_regs; ...@@ -78,6 +78,16 @@ struct dmub_srv_dcn31_regs;
struct dmcub_trace_buf_entry; 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 - return code for dmcub functions */
enum dmub_status { enum dmub_status {
DMUB_STATUS_OK = 0, DMUB_STATUS_OK = 0,
...@@ -203,7 +213,7 @@ struct dmub_srv_region_params { ...@@ -203,7 +213,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; const enum dmub_window_memory_type *window_memory_type;
}; };
/** /**
...@@ -223,7 +233,7 @@ struct dmub_srv_region_params { ...@@ -223,7 +233,7 @@ 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; uint32_t gart_size;
uint8_t num_regions; uint8_t num_regions;
struct dmub_region regions[DMUB_WINDOW_TOTAL]; struct dmub_region regions[DMUB_WINDOW_TOTAL];
}; };
...@@ -239,9 +249,10 @@ struct dmub_srv_region_info { ...@@ -239,9 +249,10 @@ struct dmub_srv_region_info {
struct dmub_srv_memory_params { struct dmub_srv_memory_params {
const struct dmub_srv_region_info *region_info; const struct dmub_srv_region_info *region_info;
void *cpu_fb_addr; void *cpu_fb_addr;
void *cpu_inbox_addr; void *cpu_gart_addr;
uint64_t gpu_fb_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;
}; };
/** /**
......
...@@ -417,58 +417,44 @@ void dmub_srv_destroy(struct dmub_srv *dmub) ...@@ -417,58 +417,44 @@ void dmub_srv_destroy(struct dmub_srv *dmub)
dmub_memset(dmub, 0, sizeof(*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 enum dmub_status
dmub_srv_calc_region_info(struct dmub_srv *dmub, dmub_srv_calc_region_info(struct dmub_srv *dmub,
const struct dmub_srv_region_params *params, const struct dmub_srv_region_params *params,
struct dmub_srv_region_info *out) 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; const struct dmub_fw_meta_info *fw_info;
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 window_sizes[DMUB_WINDOW_TOTAL] = { 0 };
uint32_t previous_top = 0;
if (!dmub->sw_init) if (!dmub->sw_init)
return DMUB_STATUS_INVALID; return DMUB_STATUS_INVALID;
memset(out, 0, sizeof(*out)); memset(out, 0, sizeof(*out));
memset(window_sizes, 0, sizeof(window_sizes));
out->num_regions = DMUB_NUM_WINDOWS; 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); fw_info = dmub_get_fw_meta_info(params);
if (fw_info) { if (fw_info) {
...@@ -486,19 +472,20 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, ...@@ -486,19 +472,20 @@ 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(previous_top, 256); window_sizes[DMUB_WINDOW_0_INST_CONST] = params->inst_const_size;
trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64); 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); out->fb_size =
fw_state->top = fw_state->base + dmub_align(fw_state_size, 64); 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); out->gart_size =
scratch_mem->top = scratch_mem->base + dmub_align(scratch_mem_size, 64); dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_GART);
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;
} }
...@@ -507,8 +494,6 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, ...@@ -507,8 +494,6 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
const struct dmub_srv_memory_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;
uint64_t gpu_base;
uint32_t i; uint32_t i;
if (!dmub->sw_init) if (!dmub->sw_init)
...@@ -519,19 +504,16 @@ enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, ...@@ -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) if (params->region_info->num_regions != DMUB_NUM_WINDOWS)
return DMUB_STATUS_INVALID; 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) { for (i = 0; i < DMUB_NUM_WINDOWS; ++i) {
const struct dmub_region *reg = const struct dmub_region *reg =
&params->region_info->regions[i]; &params->region_info->regions[i];
out->fb[i].cpu_addr = cpu_base + reg->base; if (params->window_memory_type[i] == DMUB_WINDOW_MEMORY_TYPE_GART) {
out->fb[i].gpu_addr = gpu_base + reg->base; out->fb[i].cpu_addr = (uint8_t *)params->cpu_gart_addr + reg->base;
out->fb[i].gpu_addr = params->gpu_gart_addr + reg->base;
if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) { } else {
out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base; out->fb[i].cpu_addr = (uint8_t *)params->cpu_fb_addr + reg->base;
out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base; out->fb[i].gpu_addr = params->gpu_fb_addr + reg->base;
} }
out->fb[i].size = reg->top - reg->base; out->fb[i].size = reg->top - reg->base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment