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