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/component.h> 16 #include <linux/platform_device.h> 17 #include <linux/mfd/syscon.h> 18 #include <linux/regmap.h> 19 #include <linux/clk.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/of.h> 22 #include <linux/spinlock.h> 23 24 #include <drm/drmP.h> 25 #include <drm/exynos_drm.h> 26 #include "regs-fimc.h" 27 #include "exynos_drm_drv.h" 28 #include "exynos_drm_iommu.h" 29 #include "exynos_drm_ipp.h" 30 31 /* 32 * FIMC stands for Fully Interactive Mobile Camera and 33 * supports image scaler/rotator and input/output DMA operations. 34 * input DMA reads image data from the memory. 35 * output DMA writes image data to memory. 36 * FIMC supports image rotation and image effect functions. 37 */ 38 39 #define FIMC_MAX_DEVS 4 40 #define FIMC_MAX_SRC 2 41 #define FIMC_MAX_DST 32 42 #define FIMC_SHFACTOR 10 43 #define FIMC_BUF_STOP 1 44 #define FIMC_BUF_START 2 45 #define FIMC_WIDTH_ITU_709 1280 46 #define FIMC_AUTOSUSPEND_DELAY 2000 47 48 static unsigned int fimc_mask = 0xc; 49 module_param_named(fimc_devs, fimc_mask, uint, 0644); 50 MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM"); 51 52 #define get_fimc_context(dev) platform_get_drvdata(to_platform_device(dev)) 53 54 enum { 55 FIMC_CLK_LCLK, 56 FIMC_CLK_GATE, 57 FIMC_CLK_WB_A, 58 FIMC_CLK_WB_B, 59 FIMC_CLKS_MAX 60 }; 61 62 static const char * const fimc_clock_names[] = { 63 [FIMC_CLK_LCLK] = "sclk_fimc", 64 [FIMC_CLK_GATE] = "fimc", 65 [FIMC_CLK_WB_A] = "pxl_async0", 66 [FIMC_CLK_WB_B] = "pxl_async1", 67 }; 68 69 /* 70 * A structure of scaler. 71 * 72 * @range: narrow, wide. 73 * @bypass: unused scaler path. 74 * @up_h: horizontal scale up. 75 * @up_v: vertical scale up. 76 * @hratio: horizontal ratio. 77 * @vratio: vertical ratio. 78 */ 79 struct fimc_scaler { 80 bool range; 81 bool bypass; 82 bool up_h; 83 bool up_v; 84 u32 hratio; 85 u32 vratio; 86 }; 87 88 /* 89 * A structure of fimc context. 90 * 91 * @regs_res: register resources. 92 * @regs: memory mapped io registers. 93 * @lock: locking of operations. 94 * @clocks: fimc clocks. 95 * @sc: scaler infomations. 96 * @pol: porarity of writeback. 97 * @id: fimc id. 98 * @irq: irq number. 99 */ 100 struct fimc_context { 101 struct exynos_drm_ipp ipp; 102 struct drm_device *drm_dev; 103 struct device *dev; 104 struct exynos_drm_ipp_task *task; 105 struct exynos_drm_ipp_formats *formats; 106 unsigned int num_formats; 107 108 struct resource *regs_res; 109 void __iomem *regs; 110 spinlock_t lock; 111 struct clk *clocks[FIMC_CLKS_MAX]; 112 struct fimc_scaler sc; 113 int id; 114 int irq; 115 }; 116 117 static u32 fimc_read(struct fimc_context *ctx, u32 reg) 118 { 119 return readl(ctx->regs + reg); 120 } 121 122 static void fimc_write(struct fimc_context *ctx, u32 val, u32 reg) 123 { 124 writel(val, ctx->regs + reg); 125 } 126 127 static void fimc_set_bits(struct fimc_context *ctx, u32 reg, u32 bits) 128 { 129 void __iomem *r = ctx->regs + reg; 130 131 writel(readl(r) | bits, r); 132 } 133 134 static void fimc_clear_bits(struct fimc_context *ctx, u32 reg, u32 bits) 135 { 136 void __iomem *r = ctx->regs + reg; 137 138 writel(readl(r) & ~bits, r); 139 } 140 141 static void fimc_sw_reset(struct fimc_context *ctx) 142 { 143 u32 cfg; 144 145 /* stop dma operation */ 146 cfg = fimc_read(ctx, EXYNOS_CISTATUS); 147 if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg)) 148 fimc_clear_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); 149 150 fimc_set_bits(ctx, EXYNOS_CISRCFMT, EXYNOS_CISRCFMT_ITU601_8BIT); 151 152 /* disable image capture */ 153 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT, 154 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 155 156 /* s/w reset */ 157 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST); 158 159 /* s/w reset complete */ 160 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST); 161 162 /* reset sequence */ 163 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 164 } 165 166 static void fimc_set_type_ctrl(struct fimc_context *ctx) 167 { 168 u32 cfg; 169 170 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 171 cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK | 172 EXYNOS_CIGCTRL_SELCAM_ITU_MASK | 173 EXYNOS_CIGCTRL_SELCAM_MIPI_MASK | 174 EXYNOS_CIGCTRL_SELCAM_FIMC_MASK | 175 EXYNOS_CIGCTRL_SELWB_CAMIF_MASK | 176 EXYNOS_CIGCTRL_SELWRITEBACK_MASK); 177 178 cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A | 179 EXYNOS_CIGCTRL_SELWRITEBACK_A | 180 EXYNOS_CIGCTRL_SELCAM_MIPI_A | 181 EXYNOS_CIGCTRL_SELCAM_FIMC_ITU); 182 183 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 184 } 185 186 static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable) 187 { 188 u32 cfg; 189 190 DRM_DEBUG_KMS("enable[%d]\n", enable); 191 192 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 193 if (enable) 194 cfg |= EXYNOS_CIGCTRL_CAM_JPEG; 195 else 196 cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG; 197 198 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 199 } 200 201 static void fimc_mask_irq(struct fimc_context *ctx, bool enable) 202 { 203 u32 cfg; 204 205 DRM_DEBUG_KMS("enable[%d]\n", enable); 206 207 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 208 if (enable) { 209 cfg &= ~EXYNOS_CIGCTRL_IRQ_OVFEN; 210 cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE | EXYNOS_CIGCTRL_IRQ_LEVEL; 211 } else 212 cfg &= ~EXYNOS_CIGCTRL_IRQ_ENABLE; 213 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 214 } 215 216 static void fimc_clear_irq(struct fimc_context *ctx) 217 { 218 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_CLR); 219 } 220 221 static bool fimc_check_ovf(struct fimc_context *ctx) 222 { 223 u32 status, flag; 224 225 status = fimc_read(ctx, EXYNOS_CISTATUS); 226 flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB | 227 EXYNOS_CISTATUS_OVFICR; 228 229 DRM_DEBUG_KMS("flag[0x%x]\n", flag); 230 231 if (status & flag) { 232 fimc_set_bits(ctx, EXYNOS_CIWDOFST, 233 EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | 234 EXYNOS_CIWDOFST_CLROVFICR); 235 236 dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n", 237 ctx->id, status); 238 return true; 239 } 240 241 return false; 242 } 243 244 static bool fimc_check_frame_end(struct fimc_context *ctx) 245 { 246 u32 cfg; 247 248 cfg = fimc_read(ctx, EXYNOS_CISTATUS); 249 250 DRM_DEBUG_KMS("cfg[0x%x]\n", cfg); 251 252 if (!(cfg & EXYNOS_CISTATUS_FRAMEEND)) 253 return false; 254 255 cfg &= ~(EXYNOS_CISTATUS_FRAMEEND); 256 fimc_write(ctx, cfg, EXYNOS_CISTATUS); 257 258 return true; 259 } 260 261 static int fimc_get_buf_id(struct fimc_context *ctx) 262 { 263 u32 cfg; 264 int frame_cnt, buf_id; 265 266 cfg = fimc_read(ctx, EXYNOS_CISTATUS2); 267 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg); 268 269 if (frame_cnt == 0) 270 frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg); 271 272 DRM_DEBUG_KMS("present[%d]before[%d]\n", 273 EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg), 274 EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg)); 275 276 if (frame_cnt == 0) { 277 DRM_ERROR("failed to get frame count.\n"); 278 return -EIO; 279 } 280 281 buf_id = frame_cnt - 1; 282 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); 283 284 return buf_id; 285 } 286 287 static void fimc_handle_lastend(struct fimc_context *ctx, bool enable) 288 { 289 u32 cfg; 290 291 DRM_DEBUG_KMS("enable[%d]\n", enable); 292 293 cfg = fimc_read(ctx, EXYNOS_CIOCTRL); 294 if (enable) 295 cfg |= EXYNOS_CIOCTRL_LASTENDEN; 296 else 297 cfg &= ~EXYNOS_CIOCTRL_LASTENDEN; 298 299 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 300 } 301 302 static void fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt) 303 { 304 u32 cfg; 305 306 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 307 308 /* RGB */ 309 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 310 cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK; 311 312 switch (fmt) { 313 case DRM_FORMAT_RGB565: 314 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565; 315 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 316 return; 317 case DRM_FORMAT_RGB888: 318 case DRM_FORMAT_XRGB8888: 319 cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888; 320 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 321 return; 322 default: 323 /* bypass */ 324 break; 325 } 326 327 /* YUV */ 328 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 329 cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK | 330 EXYNOS_MSCTRL_C_INT_IN_2PLANE | 331 EXYNOS_MSCTRL_ORDER422_YCBYCR); 332 333 switch (fmt) { 334 case DRM_FORMAT_YUYV: 335 cfg |= EXYNOS_MSCTRL_ORDER422_YCBYCR; 336 break; 337 case DRM_FORMAT_YVYU: 338 cfg |= EXYNOS_MSCTRL_ORDER422_YCRYCB; 339 break; 340 case DRM_FORMAT_UYVY: 341 cfg |= EXYNOS_MSCTRL_ORDER422_CBYCRY; 342 break; 343 case DRM_FORMAT_VYUY: 344 case DRM_FORMAT_YUV444: 345 cfg |= EXYNOS_MSCTRL_ORDER422_CRYCBY; 346 break; 347 case DRM_FORMAT_NV21: 348 case DRM_FORMAT_NV61: 349 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB | 350 EXYNOS_MSCTRL_C_INT_IN_2PLANE); 351 break; 352 case DRM_FORMAT_YUV422: 353 case DRM_FORMAT_YUV420: 354 case DRM_FORMAT_YVU420: 355 cfg |= EXYNOS_MSCTRL_C_INT_IN_3PLANE; 356 break; 357 case DRM_FORMAT_NV12: 358 case DRM_FORMAT_NV16: 359 cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR | 360 EXYNOS_MSCTRL_C_INT_IN_2PLANE); 361 break; 362 } 363 364 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 365 } 366 367 static void fimc_src_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled) 368 { 369 u32 cfg; 370 371 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 372 373 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 374 cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB; 375 376 switch (fmt) { 377 case DRM_FORMAT_RGB565: 378 case DRM_FORMAT_RGB888: 379 case DRM_FORMAT_XRGB8888: 380 cfg |= EXYNOS_MSCTRL_INFORMAT_RGB; 381 break; 382 case DRM_FORMAT_YUV444: 383 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420; 384 break; 385 case DRM_FORMAT_YUYV: 386 case DRM_FORMAT_YVYU: 387 case DRM_FORMAT_UYVY: 388 case DRM_FORMAT_VYUY: 389 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE; 390 break; 391 case DRM_FORMAT_NV16: 392 case DRM_FORMAT_NV61: 393 case DRM_FORMAT_YUV422: 394 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422; 395 break; 396 case DRM_FORMAT_YUV420: 397 case DRM_FORMAT_YVU420: 398 case DRM_FORMAT_NV12: 399 case DRM_FORMAT_NV21: 400 cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420; 401 break; 402 } 403 404 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 405 406 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 407 cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK; 408 409 if (tiled) 410 cfg |= EXYNOS_CIDMAPARAM_R_MODE_64X32; 411 else 412 cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR; 413 414 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 415 416 fimc_src_set_fmt_order(ctx, fmt); 417 } 418 419 static void fimc_src_set_transf(struct fimc_context *ctx, unsigned int rotation) 420 { 421 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK; 422 u32 cfg1, cfg2; 423 424 DRM_DEBUG_KMS("rotation[%x]\n", rotation); 425 426 cfg1 = fimc_read(ctx, EXYNOS_MSCTRL); 427 cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR | 428 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 429 430 cfg2 = fimc_read(ctx, EXYNOS_CITRGFMT); 431 cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 432 433 switch (degree) { 434 case DRM_MODE_ROTATE_0: 435 if (rotation & DRM_MODE_REFLECT_X) 436 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 437 if (rotation & DRM_MODE_REFLECT_Y) 438 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 439 break; 440 case DRM_MODE_ROTATE_90: 441 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 442 if (rotation & DRM_MODE_REFLECT_X) 443 cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR; 444 if (rotation & DRM_MODE_REFLECT_Y) 445 cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR; 446 break; 447 case DRM_MODE_ROTATE_180: 448 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 449 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 450 if (rotation & DRM_MODE_REFLECT_X) 451 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 452 if (rotation & DRM_MODE_REFLECT_Y) 453 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 454 break; 455 case DRM_MODE_ROTATE_270: 456 cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR | 457 EXYNOS_MSCTRL_FLIP_Y_MIRROR); 458 cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE; 459 if (rotation & DRM_MODE_REFLECT_X) 460 cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR; 461 if (rotation & DRM_MODE_REFLECT_Y) 462 cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR; 463 break; 464 } 465 466 fimc_write(ctx, cfg1, EXYNOS_MSCTRL); 467 fimc_write(ctx, cfg2, EXYNOS_CITRGFMT); 468 } 469 470 static void fimc_set_window(struct fimc_context *ctx, 471 struct exynos_drm_ipp_buffer *buf) 472 { 473 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; 474 u32 cfg, h1, h2, v1, v2; 475 476 /* cropped image */ 477 h1 = buf->rect.x; 478 h2 = real_width - buf->rect.w - buf->rect.x; 479 v1 = buf->rect.y; 480 v2 = buf->buf.height - buf->rect.h - buf->rect.y; 481 482 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", 483 buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h, 484 real_width, buf->buf.height); 485 DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2); 486 487 /* 488 * set window offset 1, 2 size 489 * check figure 43-21 in user manual 490 */ 491 cfg = fimc_read(ctx, EXYNOS_CIWDOFST); 492 cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK | 493 EXYNOS_CIWDOFST_WINVEROFST_MASK); 494 cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) | 495 EXYNOS_CIWDOFST_WINVEROFST(v1)); 496 cfg |= EXYNOS_CIWDOFST_WINOFSEN; 497 fimc_write(ctx, cfg, EXYNOS_CIWDOFST); 498 499 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) | 500 EXYNOS_CIWDOFST2_WINVEROFST2(v2)); 501 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2); 502 } 503 504 static void fimc_src_set_size(struct fimc_context *ctx, 505 struct exynos_drm_ipp_buffer *buf) 506 { 507 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; 508 u32 cfg; 509 510 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", real_width, buf->buf.height); 511 512 /* original size */ 513 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(real_width) | 514 EXYNOS_ORGISIZE_VERTICAL(buf->buf.height)); 515 516 fimc_write(ctx, cfg, EXYNOS_ORGISIZE); 517 518 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y, 519 buf->rect.w, buf->rect.h); 520 521 /* set input DMA image size */ 522 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE); 523 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK | 524 EXYNOS_CIREAL_ISIZE_WIDTH_MASK); 525 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(buf->rect.w) | 526 EXYNOS_CIREAL_ISIZE_HEIGHT(buf->rect.h)); 527 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE); 528 529 /* 530 * set input FIFO image size 531 * for now, we support only ITU601 8 bit mode 532 */ 533 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT | 534 EXYNOS_CISRCFMT_SOURCEHSIZE(real_width) | 535 EXYNOS_CISRCFMT_SOURCEVSIZE(buf->buf.height)); 536 fimc_write(ctx, cfg, EXYNOS_CISRCFMT); 537 538 /* offset Y(RGB), Cb, Cr */ 539 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(buf->rect.x) | 540 EXYNOS_CIIYOFF_VERTICAL(buf->rect.y)); 541 fimc_write(ctx, cfg, EXYNOS_CIIYOFF); 542 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(buf->rect.x) | 543 EXYNOS_CIICBOFF_VERTICAL(buf->rect.y)); 544 fimc_write(ctx, cfg, EXYNOS_CIICBOFF); 545 cfg = (EXYNOS_CIICROFF_HORIZONTAL(buf->rect.x) | 546 EXYNOS_CIICROFF_VERTICAL(buf->rect.y)); 547 fimc_write(ctx, cfg, EXYNOS_CIICROFF); 548 549 fimc_set_window(ctx, buf); 550 } 551 552 static void fimc_src_set_addr(struct fimc_context *ctx, 553 struct exynos_drm_ipp_buffer *buf) 554 { 555 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIIYSA(0)); 556 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIICBSA(0)); 557 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIICRSA(0)); 558 } 559 560 static void fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt) 561 { 562 u32 cfg; 563 564 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 565 566 /* RGB */ 567 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 568 cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK; 569 570 switch (fmt) { 571 case DRM_FORMAT_RGB565: 572 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565; 573 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 574 return; 575 case DRM_FORMAT_RGB888: 576 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888; 577 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 578 return; 579 case DRM_FORMAT_XRGB8888: 580 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 | 581 EXYNOS_CISCCTRL_EXTRGB_EXTENSION); 582 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 583 break; 584 default: 585 /* bypass */ 586 break; 587 } 588 589 /* YUV */ 590 cfg = fimc_read(ctx, EXYNOS_CIOCTRL); 591 cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK | 592 EXYNOS_CIOCTRL_ORDER422_MASK | 593 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK); 594 595 switch (fmt) { 596 case DRM_FORMAT_XRGB8888: 597 cfg |= EXYNOS_CIOCTRL_ALPHA_OUT; 598 break; 599 case DRM_FORMAT_YUYV: 600 cfg |= EXYNOS_CIOCTRL_ORDER422_YCBYCR; 601 break; 602 case DRM_FORMAT_YVYU: 603 cfg |= EXYNOS_CIOCTRL_ORDER422_YCRYCB; 604 break; 605 case DRM_FORMAT_UYVY: 606 cfg |= EXYNOS_CIOCTRL_ORDER422_CBYCRY; 607 break; 608 case DRM_FORMAT_VYUY: 609 cfg |= EXYNOS_CIOCTRL_ORDER422_CRYCBY; 610 break; 611 case DRM_FORMAT_NV21: 612 case DRM_FORMAT_NV61: 613 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB; 614 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 615 break; 616 case DRM_FORMAT_YUV422: 617 case DRM_FORMAT_YUV420: 618 case DRM_FORMAT_YVU420: 619 cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE; 620 break; 621 case DRM_FORMAT_NV12: 622 case DRM_FORMAT_NV16: 623 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR; 624 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 625 break; 626 } 627 628 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 629 } 630 631 static void fimc_dst_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled) 632 { 633 u32 cfg; 634 635 DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); 636 637 cfg = fimc_read(ctx, EXYNOS_CIEXTEN); 638 639 if (fmt == DRM_FORMAT_AYUV) { 640 cfg |= EXYNOS_CIEXTEN_YUV444_OUT; 641 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 642 } else { 643 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT; 644 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 645 646 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 647 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK; 648 649 switch (fmt) { 650 case DRM_FORMAT_RGB565: 651 case DRM_FORMAT_RGB888: 652 case DRM_FORMAT_XRGB8888: 653 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB; 654 break; 655 case DRM_FORMAT_YUYV: 656 case DRM_FORMAT_YVYU: 657 case DRM_FORMAT_UYVY: 658 case DRM_FORMAT_VYUY: 659 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE; 660 break; 661 case DRM_FORMAT_NV16: 662 case DRM_FORMAT_NV61: 663 case DRM_FORMAT_YUV422: 664 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422; 665 break; 666 case DRM_FORMAT_YUV420: 667 case DRM_FORMAT_YVU420: 668 case DRM_FORMAT_NV12: 669 case DRM_FORMAT_NV21: 670 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420; 671 break; 672 } 673 674 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 675 } 676 677 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 678 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK; 679 680 if (tiled) 681 cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32; 682 else 683 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR; 684 685 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 686 687 fimc_dst_set_fmt_order(ctx, fmt); 688 } 689 690 static void fimc_dst_set_transf(struct fimc_context *ctx, unsigned int rotation) 691 { 692 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK; 693 u32 cfg; 694 695 DRM_DEBUG_KMS("rotation[0x%x]\n", rotation); 696 697 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 698 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; 699 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 700 701 switch (degree) { 702 case DRM_MODE_ROTATE_0: 703 if (rotation & DRM_MODE_REFLECT_X) 704 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 705 if (rotation & DRM_MODE_REFLECT_Y) 706 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 707 break; 708 case DRM_MODE_ROTATE_90: 709 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 710 if (rotation & DRM_MODE_REFLECT_X) 711 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 712 if (rotation & DRM_MODE_REFLECT_Y) 713 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 714 break; 715 case DRM_MODE_ROTATE_180: 716 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR | 717 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 718 if (rotation & DRM_MODE_REFLECT_X) 719 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 720 if (rotation & DRM_MODE_REFLECT_Y) 721 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 722 break; 723 case DRM_MODE_ROTATE_270: 724 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE | 725 EXYNOS_CITRGFMT_FLIP_X_MIRROR | 726 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 727 if (rotation & DRM_MODE_REFLECT_X) 728 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 729 if (rotation & DRM_MODE_REFLECT_Y) 730 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 731 break; 732 } 733 734 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 735 } 736 737 static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 738 struct drm_exynos_ipp_task_rect *src, 739 struct drm_exynos_ipp_task_rect *dst) 740 { 741 u32 cfg, cfg_ext, shfactor; 742 u32 pre_dst_width, pre_dst_height; 743 u32 hfactor, vfactor; 744 int ret = 0; 745 u32 src_w, src_h, dst_w, dst_h; 746 747 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT); 748 if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) { 749 src_w = src->h; 750 src_h = src->w; 751 } else { 752 src_w = src->w; 753 src_h = src->h; 754 } 755 756 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) { 757 dst_w = dst->h; 758 dst_h = dst->w; 759 } else { 760 dst_w = dst->w; 761 dst_h = dst->h; 762 } 763 764 /* fimc_ippdrv_check_property assures that dividers are not null */ 765 hfactor = fls(src_w / dst_w / 2); 766 if (hfactor > FIMC_SHFACTOR / 2) { 767 dev_err(ctx->dev, "failed to get ratio horizontal.\n"); 768 return -EINVAL; 769 } 770 771 vfactor = fls(src_h / dst_h / 2); 772 if (vfactor > FIMC_SHFACTOR / 2) { 773 dev_err(ctx->dev, "failed to get ratio vertical.\n"); 774 return -EINVAL; 775 } 776 777 pre_dst_width = src_w >> hfactor; 778 pre_dst_height = src_h >> vfactor; 779 DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n", 780 pre_dst_width, pre_dst_height); 781 DRM_DEBUG_KMS("hfactor[%d]vfactor[%d]\n", hfactor, vfactor); 782 783 sc->hratio = (src_w << 14) / (dst_w << hfactor); 784 sc->vratio = (src_h << 14) / (dst_h << vfactor); 785 sc->up_h = (dst_w >= src_w) ? true : false; 786 sc->up_v = (dst_h >= src_h) ? true : false; 787 DRM_DEBUG_KMS("hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", 788 sc->hratio, sc->vratio, sc->up_h, sc->up_v); 789 790 shfactor = FIMC_SHFACTOR - (hfactor + vfactor); 791 DRM_DEBUG_KMS("shfactor[%d]\n", shfactor); 792 793 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | 794 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) | 795 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor)); 796 fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO); 797 798 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) | 799 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height)); 800 fimc_write(ctx, cfg, EXYNOS_CISCPREDST); 801 802 return ret; 803 } 804 805 static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc) 806 { 807 u32 cfg, cfg_ext; 808 809 DRM_DEBUG_KMS("range[%d]bypass[%d]up_h[%d]up_v[%d]\n", 810 sc->range, sc->bypass, sc->up_h, sc->up_v); 811 DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n", 812 sc->hratio, sc->vratio); 813 814 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 815 cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS | 816 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V | 817 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK | 818 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK | 819 EXYNOS_CISCCTRL_CSCR2Y_WIDE | 820 EXYNOS_CISCCTRL_CSCY2R_WIDE); 821 822 if (sc->range) 823 cfg |= (EXYNOS_CISCCTRL_CSCR2Y_WIDE | 824 EXYNOS_CISCCTRL_CSCY2R_WIDE); 825 if (sc->bypass) 826 cfg |= EXYNOS_CISCCTRL_SCALERBYPASS; 827 if (sc->up_h) 828 cfg |= EXYNOS_CISCCTRL_SCALEUP_H; 829 if (sc->up_v) 830 cfg |= EXYNOS_CISCCTRL_SCALEUP_V; 831 832 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) | 833 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6))); 834 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 835 836 cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN); 837 cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK; 838 cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK; 839 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) | 840 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio)); 841 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN); 842 } 843 844 static void fimc_dst_set_size(struct fimc_context *ctx, 845 struct exynos_drm_ipp_buffer *buf) 846 { 847 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; 848 u32 cfg, cfg_ext; 849 850 DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", real_width, buf->buf.height); 851 852 /* original size */ 853 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(real_width) | 854 EXYNOS_ORGOSIZE_VERTICAL(buf->buf.height)); 855 856 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE); 857 858 DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y, 859 buf->rect.w, buf->rect.h); 860 861 /* CSC ITU */ 862 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 863 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK; 864 865 if (buf->buf.width >= FIMC_WIDTH_ITU_709) 866 cfg |= EXYNOS_CIGCTRL_CSC_ITU709; 867 else 868 cfg |= EXYNOS_CIGCTRL_CSC_ITU601; 869 870 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 871 872 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT); 873 874 /* target image size */ 875 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 876 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK | 877 EXYNOS_CITRGFMT_TARGETV_MASK); 878 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) 879 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.h) | 880 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.w)); 881 else 882 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.w) | 883 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.h)); 884 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 885 886 /* target area */ 887 cfg = EXYNOS_CITAREA_TARGET_AREA(buf->rect.w * buf->rect.h); 888 fimc_write(ctx, cfg, EXYNOS_CITAREA); 889 890 /* offset Y(RGB), Cb, Cr */ 891 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(buf->rect.x) | 892 EXYNOS_CIOYOFF_VERTICAL(buf->rect.y)); 893 fimc_write(ctx, cfg, EXYNOS_CIOYOFF); 894 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(buf->rect.x) | 895 EXYNOS_CIOCBOFF_VERTICAL(buf->rect.y)); 896 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF); 897 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(buf->rect.x) | 898 EXYNOS_CIOCROFF_VERTICAL(buf->rect.y)); 899 fimc_write(ctx, cfg, EXYNOS_CIOCROFF); 900 } 901 902 static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, 903 bool enqueue) 904 { 905 unsigned long flags; 906 u32 buf_num; 907 u32 cfg; 908 909 DRM_DEBUG_KMS("buf_id[%d]enqueu[%d]\n", buf_id, enqueue); 910 911 spin_lock_irqsave(&ctx->lock, flags); 912 913 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ); 914 915 if (enqueue) 916 cfg |= (1 << buf_id); 917 else 918 cfg &= ~(1 << buf_id); 919 920 fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ); 921 922 buf_num = hweight32(cfg); 923 924 if (enqueue && buf_num >= FIMC_BUF_START) 925 fimc_mask_irq(ctx, true); 926 else if (!enqueue && buf_num <= FIMC_BUF_STOP) 927 fimc_mask_irq(ctx, false); 928 929 spin_unlock_irqrestore(&ctx->lock, flags); 930 } 931 932 static void fimc_dst_set_addr(struct fimc_context *ctx, 933 struct exynos_drm_ipp_buffer *buf) 934 { 935 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIOYSA(0)); 936 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIOCBSA(0)); 937 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIOCRSA(0)); 938 939 fimc_dst_set_buf_seq(ctx, 0, true); 940 } 941 942 static void fimc_stop(struct fimc_context *ctx); 943 944 static irqreturn_t fimc_irq_handler(int irq, void *dev_id) 945 { 946 struct fimc_context *ctx = dev_id; 947 int buf_id; 948 949 DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id); 950 951 fimc_clear_irq(ctx); 952 if (fimc_check_ovf(ctx)) 953 return IRQ_NONE; 954 955 if (!fimc_check_frame_end(ctx)) 956 return IRQ_NONE; 957 958 buf_id = fimc_get_buf_id(ctx); 959 if (buf_id < 0) 960 return IRQ_HANDLED; 961 962 DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); 963 964 if (ctx->task) { 965 struct exynos_drm_ipp_task *task = ctx->task; 966 967 ctx->task = NULL; 968 pm_runtime_mark_last_busy(ctx->dev); 969 pm_runtime_put_autosuspend(ctx->dev); 970 exynos_drm_ipp_task_done(task, 0); 971 } 972 973 fimc_dst_set_buf_seq(ctx, buf_id, false); 974 fimc_stop(ctx); 975 976 return IRQ_HANDLED; 977 } 978 979 static void fimc_clear_addr(struct fimc_context *ctx) 980 { 981 int i; 982 983 for (i = 0; i < FIMC_MAX_SRC; i++) { 984 fimc_write(ctx, 0, EXYNOS_CIIYSA(i)); 985 fimc_write(ctx, 0, EXYNOS_CIICBSA(i)); 986 fimc_write(ctx, 0, EXYNOS_CIICRSA(i)); 987 } 988 989 for (i = 0; i < FIMC_MAX_DST; i++) { 990 fimc_write(ctx, 0, EXYNOS_CIOYSA(i)); 991 fimc_write(ctx, 0, EXYNOS_CIOCBSA(i)); 992 fimc_write(ctx, 0, EXYNOS_CIOCRSA(i)); 993 } 994 } 995 996 static void fimc_reset(struct fimc_context *ctx) 997 { 998 /* reset h/w block */ 999 fimc_sw_reset(ctx); 1000 1001 /* reset scaler capability */ 1002 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); 1003 1004 fimc_clear_addr(ctx); 1005 } 1006 1007 static void fimc_start(struct fimc_context *ctx) 1008 { 1009 u32 cfg0, cfg1; 1010 1011 fimc_mask_irq(ctx, true); 1012 1013 /* If set true, we can save jpeg about screen */ 1014 fimc_handle_jpeg(ctx, false); 1015 fimc_set_scaler(ctx, &ctx->sc); 1016 1017 fimc_set_type_ctrl(ctx); 1018 fimc_handle_lastend(ctx, false); 1019 1020 /* setup dma */ 1021 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL); 1022 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK; 1023 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY; 1024 fimc_write(ctx, cfg0, EXYNOS_MSCTRL); 1025 1026 /* Reset status */ 1027 fimc_write(ctx, 0x0, EXYNOS_CISTATUS); 1028 1029 cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT); 1030 cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1031 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1032 1033 /* Scaler */ 1034 cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL); 1035 cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK; 1036 cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE | 1037 EXYNOS_CISCCTRL_SCALERSTART); 1038 1039 fimc_write(ctx, cfg1, EXYNOS_CISCCTRL); 1040 1041 /* Enable image capture*/ 1042 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN; 1043 fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT); 1044 1045 /* Disable frame end irq */ 1046 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1047 1048 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK); 1049 1050 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); 1051 } 1052 1053 static void fimc_stop(struct fimc_context *ctx) 1054 { 1055 u32 cfg; 1056 1057 /* Source clear */ 1058 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 1059 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK; 1060 cfg &= ~EXYNOS_MSCTRL_ENVID; 1061 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 1062 1063 fimc_mask_irq(ctx, false); 1064 1065 /* reset sequence */ 1066 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 1067 1068 /* Scaler disable */ 1069 fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART); 1070 1071 /* Disable image capture */ 1072 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT, 1073 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 1074 1075 /* Enable frame end irq */ 1076 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1077 } 1078 1079 static int fimc_commit(struct exynos_drm_ipp *ipp, 1080 struct exynos_drm_ipp_task *task) 1081 { 1082 struct fimc_context *ctx = 1083 container_of(ipp, struct fimc_context, ipp); 1084 1085 pm_runtime_get_sync(ctx->dev); 1086 ctx->task = task; 1087 1088 fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); 1089 fimc_src_set_size(ctx, &task->src); 1090 fimc_src_set_transf(ctx, DRM_MODE_ROTATE_0); 1091 fimc_src_set_addr(ctx, &task->src); 1092 fimc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier); 1093 fimc_dst_set_transf(ctx, task->transform.rotation); 1094 fimc_dst_set_size(ctx, &task->dst); 1095 fimc_dst_set_addr(ctx, &task->dst); 1096 fimc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect); 1097 fimc_start(ctx); 1098 1099 return 0; 1100 } 1101 1102 static void fimc_abort(struct exynos_drm_ipp *ipp, 1103 struct exynos_drm_ipp_task *task) 1104 { 1105 struct fimc_context *ctx = 1106 container_of(ipp, struct fimc_context, ipp); 1107 1108 fimc_reset(ctx); 1109 1110 if (ctx->task) { 1111 struct exynos_drm_ipp_task *task = ctx->task; 1112 1113 ctx->task = NULL; 1114 pm_runtime_mark_last_busy(ctx->dev); 1115 pm_runtime_put_autosuspend(ctx->dev); 1116 exynos_drm_ipp_task_done(task, -EIO); 1117 } 1118 } 1119 1120 static struct exynos_drm_ipp_funcs ipp_funcs = { 1121 .commit = fimc_commit, 1122 .abort = fimc_abort, 1123 }; 1124 1125 static int fimc_bind(struct device *dev, struct device *master, void *data) 1126 { 1127 struct fimc_context *ctx = dev_get_drvdata(dev); 1128 struct drm_device *drm_dev = data; 1129 struct exynos_drm_ipp *ipp = &ctx->ipp; 1130 1131 ctx->drm_dev = drm_dev; 1132 drm_iommu_attach_device(drm_dev, dev); 1133 1134 exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, 1135 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | 1136 DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, 1137 ctx->formats, ctx->num_formats, "fimc"); 1138 1139 dev_info(dev, "The exynos fimc has been probed successfully\n"); 1140 1141 return 0; 1142 } 1143 1144 static void fimc_unbind(struct device *dev, struct device *master, 1145 void *data) 1146 { 1147 struct fimc_context *ctx = dev_get_drvdata(dev); 1148 struct drm_device *drm_dev = data; 1149 struct exynos_drm_ipp *ipp = &ctx->ipp; 1150 1151 exynos_drm_ipp_unregister(drm_dev, ipp); 1152 drm_iommu_detach_device(drm_dev, dev); 1153 } 1154 1155 static const struct component_ops fimc_component_ops = { 1156 .bind = fimc_bind, 1157 .unbind = fimc_unbind, 1158 }; 1159 1160 static void fimc_put_clocks(struct fimc_context *ctx) 1161 { 1162 int i; 1163 1164 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1165 if (IS_ERR(ctx->clocks[i])) 1166 continue; 1167 clk_put(ctx->clocks[i]); 1168 ctx->clocks[i] = ERR_PTR(-EINVAL); 1169 } 1170 } 1171 1172 static int fimc_setup_clocks(struct fimc_context *ctx) 1173 { 1174 struct device *fimc_dev = ctx->dev; 1175 struct device *dev; 1176 int ret, i; 1177 1178 for (i = 0; i < FIMC_CLKS_MAX; i++) 1179 ctx->clocks[i] = ERR_PTR(-EINVAL); 1180 1181 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1182 if (i == FIMC_CLK_WB_A || i == FIMC_CLK_WB_B) 1183 dev = fimc_dev->parent; 1184 else 1185 dev = fimc_dev; 1186 1187 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]); 1188 if (IS_ERR(ctx->clocks[i])) { 1189 ret = PTR_ERR(ctx->clocks[i]); 1190 dev_err(fimc_dev, "failed to get clock: %s\n", 1191 fimc_clock_names[i]); 1192 goto e_clk_free; 1193 } 1194 } 1195 1196 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]); 1197 if (!ret) 1198 return ret; 1199 e_clk_free: 1200 fimc_put_clocks(ctx); 1201 return ret; 1202 } 1203 1204 int exynos_drm_check_fimc_device(struct device *dev) 1205 { 1206 int id = of_alias_get_id(dev->of_node, "fimc"); 1207 1208 if (id >= 0 && (BIT(id) & fimc_mask)) 1209 return 0; 1210 return -ENODEV; 1211 } 1212 1213 static const unsigned int fimc_formats[] = { 1214 DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, 1215 DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61, 1216 DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU, 1217 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422, 1218 DRM_FORMAT_YUV444, 1219 }; 1220 1221 static const unsigned int fimc_tiled_formats[] = { 1222 DRM_FORMAT_NV12, DRM_FORMAT_NV21, 1223 }; 1224 1225 static const struct drm_exynos_ipp_limit fimc_4210_limits_v1[] = { 1226 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) }, 1227 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4224, 2 }, .v = { 16, 0, 2 }) }, 1228 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1920 }, .v = { 128, 0 }) }, 1229 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1230 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1231 }; 1232 1233 static const struct drm_exynos_ipp_limit fimc_4210_limits_v2[] = { 1234 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) }, 1235 { IPP_SIZE_LIMIT(AREA, .h = { 16, 1920, 2 }, .v = { 16, 0, 2 }) }, 1236 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1366 }, .v = { 128, 0 }) }, 1237 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1238 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1239 }; 1240 1241 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v1[] = { 1242 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) }, 1243 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1920, 2 }, .v = { 128, 0, 2 }) }, 1244 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1245 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1246 }; 1247 1248 static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2[] = { 1249 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) }, 1250 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1366, 2 }, .v = { 128, 0, 2 }) }, 1251 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1252 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1253 }; 1254 1255 static int fimc_probe(struct platform_device *pdev) 1256 { 1257 const struct drm_exynos_ipp_limit *limits; 1258 struct exynos_drm_ipp_formats *formats; 1259 struct device *dev = &pdev->dev; 1260 struct fimc_context *ctx; 1261 struct resource *res; 1262 int ret; 1263 int i, j, num_limits, num_formats; 1264 1265 if (exynos_drm_check_fimc_device(dev) != 0) 1266 return -ENODEV; 1267 1268 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1269 if (!ctx) 1270 return -ENOMEM; 1271 1272 ctx->dev = dev; 1273 ctx->id = of_alias_get_id(dev->of_node, "fimc"); 1274 1275 /* construct formats/limits array */ 1276 num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats); 1277 formats = devm_kcalloc(dev, num_formats, sizeof(*formats), 1278 GFP_KERNEL); 1279 if (!formats) 1280 return -ENOMEM; 1281 1282 /* linear formats */ 1283 if (ctx->id < 3) { 1284 limits = fimc_4210_limits_v1; 1285 num_limits = ARRAY_SIZE(fimc_4210_limits_v1); 1286 } else { 1287 limits = fimc_4210_limits_v2; 1288 num_limits = ARRAY_SIZE(fimc_4210_limits_v2); 1289 } 1290 for (i = 0; i < ARRAY_SIZE(fimc_formats); i++) { 1291 formats[i].fourcc = fimc_formats[i]; 1292 formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE | 1293 DRM_EXYNOS_IPP_FORMAT_DESTINATION; 1294 formats[i].limits = limits; 1295 formats[i].num_limits = num_limits; 1296 } 1297 1298 /* tiled formats */ 1299 if (ctx->id < 3) { 1300 limits = fimc_4210_limits_tiled_v1; 1301 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v1); 1302 } else { 1303 limits = fimc_4210_limits_tiled_v2; 1304 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v2); 1305 } 1306 for (j = i, i = 0; i < ARRAY_SIZE(fimc_tiled_formats); j++, i++) { 1307 formats[j].fourcc = fimc_tiled_formats[i]; 1308 formats[j].modifier = DRM_FORMAT_MOD_SAMSUNG_64_32_TILE; 1309 formats[j].type = DRM_EXYNOS_IPP_FORMAT_SOURCE | 1310 DRM_EXYNOS_IPP_FORMAT_DESTINATION; 1311 formats[j].limits = limits; 1312 formats[j].num_limits = num_limits; 1313 } 1314 1315 ctx->formats = formats; 1316 ctx->num_formats = num_formats; 1317 1318 /* resource memory */ 1319 ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1320 ctx->regs = devm_ioremap_resource(dev, ctx->regs_res); 1321 if (IS_ERR(ctx->regs)) 1322 return PTR_ERR(ctx->regs); 1323 1324 /* resource irq */ 1325 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1326 if (!res) { 1327 dev_err(dev, "failed to request irq resource.\n"); 1328 return -ENOENT; 1329 } 1330 1331 ret = devm_request_irq(dev, res->start, fimc_irq_handler, 1332 0, dev_name(dev), ctx); 1333 if (ret < 0) { 1334 dev_err(dev, "failed to request irq.\n"); 1335 return ret; 1336 } 1337 1338 ret = fimc_setup_clocks(ctx); 1339 if (ret < 0) 1340 return ret; 1341 1342 spin_lock_init(&ctx->lock); 1343 platform_set_drvdata(pdev, ctx); 1344 1345 pm_runtime_use_autosuspend(dev); 1346 pm_runtime_set_autosuspend_delay(dev, FIMC_AUTOSUSPEND_DELAY); 1347 pm_runtime_enable(dev); 1348 1349 ret = component_add(dev, &fimc_component_ops); 1350 if (ret) 1351 goto err_pm_dis; 1352 1353 dev_info(dev, "drm fimc registered successfully.\n"); 1354 1355 return 0; 1356 1357 err_pm_dis: 1358 pm_runtime_dont_use_autosuspend(dev); 1359 pm_runtime_disable(dev); 1360 fimc_put_clocks(ctx); 1361 1362 return ret; 1363 } 1364 1365 static int fimc_remove(struct platform_device *pdev) 1366 { 1367 struct device *dev = &pdev->dev; 1368 struct fimc_context *ctx = get_fimc_context(dev); 1369 1370 component_del(dev, &fimc_component_ops); 1371 pm_runtime_dont_use_autosuspend(dev); 1372 pm_runtime_disable(dev); 1373 1374 fimc_put_clocks(ctx); 1375 1376 return 0; 1377 } 1378 1379 #ifdef CONFIG_PM 1380 static int fimc_runtime_suspend(struct device *dev) 1381 { 1382 struct fimc_context *ctx = get_fimc_context(dev); 1383 1384 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1385 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]); 1386 return 0; 1387 } 1388 1389 static int fimc_runtime_resume(struct device *dev) 1390 { 1391 struct fimc_context *ctx = get_fimc_context(dev); 1392 1393 DRM_DEBUG_KMS("id[%d]\n", ctx->id); 1394 return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]); 1395 } 1396 #endif 1397 1398 static const struct dev_pm_ops fimc_pm_ops = { 1399 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1400 pm_runtime_force_resume) 1401 SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL) 1402 }; 1403 1404 static const struct of_device_id fimc_of_match[] = { 1405 { .compatible = "samsung,exynos4210-fimc" }, 1406 { .compatible = "samsung,exynos4212-fimc" }, 1407 { }, 1408 }; 1409 MODULE_DEVICE_TABLE(of, fimc_of_match); 1410 1411 struct platform_driver fimc_driver = { 1412 .probe = fimc_probe, 1413 .remove = fimc_remove, 1414 .driver = { 1415 .of_match_table = fimc_of_match, 1416 .name = "exynos-drm-fimc", 1417 .owner = THIS_MODULE, 1418 .pm = &fimc_pm_ops, 1419 }, 1420 }; 1421