summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/meson/meson_plane.c2
-rw-r--r--drivers/gpu/drm/meson/meson_registers.h27
-rw-r--r--drivers/gpu/drm/meson/meson_viu.c82
3 files changed, 72 insertions, 39 deletions
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 80b8d70c4d75..b9e1e117fb85 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -328,7 +328,7 @@ static void meson_plane_atomic_disable(struct drm_plane *plane,
/* Disable OSD1 */
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
- writel_bits_relaxed(3 << 8, 0,
+ writel_bits_relaxed(VIU_OSD1_POSTBLD_SRC_OSD1, 0,
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
else
writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index ffaf04e1305b..d67f74f2883a 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -138,11 +138,19 @@
#define VIU_ADDR_START 0x1a00
#define VIU_ADDR_END 0x1aff
#define VIU_SW_RESET 0x1a01
+#define VIU_SW_RESET_OSD1 BIT(0)
#define VIU_MISC_CTRL0 0x1a06
+#define VIU_CTRL0_VD1_AFBC_MASK 0x170000
#define VIU_MISC_CTRL1 0x1a07
#define D2D3_INTF_LENGTH 0x1a08
#define D2D3_INTF_CTRL0 0x1a09
#define VIU_OSD1_CTRL_STAT 0x1a10
+#define VIU_OSD1_OSD_BLK_ENABLE BIT(0)
+#define VIU_OSD1_POSTBLD_SRC_VD1 (1 << 8)
+#define VIU_OSD1_POSTBLD_SRC_VD2 (2 << 8)
+#define VIU_OSD1_POSTBLD_SRC_OSD1 (3 << 8)
+#define VIU_OSD1_POSTBLD_SRC_OSD2 (4 << 8)
+#define VIU_OSD1_OSD_ENABLE BIT(21)
#define VIU_OSD1_CTRL_STAT2 0x1a2d
#define VIU_OSD1_COLOR_ADDR 0x1a11
#define VIU_OSD1_COLOR 0x1a12
@@ -232,6 +240,12 @@
#define VIU_OSD3_MALI_UNPACK_CTRL 0x3d9f
#define VIU_OSD3_DIMM_CTRL 0x3da0
+#define VIU_OSD_DDR_PRIORITY_URGENT BIT(0)
+#define VIU_OSD_HOLD_FIFO_LINES(lines) ((lines & 0x1f) << 5)
+#define VIU_OSD_FIFO_DEPTH_VAL(val) ((val & 0x7f) << 12)
+#define VIU_OSD_WORDS_PER_BURST(words) (((words & 0x4) >> 1) << 22)
+#define VIU_OSD_FIFO_LIMITS(size) ((size & 0xf) << 24)
+
#define VD1_IF0_GEN_REG 0x1a50
#define VD1_IF0_CANVAS0 0x1a51
#define VD1_IF0_CANVAS1 0x1a52
@@ -1612,10 +1626,18 @@
#define VPU_MAFBC_PREFETCH_CFG_S3 0x3a7c
#define DOLBY_PATH_CTRL 0x1a0c
+#define DOLBY_BYPASS_EN(val) (val & 0xf)
#define OSD_PATH_MISC_CTRL 0x1a0e
#define MALI_AFBCD_TOP_CTRL 0x1a0f
#define VIU_OSD_BLEND_CTRL 0x39b0
+#define VIU_OSD_BLEND_REORDER(dest, src) ((src) << (dest * 4))
+#define VIU_OSD_BLEND_DIN_EN(bits) ((bits & 0xf) << 20)
+#define VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 BIT(24)
+#define VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 BIT(25)
+#define VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 BIT(26)
+#define VIU_OSD_BLEND_BLEN2_PREMULT_EN(input) ((input & 0x3) << 27)
+#define VIU_OSD_BLEND_HOLD_LINES(lines) ((lines & 0x7) << 29)
#define VIU_OSD_BLEND_CTRL1 0x39c0
#define VIU_OSD_BLEND_DIN0_SCOPE_H 0x39b1
#define VIU_OSD_BLEND_DIN0_SCOPE_V 0x39b2
@@ -1657,6 +1679,11 @@
#define VD_BLEND_POSTBLD_PREMULT_EN BIT(16)
#define OSD1_BLEND_SRC_CTRL 0x1dfd
#define OSD2_BLEND_SRC_CTRL 0x1dfe
+#define OSD_BLEND_POSTBLD_SRC_VD1 (1 << 8)
+#define OSD_BLEND_POSTBLD_SRC_VD2 (2 << 8)
+#define OSD_BLEND_POSTBLD_SRC_OSD1 (3 << 8)
+#define OSD_BLEND_POSTBLD_SRC_OSD2 (4 << 8)
+#define OSD_BLEND_PATH_SEL_ENABLE BIT(20)
#define VPP_POST_BLEND_BLEND_DUMMY_DATA 0x3968
#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 9f8a450d50d5..e70cd55d56c9 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -320,9 +320,9 @@ void meson_viu_osd1_reset(struct meson_drm *priv)
priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
/* Reset OSD1 */
- writel_bits_relaxed(BIT(0), BIT(0),
+ writel_bits_relaxed(VIU_SW_RESET_OSD1, VIU_SW_RESET_OSD1,
priv->io_base + _REG(VIU_SW_RESET));
- writel_bits_relaxed(BIT(0), 0,
+ writel_bits_relaxed(VIU_SW_RESET_OSD1, 0,
priv->io_base + _REG(VIU_SW_RESET));
/* Rewrite these registers state lost in the reset */
@@ -335,15 +335,22 @@ void meson_viu_osd1_reset(struct meson_drm *priv)
meson_viu_load_matrix(priv);
}
+static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
+{
+ uint32_t val = (((length & 0x80) % 24) / 12);
+
+ return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
+}
+
void meson_viu_init(struct meson_drm *priv)
{
uint32_t reg;
/* Disable OSDs */
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
+ writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
+ writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
+ priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
/* On GXL/GXM, Use the 10bit HDR conversion matrix */
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
@@ -354,19 +361,17 @@ void meson_viu_init(struct meson_drm *priv)
true);
/* Initialize OSD1 fifo control register */
- reg = BIT(0) | /* Urgent DDR request priority */
- (4 << 5); /* hold_fifo_lines */
+ reg = VIU_OSD_DDR_PRIORITY_URGENT |
+ VIU_OSD_HOLD_FIFO_LINES(4) |
+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */
+
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
- reg |= (1 << 10) | /* burst length 32 */
- (32 << 12) | /* fifo_depth_val: 32*8=256 */
- (2 << 22) | /* 4 words in 1 burst */
- (2 << 24) |
- (1 << 31);
+ reg |= meson_viu_osd_burst_length_reg(32);
else
- reg |= (3 << 10) | /* burst length 64 */
- (32 << 12) | /* fifo_depth_val: 32*8=256 */
- (2 << 22) | /* 4 words in 1 burst */
- (2 << 24);
+ reg |= meson_viu_osd_burst_length_reg(64);
+
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
@@ -379,12 +384,9 @@ void meson_viu_init(struct meson_drm *priv)
priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
/* Disable VD1 AFBC */
- /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 */
- writel_bits_relaxed(0x7 << 16, 0,
- priv->io_base + _REG(VIU_MISC_CTRL0));
- /* afbc vd1 set=0 */
- writel_bits_relaxed(BIT(20), 0,
- priv->io_base + _REG(VIU_MISC_CTRL0));
+ /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
+ writel_bits_relaxed(VIU_CTRL0_VD1_AFBC_MASK, 0,
+ priv->io_base + _REG(VIU_MISC_CTRL0));
writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));
writel_relaxed(0x00FF00C0,
@@ -393,27 +395,31 @@ void meson_viu_init(struct meson_drm *priv)
priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
- writel_relaxed(4 << 29 |
- 1 << 27 |
- 1 << 26 | /* blend_din0 input to blend0 */
- 1 << 25 | /* blend1_dout to blend2 */
- 1 << 24 | /* blend1_din3 input to blend1 */
- 1 << 20 |
- 0 << 16 |
- 1,
- priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
- writel_relaxed(1 << 20,
- priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
- writel_relaxed(1 << 20,
- priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
+ writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
+ VIU_OSD_BLEND_REORDER(1, 0) |
+ VIU_OSD_BLEND_REORDER(2, 0) |
+ VIU_OSD_BLEND_REORDER(3, 0) |
+ VIU_OSD_BLEND_DIN_EN(1) |
+ VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
+ VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
+ VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
+ VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
+ VIU_OSD_BLEND_HOLD_LINES(4),
+ priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
+
+ writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
+ priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
+ writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
+ priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
writel_relaxed(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
writel_relaxed(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
writel_relaxed(0,
priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
writel_relaxed(0,
priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
- writel_bits_relaxed(0x3 << 2, 0x3 << 2,
- priv->io_base + _REG(DOLBY_PATH_CTRL));
+
+ writel_bits_relaxed(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
+ priv->io_base + _REG(DOLBY_PATH_CTRL));
}
priv->viu.osd1_enabled = false;