root/drivers/media/platform/s3c-camif/camif-regs.c

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

DEFINITIONS

This source file includes following definitions.
  1. camif_hw_reset
  2. camif_hw_clear_pending_irq
  3. camif_hw_set_test_pattern
  4. camif_hw_set_effect
  5. camif_hw_set_source_format
  6. camif_hw_set_camera_crop
  7. camif_hw_clear_fifo_overflow
  8. camif_hw_set_camera_bus
  9. camif_hw_set_output_addr
  10. camif_hw_set_out_dma_size
  11. camif_get_dma_burst
  12. camif_hw_set_output_dma
  13. camif_hw_set_input_path
  14. camif_hw_set_target_format
  15. camif_hw_set_flip
  16. camif_hw_set_prescaler
  17. camif_s3c244x_hw_set_scaler
  18. camif_s3c64xx_hw_set_scaler
  19. camif_hw_set_scaler
  20. camif_hw_enable_scaler
  21. camif_hw_set_lastirq
  22. camif_hw_enable_capture
  23. camif_hw_disable_capture
  24. camif_hw_dump_regs

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Samsung s3c24xx/s3c64xx SoC CAMIF driver
   4  *
   5  * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
   6  * Copyright (C) 2012 Tomasz Figa <tomasz.figa@gmail.com>
   7 */
   8 #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
   9 
  10 #include <linux/delay.h>
  11 #include "camif-regs.h"
  12 
  13 #define camif_write(_camif, _off, _val) writel(_val, (_camif)->io_base + (_off))
  14 #define camif_read(_camif, _off)        readl((_camif)->io_base + (_off))
  15 
  16 void camif_hw_reset(struct camif_dev *camif)
  17 {
  18         u32 cfg;
  19 
  20         cfg = camif_read(camif, S3C_CAMIF_REG_CISRCFMT);
  21         cfg |= CISRCFMT_ITU601_8BIT;
  22         camif_write(camif, S3C_CAMIF_REG_CISRCFMT, cfg);
  23 
  24         /* S/W reset */
  25         cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
  26         cfg |= CIGCTRL_SWRST;
  27         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV)
  28                 cfg |= CIGCTRL_IRQ_LEVEL;
  29         camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
  30         udelay(10);
  31 
  32         cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
  33         cfg &= ~CIGCTRL_SWRST;
  34         camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
  35         udelay(10);
  36 }
  37 
  38 void camif_hw_clear_pending_irq(struct camif_vp *vp)
  39 {
  40         u32 cfg = camif_read(vp->camif, S3C_CAMIF_REG_CIGCTRL);
  41         cfg |= CIGCTRL_IRQ_CLR(vp->id);
  42         camif_write(vp->camif, S3C_CAMIF_REG_CIGCTRL, cfg);
  43 }
  44 
  45 /*
  46  * Sets video test pattern (off, color bar, horizontal or vertical gradient).
  47  * External sensor pixel clock must be active for the test pattern to work.
  48  */
  49 void camif_hw_set_test_pattern(struct camif_dev *camif, unsigned int pattern)
  50 {
  51         u32 cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
  52         cfg &= ~CIGCTRL_TESTPATTERN_MASK;
  53         cfg |= (pattern << 27);
  54         camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
  55 }
  56 
  57 void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect,
  58                         unsigned int cr, unsigned int cb)
  59 {
  60         static const struct v4l2_control colorfx[] = {
  61                 { V4L2_COLORFX_NONE,            CIIMGEFF_FIN_BYPASS },
  62                 { V4L2_COLORFX_BW,              CIIMGEFF_FIN_ARBITRARY },
  63                 { V4L2_COLORFX_SEPIA,           CIIMGEFF_FIN_ARBITRARY },
  64                 { V4L2_COLORFX_NEGATIVE,        CIIMGEFF_FIN_NEGATIVE },
  65                 { V4L2_COLORFX_ART_FREEZE,      CIIMGEFF_FIN_ARTFREEZE },
  66                 { V4L2_COLORFX_EMBOSS,          CIIMGEFF_FIN_EMBOSSING },
  67                 { V4L2_COLORFX_SILHOUETTE,      CIIMGEFF_FIN_SILHOUETTE },
  68                 { V4L2_COLORFX_SET_CBCR,        CIIMGEFF_FIN_ARBITRARY },
  69         };
  70         unsigned int i, cfg;
  71 
  72         for (i = 0; i < ARRAY_SIZE(colorfx); i++)
  73                 if (colorfx[i].id == effect)
  74                         break;
  75 
  76         if (i == ARRAY_SIZE(colorfx))
  77                 return;
  78 
  79         cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset));
  80         /* Set effect */
  81         cfg &= ~CIIMGEFF_FIN_MASK;
  82         cfg |= colorfx[i].value;
  83         /* Set both paths */
  84         if (camif->variant->ip_revision >= S3C6400_CAMIF_IP_REV) {
  85                 if (effect == V4L2_COLORFX_NONE)
  86                         cfg &= ~CIIMGEFF_IE_ENABLE_MASK;
  87                 else
  88                         cfg |= CIIMGEFF_IE_ENABLE_MASK;
  89         }
  90         cfg &= ~CIIMGEFF_PAT_CBCR_MASK;
  91         cfg |= cr | (cb << 13);
  92         camif_write(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset), cfg);
  93 }
  94 
  95 static const u32 src_pixfmt_map[8][2] = {
  96         { MEDIA_BUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR },
  97         { MEDIA_BUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB },
  98         { MEDIA_BUS_FMT_UYVY8_2X8, CISRCFMT_ORDER422_CBYCRY },
  99         { MEDIA_BUS_FMT_VYUY8_2X8, CISRCFMT_ORDER422_CRYCBY },
 100 };
 101 
 102 /* Set camera input pixel format and resolution */
 103 void camif_hw_set_source_format(struct camif_dev *camif)
 104 {
 105         struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
 106         int i;
 107         u32 cfg;
 108 
 109         for (i = ARRAY_SIZE(src_pixfmt_map) - 1; i >= 0; i--) {
 110                 if (src_pixfmt_map[i][0] == mf->code)
 111                         break;
 112         }
 113         if (i < 0) {
 114                 i = 0;
 115                 dev_err(camif->dev,
 116                         "Unsupported pixel code, falling back to %#08x\n",
 117                         src_pixfmt_map[i][0]);
 118         }
 119 
 120         cfg = camif_read(camif, S3C_CAMIF_REG_CISRCFMT);
 121         cfg &= ~(CISRCFMT_ORDER422_MASK | CISRCFMT_SIZE_CAM_MASK);
 122         cfg |= (mf->width << 16) | mf->height;
 123         cfg |= src_pixfmt_map[i][1];
 124         camif_write(camif, S3C_CAMIF_REG_CISRCFMT, cfg);
 125 }
 126 
 127 /* Set the camera host input window offsets (cropping) */
 128 void camif_hw_set_camera_crop(struct camif_dev *camif)
 129 {
 130         struct v4l2_mbus_framefmt *mf = &camif->mbus_fmt;
 131         struct v4l2_rect *crop = &camif->camif_crop;
 132         u32 hoff2, voff2;
 133         u32 cfg;
 134 
 135         /* Note: s3c244x requirement: left = f_width - rect.width / 2 */
 136         cfg = camif_read(camif, S3C_CAMIF_REG_CIWDOFST);
 137         cfg &= ~(CIWDOFST_OFST_MASK | CIWDOFST_WINOFSEN);
 138         cfg |= (crop->left << 16) | crop->top;
 139         if (crop->left != 0 || crop->top != 0)
 140                 cfg |= CIWDOFST_WINOFSEN;
 141         camif_write(camif, S3C_CAMIF_REG_CIWDOFST, cfg);
 142 
 143         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
 144                 hoff2 = mf->width - crop->width - crop->left;
 145                 voff2 = mf->height - crop->height - crop->top;
 146                 cfg = (hoff2 << 16) | voff2;
 147                 camif_write(camif, S3C_CAMIF_REG_CIWDOFST2, cfg);
 148         }
 149 }
 150 
 151 void camif_hw_clear_fifo_overflow(struct camif_vp *vp)
 152 {
 153         struct camif_dev *camif = vp->camif;
 154         u32 cfg;
 155 
 156         cfg = camif_read(camif, S3C_CAMIF_REG_CIWDOFST);
 157         if (vp->id == 0)
 158                 cfg |= (CIWDOFST_CLROVCOFIY | CIWDOFST_CLROVCOFICB |
 159                         CIWDOFST_CLROVCOFICR);
 160         else
 161                 cfg |= (/* CIWDOFST_CLROVPRFIY | */ CIWDOFST_CLROVPRFICB |
 162                         CIWDOFST_CLROVPRFICR);
 163         camif_write(camif, S3C_CAMIF_REG_CIWDOFST, cfg);
 164 }
 165 
 166 /* Set video bus signals polarity */
 167 void camif_hw_set_camera_bus(struct camif_dev *camif)
 168 {
 169         unsigned int flags = camif->pdata.sensor.flags;
 170 
 171         u32 cfg = camif_read(camif, S3C_CAMIF_REG_CIGCTRL);
 172 
 173         cfg &= ~(CIGCTRL_INVPOLPCLK | CIGCTRL_INVPOLVSYNC |
 174                  CIGCTRL_INVPOLHREF | CIGCTRL_INVPOLFIELD);
 175 
 176         if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 177                 cfg |= CIGCTRL_INVPOLPCLK;
 178 
 179         if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
 180                 cfg |= CIGCTRL_INVPOLVSYNC;
 181         /*
 182          * HREF is normally high during frame active data
 183          * transmission and low during horizontal synchronization
 184          * period. Thus HREF active high means HSYNC active low.
 185          */
 186         if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
 187                 cfg |= CIGCTRL_INVPOLHREF; /* HREF active low */
 188 
 189         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
 190                 if (flags & V4L2_MBUS_FIELD_EVEN_LOW)
 191                         cfg |= CIGCTRL_INVPOLFIELD;
 192                 cfg |= CIGCTRL_FIELDMODE;
 193         }
 194 
 195         pr_debug("Setting CIGCTRL to: %#x\n", cfg);
 196 
 197         camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
 198 }
 199 
 200 void camif_hw_set_output_addr(struct camif_vp *vp,
 201                               struct camif_addr *paddr, int i)
 202 {
 203         struct camif_dev *camif = vp->camif;
 204 
 205         camif_write(camif, S3C_CAMIF_REG_CIYSA(vp->id, i), paddr->y);
 206         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV
 207                 || vp->id == VP_CODEC) {
 208                 camif_write(camif, S3C_CAMIF_REG_CICBSA(vp->id, i),
 209                                                                 paddr->cb);
 210                 camif_write(camif, S3C_CAMIF_REG_CICRSA(vp->id, i),
 211                                                                 paddr->cr);
 212         }
 213 
 214         pr_debug("dst_buf[%d]: %pad, cb: %pad, cr: %pad\n",
 215                  i, &paddr->y, &paddr->cb, &paddr->cr);
 216 }
 217 
 218 static void camif_hw_set_out_dma_size(struct camif_vp *vp)
 219 {
 220         struct camif_frame *frame = &vp->out_frame;
 221         u32 cfg;
 222 
 223         cfg = camif_read(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
 224         cfg &= ~CITRGFMT_TARGETSIZE_MASK;
 225         cfg |= (frame->f_width << 16) | frame->f_height;
 226         camif_write(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
 227 }
 228 
 229 static void camif_get_dma_burst(u32 width, u32 ybpp, u32 *mburst, u32 *rburst)
 230 {
 231         unsigned int nwords = width * ybpp / 4;
 232         unsigned int div, rem;
 233 
 234         if (WARN_ON(width < 8 || (width * ybpp) & 7))
 235                 return;
 236 
 237         for (div = 16; div >= 2; div /= 2) {
 238                 if (nwords < div)
 239                         continue;
 240 
 241                 rem = nwords & (div - 1);
 242                 if (rem == 0) {
 243                         *mburst = div;
 244                         *rburst = div;
 245                         break;
 246                 }
 247                 if (rem == div / 2 || rem == div / 4) {
 248                         *mburst = div;
 249                         *rburst = rem;
 250                         break;
 251                 }
 252         }
 253 }
 254 
 255 void camif_hw_set_output_dma(struct camif_vp *vp)
 256 {
 257         struct camif_dev *camif = vp->camif;
 258         struct camif_frame *frame = &vp->out_frame;
 259         const struct camif_fmt *fmt = vp->out_fmt;
 260         unsigned int ymburst = 0, yrburst = 0;
 261         u32 cfg;
 262 
 263         camif_hw_set_out_dma_size(vp);
 264 
 265         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV) {
 266                 struct camif_dma_offset *offset = &frame->dma_offset;
 267                 /* Set the input dma offsets. */
 268                 cfg = S3C_CISS_OFFS_INITIAL(offset->initial);
 269                 cfg |= S3C_CISS_OFFS_LINE(offset->line);
 270                 camif_write(camif, S3C_CAMIF_REG_CISSY(vp->id), cfg);
 271                 camif_write(camif, S3C_CAMIF_REG_CISSCB(vp->id), cfg);
 272                 camif_write(camif, S3C_CAMIF_REG_CISSCR(vp->id), cfg);
 273         }
 274 
 275         /* Configure DMA burst values */
 276         camif_get_dma_burst(frame->rect.width, fmt->ybpp, &ymburst, &yrburst);
 277 
 278         cfg = camif_read(camif, S3C_CAMIF_REG_CICTRL(vp->id, vp->offset));
 279         cfg &= ~CICTRL_BURST_MASK;
 280 
 281         cfg |= CICTRL_YBURST1(ymburst) | CICTRL_YBURST2(yrburst);
 282         cfg |= CICTRL_CBURST1(ymburst / 2) | CICTRL_CBURST2(yrburst / 2);
 283 
 284         camif_write(camif, S3C_CAMIF_REG_CICTRL(vp->id, vp->offset), cfg);
 285 
 286         pr_debug("ymburst: %u, yrburst: %u\n", ymburst, yrburst);
 287 }
 288 
 289 void camif_hw_set_input_path(struct camif_vp *vp)
 290 {
 291         u32 cfg = camif_read(vp->camif, S3C_CAMIF_REG_MSCTRL(vp->id));
 292         cfg &= ~MSCTRL_SEL_DMA_CAM;
 293         camif_write(vp->camif, S3C_CAMIF_REG_MSCTRL(vp->id), cfg);
 294 }
 295 
 296 void camif_hw_set_target_format(struct camif_vp *vp)
 297 {
 298         struct camif_dev *camif = vp->camif;
 299         struct camif_frame *frame = &vp->out_frame;
 300         u32 cfg;
 301 
 302         pr_debug("fw: %d, fh: %d color: %d\n", frame->f_width,
 303                  frame->f_height, vp->out_fmt->color);
 304 
 305         cfg = camif_read(camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
 306         cfg &= ~CITRGFMT_TARGETSIZE_MASK;
 307 
 308         if (camif->variant->ip_revision == S3C244X_CAMIF_IP_REV) {
 309                 /* We currently support only YCbCr 4:2:2 at the camera input */
 310                 cfg |= CITRGFMT_IN422;
 311                 cfg &= ~CITRGFMT_OUT422;
 312                 if (vp->out_fmt->color == IMG_FMT_YCBCR422P)
 313                         cfg |= CITRGFMT_OUT422;
 314         } else {
 315                 cfg &= ~CITRGFMT_OUTFORMAT_MASK;
 316                 switch (vp->out_fmt->color) {
 317                 case IMG_FMT_RGB565...IMG_FMT_XRGB8888:
 318                         cfg |= CITRGFMT_OUTFORMAT_RGB;
 319                         break;
 320                 case IMG_FMT_YCBCR420...IMG_FMT_YCRCB420:
 321                         cfg |= CITRGFMT_OUTFORMAT_YCBCR420;
 322                         break;
 323                 case IMG_FMT_YCBCR422P:
 324                         cfg |= CITRGFMT_OUTFORMAT_YCBCR422;
 325                         break;
 326                 case IMG_FMT_YCBYCR422...IMG_FMT_CRYCBY422:
 327                         cfg |= CITRGFMT_OUTFORMAT_YCBCR422I;
 328                         break;
 329                 }
 330         }
 331 
 332         /* Rotation is only supported by s3c64xx */
 333         if (vp->rotation == 90 || vp->rotation == 270)
 334                 cfg |= (frame->f_height << 16) | frame->f_width;
 335         else
 336                 cfg |= (frame->f_width << 16) | frame->f_height;
 337         camif_write(camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
 338 
 339         /* Target area, output pixel width * height */
 340         cfg = camif_read(camif, S3C_CAMIF_REG_CITAREA(vp->id, vp->offset));
 341         cfg &= ~CITAREA_MASK;
 342         cfg |= (frame->f_width * frame->f_height);
 343         camif_write(camif, S3C_CAMIF_REG_CITAREA(vp->id, vp->offset), cfg);
 344 }
 345 
 346 void camif_hw_set_flip(struct camif_vp *vp)
 347 {
 348         u32 cfg = camif_read(vp->camif,
 349                                 S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset));
 350 
 351         cfg &= ~CITRGFMT_FLIP_MASK;
 352 
 353         if (vp->hflip)
 354                 cfg |= CITRGFMT_FLIP_Y_MIRROR;
 355         if (vp->vflip)
 356                 cfg |= CITRGFMT_FLIP_X_MIRROR;
 357 
 358         camif_write(vp->camif, S3C_CAMIF_REG_CITRGFMT(vp->id, vp->offset), cfg);
 359 }
 360 
 361 static void camif_hw_set_prescaler(struct camif_vp *vp)
 362 {
 363         struct camif_dev *camif = vp->camif;
 364         struct camif_scaler *sc = &vp->scaler;
 365         u32 cfg, shfactor, addr;
 366 
 367         addr = S3C_CAMIF_REG_CISCPRERATIO(vp->id, vp->offset);
 368 
 369         shfactor = 10 - (sc->h_shift + sc->v_shift);
 370         cfg = shfactor << 28;
 371 
 372         cfg |= (sc->pre_h_ratio << 16) | sc->pre_v_ratio;
 373         camif_write(camif, addr, cfg);
 374 
 375         cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
 376         camif_write(camif, S3C_CAMIF_REG_CISCPREDST(vp->id, vp->offset), cfg);
 377 }
 378 
 379 static void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
 380 {
 381         struct camif_dev *camif = vp->camif;
 382         struct camif_scaler *scaler = &vp->scaler;
 383         unsigned int color = vp->out_fmt->color;
 384         u32 cfg;
 385 
 386         camif_hw_set_prescaler(vp);
 387 
 388         cfg = camif_read(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset));
 389 
 390         cfg &= ~(CISCCTRL_SCALEUP_MASK | CISCCTRL_SCALERBYPASS |
 391                  CISCCTRL_MAIN_RATIO_MASK | CIPRSCCTRL_RGB_FORMAT_24BIT);
 392 
 393         if (scaler->enable) {
 394                 if (scaler->scaleup_h) {
 395                         if (vp->id == VP_CODEC)
 396                                 cfg |= CISCCTRL_SCALEUP_H;
 397                         else
 398                                 cfg |= CIPRSCCTRL_SCALEUP_H;
 399                 }
 400                 if (scaler->scaleup_v) {
 401                         if (vp->id == VP_CODEC)
 402                                 cfg |= CISCCTRL_SCALEUP_V;
 403                         else
 404                                 cfg |= CIPRSCCTRL_SCALEUP_V;
 405                 }
 406         } else {
 407                 if (vp->id == VP_CODEC)
 408                         cfg |= CISCCTRL_SCALERBYPASS;
 409         }
 410 
 411         cfg |= ((scaler->main_h_ratio & 0x1ff) << 16);
 412         cfg |= scaler->main_v_ratio & 0x1ff;
 413 
 414         if (vp->id == VP_PREVIEW) {
 415                 if (color == IMG_FMT_XRGB8888)
 416                         cfg |= CIPRSCCTRL_RGB_FORMAT_24BIT;
 417                 cfg |= CIPRSCCTRL_SAMPLE;
 418         }
 419 
 420         camif_write(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset), cfg);
 421 
 422         pr_debug("main: h_ratio: %#x, v_ratio: %#x",
 423                  scaler->main_h_ratio, scaler->main_v_ratio);
 424 }
 425 
 426 static void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
 427 {
 428         struct camif_dev *camif = vp->camif;
 429         struct camif_scaler *scaler = &vp->scaler;
 430         unsigned int color = vp->out_fmt->color;
 431         u32 cfg;
 432 
 433         camif_hw_set_prescaler(vp);
 434 
 435         cfg = camif_read(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset));
 436 
 437         cfg &= ~(CISCCTRL_CSCR2Y_WIDE | CISCCTRL_CSCY2R_WIDE
 438                 | CISCCTRL_SCALEUP_H | CISCCTRL_SCALEUP_V
 439                 | CISCCTRL_SCALERBYPASS | CISCCTRL_ONE2ONE
 440                 | CISCCTRL_INRGB_FMT_MASK | CISCCTRL_OUTRGB_FMT_MASK
 441                 | CISCCTRL_INTERLACE | CISCCTRL_EXTRGB_EXTENSION
 442                 | CISCCTRL_MAIN_RATIO_MASK);
 443 
 444         cfg |= (CISCCTRL_CSCR2Y_WIDE | CISCCTRL_CSCY2R_WIDE);
 445 
 446         if (!scaler->enable) {
 447                 cfg |= CISCCTRL_SCALERBYPASS;
 448         } else {
 449                 if (scaler->scaleup_h)
 450                         cfg |= CISCCTRL_SCALEUP_H;
 451                 if (scaler->scaleup_v)
 452                         cfg |= CISCCTRL_SCALEUP_V;
 453                 if (scaler->copy)
 454                         cfg |= CISCCTRL_ONE2ONE;
 455         }
 456 
 457         switch (color) {
 458         case IMG_FMT_RGB666:
 459                 cfg |= CISCCTRL_OUTRGB_FMT_RGB666;
 460                 break;
 461         case IMG_FMT_XRGB8888:
 462                 cfg |= CISCCTRL_OUTRGB_FMT_RGB888;
 463                 break;
 464         }
 465 
 466         cfg |= (scaler->main_h_ratio & 0x1ff) << 16;
 467         cfg |= scaler->main_v_ratio & 0x1ff;
 468 
 469         camif_write(camif, S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset), cfg);
 470 
 471         pr_debug("main: h_ratio: %#x, v_ratio: %#x",
 472                  scaler->main_h_ratio, scaler->main_v_ratio);
 473 }
 474 
 475 void camif_hw_set_scaler(struct camif_vp *vp)
 476 {
 477         unsigned int ip_rev = vp->camif->variant->ip_revision;
 478 
 479         if (ip_rev == S3C244X_CAMIF_IP_REV)
 480                 camif_s3c244x_hw_set_scaler(vp);
 481         else
 482                 camif_s3c64xx_hw_set_scaler(vp);
 483 }
 484 
 485 void camif_hw_enable_scaler(struct camif_vp *vp, bool on)
 486 {
 487         u32 addr = S3C_CAMIF_REG_CISCCTRL(vp->id, vp->offset);
 488         u32 cfg;
 489 
 490         cfg = camif_read(vp->camif, addr);
 491         if (on)
 492                 cfg |= CISCCTRL_SCALERSTART;
 493         else
 494                 cfg &= ~CISCCTRL_SCALERSTART;
 495         camif_write(vp->camif, addr, cfg);
 496 }
 497 
 498 void camif_hw_set_lastirq(struct camif_vp *vp, int enable)
 499 {
 500         u32 addr = S3C_CAMIF_REG_CICTRL(vp->id, vp->offset);
 501         u32 cfg;
 502 
 503         cfg = camif_read(vp->camif, addr);
 504         if (enable)
 505                 cfg |= CICTRL_LASTIRQ_ENABLE;
 506         else
 507                 cfg &= ~CICTRL_LASTIRQ_ENABLE;
 508         camif_write(vp->camif, addr, cfg);
 509 }
 510 
 511 void camif_hw_enable_capture(struct camif_vp *vp)
 512 {
 513         struct camif_dev *camif = vp->camif;
 514         u32 cfg;
 515 
 516         cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset));
 517         camif->stream_count++;
 518 
 519         if (camif->variant->ip_revision == S3C6410_CAMIF_IP_REV)
 520                 cfg |= CIIMGCPT_CPT_FREN_ENABLE(vp->id);
 521 
 522         if (vp->scaler.enable)
 523                 cfg |= CIIMGCPT_IMGCPTEN_SC(vp->id);
 524 
 525         if (camif->stream_count == 1)
 526                 cfg |= CIIMGCPT_IMGCPTEN;
 527 
 528         camif_write(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset), cfg);
 529 
 530         pr_debug("CIIMGCPT: %#x, camif->stream_count: %d\n",
 531                  cfg, camif->stream_count);
 532 }
 533 
 534 void camif_hw_disable_capture(struct camif_vp *vp)
 535 {
 536         struct camif_dev *camif = vp->camif;
 537         u32 cfg;
 538 
 539         cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset));
 540         cfg &= ~CIIMGCPT_IMGCPTEN_SC(vp->id);
 541 
 542         if (WARN_ON(--(camif->stream_count) < 0))
 543                 camif->stream_count = 0;
 544 
 545         if (camif->stream_count == 0)
 546                 cfg &= ~CIIMGCPT_IMGCPTEN;
 547 
 548         pr_debug("CIIMGCPT: %#x, camif->stream_count: %d\n",
 549                  cfg, camif->stream_count);
 550 
 551         camif_write(camif, S3C_CAMIF_REG_CIIMGCPT(vp->offset), cfg);
 552 }
 553 
 554 void camif_hw_dump_regs(struct camif_dev *camif, const char *label)
 555 {
 556         struct {
 557                 u32 offset;
 558                 const char * const name;
 559         } registers[] = {
 560                 { S3C_CAMIF_REG_CISRCFMT,               "CISRCFMT" },
 561                 { S3C_CAMIF_REG_CIWDOFST,               "CIWDOFST" },
 562                 { S3C_CAMIF_REG_CIGCTRL,                "CIGCTRL" },
 563                 { S3C_CAMIF_REG_CIWDOFST2,              "CIWDOFST2" },
 564                 { S3C_CAMIF_REG_CIYSA(0, 0),            "CICOYSA0" },
 565                 { S3C_CAMIF_REG_CICBSA(0, 0),           "CICOCBSA0" },
 566                 { S3C_CAMIF_REG_CICRSA(0, 0),           "CICOCRSA0" },
 567                 { S3C_CAMIF_REG_CIYSA(0, 1),            "CICOYSA1" },
 568                 { S3C_CAMIF_REG_CICBSA(0, 1),           "CICOCBSA1" },
 569                 { S3C_CAMIF_REG_CICRSA(0, 1),           "CICOCRSA1" },
 570                 { S3C_CAMIF_REG_CIYSA(0, 2),            "CICOYSA2" },
 571                 { S3C_CAMIF_REG_CICBSA(0, 2),           "CICOCBSA2" },
 572                 { S3C_CAMIF_REG_CICRSA(0, 2),           "CICOCRSA2" },
 573                 { S3C_CAMIF_REG_CIYSA(0, 3),            "CICOYSA3" },
 574                 { S3C_CAMIF_REG_CICBSA(0, 3),           "CICOCBSA3" },
 575                 { S3C_CAMIF_REG_CICRSA(0, 3),           "CICOCRSA3" },
 576                 { S3C_CAMIF_REG_CIYSA(1, 0),            "CIPRYSA0" },
 577                 { S3C_CAMIF_REG_CIYSA(1, 1),            "CIPRYSA1" },
 578                 { S3C_CAMIF_REG_CIYSA(1, 2),            "CIPRYSA2" },
 579                 { S3C_CAMIF_REG_CIYSA(1, 3),            "CIPRYSA3" },
 580                 { S3C_CAMIF_REG_CITRGFMT(0, 0),         "CICOTRGFMT" },
 581                 { S3C_CAMIF_REG_CITRGFMT(1, 0),         "CIPRTRGFMT" },
 582                 { S3C_CAMIF_REG_CICTRL(0, 0),           "CICOCTRL" },
 583                 { S3C_CAMIF_REG_CICTRL(1, 0),           "CIPRCTRL" },
 584                 { S3C_CAMIF_REG_CISCPREDST(0, 0),       "CICOSCPREDST" },
 585                 { S3C_CAMIF_REG_CISCPREDST(1, 0),       "CIPRSCPREDST" },
 586                 { S3C_CAMIF_REG_CISCPRERATIO(0, 0),     "CICOSCPRERATIO" },
 587                 { S3C_CAMIF_REG_CISCPRERATIO(1, 0),     "CIPRSCPRERATIO" },
 588                 { S3C_CAMIF_REG_CISCCTRL(0, 0),         "CICOSCCTRL" },
 589                 { S3C_CAMIF_REG_CISCCTRL(1, 0),         "CIPRSCCTRL" },
 590                 { S3C_CAMIF_REG_CITAREA(0, 0),          "CICOTAREA" },
 591                 { S3C_CAMIF_REG_CITAREA(1, 0),          "CIPRTAREA" },
 592                 { S3C_CAMIF_REG_CISTATUS(0, 0),         "CICOSTATUS" },
 593                 { S3C_CAMIF_REG_CISTATUS(1, 0),         "CIPRSTATUS" },
 594                 { S3C_CAMIF_REG_CIIMGCPT(0),            "CIIMGCPT" },
 595         };
 596         u32 i;
 597 
 598         pr_info("--- %s ---\n", label);
 599         for (i = 0; i < ARRAY_SIZE(registers); i++) {
 600                 u32 cfg = readl(camif->io_base + registers[i].offset);
 601                 dev_info(camif->dev, "%s:\t0x%08x\n", registers[i].name, cfg);
 602         }
 603 }

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