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