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