2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/mixer_reg.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
19 #include "regs-mixer.h"
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <linux/i2c.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/clk.h>
32 #include <linux/regulator/consumer.h>
34 #include <linux/component.h>
36 #include <drm/exynos_drm.h>
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_crtc.h"
40 #include "exynos_drm_plane.h"
41 #include "exynos_drm_iommu.h"
42 #include "exynos_mixer.h"
44 #define MIXER_WIN_NR 3
45 #define MIXER_DEFAULT_WIN 0
47 /* The pixelformats that are natively supported by the mixer. */
48 #define MXR_FORMAT_RGB565 4
49 #define MXR_FORMAT_ARGB1555 5
50 #define MXR_FORMAT_ARGB4444 6
51 #define MXR_FORMAT_ARGB8888 7
53 struct mixer_resources
{
55 void __iomem
*mixer_regs
;
56 void __iomem
*vp_regs
;
61 struct clk
*sclk_mixer
;
62 struct clk
*sclk_hdmi
;
63 struct clk
*mout_mixer
;
66 enum mixer_version_id
{
72 struct mixer_context
{
73 struct platform_device
*pdev
;
75 struct drm_device
*drm_dev
;
76 struct exynos_drm_crtc
*crtc
;
77 struct exynos_drm_plane planes
[MIXER_WIN_NR
];
85 struct mutex mixer_mutex
;
86 struct mixer_resources mixer_res
;
87 enum mixer_version_id mxr_ver
;
88 wait_queue_head_t wait_vsync_queue
;
89 atomic_t wait_vsync_event
;
92 struct mixer_drv_data
{
93 enum mixer_version_id version
;
98 static const u8 filter_y_horiz_tap8
[] = {
99 0, -1, -1, -1, -1, -1, -1, -1,
100 -1, -1, -1, -1, -1, 0, 0, 0,
101 0, 2, 4, 5, 6, 6, 6, 6,
102 6, 5, 5, 4, 3, 2, 1, 1,
103 0, -6, -12, -16, -18, -20, -21, -20,
104 -20, -18, -16, -13, -10, -8, -5, -2,
105 127, 126, 125, 121, 114, 107, 99, 89,
106 79, 68, 57, 46, 35, 25, 16, 8,
109 static const u8 filter_y_vert_tap4
[] = {
110 0, -3, -6, -8, -8, -8, -8, -7,
111 -6, -5, -4, -3, -2, -1, -1, 0,
112 127, 126, 124, 118, 111, 102, 92, 81,
113 70, 59, 48, 37, 27, 19, 11, 5,
114 0, 5, 11, 19, 27, 37, 48, 59,
115 70, 81, 92, 102, 111, 118, 124, 126,
116 0, 0, -1, -1, -2, -3, -4, -5,
117 -6, -7, -8, -8, -8, -8, -6, -3,
120 static const u8 filter_cr_horiz_tap4
[] = {
121 0, -3, -6, -8, -8, -8, -8, -7,
122 -6, -5, -4, -3, -2, -1, -1, 0,
123 127, 126, 124, 118, 111, 102, 92, 81,
124 70, 59, 48, 37, 27, 19, 11, 5,
127 static inline u32
vp_reg_read(struct mixer_resources
*res
, u32 reg_id
)
129 return readl(res
->vp_regs
+ reg_id
);
132 static inline void vp_reg_write(struct mixer_resources
*res
, u32 reg_id
,
135 writel(val
, res
->vp_regs
+ reg_id
);
138 static inline void vp_reg_writemask(struct mixer_resources
*res
, u32 reg_id
,
141 u32 old
= vp_reg_read(res
, reg_id
);
143 val
= (val
& mask
) | (old
& ~mask
);
144 writel(val
, res
->vp_regs
+ reg_id
);
147 static inline u32
mixer_reg_read(struct mixer_resources
*res
, u32 reg_id
)
149 return readl(res
->mixer_regs
+ reg_id
);
152 static inline void mixer_reg_write(struct mixer_resources
*res
, u32 reg_id
,
155 writel(val
, res
->mixer_regs
+ reg_id
);
158 static inline void mixer_reg_writemask(struct mixer_resources
*res
,
159 u32 reg_id
, u32 val
, u32 mask
)
161 u32 old
= mixer_reg_read(res
, reg_id
);
163 val
= (val
& mask
) | (old
& ~mask
);
164 writel(val
, res
->mixer_regs
+ reg_id
);
167 static void mixer_regs_dump(struct mixer_context
*ctx
)
169 #define DUMPREG(reg_id) \
171 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
172 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
178 DUMPREG(MXR_INT_STATUS
);
180 DUMPREG(MXR_LAYER_CFG
);
181 DUMPREG(MXR_VIDEO_CFG
);
183 DUMPREG(MXR_GRAPHIC0_CFG
);
184 DUMPREG(MXR_GRAPHIC0_BASE
);
185 DUMPREG(MXR_GRAPHIC0_SPAN
);
186 DUMPREG(MXR_GRAPHIC0_WH
);
187 DUMPREG(MXR_GRAPHIC0_SXY
);
188 DUMPREG(MXR_GRAPHIC0_DXY
);
190 DUMPREG(MXR_GRAPHIC1_CFG
);
191 DUMPREG(MXR_GRAPHIC1_BASE
);
192 DUMPREG(MXR_GRAPHIC1_SPAN
);
193 DUMPREG(MXR_GRAPHIC1_WH
);
194 DUMPREG(MXR_GRAPHIC1_SXY
);
195 DUMPREG(MXR_GRAPHIC1_DXY
);
199 static void vp_regs_dump(struct mixer_context
*ctx
)
201 #define DUMPREG(reg_id) \
203 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
204 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
209 DUMPREG(VP_SHADOW_UPDATE
);
210 DUMPREG(VP_FIELD_ID
);
212 DUMPREG(VP_IMG_SIZE_Y
);
213 DUMPREG(VP_IMG_SIZE_C
);
214 DUMPREG(VP_PER_RATE_CTRL
);
215 DUMPREG(VP_TOP_Y_PTR
);
216 DUMPREG(VP_BOT_Y_PTR
);
217 DUMPREG(VP_TOP_C_PTR
);
218 DUMPREG(VP_BOT_C_PTR
);
219 DUMPREG(VP_ENDIAN_MODE
);
220 DUMPREG(VP_SRC_H_POSITION
);
221 DUMPREG(VP_SRC_V_POSITION
);
222 DUMPREG(VP_SRC_WIDTH
);
223 DUMPREG(VP_SRC_HEIGHT
);
224 DUMPREG(VP_DST_H_POSITION
);
225 DUMPREG(VP_DST_V_POSITION
);
226 DUMPREG(VP_DST_WIDTH
);
227 DUMPREG(VP_DST_HEIGHT
);
234 static inline void vp_filter_set(struct mixer_resources
*res
,
235 int reg_id
, const u8
*data
, unsigned int size
)
237 /* assure 4-byte align */
239 for (; size
; size
-= 4, reg_id
+= 4, data
+= 4) {
240 u32 val
= (data
[0] << 24) | (data
[1] << 16) |
241 (data
[2] << 8) | data
[3];
242 vp_reg_write(res
, reg_id
, val
);
246 static void vp_default_filter(struct mixer_resources
*res
)
248 vp_filter_set(res
, VP_POLY8_Y0_LL
,
249 filter_y_horiz_tap8
, sizeof(filter_y_horiz_tap8
));
250 vp_filter_set(res
, VP_POLY4_Y0_LL
,
251 filter_y_vert_tap4
, sizeof(filter_y_vert_tap4
));
252 vp_filter_set(res
, VP_POLY4_C0_LL
,
253 filter_cr_horiz_tap4
, sizeof(filter_cr_horiz_tap4
));
256 static void mixer_vsync_set_update(struct mixer_context
*ctx
, bool enable
)
258 struct mixer_resources
*res
= &ctx
->mixer_res
;
260 /* block update on vsync */
261 mixer_reg_writemask(res
, MXR_STATUS
, enable
?
262 MXR_STATUS_SYNC_ENABLE
: 0, MXR_STATUS_SYNC_ENABLE
);
265 vp_reg_write(res
, VP_SHADOW_UPDATE
, enable
?
266 VP_SHADOW_UPDATE_ENABLE
: 0);
269 static void mixer_cfg_scan(struct mixer_context
*ctx
, unsigned int height
)
271 struct mixer_resources
*res
= &ctx
->mixer_res
;
274 /* choosing between interlace and progressive mode */
275 val
= (ctx
->interlace
? MXR_CFG_SCAN_INTERLACE
:
276 MXR_CFG_SCAN_PROGRESSIVE
);
278 if (ctx
->mxr_ver
!= MXR_VER_128_0_0_184
) {
279 /* choosing between proper HD and SD mode */
281 val
|= MXR_CFG_SCAN_NTSC
| MXR_CFG_SCAN_SD
;
282 else if (height
<= 576)
283 val
|= MXR_CFG_SCAN_PAL
| MXR_CFG_SCAN_SD
;
284 else if (height
<= 720)
285 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
286 else if (height
<= 1080)
287 val
|= MXR_CFG_SCAN_HD_1080
| MXR_CFG_SCAN_HD
;
289 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
292 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_SCAN_MASK
);
295 static void mixer_cfg_rgb_fmt(struct mixer_context
*ctx
, unsigned int height
)
297 struct mixer_resources
*res
= &ctx
->mixer_res
;
301 val
= MXR_CFG_RGB601_0_255
;
302 } else if (height
== 576) {
303 val
= MXR_CFG_RGB601_0_255
;
304 } else if (height
== 720) {
305 val
= MXR_CFG_RGB709_16_235
;
306 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
307 (1 << 30) | (94 << 20) | (314 << 10) |
309 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
310 (972 << 20) | (851 << 10) | (225 << 0));
311 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
312 (225 << 20) | (820 << 10) | (1004 << 0));
313 } else if (height
== 1080) {
314 val
= MXR_CFG_RGB709_16_235
;
315 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
316 (1 << 30) | (94 << 20) | (314 << 10) |
318 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
319 (972 << 20) | (851 << 10) | (225 << 0));
320 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
321 (225 << 20) | (820 << 10) | (1004 << 0));
323 val
= MXR_CFG_RGB709_16_235
;
324 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
325 (1 << 30) | (94 << 20) | (314 << 10) |
327 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
328 (972 << 20) | (851 << 10) | (225 << 0));
329 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
330 (225 << 20) | (820 << 10) | (1004 << 0));
333 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_RGB_FMT_MASK
);
336 static void mixer_cfg_layer(struct mixer_context
*ctx
, unsigned int win
,
339 struct mixer_resources
*res
= &ctx
->mixer_res
;
340 u32 val
= enable
? ~0 : 0;
344 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP0_ENABLE
);
347 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP1_ENABLE
);
350 if (ctx
->vp_enabled
) {
351 vp_reg_writemask(res
, VP_ENABLE
, val
, VP_ENABLE_ON
);
352 mixer_reg_writemask(res
, MXR_CFG
, val
,
355 /* control blending of graphic layer 0 */
356 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(0), val
,
357 MXR_GRP_CFG_BLEND_PRE_MUL
|
358 MXR_GRP_CFG_PIXEL_BLEND_EN
);
364 static void mixer_run(struct mixer_context
*ctx
)
366 struct mixer_resources
*res
= &ctx
->mixer_res
;
368 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_REG_RUN
);
371 static void mixer_stop(struct mixer_context
*ctx
)
373 struct mixer_resources
*res
= &ctx
->mixer_res
;
376 mixer_reg_writemask(res
, MXR_STATUS
, 0, MXR_STATUS_REG_RUN
);
378 while (!(mixer_reg_read(res
, MXR_STATUS
) & MXR_STATUS_REG_IDLE
) &&
380 usleep_range(10000, 12000);
383 static void vp_video_buffer(struct mixer_context
*ctx
, unsigned int win
)
385 struct mixer_resources
*res
= &ctx
->mixer_res
;
387 struct exynos_drm_plane
*plane
;
388 dma_addr_t luma_addr
[2], chroma_addr
[2];
389 bool tiled_mode
= false;
390 bool crcb_mode
= false;
393 plane
= &ctx
->planes
[win
];
395 switch (plane
->pixel_format
) {
396 case DRM_FORMAT_NV12
:
399 case DRM_FORMAT_NV21
:
403 DRM_ERROR("pixel format for vp is wrong [%d].\n",
404 plane
->pixel_format
);
408 luma_addr
[0] = plane
->dma_addr
[0];
409 chroma_addr
[0] = plane
->dma_addr
[1];
411 if (plane
->scan_flag
& DRM_MODE_FLAG_INTERLACE
) {
412 ctx
->interlace
= true;
414 luma_addr
[1] = luma_addr
[0] + 0x40;
415 chroma_addr
[1] = chroma_addr
[0] + 0x40;
417 luma_addr
[1] = luma_addr
[0] + plane
->pitch
;
418 chroma_addr
[1] = chroma_addr
[0] + plane
->pitch
;
421 ctx
->interlace
= false;
426 spin_lock_irqsave(&res
->reg_slock
, flags
);
427 mixer_vsync_set_update(ctx
, false);
429 /* interlace or progressive scan mode */
430 val
= (ctx
->interlace
? ~0 : 0);
431 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_LINE_SKIP
);
434 val
= (crcb_mode
? VP_MODE_NV21
: VP_MODE_NV12
);
435 val
|= (tiled_mode
? VP_MODE_MEM_TILED
: VP_MODE_MEM_LINEAR
);
436 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_FMT_MASK
);
438 /* setting size of input image */
439 vp_reg_write(res
, VP_IMG_SIZE_Y
, VP_IMG_HSIZE(plane
->pitch
) |
440 VP_IMG_VSIZE(plane
->fb_height
));
441 /* chroma height has to reduced by 2 to avoid chroma distorions */
442 vp_reg_write(res
, VP_IMG_SIZE_C
, VP_IMG_HSIZE(plane
->pitch
) |
443 VP_IMG_VSIZE(plane
->fb_height
/ 2));
445 vp_reg_write(res
, VP_SRC_WIDTH
, plane
->src_width
);
446 vp_reg_write(res
, VP_SRC_HEIGHT
, plane
->src_height
);
447 vp_reg_write(res
, VP_SRC_H_POSITION
,
448 VP_SRC_H_POSITION_VAL(plane
->src_x
));
449 vp_reg_write(res
, VP_SRC_V_POSITION
, plane
->src_y
);
451 vp_reg_write(res
, VP_DST_WIDTH
, plane
->crtc_width
);
452 vp_reg_write(res
, VP_DST_H_POSITION
, plane
->crtc_x
);
453 if (ctx
->interlace
) {
454 vp_reg_write(res
, VP_DST_HEIGHT
, plane
->crtc_height
/ 2);
455 vp_reg_write(res
, VP_DST_V_POSITION
, plane
->crtc_y
/ 2);
457 vp_reg_write(res
, VP_DST_HEIGHT
, plane
->crtc_height
);
458 vp_reg_write(res
, VP_DST_V_POSITION
, plane
->crtc_y
);
461 vp_reg_write(res
, VP_H_RATIO
, plane
->h_ratio
);
462 vp_reg_write(res
, VP_V_RATIO
, plane
->v_ratio
);
464 vp_reg_write(res
, VP_ENDIAN_MODE
, VP_ENDIAN_MODE_LITTLE
);
466 /* set buffer address to vp */
467 vp_reg_write(res
, VP_TOP_Y_PTR
, luma_addr
[0]);
468 vp_reg_write(res
, VP_BOT_Y_PTR
, luma_addr
[1]);
469 vp_reg_write(res
, VP_TOP_C_PTR
, chroma_addr
[0]);
470 vp_reg_write(res
, VP_BOT_C_PTR
, chroma_addr
[1]);
472 mixer_cfg_scan(ctx
, plane
->mode_height
);
473 mixer_cfg_rgb_fmt(ctx
, plane
->mode_height
);
474 mixer_cfg_layer(ctx
, win
, true);
477 mixer_vsync_set_update(ctx
, true);
478 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
480 mixer_regs_dump(ctx
);
484 static void mixer_layer_update(struct mixer_context
*ctx
)
486 struct mixer_resources
*res
= &ctx
->mixer_res
;
488 mixer_reg_writemask(res
, MXR_CFG
, ~0, MXR_CFG_LAYER_UPDATE
);
491 static int mixer_setup_scale(const struct exynos_drm_plane
*plane
,
492 unsigned int *x_ratio
, unsigned int *y_ratio
)
494 if (plane
->crtc_width
!= plane
->src_width
) {
495 if (plane
->crtc_width
== 2 * plane
->src_width
)
501 if (plane
->crtc_height
!= plane
->src_height
) {
502 if (plane
->crtc_height
== 2 * plane
->src_height
)
511 DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n");
515 static void mixer_graph_buffer(struct mixer_context
*ctx
, unsigned int win
)
517 struct mixer_resources
*res
= &ctx
->mixer_res
;
519 struct exynos_drm_plane
*plane
;
520 unsigned int x_ratio
= 0, y_ratio
= 0;
521 unsigned int src_x_offset
, src_y_offset
, dst_x_offset
, dst_y_offset
;
526 plane
= &ctx
->planes
[win
];
528 switch (plane
->pixel_format
) {
529 case DRM_FORMAT_XRGB4444
:
530 fmt
= MXR_FORMAT_ARGB4444
;
533 case DRM_FORMAT_XRGB1555
:
534 fmt
= MXR_FORMAT_ARGB1555
;
537 case DRM_FORMAT_RGB565
:
538 fmt
= MXR_FORMAT_RGB565
;
541 case DRM_FORMAT_XRGB8888
:
542 case DRM_FORMAT_ARGB8888
:
543 fmt
= MXR_FORMAT_ARGB8888
;
547 DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
551 /* check if mixer supports requested scaling setup */
552 if (mixer_setup_scale(plane
, &x_ratio
, &y_ratio
))
555 dst_x_offset
= plane
->crtc_x
;
556 dst_y_offset
= plane
->crtc_y
;
558 /* converting dma address base and source offset */
559 dma_addr
= plane
->dma_addr
[0]
560 + (plane
->src_x
* plane
->bpp
>> 3)
561 + (plane
->src_y
* plane
->pitch
);
565 if (plane
->scan_flag
& DRM_MODE_FLAG_INTERLACE
)
566 ctx
->interlace
= true;
568 ctx
->interlace
= false;
570 spin_lock_irqsave(&res
->reg_slock
, flags
);
571 mixer_vsync_set_update(ctx
, false);
574 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(win
),
575 MXR_GRP_CFG_FORMAT_VAL(fmt
), MXR_GRP_CFG_FORMAT_MASK
);
578 mixer_reg_write(res
, MXR_GRAPHIC_SPAN(win
),
579 plane
->pitch
/ (plane
->bpp
>> 3));
581 /* setup display size */
582 if (ctx
->mxr_ver
== MXR_VER_128_0_0_184
&&
583 win
== MIXER_DEFAULT_WIN
) {
584 val
= MXR_MXR_RES_HEIGHT(plane
->mode_height
);
585 val
|= MXR_MXR_RES_WIDTH(plane
->mode_width
);
586 mixer_reg_write(res
, MXR_RESOLUTION
, val
);
589 val
= MXR_GRP_WH_WIDTH(plane
->src_width
);
590 val
|= MXR_GRP_WH_HEIGHT(plane
->src_height
);
591 val
|= MXR_GRP_WH_H_SCALE(x_ratio
);
592 val
|= MXR_GRP_WH_V_SCALE(y_ratio
);
593 mixer_reg_write(res
, MXR_GRAPHIC_WH(win
), val
);
595 /* setup offsets in source image */
596 val
= MXR_GRP_SXY_SX(src_x_offset
);
597 val
|= MXR_GRP_SXY_SY(src_y_offset
);
598 mixer_reg_write(res
, MXR_GRAPHIC_SXY(win
), val
);
600 /* setup offsets in display image */
601 val
= MXR_GRP_DXY_DX(dst_x_offset
);
602 val
|= MXR_GRP_DXY_DY(dst_y_offset
);
603 mixer_reg_write(res
, MXR_GRAPHIC_DXY(win
), val
);
605 /* set buffer address to mixer */
606 mixer_reg_write(res
, MXR_GRAPHIC_BASE(win
), dma_addr
);
608 mixer_cfg_scan(ctx
, plane
->mode_height
);
609 mixer_cfg_rgb_fmt(ctx
, plane
->mode_height
);
610 mixer_cfg_layer(ctx
, win
, true);
612 /* layer update mandatory for mixer 16.0.33.0 */
613 if (ctx
->mxr_ver
== MXR_VER_16_0_33_0
||
614 ctx
->mxr_ver
== MXR_VER_128_0_0_184
)
615 mixer_layer_update(ctx
);
619 mixer_vsync_set_update(ctx
, true);
620 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
622 mixer_regs_dump(ctx
);
625 static void vp_win_reset(struct mixer_context
*ctx
)
627 struct mixer_resources
*res
= &ctx
->mixer_res
;
630 vp_reg_write(res
, VP_SRESET
, VP_SRESET_PROCESSING
);
631 for (tries
= 100; tries
; --tries
) {
632 /* waiting until VP_SRESET_PROCESSING is 0 */
633 if (~vp_reg_read(res
, VP_SRESET
) & VP_SRESET_PROCESSING
)
635 usleep_range(10000, 12000);
637 WARN(tries
== 0, "failed to reset Video Processor\n");
640 static void mixer_win_reset(struct mixer_context
*ctx
)
642 struct mixer_resources
*res
= &ctx
->mixer_res
;
644 u32 val
; /* value stored to register */
646 spin_lock_irqsave(&res
->reg_slock
, flags
);
647 mixer_vsync_set_update(ctx
, false);
649 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_DST_HDMI
, MXR_CFG_DST_MASK
);
651 /* set output in RGB888 mode */
652 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_OUT_RGB888
, MXR_CFG_OUT_MASK
);
654 /* 16 beat burst in DMA */
655 mixer_reg_writemask(res
, MXR_STATUS
, MXR_STATUS_16_BURST
,
656 MXR_STATUS_BURST_MASK
);
658 /* setting default layer priority: layer1 > layer0 > video
659 * because typical usage scenario would be
661 * layer0 - framebuffer
662 * video - video overlay
664 val
= MXR_LAYER_CFG_GRP1_VAL(3);
665 val
|= MXR_LAYER_CFG_GRP0_VAL(2);
667 val
|= MXR_LAYER_CFG_VP_VAL(1);
668 mixer_reg_write(res
, MXR_LAYER_CFG
, val
);
670 /* setting background color */
671 mixer_reg_write(res
, MXR_BG_COLOR0
, 0x008080);
672 mixer_reg_write(res
, MXR_BG_COLOR1
, 0x008080);
673 mixer_reg_write(res
, MXR_BG_COLOR2
, 0x008080);
675 /* setting graphical layers */
676 val
= MXR_GRP_CFG_COLOR_KEY_DISABLE
; /* no blank key */
677 val
|= MXR_GRP_CFG_WIN_BLEND_EN
;
678 val
|= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
680 /* Don't blend layer 0 onto the mixer background */
681 mixer_reg_write(res
, MXR_GRAPHIC_CFG(0), val
);
683 /* Blend layer 1 into layer 0 */
684 val
|= MXR_GRP_CFG_BLEND_PRE_MUL
;
685 val
|= MXR_GRP_CFG_PIXEL_BLEND_EN
;
686 mixer_reg_write(res
, MXR_GRAPHIC_CFG(1), val
);
688 /* setting video layers */
689 val
= MXR_GRP_CFG_ALPHA_VAL(0);
690 mixer_reg_write(res
, MXR_VIDEO_CFG
, val
);
692 if (ctx
->vp_enabled
) {
693 /* configuration of Video Processor Registers */
695 vp_default_filter(res
);
698 /* disable all layers */
699 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP0_ENABLE
);
700 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP1_ENABLE
);
702 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_VP_ENABLE
);
704 mixer_vsync_set_update(ctx
, true);
705 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
708 static irqreturn_t
mixer_irq_handler(int irq
, void *arg
)
710 struct mixer_context
*ctx
= arg
;
711 struct mixer_resources
*res
= &ctx
->mixer_res
;
712 u32 val
, base
, shadow
;
714 spin_lock(&res
->reg_slock
);
716 /* read interrupt status for handling and clearing flags for VSYNC */
717 val
= mixer_reg_read(res
, MXR_INT_STATUS
);
720 if (val
& MXR_INT_STATUS_VSYNC
) {
721 /* vsync interrupt use different bit for read and clear */
722 val
|= MXR_INT_CLEAR_VSYNC
;
723 val
&= ~MXR_INT_STATUS_VSYNC
;
725 /* interlace scan need to check shadow register */
726 if (ctx
->interlace
) {
727 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(0));
728 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(0));
732 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(1));
733 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(1));
738 drm_handle_vblank(ctx
->drm_dev
, ctx
->pipe
);
739 exynos_drm_crtc_finish_pageflip(ctx
->drm_dev
, ctx
->pipe
);
741 /* set wait vsync event to zero and wake up queue. */
742 if (atomic_read(&ctx
->wait_vsync_event
)) {
743 atomic_set(&ctx
->wait_vsync_event
, 0);
744 wake_up(&ctx
->wait_vsync_queue
);
749 /* clear interrupts */
750 mixer_reg_write(res
, MXR_INT_STATUS
, val
);
752 spin_unlock(&res
->reg_slock
);
757 static int mixer_resources_init(struct mixer_context
*mixer_ctx
)
759 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
760 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
761 struct resource
*res
;
764 spin_lock_init(&mixer_res
->reg_slock
);
766 mixer_res
->mixer
= devm_clk_get(dev
, "mixer");
767 if (IS_ERR(mixer_res
->mixer
)) {
768 dev_err(dev
, "failed to get clock 'mixer'\n");
772 mixer_res
->hdmi
= devm_clk_get(dev
, "hdmi");
773 if (IS_ERR(mixer_res
->hdmi
)) {
774 dev_err(dev
, "failed to get clock 'hdmi'\n");
775 return PTR_ERR(mixer_res
->hdmi
);
778 mixer_res
->sclk_hdmi
= devm_clk_get(dev
, "sclk_hdmi");
779 if (IS_ERR(mixer_res
->sclk_hdmi
)) {
780 dev_err(dev
, "failed to get clock 'sclk_hdmi'\n");
783 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 0);
785 dev_err(dev
, "get memory resource failed.\n");
789 mixer_res
->mixer_regs
= devm_ioremap(dev
, res
->start
,
791 if (mixer_res
->mixer_regs
== NULL
) {
792 dev_err(dev
, "register mapping failed.\n");
796 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_IRQ
, 0);
798 dev_err(dev
, "get interrupt resource failed.\n");
802 ret
= devm_request_irq(dev
, res
->start
, mixer_irq_handler
,
803 0, "drm_mixer", mixer_ctx
);
805 dev_err(dev
, "request interrupt failed.\n");
808 mixer_res
->irq
= res
->start
;
813 static int vp_resources_init(struct mixer_context
*mixer_ctx
)
815 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
816 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
817 struct resource
*res
;
819 mixer_res
->vp
= devm_clk_get(dev
, "vp");
820 if (IS_ERR(mixer_res
->vp
)) {
821 dev_err(dev
, "failed to get clock 'vp'\n");
825 if (mixer_ctx
->has_sclk
) {
826 mixer_res
->sclk_mixer
= devm_clk_get(dev
, "sclk_mixer");
827 if (IS_ERR(mixer_res
->sclk_mixer
)) {
828 dev_err(dev
, "failed to get clock 'sclk_mixer'\n");
831 mixer_res
->mout_mixer
= devm_clk_get(dev
, "mout_mixer");
832 if (IS_ERR(mixer_res
->mout_mixer
)) {
833 dev_err(dev
, "failed to get clock 'mout_mixer'\n");
837 if (mixer_res
->sclk_hdmi
&& mixer_res
->mout_mixer
)
838 clk_set_parent(mixer_res
->mout_mixer
,
839 mixer_res
->sclk_hdmi
);
842 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 1);
844 dev_err(dev
, "get memory resource failed.\n");
848 mixer_res
->vp_regs
= devm_ioremap(dev
, res
->start
,
850 if (mixer_res
->vp_regs
== NULL
) {
851 dev_err(dev
, "register mapping failed.\n");
858 static int mixer_initialize(struct mixer_context
*mixer_ctx
,
859 struct drm_device
*drm_dev
)
862 struct exynos_drm_private
*priv
;
863 priv
= drm_dev
->dev_private
;
865 mixer_ctx
->drm_dev
= drm_dev
;
866 mixer_ctx
->pipe
= priv
->pipe
++;
868 /* acquire resources: regs, irqs, clocks */
869 ret
= mixer_resources_init(mixer_ctx
);
871 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret
);
875 if (mixer_ctx
->vp_enabled
) {
876 /* acquire vp resources: regs, irqs, clocks */
877 ret
= vp_resources_init(mixer_ctx
);
879 DRM_ERROR("vp_resources_init failed ret=%d\n", ret
);
884 ret
= drm_iommu_attach_device_if_possible(mixer_ctx
->crtc
, drm_dev
,
892 static void mixer_ctx_remove(struct mixer_context
*mixer_ctx
)
894 if (is_drm_iommu_supported(mixer_ctx
->drm_dev
))
895 drm_iommu_detach_device(mixer_ctx
->drm_dev
, mixer_ctx
->dev
);
898 static int mixer_enable_vblank(struct exynos_drm_crtc
*crtc
)
900 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
901 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
903 if (!mixer_ctx
->powered
) {
904 mixer_ctx
->int_en
|= MXR_INT_EN_VSYNC
;
908 /* enable vsync interrupt */
909 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
910 mixer_reg_writemask(res
, MXR_INT_EN
, ~0, MXR_INT_EN_VSYNC
);
915 static void mixer_disable_vblank(struct exynos_drm_crtc
*crtc
)
917 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
918 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
920 if (!mixer_ctx
->powered
) {
921 mixer_ctx
->int_en
&= MXR_INT_EN_VSYNC
;
925 /* disable vsync interrupt */
926 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
927 mixer_reg_writemask(res
, MXR_INT_EN
, 0, MXR_INT_EN_VSYNC
);
930 static void mixer_win_commit(struct exynos_drm_crtc
*crtc
, unsigned int win
)
932 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
934 DRM_DEBUG_KMS("win: %d\n", win
);
936 mutex_lock(&mixer_ctx
->mixer_mutex
);
937 if (!mixer_ctx
->powered
) {
938 mutex_unlock(&mixer_ctx
->mixer_mutex
);
941 mutex_unlock(&mixer_ctx
->mixer_mutex
);
943 if (win
> 1 && mixer_ctx
->vp_enabled
)
944 vp_video_buffer(mixer_ctx
, win
);
946 mixer_graph_buffer(mixer_ctx
, win
);
949 static void mixer_win_disable(struct exynos_drm_crtc
*crtc
, unsigned int win
)
951 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
952 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
955 DRM_DEBUG_KMS("win: %d\n", win
);
957 mutex_lock(&mixer_ctx
->mixer_mutex
);
958 if (!mixer_ctx
->powered
) {
959 mutex_unlock(&mixer_ctx
->mixer_mutex
);
962 mutex_unlock(&mixer_ctx
->mixer_mutex
);
964 spin_lock_irqsave(&res
->reg_slock
, flags
);
965 mixer_vsync_set_update(mixer_ctx
, false);
967 mixer_cfg_layer(mixer_ctx
, win
, false);
969 mixer_vsync_set_update(mixer_ctx
, true);
970 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
973 static void mixer_wait_for_vblank(struct exynos_drm_crtc
*crtc
)
975 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
978 mutex_lock(&mixer_ctx
->mixer_mutex
);
979 if (!mixer_ctx
->powered
) {
980 mutex_unlock(&mixer_ctx
->mixer_mutex
);
983 mutex_unlock(&mixer_ctx
->mixer_mutex
);
985 err
= drm_vblank_get(mixer_ctx
->drm_dev
, mixer_ctx
->pipe
);
987 DRM_DEBUG_KMS("failed to acquire vblank counter\n");
991 atomic_set(&mixer_ctx
->wait_vsync_event
, 1);
994 * wait for MIXER to signal VSYNC interrupt or return after
995 * timeout which is set to 50ms (refresh rate of 20).
997 if (!wait_event_timeout(mixer_ctx
->wait_vsync_queue
,
998 !atomic_read(&mixer_ctx
->wait_vsync_event
),
1000 DRM_DEBUG_KMS("vblank wait timed out.\n");
1002 drm_vblank_put(mixer_ctx
->drm_dev
, mixer_ctx
->pipe
);
1005 static void mixer_enable(struct exynos_drm_crtc
*crtc
)
1007 struct mixer_context
*ctx
= crtc
->ctx
;
1008 struct mixer_resources
*res
= &ctx
->mixer_res
;
1011 mutex_lock(&ctx
->mixer_mutex
);
1013 mutex_unlock(&ctx
->mixer_mutex
);
1017 mutex_unlock(&ctx
->mixer_mutex
);
1019 pm_runtime_get_sync(ctx
->dev
);
1021 ret
= clk_prepare_enable(res
->mixer
);
1023 DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret
);
1026 ret
= clk_prepare_enable(res
->hdmi
);
1028 DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret
);
1031 if (ctx
->vp_enabled
) {
1032 ret
= clk_prepare_enable(res
->vp
);
1034 DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
1038 if (ctx
->has_sclk
) {
1039 ret
= clk_prepare_enable(res
->sclk_mixer
);
1041 DRM_ERROR("Failed to prepare_enable the " \
1042 "sclk_mixer clk [%d]\n",
1049 mutex_lock(&ctx
->mixer_mutex
);
1050 ctx
->powered
= true;
1051 mutex_unlock(&ctx
->mixer_mutex
);
1053 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_SOFT_RESET
);
1055 if (ctx
->int_en
& MXR_INT_EN_VSYNC
)
1056 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
1057 mixer_reg_write(res
, MXR_INT_EN
, ctx
->int_en
);
1058 mixer_win_reset(ctx
);
1061 static void mixer_disable(struct exynos_drm_crtc
*crtc
)
1063 struct mixer_context
*ctx
= crtc
->ctx
;
1064 struct mixer_resources
*res
= &ctx
->mixer_res
;
1067 mutex_lock(&ctx
->mixer_mutex
);
1068 if (!ctx
->powered
) {
1069 mutex_unlock(&ctx
->mixer_mutex
);
1072 mutex_unlock(&ctx
->mixer_mutex
);
1075 mixer_regs_dump(ctx
);
1077 for (i
= 0; i
< MIXER_WIN_NR
; i
++)
1078 mixer_win_disable(crtc
, i
);
1080 ctx
->int_en
= mixer_reg_read(res
, MXR_INT_EN
);
1082 mutex_lock(&ctx
->mixer_mutex
);
1083 ctx
->powered
= false;
1084 mutex_unlock(&ctx
->mixer_mutex
);
1086 clk_disable_unprepare(res
->hdmi
);
1087 clk_disable_unprepare(res
->mixer
);
1088 if (ctx
->vp_enabled
) {
1089 clk_disable_unprepare(res
->vp
);
1091 clk_disable_unprepare(res
->sclk_mixer
);
1094 pm_runtime_put_sync(ctx
->dev
);
1097 /* Only valid for Mixer version 16.0.33.0 */
1098 int mixer_check_mode(struct drm_display_mode
*mode
)
1105 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1106 mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
,
1107 (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0);
1109 if ((w
>= 464 && w
<= 720 && h
>= 261 && h
<= 576) ||
1110 (w
>= 1024 && w
<= 1280 && h
>= 576 && h
<= 720) ||
1111 (w
>= 1664 && w
<= 1920 && h
>= 936 && h
<= 1080))
1117 static const struct exynos_drm_crtc_ops mixer_crtc_ops
= {
1118 .enable
= mixer_enable
,
1119 .disable
= mixer_disable
,
1120 .enable_vblank
= mixer_enable_vblank
,
1121 .disable_vblank
= mixer_disable_vblank
,
1122 .wait_for_vblank
= mixer_wait_for_vblank
,
1123 .win_commit
= mixer_win_commit
,
1124 .win_disable
= mixer_win_disable
,
1127 static struct mixer_drv_data exynos5420_mxr_drv_data
= {
1128 .version
= MXR_VER_128_0_0_184
,
1132 static struct mixer_drv_data exynos5250_mxr_drv_data
= {
1133 .version
= MXR_VER_16_0_33_0
,
1137 static struct mixer_drv_data exynos4212_mxr_drv_data
= {
1138 .version
= MXR_VER_0_0_0_16
,
1142 static struct mixer_drv_data exynos4210_mxr_drv_data
= {
1143 .version
= MXR_VER_0_0_0_16
,
1148 static const struct platform_device_id mixer_driver_types
[] = {
1150 .name
= "s5p-mixer",
1151 .driver_data
= (unsigned long)&exynos4210_mxr_drv_data
,
1153 .name
= "exynos5-mixer",
1154 .driver_data
= (unsigned long)&exynos5250_mxr_drv_data
,
1160 static struct of_device_id mixer_match_types
[] = {
1162 .compatible
= "samsung,exynos4210-mixer",
1163 .data
= &exynos4210_mxr_drv_data
,
1165 .compatible
= "samsung,exynos4212-mixer",
1166 .data
= &exynos4212_mxr_drv_data
,
1168 .compatible
= "samsung,exynos5-mixer",
1169 .data
= &exynos5250_mxr_drv_data
,
1171 .compatible
= "samsung,exynos5250-mixer",
1172 .data
= &exynos5250_mxr_drv_data
,
1174 .compatible
= "samsung,exynos5420-mixer",
1175 .data
= &exynos5420_mxr_drv_data
,
1180 MODULE_DEVICE_TABLE(of
, mixer_match_types
);
1182 static int mixer_bind(struct device
*dev
, struct device
*manager
, void *data
)
1184 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1185 struct drm_device
*drm_dev
= data
;
1186 struct exynos_drm_plane
*exynos_plane
;
1187 enum drm_plane_type type
;
1191 ret
= mixer_initialize(ctx
, drm_dev
);
1195 for (zpos
= 0; zpos
< MIXER_WIN_NR
; zpos
++) {
1196 type
= (zpos
== MIXER_DEFAULT_WIN
) ? DRM_PLANE_TYPE_PRIMARY
:
1197 DRM_PLANE_TYPE_OVERLAY
;
1198 ret
= exynos_plane_init(drm_dev
, &ctx
->planes
[zpos
],
1199 1 << ctx
->pipe
, type
, zpos
);
1204 exynos_plane
= &ctx
->planes
[MIXER_DEFAULT_WIN
];
1205 ctx
->crtc
= exynos_drm_crtc_create(drm_dev
, &exynos_plane
->base
,
1206 ctx
->pipe
, EXYNOS_DISPLAY_TYPE_HDMI
,
1207 &mixer_crtc_ops
, ctx
);
1208 if (IS_ERR(ctx
->crtc
)) {
1209 mixer_ctx_remove(ctx
);
1210 ret
= PTR_ERR(ctx
->crtc
);
1217 devm_kfree(dev
, ctx
);
1221 static void mixer_unbind(struct device
*dev
, struct device
*master
, void *data
)
1223 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1225 mixer_ctx_remove(ctx
);
1228 static const struct component_ops mixer_component_ops
= {
1230 .unbind
= mixer_unbind
,
1233 static int mixer_probe(struct platform_device
*pdev
)
1235 struct device
*dev
= &pdev
->dev
;
1236 struct mixer_drv_data
*drv
;
1237 struct mixer_context
*ctx
;
1240 ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
), GFP_KERNEL
);
1242 DRM_ERROR("failed to alloc mixer context.\n");
1246 mutex_init(&ctx
->mixer_mutex
);
1249 const struct of_device_id
*match
;
1251 match
= of_match_node(mixer_match_types
, dev
->of_node
);
1252 drv
= (struct mixer_drv_data
*)match
->data
;
1254 drv
= (struct mixer_drv_data
*)
1255 platform_get_device_id(pdev
)->driver_data
;
1260 ctx
->vp_enabled
= drv
->is_vp_enabled
;
1261 ctx
->has_sclk
= drv
->has_sclk
;
1262 ctx
->mxr_ver
= drv
->version
;
1263 init_waitqueue_head(&ctx
->wait_vsync_queue
);
1264 atomic_set(&ctx
->wait_vsync_event
, 0);
1266 platform_set_drvdata(pdev
, ctx
);
1268 ret
= component_add(&pdev
->dev
, &mixer_component_ops
);
1270 pm_runtime_enable(dev
);
1275 static int mixer_remove(struct platform_device
*pdev
)
1277 pm_runtime_disable(&pdev
->dev
);
1279 component_del(&pdev
->dev
, &mixer_component_ops
);
1284 struct platform_driver mixer_driver
= {
1286 .name
= "exynos-mixer",
1287 .owner
= THIS_MODULE
,
1288 .of_match_table
= mixer_match_types
,
1290 .probe
= mixer_probe
,
1291 .remove
= mixer_remove
,
1292 .id_table
= mixer_driver_types
,