1
2
3
4
5
6
7
8
9
10
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
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) {
46 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
47 EXYNOS4_ENC_MODE,
48 base + EXYNOS4_JPEG_CNTL_REG);
49 } else {
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;
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);
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);
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