linux/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos4.c
<<
>>
Prefs
   1/* Copyright (c) 2013 Samsung Electronics Co., Ltd.
   2 *              http://www.samsung.com/
   3 *
   4 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
   5 *
   6 * Register interface file for JPEG driver on Exynos4x12.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12#include <linux/io.h>
  13#include <linux/delay.h>
  14
  15#include "jpeg-core.h"
  16#include "jpeg-hw-exynos4.h"
  17#include "jpeg-regs.h"
  18
  19void exynos4_jpeg_sw_reset(void __iomem *base)
  20{
  21        unsigned int reg;
  22
  23        reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
  24        writel(reg & ~(EXYNOS4_DEC_MODE | EXYNOS4_ENC_MODE),
  25                                base + EXYNOS4_JPEG_CNTL_REG);
  26
  27        reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
  28        writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
  29
  30        udelay(100);
  31
  32        writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
  33}
  34
  35void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
  36{
  37        unsigned int reg;
  38
  39        reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
  40        /* set exynos4_jpeg mod register */
  41        if (mode == S5P_JPEG_DECODE) {
  42                writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
  43                                        EXYNOS4_DEC_MODE,
  44                        base + EXYNOS4_JPEG_CNTL_REG);
  45        } else if (mode == S5P_JPEG_ENCODE) {/* encode */
  46                writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
  47                                        EXYNOS4_ENC_MODE,
  48                        base + EXYNOS4_JPEG_CNTL_REG);
  49        } else { /* disable both */
  50                writel(reg & EXYNOS4_ENC_DEC_MODE_MASK,
  51                        base + EXYNOS4_JPEG_CNTL_REG);
  52        }
  53}
  54
  55void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt,
  56                                unsigned int version)
  57{
  58        unsigned int reg;
  59        unsigned int exynos4_swap_chroma_cbcr;
  60        unsigned int exynos4_swap_chroma_crcb;
  61
  62        if (version == SJPEG_EXYNOS4) {
  63                exynos4_swap_chroma_cbcr = EXYNOS4_SWAP_CHROMA_CBCR;
  64                exynos4_swap_chroma_crcb = EXYNOS4_SWAP_CHROMA_CRCB;
  65        } else {
  66                exynos4_swap_chroma_cbcr = EXYNOS5433_SWAP_CHROMA_CBCR;
  67                exynos4_swap_chroma_crcb = EXYNOS5433_SWAP_CHROMA_CRCB;
  68        }
  69
  70        reg = readl(base + EXYNOS4_IMG_FMT_REG) &
  71                        EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */
  72
  73        switch (img_fmt) {
  74        case V4L2_PIX_FMT_GREY:
  75                reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP;
  76                break;
  77        case V4L2_PIX_FMT_RGB32:
  78                reg = reg | EXYNOS4_ENC_RGB_IMG |
  79                                EXYNOS4_RGB_IP_RGB_32BIT_IMG;
  80                break;
  81        case V4L2_PIX_FMT_RGB565:
  82                reg = reg | EXYNOS4_ENC_RGB_IMG |
  83                                EXYNOS4_RGB_IP_RGB_16BIT_IMG;
  84                break;
  85        case V4L2_PIX_FMT_NV24:
  86                reg = reg | EXYNOS4_ENC_YUV_444_IMG |
  87                                EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
  88                                exynos4_swap_chroma_cbcr;
  89                break;
  90        case V4L2_PIX_FMT_NV42:
  91                reg = reg | EXYNOS4_ENC_YUV_444_IMG |
  92                                EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
  93                                exynos4_swap_chroma_crcb;
  94                break;
  95        case V4L2_PIX_FMT_YUYV:
  96                reg = reg | EXYNOS4_DEC_YUV_422_IMG |
  97                                EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
  98                                exynos4_swap_chroma_cbcr;
  99                break;
 100
 101        case V4L2_PIX_FMT_YVYU:
 102                reg = reg | EXYNOS4_DEC_YUV_422_IMG |
 103                                EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
 104                                exynos4_swap_chroma_crcb;
 105                break;
 106        case V4L2_PIX_FMT_NV16:
 107                reg = reg | EXYNOS4_DEC_YUV_422_IMG |
 108                                EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
 109                                exynos4_swap_chroma_cbcr;
 110                break;
 111        case V4L2_PIX_FMT_NV61:
 112                reg = reg | EXYNOS4_DEC_YUV_422_IMG |
 113                                EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
 114                                exynos4_swap_chroma_crcb;
 115                break;
 116        case V4L2_PIX_FMT_NV12:
 117                reg = reg | EXYNOS4_DEC_YUV_420_IMG |
 118                                EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
 119                                exynos4_swap_chroma_cbcr;
 120                break;
 121        case V4L2_PIX_FMT_NV21:
 122                reg = reg | EXYNOS4_DEC_YUV_420_IMG |
 123                                EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
 124                                exynos4_swap_chroma_crcb;
 125                break;
 126        case V4L2_PIX_FMT_YUV420:
 127                reg = reg | EXYNOS4_DEC_YUV_420_IMG |
 128                                EXYNOS4_YUV_420_IP_YUV_420_3P_IMG |
 129                                exynos4_swap_chroma_cbcr;
 130                break;
 131        default:
 132                break;
 133
 134        }
 135
 136        writel(reg, base + EXYNOS4_IMG_FMT_REG);
 137}
 138
 139void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt,
 140                                    unsigned int version)
 141{
 142        unsigned int reg;
 143
 144        reg = readl(base + EXYNOS4_IMG_FMT_REG) &
 145                        ~(version == SJPEG_EXYNOS4 ? EXYNOS4_ENC_FMT_MASK :
 146                          EXYNOS5433_ENC_FMT_MASK); /* clear enc format */
 147
 148        switch (out_fmt) {
 149        case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
 150                reg = reg | EXYNOS4_ENC_FMT_GRAY;
 151                break;
 152
 153        case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
 154                reg = reg | EXYNOS4_ENC_FMT_YUV_444;
 155                break;
 156
 157        case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
 158                reg = reg | EXYNOS4_ENC_FMT_YUV_422;
 159                break;
 160
 161        case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
 162                reg = reg | EXYNOS4_ENC_FMT_YUV_420;
 163                break;
 164
 165        default:
 166                break;
 167        }
 168
 169        writel(reg, base + EXYNOS4_IMG_FMT_REG);
 170}
 171
 172void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version)
 173{
 174        unsigned int reg;
 175
 176        if (version == SJPEG_EXYNOS4) {
 177                reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK;
 178                writel(reg | EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
 179        } else {
 180                reg = readl(base + EXYNOS4_INT_EN_REG) &
 181                                                        ~EXYNOS5433_INT_EN_MASK;
 182                writel(reg | EXYNOS5433_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
 183        }
 184}
 185
 186unsigned int exynos4_jpeg_get_int_status(void __iomem *base)
 187{
 188        return readl(base + EXYNOS4_INT_STATUS_REG);
 189}
 190
 191unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base)
 192{
 193        return readl(base + EXYNOS4_FIFO_STATUS_REG);
 194}
 195
 196void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value)
 197{
 198        unsigned int    reg;
 199
 200        reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN;
 201
 202        if (value == 1)
 203                writel(reg | EXYNOS4_HUF_TBL_EN,
 204                                        base + EXYNOS4_JPEG_CNTL_REG);
 205        else
 206                writel(reg & ~EXYNOS4_HUF_TBL_EN,
 207                                        base + EXYNOS4_JPEG_CNTL_REG);
 208}
 209
 210void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value)
 211{
 212        unsigned int    reg;
 213
 214        reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN);
 215
 216        if (value == 1)
 217                writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
 218        else
 219                writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
 220}
 221
 222void exynos4_jpeg_set_stream_buf_address(void __iomem *base,
 223                                         unsigned int address)
 224{
 225        writel(address, base + EXYNOS4_OUT_MEM_BASE_REG);
 226}
 227
 228void exynos4_jpeg_set_stream_size(void __iomem *base,
 229                unsigned int x_value, unsigned int y_value)
 230{
 231        writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */
 232        writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value),
 233                        base + EXYNOS4_JPEG_IMG_SIZE_REG);
 234}
 235
 236void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
 237                                struct s5p_jpeg_addr *exynos4_jpeg_addr)
 238{
 239        writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG);
 240        writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG);
 241        writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG);
 242}
 243
 244void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
 245                enum exynos4_jpeg_img_quality_level level)
 246{
 247        unsigned int    reg;
 248
 249        reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 |
 250                EXYNOS4_Q_TBL_COMP3_1 |
 251                EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 |
 252                EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 |
 253                EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1;
 254
 255        writel(reg, base + EXYNOS4_TBL_SEL_REG);
 256}
 257
 258void exynos4_jpeg_set_dec_components(void __iomem *base, int n)
 259{
 260        unsigned int    reg;
 261
 262        reg = readl(base + EXYNOS4_TBL_SEL_REG);
 263
 264        reg |= EXYNOS4_NF(n);
 265        writel(reg, base + EXYNOS4_TBL_SEL_REG);
 266}
 267
 268void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x)
 269{
 270        unsigned int    reg;
 271
 272        reg = readl(base + EXYNOS4_TBL_SEL_REG);
 273
 274        reg |= EXYNOS4_Q_TBL_COMP(c, x);
 275        writel(reg, base + EXYNOS4_TBL_SEL_REG);
 276}
 277
 278void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x)
 279{
 280        unsigned int    reg;
 281
 282        reg = readl(base + EXYNOS4_TBL_SEL_REG);
 283
 284        reg |= EXYNOS4_HUFF_TBL_COMP(c, x);
 285        writel(reg, base + EXYNOS4_TBL_SEL_REG);
 286}
 287
 288void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
 289{
 290        if (fmt == V4L2_PIX_FMT_GREY)
 291                writel(0xd2, base + EXYNOS4_HUFF_CNT_REG);
 292        else
 293                writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG);
 294}
 295
 296unsigned int exynos4_jpeg_get_stream_size(void __iomem *base)
 297{
 298        return readl(base + EXYNOS4_BITSTREAM_SIZE_REG);
 299}
 300
 301void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
 302{
 303        writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG);
 304}
 305
 306void exynos4_jpeg_get_frame_size(void __iomem *base,
 307                        unsigned int *width, unsigned int *height)
 308{
 309        *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) &
 310                                EXYNOS4_DECODED_SIZE_MASK);
 311        *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) &
 312                                EXYNOS4_DECODED_SIZE_MASK;
 313}
 314
 315unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base)
 316{
 317        return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) &
 318                                EXYNOS4_JPEG_DECODED_IMG_FMT_MASK;
 319}
 320
 321void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size)
 322{
 323        writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG);
 324}
 325