blob: 12f8c4194ad744dcfd3d457f3db9dd0a8b321597 [file] [log] [blame]
Neil Armstrongadd986c2018-07-24 17:45:28 +02001// 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 */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020015#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
Neil Armstrongadd986c2018-07-24 17:45:28 +020016#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020017#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
Neil Armstrongadd986c2018-07-24 17:45:28 +020018#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
24void 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
29static 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
41static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020047 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +020048 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
54static 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
66static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020072 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +020073 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
81enum viu_matrix_sel_e {
82 VIU_MATRIX_OSD_EOTF = 0,
83 VIU_MATRIX_OSD,
84};
85
86enum 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
98static 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 */
110static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200117static 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200145static 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
217static 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 */
301static 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 */
314static 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
328static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200355static 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200362void meson_vpu_init(struct udevice *dev)
363{
364 struct meson_vpu_priv *priv = dev_get_priv(dev);
365 u32 reg;
366
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200367 /*
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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200387
388 /* Disable CVBS VDAC */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200389 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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200396
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 */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200404 writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI |
405 VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
406 priv->io_base + _REG(VPU_HDMI_SETTING));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200407
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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200422 writel(VPP_PPS_DUMMY_DATA_MODE,
423 priv->io_base + _REG(VPP_DOLBY_CTRL));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200424 writel(0x1020080,
425 priv->io_base + _REG(VPP_DUMMY_DATA1));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200426 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
427 writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200428
429 /* Initialize vpu fifo control registers */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200430 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200438
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200439 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200443
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200444 /* Turn off POSTBLEND */
445 writel_bits(VPP_POSTBLEND_ENABLE, 0,
446 priv->io_base + _REG(VPP_MISC));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200447
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200448 /* 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200453
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200454 /* 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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200460
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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200465
466 writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
467 VPP_SC_VD_EN_ENABLE,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200468 priv->io_base + _REG(VPP_SC_MISC));
469
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200470 /* Enable minus black level for vadj1 */
471 writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
472 priv->io_base + _REG(VPP_VADJ_CTRL));
473
Neil Armstrongadd986c2018-07-24 17:45:28 +0200474 /* 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 */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200487 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200488 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200489 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200490 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);
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200496 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
497 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
498 true);
Neil Armstrongadd986c2018-07-24 17:45:28 +0200499
500 /* Initialize OSD1 fifo control register */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200501 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200512 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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200522
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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200557}