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