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
;
101 struct exynos_drm_ipp_task
*task
;
102 struct exynos_drm_ipp_formats
*formats
;
103 unsigned int num_formats
;
105 struct resource
*regs_res
;
108 struct clk
*clocks
[FIMC_CLKS_MAX
];
109 struct fimc_scaler sc
;
114 static u32
fimc_read(struct fimc_context
*ctx
, u32 reg
)
116 return readl(ctx
->regs
+ reg
);
119 static void fimc_write(struct fimc_context
*ctx
, u32 val
, u32 reg
)
121 writel(val
, ctx
->regs
+ reg
);
124 static void fimc_set_bits(struct fimc_context
*ctx
, u32 reg
, u32 bits
)
126 void __iomem
*r
= ctx
->regs
+ reg
;
128 writel(readl(r
) | bits
, r
);
131 static void fimc_clear_bits(struct fimc_context
*ctx
, u32 reg
, u32 bits
)
133 void __iomem
*r
= ctx
->regs
+ reg
;
135 writel(readl(r
) & ~bits
, r
);
138 static void fimc_sw_reset(struct fimc_context
*ctx
)
142 /* stop dma operation */
143 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS
);
144 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg
))
145 fimc_clear_bits(ctx
, EXYNOS_MSCTRL
, EXYNOS_MSCTRL_ENVID
);
147 fimc_set_bits(ctx
, EXYNOS_CISRCFMT
, EXYNOS_CISRCFMT_ITU601_8BIT
);
149 /* disable image capture */
150 fimc_clear_bits(ctx
, EXYNOS_CIIMGCPT
,
151 EXYNOS_CIIMGCPT_IMGCPTEN_SC
| EXYNOS_CIIMGCPT_IMGCPTEN
);
154 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_SWRST
);
156 /* s/w reset complete */
157 fimc_clear_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_SWRST
);
160 fimc_write(ctx
, 0x0, EXYNOS_CIFCNTSEQ
);
163 static void fimc_set_type_ctrl(struct fimc_context
*ctx
)
167 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
168 cfg
&= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK
|
169 EXYNOS_CIGCTRL_SELCAM_ITU_MASK
|
170 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK
|
171 EXYNOS_CIGCTRL_SELCAM_FIMC_MASK
|
172 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK
|
173 EXYNOS_CIGCTRL_SELWRITEBACK_MASK
);
175 cfg
|= (EXYNOS_CIGCTRL_SELCAM_ITU_A
|
176 EXYNOS_CIGCTRL_SELWRITEBACK_A
|
177 EXYNOS_CIGCTRL_SELCAM_MIPI_A
|
178 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU
);
180 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
183 static void fimc_handle_jpeg(struct fimc_context
*ctx
, bool enable
)
187 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
189 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
191 cfg
|= EXYNOS_CIGCTRL_CAM_JPEG
;
193 cfg
&= ~EXYNOS_CIGCTRL_CAM_JPEG
;
195 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
198 static void fimc_mask_irq(struct fimc_context
*ctx
, bool enable
)
202 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
204 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
206 cfg
&= ~EXYNOS_CIGCTRL_IRQ_OVFEN
;
207 cfg
|= EXYNOS_CIGCTRL_IRQ_ENABLE
| EXYNOS_CIGCTRL_IRQ_LEVEL
;
209 cfg
&= ~EXYNOS_CIGCTRL_IRQ_ENABLE
;
210 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
213 static void fimc_clear_irq(struct fimc_context
*ctx
)
215 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_CLR
);
218 static bool fimc_check_ovf(struct fimc_context
*ctx
)
222 status
= fimc_read(ctx
, EXYNOS_CISTATUS
);
223 flag
= EXYNOS_CISTATUS_OVFIY
| EXYNOS_CISTATUS_OVFICB
|
224 EXYNOS_CISTATUS_OVFICR
;
226 DRM_DEV_DEBUG_KMS(ctx
->dev
, "flag[0x%x]\n", flag
);
229 fimc_set_bits(ctx
, EXYNOS_CIWDOFST
,
230 EXYNOS_CIWDOFST_CLROVFIY
| EXYNOS_CIWDOFST_CLROVFICB
|
231 EXYNOS_CIWDOFST_CLROVFICR
);
233 DRM_DEV_ERROR(ctx
->dev
,
234 "occurred overflow at %d, status 0x%x.\n",
242 static bool fimc_check_frame_end(struct fimc_context
*ctx
)
246 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS
);
248 DRM_DEV_DEBUG_KMS(ctx
->dev
, "cfg[0x%x]\n", cfg
);
250 if (!(cfg
& EXYNOS_CISTATUS_FRAMEEND
))
253 cfg
&= ~(EXYNOS_CISTATUS_FRAMEEND
);
254 fimc_write(ctx
, cfg
, EXYNOS_CISTATUS
);
259 static int fimc_get_buf_id(struct fimc_context
*ctx
)
262 int frame_cnt
, buf_id
;
264 cfg
= fimc_read(ctx
, EXYNOS_CISTATUS2
);
265 frame_cnt
= EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg
);
268 frame_cnt
= EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg
);
270 DRM_DEV_DEBUG_KMS(ctx
->dev
, "present[%d]before[%d]\n",
271 EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg
),
272 EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg
));
274 if (frame_cnt
== 0) {
275 DRM_DEV_ERROR(ctx
->dev
, "failed to get frame count.\n");
279 buf_id
= frame_cnt
- 1;
280 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]\n", buf_id
);
285 static void fimc_handle_lastend(struct fimc_context
*ctx
, bool enable
)
289 DRM_DEV_DEBUG_KMS(ctx
->dev
, "enable[%d]\n", enable
);
291 cfg
= fimc_read(ctx
, EXYNOS_CIOCTRL
);
293 cfg
|= EXYNOS_CIOCTRL_LASTENDEN
;
295 cfg
&= ~EXYNOS_CIOCTRL_LASTENDEN
;
297 fimc_write(ctx
, cfg
, EXYNOS_CIOCTRL
);
300 static void fimc_src_set_fmt_order(struct fimc_context
*ctx
, u32 fmt
)
304 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
307 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
308 cfg
&= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK
;
311 case DRM_FORMAT_RGB565
:
312 cfg
|= EXYNOS_CISCCTRL_INRGB_FMT_RGB565
;
313 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
315 case DRM_FORMAT_RGB888
:
316 case DRM_FORMAT_XRGB8888
:
317 cfg
|= EXYNOS_CISCCTRL_INRGB_FMT_RGB888
;
318 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
326 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
327 cfg
&= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK
|
328 EXYNOS_MSCTRL_C_INT_IN_2PLANE
|
329 EXYNOS_MSCTRL_ORDER422_YCBYCR
);
332 case DRM_FORMAT_YUYV
:
333 cfg
|= EXYNOS_MSCTRL_ORDER422_YCBYCR
;
335 case DRM_FORMAT_YVYU
:
336 cfg
|= EXYNOS_MSCTRL_ORDER422_YCRYCB
;
338 case DRM_FORMAT_UYVY
:
339 cfg
|= EXYNOS_MSCTRL_ORDER422_CBYCRY
;
341 case DRM_FORMAT_VYUY
:
342 case DRM_FORMAT_YUV444
:
343 cfg
|= EXYNOS_MSCTRL_ORDER422_CRYCBY
;
345 case DRM_FORMAT_NV21
:
346 case DRM_FORMAT_NV61
:
347 cfg
|= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB
|
348 EXYNOS_MSCTRL_C_INT_IN_2PLANE
);
350 case DRM_FORMAT_YUV422
:
351 case DRM_FORMAT_YUV420
:
352 case DRM_FORMAT_YVU420
:
353 cfg
|= EXYNOS_MSCTRL_C_INT_IN_3PLANE
;
355 case DRM_FORMAT_NV12
:
356 case DRM_FORMAT_NV16
:
357 cfg
|= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR
|
358 EXYNOS_MSCTRL_C_INT_IN_2PLANE
);
362 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
365 static void fimc_src_set_fmt(struct fimc_context
*ctx
, u32 fmt
, bool tiled
)
369 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
371 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
372 cfg
&= ~EXYNOS_MSCTRL_INFORMAT_RGB
;
375 case DRM_FORMAT_RGB565
:
376 case DRM_FORMAT_RGB888
:
377 case DRM_FORMAT_XRGB8888
:
378 cfg
|= EXYNOS_MSCTRL_INFORMAT_RGB
;
380 case DRM_FORMAT_YUV444
:
381 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR420
;
383 case DRM_FORMAT_YUYV
:
384 case DRM_FORMAT_YVYU
:
385 case DRM_FORMAT_UYVY
:
386 case DRM_FORMAT_VYUY
:
387 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE
;
389 case DRM_FORMAT_NV16
:
390 case DRM_FORMAT_NV61
:
391 case DRM_FORMAT_YUV422
:
392 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR422
;
394 case DRM_FORMAT_YUV420
:
395 case DRM_FORMAT_YVU420
:
396 case DRM_FORMAT_NV12
:
397 case DRM_FORMAT_NV21
:
398 cfg
|= EXYNOS_MSCTRL_INFORMAT_YCBCR420
;
402 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
404 cfg
= fimc_read(ctx
, EXYNOS_CIDMAPARAM
);
405 cfg
&= ~EXYNOS_CIDMAPARAM_R_MODE_MASK
;
408 cfg
|= EXYNOS_CIDMAPARAM_R_MODE_64X32
;
410 cfg
|= EXYNOS_CIDMAPARAM_R_MODE_LINEAR
;
412 fimc_write(ctx
, cfg
, EXYNOS_CIDMAPARAM
);
414 fimc_src_set_fmt_order(ctx
, fmt
);
417 static void fimc_src_set_transf(struct fimc_context
*ctx
, unsigned int rotation
)
419 unsigned int degree
= rotation
& DRM_MODE_ROTATE_MASK
;
422 DRM_DEV_DEBUG_KMS(ctx
->dev
, "rotation[%x]\n", rotation
);
424 cfg1
= fimc_read(ctx
, EXYNOS_MSCTRL
);
425 cfg1
&= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR
|
426 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
428 cfg2
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
429 cfg2
&= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
432 case DRM_MODE_ROTATE_0
:
433 if (rotation
& DRM_MODE_REFLECT_X
)
434 cfg1
|= EXYNOS_MSCTRL_FLIP_X_MIRROR
;
435 if (rotation
& DRM_MODE_REFLECT_Y
)
436 cfg1
|= EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
438 case DRM_MODE_ROTATE_90
:
439 cfg2
|= EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
440 if (rotation
& DRM_MODE_REFLECT_X
)
441 cfg1
|= EXYNOS_MSCTRL_FLIP_X_MIRROR
;
442 if (rotation
& DRM_MODE_REFLECT_Y
)
443 cfg1
|= EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
445 case DRM_MODE_ROTATE_180
:
446 cfg1
|= (EXYNOS_MSCTRL_FLIP_X_MIRROR
|
447 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
448 if (rotation
& DRM_MODE_REFLECT_X
)
449 cfg1
&= ~EXYNOS_MSCTRL_FLIP_X_MIRROR
;
450 if (rotation
& DRM_MODE_REFLECT_Y
)
451 cfg1
&= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
453 case DRM_MODE_ROTATE_270
:
454 cfg1
|= (EXYNOS_MSCTRL_FLIP_X_MIRROR
|
455 EXYNOS_MSCTRL_FLIP_Y_MIRROR
);
456 cfg2
|= EXYNOS_CITRGFMT_INROT90_CLOCKWISE
;
457 if (rotation
& DRM_MODE_REFLECT_X
)
458 cfg1
&= ~EXYNOS_MSCTRL_FLIP_X_MIRROR
;
459 if (rotation
& DRM_MODE_REFLECT_Y
)
460 cfg1
&= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR
;
464 fimc_write(ctx
, cfg1
, EXYNOS_MSCTRL
);
465 fimc_write(ctx
, cfg2
, EXYNOS_CITRGFMT
);
468 static void fimc_set_window(struct fimc_context
*ctx
,
469 struct exynos_drm_ipp_buffer
*buf
)
471 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
472 u32 cfg
, h1
, h2
, v1
, v2
;
476 h2
= real_width
- buf
->rect
.w
- buf
->rect
.x
;
478 v2
= buf
->buf
.height
- buf
->rect
.h
- buf
->rect
.y
;
480 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
481 buf
->rect
.x
, buf
->rect
.y
, buf
->rect
.w
, buf
->rect
.h
,
482 real_width
, buf
->buf
.height
);
483 DRM_DEV_DEBUG_KMS(ctx
->dev
, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1
, h2
, v1
,
487 * set window offset 1, 2 size
488 * check figure 43-21 in user manual
490 cfg
= fimc_read(ctx
, EXYNOS_CIWDOFST
);
491 cfg
&= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK
|
492 EXYNOS_CIWDOFST_WINVEROFST_MASK
);
493 cfg
|= (EXYNOS_CIWDOFST_WINHOROFST(h1
) |
494 EXYNOS_CIWDOFST_WINVEROFST(v1
));
495 cfg
|= EXYNOS_CIWDOFST_WINOFSEN
;
496 fimc_write(ctx
, cfg
, EXYNOS_CIWDOFST
);
498 cfg
= (EXYNOS_CIWDOFST2_WINHOROFST2(h2
) |
499 EXYNOS_CIWDOFST2_WINVEROFST2(v2
));
500 fimc_write(ctx
, cfg
, EXYNOS_CIWDOFST2
);
503 static void fimc_src_set_size(struct fimc_context
*ctx
,
504 struct exynos_drm_ipp_buffer
*buf
)
506 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
509 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hsize[%d]vsize[%d]\n", real_width
,
513 cfg
= (EXYNOS_ORGISIZE_HORIZONTAL(real_width
) |
514 EXYNOS_ORGISIZE_VERTICAL(buf
->buf
.height
));
516 fimc_write(ctx
, cfg
, EXYNOS_ORGISIZE
);
518 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]\n", buf
->rect
.x
,
519 buf
->rect
.y
, buf
->rect
.w
, buf
->rect
.h
);
521 /* set input DMA image size */
522 cfg
= fimc_read(ctx
, EXYNOS_CIREAL_ISIZE
);
523 cfg
&= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK
|
524 EXYNOS_CIREAL_ISIZE_WIDTH_MASK
);
525 cfg
|= (EXYNOS_CIREAL_ISIZE_WIDTH(buf
->rect
.w
) |
526 EXYNOS_CIREAL_ISIZE_HEIGHT(buf
->rect
.h
));
527 fimc_write(ctx
, cfg
, EXYNOS_CIREAL_ISIZE
);
530 * set input FIFO image size
531 * for now, we support only ITU601 8 bit mode
533 cfg
= (EXYNOS_CISRCFMT_ITU601_8BIT
|
534 EXYNOS_CISRCFMT_SOURCEHSIZE(real_width
) |
535 EXYNOS_CISRCFMT_SOURCEVSIZE(buf
->buf
.height
));
536 fimc_write(ctx
, cfg
, EXYNOS_CISRCFMT
);
538 /* offset Y(RGB), Cb, Cr */
539 cfg
= (EXYNOS_CIIYOFF_HORIZONTAL(buf
->rect
.x
) |
540 EXYNOS_CIIYOFF_VERTICAL(buf
->rect
.y
));
541 fimc_write(ctx
, cfg
, EXYNOS_CIIYOFF
);
542 cfg
= (EXYNOS_CIICBOFF_HORIZONTAL(buf
->rect
.x
) |
543 EXYNOS_CIICBOFF_VERTICAL(buf
->rect
.y
));
544 fimc_write(ctx
, cfg
, EXYNOS_CIICBOFF
);
545 cfg
= (EXYNOS_CIICROFF_HORIZONTAL(buf
->rect
.x
) |
546 EXYNOS_CIICROFF_VERTICAL(buf
->rect
.y
));
547 fimc_write(ctx
, cfg
, EXYNOS_CIICROFF
);
549 fimc_set_window(ctx
, buf
);
552 static void fimc_src_set_addr(struct fimc_context
*ctx
,
553 struct exynos_drm_ipp_buffer
*buf
)
555 fimc_write(ctx
, buf
->dma_addr
[0], EXYNOS_CIIYSA(0));
556 fimc_write(ctx
, buf
->dma_addr
[1], EXYNOS_CIICBSA(0));
557 fimc_write(ctx
, buf
->dma_addr
[2], EXYNOS_CIICRSA(0));
560 static void fimc_dst_set_fmt_order(struct fimc_context
*ctx
, u32 fmt
)
564 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
567 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
568 cfg
&= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK
;
571 case DRM_FORMAT_RGB565
:
572 cfg
|= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565
;
573 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
575 case DRM_FORMAT_RGB888
:
576 cfg
|= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888
;
577 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
579 case DRM_FORMAT_XRGB8888
:
580 cfg
|= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888
|
581 EXYNOS_CISCCTRL_EXTRGB_EXTENSION
);
582 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
590 cfg
= fimc_read(ctx
, EXYNOS_CIOCTRL
);
591 cfg
&= ~(EXYNOS_CIOCTRL_ORDER2P_MASK
|
592 EXYNOS_CIOCTRL_ORDER422_MASK
|
593 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK
);
596 case DRM_FORMAT_XRGB8888
:
597 cfg
|= EXYNOS_CIOCTRL_ALPHA_OUT
;
599 case DRM_FORMAT_YUYV
:
600 cfg
|= EXYNOS_CIOCTRL_ORDER422_YCBYCR
;
602 case DRM_FORMAT_YVYU
:
603 cfg
|= EXYNOS_CIOCTRL_ORDER422_YCRYCB
;
605 case DRM_FORMAT_UYVY
:
606 cfg
|= EXYNOS_CIOCTRL_ORDER422_CBYCRY
;
608 case DRM_FORMAT_VYUY
:
609 cfg
|= EXYNOS_CIOCTRL_ORDER422_CRYCBY
;
611 case DRM_FORMAT_NV21
:
612 case DRM_FORMAT_NV61
:
613 cfg
|= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB
;
614 cfg
|= EXYNOS_CIOCTRL_YCBCR_2PLANE
;
616 case DRM_FORMAT_YUV422
:
617 case DRM_FORMAT_YUV420
:
618 case DRM_FORMAT_YVU420
:
619 cfg
|= EXYNOS_CIOCTRL_YCBCR_3PLANE
;
621 case DRM_FORMAT_NV12
:
622 case DRM_FORMAT_NV16
:
623 cfg
|= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR
;
624 cfg
|= EXYNOS_CIOCTRL_YCBCR_2PLANE
;
628 fimc_write(ctx
, cfg
, EXYNOS_CIOCTRL
);
631 static void fimc_dst_set_fmt(struct fimc_context
*ctx
, u32 fmt
, bool tiled
)
635 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fmt[0x%x]\n", fmt
);
637 cfg
= fimc_read(ctx
, EXYNOS_CIEXTEN
);
639 if (fmt
== DRM_FORMAT_AYUV
) {
640 cfg
|= EXYNOS_CIEXTEN_YUV444_OUT
;
641 fimc_write(ctx
, cfg
, EXYNOS_CIEXTEN
);
643 cfg
&= ~EXYNOS_CIEXTEN_YUV444_OUT
;
644 fimc_write(ctx
, cfg
, EXYNOS_CIEXTEN
);
646 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
647 cfg
&= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK
;
650 case DRM_FORMAT_RGB565
:
651 case DRM_FORMAT_RGB888
:
652 case DRM_FORMAT_XRGB8888
:
653 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_RGB
;
655 case DRM_FORMAT_YUYV
:
656 case DRM_FORMAT_YVYU
:
657 case DRM_FORMAT_UYVY
:
658 case DRM_FORMAT_VYUY
:
659 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE
;
661 case DRM_FORMAT_NV16
:
662 case DRM_FORMAT_NV61
:
663 case DRM_FORMAT_YUV422
:
664 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422
;
666 case DRM_FORMAT_YUV420
:
667 case DRM_FORMAT_YVU420
:
668 case DRM_FORMAT_NV12
:
669 case DRM_FORMAT_NV21
:
670 cfg
|= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420
;
674 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
677 cfg
= fimc_read(ctx
, EXYNOS_CIDMAPARAM
);
678 cfg
&= ~EXYNOS_CIDMAPARAM_W_MODE_MASK
;
681 cfg
|= EXYNOS_CIDMAPARAM_W_MODE_64X32
;
683 cfg
|= EXYNOS_CIDMAPARAM_W_MODE_LINEAR
;
685 fimc_write(ctx
, cfg
, EXYNOS_CIDMAPARAM
);
687 fimc_dst_set_fmt_order(ctx
, fmt
);
690 static void fimc_dst_set_transf(struct fimc_context
*ctx
, unsigned int rotation
)
692 unsigned int degree
= rotation
& DRM_MODE_ROTATE_MASK
;
695 DRM_DEV_DEBUG_KMS(ctx
->dev
, "rotation[0x%x]\n", rotation
);
697 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
698 cfg
&= ~EXYNOS_CITRGFMT_FLIP_MASK
;
699 cfg
&= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
;
702 case DRM_MODE_ROTATE_0
:
703 if (rotation
& DRM_MODE_REFLECT_X
)
704 cfg
|= EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
705 if (rotation
& DRM_MODE_REFLECT_Y
)
706 cfg
|= EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
708 case DRM_MODE_ROTATE_90
:
709 cfg
|= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
;
710 if (rotation
& DRM_MODE_REFLECT_X
)
711 cfg
|= EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
712 if (rotation
& DRM_MODE_REFLECT_Y
)
713 cfg
|= EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
715 case DRM_MODE_ROTATE_180
:
716 cfg
|= (EXYNOS_CITRGFMT_FLIP_X_MIRROR
|
717 EXYNOS_CITRGFMT_FLIP_Y_MIRROR
);
718 if (rotation
& DRM_MODE_REFLECT_X
)
719 cfg
&= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
720 if (rotation
& DRM_MODE_REFLECT_Y
)
721 cfg
&= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
723 case DRM_MODE_ROTATE_270
:
724 cfg
|= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
|
725 EXYNOS_CITRGFMT_FLIP_X_MIRROR
|
726 EXYNOS_CITRGFMT_FLIP_Y_MIRROR
);
727 if (rotation
& DRM_MODE_REFLECT_X
)
728 cfg
&= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR
;
729 if (rotation
& DRM_MODE_REFLECT_Y
)
730 cfg
&= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR
;
734 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
737 static int fimc_set_prescaler(struct fimc_context
*ctx
, struct fimc_scaler
*sc
,
738 struct drm_exynos_ipp_task_rect
*src
,
739 struct drm_exynos_ipp_task_rect
*dst
)
741 u32 cfg
, cfg_ext
, shfactor
;
742 u32 pre_dst_width
, pre_dst_height
;
743 u32 hfactor
, vfactor
;
745 u32 src_w
, src_h
, dst_w
, dst_h
;
747 cfg_ext
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
748 if (cfg_ext
& EXYNOS_CITRGFMT_INROT90_CLOCKWISE
) {
756 if (cfg_ext
& EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
) {
764 /* fimc_ippdrv_check_property assures that dividers are not null */
765 hfactor
= fls(src_w
/ dst_w
/ 2);
766 if (hfactor
> FIMC_SHFACTOR
/ 2) {
767 dev_err(ctx
->dev
, "failed to get ratio horizontal.\n");
771 vfactor
= fls(src_h
/ dst_h
/ 2);
772 if (vfactor
> FIMC_SHFACTOR
/ 2) {
773 dev_err(ctx
->dev
, "failed to get ratio vertical.\n");
777 pre_dst_width
= src_w
>> hfactor
;
778 pre_dst_height
= src_h
>> vfactor
;
779 DRM_DEV_DEBUG_KMS(ctx
->dev
, "pre_dst_width[%d]pre_dst_height[%d]\n",
780 pre_dst_width
, pre_dst_height
);
781 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hfactor[%d]vfactor[%d]\n", hfactor
,
784 sc
->hratio
= (src_w
<< 14) / (dst_w
<< hfactor
);
785 sc
->vratio
= (src_h
<< 14) / (dst_h
<< vfactor
);
786 sc
->up_h
= (dst_w
>= src_w
) ? true : false;
787 sc
->up_v
= (dst_h
>= src_h
) ? true : false;
788 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
789 sc
->hratio
, sc
->vratio
, sc
->up_h
, sc
->up_v
);
791 shfactor
= FIMC_SHFACTOR
- (hfactor
+ vfactor
);
792 DRM_DEV_DEBUG_KMS(ctx
->dev
, "shfactor[%d]\n", shfactor
);
794 cfg
= (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor
) |
795 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor
) |
796 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor
));
797 fimc_write(ctx
, cfg
, EXYNOS_CISCPRERATIO
);
799 cfg
= (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width
) |
800 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height
));
801 fimc_write(ctx
, cfg
, EXYNOS_CISCPREDST
);
806 static void fimc_set_scaler(struct fimc_context
*ctx
, struct fimc_scaler
*sc
)
810 DRM_DEV_DEBUG_KMS(ctx
->dev
, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
811 sc
->range
, sc
->bypass
, sc
->up_h
, sc
->up_v
);
812 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hratio[%d]vratio[%d]\n",
813 sc
->hratio
, sc
->vratio
);
815 cfg
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
816 cfg
&= ~(EXYNOS_CISCCTRL_SCALERBYPASS
|
817 EXYNOS_CISCCTRL_SCALEUP_H
| EXYNOS_CISCCTRL_SCALEUP_V
|
818 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK
|
819 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK
|
820 EXYNOS_CISCCTRL_CSCR2Y_WIDE
|
821 EXYNOS_CISCCTRL_CSCY2R_WIDE
);
824 cfg
|= (EXYNOS_CISCCTRL_CSCR2Y_WIDE
|
825 EXYNOS_CISCCTRL_CSCY2R_WIDE
);
827 cfg
|= EXYNOS_CISCCTRL_SCALERBYPASS
;
829 cfg
|= EXYNOS_CISCCTRL_SCALEUP_H
;
831 cfg
|= EXYNOS_CISCCTRL_SCALEUP_V
;
833 cfg
|= (EXYNOS_CISCCTRL_MAINHORRATIO((sc
->hratio
>> 6)) |
834 EXYNOS_CISCCTRL_MAINVERRATIO((sc
->vratio
>> 6)));
835 fimc_write(ctx
, cfg
, EXYNOS_CISCCTRL
);
837 cfg_ext
= fimc_read(ctx
, EXYNOS_CIEXTEN
);
838 cfg_ext
&= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK
;
839 cfg_ext
&= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK
;
840 cfg_ext
|= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc
->hratio
) |
841 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc
->vratio
));
842 fimc_write(ctx
, cfg_ext
, EXYNOS_CIEXTEN
);
845 static void fimc_dst_set_size(struct fimc_context
*ctx
,
846 struct exynos_drm_ipp_buffer
*buf
)
848 unsigned int real_width
= buf
->buf
.pitch
[0] / buf
->format
->cpp
[0];
851 DRM_DEV_DEBUG_KMS(ctx
->dev
, "hsize[%d]vsize[%d]\n", real_width
,
855 cfg
= (EXYNOS_ORGOSIZE_HORIZONTAL(real_width
) |
856 EXYNOS_ORGOSIZE_VERTICAL(buf
->buf
.height
));
858 fimc_write(ctx
, cfg
, EXYNOS_ORGOSIZE
);
860 DRM_DEV_DEBUG_KMS(ctx
->dev
, "x[%d]y[%d]w[%d]h[%d]\n", buf
->rect
.x
,
862 buf
->rect
.w
, buf
->rect
.h
);
865 cfg
= fimc_read(ctx
, EXYNOS_CIGCTRL
);
866 cfg
&= ~EXYNOS_CIGCTRL_CSC_MASK
;
868 if (buf
->buf
.width
>= FIMC_WIDTH_ITU_709
)
869 cfg
|= EXYNOS_CIGCTRL_CSC_ITU709
;
871 cfg
|= EXYNOS_CIGCTRL_CSC_ITU601
;
873 fimc_write(ctx
, cfg
, EXYNOS_CIGCTRL
);
875 cfg_ext
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
877 /* target image size */
878 cfg
= fimc_read(ctx
, EXYNOS_CITRGFMT
);
879 cfg
&= ~(EXYNOS_CITRGFMT_TARGETH_MASK
|
880 EXYNOS_CITRGFMT_TARGETV_MASK
);
881 if (cfg_ext
& EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE
)
882 cfg
|= (EXYNOS_CITRGFMT_TARGETHSIZE(buf
->rect
.h
) |
883 EXYNOS_CITRGFMT_TARGETVSIZE(buf
->rect
.w
));
885 cfg
|= (EXYNOS_CITRGFMT_TARGETHSIZE(buf
->rect
.w
) |
886 EXYNOS_CITRGFMT_TARGETVSIZE(buf
->rect
.h
));
887 fimc_write(ctx
, cfg
, EXYNOS_CITRGFMT
);
890 cfg
= EXYNOS_CITAREA_TARGET_AREA(buf
->rect
.w
* buf
->rect
.h
);
891 fimc_write(ctx
, cfg
, EXYNOS_CITAREA
);
893 /* offset Y(RGB), Cb, Cr */
894 cfg
= (EXYNOS_CIOYOFF_HORIZONTAL(buf
->rect
.x
) |
895 EXYNOS_CIOYOFF_VERTICAL(buf
->rect
.y
));
896 fimc_write(ctx
, cfg
, EXYNOS_CIOYOFF
);
897 cfg
= (EXYNOS_CIOCBOFF_HORIZONTAL(buf
->rect
.x
) |
898 EXYNOS_CIOCBOFF_VERTICAL(buf
->rect
.y
));
899 fimc_write(ctx
, cfg
, EXYNOS_CIOCBOFF
);
900 cfg
= (EXYNOS_CIOCROFF_HORIZONTAL(buf
->rect
.x
) |
901 EXYNOS_CIOCROFF_VERTICAL(buf
->rect
.y
));
902 fimc_write(ctx
, cfg
, EXYNOS_CIOCROFF
);
905 static void fimc_dst_set_buf_seq(struct fimc_context
*ctx
, u32 buf_id
,
912 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]enqueu[%d]\n", buf_id
, enqueue
);
914 spin_lock_irqsave(&ctx
->lock
, flags
);
916 cfg
= fimc_read(ctx
, EXYNOS_CIFCNTSEQ
);
919 cfg
|= (1 << buf_id
);
921 cfg
&= ~(1 << buf_id
);
923 fimc_write(ctx
, cfg
, EXYNOS_CIFCNTSEQ
);
925 buf_num
= hweight32(cfg
);
927 if (enqueue
&& buf_num
>= FIMC_BUF_START
)
928 fimc_mask_irq(ctx
, true);
929 else if (!enqueue
&& buf_num
<= FIMC_BUF_STOP
)
930 fimc_mask_irq(ctx
, false);
932 spin_unlock_irqrestore(&ctx
->lock
, flags
);
935 static void fimc_dst_set_addr(struct fimc_context
*ctx
,
936 struct exynos_drm_ipp_buffer
*buf
)
938 fimc_write(ctx
, buf
->dma_addr
[0], EXYNOS_CIOYSA(0));
939 fimc_write(ctx
, buf
->dma_addr
[1], EXYNOS_CIOCBSA(0));
940 fimc_write(ctx
, buf
->dma_addr
[2], EXYNOS_CIOCRSA(0));
942 fimc_dst_set_buf_seq(ctx
, 0, true);
945 static void fimc_stop(struct fimc_context
*ctx
);
947 static irqreturn_t
fimc_irq_handler(int irq
, void *dev_id
)
949 struct fimc_context
*ctx
= dev_id
;
952 DRM_DEV_DEBUG_KMS(ctx
->dev
, "fimc id[%d]\n", ctx
->id
);
955 if (fimc_check_ovf(ctx
))
958 if (!fimc_check_frame_end(ctx
))
961 buf_id
= fimc_get_buf_id(ctx
);
965 DRM_DEV_DEBUG_KMS(ctx
->dev
, "buf_id[%d]\n", buf_id
);
968 struct exynos_drm_ipp_task
*task
= ctx
->task
;
971 pm_runtime_mark_last_busy(ctx
->dev
);
972 pm_runtime_put_autosuspend(ctx
->dev
);
973 exynos_drm_ipp_task_done(task
, 0);
976 fimc_dst_set_buf_seq(ctx
, buf_id
, false);
982 static void fimc_clear_addr(struct fimc_context
*ctx
)
986 for (i
= 0; i
< FIMC_MAX_SRC
; i
++) {
987 fimc_write(ctx
, 0, EXYNOS_CIIYSA(i
));
988 fimc_write(ctx
, 0, EXYNOS_CIICBSA(i
));
989 fimc_write(ctx
, 0, EXYNOS_CIICRSA(i
));
992 for (i
= 0; i
< FIMC_MAX_DST
; i
++) {
993 fimc_write(ctx
, 0, EXYNOS_CIOYSA(i
));
994 fimc_write(ctx
, 0, EXYNOS_CIOCBSA(i
));
995 fimc_write(ctx
, 0, EXYNOS_CIOCRSA(i
));
999 static void fimc_reset(struct fimc_context
*ctx
)
1001 /* reset h/w block */
1004 /* reset scaler capability */
1005 memset(&ctx
->sc
, 0x0, sizeof(ctx
->sc
));
1007 fimc_clear_addr(ctx
);
1010 static void fimc_start(struct fimc_context
*ctx
)
1014 fimc_mask_irq(ctx
, true);
1016 /* If set true, we can save jpeg about screen */
1017 fimc_handle_jpeg(ctx
, false);
1018 fimc_set_scaler(ctx
, &ctx
->sc
);
1020 fimc_set_type_ctrl(ctx
);
1021 fimc_handle_lastend(ctx
, false);
1024 cfg0
= fimc_read(ctx
, EXYNOS_MSCTRL
);
1025 cfg0
&= ~EXYNOS_MSCTRL_INPUT_MASK
;
1026 cfg0
|= EXYNOS_MSCTRL_INPUT_MEMORY
;
1027 fimc_write(ctx
, cfg0
, EXYNOS_MSCTRL
);
1030 fimc_write(ctx
, 0x0, EXYNOS_CISTATUS
);
1032 cfg0
= fimc_read(ctx
, EXYNOS_CIIMGCPT
);
1033 cfg0
&= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC
;
1034 cfg0
|= EXYNOS_CIIMGCPT_IMGCPTEN_SC
;
1037 cfg1
= fimc_read(ctx
, EXYNOS_CISCCTRL
);
1038 cfg1
&= ~EXYNOS_CISCCTRL_SCAN_MASK
;
1039 cfg1
|= (EXYNOS_CISCCTRL_PROGRESSIVE
|
1040 EXYNOS_CISCCTRL_SCALERSTART
);
1042 fimc_write(ctx
, cfg1
, EXYNOS_CISCCTRL
);
1044 /* Enable image capture*/
1045 cfg0
|= EXYNOS_CIIMGCPT_IMGCPTEN
;
1046 fimc_write(ctx
, cfg0
, EXYNOS_CIIMGCPT
);
1048 /* Disable frame end irq */
1049 fimc_clear_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_END_DISABLE
);
1051 fimc_clear_bits(ctx
, EXYNOS_CIOCTRL
, EXYNOS_CIOCTRL_WEAVE_MASK
);
1053 fimc_set_bits(ctx
, EXYNOS_MSCTRL
, EXYNOS_MSCTRL_ENVID
);
1056 static void fimc_stop(struct fimc_context
*ctx
)
1061 cfg
= fimc_read(ctx
, EXYNOS_MSCTRL
);
1062 cfg
&= ~EXYNOS_MSCTRL_INPUT_MASK
;
1063 cfg
&= ~EXYNOS_MSCTRL_ENVID
;
1064 fimc_write(ctx
, cfg
, EXYNOS_MSCTRL
);
1066 fimc_mask_irq(ctx
, false);
1068 /* reset sequence */
1069 fimc_write(ctx
, 0x0, EXYNOS_CIFCNTSEQ
);
1071 /* Scaler disable */
1072 fimc_clear_bits(ctx
, EXYNOS_CISCCTRL
, EXYNOS_CISCCTRL_SCALERSTART
);
1074 /* Disable image capture */
1075 fimc_clear_bits(ctx
, EXYNOS_CIIMGCPT
,
1076 EXYNOS_CIIMGCPT_IMGCPTEN_SC
| EXYNOS_CIIMGCPT_IMGCPTEN
);
1078 /* Enable frame end irq */
1079 fimc_set_bits(ctx
, EXYNOS_CIGCTRL
, EXYNOS_CIGCTRL_IRQ_END_DISABLE
);
1082 static int fimc_commit(struct exynos_drm_ipp
*ipp
,
1083 struct exynos_drm_ipp_task
*task
)
1085 struct fimc_context
*ctx
=
1086 container_of(ipp
, struct fimc_context
, ipp
);
1088 pm_runtime_get_sync(ctx
->dev
);
1091 fimc_src_set_fmt(ctx
, task
->src
.buf
.fourcc
, task
->src
.buf
.modifier
);
1092 fimc_src_set_size(ctx
, &task
->src
);
1093 fimc_src_set_transf(ctx
, DRM_MODE_ROTATE_0
);
1094 fimc_src_set_addr(ctx
, &task
->src
);
1095 fimc_dst_set_fmt(ctx
, task
->dst
.buf
.fourcc
, task
->dst
.buf
.modifier
);
1096 fimc_dst_set_transf(ctx
, task
->transform
.rotation
);
1097 fimc_dst_set_size(ctx
, &task
->dst
);
1098 fimc_dst_set_addr(ctx
, &task
->dst
);
1099 fimc_set_prescaler(ctx
, &ctx
->sc
, &task
->src
.rect
, &task
->dst
.rect
);
1105 static void fimc_abort(struct exynos_drm_ipp
*ipp
,
1106 struct exynos_drm_ipp_task
*task
)
1108 struct fimc_context
*ctx
=
1109 container_of(ipp
, struct fimc_context
, ipp
);
1114 struct exynos_drm_ipp_task
*task
= ctx
->task
;
1117 pm_runtime_mark_last_busy(ctx
->dev
);
1118 pm_runtime_put_autosuspend(ctx
->dev
);
1119 exynos_drm_ipp_task_done(task
, -EIO
);
1123 static struct exynos_drm_ipp_funcs ipp_funcs
= {
1124 .commit
= fimc_commit
,
1125 .abort
= fimc_abort
,
1128 static int fimc_bind(struct device
*dev
, struct device
*master
, void *data
)
1130 struct fimc_context
*ctx
= dev_get_drvdata(dev
);
1131 struct drm_device
*drm_dev
= data
;
1132 struct exynos_drm_ipp
*ipp
= &ctx
->ipp
;
1134 ctx
->drm_dev
= drm_dev
;
1135 ipp
->drm_dev
= drm_dev
;
1136 exynos_drm_register_dma(drm_dev
, dev
);
1138 exynos_drm_ipp_register(dev
, ipp
, &ipp_funcs
,
1139 DRM_EXYNOS_IPP_CAP_CROP
| DRM_EXYNOS_IPP_CAP_ROTATE
|
1140 DRM_EXYNOS_IPP_CAP_SCALE
| DRM_EXYNOS_IPP_CAP_CONVERT
,
1141 ctx
->formats
, ctx
->num_formats
, "fimc");
1143 dev_info(dev
, "The exynos fimc has been probed successfully\n");
1148 static void fimc_unbind(struct device
*dev
, struct device
*master
,
1151 struct fimc_context
*ctx
= dev_get_drvdata(dev
);
1152 struct drm_device
*drm_dev
= data
;
1153 struct exynos_drm_ipp
*ipp
= &ctx
->ipp
;
1155 exynos_drm_ipp_unregister(dev
, ipp
);
1156 exynos_drm_unregister_dma(drm_dev
, dev
);
1159 static const struct component_ops fimc_component_ops
= {
1161 .unbind
= fimc_unbind
,
1164 static void fimc_put_clocks(struct fimc_context
*ctx
)
1168 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++) {
1169 if (IS_ERR(ctx
->clocks
[i
]))
1171 clk_put(ctx
->clocks
[i
]);
1172 ctx
->clocks
[i
] = ERR_PTR(-EINVAL
);
1176 static int fimc_setup_clocks(struct fimc_context
*ctx
)
1178 struct device
*fimc_dev
= ctx
->dev
;
1182 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++)
1183 ctx
->clocks
[i
] = ERR_PTR(-EINVAL
);
1185 for (i
= 0; i
< FIMC_CLKS_MAX
; i
++) {
1186 if (i
== FIMC_CLK_WB_A
|| i
== FIMC_CLK_WB_B
)
1187 dev
= fimc_dev
->parent
;
1191 ctx
->clocks
[i
] = clk_get(dev
, fimc_clock_names
[i
]);
1192 if (IS_ERR(ctx
->clocks
[i
])) {
1193 ret
= PTR_ERR(ctx
->clocks
[i
]);
1194 dev_err(fimc_dev
, "failed to get clock: %s\n",
1195 fimc_clock_names
[i
]);
1200 ret
= clk_prepare_enable(ctx
->clocks
[FIMC_CLK_LCLK
]);
1204 fimc_put_clocks(ctx
);
1208 int exynos_drm_check_fimc_device(struct device
*dev
)
1210 int id
= of_alias_get_id(dev
->of_node
, "fimc");
1212 if (id
>= 0 && (BIT(id
) & fimc_mask
))
1217 static const unsigned int fimc_formats
[] = {
1218 DRM_FORMAT_XRGB8888
, DRM_FORMAT_RGB565
,
1219 DRM_FORMAT_NV12
, DRM_FORMAT_NV16
, DRM_FORMAT_NV21
, DRM_FORMAT_NV61
,
1220 DRM_FORMAT_UYVY
, DRM_FORMAT_VYUY
, DRM_FORMAT_YUYV
, DRM_FORMAT_YVYU
,
1221 DRM_FORMAT_YUV420
, DRM_FORMAT_YVU420
, DRM_FORMAT_YUV422
,
1225 static const unsigned int fimc_tiled_formats
[] = {
1226 DRM_FORMAT_NV12
, DRM_FORMAT_NV21
,
1229 static const struct drm_exynos_ipp_limit fimc_4210_limits_v1
[] = {
1230 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 16, 8192, 8 }, .v
= { 16, 8192, 2 }) },
1231 { IPP_SIZE_LIMIT(AREA
, .h
= { 16, 4224, 2 }, .v
= { 16, 0, 2 }) },
1232 { IPP_SIZE_LIMIT(ROTATED
, .h
= { 128, 1920 }, .v
= { 128, 0 }) },
1233 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1234 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1237 static const struct drm_exynos_ipp_limit fimc_4210_limits_v2
[] = {
1238 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 16, 8192, 8 }, .v
= { 16, 8192, 2 }) },
1239 { IPP_SIZE_LIMIT(AREA
, .h
= { 16, 1920, 2 }, .v
= { 16, 0, 2 }) },
1240 { IPP_SIZE_LIMIT(ROTATED
, .h
= { 128, 1366 }, .v
= { 128, 0 }) },
1241 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1242 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1245 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v1
[] = {
1246 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 128, 1920, 128 }, .v
= { 32, 1920, 32 }) },
1247 { IPP_SIZE_LIMIT(AREA
, .h
= { 128, 1920, 2 }, .v
= { 128, 0, 2 }) },
1248 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1249 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1252 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2
[] = {
1253 { IPP_SIZE_LIMIT(BUFFER
, .h
= { 128, 1920, 128 }, .v
= { 32, 1920, 32 }) },
1254 { IPP_SIZE_LIMIT(AREA
, .h
= { 128, 1366, 2 }, .v
= { 128, 0, 2 }) },
1255 { IPP_SCALE_LIMIT(.h
= { (1 << 16) / 64, (1 << 16) * 64 },
1256 .v
= { (1 << 16) / 64, (1 << 16) * 64 }) },
1259 static int fimc_probe(struct platform_device
*pdev
)
1261 const struct drm_exynos_ipp_limit
*limits
;
1262 struct exynos_drm_ipp_formats
*formats
;
1263 struct device
*dev
= &pdev
->dev
;
1264 struct fimc_context
*ctx
;
1265 struct resource
*res
;
1267 int i
, j
, num_limits
, num_formats
;
1269 if (exynos_drm_check_fimc_device(dev
) != 0)
1272 ctx
= devm_kzalloc(dev
, sizeof(*ctx
), GFP_KERNEL
);
1277 ctx
->id
= of_alias_get_id(dev
->of_node
, "fimc");
1279 /* construct formats/limits array */
1280 num_formats
= ARRAY_SIZE(fimc_formats
) + ARRAY_SIZE(fimc_tiled_formats
);
1281 formats
= devm_kcalloc(dev
, num_formats
, sizeof(*formats
),
1286 /* linear formats */
1288 limits
= fimc_4210_limits_v1
;
1289 num_limits
= ARRAY_SIZE(fimc_4210_limits_v1
);
1291 limits
= fimc_4210_limits_v2
;
1292 num_limits
= ARRAY_SIZE(fimc_4210_limits_v2
);
1294 for (i
= 0; i
< ARRAY_SIZE(fimc_formats
); i
++) {
1295 formats
[i
].fourcc
= fimc_formats
[i
];
1296 formats
[i
].type
= DRM_EXYNOS_IPP_FORMAT_SOURCE
|
1297 DRM_EXYNOS_IPP_FORMAT_DESTINATION
;
1298 formats
[i
].limits
= limits
;
1299 formats
[i
].num_limits
= num_limits
;
1304 limits
= fimc_4210_limits_tiled_v1
;
1305 num_limits
= ARRAY_SIZE(fimc_4210_limits_tiled_v1
);
1307 limits
= fimc_4210_limits_tiled_v2
;
1308 num_limits
= ARRAY_SIZE(fimc_4210_limits_tiled_v2
);
1310 for (j
= i
, i
= 0; i
< ARRAY_SIZE(fimc_tiled_formats
); j
++, i
++) {
1311 formats
[j
].fourcc
= fimc_tiled_formats
[i
];
1312 formats
[j
].modifier
= DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
;
1313 formats
[j
].type
= DRM_EXYNOS_IPP_FORMAT_SOURCE
|
1314 DRM_EXYNOS_IPP_FORMAT_DESTINATION
;
1315 formats
[j
].limits
= limits
;
1316 formats
[j
].num_limits
= num_limits
;
1319 ctx
->formats
= formats
;
1320 ctx
->num_formats
= num_formats
;
1322 /* resource memory */
1323 ctx
->regs_res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1324 ctx
->regs
= devm_ioremap_resource(dev
, ctx
->regs_res
);
1325 if (IS_ERR(ctx
->regs
))
1326 return PTR_ERR(ctx
->regs
);
1329 res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
1331 dev_err(dev
, "failed to request irq resource.\n");
1335 ret
= devm_request_irq(dev
, res
->start
, fimc_irq_handler
,
1336 0, dev_name(dev
), ctx
);
1338 dev_err(dev
, "failed to request irq.\n");
1342 ret
= fimc_setup_clocks(ctx
);
1346 spin_lock_init(&ctx
->lock
);
1347 platform_set_drvdata(pdev
, ctx
);
1349 pm_runtime_use_autosuspend(dev
);
1350 pm_runtime_set_autosuspend_delay(dev
, FIMC_AUTOSUSPEND_DELAY
);
1351 pm_runtime_enable(dev
);
1353 ret
= component_add(dev
, &fimc_component_ops
);
1357 dev_info(dev
, "drm fimc registered successfully.\n");
1362 pm_runtime_dont_use_autosuspend(dev
);
1363 pm_runtime_disable(dev
);
1364 fimc_put_clocks(ctx
);
1369 static int fimc_remove(struct platform_device
*pdev
)
1371 struct device
*dev
= &pdev
->dev
;
1372 struct fimc_context
*ctx
= get_fimc_context(dev
);
1374 component_del(dev
, &fimc_component_ops
);
1375 pm_runtime_dont_use_autosuspend(dev
);
1376 pm_runtime_disable(dev
);
1378 fimc_put_clocks(ctx
);
1384 static int fimc_runtime_suspend(struct device
*dev
)
1386 struct fimc_context
*ctx
= get_fimc_context(dev
);
1388 DRM_DEV_DEBUG_KMS(dev
, "id[%d]\n", ctx
->id
);
1389 clk_disable_unprepare(ctx
->clocks
[FIMC_CLK_GATE
]);
1393 static int fimc_runtime_resume(struct device
*dev
)
1395 struct fimc_context
*ctx
= get_fimc_context(dev
);
1397 DRM_DEV_DEBUG_KMS(dev
, "id[%d]\n", ctx
->id
);
1398 return clk_prepare_enable(ctx
->clocks
[FIMC_CLK_GATE
]);
1402 static const struct dev_pm_ops fimc_pm_ops
= {
1403 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
1404 pm_runtime_force_resume
)
1405 SET_RUNTIME_PM_OPS(fimc_runtime_suspend
, fimc_runtime_resume
, NULL
)
1408 static const struct of_device_id fimc_of_match
[] = {
1409 { .compatible
= "samsung,exynos4210-fimc" },
1410 { .compatible
= "samsung,exynos4212-fimc" },
1413 MODULE_DEVICE_TABLE(of
, fimc_of_match
);
1415 struct platform_driver fimc_driver
= {
1416 .probe
= fimc_probe
,
1417 .remove
= fimc_remove
,
1419 .of_match_table
= fimc_of_match
,
1420 .name
= "exynos-drm-fimc",
1421 .owner
= THIS_MODULE
,