root/drivers/gpu/drm/exynos/exynos_drm_fimc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fimc_read
  2. fimc_write
  3. fimc_set_bits
  4. fimc_clear_bits
  5. fimc_sw_reset
  6. fimc_set_type_ctrl
  7. fimc_handle_jpeg
  8. fimc_mask_irq
  9. fimc_clear_irq
  10. fimc_check_ovf
  11. fimc_check_frame_end
  12. fimc_get_buf_id
  13. fimc_handle_lastend
  14. fimc_src_set_fmt_order
  15. fimc_src_set_fmt
  16. fimc_src_set_transf
  17. fimc_set_window
  18. fimc_src_set_size
  19. fimc_src_set_addr
  20. fimc_dst_set_fmt_order
  21. fimc_dst_set_fmt
  22. fimc_dst_set_transf
  23. fimc_set_prescaler
  24. fimc_set_scaler
  25. fimc_dst_set_size
  26. fimc_dst_set_buf_seq
  27. fimc_dst_set_addr
  28. fimc_irq_handler
  29. fimc_clear_addr
  30. fimc_reset
  31. fimc_start
  32. fimc_stop
  33. fimc_commit
  34. fimc_abort
  35. fimc_bind
  36. fimc_unbind
  37. fimc_put_clocks
  38. fimc_setup_clocks
  39. exynos_drm_check_fimc_device
  40. fimc_probe
  41. fimc_remove
  42. fimc_runtime_suspend
  43. fimc_runtime_resume

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

/* [<][>][^][v][top][bottom][index][help] */