ENGR00123294 MX53: 4 stripes algorithm for support resizing for big screen
[efikamx:linux-kernel.git] / drivers / mxc / ipu3 / ipu_param_mem.h
1 /*
2  * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
6  * The code contained herein is licensed under the GNU General Public
7  * License. You may obtain a copy of the GNU General Public License
8  * Version 2 or later at the following locations:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13 #ifndef __INCLUDE_IPU_PARAM_MEM_H__
14 #define __INCLUDE_IPU_PARAM_MEM_H__
15
16 #include <linux/types.h>
17 #include <linux/bitrev.h>
18
19 extern u32 *ipu_cpmem_base;
20
21 struct ipu_ch_param_word {
22         uint32_t data[5];
23         uint32_t res[3];
24 };
25
26 struct ipu_ch_param {
27         struct ipu_ch_param_word word[2];
28 };
29
30 #define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch))
31
32 #define _param_word(base, w) \
33         (((struct ipu_ch_param *)(base))->word[(w)].data)
34
35 #define ipu_ch_param_set_field(base, w, bit, size, v) { \
36         int i = (bit) / 32; \
37         int off = (bit) % 32; \
38         _param_word(base, w)[i] |= (v) << off; \
39         if (((bit)+(size)-1)/32 > i) { \
40                 _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
41         } \
42 }
43
44 #define ipu_ch_param_mod_field(base, w, bit, size, v) { \
45         int i = (bit) / 32; \
46         int off = (bit) % 32; \
47         u32 mask = (1UL << size) - 1; \
48         u32 temp = _param_word(base, w)[i]; \
49         temp &= ~(mask << off); \
50         _param_word(base, w)[i] = temp | (v) << off; \
51         if (((bit)+(size)-1)/32 > i) { \
52                 temp = _param_word(base, w)[i + 1]; \
53                 temp &= ~(mask >> (32 - off)); \
54                 _param_word(base, w)[i + 1] = \
55                         temp | ((v) >> (off ? (32 - off) : 0)); \
56         } \
57 }
58
59 #define ipu_ch_param_read_field(base, w, bit, size) ({ \
60         u32 temp2; \
61         int i = (bit) / 32; \
62         int off = (bit) % 32; \
63         u32 mask = (1UL << size) - 1; \
64         u32 temp1 = _param_word(base, w)[i]; \
65         temp1 = mask & (temp1 >> off); \
66         if (((bit)+(size)-1)/32 > i) { \
67                 temp2 = _param_word(base, w)[i + 1]; \
68                 temp2 &= mask >> (off ? (32 - off) : 0); \
69                 temp1 |= temp2 << (off ? (32 - off) : 0); \
70         } \
71         temp1; \
72 })
73
74 static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p,
75                                               int red_width, int red_offset,
76                                               int green_width, int green_offset,
77                                               int blue_width, int blue_offset,
78                                               int alpha_width, int alpha_offset)
79 {
80         /* Setup red width and offset */
81         ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1);
82         ipu_ch_param_set_field(p, 1, 128, 5, red_offset);
83         /* Setup green width and offset */
84         ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1);
85         ipu_ch_param_set_field(p, 1, 133, 5, green_offset);
86         /* Setup blue width and offset */
87         ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1);
88         ipu_ch_param_set_field(p, 1, 138, 5, blue_offset);
89         /* Setup alpha width and offset */
90         ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1);
91         ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset);
92 }
93
94 static inline void _ipu_ch_param_dump(int ch)
95 {
96         struct ipu_ch_param *p = ipu_ch_param_addr(ch);
97         pr_debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch,
98                  p->word[0].data[0], p->word[0].data[1], p->word[0].data[2],
99                  p->word[0].data[3], p->word[0].data[4]);
100         pr_debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch,
101                  p->word[1].data[0], p->word[1].data[1], p->word[1].data[2],
102                  p->word[1].data[3], p->word[1].data[4]);
103         pr_debug("PFS 0x%x, ",
104                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4));
105         pr_debug("BPP 0x%x, ",
106                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3));
107         pr_debug("NPB 0x%x\n",
108                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7));
109
110         pr_debug("FW %d, ",
111                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13));
112         pr_debug("FH %d, ",
113                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12));
114         pr_debug("Stride %d\n",
115                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14));
116
117         pr_debug("Width0 %d+1, ",
118                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3));
119         pr_debug("Width1 %d+1, ",
120                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3));
121         pr_debug("Width2 %d+1, ",
122                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3));
123         pr_debug("Width3 %d+1, ",
124                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3));
125         pr_debug("Offset0 %d, ",
126                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5));
127         pr_debug("Offset1 %d, ",
128                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5));
129         pr_debug("Offset2 %d, ",
130                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5));
131         pr_debug("Offset3 %d\n",
132                  ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5));
133 }
134
135 static inline void _ipu_ch_param_init(int ch,
136                                       uint32_t pixel_fmt, uint32_t width,
137                                       uint32_t height, uint32_t stride,
138                                       uint32_t u, uint32_t v,
139                                       uint32_t uv_stride, dma_addr_t addr0,
140                                       dma_addr_t addr1)
141 {
142         uint32_t u_offset = 0;
143         uint32_t v_offset = 0;
144         struct ipu_ch_param params;
145
146         memset(&params, 0, sizeof(params));
147
148         ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
149
150         if ((ch == 8) || (ch == 9) || (ch == 10)) {
151                 ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
152                 ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
153         } else {
154                 ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
155                 ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
156         }
157
158         /* EBA is 8-byte aligned */
159         ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
160         ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
161         if (addr0%8)
162                 dev_warn(g_ipu_dev,
163                          "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
164         if (addr1%8)
165                 dev_warn(g_ipu_dev,
166                          "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
167
168         switch (pixel_fmt) {
169         case IPU_PIX_FMT_GENERIC:
170                 /*Represents 8-bit Generic data */
171                 ipu_ch_param_set_field(&params, 0, 107, 3, 5);  /* bits/pixel */
172                 ipu_ch_param_set_field(&params, 1, 85, 4, 6);   /* pix format */
173                 ipu_ch_param_set_field(&params, 1, 78, 7, 63);  /* burst size */
174
175                 break;
176         case IPU_PIX_FMT_GENERIC_32:
177                 /*Represents 32-bit Generic data */
178                 break;
179         case IPU_PIX_FMT_RGB565:
180                 ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
181                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
182                 ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
183
184                 _ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
185                 break;
186         case IPU_PIX_FMT_BGR24:
187                 ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
188                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
189                 ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
190
191                 _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
192                 break;
193         case IPU_PIX_FMT_RGB24:
194         case IPU_PIX_FMT_YUV444:
195                 ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
196                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
197                 ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
198
199                 _ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
200                 break;
201         case IPU_PIX_FMT_BGRA32:
202         case IPU_PIX_FMT_BGR32:
203                 ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
204                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
205                 ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
206
207                 _ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
208                 break;
209         case IPU_PIX_FMT_RGBA32:
210         case IPU_PIX_FMT_RGB32:
211                 ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
212                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
213                 ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
214
215                 _ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
216                 break;
217         case IPU_PIX_FMT_ABGR32:
218                 ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
219                 ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
220
221                 _ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
222                 break;
223         case IPU_PIX_FMT_UYVY:
224                 ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
225                 ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
226                 ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
227                 break;
228         case IPU_PIX_FMT_YUYV:
229                 ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
230                 ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
231                 ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
232                 break;
233         case IPU_PIX_FMT_YUV420P2:
234         case IPU_PIX_FMT_YUV420P:
235                 ipu_ch_param_set_field(&params, 1, 85, 4, 2);   /* pix format */
236
237                 if (uv_stride < stride / 2)
238                         uv_stride = stride / 2;
239
240                 u_offset = stride * height;
241                 v_offset = u_offset + (uv_stride * height / 2);
242                 if ((ch == 8) || (ch == 9) || (ch == 10)) {
243                         ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
244                         uv_stride = uv_stride*2;
245                 } else {
246                         ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
247                 }
248                 break;
249         case IPU_PIX_FMT_YVU422P:
250                 /* BPP & pixel format */
251                 ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
252                 ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
253
254                 if (uv_stride < stride / 2)
255                         uv_stride = stride / 2;
256
257                 v_offset = (v == 0) ? stride * height : v;
258                 u_offset = (u == 0) ? v_offset + v_offset / 2 : u;
259                 break;
260         case IPU_PIX_FMT_YUV422P:
261                 /* BPP & pixel format */
262                 ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
263                 ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
264
265                 if (uv_stride < stride / 2)
266                         uv_stride = stride / 2;
267
268                 u_offset = (u == 0) ? stride * height : u;
269                 v_offset = (v == 0) ? u_offset + u_offset / 2 : v;
270                 break;
271         case IPU_PIX_FMT_NV12:
272                 /* BPP & pixel format */
273                 ipu_ch_param_set_field(&params, 1, 85, 4, 4);   /* pix format */
274                 uv_stride = stride;
275                 u_offset = (u == 0) ? stride * height : u;
276                 if ((ch == 8) || (ch == 9) || (ch == 10)) {
277                         ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
278                         uv_stride = uv_stride*2;
279                 } else {
280                         ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
281                 }
282                 break;
283         default:
284                 dev_err(g_ipu_dev, "mxc ipu: unimplemented pixel format\n");
285                 break;
286         }
287         /*set burst size to 16*/
288
289
290         if (uv_stride)
291                 ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
292
293         /* Get the uv offset from user when need cropping */
294         if (u || v) {
295                 u_offset = u;
296                 v_offset = v;
297         }
298
299         /* UBO and VBO are 22-bit and 8-byte aligned */
300         if (u_offset/8 > 0x3fffff)
301                 dev_warn(g_ipu_dev,
302                          "IDMAC%d's U offset exceeds IPU limitation\n", ch);
303         if (v_offset/8 > 0x3fffff)
304                 dev_warn(g_ipu_dev,
305                          "IDMAC%d's V offset exceeds IPU limitation\n", ch);
306         if (u_offset%8)
307                 dev_warn(g_ipu_dev,
308                          "IDMAC%d's U offset is not 8-byte aligned\n", ch);
309         if (v_offset%8)
310                 dev_warn(g_ipu_dev,
311                          "IDMAC%d's V offset is not 8-byte aligned\n", ch);
312
313         ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
314         ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
315
316         pr_debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch));
317         memcpy(ipu_ch_param_addr(ch), &params, sizeof(params));
318 };
319
320 static inline void _ipu_ch_param_set_burst_size(uint32_t ch,
321                                                 uint16_t burst_pixels)
322 {
323         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 78, 7,
324                                burst_pixels - 1);
325 };
326
327 static inline int _ipu_ch_param_get_burst_size(uint32_t ch)
328 {
329         return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7) + 1;
330 };
331
332 static inline int _ipu_ch_param_get_bpp(uint32_t ch)
333 {
334         return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3);
335 };
336
337 static inline void _ipu_ch_param_set_buffer(uint32_t ch, int bufNum,
338                                             dma_addr_t phyaddr)
339 {
340         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 29 * bufNum, 29,
341                                phyaddr / 8);
342 };
343
344 static inline void _ipu_ch_param_set_rotation(uint32_t ch,
345                                               ipu_rotate_mode_t rot)
346 {
347         u32 temp_rot = bitrev8(rot) >> 5;
348         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 119, 3, temp_rot);
349 };
350
351 static inline void _ipu_ch_param_set_block_mode(uint32_t ch)
352 {
353         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 117, 2, 1);
354 };
355
356 static inline void _ipu_ch_param_set_alpha_use_separate_channel(uint32_t ch,
357                                                                 bool option)
358 {
359         if (option) {
360                 ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 89, 1, 1);
361         } else {
362                 ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 89, 1, 0);
363         }
364 };
365
366 static inline void _ipu_ch_param_set_alpha_condition_read(uint32_t ch)
367 {
368         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 149, 1, 1);
369 };
370
371 static inline void _ipu_ch_param_set_alpha_buffer_memory(uint32_t ch)
372 {
373         int alp_mem_idx;
374
375         switch (ch) {
376         case 14: /* PRP graphic */
377                 alp_mem_idx = 0;
378                 break;
379         case 15: /* PP graphic */
380                 alp_mem_idx = 1;
381                 break;
382         case 23: /* DP BG SYNC graphic */
383                 alp_mem_idx = 4;
384                 break;
385         case 27: /* DP FG SYNC graphic */
386                 alp_mem_idx = 2;
387                 break;
388         default:
389                 dev_err(g_ipu_dev, "unsupported correlative channel of local "
390                         "alpha channel\n");
391                 return;
392         }
393
394         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 90, 3, alp_mem_idx);
395 };
396
397 static inline void _ipu_ch_param_set_interlaced_scan(uint32_t ch)
398 {
399         u32 stride;
400         ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 113, 1, 1);
401         stride = ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14) + 1;
402         /* ILO is 20-bit and 8-byte aligned */
403         if (stride/8 > 0xfffff)
404                 dev_warn(g_ipu_dev,
405                          "IDMAC%d's ILO exceeds IPU limitation\n", ch);
406         if (stride%8)
407                 dev_warn(g_ipu_dev,
408                          "IDMAC%d's ILO is not 8-byte aligned\n", ch);
409         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 58, 20, stride / 8);
410         stride *= 2;
411         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1);
412 };
413
414 static inline void _ipu_ch_param_set_high_priority(uint32_t ch)
415 {
416         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 93, 2, 1);
417 };
418
419 /* IDMAC U/V offset changing support */
420 /* U and V input is not affected, */
421 /* the update is done by new calculation according to */
422 /* vertical_offset and horizontal_offset */
423 static inline void _ipu_ch_offset_update(int ch,
424                                         uint32_t pixel_fmt,
425                                         uint32_t width,
426                                         uint32_t height,
427                                         uint32_t stride,
428                                         uint32_t u,
429                                         uint32_t v,
430                                         uint32_t uv_stride,
431                                         uint32_t vertical_offset,
432                                         uint32_t horizontal_offset)
433 {
434         uint32_t u_offset = 0;
435         uint32_t v_offset = 0;
436         uint32_t u_fix = 0;
437         uint32_t v_fix = 0;
438
439         switch (pixel_fmt) {
440         case IPU_PIX_FMT_GENERIC:
441         case IPU_PIX_FMT_GENERIC_32:
442         case IPU_PIX_FMT_RGB565:
443         case IPU_PIX_FMT_BGR24:
444         case IPU_PIX_FMT_RGB24:
445         case IPU_PIX_FMT_YUV444:
446         case IPU_PIX_FMT_BGRA32:
447         case IPU_PIX_FMT_BGR32:
448         case IPU_PIX_FMT_RGBA32:
449         case IPU_PIX_FMT_RGB32:
450         case IPU_PIX_FMT_ABGR32:
451         case IPU_PIX_FMT_UYVY:
452         case IPU_PIX_FMT_YUYV:
453                 break;
454
455         case IPU_PIX_FMT_YUV420P2:
456         case IPU_PIX_FMT_YUV420P:
457                 if (uv_stride < stride / 2)
458                         uv_stride = stride / 2;
459
460                 u_offset = stride * (height - vertical_offset - 1) +
461                                         (stride - horizontal_offset) +
462                                         (uv_stride * vertical_offset / 2) +
463                                         horizontal_offset / 2;
464                 v_offset = u_offset + (uv_stride * height / 2);
465                 u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
466                                         (horizontal_offset / 2) -
467                                         (stride * vertical_offset) - (horizontal_offset)) :
468                                         u_offset;
469                 v_fix = v ? (v + (uv_stride * vertical_offset / 2) +
470                                         (horizontal_offset / 2) -
471                                         (stride * vertical_offset) - (horizontal_offset)) :
472                                         v_offset;
473
474                 break;
475         case IPU_PIX_FMT_YVU422P:
476                 if (uv_stride < stride / 2)
477                         uv_stride = stride / 2;
478
479                 v_offset = stride * (height - vertical_offset - 1) +
480                                         (stride - horizontal_offset) +
481                                         (uv_stride * vertical_offset) +
482                                         horizontal_offset / 2;
483                 u_offset = v_offset + uv_stride * height;
484                 u_fix = u ? (u + (uv_stride * vertical_offset) +
485                                         horizontal_offset / 2 -
486                                         (stride * vertical_offset) - (horizontal_offset)) :
487                                         u_offset;
488                 v_fix = v ? (v + (uv_stride * vertical_offset) +
489                                         horizontal_offset / 2 -
490                                         (stride * vertical_offset) - (horizontal_offset)) :
491                                         v_offset;
492                 break;
493         case IPU_PIX_FMT_YUV422P:
494                 if (uv_stride < stride / 2)
495                         uv_stride = stride / 2;
496
497                 u_offset = stride * (height - vertical_offset - 1) +
498                                         (stride - horizontal_offset) +
499                                         (uv_stride * vertical_offset) +
500                                         horizontal_offset / 2;
501                 v_offset = u_offset + uv_stride * height;
502                 u_fix = u ? (u + (uv_stride * vertical_offset) +
503                                         horizontal_offset / 2 -
504                                         (stride * vertical_offset) - (horizontal_offset)) :
505                                         u_offset;
506                 v_fix = v ? (v + (uv_stride * vertical_offset) +
507                                         horizontal_offset / 2 -
508                                         (stride * vertical_offset) - (horizontal_offset)) :
509                                         v_offset;
510                 break;
511
512         case IPU_PIX_FMT_NV12:
513                 uv_stride = stride;
514                 u_offset = stride * (height - vertical_offset - 1) +
515                                         (stride - horizontal_offset) +
516                                         (uv_stride * vertical_offset / 2) +
517                                         horizontal_offset;
518                 u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
519                                         horizontal_offset -
520                                         (stride * vertical_offset) - (horizontal_offset)) :
521                                         u_offset;
522
523                 break;
524         default:
525                 dev_err(g_ipu_dev, "mxc ipu: unimplemented pixel format\n");
526                 break;
527         }
528
529
530
531         if (u_fix > u_offset)
532                 u_offset = u_fix;
533
534         if (v_fix > v_offset)
535                 v_offset = v_fix;
536
537         /* UBO and VBO are 22-bit and 8-byte aligned */
538         if (u_offset/8 > 0x3fffff)
539                 dev_warn(g_ipu_dev,
540                         "IDMAC%d's U offset exceeds IPU limitation\n", ch);
541         if (v_offset/8 > 0x3fffff)
542                 dev_warn(g_ipu_dev,
543                         "IDMAC%d's V offset exceeds IPU limitation\n", ch);
544         if (u_offset%8)
545                 dev_warn(g_ipu_dev,
546                         "IDMAC%d's U offset is not 8-byte aligned\n", ch);
547         if (v_offset%8)
548                 dev_warn(g_ipu_dev,
549                         "IDMAC%d's V offset is not 8-byte aligned\n", ch);
550
551         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 46, 22, u_offset / 8);
552         ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 68, 22, v_offset / 8);
553
554 };
555
556 static inline void _ipu_ch_params_set_alpha_width(uint32_t ch, int alpha_width)
557 {
558         ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 125, 3, alpha_width - 1);
559 };
560
561 #endif