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>
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 {
84 struct mixer_context {
85 struct platform_device *pdev;
87 struct drm_device *drm_dev;
94 struct mutex mixer_mutex;
95 struct mixer_resources mixer_res;
96 struct hdmi_win_data win_data[MIXER_WIN_NR];
97 enum mixer_version_id mxr_ver;
99 wait_queue_head_t wait_vsync_queue;
100 atomic_t wait_vsync_event;
103 struct mixer_drv_data {
104 enum mixer_version_id version;
108 static const u8 filter_y_horiz_tap8[] = {
109 0, -1, -1, -1, -1, -1, -1, -1,
110 -1, -1, -1, -1, -1, 0, 0, 0,
111 0, 2, 4, 5, 6, 6, 6, 6,
112 6, 5, 5, 4, 3, 2, 1, 1,
113 0, -6, -12, -16, -18, -20, -21, -20,
114 -20, -18, -16, -13, -10, -8, -5, -2,
115 127, 126, 125, 121, 114, 107, 99, 89,
116 79, 68, 57, 46, 35, 25, 16, 8,
119 static const u8 filter_y_vert_tap4[] = {
120 0, -3, -6, -8, -8, -8, -8, -7,
121 -6, -5, -4, -3, -2, -1, -1, 0,
122 127, 126, 124, 118, 111, 102, 92, 81,
123 70, 59, 48, 37, 27, 19, 11, 5,
124 0, 5, 11, 19, 27, 37, 48, 59,
125 70, 81, 92, 102, 111, 118, 124, 126,
126 0, 0, -1, -1, -2, -3, -4, -5,
127 -6, -7, -8, -8, -8, -8, -6, -3,
130 static const u8 filter_cr_horiz_tap4[] = {
131 0, -3, -6, -8, -8, -8, -8, -7,
132 -6, -5, -4, -3, -2, -1, -1, 0,
133 127, 126, 124, 118, 111, 102, 92, 81,
134 70, 59, 48, 37, 27, 19, 11, 5,
137 static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
139 return readl(res->vp_regs + reg_id);
142 static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
145 writel(val, res->vp_regs + reg_id);
148 static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
151 u32 old = vp_reg_read(res, reg_id);
153 val = (val & mask) | (old & ~mask);
154 writel(val, res->vp_regs + reg_id);
157 static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
159 return readl(res->mixer_regs + reg_id);
162 static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
165 writel(val, res->mixer_regs + reg_id);
168 static inline void mixer_reg_writemask(struct mixer_resources *res,
169 u32 reg_id, u32 val, u32 mask)
171 u32 old = mixer_reg_read(res, reg_id);
173 val = (val & mask) | (old & ~mask);
174 writel(val, res->mixer_regs + reg_id);
177 static void mixer_regs_dump(struct mixer_context *ctx)
179 #define DUMPREG(reg_id) \
181 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
182 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
188 DUMPREG(MXR_INT_STATUS);
190 DUMPREG(MXR_LAYER_CFG);
191 DUMPREG(MXR_VIDEO_CFG);
193 DUMPREG(MXR_GRAPHIC0_CFG);
194 DUMPREG(MXR_GRAPHIC0_BASE);
195 DUMPREG(MXR_GRAPHIC0_SPAN);
196 DUMPREG(MXR_GRAPHIC0_WH);
197 DUMPREG(MXR_GRAPHIC0_SXY);
198 DUMPREG(MXR_GRAPHIC0_DXY);
200 DUMPREG(MXR_GRAPHIC1_CFG);
201 DUMPREG(MXR_GRAPHIC1_BASE);
202 DUMPREG(MXR_GRAPHIC1_SPAN);
203 DUMPREG(MXR_GRAPHIC1_WH);
204 DUMPREG(MXR_GRAPHIC1_SXY);
205 DUMPREG(MXR_GRAPHIC1_DXY);
209 static void vp_regs_dump(struct mixer_context *ctx)
211 #define DUMPREG(reg_id) \
213 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
214 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
219 DUMPREG(VP_SHADOW_UPDATE);
220 DUMPREG(VP_FIELD_ID);
222 DUMPREG(VP_IMG_SIZE_Y);
223 DUMPREG(VP_IMG_SIZE_C);
224 DUMPREG(VP_PER_RATE_CTRL);
225 DUMPREG(VP_TOP_Y_PTR);
226 DUMPREG(VP_BOT_Y_PTR);
227 DUMPREG(VP_TOP_C_PTR);
228 DUMPREG(VP_BOT_C_PTR);
229 DUMPREG(VP_ENDIAN_MODE);
230 DUMPREG(VP_SRC_H_POSITION);
231 DUMPREG(VP_SRC_V_POSITION);
232 DUMPREG(VP_SRC_WIDTH);
233 DUMPREG(VP_SRC_HEIGHT);
234 DUMPREG(VP_DST_H_POSITION);
235 DUMPREG(VP_DST_V_POSITION);
236 DUMPREG(VP_DST_WIDTH);
237 DUMPREG(VP_DST_HEIGHT);
244 static inline void vp_filter_set(struct mixer_resources *res,
245 int reg_id, const u8 *data, unsigned int size)
247 /* assure 4-byte align */
249 for (; size; size -= 4, reg_id += 4, data += 4) {
250 u32 val = (data[0] << 24) | (data[1] << 16) |
251 (data[2] << 8) | data[3];
252 vp_reg_write(res, reg_id, val);
256 static void vp_default_filter(struct mixer_resources *res)
258 vp_filter_set(res, VP_POLY8_Y0_LL,
259 filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
260 vp_filter_set(res, VP_POLY4_Y0_LL,
261 filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
262 vp_filter_set(res, VP_POLY4_C0_LL,
263 filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
266 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
268 struct mixer_resources *res = &ctx->mixer_res;
270 /* block update on vsync */
271 mixer_reg_writemask(res, MXR_STATUS, enable ?
272 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
275 vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
276 VP_SHADOW_UPDATE_ENABLE : 0);
279 static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
281 struct mixer_resources *res = &ctx->mixer_res;
284 /* choosing between interlace and progressive mode */
285 val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
286 MXR_CFG_SCAN_PROGRASSIVE);
288 if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
289 /* choosing between proper HD and SD mode */
291 val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
292 else if (height <= 576)
293 val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
294 else if (height <= 720)
295 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
296 else if (height <= 1080)
297 val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
299 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
302 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
305 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
307 struct mixer_resources *res = &ctx->mixer_res;
311 val = MXR_CFG_RGB601_0_255;
312 } else if (height == 576) {
313 val = MXR_CFG_RGB601_0_255;
314 } else if (height == 720) {
315 val = MXR_CFG_RGB709_16_235;
316 mixer_reg_write(res, MXR_CM_COEFF_Y,
317 (1 << 30) | (94 << 20) | (314 << 10) |
319 mixer_reg_write(res, MXR_CM_COEFF_CB,
320 (972 << 20) | (851 << 10) | (225 << 0));
321 mixer_reg_write(res, MXR_CM_COEFF_CR,
322 (225 << 20) | (820 << 10) | (1004 << 0));
323 } else if (height == 1080) {
324 val = MXR_CFG_RGB709_16_235;
325 mixer_reg_write(res, MXR_CM_COEFF_Y,
326 (1 << 30) | (94 << 20) | (314 << 10) |
328 mixer_reg_write(res, MXR_CM_COEFF_CB,
329 (972 << 20) | (851 << 10) | (225 << 0));
330 mixer_reg_write(res, MXR_CM_COEFF_CR,
331 (225 << 20) | (820 << 10) | (1004 << 0));
333 val = MXR_CFG_RGB709_16_235;
334 mixer_reg_write(res, MXR_CM_COEFF_Y,
335 (1 << 30) | (94 << 20) | (314 << 10) |
337 mixer_reg_write(res, MXR_CM_COEFF_CB,
338 (972 << 20) | (851 << 10) | (225 << 0));
339 mixer_reg_write(res, MXR_CM_COEFF_CR,
340 (225 << 20) | (820 << 10) | (1004 << 0));
343 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
346 static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
348 struct mixer_resources *res = &ctx->mixer_res;
349 u32 val = enable ? ~0 : 0;
353 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
356 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
359 if (ctx->vp_enabled) {
360 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
361 mixer_reg_writemask(res, MXR_CFG, val,
368 static void mixer_run(struct mixer_context *ctx)
370 struct mixer_resources *res = &ctx->mixer_res;
372 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
374 mixer_regs_dump(ctx);
377 static void vp_video_buffer(struct mixer_context *ctx, int win)
379 struct mixer_resources *res = &ctx->mixer_res;
381 struct hdmi_win_data *win_data;
382 unsigned int x_ratio, y_ratio;
383 unsigned int buf_num = 1;
384 dma_addr_t luma_addr[2], chroma_addr[2];
385 bool tiled_mode = false;
386 bool crcb_mode = false;
389 win_data = &ctx->win_data[win];
391 switch (win_data->pixel_format) {
392 case DRM_FORMAT_NV12MT:
394 case DRM_FORMAT_NV12:
398 /* TODO: single buffer format NV12, NV21 */
400 /* ignore pixel format at disable time */
401 if (!win_data->dma_addr)
404 DRM_ERROR("pixel format for vp is wrong [%d].\n",
405 win_data->pixel_format);
409 /* scaling feature: (src << 16) / dst */
410 x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
411 y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
414 luma_addr[0] = win_data->dma_addr;
415 chroma_addr[0] = win_data->chroma_dma_addr;
417 luma_addr[0] = win_data->dma_addr;
418 chroma_addr[0] = win_data->dma_addr
419 + (win_data->fb_width * win_data->fb_height);
422 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
423 ctx->interlace = true;
425 luma_addr[1] = luma_addr[0] + 0x40;
426 chroma_addr[1] = chroma_addr[0] + 0x40;
428 luma_addr[1] = luma_addr[0] + win_data->fb_width;
429 chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
432 ctx->interlace = false;
437 spin_lock_irqsave(&res->reg_slock, flags);
438 mixer_vsync_set_update(ctx, false);
440 /* interlace or progressive scan mode */
441 val = (ctx->interlace ? ~0 : 0);
442 vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
445 val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
446 val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
447 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
449 /* setting size of input image */
450 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
451 VP_IMG_VSIZE(win_data->fb_height));
452 /* chroma height has to reduced by 2 to avoid chroma distorions */
453 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
454 VP_IMG_VSIZE(win_data->fb_height / 2));
456 vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
457 vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
458 vp_reg_write(res, VP_SRC_H_POSITION,
459 VP_SRC_H_POSITION_VAL(win_data->fb_x));
460 vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
462 vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
463 vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
464 if (ctx->interlace) {
465 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
466 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
468 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
469 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
472 vp_reg_write(res, VP_H_RATIO, x_ratio);
473 vp_reg_write(res, VP_V_RATIO, y_ratio);
475 vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
477 /* set buffer address to vp */
478 vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
479 vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
480 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
481 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
483 mixer_cfg_scan(ctx, win_data->mode_height);
484 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
485 mixer_cfg_layer(ctx, win, true);
488 mixer_vsync_set_update(ctx, true);
489 spin_unlock_irqrestore(&res->reg_slock, flags);
494 static void mixer_layer_update(struct mixer_context *ctx)
496 struct mixer_resources *res = &ctx->mixer_res;
499 val = mixer_reg_read(res, MXR_CFG);
501 /* allow one update per vsync only */
502 if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
503 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
506 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
508 struct mixer_resources *res = &ctx->mixer_res;
510 struct hdmi_win_data *win_data;
511 unsigned int x_ratio, y_ratio;
512 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
517 win_data = &ctx->win_data[win];
524 switch (win_data->bpp) {
535 /* 2x scaling feature */
539 dst_x_offset = win_data->crtc_x;
540 dst_y_offset = win_data->crtc_y;
542 /* converting dma address base and source offset */
543 dma_addr = win_data->dma_addr
544 + (win_data->fb_x * win_data->bpp >> 3)
545 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
549 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE)
550 ctx->interlace = true;
552 ctx->interlace = false;
554 spin_lock_irqsave(&res->reg_slock, flags);
555 mixer_vsync_set_update(ctx, false);
558 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
559 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
562 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
564 /* setup display size */
565 if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
566 win == MIXER_DEFAULT_WIN) {
567 val = MXR_MXR_RES_HEIGHT(win_data->fb_height);
568 val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
569 mixer_reg_write(res, MXR_RESOLUTION, val);
572 val = MXR_GRP_WH_WIDTH(win_data->crtc_width);
573 val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
574 val |= MXR_GRP_WH_H_SCALE(x_ratio);
575 val |= MXR_GRP_WH_V_SCALE(y_ratio);
576 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
578 /* setup offsets in source image */
579 val = MXR_GRP_SXY_SX(src_x_offset);
580 val |= MXR_GRP_SXY_SY(src_y_offset);
581 mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
583 /* setup offsets in display image */
584 val = MXR_GRP_DXY_DX(dst_x_offset);
585 val |= MXR_GRP_DXY_DY(dst_y_offset);
586 mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
588 /* set buffer address to mixer */
589 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
591 mixer_cfg_scan(ctx, win_data->mode_height);
592 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
593 mixer_cfg_layer(ctx, win, true);
595 /* layer update mandatory for mixer 16.0.33.0 */
596 if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
597 ctx->mxr_ver == MXR_VER_128_0_0_184)
598 mixer_layer_update(ctx);
602 mixer_vsync_set_update(ctx, true);
603 spin_unlock_irqrestore(&res->reg_slock, flags);
606 static void vp_win_reset(struct mixer_context *ctx)
608 struct mixer_resources *res = &ctx->mixer_res;
611 vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
612 for (tries = 100; tries; --tries) {
613 /* waiting until VP_SRESET_PROCESSING is 0 */
614 if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
616 usleep_range(10000, 12000);
618 WARN(tries == 0, "failed to reset Video Processor\n");
621 static void mixer_win_reset(struct mixer_context *ctx)
623 struct mixer_resources *res = &ctx->mixer_res;
625 u32 val; /* value stored to register */
627 spin_lock_irqsave(&res->reg_slock, flags);
628 mixer_vsync_set_update(ctx, false);
630 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
632 /* set output in RGB888 mode */
633 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
635 /* 16 beat burst in DMA */
636 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
637 MXR_STATUS_BURST_MASK);
639 /* setting default layer priority: layer1 > layer0 > video
640 * because typical usage scenario would be
642 * layer0 - framebuffer
643 * video - video overlay
645 val = MXR_LAYER_CFG_GRP1_VAL(3);
646 val |= MXR_LAYER_CFG_GRP0_VAL(2);
648 val |= MXR_LAYER_CFG_VP_VAL(1);
649 mixer_reg_write(res, MXR_LAYER_CFG, val);
651 /* setting background color */
652 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
653 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
654 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
656 /* setting graphical layers */
657 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
658 val |= MXR_GRP_CFG_WIN_BLEND_EN;
659 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
661 /* Don't blend layer 0 onto the mixer background */
662 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
664 /* Blend layer 1 into layer 0 */
665 val |= MXR_GRP_CFG_BLEND_PRE_MUL;
666 val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
667 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
669 /* setting video layers */
670 val = MXR_GRP_CFG_ALPHA_VAL(0);
671 mixer_reg_write(res, MXR_VIDEO_CFG, val);
673 if (ctx->vp_enabled) {
674 /* configuration of Video Processor Registers */
676 vp_default_filter(res);
679 /* disable all layers */
680 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
681 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
683 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
685 mixer_vsync_set_update(ctx, true);
686 spin_unlock_irqrestore(&res->reg_slock, flags);
689 static irqreturn_t mixer_irq_handler(int irq, void *arg)
691 struct mixer_context *ctx = arg;
692 struct mixer_resources *res = &ctx->mixer_res;
693 u32 val, base, shadow;
695 spin_lock(&res->reg_slock);
697 /* read interrupt status for handling and clearing flags for VSYNC */
698 val = mixer_reg_read(res, MXR_INT_STATUS);
701 if (val & MXR_INT_STATUS_VSYNC) {
702 /* interlace scan need to check shadow register */
703 if (ctx->interlace) {
704 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
705 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
709 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
710 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
715 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
716 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
718 /* set wait vsync event to zero and wake up queue. */
719 if (atomic_read(&ctx->wait_vsync_event)) {
720 atomic_set(&ctx->wait_vsync_event, 0);
721 wake_up(&ctx->wait_vsync_queue);
726 /* clear interrupts */
727 if (~val & MXR_INT_EN_VSYNC) {
728 /* vsync interrupt use different bit for read and clear */
729 val &= ~MXR_INT_EN_VSYNC;
730 val |= MXR_INT_CLEAR_VSYNC;
732 mixer_reg_write(res, MXR_INT_STATUS, val);
734 spin_unlock(&res->reg_slock);
739 static int mixer_resources_init(struct mixer_context *mixer_ctx)
741 struct device *dev = &mixer_ctx->pdev->dev;
742 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
743 struct resource *res;
746 spin_lock_init(&mixer_res->reg_slock);
748 mixer_res->mixer = devm_clk_get(dev, "mixer");
749 if (IS_ERR(mixer_res->mixer)) {
750 dev_err(dev, "failed to get clock 'mixer'\n");
754 mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
755 if (IS_ERR(mixer_res->sclk_hdmi)) {
756 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
759 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
761 dev_err(dev, "get memory resource failed.\n");
765 mixer_res->mixer_regs = devm_ioremap(dev, res->start,
767 if (mixer_res->mixer_regs == NULL) {
768 dev_err(dev, "register mapping failed.\n");
772 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
774 dev_err(dev, "get interrupt resource failed.\n");
778 ret = devm_request_irq(dev, res->start, mixer_irq_handler,
779 0, "drm_mixer", mixer_ctx);
781 dev_err(dev, "request interrupt failed.\n");
784 mixer_res->irq = res->start;
789 static int vp_resources_init(struct mixer_context *mixer_ctx)
791 struct device *dev = &mixer_ctx->pdev->dev;
792 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
793 struct resource *res;
795 mixer_res->vp = devm_clk_get(dev, "vp");
796 if (IS_ERR(mixer_res->vp)) {
797 dev_err(dev, "failed to get clock 'vp'\n");
800 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
801 if (IS_ERR(mixer_res->sclk_mixer)) {
802 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
805 mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
806 if (IS_ERR(mixer_res->sclk_dac)) {
807 dev_err(dev, "failed to get clock 'sclk_dac'\n");
811 if (mixer_res->sclk_hdmi)
812 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
814 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
816 dev_err(dev, "get memory resource failed.\n");
820 mixer_res->vp_regs = devm_ioremap(dev, res->start,
822 if (mixer_res->vp_regs == NULL) {
823 dev_err(dev, "register mapping failed.\n");
830 static int mixer_initialize(void *ctx, struct drm_device *drm_dev)
833 struct mixer_context *mixer_ctx = ctx;
835 mixer_ctx->drm_dev = drm_dev;
837 /* acquire resources: regs, irqs, clocks */
838 ret = mixer_resources_init(mixer_ctx);
840 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
844 if (mixer_ctx->vp_enabled) {
845 /* acquire vp resources: regs, irqs, clocks */
846 ret = vp_resources_init(mixer_ctx);
848 DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
856 static int mixer_iommu_on(void *ctx, bool enable)
858 struct mixer_context *mdata = ctx;
860 if (is_drm_iommu_supported(mdata->drm_dev)) {
862 return drm_iommu_attach_device(mdata->drm_dev,
865 drm_iommu_detach_device(mdata->drm_dev, mdata->dev);
870 static int mixer_enable_vblank(void *ctx, int pipe)
872 struct mixer_context *mixer_ctx = ctx;
873 struct mixer_resources *res = &mixer_ctx->mixer_res;
875 mixer_ctx->pipe = pipe;
877 /* enable vsync interrupt */
878 mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
884 static void mixer_disable_vblank(void *ctx)
886 struct mixer_context *mixer_ctx = ctx;
887 struct mixer_resources *res = &mixer_ctx->mixer_res;
889 /* disable vsync interrupt */
890 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
893 static void mixer_win_mode_set(void *ctx,
894 struct exynos_drm_overlay *overlay)
896 struct mixer_context *mixer_ctx = ctx;
897 struct hdmi_win_data *win_data;
901 DRM_ERROR("overlay is NULL\n");
905 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
906 overlay->fb_width, overlay->fb_height,
907 overlay->fb_x, overlay->fb_y,
908 overlay->crtc_width, overlay->crtc_height,
909 overlay->crtc_x, overlay->crtc_y);
912 if (win == DEFAULT_ZPOS)
913 win = MIXER_DEFAULT_WIN;
915 if (win < 0 || win >= MIXER_WIN_NR) {
916 DRM_ERROR("mixer window[%d] is wrong\n", win);
920 win_data = &mixer_ctx->win_data[win];
922 win_data->dma_addr = overlay->dma_addr[0];
923 win_data->chroma_dma_addr = overlay->dma_addr[1];
924 win_data->pixel_format = overlay->pixel_format;
925 win_data->bpp = overlay->bpp;
927 win_data->crtc_x = overlay->crtc_x;
928 win_data->crtc_y = overlay->crtc_y;
929 win_data->crtc_width = overlay->crtc_width;
930 win_data->crtc_height = overlay->crtc_height;
932 win_data->fb_x = overlay->fb_x;
933 win_data->fb_y = overlay->fb_y;
934 win_data->fb_width = overlay->fb_width;
935 win_data->fb_height = overlay->fb_height;
936 win_data->src_width = overlay->src_width;
937 win_data->src_height = overlay->src_height;
939 win_data->mode_width = overlay->mode_width;
940 win_data->mode_height = overlay->mode_height;
942 win_data->scan_flags = overlay->scan_flag;
945 static void mixer_win_commit(void *ctx, int win)
947 struct mixer_context *mixer_ctx = ctx;
949 DRM_DEBUG_KMS("win: %d\n", win);
951 mutex_lock(&mixer_ctx->mixer_mutex);
952 if (!mixer_ctx->powered) {
953 mutex_unlock(&mixer_ctx->mixer_mutex);
956 mutex_unlock(&mixer_ctx->mixer_mutex);
958 if (win > 1 && mixer_ctx->vp_enabled)
959 vp_video_buffer(mixer_ctx, win);
961 mixer_graph_buffer(mixer_ctx, win);
963 mixer_ctx->win_data[win].enabled = true;
966 static void mixer_win_disable(void *ctx, int win)
968 struct mixer_context *mixer_ctx = ctx;
969 struct mixer_resources *res = &mixer_ctx->mixer_res;
972 DRM_DEBUG_KMS("win: %d\n", win);
974 mutex_lock(&mixer_ctx->mixer_mutex);
975 if (!mixer_ctx->powered) {
976 mutex_unlock(&mixer_ctx->mixer_mutex);
977 mixer_ctx->win_data[win].resume = false;
980 mutex_unlock(&mixer_ctx->mixer_mutex);
982 spin_lock_irqsave(&res->reg_slock, flags);
983 mixer_vsync_set_update(mixer_ctx, false);
985 mixer_cfg_layer(mixer_ctx, win, false);
987 mixer_vsync_set_update(mixer_ctx, true);
988 spin_unlock_irqrestore(&res->reg_slock, flags);
990 mixer_ctx->win_data[win].enabled = false;
993 static int mixer_check_mode(void *ctx, struct drm_display_mode *mode)
995 struct mixer_context *mixer_ctx = ctx;
1001 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1002 mode->hdisplay, mode->vdisplay, mode->vrefresh,
1003 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1005 if (mixer_ctx->mxr_ver == MXR_VER_0_0_0_16 ||
1006 mixer_ctx->mxr_ver == MXR_VER_128_0_0_184)
1009 if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
1010 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
1011 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
1016 static void mixer_wait_for_vblank(void *ctx)
1018 struct mixer_context *mixer_ctx = ctx;
1020 mutex_lock(&mixer_ctx->mixer_mutex);
1021 if (!mixer_ctx->powered) {
1022 mutex_unlock(&mixer_ctx->mixer_mutex);
1025 mutex_unlock(&mixer_ctx->mixer_mutex);
1027 atomic_set(&mixer_ctx->wait_vsync_event, 1);
1030 * wait for MIXER to signal VSYNC interrupt or return after
1031 * timeout which is set to 50ms (refresh rate of 20).
1033 if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
1034 !atomic_read(&mixer_ctx->wait_vsync_event),
1036 DRM_DEBUG_KMS("vblank wait timed out.\n");
1039 static void mixer_window_suspend(struct mixer_context *ctx)
1041 struct hdmi_win_data *win_data;
1044 for (i = 0; i < MIXER_WIN_NR; i++) {
1045 win_data = &ctx->win_data[i];
1046 win_data->resume = win_data->enabled;
1047 mixer_win_disable(ctx, i);
1049 mixer_wait_for_vblank(ctx);
1052 static void mixer_window_resume(struct mixer_context *ctx)
1054 struct hdmi_win_data *win_data;
1057 for (i = 0; i < MIXER_WIN_NR; i++) {
1058 win_data = &ctx->win_data[i];
1059 win_data->enabled = win_data->resume;
1060 win_data->resume = false;
1064 static void mixer_poweron(struct mixer_context *ctx)
1066 struct mixer_resources *res = &ctx->mixer_res;
1068 mutex_lock(&ctx->mixer_mutex);
1070 mutex_unlock(&ctx->mixer_mutex);
1073 ctx->powered = true;
1074 mutex_unlock(&ctx->mixer_mutex);
1076 clk_prepare_enable(res->mixer);
1077 if (ctx->vp_enabled) {
1078 clk_prepare_enable(res->vp);
1079 clk_prepare_enable(res->sclk_mixer);
1082 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1083 mixer_win_reset(ctx);
1085 mixer_window_resume(ctx);
1088 static void mixer_poweroff(struct mixer_context *ctx)
1090 struct mixer_resources *res = &ctx->mixer_res;
1092 mutex_lock(&ctx->mixer_mutex);
1095 mutex_unlock(&ctx->mixer_mutex);
1097 mixer_window_suspend(ctx);
1099 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1101 clk_disable_unprepare(res->mixer);
1102 if (ctx->vp_enabled) {
1103 clk_disable_unprepare(res->vp);
1104 clk_disable_unprepare(res->sclk_mixer);
1107 mutex_lock(&ctx->mixer_mutex);
1108 ctx->powered = false;
1111 mutex_unlock(&ctx->mixer_mutex);
1114 static void mixer_dpms(void *ctx, int mode)
1116 struct mixer_context *mixer_ctx = ctx;
1119 case DRM_MODE_DPMS_ON:
1120 if (pm_runtime_suspended(mixer_ctx->dev))
1121 pm_runtime_get_sync(mixer_ctx->dev);
1123 case DRM_MODE_DPMS_STANDBY:
1124 case DRM_MODE_DPMS_SUSPEND:
1125 case DRM_MODE_DPMS_OFF:
1126 if (!pm_runtime_suspended(mixer_ctx->dev))
1127 pm_runtime_put_sync(mixer_ctx->dev);
1130 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
1135 static struct exynos_mixer_ops mixer_ops = {
1137 .initialize = mixer_initialize,
1138 .iommu_on = mixer_iommu_on,
1139 .enable_vblank = mixer_enable_vblank,
1140 .disable_vblank = mixer_disable_vblank,
1141 .wait_for_vblank = mixer_wait_for_vblank,
1143 .win_mode_set = mixer_win_mode_set,
1144 .win_commit = mixer_win_commit,
1145 .win_disable = mixer_win_disable,
1148 .check_mode = mixer_check_mode,
1151 static struct mixer_drv_data exynos5420_mxr_drv_data = {
1152 .version = MXR_VER_128_0_0_184,
1156 static struct mixer_drv_data exynos5250_mxr_drv_data = {
1157 .version = MXR_VER_16_0_33_0,
1161 static struct mixer_drv_data exynos4210_mxr_drv_data = {
1162 .version = MXR_VER_0_0_0_16,
1166 static struct platform_device_id mixer_driver_types[] = {
1168 .name = "s5p-mixer",
1169 .driver_data = (unsigned long)&exynos4210_mxr_drv_data,
1171 .name = "exynos5-mixer",
1172 .driver_data = (unsigned long)&exynos5250_mxr_drv_data,
1178 static struct of_device_id mixer_match_types[] = {
1180 .compatible = "samsung,exynos5-mixer",
1181 .data = &exynos5250_mxr_drv_data,
1183 .compatible = "samsung,exynos5250-mixer",
1184 .data = &exynos5250_mxr_drv_data,
1186 .compatible = "samsung,exynos5420-mixer",
1187 .data = &exynos5420_mxr_drv_data,
1193 static int mixer_probe(struct platform_device *pdev)
1195 struct device *dev = &pdev->dev;
1196 struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1197 struct mixer_context *ctx;
1198 struct mixer_drv_data *drv;
1200 dev_info(dev, "probe start\n");
1202 drm_hdmi_ctx = devm_kzalloc(dev, sizeof(*drm_hdmi_ctx),
1207 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1211 mutex_init(&ctx->mixer_mutex);
1214 const struct of_device_id *match;
1215 match = of_match_node(mixer_match_types, dev->of_node);
1216 drv = (struct mixer_drv_data *)match->data;
1218 drv = (struct mixer_drv_data *)
1219 platform_get_device_id(pdev)->driver_data;
1224 ctx->parent_ctx = (void *)drm_hdmi_ctx;
1225 drm_hdmi_ctx->ctx = (void *)ctx;
1226 ctx->vp_enabled = drv->is_vp_enabled;
1227 ctx->mxr_ver = drv->version;
1228 init_waitqueue_head(&ctx->wait_vsync_queue);
1229 atomic_set(&ctx->wait_vsync_event, 0);
1231 platform_set_drvdata(pdev, drm_hdmi_ctx);
1233 /* attach mixer driver to common hdmi. */
1234 exynos_mixer_drv_attach(drm_hdmi_ctx);
1236 /* register specific callback point to common hdmi. */
1237 exynos_mixer_ops_register(&mixer_ops);
1239 pm_runtime_enable(dev);
1244 static int mixer_remove(struct platform_device *pdev)
1246 dev_info(&pdev->dev, "remove successful\n");
1248 pm_runtime_disable(&pdev->dev);
1253 #ifdef CONFIG_PM_SLEEP
1254 static int mixer_suspend(struct device *dev)
1256 struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1257 struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1259 if (pm_runtime_suspended(dev)) {
1260 DRM_DEBUG_KMS("Already suspended\n");
1264 mixer_poweroff(ctx);
1269 static int mixer_resume(struct device *dev)
1271 struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1272 struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1274 if (!pm_runtime_suspended(dev)) {
1275 DRM_DEBUG_KMS("Already resumed\n");
1285 #ifdef CONFIG_PM_RUNTIME
1286 static int mixer_runtime_suspend(struct device *dev)
1288 struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1289 struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1291 mixer_poweroff(ctx);
1296 static int mixer_runtime_resume(struct device *dev)
1298 struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1299 struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1307 static const struct dev_pm_ops mixer_pm_ops = {
1308 SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume)
1309 SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL)
1312 struct platform_driver mixer_driver = {
1314 .name = "exynos-mixer",
1315 .owner = THIS_MODULE,
1316 .pm = &mixer_pm_ops,
1317 .of_match_table = mixer_match_types,
1319 .probe = mixer_probe,
1320 .remove = mixer_remove,
1321 .id_table = mixer_driver_types,