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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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 DRM_DEV_ERROR(ctx->dev, 236 "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_ERROR(ctx->dev, "failed to get frame count.\n"); 278 return -EIO; 279 } 280 281 buf_id = frame_cnt - 1; 282 DRM_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "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_DEV_DEBUG_KMS(ctx->dev, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, 486 v2); 487 488 /* 489 * set window offset 1, 2 size 490 * check figure 43-21 in user manual 491 */ 492 cfg = fimc_read(ctx, EXYNOS_CIWDOFST); 493 cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK | 494 EXYNOS_CIWDOFST_WINVEROFST_MASK); 495 cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) | 496 EXYNOS_CIWDOFST_WINVEROFST(v1)); 497 cfg |= EXYNOS_CIWDOFST_WINOFSEN; 498 fimc_write(ctx, cfg, EXYNOS_CIWDOFST); 499 500 cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) | 501 EXYNOS_CIWDOFST2_WINVEROFST2(v2)); 502 fimc_write(ctx, cfg, EXYNOS_CIWDOFST2); 503 } 504 505 static void fimc_src_set_size(struct fimc_context *ctx, 506 struct exynos_drm_ipp_buffer *buf) 507 { 508 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; 509 u32 cfg; 510 511 DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, 512 buf->buf.height); 513 514 /* original size */ 515 cfg = (EXYNOS_ORGISIZE_HORIZONTAL(real_width) | 516 EXYNOS_ORGISIZE_VERTICAL(buf->buf.height)); 517 518 fimc_write(ctx, cfg, EXYNOS_ORGISIZE); 519 520 DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, 521 buf->rect.y, buf->rect.w, buf->rect.h); 522 523 /* set input DMA image size */ 524 cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE); 525 cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK | 526 EXYNOS_CIREAL_ISIZE_WIDTH_MASK); 527 cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(buf->rect.w) | 528 EXYNOS_CIREAL_ISIZE_HEIGHT(buf->rect.h)); 529 fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE); 530 531 /* 532 * set input FIFO image size 533 * for now, we support only ITU601 8 bit mode 534 */ 535 cfg = (EXYNOS_CISRCFMT_ITU601_8BIT | 536 EXYNOS_CISRCFMT_SOURCEHSIZE(real_width) | 537 EXYNOS_CISRCFMT_SOURCEVSIZE(buf->buf.height)); 538 fimc_write(ctx, cfg, EXYNOS_CISRCFMT); 539 540 /* offset Y(RGB), Cb, Cr */ 541 cfg = (EXYNOS_CIIYOFF_HORIZONTAL(buf->rect.x) | 542 EXYNOS_CIIYOFF_VERTICAL(buf->rect.y)); 543 fimc_write(ctx, cfg, EXYNOS_CIIYOFF); 544 cfg = (EXYNOS_CIICBOFF_HORIZONTAL(buf->rect.x) | 545 EXYNOS_CIICBOFF_VERTICAL(buf->rect.y)); 546 fimc_write(ctx, cfg, EXYNOS_CIICBOFF); 547 cfg = (EXYNOS_CIICROFF_HORIZONTAL(buf->rect.x) | 548 EXYNOS_CIICROFF_VERTICAL(buf->rect.y)); 549 fimc_write(ctx, cfg, EXYNOS_CIICROFF); 550 551 fimc_set_window(ctx, buf); 552 } 553 554 static void fimc_src_set_addr(struct fimc_context *ctx, 555 struct exynos_drm_ipp_buffer *buf) 556 { 557 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIIYSA(0)); 558 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIICBSA(0)); 559 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIICRSA(0)); 560 } 561 562 static void fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt) 563 { 564 u32 cfg; 565 566 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); 567 568 /* RGB */ 569 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 570 cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK; 571 572 switch (fmt) { 573 case DRM_FORMAT_RGB565: 574 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565; 575 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 576 return; 577 case DRM_FORMAT_RGB888: 578 cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888; 579 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 580 return; 581 case DRM_FORMAT_XRGB8888: 582 cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 | 583 EXYNOS_CISCCTRL_EXTRGB_EXTENSION); 584 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 585 break; 586 default: 587 /* bypass */ 588 break; 589 } 590 591 /* YUV */ 592 cfg = fimc_read(ctx, EXYNOS_CIOCTRL); 593 cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK | 594 EXYNOS_CIOCTRL_ORDER422_MASK | 595 EXYNOS_CIOCTRL_YCBCR_PLANE_MASK); 596 597 switch (fmt) { 598 case DRM_FORMAT_XRGB8888: 599 cfg |= EXYNOS_CIOCTRL_ALPHA_OUT; 600 break; 601 case DRM_FORMAT_YUYV: 602 cfg |= EXYNOS_CIOCTRL_ORDER422_YCBYCR; 603 break; 604 case DRM_FORMAT_YVYU: 605 cfg |= EXYNOS_CIOCTRL_ORDER422_YCRYCB; 606 break; 607 case DRM_FORMAT_UYVY: 608 cfg |= EXYNOS_CIOCTRL_ORDER422_CBYCRY; 609 break; 610 case DRM_FORMAT_VYUY: 611 cfg |= EXYNOS_CIOCTRL_ORDER422_CRYCBY; 612 break; 613 case DRM_FORMAT_NV21: 614 case DRM_FORMAT_NV61: 615 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB; 616 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 617 break; 618 case DRM_FORMAT_YUV422: 619 case DRM_FORMAT_YUV420: 620 case DRM_FORMAT_YVU420: 621 cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE; 622 break; 623 case DRM_FORMAT_NV12: 624 case DRM_FORMAT_NV16: 625 cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR; 626 cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE; 627 break; 628 } 629 630 fimc_write(ctx, cfg, EXYNOS_CIOCTRL); 631 } 632 633 static void fimc_dst_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled) 634 { 635 u32 cfg; 636 637 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); 638 639 cfg = fimc_read(ctx, EXYNOS_CIEXTEN); 640 641 if (fmt == DRM_FORMAT_AYUV) { 642 cfg |= EXYNOS_CIEXTEN_YUV444_OUT; 643 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 644 } else { 645 cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT; 646 fimc_write(ctx, cfg, EXYNOS_CIEXTEN); 647 648 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 649 cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK; 650 651 switch (fmt) { 652 case DRM_FORMAT_RGB565: 653 case DRM_FORMAT_RGB888: 654 case DRM_FORMAT_XRGB8888: 655 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB; 656 break; 657 case DRM_FORMAT_YUYV: 658 case DRM_FORMAT_YVYU: 659 case DRM_FORMAT_UYVY: 660 case DRM_FORMAT_VYUY: 661 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE; 662 break; 663 case DRM_FORMAT_NV16: 664 case DRM_FORMAT_NV61: 665 case DRM_FORMAT_YUV422: 666 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422; 667 break; 668 case DRM_FORMAT_YUV420: 669 case DRM_FORMAT_YVU420: 670 case DRM_FORMAT_NV12: 671 case DRM_FORMAT_NV21: 672 cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420; 673 break; 674 } 675 676 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 677 } 678 679 cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM); 680 cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK; 681 682 if (tiled) 683 cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32; 684 else 685 cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR; 686 687 fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM); 688 689 fimc_dst_set_fmt_order(ctx, fmt); 690 } 691 692 static void fimc_dst_set_transf(struct fimc_context *ctx, unsigned int rotation) 693 { 694 unsigned int degree = rotation & DRM_MODE_ROTATE_MASK; 695 u32 cfg; 696 697 DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[0x%x]\n", rotation); 698 699 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 700 cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; 701 cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 702 703 switch (degree) { 704 case DRM_MODE_ROTATE_0: 705 if (rotation & DRM_MODE_REFLECT_X) 706 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 707 if (rotation & DRM_MODE_REFLECT_Y) 708 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 709 break; 710 case DRM_MODE_ROTATE_90: 711 cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE; 712 if (rotation & DRM_MODE_REFLECT_X) 713 cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR; 714 if (rotation & DRM_MODE_REFLECT_Y) 715 cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 716 break; 717 case DRM_MODE_ROTATE_180: 718 cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR | 719 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 720 if (rotation & DRM_MODE_REFLECT_X) 721 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 722 if (rotation & DRM_MODE_REFLECT_Y) 723 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 724 break; 725 case DRM_MODE_ROTATE_270: 726 cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE | 727 EXYNOS_CITRGFMT_FLIP_X_MIRROR | 728 EXYNOS_CITRGFMT_FLIP_Y_MIRROR); 729 if (rotation & DRM_MODE_REFLECT_X) 730 cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR; 731 if (rotation & DRM_MODE_REFLECT_Y) 732 cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR; 733 break; 734 } 735 736 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 737 } 738 739 static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, 740 struct drm_exynos_ipp_task_rect *src, 741 struct drm_exynos_ipp_task_rect *dst) 742 { 743 u32 cfg, cfg_ext, shfactor; 744 u32 pre_dst_width, pre_dst_height; 745 u32 hfactor, vfactor; 746 int ret = 0; 747 u32 src_w, src_h, dst_w, dst_h; 748 749 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT); 750 if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) { 751 src_w = src->h; 752 src_h = src->w; 753 } else { 754 src_w = src->w; 755 src_h = src->h; 756 } 757 758 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) { 759 dst_w = dst->h; 760 dst_h = dst->w; 761 } else { 762 dst_w = dst->w; 763 dst_h = dst->h; 764 } 765 766 /* fimc_ippdrv_check_property assures that dividers are not null */ 767 hfactor = fls(src_w / dst_w / 2); 768 if (hfactor > FIMC_SHFACTOR / 2) { 769 dev_err(ctx->dev, "failed to get ratio horizontal.\n"); 770 return -EINVAL; 771 } 772 773 vfactor = fls(src_h / dst_h / 2); 774 if (vfactor > FIMC_SHFACTOR / 2) { 775 dev_err(ctx->dev, "failed to get ratio vertical.\n"); 776 return -EINVAL; 777 } 778 779 pre_dst_width = src_w >> hfactor; 780 pre_dst_height = src_h >> vfactor; 781 DRM_DEV_DEBUG_KMS(ctx->dev, "pre_dst_width[%d]pre_dst_height[%d]\n", 782 pre_dst_width, pre_dst_height); 783 DRM_DEV_DEBUG_KMS(ctx->dev, "hfactor[%d]vfactor[%d]\n", hfactor, 784 vfactor); 785 786 sc->hratio = (src_w << 14) / (dst_w << hfactor); 787 sc->vratio = (src_h << 14) / (dst_h << vfactor); 788 sc->up_h = (dst_w >= src_w) ? true : false; 789 sc->up_v = (dst_h >= src_h) ? true : false; 790 DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", 791 sc->hratio, sc->vratio, sc->up_h, sc->up_v); 792 793 shfactor = FIMC_SHFACTOR - (hfactor + vfactor); 794 DRM_DEV_DEBUG_KMS(ctx->dev, "shfactor[%d]\n", shfactor); 795 796 cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | 797 EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) | 798 EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor)); 799 fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO); 800 801 cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) | 802 EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height)); 803 fimc_write(ctx, cfg, EXYNOS_CISCPREDST); 804 805 return ret; 806 } 807 808 static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc) 809 { 810 u32 cfg, cfg_ext; 811 812 DRM_DEV_DEBUG_KMS(ctx->dev, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n", 813 sc->range, sc->bypass, sc->up_h, sc->up_v); 814 DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]\n", 815 sc->hratio, sc->vratio); 816 817 cfg = fimc_read(ctx, EXYNOS_CISCCTRL); 818 cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS | 819 EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V | 820 EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK | 821 EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK | 822 EXYNOS_CISCCTRL_CSCR2Y_WIDE | 823 EXYNOS_CISCCTRL_CSCY2R_WIDE); 824 825 if (sc->range) 826 cfg |= (EXYNOS_CISCCTRL_CSCR2Y_WIDE | 827 EXYNOS_CISCCTRL_CSCY2R_WIDE); 828 if (sc->bypass) 829 cfg |= EXYNOS_CISCCTRL_SCALERBYPASS; 830 if (sc->up_h) 831 cfg |= EXYNOS_CISCCTRL_SCALEUP_H; 832 if (sc->up_v) 833 cfg |= EXYNOS_CISCCTRL_SCALEUP_V; 834 835 cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) | 836 EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6))); 837 fimc_write(ctx, cfg, EXYNOS_CISCCTRL); 838 839 cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN); 840 cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK; 841 cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK; 842 cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) | 843 EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio)); 844 fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN); 845 } 846 847 static void fimc_dst_set_size(struct fimc_context *ctx, 848 struct exynos_drm_ipp_buffer *buf) 849 { 850 unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; 851 u32 cfg, cfg_ext; 852 853 DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, 854 buf->buf.height); 855 856 /* original size */ 857 cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(real_width) | 858 EXYNOS_ORGOSIZE_VERTICAL(buf->buf.height)); 859 860 fimc_write(ctx, cfg, EXYNOS_ORGOSIZE); 861 862 DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, 863 buf->rect.y, 864 buf->rect.w, buf->rect.h); 865 866 /* CSC ITU */ 867 cfg = fimc_read(ctx, EXYNOS_CIGCTRL); 868 cfg &= ~EXYNOS_CIGCTRL_CSC_MASK; 869 870 if (buf->buf.width >= FIMC_WIDTH_ITU_709) 871 cfg |= EXYNOS_CIGCTRL_CSC_ITU709; 872 else 873 cfg |= EXYNOS_CIGCTRL_CSC_ITU601; 874 875 fimc_write(ctx, cfg, EXYNOS_CIGCTRL); 876 877 cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT); 878 879 /* target image size */ 880 cfg = fimc_read(ctx, EXYNOS_CITRGFMT); 881 cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK | 882 EXYNOS_CITRGFMT_TARGETV_MASK); 883 if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) 884 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.h) | 885 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.w)); 886 else 887 cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.w) | 888 EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.h)); 889 fimc_write(ctx, cfg, EXYNOS_CITRGFMT); 890 891 /* target area */ 892 cfg = EXYNOS_CITAREA_TARGET_AREA(buf->rect.w * buf->rect.h); 893 fimc_write(ctx, cfg, EXYNOS_CITAREA); 894 895 /* offset Y(RGB), Cb, Cr */ 896 cfg = (EXYNOS_CIOYOFF_HORIZONTAL(buf->rect.x) | 897 EXYNOS_CIOYOFF_VERTICAL(buf->rect.y)); 898 fimc_write(ctx, cfg, EXYNOS_CIOYOFF); 899 cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(buf->rect.x) | 900 EXYNOS_CIOCBOFF_VERTICAL(buf->rect.y)); 901 fimc_write(ctx, cfg, EXYNOS_CIOCBOFF); 902 cfg = (EXYNOS_CIOCROFF_HORIZONTAL(buf->rect.x) | 903 EXYNOS_CIOCROFF_VERTICAL(buf->rect.y)); 904 fimc_write(ctx, cfg, EXYNOS_CIOCROFF); 905 } 906 907 static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, 908 bool enqueue) 909 { 910 unsigned long flags; 911 u32 buf_num; 912 u32 cfg; 913 914 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueu[%d]\n", buf_id, enqueue); 915 916 spin_lock_irqsave(&ctx->lock, flags); 917 918 cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ); 919 920 if (enqueue) 921 cfg |= (1 << buf_id); 922 else 923 cfg &= ~(1 << buf_id); 924 925 fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ); 926 927 buf_num = hweight32(cfg); 928 929 if (enqueue && buf_num >= FIMC_BUF_START) 930 fimc_mask_irq(ctx, true); 931 else if (!enqueue && buf_num <= FIMC_BUF_STOP) 932 fimc_mask_irq(ctx, false); 933 934 spin_unlock_irqrestore(&ctx->lock, flags); 935 } 936 937 static void fimc_dst_set_addr(struct fimc_context *ctx, 938 struct exynos_drm_ipp_buffer *buf) 939 { 940 fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIOYSA(0)); 941 fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIOCBSA(0)); 942 fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIOCRSA(0)); 943 944 fimc_dst_set_buf_seq(ctx, 0, true); 945 } 946 947 static void fimc_stop(struct fimc_context *ctx); 948 949 static irqreturn_t fimc_irq_handler(int irq, void *dev_id) 950 { 951 struct fimc_context *ctx = dev_id; 952 int buf_id; 953 954 DRM_DEV_DEBUG_KMS(ctx->dev, "fimc id[%d]\n", ctx->id); 955 956 fimc_clear_irq(ctx); 957 if (fimc_check_ovf(ctx)) 958 return IRQ_NONE; 959 960 if (!fimc_check_frame_end(ctx)) 961 return IRQ_NONE; 962 963 buf_id = fimc_get_buf_id(ctx); 964 if (buf_id < 0) 965 return IRQ_HANDLED; 966 967 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id); 968 969 if (ctx->task) { 970 struct exynos_drm_ipp_task *task = ctx->task; 971 972 ctx->task = NULL; 973 pm_runtime_mark_last_busy(ctx->dev); 974 pm_runtime_put_autosuspend(ctx->dev); 975 exynos_drm_ipp_task_done(task, 0); 976 } 977 978 fimc_dst_set_buf_seq(ctx, buf_id, false); 979 fimc_stop(ctx); 980 981 return IRQ_HANDLED; 982 } 983 984 static void fimc_clear_addr(struct fimc_context *ctx) 985 { 986 int i; 987 988 for (i = 0; i < FIMC_MAX_SRC; i++) { 989 fimc_write(ctx, 0, EXYNOS_CIIYSA(i)); 990 fimc_write(ctx, 0, EXYNOS_CIICBSA(i)); 991 fimc_write(ctx, 0, EXYNOS_CIICRSA(i)); 992 } 993 994 for (i = 0; i < FIMC_MAX_DST; i++) { 995 fimc_write(ctx, 0, EXYNOS_CIOYSA(i)); 996 fimc_write(ctx, 0, EXYNOS_CIOCBSA(i)); 997 fimc_write(ctx, 0, EXYNOS_CIOCRSA(i)); 998 } 999 } 1000 1001 static void fimc_reset(struct fimc_context *ctx) 1002 { 1003 /* reset h/w block */ 1004 fimc_sw_reset(ctx); 1005 1006 /* reset scaler capability */ 1007 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); 1008 1009 fimc_clear_addr(ctx); 1010 } 1011 1012 static void fimc_start(struct fimc_context *ctx) 1013 { 1014 u32 cfg0, cfg1; 1015 1016 fimc_mask_irq(ctx, true); 1017 1018 /* If set true, we can save jpeg about screen */ 1019 fimc_handle_jpeg(ctx, false); 1020 fimc_set_scaler(ctx, &ctx->sc); 1021 1022 fimc_set_type_ctrl(ctx); 1023 fimc_handle_lastend(ctx, false); 1024 1025 /* setup dma */ 1026 cfg0 = fimc_read(ctx, EXYNOS_MSCTRL); 1027 cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK; 1028 cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY; 1029 fimc_write(ctx, cfg0, EXYNOS_MSCTRL); 1030 1031 /* Reset status */ 1032 fimc_write(ctx, 0x0, EXYNOS_CISTATUS); 1033 1034 cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT); 1035 cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1036 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC; 1037 1038 /* Scaler */ 1039 cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL); 1040 cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK; 1041 cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE | 1042 EXYNOS_CISCCTRL_SCALERSTART); 1043 1044 fimc_write(ctx, cfg1, EXYNOS_CISCCTRL); 1045 1046 /* Enable image capture*/ 1047 cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN; 1048 fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT); 1049 1050 /* Disable frame end irq */ 1051 fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1052 1053 fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK); 1054 1055 fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); 1056 } 1057 1058 static void fimc_stop(struct fimc_context *ctx) 1059 { 1060 u32 cfg; 1061 1062 /* Source clear */ 1063 cfg = fimc_read(ctx, EXYNOS_MSCTRL); 1064 cfg &= ~EXYNOS_MSCTRL_INPUT_MASK; 1065 cfg &= ~EXYNOS_MSCTRL_ENVID; 1066 fimc_write(ctx, cfg, EXYNOS_MSCTRL); 1067 1068 fimc_mask_irq(ctx, false); 1069 1070 /* reset sequence */ 1071 fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ); 1072 1073 /* Scaler disable */ 1074 fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART); 1075 1076 /* Disable image capture */ 1077 fimc_clear_bits(ctx, EXYNOS_CIIMGCPT, 1078 EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN); 1079 1080 /* Enable frame end irq */ 1081 fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE); 1082 } 1083 1084 static int fimc_commit(struct exynos_drm_ipp *ipp, 1085 struct exynos_drm_ipp_task *task) 1086 { 1087 struct fimc_context *ctx = 1088 container_of(ipp, struct fimc_context, ipp); 1089 1090 pm_runtime_get_sync(ctx->dev); 1091 ctx->task = task; 1092 1093 fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); 1094 fimc_src_set_size(ctx, &task->src); 1095 fimc_src_set_transf(ctx, DRM_MODE_ROTATE_0); 1096 fimc_src_set_addr(ctx, &task->src); 1097 fimc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier); 1098 fimc_dst_set_transf(ctx, task->transform.rotation); 1099 fimc_dst_set_size(ctx, &task->dst); 1100 fimc_dst_set_addr(ctx, &task->dst); 1101 fimc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect); 1102 fimc_start(ctx); 1103 1104 return 0; 1105 } 1106 1107 static void fimc_abort(struct exynos_drm_ipp *ipp, 1108 struct exynos_drm_ipp_task *task) 1109 { 1110 struct fimc_context *ctx = 1111 container_of(ipp, struct fimc_context, ipp); 1112 1113 fimc_reset(ctx); 1114 1115 if (ctx->task) { 1116 struct exynos_drm_ipp_task *task = ctx->task; 1117 1118 ctx->task = NULL; 1119 pm_runtime_mark_last_busy(ctx->dev); 1120 pm_runtime_put_autosuspend(ctx->dev); 1121 exynos_drm_ipp_task_done(task, -EIO); 1122 } 1123 } 1124 1125 static struct exynos_drm_ipp_funcs ipp_funcs = { 1126 .commit = fimc_commit, 1127 .abort = fimc_abort, 1128 }; 1129 1130 static int fimc_bind(struct device *dev, struct device *master, void *data) 1131 { 1132 struct fimc_context *ctx = dev_get_drvdata(dev); 1133 struct drm_device *drm_dev = data; 1134 struct exynos_drm_ipp *ipp = &ctx->ipp; 1135 1136 ctx->drm_dev = drm_dev; 1137 ipp->drm_dev = drm_dev; 1138 exynos_drm_register_dma(drm_dev, dev); 1139 1140 exynos_drm_ipp_register(dev, ipp, &ipp_funcs, 1141 DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | 1142 DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, 1143 ctx->formats, ctx->num_formats, "fimc"); 1144 1145 dev_info(dev, "The exynos fimc has been probed successfully\n"); 1146 1147 return 0; 1148 } 1149 1150 static void fimc_unbind(struct device *dev, struct device *master, 1151 void *data) 1152 { 1153 struct fimc_context *ctx = dev_get_drvdata(dev); 1154 struct drm_device *drm_dev = data; 1155 struct exynos_drm_ipp *ipp = &ctx->ipp; 1156 1157 exynos_drm_ipp_unregister(dev, ipp); 1158 exynos_drm_unregister_dma(drm_dev, dev); 1159 } 1160 1161 static const struct component_ops fimc_component_ops = { 1162 .bind = fimc_bind, 1163 .unbind = fimc_unbind, 1164 }; 1165 1166 static void fimc_put_clocks(struct fimc_context *ctx) 1167 { 1168 int i; 1169 1170 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1171 if (IS_ERR(ctx->clocks[i])) 1172 continue; 1173 clk_put(ctx->clocks[i]); 1174 ctx->clocks[i] = ERR_PTR(-EINVAL); 1175 } 1176 } 1177 1178 static int fimc_setup_clocks(struct fimc_context *ctx) 1179 { 1180 struct device *fimc_dev = ctx->dev; 1181 struct device *dev; 1182 int ret, i; 1183 1184 for (i = 0; i < FIMC_CLKS_MAX; i++) 1185 ctx->clocks[i] = ERR_PTR(-EINVAL); 1186 1187 for (i = 0; i < FIMC_CLKS_MAX; i++) { 1188 if (i == FIMC_CLK_WB_A || i == FIMC_CLK_WB_B) 1189 dev = fimc_dev->parent; 1190 else 1191 dev = fimc_dev; 1192 1193 ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]); 1194 if (IS_ERR(ctx->clocks[i])) { 1195 ret = PTR_ERR(ctx->clocks[i]); 1196 dev_err(fimc_dev, "failed to get clock: %s\n", 1197 fimc_clock_names[i]); 1198 goto e_clk_free; 1199 } 1200 } 1201 1202 ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]); 1203 if (!ret) 1204 return ret; 1205 e_clk_free: 1206 fimc_put_clocks(ctx); 1207 return ret; 1208 } 1209 1210 int exynos_drm_check_fimc_device(struct device *dev) 1211 { 1212 int id = of_alias_get_id(dev->of_node, "fimc"); 1213 1214 if (id >= 0 && (BIT(id) & fimc_mask)) 1215 return 0; 1216 return -ENODEV; 1217 } 1218 1219 static const unsigned int fimc_formats[] = { 1220 DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, 1221 DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61, 1222 DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU, 1223 DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422, 1224 DRM_FORMAT_YUV444, 1225 }; 1226 1227 static const unsigned int fimc_tiled_formats[] = { 1228 DRM_FORMAT_NV12, DRM_FORMAT_NV21, 1229 }; 1230 1231 static const struct drm_exynos_ipp_limit fimc_4210_limits_v1[] = { 1232 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) }, 1233 { IPP_SIZE_LIMIT(AREA, .h = { 16, 4224, 2 }, .v = { 16, 0, 2 }) }, 1234 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1920 }, .v = { 128, 0 }) }, 1235 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1236 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1237 }; 1238 1239 static const struct drm_exynos_ipp_limit fimc_4210_limits_v2[] = { 1240 { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) }, 1241 { IPP_SIZE_LIMIT(AREA, .h = { 16, 1920, 2 }, .v = { 16, 0, 2 }) }, 1242 { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1366 }, .v = { 128, 0 }) }, 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_v1[] = { 1248 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) }, 1249 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1920, 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 const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2[] = { 1255 { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) }, 1256 { IPP_SIZE_LIMIT(AREA, .h = { 128, 1366, 2 }, .v = { 128, 0, 2 }) }, 1257 { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 }, 1258 .v = { (1 << 16) / 64, (1 << 16) * 64 }) }, 1259 }; 1260 1261 static int fimc_probe(struct platform_device *pdev) 1262 { 1263 const struct drm_exynos_ipp_limit *limits; 1264 struct exynos_drm_ipp_formats *formats; 1265 struct device *dev = &pdev->dev; 1266 struct fimc_context *ctx; 1267 struct resource *res; 1268 int ret; 1269 int i, j, num_limits, num_formats; 1270 1271 if (exynos_drm_check_fimc_device(dev) != 0) 1272 return -ENODEV; 1273 1274 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 1275 if (!ctx) 1276 return -ENOMEM; 1277 1278 ctx->dev = dev; 1279 ctx->id = of_alias_get_id(dev->of_node, "fimc"); 1280 1281 /* construct formats/limits array */ 1282 num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats); 1283 formats = devm_kcalloc(dev, num_formats, sizeof(*formats), 1284 GFP_KERNEL); 1285 if (!formats) 1286 return -ENOMEM; 1287 1288 /* linear formats */ 1289 if (ctx->id < 3) { 1290 limits = fimc_4210_limits_v1; 1291 num_limits = ARRAY_SIZE(fimc_4210_limits_v1); 1292 } else { 1293 limits = fimc_4210_limits_v2; 1294 num_limits = ARRAY_SIZE(fimc_4210_limits_v2); 1295 } 1296 for (i = 0; i < ARRAY_SIZE(fimc_formats); i++) { 1297 formats[i].fourcc = fimc_formats[i]; 1298 formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE | 1299 DRM_EXYNOS_IPP_FORMAT_DESTINATION; 1300 formats[i].limits = limits; 1301 formats[i].num_limits = num_limits; 1302 } 1303 1304 /* tiled formats */ 1305 if (ctx->id < 3) { 1306 limits = fimc_4210_limits_tiled_v1; 1307 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v1); 1308 } else { 1309 limits = fimc_4210_limits_tiled_v2; 1310 num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v2); 1311 } 1312 for (j = i, i = 0; i < ARRAY_SIZE(fimc_tiled_formats); j++, i++) { 1313 formats[j].fourcc = fimc_tiled_formats[i]; 1314 formats[j].modifier = DRM_FORMAT_MOD_SAMSUNG_64_32_TILE; 1315 formats[j].type = DRM_EXYNOS_IPP_FORMAT_SOURCE | 1316 DRM_EXYNOS_IPP_FORMAT_DESTINATION; 1317 formats[j].limits = limits; 1318 formats[j].num_limits = num_limits; 1319 } 1320 1321 ctx->formats = formats; 1322 ctx->num_formats = num_formats; 1323 1324 /* resource memory */ 1325 ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1326 ctx->regs = devm_ioremap_resource(dev, ctx->regs_res); 1327 if (IS_ERR(ctx->regs)) 1328 return PTR_ERR(ctx->regs); 1329 1330 /* resource irq */ 1331 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1332 if (!res) { 1333 dev_err(dev, "failed to request irq resource.\n"); 1334 return -ENOENT; 1335 } 1336 1337 ret = devm_request_irq(dev, res->start, fimc_irq_handler, 1338 0, dev_name(dev), ctx); 1339 if (ret < 0) { 1340 dev_err(dev, "failed to request irq.\n"); 1341 return ret; 1342 } 1343 1344 ret = fimc_setup_clocks(ctx); 1345 if (ret < 0) 1346 return ret; 1347 1348 spin_lock_init(&ctx->lock); 1349 platform_set_drvdata(pdev, ctx); 1350 1351 pm_runtime_use_autosuspend(dev); 1352 pm_runtime_set_autosuspend_delay(dev, FIMC_AUTOSUSPEND_DELAY); 1353 pm_runtime_enable(dev); 1354 1355 ret = component_add(dev, &fimc_component_ops); 1356 if (ret) 1357 goto err_pm_dis; 1358 1359 dev_info(dev, "drm fimc registered successfully.\n"); 1360 1361 return 0; 1362 1363 err_pm_dis: 1364 pm_runtime_dont_use_autosuspend(dev); 1365 pm_runtime_disable(dev); 1366 fimc_put_clocks(ctx); 1367 1368 return ret; 1369 } 1370 1371 static int fimc_remove(struct platform_device *pdev) 1372 { 1373 struct device *dev = &pdev->dev; 1374 struct fimc_context *ctx = get_fimc_context(dev); 1375 1376 component_del(dev, &fimc_component_ops); 1377 pm_runtime_dont_use_autosuspend(dev); 1378 pm_runtime_disable(dev); 1379 1380 fimc_put_clocks(ctx); 1381 1382 return 0; 1383 } 1384 1385 #ifdef CONFIG_PM 1386 static int fimc_runtime_suspend(struct device *dev) 1387 { 1388 struct fimc_context *ctx = get_fimc_context(dev); 1389 1390 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); 1391 clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]); 1392 return 0; 1393 } 1394 1395 static int fimc_runtime_resume(struct device *dev) 1396 { 1397 struct fimc_context *ctx = get_fimc_context(dev); 1398 1399 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); 1400 return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]); 1401 } 1402 #endif 1403 1404 static const struct dev_pm_ops fimc_pm_ops = { 1405 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1406 pm_runtime_force_resume) 1407 SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL) 1408 }; 1409 1410 static const struct of_device_id fimc_of_match[] = { 1411 { .compatible = "samsung,exynos4210-fimc" }, 1412 { .compatible = "samsung,exynos4212-fimc" }, 1413 { }, 1414 }; 1415 MODULE_DEVICE_TABLE(of, fimc_of_match); 1416 1417 struct platform_driver fimc_driver = { 1418 .probe = fimc_probe, 1419 .remove = fimc_remove, 1420 .driver = { 1421 .of_match_table = fimc_of_match, 1422 .name = "exynos-drm-fimc", 1423 .owner = THIS_MODULE, 1424 .pm = &fimc_pm_ops, 1425 }, 1426 }; 1427