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