xref: /openbmc/linux/drivers/gpu/drm/meson/meson_viu.c (revision f9a23481)
1bbbe775eSNeil Armstrong /*
2bbbe775eSNeil Armstrong  * Copyright (C) 2016 BayLibre, SAS
3bbbe775eSNeil Armstrong  * Author: Neil Armstrong <narmstrong@baylibre.com>
4bbbe775eSNeil Armstrong  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5bbbe775eSNeil Armstrong  * Copyright (C) 2014 Endless Mobile
6bbbe775eSNeil Armstrong  *
7bbbe775eSNeil Armstrong  * This program is free software; you can redistribute it and/or
8bbbe775eSNeil Armstrong  * modify it under the terms of the GNU General Public License as
9bbbe775eSNeil Armstrong  * published by the Free Software Foundation; either version 2 of the
10bbbe775eSNeil Armstrong  * License, or (at your option) any later version.
11bbbe775eSNeil Armstrong  *
12bbbe775eSNeil Armstrong  * This program is distributed in the hope that it will be useful, but
13bbbe775eSNeil Armstrong  * WITHOUT ANY WARRANTY; without even the implied warranty of
14bbbe775eSNeil Armstrong  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15bbbe775eSNeil Armstrong  * General Public License for more details.
16bbbe775eSNeil Armstrong  *
17bbbe775eSNeil Armstrong  * You should have received a copy of the GNU General Public License
18bbbe775eSNeil Armstrong  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19bbbe775eSNeil Armstrong  */
20bbbe775eSNeil Armstrong 
21bbbe775eSNeil Armstrong #include <linux/kernel.h>
22bbbe775eSNeil Armstrong #include <linux/module.h>
23bbbe775eSNeil Armstrong #include <drm/drmP.h>
24bbbe775eSNeil Armstrong #include "meson_drv.h"
25bbbe775eSNeil Armstrong #include "meson_viu.h"
26bbbe775eSNeil Armstrong #include "meson_vpp.h"
27bbbe775eSNeil Armstrong #include "meson_venc.h"
28bbbe775eSNeil Armstrong #include "meson_canvas.h"
29bbbe775eSNeil Armstrong #include "meson_registers.h"
30bbbe775eSNeil Armstrong 
312021d5b7SNeil Armstrong /**
322021d5b7SNeil Armstrong  * DOC: Video Input Unit
332021d5b7SNeil Armstrong  *
34bbbe775eSNeil Armstrong  * VIU Handles the Pixel scanout and the basic Colorspace conversions
35bbbe775eSNeil Armstrong  * We handle the following features :
362021d5b7SNeil Armstrong  *
37bbbe775eSNeil Armstrong  * - OSD1 RGB565/RGB888/xRGB8888 scanout
38bbbe775eSNeil Armstrong  * - RGB conversion to x/cb/cr
39bbbe775eSNeil Armstrong  * - Progressive or Interlace buffer scanout
40bbbe775eSNeil Armstrong  * - OSD1 Commit on Vsync
41bbbe775eSNeil Armstrong  * - HDR OSD matrix for GXL/GXM
42bbbe775eSNeil Armstrong  *
43bbbe775eSNeil Armstrong  * What is missing :
442021d5b7SNeil Armstrong  *
45bbbe775eSNeil Armstrong  * - BGR888/xBGR8888/BGRx8888/BGRx8888 modes
46bbbe775eSNeil Armstrong  * - YUV4:2:2 Y0CbY1Cr scanout
47bbbe775eSNeil Armstrong  * - Conversion to YUV 4:4:4 from 4:2:2 input
48bbbe775eSNeil Armstrong  * - Colorkey Alpha matching
49bbbe775eSNeil Armstrong  * - Big endian scanout
50bbbe775eSNeil Armstrong  * - X/Y reverse scanout
51bbbe775eSNeil Armstrong  * - Global alpha setup
52bbbe775eSNeil Armstrong  * - OSD2 support, would need interlace switching on vsync
53bbbe775eSNeil Armstrong  * - OSD1 full scaling to support TV overscan
54bbbe775eSNeil Armstrong  */
55bbbe775eSNeil Armstrong 
56bbbe775eSNeil Armstrong /* OSD csc defines */
57bbbe775eSNeil Armstrong 
58bbbe775eSNeil Armstrong enum viu_matrix_sel_e {
59bbbe775eSNeil Armstrong 	VIU_MATRIX_OSD_EOTF = 0,
60bbbe775eSNeil Armstrong 	VIU_MATRIX_OSD,
61bbbe775eSNeil Armstrong };
62bbbe775eSNeil Armstrong 
63bbbe775eSNeil Armstrong enum viu_lut_sel_e {
64bbbe775eSNeil Armstrong 	VIU_LUT_OSD_EOTF = 0,
65bbbe775eSNeil Armstrong 	VIU_LUT_OSD_OETF,
66bbbe775eSNeil Armstrong };
67bbbe775eSNeil Armstrong 
68bbbe775eSNeil Armstrong #define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
69bbbe775eSNeil Armstrong #define MATRIX_5X3_COEF_SIZE 24
70bbbe775eSNeil Armstrong 
71bbbe775eSNeil Armstrong #define EOTF_COEFF_NORM(a) ((int)((((a) * 4096.0) + 1) / 2))
72bbbe775eSNeil Armstrong #define EOTF_COEFF_SIZE 10
73bbbe775eSNeil Armstrong #define EOTF_COEFF_RIGHTSHIFT 1
74bbbe775eSNeil Armstrong 
75bbbe775eSNeil Armstrong static int RGB709_to_YUV709l_coeff[MATRIX_5X3_COEF_SIZE] = {
76bbbe775eSNeil Armstrong 	0, 0, 0, /* pre offset */
77bbbe775eSNeil Armstrong 	COEFF_NORM(0.181873),	COEFF_NORM(0.611831),	COEFF_NORM(0.061765),
78bbbe775eSNeil Armstrong 	COEFF_NORM(-0.100251),	COEFF_NORM(-0.337249),	COEFF_NORM(0.437500),
79bbbe775eSNeil Armstrong 	COEFF_NORM(0.437500),	COEFF_NORM(-0.397384),	COEFF_NORM(-0.040116),
80bbbe775eSNeil Armstrong 	0, 0, 0, /* 10'/11'/12' */
81bbbe775eSNeil Armstrong 	0, 0, 0, /* 20'/21'/22' */
82bbbe775eSNeil Armstrong 	64, 512, 512, /* offset */
83bbbe775eSNeil Armstrong 	0, 0, 0 /* mode, right_shift, clip_en */
84bbbe775eSNeil Armstrong };
85bbbe775eSNeil Armstrong 
86bbbe775eSNeil Armstrong /*  eotf matrix: bypass */
87bbbe775eSNeil Armstrong static int eotf_bypass_coeff[EOTF_COEFF_SIZE] = {
88bbbe775eSNeil Armstrong 	EOTF_COEFF_NORM(1.0),	EOTF_COEFF_NORM(0.0),	EOTF_COEFF_NORM(0.0),
89bbbe775eSNeil Armstrong 	EOTF_COEFF_NORM(0.0),	EOTF_COEFF_NORM(1.0),	EOTF_COEFF_NORM(0.0),
90bbbe775eSNeil Armstrong 	EOTF_COEFF_NORM(0.0),	EOTF_COEFF_NORM(0.0),	EOTF_COEFF_NORM(1.0),
91bbbe775eSNeil Armstrong 	EOTF_COEFF_RIGHTSHIFT /* right shift */
92bbbe775eSNeil Armstrong };
93bbbe775eSNeil Armstrong 
94bbbe775eSNeil Armstrong void meson_viu_set_osd_matrix(struct meson_drm *priv,
95bbbe775eSNeil Armstrong 			      enum viu_matrix_sel_e m_select,
96bbbe775eSNeil Armstrong 			      int *m, bool csc_on)
97bbbe775eSNeil Armstrong {
98bbbe775eSNeil Armstrong 	if (m_select == VIU_MATRIX_OSD) {
99bbbe775eSNeil Armstrong 		/* osd matrix, VIU_MATRIX_0 */
100bbbe775eSNeil Armstrong 		writel(((m[0] & 0xfff) << 16) | (m[1] & 0xfff),
101bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET0_1));
102bbbe775eSNeil Armstrong 		writel(m[2] & 0xfff,
103bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_PRE_OFFSET2));
104bbbe775eSNeil Armstrong 		writel(((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff),
105bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COEF00_01));
106bbbe775eSNeil Armstrong 		writel(((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff),
107bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COEF02_10));
108bbbe775eSNeil Armstrong 		writel(((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff),
109bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COEF11_12));
110bbbe775eSNeil Armstrong 		writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff),
111bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COEF20_21));
112bbbe775eSNeil Armstrong 
113bbbe775eSNeil Armstrong 		if (m[21]) {
114bbbe775eSNeil Armstrong 			writel(((m[11] & 0x1fff) << 16) | (m[12] & 0x1fff),
115bbbe775eSNeil Armstrong 				priv->io_base +
116bbbe775eSNeil Armstrong 					_REG(VIU_OSD1_MATRIX_COEF22_30));
117bbbe775eSNeil Armstrong 			writel(((m[13] & 0x1fff) << 16) | (m[14] & 0x1fff),
118bbbe775eSNeil Armstrong 				priv->io_base +
119bbbe775eSNeil Armstrong 					_REG(VIU_OSD1_MATRIX_COEF31_32));
120bbbe775eSNeil Armstrong 			writel(((m[15] & 0x1fff) << 16) | (m[16] & 0x1fff),
121bbbe775eSNeil Armstrong 				priv->io_base +
122bbbe775eSNeil Armstrong 					_REG(VIU_OSD1_MATRIX_COEF40_41));
123bbbe775eSNeil Armstrong 			writel(m[17] & 0x1fff, priv->io_base +
124bbbe775eSNeil Armstrong 				_REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
125bbbe775eSNeil Armstrong 		} else
126bbbe775eSNeil Armstrong 			writel((m[11] & 0x1fff) << 16, priv->io_base +
127bbbe775eSNeil Armstrong 				_REG(VIU_OSD1_MATRIX_COEF22_30));
128bbbe775eSNeil Armstrong 
129bbbe775eSNeil Armstrong 		writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff),
130bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET0_1));
131bbbe775eSNeil Armstrong 		writel(m[20] & 0xfff,
132bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_OFFSET2));
133bbbe775eSNeil Armstrong 
134bbbe775eSNeil Armstrong 		writel_bits_relaxed(3 << 30, m[21] << 30,
135bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
136bbbe775eSNeil Armstrong 		writel_bits_relaxed(7 << 16, m[22] << 16,
137bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_COLMOD_COEF42));
138bbbe775eSNeil Armstrong 
139bbbe775eSNeil Armstrong 		/* 23 reserved for clipping control */
140bbbe775eSNeil Armstrong 		writel_bits_relaxed(BIT(0), csc_on ? BIT(0) : 0,
141bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
142bbbe775eSNeil Armstrong 		writel_bits_relaxed(BIT(1), 0,
143bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_MATRIX_CTRL));
144bbbe775eSNeil Armstrong 	} else if (m_select == VIU_MATRIX_OSD_EOTF) {
145bbbe775eSNeil Armstrong 		int i;
146bbbe775eSNeil Armstrong 
147bbbe775eSNeil Armstrong 		/* osd eotf matrix, VIU_MATRIX_OSD_EOTF */
148bbbe775eSNeil Armstrong 		for (i = 0; i < 5; i++)
149bbbe775eSNeil Armstrong 			writel(((m[i * 2] & 0x1fff) << 16) |
150bbbe775eSNeil Armstrong 				(m[i * 2 + 1] & 0x1fff), priv->io_base +
151bbbe775eSNeil Armstrong 				_REG(VIU_OSD1_EOTF_CTL + i + 1));
152bbbe775eSNeil Armstrong 
153bbbe775eSNeil Armstrong 		writel_bits_relaxed(BIT(30), csc_on ? BIT(30) : 0,
154bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
155bbbe775eSNeil Armstrong 		writel_bits_relaxed(BIT(31), csc_on ? BIT(31) : 0,
156bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_EOTF_CTL));
157bbbe775eSNeil Armstrong 	}
158bbbe775eSNeil Armstrong }
159bbbe775eSNeil Armstrong 
160bbbe775eSNeil Armstrong #define OSD_EOTF_LUT_SIZE 33
161bbbe775eSNeil Armstrong #define OSD_OETF_LUT_SIZE 41
162bbbe775eSNeil Armstrong 
163bbbe775eSNeil Armstrong void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
164bbbe775eSNeil Armstrong 			   unsigned int *r_map, unsigned int *g_map,
165bbbe775eSNeil Armstrong 			   unsigned int *b_map,
166bbbe775eSNeil Armstrong 			   bool csc_on)
167bbbe775eSNeil Armstrong {
168bbbe775eSNeil Armstrong 	unsigned int addr_port;
169bbbe775eSNeil Armstrong 	unsigned int data_port;
170bbbe775eSNeil Armstrong 	unsigned int ctrl_port;
171bbbe775eSNeil Armstrong 	int i;
172bbbe775eSNeil Armstrong 
173bbbe775eSNeil Armstrong 	if (lut_sel == VIU_LUT_OSD_EOTF) {
174bbbe775eSNeil Armstrong 		addr_port = VIU_OSD1_EOTF_LUT_ADDR_PORT;
175bbbe775eSNeil Armstrong 		data_port = VIU_OSD1_EOTF_LUT_DATA_PORT;
176bbbe775eSNeil Armstrong 		ctrl_port = VIU_OSD1_EOTF_CTL;
177bbbe775eSNeil Armstrong 	} else if (lut_sel == VIU_LUT_OSD_OETF) {
178bbbe775eSNeil Armstrong 		addr_port = VIU_OSD1_OETF_LUT_ADDR_PORT;
179bbbe775eSNeil Armstrong 		data_port = VIU_OSD1_OETF_LUT_DATA_PORT;
180bbbe775eSNeil Armstrong 		ctrl_port = VIU_OSD1_OETF_CTL;
181bbbe775eSNeil Armstrong 	} else
182bbbe775eSNeil Armstrong 		return;
183bbbe775eSNeil Armstrong 
184bbbe775eSNeil Armstrong 	if (lut_sel == VIU_LUT_OSD_OETF) {
185bbbe775eSNeil Armstrong 		writel(0, priv->io_base + _REG(addr_port));
186bbbe775eSNeil Armstrong 
187bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
188bbbe775eSNeil Armstrong 			writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
189bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
190bbbe775eSNeil Armstrong 
191bbbe775eSNeil Armstrong 		writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
192bbbe775eSNeil Armstrong 			priv->io_base + _REG(data_port));
193bbbe775eSNeil Armstrong 
194bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
195bbbe775eSNeil Armstrong 			writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
196bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
197bbbe775eSNeil Armstrong 
198bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
199bbbe775eSNeil Armstrong 			writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
200bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
201bbbe775eSNeil Armstrong 
202bbbe775eSNeil Armstrong 		writel(b_map[OSD_OETF_LUT_SIZE - 1],
203bbbe775eSNeil Armstrong 			priv->io_base + _REG(data_port));
204bbbe775eSNeil Armstrong 
205bbbe775eSNeil Armstrong 		if (csc_on)
206bbbe775eSNeil Armstrong 			writel_bits_relaxed(0x7 << 29, 7 << 29,
207bbbe775eSNeil Armstrong 					    priv->io_base + _REG(ctrl_port));
208bbbe775eSNeil Armstrong 		else
209bbbe775eSNeil Armstrong 			writel_bits_relaxed(0x7 << 29, 0,
210bbbe775eSNeil Armstrong 					    priv->io_base + _REG(ctrl_port));
211bbbe775eSNeil Armstrong 	} else if (lut_sel == VIU_LUT_OSD_EOTF) {
212bbbe775eSNeil Armstrong 		writel(0, priv->io_base + _REG(addr_port));
213bbbe775eSNeil Armstrong 
214bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
215bbbe775eSNeil Armstrong 			writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
216bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
217bbbe775eSNeil Armstrong 
218bbbe775eSNeil Armstrong 		writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
219bbbe775eSNeil Armstrong 			priv->io_base + _REG(data_port));
220bbbe775eSNeil Armstrong 
221bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
222bbbe775eSNeil Armstrong 			writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
223bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
224bbbe775eSNeil Armstrong 
225bbbe775eSNeil Armstrong 		for (i = 0; i < 20; i++)
226bbbe775eSNeil Armstrong 			writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
227bbbe775eSNeil Armstrong 				priv->io_base + _REG(data_port));
228bbbe775eSNeil Armstrong 
229bbbe775eSNeil Armstrong 		writel(b_map[OSD_EOTF_LUT_SIZE - 1],
230bbbe775eSNeil Armstrong 			priv->io_base + _REG(data_port));
231bbbe775eSNeil Armstrong 
232bbbe775eSNeil Armstrong 		if (csc_on)
233bbbe775eSNeil Armstrong 			writel_bits_relaxed(7 << 27, 7 << 27,
234bbbe775eSNeil Armstrong 					    priv->io_base + _REG(ctrl_port));
235bbbe775eSNeil Armstrong 		else
236bbbe775eSNeil Armstrong 			writel_bits_relaxed(7 << 27, 0,
237bbbe775eSNeil Armstrong 					    priv->io_base + _REG(ctrl_port));
238bbbe775eSNeil Armstrong 
239bbbe775eSNeil Armstrong 		writel_bits_relaxed(BIT(31), BIT(31),
240bbbe775eSNeil Armstrong 				    priv->io_base + _REG(ctrl_port));
241bbbe775eSNeil Armstrong 	}
242bbbe775eSNeil Armstrong }
243bbbe775eSNeil Armstrong 
244bbbe775eSNeil Armstrong /* eotf lut: linear */
245bbbe775eSNeil Armstrong static unsigned int eotf_33_linear_mapping[OSD_EOTF_LUT_SIZE] = {
246bbbe775eSNeil Armstrong 	0x0000,	0x0200,	0x0400, 0x0600,
247bbbe775eSNeil Armstrong 	0x0800, 0x0a00, 0x0c00, 0x0e00,
248bbbe775eSNeil Armstrong 	0x1000, 0x1200, 0x1400, 0x1600,
249bbbe775eSNeil Armstrong 	0x1800, 0x1a00, 0x1c00, 0x1e00,
250bbbe775eSNeil Armstrong 	0x2000, 0x2200, 0x2400, 0x2600,
251bbbe775eSNeil Armstrong 	0x2800, 0x2a00, 0x2c00, 0x2e00,
252bbbe775eSNeil Armstrong 	0x3000, 0x3200, 0x3400, 0x3600,
253bbbe775eSNeil Armstrong 	0x3800, 0x3a00, 0x3c00, 0x3e00,
254bbbe775eSNeil Armstrong 	0x4000
255bbbe775eSNeil Armstrong };
256bbbe775eSNeil Armstrong 
257bbbe775eSNeil Armstrong /* osd oetf lut: linear */
258bbbe775eSNeil Armstrong static unsigned int oetf_41_linear_mapping[OSD_OETF_LUT_SIZE] = {
259bbbe775eSNeil Armstrong 	0, 0, 0, 0,
260bbbe775eSNeil Armstrong 	0, 32, 64, 96,
261bbbe775eSNeil Armstrong 	128, 160, 196, 224,
262bbbe775eSNeil Armstrong 	256, 288, 320, 352,
263bbbe775eSNeil Armstrong 	384, 416, 448, 480,
264bbbe775eSNeil Armstrong 	512, 544, 576, 608,
265bbbe775eSNeil Armstrong 	640, 672, 704, 736,
266bbbe775eSNeil Armstrong 	768, 800, 832, 864,
267bbbe775eSNeil Armstrong 	896, 928, 960, 992,
268bbbe775eSNeil Armstrong 	1023, 1023, 1023, 1023,
269bbbe775eSNeil Armstrong 	1023
270bbbe775eSNeil Armstrong };
271bbbe775eSNeil Armstrong 
272bbbe775eSNeil Armstrong static void meson_viu_load_matrix(struct meson_drm *priv)
273bbbe775eSNeil Armstrong {
274bbbe775eSNeil Armstrong 	/* eotf lut bypass */
275bbbe775eSNeil Armstrong 	meson_viu_set_osd_lut(priv, VIU_LUT_OSD_EOTF,
276bbbe775eSNeil Armstrong 			      eotf_33_linear_mapping, /* R */
277bbbe775eSNeil Armstrong 			      eotf_33_linear_mapping, /* G */
278bbbe775eSNeil Armstrong 			      eotf_33_linear_mapping, /* B */
279bbbe775eSNeil Armstrong 			      false);
280bbbe775eSNeil Armstrong 
281bbbe775eSNeil Armstrong 	/* eotf matrix bypass */
282bbbe775eSNeil Armstrong 	meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD_EOTF,
283bbbe775eSNeil Armstrong 				 eotf_bypass_coeff,
284bbbe775eSNeil Armstrong 				 false);
285bbbe775eSNeil Armstrong 
286bbbe775eSNeil Armstrong 	/* oetf lut bypass */
287bbbe775eSNeil Armstrong 	meson_viu_set_osd_lut(priv, VIU_LUT_OSD_OETF,
288bbbe775eSNeil Armstrong 			      oetf_41_linear_mapping, /* R */
289bbbe775eSNeil Armstrong 			      oetf_41_linear_mapping, /* G */
290bbbe775eSNeil Armstrong 			      oetf_41_linear_mapping, /* B */
291bbbe775eSNeil Armstrong 			      false);
292bbbe775eSNeil Armstrong 
293bbbe775eSNeil Armstrong 	/* osd matrix RGB709 to YUV709 limit */
294bbbe775eSNeil Armstrong 	meson_viu_set_osd_matrix(priv, VIU_MATRIX_OSD,
295bbbe775eSNeil Armstrong 				 RGB709_to_YUV709l_coeff,
296bbbe775eSNeil Armstrong 				 true);
297bbbe775eSNeil Armstrong }
298bbbe775eSNeil Armstrong 
299bbbe775eSNeil Armstrong void meson_viu_init(struct meson_drm *priv)
300bbbe775eSNeil Armstrong {
301bbbe775eSNeil Armstrong 	uint32_t reg;
302bbbe775eSNeil Armstrong 
303bbbe775eSNeil Armstrong 	/* Disable OSDs */
304bbbe775eSNeil Armstrong 	writel_bits_relaxed(BIT(0) | BIT(21), 0,
305bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
306bbbe775eSNeil Armstrong 	writel_bits_relaxed(BIT(0) | BIT(21), 0,
307bbbe775eSNeil Armstrong 			priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
308bbbe775eSNeil Armstrong 
309bbbe775eSNeil Armstrong 	/* On GXL/GXM, Use the 10bit HDR conversion matrix */
310bbbe775eSNeil Armstrong 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
311bbbe775eSNeil Armstrong 	    meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
312bbbe775eSNeil Armstrong 		meson_viu_load_matrix(priv);
313bbbe775eSNeil Armstrong 
314bbbe775eSNeil Armstrong 	/* Initialize OSD1 fifo control register */
315bbbe775eSNeil Armstrong 	reg = BIT(0) |	/* Urgent DDR request priority */
316bbbe775eSNeil Armstrong 	      (4 << 5) | /* hold_fifo_lines */
317bbbe775eSNeil Armstrong 	      (3 << 10) | /* burst length 64 */
318bbbe775eSNeil Armstrong 	      (32 << 12) | /* fifo_depth_val: 32*8=256 */
319bbbe775eSNeil Armstrong 	      (2 << 22) | /* 4 words in 1 burst */
320bbbe775eSNeil Armstrong 	      (2 << 24);
321bbbe775eSNeil Armstrong 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
322bbbe775eSNeil Armstrong 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
323bbbe775eSNeil Armstrong 
324bbbe775eSNeil Armstrong 	/* Set OSD alpha replace value */
325bbbe775eSNeil Armstrong 	writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
326bbbe775eSNeil Armstrong 			    0xff << OSD_REPLACE_SHIFT,
327bbbe775eSNeil Armstrong 			    priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
328bbbe775eSNeil Armstrong 	writel_bits_relaxed(0xff << OSD_REPLACE_SHIFT,
329bbbe775eSNeil Armstrong 			    0xff << OSD_REPLACE_SHIFT,
330bbbe775eSNeil Armstrong 			    priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
331bbbe775eSNeil Armstrong 
332f9a23481SNeil Armstrong 	/* Disable VD1 AFBC */
333f9a23481SNeil Armstrong 	/* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 */
334f9a23481SNeil Armstrong 	writel_bits_relaxed(0x7 << 16, 0,
335f9a23481SNeil Armstrong 			priv->io_base + _REG(VIU_MISC_CTRL0));
336f9a23481SNeil Armstrong 	/* afbc vd1 set=0 */
337f9a23481SNeil Armstrong 	writel_bits_relaxed(BIT(20), 0,
338f9a23481SNeil Armstrong 			priv->io_base + _REG(VIU_MISC_CTRL0));
339f9a23481SNeil Armstrong 	writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));
340f9a23481SNeil Armstrong 
341f9a23481SNeil Armstrong 	writel_relaxed(0x00FF00C0,
342f9a23481SNeil Armstrong 			priv->io_base + _REG(VD1_IF0_LUMA_FIFO_SIZE));
343f9a23481SNeil Armstrong 	writel_relaxed(0x00FF00C0,
344f9a23481SNeil Armstrong 			priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
345f9a23481SNeil Armstrong 
346f9a23481SNeil Armstrong 
347bbbe775eSNeil Armstrong 	priv->viu.osd1_enabled = false;
348bbbe775eSNeil Armstrong 	priv->viu.osd1_commit = false;
349bbbe775eSNeil Armstrong 	priv->viu.osd1_interlace = false;
350bbbe775eSNeil Armstrong }
351