root/drivers/media/platform/exynos4-is/fimc-reg.c

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

DEFINITIONS

This source file includes following definitions.
  1. fimc_hw_reset
  2. fimc_hw_get_in_flip
  3. fimc_hw_get_target_flip
  4. fimc_hw_set_rotation
  5. fimc_hw_set_target_format
  6. fimc_hw_set_out_dma_size
  7. fimc_hw_set_out_dma
  8. fimc_hw_en_autoload
  9. fimc_hw_en_lastirq
  10. fimc_hw_set_prescaler
  11. fimc_hw_set_scaler
  12. fimc_hw_set_mainscaler
  13. fimc_hw_enable_capture
  14. fimc_hw_disable_capture
  15. fimc_hw_set_effect
  16. fimc_hw_set_rgb_alpha
  17. fimc_hw_set_in_dma_size
  18. fimc_hw_set_in_dma
  19. fimc_hw_set_input_path
  20. fimc_hw_set_output_path
  21. fimc_hw_set_input_addr
  22. fimc_hw_set_output_addr
  23. fimc_hw_set_camera_polarity
  24. fimc_hw_set_camera_source
  25. fimc_hw_set_camera_offset
  26. fimc_hw_set_camera_type
  27. fimc_hw_clear_irq
  28. fimc_hw_enable_scaler
  29. fimc_hw_activate_input_dma
  30. fimc_hw_get_frame_index
  31. fimc_hw_get_prev_frame_index
  32. fimc_activate_capture
  33. fimc_deactivate_capture
  34. fimc_hw_camblk_cfg_writeback

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Register interface file for Samsung Camera Interface (FIMC) driver
   4  *
   5  * Copyright (C) 2010 - 2013 Samsung Electronics Co., Ltd.
   6  * Sylwester Nawrocki <s.nawrocki@samsung.com>
   7 */
   8 
   9 #include <linux/delay.h>
  10 #include <linux/io.h>
  11 #include <linux/regmap.h>
  12 
  13 #include <media/drv-intf/exynos-fimc.h>
  14 #include "media-dev.h"
  15 
  16 #include "fimc-reg.h"
  17 #include "fimc-core.h"
  18 
  19 void fimc_hw_reset(struct fimc_dev *dev)
  20 {
  21         u32 cfg;
  22 
  23         cfg = readl(dev->regs + FIMC_REG_CISRCFMT);
  24         cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
  25         writel(cfg, dev->regs + FIMC_REG_CISRCFMT);
  26 
  27         /* Software reset. */
  28         cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
  29         cfg |= (FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL);
  30         writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
  31         udelay(10);
  32 
  33         cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
  34         cfg &= ~FIMC_REG_CIGCTRL_SWRST;
  35         writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
  36 
  37         if (dev->drv_data->out_buf_count > 4)
  38                 fimc_hw_set_dma_seq(dev, 0xF);
  39 }
  40 
  41 static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
  42 {
  43         u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL;
  44 
  45         if (ctx->hflip)
  46                 flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR;
  47         if (ctx->vflip)
  48                 flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR;
  49 
  50         if (ctx->rotation <= 90)
  51                 return flip;
  52 
  53         return (flip ^ FIMC_REG_MSCTRL_FLIP_180) & FIMC_REG_MSCTRL_FLIP_180;
  54 }
  55 
  56 static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
  57 {
  58         u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL;
  59 
  60         if (ctx->hflip)
  61                 flip |= FIMC_REG_CITRGFMT_FLIP_Y_MIRROR;
  62         if (ctx->vflip)
  63                 flip |= FIMC_REG_CITRGFMT_FLIP_X_MIRROR;
  64 
  65         if (ctx->rotation <= 90)
  66                 return flip;
  67 
  68         return (flip ^ FIMC_REG_CITRGFMT_FLIP_180) & FIMC_REG_CITRGFMT_FLIP_180;
  69 }
  70 
  71 void fimc_hw_set_rotation(struct fimc_ctx *ctx)
  72 {
  73         u32 cfg, flip;
  74         struct fimc_dev *dev = ctx->fimc_dev;
  75 
  76         cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
  77         cfg &= ~(FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
  78                  FIMC_REG_CITRGFMT_FLIP_180);
  79 
  80         /*
  81          * The input and output rotator cannot work simultaneously.
  82          * Use the output rotator in output DMA mode or the input rotator
  83          * in direct fifo output mode.
  84          */
  85         if (ctx->rotation == 90 || ctx->rotation == 270) {
  86                 if (ctx->out_path == FIMC_IO_LCDFIFO)
  87                         cfg |= FIMC_REG_CITRGFMT_INROT90;
  88                 else
  89                         cfg |= FIMC_REG_CITRGFMT_OUTROT90;
  90         }
  91 
  92         if (ctx->out_path == FIMC_IO_DMA) {
  93                 cfg |= fimc_hw_get_target_flip(ctx);
  94                 writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
  95         } else {
  96                 /* LCD FIFO path */
  97                 flip = readl(dev->regs + FIMC_REG_MSCTRL);
  98                 flip &= ~FIMC_REG_MSCTRL_FLIP_MASK;
  99                 flip |= fimc_hw_get_in_flip(ctx);
 100                 writel(flip, dev->regs + FIMC_REG_MSCTRL);
 101         }
 102 }
 103 
 104 void fimc_hw_set_target_format(struct fimc_ctx *ctx)
 105 {
 106         u32 cfg;
 107         struct fimc_dev *dev = ctx->fimc_dev;
 108         struct fimc_frame *frame = &ctx->d_frame;
 109 
 110         dbg("w= %d, h= %d color: %d", frame->width,
 111             frame->height, frame->fmt->color);
 112 
 113         cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
 114         cfg &= ~(FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
 115                  FIMC_REG_CITRGFMT_VSIZE_MASK);
 116 
 117         switch (frame->fmt->color) {
 118         case FIMC_FMT_RGB444...FIMC_FMT_RGB888:
 119                 cfg |= FIMC_REG_CITRGFMT_RGB;
 120                 break;
 121         case FIMC_FMT_YCBCR420:
 122                 cfg |= FIMC_REG_CITRGFMT_YCBCR420;
 123                 break;
 124         case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
 125                 if (frame->fmt->colplanes == 1)
 126                         cfg |= FIMC_REG_CITRGFMT_YCBCR422_1P;
 127                 else
 128                         cfg |= FIMC_REG_CITRGFMT_YCBCR422;
 129                 break;
 130         default:
 131                 break;
 132         }
 133 
 134         if (ctx->rotation == 90 || ctx->rotation == 270)
 135                 cfg |= (frame->height << 16) | frame->width;
 136         else
 137                 cfg |= (frame->width << 16) | frame->height;
 138 
 139         writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
 140 
 141         cfg = readl(dev->regs + FIMC_REG_CITAREA);
 142         cfg &= ~FIMC_REG_CITAREA_MASK;
 143         cfg |= (frame->width * frame->height);
 144         writel(cfg, dev->regs + FIMC_REG_CITAREA);
 145 }
 146 
 147 static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
 148 {
 149         struct fimc_dev *dev = ctx->fimc_dev;
 150         struct fimc_frame *frame = &ctx->d_frame;
 151         u32 cfg;
 152 
 153         cfg = (frame->f_height << 16) | frame->f_width;
 154         writel(cfg, dev->regs + FIMC_REG_ORGOSIZE);
 155 
 156         /* Select color space conversion equation (HD/SD size).*/
 157         cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
 158         if (frame->f_width >= 1280) /* HD */
 159                 cfg |= FIMC_REG_CIGCTRL_CSC_ITU601_709;
 160         else    /* SD */
 161                 cfg &= ~FIMC_REG_CIGCTRL_CSC_ITU601_709;
 162         writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
 163 
 164 }
 165 
 166 void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
 167 {
 168         struct fimc_dev *dev = ctx->fimc_dev;
 169         struct fimc_frame *frame = &ctx->d_frame;
 170         struct fimc_dma_offset *offset = &frame->dma_offset;
 171         struct fimc_fmt *fmt = frame->fmt;
 172         u32 cfg;
 173 
 174         /* Set the input dma offsets. */
 175         cfg = (offset->y_v << 16) | offset->y_h;
 176         writel(cfg, dev->regs + FIMC_REG_CIOYOFF);
 177 
 178         cfg = (offset->cb_v << 16) | offset->cb_h;
 179         writel(cfg, dev->regs + FIMC_REG_CIOCBOFF);
 180 
 181         cfg = (offset->cr_v << 16) | offset->cr_h;
 182         writel(cfg, dev->regs + FIMC_REG_CIOCROFF);
 183 
 184         fimc_hw_set_out_dma_size(ctx);
 185 
 186         /* Configure chroma components order. */
 187         cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
 188 
 189         cfg &= ~(FIMC_REG_CIOCTRL_ORDER2P_MASK |
 190                  FIMC_REG_CIOCTRL_ORDER422_MASK |
 191                  FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
 192                  FIMC_REG_CIOCTRL_RGB16FMT_MASK);
 193 
 194         if (fmt->colplanes == 1)
 195                 cfg |= ctx->out_order_1p;
 196         else if (fmt->colplanes == 2)
 197                 cfg |= ctx->out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE;
 198         else if (fmt->colplanes == 3)
 199                 cfg |= FIMC_REG_CIOCTRL_YCBCR_3PLANE;
 200 
 201         if (fmt->color == FIMC_FMT_RGB565)
 202                 cfg |= FIMC_REG_CIOCTRL_RGB565;
 203         else if (fmt->color == FIMC_FMT_RGB555)
 204                 cfg |= FIMC_REG_CIOCTRL_ARGB1555;
 205         else if (fmt->color == FIMC_FMT_RGB444)
 206                 cfg |= FIMC_REG_CIOCTRL_ARGB4444;
 207 
 208         writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
 209 }
 210 
 211 static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
 212 {
 213         u32 cfg = readl(dev->regs + FIMC_REG_ORGISIZE);
 214         if (enable)
 215                 cfg |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
 216         else
 217                 cfg &= ~FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
 218         writel(cfg, dev->regs + FIMC_REG_ORGISIZE);
 219 }
 220 
 221 void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
 222 {
 223         u32 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
 224         if (enable)
 225                 cfg |= FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
 226         else
 227                 cfg &= ~FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
 228         writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
 229 }
 230 
 231 void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
 232 {
 233         struct fimc_dev *dev =  ctx->fimc_dev;
 234         struct fimc_scaler *sc = &ctx->scaler;
 235         u32 cfg, shfactor;
 236 
 237         shfactor = 10 - (sc->hfactor + sc->vfactor);
 238         cfg = shfactor << 28;
 239 
 240         cfg |= (sc->pre_hratio << 16) | sc->pre_vratio;
 241         writel(cfg, dev->regs + FIMC_REG_CISCPRERATIO);
 242 
 243         cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
 244         writel(cfg, dev->regs + FIMC_REG_CISCPREDST);
 245 }
 246 
 247 static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
 248 {
 249         struct fimc_dev *dev = ctx->fimc_dev;
 250         struct fimc_scaler *sc = &ctx->scaler;
 251         struct fimc_frame *src_frame = &ctx->s_frame;
 252         struct fimc_frame *dst_frame = &ctx->d_frame;
 253 
 254         u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
 255 
 256         cfg &= ~(FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
 257                  FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
 258                  FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
 259                  FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
 260                  FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT);
 261 
 262         if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
 263                 cfg |= (FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
 264                         FIMC_REG_CISCCTRL_CSCY2R_WIDE);
 265 
 266         if (!sc->enabled)
 267                 cfg |= FIMC_REG_CISCCTRL_SCALERBYPASS;
 268 
 269         if (sc->scaleup_h)
 270                 cfg |= FIMC_REG_CISCCTRL_SCALEUP_H;
 271 
 272         if (sc->scaleup_v)
 273                 cfg |= FIMC_REG_CISCCTRL_SCALEUP_V;
 274 
 275         if (sc->copy_mode)
 276                 cfg |= FIMC_REG_CISCCTRL_ONE2ONE;
 277 
 278         if (ctx->in_path == FIMC_IO_DMA) {
 279                 switch (src_frame->fmt->color) {
 280                 case FIMC_FMT_RGB565:
 281                         cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB565;
 282                         break;
 283                 case FIMC_FMT_RGB666:
 284                         cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB666;
 285                         break;
 286                 case FIMC_FMT_RGB888:
 287                         cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB888;
 288                         break;
 289                 }
 290         }
 291 
 292         if (ctx->out_path == FIMC_IO_DMA) {
 293                 u32 color = dst_frame->fmt->color;
 294 
 295                 if (color >= FIMC_FMT_RGB444 && color <= FIMC_FMT_RGB565)
 296                         cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565;
 297                 else if (color == FIMC_FMT_RGB666)
 298                         cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666;
 299                 else if (color == FIMC_FMT_RGB888)
 300                         cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
 301         } else {
 302                 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
 303 
 304                 if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
 305                         cfg |= FIMC_REG_CISCCTRL_INTERLACE;
 306         }
 307 
 308         writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
 309 }
 310 
 311 void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
 312 {
 313         struct fimc_dev *dev = ctx->fimc_dev;
 314         const struct fimc_variant *variant = dev->variant;
 315         struct fimc_scaler *sc = &ctx->scaler;
 316         u32 cfg;
 317 
 318         dbg("main_hratio= 0x%X  main_vratio= 0x%X",
 319             sc->main_hratio, sc->main_vratio);
 320 
 321         fimc_hw_set_scaler(ctx);
 322 
 323         cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
 324         cfg &= ~(FIMC_REG_CISCCTRL_MHRATIO_MASK |
 325                  FIMC_REG_CISCCTRL_MVRATIO_MASK);
 326 
 327         if (variant->has_mainscaler_ext) {
 328                 cfg |= FIMC_REG_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
 329                 cfg |= FIMC_REG_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
 330                 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
 331 
 332                 cfg = readl(dev->regs + FIMC_REG_CIEXTEN);
 333 
 334                 cfg &= ~(FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
 335                          FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK);
 336                 cfg |= FIMC_REG_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
 337                 cfg |= FIMC_REG_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
 338                 writel(cfg, dev->regs + FIMC_REG_CIEXTEN);
 339         } else {
 340                 cfg |= FIMC_REG_CISCCTRL_MHRATIO(sc->main_hratio);
 341                 cfg |= FIMC_REG_CISCCTRL_MVRATIO(sc->main_vratio);
 342                 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
 343         }
 344 }
 345 
 346 void fimc_hw_enable_capture(struct fimc_ctx *ctx)
 347 {
 348         struct fimc_dev *dev = ctx->fimc_dev;
 349         u32 cfg;
 350 
 351         cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
 352         cfg |= FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE;
 353 
 354         if (ctx->scaler.enabled)
 355                 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
 356         else
 357                 cfg &= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
 358 
 359         cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
 360         writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
 361 }
 362 
 363 void fimc_hw_disable_capture(struct fimc_dev *dev)
 364 {
 365         u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
 366         cfg &= ~(FIMC_REG_CIIMGCPT_IMGCPTEN |
 367                  FIMC_REG_CIIMGCPT_IMGCPTEN_SC);
 368         writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
 369 }
 370 
 371 void fimc_hw_set_effect(struct fimc_ctx *ctx)
 372 {
 373         struct fimc_dev *dev = ctx->fimc_dev;
 374         struct fimc_effect *effect = &ctx->effect;
 375         u32 cfg = 0;
 376 
 377         if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
 378                 cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
 379                         FIMC_REG_CIIMGEFF_IE_ENABLE;
 380                 cfg |= effect->type;
 381                 if (effect->type == FIMC_REG_CIIMGEFF_FIN_ARBITRARY)
 382                         cfg |= (effect->pat_cb << 13) | effect->pat_cr;
 383         }
 384 
 385         writel(cfg, dev->regs + FIMC_REG_CIIMGEFF);
 386 }
 387 
 388 void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
 389 {
 390         struct fimc_dev *dev = ctx->fimc_dev;
 391         struct fimc_frame *frame = &ctx->d_frame;
 392         u32 cfg;
 393 
 394         if (!(frame->fmt->flags & FMT_HAS_ALPHA))
 395                 return;
 396 
 397         cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
 398         cfg &= ~FIMC_REG_CIOCTRL_ALPHA_OUT_MASK;
 399         cfg |= (frame->alpha << 4);
 400         writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
 401 }
 402 
 403 static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
 404 {
 405         struct fimc_dev *dev = ctx->fimc_dev;
 406         struct fimc_frame *frame = &ctx->s_frame;
 407         u32 cfg_o = 0;
 408         u32 cfg_r = 0;
 409 
 410         if (FIMC_IO_LCDFIFO == ctx->out_path)
 411                 cfg_r |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
 412 
 413         cfg_o |= (frame->f_height << 16) | frame->f_width;
 414         cfg_r |= (frame->height << 16) | frame->width;
 415 
 416         writel(cfg_o, dev->regs + FIMC_REG_ORGISIZE);
 417         writel(cfg_r, dev->regs + FIMC_REG_CIREAL_ISIZE);
 418 }
 419 
 420 void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
 421 {
 422         struct fimc_dev *dev = ctx->fimc_dev;
 423         struct fimc_frame *frame = &ctx->s_frame;
 424         struct fimc_dma_offset *offset = &frame->dma_offset;
 425         u32 cfg;
 426 
 427         /* Set the pixel offsets. */
 428         cfg = (offset->y_v << 16) | offset->y_h;
 429         writel(cfg, dev->regs + FIMC_REG_CIIYOFF);
 430 
 431         cfg = (offset->cb_v << 16) | offset->cb_h;
 432         writel(cfg, dev->regs + FIMC_REG_CIICBOFF);
 433 
 434         cfg = (offset->cr_v << 16) | offset->cr_h;
 435         writel(cfg, dev->regs + FIMC_REG_CIICROFF);
 436 
 437         /* Input original and real size. */
 438         fimc_hw_set_in_dma_size(ctx);
 439 
 440         /* Use DMA autoload only in FIFO mode. */
 441         fimc_hw_en_autoload(dev, ctx->out_path == FIMC_IO_LCDFIFO);
 442 
 443         /* Set the input DMA to process single frame only. */
 444         cfg = readl(dev->regs + FIMC_REG_MSCTRL);
 445         cfg &= ~(FIMC_REG_MSCTRL_INFORMAT_MASK
 446                  | FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
 447                  | FIMC_REG_MSCTRL_INPUT_MASK
 448                  | FIMC_REG_MSCTRL_C_INT_IN_MASK
 449                  | FIMC_REG_MSCTRL_2P_IN_ORDER_MASK
 450                  | FIMC_REG_MSCTRL_ORDER422_MASK);
 451 
 452         cfg |= (FIMC_REG_MSCTRL_IN_BURST_COUNT(4)
 453                 | FIMC_REG_MSCTRL_INPUT_MEMORY
 454                 | FIMC_REG_MSCTRL_FIFO_CTRL_FULL);
 455 
 456         switch (frame->fmt->color) {
 457         case FIMC_FMT_RGB565...FIMC_FMT_RGB888:
 458                 cfg |= FIMC_REG_MSCTRL_INFORMAT_RGB;
 459                 break;
 460         case FIMC_FMT_YCBCR420:
 461                 cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR420;
 462 
 463                 if (frame->fmt->colplanes == 2)
 464                         cfg |= ctx->in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
 465                 else
 466                         cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
 467 
 468                 break;
 469         case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
 470                 if (frame->fmt->colplanes == 1) {
 471                         cfg |= ctx->in_order_1p
 472                                 | FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P;
 473                 } else {
 474                         cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR422;
 475 
 476                         if (frame->fmt->colplanes == 2)
 477                                 cfg |= ctx->in_order_2p
 478                                         | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
 479                         else
 480                                 cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
 481                 }
 482                 break;
 483         default:
 484                 break;
 485         }
 486 
 487         writel(cfg, dev->regs + FIMC_REG_MSCTRL);
 488 
 489         /* Input/output DMA linear/tiled mode. */
 490         cfg = readl(dev->regs + FIMC_REG_CIDMAPARAM);
 491         cfg &= ~FIMC_REG_CIDMAPARAM_TILE_MASK;
 492 
 493         if (tiled_fmt(ctx->s_frame.fmt))
 494                 cfg |= FIMC_REG_CIDMAPARAM_R_64X32;
 495 
 496         if (tiled_fmt(ctx->d_frame.fmt))
 497                 cfg |= FIMC_REG_CIDMAPARAM_W_64X32;
 498 
 499         writel(cfg, dev->regs + FIMC_REG_CIDMAPARAM);
 500 }
 501 
 502 
 503 void fimc_hw_set_input_path(struct fimc_ctx *ctx)
 504 {
 505         struct fimc_dev *dev = ctx->fimc_dev;
 506 
 507         u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
 508         cfg &= ~FIMC_REG_MSCTRL_INPUT_MASK;
 509 
 510         if (ctx->in_path == FIMC_IO_DMA)
 511                 cfg |= FIMC_REG_MSCTRL_INPUT_MEMORY;
 512         else
 513                 cfg |= FIMC_REG_MSCTRL_INPUT_EXTCAM;
 514 
 515         writel(cfg, dev->regs + FIMC_REG_MSCTRL);
 516 }
 517 
 518 void fimc_hw_set_output_path(struct fimc_ctx *ctx)
 519 {
 520         struct fimc_dev *dev = ctx->fimc_dev;
 521 
 522         u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
 523         cfg &= ~FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
 524         if (ctx->out_path == FIMC_IO_LCDFIFO)
 525                 cfg |= FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
 526         writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
 527 }
 528 
 529 void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr)
 530 {
 531         u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
 532         cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
 533         writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
 534 
 535         writel(paddr->y, dev->regs + FIMC_REG_CIIYSA(0));
 536         writel(paddr->cb, dev->regs + FIMC_REG_CIICBSA(0));
 537         writel(paddr->cr, dev->regs + FIMC_REG_CIICRSA(0));
 538 
 539         cfg &= ~FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
 540         writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
 541 }
 542 
 543 void fimc_hw_set_output_addr(struct fimc_dev *dev,
 544                              struct fimc_addr *paddr, int index)
 545 {
 546         int i = (index == -1) ? 0 : index;
 547         do {
 548                 writel(paddr->y, dev->regs + FIMC_REG_CIOYSA(i));
 549                 writel(paddr->cb, dev->regs + FIMC_REG_CIOCBSA(i));
 550                 writel(paddr->cr, dev->regs + FIMC_REG_CIOCRSA(i));
 551                 dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
 552                     i, paddr->y, paddr->cb, paddr->cr);
 553         } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
 554 }
 555 
 556 int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
 557                                 struct fimc_source_info *cam)
 558 {
 559         u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
 560 
 561         cfg &= ~(FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
 562                  FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
 563                  FIMC_REG_CIGCTRL_INVPOLFIELD);
 564 
 565         if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 566                 cfg |= FIMC_REG_CIGCTRL_INVPOLPCLK;
 567 
 568         if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
 569                 cfg |= FIMC_REG_CIGCTRL_INVPOLVSYNC;
 570 
 571         if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
 572                 cfg |= FIMC_REG_CIGCTRL_INVPOLHREF;
 573 
 574         if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
 575                 cfg |= FIMC_REG_CIGCTRL_INVPOLHSYNC;
 576 
 577         if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
 578                 cfg |= FIMC_REG_CIGCTRL_INVPOLFIELD;
 579 
 580         writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
 581 
 582         return 0;
 583 }
 584 
 585 struct mbus_pixfmt_desc {
 586         u32 pixelcode;
 587         u32 cisrcfmt;
 588         u16 bus_width;
 589 };
 590 
 591 static const struct mbus_pixfmt_desc pix_desc[] = {
 592         { MEDIA_BUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
 593         { MEDIA_BUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
 594         { MEDIA_BUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
 595         { MEDIA_BUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
 596 };
 597 
 598 int fimc_hw_set_camera_source(struct fimc_dev *fimc,
 599                               struct fimc_source_info *source)
 600 {
 601         struct fimc_vid_cap *vc = &fimc->vid_cap;
 602         struct fimc_frame *f = &vc->ctx->s_frame;
 603         u32 bus_width, cfg = 0;
 604         int i;
 605 
 606         switch (source->fimc_bus_type) {
 607         case FIMC_BUS_TYPE_ITU_601:
 608         case FIMC_BUS_TYPE_ITU_656:
 609                 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
 610                         if (vc->ci_fmt.code == pix_desc[i].pixelcode) {
 611                                 cfg = pix_desc[i].cisrcfmt;
 612                                 bus_width = pix_desc[i].bus_width;
 613                                 break;
 614                         }
 615                 }
 616 
 617                 if (i == ARRAY_SIZE(pix_desc)) {
 618                         v4l2_err(&vc->ve.vdev,
 619                                  "Camera color format not supported: %d\n",
 620                                  vc->ci_fmt.code);
 621                         return -EINVAL;
 622                 }
 623 
 624                 if (source->fimc_bus_type == FIMC_BUS_TYPE_ITU_601) {
 625                         if (bus_width == 8)
 626                                 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
 627                         else if (bus_width == 16)
 628                                 cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
 629                 } /* else defaults to ITU-R BT.656 8-bit */
 630                 break;
 631         case FIMC_BUS_TYPE_MIPI_CSI2:
 632                 if (fimc_fmt_is_user_defined(f->fmt->color))
 633                         cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
 634                 break;
 635         default:
 636         case FIMC_BUS_TYPE_ISP_WRITEBACK:
 637                 /* Anything to do here ? */
 638                 break;
 639         }
 640 
 641         cfg |= (f->o_width << 16) | f->o_height;
 642         writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
 643         return 0;
 644 }
 645 
 646 void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
 647 {
 648         u32 hoff2, voff2;
 649 
 650         u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);
 651 
 652         cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
 653         cfg |=  FIMC_REG_CIWDOFST_OFF_EN |
 654                 (f->offs_h << 16) | f->offs_v;
 655 
 656         writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);
 657 
 658         /* See CIWDOFSTn register description in the datasheet for details. */
 659         hoff2 = f->o_width - f->width - f->offs_h;
 660         voff2 = f->o_height - f->height - f->offs_v;
 661         cfg = (hoff2 << 16) | voff2;
 662         writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
 663 }
 664 
 665 int fimc_hw_set_camera_type(struct fimc_dev *fimc,
 666                             struct fimc_source_info *source)
 667 {
 668         struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
 669         u32 csis_data_alignment = 32;
 670         u32 cfg, tmp;
 671 
 672         cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
 673 
 674         /* Select ITU B interface, disable Writeback path and test pattern. */
 675         cfg &= ~(FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
 676                 FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
 677                 FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG |
 678                 FIMC_REG_CIGCTRL_SELWB_A);
 679 
 680         switch (source->fimc_bus_type) {
 681         case FIMC_BUS_TYPE_MIPI_CSI2:
 682                 cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI;
 683 
 684                 if (source->mux_id == 0)
 685                         cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI_A;
 686 
 687                 /* TODO: add remaining supported formats. */
 688                 switch (vid_cap->ci_fmt.code) {
 689                 case MEDIA_BUS_FMT_VYUY8_2X8:
 690                         tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
 691                         break;
 692                 case MEDIA_BUS_FMT_JPEG_1X8:
 693                 case MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8:
 694                         tmp = FIMC_REG_CSIIMGFMT_USER(1);
 695                         cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
 696                         break;
 697                 default:
 698                         v4l2_err(&vid_cap->ve.vdev,
 699                                  "Not supported camera pixel format: %#x\n",
 700                                  vid_cap->ci_fmt.code);
 701                         return -EINVAL;
 702                 }
 703                 tmp |= (csis_data_alignment == 32) << 8;
 704 
 705                 writel(tmp, fimc->regs + FIMC_REG_CSIIMGFMT);
 706                 break;
 707         case FIMC_BUS_TYPE_ITU_601...FIMC_BUS_TYPE_ITU_656:
 708                 if (source->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
 709                         cfg |= FIMC_REG_CIGCTRL_SELCAM_ITU_A;
 710                 break;
 711         case FIMC_BUS_TYPE_LCD_WRITEBACK_A:
 712                 cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
 713                 /* fall through */
 714         case FIMC_BUS_TYPE_ISP_WRITEBACK:
 715                 if (fimc->variant->has_isp_wb)
 716                         cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
 717                 else
 718                         WARN_ONCE(1, "ISP Writeback input is not supported\n");
 719                 break;
 720         default:
 721                 v4l2_err(&vid_cap->ve.vdev,
 722                          "Invalid FIMC bus type selected: %d\n",
 723                          source->fimc_bus_type);
 724                 return -EINVAL;
 725         }
 726         writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
 727 
 728         return 0;
 729 }
 730 
 731 void fimc_hw_clear_irq(struct fimc_dev *dev)
 732 {
 733         u32 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
 734         cfg |= FIMC_REG_CIGCTRL_IRQ_CLR;
 735         writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
 736 }
 737 
 738 void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
 739 {
 740         u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
 741         if (on)
 742                 cfg |= FIMC_REG_CISCCTRL_SCALERSTART;
 743         else
 744                 cfg &= ~FIMC_REG_CISCCTRL_SCALERSTART;
 745         writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
 746 }
 747 
 748 void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
 749 {
 750         u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
 751         if (on)
 752                 cfg |= FIMC_REG_MSCTRL_ENVID;
 753         else
 754                 cfg &= ~FIMC_REG_MSCTRL_ENVID;
 755         writel(cfg, dev->regs + FIMC_REG_MSCTRL);
 756 }
 757 
 758 /* Return an index to the buffer actually being written. */
 759 s32 fimc_hw_get_frame_index(struct fimc_dev *dev)
 760 {
 761         s32 reg;
 762 
 763         if (dev->drv_data->cistatus2) {
 764                 reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3f;
 765                 return reg - 1;
 766         }
 767 
 768         reg = readl(dev->regs + FIMC_REG_CISTATUS);
 769 
 770         return (reg & FIMC_REG_CISTATUS_FRAMECNT_MASK) >>
 771                 FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
 772 }
 773 
 774 /* Return an index to the buffer being written previously. */
 775 s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev)
 776 {
 777         s32 reg;
 778 
 779         if (!dev->drv_data->cistatus2)
 780                 return -1;
 781 
 782         reg = readl(dev->regs + FIMC_REG_CISTATUS2);
 783         return ((reg >> 7) & 0x3f) - 1;
 784 }
 785 
 786 /* Locking: the caller holds fimc->slock */
 787 void fimc_activate_capture(struct fimc_ctx *ctx)
 788 {
 789         fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
 790         fimc_hw_enable_capture(ctx);
 791 }
 792 
 793 void fimc_deactivate_capture(struct fimc_dev *fimc)
 794 {
 795         fimc_hw_en_lastirq(fimc, true);
 796         fimc_hw_disable_capture(fimc);
 797         fimc_hw_enable_scaler(fimc, false);
 798         fimc_hw_en_lastirq(fimc, false);
 799 }
 800 
 801 int fimc_hw_camblk_cfg_writeback(struct fimc_dev *fimc)
 802 {
 803         struct regmap *map = fimc->sysreg;
 804         unsigned int mask, val, camblk_cfg;
 805         int ret;
 806 
 807         if (map == NULL)
 808                 return 0;
 809 
 810         ret = regmap_read(map, SYSREG_CAMBLK, &camblk_cfg);
 811         if (ret < 0 || ((camblk_cfg & 0x00700000) >> 20 != 0x3))
 812                 return ret;
 813 
 814         if (!WARN(fimc->id >= 3, "not supported id: %d\n", fimc->id))
 815                 val = 0x1 << (fimc->id + 20);
 816         else
 817                 val = 0;
 818 
 819         mask = SYSREG_CAMBLK_FIFORST_ISP | SYSREG_CAMBLK_ISPWB_FULL_EN;
 820         ret = regmap_update_bits(map, SYSREG_CAMBLK, mask, val);
 821         if (ret < 0)
 822                 return ret;
 823 
 824         usleep_range(1000, 2000);
 825 
 826         val |= SYSREG_CAMBLK_FIFORST_ISP;
 827         ret = regmap_update_bits(map, SYSREG_CAMBLK, mask, val);
 828         if (ret < 0)
 829                 return ret;
 830 
 831         mask = SYSREG_ISPBLK_FIFORST_CAM_BLK;
 832         ret = regmap_update_bits(map, SYSREG_ISPBLK, mask, ~mask);
 833         if (ret < 0)
 834                 return ret;
 835 
 836         usleep_range(1000, 2000);
 837 
 838         return regmap_update_bits(map, SYSREG_ISPBLK, mask, mask);
 839 }

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