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/module.h>
27 #include <linux/platform_device.h>
28 #include <linux/interrupt.h>
29 #include <linux/irq.h>
30 #include <linux/delay.h>
31 #include <linux/pm_runtime.h>
32 #include <linux/clk.h>
33 #include <linux/regulator/consumer.h>
35 #include <drm/exynos_drm.h>
37 #include "exynos_drm_drv.h"
38 #include "exynos_drm_crtc.h"
39 #include "exynos_drm_hdmi.h"
40 #include "exynos_drm_iommu.h"
42 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
44 struct hdmi_win_data
{
46 dma_addr_t chroma_dma_addr
;
47 uint32_t pixel_format
;
51 unsigned int crtc_width
;
52 unsigned int crtc_height
;
55 unsigned int fb_width
;
56 unsigned int fb_height
;
57 unsigned int src_width
;
58 unsigned int src_height
;
59 unsigned int mode_width
;
60 unsigned int mode_height
;
61 unsigned int scan_flags
;
66 struct mixer_resources
{
68 void __iomem
*mixer_regs
;
69 void __iomem
*vp_regs
;
73 struct clk
*sclk_mixer
;
74 struct clk
*sclk_hdmi
;
78 enum mixer_version_id
{
83 struct mixer_context
{
85 struct drm_device
*drm_dev
;
92 struct mutex mixer_mutex
;
93 struct mixer_resources mixer_res
;
94 struct hdmi_win_data win_data
[MIXER_WIN_NR
];
95 enum mixer_version_id mxr_ver
;
97 wait_queue_head_t wait_vsync_queue
;
98 atomic_t wait_vsync_event
;
101 struct mixer_drv_data
{
102 enum mixer_version_id version
;
106 static const u8 filter_y_horiz_tap8
[] = {
107 0, -1, -1, -1, -1, -1, -1, -1,
108 -1, -1, -1, -1, -1, 0, 0, 0,
109 0, 2, 4, 5, 6, 6, 6, 6,
110 6, 5, 5, 4, 3, 2, 1, 1,
111 0, -6, -12, -16, -18, -20, -21, -20,
112 -20, -18, -16, -13, -10, -8, -5, -2,
113 127, 126, 125, 121, 114, 107, 99, 89,
114 79, 68, 57, 46, 35, 25, 16, 8,
117 static const u8 filter_y_vert_tap4
[] = {
118 0, -3, -6, -8, -8, -8, -8, -7,
119 -6, -5, -4, -3, -2, -1, -1, 0,
120 127, 126, 124, 118, 111, 102, 92, 81,
121 70, 59, 48, 37, 27, 19, 11, 5,
122 0, 5, 11, 19, 27, 37, 48, 59,
123 70, 81, 92, 102, 111, 118, 124, 126,
124 0, 0, -1, -1, -2, -3, -4, -5,
125 -6, -7, -8, -8, -8, -8, -6, -3,
128 static const u8 filter_cr_horiz_tap4
[] = {
129 0, -3, -6, -8, -8, -8, -8, -7,
130 -6, -5, -4, -3, -2, -1, -1, 0,
131 127, 126, 124, 118, 111, 102, 92, 81,
132 70, 59, 48, 37, 27, 19, 11, 5,
135 static inline u32
vp_reg_read(struct mixer_resources
*res
, u32 reg_id
)
137 return readl(res
->vp_regs
+ reg_id
);
140 static inline void vp_reg_write(struct mixer_resources
*res
, u32 reg_id
,
143 writel(val
, res
->vp_regs
+ reg_id
);
146 static inline void vp_reg_writemask(struct mixer_resources
*res
, u32 reg_id
,
149 u32 old
= vp_reg_read(res
, reg_id
);
151 val
= (val
& mask
) | (old
& ~mask
);
152 writel(val
, res
->vp_regs
+ reg_id
);
155 static inline u32
mixer_reg_read(struct mixer_resources
*res
, u32 reg_id
)
157 return readl(res
->mixer_regs
+ reg_id
);
160 static inline void mixer_reg_write(struct mixer_resources
*res
, u32 reg_id
,
163 writel(val
, res
->mixer_regs
+ reg_id
);
166 static inline void mixer_reg_writemask(struct mixer_resources
*res
,
167 u32 reg_id
, u32 val
, u32 mask
)
169 u32 old
= mixer_reg_read(res
, reg_id
);
171 val
= (val
& mask
) | (old
& ~mask
);
172 writel(val
, res
->mixer_regs
+ reg_id
);
175 static void mixer_regs_dump(struct mixer_context
*ctx
)
177 #define DUMPREG(reg_id) \
179 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
180 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
186 DUMPREG(MXR_INT_STATUS
);
188 DUMPREG(MXR_LAYER_CFG
);
189 DUMPREG(MXR_VIDEO_CFG
);
191 DUMPREG(MXR_GRAPHIC0_CFG
);
192 DUMPREG(MXR_GRAPHIC0_BASE
);
193 DUMPREG(MXR_GRAPHIC0_SPAN
);
194 DUMPREG(MXR_GRAPHIC0_WH
);
195 DUMPREG(MXR_GRAPHIC0_SXY
);
196 DUMPREG(MXR_GRAPHIC0_DXY
);
198 DUMPREG(MXR_GRAPHIC1_CFG
);
199 DUMPREG(MXR_GRAPHIC1_BASE
);
200 DUMPREG(MXR_GRAPHIC1_SPAN
);
201 DUMPREG(MXR_GRAPHIC1_WH
);
202 DUMPREG(MXR_GRAPHIC1_SXY
);
203 DUMPREG(MXR_GRAPHIC1_DXY
);
207 static void vp_regs_dump(struct mixer_context
*ctx
)
209 #define DUMPREG(reg_id) \
211 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
212 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
217 DUMPREG(VP_SHADOW_UPDATE
);
218 DUMPREG(VP_FIELD_ID
);
220 DUMPREG(VP_IMG_SIZE_Y
);
221 DUMPREG(VP_IMG_SIZE_C
);
222 DUMPREG(VP_PER_RATE_CTRL
);
223 DUMPREG(VP_TOP_Y_PTR
);
224 DUMPREG(VP_BOT_Y_PTR
);
225 DUMPREG(VP_TOP_C_PTR
);
226 DUMPREG(VP_BOT_C_PTR
);
227 DUMPREG(VP_ENDIAN_MODE
);
228 DUMPREG(VP_SRC_H_POSITION
);
229 DUMPREG(VP_SRC_V_POSITION
);
230 DUMPREG(VP_SRC_WIDTH
);
231 DUMPREG(VP_SRC_HEIGHT
);
232 DUMPREG(VP_DST_H_POSITION
);
233 DUMPREG(VP_DST_V_POSITION
);
234 DUMPREG(VP_DST_WIDTH
);
235 DUMPREG(VP_DST_HEIGHT
);
242 static inline void vp_filter_set(struct mixer_resources
*res
,
243 int reg_id
, const u8
*data
, unsigned int size
)
245 /* assure 4-byte align */
247 for (; size
; size
-= 4, reg_id
+= 4, data
+= 4) {
248 u32 val
= (data
[0] << 24) | (data
[1] << 16) |
249 (data
[2] << 8) | data
[3];
250 vp_reg_write(res
, reg_id
, val
);
254 static void vp_default_filter(struct mixer_resources
*res
)
256 vp_filter_set(res
, VP_POLY8_Y0_LL
,
257 filter_y_horiz_tap8
, sizeof(filter_y_horiz_tap8
));
258 vp_filter_set(res
, VP_POLY4_Y0_LL
,
259 filter_y_vert_tap4
, sizeof(filter_y_vert_tap4
));
260 vp_filter_set(res
, VP_POLY4_C0_LL
,
261 filter_cr_horiz_tap4
, sizeof(filter_cr_horiz_tap4
));
264 static void mixer_vsync_set_update(struct mixer_context
*ctx
, bool enable
)
266 struct mixer_resources
*res
= &ctx
->mixer_res
;
268 /* block update on vsync */
269 mixer_reg_writemask(res
, MXR_STATUS
, enable
?
270 MXR_STATUS_SYNC_ENABLE
: 0, MXR_STATUS_SYNC_ENABLE
);
273 vp_reg_write(res
, VP_SHADOW_UPDATE
, enable
?
274 VP_SHADOW_UPDATE_ENABLE
: 0);
277 static void mixer_cfg_scan(struct mixer_context
*ctx
, unsigned int height
)
279 struct mixer_resources
*res
= &ctx
->mixer_res
;
282 /* choosing between interlace and progressive mode */
283 val
= (ctx
->interlace
? MXR_CFG_SCAN_INTERLACE
:
284 MXR_CFG_SCAN_PROGRASSIVE
);
286 /* choosing between porper HD and SD mode */
288 val
|= MXR_CFG_SCAN_NTSC
| MXR_CFG_SCAN_SD
;
289 else if (height
<= 576)
290 val
|= MXR_CFG_SCAN_PAL
| MXR_CFG_SCAN_SD
;
291 else if (height
<= 720)
292 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
293 else if (height
<= 1080)
294 val
|= MXR_CFG_SCAN_HD_1080
| MXR_CFG_SCAN_HD
;
296 val
|= MXR_CFG_SCAN_HD_720
| MXR_CFG_SCAN_HD
;
298 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_SCAN_MASK
);
301 static void mixer_cfg_rgb_fmt(struct mixer_context
*ctx
, unsigned int height
)
303 struct mixer_resources
*res
= &ctx
->mixer_res
;
307 val
= MXR_CFG_RGB601_0_255
;
308 } else if (height
== 576) {
309 val
= MXR_CFG_RGB601_0_255
;
310 } else if (height
== 720) {
311 val
= MXR_CFG_RGB709_16_235
;
312 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
313 (1 << 30) | (94 << 20) | (314 << 10) |
315 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
316 (972 << 20) | (851 << 10) | (225 << 0));
317 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
318 (225 << 20) | (820 << 10) | (1004 << 0));
319 } else if (height
== 1080) {
320 val
= MXR_CFG_RGB709_16_235
;
321 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
322 (1 << 30) | (94 << 20) | (314 << 10) |
324 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
325 (972 << 20) | (851 << 10) | (225 << 0));
326 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
327 (225 << 20) | (820 << 10) | (1004 << 0));
329 val
= MXR_CFG_RGB709_16_235
;
330 mixer_reg_write(res
, MXR_CM_COEFF_Y
,
331 (1 << 30) | (94 << 20) | (314 << 10) |
333 mixer_reg_write(res
, MXR_CM_COEFF_CB
,
334 (972 << 20) | (851 << 10) | (225 << 0));
335 mixer_reg_write(res
, MXR_CM_COEFF_CR
,
336 (225 << 20) | (820 << 10) | (1004 << 0));
339 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_RGB_FMT_MASK
);
342 static void mixer_cfg_layer(struct mixer_context
*ctx
, int win
, bool enable
)
344 struct mixer_resources
*res
= &ctx
->mixer_res
;
345 u32 val
= enable
? ~0 : 0;
349 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP0_ENABLE
);
352 mixer_reg_writemask(res
, MXR_CFG
, val
, MXR_CFG_GRP1_ENABLE
);
355 if (ctx
->vp_enabled
) {
356 vp_reg_writemask(res
, VP_ENABLE
, val
, VP_ENABLE_ON
);
357 mixer_reg_writemask(res
, MXR_CFG
, val
,
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
);
370 mixer_regs_dump(ctx
);
373 static void vp_video_buffer(struct mixer_context
*ctx
, int win
)
375 struct mixer_resources
*res
= &ctx
->mixer_res
;
377 struct hdmi_win_data
*win_data
;
378 unsigned int x_ratio
, y_ratio
;
379 unsigned int buf_num
;
380 dma_addr_t luma_addr
[2], chroma_addr
[2];
381 bool tiled_mode
= false;
382 bool crcb_mode
= false;
385 win_data
= &ctx
->win_data
[win
];
387 switch (win_data
->pixel_format
) {
388 case DRM_FORMAT_NV12MT
:
390 case DRM_FORMAT_NV12
:
394 /* TODO: single buffer format NV12, NV21 */
396 /* ignore pixel format at disable time */
397 if (!win_data
->dma_addr
)
400 DRM_ERROR("pixel format for vp is wrong [%d].\n",
401 win_data
->pixel_format
);
405 /* scaling feature: (src << 16) / dst */
406 x_ratio
= (win_data
->src_width
<< 16) / win_data
->crtc_width
;
407 y_ratio
= (win_data
->src_height
<< 16) / win_data
->crtc_height
;
410 luma_addr
[0] = win_data
->dma_addr
;
411 chroma_addr
[0] = win_data
->chroma_dma_addr
;
413 luma_addr
[0] = win_data
->dma_addr
;
414 chroma_addr
[0] = win_data
->dma_addr
415 + (win_data
->fb_width
* win_data
->fb_height
);
418 if (win_data
->scan_flags
& DRM_MODE_FLAG_INTERLACE
) {
419 ctx
->interlace
= true;
421 luma_addr
[1] = luma_addr
[0] + 0x40;
422 chroma_addr
[1] = chroma_addr
[0] + 0x40;
424 luma_addr
[1] = luma_addr
[0] + win_data
->fb_width
;
425 chroma_addr
[1] = chroma_addr
[0] + win_data
->fb_width
;
428 ctx
->interlace
= false;
433 spin_lock_irqsave(&res
->reg_slock
, flags
);
434 mixer_vsync_set_update(ctx
, false);
436 /* interlace or progressive scan mode */
437 val
= (ctx
->interlace
? ~0 : 0);
438 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_LINE_SKIP
);
441 val
= (crcb_mode
? VP_MODE_NV21
: VP_MODE_NV12
);
442 val
|= (tiled_mode
? VP_MODE_MEM_TILED
: VP_MODE_MEM_LINEAR
);
443 vp_reg_writemask(res
, VP_MODE
, val
, VP_MODE_FMT_MASK
);
445 /* setting size of input image */
446 vp_reg_write(res
, VP_IMG_SIZE_Y
, VP_IMG_HSIZE(win_data
->fb_width
) |
447 VP_IMG_VSIZE(win_data
->fb_height
));
448 /* chroma height has to reduced by 2 to avoid chroma distorions */
449 vp_reg_write(res
, VP_IMG_SIZE_C
, VP_IMG_HSIZE(win_data
->fb_width
) |
450 VP_IMG_VSIZE(win_data
->fb_height
/ 2));
452 vp_reg_write(res
, VP_SRC_WIDTH
, win_data
->src_width
);
453 vp_reg_write(res
, VP_SRC_HEIGHT
, win_data
->src_height
);
454 vp_reg_write(res
, VP_SRC_H_POSITION
,
455 VP_SRC_H_POSITION_VAL(win_data
->fb_x
));
456 vp_reg_write(res
, VP_SRC_V_POSITION
, win_data
->fb_y
);
458 vp_reg_write(res
, VP_DST_WIDTH
, win_data
->crtc_width
);
459 vp_reg_write(res
, VP_DST_H_POSITION
, win_data
->crtc_x
);
460 if (ctx
->interlace
) {
461 vp_reg_write(res
, VP_DST_HEIGHT
, win_data
->crtc_height
/ 2);
462 vp_reg_write(res
, VP_DST_V_POSITION
, win_data
->crtc_y
/ 2);
464 vp_reg_write(res
, VP_DST_HEIGHT
, win_data
->crtc_height
);
465 vp_reg_write(res
, VP_DST_V_POSITION
, win_data
->crtc_y
);
468 vp_reg_write(res
, VP_H_RATIO
, x_ratio
);
469 vp_reg_write(res
, VP_V_RATIO
, y_ratio
);
471 vp_reg_write(res
, VP_ENDIAN_MODE
, VP_ENDIAN_MODE_LITTLE
);
473 /* set buffer address to vp */
474 vp_reg_write(res
, VP_TOP_Y_PTR
, luma_addr
[0]);
475 vp_reg_write(res
, VP_BOT_Y_PTR
, luma_addr
[1]);
476 vp_reg_write(res
, VP_TOP_C_PTR
, chroma_addr
[0]);
477 vp_reg_write(res
, VP_BOT_C_PTR
, chroma_addr
[1]);
479 mixer_cfg_scan(ctx
, win_data
->mode_height
);
480 mixer_cfg_rgb_fmt(ctx
, win_data
->mode_height
);
481 mixer_cfg_layer(ctx
, win
, true);
484 mixer_vsync_set_update(ctx
, true);
485 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
490 static void mixer_layer_update(struct mixer_context
*ctx
)
492 struct mixer_resources
*res
= &ctx
->mixer_res
;
495 val
= mixer_reg_read(res
, MXR_CFG
);
497 /* allow one update per vsync only */
498 if (!(val
& MXR_CFG_LAYER_UPDATE_COUNT_MASK
))
499 mixer_reg_writemask(res
, MXR_CFG
, ~0, MXR_CFG_LAYER_UPDATE
);
502 static void mixer_graph_buffer(struct mixer_context
*ctx
, int win
)
504 struct mixer_resources
*res
= &ctx
->mixer_res
;
506 struct hdmi_win_data
*win_data
;
507 unsigned int x_ratio
, y_ratio
;
508 unsigned int src_x_offset
, src_y_offset
, dst_x_offset
, dst_y_offset
;
513 win_data
= &ctx
->win_data
[win
];
520 switch (win_data
->bpp
) {
531 /* 2x scaling feature */
535 dst_x_offset
= win_data
->crtc_x
;
536 dst_y_offset
= win_data
->crtc_y
;
538 /* converting dma address base and source offset */
539 dma_addr
= win_data
->dma_addr
540 + (win_data
->fb_x
* win_data
->bpp
>> 3)
541 + (win_data
->fb_y
* win_data
->fb_width
* win_data
->bpp
>> 3);
545 if (win_data
->scan_flags
& DRM_MODE_FLAG_INTERLACE
)
546 ctx
->interlace
= true;
548 ctx
->interlace
= false;
550 spin_lock_irqsave(&res
->reg_slock
, flags
);
551 mixer_vsync_set_update(ctx
, false);
554 mixer_reg_writemask(res
, MXR_GRAPHIC_CFG(win
),
555 MXR_GRP_CFG_FORMAT_VAL(fmt
), MXR_GRP_CFG_FORMAT_MASK
);
558 mixer_reg_write(res
, MXR_GRAPHIC_SPAN(win
), win_data
->fb_width
);
560 val
= MXR_GRP_WH_WIDTH(win_data
->crtc_width
);
561 val
|= MXR_GRP_WH_HEIGHT(win_data
->crtc_height
);
562 val
|= MXR_GRP_WH_H_SCALE(x_ratio
);
563 val
|= MXR_GRP_WH_V_SCALE(y_ratio
);
564 mixer_reg_write(res
, MXR_GRAPHIC_WH(win
), val
);
566 /* setup offsets in source image */
567 val
= MXR_GRP_SXY_SX(src_x_offset
);
568 val
|= MXR_GRP_SXY_SY(src_y_offset
);
569 mixer_reg_write(res
, MXR_GRAPHIC_SXY(win
), val
);
571 /* setup offsets in display image */
572 val
= MXR_GRP_DXY_DX(dst_x_offset
);
573 val
|= MXR_GRP_DXY_DY(dst_y_offset
);
574 mixer_reg_write(res
, MXR_GRAPHIC_DXY(win
), val
);
576 /* set buffer address to mixer */
577 mixer_reg_write(res
, MXR_GRAPHIC_BASE(win
), dma_addr
);
579 mixer_cfg_scan(ctx
, win_data
->mode_height
);
580 mixer_cfg_rgb_fmt(ctx
, win_data
->mode_height
);
581 mixer_cfg_layer(ctx
, win
, true);
583 /* layer update mandatory for mixer 16.0.33.0 */
584 if (ctx
->mxr_ver
== MXR_VER_16_0_33_0
)
585 mixer_layer_update(ctx
);
589 mixer_vsync_set_update(ctx
, true);
590 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
593 static void vp_win_reset(struct mixer_context
*ctx
)
595 struct mixer_resources
*res
= &ctx
->mixer_res
;
598 vp_reg_write(res
, VP_SRESET
, VP_SRESET_PROCESSING
);
599 for (tries
= 100; tries
; --tries
) {
600 /* waiting until VP_SRESET_PROCESSING is 0 */
601 if (~vp_reg_read(res
, VP_SRESET
) & VP_SRESET_PROCESSING
)
603 usleep_range(10000, 12000);
605 WARN(tries
== 0, "failed to reset Video Processor\n");
608 static void mixer_win_reset(struct mixer_context
*ctx
)
610 struct mixer_resources
*res
= &ctx
->mixer_res
;
612 u32 val
; /* value stored to register */
614 spin_lock_irqsave(&res
->reg_slock
, flags
);
615 mixer_vsync_set_update(ctx
, false);
617 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_DST_HDMI
, MXR_CFG_DST_MASK
);
619 /* set output in RGB888 mode */
620 mixer_reg_writemask(res
, MXR_CFG
, MXR_CFG_OUT_RGB888
, MXR_CFG_OUT_MASK
);
622 /* 16 beat burst in DMA */
623 mixer_reg_writemask(res
, MXR_STATUS
, MXR_STATUS_16_BURST
,
624 MXR_STATUS_BURST_MASK
);
626 /* setting default layer priority: layer1 > layer0 > video
627 * because typical usage scenario would be
629 * layer0 - framebuffer
630 * video - video overlay
632 val
= MXR_LAYER_CFG_GRP1_VAL(3);
633 val
|= MXR_LAYER_CFG_GRP0_VAL(2);
635 val
|= MXR_LAYER_CFG_VP_VAL(1);
636 mixer_reg_write(res
, MXR_LAYER_CFG
, val
);
638 /* setting background color */
639 mixer_reg_write(res
, MXR_BG_COLOR0
, 0x008080);
640 mixer_reg_write(res
, MXR_BG_COLOR1
, 0x008080);
641 mixer_reg_write(res
, MXR_BG_COLOR2
, 0x008080);
643 /* setting graphical layers */
644 val
= MXR_GRP_CFG_COLOR_KEY_DISABLE
; /* no blank key */
645 val
|= MXR_GRP_CFG_WIN_BLEND_EN
;
646 val
|= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
648 /* Don't blend layer 0 onto the mixer background */
649 mixer_reg_write(res
, MXR_GRAPHIC_CFG(0), val
);
651 /* Blend layer 1 into layer 0 */
652 val
|= MXR_GRP_CFG_BLEND_PRE_MUL
;
653 val
|= MXR_GRP_CFG_PIXEL_BLEND_EN
;
654 mixer_reg_write(res
, MXR_GRAPHIC_CFG(1), val
);
656 /* setting video layers */
657 val
= MXR_GRP_CFG_ALPHA_VAL(0);
658 mixer_reg_write(res
, MXR_VIDEO_CFG
, val
);
660 if (ctx
->vp_enabled
) {
661 /* configuration of Video Processor Registers */
663 vp_default_filter(res
);
666 /* disable all layers */
667 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP0_ENABLE
);
668 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_GRP1_ENABLE
);
670 mixer_reg_writemask(res
, MXR_CFG
, 0, MXR_CFG_VP_ENABLE
);
672 mixer_vsync_set_update(ctx
, true);
673 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
676 static int mixer_iommu_on(void *ctx
, bool enable
)
678 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
;
679 struct mixer_context
*mdata
= ctx
;
680 struct drm_device
*drm_dev
;
682 drm_hdmi_ctx
= mdata
->parent_ctx
;
683 drm_dev
= drm_hdmi_ctx
->drm_dev
;
685 if (is_drm_iommu_supported(drm_dev
)) {
687 return drm_iommu_attach_device(drm_dev
, mdata
->dev
);
689 drm_iommu_detach_device(drm_dev
, mdata
->dev
);
694 static int mixer_enable_vblank(void *ctx
, int pipe
)
696 struct mixer_context
*mixer_ctx
= ctx
;
697 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
699 mixer_ctx
->pipe
= pipe
;
701 /* enable vsync interrupt */
702 mixer_reg_writemask(res
, MXR_INT_EN
, MXR_INT_EN_VSYNC
,
708 static void mixer_disable_vblank(void *ctx
)
710 struct mixer_context
*mixer_ctx
= ctx
;
711 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
713 /* disable vsync interrupt */
714 mixer_reg_writemask(res
, MXR_INT_EN
, 0, MXR_INT_EN_VSYNC
);
717 static void mixer_win_mode_set(void *ctx
,
718 struct exynos_drm_overlay
*overlay
)
720 struct mixer_context
*mixer_ctx
= ctx
;
721 struct hdmi_win_data
*win_data
;
725 DRM_ERROR("overlay is NULL\n");
729 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
730 overlay
->fb_width
, overlay
->fb_height
,
731 overlay
->fb_x
, overlay
->fb_y
,
732 overlay
->crtc_width
, overlay
->crtc_height
,
733 overlay
->crtc_x
, overlay
->crtc_y
);
736 if (win
== DEFAULT_ZPOS
)
737 win
= MIXER_DEFAULT_WIN
;
739 if (win
< 0 || win
>= MIXER_WIN_NR
) {
740 DRM_ERROR("mixer window[%d] is wrong\n", win
);
744 win_data
= &mixer_ctx
->win_data
[win
];
746 win_data
->dma_addr
= overlay
->dma_addr
[0];
747 win_data
->chroma_dma_addr
= overlay
->dma_addr
[1];
748 win_data
->pixel_format
= overlay
->pixel_format
;
749 win_data
->bpp
= overlay
->bpp
;
751 win_data
->crtc_x
= overlay
->crtc_x
;
752 win_data
->crtc_y
= overlay
->crtc_y
;
753 win_data
->crtc_width
= overlay
->crtc_width
;
754 win_data
->crtc_height
= overlay
->crtc_height
;
756 win_data
->fb_x
= overlay
->fb_x
;
757 win_data
->fb_y
= overlay
->fb_y
;
758 win_data
->fb_width
= overlay
->fb_width
;
759 win_data
->fb_height
= overlay
->fb_height
;
760 win_data
->src_width
= overlay
->src_width
;
761 win_data
->src_height
= overlay
->src_height
;
763 win_data
->mode_width
= overlay
->mode_width
;
764 win_data
->mode_height
= overlay
->mode_height
;
766 win_data
->scan_flags
= overlay
->scan_flag
;
769 static void mixer_win_commit(void *ctx
, int win
)
771 struct mixer_context
*mixer_ctx
= ctx
;
773 DRM_DEBUG_KMS("win: %d\n", win
);
775 mutex_lock(&mixer_ctx
->mixer_mutex
);
776 if (!mixer_ctx
->powered
) {
777 mutex_unlock(&mixer_ctx
->mixer_mutex
);
780 mutex_unlock(&mixer_ctx
->mixer_mutex
);
782 if (win
> 1 && mixer_ctx
->vp_enabled
)
783 vp_video_buffer(mixer_ctx
, win
);
785 mixer_graph_buffer(mixer_ctx
, win
);
787 mixer_ctx
->win_data
[win
].enabled
= true;
790 static void mixer_win_disable(void *ctx
, int win
)
792 struct mixer_context
*mixer_ctx
= ctx
;
793 struct mixer_resources
*res
= &mixer_ctx
->mixer_res
;
796 DRM_DEBUG_KMS("win: %d\n", win
);
798 mutex_lock(&mixer_ctx
->mixer_mutex
);
799 if (!mixer_ctx
->powered
) {
800 mutex_unlock(&mixer_ctx
->mixer_mutex
);
801 mixer_ctx
->win_data
[win
].resume
= false;
804 mutex_unlock(&mixer_ctx
->mixer_mutex
);
806 spin_lock_irqsave(&res
->reg_slock
, flags
);
807 mixer_vsync_set_update(mixer_ctx
, false);
809 mixer_cfg_layer(mixer_ctx
, win
, false);
811 mixer_vsync_set_update(mixer_ctx
, true);
812 spin_unlock_irqrestore(&res
->reg_slock
, flags
);
814 mixer_ctx
->win_data
[win
].enabled
= false;
817 static int mixer_check_mode(void *ctx
, struct drm_display_mode
*mode
)
824 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
825 mode
->hdisplay
, mode
->vdisplay
, mode
->vrefresh
,
826 (mode
->flags
& DRM_MODE_FLAG_INTERLACE
) ? 1 : 0);
828 if ((w
>= 464 && w
<= 720 && h
>= 261 && h
<= 576) ||
829 (w
>= 1024 && w
<= 1280 && h
>= 576 && h
<= 720) ||
830 (w
>= 1664 && w
<= 1920 && h
>= 936 && h
<= 1080))
835 static void mixer_wait_for_vblank(void *ctx
)
837 struct mixer_context
*mixer_ctx
= ctx
;
839 mutex_lock(&mixer_ctx
->mixer_mutex
);
840 if (!mixer_ctx
->powered
) {
841 mutex_unlock(&mixer_ctx
->mixer_mutex
);
844 mutex_unlock(&mixer_ctx
->mixer_mutex
);
846 atomic_set(&mixer_ctx
->wait_vsync_event
, 1);
849 * wait for MIXER to signal VSYNC interrupt or return after
850 * timeout which is set to 50ms (refresh rate of 20).
852 if (!wait_event_timeout(mixer_ctx
->wait_vsync_queue
,
853 !atomic_read(&mixer_ctx
->wait_vsync_event
),
855 DRM_DEBUG_KMS("vblank wait timed out.\n");
858 static void mixer_window_suspend(struct mixer_context
*ctx
)
860 struct hdmi_win_data
*win_data
;
863 for (i
= 0; i
< MIXER_WIN_NR
; i
++) {
864 win_data
= &ctx
->win_data
[i
];
865 win_data
->resume
= win_data
->enabled
;
866 mixer_win_disable(ctx
, i
);
868 mixer_wait_for_vblank(ctx
);
871 static void mixer_window_resume(struct mixer_context
*ctx
)
873 struct hdmi_win_data
*win_data
;
876 for (i
= 0; i
< MIXER_WIN_NR
; i
++) {
877 win_data
= &ctx
->win_data
[i
];
878 win_data
->enabled
= win_data
->resume
;
879 win_data
->resume
= false;
883 static void mixer_poweron(struct mixer_context
*ctx
)
885 struct mixer_resources
*res
= &ctx
->mixer_res
;
887 mutex_lock(&ctx
->mixer_mutex
);
889 mutex_unlock(&ctx
->mixer_mutex
);
893 mutex_unlock(&ctx
->mixer_mutex
);
895 clk_prepare_enable(res
->mixer
);
896 if (ctx
->vp_enabled
) {
897 clk_prepare_enable(res
->vp
);
898 clk_prepare_enable(res
->sclk_mixer
);
901 mixer_reg_write(res
, MXR_INT_EN
, ctx
->int_en
);
902 mixer_win_reset(ctx
);
904 mixer_window_resume(ctx
);
907 static void mixer_poweroff(struct mixer_context
*ctx
)
909 struct mixer_resources
*res
= &ctx
->mixer_res
;
911 mutex_lock(&ctx
->mixer_mutex
);
914 mutex_unlock(&ctx
->mixer_mutex
);
916 mixer_window_suspend(ctx
);
918 ctx
->int_en
= mixer_reg_read(res
, MXR_INT_EN
);
920 clk_disable_unprepare(res
->mixer
);
921 if (ctx
->vp_enabled
) {
922 clk_disable_unprepare(res
->vp
);
923 clk_disable_unprepare(res
->sclk_mixer
);
926 mutex_lock(&ctx
->mixer_mutex
);
927 ctx
->powered
= false;
930 mutex_unlock(&ctx
->mixer_mutex
);
933 static void mixer_dpms(void *ctx
, int mode
)
935 struct mixer_context
*mixer_ctx
= ctx
;
938 case DRM_MODE_DPMS_ON
:
939 if (pm_runtime_suspended(mixer_ctx
->dev
))
940 pm_runtime_get_sync(mixer_ctx
->dev
);
942 case DRM_MODE_DPMS_STANDBY
:
943 case DRM_MODE_DPMS_SUSPEND
:
944 case DRM_MODE_DPMS_OFF
:
945 if (!pm_runtime_suspended(mixer_ctx
->dev
))
946 pm_runtime_put_sync(mixer_ctx
->dev
);
949 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode
);
954 static struct exynos_mixer_ops mixer_ops
= {
956 .iommu_on
= mixer_iommu_on
,
957 .enable_vblank
= mixer_enable_vblank
,
958 .disable_vblank
= mixer_disable_vblank
,
959 .wait_for_vblank
= mixer_wait_for_vblank
,
963 .win_mode_set
= mixer_win_mode_set
,
964 .win_commit
= mixer_win_commit
,
965 .win_disable
= mixer_win_disable
,
968 .check_mode
= mixer_check_mode
,
971 static irqreturn_t
mixer_irq_handler(int irq
, void *arg
)
973 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
= arg
;
974 struct mixer_context
*ctx
= drm_hdmi_ctx
->ctx
;
975 struct mixer_resources
*res
= &ctx
->mixer_res
;
976 u32 val
, base
, shadow
;
978 spin_lock(&res
->reg_slock
);
980 /* read interrupt status for handling and clearing flags for VSYNC */
981 val
= mixer_reg_read(res
, MXR_INT_STATUS
);
984 if (val
& MXR_INT_STATUS_VSYNC
) {
985 /* interlace scan need to check shadow register */
986 if (ctx
->interlace
) {
987 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(0));
988 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(0));
992 base
= mixer_reg_read(res
, MXR_GRAPHIC_BASE(1));
993 shadow
= mixer_reg_read(res
, MXR_GRAPHIC_BASE_S(1));
998 drm_handle_vblank(drm_hdmi_ctx
->drm_dev
, ctx
->pipe
);
999 exynos_drm_crtc_finish_pageflip(drm_hdmi_ctx
->drm_dev
,
1002 /* set wait vsync event to zero and wake up queue. */
1003 if (atomic_read(&ctx
->wait_vsync_event
)) {
1004 atomic_set(&ctx
->wait_vsync_event
, 0);
1005 DRM_WAKEUP(&ctx
->wait_vsync_queue
);
1010 /* clear interrupts */
1011 if (~val
& MXR_INT_EN_VSYNC
) {
1012 /* vsync interrupt use different bit for read and clear */
1013 val
&= ~MXR_INT_EN_VSYNC
;
1014 val
|= MXR_INT_CLEAR_VSYNC
;
1016 mixer_reg_write(res
, MXR_INT_STATUS
, val
);
1018 spin_unlock(&res
->reg_slock
);
1023 static int mixer_resources_init(struct exynos_drm_hdmi_context
*ctx
,
1024 struct platform_device
*pdev
)
1026 struct mixer_context
*mixer_ctx
= ctx
->ctx
;
1027 struct device
*dev
= &pdev
->dev
;
1028 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
1029 struct resource
*res
;
1032 spin_lock_init(&mixer_res
->reg_slock
);
1034 mixer_res
->mixer
= devm_clk_get(dev
, "mixer");
1035 if (IS_ERR(mixer_res
->mixer
)) {
1036 dev_err(dev
, "failed to get clock 'mixer'\n");
1040 mixer_res
->sclk_hdmi
= devm_clk_get(dev
, "sclk_hdmi");
1041 if (IS_ERR(mixer_res
->sclk_hdmi
)) {
1042 dev_err(dev
, "failed to get clock 'sclk_hdmi'\n");
1045 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1047 dev_err(dev
, "get memory resource failed.\n");
1051 mixer_res
->mixer_regs
= devm_ioremap(dev
, res
->start
,
1052 resource_size(res
));
1053 if (mixer_res
->mixer_regs
== NULL
) {
1054 dev_err(dev
, "register mapping failed.\n");
1058 res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
1060 dev_err(dev
, "get interrupt resource failed.\n");
1064 ret
= devm_request_irq(dev
, res
->start
, mixer_irq_handler
,
1065 0, "drm_mixer", ctx
);
1067 dev_err(dev
, "request interrupt failed.\n");
1070 mixer_res
->irq
= res
->start
;
1075 static int vp_resources_init(struct exynos_drm_hdmi_context
*ctx
,
1076 struct platform_device
*pdev
)
1078 struct mixer_context
*mixer_ctx
= ctx
->ctx
;
1079 struct device
*dev
= &pdev
->dev
;
1080 struct mixer_resources
*mixer_res
= &mixer_ctx
->mixer_res
;
1081 struct resource
*res
;
1083 mixer_res
->vp
= devm_clk_get(dev
, "vp");
1084 if (IS_ERR(mixer_res
->vp
)) {
1085 dev_err(dev
, "failed to get clock 'vp'\n");
1088 mixer_res
->sclk_mixer
= devm_clk_get(dev
, "sclk_mixer");
1089 if (IS_ERR(mixer_res
->sclk_mixer
)) {
1090 dev_err(dev
, "failed to get clock 'sclk_mixer'\n");
1093 mixer_res
->sclk_dac
= devm_clk_get(dev
, "sclk_dac");
1094 if (IS_ERR(mixer_res
->sclk_dac
)) {
1095 dev_err(dev
, "failed to get clock 'sclk_dac'\n");
1099 if (mixer_res
->sclk_hdmi
)
1100 clk_set_parent(mixer_res
->sclk_mixer
, mixer_res
->sclk_hdmi
);
1102 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
1104 dev_err(dev
, "get memory resource failed.\n");
1108 mixer_res
->vp_regs
= devm_ioremap(dev
, res
->start
,
1109 resource_size(res
));
1110 if (mixer_res
->vp_regs
== NULL
) {
1111 dev_err(dev
, "register mapping failed.\n");
1118 static struct mixer_drv_data exynos5_mxr_drv_data
= {
1119 .version
= MXR_VER_16_0_33_0
,
1123 static struct mixer_drv_data exynos4_mxr_drv_data
= {
1124 .version
= MXR_VER_0_0_0_16
,
1128 static struct platform_device_id mixer_driver_types
[] = {
1130 .name
= "s5p-mixer",
1131 .driver_data
= (unsigned long)&exynos4_mxr_drv_data
,
1133 .name
= "exynos5-mixer",
1134 .driver_data
= (unsigned long)&exynos5_mxr_drv_data
,
1140 static struct of_device_id mixer_match_types
[] = {
1142 .compatible
= "samsung,exynos5-mixer",
1143 .data
= &exynos5_mxr_drv_data
,
1149 static int mixer_probe(struct platform_device
*pdev
)
1151 struct device
*dev
= &pdev
->dev
;
1152 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
;
1153 struct mixer_context
*ctx
;
1154 struct mixer_drv_data
*drv
;
1157 dev_info(dev
, "probe start\n");
1159 drm_hdmi_ctx
= devm_kzalloc(dev
, sizeof(*drm_hdmi_ctx
),
1161 if (!drm_hdmi_ctx
) {
1162 DRM_ERROR("failed to allocate common hdmi context.\n");
1166 ctx
= devm_kzalloc(dev
, sizeof(*ctx
), GFP_KERNEL
);
1168 DRM_ERROR("failed to alloc mixer context.\n");
1172 mutex_init(&ctx
->mixer_mutex
);
1175 const struct of_device_id
*match
;
1176 match
= of_match_node(mixer_match_types
, dev
->of_node
);
1177 drv
= (struct mixer_drv_data
*)match
->data
;
1179 drv
= (struct mixer_drv_data
*)
1180 platform_get_device_id(pdev
)->driver_data
;
1184 ctx
->parent_ctx
= (void *)drm_hdmi_ctx
;
1185 drm_hdmi_ctx
->ctx
= (void *)ctx
;
1186 ctx
->vp_enabled
= drv
->is_vp_enabled
;
1187 ctx
->mxr_ver
= drv
->version
;
1188 DRM_INIT_WAITQUEUE(&ctx
->wait_vsync_queue
);
1189 atomic_set(&ctx
->wait_vsync_event
, 0);
1191 platform_set_drvdata(pdev
, drm_hdmi_ctx
);
1193 /* acquire resources: regs, irqs, clocks */
1194 ret
= mixer_resources_init(drm_hdmi_ctx
, pdev
);
1196 DRM_ERROR("mixer_resources_init failed\n");
1200 if (ctx
->vp_enabled
) {
1201 /* acquire vp resources: regs, irqs, clocks */
1202 ret
= vp_resources_init(drm_hdmi_ctx
, pdev
);
1204 DRM_ERROR("vp_resources_init failed\n");
1209 /* attach mixer driver to common hdmi. */
1210 exynos_mixer_drv_attach(drm_hdmi_ctx
);
1212 /* register specific callback point to common hdmi. */
1213 exynos_mixer_ops_register(&mixer_ops
);
1215 pm_runtime_enable(dev
);
1221 dev_info(dev
, "probe failed\n");
1225 static int mixer_remove(struct platform_device
*pdev
)
1227 dev_info(&pdev
->dev
, "remove successful\n");
1229 pm_runtime_disable(&pdev
->dev
);
1234 #ifdef CONFIG_PM_SLEEP
1235 static int mixer_suspend(struct device
*dev
)
1237 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
= get_mixer_context(dev
);
1238 struct mixer_context
*ctx
= drm_hdmi_ctx
->ctx
;
1240 if (pm_runtime_suspended(dev
)) {
1241 DRM_DEBUG_KMS("Already suspended\n");
1245 mixer_poweroff(ctx
);
1250 static int mixer_resume(struct device
*dev
)
1252 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
= get_mixer_context(dev
);
1253 struct mixer_context
*ctx
= drm_hdmi_ctx
->ctx
;
1255 if (!pm_runtime_suspended(dev
)) {
1256 DRM_DEBUG_KMS("Already resumed\n");
1266 #ifdef CONFIG_PM_RUNTIME
1267 static int mixer_runtime_suspend(struct device
*dev
)
1269 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
= get_mixer_context(dev
);
1270 struct mixer_context
*ctx
= drm_hdmi_ctx
->ctx
;
1272 mixer_poweroff(ctx
);
1277 static int mixer_runtime_resume(struct device
*dev
)
1279 struct exynos_drm_hdmi_context
*drm_hdmi_ctx
= get_mixer_context(dev
);
1280 struct mixer_context
*ctx
= drm_hdmi_ctx
->ctx
;
1288 static const struct dev_pm_ops mixer_pm_ops
= {
1289 SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend
, mixer_resume
)
1290 SET_RUNTIME_PM_OPS(mixer_runtime_suspend
, mixer_runtime_resume
, NULL
)
1293 struct platform_driver mixer_driver
= {
1295 .name
= "exynos-mixer",
1296 .owner
= THIS_MODULE
,
1297 .pm
= &mixer_pm_ops
,
1298 .of_match_table
= mixer_match_types
,
1300 .probe
= mixer_probe
,
1301 .remove
= mixer_remove
,
1302 .id_table
= mixer_driver_types
,