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 *hdmi; 76 struct clk *sclk_mixer; 77 struct clk *sclk_hdmi; 78 struct clk *mout_mixer; 79 }; 80 81 enum mixer_version_id { 82 MXR_VER_0_0_0_16, 83 MXR_VER_16_0_33_0, 84 MXR_VER_128_0_0_184, 85 }; 86 87 struct mixer_context { 88 struct platform_device *pdev; 89 struct device *dev; 90 struct drm_device *drm_dev; 91 struct exynos_drm_crtc *crtc; 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_NV12: 417 crcb_mode = false; 418 buf_num = 2; 419 break; 420 /* TODO: single buffer format NV12, NV21 */ 421 default: 422 /* ignore pixel format at disable time */ 423 if (!win_data->dma_addr) 424 break; 425 426 DRM_ERROR("pixel format for vp is wrong [%d].\n", 427 win_data->pixel_format); 428 return; 429 } 430 431 /* scaling feature: (src << 16) / dst */ 432 x_ratio = (win_data->src_width << 16) / win_data->crtc_width; 433 y_ratio = (win_data->src_height << 16) / win_data->crtc_height; 434 435 if (buf_num == 2) { 436 luma_addr[0] = win_data->dma_addr; 437 chroma_addr[0] = win_data->chroma_dma_addr; 438 } else { 439 luma_addr[0] = win_data->dma_addr; 440 chroma_addr[0] = win_data->dma_addr 441 + (win_data->fb_width * win_data->fb_height); 442 } 443 444 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { 445 ctx->interlace = true; 446 if (tiled_mode) { 447 luma_addr[1] = luma_addr[0] + 0x40; 448 chroma_addr[1] = chroma_addr[0] + 0x40; 449 } else { 450 luma_addr[1] = luma_addr[0] + win_data->fb_width; 451 chroma_addr[1] = chroma_addr[0] + win_data->fb_width; 452 } 453 } else { 454 ctx->interlace = false; 455 luma_addr[1] = 0; 456 chroma_addr[1] = 0; 457 } 458 459 spin_lock_irqsave(&res->reg_slock, flags); 460 mixer_vsync_set_update(ctx, false); 461 462 /* interlace or progressive scan mode */ 463 val = (ctx->interlace ? ~0 : 0); 464 vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP); 465 466 /* setup format */ 467 val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12); 468 val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR); 469 vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); 470 471 /* setting size of input image */ 472 vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) | 473 VP_IMG_VSIZE(win_data->fb_height)); 474 /* chroma height has to reduced by 2 to avoid chroma distorions */ 475 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) | 476 VP_IMG_VSIZE(win_data->fb_height / 2)); 477 478 vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width); 479 vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height); 480 vp_reg_write(res, VP_SRC_H_POSITION, 481 VP_SRC_H_POSITION_VAL(win_data->fb_x)); 482 vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y); 483 484 vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width); 485 vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x); 486 if (ctx->interlace) { 487 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2); 488 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2); 489 } else { 490 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height); 491 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y); 492 } 493 494 vp_reg_write(res, VP_H_RATIO, x_ratio); 495 vp_reg_write(res, VP_V_RATIO, y_ratio); 496 497 vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); 498 499 /* set buffer address to vp */ 500 vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]); 501 vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]); 502 vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); 503 vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); 504 505 mixer_cfg_scan(ctx, win_data->mode_height); 506 mixer_cfg_rgb_fmt(ctx, win_data->mode_height); 507 mixer_cfg_layer(ctx, win, true); 508 mixer_run(ctx); 509 510 mixer_vsync_set_update(ctx, true); 511 spin_unlock_irqrestore(&res->reg_slock, flags); 512 513 vp_regs_dump(ctx); 514 } 515 516 static void mixer_layer_update(struct mixer_context *ctx) 517 { 518 struct mixer_resources *res = &ctx->mixer_res; 519 520 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); 521 } 522 523 static void mixer_graph_buffer(struct mixer_context *ctx, int win) 524 { 525 struct mixer_resources *res = &ctx->mixer_res; 526 unsigned long flags; 527 struct hdmi_win_data *win_data; 528 unsigned int x_ratio, y_ratio; 529 unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; 530 dma_addr_t dma_addr; 531 unsigned int fmt; 532 u32 val; 533 534 win_data = &ctx->win_data[win]; 535 536 #define RGB565 4 537 #define ARGB1555 5 538 #define ARGB4444 6 539 #define ARGB8888 7 540 541 switch (win_data->bpp) { 542 case 16: 543 fmt = ARGB4444; 544 break; 545 case 32: 546 fmt = ARGB8888; 547 break; 548 default: 549 fmt = ARGB8888; 550 } 551 552 /* 2x scaling feature */ 553 x_ratio = 0; 554 y_ratio = 0; 555 556 dst_x_offset = win_data->crtc_x; 557 dst_y_offset = win_data->crtc_y; 558 559 /* converting dma address base and source offset */ 560 dma_addr = win_data->dma_addr 561 + (win_data->fb_x * win_data->bpp >> 3) 562 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3); 563 src_x_offset = 0; 564 src_y_offset = 0; 565 566 if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) 567 ctx->interlace = true; 568 else 569 ctx->interlace = false; 570 571 spin_lock_irqsave(&res->reg_slock, flags); 572 mixer_vsync_set_update(ctx, false); 573 574 /* setup format */ 575 mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), 576 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK); 577 578 /* setup geometry */ 579 mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width); 580 581 /* setup display size */ 582 if (ctx->mxr_ver == MXR_VER_128_0_0_184 && 583 win == MIXER_DEFAULT_WIN) { 584 val = MXR_MXR_RES_HEIGHT(win_data->mode_height); 585 val |= MXR_MXR_RES_WIDTH(win_data->mode_width); 586 mixer_reg_write(res, MXR_RESOLUTION, val); 587 } 588 589 val = MXR_GRP_WH_WIDTH(win_data->crtc_width); 590 val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height); 591 val |= MXR_GRP_WH_H_SCALE(x_ratio); 592 val |= MXR_GRP_WH_V_SCALE(y_ratio); 593 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); 594 595 /* setup offsets in source image */ 596 val = MXR_GRP_SXY_SX(src_x_offset); 597 val |= MXR_GRP_SXY_SY(src_y_offset); 598 mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val); 599 600 /* setup offsets in display image */ 601 val = MXR_GRP_DXY_DX(dst_x_offset); 602 val |= MXR_GRP_DXY_DY(dst_y_offset); 603 mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val); 604 605 /* set buffer address to mixer */ 606 mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); 607 608 mixer_cfg_scan(ctx, win_data->mode_height); 609 mixer_cfg_rgb_fmt(ctx, win_data->mode_height); 610 mixer_cfg_layer(ctx, win, true); 611 612 /* layer update mandatory for mixer 16.0.33.0 */ 613 if (ctx->mxr_ver == MXR_VER_16_0_33_0 || 614 ctx->mxr_ver == MXR_VER_128_0_0_184) 615 mixer_layer_update(ctx); 616 617 mixer_run(ctx); 618 619 mixer_vsync_set_update(ctx, true); 620 spin_unlock_irqrestore(&res->reg_slock, flags); 621 } 622 623 static void vp_win_reset(struct mixer_context *ctx) 624 { 625 struct mixer_resources *res = &ctx->mixer_res; 626 int tries = 100; 627 628 vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING); 629 for (tries = 100; tries; --tries) { 630 /* waiting until VP_SRESET_PROCESSING is 0 */ 631 if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING) 632 break; 633 usleep_range(10000, 12000); 634 } 635 WARN(tries == 0, "failed to reset Video Processor\n"); 636 } 637 638 static void mixer_win_reset(struct mixer_context *ctx) 639 { 640 struct mixer_resources *res = &ctx->mixer_res; 641 unsigned long flags; 642 u32 val; /* value stored to register */ 643 644 spin_lock_irqsave(&res->reg_slock, flags); 645 mixer_vsync_set_update(ctx, false); 646 647 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); 648 649 /* set output in RGB888 mode */ 650 mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK); 651 652 /* 16 beat burst in DMA */ 653 mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, 654 MXR_STATUS_BURST_MASK); 655 656 /* setting default layer priority: layer1 > layer0 > video 657 * because typical usage scenario would be 658 * layer1 - OSD 659 * layer0 - framebuffer 660 * video - video overlay 661 */ 662 val = MXR_LAYER_CFG_GRP1_VAL(3); 663 val |= MXR_LAYER_CFG_GRP0_VAL(2); 664 if (ctx->vp_enabled) 665 val |= MXR_LAYER_CFG_VP_VAL(1); 666 mixer_reg_write(res, MXR_LAYER_CFG, val); 667 668 /* setting background color */ 669 mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); 670 mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); 671 mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); 672 673 /* setting graphical layers */ 674 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ 675 val |= MXR_GRP_CFG_WIN_BLEND_EN; 676 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ 677 678 /* Don't blend layer 0 onto the mixer background */ 679 mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); 680 681 /* Blend layer 1 into layer 0 */ 682 val |= MXR_GRP_CFG_BLEND_PRE_MUL; 683 val |= MXR_GRP_CFG_PIXEL_BLEND_EN; 684 mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); 685 686 /* setting video layers */ 687 val = MXR_GRP_CFG_ALPHA_VAL(0); 688 mixer_reg_write(res, MXR_VIDEO_CFG, val); 689 690 if (ctx->vp_enabled) { 691 /* configuration of Video Processor Registers */ 692 vp_win_reset(ctx); 693 vp_default_filter(res); 694 } 695 696 /* disable all layers */ 697 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE); 698 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE); 699 if (ctx->vp_enabled) 700 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); 701 702 mixer_vsync_set_update(ctx, true); 703 spin_unlock_irqrestore(&res->reg_slock, flags); 704 } 705 706 static irqreturn_t mixer_irq_handler(int irq, void *arg) 707 { 708 struct mixer_context *ctx = arg; 709 struct mixer_resources *res = &ctx->mixer_res; 710 u32 val, base, shadow; 711 712 spin_lock(&res->reg_slock); 713 714 /* read interrupt status for handling and clearing flags for VSYNC */ 715 val = mixer_reg_read(res, MXR_INT_STATUS); 716 717 /* handling VSYNC */ 718 if (val & MXR_INT_STATUS_VSYNC) { 719 /* interlace scan need to check shadow register */ 720 if (ctx->interlace) { 721 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0)); 722 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0)); 723 if (base != shadow) 724 goto out; 725 726 base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1)); 727 shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1)); 728 if (base != shadow) 729 goto out; 730 } 731 732 drm_handle_vblank(ctx->drm_dev, ctx->pipe); 733 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); 734 735 /* set wait vsync event to zero and wake up queue. */ 736 if (atomic_read(&ctx->wait_vsync_event)) { 737 atomic_set(&ctx->wait_vsync_event, 0); 738 wake_up(&ctx->wait_vsync_queue); 739 } 740 } 741 742 out: 743 /* clear interrupts */ 744 if (~val & MXR_INT_EN_VSYNC) { 745 /* vsync interrupt use different bit for read and clear */ 746 val &= ~MXR_INT_EN_VSYNC; 747 val |= MXR_INT_CLEAR_VSYNC; 748 } 749 mixer_reg_write(res, MXR_INT_STATUS, val); 750 751 spin_unlock(&res->reg_slock); 752 753 return IRQ_HANDLED; 754 } 755 756 static int mixer_resources_init(struct mixer_context *mixer_ctx) 757 { 758 struct device *dev = &mixer_ctx->pdev->dev; 759 struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; 760 struct resource *res; 761 int ret; 762 763 spin_lock_init(&mixer_res->reg_slock); 764 765 mixer_res->mixer = devm_clk_get(dev, "mixer"); 766 if (IS_ERR(mixer_res->mixer)) { 767 dev_err(dev, "failed to get clock 'mixer'\n"); 768 return -ENODEV; 769 } 770 771 mixer_res->hdmi = devm_clk_get(dev, "hdmi"); 772 if (IS_ERR(mixer_res->hdmi)) { 773 dev_err(dev, "failed to get clock 'hdmi'\n"); 774 return PTR_ERR(mixer_res->hdmi); 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 mixer_context *mixer_ctx, 858 struct drm_device *drm_dev) 859 { 860 int ret; 861 struct exynos_drm_private *priv; 862 priv = drm_dev->dev_private; 863 864 mixer_ctx->drm_dev = drm_dev; 865 mixer_ctx->pipe = priv->pipe++; 866 867 /* acquire resources: regs, irqs, clocks */ 868 ret = mixer_resources_init(mixer_ctx); 869 if (ret) { 870 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret); 871 return ret; 872 } 873 874 if (mixer_ctx->vp_enabled) { 875 /* acquire vp resources: regs, irqs, clocks */ 876 ret = vp_resources_init(mixer_ctx); 877 if (ret) { 878 DRM_ERROR("vp_resources_init failed ret=%d\n", ret); 879 return ret; 880 } 881 } 882 883 if (!is_drm_iommu_supported(mixer_ctx->drm_dev)) 884 return 0; 885 886 return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 887 } 888 889 static void mixer_ctx_remove(struct mixer_context *mixer_ctx) 890 { 891 if (is_drm_iommu_supported(mixer_ctx->drm_dev)) 892 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 893 } 894 895 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) 896 { 897 struct mixer_context *mixer_ctx = crtc->ctx; 898 struct mixer_resources *res = &mixer_ctx->mixer_res; 899 900 if (!mixer_ctx->powered) { 901 mixer_ctx->int_en |= MXR_INT_EN_VSYNC; 902 return 0; 903 } 904 905 /* enable vsync interrupt */ 906 mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC, 907 MXR_INT_EN_VSYNC); 908 909 return 0; 910 } 911 912 static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) 913 { 914 struct mixer_context *mixer_ctx = crtc->ctx; 915 struct mixer_resources *res = &mixer_ctx->mixer_res; 916 917 /* disable vsync interrupt */ 918 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); 919 } 920 921 static void mixer_win_mode_set(struct exynos_drm_crtc *crtc, 922 struct exynos_drm_plane *plane) 923 { 924 struct mixer_context *mixer_ctx = crtc->ctx; 925 struct hdmi_win_data *win_data; 926 int win; 927 928 if (!plane) { 929 DRM_ERROR("plane is NULL\n"); 930 return; 931 } 932 933 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", 934 plane->fb_width, plane->fb_height, 935 plane->fb_x, plane->fb_y, 936 plane->crtc_width, plane->crtc_height, 937 plane->crtc_x, plane->crtc_y); 938 939 win = plane->zpos; 940 if (win == DEFAULT_ZPOS) 941 win = MIXER_DEFAULT_WIN; 942 943 if (win < 0 || win >= MIXER_WIN_NR) { 944 DRM_ERROR("mixer window[%d] is wrong\n", win); 945 return; 946 } 947 948 win_data = &mixer_ctx->win_data[win]; 949 950 win_data->dma_addr = plane->dma_addr[0]; 951 win_data->chroma_dma_addr = plane->dma_addr[1]; 952 win_data->pixel_format = plane->pixel_format; 953 win_data->bpp = plane->bpp; 954 955 win_data->crtc_x = plane->crtc_x; 956 win_data->crtc_y = plane->crtc_y; 957 win_data->crtc_width = plane->crtc_width; 958 win_data->crtc_height = plane->crtc_height; 959 960 win_data->fb_x = plane->fb_x; 961 win_data->fb_y = plane->fb_y; 962 win_data->fb_width = plane->fb_width; 963 win_data->fb_height = plane->fb_height; 964 win_data->src_width = plane->src_width; 965 win_data->src_height = plane->src_height; 966 967 win_data->mode_width = plane->mode_width; 968 win_data->mode_height = plane->mode_height; 969 970 win_data->scan_flags = plane->scan_flag; 971 } 972 973 static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos) 974 { 975 struct mixer_context *mixer_ctx = crtc->ctx; 976 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 977 978 DRM_DEBUG_KMS("win: %d\n", win); 979 980 mutex_lock(&mixer_ctx->mixer_mutex); 981 if (!mixer_ctx->powered) { 982 mutex_unlock(&mixer_ctx->mixer_mutex); 983 return; 984 } 985 mutex_unlock(&mixer_ctx->mixer_mutex); 986 987 if (win > 1 && mixer_ctx->vp_enabled) 988 vp_video_buffer(mixer_ctx, win); 989 else 990 mixer_graph_buffer(mixer_ctx, win); 991 992 mixer_ctx->win_data[win].enabled = true; 993 } 994 995 static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos) 996 { 997 struct mixer_context *mixer_ctx = crtc->ctx; 998 struct mixer_resources *res = &mixer_ctx->mixer_res; 999 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 1000 unsigned long flags; 1001 1002 DRM_DEBUG_KMS("win: %d\n", win); 1003 1004 mutex_lock(&mixer_ctx->mixer_mutex); 1005 if (!mixer_ctx->powered) { 1006 mutex_unlock(&mixer_ctx->mixer_mutex); 1007 mixer_ctx->win_data[win].resume = false; 1008 return; 1009 } 1010 mutex_unlock(&mixer_ctx->mixer_mutex); 1011 1012 spin_lock_irqsave(&res->reg_slock, flags); 1013 mixer_vsync_set_update(mixer_ctx, false); 1014 1015 mixer_cfg_layer(mixer_ctx, win, false); 1016 1017 mixer_vsync_set_update(mixer_ctx, true); 1018 spin_unlock_irqrestore(&res->reg_slock, flags); 1019 1020 mixer_ctx->win_data[win].enabled = false; 1021 } 1022 1023 static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) 1024 { 1025 struct mixer_context *mixer_ctx = crtc->ctx; 1026 int err; 1027 1028 mutex_lock(&mixer_ctx->mixer_mutex); 1029 if (!mixer_ctx->powered) { 1030 mutex_unlock(&mixer_ctx->mixer_mutex); 1031 return; 1032 } 1033 mutex_unlock(&mixer_ctx->mixer_mutex); 1034 1035 err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe); 1036 if (err < 0) { 1037 DRM_DEBUG_KMS("failed to acquire vblank counter\n"); 1038 return; 1039 } 1040 1041 atomic_set(&mixer_ctx->wait_vsync_event, 1); 1042 1043 /* 1044 * wait for MIXER to signal VSYNC interrupt or return after 1045 * timeout which is set to 50ms (refresh rate of 20). 1046 */ 1047 if (!wait_event_timeout(mixer_ctx->wait_vsync_queue, 1048 !atomic_read(&mixer_ctx->wait_vsync_event), 1049 HZ/20)) 1050 DRM_DEBUG_KMS("vblank wait timed out.\n"); 1051 1052 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); 1053 } 1054 1055 static void mixer_window_suspend(struct mixer_context *ctx) 1056 { 1057 struct hdmi_win_data *win_data; 1058 int i; 1059 1060 for (i = 0; i < MIXER_WIN_NR; i++) { 1061 win_data = &ctx->win_data[i]; 1062 win_data->resume = win_data->enabled; 1063 mixer_win_disable(ctx->crtc, i); 1064 } 1065 mixer_wait_for_vblank(ctx->crtc); 1066 } 1067 1068 static void mixer_window_resume(struct mixer_context *ctx) 1069 { 1070 struct hdmi_win_data *win_data; 1071 int i; 1072 1073 for (i = 0; i < MIXER_WIN_NR; i++) { 1074 win_data = &ctx->win_data[i]; 1075 win_data->enabled = win_data->resume; 1076 win_data->resume = false; 1077 if (win_data->enabled) 1078 mixer_win_commit(ctx->crtc, i); 1079 } 1080 } 1081 1082 static void mixer_poweron(struct mixer_context *ctx) 1083 { 1084 struct mixer_resources *res = &ctx->mixer_res; 1085 1086 mutex_lock(&ctx->mixer_mutex); 1087 if (ctx->powered) { 1088 mutex_unlock(&ctx->mixer_mutex); 1089 return; 1090 } 1091 1092 mutex_unlock(&ctx->mixer_mutex); 1093 1094 pm_runtime_get_sync(ctx->dev); 1095 1096 clk_prepare_enable(res->mixer); 1097 clk_prepare_enable(res->hdmi); 1098 if (ctx->vp_enabled) { 1099 clk_prepare_enable(res->vp); 1100 if (ctx->has_sclk) 1101 clk_prepare_enable(res->sclk_mixer); 1102 } 1103 1104 mutex_lock(&ctx->mixer_mutex); 1105 ctx->powered = true; 1106 mutex_unlock(&ctx->mixer_mutex); 1107 1108 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); 1109 1110 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1111 mixer_win_reset(ctx); 1112 1113 mixer_window_resume(ctx); 1114 } 1115 1116 static void mixer_poweroff(struct mixer_context *ctx) 1117 { 1118 struct mixer_resources *res = &ctx->mixer_res; 1119 1120 mutex_lock(&ctx->mixer_mutex); 1121 if (!ctx->powered) { 1122 mutex_unlock(&ctx->mixer_mutex); 1123 return; 1124 } 1125 mutex_unlock(&ctx->mixer_mutex); 1126 1127 mixer_stop(ctx); 1128 mixer_window_suspend(ctx); 1129 1130 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1131 1132 mutex_lock(&ctx->mixer_mutex); 1133 ctx->powered = false; 1134 mutex_unlock(&ctx->mixer_mutex); 1135 1136 clk_disable_unprepare(res->hdmi); 1137 clk_disable_unprepare(res->mixer); 1138 if (ctx->vp_enabled) { 1139 clk_disable_unprepare(res->vp); 1140 if (ctx->has_sclk) 1141 clk_disable_unprepare(res->sclk_mixer); 1142 } 1143 1144 pm_runtime_put_sync(ctx->dev); 1145 } 1146 1147 static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode) 1148 { 1149 switch (mode) { 1150 case DRM_MODE_DPMS_ON: 1151 mixer_poweron(crtc->ctx); 1152 break; 1153 case DRM_MODE_DPMS_STANDBY: 1154 case DRM_MODE_DPMS_SUSPEND: 1155 case DRM_MODE_DPMS_OFF: 1156 mixer_poweroff(crtc->ctx); 1157 break; 1158 default: 1159 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 1160 break; 1161 } 1162 } 1163 1164 /* Only valid for Mixer version 16.0.33.0 */ 1165 int mixer_check_mode(struct drm_display_mode *mode) 1166 { 1167 u32 w, h; 1168 1169 w = mode->hdisplay; 1170 h = mode->vdisplay; 1171 1172 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", 1173 mode->hdisplay, mode->vdisplay, mode->vrefresh, 1174 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0); 1175 1176 if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) || 1177 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) || 1178 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080)) 1179 return 0; 1180 1181 return -EINVAL; 1182 } 1183 1184 static struct exynos_drm_crtc_ops mixer_crtc_ops = { 1185 .dpms = mixer_dpms, 1186 .enable_vblank = mixer_enable_vblank, 1187 .disable_vblank = mixer_disable_vblank, 1188 .wait_for_vblank = mixer_wait_for_vblank, 1189 .win_mode_set = mixer_win_mode_set, 1190 .win_commit = mixer_win_commit, 1191 .win_disable = mixer_win_disable, 1192 }; 1193 1194 static struct mixer_drv_data exynos5420_mxr_drv_data = { 1195 .version = MXR_VER_128_0_0_184, 1196 .is_vp_enabled = 0, 1197 }; 1198 1199 static struct mixer_drv_data exynos5250_mxr_drv_data = { 1200 .version = MXR_VER_16_0_33_0, 1201 .is_vp_enabled = 0, 1202 }; 1203 1204 static struct mixer_drv_data exynos4212_mxr_drv_data = { 1205 .version = MXR_VER_0_0_0_16, 1206 .is_vp_enabled = 1, 1207 }; 1208 1209 static struct mixer_drv_data exynos4210_mxr_drv_data = { 1210 .version = MXR_VER_0_0_0_16, 1211 .is_vp_enabled = 1, 1212 .has_sclk = 1, 1213 }; 1214 1215 static struct platform_device_id mixer_driver_types[] = { 1216 { 1217 .name = "s5p-mixer", 1218 .driver_data = (unsigned long)&exynos4210_mxr_drv_data, 1219 }, { 1220 .name = "exynos5-mixer", 1221 .driver_data = (unsigned long)&exynos5250_mxr_drv_data, 1222 }, { 1223 /* end node */ 1224 } 1225 }; 1226 1227 static struct of_device_id mixer_match_types[] = { 1228 { 1229 .compatible = "samsung,exynos4210-mixer", 1230 .data = &exynos4210_mxr_drv_data, 1231 }, { 1232 .compatible = "samsung,exynos4212-mixer", 1233 .data = &exynos4212_mxr_drv_data, 1234 }, { 1235 .compatible = "samsung,exynos5-mixer", 1236 .data = &exynos5250_mxr_drv_data, 1237 }, { 1238 .compatible = "samsung,exynos5250-mixer", 1239 .data = &exynos5250_mxr_drv_data, 1240 }, { 1241 .compatible = "samsung,exynos5420-mixer", 1242 .data = &exynos5420_mxr_drv_data, 1243 }, { 1244 /* end node */ 1245 } 1246 }; 1247 MODULE_DEVICE_TABLE(of, mixer_match_types); 1248 1249 static int mixer_bind(struct device *dev, struct device *manager, void *data) 1250 { 1251 struct mixer_context *ctx = dev_get_drvdata(dev); 1252 struct drm_device *drm_dev = data; 1253 int ret; 1254 1255 ret = mixer_initialize(ctx, drm_dev); 1256 if (ret) 1257 return ret; 1258 1259 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, 1260 EXYNOS_DISPLAY_TYPE_HDMI, 1261 &mixer_crtc_ops, ctx); 1262 if (IS_ERR(ctx->crtc)) { 1263 mixer_ctx_remove(ctx); 1264 ret = PTR_ERR(ctx->crtc); 1265 goto free_ctx; 1266 } 1267 1268 return 0; 1269 1270 free_ctx: 1271 devm_kfree(dev, ctx); 1272 return ret; 1273 } 1274 1275 static void mixer_unbind(struct device *dev, struct device *master, void *data) 1276 { 1277 struct mixer_context *ctx = dev_get_drvdata(dev); 1278 1279 mixer_ctx_remove(ctx); 1280 } 1281 1282 static const struct component_ops mixer_component_ops = { 1283 .bind = mixer_bind, 1284 .unbind = mixer_unbind, 1285 }; 1286 1287 static int mixer_probe(struct platform_device *pdev) 1288 { 1289 struct device *dev = &pdev->dev; 1290 struct mixer_drv_data *drv; 1291 struct mixer_context *ctx; 1292 int ret; 1293 1294 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 1295 if (!ctx) { 1296 DRM_ERROR("failed to alloc mixer context.\n"); 1297 return -ENOMEM; 1298 } 1299 1300 mutex_init(&ctx->mixer_mutex); 1301 1302 if (dev->of_node) { 1303 const struct of_device_id *match; 1304 1305 match = of_match_node(mixer_match_types, dev->of_node); 1306 drv = (struct mixer_drv_data *)match->data; 1307 } else { 1308 drv = (struct mixer_drv_data *) 1309 platform_get_device_id(pdev)->driver_data; 1310 } 1311 1312 ctx->pdev = pdev; 1313 ctx->dev = dev; 1314 ctx->vp_enabled = drv->is_vp_enabled; 1315 ctx->has_sclk = drv->has_sclk; 1316 ctx->mxr_ver = drv->version; 1317 init_waitqueue_head(&ctx->wait_vsync_queue); 1318 atomic_set(&ctx->wait_vsync_event, 0); 1319 1320 platform_set_drvdata(pdev, ctx); 1321 1322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 1323 EXYNOS_DISPLAY_TYPE_HDMI); 1324 if (ret) 1325 return ret; 1326 1327 ret = component_add(&pdev->dev, &mixer_component_ops); 1328 if (ret) { 1329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1330 return ret; 1331 } 1332 1333 pm_runtime_enable(dev); 1334 1335 return ret; 1336 } 1337 1338 static int mixer_remove(struct platform_device *pdev) 1339 { 1340 pm_runtime_disable(&pdev->dev); 1341 1342 component_del(&pdev->dev, &mixer_component_ops); 1343 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC); 1344 1345 return 0; 1346 } 1347 1348 struct platform_driver mixer_driver = { 1349 .driver = { 1350 .name = "exynos-mixer", 1351 .owner = THIS_MODULE, 1352 .of_match_table = mixer_match_types, 1353 }, 1354 .probe = mixer_probe, 1355 .remove = mixer_remove, 1356 .id_table = mixer_driver_types, 1357 }; 1358