]> Git Repo - linux.git/blob - drivers/gpu/drm/meson/meson_viu.c
Merge tag 'for-linus-6.14-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / meson / meson_viu.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2016 BayLibre, SAS
4  * Author: Neil Armstrong <[email protected]>
5  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
6  * Copyright (C) 2014 Endless Mobile
7  */
8
9 #include <linux/export.h>
10 #include <linux/bitfield.h>
11
12 #include <drm/drm_fourcc.h>
13
14 #include "meson_drv.h"
15 #include "meson_viu.h"
16 #include "meson_registers.h"
17
18 /**
19  * DOC: Video Input Unit
20  *
21  * VIU Handles the Pixel scanout and the basic Colorspace conversions
22  * We handle the following features :
23  *
24  * - OSD1 RGB565/RGB888/xRGB8888 scanout
25  * - RGB conversion to x/cb/cr
26  * - Progressive or Interlace buffer scanout
27  * - OSD1 Commit on Vsync
28  * - HDR OSD matrix for GXL/GXM
29  *
30  * What is missing :
31  *
32  * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes
33  * - YUV4:2:2 Y0CbY1Cr scanout
34  * - Conversion to YUV 4:4:4 from 4:2:2 input
35  * - Colorkey Alpha matching
36  * - Big endian scanout
37  * - X/Y reverse scanout
38  * - Global alpha setup
39  * - OSD2 support, would need interlace switching on vsync
40  * - OSD1 full scaling to support TV overscan
41  */
42
43 /* OSD csc defines */
44
45 enum viu_matrix_sel_e {
46         VIU_MATRIX_OSD_EOTF = 0,
47         VIU_MATRIX_OSD,
48 };
49
50 enum viu_lut_sel_e {
51         VIU_LUT_OSD_EOTF = 0,
52         VIU_LUT_OSD_OETF,
53 };
54
55 #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
56 #define MATRIX_5X3_COEF_SIZE 24
57
58 #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
59 #define EOTF_COEFF_SIZE 10
60 #define EOTF_COEFF_RIGHTSHIFT 1
61
62 static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
63         0, 0, 0, /* pre offset */
64         COEFF_NORM(0.181873),   COEFF_NORM(0.611831),   COEFF_NORM(0.061765),
65         COEFF_NORM(-0.100251),  COEFF_NORM(-0.337249),  COEFF_NORM(0.437500),
66         COEFF_NORM(0.437500),   COEFF_NORM(-0.397384),  COEFF_NORM(-0.040116),
67         0, 0, 0, /* 10'/11'/12' */
68         0, 0, 0, /* 20'/21'/22' */
69         64, 512, 512, /* offset */
70         0, 0, 0 /* mode, right_shift, clip_en */
71 };
72
73 /*  eotf matrix: bypass */
74 static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
75         EOTF_COEFF_NORM(1.0),   EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(0.0),
76         EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(1.0),   EOTF_COEFF_NORM(0.0),
77         EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(0.0),   EOTF_COEFF_NORM(1.0),
78         EOTF_COEFF_RIGHTSHIFT /* right shift */
79 };
80
81 static void meson_viu_set_g12a_osd1_matrix(struct meson_drm *priv,
82                                            int *m, bool csc_on)
83 {
84         /* VPP WRAP OSD1 matrix */
85         writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
86                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET0_1));
87         writel(m[2] & 0xfff,
88                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_PRE_OFFSET2));
89         writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
90                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF00_01));
91         writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
92                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF02_10));
93         writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
94                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12));
95         writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
96                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21));
97         writel((m[11] & 0x1fff),
98                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22));
99
100         writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
101                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET0_1));
102         writel(m[20] & 0xfff,
103                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_OFFSET2));
104
105         writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0,
106                 priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
107 }
108
109 static void meson_viu_set_osd_matrix(struct meson_drm *priv,
110                                      enum viu_matrix_sel_e m_select,
111                               int *m, bool csc_on)
112 {
113         if (m_select == VIU_MATRIX_OSD) {
114                 /* osd matrix, VIU_MATRIX_0 */
115                 writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
116                         priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
117                 writel(m[2] & 0xfff,
118                         priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
119                 writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
120                         priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
121                 writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
122                         priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
123                 writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
124                         priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
125                 writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
126                         priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
127
128                 if (m[21]) {
129                         writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
130                                 priv->io_base +
131                                         _REG(VIU_OSD1_MATRIX_COEF22_30));
132                         writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
133                                 priv->io_base +
134                                         _REG(VIU_OSD1_MATRIX_COEF31_32));
135                         writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
136                                 priv->io_base +
137                                         _REG(VIU_OSD1_MATRIX_COEF40_41));
138                         writel(m[17] & 0x1fff, priv->io_base +
139                                 _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
140                 } else
141                         writel((m[11] & 0x1fff) << 16, priv->io_base +
142                                 _REG(VIU_OSD1_MATRIX_COEF22_30));
143
144                 writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
145                         priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
146                 writel(m[20] & 0xfff,
147                         priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
148
149                 writel_bits_relaxed(3 << 30, m[21] << 30,
150                         priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
151                 writel_bits_relaxed(7 << 16, m[22] << 16,
152                         priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
153
154                 /* 23 reserved for clipping control */
155                 writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0,
156                         priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
157                 writel_bits_relaxed(BIT(1), 0,
158                         priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
159         } else if (m_select == VIU_MATRIX_OSD_EOTF) {
160                 int i;
161
162                 /* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
163                 for (i = 0; i < 5; i++)
164                         writel(((m[i * 2] & 0x1fff) << 16) |
165                                 (m[i * 2 + 1] & 0x1fff), priv->io_base +
166                                 _REG(VIU_OSD1_EOTF_CTL + i + 1));
167
168                 writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0,
169                         priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
170                 writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0,
171                         priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
172         }
173 }
174
175 #define OSD_EOTF_LUT_SIZE 33
176 #define OSD_OETF_LUT_SIZE 41
177
178 static void
179 meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
180                       unsigned int *r_map, unsigned int *g_map,
181                       unsigned int *b_map, bool csc_on)
182 {
183         unsigned int addr_port;
184         unsigned int data_port;
185         unsigned int ctrl_port;
186         int i;
187
188         if (lut_sel == VIU_LUT_OSD_EOTF) {
189                 addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
190                 data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
191                 ctrl_port = VIU_OSD1_EOTF_CTL;
192         } else if (lut_sel == VIU_LUT_OSD_OETF) {
193                 addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
194                 data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
195                 ctrl_port = VIU_OSD1_OETF_CTL;
196         } else
197                 return;
198
199         if (lut_sel == VIU_LUT_OSD_OETF) {
200                 writel(0, priv->io_base + _REG(addr_port));
201
202                 for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
203                         writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
204                                 priv->io_base + _REG(data_port));
205
206                 writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
207                         priv->io_base + _REG(data_port));
208
209                 for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
210                         writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
211                                 priv->io_base + _REG(data_port));
212
213                 for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
214                         writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
215                                 priv->io_base + _REG(data_port));
216
217                 writel(b_map[OSD_OETF_LUT_SIZE - 1],
218                         priv->io_base + _REG(data_port));
219
220                 if (csc_on)
221                         writel_bits_relaxed(0x7 << 29, 7 << 29,
222                                             priv->io_base + _REG(ctrl_port));
223                 else
224                         writel_bits_relaxed(0x7 << 29, 0,
225                                             priv->io_base + _REG(ctrl_port));
226         } else if (lut_sel == VIU_LUT_OSD_EOTF) {
227                 writel(0, priv->io_base + _REG(addr_port));
228
229                 for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
230                         writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
231                                 priv->io_base + _REG(data_port));
232
233                 writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
234                         priv->io_base + _REG(data_port));
235
236                 for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
237                         writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
238                                 priv->io_base + _REG(data_port));
239
240                 for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
241                         writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
242                                 priv->io_base + _REG(data_port));
243
244                 writel(b_map[OSD_EOTF_LUT_SIZE - 1],
245                         priv->io_base + _REG(data_port));
246
247                 if (csc_on)
248                         writel_bits_relaxed(7 << 27, 7 << 27,
249                                             priv->io_base + _REG(ctrl_port));
250                 else
251                         writel_bits_relaxed(7 << 27, 0,
252                                             priv->io_base + _REG(ctrl_port));
253
254                 writel_bits_relaxed(BIT(31), BIT(31),
255                                     priv->io_base + _REG(ctrl_port));
256         }
257 }
258
259 /* eotf lut: linear */
260 static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
261         0x0000, 0x0200, 0x0400, 0x0600,
262         0x0800, 0x0a00, 0x0c00, 0x0e00,
263         0x1000, 0x1200, 0x1400, 0x1600,
264         0x1800, 0x1a00, 0x1c00, 0x1e00,
265         0x2000, 0x2200, 0x2400, 0x2600,
266         0x2800, 0x2a00, 0x2c00, 0x2e00,
267         0x3000, 0x3200, 0x3400, 0x3600,
268         0x3800, 0x3a00, 0x3c00, 0x3e00,
269         0x4000
270 };
271
272 /* osd oetf lut: linear */
273 static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
274         0, 0, 0, 0,
275         0, 32, 64, 96,
276         128, 160, 196, 224,
277         256, 288, 320, 352,
278         384, 416, 448, 480,
279         512, 544, 576, 608,
280         640, 672, 704, 736,
281         768, 800, 832, 864,
282         896, 928, 960, 992,
283         1023, 1023, 1023, 1023,
284         1023
285 };
286
287 static void meson_viu_load_matrix(struct meson_drm *priv)
288 {
289         /* eotf lut bypass */
290         meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
291                               eotf_33_linear_mapping, /* R */
292                               eotf_33_linear_mapping, /* G */
293                               eotf_33_linear_mapping, /* B */
294                               false);
295
296         /* eotf matrix bypass */
297         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
298                                  eotf_bypass_coeff,
299                                  false);
300
301         /* oetf lut bypass */
302         meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
303                               oetf_41_linear_mapping, /* R */
304                               oetf_41_linear_mapping, /* G */
305                               oetf_41_linear_mapping, /* B */
306                               false);
307
308         /* osd matrix RGB709 to YUV709 limit */
309         meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
310                                  RGB709_to_YUV709l_coeff,
311                                  true);
312 }
313
314 /* VIU OSD1 Reset as workaround for GXL+ Alpha OSD Bug */
315 void meson_viu_osd1_reset(struct meson_drm *priv)
316 {
317         uint32_t osd1_fifo_ctrl_stat, osd1_ctrl_stat2;
318
319         /* Save these 2 registers state */
320         osd1_fifo_ctrl_stat = readl_relaxed(
321                                 priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
322         osd1_ctrl_stat2 = readl_relaxed(
323                                 priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
324
325         /* Reset OSD1 */
326         writel_bits_relaxed(VIU_SW_RESET_OSD1, VIU_SW_RESET_OSD1,
327                             priv->io_base + _REG(VIU_SW_RESET));
328         writel_bits_relaxed(VIU_SW_RESET_OSD1, 0,
329                             priv->io_base + _REG(VIU_SW_RESET));
330
331         /* Rewrite these registers state lost in the reset */
332         writel_relaxed(osd1_fifo_ctrl_stat,
333                        priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
334         writel_relaxed(osd1_ctrl_stat2,
335                        priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
336
337         /* Reload the conversion matrix */
338         meson_viu_load_matrix(priv);
339 }
340
341 #define OSD1_MALI_ORDER_ABGR                            \
342         (FIELD_PREP(VIU_OSD1_MALI_AFBCD_A_REORDER,      \
343                     VIU_OSD1_MALI_REORDER_A) |          \
344          FIELD_PREP(VIU_OSD1_MALI_AFBCD_B_REORDER,      \
345                     VIU_OSD1_MALI_REORDER_B) |          \
346          FIELD_PREP(VIU_OSD1_MALI_AFBCD_G_REORDER,      \
347                     VIU_OSD1_MALI_REORDER_G) |          \
348          FIELD_PREP(VIU_OSD1_MALI_AFBCD_R_REORDER,      \
349                     VIU_OSD1_MALI_REORDER_R))
350
351 #define OSD1_MALI_ORDER_ARGB                            \
352         (FIELD_PREP(VIU_OSD1_MALI_AFBCD_A_REORDER,      \
353                     VIU_OSD1_MALI_REORDER_A) |          \
354          FIELD_PREP(VIU_OSD1_MALI_AFBCD_B_REORDER,      \
355                     VIU_OSD1_MALI_REORDER_R) |          \
356          FIELD_PREP(VIU_OSD1_MALI_AFBCD_G_REORDER,      \
357                     VIU_OSD1_MALI_REORDER_G) |          \
358          FIELD_PREP(VIU_OSD1_MALI_AFBCD_R_REORDER,      \
359                     VIU_OSD1_MALI_REORDER_B))
360
361 void meson_viu_g12a_enable_osd1_afbc(struct meson_drm *priv)
362 {
363         u32 afbc_order = OSD1_MALI_ORDER_ARGB;
364
365         /* Enable Mali AFBC Unpack */
366         writel_bits_relaxed(VIU_OSD1_MALI_UNPACK_EN,
367                             VIU_OSD1_MALI_UNPACK_EN,
368                             priv->io_base + _REG(VIU_OSD1_MALI_UNPACK_CTRL));
369
370         switch (priv->afbcd.format) {
371         case DRM_FORMAT_XBGR8888:
372         case DRM_FORMAT_ABGR8888:
373                 afbc_order = OSD1_MALI_ORDER_ABGR;
374                 break;
375         }
376
377         /* Setup RGBA Reordering */
378         writel_bits_relaxed(VIU_OSD1_MALI_AFBCD_A_REORDER |
379                             VIU_OSD1_MALI_AFBCD_B_REORDER |
380                             VIU_OSD1_MALI_AFBCD_G_REORDER |
381                             VIU_OSD1_MALI_AFBCD_R_REORDER,
382                             afbc_order,
383                             priv->io_base + _REG(VIU_OSD1_MALI_UNPACK_CTRL));
384
385         /* Select AFBCD path for OSD1 */
386         writel_bits_relaxed(OSD_PATH_OSD_AXI_SEL_OSD1_AFBCD,
387                             OSD_PATH_OSD_AXI_SEL_OSD1_AFBCD,
388                             priv->io_base + _REG(OSD_PATH_MISC_CTRL));
389 }
390
391 void meson_viu_g12a_disable_osd1_afbc(struct meson_drm *priv)
392 {
393         /* Disable AFBCD path for OSD1 */
394         writel_bits_relaxed(OSD_PATH_OSD_AXI_SEL_OSD1_AFBCD, 0,
395                             priv->io_base + _REG(OSD_PATH_MISC_CTRL));
396
397         /* Disable AFBCD unpack */
398         writel_bits_relaxed(VIU_OSD1_MALI_UNPACK_EN, 0,
399                             priv->io_base + _REG(VIU_OSD1_MALI_UNPACK_CTRL));
400 }
401
402 void meson_viu_gxm_enable_osd1_afbc(struct meson_drm *priv)
403 {
404         writel_bits_relaxed(MALI_AFBC_MISC, FIELD_PREP(MALI_AFBC_MISC, 0x90),
405                             priv->io_base + _REG(VIU_MISC_CTRL1));
406 }
407
408 void meson_viu_gxm_disable_osd1_afbc(struct meson_drm *priv)
409 {
410         writel_bits_relaxed(MALI_AFBC_MISC, FIELD_PREP(MALI_AFBC_MISC, 0x00),
411                             priv->io_base + _REG(VIU_MISC_CTRL1));
412 }
413
414 void meson_viu_init(struct meson_drm *priv)
415 {
416         uint32_t reg;
417
418         /* Disable OSDs */
419         writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
420                             priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
421         writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
422                             priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
423
424         /* On GXL/GXM, Use the 10bit HDR conversion matrix */
425         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
426             meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
427                 meson_viu_load_matrix(priv);
428         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
429                 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
430                                                true);
431                 /* fix green/pink color distortion from vendor u-boot */
432                 writel_bits_relaxed(OSD1_HDR2_CTRL_REG_ONLY_MAT |
433                                 OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN, 0,
434                                 priv->io_base + _REG(OSD1_HDR2_CTRL));
435         }
436
437         /* Initialize OSD1 fifo control register */
438         reg = VIU_OSD_DDR_PRIORITY_URGENT |
439                 VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
440                 VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
441                 VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
442
443         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
444                 reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
445         else
446                 reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));
447
448         writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
449         writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
450
451         /* Set OSD alpha replace value */
452         writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
453                             0xff << OSD_REPLACE_SHIFT,
454                             priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
455         writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
456                             0xff << OSD_REPLACE_SHIFT,
457                             priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
458
459         /* Disable VD1 AFBC */
460         /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
461         writel_bits_relaxed(VIU_CTRL0_VD1_AFBC_MASK, 0,
462                             priv->io_base + _REG(VIU_MISC_CTRL0));
463         writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));
464
465         writel_relaxed(0x00FF00C0,
466                         priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
467         writel_relaxed(0x00FF00C0,
468                         priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
469
470         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
471                 u32 val = (u32)VIU_OSD_BLEND_REORDER(0, 1) |
472                           (u32)VIU_OSD_BLEND_REORDER(1, 0) |
473                           (u32)VIU_OSD_BLEND_REORDER(2, 0) |
474                           (u32)VIU_OSD_BLEND_REORDER(3, 0) |
475                           (u32)VIU_OSD_BLEND_DIN_EN(1) |
476                           (u32)VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
477                           (u32)VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
478                           (u32)VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
479                           (u32)VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
480                           (u32)VIU_OSD_BLEND_HOLD_LINES(4);
481                 writel_relaxed(val, priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
482
483                 writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
484                                priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
485                 writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
486                                priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
487                 writel_relaxed(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
488                 writel_relaxed(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
489                 writel_relaxed(0,
490                                 priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
491                 writel_relaxed(0,
492                                 priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
493
494                 writel_bits_relaxed(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
495                                     priv->io_base + _REG(DOLBY_PATH_CTRL));
496
497                 meson_viu_g12a_disable_osd1_afbc(priv);
498         }
499
500         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM))
501                 meson_viu_gxm_disable_osd1_afbc(priv);
502
503         priv->viu.osd1_enabled = false;
504         priv->viu.osd1_commit = false;
505         priv->viu.osd1_interlace = false;
506 }
This page took 0.060965 seconds and 4 git commands to generate.