blob: 8408c59eaa103c7caf375eceb90d6c276468f45c [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
Simon Glassf74c7bd2019-10-27 09:54:03 -060011#include <common.h>
12#include <dm.h>
13#include <asm/io.h>
14
Neil Armstrongadd986c2018-07-24 17:45:28 +020015#include "meson_vpu.h"
16
17/* HHI Registers */
18#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020019#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
Neil Armstrongadd986c2018-07-24 17:45:28 +020020#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020021#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
Neil Armstrongadd986c2018-07-24 17:45:28 +020022#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
28void 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
33static 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
45static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020051 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +020052 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
58static 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
70static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +020076 writel(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +020077 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
85enum viu_matrix_sel_e {
86 VIU_MATRIX_OSD_EOTF = 0,
87 VIU_MATRIX_OSD,
88};
89
90enum 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
102static 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 */
114static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200121static 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200149static 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
221static 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 */
305static 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 */
318static 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
332static 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
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200359static 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200366void meson_vpu_init(struct udevice *dev)
367{
368 struct meson_vpu_priv *priv = dev_get_priv(dev);
369 u32 reg;
370
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200371 /*
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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200391
392 /* Disable CVBS VDAC */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200393 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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200400
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 */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200408 writel_bits(VPU_HDMI_ENCI_DATA_TO_HDMI |
409 VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
410 priv->io_base + _REG(VPU_HDMI_SETTING));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200411
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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200426 writel(VPP_PPS_DUMMY_DATA_MODE,
427 priv->io_base + _REG(VPP_DOLBY_CTRL));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200428 writel(0x1020080,
429 priv->io_base + _REG(VPP_DUMMY_DATA1));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200430 } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
431 writel(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200432
433 /* Initialize vpu fifo control registers */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200434 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200442
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200443 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200447
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200448 /* Turn off POSTBLEND */
449 writel_bits(VPP_POSTBLEND_ENABLE, 0,
450 priv->io_base + _REG(VPP_MISC));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200451
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200452 /* 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));
Neil Armstrongadd986c2018-07-24 17:45:28 +0200457
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200458 /* 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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200464
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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200469
470 writel(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
471 VPP_SC_VD_EN_ENABLE,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200472 priv->io_base + _REG(VPP_SC_MISC));
473
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200474 /* Enable minus black level for vadj1 */
475 writel(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
476 priv->io_base + _REG(VPP_VADJ_CTRL));
477
Neil Armstrongadd986c2018-07-24 17:45:28 +0200478 /* 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 */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200491 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200492 priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200493 writel_bits(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
Neil Armstrongadd986c2018-07-24 17:45:28 +0200494 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);
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200500 else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
501 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
502 true);
Neil Armstrongadd986c2018-07-24 17:45:28 +0200503
504 /* Initialize OSD1 fifo control register */
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200505 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
Neil Armstrongadd986c2018-07-24 17:45:28 +0200516 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));
Neil Armstrong57d6dfe2019-08-30 14:09:24 +0200526
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 }
Neil Armstrongadd986c2018-07-24 17:45:28 +0200561}