1 // SPDX-License-Identifier: GPL-2.0
3 * Amlogic Meson Video Processing Unit driver
5 * Copyright (c) 2018 BayLibre, SAS.
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
14 #include <linux/bitops.h>
16 #include "meson_vpu.h"
19 #define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
20 #define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
21 #define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
22 #define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
23 #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
26 #define OSD_REPLACE_EN BIT(14)
27 #define OSD_REPLACE_SHIFT 6
29 void meson_vpp_setup_mux(struct meson_vpu_priv *priv, unsigned int mux)
31 writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
34 static unsigned int vpp_filter_coefs_4point_bspline[] = {
35 0x15561500, 0x14561600, 0x13561700, 0x12561800,
36 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
37 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
38 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
39 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
40 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
41 0x05473301, 0x05463401, 0x04453601, 0x04433702,
42 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
46 static void meson_vpp_write_scaling_filter_coefs(struct meson_vpu_priv *priv,
47 const unsigned int *coefs,
52 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
53 priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
54 for (i = 0; i < 33; i++)
56 priv->io_base + _REG(VPP_OSD_SCALE_COEF));
59 static const u32 vpp_filter_coefs_bicubic[] = {
60 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300,
61 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
62 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
63 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
64 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
65 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
66 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
67 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
71 static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_vpu_priv *priv,
72 const unsigned int *coefs,
77 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
78 priv->io_base + _REG(VPP_SCALE_COEF_IDX));
79 for (i = 0; i < 33; i++)
81 priv->io_base + _REG(VPP_SCALE_COEF));
86 enum viu_matrix_sel_e {
87 VIU_MATRIX_OSD_EOTF = 0,
96 #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
97 #define MATRIX_5X3_COEF_SIZE 24
99 #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
100 #define EOTF_COEFF_SIZE 10
101 #define EOTF_COEFF_RIGHTSHIFT 1
103 static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
104 0, 0, 0, /* pre offset */
105 COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
106 COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
107 COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
108 0, 0, 0, /* 10'/11'/12' */
109 0, 0, 0, /* 20'/21'/22' */
110 64, 512, 512, /* offset */
111 0, 0, 0 /* mode, right_shift, clip_en */
114 /* eotf matrix: bypass */
115 static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
116 EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0),
117 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0), EOTF_COEFF_NORM(0.0),
118 EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(0.0), EOTF_COEFF_NORM(1.0),
119 EOTF_COEFF_RIGHTSHIFT /* right shift */
122 static void meson_viu_set_g12a_osd1_matrix(struct meson_vpu_priv *priv,
125 /* VPP WRAP OSD1 matrix */
126 writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
127 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1));
129 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2));
130 writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
131 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01));
132 writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
133 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10));
134 writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
135 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12));
136 writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
137 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21));
138 writel((m[11] & 0x1fff) << 16,
139 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22));
141 writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
142 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1));
143 writel(m[20] & 0xfff,
144 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2));
146 writel_bits(BIT(0), csc_on ? BIT(0) : 0,
147 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
150 static void meson_viu_set_osd_matrix(struct meson_vpu_priv *priv,
151 enum viu_matrix_sel_e m_select,
154 if (m_select == VIU_MATRIX_OSD) {
155 /* osd matrix, VIU_MATRIX_0 */
156 writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
157 priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
159 priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
160 writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
161 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
162 writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
163 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
164 writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
165 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
166 writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
167 priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
170 writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
172 _REG(VIU_OSD1_MATRIX_COEF22_30));
173 writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
175 _REG(VIU_OSD1_MATRIX_COEF31_32));
176 writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
178 _REG(VIU_OSD1_MATRIX_COEF40_41));
179 writel(m[17] & 0x1fff, priv->io_base +
180 _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
182 writel((m[11] & 0x1fff) << 16, priv->io_base +
183 _REG(VIU_OSD1_MATRIX_COEF22_30));
186 writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
187 priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
188 writel(m[20] & 0xfff,
189 priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
191 writel_bits(3 << 30, m[21] << 30,
193 _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
194 writel_bits(7 << 16, m[22] << 16,
196 _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
198 /* 23 reserved for clipping control */
199 writel_bits(BIT(0), csc_on ? BIT(0) : 0,
200 priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
201 writel_bits(BIT(1), 0,
202 priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
203 } else if (m_select == VIU_MATRIX_OSD_EOTF) {
206 /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
207 for (i = 0; i < 5; i++)
208 writel(((m[i * 2] & 0x1fff) << 16) |
209 (m[i * 2 + 1] & 0x1fff), priv->io_base +
210 _REG(VIU_OSD1_EOTF_CTL + i + 1));
212 writel_bits(BIT(30), csc_on ? BIT(30) : 0,
213 priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
214 writel_bits(BIT(31), csc_on ? BIT(31) : 0,
215 priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
219 #define OSD_EOTF_LUT_SIZE 33
220 #define OSD_OETF_LUT_SIZE 41
222 static void meson_viu_set_osd_lut(struct meson_vpu_priv *priv,
223 enum viu_lut_sel_e lut_sel,
224 unsigned int *r_map, unsigned int *g_map,
228 unsigned int addr_port;
229 unsigned int data_port;
230 unsigned int ctrl_port;
233 if (lut_sel == VIU_LUT_OSD_EOTF) {
234 addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
235 data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
236 ctrl_port = VIU_OSD1_EOTF_CTL;
237 } else if (lut_sel == VIU_LUT_OSD_OETF) {
238 addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
239 data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
240 ctrl_port = VIU_OSD1_OETF_CTL;
245 if (lut_sel == VIU_LUT_OSD_OETF) {
246 writel(0, priv->io_base + _REG(addr_port));
248 for (i = 0; i < 20; i++)
249 writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
250 priv->io_base + _REG(data_port));
252 writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
253 priv->io_base + _REG(data_port));
255 for (i = 0; i < 20; i++)
256 writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
257 priv->io_base + _REG(data_port));
259 for (i = 0; i < 20; i++)
260 writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
261 priv->io_base + _REG(data_port));
263 writel(b_map[OSD_OETF_LUT_SIZE - 1],
264 priv->io_base + _REG(data_port));
267 writel_bits(0x7 << 29, 7 << 29,
268 priv->io_base + _REG(ctrl_port));
270 writel_bits(0x7 << 29, 0,
271 priv->io_base + _REG(ctrl_port));
272 } else if (lut_sel == VIU_LUT_OSD_EOTF) {
273 writel(0, priv->io_base + _REG(addr_port));
275 for (i = 0; i < 20; i++)
276 writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
277 priv->io_base + _REG(data_port));
279 writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
280 priv->io_base + _REG(data_port));
282 for (i = 0; i < 20; i++)
283 writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
284 priv->io_base + _REG(data_port));
286 for (i = 0; i < 20; i++)
287 writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
288 priv->io_base + _REG(data_port));
290 writel(b_map[OSD_EOTF_LUT_SIZE - 1],
291 priv->io_base + _REG(data_port));
294 writel_bits(7 << 27, 7 << 27,
295 priv->io_base + _REG(ctrl_port));
297 writel_bits(7 << 27, 0,
298 priv->io_base + _REG(ctrl_port));
300 writel_bits(BIT(31), BIT(31),
301 priv->io_base + _REG(ctrl_port));
305 /* eotf lut: linear */
306 static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
307 0x0000, 0x0200, 0x0400, 0x0600,
308 0x0800, 0x0a00, 0x0c00, 0x0e00,
309 0x1000, 0x1200, 0x1400, 0x1600,
310 0x1800, 0x1a00, 0x1c00, 0x1e00,
311 0x2000, 0x2200, 0x2400, 0x2600,
312 0x2800, 0x2a00, 0x2c00, 0x2e00,
313 0x3000, 0x3200, 0x3400, 0x3600,
314 0x3800, 0x3a00, 0x3c00, 0x3e00,
318 /* osd oetf lut: linear */
319 static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
329 1023, 1023, 1023, 1023,
333 static void meson_viu_load_matrix(struct meson_vpu_priv *priv)
335 /* eotf lut bypass */
336 meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
337 eotf_33_linear_mapping, /* R */
338 eotf_33_linear_mapping, /* G */
339 eotf_33_linear_mapping, /* B */
342 /* eotf matrix bypass */
343 meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
347 /* oetf lut bypass */
348 meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
349 oetf_41_linear_mapping, /* R */
350 oetf_41_linear_mapping, /* G */
351 oetf_41_linear_mapping, /* B */
354 /* osd matrix RGB709 to YUV709 limit */
355 meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
356 RGB709_to_YUV709l_coeff,
360 static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
362 u32 val = (((length & 0x80) % 24) / 12);
364 return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
367 void meson_vpu_init(struct udevice *dev)
369 struct meson_vpu_priv *priv = dev_get_priv(dev);
373 * Slave dc0 and dc5 connected to master port 1.
374 * By default other slaves are connected to master port 0.
376 reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) |
377 VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1);
378 writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
380 /* Slave dc0 connected to master port 1 */
381 reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1);
382 writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
384 /* Slave dc4 and dc7 connected to master port 1 */
385 reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) |
386 VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1);
387 writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
389 /* Slave dc1 connected to master port 1 */
390 reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1);
391 writel(reg, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
393 /* Disable CVBS VDAC */
394 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
395 hhi_write(HHI_VDAC_CNTL0_G12A, 0);
396 hhi_write(HHI_VDAC_CNTL1_G12A, 8);
398 hhi_write(HHI_VDAC_CNTL0, 0);
399 hhi_write(HHI_VDAC_CNTL1, 8);
402 /* Power Down Dacs */
403 writel(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
405 /* Disable HDMI PHY */
406 hhi_write(HHI_HDMI_PHY_CNTL0, 0);
409 writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI |
410 VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
411 priv->io_base + _REG(VPU_HDMI_SETTING));
413 /* Disable all encoders */
414 writel(0, priv->io_base + _REG(ENCI_VIDEO_EN));
415 writel(0, priv->io_base + _REG(ENCP_VIDEO_EN));
416 writel(0, priv->io_base + _REG(ENCL_VIDEO_EN));
418 /* Disable VSync IRQ */
419 writel(0, priv->io_base + _REG(VENC_INTCTRL));
421 /* set dummy data default YUV black */
422 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
423 writel(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1));
424 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) {
425 writel_bits(0xff << 16, 0xff << 16,
426 priv->io_base + _REG(VIU_MISC_CTRL1));
427 writel(VPP_PPS_DUMMY_DATA_MODE,
428 priv->io_base + _REG(VPP_DOLBY_CTRL));
430 priv->io_base + _REG(VPP_DUMMY_DATA1));
431 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
432 writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
434 /* Initialize vpu fifo control registers */
435 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
436 writel(VPP_OFIFO_SIZE_DEFAULT,
437 priv->io_base + _REG(VPP_OFIFO_SIZE));
439 writel_bits(VPP_OFIFO_SIZE_MASK, 0x77f,
440 priv->io_base + _REG(VPP_OFIFO_SIZE));
441 writel(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4),
442 priv->io_base + _REG(VPP_HOLD_LINES));
444 if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
445 /* Turn off preblend */
446 writel_bits(VPP_PREBLEND_ENABLE, 0,
447 priv->io_base + _REG(VPP_MISC));
449 /* Turn off POSTBLEND */
450 writel_bits(VPP_POSTBLEND_ENABLE, 0,
451 priv->io_base + _REG(VPP_MISC));
453 /* Force all planes off */
454 writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND |
455 VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND |
456 VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0,
457 priv->io_base + _REG(VPP_MISC));
459 /* Setup default VD settings */
461 priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END));
463 priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
466 /* Disable Scalers */
467 writel(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
468 writel(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
469 writel(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
471 writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
473 priv->io_base + _REG(VPP_SC_MISC));
475 /* Enable minus black level for vadj1 */
476 writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
477 priv->io_base + _REG(VPP_VADJ_CTRL));
479 /* Write in the proper filter coefficients. */
480 meson_vpp_write_scaling_filter_coefs(priv,
481 vpp_filter_coefs_4point_bspline, false);
482 meson_vpp_write_scaling_filter_coefs(priv,
483 vpp_filter_coefs_4point_bspline, true);
485 /* Write the VD proper filter coefficients. */
486 meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
488 meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
492 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
493 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
494 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
495 priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
497 /* On GXL/GXM, Use the 10bit HDR conversion matrix */
498 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
499 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
500 meson_viu_load_matrix(priv);
501 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
502 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
505 /* Initialize OSD1 fifo control register */
506 reg = VIU_OSD_DDR_PRIORITY_URGENT |
507 VIU_OSD_HOLD_FIFO_LINES(4) |
508 VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
509 VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
510 VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */
512 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
513 reg |= meson_viu_osd_burst_length_reg(32);
515 reg |= meson_viu_osd_burst_length_reg(64);
517 writel(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
518 writel(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
520 /* Set OSD alpha replace value */
521 writel_bits(0xff << OSD_REPLACE_SHIFT,
522 0xff << OSD_REPLACE_SHIFT,
523 priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
524 writel_bits(0xff << OSD_REPLACE_SHIFT,
525 0xff << OSD_REPLACE_SHIFT,
526 priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
528 /* Disable VD1 AFBC */
529 /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
530 writel_bits(VIU_CTRL0_VD1_AFBC_MASK, 0,
531 priv->io_base + _REG(VIU_MISC_CTRL0));
532 writel(0, priv->io_base + _REG(AFBC_ENABLE));
535 priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
537 priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
539 if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
540 writel(VIU_OSD_BLEND_REORDER(0, 1) |
541 VIU_OSD_BLEND_REORDER(1, 0) |
542 VIU_OSD_BLEND_REORDER(2, 0) |
543 VIU_OSD_BLEND_REORDER(3, 0) |
544 VIU_OSD_BLEND_DIN_EN(1) |
545 VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
546 VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
547 VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
548 VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
549 VIU_OSD_BLEND_HOLD_LINES(4),
550 priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
551 writel(OSD_BLEND_PATH_SEL_ENABLE,
552 priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
553 writel(OSD_BLEND_PATH_SEL_ENABLE,
554 priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
555 writel(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
556 writel(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
557 writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
558 writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
559 writel_bits(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
560 priv->io_base + _REG(DOLBY_PATH_CTRL));