1
2
3
4
5
6
7
8
9
10#include <linux/io.h>
11#include <linux/videodev2.h>
12#include <linux/delay.h>
13
14#include "jpeg-core.h"
15#include "jpeg-regs.h"
16#include "jpeg-hw-exynos3250.h"
17
18void exynos3250_jpeg_reset(void __iomem *regs)
19{
20 u32 reg = 1;
21 int count = 1000;
22
23 writel(1, regs + EXYNOS3250_SW_RESET);
24
25 while (reg != 0 && --count > 0) {
26 udelay(1);
27 cpu_relax();
28 reg = readl(regs + EXYNOS3250_SW_RESET);
29 }
30
31 reg = 0;
32 count = 1000;
33
34 while (reg != 1 && --count > 0) {
35 writel(1, regs + EXYNOS3250_JPGDRI);
36 udelay(1);
37 cpu_relax();
38 reg = readl(regs + EXYNOS3250_JPGDRI);
39 }
40
41 writel(0, regs + EXYNOS3250_JPGDRI);
42}
43
44void exynos3250_jpeg_poweron(void __iomem *regs)
45{
46 writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
47}
48
49void exynos3250_jpeg_set_dma_num(void __iomem *regs)
50{
51 writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &
52 EXYNOS3250_WDMA_ISSUE_NUM_MASK) |
53 ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &
54 EXYNOS3250_RDMA_ISSUE_NUM_MASK) |
55 ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &
56 EXYNOS3250_ISSUE_GATHER_NUM_MASK),
57 regs + EXYNOS3250_DMA_ISSUE_NUM);
58}
59
60void exynos3250_jpeg_clk_set(void __iomem *base)
61{
62 u32 reg;
63
64 reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;
65
66 writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);
67}
68
69void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)
70{
71 u32 reg;
72
73 reg = readl(regs + EXYNOS3250_JPGCMOD) &
74 EXYNOS3250_MODE_Y16_MASK;
75
76 switch (fmt) {
77 case V4L2_PIX_FMT_RGB32:
78 reg |= EXYNOS3250_MODE_SEL_ARGB8888;
79 break;
80 case V4L2_PIX_FMT_BGR32:
81 reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;
82 break;
83 case V4L2_PIX_FMT_RGB565:
84 reg |= EXYNOS3250_MODE_SEL_RGB565;
85 break;
86 case V4L2_PIX_FMT_RGB565X:
87 reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;
88 break;
89 case V4L2_PIX_FMT_YUYV:
90 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;
91 break;
92 case V4L2_PIX_FMT_YVYU:
93 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |
94 EXYNOS3250_SRC_SWAP_UV;
95 break;
96 case V4L2_PIX_FMT_UYVY:
97 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;
98 break;
99 case V4L2_PIX_FMT_VYUY:
100 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |
101 EXYNOS3250_SRC_SWAP_UV;
102 break;
103 case V4L2_PIX_FMT_NV12:
104 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;
105 break;
106 case V4L2_PIX_FMT_NV21:
107 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;
108 break;
109 case V4L2_PIX_FMT_YUV420:
110 reg |= EXYNOS3250_MODE_SEL_420_3P;
111 break;
112 default:
113 break;
114
115 }
116
117 writel(reg, regs + EXYNOS3250_JPGCMOD);
118}
119
120void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)
121{
122 u32 reg;
123
124 reg = readl(regs + EXYNOS3250_JPGCMOD);
125 if (y16)
126 reg |= EXYNOS3250_MODE_Y16;
127 else
128 reg &= ~EXYNOS3250_MODE_Y16_MASK;
129 writel(reg, regs + EXYNOS3250_JPGCMOD);
130}
131
132void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)
133{
134 u32 reg, m;
135
136 if (mode == S5P_JPEG_ENCODE)
137 m = EXYNOS3250_PROC_MODE_COMPR;
138 else
139 m = EXYNOS3250_PROC_MODE_DECOMPR;
140 reg = readl(regs + EXYNOS3250_JPGMOD);
141 reg &= ~EXYNOS3250_PROC_MODE_MASK;
142 reg |= m;
143 writel(reg, regs + EXYNOS3250_JPGMOD);
144}
145
146void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
147{
148 u32 reg, m = 0;
149
150 switch (mode) {
151 case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
152 m = EXYNOS3250_SUBSAMPLING_MODE_444;
153 break;
154 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
155 m = EXYNOS3250_SUBSAMPLING_MODE_422;
156 break;
157 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
158 m = EXYNOS3250_SUBSAMPLING_MODE_420;
159 break;
160 }
161
162 reg = readl(regs + EXYNOS3250_JPGMOD);
163 reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;
164 reg |= m;
165 writel(reg, regs + EXYNOS3250_JPGMOD);
166}
167
168unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
169{
170 return readl(regs + EXYNOS3250_JPGMOD) &
171 EXYNOS3250_SUBSAMPLING_MODE_MASK;
172}
173
174void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)
175{
176 u32 reg;
177
178 reg = dri & EXYNOS3250_JPGDRI_MASK;
179 writel(reg, regs + EXYNOS3250_JPGDRI);
180}
181
182void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
183{
184 unsigned long reg;
185
186 reg = readl(regs + EXYNOS3250_QHTBL);
187 reg &= ~EXYNOS3250_QT_NUM_MASK(t);
188 reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &
189 EXYNOS3250_QT_NUM_MASK(t);
190 writel(reg, regs + EXYNOS3250_QHTBL);
191}
192
193void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
194{
195 unsigned long reg;
196
197 reg = readl(regs + EXYNOS3250_QHTBL);
198 reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);
199
200 reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &
201 EXYNOS3250_HT_NUM_AC_MASK(t);
202 writel(reg, regs + EXYNOS3250_QHTBL);
203}
204
205void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
206{
207 unsigned long reg;
208
209 reg = readl(regs + EXYNOS3250_QHTBL);
210 reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);
211
212 reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &
213 EXYNOS3250_HT_NUM_DC_MASK(t);
214 writel(reg, regs + EXYNOS3250_QHTBL);
215}
216
217void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)
218{
219 u32 reg;
220
221 reg = y & EXYNOS3250_JPGY_MASK;
222 writel(reg, regs + EXYNOS3250_JPGY);
223}
224
225void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)
226{
227 u32 reg;
228
229 reg = x & EXYNOS3250_JPGX_MASK;
230 writel(reg, regs + EXYNOS3250_JPGX);
231}
232
233#if 0
234unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
235{
236 return readl(regs + EXYNOS3250_JPGY);
237}
238
239unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
240{
241 return readl(regs + EXYNOS3250_JPGX);
242}
243#endif
244
245void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
246{
247 u32 reg;
248
249 reg = readl(regs + EXYNOS3250_JPGINTSE);
250 reg |= (EXYNOS3250_JPEG_DONE_EN |
251 EXYNOS3250_WDMA_DONE_EN |
252 EXYNOS3250_RDMA_DONE_EN |
253 EXYNOS3250_ENC_STREAM_INT_EN |
254 EXYNOS3250_CORE_DONE_EN |
255 EXYNOS3250_ERR_INT_EN |
256 EXYNOS3250_HEAD_INT_EN);
257 writel(reg, regs + EXYNOS3250_JPGINTSE);
258}
259
260void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
261{
262 u32 reg;
263
264 reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
265 writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
266}
267
268void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
269{
270 u32 reg;
271
272 switch (fmt) {
273 case V4L2_PIX_FMT_RGB32:
274 reg = EXYNOS3250_OUT_FMT_ARGB8888;
275 break;
276 case V4L2_PIX_FMT_BGR32:
277 reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
278 break;
279 case V4L2_PIX_FMT_RGB565:
280 reg = EXYNOS3250_OUT_FMT_RGB565;
281 break;
282 case V4L2_PIX_FMT_RGB565X:
283 reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
284 break;
285 case V4L2_PIX_FMT_YUYV:
286 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
287 break;
288 case V4L2_PIX_FMT_YVYU:
289 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
290 EXYNOS3250_OUT_SWAP_UV;
291 break;
292 case V4L2_PIX_FMT_UYVY:
293 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
294 break;
295 case V4L2_PIX_FMT_VYUY:
296 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
297 EXYNOS3250_OUT_SWAP_UV;
298 break;
299 case V4L2_PIX_FMT_NV12:
300 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
301 break;
302 case V4L2_PIX_FMT_NV21:
303 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
304 break;
305 case V4L2_PIX_FMT_YUV420:
306 reg = EXYNOS3250_OUT_FMT_420_3P;
307 break;
308 default:
309 reg = 0;
310 break;
311 }
312
313 writel(reg, regs + EXYNOS3250_OUTFORM);
314}
315
316void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
317{
318 writel(addr, regs + EXYNOS3250_JPG_JPGADR);
319}
320
321void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
322{
323 writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
324 writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
325 writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
326}
327
328void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
329 unsigned int width)
330{
331 u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
332
333 switch (img_fmt) {
334 case V4L2_PIX_FMT_RGB32:
335 reg_luma = 4 * width;
336 break;
337 case V4L2_PIX_FMT_RGB565:
338 case V4L2_PIX_FMT_RGB565X:
339 case V4L2_PIX_FMT_YUYV:
340 case V4L2_PIX_FMT_YVYU:
341 case V4L2_PIX_FMT_UYVY:
342 case V4L2_PIX_FMT_VYUY:
343 reg_luma = 2 * width;
344 break;
345 case V4L2_PIX_FMT_NV12:
346 case V4L2_PIX_FMT_NV21:
347 reg_luma = width;
348 reg_cb = reg_luma;
349 break;
350 case V4L2_PIX_FMT_YUV420:
351 reg_luma = width;
352 reg_cb = reg_cr = reg_luma / 2;
353 break;
354 default:
355 break;
356 }
357
358 writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
359 writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
360 writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
361}
362
363void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
364 unsigned int y_offset)
365{
366 u32 reg;
367
368 reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
369 EXYNOS3250_LUMA_YY_OFFSET_MASK;
370 reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
371 EXYNOS3250_LUMA_YX_OFFSET_MASK;
372
373 writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
374
375 reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
376 EXYNOS3250_CHROMA_YY_OFFSET_MASK;
377 reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
378 EXYNOS3250_CHROMA_YX_OFFSET_MASK;
379
380 writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
381
382 reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
383 EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
384 reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
385 EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
386
387 writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
388}
389
390void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
391{
392 if (mode == S5P_JPEG_ENCODE) {
393 writel(EXYNOS3250_JPEG_ENC_COEF1,
394 base + EXYNOS3250_JPG_COEF(1));
395 writel(EXYNOS3250_JPEG_ENC_COEF2,
396 base + EXYNOS3250_JPG_COEF(2));
397 writel(EXYNOS3250_JPEG_ENC_COEF3,
398 base + EXYNOS3250_JPG_COEF(3));
399 } else {
400 writel(EXYNOS3250_JPEG_DEC_COEF1,
401 base + EXYNOS3250_JPG_COEF(1));
402 writel(EXYNOS3250_JPEG_DEC_COEF2,
403 base + EXYNOS3250_JPG_COEF(2));
404 writel(EXYNOS3250_JPEG_DEC_COEF3,
405 base + EXYNOS3250_JPG_COEF(3));
406 }
407}
408
409void exynos3250_jpeg_start(void __iomem *regs)
410{
411 writel(1, regs + EXYNOS3250_JSTART);
412}
413
414void exynos3250_jpeg_rstart(void __iomem *regs)
415{
416 writel(1, regs + EXYNOS3250_JRSTART);
417}
418
419unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
420{
421 return readl(regs + EXYNOS3250_JPGINTST);
422}
423
424void exynos3250_jpeg_clear_int_status(void __iomem *regs,
425 unsigned int value)
426{
427 writel(value, regs + EXYNOS3250_JPGINTST);
428}
429
430unsigned int exynos3250_jpeg_operating(void __iomem *regs)
431{
432 return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
433}
434
435unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
436{
437 return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
438}
439
440void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
441 unsigned int size)
442{
443 writel(size & EXYNOS3250_DEC_STREAM_MASK,
444 regs + EXYNOS3250_DEC_STREAM_SIZE);
445}
446
447void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
448 unsigned int sratio)
449{
450 switch (sratio) {
451 case 1:
452 default:
453 sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
454 break;
455 case 2:
456 sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
457 break;
458 case 4:
459 sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
460 break;
461 case 8:
462 sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
463 break;
464 }
465
466 writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
467 regs + EXYNOS3250_DEC_SCALING_RATIO);
468}
469
470void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
471{
472 time_value &= EXYNOS3250_TIMER_INIT_MASK;
473
474 writel(EXYNOS3250_TIMER_INT_STAT | time_value,
475 regs + EXYNOS3250_TIMER_SE);
476}
477
478unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
479{
480 return readl(regs + EXYNOS3250_TIMER_ST);
481}
482
483void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
484{
485 writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);
486}
487