1 // SPDX-License-Identifier: GPL-2.0-only
2 /* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
11 #include <linux/videodev2.h>
12 #include <linux/delay.h>
14 #include "jpeg-core.h"
15 #include "jpeg-regs.h"
16 #include "jpeg-hw-exynos3250.h"
18 void exynos3250_jpeg_reset(void __iomem
*regs
)
23 writel(1, regs
+ EXYNOS3250_SW_RESET
);
24 /* no other way but polling for when JPEG IP becomes operational */
25 while (reg
!= 0 && --count
> 0) {
28 reg
= readl(regs
+ EXYNOS3250_SW_RESET
);
34 while (reg
!= 1 && --count
> 0) {
35 writel(1, regs
+ EXYNOS3250_JPGDRI
);
38 reg
= readl(regs
+ EXYNOS3250_JPGDRI
);
41 writel(0, regs
+ EXYNOS3250_JPGDRI
);
44 void exynos3250_jpeg_poweron(void __iomem
*regs
)
46 writel(EXYNOS3250_POWER_ON
, regs
+ EXYNOS3250_JPGCLKCON
);
49 void exynos3250_jpeg_set_dma_num(void __iomem
*regs
)
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
);
60 void exynos3250_jpeg_clk_set(void __iomem
*base
)
64 reg
= readl(base
+ EXYNOS3250_JPGCMOD
) & ~EXYNOS3250_HALF_EN_MASK
;
66 writel(reg
| EXYNOS3250_HALF_EN
, base
+ EXYNOS3250_JPGCMOD
);
69 void exynos3250_jpeg_input_raw_fmt(void __iomem
*regs
, unsigned int fmt
)
73 reg
= readl(regs
+ EXYNOS3250_JPGCMOD
) &
74 EXYNOS3250_MODE_Y16_MASK
;
77 case V4L2_PIX_FMT_RGB32
:
78 reg
|= EXYNOS3250_MODE_SEL_ARGB8888
;
80 case V4L2_PIX_FMT_BGR32
:
81 reg
|= EXYNOS3250_MODE_SEL_ARGB8888
| EXYNOS3250_SRC_SWAP_RGB
;
83 case V4L2_PIX_FMT_RGB565
:
84 reg
|= EXYNOS3250_MODE_SEL_RGB565
;
86 case V4L2_PIX_FMT_RGB565X
:
87 reg
|= EXYNOS3250_MODE_SEL_RGB565
| EXYNOS3250_SRC_SWAP_RGB
;
89 case V4L2_PIX_FMT_YUYV
:
90 reg
|= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR
;
92 case V4L2_PIX_FMT_YVYU
:
93 reg
|= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR
|
94 EXYNOS3250_SRC_SWAP_UV
;
96 case V4L2_PIX_FMT_UYVY
:
97 reg
|= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM
;
99 case V4L2_PIX_FMT_VYUY
:
100 reg
|= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM
|
101 EXYNOS3250_SRC_SWAP_UV
;
103 case V4L2_PIX_FMT_NV12
:
104 reg
|= EXYNOS3250_MODE_SEL_420_2P
| EXYNOS3250_SRC_NV12
;
106 case V4L2_PIX_FMT_NV21
:
107 reg
|= EXYNOS3250_MODE_SEL_420_2P
| EXYNOS3250_SRC_NV21
;
109 case V4L2_PIX_FMT_YUV420
:
110 reg
|= EXYNOS3250_MODE_SEL_420_3P
;
117 writel(reg
, regs
+ EXYNOS3250_JPGCMOD
);
120 void exynos3250_jpeg_set_y16(void __iomem
*regs
, bool y16
)
124 reg
= readl(regs
+ EXYNOS3250_JPGCMOD
);
126 reg
|= EXYNOS3250_MODE_Y16
;
128 reg
&= ~EXYNOS3250_MODE_Y16_MASK
;
129 writel(reg
, regs
+ EXYNOS3250_JPGCMOD
);
132 void exynos3250_jpeg_proc_mode(void __iomem
*regs
, unsigned int mode
)
136 if (mode
== S5P_JPEG_ENCODE
)
137 m
= EXYNOS3250_PROC_MODE_COMPR
;
139 m
= EXYNOS3250_PROC_MODE_DECOMPR
;
140 reg
= readl(regs
+ EXYNOS3250_JPGMOD
);
141 reg
&= ~EXYNOS3250_PROC_MODE_MASK
;
143 writel(reg
, regs
+ EXYNOS3250_JPGMOD
);
146 void exynos3250_jpeg_subsampling_mode(void __iomem
*regs
, unsigned int mode
)
151 case V4L2_JPEG_CHROMA_SUBSAMPLING_444
:
152 m
= EXYNOS3250_SUBSAMPLING_MODE_444
;
154 case V4L2_JPEG_CHROMA_SUBSAMPLING_422
:
155 m
= EXYNOS3250_SUBSAMPLING_MODE_422
;
157 case V4L2_JPEG_CHROMA_SUBSAMPLING_420
:
158 m
= EXYNOS3250_SUBSAMPLING_MODE_420
;
162 reg
= readl(regs
+ EXYNOS3250_JPGMOD
);
163 reg
&= ~EXYNOS3250_SUBSAMPLING_MODE_MASK
;
165 writel(reg
, regs
+ EXYNOS3250_JPGMOD
);
168 unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem
*regs
)
170 return readl(regs
+ EXYNOS3250_JPGMOD
) &
171 EXYNOS3250_SUBSAMPLING_MODE_MASK
;
174 void exynos3250_jpeg_dri(void __iomem
*regs
, unsigned int dri
)
178 reg
= dri
& EXYNOS3250_JPGDRI_MASK
;
179 writel(reg
, regs
+ EXYNOS3250_JPGDRI
);
182 void exynos3250_jpeg_qtbl(void __iomem
*regs
, unsigned int t
, unsigned int n
)
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
);
193 void exynos3250_jpeg_htbl_ac(void __iomem
*regs
, unsigned int t
)
197 reg
= readl(regs
+ EXYNOS3250_QHTBL
);
198 reg
&= ~EXYNOS3250_HT_NUM_AC_MASK(t
);
199 /* this driver uses table 0 for all color components */
200 reg
|= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t
)) &
201 EXYNOS3250_HT_NUM_AC_MASK(t
);
202 writel(reg
, regs
+ EXYNOS3250_QHTBL
);
205 void exynos3250_jpeg_htbl_dc(void __iomem
*regs
, unsigned int t
)
209 reg
= readl(regs
+ EXYNOS3250_QHTBL
);
210 reg
&= ~EXYNOS3250_HT_NUM_DC_MASK(t
);
211 /* this driver uses table 0 for all color components */
212 reg
|= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t
)) &
213 EXYNOS3250_HT_NUM_DC_MASK(t
);
214 writel(reg
, regs
+ EXYNOS3250_QHTBL
);
217 void exynos3250_jpeg_set_y(void __iomem
*regs
, unsigned int y
)
221 reg
= y
& EXYNOS3250_JPGY_MASK
;
222 writel(reg
, regs
+ EXYNOS3250_JPGY
);
225 void exynos3250_jpeg_set_x(void __iomem
*regs
, unsigned int x
)
229 reg
= x
& EXYNOS3250_JPGX_MASK
;
230 writel(reg
, regs
+ EXYNOS3250_JPGX
);
233 #if 0 /* Currently unused */
234 unsigned int exynos3250_jpeg_get_y(void __iomem
*regs
)
236 return readl(regs
+ EXYNOS3250_JPGY
);
239 unsigned int exynos3250_jpeg_get_x(void __iomem
*regs
)
241 return readl(regs
+ EXYNOS3250_JPGX
);
245 void exynos3250_jpeg_interrupts_enable(void __iomem
*regs
)
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
);
260 void exynos3250_jpeg_enc_stream_bound(void __iomem
*regs
, unsigned int size
)
264 reg
= size
& EXYNOS3250_ENC_STREAM_BOUND_MASK
;
265 writel(reg
, regs
+ EXYNOS3250_ENC_STREAM_BOUND
);
268 void exynos3250_jpeg_output_raw_fmt(void __iomem
*regs
, unsigned int fmt
)
273 case V4L2_PIX_FMT_RGB32
:
274 reg
= EXYNOS3250_OUT_FMT_ARGB8888
;
276 case V4L2_PIX_FMT_BGR32
:
277 reg
= EXYNOS3250_OUT_FMT_ARGB8888
| EXYNOS3250_OUT_SWAP_RGB
;
279 case V4L2_PIX_FMT_RGB565
:
280 reg
= EXYNOS3250_OUT_FMT_RGB565
;
282 case V4L2_PIX_FMT_RGB565X
:
283 reg
= EXYNOS3250_OUT_FMT_RGB565
| EXYNOS3250_OUT_SWAP_RGB
;
285 case V4L2_PIX_FMT_YUYV
:
286 reg
= EXYNOS3250_OUT_FMT_422_1P_LUM_CHR
;
288 case V4L2_PIX_FMT_YVYU
:
289 reg
= EXYNOS3250_OUT_FMT_422_1P_LUM_CHR
|
290 EXYNOS3250_OUT_SWAP_UV
;
292 case V4L2_PIX_FMT_UYVY
:
293 reg
= EXYNOS3250_OUT_FMT_422_1P_CHR_LUM
;
295 case V4L2_PIX_FMT_VYUY
:
296 reg
= EXYNOS3250_OUT_FMT_422_1P_CHR_LUM
|
297 EXYNOS3250_OUT_SWAP_UV
;
299 case V4L2_PIX_FMT_NV12
:
300 reg
= EXYNOS3250_OUT_FMT_420_2P
| EXYNOS3250_OUT_NV12
;
302 case V4L2_PIX_FMT_NV21
:
303 reg
= EXYNOS3250_OUT_FMT_420_2P
| EXYNOS3250_OUT_NV21
;
305 case V4L2_PIX_FMT_YUV420
:
306 reg
= EXYNOS3250_OUT_FMT_420_3P
;
313 writel(reg
, regs
+ EXYNOS3250_OUTFORM
);
316 void exynos3250_jpeg_jpgadr(void __iomem
*regs
, unsigned int addr
)
318 writel(addr
, regs
+ EXYNOS3250_JPG_JPGADR
);
321 void exynos3250_jpeg_imgadr(void __iomem
*regs
, struct s5p_jpeg_addr
*img_addr
)
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
);
328 void exynos3250_jpeg_stride(void __iomem
*regs
, unsigned int img_fmt
,
331 u32 reg_luma
= 0, reg_cr
= 0, reg_cb
= 0;
334 case V4L2_PIX_FMT_RGB32
:
335 reg_luma
= 4 * width
;
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
;
345 case V4L2_PIX_FMT_NV12
:
346 case V4L2_PIX_FMT_NV21
:
350 case V4L2_PIX_FMT_YUV420
:
352 reg_cb
= reg_cr
= reg_luma
/ 2;
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
);
363 void exynos3250_jpeg_offset(void __iomem
*regs
, unsigned int x_offset
,
364 unsigned int y_offset
)
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
;
373 writel(reg
, regs
+ EXYNOS3250_LUMA_XY_OFFSET
);
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
;
380 writel(reg
, regs
+ EXYNOS3250_CHROMA_XY_OFFSET
);
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
;
387 writel(reg
, regs
+ EXYNOS3250_CHROMA_CR_XY_OFFSET
);
390 void exynos3250_jpeg_coef(void __iomem
*base
, unsigned int mode
)
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));
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));
409 void exynos3250_jpeg_start(void __iomem
*regs
)
411 writel(1, regs
+ EXYNOS3250_JSTART
);
414 void exynos3250_jpeg_rstart(void __iomem
*regs
)
416 writel(1, regs
+ EXYNOS3250_JRSTART
);
419 unsigned int exynos3250_jpeg_get_int_status(void __iomem
*regs
)
421 return readl(regs
+ EXYNOS3250_JPGINTST
);
424 void exynos3250_jpeg_clear_int_status(void __iomem
*regs
,
427 writel(value
, regs
+ EXYNOS3250_JPGINTST
);
430 unsigned int exynos3250_jpeg_operating(void __iomem
*regs
)
432 return readl(regs
+ S5P_JPGOPR
) & EXYNOS3250_JPGOPR_MASK
;
435 unsigned int exynos3250_jpeg_compressed_size(void __iomem
*regs
)
437 return readl(regs
+ EXYNOS3250_JPGCNT
) & EXYNOS3250_JPGCNT_MASK
;
440 void exynos3250_jpeg_dec_stream_size(void __iomem
*regs
,
443 writel(size
& EXYNOS3250_DEC_STREAM_MASK
,
444 regs
+ EXYNOS3250_DEC_STREAM_SIZE
);
447 void exynos3250_jpeg_dec_scaling_ratio(void __iomem
*regs
,
453 sratio
= EXYNOS3250_DEC_SCALE_FACTOR_8_8
;
456 sratio
= EXYNOS3250_DEC_SCALE_FACTOR_4_8
;
459 sratio
= EXYNOS3250_DEC_SCALE_FACTOR_2_8
;
462 sratio
= EXYNOS3250_DEC_SCALE_FACTOR_1_8
;
466 writel(sratio
& EXYNOS3250_DEC_SCALE_FACTOR_MASK
,
467 regs
+ EXYNOS3250_DEC_SCALING_RATIO
);
470 void exynos3250_jpeg_set_timer(void __iomem
*regs
, unsigned int time_value
)
472 time_value
&= EXYNOS3250_TIMER_INIT_MASK
;
474 writel(EXYNOS3250_TIMER_INT_STAT
| time_value
,
475 regs
+ EXYNOS3250_TIMER_SE
);
478 unsigned int exynos3250_jpeg_get_timer_status(void __iomem
*regs
)
480 return readl(regs
+ EXYNOS3250_TIMER_ST
);
483 void exynos3250_jpeg_clear_timer_status(void __iomem
*regs
)
485 writel(EXYNOS3250_TIMER_INT_STAT
, regs
+ EXYNOS3250_TIMER_ST
);