1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * Eunchul Kim <chulspro.kim@samsung.com>
6 * Jinyoung Jeon <jy0.jeon@samsung.com>
7 * Sangmin Lee <lsmin.lee@samsung.com>
10 #include <linux/clk.h>
11 #include <linux/component.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/spinlock.h>
20 #include <drm/drm_fourcc.h>
21 #include <drm/drm_print.h>
22 #include <drm/exynos_drm.h>
24 #include "exynos_drm_drv.h"
25 #include "exynos_drm_ipp.h"
26 #include "regs-fimc.h"
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.
36 #define FIMC_MAX_DEVS 4
37 #define FIMC_MAX_SRC 2
38 #define FIMC_MAX_DST 32
39 #define FIMC_SHFACTOR 10
40 #define FIMC_BUF_STOP 1
41 #define FIMC_BUF_START 2
42 #define FIMC_WIDTH_ITU_709 1280
43 #define FIMC_AUTOSUSPEND_DELAY 2000
45 static unsigned int fimc_mask
= 0xc;
46 module_param_named(fimc_devs
, fimc_mask
, uint
, 0644);
47 MODULE_PARM_DESC(fimc_devs
, "Alias mask for assigning FIMC devices to Exynos DRM");
49 #define get_fimc_context(dev) dev_get_drvdata(dev)
59 static const char * const fimc_clock_names
[] = {
60 [FIMC_CLK_LCLK
] = "sclk_fimc",
61 [FIMC_CLK_GATE
] = "fimc",
62 [FIMC_CLK_WB_A
] = "pxl_async0",
63 [FIMC_CLK_WB_B
] = "pxl_async1",
67 * A structure of scaler.
69 * @range: narrow, wide.
70 * @bypass: unused scaler path.
71 * @up_h: horizontal scale up.
72 * @up_v: vertical scale up.
73 * @hratio: horizontal ratio.
74 * @vratio: vertical ratio.
86 * A structure of fimc context.
88 * @regs_res: register resources.
89 * @regs: memory mapped io registers.
90 * @lock: locking of operations.
91 * @clocks: fimc clocks.
92 * @sc: scaler infomations.
93 * @pol: porarity of writeback.
98 struct exynos_drm_ipp ipp
;
99 struct drm_device
*drm_dev
;
102 struct exynos_drm_ipp_task
*task
;
103 struct exynos_drm_ipp_formats
*formats
;
104 unsigned int num_formats
;
106 struct resource
*regs_res
;
109 struct clk
*clocks
[FIMC_CLKS_MAX
];
110 struct fimc_scaler sc
;
115 static u32
fimc_read(struct fimc_context
*ctx
, u32 reg
)
117 return readl(ctx
->regs
+ reg
);
120 static void fimc_write(struct fimc_context
*ctx
, u32 val
, u32 reg
)
122 writel(val
, ctx
->regs
+ reg
);
125 static void fimc_set_bits(struct fimc_context
*ctx
, u32 reg
, u32 bits
)
127 void __iomem
*r
= ctx
->regs
+ reg
;
129 writel(readl(r
) | bits
, r
);
132 static void fimc_clear_bits(struct fimc_context
*ctx
, u32 reg
, u32 bits
)
134 void __iomem
*r
= ctx
->regs
+ reg
;
136 writel(readl(r
) & ~bits
, r
);
139 static void fimc_sw_reset(struct fimc_context
*ctx
)
143 /* stop dma operation */
144 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS
);
145 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg
))
146 fimc_clear_bits(ctx
, EXYNOS_MSCTRL
, EXYNOS_MSCTRL_ENVID
);
148 fimc_set_bits(ctx
, EXYNOS_CISRCFMT
, EXYNOS_CISRCFMT_ITU601_8BIT
);
150 /* disable image capture */
151 fimc_clear_bits(ctx
, EXYNOS_CIIMGCPT
,
152 EXYNOS_CIIMGCPT_IMGCPTEN_SC
| EXYNOS_CIIMGCPT_IMGCPTEN
);
155 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_SWRST
);
157 /* s/w reset complete */
158 fimc_clear_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_SWRST
);
161 fimc_write(ctx
, 0x0, EXYNOS_CIFCNTSEQ
);
164 static void fimc_set_type_ctrl(struct fimc_context
*ctx
)
168 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
169 cfg
&= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK
|
170 EXYNOS_CIGCTRL_SELCAM_ITU_MASK
|
171 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK
|
172 EXYNOS_CIGCTRL_SELCAM_FIMC_MASK
|
173 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK
|
174 EXYNOS_CIGCTRL_SELWRITEBACK_MASK
);
176 cfg
|= (EXYNOS_CIGCTRL_SELCAM_ITU_A
|
177 EXYNOS_CIGCTRL_SELWRITEBACK_A
|
178 EXYNOS_CIGCTRL_SELCAM_MIPI_A
|
179 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU
);
181 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
184 static void fimc_handle_jpeg(struct fimc_context
*ctx
, bool enable
)
188 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
190 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
192 cfg
|= EXYNOS_CIGCTRL_CAM_JPEG
;
194 cfg
&= ~EXYNOS_CIGCTRL_CAM_JPEG
;
196 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
199 static void fimc_mask_irq(struct fimc_context
*ctx
, bool enable
)
203 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
205 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
207 cfg
&= ~EXYNOS_CIGCTRL_IRQ_OVFEN
;
208 cfg
|= EXYNOS_CIGCTRL_IRQ_ENABLE
| EXYNOS_CIGCTRL_IRQ_LEVEL
;
210 cfg
&= ~EXYNOS_CIGCTRL_IRQ_ENABLE
;
211 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
214 static void fimc_clear_irq(struct fimc_context
*ctx
)
216 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_CLR
);
219 static bool fimc_check_ovf(struct fimc_context
*ctx
)
223 status
= fimc_read(ctx
, EXYNOS_CISTATUS
);
224 flag
= EXYNOS_CISTATUS_OVFIY
| EXYNOS_CISTATUS_OVFICB
|
225 EXYNOS_CISTATUS_OVFICR
;
227 DRM_DEV_DEBUG_KMS(ctx
->dev
, "flag[0x%x]\n", flag
);
230 fimc_set_bits(ctx
, EXYNOS_CIWDOFST
,
231 EXYNOS_CIWDOFST_CLROVFIY
| EXYNOS_CIWDOFST_CLROVFICB
|
232 EXYNOS_CIWDOFST_CLROVFICR
);
234 DRM_DEV_ERROR(ctx
->dev
,
235 "occurred overflow at %d, status 0x%x.\n",
243 static bool fimc_check_frame_end(struct fimc_context
*ctx
)
247 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS
);
249 DRM_DEV_DEBUG_KMS(ctx
->dev
, "cfg[0x%x]\n", cfg
);
251 if (!(cfg
& EXYNOS_CISTATUS_FRAMEEND
))
254 cfg
&= ~(EXYNOS_CISTATUS_FRAMEEND
);
255 fimc_write(ctx
, cfg
, EXYNOS_CISTATUS
);
260 static int fimc_get_buf_id(struct fimc_context
*ctx
)
263 int frame_cnt
, buf_id
;
265 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS2
);
266 frame_cnt
= EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg
);
269 frame_cnt
= EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg
);
271 DRM_DEV_DEBUG_KMS(ctx
->dev
, "present[%d]before[%d]\n",
272 EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg
),
273 EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg
));
275 if (frame_cnt
== 0) {
276 DRM_DEV_ERROR(ctx
->dev
, "failed to get frame count.\n");
280 buf_id
= frame_cnt
- 1;
281 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]\n", buf_id
);
286 static void fimc_handle_lastend(struct fimc_context
*ctx
, bool enable
)
290 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
292 cfg
= fimc_read(ctx
, EXYNOS_CIOCTRL
);
294 cfg
|= EXYNOS_CIOCTRL_LASTENDEN
;
296 cfg
&= ~EXYNOS_CIOCTRL_LASTENDEN
;
298 fimc_write(ctx
, cfg
, EXYNOS_CIOCTRL
);
301 static void fimc_src_set_fmt_order(struct fimc_context
*ctx
, u32 fmt
)
305 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
308 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
309 cfg
&= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK
;
312 case DRM_FORMAT_RGB565
:
313 cfg
|= EXYNOS_CISCCTRL_INRGB_FMT_RGB565
;
314 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
316 case DRM_FORMAT_RGB888
:
317 case DRM_FORMAT_XRGB8888
:
318 cfg
|= EXYNOS_CISCCTRL_INRGB_FMT_RGB888
;
319 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
327 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
328 cfg
&= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK
|
329 EXYNOS_MSCTRL_C_INT_IN_2PLANE
|
330 EXYNOS_MSCTRL_ORDER422_YCBYCR
);
333 case DRM_FORMAT_YUYV
:
334 cfg
|= EXYNOS_MSCTRL_ORDER422_YCBYCR
;
336 case DRM_FORMAT_YVYU
:
337 cfg
|= EXYNOS_MSCTRL_ORDER422_YCRYCB
;
339 case DRM_FORMAT_UYVY
:
340 cfg
|= EXYNOS_MSCTRL_ORDER422_CBYCRY
;
342 case DRM_FORMAT_VYUY
:
343 case DRM_FORMAT_YUV444
:
344 cfg
|= EXYNOS_MSCTRL_ORDER422_CRYCBY
;
346 case DRM_FORMAT_NV21
:
347 case DRM_FORMAT_NV61
:
348 cfg
|= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB
|
349 EXYNOS_MSCTRL_C_INT_IN_2PLANE
);
351 case DRM_FORMAT_YUV422
:
352 case DRM_FORMAT_YUV420
:
353 case DRM_FORMAT_YVU420
:
354 cfg
|= EXYNOS_MSCTRL_C_INT_IN_3PLANE
;
356 case DRM_FORMAT_NV12
:
357 case DRM_FORMAT_NV16
:
358 cfg
|= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR
|
359 EXYNOS_MSCTRL_C_INT_IN_2PLANE
);
363 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
366 static void fimc_src_set_fmt(struct fimc_context
*ctx
, u32 fmt
, bool tiled
)
370 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
372 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
373 cfg
&= ~EXYNOS_MSCTRL_INFORMAT_RGB
;
376 case DRM_FORMAT_RGB565
:
377 case DRM_FORMAT_RGB888
:
378 case DRM_FORMAT_XRGB8888
:
379 cfg
|= EXYNOS_MSCTRL_INFORMAT_RGB
;
381 case DRM_FORMAT_YUV444
:
382 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR420
;
384 case DRM_FORMAT_YUYV
:
385 case DRM_FORMAT_YVYU
:
386 case DRM_FORMAT_UYVY
:
387 case DRM_FORMAT_VYUY
:
388 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE
;
390 case DRM_FORMAT_NV16
:
391 case DRM_FORMAT_NV61
:
392 case DRM_FORMAT_YUV422
:
393 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR422
;
395 case DRM_FORMAT_YUV420
:
396 case DRM_FORMAT_YVU420
:
397 case DRM_FORMAT_NV12
:
398 case DRM_FORMAT_NV21
:
399 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR420
;
403 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
405 cfg
= fimc_read(ctx
, EXYNOS_CIDMAPARAM
);
406 cfg
&= ~EXYNOS_CIDMAPARAM_R_MODE_MASK
;
409 cfg
|= EXYNOS_CIDMAPARAM_R_MODE_64X32
;
411 cfg
|= EXYNOS_CIDMAPARAM_R_MODE_LINEAR
;
413 fimc_write(ctx
, cfg
, EXYNOS_CIDMAPARAM
);
415 fimc_src_set_fmt_order(ctx
, fmt
);
418 static void fimc_src_set_transf(struct fimc_context
*ctx
, unsigned int rotation
)
420 unsigned int degree
= rotation
& DRM_MODE_ROTATE_MASK
;
423 DRM_DEV_DEBUG_KMS(ctx
->dev
, "rotation[%x]\n", rotation
);
425 cfg1
= fimc_read(ctx
, EXYNOS_MSCTRL
);
426 cfg1
&= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR
|
427 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
429 cfg2
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
430 cfg2
&= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
433 case DRM_MODE_ROTATE_0
:
434 if (rotation
& DRM_MODE_REFLECT_X
)
435 cfg1
|= EXYNOS_MSCTRL_FLIP_X_MIRROR
;
436 if (rotation
& DRM_MODE_REFLECT_Y
)
437 cfg1
|= EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
439 case DRM_MODE_ROTATE_90
:
440 cfg2
|= EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
441 if (rotation
& DRM_MODE_REFLECT_X
)
442 cfg1
|= EXYNOS_MSCTRL_FLIP_X_MIRROR
;
443 if (rotation
& DRM_MODE_REFLECT_Y
)
444 cfg1
|= EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
446 case DRM_MODE_ROTATE_180
:
447 cfg1
|= (EXYNOS_MSCTRL_FLIP_X_MIRROR
|
448 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
449 if (rotation
& DRM_MODE_REFLECT_X
)
450 cfg1
&= ~EXYNOS_MSCTRL_FLIP_X_MIRROR
;
451 if (rotation
& DRM_MODE_REFLECT_Y
)
452 cfg1
&= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
454 case DRM_MODE_ROTATE_270
:
455 cfg1
|= (EXYNOS_MSCTRL_FLIP_X_MIRROR
|
456 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
457 cfg2
|= EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
458 if (rotation
& DRM_MODE_REFLECT_X
)
459 cfg1
&= ~EXYNOS_MSCTRL_FLIP_X_MIRROR
;
460 if (rotation
& DRM_MODE_REFLECT_Y
)
461 cfg1
&= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
465 fimc_write(ctx
, cfg1
, EXYNOS_MSCTRL
);
466 fimc_write(ctx
, cfg2
, EXYNOS_CITRGFMT
);
469 static void fimc_set_window(struct fimc_context
*ctx
,
470 struct exynos_drm_ipp_buffer
*buf
)
472 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
473 u32 cfg
, h1
, h2
, v1
, v2
;
477 h2
= real_width
- buf
->rect
.w
- buf
->rect
.x
;
479 v2
= buf
->buf
.height
- buf
->rect
.h
- buf
->rect
.y
;
481 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
482 buf
->rect
.x
, buf
->rect
.y
, buf
->rect
.w
, buf
->rect
.h
,
483 real_width
, buf
->buf
.height
);
484 DRM_DEV_DEBUG_KMS(ctx
->dev
, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1
, h2
, v1
,
488 * set window offset 1, 2 size
489 * check figure 43-21 in user manual
491 cfg
= fimc_read(ctx
, EXYNOS_CIWDOFST
);
492 cfg
&= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK
|
493 EXYNOS_CIWDOFST_WINVEROFST_MASK
);
494 cfg
|= (EXYNOS_CIWDOFST_WINHOROFST(h1
) |
495 EXYNOS_CIWDOFST_WINVEROFST(v1
));
496 cfg
|= EXYNOS_CIWDOFST_WINOFSEN
;
497 fimc_write(ctx
, cfg
, EXYNOS_CIWDOFST
);
499 cfg
= (EXYNOS_CIWDOFST2_WINHOROFST2(h2
) |
500 EXYNOS_CIWDOFST2_WINVEROFST2(v2
));
501 fimc_write(ctx
, cfg
, EXYNOS_CIWDOFST2
);
504 static void fimc_src_set_size(struct fimc_context
*ctx
,
505 struct exynos_drm_ipp_buffer
*buf
)
507 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
510 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hsize[%d]vsize[%d]\n", real_width
,
514 cfg
= (EXYNOS_ORGISIZE_HORIZONTAL(real_width
) |
515 EXYNOS_ORGISIZE_VERTICAL(buf
->buf
.height
));
517 fimc_write(ctx
, cfg
, EXYNOS_ORGISIZE
);
519 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]\n", buf
->rect
.x
,
520 buf
->rect
.y
, buf
->rect
.w
, buf
->rect
.h
);
522 /* set input DMA image size */
523 cfg
= fimc_read(ctx
, EXYNOS_CIREAL_ISIZE
);
524 cfg
&= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK
|
525 EXYNOS_CIREAL_ISIZE_WIDTH_MASK
);
526 cfg
|= (EXYNOS_CIREAL_ISIZE_WIDTH(buf
->rect
.w
) |
527 EXYNOS_CIREAL_ISIZE_HEIGHT(buf
->rect
.h
));
528 fimc_write(ctx
, cfg
, EXYNOS_CIREAL_ISIZE
);
531 * set input FIFO image size
532 * for now, we support only ITU601 8 bit mode
534 cfg
= (EXYNOS_CISRCFMT_ITU601_8BIT
|
535 EXYNOS_CISRCFMT_SOURCEHSIZE(real_width
) |
536 EXYNOS_CISRCFMT_SOURCEVSIZE(buf
->buf
.height
));
537 fimc_write(ctx
, cfg
, EXYNOS_CISRCFMT
);
539 /* offset Y(RGB), Cb, Cr */
540 cfg
= (EXYNOS_CIIYOFF_HORIZONTAL(buf
->rect
.x
) |
541 EXYNOS_CIIYOFF_VERTICAL(buf
->rect
.y
));
542 fimc_write(ctx
, cfg
, EXYNOS_CIIYOFF
);
543 cfg
= (EXYNOS_CIICBOFF_HORIZONTAL(buf
->rect
.x
) |
544 EXYNOS_CIICBOFF_VERTICAL(buf
->rect
.y
));
545 fimc_write(ctx
, cfg
, EXYNOS_CIICBOFF
);
546 cfg
= (EXYNOS_CIICROFF_HORIZONTAL(buf
->rect
.x
) |
547 EXYNOS_CIICROFF_VERTICAL(buf
->rect
.y
));
548 fimc_write(ctx
, cfg
, EXYNOS_CIICROFF
);
550 fimc_set_window(ctx
, buf
);
553 static void fimc_src_set_addr(struct fimc_context
*ctx
,
554 struct exynos_drm_ipp_buffer
*buf
)
556 fimc_write(ctx
, buf
->dma_addr
[0], EXYNOS_CIIYSA(0));
557 fimc_write(ctx
, buf
->dma_addr
[1], EXYNOS_CIICBSA(0));
558 fimc_write(ctx
, buf
->dma_addr
[2], EXYNOS_CIICRSA(0));
561 static void fimc_dst_set_fmt_order(struct fimc_context
*ctx
, u32 fmt
)
565 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
568 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
569 cfg
&= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK
;
572 case DRM_FORMAT_RGB565
:
573 cfg
|= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565
;
574 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
576 case DRM_FORMAT_RGB888
:
577 cfg
|= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888
;
578 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
580 case DRM_FORMAT_XRGB8888
:
581 cfg
|= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888
|
582 EXYNOS_CISCCTRL_EXTRGB_EXTENSION
);
583 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
591 cfg
= fimc_read(ctx
, EXYNOS_CIOCTRL
);
592 cfg
&= ~(EXYNOS_CIOCTRL_ORDER2P_MASK
|
593 EXYNOS_CIOCTRL_ORDER422_MASK
|
594 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK
);
597 case DRM_FORMAT_XRGB8888
:
598 cfg
|= EXYNOS_CIOCTRL_ALPHA_OUT
;
600 case DRM_FORMAT_YUYV
:
601 cfg
|= EXYNOS_CIOCTRL_ORDER422_YCBYCR
;
603 case DRM_FORMAT_YVYU
:
604 cfg
|= EXYNOS_CIOCTRL_ORDER422_YCRYCB
;
606 case DRM_FORMAT_UYVY
:
607 cfg
|= EXYNOS_CIOCTRL_ORDER422_CBYCRY
;
609 case DRM_FORMAT_VYUY
:
610 cfg
|= EXYNOS_CIOCTRL_ORDER422_CRYCBY
;
612 case DRM_FORMAT_NV21
:
613 case DRM_FORMAT_NV61
:
614 cfg
|= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB
;
615 cfg
|= EXYNOS_CIOCTRL_YCBCR_2PLANE
;
617 case DRM_FORMAT_YUV422
:
618 case DRM_FORMAT_YUV420
:
619 case DRM_FORMAT_YVU420
:
620 cfg
|= EXYNOS_CIOCTRL_YCBCR_3PLANE
;
622 case DRM_FORMAT_NV12
:
623 case DRM_FORMAT_NV16
:
624 cfg
|= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR
;
625 cfg
|= EXYNOS_CIOCTRL_YCBCR_2PLANE
;
629 fimc_write(ctx
, cfg
, EXYNOS_CIOCTRL
);
632 static void fimc_dst_set_fmt(struct fimc_context
*ctx
, u32 fmt
, bool tiled
)
636 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
638 cfg
= fimc_read(ctx
, EXYNOS_CIEXTEN
);
640 if (fmt
== DRM_FORMAT_AYUV
) {
641 cfg
|= EXYNOS_CIEXTEN_YUV444_OUT
;
642 fimc_write(ctx
, cfg
, EXYNOS_CIEXTEN
);
644 cfg
&= ~EXYNOS_CIEXTEN_YUV444_OUT
;
645 fimc_write(ctx
, cfg
, EXYNOS_CIEXTEN
);
647 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
648 cfg
&= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK
;
651 case DRM_FORMAT_RGB565
:
652 case DRM_FORMAT_RGB888
:
653 case DRM_FORMAT_XRGB8888
:
654 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_RGB
;
656 case DRM_FORMAT_YUYV
:
657 case DRM_FORMAT_YVYU
:
658 case DRM_FORMAT_UYVY
:
659 case DRM_FORMAT_VYUY
:
660 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE
;
662 case DRM_FORMAT_NV16
:
663 case DRM_FORMAT_NV61
:
664 case DRM_FORMAT_YUV422
:
665 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422
;
667 case DRM_FORMAT_YUV420
:
668 case DRM_FORMAT_YVU420
:
669 case DRM_FORMAT_NV12
:
670 case DRM_FORMAT_NV21
:
671 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420
;
675 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
678 cfg
= fimc_read(ctx
, EXYNOS_CIDMAPARAM
);
679 cfg
&= ~EXYNOS_CIDMAPARAM_W_MODE_MASK
;
682 cfg
|= EXYNOS_CIDMAPARAM_W_MODE_64X32
;
684 cfg
|= EXYNOS_CIDMAPARAM_W_MODE_LINEAR
;
686 fimc_write(ctx
, cfg
, EXYNOS_CIDMAPARAM
);
688 fimc_dst_set_fmt_order(ctx
, fmt
);
691 static void fimc_dst_set_transf(struct fimc_context
*ctx
, unsigned int rotation
)
693 unsigned int degree
= rotation
& DRM_MODE_ROTATE_MASK
;
696 DRM_DEV_DEBUG_KMS(ctx
->dev
, "rotation[0x%x]\n", rotation
);
698 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
699 cfg
&= ~EXYNOS_CITRGFMT_FLIP_MASK
;
700 cfg
&= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
;
703 case DRM_MODE_ROTATE_0
:
704 if (rotation
& DRM_MODE_REFLECT_X
)
705 cfg
|= EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
706 if (rotation
& DRM_MODE_REFLECT_Y
)
707 cfg
|= EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
709 case DRM_MODE_ROTATE_90
:
710 cfg
|= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
;
711 if (rotation
& DRM_MODE_REFLECT_X
)
712 cfg
|= EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
713 if (rotation
& DRM_MODE_REFLECT_Y
)
714 cfg
|= EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
716 case DRM_MODE_ROTATE_180
:
717 cfg
|= (EXYNOS_CITRGFMT_FLIP_X_MIRROR
|
718 EXYNOS_CITRGFMT_FLIP_Y_MIRROR
);
719 if (rotation
& DRM_MODE_REFLECT_X
)
720 cfg
&= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
721 if (rotation
& DRM_MODE_REFLECT_Y
)
722 cfg
&= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
724 case DRM_MODE_ROTATE_270
:
725 cfg
|= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
|
726 EXYNOS_CITRGFMT_FLIP_X_MIRROR
|
727 EXYNOS_CITRGFMT_FLIP_Y_MIRROR
);
728 if (rotation
& DRM_MODE_REFLECT_X
)
729 cfg
&= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
730 if (rotation
& DRM_MODE_REFLECT_Y
)
731 cfg
&= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
735 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
738 static int fimc_set_prescaler(struct fimc_context
*ctx
, struct fimc_scaler
*sc
,
739 struct drm_exynos_ipp_task_rect
*src
,
740 struct drm_exynos_ipp_task_rect
*dst
)
742 u32 cfg
, cfg_ext
, shfactor
;
743 u32 pre_dst_width
, pre_dst_height
;
744 u32 hfactor
, vfactor
;
746 u32 src_w
, src_h
, dst_w
, dst_h
;
748 cfg_ext
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
749 if (cfg_ext
& EXYNOS_CITRGFMT_INROT90_CLOCKWISE
) {
757 if (cfg_ext
& EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
) {
765 /* fimc_ippdrv_check_property assures that dividers are not null */
766 hfactor
= fls(src_w
/ dst_w
/ 2);
767 if (hfactor
> FIMC_SHFACTOR
/ 2) {
768 dev_err(ctx
->dev
, "failed to get ratio horizontal.\n");
772 vfactor
= fls(src_h
/ dst_h
/ 2);
773 if (vfactor
> FIMC_SHFACTOR
/ 2) {
774 dev_err(ctx
->dev
, "failed to get ratio vertical.\n");
778 pre_dst_width
= src_w
>> hfactor
;
779 pre_dst_height
= src_h
>> vfactor
;
780 DRM_DEV_DEBUG_KMS(ctx
->dev
, "pre_dst_width[%d]pre_dst_height[%d]\n",
781 pre_dst_width
, pre_dst_height
);
782 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hfactor[%d]vfactor[%d]\n", hfactor
,
785 sc
->hratio
= (src_w
<< 14) / (dst_w
<< hfactor
);
786 sc
->vratio
= (src_h
<< 14) / (dst_h
<< vfactor
);
787 sc
->up_h
= (dst_w
>= src_w
) ? true : false;
788 sc
->up_v
= (dst_h
>= src_h
) ? true : false;
789 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
790 sc
->hratio
, sc
->vratio
, sc
->up_h
, sc
->up_v
);
792 shfactor
= FIMC_SHFACTOR
- (hfactor
+ vfactor
);
793 DRM_DEV_DEBUG_KMS(ctx
->dev
, "shfactor[%d]\n", shfactor
);
795 cfg
= (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor
) |
796 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor
) |
797 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor
));
798 fimc_write(ctx
, cfg
, EXYNOS_CISCPRERATIO
);
800 cfg
= (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width
) |
801 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height
));
802 fimc_write(ctx
, cfg
, EXYNOS_CISCPREDST
);
807 static void fimc_set_scaler(struct fimc_context
*ctx
, struct fimc_scaler
*sc
)
811 DRM_DEV_DEBUG_KMS(ctx
->dev
, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
812 sc
->range
, sc
->bypass
, sc
->up_h
, sc
->up_v
);
813 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hratio[%d]vratio[%d]\n",
814 sc
->hratio
, sc
->vratio
);
816 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
817 cfg
&= ~(EXYNOS_CISCCTRL_SCALERBYPASS
|
818 EXYNOS_CISCCTRL_SCALEUP_H
| EXYNOS_CISCCTRL_SCALEUP_V
|
819 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK
|
820 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK
|
821 EXYNOS_CISCCTRL_CSCR2Y_WIDE
|
822 EXYNOS_CISCCTRL_CSCY2R_WIDE
);
825 cfg
|= (EXYNOS_CISCCTRL_CSCR2Y_WIDE
|
826 EXYNOS_CISCCTRL_CSCY2R_WIDE
);
828 cfg
|= EXYNOS_CISCCTRL_SCALERBYPASS
;
830 cfg
|= EXYNOS_CISCCTRL_SCALEUP_H
;
832 cfg
|= EXYNOS_CISCCTRL_SCALEUP_V
;
834 cfg
|= (EXYNOS_CISCCTRL_MAINHORRATIO((sc
->hratio
>> 6)) |
835 EXYNOS_CISCCTRL_MAINVERRATIO((sc
->vratio
>> 6)));
836 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
838 cfg_ext
= fimc_read(ctx
, EXYNOS_CIEXTEN
);
839 cfg_ext
&= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK
;
840 cfg_ext
&= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK
;
841 cfg_ext
|= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc
->hratio
) |
842 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc
->vratio
));
843 fimc_write(ctx
, cfg_ext
, EXYNOS_CIEXTEN
);
846 static void fimc_dst_set_size(struct fimc_context
*ctx
,
847 struct exynos_drm_ipp_buffer
*buf
)
849 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
852 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hsize[%d]vsize[%d]\n", real_width
,
856 cfg
= (EXYNOS_ORGOSIZE_HORIZONTAL(real_width
) |
857 EXYNOS_ORGOSIZE_VERTICAL(buf
->buf
.height
));
859 fimc_write(ctx
, cfg
, EXYNOS_ORGOSIZE
);
861 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]\n", buf
->rect
.x
,
863 buf
->rect
.w
, buf
->rect
.h
);
866 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
867 cfg
&= ~EXYNOS_CIGCTRL_CSC_MASK
;
869 if (buf
->buf
.width
>= FIMC_WIDTH_ITU_709
)
870 cfg
|= EXYNOS_CIGCTRL_CSC_ITU709
;
872 cfg
|= EXYNOS_CIGCTRL_CSC_ITU601
;
874 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
876 cfg_ext
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
878 /* target image size */
879 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
880 cfg
&= ~(EXYNOS_CITRGFMT_TARGETH_MASK
|
881 EXYNOS_CITRGFMT_TARGETV_MASK
);
882 if (cfg_ext
& EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
)
883 cfg
|= (EXYNOS_CITRGFMT_TARGETHSIZE(buf
->rect
.h
) |
884 EXYNOS_CITRGFMT_TARGETVSIZE(buf
->rect
.w
));
886 cfg
|= (EXYNOS_CITRGFMT_TARGETHSIZE(buf
->rect
.w
) |
887 EXYNOS_CITRGFMT_TARGETVSIZE(buf
->rect
.h
));
888 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
891 cfg
= EXYNOS_CITAREA_TARGET_AREA(buf
->rect
.w
* buf
->rect
.h
);
892 fimc_write(ctx
, cfg
, EXYNOS_CITAREA
);
894 /* offset Y(RGB), Cb, Cr */
895 cfg
= (EXYNOS_CIOYOFF_HORIZONTAL(buf
->rect
.x
) |
896 EXYNOS_CIOYOFF_VERTICAL(buf
->rect
.y
));
897 fimc_write(ctx
, cfg
, EXYNOS_CIOYOFF
);
898 cfg
= (EXYNOS_CIOCBOFF_HORIZONTAL(buf
->rect
.x
) |
899 EXYNOS_CIOCBOFF_VERTICAL(buf
->rect
.y
));
900 fimc_write(ctx
, cfg
, EXYNOS_CIOCBOFF
);
901 cfg
= (EXYNOS_CIOCROFF_HORIZONTAL(buf
->rect
.x
) |
902 EXYNOS_CIOCROFF_VERTICAL(buf
->rect
.y
));
903 fimc_write(ctx
, cfg
, EXYNOS_CIOCROFF
);
906 static void fimc_dst_set_buf_seq(struct fimc_context
*ctx
, u32 buf_id
,
913 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]enqueu[%d]\n", buf_id
, enqueue
);
915 spin_lock_irqsave(&ctx
->lock
, flags
);
917 cfg
= fimc_read(ctx
, EXYNOS_CIFCNTSEQ
);
920 cfg
|= (1 << buf_id
);
922 cfg
&= ~(1 << buf_id
);
924 fimc_write(ctx
, cfg
, EXYNOS_CIFCNTSEQ
);
926 buf_num
= hweight32(cfg
);
928 if (enqueue
&& buf_num
>= FIMC_BUF_START
)
929 fimc_mask_irq(ctx
, true);
930 else if (!enqueue
&& buf_num
<= FIMC_BUF_STOP
)
931 fimc_mask_irq(ctx
, false);
933 spin_unlock_irqrestore(&ctx
->lock
, flags
);
936 static void fimc_dst_set_addr(struct fimc_context
*ctx
,
937 struct exynos_drm_ipp_buffer
*buf
)
939 fimc_write(ctx
, buf
->dma_addr
[0], EXYNOS_CIOYSA(0));
940 fimc_write(ctx
, buf
->dma_addr
[1], EXYNOS_CIOCBSA(0));
941 fimc_write(ctx
, buf
->dma_addr
[2], EXYNOS_CIOCRSA(0));
943 fimc_dst_set_buf_seq(ctx
, 0, true);
946 static void fimc_stop(struct fimc_context
*ctx
);
948 static irqreturn_t
fimc_irq_handler(int irq
, void *dev_id
)
950 struct fimc_context
*ctx
= dev_id
;
953 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fimc id[%d]\n", ctx
->id
);
956 if (fimc_check_ovf(ctx
))
959 if (!fimc_check_frame_end(ctx
))
962 buf_id
= fimc_get_buf_id(ctx
);
966 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]\n", buf_id
);
969 struct exynos_drm_ipp_task
*task
= ctx
->task
;
972 pm_runtime_mark_last_busy(ctx
->dev
);
973 pm_runtime_put_autosuspend(ctx
->dev
);
974 exynos_drm_ipp_task_done(task
, 0);
977 fimc_dst_set_buf_seq(ctx
, buf_id
, false);
983 static void fimc_clear_addr(struct fimc_context
*ctx
)
987 for (i
= 0; i
< FIMC_MAX_SRC
; i
++) {
988 fimc_write(ctx
, 0, EXYNOS_CIIYSA(i
));
989 fimc_write(ctx
, 0, EXYNOS_CIICBSA(i
));
990 fimc_write(ctx
, 0, EXYNOS_CIICRSA(i
));
993 for (i
= 0; i
< FIMC_MAX_DST
; i
++) {
994 fimc_write(ctx
, 0, EXYNOS_CIOYSA(i
));
995 fimc_write(ctx
, 0, EXYNOS_CIOCBSA(i
));
996 fimc_write(ctx
, 0, EXYNOS_CIOCRSA(i
));
1000 static void fimc_reset(struct fimc_context
*ctx
)
1002 /* reset h/w block */
1005 /* reset scaler capability */
1006 memset(&ctx
->sc
, 0x0, sizeof(ctx
->sc
));
1008 fimc_clear_addr(ctx
);
1011 static void fimc_start(struct fimc_context
*ctx
)
1015 fimc_mask_irq(ctx
, true);
1017 /* If set true, we can save jpeg about screen */
1018 fimc_handle_jpeg(ctx
, false);
1019 fimc_set_scaler(ctx
, &ctx
->sc
);
1021 fimc_set_type_ctrl(ctx
);
1022 fimc_handle_lastend(ctx
, false);
1025 cfg0
= fimc_read(ctx
, EXYNOS_MSCTRL
);
1026 cfg0
&= ~EXYNOS_MSCTRL_INPUT_MASK
;
1027 cfg0
|= EXYNOS_MSCTRL_INPUT_MEMORY
;
1028 fimc_write(ctx
, cfg0
, EXYNOS_MSCTRL
);
1031 fimc_write(ctx
, 0x0, EXYNOS_CISTATUS
);
1033 cfg0
= fimc_read(ctx
, EXYNOS_CIIMGCPT
);
1034 cfg0
&= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC
;
1035 cfg0
|= EXYNOS_CIIMGCPT_IMGCPTEN_SC
;
1038 cfg1
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
1039 cfg1
&= ~EXYNOS_CISCCTRL_SCAN_MASK
;
1040 cfg1
|= (EXYNOS_CISCCTRL_PROGRESSIVE
|
1041 EXYNOS_CISCCTRL_SCALERSTART
);
1043 fimc_write(ctx
, cfg1
, EXYNOS_CISCCTRL
);
1045 /* Enable image capture*/
1046 cfg0
|= EXYNOS_CIIMGCPT_IMGCPTEN
;
1047 fimc_write(ctx
, cfg0
, EXYNOS_CIIMGCPT
);
1049 /* Disable frame end irq */
1050 fimc_clear_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_END_DISABLE
);
1052 fimc_clear_bits(ctx
, EXYNOS_CIOCTRL
, EXYNOS_CIOCTRL_WEAVE_MASK
);
1054 fimc_set_bits(ctx
, EXYNOS_MSCTRL
, EXYNOS_MSCTRL_ENVID
);
1057 static void fimc_stop(struct fimc_context
*ctx
)
1062 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
1063 cfg
&= ~EXYNOS_MSCTRL_INPUT_MASK
;
1064 cfg
&= ~EXYNOS_MSCTRL_ENVID
;
1065 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
1067 fimc_mask_irq(ctx
, false);
1069 /* reset sequence */
1070 fimc_write(ctx
, 0x0, EXYNOS_CIFCNTSEQ
);
1072 /* Scaler disable */
1073 fimc_clear_bits(ctx
, EXYNOS_CISCCTRL
, EXYNOS_CISCCTRL_SCALERSTART
);
1075 /* Disable image capture */
1076 fimc_clear_bits(ctx
, EXYNOS_CIIMGCPT
,
1077 EXYNOS_CIIMGCPT_IMGCPTEN_SC
| EXYNOS_CIIMGCPT_IMGCPTEN
);
1079 /* Enable frame end irq */
1080 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_END_DISABLE
);
1083 static int fimc_commit(struct exynos_drm_ipp
*ipp
,
1084 struct exynos_drm_ipp_task
*task
)
1086 struct fimc_context
*ctx
=
1087 container_of(ipp
, struct fimc_context
, ipp
);
1089 pm_runtime_get_sync(ctx
->dev
);
1092 fimc_src_set_fmt(ctx
, task
->src
.buf
.fourcc
, task
->src
.buf
.modifier
);
1093 fimc_src_set_size(ctx
, &task
->src
);
1094 fimc_src_set_transf(ctx
, DRM_MODE_ROTATE_0
);
1095 fimc_src_set_addr(ctx
, &task
->src
);
1096 fimc_dst_set_fmt(ctx
, task
->dst
.buf
.fourcc
, task
->dst
.buf
.modifier
);
1097 fimc_dst_set_transf(ctx
, task
->transform
.rotation
);
1098 fimc_dst_set_size(ctx
, &task
->dst
);
1099 fimc_dst_set_addr(ctx
, &task
->dst
);
1100 fimc_set_prescaler(ctx
, &ctx
->sc
, &task
->src
.rect
, &task
->dst
.rect
);
1106 static void fimc_abort(struct exynos_drm_ipp
*ipp
,
1107 struct exynos_drm_ipp_task
*task
)
1109 struct fimc_context
*ctx
=
1110 container_of(ipp
, struct fimc_context
, ipp
);
1115 struct exynos_drm_ipp_task
*task
= ctx
->task
;
1118 pm_runtime_mark_last_busy(ctx
->dev
);
1119 pm_runtime_put_autosuspend(ctx
->dev
);
1120 exynos_drm_ipp_task_done(task
, -EIO
);
1124 static struct exynos_drm_ipp_funcs ipp_funcs
= {
1125 .commit
= fimc_commit
,
1126 .abort
= fimc_abort
,
1129 static int fimc_bind(struct device
*dev
, struct device
*master
, void *data
)
1131 struct fimc_context
*ctx
= dev_get_drvdata(dev
);
1132 struct drm_device
*drm_dev
= data
;
1133 struct exynos_drm_ipp
*ipp
= &ctx
->ipp
;
1135 ctx
->drm_dev
= drm_dev
;
1136 ipp
->drm_dev
= drm_dev
;
1137 exynos_drm_register_dma(drm_dev
, dev
, &ctx
->dma_priv
);
1139 exynos_drm_ipp_register(dev
, ipp
, &ipp_funcs
,
1140 DRM_EXYNOS_IPP_CAP_CROP
| DRM_EXYNOS_IPP_CAP_ROTATE
|
1141 DRM_EXYNOS_IPP_CAP_SCALE
| DRM_EXYNOS_IPP_CAP_CONVERT
,
1142 ctx
->formats
, ctx
->num_formats
, "fimc");
1144 dev_info(dev
, "The exynos fimc has been probed successfully\n");
1149 static void fimc_unbind(struct device
*dev
, struct device
*master
,
1152 struct fimc_context
*ctx
= dev_get_drvdata(dev
);
1153 struct drm_device
*drm_dev
= data
;
1154 struct exynos_drm_ipp
*ipp
= &ctx
->ipp
;
1156 exynos_drm_ipp_unregister(dev
, ipp
);
1157 exynos_drm_unregister_dma(drm_dev
, dev
, &ctx
->dma_priv
);
1160 static const struct component_ops fimc_component_ops
= {
1162 .unbind
= fimc_unbind
,
1165 static void fimc_put_clocks(struct fimc_context
*ctx
)
1169 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++) {
1170 if (IS_ERR(ctx
->clocks
[i
]))
1172 clk_put(ctx
->clocks
[i
]);
1173 ctx
->clocks
[i
] = ERR_PTR(-EINVAL
);
1177 static int fimc_setup_clocks(struct fimc_context
*ctx
)
1179 struct device
*fimc_dev
= ctx
->dev
;
1183 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++)
1184 ctx
->clocks
[i
] = ERR_PTR(-EINVAL
);
1186 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++) {
1187 if (i
== FIMC_CLK_WB_A
|| i
== FIMC_CLK_WB_B
)
1188 dev
= fimc_dev
->parent
;
1192 ctx
->clocks
[i
] = clk_get(dev
, fimc_clock_names
[i
]);
1193 if (IS_ERR(ctx
->clocks
[i
])) {
1194 ret
= PTR_ERR(ctx
->clocks
[i
]);
1195 dev_err(fimc_dev
, "failed to get clock: %s\n",
1196 fimc_clock_names
[i
]);
1201 ret
= clk_prepare_enable(ctx
->clocks
[FIMC_CLK_LCLK
]);
1205 fimc_put_clocks(ctx
);
1209 int exynos_drm_check_fimc_device(struct device
*dev
)
1211 int id
= of_alias_get_id(dev
->of_node
, "fimc");
1213 if (id
>= 0 && (BIT(id
) & fimc_mask
))
1218 static const unsigned int fimc_formats
[] = {
1219 DRM_FORMAT_XRGB8888
, DRM_FORMAT_RGB565
,
1220 DRM_FORMAT_NV12
, DRM_FORMAT_NV16
, DRM_FORMAT_NV21
, DRM_FORMAT_NV61
,
1221 DRM_FORMAT_UYVY
, DRM_FORMAT_VYUY
, DRM_FORMAT_YUYV
, DRM_FORMAT_YVYU
,
1222 DRM_FORMAT_YUV420
, DRM_FORMAT_YVU420
, DRM_FORMAT_YUV422
,
1226 static const unsigned int fimc_tiled_formats
[] = {
1227 DRM_FORMAT_NV12
, DRM_FORMAT_NV21
,
1230 static const struct drm_exynos_ipp_limit fimc_4210_limits_v1
[] = {
1231 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 16, 8192, 8 }, .v
= { 16, 8192, 2 }) },
1232 { IPP_SIZE_LIMIT(AREA
, .h
= { 16, 4224, 2 }, .v
= { 16, 0, 2 }) },
1233 { IPP_SIZE_LIMIT(ROTATED
, .h
= { 128, 1920 }, .v
= { 128, 0 }) },
1234 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1235 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1238 static const struct drm_exynos_ipp_limit fimc_4210_limits_v2
[] = {
1239 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 16, 8192, 8 }, .v
= { 16, 8192, 2 }) },
1240 { IPP_SIZE_LIMIT(AREA
, .h
= { 16, 1920, 2 }, .v
= { 16, 0, 2 }) },
1241 { IPP_SIZE_LIMIT(ROTATED
, .h
= { 128, 1366 }, .v
= { 128, 0 }) },
1242 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1243 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1246 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v1
[] = {
1247 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 128, 1920, 128 }, .v
= { 32, 1920, 32 }) },
1248 { IPP_SIZE_LIMIT(AREA
, .h
= { 128, 1920, 2 }, .v
= { 128, 0, 2 }) },
1249 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1250 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1253 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2
[] = {
1254 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 128, 1920, 128 }, .v
= { 32, 1920, 32 }) },
1255 { IPP_SIZE_LIMIT(AREA
, .h
= { 128, 1366, 2 }, .v
= { 128, 0, 2 }) },
1256 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1257 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1260 static int fimc_probe(struct platform_device
*pdev
)
1262 const struct drm_exynos_ipp_limit
*limits
;
1263 struct exynos_drm_ipp_formats
*formats
;
1264 struct device
*dev
= &pdev
->dev
;
1265 struct fimc_context
*ctx
;
1266 struct resource
*res
;
1268 int i
, j
, num_limits
, num_formats
;
1270 if (exynos_drm_check_fimc_device(dev
) != 0)
1273 ctx
= devm_kzalloc(dev
, sizeof(*ctx
), GFP_KERNEL
);
1278 ctx
->id
= of_alias_get_id(dev
->of_node
, "fimc");
1280 /* construct formats/limits array */
1281 num_formats
= ARRAY_SIZE(fimc_formats
) + ARRAY_SIZE(fimc_tiled_formats
);
1282 formats
= devm_kcalloc(dev
, num_formats
, sizeof(*formats
),
1287 /* linear formats */
1289 limits
= fimc_4210_limits_v1
;
1290 num_limits
= ARRAY_SIZE(fimc_4210_limits_v1
);
1292 limits
= fimc_4210_limits_v2
;
1293 num_limits
= ARRAY_SIZE(fimc_4210_limits_v2
);
1295 for (i
= 0; i
< ARRAY_SIZE(fimc_formats
); i
++) {
1296 formats
[i
].fourcc
= fimc_formats
[i
];
1297 formats
[i
].type
= DRM_EXYNOS_IPP_FORMAT_SOURCE
|
1298 DRM_EXYNOS_IPP_FORMAT_DESTINATION
;
1299 formats
[i
].limits
= limits
;
1300 formats
[i
].num_limits
= num_limits
;
1305 limits
= fimc_4210_limits_tiled_v1
;
1306 num_limits
= ARRAY_SIZE(fimc_4210_limits_tiled_v1
);
1308 limits
= fimc_4210_limits_tiled_v2
;
1309 num_limits
= ARRAY_SIZE(fimc_4210_limits_tiled_v2
);
1311 for (j
= i
, i
= 0; i
< ARRAY_SIZE(fimc_tiled_formats
); j
++, i
++) {
1312 formats
[j
].fourcc
= fimc_tiled_formats
[i
];
1313 formats
[j
].modifier
= DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
;
1314 formats
[j
].type
= DRM_EXYNOS_IPP_FORMAT_SOURCE
|
1315 DRM_EXYNOS_IPP_FORMAT_DESTINATION
;
1316 formats
[j
].limits
= limits
;
1317 formats
[j
].num_limits
= num_limits
;
1320 ctx
->formats
= formats
;
1321 ctx
->num_formats
= num_formats
;
1323 /* resource memory */
1324 ctx
->regs_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1325 ctx
->regs
= devm_ioremap_resource(dev
, ctx
->regs_res
);
1326 if (IS_ERR(ctx
->regs
))
1327 return PTR_ERR(ctx
->regs
);
1330 res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
1332 dev_err(dev
, "failed to request irq resource.\n");
1336 ret
= devm_request_irq(dev
, res
->start
, fimc_irq_handler
,
1337 0, dev_name(dev
), ctx
);
1339 dev_err(dev
, "failed to request irq.\n");
1343 ret
= fimc_setup_clocks(ctx
);
1347 spin_lock_init(&ctx
->lock
);
1348 platform_set_drvdata(pdev
, ctx
);
1350 pm_runtime_use_autosuspend(dev
);
1351 pm_runtime_set_autosuspend_delay(dev
, FIMC_AUTOSUSPEND_DELAY
);
1352 pm_runtime_enable(dev
);
1354 ret
= component_add(dev
, &fimc_component_ops
);
1358 dev_info(dev
, "drm fimc registered successfully.\n");
1363 pm_runtime_dont_use_autosuspend(dev
);
1364 pm_runtime_disable(dev
);
1365 fimc_put_clocks(ctx
);
1370 static int fimc_remove(struct platform_device
*pdev
)
1372 struct device
*dev
= &pdev
->dev
;
1373 struct fimc_context
*ctx
= get_fimc_context(dev
);
1375 component_del(dev
, &fimc_component_ops
);
1376 pm_runtime_dont_use_autosuspend(dev
);
1377 pm_runtime_disable(dev
);
1379 fimc_put_clocks(ctx
);
1385 static int fimc_runtime_suspend(struct device
*dev
)
1387 struct fimc_context
*ctx
= get_fimc_context(dev
);
1389 DRM_DEV_DEBUG_KMS(dev
, "id[%d]\n", ctx
->id
);
1390 clk_disable_unprepare(ctx
->clocks
[FIMC_CLK_GATE
]);
1394 static int fimc_runtime_resume(struct device
*dev
)
1396 struct fimc_context
*ctx
= get_fimc_context(dev
);
1398 DRM_DEV_DEBUG_KMS(dev
, "id[%d]\n", ctx
->id
);
1399 return clk_prepare_enable(ctx
->clocks
[FIMC_CLK_GATE
]);
1403 static const struct dev_pm_ops fimc_pm_ops
= {
1404 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
1405 pm_runtime_force_resume
)
1406 SET_RUNTIME_PM_OPS(fimc_runtime_suspend
, fimc_runtime_resume
, NULL
)
1409 static const struct of_device_id fimc_of_match
[] = {
1410 { .compatible
= "samsung,exynos4210-fimc" },
1411 { .compatible
= "samsung,exynos4212-fimc" },
1414 MODULE_DEVICE_TABLE(of
, fimc_of_match
);
1416 struct platform_driver fimc_driver
= {
1417 .probe
= fimc_probe
,
1418 .remove
= fimc_remove
,
1420 .of_match_table
= fimc_of_match
,
1421 .name
= "exynos-drm-fimc",
1422 .owner
= THIS_MODULE
,