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