diff options
author | Jun Lei <Jun.Lei@amd.com> | 2019-05-13 15:09:13 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-06-22 09:34:13 -0500 |
commit | 3979efcec6272848fca96496c53096f6ee8aa32f (patch) | |
tree | d08bfb3831bd99ddd98cf425d948e2709e8cbcdd | |
parent | a746a2585542179bf9ec37c5243a10a6490ba41d (diff) | |
download | linux-3979efcec6272848fca96496c53096f6ee8aa32f.tar.bz2 |
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: Jun Lei <Jun.Lei@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 5 |
2 files changed, 65 insertions, 17 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c index a851574f118a..724f1c5ef614 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c @@ -303,6 +303,49 @@ void hubbub2_setup_vmid_ptb(struct hubbub *hubbub, 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, struct hubbub_addr_config *config) @@ -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 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, FB_BASE, config->pa_config.system_aperture.fb_base); REG_SET(DCN_VM_FB_LOCATION_TOP, 0, @@ -330,18 +368,27 @@ void hubbub2_init_dchub(struct hubbub *hubbub, REG_SET(DCN_VM_AGP_BASE, 0, AGP_BASE, config->pa_config.system_aperture.agp_base); - // Init VMID 0 based on PA 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); + 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 1-15 based on VA config - for (i = 1; i < 16; i++) { - virt_config.page_table_start_addr = config->va_config.page_table_start_addr; - virt_config.page_table_end_addr = config->va_config.page_table_end_addr; - virt_config.depth = config->va_config.page_table_depth; - virt_config.block_size = config->va_config.page_table_block_size; + // Init VMID 0 based on PA 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); + } + + if (config->va_config.page_table_start_addr != config->va_config.page_table_end_addr) { + // Init VMID 1-15 based on VA config + for (i = 1; i < 16; i++) { + 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 >> 12; + virt_config.depth = page_table_depth_to_hw(config->va_config.page_table_depth); + 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); + } } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 914071393d1c..2cbffe2809b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.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, pipe_ctx->pipe_idx); - // Call hubbub to program PTB of VMID - if (dc->res_pool->hubbub->funcs->setup_vmid_ptb) + // Call hubbub to program PTB of VMID only if its VA + // 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, plane_state->address.page_table_base.quad_part, vmid); |