Merge tag 'u-boot-amlogic-20200420' of https://gitlab.denx.de/u-boot/custodians/u...
[oweals/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
15 #include "meson_vpu.h"
16
17 /* HHI Registers */
18 #define HHI_VDAC_CNTL0          0x2F4 /* 0xbd offset in data sheet */
19 #define HHI_VDAC_CNTL0_G12A     0x2EC /* 0xbd offset in data sheet */
20 #define HHI_VDAC_CNTL1          0x2F8 /* 0xbe offset in data sheet */
21 #define HHI_VDAC_CNTL1_G12A     0x2F0 /* 0xbe offset in data sheet */
22 #define HHI_HDMI_PHY_CNTL0      0x3a0 /* 0xe8 offset in data sheet */
23
24 /* OSDx_CTRL_STAT2 */
25 #define OSD_REPLACE_EN          BIT(14)
26 #define OSD_REPLACE_SHIFT       6
27
28 void meson_vpp_setup_mux(struct meson_vpu_priv *priv, unsigned int mux)
29 {
30         writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
31 }
32
33 static unsigned int vpp_filter_coefs_4point_bspline[] = {
34         0x15561500, 0x14561600, 0x13561700, 0x12561800,
35         0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
36         0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
37         0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
38         0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
39         0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
40         0x05473301, 0x05463401, 0x04453601, 0x04433702,
41         0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
42         0x033d3d03
43 };
44
45 static void meson_vpp_write_scaling_filter_coefs(struct meson_vpu_priv *priv,
46                                                  const unsigned int *coefs,
47                                                  bool is_horizontal)
48 {
49         int i;
50
51         writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
52                priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
53         for (i = 0; i < 33; i++)
54                 writel(coefs[i],
55                        priv->io_base + _REG(VPP_OSD_SCALE_COEF));
56 }
57
58 static const u32 vpp_filter_coefs_bicubic[] = {
59         0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300,
60         0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
61         0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
62         0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
63         0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
64         0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
65         0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
66         0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
67         0xf84848f8
68 };
69
70 static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_vpu_priv *priv,
71                                                     const unsigned int *coefs,
72                                                     bool is_horizontal)
73 {
74         int i;
75
76         writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
77                priv->io_base + _REG(VPP_SCALE_COEF_IDX));
78         for (i = 0; i < 33; i++)
79                 writel(coefs[i],
80                        priv->io_base + _REG(VPP_SCALE_COEF));
81 }
82
83 /* OSD csc defines */
84
85 enum viu_matrix_sel_e {
86         VIU_MATRIX_OSD_EOTF = 0,
87         VIU_MATRIX_OSD,
88 };
89
90 enum viu_lut_sel_e {
91         VIU_LUT_OSD_EOTF = 0,
92         VIU_LUT_OSD_OETF,
93 };
94
95 #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
96 #define MATRIX_5X3_COEF_SIZE 24
97
98 #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
99 #define EOTF_COEFF_SIZE 10
100 #define EOTF_COEFF_RIGHTSHIFT 1
101
102 static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
103         0, 0, 0, /* pre offset */
104         COEFF_NORM(0.181873),   COEFF_NORM(0.611831),   COEFF_NORM(0.061765),
105         COEFF_NORM(-0.100251),  COEFF_NORM(-0.337249),  COEFF_NORM(0.437500),
106         COEFF_NORM(0.437500),   COEFF_NORM(-0.397384),  COEFF_NORM(-0.040116),
107         0, 0, 0, /* 10'/11'/12' */
108         0, 0, 0, /* 20'/21'/22' */
109         64, 512, 512, /* offset */
110         0, 0, 0 /* mode, right_shift, clip_en */
111 };
112
113 /*  eotf matrix: bypass */
114 static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
115         EOTF_COEFF_NORM(1.0),   EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(0.0),
116         EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(1.0),   EOTF_COEFF_NORM(0.0),
117         EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(1.0),
118         EOTF_COEFF_RIGHTSHIFT /* right shift */
119 };
120
121 static void meson_viu_set_g12a_osd1_matrix(struct meson_vpu_priv *priv,
122                                            int *m, bool csc_on)
123 {
124         /* VPP WRAP OSD1 matrix */
125         writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
126                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1));
127         writel(m[2] & 0xfff,
128                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2));
129         writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
130                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01));
131         writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
132                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10));
133         writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
134                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12));
135         writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
136                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21));
137         writel((m[11] & 0x1fff) << 16,
138                priv->io_base +  _REG(VPP_WRAP_OSD1_MATRIX_COEF22));
139
140         writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
141                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1));
142         writel(m[20] & 0xfff,
143                priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2));
144
145         writel_bits(BIT(0), csc_on ? BIT(0) : 0,
146                     priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
147 }
148
149 static void meson_viu_set_osd_matrix(struct meson_vpu_priv *priv,
150                                      enum viu_matrix_sel_e m_select,
151                                      int *m, bool csc_on)
152 {
153         if (m_select == VIU_MATRIX_OSD) {
154                 /* osd matrix, VIU_MATRIX_0 */
155                 writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
156                        priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
157                 writel(m[2] & 0xfff,
158                        priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
159                 writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
160                        priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
161                 writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
162                        priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
163                 writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
164                        priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
165                 writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
166                        priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
167
168                 if (m[21]) {
169                         writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
170                                priv->io_base +
171                                         _REG(VIU_OSD1_MATRIX_COEF22_30));
172                         writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
173                                priv->io_base +
174                                         _REG(VIU_OSD1_MATRIX_COEF31_32));
175                         writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
176                                priv->io_base +
177                                         _REG(VIU_OSD1_MATRIX_COEF40_41));
178                         writel(m[17] & 0x1fff, priv->io_base +
179                                _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
180                 } else {
181                         writel((m[11] & 0x1fff) << 16, priv->io_base +
182                                _REG(VIU_OSD1_MATRIX_COEF22_30));
183                 }
184
185                 writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
186                        priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
187                 writel(m[20] & 0xfff,
188                        priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
189
190                 writel_bits(3 << 30, m[21] << 30,
191                             priv->io_base +
192                             _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
193                 writel_bits(7 << 16, m[22] << 16,
194                             priv->io_base +
195                             _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
196
197                 /* 23 reserved for clipping control */
198                 writel_bits(BIT(0), csc_on ? BIT(0) : 0,
199                             priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
200                 writel_bits(BIT(1), 0,
201                             priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
202         } else if (m_select == VIU_MATRIX_OSD_EOTF) {
203                 int i;
204
205                 /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
206                 for (i = 0; i < 5; i++)
207                         writel(((m[i * 2] & 0x1fff) << 16) |
208                                 (m[i * 2 + 1] & 0x1fff), priv->io_base +
209                                 _REG(VIU_OSD1_EOTF_CTL + i + 1));
210
211                 writel_bits(BIT(30), csc_on ? BIT(30) : 0,
212                             priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
213                 writel_bits(BIT(31), csc_on ? BIT(31) : 0,
214                             priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
215         }
216 }
217
218 #define OSD_EOTF_LUT_SIZE 33
219 #define OSD_OETF_LUT_SIZE 41
220
221 static void meson_viu_set_osd_lut(struct meson_vpu_priv *priv,
222                                   enum viu_lut_sel_e lut_sel,
223                                   unsigned int *r_map, unsigned int *g_map,
224                                   unsigned int *b_map,
225                                   bool csc_on)
226 {
227         unsigned int addr_port;
228         unsigned int data_port;
229         unsigned int ctrl_port;
230         int i;
231
232         if (lut_sel == VIU_LUT_OSD_EOTF) {
233                 addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
234                 data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
235                 ctrl_port = VIU_OSD1_EOTF_CTL;
236         } else if (lut_sel == VIU_LUT_OSD_OETF) {
237                 addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
238                 data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
239                 ctrl_port = VIU_OSD1_OETF_CTL;
240         } else {
241                 return;
242         }
243
244         if (lut_sel == VIU_LUT_OSD_OETF) {
245                 writel(0, priv->io_base + _REG(addr_port));
246
247                 for (i = 0; i < 20; i++)
248                         writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
249                                priv->io_base + _REG(data_port));
250
251                 writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
252                        priv->io_base + _REG(data_port));
253
254                 for (i = 0; i < 20; i++)
255                         writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
256                                priv->io_base + _REG(data_port));
257
258                 for (i = 0; i < 20; i++)
259                         writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
260                                priv->io_base + _REG(data_port));
261
262                 writel(b_map[OSD_OETF_LUT_SIZE - 1],
263                        priv->io_base + _REG(data_port));
264
265                 if (csc_on)
266                         writel_bits(0x7 << 29, 7 << 29,
267                                     priv->io_base + _REG(ctrl_port));
268                 else
269                         writel_bits(0x7 << 29, 0,
270                                     priv->io_base + _REG(ctrl_port));
271         } else if (lut_sel == VIU_LUT_OSD_EOTF) {
272                 writel(0, priv->io_base + _REG(addr_port));
273
274                 for (i = 0; i < 20; i++)
275                         writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
276                                priv->io_base + _REG(data_port));
277
278                 writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
279                        priv->io_base + _REG(data_port));
280
281                 for (i = 0; i < 20; i++)
282                         writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
283                                priv->io_base + _REG(data_port));
284
285                 for (i = 0; i < 20; i++)
286                         writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
287                                priv->io_base + _REG(data_port));
288
289                 writel(b_map[OSD_EOTF_LUT_SIZE - 1],
290                        priv->io_base + _REG(data_port));
291
292                 if (csc_on)
293                         writel_bits(7 << 27, 7 << 27,
294                                     priv->io_base + _REG(ctrl_port));
295                 else
296                         writel_bits(7 << 27, 0,
297                                     priv->io_base + _REG(ctrl_port));
298
299                 writel_bits(BIT(31), BIT(31),
300                             priv->io_base + _REG(ctrl_port));
301         }
302 }
303
304 /* eotf lut: linear */
305 static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
306         0x0000, 0x0200, 0x0400, 0x0600,
307         0x0800, 0x0a00, 0x0c00, 0x0e00,
308         0x1000, 0x1200, 0x1400, 0x1600,
309         0x1800, 0x1a00, 0x1c00, 0x1e00,
310         0x2000, 0x2200, 0x2400, 0x2600,
311         0x2800, 0x2a00, 0x2c00, 0x2e00,
312         0x3000, 0x3200, 0x3400, 0x3600,
313         0x3800, 0x3a00, 0x3c00, 0x3e00,
314         0x4000
315 };
316
317 /* osd oetf lut: linear */
318 static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
319         0, 0, 0, 0,
320         0, 32, 64, 96,
321         128, 160, 196, 224,
322         256, 288, 320, 352,
323         384, 416, 448, 480,
324         512, 544, 576, 608,
325         640, 672, 704, 736,
326         768, 800, 832, 864,
327         896, 928, 960, 992,
328         1023, 1023, 1023, 1023,
329         1023
330 };
331
332 static void meson_viu_load_matrix(struct meson_vpu_priv *priv)
333 {
334         /* eotf lut bypass */
335         meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
336                               eotf_33_linear_mapping, /* R */
337                               eotf_33_linear_mapping, /* G */
338                               eotf_33_linear_mapping, /* B */
339                               false);
340
341         /* eotf matrix bypass */
342         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
343                                  eotf_bypass_coeff,
344                                  false);
345
346         /* oetf lut bypass */
347         meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
348                               oetf_41_linear_mapping, /* R */
349                               oetf_41_linear_mapping, /* G */
350                               oetf_41_linear_mapping, /* B */
351                               false);
352
353         /* osd matrix RGB709 to YUV709 limit */
354         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
355                                  RGB709_to_YUV709l_coeff,
356                                  true);
357 }
358
359 static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
360 {
361         u32 val = (((length & 0x80) % 24) / 12);
362
363         return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
364 }
365
366 void meson_vpu_init(struct udevice *dev)
367 {
368         struct meson_vpu_priv *priv = dev_get_priv(dev);
369         u32 reg;
370
371         /*
372          * Slave dc0 and dc5 connected to master port 1.
373          * By default other slaves are connected to master port 0.
374          */
375         reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) |
376                 VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1);
377         writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
378
379         /* Slave dc0 connected to master port 1 */
380         reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1);
381         writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
382
383         /* Slave dc4 and dc7 connected to master port 1 */
384         reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) |
385                 VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1);
386         writel(reg, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
387
388         /* Slave dc1 connected to master port 1 */
389         reg = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1);
390         writel(reg, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
391
392         /* Disable CVBS VDAC */
393         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
394                 hhi_write(HHI_VDAC_CNTL0_G12A, 0);
395                 hhi_write(HHI_VDAC_CNTL1_G12A, 8);
396         } else {
397                 hhi_write(HHI_VDAC_CNTL0, 0);
398                 hhi_write(HHI_VDAC_CNTL1, 8);
399         }
400
401         /* Power Down Dacs */
402         writel(0xff, priv->io_base + _REG(VENC_VDAC_SETTING));
403
404         /* Disable HDMI PHY */
405         hhi_write(HHI_HDMI_PHY_CNTL0, 0);
406
407         /* Disable HDMI */
408         writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI |
409                     VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
410                     priv->io_base + _REG(VPU_HDMI_SETTING));
411
412         /* Disable all encoders */
413         writel(0, priv->io_base + _REG(ENCI_VIDEO_EN));
414         writel(0, priv->io_base + _REG(ENCP_VIDEO_EN));
415         writel(0, priv->io_base + _REG(ENCL_VIDEO_EN));
416
417         /* Disable VSync IRQ */
418         writel(0, priv->io_base + _REG(VENC_INTCTRL));
419
420         /* set dummy data default YUV black */
421         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
422                 writel(0x108080, priv->io_base + _REG(VPP_DUMMY_DATA1));
423         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM)) {
424                 writel_bits(0xff << 16, 0xff << 16,
425                             priv->io_base + _REG(VIU_MISC_CTRL1));
426                 writel(VPP_PPS_DUMMY_DATA_MODE,
427                        priv->io_base + _REG(VPP_DOLBY_CTRL));
428                 writel(0x1020080,
429                        priv->io_base + _REG(VPP_DUMMY_DATA1));
430         } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
431                 writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
432
433         /* Initialize vpu fifo control registers */
434         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
435                 writel(VPP_OFIFO_SIZE_DEFAULT,
436                        priv->io_base + _REG(VPP_OFIFO_SIZE));
437         else
438                 writel_bits(VPP_OFIFO_SIZE_MASK, 0x77f,
439                             priv->io_base + _REG(VPP_OFIFO_SIZE));
440         writel(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4),
441                priv->io_base + _REG(VPP_HOLD_LINES));
442
443         if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
444                 /* Turn off preblend */
445                 writel_bits(VPP_PREBLEND_ENABLE, 0,
446                             priv->io_base + _REG(VPP_MISC));
447
448                 /* Turn off POSTBLEND */
449                 writel_bits(VPP_POSTBLEND_ENABLE, 0,
450                             priv->io_base + _REG(VPP_MISC));
451
452                 /* Force all planes off */
453                 writel_bits(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND |
454                             VPP_VD1_POSTBLEND | VPP_VD2_POSTBLEND |
455                             VPP_VD1_PREBLEND | VPP_VD2_PREBLEND, 0,
456                             priv->io_base + _REG(VPP_MISC));
457
458                 /* Setup default VD settings */
459                 writel(4096,
460                        priv->io_base + _REG(VPP_PREBLEND_VD1_H_START_END));
461                 writel(4096,
462                        priv->io_base + _REG(VPP_BLEND_VD2_H_START_END));
463         }
464
465         /* Disable Scalers */
466         writel(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
467         writel(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
468         writel(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
469
470         writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
471                VPP_SC_VD_EN_ENABLE,
472                priv->io_base + _REG(VPP_SC_MISC));
473
474         /* Enable minus black level for vadj1 */
475         writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
476                priv->io_base + _REG(VPP_VADJ_CTRL));
477
478         /* Write in the proper filter coefficients. */
479         meson_vpp_write_scaling_filter_coefs(priv,
480                                 vpp_filter_coefs_4point_bspline, false);
481         meson_vpp_write_scaling_filter_coefs(priv,
482                                 vpp_filter_coefs_4point_bspline, true);
483
484         /* Write the VD proper filter coefficients. */
485         meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
486                                                 false);
487         meson_vpp_write_vd_scaling_filter_coefs(priv, vpp_filter_coefs_bicubic,
488                                                 true);
489
490         /* Disable OSDs */
491         writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
492                     priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
493         writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
494                     priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
495
496         /* On GXL/GXM, Use the 10bit HDR conversion matrix */
497         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
498             meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
499                 meson_viu_load_matrix(priv);
500         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
501                 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
502                                                true);
503
504         /* Initialize OSD1 fifo control register */
505         reg = VIU_OSD_DDR_PRIORITY_URGENT |
506                 VIU_OSD_HOLD_FIFO_LINES(4) |
507                 VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
508                 VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
509                 VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
510
511         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
512                 reg |= meson_viu_osd_burst_length_reg(32);
513         else
514                 reg |= meson_viu_osd_burst_length_reg(64);
515
516         writel(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
517         writel(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
518
519         /* Set OSD alpha replace value */
520         writel_bits(0xff << OSD_REPLACE_SHIFT,
521                     0xff << OSD_REPLACE_SHIFT,
522                     priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
523         writel_bits(0xff << OSD_REPLACE_SHIFT,
524                     0xff << OSD_REPLACE_SHIFT,
525                     priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
526
527         /* Disable VD1 AFBC */
528         /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
529         writel_bits(VIU_CTRL0_VD1_AFBC_MASK, 0,
530                     priv->io_base + _REG(VIU_MISC_CTRL0));
531         writel(0, priv->io_base + _REG(AFBC_ENABLE));
532
533         writel(0x00FF00C0,
534                priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
535         writel(0x00FF00C0,
536                priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
537
538         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
539                 writel(VIU_OSD_BLEND_REORDER(0, 1) |
540                        VIU_OSD_BLEND_REORDER(1, 0) |
541                        VIU_OSD_BLEND_REORDER(2, 0) |
542                        VIU_OSD_BLEND_REORDER(3, 0) |
543                        VIU_OSD_BLEND_DIN_EN(1) |
544                        VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
545                        VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
546                        VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
547                        VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
548                        VIU_OSD_BLEND_HOLD_LINES(4),
549                        priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
550                 writel(OSD_BLEND_PATH_SEL_ENABLE,
551                        priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
552                 writel(OSD_BLEND_PATH_SEL_ENABLE,
553                        priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
554                 writel(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
555                 writel(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
556                 writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
557                 writel(0, priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
558                 writel_bits(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
559                             priv->io_base + _REG(DOLBY_PATH_CTRL));
560         }
561 }