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