brcmsmac: rework of mac80211 .flush() callback operation
[pandora-kernel.git] / drivers / gpu / drm / exynos / exynos_drm_fimc.c
1 /*
2  * Copyright (C) 2012 Samsung Electronics Co.Ltd
3  * Authors:
4  *      Eunchul Kim <chulspro.kim@samsung.com>
5  *      Jinyoung Jeon <jy0.jeon@samsung.com>
6  *      Sangmin Lee <lsmin.lee@samsung.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  *
13  */
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/clk.h>
18 #include <linux/pm_runtime.h>
19 #include <plat/map-base.h>
20
21 #include <drm/drmP.h>
22 #include <drm/exynos_drm.h>
23 #include "regs-fimc.h"
24 #include "exynos_drm_ipp.h"
25 #include "exynos_drm_fimc.h"
26
27 /*
28  * FIMC is stand for Fully Interactive Mobile Camera and
29  * supports image scaler/rotator and input/output DMA operations.
30  * input DMA reads image data from the memory.
31  * output DMA writes image data to memory.
32  * FIMC supports image rotation and image effect functions.
33  *
34  * M2M operation : supports crop/scale/rotation/csc so on.
35  * Memory ----> FIMC H/W ----> Memory.
36  * Writeback operation : supports cloned screen with FIMD.
37  * FIMD ----> FIMC H/W ----> Memory.
38  * Output operation : supports direct display using local path.
39  * Memory ----> FIMC H/W ----> FIMD.
40  */
41
42 /*
43  * TODO
44  * 1. check suspend/resume api if needed.
45  * 2. need to check use case platform_device_id.
46  * 3. check src/dst size with, height.
47  * 4. added check_prepare api for right register.
48  * 5. need to add supported list in prop_list.
49  * 6. check prescaler/scaler optimization.
50  */
51
52 #define FIMC_MAX_DEVS   4
53 #define FIMC_MAX_SRC    2
54 #define FIMC_MAX_DST    32
55 #define FIMC_SHFACTOR   10
56 #define FIMC_BUF_STOP   1
57 #define FIMC_BUF_START  2
58 #define FIMC_REG_SZ             32
59 #define FIMC_WIDTH_ITU_709      1280
60 #define FIMC_REFRESH_MAX        60
61 #define FIMC_REFRESH_MIN        12
62 #define FIMC_CROP_MAX   8192
63 #define FIMC_CROP_MIN   32
64 #define FIMC_SCALE_MAX  4224
65 #define FIMC_SCALE_MIN  32
66
67 #define get_fimc_context(dev)   platform_get_drvdata(to_platform_device(dev))
68 #define get_ctx_from_ippdrv(ippdrv)     container_of(ippdrv,\
69                                         struct fimc_context, ippdrv);
70 #define fimc_read(offset)               readl(ctx->regs + (offset))
71 #define fimc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
72
73 enum fimc_wb {
74         FIMC_WB_NONE,
75         FIMC_WB_A,
76         FIMC_WB_B,
77 };
78
79 /*
80  * A structure of scaler.
81  *
82  * @range: narrow, wide.
83  * @bypass: unused scaler path.
84  * @up_h: horizontal scale up.
85  * @up_v: vertical scale up.
86  * @hratio: horizontal ratio.
87  * @vratio: vertical ratio.
88  */
89 struct fimc_scaler {
90         bool    range;
91         bool bypass;
92         bool up_h;
93         bool up_v;
94         u32 hratio;
95         u32 vratio;
96 };
97
98 /*
99  * A structure of scaler capability.
100  *
101  * find user manual table 43-1.
102  * @in_hori: scaler input horizontal size.
103  * @bypass: scaler bypass mode.
104  * @dst_h_wo_rot: target horizontal size without output rotation.
105  * @dst_h_rot: target horizontal size with output rotation.
106  * @rl_w_wo_rot: real width without input rotation.
107  * @rl_h_rot: real height without output rotation.
108  */
109 struct fimc_capability {
110         /* scaler */
111         u32     in_hori;
112         u32     bypass;
113         /* output rotator */
114         u32     dst_h_wo_rot;
115         u32     dst_h_rot;
116         /* input rotator */
117         u32     rl_w_wo_rot;
118         u32     rl_h_rot;
119 };
120
121 /*
122  * A structure of fimc driver data.
123  *
124  * @parent_clk: name of parent clock.
125  */
126 struct fimc_driverdata {
127         char    *parent_clk;
128 };
129
130 /*
131  * A structure of fimc context.
132  *
133  * @ippdrv: prepare initialization using ippdrv.
134  * @regs_res: register resources.
135  * @regs: memory mapped io registers.
136  * @lock: locking of operations.
137  * @sclk_fimc_clk: fimc source clock.
138  * @fimc_clk: fimc clock.
139  * @wb_clk: writeback a clock.
140  * @wb_b_clk: writeback b clock.
141  * @sc: scaler infomations.
142  * @odr: ordering of YUV.
143  * @ver: fimc version.
144  * @pol: porarity of writeback.
145  * @id: fimc id.
146  * @irq: irq number.
147  * @suspended: qos operations.
148  */
149 struct fimc_context {
150         struct exynos_drm_ippdrv        ippdrv;
151         struct resource *regs_res;
152         void __iomem    *regs;
153         struct mutex    lock;
154         struct clk      *sclk_fimc_clk;
155         struct clk      *fimc_clk;
156         struct clk      *wb_clk;
157         struct clk      *wb_b_clk;
158         struct fimc_scaler      sc;
159         struct fimc_driverdata  *ddata;
160         struct exynos_drm_ipp_pol       pol;
161         int     id;
162         int     irq;
163         bool    suspended;
164 };
165
166 static void fimc_sw_reset(struct fimc_context *ctx, bool pattern)
167 {
168         u32 cfg;
169
170         DRM_DEBUG_KMS("%s:pattern[%d]\n", __func__, pattern);
171
172         cfg = fimc_read(EXYNOS_CISRCFMT);
173         cfg |= EXYNOS_CISRCFMT_ITU601_8BIT;
174         if (pattern)
175                 cfg |= EXYNOS_CIGCTRL_TESTPATTERN_COLOR_BAR;
176
177         fimc_write(cfg, EXYNOS_CISRCFMT);
178
179         /* s/w reset */
180         cfg = fimc_read(EXYNOS_CIGCTRL);
181         cfg |= (EXYNOS_CIGCTRL_SWRST);
182         fimc_write(cfg, EXYNOS_CIGCTRL);
183
184         /* s/w reset complete */
185         cfg = fimc_read(EXYNOS_CIGCTRL);
186         cfg &= ~EXYNOS_CIGCTRL_SWRST;
187         fimc_write(cfg, EXYNOS_CIGCTRL);
188
189         /* reset sequence */
190         fimc_write(0x0, EXYNOS_CIFCNTSEQ);
191 }
192
193 static void fimc_set_camblk_fimd0_wb(struct fimc_context *ctx)
194 {
195         u32 camblk_cfg;
196
197         DRM_DEBUG_KMS("%s\n", __func__);
198
199         camblk_cfg = readl(SYSREG_CAMERA_BLK);
200         camblk_cfg &= ~(SYSREG_FIMD0WB_DEST_MASK);
201         camblk_cfg |= ctx->id << (SYSREG_FIMD0WB_DEST_SHIFT);
202
203         writel(camblk_cfg, SYSREG_CAMERA_BLK);
204 }
205
206 static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb)
207 {
208         u32 cfg;
209
210         DRM_DEBUG_KMS("%s:wb[%d]\n", __func__, wb);
211
212         cfg = fimc_read(EXYNOS_CIGCTRL);
213         cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
214                 EXYNOS_CIGCTRL_SELCAM_ITU_MASK |
215                 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK |
216                 EXYNOS_CIGCTRL_SELCAM_FIMC_MASK |
217                 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK |
218                 EXYNOS_CIGCTRL_SELWRITEBACK_MASK);
219
220         switch (wb) {
221         case FIMC_WB_A:
222                 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_A |
223                         EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK);
224                 break;
225         case FIMC_WB_B:
226                 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_B |
227                         EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK);
228                 break;
229         case FIMC_WB_NONE:
230         default:
231                 cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A |
232                         EXYNOS_CIGCTRL_SELWRITEBACK_A |
233                         EXYNOS_CIGCTRL_SELCAM_MIPI_A |
234                         EXYNOS_CIGCTRL_SELCAM_FIMC_ITU);
235                 break;
236         }
237
238         fimc_write(cfg, EXYNOS_CIGCTRL);
239 }
240
241 static void fimc_set_polarity(struct fimc_context *ctx,
242                 struct exynos_drm_ipp_pol *pol)
243 {
244         u32 cfg;
245
246         DRM_DEBUG_KMS("%s:inv_pclk[%d]inv_vsync[%d]\n",
247                 __func__, pol->inv_pclk, pol->inv_vsync);
248         DRM_DEBUG_KMS("%s:inv_href[%d]inv_hsync[%d]\n",
249                 __func__, pol->inv_href, pol->inv_hsync);
250
251         cfg = fimc_read(EXYNOS_CIGCTRL);
252         cfg &= ~(EXYNOS_CIGCTRL_INVPOLPCLK | EXYNOS_CIGCTRL_INVPOLVSYNC |
253                  EXYNOS_CIGCTRL_INVPOLHREF | EXYNOS_CIGCTRL_INVPOLHSYNC);
254
255         if (pol->inv_pclk)
256                 cfg |= EXYNOS_CIGCTRL_INVPOLPCLK;
257         if (pol->inv_vsync)
258                 cfg |= EXYNOS_CIGCTRL_INVPOLVSYNC;
259         if (pol->inv_href)
260                 cfg |= EXYNOS_CIGCTRL_INVPOLHREF;
261         if (pol->inv_hsync)
262                 cfg |= EXYNOS_CIGCTRL_INVPOLHSYNC;
263
264         fimc_write(cfg, EXYNOS_CIGCTRL);
265 }
266
267 static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
268 {
269         u32 cfg;
270
271         DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
272
273         cfg = fimc_read(EXYNOS_CIGCTRL);
274         if (enable)
275                 cfg |= EXYNOS_CIGCTRL_CAM_JPEG;
276         else
277                 cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG;
278
279         fimc_write(cfg, EXYNOS_CIGCTRL);
280 }
281
282 static void fimc_handle_irq(struct fimc_context *ctx, bool enable,
283                 bool overflow, bool level)
284 {
285         u32 cfg;
286
287         DRM_DEBUG_KMS("%s:enable[%d]overflow[%d]level[%d]\n", __func__,
288                         enable, overflow, level);
289
290         cfg = fimc_read(EXYNOS_CIGCTRL);
291         if (enable) {
292                 cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_LEVEL);
293                 cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE;
294                 if (overflow)
295                         cfg |= EXYNOS_CIGCTRL_IRQ_OVFEN;
296                 if (level)
297                         cfg |= EXYNOS_CIGCTRL_IRQ_LEVEL;
298         } else
299                 cfg &= ~(EXYNOS_CIGCTRL_IRQ_OVFEN | EXYNOS_CIGCTRL_IRQ_ENABLE);
300
301         fimc_write(cfg, EXYNOS_CIGCTRL);
302 }
303
304 static void fimc_clear_irq(struct fimc_context *ctx)
305 {
306         u32 cfg;
307
308         DRM_DEBUG_KMS("%s\n", __func__);
309
310         cfg = fimc_read(EXYNOS_CIGCTRL);
311         cfg |= EXYNOS_CIGCTRL_IRQ_CLR;
312         fimc_write(cfg, EXYNOS_CIGCTRL);
313 }
314
315 static bool fimc_check_ovf(struct fimc_context *ctx)
316 {
317         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
318         u32 cfg, status, flag;
319
320         status = fimc_read(EXYNOS_CISTATUS);
321         flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
322                 EXYNOS_CISTATUS_OVFICR;
323
324         DRM_DEBUG_KMS("%s:flag[0x%x]\n", __func__, flag);
325
326         if (status & flag) {
327                 cfg = fimc_read(EXYNOS_CIWDOFST);
328                 cfg |= (EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
329                         EXYNOS_CIWDOFST_CLROVFICR);
330
331                 fimc_write(cfg, EXYNOS_CIWDOFST);
332
333                 cfg = fimc_read(EXYNOS_CIWDOFST);
334                 cfg &= ~(EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
335                         EXYNOS_CIWDOFST_CLROVFICR);
336
337                 fimc_write(cfg, EXYNOS_CIWDOFST);
338
339                 dev_err(ippdrv->dev, "occured overflow at %d, status 0x%x.\n",
340                         ctx->id, status);
341                 return true;
342         }
343
344         return false;
345 }
346
347 static bool fimc_check_frame_end(struct fimc_context *ctx)
348 {
349         u32 cfg;
350
351         cfg = fimc_read(EXYNOS_CISTATUS);
352
353         DRM_DEBUG_KMS("%s:cfg[0x%x]\n", __func__, cfg);
354
355         if (!(cfg & EXYNOS_CISTATUS_FRAMEEND))
356                 return false;
357
358         cfg &= ~(EXYNOS_CISTATUS_FRAMEEND);
359         fimc_write(cfg, EXYNOS_CISTATUS);
360
361         return true;
362 }
363
364 static int fimc_get_buf_id(struct fimc_context *ctx)
365 {
366         u32 cfg;
367         int frame_cnt, buf_id;
368
369         DRM_DEBUG_KMS("%s\n", __func__);
370
371         cfg = fimc_read(EXYNOS_CISTATUS2);
372         frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
373
374         if (frame_cnt == 0)
375                 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg);
376
377         DRM_DEBUG_KMS("%s:present[%d]before[%d]\n", __func__,
378                 EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg),
379                 EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg));
380
381         if (frame_cnt == 0) {
382                 DRM_ERROR("failed to get frame count.\n");
383                 return -EIO;
384         }
385
386         buf_id = frame_cnt - 1;
387         DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
388
389         return buf_id;
390 }
391
392 static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
393 {
394         u32 cfg;
395
396         DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
397
398         cfg = fimc_read(EXYNOS_CIOCTRL);
399         if (enable)
400                 cfg |= EXYNOS_CIOCTRL_LASTENDEN;
401         else
402                 cfg &= ~EXYNOS_CIOCTRL_LASTENDEN;
403
404         fimc_write(cfg, EXYNOS_CIOCTRL);
405 }
406
407
408 static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
409 {
410         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
411         u32 cfg;
412
413         DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
414
415         /* RGB */
416         cfg = fimc_read(EXYNOS_CISCCTRL);
417         cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK;
418
419         switch (fmt) {
420         case DRM_FORMAT_RGB565:
421                 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565;
422                 fimc_write(cfg, EXYNOS_CISCCTRL);
423                 return 0;
424         case DRM_FORMAT_RGB888:
425         case DRM_FORMAT_XRGB8888:
426                 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
427                 fimc_write(cfg, EXYNOS_CISCCTRL);
428                 return 0;
429         default:
430                 /* bypass */
431                 break;
432         }
433
434         /* YUV */
435         cfg = fimc_read(EXYNOS_MSCTRL);
436         cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK |
437                 EXYNOS_MSCTRL_C_INT_IN_2PLANE |
438                 EXYNOS_MSCTRL_ORDER422_YCBYCR);
439
440         switch (fmt) {
441         case DRM_FORMAT_YUYV:
442                 cfg |= EXYNOS_MSCTRL_ORDER422_YCBYCR;
443                 break;
444         case DRM_FORMAT_YVYU:
445                 cfg |= EXYNOS_MSCTRL_ORDER422_YCRYCB;
446                 break;
447         case DRM_FORMAT_UYVY:
448                 cfg |= EXYNOS_MSCTRL_ORDER422_CBYCRY;
449                 break;
450         case DRM_FORMAT_VYUY:
451         case DRM_FORMAT_YUV444:
452                 cfg |= EXYNOS_MSCTRL_ORDER422_CRYCBY;
453                 break;
454         case DRM_FORMAT_NV21:
455         case DRM_FORMAT_NV61:
456                 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB |
457                         EXYNOS_MSCTRL_C_INT_IN_2PLANE);
458                 break;
459         case DRM_FORMAT_YUV422:
460         case DRM_FORMAT_YUV420:
461         case DRM_FORMAT_YVU420:
462                 cfg |= EXYNOS_MSCTRL_C_INT_IN_3PLANE;
463                 break;
464         case DRM_FORMAT_NV12:
465         case DRM_FORMAT_NV12MT:
466         case DRM_FORMAT_NV16:
467                 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR |
468                         EXYNOS_MSCTRL_C_INT_IN_2PLANE);
469                 break;
470         default:
471                 dev_err(ippdrv->dev, "inavlid source yuv order 0x%x.\n", fmt);
472                 return -EINVAL;
473         }
474
475         fimc_write(cfg, EXYNOS_MSCTRL);
476
477         return 0;
478 }
479
480 static int fimc_src_set_fmt(struct device *dev, u32 fmt)
481 {
482         struct fimc_context *ctx = get_fimc_context(dev);
483         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
484         u32 cfg;
485
486         DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
487
488         cfg = fimc_read(EXYNOS_MSCTRL);
489         cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
490
491         switch (fmt) {
492         case DRM_FORMAT_RGB565:
493         case DRM_FORMAT_RGB888:
494         case DRM_FORMAT_XRGB8888:
495                 cfg |= EXYNOS_MSCTRL_INFORMAT_RGB;
496                 break;
497         case DRM_FORMAT_YUV444:
498                 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
499                 break;
500         case DRM_FORMAT_YUYV:
501         case DRM_FORMAT_YVYU:
502         case DRM_FORMAT_UYVY:
503         case DRM_FORMAT_VYUY:
504                 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE;
505                 break;
506         case DRM_FORMAT_NV16:
507         case DRM_FORMAT_NV61:
508         case DRM_FORMAT_YUV422:
509                 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422;
510                 break;
511         case DRM_FORMAT_YUV420:
512         case DRM_FORMAT_YVU420:
513         case DRM_FORMAT_NV12:
514         case DRM_FORMAT_NV21:
515         case DRM_FORMAT_NV12MT:
516                 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
517                 break;
518         default:
519                 dev_err(ippdrv->dev, "inavlid source format 0x%x.\n", fmt);
520                 return -EINVAL;
521         }
522
523         fimc_write(cfg, EXYNOS_MSCTRL);
524
525         cfg = fimc_read(EXYNOS_CIDMAPARAM);
526         cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
527
528         if (fmt == DRM_FORMAT_NV12MT)
529                 cfg |= EXYNOS_CIDMAPARAM_R_MODE_64X32;
530         else
531                 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
532
533         fimc_write(cfg, EXYNOS_CIDMAPARAM);
534
535         return fimc_src_set_fmt_order(ctx, fmt);
536 }
537
538 static int fimc_src_set_transf(struct device *dev,
539                 enum drm_exynos_degree degree,
540                 enum drm_exynos_flip flip, bool *swap)
541 {
542         struct fimc_context *ctx = get_fimc_context(dev);
543         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
544         u32 cfg1, cfg2;
545
546         DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
547                 degree, flip);
548
549         cfg1 = fimc_read(EXYNOS_MSCTRL);
550         cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
551                 EXYNOS_MSCTRL_FLIP_Y_MIRROR);
552
553         cfg2 = fimc_read(EXYNOS_CITRGFMT);
554         cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
555
556         switch (degree) {
557         case EXYNOS_DRM_DEGREE_0:
558                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
559                         cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
560                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
561                         cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
562                 break;
563         case EXYNOS_DRM_DEGREE_90:
564                 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
565                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
566                         cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
567                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
568                         cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
569                 break;
570         case EXYNOS_DRM_DEGREE_180:
571                 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
572                         EXYNOS_MSCTRL_FLIP_Y_MIRROR);
573                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
574                         cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
575                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
576                         cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
577                 break;
578         case EXYNOS_DRM_DEGREE_270:
579                 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
580                         EXYNOS_MSCTRL_FLIP_Y_MIRROR);
581                 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
582                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
583                         cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
584                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
585                         cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
586                 break;
587         default:
588                 dev_err(ippdrv->dev, "inavlid degree value %d.\n", degree);
589                 return -EINVAL;
590         }
591
592         fimc_write(cfg1, EXYNOS_MSCTRL);
593         fimc_write(cfg2, EXYNOS_CITRGFMT);
594         *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0;
595
596         return 0;
597 }
598
599 static int fimc_set_window(struct fimc_context *ctx,
600                 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz)
601 {
602         u32 cfg, h1, h2, v1, v2;
603
604         /* cropped image */
605         h1 = pos->x;
606         h2 = sz->hsize - pos->w - pos->x;
607         v1 = pos->y;
608         v2 = sz->vsize - pos->h - pos->y;
609
610         DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
611         __func__, pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize);
612         DRM_DEBUG_KMS("%s:h1[%d]h2[%d]v1[%d]v2[%d]\n", __func__,
613                 h1, h2, v1, v2);
614
615         /*
616          * set window offset 1, 2 size
617          * check figure 43-21 in user manual
618          */
619         cfg = fimc_read(EXYNOS_CIWDOFST);
620         cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK |
621                 EXYNOS_CIWDOFST_WINVEROFST_MASK);
622         cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) |
623                 EXYNOS_CIWDOFST_WINVEROFST(v1));
624         cfg |= EXYNOS_CIWDOFST_WINOFSEN;
625         fimc_write(cfg, EXYNOS_CIWDOFST);
626
627         cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) |
628                 EXYNOS_CIWDOFST2_WINVEROFST2(v2));
629         fimc_write(cfg, EXYNOS_CIWDOFST2);
630
631         return 0;
632 }
633
634 static int fimc_src_set_size(struct device *dev, int swap,
635                 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz)
636 {
637         struct fimc_context *ctx = get_fimc_context(dev);
638         struct drm_exynos_pos img_pos = *pos;
639         struct drm_exynos_sz img_sz = *sz;
640         u32 cfg;
641
642         DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
643                 __func__, swap, sz->hsize, sz->vsize);
644
645         /* original size */
646         cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) |
647                 EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize));
648
649         fimc_write(cfg, EXYNOS_ORGISIZE);
650
651         DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n", __func__,
652                 pos->x, pos->y, pos->w, pos->h);
653
654         if (swap) {
655                 img_pos.w = pos->h;
656                 img_pos.h = pos->w;
657                 img_sz.hsize = sz->vsize;
658                 img_sz.vsize = sz->hsize;
659         }
660
661         /* set input DMA image size */
662         cfg = fimc_read(EXYNOS_CIREAL_ISIZE);
663         cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK |
664                 EXYNOS_CIREAL_ISIZE_WIDTH_MASK);
665         cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) |
666                 EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h));
667         fimc_write(cfg, EXYNOS_CIREAL_ISIZE);
668
669         /*
670          * set input FIFO image size
671          * for now, we support only ITU601 8 bit mode
672          */
673         cfg = (EXYNOS_CISRCFMT_ITU601_8BIT |
674                 EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) |
675                 EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize));
676         fimc_write(cfg, EXYNOS_CISRCFMT);
677
678         /* offset Y(RGB), Cb, Cr */
679         cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) |
680                 EXYNOS_CIIYOFF_VERTICAL(img_pos.y));
681         fimc_write(cfg, EXYNOS_CIIYOFF);
682         cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) |
683                 EXYNOS_CIICBOFF_VERTICAL(img_pos.y));
684         fimc_write(cfg, EXYNOS_CIICBOFF);
685         cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) |
686                 EXYNOS_CIICROFF_VERTICAL(img_pos.y));
687         fimc_write(cfg, EXYNOS_CIICROFF);
688
689         return fimc_set_window(ctx, &img_pos, &img_sz);
690 }
691
692 static int fimc_src_set_addr(struct device *dev,
693                 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id,
694                 enum drm_exynos_ipp_buf_type buf_type)
695 {
696         struct fimc_context *ctx = get_fimc_context(dev);
697         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
698         struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd;
699         struct drm_exynos_ipp_property *property;
700         struct drm_exynos_ipp_config *config;
701
702         if (!c_node) {
703                 DRM_ERROR("failed to get c_node.\n");
704                 return -EINVAL;
705         }
706
707         property = &c_node->property;
708         if (!property) {
709                 DRM_ERROR("failed to get property.\n");
710                 return -EINVAL;
711         }
712
713         DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
714                 property->prop_id, buf_id, buf_type);
715
716         if (buf_id > FIMC_MAX_SRC) {
717                 dev_info(ippdrv->dev, "inavlid buf_id %d.\n", buf_id);
718                 return -ENOMEM;
719         }
720
721         /* address register set */
722         switch (buf_type) {
723         case IPP_BUF_ENQUEUE:
724                 config = &property->config[EXYNOS_DRM_OPS_SRC];
725                 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
726                         EXYNOS_CIIYSA(buf_id));
727
728                 if (config->fmt == DRM_FORMAT_YVU420) {
729                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
730                                 EXYNOS_CIICBSA(buf_id));
731                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
732                                 EXYNOS_CIICRSA(buf_id));
733                 } else {
734                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
735                                 EXYNOS_CIICBSA(buf_id));
736                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
737                                 EXYNOS_CIICRSA(buf_id));
738                 }
739                 break;
740         case IPP_BUF_DEQUEUE:
741                 fimc_write(0x0, EXYNOS_CIIYSA(buf_id));
742                 fimc_write(0x0, EXYNOS_CIICBSA(buf_id));
743                 fimc_write(0x0, EXYNOS_CIICRSA(buf_id));
744                 break;
745         default:
746                 /* bypass */
747                 break;
748         }
749
750         return 0;
751 }
752
753 static struct exynos_drm_ipp_ops fimc_src_ops = {
754         .set_fmt = fimc_src_set_fmt,
755         .set_transf = fimc_src_set_transf,
756         .set_size = fimc_src_set_size,
757         .set_addr = fimc_src_set_addr,
758 };
759
760 static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
761 {
762         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
763         u32 cfg;
764
765         DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
766
767         /* RGB */
768         cfg = fimc_read(EXYNOS_CISCCTRL);
769         cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK;
770
771         switch (fmt) {
772         case DRM_FORMAT_RGB565:
773                 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565;
774                 fimc_write(cfg, EXYNOS_CISCCTRL);
775                 return 0;
776         case DRM_FORMAT_RGB888:
777                 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888;
778                 fimc_write(cfg, EXYNOS_CISCCTRL);
779                 return 0;
780         case DRM_FORMAT_XRGB8888:
781                 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
782                         EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
783                 fimc_write(cfg, EXYNOS_CISCCTRL);
784                 break;
785         default:
786                 /* bypass */
787                 break;
788         }
789
790         /* YUV */
791         cfg = fimc_read(EXYNOS_CIOCTRL);
792         cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK |
793                 EXYNOS_CIOCTRL_ORDER422_MASK |
794                 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK);
795
796         switch (fmt) {
797         case DRM_FORMAT_XRGB8888:
798                 cfg |= EXYNOS_CIOCTRL_ALPHA_OUT;
799                 break;
800         case DRM_FORMAT_YUYV:
801                 cfg |= EXYNOS_CIOCTRL_ORDER422_YCBYCR;
802                 break;
803         case DRM_FORMAT_YVYU:
804                 cfg |= EXYNOS_CIOCTRL_ORDER422_YCRYCB;
805                 break;
806         case DRM_FORMAT_UYVY:
807                 cfg |= EXYNOS_CIOCTRL_ORDER422_CBYCRY;
808                 break;
809         case DRM_FORMAT_VYUY:
810                 cfg |= EXYNOS_CIOCTRL_ORDER422_CRYCBY;
811                 break;
812         case DRM_FORMAT_NV21:
813         case DRM_FORMAT_NV61:
814                 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB;
815                 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
816                 break;
817         case DRM_FORMAT_YUV422:
818         case DRM_FORMAT_YUV420:
819         case DRM_FORMAT_YVU420:
820                 cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE;
821                 break;
822         case DRM_FORMAT_NV12:
823         case DRM_FORMAT_NV12MT:
824         case DRM_FORMAT_NV16:
825                 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR;
826                 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
827                 break;
828         default:
829                 dev_err(ippdrv->dev, "inavlid target yuv order 0x%x.\n", fmt);
830                 return -EINVAL;
831         }
832
833         fimc_write(cfg, EXYNOS_CIOCTRL);
834
835         return 0;
836 }
837
838 static int fimc_dst_set_fmt(struct device *dev, u32 fmt)
839 {
840         struct fimc_context *ctx = get_fimc_context(dev);
841         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
842         u32 cfg;
843
844         DRM_DEBUG_KMS("%s:fmt[0x%x]\n", __func__, fmt);
845
846         cfg = fimc_read(EXYNOS_CIEXTEN);
847
848         if (fmt == DRM_FORMAT_AYUV) {
849                 cfg |= EXYNOS_CIEXTEN_YUV444_OUT;
850                 fimc_write(cfg, EXYNOS_CIEXTEN);
851         } else {
852                 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT;
853                 fimc_write(cfg, EXYNOS_CIEXTEN);
854
855                 cfg = fimc_read(EXYNOS_CITRGFMT);
856                 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK;
857
858                 switch (fmt) {
859                 case DRM_FORMAT_RGB565:
860                 case DRM_FORMAT_RGB888:
861                 case DRM_FORMAT_XRGB8888:
862                         cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB;
863                         break;
864                 case DRM_FORMAT_YUYV:
865                 case DRM_FORMAT_YVYU:
866                 case DRM_FORMAT_UYVY:
867                 case DRM_FORMAT_VYUY:
868                         cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE;
869                         break;
870                 case DRM_FORMAT_NV16:
871                 case DRM_FORMAT_NV61:
872                 case DRM_FORMAT_YUV422:
873                         cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422;
874                         break;
875                 case DRM_FORMAT_YUV420:
876                 case DRM_FORMAT_YVU420:
877                 case DRM_FORMAT_NV12:
878                 case DRM_FORMAT_NV12MT:
879                 case DRM_FORMAT_NV21:
880                         cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420;
881                         break;
882                 default:
883                         dev_err(ippdrv->dev, "inavlid target format 0x%x.\n",
884                                 fmt);
885                         return -EINVAL;
886                 }
887
888                 fimc_write(cfg, EXYNOS_CITRGFMT);
889         }
890
891         cfg = fimc_read(EXYNOS_CIDMAPARAM);
892         cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
893
894         if (fmt == DRM_FORMAT_NV12MT)
895                 cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32;
896         else
897                 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
898
899         fimc_write(cfg, EXYNOS_CIDMAPARAM);
900
901         return fimc_dst_set_fmt_order(ctx, fmt);
902 }
903
904 static int fimc_dst_set_transf(struct device *dev,
905                 enum drm_exynos_degree degree,
906                 enum drm_exynos_flip flip, bool *swap)
907 {
908         struct fimc_context *ctx = get_fimc_context(dev);
909         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
910         u32 cfg;
911
912         DRM_DEBUG_KMS("%s:degree[%d]flip[0x%x]\n", __func__,
913                 degree, flip);
914
915         cfg = fimc_read(EXYNOS_CITRGFMT);
916         cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
917         cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
918
919         switch (degree) {
920         case EXYNOS_DRM_DEGREE_0:
921                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
922                         cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
923                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
924                         cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
925                 break;
926         case EXYNOS_DRM_DEGREE_90:
927                 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
928                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
929                         cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
930                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
931                         cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
932                 break;
933         case EXYNOS_DRM_DEGREE_180:
934                 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR |
935                         EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
936                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
937                         cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
938                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
939                         cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
940                 break;
941         case EXYNOS_DRM_DEGREE_270:
942                 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE |
943                         EXYNOS_CITRGFMT_FLIP_X_MIRROR |
944                         EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
945                 if (flip & EXYNOS_DRM_FLIP_VERTICAL)
946                         cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
947                 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL)
948                         cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
949                 break;
950         default:
951                 dev_err(ippdrv->dev, "inavlid degree value %d.\n", degree);
952                 return -EINVAL;
953         }
954
955         fimc_write(cfg, EXYNOS_CITRGFMT);
956         *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0;
957
958         return 0;
959 }
960
961 static int fimc_get_ratio_shift(u32 src, u32 dst, u32 *ratio, u32 *shift)
962 {
963         DRM_DEBUG_KMS("%s:src[%d]dst[%d]\n", __func__, src, dst);
964
965         if (src >= dst * 64) {
966                 DRM_ERROR("failed to make ratio and shift.\n");
967                 return -EINVAL;
968         } else if (src >= dst * 32) {
969                 *ratio = 32;
970                 *shift = 5;
971         } else if (src >= dst * 16) {
972                 *ratio = 16;
973                 *shift = 4;
974         } else if (src >= dst * 8) {
975                 *ratio = 8;
976                 *shift = 3;
977         } else if (src >= dst * 4) {
978                 *ratio = 4;
979                 *shift = 2;
980         } else if (src >= dst * 2) {
981                 *ratio = 2;
982                 *shift = 1;
983         } else {
984                 *ratio = 1;
985                 *shift = 0;
986         }
987
988         return 0;
989 }
990
991 static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
992                 struct drm_exynos_pos *src, struct drm_exynos_pos *dst)
993 {
994         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
995         u32 cfg, cfg_ext, shfactor;
996         u32 pre_dst_width, pre_dst_height;
997         u32 pre_hratio, hfactor, pre_vratio, vfactor;
998         int ret = 0;
999         u32 src_w, src_h, dst_w, dst_h;
1000
1001         cfg_ext = fimc_read(EXYNOS_CITRGFMT);
1002         if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) {
1003                 src_w = src->h;
1004                 src_h = src->w;
1005         } else {
1006                 src_w = src->w;
1007                 src_h = src->h;
1008         }
1009
1010         if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) {
1011                 dst_w = dst->h;
1012                 dst_h = dst->w;
1013         } else {
1014                 dst_w = dst->w;
1015                 dst_h = dst->h;
1016         }
1017
1018         ret = fimc_get_ratio_shift(src_w, dst_w, &pre_hratio, &hfactor);
1019         if (ret) {
1020                 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n");
1021                 return ret;
1022         }
1023
1024         ret = fimc_get_ratio_shift(src_h, dst_h, &pre_vratio, &vfactor);
1025         if (ret) {
1026                 dev_err(ippdrv->dev, "failed to get ratio vertical.\n");
1027                 return ret;
1028         }
1029
1030         pre_dst_width = src_w / pre_hratio;
1031         pre_dst_height = src_h / pre_vratio;
1032         DRM_DEBUG_KMS("%s:pre_dst_width[%d]pre_dst_height[%d]\n", __func__,
1033                 pre_dst_width, pre_dst_height);
1034         DRM_DEBUG_KMS("%s:pre_hratio[%d]hfactor[%d]pre_vratio[%d]vfactor[%d]\n",
1035                 __func__, pre_hratio, hfactor, pre_vratio, vfactor);
1036
1037         sc->hratio = (src_w << 14) / (dst_w << hfactor);
1038         sc->vratio = (src_h << 14) / (dst_h << vfactor);
1039         sc->up_h = (dst_w >= src_w) ? true : false;
1040         sc->up_v = (dst_h >= src_h) ? true : false;
1041         DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
1042         __func__, sc->hratio, sc->vratio, sc->up_h, sc->up_v);
1043
1044         shfactor = FIMC_SHFACTOR - (hfactor + vfactor);
1045         DRM_DEBUG_KMS("%s:shfactor[%d]\n", __func__, shfactor);
1046
1047         cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
1048                 EXYNOS_CISCPRERATIO_PREHORRATIO(pre_hratio) |
1049                 EXYNOS_CISCPRERATIO_PREVERRATIO(pre_vratio));
1050         fimc_write(cfg, EXYNOS_CISCPRERATIO);
1051
1052         cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |
1053                 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height));
1054         fimc_write(cfg, EXYNOS_CISCPREDST);
1055
1056         return ret;
1057 }
1058
1059 static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
1060 {
1061         u32 cfg, cfg_ext;
1062
1063         DRM_DEBUG_KMS("%s:range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
1064                 __func__, sc->range, sc->bypass, sc->up_h, sc->up_v);
1065         DRM_DEBUG_KMS("%s:hratio[%d]vratio[%d]\n",
1066                 __func__, sc->hratio, sc->vratio);
1067
1068         cfg = fimc_read(EXYNOS_CISCCTRL);
1069         cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
1070                 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V |
1071                 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK |
1072                 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK |
1073                 EXYNOS_CISCCTRL_CSCR2Y_WIDE |
1074                 EXYNOS_CISCCTRL_CSCY2R_WIDE);
1075
1076         if (sc->range)
1077                 cfg |= (EXYNOS_CISCCTRL_CSCR2Y_WIDE |
1078                         EXYNOS_CISCCTRL_CSCY2R_WIDE);
1079         if (sc->bypass)
1080                 cfg |= EXYNOS_CISCCTRL_SCALERBYPASS;
1081         if (sc->up_h)
1082                 cfg |= EXYNOS_CISCCTRL_SCALEUP_H;
1083         if (sc->up_v)
1084                 cfg |= EXYNOS_CISCCTRL_SCALEUP_V;
1085
1086         cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) |
1087                 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6)));
1088         fimc_write(cfg, EXYNOS_CISCCTRL);
1089
1090         cfg_ext = fimc_read(EXYNOS_CIEXTEN);
1091         cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK;
1092         cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK;
1093         cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) |
1094                 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio));
1095         fimc_write(cfg_ext, EXYNOS_CIEXTEN);
1096 }
1097
1098 static int fimc_dst_set_size(struct device *dev, int swap,
1099                 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz)
1100 {
1101         struct fimc_context *ctx = get_fimc_context(dev);
1102         struct drm_exynos_pos img_pos = *pos;
1103         struct drm_exynos_sz img_sz = *sz;
1104         u32 cfg;
1105
1106         DRM_DEBUG_KMS("%s:swap[%d]hsize[%d]vsize[%d]\n",
1107                 __func__, swap, sz->hsize, sz->vsize);
1108
1109         /* original size */
1110         cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) |
1111                 EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize));
1112
1113         fimc_write(cfg, EXYNOS_ORGOSIZE);
1114
1115         DRM_DEBUG_KMS("%s:x[%d]y[%d]w[%d]h[%d]\n",
1116                 __func__, pos->x, pos->y, pos->w, pos->h);
1117
1118         /* CSC ITU */
1119         cfg = fimc_read(EXYNOS_CIGCTRL);
1120         cfg &= ~EXYNOS_CIGCTRL_CSC_MASK;
1121
1122         if (sz->hsize >= FIMC_WIDTH_ITU_709)
1123                 cfg |= EXYNOS_CIGCTRL_CSC_ITU709;
1124         else
1125                 cfg |= EXYNOS_CIGCTRL_CSC_ITU601;
1126
1127         fimc_write(cfg, EXYNOS_CIGCTRL);
1128
1129         if (swap) {
1130                 img_pos.w = pos->h;
1131                 img_pos.h = pos->w;
1132                 img_sz.hsize = sz->vsize;
1133                 img_sz.vsize = sz->hsize;
1134         }
1135
1136         /* target image size */
1137         cfg = fimc_read(EXYNOS_CITRGFMT);
1138         cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK |
1139                 EXYNOS_CITRGFMT_TARGETV_MASK);
1140         cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) |
1141                 EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h));
1142         fimc_write(cfg, EXYNOS_CITRGFMT);
1143
1144         /* target area */
1145         cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h);
1146         fimc_write(cfg, EXYNOS_CITAREA);
1147
1148         /* offset Y(RGB), Cb, Cr */
1149         cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) |
1150                 EXYNOS_CIOYOFF_VERTICAL(img_pos.y));
1151         fimc_write(cfg, EXYNOS_CIOYOFF);
1152         cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) |
1153                 EXYNOS_CIOCBOFF_VERTICAL(img_pos.y));
1154         fimc_write(cfg, EXYNOS_CIOCBOFF);
1155         cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) |
1156                 EXYNOS_CIOCROFF_VERTICAL(img_pos.y));
1157         fimc_write(cfg, EXYNOS_CIOCROFF);
1158
1159         return 0;
1160 }
1161
1162 static int fimc_dst_get_buf_seq(struct fimc_context *ctx)
1163 {
1164         u32 cfg, i, buf_num = 0;
1165         u32 mask = 0x00000001;
1166
1167         cfg = fimc_read(EXYNOS_CIFCNTSEQ);
1168
1169         for (i = 0; i < FIMC_REG_SZ; i++)
1170                 if (cfg & (mask << i))
1171                         buf_num++;
1172
1173         DRM_DEBUG_KMS("%s:buf_num[%d]\n", __func__, buf_num);
1174
1175         return buf_num;
1176 }
1177
1178 static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
1179                 enum drm_exynos_ipp_buf_type buf_type)
1180 {
1181         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1182         bool enable;
1183         u32 cfg;
1184         u32 mask = 0x00000001 << buf_id;
1185         int ret = 0;
1186
1187         DRM_DEBUG_KMS("%s:buf_id[%d]buf_type[%d]\n", __func__,
1188                 buf_id, buf_type);
1189
1190         mutex_lock(&ctx->lock);
1191
1192         /* mask register set */
1193         cfg = fimc_read(EXYNOS_CIFCNTSEQ);
1194
1195         switch (buf_type) {
1196         case IPP_BUF_ENQUEUE:
1197                 enable = true;
1198                 break;
1199         case IPP_BUF_DEQUEUE:
1200                 enable = false;
1201                 break;
1202         default:
1203                 dev_err(ippdrv->dev, "invalid buf ctrl parameter.\n");
1204                 ret =  -EINVAL;
1205                 goto err_unlock;
1206         }
1207
1208         /* sequence id */
1209         cfg &= (~mask);
1210         cfg |= (enable << buf_id);
1211         fimc_write(cfg, EXYNOS_CIFCNTSEQ);
1212
1213         /* interrupt enable */
1214         if (buf_type == IPP_BUF_ENQUEUE &&
1215             fimc_dst_get_buf_seq(ctx) >= FIMC_BUF_START)
1216                 fimc_handle_irq(ctx, true, false, true);
1217
1218         /* interrupt disable */
1219         if (buf_type == IPP_BUF_DEQUEUE &&
1220             fimc_dst_get_buf_seq(ctx) <= FIMC_BUF_STOP)
1221                 fimc_handle_irq(ctx, false, false, true);
1222
1223 err_unlock:
1224         mutex_unlock(&ctx->lock);
1225         return ret;
1226 }
1227
1228 static int fimc_dst_set_addr(struct device *dev,
1229                 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id,
1230                 enum drm_exynos_ipp_buf_type buf_type)
1231 {
1232         struct fimc_context *ctx = get_fimc_context(dev);
1233         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1234         struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd;
1235         struct drm_exynos_ipp_property *property;
1236         struct drm_exynos_ipp_config *config;
1237
1238         if (!c_node) {
1239                 DRM_ERROR("failed to get c_node.\n");
1240                 return -EINVAL;
1241         }
1242
1243         property = &c_node->property;
1244         if (!property) {
1245                 DRM_ERROR("failed to get property.\n");
1246                 return -EINVAL;
1247         }
1248
1249         DRM_DEBUG_KMS("%s:prop_id[%d]buf_id[%d]buf_type[%d]\n", __func__,
1250                 property->prop_id, buf_id, buf_type);
1251
1252         if (buf_id > FIMC_MAX_DST) {
1253                 dev_info(ippdrv->dev, "inavlid buf_id %d.\n", buf_id);
1254                 return -ENOMEM;
1255         }
1256
1257         /* address register set */
1258         switch (buf_type) {
1259         case IPP_BUF_ENQUEUE:
1260                 config = &property->config[EXYNOS_DRM_OPS_DST];
1261
1262                 fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_Y],
1263                         EXYNOS_CIOYSA(buf_id));
1264
1265                 if (config->fmt == DRM_FORMAT_YVU420) {
1266                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
1267                                 EXYNOS_CIOCBSA(buf_id));
1268                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
1269                                 EXYNOS_CIOCRSA(buf_id));
1270                 } else {
1271                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CB],
1272                                 EXYNOS_CIOCBSA(buf_id));
1273                         fimc_write(buf_info->base[EXYNOS_DRM_PLANAR_CR],
1274                                 EXYNOS_CIOCRSA(buf_id));
1275                 }
1276                 break;
1277         case IPP_BUF_DEQUEUE:
1278                 fimc_write(0x0, EXYNOS_CIOYSA(buf_id));
1279                 fimc_write(0x0, EXYNOS_CIOCBSA(buf_id));
1280                 fimc_write(0x0, EXYNOS_CIOCRSA(buf_id));
1281                 break;
1282         default:
1283                 /* bypass */
1284                 break;
1285         }
1286
1287         return fimc_dst_set_buf_seq(ctx, buf_id, buf_type);
1288 }
1289
1290 static struct exynos_drm_ipp_ops fimc_dst_ops = {
1291         .set_fmt = fimc_dst_set_fmt,
1292         .set_transf = fimc_dst_set_transf,
1293         .set_size = fimc_dst_set_size,
1294         .set_addr = fimc_dst_set_addr,
1295 };
1296
1297 static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable)
1298 {
1299         DRM_DEBUG_KMS("%s:enable[%d]\n", __func__, enable);
1300
1301         if (enable) {
1302                 clk_enable(ctx->sclk_fimc_clk);
1303                 clk_enable(ctx->fimc_clk);
1304                 clk_enable(ctx->wb_clk);
1305                 ctx->suspended = false;
1306         } else {
1307                 clk_disable(ctx->sclk_fimc_clk);
1308                 clk_disable(ctx->fimc_clk);
1309                 clk_disable(ctx->wb_clk);
1310                 ctx->suspended = true;
1311         }
1312
1313         return 0;
1314 }
1315
1316 static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
1317 {
1318         struct fimc_context *ctx = dev_id;
1319         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1320         struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd;
1321         struct drm_exynos_ipp_event_work *event_work =
1322                 c_node->event_work;
1323         int buf_id;
1324
1325         DRM_DEBUG_KMS("%s:fimc id[%d]\n", __func__, ctx->id);
1326
1327         fimc_clear_irq(ctx);
1328         if (fimc_check_ovf(ctx))
1329                 return IRQ_NONE;
1330
1331         if (!fimc_check_frame_end(ctx))
1332                 return IRQ_NONE;
1333
1334         buf_id = fimc_get_buf_id(ctx);
1335         if (buf_id < 0)
1336                 return IRQ_HANDLED;
1337
1338         DRM_DEBUG_KMS("%s:buf_id[%d]\n", __func__, buf_id);
1339
1340         if (fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE) < 0) {
1341                 DRM_ERROR("failed to dequeue.\n");
1342                 return IRQ_HANDLED;
1343         }
1344
1345         event_work->ippdrv = ippdrv;
1346         event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id;
1347         queue_work(ippdrv->event_workq, (struct work_struct *)event_work);
1348
1349         return IRQ_HANDLED;
1350 }
1351
1352 static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv)
1353 {
1354         struct drm_exynos_ipp_prop_list *prop_list;
1355
1356         DRM_DEBUG_KMS("%s\n", __func__);
1357
1358         prop_list = devm_kzalloc(ippdrv->dev, sizeof(*prop_list), GFP_KERNEL);
1359         if (!prop_list) {
1360                 DRM_ERROR("failed to alloc property list.\n");
1361                 return -ENOMEM;
1362         }
1363
1364         prop_list->version = 1;
1365         prop_list->writeback = 1;
1366         prop_list->refresh_min = FIMC_REFRESH_MIN;
1367         prop_list->refresh_max = FIMC_REFRESH_MAX;
1368         prop_list->flip = (1 << EXYNOS_DRM_FLIP_NONE) |
1369                                 (1 << EXYNOS_DRM_FLIP_VERTICAL) |
1370                                 (1 << EXYNOS_DRM_FLIP_HORIZONTAL);
1371         prop_list->degree = (1 << EXYNOS_DRM_DEGREE_0) |
1372                                 (1 << EXYNOS_DRM_DEGREE_90) |
1373                                 (1 << EXYNOS_DRM_DEGREE_180) |
1374                                 (1 << EXYNOS_DRM_DEGREE_270);
1375         prop_list->csc = 1;
1376         prop_list->crop = 1;
1377         prop_list->crop_max.hsize = FIMC_CROP_MAX;
1378         prop_list->crop_max.vsize = FIMC_CROP_MAX;
1379         prop_list->crop_min.hsize = FIMC_CROP_MIN;
1380         prop_list->crop_min.vsize = FIMC_CROP_MIN;
1381         prop_list->scale = 1;
1382         prop_list->scale_max.hsize = FIMC_SCALE_MAX;
1383         prop_list->scale_max.vsize = FIMC_SCALE_MAX;
1384         prop_list->scale_min.hsize = FIMC_SCALE_MIN;
1385         prop_list->scale_min.vsize = FIMC_SCALE_MIN;
1386
1387         ippdrv->prop_list = prop_list;
1388
1389         return 0;
1390 }
1391
1392 static inline bool fimc_check_drm_flip(enum drm_exynos_flip flip)
1393 {
1394         switch (flip) {
1395         case EXYNOS_DRM_FLIP_NONE:
1396         case EXYNOS_DRM_FLIP_VERTICAL:
1397         case EXYNOS_DRM_FLIP_HORIZONTAL:
1398                 return true;
1399         default:
1400                 DRM_DEBUG_KMS("%s:invalid flip\n", __func__);
1401                 return false;
1402         }
1403 }
1404
1405 static int fimc_ippdrv_check_property(struct device *dev,
1406                 struct drm_exynos_ipp_property *property)
1407 {
1408         struct fimc_context *ctx = get_fimc_context(dev);
1409         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1410         struct drm_exynos_ipp_prop_list *pp = ippdrv->prop_list;
1411         struct drm_exynos_ipp_config *config;
1412         struct drm_exynos_pos *pos;
1413         struct drm_exynos_sz *sz;
1414         bool swap;
1415         int i;
1416
1417         DRM_DEBUG_KMS("%s\n", __func__);
1418
1419         for_each_ipp_ops(i) {
1420                 if ((i == EXYNOS_DRM_OPS_SRC) &&
1421                         (property->cmd == IPP_CMD_WB))
1422                         continue;
1423
1424                 config = &property->config[i];
1425                 pos = &config->pos;
1426                 sz = &config->sz;
1427
1428                 /* check for flip */
1429                 if (!fimc_check_drm_flip(config->flip)) {
1430                         DRM_ERROR("invalid flip.\n");
1431                         goto err_property;
1432                 }
1433
1434                 /* check for degree */
1435                 switch (config->degree) {
1436                 case EXYNOS_DRM_DEGREE_90:
1437                 case EXYNOS_DRM_DEGREE_270:
1438                         swap = true;
1439                         break;
1440                 case EXYNOS_DRM_DEGREE_0:
1441                 case EXYNOS_DRM_DEGREE_180:
1442                         swap = false;
1443                         break;
1444                 default:
1445                         DRM_ERROR("invalid degree.\n");
1446                         goto err_property;
1447                 }
1448
1449                 /* check for buffer bound */
1450                 if ((pos->x + pos->w > sz->hsize) ||
1451                         (pos->y + pos->h > sz->vsize)) {
1452                         DRM_ERROR("out of buf bound.\n");
1453                         goto err_property;
1454                 }
1455
1456                 /* check for crop */
1457                 if ((i == EXYNOS_DRM_OPS_SRC) && (pp->crop)) {
1458                         if (swap) {
1459                                 if ((pos->h < pp->crop_min.hsize) ||
1460                                         (sz->vsize > pp->crop_max.hsize) ||
1461                                         (pos->w < pp->crop_min.vsize) ||
1462                                         (sz->hsize > pp->crop_max.vsize)) {
1463                                         DRM_ERROR("out of crop size.\n");
1464                                         goto err_property;
1465                                 }
1466                         } else {
1467                                 if ((pos->w < pp->crop_min.hsize) ||
1468                                         (sz->hsize > pp->crop_max.hsize) ||
1469                                         (pos->h < pp->crop_min.vsize) ||
1470                                         (sz->vsize > pp->crop_max.vsize)) {
1471                                         DRM_ERROR("out of crop size.\n");
1472                                         goto err_property;
1473                                 }
1474                         }
1475                 }
1476
1477                 /* check for scale */
1478                 if ((i == EXYNOS_DRM_OPS_DST) && (pp->scale)) {
1479                         if (swap) {
1480                                 if ((pos->h < pp->scale_min.hsize) ||
1481                                         (sz->vsize > pp->scale_max.hsize) ||
1482                                         (pos->w < pp->scale_min.vsize) ||
1483                                         (sz->hsize > pp->scale_max.vsize)) {
1484                                         DRM_ERROR("out of scale size.\n");
1485                                         goto err_property;
1486                                 }
1487                         } else {
1488                                 if ((pos->w < pp->scale_min.hsize) ||
1489                                         (sz->hsize > pp->scale_max.hsize) ||
1490                                         (pos->h < pp->scale_min.vsize) ||
1491                                         (sz->vsize > pp->scale_max.vsize)) {
1492                                         DRM_ERROR("out of scale size.\n");
1493                                         goto err_property;
1494                                 }
1495                         }
1496                 }
1497         }
1498
1499         return 0;
1500
1501 err_property:
1502         for_each_ipp_ops(i) {
1503                 if ((i == EXYNOS_DRM_OPS_SRC) &&
1504                         (property->cmd == IPP_CMD_WB))
1505                         continue;
1506
1507                 config = &property->config[i];
1508                 pos = &config->pos;
1509                 sz = &config->sz;
1510
1511                 DRM_ERROR("[%s]f[%d]r[%d]pos[%d %d %d %d]sz[%d %d]\n",
1512                         i ? "dst" : "src", config->flip, config->degree,
1513                         pos->x, pos->y, pos->w, pos->h,
1514                         sz->hsize, sz->vsize);
1515         }
1516
1517         return -EINVAL;
1518 }
1519
1520 static void fimc_clear_addr(struct fimc_context *ctx)
1521 {
1522         int i;
1523
1524         DRM_DEBUG_KMS("%s:\n", __func__);
1525
1526         for (i = 0; i < FIMC_MAX_SRC; i++) {
1527                 fimc_write(0, EXYNOS_CIIYSA(i));
1528                 fimc_write(0, EXYNOS_CIICBSA(i));
1529                 fimc_write(0, EXYNOS_CIICRSA(i));
1530         }
1531
1532         for (i = 0; i < FIMC_MAX_DST; i++) {
1533                 fimc_write(0, EXYNOS_CIOYSA(i));
1534                 fimc_write(0, EXYNOS_CIOCBSA(i));
1535                 fimc_write(0, EXYNOS_CIOCRSA(i));
1536         }
1537 }
1538
1539 static int fimc_ippdrv_reset(struct device *dev)
1540 {
1541         struct fimc_context *ctx = get_fimc_context(dev);
1542
1543         DRM_DEBUG_KMS("%s\n", __func__);
1544
1545         /* reset h/w block */
1546         fimc_sw_reset(ctx, false);
1547
1548         /* reset scaler capability */
1549         memset(&ctx->sc, 0x0, sizeof(ctx->sc));
1550
1551         fimc_clear_addr(ctx);
1552
1553         return 0;
1554 }
1555
1556 static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1557 {
1558         struct fimc_context *ctx = get_fimc_context(dev);
1559         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1560         struct drm_exynos_ipp_cmd_node *c_node = ippdrv->cmd;
1561         struct drm_exynos_ipp_property *property;
1562         struct drm_exynos_ipp_config *config;
1563         struct drm_exynos_pos   img_pos[EXYNOS_DRM_OPS_MAX];
1564         struct drm_exynos_ipp_set_wb set_wb;
1565         int ret, i;
1566         u32 cfg0, cfg1;
1567
1568         DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
1569
1570         if (!c_node) {
1571                 DRM_ERROR("failed to get c_node.\n");
1572                 return -EINVAL;
1573         }
1574
1575         property = &c_node->property;
1576         if (!property) {
1577                 DRM_ERROR("failed to get property.\n");
1578                 return -EINVAL;
1579         }
1580
1581         fimc_handle_irq(ctx, true, false, true);
1582
1583         for_each_ipp_ops(i) {
1584                 config = &property->config[i];
1585                 img_pos[i] = config->pos;
1586         }
1587
1588         ret = fimc_set_prescaler(ctx, &ctx->sc,
1589                 &img_pos[EXYNOS_DRM_OPS_SRC],
1590                 &img_pos[EXYNOS_DRM_OPS_DST]);
1591         if (ret) {
1592                 dev_err(dev, "failed to set precalser.\n");
1593                 return ret;
1594         }
1595
1596         /* If set ture, we can save jpeg about screen */
1597         fimc_handle_jpeg(ctx, false);
1598         fimc_set_scaler(ctx, &ctx->sc);
1599         fimc_set_polarity(ctx, &ctx->pol);
1600
1601         switch (cmd) {
1602         case IPP_CMD_M2M:
1603                 fimc_set_type_ctrl(ctx, FIMC_WB_NONE);
1604                 fimc_handle_lastend(ctx, false);
1605
1606                 /* setup dma */
1607                 cfg0 = fimc_read(EXYNOS_MSCTRL);
1608                 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
1609                 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
1610                 fimc_write(cfg0, EXYNOS_MSCTRL);
1611                 break;
1612         case IPP_CMD_WB:
1613                 fimc_set_type_ctrl(ctx, FIMC_WB_A);
1614                 fimc_handle_lastend(ctx, true);
1615
1616                 /* setup FIMD */
1617                 fimc_set_camblk_fimd0_wb(ctx);
1618
1619                 set_wb.enable = 1;
1620                 set_wb.refresh = property->refresh_rate;
1621                 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
1622                 break;
1623         case IPP_CMD_OUTPUT:
1624         default:
1625                 ret = -EINVAL;
1626                 dev_err(dev, "invalid operations.\n");
1627                 return ret;
1628         }
1629
1630         /* Reset status */
1631         fimc_write(0x0, EXYNOS_CISTATUS);
1632
1633         cfg0 = fimc_read(EXYNOS_CIIMGCPT);
1634         cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC;
1635         cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC;
1636
1637         /* Scaler */
1638         cfg1 = fimc_read(EXYNOS_CISCCTRL);
1639         cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK;
1640         cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE |
1641                 EXYNOS_CISCCTRL_SCALERSTART);
1642
1643         fimc_write(cfg1, EXYNOS_CISCCTRL);
1644
1645         /* Enable image capture*/
1646         cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN;
1647         fimc_write(cfg0, EXYNOS_CIIMGCPT);
1648
1649         /* Disable frame end irq */
1650         cfg0 = fimc_read(EXYNOS_CIGCTRL);
1651         cfg0 &= ~EXYNOS_CIGCTRL_IRQ_END_DISABLE;
1652         fimc_write(cfg0, EXYNOS_CIGCTRL);
1653
1654         cfg0 = fimc_read(EXYNOS_CIOCTRL);
1655         cfg0 &= ~EXYNOS_CIOCTRL_WEAVE_MASK;
1656         fimc_write(cfg0, EXYNOS_CIOCTRL);
1657
1658         if (cmd == IPP_CMD_M2M) {
1659                 cfg0 = fimc_read(EXYNOS_MSCTRL);
1660                 cfg0 |= EXYNOS_MSCTRL_ENVID;
1661                 fimc_write(cfg0, EXYNOS_MSCTRL);
1662
1663                 cfg0 = fimc_read(EXYNOS_MSCTRL);
1664                 cfg0 |= EXYNOS_MSCTRL_ENVID;
1665                 fimc_write(cfg0, EXYNOS_MSCTRL);
1666         }
1667
1668         return 0;
1669 }
1670
1671 static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd)
1672 {
1673         struct fimc_context *ctx = get_fimc_context(dev);
1674         struct drm_exynos_ipp_set_wb set_wb = {0, 0};
1675         u32 cfg;
1676
1677         DRM_DEBUG_KMS("%s:cmd[%d]\n", __func__, cmd);
1678
1679         switch (cmd) {
1680         case IPP_CMD_M2M:
1681                 /* Source clear */
1682                 cfg = fimc_read(EXYNOS_MSCTRL);
1683                 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
1684                 cfg &= ~EXYNOS_MSCTRL_ENVID;
1685                 fimc_write(cfg, EXYNOS_MSCTRL);
1686                 break;
1687         case IPP_CMD_WB:
1688                 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb);
1689                 break;
1690         case IPP_CMD_OUTPUT:
1691         default:
1692                 dev_err(dev, "invalid operations.\n");
1693                 break;
1694         }
1695
1696         fimc_handle_irq(ctx, false, false, true);
1697
1698         /* reset sequence */
1699         fimc_write(0x0, EXYNOS_CIFCNTSEQ);
1700
1701         /* Scaler disable */
1702         cfg = fimc_read(EXYNOS_CISCCTRL);
1703         cfg &= ~EXYNOS_CISCCTRL_SCALERSTART;
1704         fimc_write(cfg, EXYNOS_CISCCTRL);
1705
1706         /* Disable image capture */
1707         cfg = fimc_read(EXYNOS_CIIMGCPT);
1708         cfg &= ~(EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
1709         fimc_write(cfg, EXYNOS_CIIMGCPT);
1710
1711         /* Enable frame end irq */
1712         cfg = fimc_read(EXYNOS_CIGCTRL);
1713         cfg |= EXYNOS_CIGCTRL_IRQ_END_DISABLE;
1714         fimc_write(cfg, EXYNOS_CIGCTRL);
1715 }
1716
1717 static int __devinit fimc_probe(struct platform_device *pdev)
1718 {
1719         struct device *dev = &pdev->dev;
1720         struct fimc_context *ctx;
1721         struct clk      *parent_clk;
1722         struct resource *res;
1723         struct exynos_drm_ippdrv *ippdrv;
1724         struct exynos_drm_fimc_pdata *pdata;
1725         struct fimc_driverdata *ddata;
1726         int ret;
1727
1728         pdata = pdev->dev.platform_data;
1729         if (!pdata) {
1730                 dev_err(dev, "no platform data specified.\n");
1731                 return -EINVAL;
1732         }
1733
1734         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1735         if (!ctx)
1736                 return -ENOMEM;
1737
1738         ddata = (struct fimc_driverdata *)
1739                 platform_get_device_id(pdev)->driver_data;
1740
1741         /* clock control */
1742         ctx->sclk_fimc_clk = clk_get(dev, "sclk_fimc");
1743         if (IS_ERR(ctx->sclk_fimc_clk)) {
1744                 dev_err(dev, "failed to get src fimc clock.\n");
1745                 ret = PTR_ERR(ctx->sclk_fimc_clk);
1746                 goto err_ctx;
1747         }
1748         clk_enable(ctx->sclk_fimc_clk);
1749
1750         ctx->fimc_clk = clk_get(dev, "fimc");
1751         if (IS_ERR(ctx->fimc_clk)) {
1752                 dev_err(dev, "failed to get fimc clock.\n");
1753                 ret = PTR_ERR(ctx->fimc_clk);
1754                 clk_disable(ctx->sclk_fimc_clk);
1755                 clk_put(ctx->sclk_fimc_clk);
1756                 goto err_ctx;
1757         }
1758
1759         ctx->wb_clk = clk_get(dev, "pxl_async0");
1760         if (IS_ERR(ctx->wb_clk)) {
1761                 dev_err(dev, "failed to get writeback a clock.\n");
1762                 ret = PTR_ERR(ctx->wb_clk);
1763                 clk_disable(ctx->sclk_fimc_clk);
1764                 clk_put(ctx->sclk_fimc_clk);
1765                 clk_put(ctx->fimc_clk);
1766                 goto err_ctx;
1767         }
1768
1769         ctx->wb_b_clk = clk_get(dev, "pxl_async1");
1770         if (IS_ERR(ctx->wb_b_clk)) {
1771                 dev_err(dev, "failed to get writeback b clock.\n");
1772                 ret = PTR_ERR(ctx->wb_b_clk);
1773                 clk_disable(ctx->sclk_fimc_clk);
1774                 clk_put(ctx->sclk_fimc_clk);
1775                 clk_put(ctx->fimc_clk);
1776                 clk_put(ctx->wb_clk);
1777                 goto err_ctx;
1778         }
1779
1780         parent_clk = clk_get(dev, ddata->parent_clk);
1781
1782         if (IS_ERR(parent_clk)) {
1783                 dev_err(dev, "failed to get parent clock.\n");
1784                 ret = PTR_ERR(parent_clk);
1785                 clk_disable(ctx->sclk_fimc_clk);
1786                 clk_put(ctx->sclk_fimc_clk);
1787                 clk_put(ctx->fimc_clk);
1788                 clk_put(ctx->wb_clk);
1789                 clk_put(ctx->wb_b_clk);
1790                 goto err_ctx;
1791         }
1792
1793         if (clk_set_parent(ctx->sclk_fimc_clk, parent_clk)) {
1794                 dev_err(dev, "failed to set parent.\n");
1795                 ret = -EINVAL;
1796                 clk_put(parent_clk);
1797                 clk_disable(ctx->sclk_fimc_clk);
1798                 clk_put(ctx->sclk_fimc_clk);
1799                 clk_put(ctx->fimc_clk);
1800                 clk_put(ctx->wb_clk);
1801                 clk_put(ctx->wb_b_clk);
1802                 goto err_ctx;
1803         }
1804
1805         clk_put(parent_clk);
1806         clk_set_rate(ctx->sclk_fimc_clk, pdata->clk_rate);
1807
1808         /* resource memory */
1809         ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1810         if (!ctx->regs_res) {
1811                 dev_err(dev, "failed to find registers.\n");
1812                 ret = -ENOENT;
1813                 goto err_clk;
1814         }
1815
1816         ctx->regs = devm_request_and_ioremap(dev, ctx->regs_res);
1817         if (!ctx->regs) {
1818                 dev_err(dev, "failed to map registers.\n");
1819                 ret = -ENXIO;
1820                 goto err_clk;
1821         }
1822
1823         /* resource irq */
1824         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1825         if (!res) {
1826                 dev_err(dev, "failed to request irq resource.\n");
1827                 ret = -ENOENT;
1828                 goto err_get_regs;
1829         }
1830
1831         ctx->irq = res->start;
1832         ret = request_threaded_irq(ctx->irq, NULL, fimc_irq_handler,
1833                 IRQF_ONESHOT, "drm_fimc", ctx);
1834         if (ret < 0) {
1835                 dev_err(dev, "failed to request irq.\n");
1836                 goto err_get_regs;
1837         }
1838
1839         /* context initailization */
1840         ctx->id = pdev->id;
1841         ctx->pol = pdata->pol;
1842         ctx->ddata = ddata;
1843
1844         ippdrv = &ctx->ippdrv;
1845         ippdrv->dev = dev;
1846         ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &fimc_src_ops;
1847         ippdrv->ops[EXYNOS_DRM_OPS_DST] = &fimc_dst_ops;
1848         ippdrv->check_property = fimc_ippdrv_check_property;
1849         ippdrv->reset = fimc_ippdrv_reset;
1850         ippdrv->start = fimc_ippdrv_start;
1851         ippdrv->stop = fimc_ippdrv_stop;
1852         ret = fimc_init_prop_list(ippdrv);
1853         if (ret < 0) {
1854                 dev_err(dev, "failed to init property list.\n");
1855                 goto err_get_irq;
1856         }
1857
1858         DRM_DEBUG_KMS("%s:id[%d]ippdrv[0x%x]\n", __func__, ctx->id,
1859                 (int)ippdrv);
1860
1861         mutex_init(&ctx->lock);
1862         platform_set_drvdata(pdev, ctx);
1863
1864         pm_runtime_set_active(dev);
1865         pm_runtime_enable(dev);
1866
1867         ret = exynos_drm_ippdrv_register(ippdrv);
1868         if (ret < 0) {
1869                 dev_err(dev, "failed to register drm fimc device.\n");
1870                 goto err_ippdrv_register;
1871         }
1872
1873         dev_info(&pdev->dev, "drm fimc registered successfully.\n");
1874
1875         return 0;
1876
1877 err_ippdrv_register:
1878         devm_kfree(dev, ippdrv->prop_list);
1879         pm_runtime_disable(dev);
1880 err_get_irq:
1881         free_irq(ctx->irq, ctx);
1882 err_get_regs:
1883         devm_iounmap(dev, ctx->regs);
1884 err_clk:
1885         clk_put(ctx->sclk_fimc_clk);
1886         clk_put(ctx->fimc_clk);
1887         clk_put(ctx->wb_clk);
1888         clk_put(ctx->wb_b_clk);
1889 err_ctx:
1890         devm_kfree(dev, ctx);
1891         return ret;
1892 }
1893
1894 static int __devexit fimc_remove(struct platform_device *pdev)
1895 {
1896         struct device *dev = &pdev->dev;
1897         struct fimc_context *ctx = get_fimc_context(dev);
1898         struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv;
1899
1900         devm_kfree(dev, ippdrv->prop_list);
1901         exynos_drm_ippdrv_unregister(ippdrv);
1902         mutex_destroy(&ctx->lock);
1903
1904         pm_runtime_set_suspended(dev);
1905         pm_runtime_disable(dev);
1906
1907         free_irq(ctx->irq, ctx);
1908         devm_iounmap(dev, ctx->regs);
1909
1910         clk_put(ctx->sclk_fimc_clk);
1911         clk_put(ctx->fimc_clk);
1912         clk_put(ctx->wb_clk);
1913         clk_put(ctx->wb_b_clk);
1914
1915         devm_kfree(dev, ctx);
1916
1917         return 0;
1918 }
1919
1920 #ifdef CONFIG_PM_SLEEP
1921 static int fimc_suspend(struct device *dev)
1922 {
1923         struct fimc_context *ctx = get_fimc_context(dev);
1924
1925         DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
1926
1927         if (pm_runtime_suspended(dev))
1928                 return 0;
1929
1930         return fimc_clk_ctrl(ctx, false);
1931 }
1932
1933 static int fimc_resume(struct device *dev)
1934 {
1935         struct fimc_context *ctx = get_fimc_context(dev);
1936
1937         DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
1938
1939         if (!pm_runtime_suspended(dev))
1940                 return fimc_clk_ctrl(ctx, true);
1941
1942         return 0;
1943 }
1944 #endif
1945
1946 #ifdef CONFIG_PM_RUNTIME
1947 static int fimc_runtime_suspend(struct device *dev)
1948 {
1949         struct fimc_context *ctx = get_fimc_context(dev);
1950
1951         DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
1952
1953         return  fimc_clk_ctrl(ctx, false);
1954 }
1955
1956 static int fimc_runtime_resume(struct device *dev)
1957 {
1958         struct fimc_context *ctx = get_fimc_context(dev);
1959
1960         DRM_DEBUG_KMS("%s:id[%d]\n", __func__, ctx->id);
1961
1962         return  fimc_clk_ctrl(ctx, true);
1963 }
1964 #endif
1965
1966 static struct fimc_driverdata exynos4210_fimc_data = {
1967         .parent_clk = "mout_mpll",
1968 };
1969
1970 static struct fimc_driverdata exynos4410_fimc_data = {
1971         .parent_clk = "mout_mpll_user",
1972 };
1973
1974 static struct platform_device_id fimc_driver_ids[] = {
1975         {
1976                 .name           = "exynos4210-fimc",
1977                 .driver_data    = (unsigned long)&exynos4210_fimc_data,
1978         }, {
1979                 .name           = "exynos4412-fimc",
1980                 .driver_data    = (unsigned long)&exynos4410_fimc_data,
1981         },
1982         {},
1983 };
1984 MODULE_DEVICE_TABLE(platform, fimc_driver_ids);
1985
1986 static const struct dev_pm_ops fimc_pm_ops = {
1987         SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
1988         SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
1989 };
1990
1991 struct platform_driver fimc_driver = {
1992         .probe          = fimc_probe,
1993         .remove         = __devexit_p(fimc_remove),
1994         .id_table       = fimc_driver_ids,
1995         .driver         = {
1996                 .name   = "exynos-drm-fimc",
1997                 .owner  = THIS_MODULE,
1998                 .pm     = &fimc_pm_ops,
1999         },
2000 };
2001