xref: /OK3568_Linux_fs/kernel/drivers/gpu/ipu-v3/ipu-cpmem.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2012 Mentor Graphics Inc.
4*4882a593Smuzhiyun  * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun #include <linux/types.h>
7*4882a593Smuzhiyun #include <linux/bitrev.h>
8*4882a593Smuzhiyun #include <linux/io.h>
9*4882a593Smuzhiyun #include <linux/sizes.h>
10*4882a593Smuzhiyun #include <drm/drm_fourcc.h>
11*4882a593Smuzhiyun #include "ipu-prv.h"
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun struct ipu_cpmem_word {
14*4882a593Smuzhiyun 	u32 data[5];
15*4882a593Smuzhiyun 	u32 res[3];
16*4882a593Smuzhiyun };
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun struct ipu_ch_param {
19*4882a593Smuzhiyun 	struct ipu_cpmem_word word[2];
20*4882a593Smuzhiyun };
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct ipu_cpmem {
23*4882a593Smuzhiyun 	struct ipu_ch_param __iomem *base;
24*4882a593Smuzhiyun 	u32 module;
25*4882a593Smuzhiyun 	spinlock_t lock;
26*4882a593Smuzhiyun 	int use_count;
27*4882a593Smuzhiyun 	struct ipu_soc *ipu;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size))
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #define IPU_FIELD_UBO		IPU_CPMEM_WORD(0, 46, 22)
33*4882a593Smuzhiyun #define IPU_FIELD_VBO		IPU_CPMEM_WORD(0, 68, 22)
34*4882a593Smuzhiyun #define IPU_FIELD_IOX		IPU_CPMEM_WORD(0, 90, 4)
35*4882a593Smuzhiyun #define IPU_FIELD_RDRW		IPU_CPMEM_WORD(0, 94, 1)
36*4882a593Smuzhiyun #define IPU_FIELD_SO		IPU_CPMEM_WORD(0, 113, 1)
37*4882a593Smuzhiyun #define IPU_FIELD_SLY		IPU_CPMEM_WORD(1, 102, 14)
38*4882a593Smuzhiyun #define IPU_FIELD_SLUV		IPU_CPMEM_WORD(1, 128, 14)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define IPU_FIELD_XV		IPU_CPMEM_WORD(0, 0, 10)
41*4882a593Smuzhiyun #define IPU_FIELD_YV		IPU_CPMEM_WORD(0, 10, 9)
42*4882a593Smuzhiyun #define IPU_FIELD_XB		IPU_CPMEM_WORD(0, 19, 13)
43*4882a593Smuzhiyun #define IPU_FIELD_YB		IPU_CPMEM_WORD(0, 32, 12)
44*4882a593Smuzhiyun #define IPU_FIELD_NSB_B		IPU_CPMEM_WORD(0, 44, 1)
45*4882a593Smuzhiyun #define IPU_FIELD_CF		IPU_CPMEM_WORD(0, 45, 1)
46*4882a593Smuzhiyun #define IPU_FIELD_SX		IPU_CPMEM_WORD(0, 46, 12)
47*4882a593Smuzhiyun #define IPU_FIELD_SY		IPU_CPMEM_WORD(0, 58, 11)
48*4882a593Smuzhiyun #define IPU_FIELD_NS		IPU_CPMEM_WORD(0, 69, 10)
49*4882a593Smuzhiyun #define IPU_FIELD_SDX		IPU_CPMEM_WORD(0, 79, 7)
50*4882a593Smuzhiyun #define IPU_FIELD_SM		IPU_CPMEM_WORD(0, 86, 10)
51*4882a593Smuzhiyun #define IPU_FIELD_SCC		IPU_CPMEM_WORD(0, 96, 1)
52*4882a593Smuzhiyun #define IPU_FIELD_SCE		IPU_CPMEM_WORD(0, 97, 1)
53*4882a593Smuzhiyun #define IPU_FIELD_SDY		IPU_CPMEM_WORD(0, 98, 7)
54*4882a593Smuzhiyun #define IPU_FIELD_SDRX		IPU_CPMEM_WORD(0, 105, 1)
55*4882a593Smuzhiyun #define IPU_FIELD_SDRY		IPU_CPMEM_WORD(0, 106, 1)
56*4882a593Smuzhiyun #define IPU_FIELD_BPP		IPU_CPMEM_WORD(0, 107, 3)
57*4882a593Smuzhiyun #define IPU_FIELD_DEC_SEL	IPU_CPMEM_WORD(0, 110, 2)
58*4882a593Smuzhiyun #define IPU_FIELD_DIM		IPU_CPMEM_WORD(0, 112, 1)
59*4882a593Smuzhiyun #define IPU_FIELD_BNDM		IPU_CPMEM_WORD(0, 114, 3)
60*4882a593Smuzhiyun #define IPU_FIELD_BM		IPU_CPMEM_WORD(0, 117, 2)
61*4882a593Smuzhiyun #define IPU_FIELD_ROT		IPU_CPMEM_WORD(0, 119, 1)
62*4882a593Smuzhiyun #define IPU_FIELD_ROT_HF_VF	IPU_CPMEM_WORD(0, 119, 3)
63*4882a593Smuzhiyun #define IPU_FIELD_HF		IPU_CPMEM_WORD(0, 120, 1)
64*4882a593Smuzhiyun #define IPU_FIELD_VF		IPU_CPMEM_WORD(0, 121, 1)
65*4882a593Smuzhiyun #define IPU_FIELD_THE		IPU_CPMEM_WORD(0, 122, 1)
66*4882a593Smuzhiyun #define IPU_FIELD_CAP		IPU_CPMEM_WORD(0, 123, 1)
67*4882a593Smuzhiyun #define IPU_FIELD_CAE		IPU_CPMEM_WORD(0, 124, 1)
68*4882a593Smuzhiyun #define IPU_FIELD_FW		IPU_CPMEM_WORD(0, 125, 13)
69*4882a593Smuzhiyun #define IPU_FIELD_FH		IPU_CPMEM_WORD(0, 138, 12)
70*4882a593Smuzhiyun #define IPU_FIELD_EBA0		IPU_CPMEM_WORD(1, 0, 29)
71*4882a593Smuzhiyun #define IPU_FIELD_EBA1		IPU_CPMEM_WORD(1, 29, 29)
72*4882a593Smuzhiyun #define IPU_FIELD_ILO		IPU_CPMEM_WORD(1, 58, 20)
73*4882a593Smuzhiyun #define IPU_FIELD_NPB		IPU_CPMEM_WORD(1, 78, 7)
74*4882a593Smuzhiyun #define IPU_FIELD_PFS		IPU_CPMEM_WORD(1, 85, 4)
75*4882a593Smuzhiyun #define IPU_FIELD_ALU		IPU_CPMEM_WORD(1, 89, 1)
76*4882a593Smuzhiyun #define IPU_FIELD_ALBM		IPU_CPMEM_WORD(1, 90, 3)
77*4882a593Smuzhiyun #define IPU_FIELD_ID		IPU_CPMEM_WORD(1, 93, 2)
78*4882a593Smuzhiyun #define IPU_FIELD_TH		IPU_CPMEM_WORD(1, 95, 7)
79*4882a593Smuzhiyun #define IPU_FIELD_SL		IPU_CPMEM_WORD(1, 102, 14)
80*4882a593Smuzhiyun #define IPU_FIELD_WID0		IPU_CPMEM_WORD(1, 116, 3)
81*4882a593Smuzhiyun #define IPU_FIELD_WID1		IPU_CPMEM_WORD(1, 119, 3)
82*4882a593Smuzhiyun #define IPU_FIELD_WID2		IPU_CPMEM_WORD(1, 122, 3)
83*4882a593Smuzhiyun #define IPU_FIELD_WID3		IPU_CPMEM_WORD(1, 125, 3)
84*4882a593Smuzhiyun #define IPU_FIELD_OFS0		IPU_CPMEM_WORD(1, 128, 5)
85*4882a593Smuzhiyun #define IPU_FIELD_OFS1		IPU_CPMEM_WORD(1, 133, 5)
86*4882a593Smuzhiyun #define IPU_FIELD_OFS2		IPU_CPMEM_WORD(1, 138, 5)
87*4882a593Smuzhiyun #define IPU_FIELD_OFS3		IPU_CPMEM_WORD(1, 143, 5)
88*4882a593Smuzhiyun #define IPU_FIELD_SXYS		IPU_CPMEM_WORD(1, 148, 1)
89*4882a593Smuzhiyun #define IPU_FIELD_CRE		IPU_CPMEM_WORD(1, 149, 1)
90*4882a593Smuzhiyun #define IPU_FIELD_DEC_SEL2	IPU_CPMEM_WORD(1, 150, 1)
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun static inline struct ipu_ch_param __iomem *
ipu_get_cpmem(struct ipuv3_channel * ch)93*4882a593Smuzhiyun ipu_get_cpmem(struct ipuv3_channel *ch)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	struct ipu_cpmem *cpmem = ch->ipu->cpmem_priv;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	return cpmem->base + ch->num;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
ipu_ch_param_write_field(struct ipuv3_channel * ch,u32 wbs,u32 v)100*4882a593Smuzhiyun static void ipu_ch_param_write_field(struct ipuv3_channel *ch, u32 wbs, u32 v)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch);
103*4882a593Smuzhiyun 	u32 bit = (wbs >> 8) % 160;
104*4882a593Smuzhiyun 	u32 size = wbs & 0xff;
105*4882a593Smuzhiyun 	u32 word = (wbs >> 8) / 160;
106*4882a593Smuzhiyun 	u32 i = bit / 32;
107*4882a593Smuzhiyun 	u32 ofs = bit % 32;
108*4882a593Smuzhiyun 	u32 mask = (1 << size) - 1;
109*4882a593Smuzhiyun 	u32 val;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	pr_debug("%s %d %d %d\n", __func__, word, bit , size);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	val = readl(&base->word[word].data[i]);
114*4882a593Smuzhiyun 	val &= ~(mask << ofs);
115*4882a593Smuzhiyun 	val |= v << ofs;
116*4882a593Smuzhiyun 	writel(val, &base->word[word].data[i]);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	if ((bit + size - 1) / 32 > i) {
119*4882a593Smuzhiyun 		val = readl(&base->word[word].data[i + 1]);
120*4882a593Smuzhiyun 		val &= ~(mask >> (ofs ? (32 - ofs) : 0));
121*4882a593Smuzhiyun 		val |= v >> (ofs ? (32 - ofs) : 0);
122*4882a593Smuzhiyun 		writel(val, &base->word[word].data[i + 1]);
123*4882a593Smuzhiyun 	}
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
ipu_ch_param_read_field(struct ipuv3_channel * ch,u32 wbs)126*4882a593Smuzhiyun static u32 ipu_ch_param_read_field(struct ipuv3_channel *ch, u32 wbs)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch);
129*4882a593Smuzhiyun 	u32 bit = (wbs >> 8) % 160;
130*4882a593Smuzhiyun 	u32 size = wbs & 0xff;
131*4882a593Smuzhiyun 	u32 word = (wbs >> 8) / 160;
132*4882a593Smuzhiyun 	u32 i = bit / 32;
133*4882a593Smuzhiyun 	u32 ofs = bit % 32;
134*4882a593Smuzhiyun 	u32 mask = (1 << size) - 1;
135*4882a593Smuzhiyun 	u32 val = 0;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	pr_debug("%s %d %d %d\n", __func__, word, bit , size);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	val = (readl(&base->word[word].data[i]) >> ofs) & mask;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	if ((bit + size - 1) / 32 > i) {
142*4882a593Smuzhiyun 		u32 tmp;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 		tmp = readl(&base->word[word].data[i + 1]);
145*4882a593Smuzhiyun 		tmp &= mask >> (ofs ? (32 - ofs) : 0);
146*4882a593Smuzhiyun 		val |= tmp << (ofs ? (32 - ofs) : 0);
147*4882a593Smuzhiyun 	}
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	return val;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun /*
153*4882a593Smuzhiyun  * The V4L2 spec defines packed RGB formats in memory byte order, which from
154*4882a593Smuzhiyun  * point of view of the IPU corresponds to little-endian words with the first
155*4882a593Smuzhiyun  * component in the least significant bits.
156*4882a593Smuzhiyun  * The DRM pixel formats and IPU internal representation are ordered the other
157*4882a593Smuzhiyun  * way around, with the first named component ordered at the most significant
158*4882a593Smuzhiyun  * bits. Further, V4L2 formats are not well defined:
159*4882a593Smuzhiyun  *     https://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html
160*4882a593Smuzhiyun  * We choose the interpretation which matches GStreamer behavior.
161*4882a593Smuzhiyun  */
v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)162*4882a593Smuzhiyun static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	switch (pixelformat) {
165*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB565:
166*4882a593Smuzhiyun 		/*
167*4882a593Smuzhiyun 		 * Here we choose the 'corrected' interpretation of RGBP, a
168*4882a593Smuzhiyun 		 * little-endian 16-bit word with the red component at the most
169*4882a593Smuzhiyun 		 * significant bits:
170*4882a593Smuzhiyun 		 * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B
171*4882a593Smuzhiyun 		 */
172*4882a593Smuzhiyun 		return DRM_FORMAT_RGB565;
173*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGR24:
174*4882a593Smuzhiyun 		/* B G R <=> [24:0] R:G:B */
175*4882a593Smuzhiyun 		return DRM_FORMAT_RGB888;
176*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB24:
177*4882a593Smuzhiyun 		/* R G B <=> [24:0] B:G:R */
178*4882a593Smuzhiyun 		return DRM_FORMAT_BGR888;
179*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGR32:
180*4882a593Smuzhiyun 		/* B G R A <=> [32:0] A:B:G:R */
181*4882a593Smuzhiyun 		return DRM_FORMAT_XRGB8888;
182*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB32:
183*4882a593Smuzhiyun 		/* R G B A <=> [32:0] A:B:G:R */
184*4882a593Smuzhiyun 		return DRM_FORMAT_XBGR8888;
185*4882a593Smuzhiyun 	case V4L2_PIX_FMT_ABGR32:
186*4882a593Smuzhiyun 		/* B G R A <=> [32:0] A:R:G:B */
187*4882a593Smuzhiyun 		return DRM_FORMAT_ARGB8888;
188*4882a593Smuzhiyun 	case V4L2_PIX_FMT_XBGR32:
189*4882a593Smuzhiyun 		/* B G R X <=> [32:0] X:R:G:B */
190*4882a593Smuzhiyun 		return DRM_FORMAT_XRGB8888;
191*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGRA32:
192*4882a593Smuzhiyun 		/* A B G R <=> [32:0] R:G:B:A */
193*4882a593Smuzhiyun 		return DRM_FORMAT_RGBA8888;
194*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGRX32:
195*4882a593Smuzhiyun 		/* X B G R <=> [32:0] R:G:B:X */
196*4882a593Smuzhiyun 		return DRM_FORMAT_RGBX8888;
197*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGBA32:
198*4882a593Smuzhiyun 		/* R G B A <=> [32:0] A:B:G:R */
199*4882a593Smuzhiyun 		return DRM_FORMAT_ABGR8888;
200*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGBX32:
201*4882a593Smuzhiyun 		/* R G B X <=> [32:0] X:B:G:R */
202*4882a593Smuzhiyun 		return DRM_FORMAT_XBGR8888;
203*4882a593Smuzhiyun 	case V4L2_PIX_FMT_ARGB32:
204*4882a593Smuzhiyun 		/* A R G B <=> [32:0] B:G:R:A */
205*4882a593Smuzhiyun 		return DRM_FORMAT_BGRA8888;
206*4882a593Smuzhiyun 	case V4L2_PIX_FMT_XRGB32:
207*4882a593Smuzhiyun 		/* X R G B <=> [32:0] B:G:R:X */
208*4882a593Smuzhiyun 		return DRM_FORMAT_BGRX8888;
209*4882a593Smuzhiyun 	case V4L2_PIX_FMT_UYVY:
210*4882a593Smuzhiyun 		return DRM_FORMAT_UYVY;
211*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUYV:
212*4882a593Smuzhiyun 		return DRM_FORMAT_YUYV;
213*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV420:
214*4882a593Smuzhiyun 		return DRM_FORMAT_YUV420;
215*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV422P:
216*4882a593Smuzhiyun 		return DRM_FORMAT_YUV422;
217*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVU420:
218*4882a593Smuzhiyun 		return DRM_FORMAT_YVU420;
219*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV12:
220*4882a593Smuzhiyun 		return DRM_FORMAT_NV12;
221*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV16:
222*4882a593Smuzhiyun 		return DRM_FORMAT_NV16;
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	return -EINVAL;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
ipu_cpmem_zero(struct ipuv3_channel * ch)228*4882a593Smuzhiyun void ipu_cpmem_zero(struct ipuv3_channel *ch)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	struct ipu_ch_param __iomem *p = ipu_get_cpmem(ch);
231*4882a593Smuzhiyun 	void __iomem *base = p;
232*4882a593Smuzhiyun 	int i;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	for (i = 0; i < sizeof(*p) / sizeof(u32); i++)
235*4882a593Smuzhiyun 		writel(0, base + i * sizeof(u32));
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_zero);
238*4882a593Smuzhiyun 
ipu_cpmem_set_resolution(struct ipuv3_channel * ch,int xres,int yres)239*4882a593Smuzhiyun void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_FW, xres - 1);
242*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_FH, yres - 1);
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_resolution);
245*4882a593Smuzhiyun 
ipu_cpmem_skip_odd_chroma_rows(struct ipuv3_channel * ch)246*4882a593Smuzhiyun void ipu_cpmem_skip_odd_chroma_rows(struct ipuv3_channel *ch)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_RDRW, 1);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_skip_odd_chroma_rows);
251*4882a593Smuzhiyun 
ipu_cpmem_set_stride(struct ipuv3_channel * ch,int stride)252*4882a593Smuzhiyun void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_SLY, stride - 1);
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_stride);
257*4882a593Smuzhiyun 
ipu_cpmem_set_high_priority(struct ipuv3_channel * ch)258*4882a593Smuzhiyun void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun 	struct ipu_soc *ipu = ch->ipu;
261*4882a593Smuzhiyun 	u32 val;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	if (ipu->ipu_type == IPUV3EX)
264*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_ID, 1);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(ch->num));
267*4882a593Smuzhiyun 	val |= 1 << (ch->num % 32);
268*4882a593Smuzhiyun 	ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(ch->num));
269*4882a593Smuzhiyun };
270*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority);
271*4882a593Smuzhiyun 
ipu_cpmem_set_buffer(struct ipuv3_channel * ch,int bufnum,dma_addr_t buf)272*4882a593Smuzhiyun void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	WARN_ON_ONCE(buf & 0x7);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	if (bufnum)
277*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3);
278*4882a593Smuzhiyun 	else
279*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_EBA0, buf >> 3);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer);
282*4882a593Smuzhiyun 
ipu_cpmem_set_uv_offset(struct ipuv3_channel * ch,u32 u_off,u32 v_off)283*4882a593Smuzhiyun void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	WARN_ON_ONCE((u_off & 0x7) || (v_off & 0x7));
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
288*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
291*4882a593Smuzhiyun 
ipu_cpmem_interlaced_scan(struct ipuv3_channel * ch,int stride,u32 pixelformat)292*4882a593Smuzhiyun void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride,
293*4882a593Smuzhiyun 			       u32 pixelformat)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	u32 ilo, sly, sluv;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	if (stride < 0) {
298*4882a593Smuzhiyun 		stride = -stride;
299*4882a593Smuzhiyun 		ilo = 0x100000 - (stride / 8);
300*4882a593Smuzhiyun 	} else {
301*4882a593Smuzhiyun 		ilo = stride / 8;
302*4882a593Smuzhiyun 	}
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	sly = (stride * 2) - 1;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	switch (pixelformat) {
307*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV420:
308*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVU420:
309*4882a593Smuzhiyun 		sluv = stride / 2 - 1;
310*4882a593Smuzhiyun 		break;
311*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV12:
312*4882a593Smuzhiyun 		sluv = stride - 1;
313*4882a593Smuzhiyun 		break;
314*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV422P:
315*4882a593Smuzhiyun 		sluv = stride - 1;
316*4882a593Smuzhiyun 		break;
317*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV16:
318*4882a593Smuzhiyun 		sluv = stride * 2 - 1;
319*4882a593Smuzhiyun 		break;
320*4882a593Smuzhiyun 	default:
321*4882a593Smuzhiyun 		sluv = 0;
322*4882a593Smuzhiyun 		break;
323*4882a593Smuzhiyun 	}
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
326*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_ILO, ilo);
327*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_SLY, sly);
328*4882a593Smuzhiyun 	if (sluv)
329*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, sluv);
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan);
332*4882a593Smuzhiyun 
ipu_cpmem_set_axi_id(struct ipuv3_channel * ch,u32 id)333*4882a593Smuzhiyun void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun 	id &= 0x3;
336*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_ID, id);
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_axi_id);
339*4882a593Smuzhiyun 
ipu_cpmem_get_burstsize(struct ipuv3_channel * ch)340*4882a593Smuzhiyun int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	return ipu_ch_param_read_field(ch, IPU_FIELD_NPB) + 1;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_get_burstsize);
345*4882a593Smuzhiyun 
ipu_cpmem_set_burstsize(struct ipuv3_channel * ch,int burstsize)346*4882a593Smuzhiyun void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1);
349*4882a593Smuzhiyun };
350*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_burstsize);
351*4882a593Smuzhiyun 
ipu_cpmem_set_block_mode(struct ipuv3_channel * ch)352*4882a593Smuzhiyun void ipu_cpmem_set_block_mode(struct ipuv3_channel *ch)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_BM, 1);
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_block_mode);
357*4882a593Smuzhiyun 
ipu_cpmem_set_rotation(struct ipuv3_channel * ch,enum ipu_rotate_mode rot)358*4882a593Smuzhiyun void ipu_cpmem_set_rotation(struct ipuv3_channel *ch,
359*4882a593Smuzhiyun 			    enum ipu_rotate_mode rot)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun 	u32 temp_rot = bitrev8(rot) >> 5;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_ROT_HF_VF, temp_rot);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_rotation);
366*4882a593Smuzhiyun 
ipu_cpmem_set_format_rgb(struct ipuv3_channel * ch,const struct ipu_rgb * rgb)367*4882a593Smuzhiyun int ipu_cpmem_set_format_rgb(struct ipuv3_channel *ch,
368*4882a593Smuzhiyun 			     const struct ipu_rgb *rgb)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun 	int bpp = 0, npb = 0, ro, go, bo, to;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset;
373*4882a593Smuzhiyun 	go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset;
374*4882a593Smuzhiyun 	bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset;
375*4882a593Smuzhiyun 	to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_WID0, rgb->red.length - 1);
378*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_OFS0, ro);
379*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_WID1, rgb->green.length - 1);
380*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_OFS1, go);
381*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_WID2, rgb->blue.length - 1);
382*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_OFS2, bo);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	if (rgb->transp.length) {
385*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_WID3,
386*4882a593Smuzhiyun 				rgb->transp.length - 1);
387*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_OFS3, to);
388*4882a593Smuzhiyun 	} else {
389*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7);
390*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_OFS3,
391*4882a593Smuzhiyun 				rgb->bits_per_pixel);
392*4882a593Smuzhiyun 	}
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	switch (rgb->bits_per_pixel) {
395*4882a593Smuzhiyun 	case 32:
396*4882a593Smuzhiyun 		bpp = 0;
397*4882a593Smuzhiyun 		npb = 15;
398*4882a593Smuzhiyun 		break;
399*4882a593Smuzhiyun 	case 24:
400*4882a593Smuzhiyun 		bpp = 1;
401*4882a593Smuzhiyun 		npb = 19;
402*4882a593Smuzhiyun 		break;
403*4882a593Smuzhiyun 	case 16:
404*4882a593Smuzhiyun 		bpp = 3;
405*4882a593Smuzhiyun 		npb = 31;
406*4882a593Smuzhiyun 		break;
407*4882a593Smuzhiyun 	case 8:
408*4882a593Smuzhiyun 		bpp = 5;
409*4882a593Smuzhiyun 		npb = 63;
410*4882a593Smuzhiyun 		break;
411*4882a593Smuzhiyun 	default:
412*4882a593Smuzhiyun 		return -EINVAL;
413*4882a593Smuzhiyun 	}
414*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp);
415*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb);
416*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 7); /* rgb mode */
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 	return 0;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb);
421*4882a593Smuzhiyun 
ipu_cpmem_set_format_passthrough(struct ipuv3_channel * ch,int width)422*4882a593Smuzhiyun int ipu_cpmem_set_format_passthrough(struct ipuv3_channel *ch, int width)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	int bpp = 0, npb = 0;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	switch (width) {
427*4882a593Smuzhiyun 	case 32:
428*4882a593Smuzhiyun 		bpp = 0;
429*4882a593Smuzhiyun 		npb = 15;
430*4882a593Smuzhiyun 		break;
431*4882a593Smuzhiyun 	case 24:
432*4882a593Smuzhiyun 		bpp = 1;
433*4882a593Smuzhiyun 		npb = 19;
434*4882a593Smuzhiyun 		break;
435*4882a593Smuzhiyun 	case 16:
436*4882a593Smuzhiyun 		bpp = 3;
437*4882a593Smuzhiyun 		npb = 31;
438*4882a593Smuzhiyun 		break;
439*4882a593Smuzhiyun 	case 8:
440*4882a593Smuzhiyun 		bpp = 5;
441*4882a593Smuzhiyun 		npb = 63;
442*4882a593Smuzhiyun 		break;
443*4882a593Smuzhiyun 	default:
444*4882a593Smuzhiyun 		return -EINVAL;
445*4882a593Smuzhiyun 	}
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp);
448*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb);
449*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 6); /* raw mode */
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return 0;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough);
454*4882a593Smuzhiyun 
ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel * ch,u32 pixel_format)455*4882a593Smuzhiyun void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun 	switch (pixel_format) {
458*4882a593Smuzhiyun 	case V4L2_PIX_FMT_UYVY:
459*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */
460*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA);/* pix fmt */
461*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */
462*4882a593Smuzhiyun 		break;
463*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUYV:
464*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */
465*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8);/* pix fmt */
466*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */
467*4882a593Smuzhiyun 		break;
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved);
471*4882a593Smuzhiyun 
ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel * ch,unsigned int uv_stride,unsigned int u_offset,unsigned int v_offset)472*4882a593Smuzhiyun void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch,
473*4882a593Smuzhiyun 				   unsigned int uv_stride,
474*4882a593Smuzhiyun 				   unsigned int u_offset, unsigned int v_offset)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun 	WARN_ON_ONCE((u_offset & 0x7) || (v_offset & 0x7));
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1);
479*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
480*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun static const struct ipu_rgb def_xrgb_32 = {
485*4882a593Smuzhiyun 	.red	= { .offset = 16, .length = 8, },
486*4882a593Smuzhiyun 	.green	= { .offset =  8, .length = 8, },
487*4882a593Smuzhiyun 	.blue	= { .offset =  0, .length = 8, },
488*4882a593Smuzhiyun 	.transp = { .offset = 24, .length = 8, },
489*4882a593Smuzhiyun 	.bits_per_pixel = 32,
490*4882a593Smuzhiyun };
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun static const struct ipu_rgb def_xbgr_32 = {
493*4882a593Smuzhiyun 	.red	= { .offset =  0, .length = 8, },
494*4882a593Smuzhiyun 	.green	= { .offset =  8, .length = 8, },
495*4882a593Smuzhiyun 	.blue	= { .offset = 16, .length = 8, },
496*4882a593Smuzhiyun 	.transp = { .offset = 24, .length = 8, },
497*4882a593Smuzhiyun 	.bits_per_pixel = 32,
498*4882a593Smuzhiyun };
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun static const struct ipu_rgb def_rgbx_32 = {
501*4882a593Smuzhiyun 	.red	= { .offset = 24, .length = 8, },
502*4882a593Smuzhiyun 	.green	= { .offset = 16, .length = 8, },
503*4882a593Smuzhiyun 	.blue	= { .offset =  8, .length = 8, },
504*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 8, },
505*4882a593Smuzhiyun 	.bits_per_pixel = 32,
506*4882a593Smuzhiyun };
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun static const struct ipu_rgb def_bgrx_32 = {
509*4882a593Smuzhiyun 	.red	= { .offset =  8, .length = 8, },
510*4882a593Smuzhiyun 	.green	= { .offset = 16, .length = 8, },
511*4882a593Smuzhiyun 	.blue	= { .offset = 24, .length = 8, },
512*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 8, },
513*4882a593Smuzhiyun 	.bits_per_pixel = 32,
514*4882a593Smuzhiyun };
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun static const struct ipu_rgb def_rgb_24 = {
517*4882a593Smuzhiyun 	.red	= { .offset = 16, .length = 8, },
518*4882a593Smuzhiyun 	.green	= { .offset =  8, .length = 8, },
519*4882a593Smuzhiyun 	.blue	= { .offset =  0, .length = 8, },
520*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 0, },
521*4882a593Smuzhiyun 	.bits_per_pixel = 24,
522*4882a593Smuzhiyun };
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun static const struct ipu_rgb def_bgr_24 = {
525*4882a593Smuzhiyun 	.red	= { .offset =  0, .length = 8, },
526*4882a593Smuzhiyun 	.green	= { .offset =  8, .length = 8, },
527*4882a593Smuzhiyun 	.blue	= { .offset = 16, .length = 8, },
528*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 0, },
529*4882a593Smuzhiyun 	.bits_per_pixel = 24,
530*4882a593Smuzhiyun };
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun static const struct ipu_rgb def_rgb_16 = {
533*4882a593Smuzhiyun 	.red	= { .offset = 11, .length = 5, },
534*4882a593Smuzhiyun 	.green	= { .offset =  5, .length = 6, },
535*4882a593Smuzhiyun 	.blue	= { .offset =  0, .length = 5, },
536*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 0, },
537*4882a593Smuzhiyun 	.bits_per_pixel = 16,
538*4882a593Smuzhiyun };
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun static const struct ipu_rgb def_bgr_16 = {
541*4882a593Smuzhiyun 	.red	= { .offset =  0, .length = 5, },
542*4882a593Smuzhiyun 	.green	= { .offset =  5, .length = 6, },
543*4882a593Smuzhiyun 	.blue	= { .offset = 11, .length = 5, },
544*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 0, },
545*4882a593Smuzhiyun 	.bits_per_pixel = 16,
546*4882a593Smuzhiyun };
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun static const struct ipu_rgb def_argb_16 = {
549*4882a593Smuzhiyun 	.red	= { .offset = 10, .length = 5, },
550*4882a593Smuzhiyun 	.green	= { .offset =  5, .length = 5, },
551*4882a593Smuzhiyun 	.blue	= { .offset =  0, .length = 5, },
552*4882a593Smuzhiyun 	.transp = { .offset = 15, .length = 1, },
553*4882a593Smuzhiyun 	.bits_per_pixel = 16,
554*4882a593Smuzhiyun };
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun static const struct ipu_rgb def_argb_16_4444 = {
557*4882a593Smuzhiyun 	.red	= { .offset =  8, .length = 4, },
558*4882a593Smuzhiyun 	.green	= { .offset =  4, .length = 4, },
559*4882a593Smuzhiyun 	.blue	= { .offset =  0, .length = 4, },
560*4882a593Smuzhiyun 	.transp = { .offset = 12, .length = 4, },
561*4882a593Smuzhiyun 	.bits_per_pixel = 16,
562*4882a593Smuzhiyun };
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun static const struct ipu_rgb def_abgr_16 = {
565*4882a593Smuzhiyun 	.red	= { .offset =  0, .length = 5, },
566*4882a593Smuzhiyun 	.green	= { .offset =  5, .length = 5, },
567*4882a593Smuzhiyun 	.blue	= { .offset = 10, .length = 5, },
568*4882a593Smuzhiyun 	.transp = { .offset = 15, .length = 1, },
569*4882a593Smuzhiyun 	.bits_per_pixel = 16,
570*4882a593Smuzhiyun };
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun static const struct ipu_rgb def_rgba_16 = {
573*4882a593Smuzhiyun 	.red	= { .offset = 11, .length = 5, },
574*4882a593Smuzhiyun 	.green	= { .offset =  6, .length = 5, },
575*4882a593Smuzhiyun 	.blue	= { .offset =  1, .length = 5, },
576*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 1, },
577*4882a593Smuzhiyun 	.bits_per_pixel = 16,
578*4882a593Smuzhiyun };
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun static const struct ipu_rgb def_bgra_16 = {
581*4882a593Smuzhiyun 	.red	= { .offset =  1, .length = 5, },
582*4882a593Smuzhiyun 	.green	= { .offset =  6, .length = 5, },
583*4882a593Smuzhiyun 	.blue	= { .offset = 11, .length = 5, },
584*4882a593Smuzhiyun 	.transp = { .offset =  0, .length = 1, },
585*4882a593Smuzhiyun 	.bits_per_pixel = 16,
586*4882a593Smuzhiyun };
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun #define Y_OFFSET(pix, x, y)	((x) + pix->bytesperline * (y))
589*4882a593Smuzhiyun #define U_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
590*4882a593Smuzhiyun 				 (pix->bytesperline * ((y) / 2) / 2) + (x) / 2)
591*4882a593Smuzhiyun #define V_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
592*4882a593Smuzhiyun 				 (pix->bytesperline * pix->height / 4) + \
593*4882a593Smuzhiyun 				 (pix->bytesperline * ((y) / 2) / 2) + (x) / 2)
594*4882a593Smuzhiyun #define U2_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
595*4882a593Smuzhiyun 				 (pix->bytesperline * (y) / 2) + (x) / 2)
596*4882a593Smuzhiyun #define V2_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
597*4882a593Smuzhiyun 				 (pix->bytesperline * pix->height / 2) + \
598*4882a593Smuzhiyun 				 (pix->bytesperline * (y) / 2) + (x) / 2)
599*4882a593Smuzhiyun #define UV_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
600*4882a593Smuzhiyun 				 (pix->bytesperline * ((y) / 2)) + (x))
601*4882a593Smuzhiyun #define UV2_OFFSET(pix, x, y)	((pix->bytesperline * pix->height) +	 \
602*4882a593Smuzhiyun 				 (pix->bytesperline * y) + (x))
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun #define NUM_ALPHA_CHANNELS	7
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun /* See Table 37-12. Alpha channels mapping. */
ipu_channel_albm(int ch_num)607*4882a593Smuzhiyun static int ipu_channel_albm(int ch_num)
608*4882a593Smuzhiyun {
609*4882a593Smuzhiyun 	switch (ch_num) {
610*4882a593Smuzhiyun 	case IPUV3_CHANNEL_G_MEM_IC_PRP_VF:	return 0;
611*4882a593Smuzhiyun 	case IPUV3_CHANNEL_G_MEM_IC_PP:		return 1;
612*4882a593Smuzhiyun 	case IPUV3_CHANNEL_MEM_FG_SYNC:		return 2;
613*4882a593Smuzhiyun 	case IPUV3_CHANNEL_MEM_FG_ASYNC:	return 3;
614*4882a593Smuzhiyun 	case IPUV3_CHANNEL_MEM_BG_SYNC:		return 4;
615*4882a593Smuzhiyun 	case IPUV3_CHANNEL_MEM_BG_ASYNC:	return 5;
616*4882a593Smuzhiyun 	case IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB: return 6;
617*4882a593Smuzhiyun 	default:
618*4882a593Smuzhiyun 		return -EINVAL;
619*4882a593Smuzhiyun 	}
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun 
ipu_cpmem_set_separate_alpha(struct ipuv3_channel * ch)622*4882a593Smuzhiyun static void ipu_cpmem_set_separate_alpha(struct ipuv3_channel *ch)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	struct ipu_soc *ipu = ch->ipu;
625*4882a593Smuzhiyun 	int albm;
626*4882a593Smuzhiyun 	u32 val;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	albm = ipu_channel_albm(ch->num);
629*4882a593Smuzhiyun 	if (albm < 0)
630*4882a593Smuzhiyun 		return;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_ALU, 1);
633*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_ALBM, albm);
634*4882a593Smuzhiyun 	ipu_ch_param_write_field(ch, IPU_FIELD_CRE, 1);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	val = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
637*4882a593Smuzhiyun 	val |= BIT(ch->num);
638*4882a593Smuzhiyun 	ipu_idmac_write(ipu, val, IDMAC_SEP_ALPHA);
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun 
ipu_cpmem_set_fmt(struct ipuv3_channel * ch,u32 drm_fourcc)641*4882a593Smuzhiyun int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc)
642*4882a593Smuzhiyun {
643*4882a593Smuzhiyun 	switch (drm_fourcc) {
644*4882a593Smuzhiyun 	case DRM_FORMAT_YUV420:
645*4882a593Smuzhiyun 	case DRM_FORMAT_YVU420:
646*4882a593Smuzhiyun 		/* pix format */
647*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 2);
648*4882a593Smuzhiyun 		/* burst size */
649*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
650*4882a593Smuzhiyun 		break;
651*4882a593Smuzhiyun 	case DRM_FORMAT_YUV422:
652*4882a593Smuzhiyun 	case DRM_FORMAT_YVU422:
653*4882a593Smuzhiyun 		/* pix format */
654*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 1);
655*4882a593Smuzhiyun 		/* burst size */
656*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
657*4882a593Smuzhiyun 		break;
658*4882a593Smuzhiyun 	case DRM_FORMAT_YUV444:
659*4882a593Smuzhiyun 	case DRM_FORMAT_YVU444:
660*4882a593Smuzhiyun 		/* pix format */
661*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0);
662*4882a593Smuzhiyun 		/* burst size */
663*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
664*4882a593Smuzhiyun 		break;
665*4882a593Smuzhiyun 	case DRM_FORMAT_NV12:
666*4882a593Smuzhiyun 		/* pix format */
667*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 4);
668*4882a593Smuzhiyun 		/* burst size */
669*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
670*4882a593Smuzhiyun 		break;
671*4882a593Smuzhiyun 	case DRM_FORMAT_NV16:
672*4882a593Smuzhiyun 		/* pix format */
673*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 3);
674*4882a593Smuzhiyun 		/* burst size */
675*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
676*4882a593Smuzhiyun 		break;
677*4882a593Smuzhiyun 	case DRM_FORMAT_UYVY:
678*4882a593Smuzhiyun 		/* bits/pixel */
679*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3);
680*4882a593Smuzhiyun 		/* pix format */
681*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA);
682*4882a593Smuzhiyun 		/* burst size */
683*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
684*4882a593Smuzhiyun 		break;
685*4882a593Smuzhiyun 	case DRM_FORMAT_YUYV:
686*4882a593Smuzhiyun 		/* bits/pixel */
687*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3);
688*4882a593Smuzhiyun 		/* pix format */
689*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8);
690*4882a593Smuzhiyun 		/* burst size */
691*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
692*4882a593Smuzhiyun 		break;
693*4882a593Smuzhiyun 	case DRM_FORMAT_ABGR8888:
694*4882a593Smuzhiyun 	case DRM_FORMAT_XBGR8888:
695*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_xbgr_32);
696*4882a593Smuzhiyun 		break;
697*4882a593Smuzhiyun 	case DRM_FORMAT_ARGB8888:
698*4882a593Smuzhiyun 	case DRM_FORMAT_XRGB8888:
699*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_xrgb_32);
700*4882a593Smuzhiyun 		break;
701*4882a593Smuzhiyun 	case DRM_FORMAT_RGBA8888:
702*4882a593Smuzhiyun 	case DRM_FORMAT_RGBX8888:
703*4882a593Smuzhiyun 	case DRM_FORMAT_RGBX8888_A8:
704*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_rgbx_32);
705*4882a593Smuzhiyun 		break;
706*4882a593Smuzhiyun 	case DRM_FORMAT_BGRA8888:
707*4882a593Smuzhiyun 	case DRM_FORMAT_BGRX8888:
708*4882a593Smuzhiyun 	case DRM_FORMAT_BGRX8888_A8:
709*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_bgrx_32);
710*4882a593Smuzhiyun 		break;
711*4882a593Smuzhiyun 	case DRM_FORMAT_BGR888:
712*4882a593Smuzhiyun 	case DRM_FORMAT_BGR888_A8:
713*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_bgr_24);
714*4882a593Smuzhiyun 		break;
715*4882a593Smuzhiyun 	case DRM_FORMAT_RGB888:
716*4882a593Smuzhiyun 	case DRM_FORMAT_RGB888_A8:
717*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_rgb_24);
718*4882a593Smuzhiyun 		break;
719*4882a593Smuzhiyun 	case DRM_FORMAT_RGB565:
720*4882a593Smuzhiyun 	case DRM_FORMAT_RGB565_A8:
721*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_rgb_16);
722*4882a593Smuzhiyun 		break;
723*4882a593Smuzhiyun 	case DRM_FORMAT_BGR565:
724*4882a593Smuzhiyun 	case DRM_FORMAT_BGR565_A8:
725*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_bgr_16);
726*4882a593Smuzhiyun 		break;
727*4882a593Smuzhiyun 	case DRM_FORMAT_ARGB1555:
728*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_argb_16);
729*4882a593Smuzhiyun 		break;
730*4882a593Smuzhiyun 	case DRM_FORMAT_ABGR1555:
731*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_abgr_16);
732*4882a593Smuzhiyun 		break;
733*4882a593Smuzhiyun 	case DRM_FORMAT_RGBA5551:
734*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_rgba_16);
735*4882a593Smuzhiyun 		break;
736*4882a593Smuzhiyun 	case DRM_FORMAT_BGRA5551:
737*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_bgra_16);
738*4882a593Smuzhiyun 		break;
739*4882a593Smuzhiyun 	case DRM_FORMAT_ARGB4444:
740*4882a593Smuzhiyun 		ipu_cpmem_set_format_rgb(ch, &def_argb_16_4444);
741*4882a593Smuzhiyun 		break;
742*4882a593Smuzhiyun 	default:
743*4882a593Smuzhiyun 		return -EINVAL;
744*4882a593Smuzhiyun 	}
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	switch (drm_fourcc) {
747*4882a593Smuzhiyun 	case DRM_FORMAT_RGB565_A8:
748*4882a593Smuzhiyun 	case DRM_FORMAT_BGR565_A8:
749*4882a593Smuzhiyun 	case DRM_FORMAT_RGB888_A8:
750*4882a593Smuzhiyun 	case DRM_FORMAT_BGR888_A8:
751*4882a593Smuzhiyun 	case DRM_FORMAT_RGBX8888_A8:
752*4882a593Smuzhiyun 	case DRM_FORMAT_BGRX8888_A8:
753*4882a593Smuzhiyun 		ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7);
754*4882a593Smuzhiyun 		ipu_cpmem_set_separate_alpha(ch);
755*4882a593Smuzhiyun 		break;
756*4882a593Smuzhiyun 	default:
757*4882a593Smuzhiyun 		break;
758*4882a593Smuzhiyun 	}
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun 	return 0;
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
763*4882a593Smuzhiyun 
ipu_cpmem_set_image(struct ipuv3_channel * ch,struct ipu_image * image)764*4882a593Smuzhiyun int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
765*4882a593Smuzhiyun {
766*4882a593Smuzhiyun 	struct v4l2_pix_format *pix = &image->pix;
767*4882a593Smuzhiyun 	int offset, u_offset, v_offset;
768*4882a593Smuzhiyun 	int ret = 0;
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	pr_debug("%s: resolution: %dx%d stride: %d\n",
771*4882a593Smuzhiyun 		 __func__, pix->width, pix->height,
772*4882a593Smuzhiyun 		 pix->bytesperline);
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	ipu_cpmem_set_resolution(ch, image->rect.width, image->rect.height);
775*4882a593Smuzhiyun 	ipu_cpmem_set_stride(ch, pix->bytesperline);
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	ipu_cpmem_set_fmt(ch, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat));
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	switch (pix->pixelformat) {
780*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV420:
781*4882a593Smuzhiyun 		offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
782*4882a593Smuzhiyun 		u_offset = image->u_offset ?
783*4882a593Smuzhiyun 			image->u_offset : U_OFFSET(pix, image->rect.left,
784*4882a593Smuzhiyun 						   image->rect.top) - offset;
785*4882a593Smuzhiyun 		v_offset = image->v_offset ?
786*4882a593Smuzhiyun 			image->v_offset : V_OFFSET(pix, image->rect.left,
787*4882a593Smuzhiyun 						   image->rect.top) - offset;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 		ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
790*4882a593Smuzhiyun 					      u_offset, v_offset);
791*4882a593Smuzhiyun 		break;
792*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YVU420:
793*4882a593Smuzhiyun 		offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
794*4882a593Smuzhiyun 		u_offset = image->u_offset ?
795*4882a593Smuzhiyun 			image->u_offset : V_OFFSET(pix, image->rect.left,
796*4882a593Smuzhiyun 						   image->rect.top) - offset;
797*4882a593Smuzhiyun 		v_offset = image->v_offset ?
798*4882a593Smuzhiyun 			image->v_offset : U_OFFSET(pix, image->rect.left,
799*4882a593Smuzhiyun 						   image->rect.top) - offset;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 		ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
802*4882a593Smuzhiyun 					      u_offset, v_offset);
803*4882a593Smuzhiyun 		break;
804*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUV422P:
805*4882a593Smuzhiyun 		offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
806*4882a593Smuzhiyun 		u_offset = image->u_offset ?
807*4882a593Smuzhiyun 			image->u_offset : U2_OFFSET(pix, image->rect.left,
808*4882a593Smuzhiyun 						    image->rect.top) - offset;
809*4882a593Smuzhiyun 		v_offset = image->v_offset ?
810*4882a593Smuzhiyun 			image->v_offset : V2_OFFSET(pix, image->rect.left,
811*4882a593Smuzhiyun 						    image->rect.top) - offset;
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 		ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
814*4882a593Smuzhiyun 					      u_offset, v_offset);
815*4882a593Smuzhiyun 		break;
816*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV12:
817*4882a593Smuzhiyun 		offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
818*4882a593Smuzhiyun 		u_offset = image->u_offset ?
819*4882a593Smuzhiyun 			image->u_offset : UV_OFFSET(pix, image->rect.left,
820*4882a593Smuzhiyun 						    image->rect.top) - offset;
821*4882a593Smuzhiyun 		v_offset = image->v_offset ? image->v_offset : 0;
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 		ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
824*4882a593Smuzhiyun 					      u_offset, v_offset);
825*4882a593Smuzhiyun 		break;
826*4882a593Smuzhiyun 	case V4L2_PIX_FMT_NV16:
827*4882a593Smuzhiyun 		offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
828*4882a593Smuzhiyun 		u_offset = image->u_offset ?
829*4882a593Smuzhiyun 			image->u_offset : UV2_OFFSET(pix, image->rect.left,
830*4882a593Smuzhiyun 						     image->rect.top) - offset;
831*4882a593Smuzhiyun 		v_offset = image->v_offset ? image->v_offset : 0;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 		ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
834*4882a593Smuzhiyun 					      u_offset, v_offset);
835*4882a593Smuzhiyun 		break;
836*4882a593Smuzhiyun 	case V4L2_PIX_FMT_UYVY:
837*4882a593Smuzhiyun 	case V4L2_PIX_FMT_YUYV:
838*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB565:
839*4882a593Smuzhiyun 		offset = image->rect.left * 2 +
840*4882a593Smuzhiyun 			image->rect.top * pix->bytesperline;
841*4882a593Smuzhiyun 		break;
842*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB32:
843*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGR32:
844*4882a593Smuzhiyun 	case V4L2_PIX_FMT_ABGR32:
845*4882a593Smuzhiyun 	case V4L2_PIX_FMT_XBGR32:
846*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGRA32:
847*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGRX32:
848*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGBA32:
849*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGBX32:
850*4882a593Smuzhiyun 	case V4L2_PIX_FMT_ARGB32:
851*4882a593Smuzhiyun 	case V4L2_PIX_FMT_XRGB32:
852*4882a593Smuzhiyun 		offset = image->rect.left * 4 +
853*4882a593Smuzhiyun 			image->rect.top * pix->bytesperline;
854*4882a593Smuzhiyun 		break;
855*4882a593Smuzhiyun 	case V4L2_PIX_FMT_RGB24:
856*4882a593Smuzhiyun 	case V4L2_PIX_FMT_BGR24:
857*4882a593Smuzhiyun 		offset = image->rect.left * 3 +
858*4882a593Smuzhiyun 			image->rect.top * pix->bytesperline;
859*4882a593Smuzhiyun 		break;
860*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SBGGR8:
861*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SGBRG8:
862*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SGRBG8:
863*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SRGGB8:
864*4882a593Smuzhiyun 	case V4L2_PIX_FMT_GREY:
865*4882a593Smuzhiyun 		offset = image->rect.left + image->rect.top * pix->bytesperline;
866*4882a593Smuzhiyun 		break;
867*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SBGGR16:
868*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SGBRG16:
869*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SGRBG16:
870*4882a593Smuzhiyun 	case V4L2_PIX_FMT_SRGGB16:
871*4882a593Smuzhiyun 	case V4L2_PIX_FMT_Y16:
872*4882a593Smuzhiyun 		offset = image->rect.left * 2 +
873*4882a593Smuzhiyun 			 image->rect.top * pix->bytesperline;
874*4882a593Smuzhiyun 		break;
875*4882a593Smuzhiyun 	default:
876*4882a593Smuzhiyun 		/* This should not happen */
877*4882a593Smuzhiyun 		WARN_ON(1);
878*4882a593Smuzhiyun 		offset = 0;
879*4882a593Smuzhiyun 		ret = -EINVAL;
880*4882a593Smuzhiyun 	}
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	ipu_cpmem_set_buffer(ch, 0, image->phys0 + offset);
883*4882a593Smuzhiyun 	ipu_cpmem_set_buffer(ch, 1, image->phys1 + offset);
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun 	return ret;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_set_image);
888*4882a593Smuzhiyun 
ipu_cpmem_dump(struct ipuv3_channel * ch)889*4882a593Smuzhiyun void ipu_cpmem_dump(struct ipuv3_channel *ch)
890*4882a593Smuzhiyun {
891*4882a593Smuzhiyun 	struct ipu_ch_param __iomem *p = ipu_get_cpmem(ch);
892*4882a593Smuzhiyun 	struct ipu_soc *ipu = ch->ipu;
893*4882a593Smuzhiyun 	int chno = ch->num;
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", chno,
896*4882a593Smuzhiyun 		readl(&p->word[0].data[0]),
897*4882a593Smuzhiyun 		readl(&p->word[0].data[1]),
898*4882a593Smuzhiyun 		readl(&p->word[0].data[2]),
899*4882a593Smuzhiyun 		readl(&p->word[0].data[3]),
900*4882a593Smuzhiyun 		readl(&p->word[0].data[4]));
901*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", chno,
902*4882a593Smuzhiyun 		readl(&p->word[1].data[0]),
903*4882a593Smuzhiyun 		readl(&p->word[1].data[1]),
904*4882a593Smuzhiyun 		readl(&p->word[1].data[2]),
905*4882a593Smuzhiyun 		readl(&p->word[1].data[3]),
906*4882a593Smuzhiyun 		readl(&p->word[1].data[4]));
907*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "PFS 0x%x, ",
908*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_PFS));
909*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "BPP 0x%x, ",
910*4882a593Smuzhiyun 		ipu_ch_param_read_field(ch, IPU_FIELD_BPP));
911*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "NPB 0x%x\n",
912*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_NPB));
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "FW %d, ",
915*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_FW));
916*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "FH %d, ",
917*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_FH));
918*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "EBA0 0x%x\n",
919*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_EBA0) << 3);
920*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "EBA1 0x%x\n",
921*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_EBA1) << 3);
922*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Stride %d\n",
923*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_SL));
924*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "scan_order %d\n",
925*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_SO));
926*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "uv_stride %d\n",
927*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_SLUV));
928*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "u_offset 0x%x\n",
929*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_UBO) << 3);
930*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "v_offset 0x%x\n",
931*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_VBO) << 3);
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Width0 %d+1, ",
934*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_WID0));
935*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Width1 %d+1, ",
936*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_WID1));
937*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Width2 %d+1, ",
938*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_WID2));
939*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Width3 %d+1, ",
940*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_WID3));
941*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Offset0 %d, ",
942*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_OFS0));
943*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Offset1 %d, ",
944*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_OFS1));
945*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Offset2 %d, ",
946*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_OFS2));
947*4882a593Smuzhiyun 	dev_dbg(ipu->dev, "Offset3 %d\n",
948*4882a593Smuzhiyun 		 ipu_ch_param_read_field(ch, IPU_FIELD_OFS3));
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(ipu_cpmem_dump);
951*4882a593Smuzhiyun 
ipu_cpmem_init(struct ipu_soc * ipu,struct device * dev,unsigned long base)952*4882a593Smuzhiyun int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun 	struct ipu_cpmem *cpmem;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	cpmem = devm_kzalloc(dev, sizeof(*cpmem), GFP_KERNEL);
957*4882a593Smuzhiyun 	if (!cpmem)
958*4882a593Smuzhiyun 		return -ENOMEM;
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	ipu->cpmem_priv = cpmem;
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 	spin_lock_init(&cpmem->lock);
963*4882a593Smuzhiyun 	cpmem->base = devm_ioremap(dev, base, SZ_128K);
964*4882a593Smuzhiyun 	if (!cpmem->base)
965*4882a593Smuzhiyun 		return -ENOMEM;
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	dev_dbg(dev, "CPMEM base: 0x%08lx remapped to %p\n",
968*4882a593Smuzhiyun 		base, cpmem->base);
969*4882a593Smuzhiyun 	cpmem->ipu = ipu;
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 	return 0;
972*4882a593Smuzhiyun }
973*4882a593Smuzhiyun 
ipu_cpmem_exit(struct ipu_soc * ipu)974*4882a593Smuzhiyun void ipu_cpmem_exit(struct ipu_soc *ipu)
975*4882a593Smuzhiyun {
976*4882a593Smuzhiyun }
977