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 
1983