]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/dma/pxp/pxp_dma_v2.c
ENGR00290664 PXP: allocate DMA TX descriptors on demand instead of in PXP initialization
[karo-tx-linux.git] / drivers / dma / pxp / pxp_dma_v2.c
1 /*
2  * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17  *
18  */
19 /*
20  * Based on STMP378X PxP driver
21  * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
22  */
23
24 #include <linux/dma-mapping.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/io.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/mutex.h>
31 #include <linux/platform_device.h>
32 #include <linux/slab.h>
33 #include <linux/vmalloc.h>
34 #include <linux/dmaengine.h>
35 #include <linux/pxp_dma.h>
36 #include <linux/timer.h>
37 #include <linux/clk.h>
38 #include <linux/workqueue.h>
39 #include <linux/sched.h>
40 #include <linux/of.h>
41 #include <linux/kthread.h>
42
43 #include "regs-pxp_v2.h"
44
45 #define PXP_DOWNSCALE_THRESHOLD         0x4000
46
47 static LIST_HEAD(head);
48 static int timeout_in_ms = 600;
49 static unsigned int block_size;
50 static struct kmem_cache *tx_desc_cache;
51
52 struct pxp_dma {
53         struct dma_device dma;
54 };
55
56 struct pxps {
57         struct platform_device *pdev;
58         struct clk *clk;
59         void __iomem *base;
60         int irq;                /* PXP IRQ to the CPU */
61
62         spinlock_t lock;
63         struct mutex clk_mutex;
64         int clk_stat;
65 #define CLK_STAT_OFF            0
66 #define CLK_STAT_ON             1
67         int pxp_ongoing;
68         int lut_state;
69
70         struct device *dev;
71         struct pxp_dma pxp_dma;
72         struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
73         struct work_struct work;
74
75         /* describes most recent processing configuration */
76         struct pxp_config_data pxp_conf_state;
77
78         /* to turn clock off when pxp is inactive */
79         struct timer_list clk_timer;
80
81         /* for pxp config dispatch asynchronously*/
82         struct task_struct *dispatch;
83         wait_queue_head_t thread_waitq;
84         struct completion complete;
85 };
86
87 #define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
88 #define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
89 #define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
90 #define to_pxp(id) container_of(id, struct pxps, pxp_dma)
91
92 #define PXP_DEF_BUFS    2
93 #define PXP_MIN_PIX     8
94
95 static uint32_t pxp_s0_formats[] = {
96         PXP_PIX_FMT_RGB32,
97         PXP_PIX_FMT_RGB565,
98         PXP_PIX_FMT_RGB555,
99         PXP_PIX_FMT_YUV420P,
100         PXP_PIX_FMT_YUV422P,
101 };
102
103 /*
104  * PXP common functions
105  */
106 static void dump_pxp_reg(struct pxps *pxp)
107 {
108         dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
109                 __raw_readl(pxp->base + HW_PXP_CTRL));
110         dev_dbg(pxp->dev, "PXP_STAT 0x%x",
111                 __raw_readl(pxp->base + HW_PXP_STAT));
112         dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
113                 __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
114         dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
115                 __raw_readl(pxp->base + HW_PXP_OUT_BUF));
116         dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
117                 __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
118         dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
119                 __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
120         dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
121                 __raw_readl(pxp->base + HW_PXP_OUT_LRC));
122         dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
123                 __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
124         dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
125                 __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
126         dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
127                 __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
128         dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
129                 __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
130         dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
131                 __raw_readl(pxp->base + HW_PXP_PS_CTRL));
132         dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
133                 __raw_readl(pxp->base + HW_PXP_PS_BUF));
134         dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
135                 __raw_readl(pxp->base + HW_PXP_PS_UBUF));
136         dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
137                 __raw_readl(pxp->base + HW_PXP_PS_VBUF));
138         dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
139                 __raw_readl(pxp->base + HW_PXP_PS_PITCH));
140         dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
141                 __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
142         dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
143                 __raw_readl(pxp->base + HW_PXP_PS_SCALE));
144         dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
145                 __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
146         dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
147                 __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
148         dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
149                 __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
150         dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
151                 __raw_readl(pxp->base + HW_PXP_AS_CTRL));
152         dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
153                 __raw_readl(pxp->base + HW_PXP_AS_BUF));
154         dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
155                 __raw_readl(pxp->base + HW_PXP_AS_PITCH));
156         dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
157                 __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
158         dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
159                 __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
160         dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
161                 __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
162         dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
163                 __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
164         dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
165                 __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
166         dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
167                 __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
168         dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
169                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
170         dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
171                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
172         dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
173                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
174         dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
175                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
176         dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
177                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
178         dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
179                 __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
180         dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
181                 __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
182         dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
183                 __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
184         dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
185                 __raw_readl(pxp->base + HW_PXP_LUT_DATA));
186         dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
187                 __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
188         dev_dbg(pxp->dev, "PXP_CFA 0x%x",
189                 __raw_readl(pxp->base + HW_PXP_CFA));
190         dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
191                 __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
192         dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
193                 __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
194         dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
195                 __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
196         dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
197                 __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
198         dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
199                 __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
200         dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
201                 __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
202         dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
203                 __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
204         dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
205                 __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
206         dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
207                 __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
208         dev_dbg(pxp->dev, "PXP_POWER 0x%x",
209                 __raw_readl(pxp->base + HW_PXP_POWER));
210         dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
211                 __raw_readl(pxp->base + HW_PXP_NEXT));
212         dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
213                 __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
214         dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
215                 __raw_readl(pxp->base + HW_PXP_DEBUG));
216         dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
217                 __raw_readl(pxp->base + HW_PXP_VERSION));
218 }
219
220 static bool is_yuv(u32 pix_fmt)
221 {
222         if ((pix_fmt == PXP_PIX_FMT_YUYV) |
223             (pix_fmt == PXP_PIX_FMT_UYVY) |
224             (pix_fmt == PXP_PIX_FMT_YVYU) |
225             (pix_fmt == PXP_PIX_FMT_VYUY) |
226             (pix_fmt == PXP_PIX_FMT_Y41P) |
227             (pix_fmt == PXP_PIX_FMT_YUV444) |
228             (pix_fmt == PXP_PIX_FMT_NV12) |
229             (pix_fmt == PXP_PIX_FMT_NV16) |
230             (pix_fmt == PXP_PIX_FMT_NV61) |
231             (pix_fmt == PXP_PIX_FMT_GREY) |
232             (pix_fmt == PXP_PIX_FMT_GY04) |
233             (pix_fmt == PXP_PIX_FMT_YVU410P) |
234             (pix_fmt == PXP_PIX_FMT_YUV410P) |
235             (pix_fmt == PXP_PIX_FMT_YVU420P) |
236             (pix_fmt == PXP_PIX_FMT_YUV420P) |
237             (pix_fmt == PXP_PIX_FMT_YUV420P2) |
238             (pix_fmt == PXP_PIX_FMT_YVU422P) |
239             (pix_fmt == PXP_PIX_FMT_YUV422P)) {
240                 return true;
241         } else {
242                 return false;
243         }
244 }
245
246 static void pxp_set_ctrl(struct pxps *pxp)
247 {
248         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
249         struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
250         u32 ctrl;
251         u32 fmt_ctrl;
252         int need_swap = 0;   /* to support YUYV and YVYU formats */
253
254         /* Configure S0 input format */
255         switch (pxp_conf->s0_param.pixel_fmt) {
256         case PXP_PIX_FMT_RGB32:
257                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
258                 break;
259         case PXP_PIX_FMT_RGB565:
260                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
261                 break;
262         case PXP_PIX_FMT_RGB555:
263                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
264                 break;
265         case PXP_PIX_FMT_YUV420P:
266                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
267                 break;
268         case PXP_PIX_FMT_YVU420P:
269                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
270                 break;
271         case PXP_PIX_FMT_GREY:
272                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
273                 break;
274         case PXP_PIX_FMT_GY04:
275                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y4;
276                 break;
277         case PXP_PIX_FMT_YUV422P:
278                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
279                 break;
280         case PXP_PIX_FMT_UYVY:
281                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
282                 break;
283         case PXP_PIX_FMT_YUYV:
284                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__UYVY1P422;
285                 need_swap = 1;
286                 break;
287         case PXP_PIX_FMT_VYUY:
288                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
289                 break;
290         case PXP_PIX_FMT_YVYU:
291                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__VYUY1P422;
292                 need_swap = 1;
293                 break;
294         case PXP_PIX_FMT_NV12:
295                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P420;
296                 break;
297         case PXP_PIX_FMT_NV21:
298                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P420;
299                 break;
300         case PXP_PIX_FMT_NV16:
301                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV2P422;
302                 break;
303         case PXP_PIX_FMT_NV61:
304                 fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YVU2P422;
305                 break;
306         default:
307                 fmt_ctrl = 0;
308         }
309
310         ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl) | BF_PXP_PS_CTRL_SWAP(need_swap);
311         __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL_SET);
312
313         /* Configure output format based on out_channel format */
314         switch (pxp_conf->out_param.pixel_fmt) {
315         case PXP_PIX_FMT_RGB32:
316                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
317                 break;
318         case PXP_PIX_FMT_BGRA32:
319                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__ARGB8888;
320                 break;
321         case PXP_PIX_FMT_RGB24:
322                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888P;
323                 break;
324         case PXP_PIX_FMT_RGB565:
325                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
326                 break;
327         case PXP_PIX_FMT_RGB555:
328                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
329                 break;
330         case PXP_PIX_FMT_GREY:
331                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
332                 break;
333         case PXP_PIX_FMT_GY04:
334                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y4;
335                 break;
336         case PXP_PIX_FMT_UYVY:
337                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__UYVY1P422;
338                 break;
339         case PXP_PIX_FMT_VYUY:
340                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__VYUY1P422;
341                 break;
342         case PXP_PIX_FMT_NV12:
343                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
344                 break;
345         case PXP_PIX_FMT_NV21:
346                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P420;
347                 break;
348         case PXP_PIX_FMT_NV16:
349                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
350                 break;
351         case PXP_PIX_FMT_NV61:
352                 fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YVU2P422;
353                 break;
354         default:
355                 fmt_ctrl = 0;
356         }
357
358         ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
359         __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
360
361         ctrl = 0;
362         if (proc_data->scaling)
363                 ;
364         if (proc_data->vflip)
365                 ctrl |= BM_PXP_CTRL_VFLIP;
366         if (proc_data->hflip)
367                 ctrl |= BM_PXP_CTRL_HFLIP;
368         if (proc_data->rotate) {
369                 ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
370                 if (proc_data->rot_pos)
371                         ctrl |= BM_PXP_CTRL_ROT_POS;
372         }
373
374         /* In default, the block size is set to 8x8
375          * But block size can be set to 16x16 due to
376          * blocksize variable modification
377          */
378         ctrl |= block_size << 23;
379
380         __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
381 }
382
383 static int pxp_start(struct pxps *pxp)
384 {
385         __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
386         __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
387         dump_pxp_reg(pxp);
388
389         return 0;
390 }
391
392 static void pxp_set_outbuf(struct pxps *pxp)
393 {
394         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
395         struct pxp_layer_param *out_params = &pxp_conf->out_param;
396
397         __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
398
399         __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
400                      BF_PXP_OUT_LRC_Y(out_params->height - 1),
401                      pxp->base + HW_PXP_OUT_LRC);
402
403         if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
404                 __raw_writel(out_params->stride * 3,
405                                 pxp->base + HW_PXP_OUT_PITCH);
406         } else if (out_params->pixel_fmt == PXP_PIX_FMT_BGRA32 ||
407                  out_params->pixel_fmt == PXP_PIX_FMT_RGB32) {
408                 __raw_writel(out_params->stride << 2,
409                                 pxp->base + HW_PXP_OUT_PITCH);
410         } else if (out_params->pixel_fmt == PXP_PIX_FMT_RGB565) {
411                 __raw_writel(out_params->stride << 1,
412                                 pxp->base + HW_PXP_OUT_PITCH);
413         } else if (out_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
414                 (out_params->pixel_fmt == PXP_PIX_FMT_VYUY)) {
415                 __raw_writel(out_params->stride << 1,
416                                 pxp->base + HW_PXP_OUT_PITCH);
417         } else if (out_params->pixel_fmt == PXP_PIX_FMT_GREY ||
418                    out_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
419                    out_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
420                    out_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
421                    out_params->pixel_fmt == PXP_PIX_FMT_NV61) {
422                 __raw_writel(out_params->stride,
423                                 pxp->base + HW_PXP_OUT_PITCH);
424         } else if (out_params->pixel_fmt == PXP_PIX_FMT_GY04) {
425                 __raw_writel(out_params->stride >> 1,
426                                 pxp->base + HW_PXP_OUT_PITCH);
427         } else {
428                 __raw_writel(0, pxp->base + HW_PXP_OUT_PITCH);
429         }
430
431         /* set global alpha if necessary */
432         if (out_params->global_alpha_enable) {
433                 __raw_writel(out_params->global_alpha << 24,
434                                 pxp->base + HW_PXP_OUT_CTRL_SET);
435                 __raw_writel(BM_PXP_OUT_CTRL_ALPHA_OUTPUT,
436                                 pxp->base + HW_PXP_OUT_CTRL_SET);
437         }
438 }
439
440 static void pxp_set_s0colorkey(struct pxps *pxp)
441 {
442         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
443         struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
444
445         /* Low and high are set equal. V4L does not allow a chromakey range */
446         if (s0_params->color_key_enable == 0 || s0_params->color_key == -1) {
447                 /* disable color key */
448                 __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
449                 __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
450         } else {
451                 __raw_writel(s0_params->color_key,
452                              pxp->base + HW_PXP_PS_CLRKEYLOW);
453                 __raw_writel(s0_params->color_key,
454                              pxp->base + HW_PXP_PS_CLRKEYHIGH);
455         }
456 }
457
458 static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
459 {
460         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
461         struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
462
463         /* Low and high are set equal. V4L does not allow a chromakey range */
464         if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
465                 __raw_writel(ol_params->color_key,
466                              pxp->base + HW_PXP_AS_CLRKEYLOW);
467                 __raw_writel(ol_params->color_key,
468                              pxp->base + HW_PXP_AS_CLRKEYHIGH);
469         } else {
470                 /* disable color key */
471                 __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
472                 __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
473         }
474 }
475
476 static void pxp_set_oln(int layer_no, struct pxps *pxp)
477 {
478         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
479         struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
480         dma_addr_t phys_addr = olparams_data->paddr;
481         u32 pitch = olparams_data->stride ? olparams_data->stride :
482                                             olparams_data->width;
483
484         __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
485
486         /* Fixme */
487         if (olparams_data->width == 0 && olparams_data->height == 0) {
488                 __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_AS_ULC);
489                 __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_LRC);
490         } else {
491                 __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
492                 if (pxp_conf->proc_data.rotate == 90 ||
493                     pxp_conf->proc_data.rotate == 270) {
494                         if (pxp_conf->proc_data.rot_pos == 1) {
495                                 __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->height - 1) |
496                                         BF_PXP_OUT_AS_LRC_Y(olparams_data->width - 1),
497                                         pxp->base + HW_PXP_OUT_AS_LRC);
498                         } else {
499                                 __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
500                                         BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
501                                         pxp->base + HW_PXP_OUT_AS_LRC);
502                         }
503                 } else {
504                         __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width - 1) |
505                                 BF_PXP_OUT_AS_LRC_Y(olparams_data->height - 1),
506                                 pxp->base + HW_PXP_OUT_AS_LRC);
507                 }
508         }
509
510         if ((olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) |
511                  (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32)) {
512                 __raw_writel(pitch << 2,
513                                 pxp->base + HW_PXP_AS_PITCH);
514         } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
515                 __raw_writel(pitch << 1,
516                                 pxp->base + HW_PXP_AS_PITCH);
517         } else {
518                 __raw_writel(0, pxp->base + HW_PXP_AS_PITCH);
519         }
520 }
521
522 static void pxp_set_olparam(int layer_no, struct pxps *pxp)
523 {
524         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
525         struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
526         u32 olparam;
527
528         olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
529         if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB32) {
530                 olparam |=
531                     BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
532         } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_BGRA32) {
533                 olparam |=
534                     BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__ARGB8888);
535                 if (!olparams_data->combine_enable) {
536                         olparam |=
537                                 BF_PXP_AS_CTRL_ALPHA_CTRL
538                                 (BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs);
539                         olparam |= 0x3 << 16;
540                 }
541         } else if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB565) {
542                 olparam |=
543                     BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
544         }
545         if (olparams_data->global_alpha_enable) {
546                 if (olparams_data->global_override) {
547                         olparam |=
548                                 BF_PXP_AS_CTRL_ALPHA_CTRL
549                                 (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
550                 } else {
551                         olparam |=
552                                 BF_PXP_AS_CTRL_ALPHA_CTRL
553                                 (BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply);
554                 }
555                 if (olparams_data->alpha_invert)
556                         olparam |= BM_PXP_AS_CTRL_ALPHA_INVERT;
557         }
558         if (olparams_data->color_key_enable)
559                 olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
560
561         __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
562 }
563
564 static void pxp_set_s0param(struct pxps *pxp)
565 {
566         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
567         struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
568         u32 s0param;
569
570         /* contains the coordinate for the PS in the OUTPUT buffer. */
571         if ((pxp_conf->s0_param).width == 0 &&
572                 (pxp_conf->s0_param).height == 0) {
573                 __raw_writel(0xffffffff, pxp->base + HW_PXP_OUT_PS_ULC);
574                 __raw_writel(0x0, pxp->base + HW_PXP_OUT_PS_LRC);
575         } else {
576                 s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
577                 s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
578                 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
579                 s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
580                                 proc_data->drect.width - 1);
581                 s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
582                                 proc_data->drect.height - 1);
583                 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
584         }
585 }
586
587 /* crop behavior is re-designed in h/w. */
588 static void pxp_set_s0crop(struct pxps *pxp)
589 {
590         /*
591          * place-holder, it's implemented in other functions in this driver.
592          * Refer to "Clipping source images" section in RM for detail.
593          */
594 }
595
596 static int pxp_set_scaling(struct pxps *pxp)
597 {
598         int ret = 0;
599         u32 xscale, yscale, s0scale;
600         u32 decx, decy, xdec = 0, ydec = 0;
601         struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
602
603         if (((proc_data->srect.width == proc_data->drect.width) &&
604             (proc_data->srect.height == proc_data->drect.height)) ||
605             ((proc_data->srect.width == 0) && (proc_data->srect.height == 0))) {
606                 proc_data->scaling = 0;
607                 __raw_writel(0x10001000, pxp->base + HW_PXP_PS_SCALE);
608                 __raw_writel(0, pxp->base + HW_PXP_PS_CTRL);
609                 goto out;
610         }
611
612         proc_data->scaling = 1;
613         decx = proc_data->srect.width / proc_data->drect.width;
614         decy = proc_data->srect.height / proc_data->drect.height;
615         if (decx > 0) {
616                 if (decx >= 2 && decx < 4) {
617                         decx = 2;
618                         xdec = 1;
619                 } else if (decx >= 4 && decx < 8) {
620                         decx = 4;
621                         xdec = 2;
622                 } else if (decx >= 8) {
623                         decx = 8;
624                         xdec = 3;
625                 }
626                 xscale = proc_data->srect.width * 0x1000 /
627                          (proc_data->drect.width * decx);
628         } else
629                 xscale = proc_data->srect.width * 0x1000 /
630                          proc_data->drect.width;
631         if (decy > 0) {
632                 if (decy >= 2 && decy < 4) {
633                         decy = 2;
634                         ydec = 1;
635                 } else if (decy >= 4 && decy < 8) {
636                         decy = 4;
637                         ydec = 2;
638                 } else if (decy >= 8) {
639                         decy = 8;
640                         ydec = 3;
641                 }
642                 yscale = proc_data->srect.height * 0x1000 /
643                          (proc_data->drect.height * decy);
644         } else
645                 yscale = proc_data->srect.height * 0x1000 /
646                          proc_data->drect.height;
647
648         __raw_writel((xdec << 10) | (ydec << 8), pxp->base + HW_PXP_PS_CTRL);
649
650         if (xscale > PXP_DOWNSCALE_THRESHOLD)
651                 xscale = PXP_DOWNSCALE_THRESHOLD;
652         if (yscale > PXP_DOWNSCALE_THRESHOLD)
653                 yscale = PXP_DOWNSCALE_THRESHOLD;
654         s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
655                 BF_PXP_PS_SCALE_XSCALE(xscale);
656         __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
657
658 out:
659         pxp_set_ctrl(pxp);
660
661         return ret;
662 }
663
664 static void pxp_set_bg(struct pxps *pxp)
665 {
666         __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
667                      pxp->base + HW_PXP_PS_BACKGROUND);
668 }
669
670 static void pxp_set_lut(struct pxps *pxp)
671 {
672         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
673         int lut_op = pxp_conf->proc_data.lut_transform;
674         u32 reg_val;
675         int i;
676         bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
677         u8 *cmap = pxp_conf->proc_data.lut_map;
678         u32 entry_src;
679         u32 pix_val;
680         u8 entry[4];
681
682         /*
683          * If LUT already configured as needed, return...
684          * Unless CMAP is needed and it has been updated.
685          */
686         if ((pxp->lut_state == lut_op) &&
687                 !(use_cmap && pxp_conf->proc_data.lut_map_updated))
688                 return;
689
690         if (lut_op == PXP_LUT_NONE) {
691                 __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
692                              pxp->base + HW_PXP_LUT_CTRL);
693         } else if (((lut_op & PXP_LUT_INVERT) != 0)
694                 && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
695                 /* Fill out LUT table with inverted monochromized values */
696
697                 /* clear bypass bit, set lookup mode & out mode */
698                 __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
699                                 (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
700                                 BF_PXP_LUT_CTRL_OUT_MODE
701                                 (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
702                                 pxp->base + HW_PXP_LUT_CTRL);
703
704                 /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
705                 __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
706
707                 /* LUT address pointer auto-increments after each data write */
708                 for (pix_val = 0; pix_val < 256; pix_val += 4) {
709                         for (i = 0; i < 4; i++) {
710                                 entry_src = use_cmap ?
711                                         cmap[pix_val + i] : pix_val + i;
712                                 entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
713                         }
714                         reg_val = (entry[3] << 24) | (entry[2] << 16) |
715                                 (entry[1] << 8) | entry[0];
716                         __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
717                 }
718         } else if ((lut_op & PXP_LUT_INVERT) != 0) {
719                 /* Fill out LUT table with 8-bit inverted values */
720
721                 /* clear bypass bit, set lookup mode & out mode */
722                 __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
723                                 (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
724                                 BF_PXP_LUT_CTRL_OUT_MODE
725                                 (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
726                                 pxp->base + HW_PXP_LUT_CTRL);
727
728                 /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
729                 __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
730
731                 /* LUT address pointer auto-increments after each data write */
732                 for (pix_val = 0; pix_val < 256; pix_val += 4) {
733                         for (i = 0; i < 4; i++) {
734                                 entry_src = use_cmap ?
735                                         cmap[pix_val + i] : pix_val + i;
736                                 entry[i] = ~entry_src & 0xFF;
737                         }
738                         reg_val = (entry[3] << 24) | (entry[2] << 16) |
739                                 (entry[1] << 8) | entry[0];
740                         __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
741                 }
742         } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
743                 /* Fill out LUT table with 8-bit monochromized values */
744
745                 /* clear bypass bit, set lookup mode & out mode */
746                 __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
747                                 (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
748                                 BF_PXP_LUT_CTRL_OUT_MODE
749                                 (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
750                                 pxp->base + HW_PXP_LUT_CTRL);
751
752                 /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
753                 __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
754
755                 /* LUT address pointer auto-increments after each data write */
756                 for (pix_val = 0; pix_val < 256; pix_val += 4) {
757                         for (i = 0; i < 4; i++) {
758                                 entry_src = use_cmap ?
759                                         cmap[pix_val + i] : pix_val + i;
760                                 entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
761                         }
762                         reg_val = (entry[3] << 24) | (entry[2] << 16) |
763                                 (entry[1] << 8) | entry[0];
764                         __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
765                 }
766         } else if (use_cmap) {
767                 /* Fill out LUT table using colormap values */
768
769                 /* clear bypass bit, set lookup mode & out mode */
770                 __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
771                                 (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
772                                 BF_PXP_LUT_CTRL_OUT_MODE
773                                 (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
774                                 pxp->base + HW_PXP_LUT_CTRL);
775
776                 /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
777                 __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
778
779                 /* LUT address pointer auto-increments after each data write */
780                 for (pix_val = 0; pix_val < 256; pix_val += 4) {
781                         for (i = 0; i < 4; i++)
782                                 entry[i] = cmap[pix_val + i];
783                         reg_val = (entry[3] << 24) | (entry[2] << 16) |
784                                 (entry[1] << 8) | entry[0];
785                         __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
786                 }
787         }
788
789         pxp->lut_state = lut_op;
790 }
791
792 static void pxp_set_csc(struct pxps *pxp)
793 {
794         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
795         struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
796         struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
797         struct pxp_layer_param *out_params = &pxp_conf->out_param;
798
799         bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
800         bool output_is_YUV = is_yuv(out_params->pixel_fmt);
801
802         if (input_is_YUV && output_is_YUV) {
803                 /*
804                  * Input = YUV, Output = YUV
805                  * No CSC unless we need to do combining
806                  */
807                 if (ol_params->combine_enable) {
808                         /* Must convert to RGB for combining with RGB overlay */
809
810                         /* CSC1 - YUV->RGB */
811                         __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
812                         __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
813                         __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
814
815                         /* CSC2 - RGB->YUV */
816                         __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
817                         __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
818                         __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
819                         __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
820                         __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
821                         __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
822                         __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
823                 } else {
824                         /* Input & Output both YUV, so bypass both CSCs */
825
826                         /* CSC1 - Bypass */
827                         __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
828
829                         /* CSC2 - Bypass */
830                         __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
831                 }
832         } else if (input_is_YUV && !output_is_YUV) {
833                 /*
834                  * Input = YUV, Output = RGB
835                  * Use CSC1 to convert to RGB
836                  */
837
838                 /* CSC1 - YUV->RGB */
839                 __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
840                 __raw_writel(0x01980204, pxp->base + HW_PXP_CSC1_COEF1);
841                 __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
842
843                 /* CSC2 - Bypass */
844                 __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
845         } else if (!input_is_YUV && output_is_YUV) {
846                 /*
847                  * Input = RGB, Output = YUV
848                  * Use CSC2 to convert to YUV
849                  */
850
851                 /* CSC1 - Bypass */
852                 __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
853
854                 /* CSC2 - RGB->YUV */
855                 __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
856                 __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
857                 __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
858                 __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
859                 __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
860                 __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
861                 __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
862         } else {
863                 /*
864                  * Input = RGB, Output = RGB
865                  * Input & Output both RGB, so bypass both CSCs
866                  */
867
868                 /* CSC1 - Bypass */
869                 __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
870
871                 /* CSC2 - Bypass */
872                 __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
873         }
874
875         /* YCrCb colorspace */
876         /* Not sure when we use this...no YCrCb formats are defined for PxP */
877         /*
878            __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
879            __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
880            __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
881          */
882
883 }
884
885 static void pxp_set_s0buf(struct pxps *pxp)
886 {
887         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
888         struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
889         struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
890         dma_addr_t Y, U, V;
891         dma_addr_t Y1, U1, V1;
892         u32 offset, bpp = 1;
893         u32 pitch = s0_params->stride ? s0_params->stride :
894                                         s0_params->width;
895
896         Y = s0_params->paddr;
897
898         if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
899                 bpp = 2;
900         else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
901                 bpp = 4;
902         offset = (proc_data->srect.top * s0_params->width +
903                  proc_data->srect.left) * bpp;
904         /* clipping or cropping */
905         Y1 = Y + offset;
906         __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF);
907         if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
908             (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
909             (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)    ||
910             (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)) {
911                 /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
912                 int s = 2;
913                 if (s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P)
914                         s = 1;
915
916                 offset = proc_data->srect.top * s0_params->width / 4 +
917                          proc_data->srect.left / 2;
918                 U = Y + (s0_params->width * s0_params->height);
919                 U1 = U + offset;
920                 V = U + ((s0_params->width * s0_params->height) >> s);
921                 V1 = V + offset;
922                 __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
923                 __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF);
924         } else if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV12) ||
925                  (s0_params->pixel_fmt == PXP_PIX_FMT_NV21) ||
926                  (s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
927                  (s0_params->pixel_fmt == PXP_PIX_FMT_NV61)) {
928                 int s = 2;
929                 if ((s0_params->pixel_fmt == PXP_PIX_FMT_NV16) ||
930                     (s0_params->pixel_fmt == PXP_PIX_FMT_NV61))
931                         s = 1;
932
933                 offset = (proc_data->srect.top * s0_params->width +
934                           proc_data->srect.left) / s;
935                 U = Y + (s0_params->width * s0_params->height);
936                 U1 = U + offset;
937
938                 __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF);
939         }
940
941         /* TODO: only support RGB565, Y8, Y4, YUV420 */
942         if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY ||
943             s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P ||
944             s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P ||
945             s0_params->pixel_fmt == PXP_PIX_FMT_NV12 ||
946             s0_params->pixel_fmt == PXP_PIX_FMT_NV21 ||
947             s0_params->pixel_fmt == PXP_PIX_FMT_NV16 ||
948             s0_params->pixel_fmt == PXP_PIX_FMT_NV61 ||
949             s0_params->pixel_fmt == PXP_PIX_FMT_YUV422P) {
950                 __raw_writel(pitch, pxp->base + HW_PXP_PS_PITCH);
951         }
952         else if (s0_params->pixel_fmt == PXP_PIX_FMT_GY04)
953                 __raw_writel(pitch >> 1,
954                                 pxp->base + HW_PXP_PS_PITCH);
955         else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB32)
956                 __raw_writel(pitch << 2,
957                                 pxp->base + HW_PXP_PS_PITCH);
958         else if (s0_params->pixel_fmt == PXP_PIX_FMT_UYVY ||
959                  s0_params->pixel_fmt == PXP_PIX_FMT_YUYV ||
960                  s0_params->pixel_fmt == PXP_PIX_FMT_VYUY ||
961                  s0_params->pixel_fmt == PXP_PIX_FMT_YVYU)
962                 __raw_writel(pitch << 1,
963                                 pxp->base + HW_PXP_PS_PITCH);
964         else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565)
965                 __raw_writel(pitch << 1,
966                                 pxp->base + HW_PXP_PS_PITCH);
967         else
968                 __raw_writel(0, pxp->base + HW_PXP_PS_PITCH);
969 }
970
971 /**
972  * pxp_config() - configure PxP for a processing task
973  * @pxps:       PXP context.
974  * @pxp_chan:   PXP channel.
975  * @return:     0 on success or negative error code on failure.
976  */
977 static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
978 {
979         struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
980         int ol_nr;
981         int i;
982
983         /* Configure PxP regs */
984         pxp_set_ctrl(pxp);
985         pxp_set_s0param(pxp);
986         pxp_set_s0crop(pxp);
987         pxp_set_scaling(pxp);
988         ol_nr = pxp_conf_data->layer_nr - 2;
989         while (ol_nr > 0) {
990                 i = pxp_conf_data->layer_nr - 2 - ol_nr;
991                 pxp_set_oln(i, pxp);
992                 pxp_set_olparam(i, pxp);
993                 /* only the color key in higher overlay will take effect. */
994                 pxp_set_olcolorkey(i, pxp);
995                 ol_nr--;
996         }
997         pxp_set_s0colorkey(pxp);
998         pxp_set_csc(pxp);
999         pxp_set_bg(pxp);
1000         pxp_set_lut(pxp);
1001
1002         pxp_set_s0buf(pxp);
1003         pxp_set_outbuf(pxp);
1004
1005         return 0;
1006 }
1007
1008 static void pxp_clk_enable(struct pxps *pxp)
1009 {
1010         mutex_lock(&pxp->clk_mutex);
1011
1012         if (pxp->clk_stat == CLK_STAT_ON) {
1013                 mutex_unlock(&pxp->clk_mutex);
1014                 return;
1015         }
1016
1017         clk_prepare_enable(pxp->clk);
1018         pxp->clk_stat = CLK_STAT_ON;
1019
1020         mutex_unlock(&pxp->clk_mutex);
1021 }
1022
1023 static void pxp_clk_disable(struct pxps *pxp)
1024 {
1025         unsigned long flags;
1026
1027         mutex_lock(&pxp->clk_mutex);
1028
1029         if (pxp->clk_stat == CLK_STAT_OFF) {
1030                 mutex_unlock(&pxp->clk_mutex);
1031                 return;
1032         }
1033
1034         spin_lock_irqsave(&pxp->lock, flags);
1035         if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
1036                 spin_unlock_irqrestore(&pxp->lock, flags);
1037                 clk_disable_unprepare(pxp->clk);
1038                 pxp->clk_stat = CLK_STAT_OFF;
1039         } else
1040                 spin_unlock_irqrestore(&pxp->lock, flags);
1041
1042         mutex_unlock(&pxp->clk_mutex);
1043 }
1044
1045 static inline void clkoff_callback(struct work_struct *w)
1046 {
1047         struct pxps *pxp = container_of(w, struct pxps, work);
1048
1049         pxp_clk_disable(pxp);
1050 }
1051
1052 static void pxp_clkoff_timer(unsigned long arg)
1053 {
1054         struct pxps *pxp = (struct pxps *)arg;
1055
1056         if ((pxp->pxp_ongoing == 0) && list_empty(&head))
1057                 schedule_work(&pxp->work);
1058         else
1059                 mod_timer(&pxp->clk_timer,
1060                           jiffies + msecs_to_jiffies(timeout_in_ms));
1061 }
1062
1063 static struct pxp_tx_desc *pxpdma_first_active(struct pxp_channel *pxp_chan)
1064 {
1065         return list_entry(pxp_chan->active_list.next, struct pxp_tx_desc, list);
1066 }
1067
1068 static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
1069 {
1070         return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
1071 }
1072
1073 /* called with pxp_chan->lock held */
1074 static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
1075 {
1076         struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
1077         struct pxps *pxp = to_pxp(pxp_dma);
1078         struct pxp_tx_desc *desc;
1079         struct pxp_tx_desc *child;
1080         int i = 0;
1081
1082         /* so far we presume only one transaction on active_list */
1083         /* S0 */
1084         desc = pxpdma_first_active(pxp_chan);
1085         memcpy(&pxp->pxp_conf_state.s0_param,
1086                &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
1087         memcpy(&pxp->pxp_conf_state.proc_data,
1088                &desc->proc_data, sizeof(struct pxp_proc_data));
1089
1090         /* Save PxP configuration */
1091         list_for_each_entry(child, &desc->tx_list, list) {
1092                 if (i == 0) {   /* Output */
1093                         memcpy(&pxp->pxp_conf_state.out_param,
1094                                &child->layer_param.out_param,
1095                                sizeof(struct pxp_layer_param));
1096                 } else {        /* Overlay */
1097                         memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
1098                                &child->layer_param.ol_param,
1099                                sizeof(struct pxp_layer_param));
1100                 }
1101
1102                 i++;
1103         }
1104         pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
1105                  pxp->pxp_conf_state.s0_param.width,
1106                  pxp->pxp_conf_state.s0_param.height,
1107                  pxp->pxp_conf_state.s0_param.paddr);
1108         pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
1109                  pxp->pxp_conf_state.out_param.width,
1110                  pxp->pxp_conf_state.out_param.height,
1111                  pxp->pxp_conf_state.out_param.paddr);
1112 }
1113
1114 static void pxpdma_dostart_work(struct pxps *pxp)
1115 {
1116         struct pxp_channel *pxp_chan = NULL;
1117         unsigned long flags, flags1;
1118
1119         spin_lock_irqsave(&pxp->lock, flags);
1120         if (list_empty(&head)) {
1121                 pxp->pxp_ongoing = 0;
1122                 spin_unlock_irqrestore(&pxp->lock, flags);
1123                 return;
1124         }
1125
1126         pxp_chan = list_entry(head.next, struct pxp_channel, list);
1127
1128         spin_lock_irqsave(&pxp_chan->lock, flags1);
1129         if (!list_empty(&pxp_chan->active_list)) {
1130                 struct pxp_tx_desc *desc;
1131                 /* REVISIT */
1132                 desc = pxpdma_first_active(pxp_chan);
1133                 __pxpdma_dostart(pxp_chan);
1134         }
1135         spin_unlock_irqrestore(&pxp_chan->lock, flags1);
1136
1137         /* Configure PxP */
1138         pxp_config(pxp, pxp_chan);
1139
1140         pxp_start(pxp);
1141
1142         spin_unlock_irqrestore(&pxp->lock, flags);
1143 }
1144
1145 static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct list_head *list)
1146 {
1147         struct pxp_tx_desc *desc = NULL;
1148         do {
1149                 desc = pxpdma_first_queued(pxp_chan);
1150                 list_move_tail(&desc->list, list);
1151         } while (!list_empty(&pxp_chan->queue));
1152 }
1153
1154 static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
1155 {
1156         struct pxp_tx_desc *desc = to_tx_desc(tx);
1157         struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
1158         dma_cookie_t cookie;
1159         unsigned long flags;
1160
1161         dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
1162
1163         mutex_lock(&pxp_chan->chan_mutex);
1164
1165         cookie = pxp_chan->dma_chan.cookie;
1166
1167         if (++cookie < 0)
1168                 cookie = 1;
1169
1170         /* from dmaengine.h: "last cookie value returned to client" */
1171         pxp_chan->dma_chan.cookie = cookie;
1172         tx->cookie = cookie;
1173
1174         /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
1175         spin_lock_irqsave(&pxp_chan->lock, flags);
1176
1177         /* Here we add the tx descriptor to our PxP task queue. */
1178         list_add_tail(&desc->list, &pxp_chan->queue);
1179
1180         spin_unlock_irqrestore(&pxp_chan->lock, flags);
1181
1182         dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
1183
1184         mutex_unlock(&pxp_chan->chan_mutex);
1185         return cookie;
1186 }
1187
1188 /**
1189  * pxp_init_channel() - initialize a PXP channel.
1190  * @pxp_dma:   PXP DMA context.
1191  * @pchan:  pointer to the channel object.
1192  * @return      0 on success or negative error code on failure.
1193  */
1194 static int pxp_init_channel(struct pxp_dma *pxp_dma,
1195                             struct pxp_channel *pxp_chan)
1196 {
1197         int ret = 0;
1198
1199         /*
1200          * We are using _virtual_ channel here.
1201          * Each channel contains all parameters of corresponding layers
1202          * for one transaction; each layer is represented as one descriptor
1203          * (i.e., pxp_tx_desc) here.
1204          */
1205
1206         INIT_LIST_HEAD(&pxp_chan->active_list);
1207         INIT_LIST_HEAD(&pxp_chan->queue);
1208
1209         return ret;
1210 }
1211
1212 static irqreturn_t pxp_irq(int irq, void *dev_id)
1213 {
1214         struct pxps *pxp = dev_id;
1215         struct pxp_channel *pxp_chan;
1216         struct pxp_tx_desc *desc;
1217         struct pxp_tx_desc *child, *_child;
1218         dma_async_tx_callback callback;
1219         void *callback_param;
1220         unsigned long flags;
1221         u32 hist_status;
1222
1223         dump_pxp_reg(pxp);
1224
1225         hist_status =
1226             __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
1227
1228         __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
1229
1230         spin_lock_irqsave(&pxp->lock, flags);
1231
1232         if (list_empty(&head)) {
1233                 pxp->pxp_ongoing = 0;
1234                 spin_unlock_irqrestore(&pxp->lock, flags);
1235                 return IRQ_NONE;
1236         }
1237
1238         pxp_chan = list_entry(head.next, struct pxp_channel, list);
1239
1240         if (list_empty(&pxp_chan->active_list)) {
1241                 pr_debug("PXP_IRQ pxp_chan->active_list empty. chan_id %d\n",
1242                          pxp_chan->dma_chan.chan_id);
1243                 pxp->pxp_ongoing = 0;
1244                 spin_unlock_irqrestore(&pxp->lock, flags);
1245                 return IRQ_NONE;
1246         }
1247
1248         /* Get descriptor and call callback */
1249         desc = pxpdma_first_active(pxp_chan);
1250
1251         pxp_chan->completed = desc->txd.cookie;
1252
1253         callback = desc->txd.callback;
1254         callback_param = desc->txd.callback_param;
1255
1256         /* Send histogram status back to caller */
1257         desc->hist_status = hist_status;
1258
1259         if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
1260                 callback(callback_param);
1261
1262         pxp_chan->status = PXP_CHANNEL_INITIALIZED;
1263
1264         list_for_each_entry_safe(child, _child, &desc->tx_list, list) {
1265                 list_del_init(&child->list);
1266                 kmem_cache_free(tx_desc_cache, (void *)child);
1267         }
1268         list_del_init(&desc->list);
1269         kmem_cache_free(tx_desc_cache, (void *)desc);
1270
1271         if (list_empty(&pxp_chan->active_list))
1272                 list_del_init(&pxp_chan->list);
1273
1274         complete(&pxp->complete);
1275         pxp->pxp_ongoing = 0;
1276         mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
1277
1278         spin_unlock_irqrestore(&pxp->lock, flags);
1279
1280         return IRQ_HANDLED;
1281 }
1282
1283 /* allocate/free dma tx descriptor dynamically*/
1284 static struct pxp_tx_desc *pxpdma_desc_alloc(struct pxp_channel *pxp_chan)
1285 {
1286         struct pxp_tx_desc *desc = NULL;
1287         struct dma_async_tx_descriptor *txd = NULL;
1288
1289         desc = kmem_cache_alloc(tx_desc_cache, GFP_KERNEL | __GFP_ZERO);
1290         if (desc == NULL)
1291                 return NULL;
1292
1293         INIT_LIST_HEAD(&desc->list);
1294         INIT_LIST_HEAD(&desc->tx_list);
1295         txd = &desc->txd;
1296         dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
1297         txd->tx_submit = pxp_tx_submit;
1298
1299         return desc;
1300 }
1301
1302 /* Allocate and initialise a transfer descriptor. */
1303 static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
1304                                                          struct scatterlist
1305                                                          *sgl,
1306                                                          unsigned int sg_len,
1307                                                          enum
1308                                                          dma_transfer_direction
1309                                                          direction,
1310                                                          unsigned long tx_flags,
1311                                                          void *context)
1312 {
1313         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1314         struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
1315         struct pxps *pxp = to_pxp(pxp_dma);
1316         struct pxp_tx_desc *desc = NULL;
1317         struct pxp_tx_desc *first = NULL, *prev = NULL;
1318         struct scatterlist *sg;
1319         unsigned long flags;
1320         dma_addr_t phys_addr;
1321         int i;
1322
1323         if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
1324                 dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
1325                         direction);
1326                 return NULL;
1327         }
1328
1329         if (unlikely(sg_len < 2))
1330                 return NULL;
1331
1332         spin_lock_irqsave(&pxp_chan->lock, flags);
1333         for_each_sg(sgl, sg, sg_len, i) {
1334                 desc = pxpdma_desc_alloc(pxp_chan);
1335                 if (!desc) {
1336                         spin_unlock_irqrestore(&pxp_chan->lock, flags);
1337                         dev_err(chan->device->dev, "no enough memory to allocate tx descriptor\n");
1338                         return NULL;
1339                 }
1340
1341                 phys_addr = sg_dma_address(sg);
1342
1343                 if (!first) {
1344                         first = desc;
1345
1346                         desc->layer_param.s0_param.paddr = phys_addr;
1347                 } else {
1348                         list_add_tail(&desc->list, &first->tx_list);
1349                         prev->next = desc;
1350                         desc->next = NULL;
1351
1352                         if (i == 1)
1353                                 desc->layer_param.out_param.paddr = phys_addr;
1354                         else
1355                                 desc->layer_param.ol_param.paddr = phys_addr;
1356                 }
1357
1358                 prev = desc;
1359         }
1360         spin_unlock_irqrestore(&pxp_chan->lock, flags);
1361
1362         pxp->pxp_conf_state.layer_nr = sg_len;
1363         first->txd.flags = tx_flags;
1364         first->len = sg_len;
1365         pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
1366                  __func__, __LINE__, first, first->len, first->txd.flags);
1367
1368         return &first->txd;
1369 }
1370
1371 static void pxp_issue_pending(struct dma_chan *chan)
1372 {
1373         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1374         struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
1375         struct pxps *pxp = to_pxp(pxp_dma);
1376         unsigned long flags0, flags;
1377         struct list_head *iter;
1378
1379         spin_lock_irqsave(&pxp->lock, flags0);
1380         spin_lock_irqsave(&pxp_chan->lock, flags);
1381
1382         if (!list_empty(&pxp_chan->queue)) {
1383                 pxpdma_dequeue(pxp_chan, &pxp_chan->active_list);
1384                 pxp_chan->status = PXP_CHANNEL_READY;
1385                 iter = head.next;
1386                 /* Avoid adding a pxp channel to head list which
1387                  * has been already listed in it. And this may
1388                  * cause the head list to be broken down.
1389                  */
1390                 if (list_empty(&head)) {
1391                         list_add_tail(&pxp_chan->list, &head);
1392                 } else {
1393                         while (iter != &head) {
1394                                 if (&pxp_chan->list == iter)
1395                                         break;
1396                                 iter = iter->next;
1397                         }
1398                         if (iter == &head)
1399                                 list_add_tail(&pxp_chan->list, &head);
1400                 }
1401         } else {
1402                 spin_unlock_irqrestore(&pxp_chan->lock, flags);
1403                 spin_unlock_irqrestore(&pxp->lock, flags0);
1404                 return;
1405         }
1406         spin_unlock_irqrestore(&pxp_chan->lock, flags);
1407         spin_unlock_irqrestore(&pxp->lock, flags0);
1408
1409         pxp_clk_enable(pxp);
1410         wake_up_interruptible(&pxp->thread_waitq);
1411 }
1412
1413 static void __pxp_terminate_all(struct dma_chan *chan)
1414 {
1415         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1416
1417         pxp_chan->status = PXP_CHANNEL_INITIALIZED;
1418 }
1419
1420 static int pxp_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1421                         unsigned long arg)
1422 {
1423         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1424
1425         /* Only supports DMA_TERMINATE_ALL */
1426         if (cmd != DMA_TERMINATE_ALL)
1427                 return -ENXIO;
1428
1429         mutex_lock(&pxp_chan->chan_mutex);
1430         __pxp_terminate_all(chan);
1431         mutex_unlock(&pxp_chan->chan_mutex);
1432
1433         return 0;
1434 }
1435
1436 static int pxp_alloc_chan_resources(struct dma_chan *chan)
1437 {
1438         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1439         struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
1440         int ret;
1441
1442         /* dmaengine.c now guarantees to only offer free channels */
1443         BUG_ON(chan->client_count > 1);
1444         WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
1445
1446         chan->cookie = 1;
1447         pxp_chan->completed = -ENXIO;
1448
1449         pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
1450         ret = pxp_init_channel(pxp_dma, pxp_chan);
1451         if (ret < 0)
1452                 goto err_chan;
1453
1454         pxp_chan->status = PXP_CHANNEL_INITIALIZED;
1455
1456         dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
1457                 chan->chan_id, pxp_chan->eof_irq);
1458
1459         return ret;
1460
1461 err_chan:
1462         return ret;
1463 }
1464
1465 static void pxp_free_chan_resources(struct dma_chan *chan)
1466 {
1467         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1468
1469         mutex_lock(&pxp_chan->chan_mutex);
1470
1471         __pxp_terminate_all(chan);
1472
1473         pxp_chan->status = PXP_CHANNEL_FREE;
1474
1475         mutex_unlock(&pxp_chan->chan_mutex);
1476 }
1477
1478 static enum dma_status pxp_tx_status(struct dma_chan *chan,
1479                                      dma_cookie_t cookie,
1480                                      struct dma_tx_state *txstate)
1481 {
1482         struct pxp_channel *pxp_chan = to_pxp_channel(chan);
1483
1484         if (cookie != chan->cookie)
1485                 return DMA_ERROR;
1486
1487         if (txstate) {
1488                 txstate->last = pxp_chan->completed;
1489                 txstate->used = chan->cookie;
1490                 txstate->residue = 0;
1491         }
1492         return DMA_SUCCESS;
1493 }
1494
1495 static int pxp_hw_init(struct pxps *pxp)
1496 {
1497         struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
1498         struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
1499         u32 reg_val;
1500
1501         /* Pull PxP out of reset */
1502         __raw_writel(0, pxp->base + HW_PXP_CTRL);
1503
1504         /* Config defaults */
1505
1506         /* Initialize non-channel-specific PxP parameters */
1507         proc_data->drect.left = proc_data->srect.left = 0;
1508         proc_data->drect.top = proc_data->srect.top = 0;
1509         proc_data->drect.width = proc_data->srect.width = 0;
1510         proc_data->drect.height = proc_data->srect.height = 0;
1511         proc_data->scaling = 0;
1512         proc_data->hflip = 0;
1513         proc_data->vflip = 0;
1514         proc_data->rotate = 0;
1515         proc_data->bgcolor = 0;
1516
1517         /* Initialize S0 channel parameters */
1518         pxp_conf->s0_param.pixel_fmt = pxp_s0_formats[0];
1519         pxp_conf->s0_param.width = 0;
1520         pxp_conf->s0_param.height = 0;
1521         pxp_conf->s0_param.color_key = -1;
1522         pxp_conf->s0_param.color_key_enable = false;
1523
1524         /* Initialize OL channel parameters */
1525         pxp_conf->ol_param[0].combine_enable = false;
1526         pxp_conf->ol_param[0].width = 0;
1527         pxp_conf->ol_param[0].height = 0;
1528         pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
1529         pxp_conf->ol_param[0].color_key_enable = false;
1530         pxp_conf->ol_param[0].color_key = -1;
1531         pxp_conf->ol_param[0].global_alpha_enable = false;
1532         pxp_conf->ol_param[0].global_alpha = 0;
1533         pxp_conf->ol_param[0].local_alpha_enable = false;
1534
1535         /* Initialize Output channel parameters */
1536         pxp_conf->out_param.width = 0;
1537         pxp_conf->out_param.height = 0;
1538         pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
1539
1540         proc_data->overlay_state = 0;
1541
1542         /* Write default h/w config */
1543         pxp_set_ctrl(pxp);
1544         pxp_set_s0param(pxp);
1545         pxp_set_s0crop(pxp);
1546         /*
1547          * simply program the ULC to a higher value than the LRC
1548          * to avoid any AS pixels to show up in the output buffer.
1549          */
1550         __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_OUT_AS_ULC);
1551         pxp_set_olparam(0, pxp);
1552         pxp_set_olcolorkey(0, pxp);
1553
1554         pxp_set_s0colorkey(pxp);
1555         pxp_set_csc(pxp);
1556         pxp_set_bg(pxp);
1557         pxp_set_lut(pxp);
1558
1559         /* One-time histogram configuration */
1560         reg_val =
1561             BF_PXP_HIST_CTRL_PANEL_MODE(BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16);
1562         __raw_writel(reg_val, pxp->base + HW_PXP_HIST_CTRL);
1563
1564         reg_val = BF_PXP_HIST2_PARAM_VALUE0(0x00) |
1565             BF_PXP_HIST2_PARAM_VALUE1(0x00F);
1566         __raw_writel(reg_val, pxp->base + HW_PXP_HIST2_PARAM);
1567
1568         reg_val = BF_PXP_HIST4_PARAM_VALUE0(0x00) |
1569             BF_PXP_HIST4_PARAM_VALUE1(0x05) |
1570             BF_PXP_HIST4_PARAM_VALUE2(0x0A) | BF_PXP_HIST4_PARAM_VALUE3(0x0F);
1571         __raw_writel(reg_val, pxp->base + HW_PXP_HIST4_PARAM);
1572
1573         reg_val = BF_PXP_HIST8_PARAM0_VALUE0(0x00) |
1574             BF_PXP_HIST8_PARAM0_VALUE1(0x02) |
1575             BF_PXP_HIST8_PARAM0_VALUE2(0x04) | BF_PXP_HIST8_PARAM0_VALUE3(0x06);
1576         __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM0);
1577         reg_val = BF_PXP_HIST8_PARAM1_VALUE4(0x09) |
1578             BF_PXP_HIST8_PARAM1_VALUE5(0x0B) |
1579             BF_PXP_HIST8_PARAM1_VALUE6(0x0D) | BF_PXP_HIST8_PARAM1_VALUE7(0x0F);
1580         __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM1);
1581
1582         reg_val = BF_PXP_HIST16_PARAM0_VALUE0(0x00) |
1583             BF_PXP_HIST16_PARAM0_VALUE1(0x01) |
1584             BF_PXP_HIST16_PARAM0_VALUE2(0x02) |
1585             BF_PXP_HIST16_PARAM0_VALUE3(0x03);
1586         __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM0);
1587         reg_val = BF_PXP_HIST16_PARAM1_VALUE4(0x04) |
1588             BF_PXP_HIST16_PARAM1_VALUE5(0x05) |
1589             BF_PXP_HIST16_PARAM1_VALUE6(0x06) |
1590             BF_PXP_HIST16_PARAM1_VALUE7(0x07);
1591         __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM1);
1592         reg_val = BF_PXP_HIST16_PARAM2_VALUE8(0x08) |
1593             BF_PXP_HIST16_PARAM2_VALUE9(0x09) |
1594             BF_PXP_HIST16_PARAM2_VALUE10(0x0A) |
1595             BF_PXP_HIST16_PARAM2_VALUE11(0x0B);
1596         __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM2);
1597         reg_val = BF_PXP_HIST16_PARAM3_VALUE12(0x0C) |
1598             BF_PXP_HIST16_PARAM3_VALUE13(0x0D) |
1599             BF_PXP_HIST16_PARAM3_VALUE14(0x0E) |
1600             BF_PXP_HIST16_PARAM3_VALUE15(0x0F);
1601         __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM3);
1602
1603         return 0;
1604 }
1605
1606 static int pxp_dma_init(struct pxps *pxp)
1607 {
1608         struct pxp_dma *pxp_dma = &pxp->pxp_dma;
1609         struct dma_device *dma = &pxp_dma->dma;
1610         int i;
1611
1612         dma_cap_set(DMA_SLAVE, dma->cap_mask);
1613         dma_cap_set(DMA_PRIVATE, dma->cap_mask);
1614
1615         /* Compulsory common fields */
1616         dma->dev = pxp->dev;
1617         dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
1618         dma->device_free_chan_resources = pxp_free_chan_resources;
1619         dma->device_tx_status = pxp_tx_status;
1620         dma->device_issue_pending = pxp_issue_pending;
1621
1622         /* Compulsory for DMA_SLAVE fields */
1623         dma->device_prep_slave_sg = pxp_prep_slave_sg;
1624         dma->device_control = pxp_control;
1625
1626         /* Initialize PxP Channels */
1627         INIT_LIST_HEAD(&dma->channels);
1628         for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
1629                 struct pxp_channel *pxp_chan = pxp->channel + i;
1630                 struct dma_chan *dma_chan = &pxp_chan->dma_chan;
1631
1632                 spin_lock_init(&pxp_chan->lock);
1633                 mutex_init(&pxp_chan->chan_mutex);
1634
1635                 /* Only one EOF IRQ for PxP, shared by all channels */
1636                 pxp_chan->eof_irq = pxp->irq;
1637                 pxp_chan->status = PXP_CHANNEL_FREE;
1638                 pxp_chan->completed = -ENXIO;
1639                 snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
1640                          "PXP EOF %d", i);
1641
1642                 dma_chan->device = &pxp_dma->dma;
1643                 dma_chan->cookie = 1;
1644                 dma_chan->chan_id = i;
1645                 list_add_tail(&dma_chan->device_node, &dma->channels);
1646         }
1647
1648         return dma_async_device_register(&pxp_dma->dma);
1649 }
1650
1651 static ssize_t clk_off_timeout_show(struct device *dev,
1652                                     struct device_attribute *attr, char *buf)
1653 {
1654         return sprintf(buf, "%d\n", timeout_in_ms);
1655 }
1656
1657 static ssize_t clk_off_timeout_store(struct device *dev,
1658                                      struct device_attribute *attr,
1659                                      const char *buf, size_t count)
1660 {
1661         int val;
1662         if (sscanf(buf, "%d", &val) > 0) {
1663                 timeout_in_ms = val;
1664                 return count;
1665         }
1666         return -EINVAL;
1667 }
1668
1669 static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
1670                    clk_off_timeout_store);
1671
1672 static ssize_t block_size_show(struct device *dev,
1673                                struct device_attribute *attr,
1674                                char *buf)
1675 {
1676         return sprintf(buf, "%d\n", block_size);
1677 }
1678
1679 static ssize_t block_size_store(struct device *dev,
1680                                 struct device_attribute *attr,
1681                                 const char *buf, size_t count)
1682 {
1683         char **last = NULL;
1684
1685         block_size = simple_strtoul(buf, last, 0);
1686         if (block_size > 1)
1687                 block_size = 1;
1688
1689         return count;
1690 }
1691 static DEVICE_ATTR(block_size, S_IWUSR | S_IRUGO,
1692                    block_size_show, block_size_store);
1693
1694 static const struct of_device_id imx_pxpdma_dt_ids[] = {
1695         { .compatible = "fsl,imx6dl-pxp-dma", },
1696         { /* sentinel */ }
1697 };
1698 MODULE_DEVICE_TABLE(of, imx_pxpdma_dt_ids);
1699
1700 static int has_pending_task(struct pxps *pxp, struct pxp_channel *task)
1701 {
1702         int found;
1703         unsigned long flags;
1704
1705         spin_lock_irqsave(&pxp->lock, flags);
1706         found = !list_empty(&head);
1707         spin_unlock_irqrestore(&pxp->lock, flags);
1708
1709         return found;
1710 }
1711
1712 static int pxp_dispatch_thread(void *argv)
1713 {
1714         struct pxps *pxp = (struct pxps *)argv;
1715         struct pxp_channel *pending = NULL;
1716         unsigned long flags;
1717
1718         while (!kthread_should_stop()) {
1719                 int ret;
1720                 ret = wait_event_interruptible(pxp->thread_waitq,
1721                                         has_pending_task(pxp, pending));
1722                 if (signal_pending(current))
1723                         continue;
1724
1725                 spin_lock_irqsave(&pxp->lock, flags);
1726                 pxp->pxp_ongoing = 1;
1727                 spin_unlock_irqrestore(&pxp->lock, flags);
1728                 init_completion(&pxp->complete);
1729                 pxpdma_dostart_work(pxp);
1730                 ret = wait_for_completion_timeout(&pxp->complete, 2 * HZ);
1731                 if (ret == 0) {
1732                         printk(KERN_EMERG "%s: task is timeout\n\n", __func__);
1733                         break;
1734                 }
1735         }
1736
1737         return 0;
1738 }
1739
1740 static int pxp_probe(struct platform_device *pdev)
1741 {
1742         struct pxps *pxp;
1743         struct resource *res;
1744         int irq;
1745         int err = 0;
1746
1747         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1748         irq = platform_get_irq(pdev, 0);
1749         if (!res || irq < 0) {
1750                 err = -ENODEV;
1751                 goto exit;
1752         }
1753
1754         pxp = devm_kzalloc(&pdev->dev, sizeof(*pxp), GFP_KERNEL);
1755         if (!pxp) {
1756                 dev_err(&pdev->dev, "failed to allocate control object\n");
1757                 err = -ENOMEM;
1758                 goto exit;
1759         }
1760
1761         pxp->dev = &pdev->dev;
1762
1763         platform_set_drvdata(pdev, pxp);
1764         pxp->irq = irq;
1765
1766         pxp->pxp_ongoing = 0;
1767         pxp->lut_state = 0;
1768
1769         spin_lock_init(&pxp->lock);
1770         mutex_init(&pxp->clk_mutex);
1771
1772         pxp->base = devm_request_and_ioremap(&pdev->dev, res);
1773         if (pxp->base == NULL) {
1774                 dev_err(&pdev->dev, "Couldn't ioremap regs\n");
1775                 err = -ENODEV;
1776                 goto exit;
1777         }
1778
1779         pxp->pdev = pdev;
1780
1781         pxp->clk = devm_clk_get(&pdev->dev, "pxp-axi");
1782         clk_prepare_enable(pxp->clk);
1783
1784         err = pxp_hw_init(pxp);
1785         clk_disable_unprepare(pxp->clk);
1786         if (err) {
1787                 dev_err(&pdev->dev, "failed to initialize hardware\n");
1788                 goto exit;
1789         }
1790
1791         err = devm_request_irq(&pdev->dev, pxp->irq, pxp_irq, 0,
1792                                 "pxp-dmaengine", pxp);
1793         if (err)
1794                 goto exit;
1795         /* Initialize DMA engine */
1796         err = pxp_dma_init(pxp);
1797         if (err < 0)
1798                 goto exit;
1799
1800         if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
1801                 dev_err(&pdev->dev,
1802                         "Unable to create file from clk_off_timeout\n");
1803                 goto exit;
1804         }
1805
1806         device_create_file(&pdev->dev, &dev_attr_block_size);
1807         dump_pxp_reg(pxp);
1808
1809         INIT_WORK(&pxp->work, clkoff_callback);
1810         init_timer(&pxp->clk_timer);
1811         pxp->clk_timer.function = pxp_clkoff_timer;
1812         pxp->clk_timer.data = (unsigned long)pxp;
1813
1814         /* allocate a kernel thread to dispatch pxp conf */
1815         pxp->dispatch = kthread_run(pxp_dispatch_thread, pxp, "pxp_dispatch");
1816         if (IS_ERR(pxp->dispatch)) {
1817                 err = PTR_ERR(pxp->dispatch);
1818                 goto exit;
1819         }
1820         init_waitqueue_head(&pxp->thread_waitq);
1821         tx_desc_cache = kmem_cache_create("tx_desc", sizeof(struct pxp_tx_desc),
1822                                           0, SLAB_HWCACHE_ALIGN, NULL);
1823         if (!tx_desc_cache) {
1824                 err = -ENOMEM;
1825                 goto exit;
1826         }
1827
1828         register_pxp_device();
1829
1830 exit:
1831         if (err)
1832                 dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe()\n");
1833         return err;
1834 }
1835
1836 static int pxp_remove(struct platform_device *pdev)
1837 {
1838         struct pxps *pxp = platform_get_drvdata(pdev);
1839
1840         unregister_pxp_device();
1841         kmem_cache_destroy(tx_desc_cache);
1842         kthread_stop(pxp->dispatch);
1843         cancel_work_sync(&pxp->work);
1844         del_timer_sync(&pxp->clk_timer);
1845         clk_disable_unprepare(pxp->clk);
1846         device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
1847         device_remove_file(&pdev->dev, &dev_attr_block_size);
1848         dma_async_device_unregister(&(pxp->pxp_dma.dma));
1849
1850         return 0;
1851 }
1852
1853 #ifdef CONFIG_PM
1854 static int pxp_suspend(struct platform_device *pdev, pm_message_t state)
1855 {
1856         struct pxps *pxp = platform_get_drvdata(pdev);
1857
1858         pxp_clk_enable(pxp);
1859         while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
1860                 ;
1861
1862         __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
1863         pxp_clk_disable(pxp);
1864
1865         return 0;
1866 }
1867
1868 static int pxp_resume(struct platform_device *pdev)
1869 {
1870         struct pxps *pxp = platform_get_drvdata(pdev);
1871
1872         pxp_clk_enable(pxp);
1873         /* Pull PxP out of reset */
1874         __raw_writel(0, pxp->base + HW_PXP_CTRL);
1875         pxp_clk_disable(pxp);
1876
1877         return 0;
1878 }
1879 #else
1880 #define pxp_suspend     NULL
1881 #define pxp_resume      NULL
1882 #endif
1883
1884 static struct platform_driver pxp_driver = {
1885         .driver = {
1886                         .name = "imx-pxp",
1887                         .of_match_table = of_match_ptr(imx_pxpdma_dt_ids),
1888                    },
1889         .probe = pxp_probe,
1890         .remove = pxp_remove,
1891         .suspend = pxp_suspend,
1892         .resume = pxp_resume,
1893 };
1894
1895 module_platform_driver(pxp_driver);
1896
1897
1898 MODULE_DESCRIPTION("i.MX PxP driver");
1899 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1900 MODULE_LICENSE("GPL");