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