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