diff options
Diffstat (limited to 'testing/linux-amlogic/0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch')
-rw-r--r-- | testing/linux-amlogic/0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/testing/linux-amlogic/0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch b/testing/linux-amlogic/0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch new file mode 100644 index 0000000000..23d0bc366f --- /dev/null +++ b/testing/linux-amlogic/0023-drm-meson-Fix-an-Alpha-Primary-Plane-bug-on-Meson-GX.patch @@ -0,0 +1,124 @@ +From 90c2e40067b0591a1419472da186463f3f84613b Mon Sep 17 00:00:00 2001 +From: Neil Armstrong <narmstrong@baylibre.com> +Date: Thu, 22 Nov 2018 17:27:20 +0100 +Subject: [PATCH] drm/meson: Fix an Alpha Primary Plane bug on Meson GXL/GXM + SoCs + +On the Amlogic GXL & GXM SoCs, a bug occurs in the OSD1 plane when +alpha is used where the alpha is not aligned with the pixel content. + +The woraround Amlogic implemented is the reset the OSD1 plane hardware +block each time the plane is updated, solving the issue. + +In the reset, we still need to save the content of 2 registers which +depends on the status of the plane, in addition to reload the scaler +conversion matrix in the same time. + +Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> + +--- + drivers/gpu/drm/meson/meson_crtc.c | 1 + + drivers/gpu/drm/meson/meson_plane.c | 12 ++++++++++++ + drivers/gpu/drm/meson/meson_viu.c | 27 +++++++++++++++++++++++++++ + drivers/gpu/drm/meson/meson_viu.h | 1 + + 4 files changed, 41 insertions(+) + +diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c +index f8e260b..5312cce 100644 +--- a/drivers/gpu/drm/meson/meson_crtc.c ++++ b/drivers/gpu/drm/meson/meson_crtc.c +@@ -202,6 +202,7 @@ void meson_crtc_irq(struct meson_drm *priv) + + /* Update the OSD registers */ + if (priv->viu.osd1_enabled && priv->viu.osd1_commit) { ++ + writel_relaxed(priv->viu.osd1_ctrl_stat, + priv->io_base + _REG(VIU_OSD1_CTRL_STAT)); + writel_relaxed(priv->viu.osd1_blk0_cfg[0], +diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c +index 12a47b4..8372288 100644 +--- a/drivers/gpu/drm/meson/meson_plane.c ++++ b/drivers/gpu/drm/meson/meson_plane.c +@@ -79,6 +79,7 @@ + struct meson_plane { + struct drm_plane base; + struct meson_drm *priv; ++ bool enabled; + }; + #define to_meson_plane(x) container_of(x, struct meson_plane, base) + +@@ -303,6 +304,15 @@ static void meson_plane_atomic_update(struct drm_plane *plane, + priv->viu.osd1_stride = fb->pitches[0]; + priv->viu.osd1_height = fb->height; + ++ if (!meson_plane->enabled) { ++ /* Reset OSD1 at updates on GXL+ SoCs */ ++ if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") || ++ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) ++ meson_viu_reset(priv); ++ ++ meson_plane->enabled = true; ++ } ++ + spin_unlock_irqrestore(&priv->drm->event_lock, flags); + } + +@@ -316,6 +326,8 @@ static void meson_plane_atomic_disable(struct drm_plane *plane, + writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0, + priv->io_base + _REG(VPP_MISC)); + ++ meson_plane->enabled = false; ++ + } + + static const struct drm_plane_helper_funcs meson_plane_helper_funcs = { +diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c +index 2dffb98..a41dd6c 100644 +--- a/drivers/gpu/drm/meson/meson_viu.c ++++ b/drivers/gpu/drm/meson/meson_viu.c +@@ -296,6 +296,33 @@ static void meson_viu_load_matrix(struct meson_drm *priv) + true); + } + ++/* VIU OSD1 Reset as workaround for GXL+ Alpha OSD Bug */ ++void meson_viu_reset(struct meson_drm *priv) ++{ ++ uint32_t osd1_fifo_ctrl_stat, osd1_ctrl_stat2; ++ ++ /* Save these 2 registers state */ ++ osd1_fifo_ctrl_stat = readl_relaxed( ++ priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); ++ osd1_ctrl_stat2 = readl_relaxed( ++ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); ++ ++ /* Reset OSD1 */ ++ writel_bits_relaxed(BIT(0), BIT(0), ++ priv->io_base + _REG(VIU_SW_RESET)); ++ writel_bits_relaxed(BIT(0), 0, ++ priv->io_base + _REG(VIU_SW_RESET)); ++ ++ /* Rewrite these registers state lost in the reset */ ++ writel_relaxed(osd1_fifo_ctrl_stat, ++ priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT)); ++ writel_relaxed(osd1_ctrl_stat2, ++ priv->io_base + _REG(VIU_OSD1_CTRL_STAT2)); ++ ++ /* Reload the conversion matrix */ ++ meson_viu_load_matrix(priv); ++} ++ + void meson_viu_init(struct meson_drm *priv) + { + uint32_t reg; +diff --git a/drivers/gpu/drm/meson/meson_viu.h b/drivers/gpu/drm/meson/meson_viu.h +index 073b191..e4a6e2f 100644 +--- a/drivers/gpu/drm/meson/meson_viu.h ++++ b/drivers/gpu/drm/meson/meson_viu.h +@@ -59,6 +59,7 @@ + #define OSD_REPLACE_EN BIT(14) + #define OSD_REPLACE_SHIFT 6 + ++void meson_viu_reset(struct meson_drm *priv); + void meson_viu_init(struct meson_drm *priv); + + #endif /* __MESON_VIU_H */ |