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/of_device.h>
35 #include <linux/component.h>
37 #include <drm/exynos_drm.h>
39 #include "exynos_drm_drv.h"
40 #include "exynos_drm_crtc.h"
41 #include "exynos_drm_fb.h"
42 #include "exynos_drm_plane.h"
43 #include "exynos_drm_iommu.h"
45 #define MIXER_WIN_NR 3
46 #define VP_DEFAULT_WIN 2
49 * Mixer color space conversion coefficient triplet.
50 * Used for CSC from RGB to YCbCr.
51 * Each coefficient is a 10-bit fixed point number with
52 * sign and no integer part, i.e.
53 * [0:8] = fractional part (representing a value y = x / 2^9)
55 * Negative values are encoded with two's complement.
57 #define MXR_CSC_C(x) ((int)((x) * 512.0) & 0x3ff)
58 #define MXR_CSC_CT(a0, a1, a2) \
59 ((MXR_CSC_C(a0) << 20) | (MXR_CSC_C(a1) << 10) | (MXR_CSC_C(a2) << 0))
61 /* YCbCr value, used for mixer background color configuration. */
62 #define MXR_YCBCR_VAL(y, cb, cr) (((y) << 16) | ((cb) << 8) | ((cr) << 0))
64 /* The pixelformats that are natively supported by the mixer. */
65 #define MXR_FORMAT_RGB565 4
66 #define MXR_FORMAT_ARGB1555 5
67 #define MXR_FORMAT_ARGB4444 6
68 #define MXR_FORMAT_ARGB8888 7
70 struct mixer_resources
{
72 void __iomem
*mixer_regs
;
73 void __iomem
*vp_regs
;
78 struct clk
*sclk_mixer
;
79 struct clk
*sclk_hdmi
;
80 struct clk
*mout_mixer
;
83 enum mixer_version_id
{
89 enum mixer_flag_bits
{
97 static const uint32_t mixer_formats
[] = {
107 static const uint32_t vp_formats
[] = {
112 struct mixer_context
{
113 struct platform_device
*pdev
;
115 struct drm_device
*drm_dev
;
116 struct exynos_drm_crtc
*crtc
;
117 struct exynos_drm_plane planes
[MIXER_WIN_NR
];
120 struct mixer_resources mixer_res
;
121 enum mixer_version_id mxr_ver
;
124 struct mixer_drv_data
{
125 enum mixer_version_id version
;
130 static const struct exynos_drm_plane_config plane_configs
[MIXER_WIN_NR
] = {
133 .type
= DRM_PLANE_TYPE_PRIMARY
,
134 .pixel_formats
= mixer_formats
,
135 .num_pixel_formats
= ARRAY_SIZE(mixer_formats
),
136 .capabilities
= EXYNOS_DRM_PLANE_CAP_DOUBLE
|
137 EXYNOS_DRM_PLANE_CAP_ZPOS
,
140 .type
= DRM_PLANE_TYPE_CURSOR
,
141 .pixel_formats
= mixer_formats
,
142 .num_pixel_formats
= ARRAY_SIZE(mixer_formats
),
143 .capabilities
= EXYNOS_DRM_PLANE_CAP_DOUBLE
|
144 EXYNOS_DRM_PLANE_CAP_ZPOS
,
147 .type
= DRM_PLANE_TYPE_OVERLAY
,
148 .pixel_formats
= vp_formats
,
149 .num_pixel_formats
= ARRAY_SIZE(vp_formats
),
150 .capabilities
= EXYNOS_DRM_PLANE_CAP_SCALE
|
151 EXYNOS_DRM_PLANE_CAP_ZPOS
,
155 static const u8 filter_y_horiz_tap8
[] = {
156 0, -1, -1, -1, -1, -1, -1, -1,
157 -1, -1, -1, -1, -1, 0, 0, 0,
158 0, 2, 4, 5, 6, 6, 6, 6,
159 6, 5, 5, 4, 3, 2, 1, 1,
160 0, -6, -12, -16, -18, -20, -21, -20,
161 -20, -18, -16, -13, -10, -8, -5, -2,
162 127, 126, 125, 121, 114, 107, 99, 89,
163 79, 68, 57, 46, 35, 25, 16, 8,
166 static const u8 filter_y_vert_tap4
[] = {
167 0, -3, -6, -8, -8, -8, -8, -7,
168 -6, -5, -4, -3, -2, -1, -1, 0,
169 127, 126, 124, 118, 111, 102, 92, 81,
170 70, 59, 48, 37, 27, 19, 11, 5,
171 0, 5, 11, 19, 27, 37, 48, 59,
172 70, 81, 92, 102, 111, 118, 124, 126,
173 0, 0, -1, -1, -2, -3, -4, -5,
174 -6, -7, -8, -8, -8, -8, -6, -3,
177 static const u8 filter_cr_horiz_tap4
[] = {
178 0, -3, -6, -8, -8, -8, -8, -7,
179 -6, -5, -4, -3, -2, -1, -1, 0,
180 127, 126, 124, 118, 111, 102, 92, 81,
181 70, 59, 48, 37, 27, 19, 11, 5,
184 static inline bool is_alpha_format(unsigned int pixel_format
)
186 switch (pixel_format
) {
187 case DRM_FORMAT_ARGB8888
:
188 case DRM_FORMAT_ARGB1555
:
189 case DRM_FORMAT_ARGB4444
:
196 static inline u32
vp_reg_read(struct mixer_resources
*res
, u32 reg_id
)
198 return readl(res
->vp_regs
+ reg_id
);
201 static inline void vp_reg_write(struct mixer_resources
*res
, u32 reg_id
,
204 writel(val
, res
->vp_regs
+ reg_id
);
207 static inline void vp_reg_writemask(struct mixer_resources
*res
, u32 reg_id
,
210 u32 old
= vp_reg_read(res
, reg_id
);
212 val
= (val
& mask
) | (old
& ~mask
);
213 writel(val
, res
->vp_regs
+ reg_id
);
216 static inline u32
mixer_reg_read(struct mixer_resources
*res
, u32 reg_id
)
218 return readl(res
->mixer_regs
+ reg_id
);
221 static inline void mixer_reg_write(struct mixer_resources
*res
, u32 reg_id
,
224 writel(val
, res
->mixer_regs
+ reg_id
);
227 static inline void mixer_reg_writemask(struct mixer_resources
*res
,
228 u32 reg_id
, u32 val
, u32 mask
)
230 u32 old
= mixer_reg_read(res
, reg_id
);
232 val
= (val
& mask
) | (old
& ~mask
);
233 writel(val
, res
->mixer_regs
+ reg_id
);
236 static void mixer_regs_dump(struct mixer_context
*ctx
)
238 #define DUMPREG(reg_id) \
240 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
241 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
247 DUMPREG(MXR_INT_STATUS
);
249 DUMPREG(MXR_LAYER_CFG
);
250 DUMPREG(MXR_VIDEO_CFG
);
252 DUMPREG(MXR_GRAPHIC0_CFG
);
253 DUMPREG(MXR_GRAPHIC0_BASE
);
254 DUMPREG(MXR_GRAPHIC0_SPAN
);
255 DUMPREG(MXR_GRAPHIC0_WH
);
256 DUMPREG(MXR_GRAPHIC0_SXY
);
257 DUMPREG(MXR_GRAPHIC0_DXY
);
259 DUMPREG(MXR_GRAPHIC1_CFG
);
260 DUMPREG(MXR_GRAPHIC1_BASE
);
261 DUMPREG(MXR_GRAPHIC1_SPAN
);
262 DUMPREG(MXR_GRAPHIC1_WH
);
263 DUMPREG(MXR_GRAPHIC1_SXY
);
264 DUMPREG(MXR_GRAPHIC1_DXY
);
268 static void vp_regs_dump(struct mixer_context
*ctx
)
270 #define DUMPREG(reg_id) \
272 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
273 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
278 DUMPREG(VP_SHADOW_UPDATE
);
279 DUMPREG(VP_FIELD_ID
);
281 DUMPREG(VP_IMG_SIZE_Y
);
282 DUMPREG(VP_IMG_SIZE_C
);
283 DUMPREG(VP_PER_RATE_CTRL
);
284 DUMPREG(VP_TOP_Y_PTR
);
285 DUMPREG(VP_BOT_Y_PTR
);
286 DUMPREG(VP_TOP_C_PTR
);
287 DUMPREG(VP_BOT_C_PTR
);
288 DUMPREG(VP_ENDIAN_MODE
);
289 DUMPREG(VP_SRC_H_POSITION
);
290 DUMPREG(VP_SRC_V_POSITION
);
291 DUMPREG(VP_SRC_WIDTH
);
292 DUMPREG(VP_SRC_HEIGHT
);
293 DUMPREG(VP_DST_H_POSITION
);
294 DUMPREG(VP_DST_V_POSITION
);
295 DUMPREG(VP_DST_WIDTH
);
296 DUMPREG(VP_DST_HEIGHT
);
303 static inline void vp_filter_set(struct mixer_resources
*res
,
304 int reg_id
, const u8
*data
, unsigned int size
)
306 /* assure 4-byte align */
308 for (; size
; size
-= 4, reg_id
+= 4, data
+= 4) {
309 u32 val
= (data
[0] << 24) | (data
[1] << 16) |
310 (data
[2] << 8) | data
[3];
311 vp_reg_write(res
, reg_id
, val
);
315 static void vp_default_filter(struct mixer_resources
*res
)
317 vp_filter_set(res
, VP_POLY8_Y0_LL
,
318 filter_y_horiz_tap8
, sizeof(filter_y_horiz_tap8
));
319 vp_filter_set(res
, VP_POLY4_Y0_LL
,
320 filter_y_vert_tap4
, sizeof(filter_y_vert_tap4
));
321 vp_filter_set(res
, VP_POLY4_C0_LL
,
322 filter_cr_horiz_tap4
, sizeof(filter_cr_horiz_tap4
));
325 static void mixer_cfg_gfx_blend(struct mixer_context
*ctx
, unsigned int win
,
328 struct mixer_resources
*res
= &ctx
->mixer_res
;
331 val
= MXR_GRP_CFG_COLOR_KEY_DISABLE
; /* no blank key */
333 /* blending based on pixel alpha */
334 val
|= MXR_GRP_CFG_BLEND_PRE_MUL
;
335 val
|= MXR_GRP_CFG_PIXEL_BLEND_EN
;
337 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(win
),
338 val
, MXR_GRP_CFG_MISC_MASK
);
341 static void mixer_cfg_vp_blend(struct mixer_context
*ctx
)
343 struct mixer_resources
*res
= &ctx
->mixer_res
;
347 * No blending at the moment since the NV12/NV21 pixelformats don't
348 * have an alpha channel. However the mixer supports a global alpha
349 * value for a layer. Once this functionality is exposed, we can
350 * support blending of the video layer through this.
353 mixer_reg_write(res
, MXR_VIDEO_CFG
, val
);
356 static void mixer_vsync_set_update(struct mixer_context
*ctx
, bool enable
)
358 struct mixer_resources
*res
= &ctx
->mixer_res
;
360 /* block update on vsync */
361 mixer_reg_writemask(res
, MXR_STATUS
, enable
?
362 MXR_STATUS_SYNC_ENABLE
: 0, MXR_STATUS_SYNC_ENABLE
);
364 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
))
365 vp_reg_write(res
, VP_SHADOW_UPDATE
, enable
?
366 VP_SHADOW_UPDATE_ENABLE
: 0);
369 static void mixer_cfg_scan(struct mixer_context
*ctx
, unsigned int height
)
371 struct mixer_resources
*res
= &ctx
->mixer_res
;
374 /* choosing between interlace and progressive mode */
375 val
= test_bit(MXR_BIT_INTERLACE
, &ctx
->flags
) ?
376 MXR_CFG_SCAN_INTERLACE
: MXR_CFG_SCAN_PROGRESSIVE
;
378 if (ctx
->mxr_ver
!= MXR_VER_128_0_0_184
) {
379 /* choosing between proper HD and SD mode */
381 val
|= MXR_CFG_SCAN_NTSC
| MXR_CFG_SCAN_SD
;
382 else if (height
<= 576)
383 val
|= MXR_CFG_SCAN_PAL
| MXR_CFG_SCAN_SD
;
384 else if (height
<= 720)
385 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
386 else if (height
<= 1080)
387 val
|= MXR_CFG_SCAN_HD_1080
| MXR_CFG_SCAN_HD
;
389 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
392 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_SCAN_MASK
);
395 static void mixer_cfg_rgb_fmt(struct mixer_context
*ctx
, unsigned int height
)
397 struct mixer_resources
*res
= &ctx
->mixer_res
;
403 val
= MXR_CFG_RGB601_0_255
;
408 val
= MXR_CFG_RGB709_16_235
;
409 /* Configure the BT.709 CSC matrix for full range RGB. */
410 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
411 MXR_CSC_CT( 0.184, 0.614, 0.063) |
412 MXR_CM_COEFF_RGB_FULL
);
413 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
414 MXR_CSC_CT(-0.102, -0.338, 0.440));
415 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
416 MXR_CSC_CT( 0.440, -0.399, -0.040));
420 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_RGB_FMT_MASK
);
423 static void mixer_cfg_layer(struct mixer_context
*ctx
, unsigned int win
,
424 unsigned int priority
, bool enable
)
426 struct mixer_resources
*res
= &ctx
->mixer_res
;
427 u32 val
= enable
? ~0 : 0;
431 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP0_ENABLE
);
432 mixer_reg_writemask(res
, MXR_LAYER_CFG
,
433 MXR_LAYER_CFG_GRP0_VAL(priority
),
434 MXR_LAYER_CFG_GRP0_MASK
);
437 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP1_ENABLE
);
438 mixer_reg_writemask(res
, MXR_LAYER_CFG
,
439 MXR_LAYER_CFG_GRP1_VAL(priority
),
440 MXR_LAYER_CFG_GRP1_MASK
);
444 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
)) {
445 vp_reg_writemask(res
, VP_ENABLE
, val
, VP_ENABLE_ON
);
446 mixer_reg_writemask(res
, MXR_CFG
, val
,
448 mixer_reg_writemask(res
, MXR_LAYER_CFG
,
449 MXR_LAYER_CFG_VP_VAL(priority
),
450 MXR_LAYER_CFG_VP_MASK
);
456 static void mixer_run(struct mixer_context
*ctx
)
458 struct mixer_resources
*res
= &ctx
->mixer_res
;
460 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_REG_RUN
);
463 static void mixer_stop(struct mixer_context
*ctx
)
465 struct mixer_resources
*res
= &ctx
->mixer_res
;
468 mixer_reg_writemask(res
, MXR_STATUS
, 0, MXR_STATUS_REG_RUN
);
470 while (!(mixer_reg_read(res
, MXR_STATUS
) & MXR_STATUS_REG_IDLE
) &&
472 usleep_range(10000, 12000);
475 static void vp_video_buffer(struct mixer_context
*ctx
,
476 struct exynos_drm_plane
*plane
)
478 struct exynos_drm_plane_state
*state
=
479 to_exynos_plane_state(plane
->base
.state
);
480 struct drm_display_mode
*mode
= &state
->base
.crtc
->state
->adjusted_mode
;
481 struct mixer_resources
*res
= &ctx
->mixer_res
;
482 struct drm_framebuffer
*fb
= state
->base
.fb
;
483 unsigned int priority
= state
->base
.normalized_zpos
+ 1;
485 dma_addr_t luma_addr
[2], chroma_addr
[2];
486 bool tiled_mode
= false;
487 bool crcb_mode
= false;
490 switch (fb
->format
->format
) {
491 case DRM_FORMAT_NV12
:
494 case DRM_FORMAT_NV21
:
498 DRM_ERROR("pixel format for vp is wrong [%d].\n",
503 luma_addr
[0] = exynos_drm_fb_dma_addr(fb
, 0);
504 chroma_addr
[0] = exynos_drm_fb_dma_addr(fb
, 1);
506 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) {
507 __set_bit(MXR_BIT_INTERLACE
, &ctx
->flags
);
509 luma_addr
[1] = luma_addr
[0] + 0x40;
510 chroma_addr
[1] = chroma_addr
[0] + 0x40;
512 luma_addr
[1] = luma_addr
[0] + fb
->pitches
[0];
513 chroma_addr
[1] = chroma_addr
[0] + fb
->pitches
[0];
516 __clear_bit(MXR_BIT_INTERLACE
, &ctx
->flags
);
521 spin_lock_irqsave(&res
->reg_slock
, flags
);
523 /* interlace or progressive scan mode */
524 val
= (test_bit(MXR_BIT_INTERLACE
, &ctx
->flags
) ? ~0 : 0);
525 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_LINE_SKIP
);
528 val
= (crcb_mode
? VP_MODE_NV21
: VP_MODE_NV12
);
529 val
|= (tiled_mode
? VP_MODE_MEM_TILED
: VP_MODE_MEM_LINEAR
);
530 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_FMT_MASK
);
532 /* setting size of input image */
533 vp_reg_write(res
, VP_IMG_SIZE_Y
, VP_IMG_HSIZE(fb
->pitches
[0]) |
534 VP_IMG_VSIZE(fb
->height
));
535 /* chroma height has to reduced by 2 to avoid chroma distorions */
536 vp_reg_write(res
, VP_IMG_SIZE_C
, VP_IMG_HSIZE(fb
->pitches
[0]) |
537 VP_IMG_VSIZE(fb
->height
/ 2));
539 vp_reg_write(res
, VP_SRC_WIDTH
, state
->src
.w
);
540 vp_reg_write(res
, VP_SRC_HEIGHT
, state
->src
.h
);
541 vp_reg_write(res
, VP_SRC_H_POSITION
,
542 VP_SRC_H_POSITION_VAL(state
->src
.x
));
543 vp_reg_write(res
, VP_SRC_V_POSITION
, state
->src
.y
);
545 vp_reg_write(res
, VP_DST_WIDTH
, state
->crtc
.w
);
546 vp_reg_write(res
, VP_DST_H_POSITION
, state
->crtc
.x
);
547 if (test_bit(MXR_BIT_INTERLACE
, &ctx
->flags
)) {
548 vp_reg_write(res
, VP_DST_HEIGHT
, state
->crtc
.h
/ 2);
549 vp_reg_write(res
, VP_DST_V_POSITION
, state
->crtc
.y
/ 2);
551 vp_reg_write(res
, VP_DST_HEIGHT
, state
->crtc
.h
);
552 vp_reg_write(res
, VP_DST_V_POSITION
, state
->crtc
.y
);
555 vp_reg_write(res
, VP_H_RATIO
, state
->h_ratio
);
556 vp_reg_write(res
, VP_V_RATIO
, state
->v_ratio
);
558 vp_reg_write(res
, VP_ENDIAN_MODE
, VP_ENDIAN_MODE_LITTLE
);
560 /* set buffer address to vp */
561 vp_reg_write(res
, VP_TOP_Y_PTR
, luma_addr
[0]);
562 vp_reg_write(res
, VP_BOT_Y_PTR
, luma_addr
[1]);
563 vp_reg_write(res
, VP_TOP_C_PTR
, chroma_addr
[0]);
564 vp_reg_write(res
, VP_BOT_C_PTR
, chroma_addr
[1]);
566 mixer_cfg_scan(ctx
, mode
->vdisplay
);
567 mixer_cfg_rgb_fmt(ctx
, mode
->vdisplay
);
568 mixer_cfg_layer(ctx
, plane
->index
, priority
, true);
569 mixer_cfg_vp_blend(ctx
);
572 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
574 mixer_regs_dump(ctx
);
578 static void mixer_layer_update(struct mixer_context
*ctx
)
580 struct mixer_resources
*res
= &ctx
->mixer_res
;
582 mixer_reg_writemask(res
, MXR_CFG
, ~0, MXR_CFG_LAYER_UPDATE
);
585 static void mixer_graph_buffer(struct mixer_context
*ctx
,
586 struct exynos_drm_plane
*plane
)
588 struct exynos_drm_plane_state
*state
=
589 to_exynos_plane_state(plane
->base
.state
);
590 struct drm_display_mode
*mode
= &state
->base
.crtc
->state
->adjusted_mode
;
591 struct mixer_resources
*res
= &ctx
->mixer_res
;
592 struct drm_framebuffer
*fb
= state
->base
.fb
;
593 unsigned int priority
= state
->base
.normalized_zpos
+ 1;
595 unsigned int win
= plane
->index
;
596 unsigned int x_ratio
= 0, y_ratio
= 0;
597 unsigned int src_x_offset
, src_y_offset
, dst_x_offset
, dst_y_offset
;
602 switch (fb
->format
->format
) {
603 case DRM_FORMAT_XRGB4444
:
604 case DRM_FORMAT_ARGB4444
:
605 fmt
= MXR_FORMAT_ARGB4444
;
608 case DRM_FORMAT_XRGB1555
:
609 case DRM_FORMAT_ARGB1555
:
610 fmt
= MXR_FORMAT_ARGB1555
;
613 case DRM_FORMAT_RGB565
:
614 fmt
= MXR_FORMAT_RGB565
;
617 case DRM_FORMAT_XRGB8888
:
618 case DRM_FORMAT_ARGB8888
:
619 fmt
= MXR_FORMAT_ARGB8888
;
623 DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
627 /* ratio is already checked by common plane code */
628 x_ratio
= state
->h_ratio
== (1 << 15);
629 y_ratio
= state
->v_ratio
== (1 << 15);
631 dst_x_offset
= state
->crtc
.x
;
632 dst_y_offset
= state
->crtc
.y
;
634 /* converting dma address base and source offset */
635 dma_addr
= exynos_drm_fb_dma_addr(fb
, 0)
636 + (state
->src
.x
* fb
->format
->cpp
[0])
637 + (state
->src
.y
* fb
->pitches
[0]);
641 if (mode
->flags
& DRM_MODE_FLAG_INTERLACE
)
642 __set_bit(MXR_BIT_INTERLACE
, &ctx
->flags
);
644 __clear_bit(MXR_BIT_INTERLACE
, &ctx
->flags
);
646 spin_lock_irqsave(&res
->reg_slock
, flags
);
649 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(win
),
650 MXR_GRP_CFG_FORMAT_VAL(fmt
), MXR_GRP_CFG_FORMAT_MASK
);
653 mixer_reg_write(res
, MXR_GRAPHIC_SPAN(win
),
654 fb
->pitches
[0] / fb
->format
->cpp
[0]);
656 /* setup display size */
657 if (ctx
->mxr_ver
== MXR_VER_128_0_0_184
&&
658 win
== DEFAULT_WIN
) {
659 val
= MXR_MXR_RES_HEIGHT(mode
->vdisplay
);
660 val
|= MXR_MXR_RES_WIDTH(mode
->hdisplay
);
661 mixer_reg_write(res
, MXR_RESOLUTION
, val
);
664 val
= MXR_GRP_WH_WIDTH(state
->src
.w
);
665 val
|= MXR_GRP_WH_HEIGHT(state
->src
.h
);
666 val
|= MXR_GRP_WH_H_SCALE(x_ratio
);
667 val
|= MXR_GRP_WH_V_SCALE(y_ratio
);
668 mixer_reg_write(res
, MXR_GRAPHIC_WH(win
), val
);
670 /* setup offsets in source image */
671 val
= MXR_GRP_SXY_SX(src_x_offset
);
672 val
|= MXR_GRP_SXY_SY(src_y_offset
);
673 mixer_reg_write(res
, MXR_GRAPHIC_SXY(win
), val
);
675 /* setup offsets in display image */
676 val
= MXR_GRP_DXY_DX(dst_x_offset
);
677 val
|= MXR_GRP_DXY_DY(dst_y_offset
);
678 mixer_reg_write(res
, MXR_GRAPHIC_DXY(win
), val
);
680 /* set buffer address to mixer */
681 mixer_reg_write(res
, MXR_GRAPHIC_BASE(win
), dma_addr
);
683 mixer_cfg_scan(ctx
, mode
->vdisplay
);
684 mixer_cfg_rgb_fmt(ctx
, mode
->vdisplay
);
685 mixer_cfg_layer(ctx
, win
, priority
, true);
686 mixer_cfg_gfx_blend(ctx
, win
, is_alpha_format(fb
->format
->format
));
688 /* layer update mandatory for mixer 16.0.33.0 */
689 if (ctx
->mxr_ver
== MXR_VER_16_0_33_0
||
690 ctx
->mxr_ver
== MXR_VER_128_0_0_184
)
691 mixer_layer_update(ctx
);
695 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
697 mixer_regs_dump(ctx
);
700 static void vp_win_reset(struct mixer_context
*ctx
)
702 struct mixer_resources
*res
= &ctx
->mixer_res
;
703 unsigned int tries
= 100;
705 vp_reg_write(res
, VP_SRESET
, VP_SRESET_PROCESSING
);
707 /* waiting until VP_SRESET_PROCESSING is 0 */
708 if (~vp_reg_read(res
, VP_SRESET
) & VP_SRESET_PROCESSING
)
712 WARN(tries
== 0, "failed to reset Video Processor\n");
715 static void mixer_win_reset(struct mixer_context
*ctx
)
717 struct mixer_resources
*res
= &ctx
->mixer_res
;
720 spin_lock_irqsave(&res
->reg_slock
, flags
);
722 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_DST_HDMI
, MXR_CFG_DST_MASK
);
724 /* set output in RGB888 mode */
725 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_OUT_RGB888
, MXR_CFG_OUT_MASK
);
727 /* 16 beat burst in DMA */
728 mixer_reg_writemask(res
, MXR_STATUS
, MXR_STATUS_16_BURST
,
729 MXR_STATUS_BURST_MASK
);
731 /* reset default layer priority */
732 mixer_reg_write(res
, MXR_LAYER_CFG
, 0);
734 /* set all background colors to RGB (0,0,0) */
735 mixer_reg_write(res
, MXR_BG_COLOR0
, MXR_YCBCR_VAL(0, 128, 128));
736 mixer_reg_write(res
, MXR_BG_COLOR1
, MXR_YCBCR_VAL(0, 128, 128));
737 mixer_reg_write(res
, MXR_BG_COLOR2
, MXR_YCBCR_VAL(0, 128, 128));
739 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
)) {
740 /* configuration of Video Processor Registers */
742 vp_default_filter(res
);
745 /* disable all layers */
746 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP0_ENABLE
);
747 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP1_ENABLE
);
748 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
))
749 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_VP_ENABLE
);
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
;
760 spin_lock(&res
->reg_slock
);
762 /* read interrupt status for handling and clearing flags for VSYNC */
763 val
= mixer_reg_read(res
, MXR_INT_STATUS
);
766 if (val
& MXR_INT_STATUS_VSYNC
) {
767 /* vsync interrupt use different bit for read and clear */
768 val
|= MXR_INT_CLEAR_VSYNC
;
769 val
&= ~MXR_INT_STATUS_VSYNC
;
771 /* interlace scan need to check shadow register */
772 if (test_bit(MXR_BIT_INTERLACE
, &ctx
->flags
)) {
773 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(0));
774 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(0));
778 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(1));
779 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(1));
784 drm_crtc_handle_vblank(&ctx
->crtc
->base
);
788 /* clear interrupts */
789 mixer_reg_write(res
, MXR_INT_STATUS
, val
);
791 spin_unlock(&res
->reg_slock
);
796 static int mixer_resources_init(struct mixer_context
*mixer_ctx
)
798 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
799 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
800 struct resource
*res
;
803 spin_lock_init(&mixer_res
->reg_slock
);
805 mixer_res
->mixer
= devm_clk_get(dev
, "mixer");
806 if (IS_ERR(mixer_res
->mixer
)) {
807 dev_err(dev
, "failed to get clock 'mixer'\n");
811 mixer_res
->hdmi
= devm_clk_get(dev
, "hdmi");
812 if (IS_ERR(mixer_res
->hdmi
)) {
813 dev_err(dev
, "failed to get clock 'hdmi'\n");
814 return PTR_ERR(mixer_res
->hdmi
);
817 mixer_res
->sclk_hdmi
= devm_clk_get(dev
, "sclk_hdmi");
818 if (IS_ERR(mixer_res
->sclk_hdmi
)) {
819 dev_err(dev
, "failed to get clock 'sclk_hdmi'\n");
822 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 0);
824 dev_err(dev
, "get memory resource failed.\n");
828 mixer_res
->mixer_regs
= devm_ioremap(dev
, res
->start
,
830 if (mixer_res
->mixer_regs
== NULL
) {
831 dev_err(dev
, "register mapping failed.\n");
835 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_IRQ
, 0);
837 dev_err(dev
, "get interrupt resource failed.\n");
841 ret
= devm_request_irq(dev
, res
->start
, mixer_irq_handler
,
842 0, "drm_mixer", mixer_ctx
);
844 dev_err(dev
, "request interrupt failed.\n");
847 mixer_res
->irq
= res
->start
;
852 static int vp_resources_init(struct mixer_context
*mixer_ctx
)
854 struct device
*dev
= &mixer_ctx
->pdev
->dev
;
855 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
856 struct resource
*res
;
858 mixer_res
->vp
= devm_clk_get(dev
, "vp");
859 if (IS_ERR(mixer_res
->vp
)) {
860 dev_err(dev
, "failed to get clock 'vp'\n");
864 if (test_bit(MXR_BIT_HAS_SCLK
, &mixer_ctx
->flags
)) {
865 mixer_res
->sclk_mixer
= devm_clk_get(dev
, "sclk_mixer");
866 if (IS_ERR(mixer_res
->sclk_mixer
)) {
867 dev_err(dev
, "failed to get clock 'sclk_mixer'\n");
870 mixer_res
->mout_mixer
= devm_clk_get(dev
, "mout_mixer");
871 if (IS_ERR(mixer_res
->mout_mixer
)) {
872 dev_err(dev
, "failed to get clock 'mout_mixer'\n");
876 if (mixer_res
->sclk_hdmi
&& mixer_res
->mout_mixer
)
877 clk_set_parent(mixer_res
->mout_mixer
,
878 mixer_res
->sclk_hdmi
);
881 res
= platform_get_resource(mixer_ctx
->pdev
, IORESOURCE_MEM
, 1);
883 dev_err(dev
, "get memory resource failed.\n");
887 mixer_res
->vp_regs
= devm_ioremap(dev
, res
->start
,
889 if (mixer_res
->vp_regs
== NULL
) {
890 dev_err(dev
, "register mapping failed.\n");
897 static int mixer_initialize(struct mixer_context
*mixer_ctx
,
898 struct drm_device
*drm_dev
)
901 struct exynos_drm_private
*priv
;
902 priv
= drm_dev
->dev_private
;
904 mixer_ctx
->drm_dev
= drm_dev
;
906 /* acquire resources: regs, irqs, clocks */
907 ret
= mixer_resources_init(mixer_ctx
);
909 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret
);
913 if (test_bit(MXR_BIT_VP_ENABLED
, &mixer_ctx
->flags
)) {
914 /* acquire vp resources: regs, irqs, clocks */
915 ret
= vp_resources_init(mixer_ctx
);
917 DRM_ERROR("vp_resources_init failed ret=%d\n", ret
);
922 return drm_iommu_attach_device(drm_dev
, mixer_ctx
->dev
);
925 static void mixer_ctx_remove(struct mixer_context
*mixer_ctx
)
927 drm_iommu_detach_device(mixer_ctx
->drm_dev
, mixer_ctx
->dev
);
930 static int mixer_enable_vblank(struct exynos_drm_crtc
*crtc
)
932 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
933 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
935 __set_bit(MXR_BIT_VSYNC
, &mixer_ctx
->flags
);
936 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
939 /* enable vsync interrupt */
940 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
941 mixer_reg_writemask(res
, MXR_INT_EN
, ~0, MXR_INT_EN_VSYNC
);
946 static void mixer_disable_vblank(struct exynos_drm_crtc
*crtc
)
948 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
949 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
951 __clear_bit(MXR_BIT_VSYNC
, &mixer_ctx
->flags
);
953 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
956 /* disable vsync interrupt */
957 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
958 mixer_reg_writemask(res
, MXR_INT_EN
, 0, MXR_INT_EN_VSYNC
);
961 static void mixer_atomic_begin(struct exynos_drm_crtc
*crtc
)
963 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
965 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
968 mixer_vsync_set_update(mixer_ctx
, false);
971 static void mixer_update_plane(struct exynos_drm_crtc
*crtc
,
972 struct exynos_drm_plane
*plane
)
974 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
976 DRM_DEBUG_KMS("win: %d\n", plane
->index
);
978 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
981 if (plane
->index
== VP_DEFAULT_WIN
)
982 vp_video_buffer(mixer_ctx
, plane
);
984 mixer_graph_buffer(mixer_ctx
, plane
);
987 static void mixer_disable_plane(struct exynos_drm_crtc
*crtc
,
988 struct exynos_drm_plane
*plane
)
990 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
991 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
994 DRM_DEBUG_KMS("win: %d\n", plane
->index
);
996 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
999 spin_lock_irqsave(&res
->reg_slock
, flags
);
1000 mixer_cfg_layer(mixer_ctx
, plane
->index
, 0, false);
1001 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
1004 static void mixer_atomic_flush(struct exynos_drm_crtc
*crtc
)
1006 struct mixer_context
*mixer_ctx
= crtc
->ctx
;
1008 if (!test_bit(MXR_BIT_POWERED
, &mixer_ctx
->flags
))
1011 mixer_vsync_set_update(mixer_ctx
, true);
1012 exynos_crtc_handle_event(crtc
);
1015 static void mixer_enable(struct exynos_drm_crtc
*crtc
)
1017 struct mixer_context
*ctx
= crtc
->ctx
;
1018 struct mixer_resources
*res
= &ctx
->mixer_res
;
1020 if (test_bit(MXR_BIT_POWERED
, &ctx
->flags
))
1023 pm_runtime_get_sync(ctx
->dev
);
1025 exynos_drm_pipe_clk_enable(crtc
, true);
1027 mixer_vsync_set_update(ctx
, false);
1029 mixer_reg_writemask(res
, MXR_STATUS
, ~0, MXR_STATUS_SOFT_RESET
);
1031 if (test_bit(MXR_BIT_VSYNC
, &ctx
->flags
)) {
1032 mixer_reg_writemask(res
, MXR_INT_STATUS
, ~0, MXR_INT_CLEAR_VSYNC
);
1033 mixer_reg_writemask(res
, MXR_INT_EN
, ~0, MXR_INT_EN_VSYNC
);
1035 mixer_win_reset(ctx
);
1037 mixer_vsync_set_update(ctx
, true);
1039 set_bit(MXR_BIT_POWERED
, &ctx
->flags
);
1042 static void mixer_disable(struct exynos_drm_crtc
*crtc
)
1044 struct mixer_context
*ctx
= crtc
->ctx
;
1047 if (!test_bit(MXR_BIT_POWERED
, &ctx
->flags
))
1051 mixer_regs_dump(ctx
);
1053 for (i
= 0; i
< MIXER_WIN_NR
; i
++)
1054 mixer_disable_plane(crtc
, &ctx
->planes
[i
]);
1056 exynos_drm_pipe_clk_enable(crtc
, false);
1058 pm_runtime_put(ctx
->dev
);
1060 clear_bit(MXR_BIT_POWERED
, &ctx
->flags
);
1063 /* Only valid for Mixer version 16.0.33.0 */
1064 static int mixer_atomic_check(struct exynos_drm_crtc
*crtc
,
1065 struct drm_crtc_state
*state
)
1067 struct drm_display_mode
*mode
= &state
->adjusted_mode
;
1073 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1074 mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
,
1075 (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0);
1077 if ((w
>= 464 && w
<= 720 && h
>= 261 && h
<= 576) ||
1078 (w
>= 1024 && w
<= 1280 && h
>= 576 && h
<= 720) ||
1079 (w
>= 1664 && w
<= 1920 && h
>= 936 && h
<= 1080))
1085 static const struct exynos_drm_crtc_ops mixer_crtc_ops
= {
1086 .enable
= mixer_enable
,
1087 .disable
= mixer_disable
,
1088 .enable_vblank
= mixer_enable_vblank
,
1089 .disable_vblank
= mixer_disable_vblank
,
1090 .atomic_begin
= mixer_atomic_begin
,
1091 .update_plane
= mixer_update_plane
,
1092 .disable_plane
= mixer_disable_plane
,
1093 .atomic_flush
= mixer_atomic_flush
,
1094 .atomic_check
= mixer_atomic_check
,
1097 static struct mixer_drv_data exynos5420_mxr_drv_data
= {
1098 .version
= MXR_VER_128_0_0_184
,
1102 static struct mixer_drv_data exynos5250_mxr_drv_data
= {
1103 .version
= MXR_VER_16_0_33_0
,
1107 static struct mixer_drv_data exynos4212_mxr_drv_data
= {
1108 .version
= MXR_VER_0_0_0_16
,
1112 static struct mixer_drv_data exynos4210_mxr_drv_data
= {
1113 .version
= MXR_VER_0_0_0_16
,
1118 static struct of_device_id mixer_match_types
[] = {
1120 .compatible
= "samsung,exynos4210-mixer",
1121 .data
= &exynos4210_mxr_drv_data
,
1123 .compatible
= "samsung,exynos4212-mixer",
1124 .data
= &exynos4212_mxr_drv_data
,
1126 .compatible
= "samsung,exynos5-mixer",
1127 .data
= &exynos5250_mxr_drv_data
,
1129 .compatible
= "samsung,exynos5250-mixer",
1130 .data
= &exynos5250_mxr_drv_data
,
1132 .compatible
= "samsung,exynos5420-mixer",
1133 .data
= &exynos5420_mxr_drv_data
,
1138 MODULE_DEVICE_TABLE(of
, mixer_match_types
);
1140 static int mixer_bind(struct device
*dev
, struct device
*manager
, void *data
)
1142 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1143 struct drm_device
*drm_dev
= data
;
1144 struct exynos_drm_plane
*exynos_plane
;
1148 ret
= mixer_initialize(ctx
, drm_dev
);
1152 for (i
= 0; i
< MIXER_WIN_NR
; i
++) {
1153 if (i
== VP_DEFAULT_WIN
&& !test_bit(MXR_BIT_VP_ENABLED
,
1157 ret
= exynos_plane_init(drm_dev
, &ctx
->planes
[i
], i
,
1163 exynos_plane
= &ctx
->planes
[DEFAULT_WIN
];
1164 ctx
->crtc
= exynos_drm_crtc_create(drm_dev
, &exynos_plane
->base
,
1165 EXYNOS_DISPLAY_TYPE_HDMI
, &mixer_crtc_ops
, ctx
);
1166 if (IS_ERR(ctx
->crtc
)) {
1167 mixer_ctx_remove(ctx
);
1168 ret
= PTR_ERR(ctx
->crtc
);
1175 devm_kfree(dev
, ctx
);
1179 static void mixer_unbind(struct device
*dev
, struct device
*master
, void *data
)
1181 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1183 mixer_ctx_remove(ctx
);
1186 static const struct component_ops mixer_component_ops
= {
1188 .unbind
= mixer_unbind
,
1191 static int mixer_probe(struct platform_device
*pdev
)
1193 struct device
*dev
= &pdev
->dev
;
1194 const struct mixer_drv_data
*drv
;
1195 struct mixer_context
*ctx
;
1198 ctx
= devm_kzalloc(&pdev
->dev
, sizeof(*ctx
), GFP_KERNEL
);
1200 DRM_ERROR("failed to alloc mixer context.\n");
1204 drv
= of_device_get_match_data(dev
);
1208 ctx
->mxr_ver
= drv
->version
;
1210 if (drv
->is_vp_enabled
)
1211 __set_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
);
1213 __set_bit(MXR_BIT_HAS_SCLK
, &ctx
->flags
);
1215 platform_set_drvdata(pdev
, ctx
);
1217 ret
= component_add(&pdev
->dev
, &mixer_component_ops
);
1219 pm_runtime_enable(dev
);
1224 static int mixer_remove(struct platform_device
*pdev
)
1226 pm_runtime_disable(&pdev
->dev
);
1228 component_del(&pdev
->dev
, &mixer_component_ops
);
1233 static int __maybe_unused
exynos_mixer_suspend(struct device
*dev
)
1235 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1236 struct mixer_resources
*res
= &ctx
->mixer_res
;
1238 clk_disable_unprepare(res
->hdmi
);
1239 clk_disable_unprepare(res
->mixer
);
1240 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
)) {
1241 clk_disable_unprepare(res
->vp
);
1242 if (test_bit(MXR_BIT_HAS_SCLK
, &ctx
->flags
))
1243 clk_disable_unprepare(res
->sclk_mixer
);
1249 static int __maybe_unused
exynos_mixer_resume(struct device
*dev
)
1251 struct mixer_context
*ctx
= dev_get_drvdata(dev
);
1252 struct mixer_resources
*res
= &ctx
->mixer_res
;
1255 ret
= clk_prepare_enable(res
->mixer
);
1257 DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret
);
1260 ret
= clk_prepare_enable(res
->hdmi
);
1262 DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret
);
1265 if (test_bit(MXR_BIT_VP_ENABLED
, &ctx
->flags
)) {
1266 ret
= clk_prepare_enable(res
->vp
);
1268 DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
1272 if (test_bit(MXR_BIT_HAS_SCLK
, &ctx
->flags
)) {
1273 ret
= clk_prepare_enable(res
->sclk_mixer
);
1275 DRM_ERROR("Failed to prepare_enable the " \
1276 "sclk_mixer clk [%d]\n",
1286 static const struct dev_pm_ops exynos_mixer_pm_ops
= {
1287 SET_RUNTIME_PM_OPS(exynos_mixer_suspend
, exynos_mixer_resume
, NULL
)
1290 struct platform_driver mixer_driver
= {
1292 .name
= "exynos-mixer",
1293 .owner
= THIS_MODULE
,
1294 .pm
= &exynos_mixer_pm_ops
,
1295 .of_match_table
= mixer_match_types
,
1297 .probe
= mixer_probe
,
1298 .remove
= mixer_remove
,