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_fb.h"
41 #include "exynos_drm_plane.h"
42 #include "exynos_drm_iommu.h"
44 #define MIXER_WIN_NR 3
45 #define VP_DEFAULT_WIN 2
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 enum mixer_flag_bits
{
77 static const uint32_t mixer_formats
[] = {
85 static const uint32_t vp_formats
[] = {
90 struct mixer_context
{
91 struct platform_device
*pdev
;
93 struct drm_device
*drm_dev
;
94 struct exynos_drm_crtc
*crtc
;
95 struct exynos_drm_plane planes
[MIXER_WIN_NR
];
102 struct mixer_resources mixer_res
;
103 enum mixer_version_id mxr_ver
;
104 wait_queue_head_t wait_vsync_queue
;
105 atomic_t wait_vsync_event
;
108 struct mixer_drv_data
{
109 enum mixer_version_id version
;
114 static const struct exynos_drm_plane_config plane_configs
[MIXER_WIN_NR
] = {
117 .type
= DRM_PLANE_TYPE_PRIMARY
,
118 .pixel_formats
= mixer_formats
,
119 .num_pixel_formats
= ARRAY_SIZE(mixer_formats
),
120 .capabilities
= EXYNOS_DRM_PLANE_CAP_DOUBLE
,
123 .type
= DRM_PLANE_TYPE_CURSOR
,
124 .pixel_formats
= mixer_formats
,
125 .num_pixel_formats
= ARRAY_SIZE(mixer_formats
),
126 .capabilities
= EXYNOS_DRM_PLANE_CAP_DOUBLE
,
129 .type
= DRM_PLANE_TYPE_OVERLAY
,
130 .pixel_formats
= vp_formats
,
131 .num_pixel_formats
= ARRAY_SIZE(vp_formats
),
132 .capabilities
= EXYNOS_DRM_PLANE_CAP_SCALE
,
136 static const u8 filter_y_horiz_tap8
[] = {
137 0, -1, -1, -1, -1, -1, -1, -1,
138 -1, -1, -1, -1, -1, 0, 0, 0,
139 0, 2, 4, 5, 6, 6, 6, 6,
140 6, 5, 5, 4, 3, 2, 1, 1,
141 0, -6, -12, -16, -18, -20, -21, -20,
142 -20, -18, -16, -13, -10, -8, -5, -2,
143 127, 126, 125, 121, 114, 107, 99, 89,
144 79, 68, 57, 46, 35, 25, 16, 8,
147 static const u8 filter_y_vert_tap4
[] = {
148 0, -3, -6, -8, -8, -8, -8, -7,
149 -6, -5, -4, -3, -2, -1, -1, 0,
150 127, 126, 124, 118, 111, 102, 92, 81,
151 70, 59, 48, 37, 27, 19, 11, 5,
152 0, 5, 11, 19, 27, 37, 48, 59,
153 70, 81, 92, 102, 111, 118, 124, 126,
154 0, 0, -1, -1, -2, -3, -4, -5,
155 -6, -7, -8, -8, -8, -8, -6, -3,
158 static const u8 filter_cr_horiz_tap4
[] = {
159 0, -3, -6, -8, -8, -8, -8, -7,
160 -6, -5, -4, -3, -2, -1, -1, 0,
161 127, 126, 124, 118, 111, 102, 92, 81,
162 70, 59, 48, 37, 27, 19, 11, 5,
165 static inline u32
vp_reg_read(struct mixer_resources
*res
, u32 reg_id
)
167 return readl(res
->vp_regs
+ reg_id
);
170 static inline void vp_reg_write(struct mixer_resources
*res
, u32 reg_id
,
173 writel(val
, res
->vp_regs
+ reg_id
);
176 static inline void vp_reg_writemask(struct mixer_resources
*res
, u32 reg_id
,
179 u32 old
= vp_reg_read(res
, reg_id
);
181 val
= (val
& mask
) | (old
& ~mask
);
182 writel(val
, res
->vp_regs
+ reg_id
);
185 static inline u32
mixer_reg_read(struct mixer_resources
*res
, u32 reg_id
)
187 return readl(res
->mixer_regs
+ reg_id
);
190 static inline void mixer_reg_write(struct mixer_resources
*res
, u32 reg_id
,
193 writel(val
, res
->mixer_regs
+ reg_id
);
196 static inline void mixer_reg_writemask(struct mixer_resources
*res
,
197 u32 reg_id
, u32 val
, u32 mask
)
199 u32 old
= mixer_reg_read(res
, reg_id
);
201 val
= (val
& mask
) | (old
& ~mask
);
202 writel(val
, res
->mixer_regs
+ reg_id
);
205 static void mixer_regs_dump(struct mixer_context
*ctx
)
207 #define DUMPREG(reg_id) \
209 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
210 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
216 DUMPREG(MXR_INT_STATUS
);
218 DUMPREG(MXR_LAYER_CFG
);
219 DUMPREG(MXR_VIDEO_CFG
);
221 DUMPREG(MXR_GRAPHIC0_CFG
);
222 DUMPREG(MXR_GRAPHIC0_BASE
);
223 DUMPREG(MXR_GRAPHIC0_SPAN
);
224 DUMPREG(MXR_GRAPHIC0_WH
);
225 DUMPREG(MXR_GRAPHIC0_SXY
);
226 DUMPREG(MXR_GRAPHIC0_DXY
);
228 DUMPREG(MXR_GRAPHIC1_CFG
);
229 DUMPREG(MXR_GRAPHIC1_BASE
);
230 DUMPREG(MXR_GRAPHIC1_SPAN
);
231 DUMPREG(MXR_GRAPHIC1_WH
);
232 DUMPREG(MXR_GRAPHIC1_SXY
);
233 DUMPREG(MXR_GRAPHIC1_DXY
);
237 static void vp_regs_dump(struct mixer_context
*ctx
)
239 #define DUMPREG(reg_id) \
241 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
242 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
247 DUMPREG(VP_SHADOW_UPDATE
);
248 DUMPREG(VP_FIELD_ID
);
250 DUMPREG(VP_IMG_SIZE_Y
);
251 DUMPREG(VP_IMG_SIZE_C
);
252 DUMPREG(VP_PER_RATE_CTRL
);
253 DUMPREG(VP_TOP_Y_PTR
);
254 DUMPREG(VP_BOT_Y_PTR
);
255 DUMPREG(VP_TOP_C_PTR
);
256 DUMPREG(VP_BOT_C_PTR
);
257 DUMPREG(VP_ENDIAN_MODE
);
258 DUMPREG(VP_SRC_H_POSITION
);
259 DUMPREG(VP_SRC_V_POSITION
);
260 DUMPREG(VP_SRC_WIDTH
);
261 DUMPREG(VP_SRC_HEIGHT
);
262 DUMPREG(VP_DST_H_POSITION
);
263 DUMPREG(VP_DST_V_POSITION
);
264 DUMPREG(VP_DST_WIDTH
);
265 DUMPREG(VP_DST_HEIGHT
);
272 static inline void vp_filter_set(struct mixer_resources
*res
,
273 int reg_id
, const u8
*data
, unsigned int size
)
275 /* assure 4-byte align */
277 for (; size
; size
-= 4, reg_id
+= 4, data
+= 4) {
278 u32 val
= (data
[0] << 24) | (data
[1] << 16) |
279 (data
[2] << 8) | data
[3];
280 vp_reg_write(res
, reg_id
, val
);
284 static void vp_default_filter(struct mixer_resources
*res
)
286 vp_filter_set(res
, VP_POLY8_Y0_LL
,
287 filter_y_horiz_tap8
, sizeof(filter_y_horiz_tap8
));
288 vp_filter_set(res
, VP_POLY4_Y0_LL
,
289 filter_y_vert_tap4
, sizeof(filter_y_vert_tap4
));
290 vp_filter_set(res
, VP_POLY4_C0_LL
,
291 filter_cr_horiz_tap4
, sizeof(filter_cr_horiz_tap4
));
294 static void mixer_vsync_set_update(struct mixer_context
*ctx
, bool enable
)
296 struct mixer_resources
*res
= &ctx
->mixer_res
;
298 /* block update on vsync */
299 mixer_reg_writemask(res
, MXR_STATUS
, enable
?
300 MXR_STATUS_SYNC_ENABLE
: 0, MXR_STATUS_SYNC_ENABLE
);
303 vp_reg_write(res
, VP_SHADOW_UPDATE
, enable
?
304 VP_SHADOW_UPDATE_ENABLE
: 0);
307 static void mixer_cfg_scan(struct mixer_context
*ctx
, unsigned int height
)
309 struct mixer_resources
*res
= &ctx
->mixer_res
;
312 /* choosing between interlace and progressive mode */
313 val
= (ctx
->interlace
? MXR_CFG_SCAN_INTERLACE
:
314 MXR_CFG_SCAN_PROGRESSIVE
);
316 if (ctx
->mxr_ver
!= MXR_VER_128_0_0_184
) {
317 /* choosing between proper HD and SD mode */
319 val
|= MXR_CFG_SCAN_NTSC
| MXR_CFG_SCAN_SD
;
320 else if (height
<= 576)
321 val
|= MXR_CFG_SCAN_PAL
| MXR_CFG_SCAN_SD
;
322 else if (height
<= 720)
323 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
324 else if (height
<= 1080)
325 val
|= MXR_CFG_SCAN_HD_1080
| MXR_CFG_SCAN_HD
;
327 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
330 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_SCAN_MASK
);
333 static void mixer_cfg_rgb_fmt(struct mixer_context
*ctx
, unsigned int height
)
335 struct mixer_resources
*res
= &ctx
->mixer_res
;
339 val
= MXR_CFG_RGB601_0_255
;
340 } else if (height
== 576) {
341 val
= MXR_CFG_RGB601_0_255
;
342 } else if (height
== 720) {
343 val
= MXR_CFG_RGB709_16_235
;
344 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
345 (1 << 30) | (94 << 20) | (314 << 10) |
347 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
348 (972 << 20) | (851 << 10) | (225 << 0));
349 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
350 (225 << 20) | (820 << 10) | (1004 << 0));
351 } else if (height
== 1080) {
352 val
= MXR_CFG_RGB709_16_235
;
353 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
354 (1 << 30) | (94 << 20) | (314 << 10) |
356 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
357 (972 << 20) | (851 << 10) | (225 << 0));
358 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
359 (225 << 20) | (820 << 10) | (1004 << 0));
361 val
= MXR_CFG_RGB709_16_235
;
362 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
363 (1 << 30) | (94 << 20) | (314 << 10) |
365 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
366 (972 << 20) | (851 << 10) | (225 << 0));
367 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
368 (225 << 20) | (820 << 10) | (1004 << 0));
371 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_RGB_FMT_MASK
);
374 static void mixer_cfg_layer(struct mixer_context
*ctx
, unsigned int win
,
377 struct mixer_resources
*res
= &ctx
->mixer_res
;
378 u32 val
= enable
? ~0 : 0;
382 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP0_ENABLE
);
385 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP1_ENABLE
);
388 if (ctx
->vp_enabled
) {
389 vp_reg_writemask(res
, VP_ENABLE
, val
, VP_ENABLE_ON
);
390 mixer_reg_writemask(res
, MXR_CFG
, val
,
393 /* control blending of graphic layer 0 */
394 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(0), val
,
395 MXR_GRP_CFG_BLEND_PRE_MUL
|
396 MXR_GRP_CFG_PIXEL_BLEND_EN
);
402 static void mixer_run(struct mixer_context
*ctx
)
404 struct mixer_resources
*res
= &ctx
->mixer_res
;
406 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_REG_RUN
);
409 static void mixer_stop(struct mixer_context
*ctx
)
411 struct mixer_resources
*res
= &ctx
->mixer_res
;
414 mixer_reg_writemask(res
, MXR_STATUS
, 0, MXR_STATUS_REG_RUN
);
416 while (!(mixer_reg_read(res
, MXR_STATUS
) & MXR_STATUS_REG_IDLE
) &&
418 usleep_range(10000, 12000);
421 static void vp_video_buffer(struct mixer_context
*ctx
,
422 struct exynos_drm_plane
*plane
)
424 struct exynos_drm_plane_state
*state
=
425 to_exynos_plane_state(plane
->base
.state
);
426 struct drm_display_mode
*mode
= &state
->base
.crtc
->state
->adjusted_mode
;
427 struct mixer_resources
*res
= &ctx
->mixer_res
;
428 struct drm_framebuffer
*fb
= state
->base
.fb
;
430 dma_addr_t luma_addr
[2], chroma_addr
[2];
431 bool tiled_mode
= false;
432 bool crcb_mode
= false;
435 switch (fb
->pixel_format
) {
436 case DRM_FORMAT_NV12
:
439 case DRM_FORMAT_NV21
:
443 DRM_ERROR("pixel format for vp is wrong [%d].\n",
448 luma_addr
[0] = exynos_drm_fb_dma_addr(fb
, 0);
449 chroma_addr
[0] = exynos_drm_fb_dma_addr(fb
, 1);
451 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) {
452 ctx
->interlace
= true;
454 luma_addr
[1] = luma_addr
[0] + 0x40;
455 chroma_addr
[1] = chroma_addr
[0] + 0x40;
457 luma_addr
[1] = luma_addr
[0] + fb
->pitches
[0];
458 chroma_addr
[1] = chroma_addr
[0] + fb
->pitches
[0];
461 ctx
->interlace
= false;
466 spin_lock_irqsave(&res
->reg_slock
, flags
);
467 mixer_vsync_set_update(ctx
, false);
469 /* interlace or progressive scan mode */
470 val
= (ctx
->interlace
? ~0 : 0);
471 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_LINE_SKIP
);
474 val
= (crcb_mode
? VP_MODE_NV21
: VP_MODE_NV12
);
475 val
|= (tiled_mode
? VP_MODE_MEM_TILED
: VP_MODE_MEM_LINEAR
);
476 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_FMT_MASK
);
478 /* setting size of input image */
479 vp_reg_write(res
, VP_IMG_SIZE_Y
, VP_IMG_HSIZE(fb
->pitches
[0]) |
480 VP_IMG_VSIZE(fb
->height
));
481 /* chroma height has to reduced by 2 to avoid chroma distorions */
482 vp_reg_write(res
, VP_IMG_SIZE_C
, VP_IMG_HSIZE(fb
->pitches
[0]) |
483 VP_IMG_VSIZE(fb
->height
/ 2));
485 vp_reg_write(res
, VP_SRC_WIDTH
, state
->src
.w
);
486 vp_reg_write(res
, VP_SRC_HEIGHT
, state
->src
.h
);
487 vp_reg_write(res
, VP_SRC_H_POSITION
,
488 VP_SRC_H_POSITION_VAL(state
->src
.x
));
489 vp_reg_write(res
, VP_SRC_V_POSITION
, state
->src
.y
);
491 vp_reg_write(res
, VP_DST_WIDTH
, state
->crtc
.w
);
492 vp_reg_write(res
, VP_DST_H_POSITION
, state
->crtc
.x
);
493 if (ctx
->interlace
) {
494 vp_reg_write(res
, VP_DST_HEIGHT
, state
->crtc
.h
/ 2);
495 vp_reg_write(res
, VP_DST_V_POSITION
, state
->crtc
.y
/ 2);
497 vp_reg_write(res
, VP_DST_HEIGHT
, state
->crtc
.h
);
498 vp_reg_write(res
, VP_DST_V_POSITION
, state
->crtc
.y
);
501 vp_reg_write(res
, VP_H_RATIO
, state
->h_ratio
);
502 vp_reg_write(res
, VP_V_RATIO
, state
->v_ratio
);
504 vp_reg_write(res
, VP_ENDIAN_MODE
, VP_ENDIAN_MODE_LITTLE
);
506 /* set buffer address to vp */
507 vp_reg_write(res
, VP_TOP_Y_PTR
, luma_addr
[0]);
508 vp_reg_write(res
, VP_BOT_Y_PTR
, luma_addr
[1]);
509 vp_reg_write(res
, VP_TOP_C_PTR
, chroma_addr
[0]);
510 vp_reg_write(res
, VP_BOT_C_PTR
, chroma_addr
[1]);
512 mixer_cfg_scan(ctx
, mode
->vdisplay
);
513 mixer_cfg_rgb_fmt(ctx
, mode
->vdisplay
);
514 mixer_cfg_layer(ctx
, plane
->zpos
, true);
517 mixer_vsync_set_update(ctx
, true);
518 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
520 mixer_regs_dump(ctx
);
524 static void mixer_layer_update(struct mixer_context
*ctx
)
526 struct mixer_resources
*res
= &ctx
->mixer_res
;
528 mixer_reg_writemask(res
, MXR_CFG
, ~0, MXR_CFG_LAYER_UPDATE
);
531 static int mixer_setup_scale(const struct exynos_drm_plane
*plane
,
532 unsigned int *x_ratio
, unsigned int *y_ratio
)
534 struct exynos_drm_plane_state
*state
=
535 to_exynos_plane_state(plane
->base
.state
);
537 if (state
->crtc
.w
!= state
->src
.w
) {
538 if (state
->crtc
.w
== 2 * state
->src
.w
)
544 if (state
->crtc
.h
!= state
->src
.h
) {
545 if (state
->crtc
.h
== 2 * state
->src
.h
)
554 DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n");
558 static void mixer_graph_buffer(struct mixer_context
*ctx
,
559 struct exynos_drm_plane
*plane
)
561 struct exynos_drm_plane_state
*state
=
562 to_exynos_plane_state(plane
->base
.state
);
563 struct drm_display_mode
*mode
= &state
->base
.crtc
->state
->adjusted_mode
;
564 struct mixer_resources
*res
= &ctx
->mixer_res
;
565 struct drm_framebuffer
*fb
= state
->base
.fb
;
567 unsigned int win
= plane
->zpos
;
568 unsigned int x_ratio
= 0, y_ratio
= 0;
569 unsigned int src_x_offset
, src_y_offset
, dst_x_offset
, dst_y_offset
;
574 switch (fb
->pixel_format
) {
575 case DRM_FORMAT_XRGB4444
:
576 fmt
= MXR_FORMAT_ARGB4444
;
579 case DRM_FORMAT_XRGB1555
:
580 fmt
= MXR_FORMAT_ARGB1555
;
583 case DRM_FORMAT_RGB565
:
584 fmt
= MXR_FORMAT_RGB565
;
587 case DRM_FORMAT_XRGB8888
:
588 case DRM_FORMAT_ARGB8888
:
589 fmt
= MXR_FORMAT_ARGB8888
;
593 DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
597 /* check if mixer supports requested scaling setup */
598 if (mixer_setup_scale(plane
, &x_ratio
, &y_ratio
))
601 dst_x_offset
= state
->crtc
.x
;
602 dst_y_offset
= state
->crtc
.y
;
604 /* converting dma address base and source offset */
605 dma_addr
= exynos_drm_fb_dma_addr(fb
, 0)
606 + (state
->src
.x
* fb
->bits_per_pixel
>> 3)
607 + (state
->src
.y
* fb
->pitches
[0]);
611 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
612 ctx
->interlace
= true;
614 ctx
->interlace
= false;
616 spin_lock_irqsave(&res
->reg_slock
, flags
);
617 mixer_vsync_set_update(ctx
, false);
620 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(win
),
621 MXR_GRP_CFG_FORMAT_VAL(fmt
), MXR_GRP_CFG_FORMAT_MASK
);
624 mixer_reg_write(res
, MXR_GRAPHIC_SPAN(win
),
625 fb
->pitches
[0] / (fb
->bits_per_pixel
>> 3));
627 /* setup display size */
628 if (ctx
->mxr_ver
== MXR_VER_128_0_0_184
&&
629 win
== DEFAULT_WIN
) {
630 val
= MXR_MXR_RES_HEIGHT(mode
->vdisplay
);
631 val
|= MXR_MXR_RES_WIDTH(mode
->hdisplay
);
632 mixer_reg_write(res
, MXR_RESOLUTION
, val
);
635 val
= MXR_GRP_WH_WIDTH(state
->src
.w
);
636 val
|= MXR_GRP_WH_HEIGHT(state
->src
.h
);
637 val
|= MXR_GRP_WH_H_SCALE(x_ratio
);
638 val
|= MXR_GRP_WH_V_SCALE(y_ratio
);
639 mixer_reg_write(res
, MXR_GRAPHIC_WH(win
), val
);
641 /* setup offsets in source image */
642 val
= MXR_GRP_SXY_SX(src_x_offset
);
643 val
|= MXR_GRP_SXY_SY(src_y_offset
);
644 mixer_reg_write(res
, MXR_GRAPHIC_SXY(win
), val
);
646 /* setup offsets in display image */
647 val
= MXR_GRP_DXY_DX(dst_x_offset
);
648 val
|= MXR_GRP_DXY_DY(dst_y_offset
);
649 mixer_reg_write(res
, MXR_GRAPHIC_DXY(win
), val
);
651 /* set buffer address to mixer */
652 mixer_reg_write(res
, MXR_GRAPHIC_BASE(win
), dma_addr
);
654 mixer_cfg_scan(ctx
, mode
->vdisplay
);
655 mixer_cfg_rgb_fmt(ctx
, mode
->vdisplay
);
656 mixer_cfg_layer(ctx
, win
, true);
658 /* layer update mandatory for mixer 16.0.33.0 */
659 if (ctx
->mxr_ver
== MXR_VER_16_0_33_0
||
660 ctx
->mxr_ver
== MXR_VER_128_0_0_184
)
661 mixer_layer_update(ctx
);
665 mixer_vsync_set_update(ctx
, true);
666 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
668 mixer_regs_dump(ctx
);
671 static void vp_win_reset(struct mixer_context
*ctx
)
673 struct mixer_resources
*res
= &ctx
->mixer_res
;
676 vp_reg_write(res
, VP_SRESET
, VP_SRESET_PROCESSING
);
677 for (tries
= 100; tries
; --tries
) {
678 /* waiting until VP_SRESET_PROCESSING is 0 */
679 if (~vp_reg_read(res
, VP_SRESET
) & VP_SRESET_PROCESSING
)
683 WARN(tries
== 0, "failed to reset Video Processor\n");
686 static void mixer_win_reset(struct mixer_context
*ctx
)
688 struct mixer_resources
*res
= &ctx
->mixer_res
;
690 u32 val
; /* value stored to register */
692 spin_lock_irqsave(&res
->reg_slock
, flags
);
693 mixer_vsync_set_update(ctx
, false);
695 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_DST_HDMI
, MXR_CFG_DST_MASK
);
697 /* set output in RGB888 mode */
698 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_OUT_RGB888
, MXR_CFG_OUT_MASK
);
700 /* 16 beat burst in DMA */
701 mixer_reg_writemask(res
, MXR_STATUS
, MXR_STATUS_16_BURST
,
702 MXR_STATUS_BURST_MASK
);
704 /* setting default layer priority: layer1 > layer0 > video
705 * because typical usage scenario would be
707 * layer0 - framebuffer
708 * video - video overlay
710 val
= MXR_LAYER_CFG_GRP1_VAL(3);
711 val
|= MXR_LAYER_CFG_GRP0_VAL(2);
713 val
|= MXR_LAYER_CFG_VP_VAL(1);
714 mixer_reg_write(res
, MXR_LAYER_CFG
, val
);
716 /* setting background color */
717 mixer_reg_write(res
, MXR_BG_COLOR0
, 0x008080);
718 mixer_reg_write(res
, MXR_BG_COLOR1
, 0x008080);
719 mixer_reg_write(res
, MXR_BG_COLOR2
, 0x008080);
721 /* setting graphical layers */
722 val
= MXR_GRP_CFG_COLOR_KEY_DISABLE
; /* no blank key */
723 val
|= MXR_GRP_CFG_WIN_BLEND_EN
;
724 val
|= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
726 /* Don't blend layer 0 onto the mixer background */
727 mixer_reg_write(res
, MXR_GRAPHIC_CFG(0), val
);
729 /* Blend layer 1 into layer 0 */
730 val
|= MXR_GRP_CFG_BLEND_PRE_MUL
;
731 val
|= MXR_GRP_CFG_PIXEL_BLEND_EN
;
732 mixer_reg_write(res
, MXR_GRAPHIC_CFG(1), val
);
734 /* setting video layers */
735 val
= MXR_GRP_CFG_ALPHA_VAL(0);
736 mixer_reg_write(res
, MXR_VIDEO_CFG
, val
);
738 if (ctx
->vp_enabled
) {
739 /* configuration of Video Processor Registers */
741 vp_default_filter(res
);
744 /* disable all layers */
745 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP0_ENABLE
);
746 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP1_ENABLE
);
748 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_VP_ENABLE
);
750 mixer_vsync_set_update(ctx
, true);
751 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
754 static irqreturn_t
mixer_irq_handler(int irq
, void *arg
)
756 struct mixer_context
*ctx
= arg
;
757 struct mixer_resources
*res
= &ctx
->mixer_res
;
758 u32 val
, base
, shadow
;
761 spin_lock(&res
->reg_slock
);
763 /* read interrupt status for handling and clearing flags for VSYNC */
764 val
= mixer_reg_read(res
, MXR_INT_STATUS
);
767 if (val
& MXR_INT_STATUS_VSYNC
) {
768 /* vsync interrupt use different bit for read and clear */
769 val
|= MXR_INT_CLEAR_VSYNC
;
770 val
&= ~MXR_INT_STATUS_VSYNC
;
772 /* interlace scan need to check shadow register */
773 if (ctx
->interlace
) {
774 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(0));
775 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(0));
779 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(1));
780 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(1));
785 drm_crtc_handle_vblank(&ctx
->crtc
->base
);
786 for (win
= 0 ; win
< MIXER_WIN_NR
; win
++) {
787 struct exynos_drm_plane
*plane
= &ctx
->planes
[win
];
789 if (!plane
->pending_fb
)
792 exynos_drm_crtc_finish_update(ctx
->crtc
, plane
);
795 /* set wait vsync event to zero and wake up queue. */
796 if (atomic_read(&ctx
->wait_vsync_event
)) {
797 atomic_set(&ctx
->wait_vsync_event
, 0);
798 wake_up(&ctx
->wait_vsync_queue
);
803 /* clear interrupts */
804 mixer_reg_write(res
, MXR_INT_STATUS
, val
);
806 spin_unlock(&res
->reg_slock
);
811 static int mixer_resources_init(struct mixer_context
*mixer_ctx
)
813 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
814 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
815 struct resource
*res
;
818 spin_lock_init(&mixer_res
->reg_slock
);
820 mixer_res
->mixer
= devm_clk_get(dev
, "mixer");
821 if (IS_ERR(mixer_res
->mixer
)) {
822 dev_err(dev
, "failed to get clock 'mixer'\n");
826 mixer_res
->hdmi
= devm_clk_get(dev
, "hdmi");
827 if (IS_ERR(mixer_res
->hdmi
)) {
828 dev_err(dev
, "failed to get clock 'hdmi'\n");
829 return PTR_ERR(mixer_res
->hdmi
);
832 mixer_res
->sclk_hdmi
= devm_clk_get(dev
, "sclk_hdmi");
833 if (IS_ERR(mixer_res
->sclk_hdmi
)) {
834 dev_err(dev
, "failed to get clock 'sclk_hdmi'\n");
837 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 0);
839 dev_err(dev
, "get memory resource failed.\n");
843 mixer_res
->mixer_regs
= devm_ioremap(dev
, res
->start
,
845 if (mixer_res
->mixer_regs
== NULL
) {
846 dev_err(dev
, "register mapping failed.\n");
850 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_IRQ
, 0);
852 dev_err(dev
, "get interrupt resource failed.\n");
856 ret
= devm_request_irq(dev
, res
->start
, mixer_irq_handler
,
857 0, "drm_mixer", mixer_ctx
);
859 dev_err(dev
, "request interrupt failed.\n");
862 mixer_res
->irq
= res
->start
;
867 static int vp_resources_init(struct mixer_context
*mixer_ctx
)
869 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
870 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
871 struct resource
*res
;
873 mixer_res
->vp
= devm_clk_get(dev
, "vp");
874 if (IS_ERR(mixer_res
->vp
)) {
875 dev_err(dev
, "failed to get clock 'vp'\n");
879 if (mixer_ctx
->has_sclk
) {
880 mixer_res
->sclk_mixer
= devm_clk_get(dev
, "sclk_mixer");
881 if (IS_ERR(mixer_res
->sclk_mixer
)) {
882 dev_err(dev
, "failed to get clock 'sclk_mixer'\n");
885 mixer_res
->mout_mixer
= devm_clk_get(dev
, "mout_mixer");
886 if (IS_ERR(mixer_res
->mout_mixer
)) {
887 dev_err(dev
, "failed to get clock 'mout_mixer'\n");
891 if (mixer_res
->sclk_hdmi
&& mixer_res
->mout_mixer
)
892 clk_set_parent(mixer_res
->mout_mixer
,
893 mixer_res
->sclk_hdmi
);
896 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 1);
898 dev_err(dev
, "get memory resource failed.\n");
902 mixer_res
->vp_regs
= devm_ioremap(dev
, res
->start
,
904 if (mixer_res
->vp_regs
== NULL
) {
905 dev_err(dev
, "register mapping failed.\n");
912 static int mixer_initialize(struct mixer_context
*mixer_ctx
,
913 struct drm_device
*drm_dev
)
916 struct exynos_drm_private
*priv
;
917 priv
= drm_dev
->dev_private
;
919 mixer_ctx
->drm_dev
= drm_dev
;
920 mixer_ctx
->pipe
= priv
->pipe
++;
922 /* acquire resources: regs, irqs, clocks */
923 ret
= mixer_resources_init(mixer_ctx
);
925 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret
);
929 if (mixer_ctx
->vp_enabled
) {
930 /* acquire vp resources: regs, irqs, clocks */
931 ret
= vp_resources_init(mixer_ctx
);
933 DRM_ERROR("vp_resources_init failed ret=%d\n", ret
);
938 ret
= drm_iommu_attach_device(drm_dev
, mixer_ctx
->dev
);
945 static void mixer_ctx_remove(struct mixer_context
*mixer_ctx
)
947 drm_iommu_detach_device(mixer_ctx
->drm_dev
, mixer_ctx
->dev
);
950 static int mixer_enable_vblank(struct exynos_drm_crtc
*crtc
)
952 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
953 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
955 __set_bit(MXR_BIT_VSYNC
, &mixer_ctx
->flags
);
956 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
959 /* enable vsync interrupt */
960 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
961 mixer_reg_writemask(res
, MXR_INT_EN
, ~0, MXR_INT_EN_VSYNC
);
966 static void mixer_disable_vblank(struct exynos_drm_crtc
*crtc
)
968 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
969 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
971 __clear_bit(MXR_BIT_VSYNC
, &mixer_ctx
->flags
);
973 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
976 /* disable vsync interrupt */
977 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
978 mixer_reg_writemask(res
, MXR_INT_EN
, 0, MXR_INT_EN_VSYNC
);
981 static void mixer_update_plane(struct exynos_drm_crtc
*crtc
,
982 struct exynos_drm_plane
*plane
)
984 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
986 DRM_DEBUG_KMS("win: %d\n", plane
->zpos
);
988 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
991 if (plane
->zpos
> 1 && mixer_ctx
->vp_enabled
)
992 vp_video_buffer(mixer_ctx
, plane
);
994 mixer_graph_buffer(mixer_ctx
, plane
);
997 static void mixer_disable_plane(struct exynos_drm_crtc
*crtc
,
998 struct exynos_drm_plane
*plane
)
1000 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
1001 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
1002 unsigned long flags
;
1004 DRM_DEBUG_KMS("win: %d\n", plane
->zpos
);
1006 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
1009 spin_lock_irqsave(&res
->reg_slock
, flags
);
1010 mixer_vsync_set_update(mixer_ctx
, false);
1012 mixer_cfg_layer(mixer_ctx
, plane
->zpos
, false);
1014 mixer_vsync_set_update(mixer_ctx
, true);
1015 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
1018 static void mixer_wait_for_vblank(struct exynos_drm_crtc
*crtc
)
1020 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
1023 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
1026 err
= drm_vblank_get(mixer_ctx
->drm_dev
, mixer_ctx
->pipe
);
1028 DRM_DEBUG_KMS("failed to acquire vblank counter\n");
1032 atomic_set(&mixer_ctx
->wait_vsync_event
, 1);
1035 * wait for MIXER to signal VSYNC interrupt or return after
1036 * timeout which is set to 50ms (refresh rate of 20).
1038 if (!wait_event_timeout(mixer_ctx
->wait_vsync_queue
,
1039 !atomic_read(&mixer_ctx
->wait_vsync_event
),
1041 DRM_DEBUG_KMS("vblank wait timed out.\n");
1043 drm_vblank_put(mixer_ctx
->drm_dev
, mixer_ctx
->pipe
);
1046 static void mixer_enable(struct exynos_drm_crtc
*crtc
)
1048 struct mixer_context
*ctx
= crtc
->ctx
;
1049 struct mixer_resources
*res
= &ctx
->mixer_res
;
1051 if (test_bit(MXR_BIT_POWERED
, &ctx
->flags
))
1054 pm_runtime_get_sync(ctx
->dev
);
1056 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_SOFT_RESET
);
1058 if (test_bit(MXR_BIT_VSYNC
, &ctx
->flags
)) {
1059 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
1060 mixer_reg_writemask(res
, MXR_INT_EN
, ~0, MXR_INT_EN_VSYNC
);
1062 mixer_win_reset(ctx
);
1064 set_bit(MXR_BIT_POWERED
, &ctx
->flags
);
1067 static void mixer_disable(struct exynos_drm_crtc
*crtc
)
1069 struct mixer_context
*ctx
= crtc
->ctx
;
1072 if (!test_bit(MXR_BIT_POWERED
, &ctx
->flags
))
1076 mixer_regs_dump(ctx
);
1078 for (i
= 0; i
< MIXER_WIN_NR
; i
++)
1079 mixer_disable_plane(crtc
, &ctx
->planes
[i
]);
1081 pm_runtime_put(ctx
->dev
);
1083 clear_bit(MXR_BIT_POWERED
, &ctx
->flags
);
1086 /* Only valid for Mixer version 16.0.33.0 */
1087 static int mixer_atomic_check(struct exynos_drm_crtc
*crtc
,
1088 struct drm_crtc_state
*state
)
1090 struct drm_display_mode
*mode
= &state
->adjusted_mode
;
1096 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1097 mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
,
1098 (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0);
1100 if ((w
>= 464 && w
<= 720 && h
>= 261 && h
<= 576) ||
1101 (w
>= 1024 && w
<= 1280 && h
>= 576 && h
<= 720) ||
1102 (w
>= 1664 && w
<= 1920 && h
>= 936 && h
<= 1080))
1108 static const struct exynos_drm_crtc_ops mixer_crtc_ops
= {
1109 .enable
= mixer_enable
,
1110 .disable
= mixer_disable
,
1111 .enable_vblank
= mixer_enable_vblank
,
1112 .disable_vblank
= mixer_disable_vblank
,
1113 .wait_for_vblank
= mixer_wait_for_vblank
,
1114 .update_plane
= mixer_update_plane
,
1115 .disable_plane
= mixer_disable_plane
,
1116 .atomic_check
= mixer_atomic_check
,
1119 static struct mixer_drv_data exynos5420_mxr_drv_data
= {
1120 .version
= MXR_VER_128_0_0_184
,
1124 static struct mixer_drv_data exynos5250_mxr_drv_data
= {
1125 .version
= MXR_VER_16_0_33_0
,
1129 static struct mixer_drv_data exynos4212_mxr_drv_data
= {
1130 .version
= MXR_VER_0_0_0_16
,
1134 static struct mixer_drv_data exynos4210_mxr_drv_data
= {
1135 .version
= MXR_VER_0_0_0_16
,
1140 static const struct platform_device_id mixer_driver_types
[] = {
1142 .name
= "s5p-mixer",
1143 .driver_data
= (unsigned long)&exynos4210_mxr_drv_data
,
1145 .name
= "exynos5-mixer",
1146 .driver_data
= (unsigned long)&exynos5250_mxr_drv_data
,
1152 static struct of_device_id mixer_match_types
[] = {
1154 .compatible
= "samsung,exynos4210-mixer",
1155 .data
= &exynos4210_mxr_drv_data
,
1157 .compatible
= "samsung,exynos4212-mixer",
1158 .data
= &exynos4212_mxr_drv_data
,
1160 .compatible
= "samsung,exynos5-mixer",
1161 .data
= &exynos5250_mxr_drv_data
,
1163 .compatible
= "samsung,exynos5250-mixer",
1164 .data
= &exynos5250_mxr_drv_data
,
1166 .compatible
= "samsung,exynos5420-mixer",
1167 .data
= &exynos5420_mxr_drv_data
,
1172 MODULE_DEVICE_TABLE(of
, mixer_match_types
);
1174 static int mixer_bind(struct device
*dev
, struct device
*manager
, void *data
)
1176 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1177 struct drm_device
*drm_dev
= data
;
1178 struct exynos_drm_plane
*exynos_plane
;
1182 ret
= mixer_initialize(ctx
, drm_dev
);
1186 for (i
= 0; i
< MIXER_WIN_NR
; i
++) {
1187 if (i
== VP_DEFAULT_WIN
&& !ctx
->vp_enabled
)
1190 ret
= exynos_plane_init(drm_dev
, &ctx
->planes
[i
],
1191 1 << ctx
->pipe
, &plane_configs
[i
]);
1196 exynos_plane
= &ctx
->planes
[DEFAULT_WIN
];
1197 ctx
->crtc
= exynos_drm_crtc_create(drm_dev
, &exynos_plane
->base
,
1198 ctx
->pipe
, EXYNOS_DISPLAY_TYPE_HDMI
,
1199 &mixer_crtc_ops
, ctx
);
1200 if (IS_ERR(ctx
->crtc
)) {
1201 mixer_ctx_remove(ctx
);
1202 ret
= PTR_ERR(ctx
->crtc
);
1209 devm_kfree(dev
, ctx
);
1213 static void mixer_unbind(struct device
*dev
, struct device
*master
, void *data
)
1215 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1217 mixer_ctx_remove(ctx
);
1220 static const struct component_ops mixer_component_ops
= {
1222 .unbind
= mixer_unbind
,
1225 static int mixer_probe(struct platform_device
*pdev
)
1227 struct device
*dev
= &pdev
->dev
;
1228 struct mixer_drv_data
*drv
;
1229 struct mixer_context
*ctx
;
1232 ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
), GFP_KERNEL
);
1234 DRM_ERROR("failed to alloc mixer context.\n");
1239 const struct of_device_id
*match
;
1241 match
= of_match_node(mixer_match_types
, dev
->of_node
);
1242 drv
= (struct mixer_drv_data
*)match
->data
;
1244 drv
= (struct mixer_drv_data
*)
1245 platform_get_device_id(pdev
)->driver_data
;
1250 ctx
->vp_enabled
= drv
->is_vp_enabled
;
1251 ctx
->has_sclk
= drv
->has_sclk
;
1252 ctx
->mxr_ver
= drv
->version
;
1253 init_waitqueue_head(&ctx
->wait_vsync_queue
);
1254 atomic_set(&ctx
->wait_vsync_event
, 0);
1256 platform_set_drvdata(pdev
, ctx
);
1258 ret
= component_add(&pdev
->dev
, &mixer_component_ops
);
1260 pm_runtime_enable(dev
);
1265 static int mixer_remove(struct platform_device
*pdev
)
1267 pm_runtime_disable(&pdev
->dev
);
1269 component_del(&pdev
->dev
, &mixer_component_ops
);
1274 #ifdef CONFIG_PM_SLEEP
1275 static int exynos_mixer_suspend(struct device
*dev
)
1277 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1278 struct mixer_resources
*res
= &ctx
->mixer_res
;
1280 clk_disable_unprepare(res
->hdmi
);
1281 clk_disable_unprepare(res
->mixer
);
1282 if (ctx
->vp_enabled
) {
1283 clk_disable_unprepare(res
->vp
);
1285 clk_disable_unprepare(res
->sclk_mixer
);
1291 static int exynos_mixer_resume(struct device
*dev
)
1293 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1294 struct mixer_resources
*res
= &ctx
->mixer_res
;
1297 ret
= clk_prepare_enable(res
->mixer
);
1299 DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret
);
1302 ret
= clk_prepare_enable(res
->hdmi
);
1304 DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret
);
1307 if (ctx
->vp_enabled
) {
1308 ret
= clk_prepare_enable(res
->vp
);
1310 DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
1314 if (ctx
->has_sclk
) {
1315 ret
= clk_prepare_enable(res
->sclk_mixer
);
1317 DRM_ERROR("Failed to prepare_enable the " \
1318 "sclk_mixer clk [%d]\n",
1329 static const struct dev_pm_ops exynos_mixer_pm_ops
= {
1330 SET_RUNTIME_PM_OPS(exynos_mixer_suspend
, exynos_mixer_resume
, NULL
)
1333 struct platform_driver mixer_driver
= {
1335 .name
= "exynos-mixer",
1336 .owner
= THIS_MODULE
,
1337 .pm
= &exynos_mixer_pm_ops
,
1338 .of_match_table
= mixer_match_types
,
1340 .probe
= mixer_probe
,
1341 .remove
= mixer_remove
,
1342 .id_table
= mixer_driver_types
,