Convert CONFIG_ATMEL_HLCD to Kconfig
[platform/kernel/u-boot.git] / drivers / video / meson / meson_vpu_init.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Amlogic Meson Video Processing Unit driver
4  *
5  * Copyright (c) 2018 BayLibre, SAS.
6  * Author: Neil Armstrong <narmstrong@baylibre.com>
7  */
8
9 #define DEBUG
10
11 #include <common.h>
12 #include <dm.h>
13 #include <asm/io.h>
14 #include <linux/bitops.h>
15
16 #include "meson_vpu.h"
17
18 /* HHI Registers */
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 */
24
25 /* OSDx_CTRL_STAT2 */
26 #define OSD_REPLACE_EN          BIT(14)
27 #define OSD_REPLACE_SHIFT       6
28
29 void meson_vpp_setup_mux(struct meson_vpu_priv *priv, unsigned int mux)
30 {
31         writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
32 }
33
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,
43         0x033d3d03
44 };
45
46 static void meson_vpp_write_scaling_filter_coefs(struct meson_vpu_priv *priv,
47                                                  const unsigned int *coefs,
48                                                  bool is_horizontal)
49 {
50         int i;
51
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++)
55                 writel(coefs[i],
56                        priv->io_base + _REG(VPP_OSD_SCALE_COEF));
57 }
58
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,
68         0xf84848f8
69 };
70
71 static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_vpu_priv *priv,
72                                                     const unsigned int *coefs,
73                                                     bool is_horizontal)
74 {
75         int i;
76
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++)
80                 writel(coefs[i],
81                        priv->io_base + _REG(VPP_SCALE_COEF));
82 }
83
84 /* OSD csc defines */
85
86 enum viu_matrix_sel_e {
87         VIU_MATRIX_OSD_EOTF = 0,
88         VIU_MATRIX_OSD,
89 };
90
91 enum viu_lut_sel_e {
92         VIU_LUT_OSD_EOTF = 0,
93         VIU_LUT_OSD_OETF,
94 };
95
96 #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
97 #define MATRIX_5X3_COEF_SIZE 24
98
99 #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
100 #define EOTF_COEFF_SIZE 10
101 #define EOTF_COEFF_RIGHTSHIFT 1
102
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 */
112 };
113
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 */
120 };
121
122 static void meson_viu_set_g12a_osd1_matrix(struct meson_vpu_priv *priv,
123                                            int *m, bool csc_on)
124 {
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));
128         writel(m[2] & 0xfff,
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));
140
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));
145
146         writel_bits(BIT(0), csc_on ? BIT(0) : 0,
147                     priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
148 }
149
150 static void meson_viu_set_osd_matrix(struct meson_vpu_priv *priv,
151                                      enum viu_matrix_sel_e m_select,
152                                      int *m, bool csc_on)
153 {
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));
158                 writel(m[2] & 0xfff,
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));
168
169                 if (m[21]) {
170                         writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
171                                priv->io_base +
172                                         _REG(VIU_OSD1_MATRIX_COEF22_30));
173                         writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
174                                priv->io_base +
175                                         _REG(VIU_OSD1_MATRIX_COEF31_32));
176                         writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
177                                priv->io_base +
178                                         _REG(VIU_OSD1_MATRIX_COEF40_41));
179                         writel(m[17] & 0x1fff, priv->io_base +
180                                _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
181                 } else {
182                         writel((m[11] & 0x1fff) << 16, priv->io_base +
183                                _REG(VIU_OSD1_MATRIX_COEF22_30));
184                 }
185
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));
190
191                 writel_bits(3 << 30, m[21] << 30,
192                             priv->io_base +
193                             _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
194                 writel_bits(7 << 16, m[22] << 16,
195                             priv->io_base +
196                             _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
197
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) {
204                 int i;
205
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));
211
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));
216         }
217 }
218
219 #define OSD_EOTF_LUT_SIZE 33
220 #define OSD_OETF_LUT_SIZE 41
221
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,
225                                   unsigned int *b_map,
226                                   bool csc_on)
227 {
228         unsigned int addr_port;
229         unsigned int data_port;
230         unsigned int ctrl_port;
231         int i;
232
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;
241         } else {
242                 return;
243         }
244
245         if (lut_sel == VIU_LUT_OSD_OETF) {
246                 writel(0, priv->io_base + _REG(addr_port));
247
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));
251
252                 writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
253                        priv->io_base + _REG(data_port));
254
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));
258
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));
262
263                 writel(b_map[OSD_OETF_LUT_SIZE - 1],
264                        priv->io_base + _REG(data_port));
265
266                 if (csc_on)
267                         writel_bits(0x7 << 29, 7 << 29,
268                                     priv->io_base + _REG(ctrl_port));
269                 else
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));
274
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));
278
279                 writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
280                        priv->io_base + _REG(data_port));
281
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));
285
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));
289
290                 writel(b_map[OSD_EOTF_LUT_SIZE - 1],
291                        priv->io_base + _REG(data_port));
292
293                 if (csc_on)
294                         writel_bits(7 << 27, 7 << 27,
295                                     priv->io_base + _REG(ctrl_port));
296                 else
297                         writel_bits(7 << 27, 0,
298                                     priv->io_base + _REG(ctrl_port));
299
300                 writel_bits(BIT(31), BIT(31),
301                             priv->io_base + _REG(ctrl_port));
302         }
303 }
304
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,
315         0x4000
316 };
317
318 /* osd oetf lut: linear */
319 static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
320         0, 0, 0, 0,
321         0, 32, 64, 96,
322         128, 160, 196, 224,
323         256, 288, 320, 352,
324         384, 416, 448, 480,
325         512, 544, 576, 608,
326         640, 672, 704, 736,
327         768, 800, 832, 864,
328         896, 928, 960, 992,
329         1023, 1023, 1023, 1023,
330         1023
331 };
332
333 static void meson_viu_load_matrix(struct meson_vpu_priv *priv)
334 {
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 */
340                               false);
341
342         /* eotf matrix bypass */
343         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
344                                  eotf_bypass_coeff,
345                                  false);
346
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 */
352                               false);
353
354         /* osd matrix RGB709 to YUV709 limit */
355         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
356                                  RGB709_to_YUV709l_coeff,
357                                  true);
358 }
359
360 static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
361 {
362         u32 val = (((length & 0x80) % 24) / 12);
363
364         return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
365 }
366
367 void meson_vpu_init(struct udevice *dev)
368 {
369         struct meson_vpu_priv *priv = dev_get_priv(dev);
370         u32 reg;
371
372         /*
373          * Slave dc0 and dc5 connected to master port 1.
374          * By default other slaves are connected to master port 0.
375          */
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));
379
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));
383
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));
388
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));
392
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);
397         } else {
398                 hhi_write(HHI_VDAC_CNTL0, 0);
399                 hhi_write(HHI_VDAC_CNTL1, 8);
400         }
401
402         /* Power Down Dacs */
403         writel(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
404
405         /* Disable HDMI PHY */
406         hhi_write(HHI_HDMI_PHY_CNTL0, 0);
407
408         /* Disable HDMI */
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));
412
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));
417
418         /* Disable VSync IRQ */
419         writel(0, priv->io_base + _REG(VENC_INTCTRL));
420
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));
429                 writel(0x1020080,
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));
433
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));
438         else
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));
443
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));
448
449                 /* Turn off POSTBLEND */
450                 writel_bits(VPP_POSTBLEND_ENABLE, 0,
451                             priv->io_base + _REG(VPP_MISC));
452
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));
458
459                 /* Setup default VD settings */
460                 writel(4096,
461                        priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END));
462                 writel(4096,
463                        priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
464         }
465
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));
470
471         writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
472                VPP_SC_VD_EN_ENABLE,
473                priv->io_base + _REG(VPP_SC_MISC));
474
475         /* Enable minus black level for vadj1 */
476         writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
477                priv->io_base + _REG(VPP_VADJ_CTRL));
478
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);
484
485         /* Write the VD proper filter coefficients. */
486         meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
487                                                 false);
488         meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
489                                                 true);
490
491         /* Disable OSDs */
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));
496
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,
503                                                true);
504
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 */
511
512         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
513                 reg |= meson_viu_osd_burst_length_reg(32);
514         else
515                 reg |= meson_viu_osd_burst_length_reg(64);
516
517         writel(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
518         writel(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
519
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));
527
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));
533
534         writel(0x00FF00C0,
535                priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
536         writel(0x00FF00C0,
537                priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
538
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));
561         }
562 }