summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorEric Yang <Eric.Yang2@amd.com>2019-10-11 22:34:20 +0300
committerAlex Deucher <alexander.deucher@amd.com>2019-11-13 23:29:43 +0300
commit1cad8ff7ecc6b70a062b8e8b74a0cd08c928341d (patch)
treec4f8e172fc29fa1ef1821df6ae22f0589fb2deab /drivers
parent47f365645a3b4a6f094fdfab080817676bfcb417 (diff)
downloadlinux-1cad8ff7ecc6b70a062b8e8b74a0cd08c928341d.tar.xz
drm/amd/display: Renoir chroma viewport WA
[Why] For unknown reason, immediate flip with host VM translation on NV12 surface will underflow on last row of PTE. [How] Hack chroma viewport height to make fetch one more row of PTE. Note that this will cause hubp underflow on all video underlay cases, but the underflow is not user visible since it is in blank region. Signed-off-by: Eric Yang <Eric.Yang2@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c65
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c1
3 files changed, 67 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index d37818730960..5d47871ff19c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -421,6 +421,8 @@ struct dc_debug_options {
bool cm_in_bypass;
#endif
int force_clock_mode;/*every mode change.*/
+
+ bool nv12_iflip_vm_wa;
};
struct dc_debug_data {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
index 2f5a5867e674..1ddd6ae22155 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
@@ -164,6 +164,69 @@ static void hubp21_setup(
}
+void hubp21_set_viewport(
+ struct hubp *hubp,
+ const struct rect *viewport,
+ const struct rect *viewport_c)
+{
+ struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
+ int patched_viewport_height = 0;
+ struct dc_debug_options *debug = &hubp->ctx->dc->debug;
+
+ REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
+ PRI_VIEWPORT_WIDTH, viewport->width,
+ PRI_VIEWPORT_HEIGHT, viewport->height);
+
+ REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0,
+ PRI_VIEWPORT_X_START, viewport->x,
+ PRI_VIEWPORT_Y_START, viewport->y);
+
+ /*for stereo*/
+ REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0,
+ SEC_VIEWPORT_WIDTH, viewport->width,
+ SEC_VIEWPORT_HEIGHT, viewport->height);
+
+ REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0,
+ SEC_VIEWPORT_X_START, viewport->x,
+ SEC_VIEWPORT_Y_START, viewport->y);
+
+ /*
+ * Work around for underflow issue with NV12 + rIOMMU translation
+ * + immediate flip. This will cause hubp underflow, but will not
+ * be user visible since underflow is in blank region
+ */
+ patched_viewport_height = viewport_c->height;
+ if (viewport_c->height != 0 && debug->nv12_iflip_vm_wa) {
+ int pte_row_height = 0;
+ int pte_rows = 0;
+
+ REG_GET(DCHUBP_REQ_SIZE_CONFIG,
+ PTE_ROW_HEIGHT_LINEAR, &pte_row_height);
+
+ pte_row_height = 1 << (pte_row_height + 3);
+ pte_rows = (viewport_c->height + pte_row_height - 1) / pte_row_height;
+ patched_viewport_height = pte_rows * pte_row_height + 3;
+ }
+
+
+ /* DC supports NV12 only at the moment */
+ REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0,
+ PRI_VIEWPORT_WIDTH_C, viewport_c->width,
+ PRI_VIEWPORT_HEIGHT_C, patched_viewport_height);
+
+ REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
+ PRI_VIEWPORT_X_START_C, viewport_c->x,
+ PRI_VIEWPORT_Y_START_C, viewport_c->y);
+
+ REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0,
+ SEC_VIEWPORT_WIDTH_C, viewport_c->width,
+ SEC_VIEWPORT_HEIGHT_C, patched_viewport_height);
+
+ REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0,
+ SEC_VIEWPORT_X_START_C, viewport_c->x,
+ SEC_VIEWPORT_Y_START_C, viewport_c->y);
+}
+
void hubp21_set_vm_system_aperture_settings(struct hubp *hubp,
struct vm_system_aperture_param *apt)
{
@@ -211,7 +274,7 @@ static struct hubp_funcs dcn21_hubp_funcs = {
.hubp_set_vm_system_aperture_settings = hubp21_set_vm_system_aperture_settings,
.set_blank = hubp1_set_blank,
.dcc_control = hubp1_dcc_control,
- .mem_program_viewport = min_set_viewport,
+ .mem_program_viewport = hubp21_set_viewport,
.set_cursor_attributes = hubp2_cursor_set_attributes,
.set_cursor_position = hubp1_cursor_set_position,
.hubp_clk_cntl = hubp1_clk_cntl,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index 6fcfc0a643c0..44dc1d15c334 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -831,6 +831,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.scl_reset_length10 = true,
.sanity_checks = true,
.disable_48mhz_pwrdwn = false,
+ .nv12_iflip_vm_wa = true
};
static const struct dc_debug_options debug_defaults_diags = {