root/drivers/media/platform/exynos-gsc/gsc-regs.c

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

DEFINITIONS

This source file includes following definitions.
  1. gsc_hw_set_sw_reset
  2. gsc_wait_reset
  3. gsc_hw_set_frm_done_irq_mask
  4. gsc_hw_set_gsc_irq_enable
  5. gsc_hw_set_input_buf_masking
  6. gsc_hw_set_output_buf_masking
  7. gsc_hw_set_input_addr
  8. gsc_hw_set_output_addr
  9. gsc_hw_set_input_path
  10. gsc_hw_set_in_size
  11. gsc_hw_set_in_image_rgb
  12. gsc_hw_set_in_image_format
  13. gsc_hw_set_output_path
  14. gsc_hw_set_out_size
  15. gsc_hw_set_out_image_rgb
  16. gsc_hw_set_out_image_format
  17. gsc_hw_set_prescaler
  18. gsc_hw_set_mainscaler
  19. gsc_hw_set_rotation
  20. gsc_hw_set_global_alpha
  21. gsc_hw_set_sfr_update

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
   4  *              http://www.samsung.com
   5  *
   6  * Samsung EXYNOS5 SoC series G-Scaler driver
   7  */
   8 
   9 #include <linux/io.h>
  10 #include <linux/delay.h>
  11 
  12 #include "gsc-core.h"
  13 
  14 void gsc_hw_set_sw_reset(struct gsc_dev *dev)
  15 {
  16         writel(GSC_SW_RESET_SRESET, dev->regs + GSC_SW_RESET);
  17 }
  18 
  19 int gsc_wait_reset(struct gsc_dev *dev)
  20 {
  21         unsigned long end = jiffies + msecs_to_jiffies(50);
  22         u32 cfg;
  23 
  24         while (time_before(jiffies, end)) {
  25                 cfg = readl(dev->regs + GSC_SW_RESET);
  26                 if (!cfg)
  27                         return 0;
  28                 usleep_range(10, 20);
  29         }
  30 
  31         return -EBUSY;
  32 }
  33 
  34 void gsc_hw_set_frm_done_irq_mask(struct gsc_dev *dev, bool mask)
  35 {
  36         u32 cfg;
  37 
  38         cfg = readl(dev->regs + GSC_IRQ);
  39         if (mask)
  40                 cfg |= GSC_IRQ_FRMDONE_MASK;
  41         else
  42                 cfg &= ~GSC_IRQ_FRMDONE_MASK;
  43         writel(cfg, dev->regs + GSC_IRQ);
  44 }
  45 
  46 void gsc_hw_set_gsc_irq_enable(struct gsc_dev *dev, bool mask)
  47 {
  48         u32 cfg;
  49 
  50         cfg = readl(dev->regs + GSC_IRQ);
  51         if (mask)
  52                 cfg |= GSC_IRQ_ENABLE;
  53         else
  54                 cfg &= ~GSC_IRQ_ENABLE;
  55         writel(cfg, dev->regs + GSC_IRQ);
  56 }
  57 
  58 void gsc_hw_set_input_buf_masking(struct gsc_dev *dev, u32 shift,
  59                                 bool enable)
  60 {
  61         u32 cfg = readl(dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
  62         u32 mask = 1 << shift;
  63 
  64         cfg &= ~mask;
  65         cfg |= enable << shift;
  66 
  67         writel(cfg, dev->regs + GSC_IN_BASE_ADDR_Y_MASK);
  68         writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CB_MASK);
  69         writel(cfg, dev->regs + GSC_IN_BASE_ADDR_CR_MASK);
  70 }
  71 
  72 void gsc_hw_set_output_buf_masking(struct gsc_dev *dev, u32 shift,
  73                                 bool enable)
  74 {
  75         u32 cfg = readl(dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
  76         u32 mask = 1 << shift;
  77 
  78         cfg &= ~mask;
  79         cfg |= enable << shift;
  80 
  81         writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_Y_MASK);
  82         writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CB_MASK);
  83         writel(cfg, dev->regs + GSC_OUT_BASE_ADDR_CR_MASK);
  84 }
  85 
  86 void gsc_hw_set_input_addr(struct gsc_dev *dev, struct gsc_addr *addr,
  87                                 int index)
  88 {
  89         pr_debug("src_buf[%d]: %pad, cb: %pad, cr: %pad", index,
  90                         &addr->y, &addr->cb, &addr->cr);
  91         writel(addr->y, dev->regs + GSC_IN_BASE_ADDR_Y(index));
  92         writel(addr->cb, dev->regs + GSC_IN_BASE_ADDR_CB(index));
  93         writel(addr->cr, dev->regs + GSC_IN_BASE_ADDR_CR(index));
  94 
  95 }
  96 
  97 void gsc_hw_set_output_addr(struct gsc_dev *dev,
  98                              struct gsc_addr *addr, int index)
  99 {
 100         pr_debug("dst_buf[%d]: %pad, cb: %pad, cr: %pad",
 101                         index, &addr->y, &addr->cb, &addr->cr);
 102         writel(addr->y, dev->regs + GSC_OUT_BASE_ADDR_Y(index));
 103         writel(addr->cb, dev->regs + GSC_OUT_BASE_ADDR_CB(index));
 104         writel(addr->cr, dev->regs + GSC_OUT_BASE_ADDR_CR(index));
 105 }
 106 
 107 void gsc_hw_set_input_path(struct gsc_ctx *ctx)
 108 {
 109         struct gsc_dev *dev = ctx->gsc_dev;
 110 
 111         u32 cfg = readl(dev->regs + GSC_IN_CON);
 112         cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
 113 
 114         if (ctx->in_path == GSC_DMA)
 115                 cfg |= GSC_IN_PATH_MEMORY;
 116 
 117         writel(cfg, dev->regs + GSC_IN_CON);
 118 }
 119 
 120 void gsc_hw_set_in_size(struct gsc_ctx *ctx)
 121 {
 122         struct gsc_dev *dev = ctx->gsc_dev;
 123         struct gsc_frame *frame = &ctx->s_frame;
 124         u32 cfg;
 125 
 126         /* Set input pixel offset */
 127         cfg = GSC_SRCIMG_OFFSET_X(frame->crop.left);
 128         cfg |= GSC_SRCIMG_OFFSET_Y(frame->crop.top);
 129         writel(cfg, dev->regs + GSC_SRCIMG_OFFSET);
 130 
 131         /* Set input original size */
 132         cfg = GSC_SRCIMG_WIDTH(frame->f_width);
 133         cfg |= GSC_SRCIMG_HEIGHT(frame->f_height);
 134         writel(cfg, dev->regs + GSC_SRCIMG_SIZE);
 135 
 136         /* Set input cropped size */
 137         cfg = GSC_CROPPED_WIDTH(frame->crop.width);
 138         cfg |= GSC_CROPPED_HEIGHT(frame->crop.height);
 139         writel(cfg, dev->regs + GSC_CROPPED_SIZE);
 140 }
 141 
 142 void gsc_hw_set_in_image_rgb(struct gsc_ctx *ctx)
 143 {
 144         struct gsc_dev *dev = ctx->gsc_dev;
 145         struct gsc_frame *frame = &ctx->s_frame;
 146         u32 cfg;
 147 
 148         cfg = readl(dev->regs + GSC_IN_CON);
 149         if (frame->colorspace == V4L2_COLORSPACE_REC709)
 150                 cfg |= GSC_IN_RGB_HD_WIDE;
 151         else
 152                 cfg |= GSC_IN_RGB_SD_WIDE;
 153 
 154         if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
 155                 cfg |= GSC_IN_RGB565;
 156         else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
 157                 cfg |= GSC_IN_XRGB8888;
 158 
 159         writel(cfg, dev->regs + GSC_IN_CON);
 160 }
 161 
 162 void gsc_hw_set_in_image_format(struct gsc_ctx *ctx)
 163 {
 164         struct gsc_dev *dev = ctx->gsc_dev;
 165         struct gsc_frame *frame = &ctx->s_frame;
 166         u32 i, depth = 0;
 167         u32 cfg;
 168 
 169         cfg = readl(dev->regs + GSC_IN_CON);
 170         cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
 171                  GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK |
 172                  GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE);
 173         writel(cfg, dev->regs + GSC_IN_CON);
 174 
 175         if (is_rgb(frame->fmt->color)) {
 176                 gsc_hw_set_in_image_rgb(ctx);
 177                 return;
 178         }
 179         for (i = 0; i < frame->fmt->num_planes; i++)
 180                 depth += frame->fmt->depth[i];
 181 
 182         switch (frame->fmt->num_comp) {
 183         case 1:
 184                 cfg |= GSC_IN_YUV422_1P;
 185                 if (frame->fmt->yorder == GSC_LSB_Y)
 186                         cfg |= GSC_IN_YUV422_1P_ORDER_LSB_Y;
 187                 else
 188                         cfg |= GSC_IN_YUV422_1P_OEDER_LSB_C;
 189                 if (frame->fmt->corder == GSC_CBCR)
 190                         cfg |= GSC_IN_CHROMA_ORDER_CBCR;
 191                 else
 192                         cfg |= GSC_IN_CHROMA_ORDER_CRCB;
 193                 break;
 194         case 2:
 195                 if (depth == 12)
 196                         cfg |= GSC_IN_YUV420_2P;
 197                 else
 198                         cfg |= GSC_IN_YUV422_2P;
 199                 if (frame->fmt->corder == GSC_CBCR)
 200                         cfg |= GSC_IN_CHROMA_ORDER_CBCR;
 201                 else
 202                         cfg |= GSC_IN_CHROMA_ORDER_CRCB;
 203                 break;
 204         case 3:
 205                 if (depth == 12)
 206                         cfg |= GSC_IN_YUV420_3P;
 207                 else
 208                         cfg |= GSC_IN_YUV422_3P;
 209                 break;
 210         }
 211 
 212         if (is_tiled(frame->fmt))
 213                 cfg |= GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE;
 214 
 215         writel(cfg, dev->regs + GSC_IN_CON);
 216 }
 217 
 218 void gsc_hw_set_output_path(struct gsc_ctx *ctx)
 219 {
 220         struct gsc_dev *dev = ctx->gsc_dev;
 221 
 222         u32 cfg = readl(dev->regs + GSC_OUT_CON);
 223         cfg &= ~GSC_OUT_PATH_MASK;
 224 
 225         if (ctx->out_path == GSC_DMA)
 226                 cfg |= GSC_OUT_PATH_MEMORY;
 227         else
 228                 cfg |= GSC_OUT_PATH_LOCAL;
 229 
 230         writel(cfg, dev->regs + GSC_OUT_CON);
 231 }
 232 
 233 void gsc_hw_set_out_size(struct gsc_ctx *ctx)
 234 {
 235         struct gsc_dev *dev = ctx->gsc_dev;
 236         struct gsc_frame *frame = &ctx->d_frame;
 237         u32 cfg;
 238 
 239         /* Set output original size */
 240         if (ctx->out_path == GSC_DMA) {
 241                 cfg = GSC_DSTIMG_OFFSET_X(frame->crop.left);
 242                 cfg |= GSC_DSTIMG_OFFSET_Y(frame->crop.top);
 243                 writel(cfg, dev->regs + GSC_DSTIMG_OFFSET);
 244 
 245                 cfg = GSC_DSTIMG_WIDTH(frame->f_width);
 246                 cfg |= GSC_DSTIMG_HEIGHT(frame->f_height);
 247                 writel(cfg, dev->regs + GSC_DSTIMG_SIZE);
 248         }
 249 
 250         /* Set output scaled size */
 251         if (ctx->gsc_ctrls.rotate->val == 90 ||
 252             ctx->gsc_ctrls.rotate->val == 270) {
 253                 cfg = GSC_SCALED_WIDTH(frame->crop.height);
 254                 cfg |= GSC_SCALED_HEIGHT(frame->crop.width);
 255         } else {
 256                 cfg = GSC_SCALED_WIDTH(frame->crop.width);
 257                 cfg |= GSC_SCALED_HEIGHT(frame->crop.height);
 258         }
 259         writel(cfg, dev->regs + GSC_SCALED_SIZE);
 260 }
 261 
 262 void gsc_hw_set_out_image_rgb(struct gsc_ctx *ctx)
 263 {
 264         struct gsc_dev *dev = ctx->gsc_dev;
 265         struct gsc_frame *frame = &ctx->d_frame;
 266         u32 cfg;
 267 
 268         cfg = readl(dev->regs + GSC_OUT_CON);
 269         if (frame->colorspace == V4L2_COLORSPACE_REC709)
 270                 cfg |= GSC_OUT_RGB_HD_WIDE;
 271         else
 272                 cfg |= GSC_OUT_RGB_SD_WIDE;
 273 
 274         if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB565X)
 275                 cfg |= GSC_OUT_RGB565;
 276         else if (frame->fmt->pixelformat == V4L2_PIX_FMT_RGB32)
 277                 cfg |= GSC_OUT_XRGB8888;
 278 
 279         writel(cfg, dev->regs + GSC_OUT_CON);
 280 }
 281 
 282 void gsc_hw_set_out_image_format(struct gsc_ctx *ctx)
 283 {
 284         struct gsc_dev *dev = ctx->gsc_dev;
 285         struct gsc_frame *frame = &ctx->d_frame;
 286         u32 i, depth = 0;
 287         u32 cfg;
 288 
 289         cfg = readl(dev->regs + GSC_OUT_CON);
 290         cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
 291                  GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK |
 292                  GSC_OUT_TILE_TYPE_MASK | GSC_OUT_TILE_MODE);
 293         writel(cfg, dev->regs + GSC_OUT_CON);
 294 
 295         if (is_rgb(frame->fmt->color)) {
 296                 gsc_hw_set_out_image_rgb(ctx);
 297                 return;
 298         }
 299 
 300         if (ctx->out_path != GSC_DMA) {
 301                 cfg |= GSC_OUT_YUV444;
 302                 goto end_set;
 303         }
 304 
 305         for (i = 0; i < frame->fmt->num_planes; i++)
 306                 depth += frame->fmt->depth[i];
 307 
 308         switch (frame->fmt->num_comp) {
 309         case 1:
 310                 cfg |= GSC_OUT_YUV422_1P;
 311                 if (frame->fmt->yorder == GSC_LSB_Y)
 312                         cfg |= GSC_OUT_YUV422_1P_ORDER_LSB_Y;
 313                 else
 314                         cfg |= GSC_OUT_YUV422_1P_OEDER_LSB_C;
 315                 if (frame->fmt->corder == GSC_CBCR)
 316                         cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
 317                 else
 318                         cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
 319                 break;
 320         case 2:
 321                 if (depth == 12)
 322                         cfg |= GSC_OUT_YUV420_2P;
 323                 else
 324                         cfg |= GSC_OUT_YUV422_2P;
 325                 if (frame->fmt->corder == GSC_CBCR)
 326                         cfg |= GSC_OUT_CHROMA_ORDER_CBCR;
 327                 else
 328                         cfg |= GSC_OUT_CHROMA_ORDER_CRCB;
 329                 break;
 330         case 3:
 331                 cfg |= GSC_OUT_YUV420_3P;
 332                 break;
 333         }
 334 
 335         if (is_tiled(frame->fmt))
 336                 cfg |= GSC_OUT_TILE_C_16x8 | GSC_OUT_TILE_MODE;
 337 
 338 end_set:
 339         writel(cfg, dev->regs + GSC_OUT_CON);
 340 }
 341 
 342 void gsc_hw_set_prescaler(struct gsc_ctx *ctx)
 343 {
 344         struct gsc_dev *dev = ctx->gsc_dev;
 345         struct gsc_scaler *sc = &ctx->scaler;
 346         u32 cfg;
 347 
 348         cfg = GSC_PRESC_SHFACTOR(sc->pre_shfactor);
 349         cfg |= GSC_PRESC_H_RATIO(sc->pre_hratio);
 350         cfg |= GSC_PRESC_V_RATIO(sc->pre_vratio);
 351         writel(cfg, dev->regs + GSC_PRE_SCALE_RATIO);
 352 }
 353 
 354 void gsc_hw_set_mainscaler(struct gsc_ctx *ctx)
 355 {
 356         struct gsc_dev *dev = ctx->gsc_dev;
 357         struct gsc_scaler *sc = &ctx->scaler;
 358         u32 cfg;
 359 
 360         cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
 361         writel(cfg, dev->regs + GSC_MAIN_H_RATIO);
 362 
 363         cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio);
 364         writel(cfg, dev->regs + GSC_MAIN_V_RATIO);
 365 }
 366 
 367 void gsc_hw_set_rotation(struct gsc_ctx *ctx)
 368 {
 369         struct gsc_dev *dev = ctx->gsc_dev;
 370         u32 cfg;
 371 
 372         cfg = readl(dev->regs + GSC_IN_CON);
 373         cfg &= ~GSC_IN_ROT_MASK;
 374 
 375         switch (ctx->gsc_ctrls.rotate->val) {
 376         case 270:
 377                 cfg |= GSC_IN_ROT_270;
 378                 break;
 379         case 180:
 380                 cfg |= GSC_IN_ROT_180;
 381                 break;
 382         case 90:
 383                 if (ctx->gsc_ctrls.hflip->val)
 384                         cfg |= GSC_IN_ROT_90_XFLIP;
 385                 else if (ctx->gsc_ctrls.vflip->val)
 386                         cfg |= GSC_IN_ROT_90_YFLIP;
 387                 else
 388                         cfg |= GSC_IN_ROT_90;
 389                 break;
 390         case 0:
 391                 if (ctx->gsc_ctrls.hflip->val)
 392                         cfg |= GSC_IN_ROT_XFLIP;
 393                 else if (ctx->gsc_ctrls.vflip->val)
 394                         cfg |= GSC_IN_ROT_YFLIP;
 395         }
 396 
 397         writel(cfg, dev->regs + GSC_IN_CON);
 398 }
 399 
 400 void gsc_hw_set_global_alpha(struct gsc_ctx *ctx)
 401 {
 402         struct gsc_dev *dev = ctx->gsc_dev;
 403         struct gsc_frame *frame = &ctx->d_frame;
 404         u32 cfg;
 405 
 406         if (!is_rgb(frame->fmt->color)) {
 407                 pr_debug("Not a RGB format");
 408                 return;
 409         }
 410 
 411         cfg = readl(dev->regs + GSC_OUT_CON);
 412         cfg &= ~GSC_OUT_GLOBAL_ALPHA_MASK;
 413 
 414         cfg |= GSC_OUT_GLOBAL_ALPHA(ctx->gsc_ctrls.global_alpha->val);
 415         writel(cfg, dev->regs + GSC_OUT_CON);
 416 }
 417 
 418 void gsc_hw_set_sfr_update(struct gsc_ctx *ctx)
 419 {
 420         struct gsc_dev *dev = ctx->gsc_dev;
 421         u32 cfg;
 422 
 423         cfg = readl(dev->regs + GSC_ENABLE);
 424         cfg |= GSC_ENABLE_SFR_UPDATE;
 425         writel(cfg, dev->regs + GSC_ENABLE);
 426 }

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