2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
4 * Seung-Woo Kim <sw0312.kim@samsung.com>
5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com>
8 * Based on drivers/media/video/s5p-tv/mixer_reg.c
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
19 #include "regs-mixer.h"
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <linux/i2c.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/clk.h>
32 #include <linux/regulator/consumer.h>
34 #include <linux/component.h>
36 #include <drm/exynos_drm.h>
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_crtc.h"
40 #include "exynos_drm_iommu.h"
41 #include "exynos_mixer.h"
43 #define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev))
45 #define MIXER_WIN_NR 3
46 #define MIXER_DEFAULT_WIN 0
48 struct hdmi_win_data {
50 dma_addr_t chroma_dma_addr;
51 uint32_t pixel_format;
55 unsigned int crtc_width;
56 unsigned int crtc_height;
59 unsigned int fb_width;
60 unsigned int fb_height;
61 unsigned int src_width;
62 unsigned int src_height;
63 unsigned int mode_width;
64 unsigned int mode_height;
65 unsigned int scan_flags;
70 struct mixer_resources {
72 void __iomem *mixer_regs;
73 void __iomem *vp_regs;
77 struct clk *sclk_mixer;
78 struct clk *sclk_hdmi;
82 enum mixer_version_id {
88 struct mixer_context {
89 struct platform_device *pdev;
91 struct drm_device *drm_dev;
98 struct mutex mixer_mutex;
99 struct mixer_resources mixer_res;
100 struct hdmi_win_data win_data[MIXER_WIN_NR];
101 enum mixer_version_id mxr_ver;
102 wait_queue_head_t wait_vsync_queue;
103 atomic_t wait_vsync_event;
106 struct mixer_drv_data {
107 enum mixer_version_id version;
111 static const u8 filter_y_horiz_tap8[] = {
112 0, -1, -1, -1, -1, -1, -1, -1,
113 -1, -1, -1, -1, -1, 0, 0, 0,
114 0, 2, 4, 5, 6, 6, 6, 6,
115 6, 5, 5, 4, 3, 2, 1, 1,
116 0, -6, -12, -16, -18, -20, -21, -20,
117 -20, -18, -16, -13, -10, -8, -5, -2,
118 127, 126, 125, 121, 114, 107, 99, 89,
119 79, 68, 57, 46, 35, 25, 16, 8,
122 static const u8 filter_y_vert_tap4[] = {
123 0, -3, -6, -8, -8, -8, -8, -7,
124 -6, -5, -4, -3, -2, -1, -1, 0,
125 127, 126, 124, 118, 111, 102, 92, 81,
126 70, 59, 48, 37, 27, 19, 11, 5,
127 0, 5, 11, 19, 27, 37, 48, 59,
128 70, 81, 92, 102, 111, 118, 124, 126,
129 0, 0, -1, -1, -2, -3, -4, -5,
130 -6, -7, -8, -8, -8, -8, -6, -3,
133 static const u8 filter_cr_horiz_tap4[] = {
134 0, -3, -6, -8, -8, -8, -8, -7,
135 -6, -5, -4, -3, -2, -1, -1, 0,
136 127, 126, 124, 118, 111, 102, 92, 81,
137 70, 59, 48, 37, 27, 19, 11, 5,
140 static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
142 return readl(res->vp_regs + reg_id);
145 static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
148 writel(val, res->vp_regs + reg_id);
151 static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
154 u32 old = vp_reg_read(res, reg_id);
156 val = (val & mask) | (old & ~mask);
157 writel(val, res->vp_regs + reg_id);
160 static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
162 return readl(res->mixer_regs + reg_id);
165 static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
168 writel(val, res->mixer_regs + reg_id);
171 static inline void mixer_reg_writemask(struct mixer_resources *res,
172 u32 reg_id, u32 val, u32 mask)
174 u32 old = mixer_reg_read(res, reg_id);
176 val = (val & mask) | (old & ~mask);
177 writel(val, res->mixer_regs + reg_id);
180 static void mixer_regs_dump(struct mixer_context *ctx)
182 #define DUMPREG(reg_id) \
184 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
185 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
191 DUMPREG(MXR_INT_STATUS);
193 DUMPREG(MXR_LAYER_CFG);
194 DUMPREG(MXR_VIDEO_CFG);
196 DUMPREG(MXR_GRAPHIC0_CFG);
197 DUMPREG(MXR_GRAPHIC0_BASE);
198 DUMPREG(MXR_GRAPHIC0_SPAN);
199 DUMPREG(MXR_GRAPHIC0_WH);
200 DUMPREG(MXR_GRAPHIC0_SXY);
201 DUMPREG(MXR_GRAPHIC0_DXY);
203 DUMPREG(MXR_GRAPHIC1_CFG);
204 DUMPREG(MXR_GRAPHIC1_BASE);
205 DUMPREG(MXR_GRAPHIC1_SPAN);
206 DUMPREG(MXR_GRAPHIC1_WH);
207 DUMPREG(MXR_GRAPHIC1_SXY);
208 DUMPREG(MXR_GRAPHIC1_DXY);
212 static void vp_regs_dump(struct mixer_context *ctx)
214 #define DUMPREG(reg_id) \
216 DRM_DEBUG_KMS(#reg_id " = %08x\n", \
217 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
222 DUMPREG(VP_SHADOW_UPDATE);
223 DUMPREG(VP_FIELD_ID);
225 DUMPREG(VP_IMG_SIZE_Y);
226 DUMPREG(VP_IMG_SIZE_C);
227 DUMPREG(VP_PER_RATE_CTRL);
228 DUMPREG(VP_TOP_Y_PTR);
229 DUMPREG(VP_BOT_Y_PTR);
230 DUMPREG(VP_TOP_C_PTR);
231 DUMPREG(VP_BOT_C_PTR);
232 DUMPREG(VP_ENDIAN_MODE);
233 DUMPREG(VP_SRC_H_POSITION);
234 DUMPREG(VP_SRC_V_POSITION);
235 DUMPREG(VP_SRC_WIDTH);
236 DUMPREG(VP_SRC_HEIGHT);
237 DUMPREG(VP_DST_H_POSITION);
238 DUMPREG(VP_DST_V_POSITION);
239 DUMPREG(VP_DST_WIDTH);
240 DUMPREG(VP_DST_HEIGHT);
247 static inline void vp_filter_set(struct mixer_resources *res,
248 int reg_id, const u8 *data, unsigned int size)
250 /* assure 4-byte align */
252 for (; size; size -= 4, reg_id += 4, data += 4) {
253 u32 val = (data[0] << 24) | (data[1] << 16) |
254 (data[2] << 8) | data[3];
255 vp_reg_write(res, reg_id, val);
259 static void vp_default_filter(struct mixer_resources *res)
261 vp_filter_set(res, VP_POLY8_Y0_LL,
262 filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
263 vp_filter_set(res, VP_POLY4_Y0_LL,
264 filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
265 vp_filter_set(res, VP_POLY4_C0_LL,
266 filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
269 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
271 struct mixer_resources *res = &ctx->mixer_res;
273 /* block update on vsync */
274 mixer_reg_writemask(res, MXR_STATUS, enable ?
275 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
278 vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
279 VP_SHADOW_UPDATE_ENABLE : 0);
282 static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
284 struct mixer_resources *res = &ctx->mixer_res;
287 /* choosing between interlace and progressive mode */
288 val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
289 MXR_CFG_SCAN_PROGRASSIVE);
291 if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
292 /* choosing between proper HD and SD mode */
294 val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
295 else if (height <= 576)
296 val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
297 else if (height <= 720)
298 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
299 else if (height <= 1080)
300 val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
302 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
305 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
308 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
310 struct mixer_resources *res = &ctx->mixer_res;
314 val = MXR_CFG_RGB601_0_255;
315 } else if (height == 576) {
316 val = MXR_CFG_RGB601_0_255;
317 } else if (height == 720) {
318 val = MXR_CFG_RGB709_16_235;
319 mixer_reg_write(res, MXR_CM_COEFF_Y,
320 (1 << 30) | (94 << 20) | (314 << 10) |
322 mixer_reg_write(res, MXR_CM_COEFF_CB,
323 (972 << 20) | (851 << 10) | (225 << 0));
324 mixer_reg_write(res, MXR_CM_COEFF_CR,
325 (225 << 20) | (820 << 10) | (1004 << 0));
326 } else if (height == 1080) {
327 val = MXR_CFG_RGB709_16_235;
328 mixer_reg_write(res, MXR_CM_COEFF_Y,
329 (1 << 30) | (94 << 20) | (314 << 10) |
331 mixer_reg_write(res, MXR_CM_COEFF_CB,
332 (972 << 20) | (851 << 10) | (225 << 0));
333 mixer_reg_write(res, MXR_CM_COEFF_CR,
334 (225 << 20) | (820 << 10) | (1004 << 0));
336 val = MXR_CFG_RGB709_16_235;
337 mixer_reg_write(res, MXR_CM_COEFF_Y,
338 (1 << 30) | (94 << 20) | (314 << 10) |
340 mixer_reg_write(res, MXR_CM_COEFF_CB,
341 (972 << 20) | (851 << 10) | (225 << 0));
342 mixer_reg_write(res, MXR_CM_COEFF_CR,
343 (225 << 20) | (820 << 10) | (1004 << 0));
346 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
349 static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
351 struct mixer_resources *res = &ctx->mixer_res;
352 u32 val = enable ? ~0 : 0;
356 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
359 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
362 if (ctx->vp_enabled) {
363 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
364 mixer_reg_writemask(res, MXR_CFG, val,
371 static void mixer_run(struct mixer_context *ctx)
373 struct mixer_resources *res = &ctx->mixer_res;
375 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
377 mixer_regs_dump(ctx);
380 static void mixer_stop(struct mixer_context *ctx)
382 struct mixer_resources *res = &ctx->mixer_res;
385 mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
387 while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
389 usleep_range(10000, 12000);
391 mixer_regs_dump(ctx);
394 static void vp_video_buffer(struct mixer_context *ctx, int win)
396 struct mixer_resources *res = &ctx->mixer_res;
398 struct hdmi_win_data *win_data;
399 unsigned int x_ratio, y_ratio;
400 unsigned int buf_num = 1;
401 dma_addr_t luma_addr[2], chroma_addr[2];
402 bool tiled_mode = false;
403 bool crcb_mode = false;
406 win_data = &ctx->win_data[win];
408 switch (win_data->pixel_format) {
409 case DRM_FORMAT_NV12MT:
411 case DRM_FORMAT_NV12:
415 /* TODO: single buffer format NV12, NV21 */
417 /* ignore pixel format at disable time */
418 if (!win_data->dma_addr)
421 DRM_ERROR("pixel format for vp is wrong [%d].\n",
422 win_data->pixel_format);
426 /* scaling feature: (src << 16) / dst */
427 x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
428 y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
431 luma_addr[0] = win_data->dma_addr;
432 chroma_addr[0] = win_data->chroma_dma_addr;
434 luma_addr[0] = win_data->dma_addr;
435 chroma_addr[0] = win_data->dma_addr
436 + (win_data->fb_width * win_data->fb_height);
439 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
440 ctx->interlace = true;
442 luma_addr[1] = luma_addr[0] + 0x40;
443 chroma_addr[1] = chroma_addr[0] + 0x40;
445 luma_addr[1] = luma_addr[0] + win_data->fb_width;
446 chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
449 ctx->interlace = false;
454 spin_lock_irqsave(&res->reg_slock, flags);
455 mixer_vsync_set_update(ctx, false);
457 /* interlace or progressive scan mode */
458 val = (ctx->interlace ? ~0 : 0);
459 vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
462 val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
463 val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
464 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
466 /* setting size of input image */
467 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
468 VP_IMG_VSIZE(win_data->fb_height));
469 /* chroma height has to reduced by 2 to avoid chroma distorions */
470 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
471 VP_IMG_VSIZE(win_data->fb_height / 2));
473 vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
474 vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
475 vp_reg_write(res, VP_SRC_H_POSITION,
476 VP_SRC_H_POSITION_VAL(win_data->fb_x));
477 vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
479 vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
480 vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
481 if (ctx->interlace) {
482 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
483 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
485 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
486 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
489 vp_reg_write(res, VP_H_RATIO, x_ratio);
490 vp_reg_write(res, VP_V_RATIO, y_ratio);
492 vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
494 /* set buffer address to vp */
495 vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
496 vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
497 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
498 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
500 mixer_cfg_scan(ctx, win_data->mode_height);
501 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
502 mixer_cfg_layer(ctx, win, true);
505 mixer_vsync_set_update(ctx, true);
506 spin_unlock_irqrestore(&res->reg_slock, flags);
511 static void mixer_layer_update(struct mixer_context *ctx)
513 struct mixer_resources *res = &ctx->mixer_res;
516 val = mixer_reg_read(res, MXR_CFG);
518 /* allow one update per vsync only */
519 if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
520 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
523 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
525 struct mixer_resources *res = &ctx->mixer_res;
527 struct hdmi_win_data *win_data;
528 unsigned int x_ratio, y_ratio;
529 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
534 win_data = &ctx->win_data[win];
541 switch (win_data->bpp) {
552 /* 2x scaling feature */
556 dst_x_offset = win_data->crtc_x;
557 dst_y_offset = win_data->crtc_y;
559 /* converting dma address base and source offset */
560 dma_addr = win_data->dma_addr
561 + (win_data->fb_x * win_data->bpp >> 3)
562 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
566 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE)
567 ctx->interlace = true;
569 ctx->interlace = false;
571 spin_lock_irqsave(&res->reg_slock, flags);
572 mixer_vsync_set_update(ctx, false);
575 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
576 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
579 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
581 /* setup display size */
582 if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
583 win == MIXER_DEFAULT_WIN) {
584 val = MXR_MXR_RES_HEIGHT(win_data->fb_height);
585 val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
586 mixer_reg_write(res, MXR_RESOLUTION, val);
589 val = MXR_GRP_WH_WIDTH(win_data->crtc_width);
590 val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
591 val |= MXR_GRP_WH_H_SCALE(x_ratio);
592 val |= MXR_GRP_WH_V_SCALE(y_ratio);
593 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
595 /* setup offsets in source image */
596 val = MXR_GRP_SXY_SX(src_x_offset);
597 val |= MXR_GRP_SXY_SY(src_y_offset);
598 mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
600 /* setup offsets in display image */
601 val = MXR_GRP_DXY_DX(dst_x_offset);
602 val |= MXR_GRP_DXY_DY(dst_y_offset);
603 mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
605 /* set buffer address to mixer */
606 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
608 mixer_cfg_scan(ctx, win_data->mode_height);
609 mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
610 mixer_cfg_layer(ctx, win, true);
612 /* layer update mandatory for mixer 16.0.33.0 */
613 if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
614 ctx->mxr_ver == MXR_VER_128_0_0_184)
615 mixer_layer_update(ctx);
619 mixer_vsync_set_update(ctx, true);
620 spin_unlock_irqrestore(&res->reg_slock, flags);
623 static void vp_win_reset(struct mixer_context *ctx)
625 struct mixer_resources *res = &ctx->mixer_res;
628 vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
629 for (tries = 100; tries; --tries) {
630 /* waiting until VP_SRESET_PROCESSING is 0 */
631 if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
633 usleep_range(10000, 12000);
635 WARN(tries == 0, "failed to reset Video Processor\n");
638 static void mixer_win_reset(struct mixer_context *ctx)
640 struct mixer_resources *res = &ctx->mixer_res;
642 u32 val; /* value stored to register */
644 spin_lock_irqsave(&res->reg_slock, flags);
645 mixer_vsync_set_update(ctx, false);
647 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
649 /* set output in RGB888 mode */
650 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
652 /* 16 beat burst in DMA */
653 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
654 MXR_STATUS_BURST_MASK);
656 /* setting default layer priority: layer1 > layer0 > video
657 * because typical usage scenario would be
659 * layer0 - framebuffer
660 * video - video overlay
662 val = MXR_LAYER_CFG_GRP1_VAL(3);
663 val |= MXR_LAYER_CFG_GRP0_VAL(2);
665 val |= MXR_LAYER_CFG_VP_VAL(1);
666 mixer_reg_write(res, MXR_LAYER_CFG, val);
668 /* setting background color */
669 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
670 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
671 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
673 /* setting graphical layers */
674 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
675 val |= MXR_GRP_CFG_WIN_BLEND_EN;
676 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
678 /* Don't blend layer 0 onto the mixer background */
679 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
681 /* Blend layer 1 into layer 0 */
682 val |= MXR_GRP_CFG_BLEND_PRE_MUL;
683 val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
684 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
686 /* setting video layers */
687 val = MXR_GRP_CFG_ALPHA_VAL(0);
688 mixer_reg_write(res, MXR_VIDEO_CFG, val);
690 if (ctx->vp_enabled) {
691 /* configuration of Video Processor Registers */
693 vp_default_filter(res);
696 /* disable all layers */
697 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
698 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
700 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
702 mixer_vsync_set_update(ctx, true);
703 spin_unlock_irqrestore(&res->reg_slock, flags);
706 static irqreturn_t mixer_irq_handler(int irq, void *arg)
708 struct mixer_context *ctx = arg;
709 struct mixer_resources *res = &ctx->mixer_res;
710 u32 val, base, shadow;
712 spin_lock(&res->reg_slock);
714 /* read interrupt status for handling and clearing flags for VSYNC */
715 val = mixer_reg_read(res, MXR_INT_STATUS);
718 if (val & MXR_INT_STATUS_VSYNC) {
719 /* interlace scan need to check shadow register */
720 if (ctx->interlace) {
721 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
722 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
726 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
727 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
732 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
733 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
735 /* set wait vsync event to zero and wake up queue. */
736 if (atomic_read(&ctx->wait_vsync_event)) {
737 atomic_set(&ctx->wait_vsync_event, 0);
738 wake_up(&ctx->wait_vsync_queue);
743 /* clear interrupts */
744 if (~val & MXR_INT_EN_VSYNC) {
745 /* vsync interrupt use different bit for read and clear */
746 val &= ~MXR_INT_EN_VSYNC;
747 val |= MXR_INT_CLEAR_VSYNC;
749 mixer_reg_write(res, MXR_INT_STATUS, val);
751 spin_unlock(&res->reg_slock);
756 static int mixer_resources_init(struct mixer_context *mixer_ctx)
758 struct device *dev = &mixer_ctx->pdev->dev;
759 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
760 struct resource *res;
763 spin_lock_init(&mixer_res->reg_slock);
765 mixer_res->mixer = devm_clk_get(dev, "mixer");
766 if (IS_ERR(mixer_res->mixer)) {
767 dev_err(dev, "failed to get clock 'mixer'\n");
771 mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
772 if (IS_ERR(mixer_res->sclk_hdmi)) {
773 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
776 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
778 dev_err(dev, "get memory resource failed.\n");
782 mixer_res->mixer_regs = devm_ioremap(dev, res->start,
784 if (mixer_res->mixer_regs == NULL) {
785 dev_err(dev, "register mapping failed.\n");
789 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
791 dev_err(dev, "get interrupt resource failed.\n");
795 ret = devm_request_irq(dev, res->start, mixer_irq_handler,
796 0, "drm_mixer", mixer_ctx);
798 dev_err(dev, "request interrupt failed.\n");
801 mixer_res->irq = res->start;
806 static int vp_resources_init(struct mixer_context *mixer_ctx)
808 struct device *dev = &mixer_ctx->pdev->dev;
809 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
810 struct resource *res;
812 mixer_res->vp = devm_clk_get(dev, "vp");
813 if (IS_ERR(mixer_res->vp)) {
814 dev_err(dev, "failed to get clock 'vp'\n");
817 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
818 if (IS_ERR(mixer_res->sclk_mixer)) {
819 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
822 mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
823 if (IS_ERR(mixer_res->sclk_dac)) {
824 dev_err(dev, "failed to get clock 'sclk_dac'\n");
828 if (mixer_res->sclk_hdmi)
829 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
831 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
833 dev_err(dev, "get memory resource failed.\n");
837 mixer_res->vp_regs = devm_ioremap(dev, res->start,
839 if (mixer_res->vp_regs == NULL) {
840 dev_err(dev, "register mapping failed.\n");
847 static int mixer_initialize(struct exynos_drm_manager *mgr,
848 struct drm_device *drm_dev)
851 struct mixer_context *mixer_ctx = mgr->ctx;
852 struct exynos_drm_private *priv;
853 priv = drm_dev->dev_private;
855 mgr->drm_dev = mixer_ctx->drm_dev = drm_dev;
856 mgr->pipe = mixer_ctx->pipe = priv->pipe++;
858 /* acquire resources: regs, irqs, clocks */
859 ret = mixer_resources_init(mixer_ctx);
861 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
865 if (mixer_ctx->vp_enabled) {
866 /* acquire vp resources: regs, irqs, clocks */
867 ret = vp_resources_init(mixer_ctx);
869 DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
874 if (!is_drm_iommu_supported(mixer_ctx->drm_dev))
877 return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
880 static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
882 struct mixer_context *mixer_ctx = mgr->ctx;
884 if (is_drm_iommu_supported(mixer_ctx->drm_dev))
885 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
888 static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
890 struct mixer_context *mixer_ctx = mgr->ctx;
891 struct mixer_resources *res = &mixer_ctx->mixer_res;
893 if (!mixer_ctx->powered) {
894 mixer_ctx->int_en |= MXR_INT_EN_VSYNC;
898 /* enable vsync interrupt */
899 mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
905 static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
907 struct mixer_context *mixer_ctx = mgr->ctx;
908 struct mixer_resources *res = &mixer_ctx->mixer_res;
910 /* disable vsync interrupt */
911 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
914 static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
915 struct exynos_drm_overlay *overlay)
917 struct mixer_context *mixer_ctx = mgr->ctx;
918 struct hdmi_win_data *win_data;
922 DRM_ERROR("overlay is NULL\n");
926 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
927 overlay->fb_width, overlay->fb_height,
928 overlay->fb_x, overlay->fb_y,
929 overlay->crtc_width, overlay->crtc_height,
930 overlay->crtc_x, overlay->crtc_y);
933 if (win == DEFAULT_ZPOS)
934 win = MIXER_DEFAULT_WIN;
936 if (win < 0 || win >= MIXER_WIN_NR) {
937 DRM_ERROR("mixer window[%d] is wrong\n", win);
941 win_data = &mixer_ctx->win_data[win];
943 win_data->dma_addr = overlay->dma_addr[0];
944 win_data->chroma_dma_addr = overlay->dma_addr[1];
945 win_data->pixel_format = overlay->pixel_format;
946 win_data->bpp = overlay->bpp;
948 win_data->crtc_x = overlay->crtc_x;
949 win_data->crtc_y = overlay->crtc_y;
950 win_data->crtc_width = overlay->crtc_width;
951 win_data->crtc_height = overlay->crtc_height;
953 win_data->fb_x = overlay->fb_x;
954 win_data->fb_y = overlay->fb_y;
955 win_data->fb_width = overlay->fb_width;
956 win_data->fb_height = overlay->fb_height;
957 win_data->src_width = overlay->src_width;
958 win_data->src_height = overlay->src_height;
960 win_data->mode_width = overlay->mode_width;
961 win_data->mode_height = overlay->mode_height;
963 win_data->scan_flags = overlay->scan_flag;
966 static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
968 struct mixer_context *mixer_ctx = mgr->ctx;
969 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
971 DRM_DEBUG_KMS("win: %d\n", win);
973 mutex_lock(&mixer_ctx->mixer_mutex);
974 if (!mixer_ctx->powered) {
975 mutex_unlock(&mixer_ctx->mixer_mutex);
978 mutex_unlock(&mixer_ctx->mixer_mutex);
980 if (win > 1 && mixer_ctx->vp_enabled)
981 vp_video_buffer(mixer_ctx, win);
983 mixer_graph_buffer(mixer_ctx, win);
985 mixer_ctx->win_data[win].enabled = true;
988 static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
990 struct mixer_context *mixer_ctx = mgr->ctx;
991 struct mixer_resources *res = &mixer_ctx->mixer_res;
992 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
995 DRM_DEBUG_KMS("win: %d\n", win);
997 mutex_lock(&mixer_ctx->mixer_mutex);
998 if (!mixer_ctx->powered) {
999 mutex_unlock(&mixer_ctx->mixer_mutex);
1000 mixer_ctx->win_data[win].resume = false;
1003 mutex_unlock(&mixer_ctx->mixer_mutex);
1005 spin_lock_irqsave(&res->reg_slock, flags);
1006 mixer_vsync_set_update(mixer_ctx, false);
1008 mixer_cfg_layer(mixer_ctx, win, false);
1010 mixer_vsync_set_update(mixer_ctx, true);
1011 spin_unlock_irqrestore(&res->reg_slock, flags);
1013 mixer_ctx->win_data[win].enabled = false;
1016 static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1018 struct mixer_context *mixer_ctx = mgr->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 exynos_drm_manager *mgr)
1041 struct mixer_context *ctx = mgr->ctx;
1042 struct hdmi_win_data *win_data;
1045 for (i = 0; i < MIXER_WIN_NR; i++) {
1046 win_data = &ctx->win_data[i];
1047 win_data->resume = win_data->enabled;
1048 mixer_win_disable(mgr, i);
1050 mixer_wait_for_vblank(mgr);
1053 static void mixer_window_resume(struct exynos_drm_manager *mgr)
1055 struct mixer_context *ctx = mgr->ctx;
1056 struct hdmi_win_data *win_data;
1059 for (i = 0; i < MIXER_WIN_NR; i++) {
1060 win_data = &ctx->win_data[i];
1061 win_data->enabled = win_data->resume;
1062 win_data->resume = false;
1063 if (win_data->enabled)
1064 mixer_win_commit(mgr, i);
1068 static void mixer_poweron(struct exynos_drm_manager *mgr)
1070 struct mixer_context *ctx = mgr->ctx;
1071 struct mixer_resources *res = &ctx->mixer_res;
1073 mutex_lock(&ctx->mixer_mutex);
1075 mutex_unlock(&ctx->mixer_mutex);
1079 mutex_unlock(&ctx->mixer_mutex);
1081 pm_runtime_get_sync(ctx->dev);
1083 clk_prepare_enable(res->mixer);
1084 if (ctx->vp_enabled) {
1085 clk_prepare_enable(res->vp);
1086 clk_prepare_enable(res->sclk_mixer);
1089 mutex_lock(&ctx->mixer_mutex);
1090 ctx->powered = true;
1091 mutex_unlock(&ctx->mixer_mutex);
1093 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1094 mixer_win_reset(ctx);
1096 mixer_window_resume(mgr);
1099 static void mixer_poweroff(struct exynos_drm_manager *mgr)
1101 struct mixer_context *ctx = mgr->ctx;
1102 struct mixer_resources *res = &ctx->mixer_res;
1104 mutex_lock(&ctx->mixer_mutex);
1105 if (!ctx->powered) {
1106 mutex_unlock(&ctx->mixer_mutex);
1109 mutex_unlock(&ctx->mixer_mutex);
1112 mixer_window_suspend(mgr);
1114 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1116 mutex_lock(&ctx->mixer_mutex);
1117 ctx->powered = false;
1118 mutex_unlock(&ctx->mixer_mutex);
1120 clk_disable_unprepare(res->mixer);
1121 if (ctx->vp_enabled) {
1122 clk_disable_unprepare(res->vp);
1123 clk_disable_unprepare(res->sclk_mixer);
1126 pm_runtime_put_sync(ctx->dev);
1129 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
1132 case DRM_MODE_DPMS_ON:
1135 case DRM_MODE_DPMS_STANDBY:
1136 case DRM_MODE_DPMS_SUSPEND:
1137 case DRM_MODE_DPMS_OFF:
1138 mixer_poweroff(mgr);
1141 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
1146 /* Only valid for Mixer version 16.0.33.0 */
1147 int mixer_check_mode(struct drm_display_mode *mode)
1154 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1155 mode->hdisplay, mode->vdisplay, mode->vrefresh,
1156 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1158 if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
1159 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
1160 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
1166 static struct exynos_drm_manager_ops mixer_manager_ops = {
1168 .enable_vblank = mixer_enable_vblank,
1169 .disable_vblank = mixer_disable_vblank,
1170 .wait_for_vblank = mixer_wait_for_vblank,
1171 .win_mode_set = mixer_win_mode_set,
1172 .win_commit = mixer_win_commit,
1173 .win_disable = mixer_win_disable,
1176 static struct exynos_drm_manager mixer_manager = {
1177 .type = EXYNOS_DISPLAY_TYPE_HDMI,
1178 .ops = &mixer_manager_ops,
1181 static struct mixer_drv_data exynos5420_mxr_drv_data = {
1182 .version = MXR_VER_128_0_0_184,
1186 static struct mixer_drv_data exynos5250_mxr_drv_data = {
1187 .version = MXR_VER_16_0_33_0,
1191 static struct mixer_drv_data exynos4210_mxr_drv_data = {
1192 .version = MXR_VER_0_0_0_16,
1196 static struct platform_device_id mixer_driver_types[] = {
1198 .name = "s5p-mixer",
1199 .driver_data = (unsigned long)&exynos4210_mxr_drv_data,
1201 .name = "exynos5-mixer",
1202 .driver_data = (unsigned long)&exynos5250_mxr_drv_data,
1208 static struct of_device_id mixer_match_types[] = {
1210 .compatible = "samsung,exynos5-mixer",
1211 .data = &exynos5250_mxr_drv_data,
1213 .compatible = "samsung,exynos5250-mixer",
1214 .data = &exynos5250_mxr_drv_data,
1216 .compatible = "samsung,exynos5420-mixer",
1217 .data = &exynos5420_mxr_drv_data,
1223 static int mixer_bind(struct device *dev, struct device *manager, void *data)
1225 struct platform_device *pdev = to_platform_device(dev);
1226 struct drm_device *drm_dev = data;
1227 struct mixer_context *ctx;
1228 struct mixer_drv_data *drv;
1231 dev_info(dev, "probe start\n");
1233 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1235 DRM_ERROR("failed to alloc mixer context.\n");
1239 mutex_init(&ctx->mixer_mutex);
1242 const struct of_device_id *match;
1243 match = of_match_node(mixer_match_types, dev->of_node);
1244 drv = (struct mixer_drv_data *)match->data;
1246 drv = (struct mixer_drv_data *)
1247 platform_get_device_id(pdev)->driver_data;
1252 ctx->vp_enabled = drv->is_vp_enabled;
1253 ctx->mxr_ver = drv->version;
1254 init_waitqueue_head(&ctx->wait_vsync_queue);
1255 atomic_set(&ctx->wait_vsync_event, 0);
1257 mixer_manager.ctx = ctx;
1258 ret = mixer_initialize(&mixer_manager, drm_dev);
1262 platform_set_drvdata(pdev, &mixer_manager);
1263 ret = exynos_drm_crtc_create(&mixer_manager);
1265 mixer_mgr_remove(&mixer_manager);
1269 pm_runtime_enable(dev);
1274 static void mixer_unbind(struct device *dev, struct device *master, void *data)
1276 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1277 struct drm_crtc *crtc = mgr->crtc;
1279 dev_info(dev, "remove successful\n");
1281 mixer_mgr_remove(mgr);
1283 pm_runtime_disable(dev);
1285 crtc->funcs->destroy(crtc);
1288 static const struct component_ops mixer_component_ops = {
1290 .unbind = mixer_unbind,
1293 static int mixer_probe(struct platform_device *pdev)
1297 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1298 mixer_manager.type);
1302 ret = component_add(&pdev->dev, &mixer_component_ops);
1304 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1309 static int mixer_remove(struct platform_device *pdev)
1311 component_del(&pdev->dev, &mixer_component_ops);
1312 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1317 struct platform_driver mixer_driver = {
1319 .name = "exynos-mixer",
1320 .owner = THIS_MODULE,
1321 .of_match_table = mixer_match_types,
1323 .probe = mixer_probe,
1324 .remove = mixer_remove,
1325 .id_table = mixer_driver_types,