]> Git Repo - linux.git/blob - drivers/gpu/drm/meson/meson_viu.c
Merge tag 'v5.6-rc3' into sched/core, to pick up fixes and dependent patches
[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) << 16,
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 static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
415 {
416         uint32_t val = (((length & 0x80) % 24) / 12);
417
418         return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
419 }
420
421 void meson_viu_init(struct meson_drm *priv)
422 {
423         uint32_t reg;
424
425         /* Disable OSDs */
426         writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
427                             priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
428         writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
429                             priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
430
431         /* On GXL/GXM, Use the 10bit HDR conversion matrix */
432         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
433             meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
434                 meson_viu_load_matrix(priv);
435         else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
436                 meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
437                                                true);
438
439         /* Initialize OSD1 fifo control register */
440         reg = VIU_OSD_DDR_PRIORITY_URGENT |
441                 VIU_OSD_HOLD_FIFO_LINES(31) |
442                 VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
443                 VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
444                 VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
445
446         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
447                 reg |= meson_viu_osd_burst_length_reg(32);
448         else
449                 reg |= meson_viu_osd_burst_length_reg(64);
450
451         writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
452         writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
453
454         /* Set OSD alpha replace value */
455         writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
456                             0xff << OSD_REPLACE_SHIFT,
457                             priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
458         writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
459                             0xff << OSD_REPLACE_SHIFT,
460                             priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
461
462         /* Disable VD1 AFBC */
463         /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
464         writel_bits_relaxed(VIU_CTRL0_VD1_AFBC_MASK, 0,
465                             priv->io_base + _REG(VIU_MISC_CTRL0));
466         writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));
467
468         writel_relaxed(0x00FF00C0,
469                         priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
470         writel_relaxed(0x00FF00C0,
471                         priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
472
473         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
474                 writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
475                                VIU_OSD_BLEND_REORDER(1, 0) |
476                                VIU_OSD_BLEND_REORDER(2, 0) |
477                                VIU_OSD_BLEND_REORDER(3, 0) |
478                                VIU_OSD_BLEND_DIN_EN(1) |
479                                VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
480                                VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
481                                VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
482                                VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
483                                VIU_OSD_BLEND_HOLD_LINES(4),
484                                priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
485
486                 writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
487                                priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
488                 writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
489                                priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
490                 writel_relaxed(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
491                 writel_relaxed(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
492                 writel_relaxed(0,
493                                 priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
494                 writel_relaxed(0,
495                                 priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
496
497                 writel_bits_relaxed(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
498                                     priv->io_base + _REG(DOLBY_PATH_CTRL));
499
500                 meson_viu_g12a_disable_osd1_afbc(priv);
501         }
502
503         if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM))
504                 meson_viu_gxm_disable_osd1_afbc(priv);
505
506         priv->viu.osd1_enabled = false;
507         priv->viu.osd1_commit = false;
508         priv->viu.osd1_interlace = false;
509 }
This page took 0.063204 seconds and 4 git commands to generate.