1 /* 2 * Copyright (C) 2011 Samsung Electronics Co.Ltd 3 * Authors: 4 * Seung-Woo Kim <sw0312.kim@samsung.com> 5 * Inki Dae <inki.dae@samsung.com> 6 * Joonyoung Shim <jy0922.shim@samsung.com> 7 * 8 * Based on drivers/media/video/s5p-tv/mixer_reg.c 9 * 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. 14 * 15 */ 16 17 #include <drm/drmP.h> 18 19 #include "regs-mixer.h" 20 #include "regs-vp.h" 21 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> 33 #include <linux/of.h> 34 #include <linux/component.h> 35 36 #include <drm/exynos_drm.h> 37 38 #include "exynos_drm_drv.h" 39 #include "exynos_drm_crtc.h" 40 #include "exynos_drm_iommu.h" 41 #include "exynos_mixer.h" 42 43 #define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev)) 44 45 #define MIXER_WIN_NR 3 46 #define MIXER_DEFAULT_WIN 0 47 48 struct hdmi_win_data { 49 dma_addr_t dma_addr; 50 dma_addr_t chroma_dma_addr; 51 uint32_t pixel_format; 52 unsigned int bpp; 53 unsigned int crtc_x; 54 unsigned int crtc_y; 55 unsigned int crtc_width; 56 unsigned int crtc_height; 57 unsigned int fb_x; 58 unsigned int fb_y; 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; 66 bool enabled; 67 bool resume; 68 }; 69 70 struct mixer_resources { 71 int irq; 72 void __iomem *mixer_regs; 73 void __iomem *vp_regs; 74 spinlock_t reg_slock; 75 struct clk *mixer; 76 struct clk *vp; 77 struct clk *sclk_mixer; 78 struct clk *sclk_hdmi; 79 struct clk *mout_mixer; 80 }; 81 82 enum mixer_version_id { 83 MXR_VER_0_0_0_16, 84 MXR_VER_16_0_33_0, 85 MXR_VER_128_0_0_184, 86 }; 87 88 struct mixer_context { 89 struct platform_device *pdev; 90 struct device *dev; 91 struct drm_device *drm_dev; 92 int pipe; 93 bool interlace; 94 bool powered; 95 bool vp_enabled; 96 bool has_sclk; 97 u32 int_en; 98 99 struct mutex mixer_mutex; 100 struct mixer_resources mixer_res; 101 struct hdmi_win_data win_data[MIXER_WIN_NR]; 102 enum mixer_version_id mxr_ver; 103 wait_queue_head_t wait_vsync_queue; 104 atomic_t wait_vsync_event; 105 }; 106 107 struct mixer_drv_data { 108 enum mixer_version_id version; 109 bool is_vp_enabled; 110 bool has_sclk; 111 }; 112 113 static const u8 filter_y_horiz_tap8[] = { 114 0, -1, -1, -1, -1, -1, -1, -1, 115 -1, -1, -1, -1, -1, 0, 0, 0, 116 0, 2, 4, 5, 6, 6, 6, 6, 117 6, 5, 5, 4, 3, 2, 1, 1, 118 0, -6, -12, -16, -18, -20, -21, -20, 119 -20, -18, -16, -13, -10, -8, -5, -2, 120 127, 126, 125, 121, 114, 107, 99, 89, 121 79, 68, 57, 46, 35, 25, 16, 8, 122 }; 123 124 static const u8 filter_y_vert_tap4[] = { 125 0, -3, -6, -8, -8, -8, -8, -7, 126 -6, -5, -4, -3, -2, -1, -1, 0, 127 127, 126, 124, 118, 111, 102, 92, 81, 128 70, 59, 48, 37, 27, 19, 11, 5, 129 0, 5, 11, 19, 27, 37, 48, 59, 130 70, 81, 92, 102, 111, 118, 124, 126, 131 0, 0, -1, -1, -2, -3, -4, -5, 132 -6, -7, -8, -8, -8, -8, -6, -3, 133 }; 134 135 static const u8 filter_cr_horiz_tap4[] = { 136 0, -3, -6, -8, -8, -8, -8, -7, 137 -6, -5, -4, -3, -2, -1, -1, 0, 138 127, 126, 124, 118, 111, 102, 92, 81, 139 70, 59, 48, 37, 27, 19, 11, 5, 140 }; 141 142 static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) 143 { 144 return readl(res->vp_regs + reg_id); 145 } 146 147 static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id, 148 u32 val) 149 { 150 writel(val, res->vp_regs + reg_id); 151 } 152 153 static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id, 154 u32 val, u32 mask) 155 { 156 u32 old = vp_reg_read(res, reg_id); 157 158 val = (val & mask) | (old & ~mask); 159 writel(val, res->vp_regs + reg_id); 160 } 161 162 static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id) 163 { 164 return readl(res->mixer_regs + reg_id); 165 } 166 167 static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id, 168 u32 val) 169 { 170 writel(val, res->mixer_regs + reg_id); 171 } 172 173 static inline void mixer_reg_writemask(struct mixer_resources *res, 174 u32 reg_id, u32 val, u32 mask) 175 { 176 u32 old = mixer_reg_read(res, reg_id); 177 178 val = (val & mask) | (old & ~mask); 179 writel(val, res->mixer_regs + reg_id); 180 } 181 182 static void mixer_regs_dump(struct mixer_context *ctx) 183 { 184 #define DUMPREG(reg_id) \ 185 do { \ 186 DRM_DEBUG_KMS(#reg_id " = %08x\n", \ 187 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \ 188 } while (0) 189 190 DUMPREG(MXR_STATUS); 191 DUMPREG(MXR_CFG); 192 DUMPREG(MXR_INT_EN); 193 DUMPREG(MXR_INT_STATUS); 194 195 DUMPREG(MXR_LAYER_CFG); 196 DUMPREG(MXR_VIDEO_CFG); 197 198 DUMPREG(MXR_GRAPHIC0_CFG); 199 DUMPREG(MXR_GRAPHIC0_BASE); 200 DUMPREG(MXR_GRAPHIC0_SPAN); 201 DUMPREG(MXR_GRAPHIC0_WH); 202 DUMPREG(MXR_GRAPHIC0_SXY); 203 DUMPREG(MXR_GRAPHIC0_DXY); 204 205 DUMPREG(MXR_GRAPHIC1_CFG); 206 DUMPREG(MXR_GRAPHIC1_BASE); 207 DUMPREG(MXR_GRAPHIC1_SPAN); 208 DUMPREG(MXR_GRAPHIC1_WH); 209 DUMPREG(MXR_GRAPHIC1_SXY); 210 DUMPREG(MXR_GRAPHIC1_DXY); 211 #undef DUMPREG 212 } 213 214 static void vp_regs_dump(struct mixer_context *ctx) 215 { 216 #define DUMPREG(reg_id) \ 217 do { \ 218 DRM_DEBUG_KMS(#reg_id " = %08x\n", \ 219 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \ 220 } while (0) 221 222 DUMPREG(VP_ENABLE); 223 DUMPREG(VP_SRESET); 224 DUMPREG(VP_SHADOW_UPDATE); 225 DUMPREG(VP_FIELD_ID); 226 DUMPREG(VP_MODE); 227 DUMPREG(VP_IMG_SIZE_Y); 228 DUMPREG(VP_IMG_SIZE_C); 229 DUMPREG(VP_PER_RATE_CTRL); 230 DUMPREG(VP_TOP_Y_PTR); 231 DUMPREG(VP_BOT_Y_PTR); 232 DUMPREG(VP_TOP_C_PTR); 233 DUMPREG(VP_BOT_C_PTR); 234 DUMPREG(VP_ENDIAN_MODE); 235 DUMPREG(VP_SRC_H_POSITION); 236 DUMPREG(VP_SRC_V_POSITION); 237 DUMPREG(VP_SRC_WIDTH); 238 DUMPREG(VP_SRC_HEIGHT); 239 DUMPREG(VP_DST_H_POSITION); 240 DUMPREG(VP_DST_V_POSITION); 241 DUMPREG(VP_DST_WIDTH); 242 DUMPREG(VP_DST_HEIGHT); 243 DUMPREG(VP_H_RATIO); 244 DUMPREG(VP_V_RATIO); 245 246 #undef DUMPREG 247 } 248 249 static inline void vp_filter_set(struct mixer_resources *res, 250 int reg_id, const u8 *data, unsigned int size) 251 { 252 /* assure 4-byte align */ 253 BUG_ON(size & 3); 254 for (; size; size -= 4, reg_id += 4, data += 4) { 255 u32 val = (data[0] << 24) | (data[1] << 16) | 256 (data[2] << 8) | data[3]; 257 vp_reg_write(res, reg_id, val); 258 } 259 } 260 261 static void vp_default_filter(struct mixer_resources *res) 262 { 263 vp_filter_set(res, VP_POLY8_Y0_LL, 264 filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8)); 265 vp_filter_set(res, VP_POLY4_Y0_LL, 266 filter_y_vert_tap4, sizeof(filter_y_vert_tap4)); 267 vp_filter_set(res, VP_POLY4_C0_LL, 268 filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); 269 } 270 271 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) 272 { 273 struct mixer_resources *res = &ctx->mixer_res; 274 275 /* block update on vsync */ 276 mixer_reg_writemask(res, MXR_STATUS, enable ? 277 MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE); 278 279 if (ctx->vp_enabled) 280 vp_reg_write(res, VP_SHADOW_UPDATE, enable ? 281 VP_SHADOW_UPDATE_ENABLE : 0); 282 } 283 284 static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height) 285 { 286 struct mixer_resources *res = &ctx->mixer_res; 287 u32 val; 288 289 /* choosing between interlace and progressive mode */ 290 val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE : 291 MXR_CFG_SCAN_PROGRASSIVE); 292 293 if (ctx->mxr_ver != MXR_VER_128_0_0_184) { 294 /* choosing between proper HD and SD mode */ 295 if (height <= 480) 296 val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD; 297 else if (height <= 576) 298 val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD; 299 else if (height <= 720) 300 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; 301 else if (height <= 1080) 302 val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD; 303 else 304 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD; 305 } 306 307 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK); 308 } 309 310 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) 311 { 312 struct mixer_resources *res = &ctx->mixer_res; 313 u32 val; 314 315 if (height == 480) { 316 val = MXR_CFG_RGB601_0_255; 317 } else if (height == 576) { 318 val = MXR_CFG_RGB601_0_255; 319 } else if (height == 720) { 320 val = MXR_CFG_RGB709_16_235; 321 mixer_reg_write(res, MXR_CM_COEFF_Y, 322 (1 << 30) | (94 << 20) | (314 << 10) | 323 (32 << 0)); 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)); 328 } else if (height == 1080) { 329 val = MXR_CFG_RGB709_16_235; 330 mixer_reg_write(res, MXR_CM_COEFF_Y, 331 (1 << 30) | (94 << 20) | (314 << 10) | 332 (32 << 0)); 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)); 337 } else { 338 val = MXR_CFG_RGB709_16_235; 339 mixer_reg_write(res, MXR_CM_COEFF_Y, 340 (1 << 30) | (94 << 20) | (314 << 10) | 341 (32 << 0)); 342 mixer_reg_write(res, MXR_CM_COEFF_CB, 343 (972 << 20) | (851 << 10) | (225 << 0)); 344 mixer_reg_write(res, MXR_CM_COEFF_CR, 345 (225 << 20) | (820 << 10) | (1004 << 0)); 346 } 347 348 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK); 349 } 350 351 static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable) 352 { 353 struct mixer_resources *res = &ctx->mixer_res; 354 u32 val = enable ? ~0 : 0; 355 356 switch (win) { 357 case 0: 358 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); 359 break; 360 case 1: 361 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); 362 break; 363 case 2: 364 if (ctx->vp_enabled) { 365 vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); 366 mixer_reg_writemask(res, MXR_CFG, val, 367 MXR_CFG_VP_ENABLE); 368 369 /* control blending of graphic layer 0 */ 370 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val, 371 MXR_GRP_CFG_BLEND_PRE_MUL | 372 MXR_GRP_CFG_PIXEL_BLEND_EN); 373 } 374 break; 375 } 376 } 377 378 static void mixer_run(struct mixer_context *ctx) 379 { 380 struct mixer_resources *res = &ctx->mixer_res; 381 382 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN); 383 384 mixer_regs_dump(ctx); 385 } 386 387 static void mixer_stop(struct mixer_context *ctx) 388 { 389 struct mixer_resources *res = &ctx->mixer_res; 390 int timeout = 20; 391 392 mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN); 393 394 while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) && 395 --timeout) 396 usleep_range(10000, 12000); 397 398 mixer_regs_dump(ctx); 399 } 400 401 static void vp_video_buffer(struct mixer_context *ctx, int win) 402 { 403 struct mixer_resources *res = &ctx->mixer_res; 404 unsigned long flags; 405 struct hdmi_win_data *win_data; 406 unsigned int x_ratio, y_ratio; 407 unsigned int buf_num = 1; 408 dma_addr_t luma_addr[2], chroma_addr[2]; 409 bool tiled_mode = false; 410 bool crcb_mode = false; 411 u32 val; 412 413 win_data = &ctx->win_data[win]; 414 415 switch (win_data->pixel_format) { 416 case DRM_FORMAT_NV12MT: 417 tiled_mode = true; 418 case DRM_FORMAT_NV12: 419 crcb_mode = false; 420 buf_num = 2; 421 break; 422 /* TODO: single buffer format NV12, NV21 */ 423 default: 424 /* ignore pixel format at disable time */ 425 if (!win_data->dma_addr) 426 break; 427 428 DRM_ERROR("pixel format for vp is wrong [%d].\n", 429 win_data->pixel_format); 430 return; 431 } 432 433 /* scaling feature: (src << 16) / dst */ 434 x_ratio = (win_data->src_width << 16) / win_data->crtc_width; 435 y_ratio = (win_data->src_height << 16) / win_data->crtc_height; 436 437 if (buf_num == 2) { 438 luma_addr[0] = win_data->dma_addr; 439 chroma_addr[0] = win_data->chroma_dma_addr; 440 } else { 441 luma_addr[0] = win_data->dma_addr; 442 chroma_addr[0] = win_data->dma_addr 443 + (win_data->fb_width * win_data->fb_height); 444 } 445 446 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { 447 ctx->interlace = true; 448 if (tiled_mode) { 449 luma_addr[1] = luma_addr[0] + 0x40; 450 chroma_addr[1] = chroma_addr[0] + 0x40; 451 } else { 452 luma_addr[1] = luma_addr[0] + win_data->fb_width; 453 chroma_addr[1] = chroma_addr[0] + win_data->fb_width; 454 } 455 } else { 456 ctx->interlace = false; 457 luma_addr[1] = 0; 458 chroma_addr[1] = 0; 459 } 460 461 spin_lock_irqsave(&res->reg_slock, flags); 462 mixer_vsync_set_update(ctx, false); 463 464 /* interlace or progressive scan mode */ 465 val = (ctx->interlace ? ~0 : 0); 466 vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP); 467 468 /* setup format */ 469 val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12); 470 val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR); 471 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); 472 473 /* setting size of input image */ 474 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) | 475 VP_IMG_VSIZE(win_data->fb_height)); 476 /* chroma height has to reduced by 2 to avoid chroma distorions */ 477 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) | 478 VP_IMG_VSIZE(win_data->fb_height / 2)); 479 480 vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width); 481 vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height); 482 vp_reg_write(res, VP_SRC_H_POSITION, 483 VP_SRC_H_POSITION_VAL(win_data->fb_x)); 484 vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y); 485 486 vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width); 487 vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x); 488 if (ctx->interlace) { 489 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2); 490 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2); 491 } else { 492 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height); 493 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y); 494 } 495 496 vp_reg_write(res, VP_H_RATIO, x_ratio); 497 vp_reg_write(res, VP_V_RATIO, y_ratio); 498 499 vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); 500 501 /* set buffer address to vp */ 502 vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]); 503 vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]); 504 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); 505 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); 506 507 mixer_cfg_scan(ctx, win_data->mode_height); 508 mixer_cfg_rgb_fmt(ctx, win_data->mode_height); 509 mixer_cfg_layer(ctx, win, true); 510 mixer_run(ctx); 511 512 mixer_vsync_set_update(ctx, true); 513 spin_unlock_irqrestore(&res->reg_slock, flags); 514 515 vp_regs_dump(ctx); 516 } 517 518 static void mixer_layer_update(struct mixer_context *ctx) 519 { 520 struct mixer_resources *res = &ctx->mixer_res; 521 522 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); 523 } 524 525 static void mixer_graph_buffer(struct mixer_context *ctx, int win) 526 { 527 struct mixer_resources *res = &ctx->mixer_res; 528 unsigned long flags; 529 struct hdmi_win_data *win_data; 530 unsigned int x_ratio, y_ratio; 531 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; 532 dma_addr_t dma_addr; 533 unsigned int fmt; 534 u32 val; 535 536 win_data = &ctx->win_data[win]; 537 538 #define RGB565 4 539 #define ARGB1555 5 540 #define ARGB4444 6 541 #define ARGB8888 7 542 543 switch (win_data->bpp) { 544 case 16: 545 fmt = ARGB4444; 546 break; 547 case 32: 548 fmt = ARGB8888; 549 break; 550 default: 551 fmt = ARGB8888; 552 } 553 554 /* 2x scaling feature */ 555 x_ratio = 0; 556 y_ratio = 0; 557 558 dst_x_offset = win_data->crtc_x; 559 dst_y_offset = win_data->crtc_y; 560 561 /* converting dma address base and source offset */ 562 dma_addr = win_data->dma_addr 563 + (win_data->fb_x * win_data->bpp >> 3) 564 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3); 565 src_x_offset = 0; 566 src_y_offset = 0; 567 568 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) 569 ctx->interlace = true; 570 else 571 ctx->interlace = false; 572 573 spin_lock_irqsave(&res->reg_slock, flags); 574 mixer_vsync_set_update(ctx, false); 575 576 /* setup format */ 577 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), 578 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); 579 580 /* setup geometry */ 581 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width); 582 583 /* setup display size */ 584 if (ctx->mxr_ver == MXR_VER_128_0_0_184 && 585 win == MIXER_DEFAULT_WIN) { 586 val = MXR_MXR_RES_HEIGHT(win_data->fb_height); 587 val |= MXR_MXR_RES_WIDTH(win_data->fb_width); 588 mixer_reg_write(res, MXR_RESOLUTION, val); 589 } 590 591 val = MXR_GRP_WH_WIDTH(win_data->crtc_width); 592 val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height); 593 val |= MXR_GRP_WH_H_SCALE(x_ratio); 594 val |= MXR_GRP_WH_V_SCALE(y_ratio); 595 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); 596 597 /* setup offsets in source image */ 598 val = MXR_GRP_SXY_SX(src_x_offset); 599 val |= MXR_GRP_SXY_SY(src_y_offset); 600 mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val); 601 602 /* setup offsets in display image */ 603 val = MXR_GRP_DXY_DX(dst_x_offset); 604 val |= MXR_GRP_DXY_DY(dst_y_offset); 605 mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val); 606 607 /* set buffer address to mixer */ 608 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); 609 610 mixer_cfg_scan(ctx, win_data->mode_height); 611 mixer_cfg_rgb_fmt(ctx, win_data->mode_height); 612 mixer_cfg_layer(ctx, win, true); 613 614 /* layer update mandatory for mixer 16.0.33.0 */ 615 if (ctx->mxr_ver == MXR_VER_16_0_33_0 || 616 ctx->mxr_ver == MXR_VER_128_0_0_184) 617 mixer_layer_update(ctx); 618 619 mixer_run(ctx); 620 621 mixer_vsync_set_update(ctx, true); 622 spin_unlock_irqrestore(&res->reg_slock, flags); 623 } 624 625 static void vp_win_reset(struct mixer_context *ctx) 626 { 627 struct mixer_resources *res = &ctx->mixer_res; 628 int tries = 100; 629 630 vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING); 631 for (tries = 100; tries; --tries) { 632 /* waiting until VP_SRESET_PROCESSING is 0 */ 633 if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) 634 break; 635 usleep_range(10000, 12000); 636 } 637 WARN(tries == 0, "failed to reset Video Processor\n"); 638 } 639 640 static void mixer_win_reset(struct mixer_context *ctx) 641 { 642 struct mixer_resources *res = &ctx->mixer_res; 643 unsigned long flags; 644 u32 val; /* value stored to register */ 645 646 spin_lock_irqsave(&res->reg_slock, flags); 647 mixer_vsync_set_update(ctx, false); 648 649 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); 650 651 /* set output in RGB888 mode */ 652 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); 653 654 /* 16 beat burst in DMA */ 655 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, 656 MXR_STATUS_BURST_MASK); 657 658 /* setting default layer priority: layer1 > layer0 > video 659 * because typical usage scenario would be 660 * layer1 - OSD 661 * layer0 - framebuffer 662 * video - video overlay 663 */ 664 val = MXR_LAYER_CFG_GRP1_VAL(3); 665 val |= MXR_LAYER_CFG_GRP0_VAL(2); 666 if (ctx->vp_enabled) 667 val |= MXR_LAYER_CFG_VP_VAL(1); 668 mixer_reg_write(res, MXR_LAYER_CFG, val); 669 670 /* setting background color */ 671 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); 672 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); 673 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); 674 675 /* setting graphical layers */ 676 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ 677 val |= MXR_GRP_CFG_WIN_BLEND_EN; 678 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ 679 680 /* Don't blend layer 0 onto the mixer background */ 681 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); 682 683 /* Blend layer 1 into layer 0 */ 684 val |= MXR_GRP_CFG_BLEND_PRE_MUL; 685 val |= MXR_GRP_CFG_PIXEL_BLEND_EN; 686 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); 687 688 /* setting video layers */ 689 val = MXR_GRP_CFG_ALPHA_VAL(0); 690 mixer_reg_write(res, MXR_VIDEO_CFG, val); 691 692 if (ctx->vp_enabled) { 693 /* configuration of Video Processor Registers */ 694 vp_win_reset(ctx); 695 vp_default_filter(res); 696 } 697 698 /* disable all layers */ 699 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); 700 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); 701 if (ctx->vp_enabled) 702 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); 703 704 mixer_vsync_set_update(ctx, true); 705 spin_unlock_irqrestore(&res->reg_slock, flags); 706 } 707 708 static irqreturn_t mixer_irq_handler(int irq, void *arg) 709 { 710 struct mixer_context *ctx = arg; 711 struct mixer_resources *res = &ctx->mixer_res; 712 u32 val, base, shadow; 713 714 spin_lock(&res->reg_slock); 715 716 /* read interrupt status for handling and clearing flags for VSYNC */ 717 val = mixer_reg_read(res, MXR_INT_STATUS); 718 719 /* handling VSYNC */ 720 if (val & MXR_INT_STATUS_VSYNC) { 721 /* interlace scan need to check shadow register */ 722 if (ctx->interlace) { 723 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); 724 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0)); 725 if (base != shadow) 726 goto out; 727 728 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1)); 729 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1)); 730 if (base != shadow) 731 goto out; 732 } 733 734 drm_handle_vblank(ctx->drm_dev, ctx->pipe); 735 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); 736 737 /* set wait vsync event to zero and wake up queue. */ 738 if (atomic_read(&ctx->wait_vsync_event)) { 739 atomic_set(&ctx->wait_vsync_event, 0); 740 wake_up(&ctx->wait_vsync_queue); 741 } 742 } 743 744 out: 745 /* clear interrupts */ 746 if (~val & MXR_INT_EN_VSYNC) { 747 /* vsync interrupt use different bit for read and clear */ 748 val &= ~MXR_INT_EN_VSYNC; 749 val |= MXR_INT_CLEAR_VSYNC; 750 } 751 mixer_reg_write(res, MXR_INT_STATUS, val); 752 753 spin_unlock(&res->reg_slock); 754 755 return IRQ_HANDLED; 756 } 757 758 static int mixer_resources_init(struct mixer_context *mixer_ctx) 759 { 760 struct device *dev = &mixer_ctx->pdev->dev; 761 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; 762 struct resource *res; 763 int ret; 764 765 spin_lock_init(&mixer_res->reg_slock); 766 767 mixer_res->mixer = devm_clk_get(dev, "mixer"); 768 if (IS_ERR(mixer_res->mixer)) { 769 dev_err(dev, "failed to get clock 'mixer'\n"); 770 return -ENODEV; 771 } 772 773 mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi"); 774 if (IS_ERR(mixer_res->sclk_hdmi)) { 775 dev_err(dev, "failed to get clock 'sclk_hdmi'\n"); 776 return -ENODEV; 777 } 778 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0); 779 if (res == NULL) { 780 dev_err(dev, "get memory resource failed.\n"); 781 return -ENXIO; 782 } 783 784 mixer_res->mixer_regs = devm_ioremap(dev, res->start, 785 resource_size(res)); 786 if (mixer_res->mixer_regs == NULL) { 787 dev_err(dev, "register mapping failed.\n"); 788 return -ENXIO; 789 } 790 791 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0); 792 if (res == NULL) { 793 dev_err(dev, "get interrupt resource failed.\n"); 794 return -ENXIO; 795 } 796 797 ret = devm_request_irq(dev, res->start, mixer_irq_handler, 798 0, "drm_mixer", mixer_ctx); 799 if (ret) { 800 dev_err(dev, "request interrupt failed.\n"); 801 return ret; 802 } 803 mixer_res->irq = res->start; 804 805 return 0; 806 } 807 808 static int vp_resources_init(struct mixer_context *mixer_ctx) 809 { 810 struct device *dev = &mixer_ctx->pdev->dev; 811 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; 812 struct resource *res; 813 814 mixer_res->vp = devm_clk_get(dev, "vp"); 815 if (IS_ERR(mixer_res->vp)) { 816 dev_err(dev, "failed to get clock 'vp'\n"); 817 return -ENODEV; 818 } 819 820 if (mixer_ctx->has_sclk) { 821 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer"); 822 if (IS_ERR(mixer_res->sclk_mixer)) { 823 dev_err(dev, "failed to get clock 'sclk_mixer'\n"); 824 return -ENODEV; 825 } 826 mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer"); 827 if (IS_ERR(mixer_res->mout_mixer)) { 828 dev_err(dev, "failed to get clock 'mout_mixer'\n"); 829 return -ENODEV; 830 } 831 832 if (mixer_res->sclk_hdmi && mixer_res->mout_mixer) 833 clk_set_parent(mixer_res->mout_mixer, 834 mixer_res->sclk_hdmi); 835 } 836 837 res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1); 838 if (res == NULL) { 839 dev_err(dev, "get memory resource failed.\n"); 840 return -ENXIO; 841 } 842 843 mixer_res->vp_regs = devm_ioremap(dev, res->start, 844 resource_size(res)); 845 if (mixer_res->vp_regs == NULL) { 846 dev_err(dev, "register mapping failed.\n"); 847 return -ENXIO; 848 } 849 850 return 0; 851 } 852 853 static int mixer_initialize(struct exynos_drm_manager *mgr, 854 struct drm_device *drm_dev) 855 { 856 int ret; 857 struct mixer_context *mixer_ctx = mgr->ctx; 858 struct exynos_drm_private *priv; 859 priv = drm_dev->dev_private; 860 861 mgr->drm_dev = mixer_ctx->drm_dev = drm_dev; 862 mgr->pipe = mixer_ctx->pipe = priv->pipe++; 863 864 /* acquire resources: regs, irqs, clocks */ 865 ret = mixer_resources_init(mixer_ctx); 866 if (ret) { 867 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret); 868 return ret; 869 } 870 871 if (mixer_ctx->vp_enabled) { 872 /* acquire vp resources: regs, irqs, clocks */ 873 ret = vp_resources_init(mixer_ctx); 874 if (ret) { 875 DRM_ERROR("vp_resources_init failed ret=%d\n", ret); 876 return ret; 877 } 878 } 879 880 if (!is_drm_iommu_supported(mixer_ctx->drm_dev)) 881 return 0; 882 883 return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 884 } 885 886 static void mixer_mgr_remove(struct exynos_drm_manager *mgr) 887 { 888 struct mixer_context *mixer_ctx = mgr->ctx; 889 890 if (is_drm_iommu_supported(mixer_ctx->drm_dev)) 891 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 892 } 893 894 static int mixer_enable_vblank(struct exynos_drm_manager *mgr) 895 { 896 struct mixer_context *mixer_ctx = mgr->ctx; 897 struct mixer_resources *res = &mixer_ctx->mixer_res; 898 899 if (!mixer_ctx->powered) { 900 mixer_ctx->int_en |= MXR_INT_EN_VSYNC; 901 return 0; 902 } 903 904 /* enable vsync interrupt */ 905 mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC, 906 MXR_INT_EN_VSYNC); 907 908 return 0; 909 } 910 911 static void mixer_disable_vblank(struct exynos_drm_manager *mgr) 912 { 913 struct mixer_context *mixer_ctx = mgr->ctx; 914 struct mixer_resources *res = &mixer_ctx->mixer_res; 915 916 /* disable vsync interrupt */ 917 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); 918 } 919 920 static void mixer_win_mode_set(struct exynos_drm_manager *mgr, 921 struct exynos_drm_overlay *overlay) 922 { 923 struct mixer_context *mixer_ctx = mgr->ctx; 924 struct hdmi_win_data *win_data; 925 int win; 926 927 if (!overlay) { 928 DRM_ERROR("overlay is NULL\n"); 929 return; 930 } 931 932 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", 933 overlay->fb_width, overlay->fb_height, 934 overlay->fb_x, overlay->fb_y, 935 overlay->crtc_width, overlay->crtc_height, 936 overlay->crtc_x, overlay->crtc_y); 937 938 win = overlay->zpos; 939 if (win == DEFAULT_ZPOS) 940 win = MIXER_DEFAULT_WIN; 941 942 if (win < 0 || win >= MIXER_WIN_NR) { 943 DRM_ERROR("mixer window[%d] is wrong\n", win); 944 return; 945 } 946 947 win_data = &mixer_ctx->win_data[win]; 948 949 win_data->dma_addr = overlay->dma_addr[0]; 950 win_data->chroma_dma_addr = overlay->dma_addr[1]; 951 win_data->pixel_format = overlay->pixel_format; 952 win_data->bpp = overlay->bpp; 953 954 win_data->crtc_x = overlay->crtc_x; 955 win_data->crtc_y = overlay->crtc_y; 956 win_data->crtc_width = overlay->crtc_width; 957 win_data->crtc_height = overlay->crtc_height; 958 959 win_data->fb_x = overlay->fb_x; 960 win_data->fb_y = overlay->fb_y; 961 win_data->fb_width = overlay->fb_width; 962 win_data->fb_height = overlay->fb_height; 963 win_data->src_width = overlay->src_width; 964 win_data->src_height = overlay->src_height; 965 966 win_data->mode_width = overlay->mode_width; 967 win_data->mode_height = overlay->mode_height; 968 969 win_data->scan_flags = overlay->scan_flag; 970 } 971 972 static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) 973 { 974 struct mixer_context *mixer_ctx = mgr->ctx; 975 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 976 977 DRM_DEBUG_KMS("win: %d\n", win); 978 979 mutex_lock(&mixer_ctx->mixer_mutex); 980 if (!mixer_ctx->powered) { 981 mutex_unlock(&mixer_ctx->mixer_mutex); 982 return; 983 } 984 mutex_unlock(&mixer_ctx->mixer_mutex); 985 986 if (win > 1 && mixer_ctx->vp_enabled) 987 vp_video_buffer(mixer_ctx, win); 988 else 989 mixer_graph_buffer(mixer_ctx, win); 990 991 mixer_ctx->win_data[win].enabled = true; 992 } 993 994 static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) 995 { 996 struct mixer_context *mixer_ctx = mgr->ctx; 997 struct mixer_resources *res = &mixer_ctx->mixer_res; 998 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 999 unsigned long flags; 1000 1001 DRM_DEBUG_KMS("win: %d\n", win); 1002 1003 mutex_lock(&mixer_ctx->mixer_mutex); 1004 if (!mixer_ctx->powered) { 1005 mutex_unlock(&mixer_ctx->mixer_mutex); 1006 mixer_ctx->win_data[win].resume = false; 1007 return; 1008 } 1009 mutex_unlock(&mixer_ctx->mixer_mutex); 1010 1011 spin_lock_irqsave(&res->reg_slock, flags); 1012 mixer_vsync_set_update(mixer_ctx, false); 1013 1014 mixer_cfg_layer(mixer_ctx, win, false); 1015 1016 mixer_vsync_set_update(mixer_ctx, true); 1017 spin_unlock_irqrestore(&res->reg_slock, flags); 1018 1019 mixer_ctx->win_data[win].enabled = false; 1020 } 1021 1022 static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) 1023 { 1024 struct mixer_context *mixer_ctx = mgr->ctx; 1025 1026 mutex_lock(&mixer_ctx->mixer_mutex); 1027 if (!mixer_ctx->powered) { 1028 mutex_unlock(&mixer_ctx->mixer_mutex); 1029 return; 1030 } 1031 mutex_unlock(&mixer_ctx->mixer_mutex); 1032 1033 drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); 1034 1035 atomic_set(&mixer_ctx->wait_vsync_event, 1); 1036 1037 /* 1038 * wait for MIXER to signal VSYNC interrupt or return after 1039 * timeout which is set to 50ms (refresh rate of 20). 1040 */ 1041 if (!wait_event_timeout(mixer_ctx->wait_vsync_queue, 1042 !atomic_read(&mixer_ctx->wait_vsync_event), 1043 HZ/20)) 1044 DRM_DEBUG_KMS("vblank wait timed out.\n"); 1045 1046 drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe); 1047 } 1048 1049 static void mixer_window_suspend(struct exynos_drm_manager *mgr) 1050 { 1051 struct mixer_context *ctx = mgr->ctx; 1052 struct hdmi_win_data *win_data; 1053 int i; 1054 1055 for (i = 0; i < MIXER_WIN_NR; i++) { 1056 win_data = &ctx->win_data[i]; 1057 win_data->resume = win_data->enabled; 1058 mixer_win_disable(mgr, i); 1059 } 1060 mixer_wait_for_vblank(mgr); 1061 } 1062 1063 static void mixer_window_resume(struct exynos_drm_manager *mgr) 1064 { 1065 struct mixer_context *ctx = mgr->ctx; 1066 struct hdmi_win_data *win_data; 1067 int i; 1068 1069 for (i = 0; i < MIXER_WIN_NR; i++) { 1070 win_data = &ctx->win_data[i]; 1071 win_data->enabled = win_data->resume; 1072 win_data->resume = false; 1073 if (win_data->enabled) 1074 mixer_win_commit(mgr, i); 1075 } 1076 } 1077 1078 static void mixer_poweron(struct exynos_drm_manager *mgr) 1079 { 1080 struct mixer_context *ctx = mgr->ctx; 1081 struct mixer_resources *res = &ctx->mixer_res; 1082 1083 mutex_lock(&ctx->mixer_mutex); 1084 if (ctx->powered) { 1085 mutex_unlock(&ctx->mixer_mutex); 1086 return; 1087 } 1088 1089 mutex_unlock(&ctx->mixer_mutex); 1090 1091 pm_runtime_get_sync(ctx->dev); 1092 1093 clk_prepare_enable(res->mixer); 1094 if (ctx->vp_enabled) { 1095 clk_prepare_enable(res->vp); 1096 if (ctx->has_sclk) 1097 clk_prepare_enable(res->sclk_mixer); 1098 } 1099 1100 mutex_lock(&ctx->mixer_mutex); 1101 ctx->powered = true; 1102 mutex_unlock(&ctx->mixer_mutex); 1103 1104 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); 1105 1106 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1107 mixer_win_reset(ctx); 1108 1109 mixer_window_resume(mgr); 1110 } 1111 1112 static void mixer_poweroff(struct exynos_drm_manager *mgr) 1113 { 1114 struct mixer_context *ctx = mgr->ctx; 1115 struct mixer_resources *res = &ctx->mixer_res; 1116 1117 mutex_lock(&ctx->mixer_mutex); 1118 if (!ctx->powered) { 1119 mutex_unlock(&ctx->mixer_mutex); 1120 return; 1121 } 1122 mutex_unlock(&ctx->mixer_mutex); 1123 1124 mixer_stop(ctx); 1125 mixer_window_suspend(mgr); 1126 1127 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1128 1129 mutex_lock(&ctx->mixer_mutex); 1130 ctx->powered = false; 1131 mutex_unlock(&ctx->mixer_mutex); 1132 1133 clk_disable_unprepare(res->mixer); 1134 if (ctx->vp_enabled) { 1135 clk_disable_unprepare(res->vp); 1136 if (ctx->has_sclk) 1137 clk_disable_unprepare(res->sclk_mixer); 1138 } 1139 1140 pm_runtime_put_sync(ctx->dev); 1141 } 1142 1143 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) 1144 { 1145 switch (mode) { 1146 case DRM_MODE_DPMS_ON: 1147 mixer_poweron(mgr); 1148 break; 1149 case DRM_MODE_DPMS_STANDBY: 1150 case DRM_MODE_DPMS_SUSPEND: 1151 case DRM_MODE_DPMS_OFF: 1152 mixer_poweroff(mgr); 1153 break; 1154 default: 1155 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 1156 break; 1157 } 1158 } 1159 1160 /* Only valid for Mixer version 16.0.33.0 */ 1161 int mixer_check_mode(struct drm_display_mode *mode) 1162 { 1163 u32 w, h; 1164 1165 w = mode->hdisplay; 1166 h = mode->vdisplay; 1167 1168 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", 1169 mode->hdisplay, mode->vdisplay, mode->vrefresh, 1170 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0); 1171 1172 if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) || 1173 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) || 1174 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) 1175 return 0; 1176 1177 return -EINVAL; 1178 } 1179 1180 static struct exynos_drm_manager_ops mixer_manager_ops = { 1181 .dpms = mixer_dpms, 1182 .enable_vblank = mixer_enable_vblank, 1183 .disable_vblank = mixer_disable_vblank, 1184 .wait_for_vblank = mixer_wait_for_vblank, 1185 .win_mode_set = mixer_win_mode_set, 1186 .win_commit = mixer_win_commit, 1187 .win_disable = mixer_win_disable, 1188 }; 1189 1190 static struct exynos_drm_manager mixer_manager = { 1191 .type = EXYNOS_DISPLAY_TYPE_HDMI, 1192 .ops = &mixer_manager_ops, 1193 }; 1194 1195 static struct mixer_drv_data exynos5420_mxr_drv_data = { 1196 .version = MXR_VER_128_0_0_184, 1197 .is_vp_enabled = 0, 1198 }; 1199 1200 static struct mixer_drv_data exynos5250_mxr_drv_data = { 1201 .version = MXR_VER_16_0_33_0, 1202 .is_vp_enabled = 0, 1203 }; 1204 1205 static struct mixer_drv_data exynos4212_mxr_drv_data = { 1206 .version = MXR_VER_0_0_0_16, 1207 .is_vp_enabled = 1, 1208 }; 1209 1210 static struct mixer_drv_data exynos4210_mxr_drv_data = { 1211 .version = MXR_VER_0_0_0_16, 1212 .is_vp_enabled = 1, 1213 .has_sclk = 1, 1214 }; 1215 1216 static struct platform_device_id mixer_driver_types[] = { 1217 { 1218 .name = "s5p-mixer", 1219 .driver_data = (unsigned long)&exynos4210_mxr_drv_data, 1220 }, { 1221 .name = "exynos5-mixer", 1222 .driver_data = (unsigned long)&exynos5250_mxr_drv_data, 1223 }, { 1224 /* end node */ 1225 } 1226 }; 1227 1228 static struct of_device_id mixer_match_types[] = { 1229 { 1230 .compatible = "samsung,exynos4210-mixer", 1231 .data = &exynos4210_mxr_drv_data, 1232 }, { 1233 .compatible = "samsung,exynos4212-mixer", 1234 .data = &exynos4212_mxr_drv_data, 1235 }, { 1236 .compatible = "samsung,exynos5-mixer", 1237 .data = &exynos5250_mxr_drv_data, 1238 }, { 1239 .compatible = "samsung,exynos5250-mixer", 1240 .data = &exynos5250_mxr_drv_data, 1241 }, { 1242 .compatible = "samsung,exynos5420-mixer", 1243 .data = &exynos5420_mxr_drv_data, 1244 }, { 1245 /* end node */ 1246 } 1247 }; 1248 MODULE_DEVICE_TABLE(of, mixer_match_types); 1249 1250 static int mixer_bind(struct device *dev, struct device *manager, void *data) 1251 { 1252 struct platform_device *pdev = to_platform_device(dev); 1253 struct drm_device *drm_dev = data; 1254 struct mixer_context *ctx; 1255 struct mixer_drv_data *drv; 1256 int ret; 1257 1258 dev_info(dev, "probe start\n"); 1259 1260 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 1261 if (!ctx) { 1262 DRM_ERROR("failed to alloc mixer context.\n"); 1263 return -ENOMEM; 1264 } 1265 1266 mutex_init(&ctx->mixer_mutex); 1267 1268 if (dev->of_node) { 1269 const struct of_device_id *match; 1270 match = of_match_node(mixer_match_types, dev->of_node); 1271 drv = (struct mixer_drv_data *)match->data; 1272 } else { 1273 drv = (struct mixer_drv_data *) 1274 platform_get_device_id(pdev)->driver_data; 1275 } 1276 1277 ctx->pdev = pdev; 1278 ctx->dev = dev; 1279 ctx->vp_enabled = drv->is_vp_enabled; 1280 ctx->has_sclk = drv->has_sclk; 1281 ctx->mxr_ver = drv->version; 1282 init_waitqueue_head(&ctx->wait_vsync_queue); 1283 atomic_set(&ctx->wait_vsync_event, 0); 1284 1285 mixer_manager.ctx = ctx; 1286 ret = mixer_initialize(&mixer_manager, drm_dev); 1287 if (ret) 1288 return ret; 1289 1290 platform_set_drvdata(pdev, &mixer_manager); 1291 ret = exynos_drm_crtc_create(&mixer_manager); 1292 if (ret) { 1293 mixer_mgr_remove(&mixer_manager); 1294 return ret; 1295 } 1296 1297 pm_runtime_enable(dev); 1298 1299 return 0; 1300 } 1301 1302 static void mixer_unbind(struct device *dev, struct device *master, void *data) 1303 { 1304 struct exynos_drm_manager *mgr = dev_get_drvdata(dev); 1305 struct drm_crtc *crtc = mgr->crtc; 1306 1307 dev_info(dev, "remove successful\n"); 1308 1309 mixer_mgr_remove(mgr); 1310 1311 pm_runtime_disable(dev); 1312 1313 crtc->funcs->destroy(crtc); 1314 } 1315 1316 static const struct component_ops mixer_component_ops = { 1317 .bind = mixer_bind, 1318 .unbind = mixer_unbind, 1319 }; 1320 1321 static int mixer_probe(struct platform_device *pdev) 1322 { 1323 int ret; 1324 1325 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 1326 mixer_manager.type); 1327 if (ret) 1328 return ret; 1329 1330 ret = component_add(&pdev->dev, &mixer_component_ops); 1331 if (ret) 1332 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1333 1334 return ret; 1335 } 1336 1337 static int mixer_remove(struct platform_device *pdev) 1338 { 1339 component_del(&pdev->dev, &mixer_component_ops); 1340 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1341 1342 return 0; 1343 } 1344 1345 struct platform_driver mixer_driver = { 1346 .driver = { 1347 .name = "exynos-mixer", 1348 .owner = THIS_MODULE, 1349 .of_match_table = mixer_match_types, 1350 }, 1351 .probe = mixer_probe, 1352 .remove = mixer_remove, 1353 .id_table = mixer_driver_types, 1354 }; 1355