Commit 3979efce authored by Jun Lei's avatar Jun Lei Committed by Alex Deucher

drm/amd/display: Add missing VM conversion from hw values

[why]
VM implemenation is missing conversion from HW values in hubbub
DM not passing actual PTB during flip

[how]
add proper HW conversion from logical values
fix cases where we programmed VA even though we are in PA
plumb in PTB from DM
Signed-off-by: default avatarJun Lei <Jun.Lei@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a746a258
...@@ -303,6 +303,49 @@ void hubbub2_setup_vmid_ptb(struct hubbub *hubbub, ...@@ -303,6 +303,49 @@ void hubbub2_setup_vmid_ptb(struct hubbub *hubbub,
dcn20_vmid_set_ptb(&hubbub1->vmid[vmid], ptb); dcn20_vmid_set_ptb(&hubbub1->vmid[vmid], ptb);
} }
static enum dcn_hubbub_page_table_depth page_table_depth_to_hw(unsigned int page_table_depth)
{
enum dcn_hubbub_page_table_depth depth = 0;
switch (page_table_depth) {
case 1:
depth = DCN_PAGE_TABLE_DEPTH_1_LEVEL;
break;
case 2:
depth = DCN_PAGE_TABLE_DEPTH_2_LEVEL;
break;
case 3:
depth = DCN_PAGE_TABLE_DEPTH_3_LEVEL;
break;
case 4:
depth = DCN_PAGE_TABLE_DEPTH_4_LEVEL;
break;
default:
ASSERT(false);
break;
}
return depth;
}
static enum dcn_hubbub_page_table_block_size page_table_block_size_to_hw(unsigned int page_table_block_size)
{
enum dcn_hubbub_page_table_block_size block_size = 0;
switch (page_table_block_size) {
case 4096:
block_size = DCN_PAGE_TABLE_BLOCK_SIZE_4KB;
break;
case 65536:
block_size = DCN_PAGE_TABLE_BLOCK_SIZE_64KB;
break;
default:
ASSERT(false);
break;
}
return block_size;
}
void hubbub2_init_dchub(struct hubbub *hubbub, void hubbub2_init_dchub(struct hubbub *hubbub,
struct hubbub_addr_config *config) struct hubbub_addr_config *config)
...@@ -312,11 +355,6 @@ void hubbub2_init_dchub(struct hubbub *hubbub, ...@@ -312,11 +355,6 @@ void hubbub2_init_dchub(struct hubbub *hubbub,
struct dcn_vmid_page_table_config phys_config; struct dcn_vmid_page_table_config phys_config;
struct dcn_vmid_page_table_config virt_config; struct dcn_vmid_page_table_config virt_config;
phys_config.depth = 0; // Depth 1
phys_config.block_size = 0; // Block size 4KB
phys_config.page_table_start_addr = config->pa_config.gart_config.page_table_start_addr;
phys_config.page_table_end_addr = config->pa_config.gart_config.page_table_end_addr;
REG_SET(DCN_VM_FB_LOCATION_BASE, 0, REG_SET(DCN_VM_FB_LOCATION_BASE, 0,
FB_BASE, config->pa_config.system_aperture.fb_base); FB_BASE, config->pa_config.system_aperture.fb_base);
REG_SET(DCN_VM_FB_LOCATION_TOP, 0, REG_SET(DCN_VM_FB_LOCATION_TOP, 0,
...@@ -330,19 +368,28 @@ void hubbub2_init_dchub(struct hubbub *hubbub, ...@@ -330,19 +368,28 @@ void hubbub2_init_dchub(struct hubbub *hubbub,
REG_SET(DCN_VM_AGP_BASE, 0, REG_SET(DCN_VM_AGP_BASE, 0,
AGP_BASE, config->pa_config.system_aperture.agp_base); AGP_BASE, config->pa_config.system_aperture.agp_base);
if (config->pa_config.gart_config.page_table_start_addr != config->pa_config.gart_config.page_table_end_addr) {
phys_config.depth = 1;
phys_config.block_size = 4096;
phys_config.page_table_start_addr = config->pa_config.gart_config.page_table_start_addr >> 12;
phys_config.page_table_end_addr = config->pa_config.gart_config.page_table_end_addr >> 12;
// Init VMID 0 based on PA config // Init VMID 0 based on PA config
dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config); dcn20_vmid_setup(&hubbub1->vmid[0], &phys_config);
dcn20_vmid_set_ptb(&hubbub1->vmid[0], config->pa_config.gart_config.page_table_base_addr); dcn20_vmid_set_ptb(&hubbub1->vmid[0], config->pa_config.gart_config.page_table_base_addr);
}
if (config->va_config.page_table_start_addr != config->va_config.page_table_end_addr) {
// Init VMID 1-15 based on VA config // Init VMID 1-15 based on VA config
for (i = 1; i < 16; i++) { for (i = 1; i < 16; i++) {
virt_config.page_table_start_addr = config->va_config.page_table_start_addr; virt_config.page_table_start_addr = config->va_config.page_table_start_addr >> 12;
virt_config.page_table_end_addr = config->va_config.page_table_end_addr; virt_config.page_table_end_addr = config->va_config.page_table_end_addr >> 12;
virt_config.depth = config->va_config.page_table_depth; virt_config.depth = page_table_depth_to_hw(config->va_config.page_table_depth);
virt_config.block_size = config->va_config.page_table_block_size; virt_config.block_size = page_table_block_size_to_hw(config->va_config.page_table_block_size);
dcn20_vmid_setup(&hubbub1->vmid[i], &virt_config); dcn20_vmid_setup(&hubbub1->vmid[i], &virt_config);
} }
}
} }
void hubbub2_update_dchub(struct hubbub *hubbub, void hubbub2_update_dchub(struct hubbub *hubbub,
......
...@@ -1631,8 +1631,9 @@ static void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c ...@@ -1631,8 +1631,9 @@ static void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_c
plane_state->address.page_table_base.quad_part, plane_state->address.page_table_base.quad_part,
pipe_ctx->pipe_idx); pipe_ctx->pipe_idx);
// Call hubbub to program PTB of VMID // Call hubbub to program PTB of VMID only if its VA
if (dc->res_pool->hubbub->funcs->setup_vmid_ptb) // PA PTB is a one-time setup at init
if (vmid > 0 && dc->res_pool->hubbub->funcs->setup_vmid_ptb)
dc->res_pool->hubbub->funcs->setup_vmid_ptb(dc->res_pool->hubbub, dc->res_pool->hubbub->funcs->setup_vmid_ptb(dc->res_pool->hubbub,
plane_state->address.page_table_base.quad_part, plane_state->address.page_table_base.quad_part,
vmid); vmid);
......
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