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