1 /* 2 * Copyright (C) 2012 Samsung Electronics Co.Ltd 3 * Authors: 4 * Eunchul Kim <chulspro.kim@samsung.com> 5 * Jinyoung Jeon <jy0.jeon@samsung.com> 6 * Sangmin Lee <lsmin.lee@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 #include <linux/kernel.h> 15 #include <linux/platform_device.h> 16 #include <linux/mfd/syscon.h> 17 #include <linux/regmap.h> 18 #include <linux/clk.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/of.h> 21 #include <linux/spinlock.h> 22 23 #include <drm/drmP.h> 24 #include <drm/exynos_drm.h> 25 #include "regs-fimc.h" 26 #include "exynos_drm_drv.h" 27 #include "exynos_drm_ipp.h" 28 #include "exynos_drm_fimc.h" 29 30 /* 31 * FIMC stands for Fully Interactive Mobile Camera and 32 * supports image scaler/rotator and input/output DMA operations. 33 * input DMA reads image data from the memory. 34 * output DMA writes image data to memory. 35 * FIMC supports image rotation and image effect functions. 36 * 37 * M2M operation : supports crop/scale/rotation/csc so on. 38 * Memory ----> FIMC H/W ----> Memory. 39 * Writeback operation : supports cloned screen with FIMD. 40 * FIMD ----> FIMC H/W ----> Memory. 41 * Output operation : supports direct display using local path. 42 * Memory ----> FIMC H/W ----> FIMD. 43 */ 44 45 /* 46 * TODO 47 * 1. check suspend/resume api if needed. 48 * 2. need to check use case platform_device_id. 49 * 3. check src/dst size with, height. 50 * 4. added check_prepare api for right register. 51 * 5. need to add supported list in prop_list. 52 * 6. check prescaler/scaler optimization. 53 */ 54 55 #define FIMC_MAX_DEVS 4 56 #define FIMC_MAX_SRC 2 57 #define FIMC_MAX_DST 32 58 #define FIMC_SHFACTOR 10 59 #define FIMC_BUF_STOP 1 60 #define FIMC_BUF_START 2 61 #define FIMC_WIDTH_ITU_709 1280 62 #define FIMC_REFRESH_MAX 60 63 #define FIMC_REFRESH_MIN 12 64 #define FIMC_CROP_MAX 8192 65 #define FIMC_CROP_MIN 32 66 #define FIMC_SCALE_MAX 4224 67 #define FIMC_SCALE_MIN 32 68 69 #define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev)) 70 #define get_ctx_from_ippdrv(ippdrv) container_of(ippdrv,\ 71 struct fimc_context, ippdrv); 72 enum fimc_wb { 73 FIMC_WB_NONE, 74 FIMC_WB_A, 75 FIMC_WB_B, 76 }; 77 78 enum { 79 FIMC_CLK_LCLK, 80 FIMC_CLK_GATE, 81 FIMC_CLK_WB_A, 82 FIMC_CLK_WB_B, 83 FIMC_CLK_MUX, 84 FIMC_CLK_PARENT, 85 FIMC_CLKS_MAX 86 }; 87 88 static const char * const fimc_clock_names[] = { 89 [FIMC_CLK_LCLK] = "sclk_fimc", 90 [FIMC_CLK_GATE] = "fimc", 91 [FIMC_CLK_WB_A] = "pxl_async0", 92 [FIMC_CLK_WB_B] = "pxl_async1", 93 [FIMC_CLK_MUX] = "mux", 94 [FIMC_CLK_PARENT] = "parent", 95 }; 96 97 #define FIMC_DEFAULT_LCLK_FREQUENCY 133000000UL 98 99 /* 100 * A structure of scaler. 101 * 102 * @range: narrow, wide. 103 * @bypass: unused scaler path. 104 * @up_h: horizontal scale up. 105 * @up_v: vertical scale up. 106 * @hratio: horizontal ratio. 107 * @vratio: vertical ratio. 108 */ 109 struct fimc_scaler { 110 bool range; 111 bool bypass; 112 bool up_h; 113 bool up_v; 114 u32 hratio; 115 u32 vratio; 116 }; 117 118 /* 119 * A structure of scaler capability. 120 * 121 * find user manual table 43-1. 122 * @in_hori: scaler input horizontal size. 123 * @bypass: scaler bypass mode. 124 * @dst_h_wo_rot: target horizontal size without output rotation. 125 * @dst_h_rot: target horizontal size with output rotation. 126 * @rl_w_wo_rot: real width without input rotation. 127 * @rl_h_rot: real height without output rotation. 128 */ 129 struct fimc_capability { 130 /* scaler */ 131 u32 in_hori; 132 u32 bypass; 133 /* output rotator */ 134 u32 dst_h_wo_rot; 135 u32 dst_h_rot; 136 /* input rotator */ 137 u32 rl_w_wo_rot; 138 u32 rl_h_rot; 139 }; 140 141 /* 142 * A structure of fimc context. 143 * 144 * @ippdrv: prepare initialization using ippdrv. 145 * @regs_res: register resources. 146 * @regs: memory mapped io registers. 147 * @lock: locking of operations. 148 * @clocks: fimc clocks. 149 * @clk_frequency: LCLK clock frequency. 150 * @sysreg: handle to SYSREG block regmap. 151 * @sc: scaler infomations. 152 * @pol: porarity of writeback. 153 * @id: fimc id. 154 * @irq: irq number. 155 * @suspended: qos operations. 156 */ 157 struct fimc_context { 158 struct exynos_drm_ippdrv ippdrv; 159 struct resource *regs_res; 160 void __iomem *regs; 161 spinlock_t lock; 162 struct clk *clocks[FIMC_CLKS_MAX]; 163 u32 clk_frequency; 164 struct regmap *sysreg; 165 struct fimc_scaler sc; 166 int id; 167 int irq; 168 bool suspended; 169 }; 170 171 static u32 fimc_read(struct fimc_context *ctx, u32 reg) 172 { 173 return readl(ctx->regs + reg); 174 } 175 176 static void fimc_write(struct fimc_context *ctx, u32 val, u32 reg) 177 { 178 writel(val, ctx->regs + reg); 179 } 180 181 static void fimc_set_bits(struct fimc_context *ctx, u32 reg, u32 bits) 182 { 183 void __iomem *r = ctx->regs + reg; 184 185 writel(readl(r) | bits, r); 186 } 187 188 static void fimc_clear_bits(struct fimc_context *ctx, u32 reg, u32 bits) 189 { 190 void __iomem *r = ctx->regs + reg; 191 192 writel(readl(r) & ~bits, r); 193 } 194 195 static void fimc_sw_reset(struct fimc_context *ctx) 196 { 197 u32 cfg; 198 199 /* stop dma operation */ 200 cfg = fimc_read(ctx, EXYNOS_CISTATUS); 201 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) 202 fimc_clear_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); 203 204 fimc_set_bits(ctx, EXYNOS_CISRCFMT, EXYNOS_CISRCFMT_ITU601_8BIT); 205 206 /* disable image capture */ 207 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT, 208 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 209 210 /* s/w reset */ 211 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST); 212 213 /* s/w reset complete */ 214 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST); 215 216 /* reset sequence */ 217 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 218 } 219 220 static int fimc_set_camblk_fimd0_wb(struct fimc_context *ctx) 221 { 222 return regmap_update_bits(ctx->sysreg, SYSREG_CAMERA_BLK, 223 SYSREG_FIMD0WB_DEST_MASK, 224 ctx->id << SYSREG_FIMD0WB_DEST_SHIFT); 225 } 226 227 static void fimc_set_type_ctrl(struct fimc_context *ctx, enum fimc_wb wb) 228 { 229 u32 cfg; 230 231 DRM_DEBUG_KMS("wb[%d]\n", wb); 232 233 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 234 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK | 235 EXYNOS_CIGCTRL_SELCAM_ITU_MASK | 236 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK | 237 EXYNOS_CIGCTRL_SELCAM_FIMC_MASK | 238 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK | 239 EXYNOS_CIGCTRL_SELWRITEBACK_MASK); 240 241 switch (wb) { 242 case FIMC_WB_A: 243 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_A | 244 EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK); 245 break; 246 case FIMC_WB_B: 247 cfg |= (EXYNOS_CIGCTRL_SELWRITEBACK_B | 248 EXYNOS_CIGCTRL_SELWB_CAMIF_WRITEBACK); 249 break; 250 case FIMC_WB_NONE: 251 default: 252 cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A | 253 EXYNOS_CIGCTRL_SELWRITEBACK_A | 254 EXYNOS_CIGCTRL_SELCAM_MIPI_A | 255 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU); 256 break; 257 } 258 259 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 260 } 261 262 static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable) 263 { 264 u32 cfg; 265 266 DRM_DEBUG_KMS("enable[%d]\n", enable); 267 268 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 269 if (enable) 270 cfg |= EXYNOS_CIGCTRL_CAM_JPEG; 271 else 272 cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG; 273 274 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 275 } 276 277 static void fimc_mask_irq(struct fimc_context *ctx, bool enable) 278 { 279 u32 cfg; 280 281 DRM_DEBUG_KMS("enable[%d]\n", enable); 282 283 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 284 if (enable) { 285 cfg &= ~EXYNOS_CIGCTRL_IRQ_OVFEN; 286 cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE | EXYNOS_CIGCTRL_IRQ_LEVEL; 287 } else 288 cfg &= ~EXYNOS_CIGCTRL_IRQ_ENABLE; 289 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 290 } 291 292 static void fimc_clear_irq(struct fimc_context *ctx) 293 { 294 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_CLR); 295 } 296 297 static bool fimc_check_ovf(struct fimc_context *ctx) 298 { 299 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 300 u32 status, flag; 301 302 status = fimc_read(ctx, EXYNOS_CISTATUS); 303 flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB | 304 EXYNOS_CISTATUS_OVFICR; 305 306 DRM_DEBUG_KMS("flag[0x%x]\n", flag); 307 308 if (status & flag) { 309 fimc_set_bits(ctx, EXYNOS_CIWDOFST, 310 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | 311 EXYNOS_CIWDOFST_CLROVFICR); 312 313 dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", 314 ctx->id, status); 315 return true; 316 } 317 318 return false; 319 } 320 321 static bool fimc_check_frame_end(struct fimc_context *ctx) 322 { 323 u32 cfg; 324 325 cfg = fimc_read(ctx, EXYNOS_CISTATUS); 326 327 DRM_DEBUG_KMS("cfg[0x%x]\n", cfg); 328 329 if (!(cfg & EXYNOS_CISTATUS_FRAMEEND)) 330 return false; 331 332 cfg &= ~(EXYNOS_CISTATUS_FRAMEEND); 333 fimc_write(ctx, cfg, EXYNOS_CISTATUS); 334 335 return true; 336 } 337 338 static int fimc_get_buf_id(struct fimc_context *ctx) 339 { 340 u32 cfg; 341 int frame_cnt, buf_id; 342 343 cfg = fimc_read(ctx, EXYNOS_CISTATUS2); 344 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg); 345 346 if (frame_cnt == 0) 347 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg); 348 349 DRM_DEBUG_KMS("present[%d]before[%d]\n", 350 EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg), 351 EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg)); 352 353 if (frame_cnt == 0) { 354 DRM_ERROR("failed to get frame count.\n"); 355 return -EIO; 356 } 357 358 buf_id = frame_cnt - 1; 359 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); 360 361 return buf_id; 362 } 363 364 static void fimc_handle_lastend(struct fimc_context *ctx, bool enable) 365 { 366 u32 cfg; 367 368 DRM_DEBUG_KMS("enable[%d]\n", enable); 369 370 cfg = fimc_read(ctx, EXYNOS_CIOCTRL); 371 if (enable) 372 cfg |= EXYNOS_CIOCTRL_LASTENDEN; 373 else 374 cfg &= ~EXYNOS_CIOCTRL_LASTENDEN; 375 376 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 377 } 378 379 380 static int fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt) 381 { 382 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 383 u32 cfg; 384 385 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 386 387 /* RGB */ 388 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 389 cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK; 390 391 switch (fmt) { 392 case DRM_FORMAT_RGB565: 393 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565; 394 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 395 return 0; 396 case DRM_FORMAT_RGB888: 397 case DRM_FORMAT_XRGB8888: 398 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888; 399 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 400 return 0; 401 default: 402 /* bypass */ 403 break; 404 } 405 406 /* YUV */ 407 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 408 cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK | 409 EXYNOS_MSCTRL_C_INT_IN_2PLANE | 410 EXYNOS_MSCTRL_ORDER422_YCBYCR); 411 412 switch (fmt) { 413 case DRM_FORMAT_YUYV: 414 cfg |= EXYNOS_MSCTRL_ORDER422_YCBYCR; 415 break; 416 case DRM_FORMAT_YVYU: 417 cfg |= EXYNOS_MSCTRL_ORDER422_YCRYCB; 418 break; 419 case DRM_FORMAT_UYVY: 420 cfg |= EXYNOS_MSCTRL_ORDER422_CBYCRY; 421 break; 422 case DRM_FORMAT_VYUY: 423 case DRM_FORMAT_YUV444: 424 cfg |= EXYNOS_MSCTRL_ORDER422_CRYCBY; 425 break; 426 case DRM_FORMAT_NV21: 427 case DRM_FORMAT_NV61: 428 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB | 429 EXYNOS_MSCTRL_C_INT_IN_2PLANE); 430 break; 431 case DRM_FORMAT_YUV422: 432 case DRM_FORMAT_YUV420: 433 case DRM_FORMAT_YVU420: 434 cfg |= EXYNOS_MSCTRL_C_INT_IN_3PLANE; 435 break; 436 case DRM_FORMAT_NV12: 437 case DRM_FORMAT_NV16: 438 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR | 439 EXYNOS_MSCTRL_C_INT_IN_2PLANE); 440 break; 441 default: 442 dev_err(ippdrv->dev, "invalid source yuv order 0x%x.\n", fmt); 443 return -EINVAL; 444 } 445 446 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 447 448 return 0; 449 } 450 451 static int fimc_src_set_fmt(struct device *dev, u32 fmt) 452 { 453 struct fimc_context *ctx = get_fimc_context(dev); 454 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 455 u32 cfg; 456 457 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 458 459 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 460 cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB; 461 462 switch (fmt) { 463 case DRM_FORMAT_RGB565: 464 case DRM_FORMAT_RGB888: 465 case DRM_FORMAT_XRGB8888: 466 cfg |= EXYNOS_MSCTRL_INFORMAT_RGB; 467 break; 468 case DRM_FORMAT_YUV444: 469 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420; 470 break; 471 case DRM_FORMAT_YUYV: 472 case DRM_FORMAT_YVYU: 473 case DRM_FORMAT_UYVY: 474 case DRM_FORMAT_VYUY: 475 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE; 476 break; 477 case DRM_FORMAT_NV16: 478 case DRM_FORMAT_NV61: 479 case DRM_FORMAT_YUV422: 480 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422; 481 break; 482 case DRM_FORMAT_YUV420: 483 case DRM_FORMAT_YVU420: 484 case DRM_FORMAT_NV12: 485 case DRM_FORMAT_NV21: 486 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420; 487 break; 488 default: 489 dev_err(ippdrv->dev, "invalid source format 0x%x.\n", fmt); 490 return -EINVAL; 491 } 492 493 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 494 495 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 496 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK; 497 498 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR; 499 500 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 501 502 return fimc_src_set_fmt_order(ctx, fmt); 503 } 504 505 static int fimc_src_set_transf(struct device *dev, 506 enum drm_exynos_degree degree, 507 enum drm_exynos_flip flip, bool *swap) 508 { 509 struct fimc_context *ctx = get_fimc_context(dev); 510 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 511 u32 cfg1, cfg2; 512 513 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 514 515 cfg1 = fimc_read(ctx, EXYNOS_MSCTRL); 516 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR | 517 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 518 519 cfg2 = fimc_read(ctx, EXYNOS_CITRGFMT); 520 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 521 522 switch (degree) { 523 case EXYNOS_DRM_DEGREE_0: 524 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 525 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 526 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 527 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 528 break; 529 case EXYNOS_DRM_DEGREE_90: 530 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 531 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 532 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 533 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 534 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 535 break; 536 case EXYNOS_DRM_DEGREE_180: 537 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 538 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 539 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 540 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 541 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 542 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 543 break; 544 case EXYNOS_DRM_DEGREE_270: 545 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 546 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 547 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 548 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 549 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 550 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 551 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 552 break; 553 default: 554 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree); 555 return -EINVAL; 556 } 557 558 fimc_write(ctx, cfg1, EXYNOS_MSCTRL); 559 fimc_write(ctx, cfg2, EXYNOS_CITRGFMT); 560 *swap = (cfg2 & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) ? 1 : 0; 561 562 return 0; 563 } 564 565 static int fimc_set_window(struct fimc_context *ctx, 566 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 567 { 568 u32 cfg, h1, h2, v1, v2; 569 570 /* cropped image */ 571 h1 = pos->x; 572 h2 = sz->hsize - pos->w - pos->x; 573 v1 = pos->y; 574 v2 = sz->vsize - pos->h - pos->y; 575 576 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", 577 pos->x, pos->y, pos->w, pos->h, sz->hsize, sz->vsize); 578 DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2); 579 580 /* 581 * set window offset 1, 2 size 582 * check figure 43-21 in user manual 583 */ 584 cfg = fimc_read(ctx, EXYNOS_CIWDOFST); 585 cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK | 586 EXYNOS_CIWDOFST_WINVEROFST_MASK); 587 cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) | 588 EXYNOS_CIWDOFST_WINVEROFST(v1)); 589 cfg |= EXYNOS_CIWDOFST_WINOFSEN; 590 fimc_write(ctx, cfg, EXYNOS_CIWDOFST); 591 592 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) | 593 EXYNOS_CIWDOFST2_WINVEROFST2(v2)); 594 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2); 595 596 return 0; 597 } 598 599 static int fimc_src_set_size(struct device *dev, int swap, 600 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 601 { 602 struct fimc_context *ctx = get_fimc_context(dev); 603 struct drm_exynos_pos img_pos = *pos; 604 struct drm_exynos_sz img_sz = *sz; 605 u32 cfg; 606 607 DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n", 608 swap, sz->hsize, sz->vsize); 609 610 /* original size */ 611 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(img_sz.hsize) | 612 EXYNOS_ORGISIZE_VERTICAL(img_sz.vsize)); 613 614 fimc_write(ctx, cfg, EXYNOS_ORGISIZE); 615 616 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 617 618 if (swap) { 619 img_pos.w = pos->h; 620 img_pos.h = pos->w; 621 img_sz.hsize = sz->vsize; 622 img_sz.vsize = sz->hsize; 623 } 624 625 /* set input DMA image size */ 626 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE); 627 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK | 628 EXYNOS_CIREAL_ISIZE_WIDTH_MASK); 629 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(img_pos.w) | 630 EXYNOS_CIREAL_ISIZE_HEIGHT(img_pos.h)); 631 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE); 632 633 /* 634 * set input FIFO image size 635 * for now, we support only ITU601 8 bit mode 636 */ 637 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT | 638 EXYNOS_CISRCFMT_SOURCEHSIZE(img_sz.hsize) | 639 EXYNOS_CISRCFMT_SOURCEVSIZE(img_sz.vsize)); 640 fimc_write(ctx, cfg, EXYNOS_CISRCFMT); 641 642 /* offset Y(RGB), Cb, Cr */ 643 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(img_pos.x) | 644 EXYNOS_CIIYOFF_VERTICAL(img_pos.y)); 645 fimc_write(ctx, cfg, EXYNOS_CIIYOFF); 646 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(img_pos.x) | 647 EXYNOS_CIICBOFF_VERTICAL(img_pos.y)); 648 fimc_write(ctx, cfg, EXYNOS_CIICBOFF); 649 cfg = (EXYNOS_CIICROFF_HORIZONTAL(img_pos.x) | 650 EXYNOS_CIICROFF_VERTICAL(img_pos.y)); 651 fimc_write(ctx, cfg, EXYNOS_CIICROFF); 652 653 return fimc_set_window(ctx, &img_pos, &img_sz); 654 } 655 656 static int fimc_src_set_addr(struct device *dev, 657 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 658 enum drm_exynos_ipp_buf_type buf_type) 659 { 660 struct fimc_context *ctx = get_fimc_context(dev); 661 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 662 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 663 struct drm_exynos_ipp_property *property; 664 struct drm_exynos_ipp_config *config; 665 666 if (!c_node) { 667 DRM_ERROR("failed to get c_node.\n"); 668 return -EINVAL; 669 } 670 671 property = &c_node->property; 672 673 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n", 674 property->prop_id, buf_id, buf_type); 675 676 if (buf_id > FIMC_MAX_SRC) { 677 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id); 678 return -ENOMEM; 679 } 680 681 /* address register set */ 682 switch (buf_type) { 683 case IPP_BUF_ENQUEUE: 684 config = &property->config[EXYNOS_DRM_OPS_SRC]; 685 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y], 686 EXYNOS_CIIYSA0); 687 688 if (config->fmt == DRM_FORMAT_YVU420) { 689 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], 690 EXYNOS_CIICBSA0); 691 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], 692 EXYNOS_CIICRSA0); 693 } else { 694 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], 695 EXYNOS_CIICBSA0); 696 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], 697 EXYNOS_CIICRSA0); 698 } 699 break; 700 case IPP_BUF_DEQUEUE: 701 fimc_write(ctx, 0x0, EXYNOS_CIIYSA0); 702 fimc_write(ctx, 0x0, EXYNOS_CIICBSA0); 703 fimc_write(ctx, 0x0, EXYNOS_CIICRSA0); 704 break; 705 default: 706 /* bypass */ 707 break; 708 } 709 710 return 0; 711 } 712 713 static struct exynos_drm_ipp_ops fimc_src_ops = { 714 .set_fmt = fimc_src_set_fmt, 715 .set_transf = fimc_src_set_transf, 716 .set_size = fimc_src_set_size, 717 .set_addr = fimc_src_set_addr, 718 }; 719 720 static int fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt) 721 { 722 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 723 u32 cfg; 724 725 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 726 727 /* RGB */ 728 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 729 cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK; 730 731 switch (fmt) { 732 case DRM_FORMAT_RGB565: 733 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565; 734 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 735 return 0; 736 case DRM_FORMAT_RGB888: 737 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888; 738 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 739 return 0; 740 case DRM_FORMAT_XRGB8888: 741 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 | 742 EXYNOS_CISCCTRL_EXTRGB_EXTENSION); 743 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 744 break; 745 default: 746 /* bypass */ 747 break; 748 } 749 750 /* YUV */ 751 cfg = fimc_read(ctx, EXYNOS_CIOCTRL); 752 cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK | 753 EXYNOS_CIOCTRL_ORDER422_MASK | 754 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK); 755 756 switch (fmt) { 757 case DRM_FORMAT_XRGB8888: 758 cfg |= EXYNOS_CIOCTRL_ALPHA_OUT; 759 break; 760 case DRM_FORMAT_YUYV: 761 cfg |= EXYNOS_CIOCTRL_ORDER422_YCBYCR; 762 break; 763 case DRM_FORMAT_YVYU: 764 cfg |= EXYNOS_CIOCTRL_ORDER422_YCRYCB; 765 break; 766 case DRM_FORMAT_UYVY: 767 cfg |= EXYNOS_CIOCTRL_ORDER422_CBYCRY; 768 break; 769 case DRM_FORMAT_VYUY: 770 cfg |= EXYNOS_CIOCTRL_ORDER422_CRYCBY; 771 break; 772 case DRM_FORMAT_NV21: 773 case DRM_FORMAT_NV61: 774 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB; 775 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 776 break; 777 case DRM_FORMAT_YUV422: 778 case DRM_FORMAT_YUV420: 779 case DRM_FORMAT_YVU420: 780 cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE; 781 break; 782 case DRM_FORMAT_NV12: 783 case DRM_FORMAT_NV16: 784 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR; 785 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 786 break; 787 default: 788 dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt); 789 return -EINVAL; 790 } 791 792 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 793 794 return 0; 795 } 796 797 static int fimc_dst_set_fmt(struct device *dev, u32 fmt) 798 { 799 struct fimc_context *ctx = get_fimc_context(dev); 800 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 801 u32 cfg; 802 803 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 804 805 cfg = fimc_read(ctx, EXYNOS_CIEXTEN); 806 807 if (fmt == DRM_FORMAT_AYUV) { 808 cfg |= EXYNOS_CIEXTEN_YUV444_OUT; 809 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 810 } else { 811 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT; 812 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 813 814 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 815 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK; 816 817 switch (fmt) { 818 case DRM_FORMAT_RGB565: 819 case DRM_FORMAT_RGB888: 820 case DRM_FORMAT_XRGB8888: 821 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB; 822 break; 823 case DRM_FORMAT_YUYV: 824 case DRM_FORMAT_YVYU: 825 case DRM_FORMAT_UYVY: 826 case DRM_FORMAT_VYUY: 827 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE; 828 break; 829 case DRM_FORMAT_NV16: 830 case DRM_FORMAT_NV61: 831 case DRM_FORMAT_YUV422: 832 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422; 833 break; 834 case DRM_FORMAT_YUV420: 835 case DRM_FORMAT_YVU420: 836 case DRM_FORMAT_NV12: 837 case DRM_FORMAT_NV21: 838 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420; 839 break; 840 default: 841 dev_err(ippdrv->dev, "invalid target format 0x%x.\n", 842 fmt); 843 return -EINVAL; 844 } 845 846 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 847 } 848 849 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 850 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK; 851 852 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR; 853 854 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 855 856 return fimc_dst_set_fmt_order(ctx, fmt); 857 } 858 859 static int fimc_dst_set_transf(struct device *dev, 860 enum drm_exynos_degree degree, 861 enum drm_exynos_flip flip, bool *swap) 862 { 863 struct fimc_context *ctx = get_fimc_context(dev); 864 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 865 u32 cfg; 866 867 DRM_DEBUG_KMS("degree[%d]flip[0x%x]\n", degree, flip); 868 869 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 870 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; 871 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 872 873 switch (degree) { 874 case EXYNOS_DRM_DEGREE_0: 875 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 876 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 877 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 878 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 879 break; 880 case EXYNOS_DRM_DEGREE_90: 881 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 882 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 883 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 884 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 885 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 886 break; 887 case EXYNOS_DRM_DEGREE_180: 888 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR | 889 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 890 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 891 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 892 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 893 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 894 break; 895 case EXYNOS_DRM_DEGREE_270: 896 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE | 897 EXYNOS_CITRGFMT_FLIP_X_MIRROR | 898 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 899 if (flip & EXYNOS_DRM_FLIP_VERTICAL) 900 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 901 if (flip & EXYNOS_DRM_FLIP_HORIZONTAL) 902 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 903 break; 904 default: 905 dev_err(ippdrv->dev, "invalid degree value %d.\n", degree); 906 return -EINVAL; 907 } 908 909 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 910 *swap = (cfg & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) ? 1 : 0; 911 912 return 0; 913 } 914 915 static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 916 struct drm_exynos_pos *src, struct drm_exynos_pos *dst) 917 { 918 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 919 u32 cfg, cfg_ext, shfactor; 920 u32 pre_dst_width, pre_dst_height; 921 u32 hfactor, vfactor; 922 int ret = 0; 923 u32 src_w, src_h, dst_w, dst_h; 924 925 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT); 926 if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) { 927 src_w = src->h; 928 src_h = src->w; 929 } else { 930 src_w = src->w; 931 src_h = src->h; 932 } 933 934 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) { 935 dst_w = dst->h; 936 dst_h = dst->w; 937 } else { 938 dst_w = dst->w; 939 dst_h = dst->h; 940 } 941 942 /* fimc_ippdrv_check_property assures that dividers are not null */ 943 hfactor = fls(src_w / dst_w / 2); 944 if (hfactor > FIMC_SHFACTOR / 2) { 945 dev_err(ippdrv->dev, "failed to get ratio horizontal.\n"); 946 return -EINVAL; 947 } 948 949 vfactor = fls(src_h / dst_h / 2); 950 if (vfactor > FIMC_SHFACTOR / 2) { 951 dev_err(ippdrv->dev, "failed to get ratio vertical.\n"); 952 return -EINVAL; 953 } 954 955 pre_dst_width = src_w >> hfactor; 956 pre_dst_height = src_h >> vfactor; 957 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n", 958 pre_dst_width, pre_dst_height); 959 DRM_DEBUG_KMS("hfactor[%d]vfactor[%d]\n", hfactor, vfactor); 960 961 sc->hratio = (src_w << 14) / (dst_w << hfactor); 962 sc->vratio = (src_h << 14) / (dst_h << vfactor); 963 sc->up_h = (dst_w >= src_w) ? true : false; 964 sc->up_v = (dst_h >= src_h) ? true : false; 965 DRM_DEBUG_KMS("hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", 966 sc->hratio, sc->vratio, sc->up_h, sc->up_v); 967 968 shfactor = FIMC_SHFACTOR - (hfactor + vfactor); 969 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor); 970 971 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | 972 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) | 973 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor)); 974 fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO); 975 976 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) | 977 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height)); 978 fimc_write(ctx, cfg, EXYNOS_CISCPREDST); 979 980 return ret; 981 } 982 983 static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc) 984 { 985 u32 cfg, cfg_ext; 986 987 DRM_DEBUG_KMS("range[%d]bypass[%d]up_h[%d]up_v[%d]\n", 988 sc->range, sc->bypass, sc->up_h, sc->up_v); 989 DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n", 990 sc->hratio, sc->vratio); 991 992 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 993 cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS | 994 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V | 995 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK | 996 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK | 997 EXYNOS_CISCCTRL_CSCR2Y_WIDE | 998 EXYNOS_CISCCTRL_CSCY2R_WIDE); 999 1000 if (sc->range) 1001 cfg |= (EXYNOS_CISCCTRL_CSCR2Y_WIDE | 1002 EXYNOS_CISCCTRL_CSCY2R_WIDE); 1003 if (sc->bypass) 1004 cfg |= EXYNOS_CISCCTRL_SCALERBYPASS; 1005 if (sc->up_h) 1006 cfg |= EXYNOS_CISCCTRL_SCALEUP_H; 1007 if (sc->up_v) 1008 cfg |= EXYNOS_CISCCTRL_SCALEUP_V; 1009 1010 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) | 1011 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6))); 1012 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 1013 1014 cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN); 1015 cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK; 1016 cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK; 1017 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) | 1018 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio)); 1019 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN); 1020 } 1021 1022 static int fimc_dst_set_size(struct device *dev, int swap, 1023 struct drm_exynos_pos *pos, struct drm_exynos_sz *sz) 1024 { 1025 struct fimc_context *ctx = get_fimc_context(dev); 1026 struct drm_exynos_pos img_pos = *pos; 1027 struct drm_exynos_sz img_sz = *sz; 1028 u32 cfg; 1029 1030 DRM_DEBUG_KMS("swap[%d]hsize[%d]vsize[%d]\n", 1031 swap, sz->hsize, sz->vsize); 1032 1033 /* original size */ 1034 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(img_sz.hsize) | 1035 EXYNOS_ORGOSIZE_VERTICAL(img_sz.vsize)); 1036 1037 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE); 1038 1039 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", pos->x, pos->y, pos->w, pos->h); 1040 1041 /* CSC ITU */ 1042 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 1043 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK; 1044 1045 if (sz->hsize >= FIMC_WIDTH_ITU_709) 1046 cfg |= EXYNOS_CIGCTRL_CSC_ITU709; 1047 else 1048 cfg |= EXYNOS_CIGCTRL_CSC_ITU601; 1049 1050 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 1051 1052 if (swap) { 1053 img_pos.w = pos->h; 1054 img_pos.h = pos->w; 1055 img_sz.hsize = sz->vsize; 1056 img_sz.vsize = sz->hsize; 1057 } 1058 1059 /* target image size */ 1060 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 1061 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK | 1062 EXYNOS_CITRGFMT_TARGETV_MASK); 1063 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(img_pos.w) | 1064 EXYNOS_CITRGFMT_TARGETVSIZE(img_pos.h)); 1065 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 1066 1067 /* target area */ 1068 cfg = EXYNOS_CITAREA_TARGET_AREA(img_pos.w * img_pos.h); 1069 fimc_write(ctx, cfg, EXYNOS_CITAREA); 1070 1071 /* offset Y(RGB), Cb, Cr */ 1072 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(img_pos.x) | 1073 EXYNOS_CIOYOFF_VERTICAL(img_pos.y)); 1074 fimc_write(ctx, cfg, EXYNOS_CIOYOFF); 1075 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(img_pos.x) | 1076 EXYNOS_CIOCBOFF_VERTICAL(img_pos.y)); 1077 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF); 1078 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(img_pos.x) | 1079 EXYNOS_CIOCROFF_VERTICAL(img_pos.y)); 1080 fimc_write(ctx, cfg, EXYNOS_CIOCROFF); 1081 1082 return 0; 1083 } 1084 1085 static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, 1086 enum drm_exynos_ipp_buf_type buf_type) 1087 { 1088 unsigned long flags; 1089 u32 buf_num; 1090 u32 cfg; 1091 1092 DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type); 1093 1094 spin_lock_irqsave(&ctx->lock, flags); 1095 1096 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ); 1097 1098 if (buf_type == IPP_BUF_ENQUEUE) 1099 cfg |= (1 << buf_id); 1100 else 1101 cfg &= ~(1 << buf_id); 1102 1103 fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ); 1104 1105 buf_num = hweight32(cfg); 1106 1107 if (buf_type == IPP_BUF_ENQUEUE && buf_num >= FIMC_BUF_START) 1108 fimc_mask_irq(ctx, true); 1109 else if (buf_type == IPP_BUF_DEQUEUE && buf_num <= FIMC_BUF_STOP) 1110 fimc_mask_irq(ctx, false); 1111 1112 spin_unlock_irqrestore(&ctx->lock, flags); 1113 } 1114 1115 static int fimc_dst_set_addr(struct device *dev, 1116 struct drm_exynos_ipp_buf_info *buf_info, u32 buf_id, 1117 enum drm_exynos_ipp_buf_type buf_type) 1118 { 1119 struct fimc_context *ctx = get_fimc_context(dev); 1120 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1121 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 1122 struct drm_exynos_ipp_property *property; 1123 struct drm_exynos_ipp_config *config; 1124 1125 if (!c_node) { 1126 DRM_ERROR("failed to get c_node.\n"); 1127 return -EINVAL; 1128 } 1129 1130 property = &c_node->property; 1131 1132 DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]buf_type[%d]\n", 1133 property->prop_id, buf_id, buf_type); 1134 1135 if (buf_id > FIMC_MAX_DST) { 1136 dev_info(ippdrv->dev, "invalid buf_id %d.\n", buf_id); 1137 return -ENOMEM; 1138 } 1139 1140 /* address register set */ 1141 switch (buf_type) { 1142 case IPP_BUF_ENQUEUE: 1143 config = &property->config[EXYNOS_DRM_OPS_DST]; 1144 1145 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y], 1146 EXYNOS_CIOYSA(buf_id)); 1147 1148 if (config->fmt == DRM_FORMAT_YVU420) { 1149 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], 1150 EXYNOS_CIOCBSA(buf_id)); 1151 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], 1152 EXYNOS_CIOCRSA(buf_id)); 1153 } else { 1154 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], 1155 EXYNOS_CIOCBSA(buf_id)); 1156 fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], 1157 EXYNOS_CIOCRSA(buf_id)); 1158 } 1159 break; 1160 case IPP_BUF_DEQUEUE: 1161 fimc_write(ctx, 0x0, EXYNOS_CIOYSA(buf_id)); 1162 fimc_write(ctx, 0x0, EXYNOS_CIOCBSA(buf_id)); 1163 fimc_write(ctx, 0x0, EXYNOS_CIOCRSA(buf_id)); 1164 break; 1165 default: 1166 /* bypass */ 1167 break; 1168 } 1169 1170 fimc_dst_set_buf_seq(ctx, buf_id, buf_type); 1171 1172 return 0; 1173 } 1174 1175 static struct exynos_drm_ipp_ops fimc_dst_ops = { 1176 .set_fmt = fimc_dst_set_fmt, 1177 .set_transf = fimc_dst_set_transf, 1178 .set_size = fimc_dst_set_size, 1179 .set_addr = fimc_dst_set_addr, 1180 }; 1181 1182 static irqreturn_t fimc_irq_handler(int irq, void *dev_id) 1183 { 1184 struct fimc_context *ctx = dev_id; 1185 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1186 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 1187 struct drm_exynos_ipp_event_work *event_work = 1188 c_node->event_work; 1189 int buf_id; 1190 1191 DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id); 1192 1193 fimc_clear_irq(ctx); 1194 if (fimc_check_ovf(ctx)) 1195 return IRQ_NONE; 1196 1197 if (!fimc_check_frame_end(ctx)) 1198 return IRQ_NONE; 1199 1200 buf_id = fimc_get_buf_id(ctx); 1201 if (buf_id < 0) 1202 return IRQ_HANDLED; 1203 1204 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); 1205 1206 fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE); 1207 1208 event_work->ippdrv = ippdrv; 1209 event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id; 1210 queue_work(ippdrv->event_workq, &event_work->work); 1211 1212 return IRQ_HANDLED; 1213 } 1214 1215 static int fimc_init_prop_list(struct exynos_drm_ippdrv *ippdrv) 1216 { 1217 struct drm_exynos_ipp_prop_list *prop_list = &ippdrv->prop_list; 1218 1219 prop_list->version = 1; 1220 prop_list->writeback = 1; 1221 prop_list->refresh_min = FIMC_REFRESH_MIN; 1222 prop_list->refresh_max = FIMC_REFRESH_MAX; 1223 prop_list->flip = (1 << EXYNOS_DRM_FLIP_NONE) | 1224 (1 << EXYNOS_DRM_FLIP_VERTICAL) | 1225 (1 << EXYNOS_DRM_FLIP_HORIZONTAL); 1226 prop_list->degree = (1 << EXYNOS_DRM_DEGREE_0) | 1227 (1 << EXYNOS_DRM_DEGREE_90) | 1228 (1 << EXYNOS_DRM_DEGREE_180) | 1229 (1 << EXYNOS_DRM_DEGREE_270); 1230 prop_list->csc = 1; 1231 prop_list->crop = 1; 1232 prop_list->crop_max.hsize = FIMC_CROP_MAX; 1233 prop_list->crop_max.vsize = FIMC_CROP_MAX; 1234 prop_list->crop_min.hsize = FIMC_CROP_MIN; 1235 prop_list->crop_min.vsize = FIMC_CROP_MIN; 1236 prop_list->scale = 1; 1237 prop_list->scale_max.hsize = FIMC_SCALE_MAX; 1238 prop_list->scale_max.vsize = FIMC_SCALE_MAX; 1239 prop_list->scale_min.hsize = FIMC_SCALE_MIN; 1240 prop_list->scale_min.vsize = FIMC_SCALE_MIN; 1241 1242 return 0; 1243 } 1244 1245 static inline bool fimc_check_drm_flip(enum drm_exynos_flip flip) 1246 { 1247 switch (flip) { 1248 case EXYNOS_DRM_FLIP_NONE: 1249 case EXYNOS_DRM_FLIP_VERTICAL: 1250 case EXYNOS_DRM_FLIP_HORIZONTAL: 1251 case EXYNOS_DRM_FLIP_BOTH: 1252 return true; 1253 default: 1254 DRM_DEBUG_KMS("invalid flip\n"); 1255 return false; 1256 } 1257 } 1258 1259 static int fimc_ippdrv_check_property(struct device *dev, 1260 struct drm_exynos_ipp_property *property) 1261 { 1262 struct fimc_context *ctx = get_fimc_context(dev); 1263 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1264 struct drm_exynos_ipp_prop_list *pp = &ippdrv->prop_list; 1265 struct drm_exynos_ipp_config *config; 1266 struct drm_exynos_pos *pos; 1267 struct drm_exynos_sz *sz; 1268 bool swap; 1269 int i; 1270 1271 for_each_ipp_ops(i) { 1272 if ((i == EXYNOS_DRM_OPS_SRC) && 1273 (property->cmd == IPP_CMD_WB)) 1274 continue; 1275 1276 config = &property->config[i]; 1277 pos = &config->pos; 1278 sz = &config->sz; 1279 1280 /* check for flip */ 1281 if (!fimc_check_drm_flip(config->flip)) { 1282 DRM_ERROR("invalid flip.\n"); 1283 goto err_property; 1284 } 1285 1286 /* check for degree */ 1287 switch (config->degree) { 1288 case EXYNOS_DRM_DEGREE_90: 1289 case EXYNOS_DRM_DEGREE_270: 1290 swap = true; 1291 break; 1292 case EXYNOS_DRM_DEGREE_0: 1293 case EXYNOS_DRM_DEGREE_180: 1294 swap = false; 1295 break; 1296 default: 1297 DRM_ERROR("invalid degree.\n"); 1298 goto err_property; 1299 } 1300 1301 /* check for buffer bound */ 1302 if ((pos->x + pos->w > sz->hsize) || 1303 (pos->y + pos->h > sz->vsize)) { 1304 DRM_ERROR("out of buf bound.\n"); 1305 goto err_property; 1306 } 1307 1308 /* check for crop */ 1309 if ((i == EXYNOS_DRM_OPS_SRC) && (pp->crop)) { 1310 if (swap) { 1311 if ((pos->h < pp->crop_min.hsize) || 1312 (sz->vsize > pp->crop_max.hsize) || 1313 (pos->w < pp->crop_min.vsize) || 1314 (sz->hsize > pp->crop_max.vsize)) { 1315 DRM_ERROR("out of crop size.\n"); 1316 goto err_property; 1317 } 1318 } else { 1319 if ((pos->w < pp->crop_min.hsize) || 1320 (sz->hsize > pp->crop_max.hsize) || 1321 (pos->h < pp->crop_min.vsize) || 1322 (sz->vsize > pp->crop_max.vsize)) { 1323 DRM_ERROR("out of crop size.\n"); 1324 goto err_property; 1325 } 1326 } 1327 } 1328 1329 /* check for scale */ 1330 if ((i == EXYNOS_DRM_OPS_DST) && (pp->scale)) { 1331 if (swap) { 1332 if ((pos->h < pp->scale_min.hsize) || 1333 (sz->vsize > pp->scale_max.hsize) || 1334 (pos->w < pp->scale_min.vsize) || 1335 (sz->hsize > pp->scale_max.vsize)) { 1336 DRM_ERROR("out of scale size.\n"); 1337 goto err_property; 1338 } 1339 } else { 1340 if ((pos->w < pp->scale_min.hsize) || 1341 (sz->hsize > pp->scale_max.hsize) || 1342 (pos->h < pp->scale_min.vsize) || 1343 (sz->vsize > pp->scale_max.vsize)) { 1344 DRM_ERROR("out of scale size.\n"); 1345 goto err_property; 1346 } 1347 } 1348 } 1349 } 1350 1351 return 0; 1352 1353 err_property: 1354 for_each_ipp_ops(i) { 1355 if ((i == EXYNOS_DRM_OPS_SRC) && 1356 (property->cmd == IPP_CMD_WB)) 1357 continue; 1358 1359 config = &property->config[i]; 1360 pos = &config->pos; 1361 sz = &config->sz; 1362 1363 DRM_ERROR("[%s]f[%d]r[%d]pos[%d %d %d %d]sz[%d %d]\n", 1364 i ? "dst" : "src", config->flip, config->degree, 1365 pos->x, pos->y, pos->w, pos->h, 1366 sz->hsize, sz->vsize); 1367 } 1368 1369 return -EINVAL; 1370 } 1371 1372 static void fimc_clear_addr(struct fimc_context *ctx) 1373 { 1374 int i; 1375 1376 for (i = 0; i < FIMC_MAX_SRC; i++) { 1377 fimc_write(ctx, 0, EXYNOS_CIIYSA(i)); 1378 fimc_write(ctx, 0, EXYNOS_CIICBSA(i)); 1379 fimc_write(ctx, 0, EXYNOS_CIICRSA(i)); 1380 } 1381 1382 for (i = 0; i < FIMC_MAX_DST; i++) { 1383 fimc_write(ctx, 0, EXYNOS_CIOYSA(i)); 1384 fimc_write(ctx, 0, EXYNOS_CIOCBSA(i)); 1385 fimc_write(ctx, 0, EXYNOS_CIOCRSA(i)); 1386 } 1387 } 1388 1389 static int fimc_ippdrv_reset(struct device *dev) 1390 { 1391 struct fimc_context *ctx = get_fimc_context(dev); 1392 1393 /* reset h/w block */ 1394 fimc_sw_reset(ctx); 1395 1396 /* reset scaler capability */ 1397 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); 1398 1399 fimc_clear_addr(ctx); 1400 1401 return 0; 1402 } 1403 1404 static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1405 { 1406 struct fimc_context *ctx = get_fimc_context(dev); 1407 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1408 struct drm_exynos_ipp_cmd_node *c_node = ippdrv->c_node; 1409 struct drm_exynos_ipp_property *property; 1410 struct drm_exynos_ipp_config *config; 1411 struct drm_exynos_pos img_pos[EXYNOS_DRM_OPS_MAX]; 1412 struct drm_exynos_ipp_set_wb set_wb; 1413 int ret, i; 1414 u32 cfg0, cfg1; 1415 1416 DRM_DEBUG_KMS("cmd[%d]\n", cmd); 1417 1418 if (!c_node) { 1419 DRM_ERROR("failed to get c_node.\n"); 1420 return -EINVAL; 1421 } 1422 1423 property = &c_node->property; 1424 1425 fimc_mask_irq(ctx, true); 1426 1427 for_each_ipp_ops(i) { 1428 config = &property->config[i]; 1429 img_pos[i] = config->pos; 1430 } 1431 1432 ret = fimc_set_prescaler(ctx, &ctx->sc, 1433 &img_pos[EXYNOS_DRM_OPS_SRC], 1434 &img_pos[EXYNOS_DRM_OPS_DST]); 1435 if (ret) { 1436 dev_err(dev, "failed to set prescaler.\n"); 1437 return ret; 1438 } 1439 1440 /* If set ture, we can save jpeg about screen */ 1441 fimc_handle_jpeg(ctx, false); 1442 fimc_set_scaler(ctx, &ctx->sc); 1443 1444 switch (cmd) { 1445 case IPP_CMD_M2M: 1446 fimc_set_type_ctrl(ctx, FIMC_WB_NONE); 1447 fimc_handle_lastend(ctx, false); 1448 1449 /* setup dma */ 1450 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL); 1451 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK; 1452 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY; 1453 fimc_write(ctx, cfg0, EXYNOS_MSCTRL); 1454 break; 1455 case IPP_CMD_WB: 1456 fimc_set_type_ctrl(ctx, FIMC_WB_A); 1457 fimc_handle_lastend(ctx, true); 1458 1459 /* setup FIMD */ 1460 ret = fimc_set_camblk_fimd0_wb(ctx); 1461 if (ret < 0) { 1462 dev_err(dev, "camblk setup failed.\n"); 1463 return ret; 1464 } 1465 1466 set_wb.enable = 1; 1467 set_wb.refresh = property->refresh_rate; 1468 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb); 1469 break; 1470 case IPP_CMD_OUTPUT: 1471 default: 1472 ret = -EINVAL; 1473 dev_err(dev, "invalid operations.\n"); 1474 return ret; 1475 } 1476 1477 /* Reset status */ 1478 fimc_write(ctx, 0x0, EXYNOS_CISTATUS); 1479 1480 cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT); 1481 cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1482 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1483 1484 /* Scaler */ 1485 cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL); 1486 cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK; 1487 cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE | 1488 EXYNOS_CISCCTRL_SCALERSTART); 1489 1490 fimc_write(ctx, cfg1, EXYNOS_CISCCTRL); 1491 1492 /* Enable image capture*/ 1493 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN; 1494 fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT); 1495 1496 /* Disable frame end irq */ 1497 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1498 1499 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK); 1500 1501 if (cmd == IPP_CMD_M2M) 1502 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); 1503 1504 return 0; 1505 } 1506 1507 static void fimc_ippdrv_stop(struct device *dev, enum drm_exynos_ipp_cmd cmd) 1508 { 1509 struct fimc_context *ctx = get_fimc_context(dev); 1510 struct drm_exynos_ipp_set_wb set_wb = {0, 0}; 1511 u32 cfg; 1512 1513 DRM_DEBUG_KMS("cmd[%d]\n", cmd); 1514 1515 switch (cmd) { 1516 case IPP_CMD_M2M: 1517 /* Source clear */ 1518 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 1519 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK; 1520 cfg &= ~EXYNOS_MSCTRL_ENVID; 1521 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 1522 break; 1523 case IPP_CMD_WB: 1524 exynos_drm_ippnb_send_event(IPP_SET_WRITEBACK, (void *)&set_wb); 1525 break; 1526 case IPP_CMD_OUTPUT: 1527 default: 1528 dev_err(dev, "invalid operations.\n"); 1529 break; 1530 } 1531 1532 fimc_mask_irq(ctx, false); 1533 1534 /* reset sequence */ 1535 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 1536 1537 /* Scaler disable */ 1538 fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART); 1539 1540 /* Disable image capture */ 1541 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT, 1542 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 1543 1544 /* Enable frame end irq */ 1545 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1546 } 1547 1548 static void fimc_put_clocks(struct fimc_context *ctx) 1549 { 1550 int i; 1551 1552 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1553 if (IS_ERR(ctx->clocks[i])) 1554 continue; 1555 clk_put(ctx->clocks[i]); 1556 ctx->clocks[i] = ERR_PTR(-EINVAL); 1557 } 1558 } 1559 1560 static int fimc_setup_clocks(struct fimc_context *ctx) 1561 { 1562 struct device *fimc_dev = ctx->ippdrv.dev; 1563 struct device *dev; 1564 int ret, i; 1565 1566 for (i = 0; i < FIMC_CLKS_MAX; i++) 1567 ctx->clocks[i] = ERR_PTR(-EINVAL); 1568 1569 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1570 if (i == FIMC_CLK_WB_A || i == FIMC_CLK_WB_B) 1571 dev = fimc_dev->parent; 1572 else 1573 dev = fimc_dev; 1574 1575 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]); 1576 if (IS_ERR(ctx->clocks[i])) { 1577 if (i >= FIMC_CLK_MUX) 1578 break; 1579 ret = PTR_ERR(ctx->clocks[i]); 1580 dev_err(fimc_dev, "failed to get clock: %s\n", 1581 fimc_clock_names[i]); 1582 goto e_clk_free; 1583 } 1584 } 1585 1586 /* Optional FIMC LCLK parent clock setting */ 1587 if (!IS_ERR(ctx->clocks[FIMC_CLK_PARENT])) { 1588 ret = clk_set_parent(ctx->clocks[FIMC_CLK_MUX], 1589 ctx->clocks[FIMC_CLK_PARENT]); 1590 if (ret < 0) { 1591 dev_err(fimc_dev, "failed to set parent.\n"); 1592 goto e_clk_free; 1593 } 1594 } 1595 1596 ret = clk_set_rate(ctx->clocks[FIMC_CLK_LCLK], ctx->clk_frequency); 1597 if (ret < 0) 1598 goto e_clk_free; 1599 1600 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]); 1601 if (!ret) 1602 return ret; 1603 e_clk_free: 1604 fimc_put_clocks(ctx); 1605 return ret; 1606 } 1607 1608 static int fimc_parse_dt(struct fimc_context *ctx) 1609 { 1610 struct device_node *node = ctx->ippdrv.dev->of_node; 1611 1612 /* Handle only devices that support the LCD Writeback data path */ 1613 if (!of_property_read_bool(node, "samsung,lcd-wb")) 1614 return -ENODEV; 1615 1616 if (of_property_read_u32(node, "clock-frequency", 1617 &ctx->clk_frequency)) 1618 ctx->clk_frequency = FIMC_DEFAULT_LCLK_FREQUENCY; 1619 1620 ctx->id = of_alias_get_id(node, "fimc"); 1621 1622 if (ctx->id < 0) { 1623 dev_err(ctx->ippdrv.dev, "failed to get node alias id.\n"); 1624 return -EINVAL; 1625 } 1626 1627 return 0; 1628 } 1629 1630 static int fimc_probe(struct platform_device *pdev) 1631 { 1632 struct device *dev = &pdev->dev; 1633 struct fimc_context *ctx; 1634 struct resource *res; 1635 struct exynos_drm_ippdrv *ippdrv; 1636 int ret; 1637 1638 if (!dev->of_node) { 1639 dev_err(dev, "device tree node not found.\n"); 1640 return -ENODEV; 1641 } 1642 1643 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1644 if (!ctx) 1645 return -ENOMEM; 1646 1647 ctx->ippdrv.dev = dev; 1648 1649 ret = fimc_parse_dt(ctx); 1650 if (ret < 0) 1651 return ret; 1652 1653 ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 1654 "samsung,sysreg"); 1655 if (IS_ERR(ctx->sysreg)) { 1656 dev_err(dev, "syscon regmap lookup failed.\n"); 1657 return PTR_ERR(ctx->sysreg); 1658 } 1659 1660 /* resource memory */ 1661 ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1662 ctx->regs = devm_ioremap_resource(dev, ctx->regs_res); 1663 if (IS_ERR(ctx->regs)) 1664 return PTR_ERR(ctx->regs); 1665 1666 /* resource irq */ 1667 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1668 if (!res) { 1669 dev_err(dev, "failed to request irq resource.\n"); 1670 return -ENOENT; 1671 } 1672 1673 ctx->irq = res->start; 1674 ret = devm_request_threaded_irq(dev, ctx->irq, NULL, fimc_irq_handler, 1675 IRQF_ONESHOT, "drm_fimc", ctx); 1676 if (ret < 0) { 1677 dev_err(dev, "failed to request irq.\n"); 1678 return ret; 1679 } 1680 1681 ret = fimc_setup_clocks(ctx); 1682 if (ret < 0) 1683 return ret; 1684 1685 ippdrv = &ctx->ippdrv; 1686 ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &fimc_src_ops; 1687 ippdrv->ops[EXYNOS_DRM_OPS_DST] = &fimc_dst_ops; 1688 ippdrv->check_property = fimc_ippdrv_check_property; 1689 ippdrv->reset = fimc_ippdrv_reset; 1690 ippdrv->start = fimc_ippdrv_start; 1691 ippdrv->stop = fimc_ippdrv_stop; 1692 ret = fimc_init_prop_list(ippdrv); 1693 if (ret < 0) { 1694 dev_err(dev, "failed to init property list.\n"); 1695 goto err_put_clk; 1696 } 1697 1698 DRM_DEBUG_KMS("id[%d]ippdrv[%p]\n", ctx->id, ippdrv); 1699 1700 spin_lock_init(&ctx->lock); 1701 platform_set_drvdata(pdev, ctx); 1702 1703 pm_runtime_enable(dev); 1704 1705 ret = exynos_drm_ippdrv_register(ippdrv); 1706 if (ret < 0) { 1707 dev_err(dev, "failed to register drm fimc device.\n"); 1708 goto err_pm_dis; 1709 } 1710 1711 dev_info(dev, "drm fimc registered successfully.\n"); 1712 1713 return 0; 1714 1715 err_pm_dis: 1716 pm_runtime_disable(dev); 1717 err_put_clk: 1718 fimc_put_clocks(ctx); 1719 1720 return ret; 1721 } 1722 1723 static int fimc_remove(struct platform_device *pdev) 1724 { 1725 struct device *dev = &pdev->dev; 1726 struct fimc_context *ctx = get_fimc_context(dev); 1727 struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; 1728 1729 exynos_drm_ippdrv_unregister(ippdrv); 1730 1731 fimc_put_clocks(ctx); 1732 pm_runtime_set_suspended(dev); 1733 pm_runtime_disable(dev); 1734 1735 return 0; 1736 } 1737 1738 #ifdef CONFIG_PM 1739 static int fimc_clk_ctrl(struct fimc_context *ctx, bool enable) 1740 { 1741 DRM_DEBUG_KMS("enable[%d]\n", enable); 1742 1743 if (enable) { 1744 clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]); 1745 clk_prepare_enable(ctx->clocks[FIMC_CLK_WB_A]); 1746 ctx->suspended = false; 1747 } else { 1748 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]); 1749 clk_disable_unprepare(ctx->clocks[FIMC_CLK_WB_A]); 1750 ctx->suspended = true; 1751 } 1752 1753 return 0; 1754 } 1755 1756 static int fimc_runtime_suspend(struct device *dev) 1757 { 1758 struct fimc_context *ctx = get_fimc_context(dev); 1759 1760 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1761 1762 return fimc_clk_ctrl(ctx, false); 1763 } 1764 1765 static int fimc_runtime_resume(struct device *dev) 1766 { 1767 struct fimc_context *ctx = get_fimc_context(dev); 1768 1769 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1770 1771 return fimc_clk_ctrl(ctx, true); 1772 } 1773 #endif 1774 1775 static const struct dev_pm_ops fimc_pm_ops = { 1776 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1777 pm_runtime_force_resume) 1778 SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL) 1779 }; 1780 1781 static const struct of_device_id fimc_of_match[] = { 1782 { .compatible = "samsung,exynos4210-fimc" }, 1783 { .compatible = "samsung,exynos4212-fimc" }, 1784 { }, 1785 }; 1786 MODULE_DEVICE_TABLE(of, fimc_of_match); 1787 1788 struct platform_driver fimc_driver = { 1789 .probe = fimc_probe, 1790 .remove = fimc_remove, 1791 .driver = { 1792 .of_match_table = fimc_of_match, 1793 .name = "exynos-drm-fimc", 1794 .owner = THIS_MODULE, 1795 .pm = &fimc_pm_ops, 1796 }, 1797 }; 1798 1799