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_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); 25 26 udelay(100); 27 28 writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG); 29} 30 31void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode) 32{ 33 unsigned int reg; 34 35 reg = readl(base + EXYNOS4_JPEG_CNTL_REG); 36 /* set exynos4_jpeg mod register */ 37 if (mode == S5P_JPEG_DECODE) { 38 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | 39 EXYNOS4_DEC_MODE, 40 base + EXYNOS4_JPEG_CNTL_REG); 41 } else {/* encode */ 42 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) | 43 EXYNOS4_ENC_MODE, 44 base + EXYNOS4_JPEG_CNTL_REG); 45 } 46} 47 48void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt) 49{ 50 unsigned int reg; 51 52 reg = readl(base + EXYNOS4_IMG_FMT_REG) & 53 EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */ 54 55 switch (img_fmt) { 56 case V4L2_PIX_FMT_GREY: 57 reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP; 58 break; 59 case V4L2_PIX_FMT_RGB32: 60 reg = reg | EXYNOS4_ENC_RGB_IMG | 61 EXYNOS4_RGB_IP_RGB_32BIT_IMG; 62 break; 63 case V4L2_PIX_FMT_RGB565: 64 reg = reg | EXYNOS4_ENC_RGB_IMG | 65 EXYNOS4_RGB_IP_RGB_16BIT_IMG; 66 break; 67 case V4L2_PIX_FMT_NV24: 68 reg = reg | EXYNOS4_ENC_YUV_444_IMG | 69 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | 70 EXYNOS4_SWAP_CHROMA_CBCR; 71 break; 72 case V4L2_PIX_FMT_NV42: 73 reg = reg | EXYNOS4_ENC_YUV_444_IMG | 74 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG | 75 EXYNOS4_SWAP_CHROMA_CRCB; 76 break; 77 case V4L2_PIX_FMT_YUYV: 78 reg = reg | EXYNOS4_DEC_YUV_422_IMG | 79 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | 80 EXYNOS4_SWAP_CHROMA_CBCR; 81 break; 82 83 case V4L2_PIX_FMT_YVYU: 84 reg = reg | EXYNOS4_DEC_YUV_422_IMG | 85 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG | 86 EXYNOS4_SWAP_CHROMA_CRCB; 87 break; 88 case V4L2_PIX_FMT_NV16: 89 reg = reg | EXYNOS4_DEC_YUV_422_IMG | 90 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | 91 EXYNOS4_SWAP_CHROMA_CBCR; 92 break; 93 case V4L2_PIX_FMT_NV61: 94 reg = reg | EXYNOS4_DEC_YUV_422_IMG | 95 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG | 96 EXYNOS4_SWAP_CHROMA_CRCB; 97 break; 98 case V4L2_PIX_FMT_NV12: 99 reg = reg | EXYNOS4_DEC_YUV_420_IMG | 100 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | 101 EXYNOS4_SWAP_CHROMA_CBCR; 102 break; 103 case V4L2_PIX_FMT_NV21: 104 reg = reg | EXYNOS4_DEC_YUV_420_IMG | 105 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG | 106 EXYNOS4_SWAP_CHROMA_CRCB; 107 break; 108 case V4L2_PIX_FMT_YUV420: 109 reg = reg | EXYNOS4_DEC_YUV_420_IMG | 110 EXYNOS4_YUV_420_IP_YUV_420_3P_IMG | 111 EXYNOS4_SWAP_CHROMA_CBCR; 112 break; 113 default: 114 break; 115 116 } 117 118 writel(reg, base + EXYNOS4_IMG_FMT_REG); 119} 120 121void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt) 122{ 123 unsigned int reg; 124 125 reg = readl(base + EXYNOS4_IMG_FMT_REG) & 126 ~EXYNOS4_ENC_FMT_MASK; /* clear enc format */ 127 128 switch (out_fmt) { 129 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY: 130 reg = reg | EXYNOS4_ENC_FMT_GRAY; 131 break; 132 133 case V4L2_JPEG_CHROMA_SUBSAMPLING_444: 134 reg = reg | EXYNOS4_ENC_FMT_YUV_444; 135 break; 136 137 case V4L2_JPEG_CHROMA_SUBSAMPLING_422: 138 reg = reg | EXYNOS4_ENC_FMT_YUV_422; 139 break; 140 141 case V4L2_JPEG_CHROMA_SUBSAMPLING_420: 142 reg = reg | EXYNOS4_ENC_FMT_YUV_420; 143 break; 144 145 default: 146 break; 147 } 148 149 writel(reg, base + EXYNOS4_IMG_FMT_REG); 150} 151 152void exynos4_jpeg_set_interrupt(void __iomem *base) 153{ 154 writel(EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG); 155} 156 157unsigned int exynos4_jpeg_get_int_status(void __iomem *base) 158{ 159 unsigned int int_status; 160 161 int_status = readl(base + EXYNOS4_INT_STATUS_REG); 162 163 return int_status; 164} 165 166unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base) 167{ 168 unsigned int fifo_status; 169 170 fifo_status = readl(base + EXYNOS4_FIFO_STATUS_REG); 171 172 return fifo_status; 173} 174 175void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value) 176{ 177 unsigned int reg; 178 179 reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN; 180 181 if (value == 1) 182 writel(reg | EXYNOS4_HUF_TBL_EN, 183 base + EXYNOS4_JPEG_CNTL_REG); 184 else 185 writel(reg & ~EXYNOS4_HUF_TBL_EN, 186 base + EXYNOS4_JPEG_CNTL_REG); 187} 188 189void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value) 190{ 191 unsigned int reg; 192 193 reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN); 194 195 if (value == 1) 196 writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); 197 else 198 writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG); 199} 200 201void exynos4_jpeg_set_stream_buf_address(void __iomem *base, 202 unsigned int address) 203{ 204 writel(address, base + EXYNOS4_OUT_MEM_BASE_REG); 205} 206 207void exynos4_jpeg_set_stream_size(void __iomem *base, 208 unsigned int x_value, unsigned int y_value) 209{ 210 writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */ 211 writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value), 212 base + EXYNOS4_JPEG_IMG_SIZE_REG); 213} 214 215void exynos4_jpeg_set_frame_buf_address(void __iomem *base, 216 struct s5p_jpeg_addr *exynos4_jpeg_addr) 217{ 218 writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG); 219 writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG); 220 writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG); 221} 222 223void exynos4_jpeg_set_encode_tbl_select(void __iomem *base, 224 enum exynos4_jpeg_img_quality_level level) 225{ 226 unsigned int reg; 227 228 reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 | 229 EXYNOS4_Q_TBL_COMP3_1 | 230 EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 | 231 EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 | 232 EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1; 233 234 writel(reg, base + EXYNOS4_TBL_SEL_REG); 235} 236 237void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt) 238{ 239 if (fmt == V4L2_PIX_FMT_GREY) 240 writel(0xd2, base + EXYNOS4_HUFF_CNT_REG); 241 else 242 writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG); 243} 244 245unsigned int exynos4_jpeg_get_stream_size(void __iomem *base) 246{ 247 unsigned int size; 248 249 size = readl(base + EXYNOS4_BITSTREAM_SIZE_REG); 250 return size; 251} 252 253void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size) 254{ 255 writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG); 256} 257 258void exynos4_jpeg_get_frame_size(void __iomem *base, 259 unsigned int *width, unsigned int *height) 260{ 261 *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) & 262 EXYNOS4_DECODED_SIZE_MASK); 263 *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) & 264 EXYNOS4_DECODED_SIZE_MASK; 265} 266 267unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base) 268{ 269 return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) & 270 EXYNOS4_JPEG_DECODED_IMG_FMT_MASK; 271} 272 273void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size) 274{ 275 writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG); 276} 277