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