1 /* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h
3 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
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.
14 #include <linux/videodev2.h>
15 #include <linux/delay.h>
17 #include "jpeg-core.h"
18 #include "jpeg-regs.h"
19 #include "jpeg-hw-exynos3250.h"
21 void exynos3250_jpeg_reset(void __iomem *regs)
26 writel(1, regs + EXYNOS3250_SW_RESET);
27 /* no other way but polling for when JPEG IP becomes operational */
28 while (reg != 0 && --count > 0) {
31 reg = readl(regs + EXYNOS3250_SW_RESET);
37 while (reg != 1 && --count > 0) {
38 writel(1, regs + EXYNOS3250_JPGDRI);
41 reg = readl(regs + EXYNOS3250_JPGDRI);
44 writel(0, regs + EXYNOS3250_JPGDRI);
47 void exynos3250_jpeg_poweron(void __iomem *regs)
49 writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
52 void exynos3250_jpeg_set_dma_num(void __iomem *regs)
54 writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &
55 EXYNOS3250_WDMA_ISSUE_NUM_MASK) |
56 ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &
57 EXYNOS3250_RDMA_ISSUE_NUM_MASK) |
58 ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &
59 EXYNOS3250_ISSUE_GATHER_NUM_MASK),
60 regs + EXYNOS3250_DMA_ISSUE_NUM);
63 void exynos3250_jpeg_clk_set(void __iomem *base)
67 reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;
69 writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);
72 void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)
76 reg = readl(regs + EXYNOS3250_JPGCMOD) &
77 EXYNOS3250_MODE_Y16_MASK;
80 case V4L2_PIX_FMT_RGB32:
81 reg |= EXYNOS3250_MODE_SEL_ARGB8888;
83 case V4L2_PIX_FMT_BGR32:
84 reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;
86 case V4L2_PIX_FMT_RGB565:
87 reg |= EXYNOS3250_MODE_SEL_RGB565;
89 case V4L2_PIX_FMT_RGB565X:
90 reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;
92 case V4L2_PIX_FMT_YUYV:
93 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;
95 case V4L2_PIX_FMT_YVYU:
96 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |
97 EXYNOS3250_SRC_SWAP_UV;
99 case V4L2_PIX_FMT_UYVY:
100 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;
102 case V4L2_PIX_FMT_VYUY:
103 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |
104 EXYNOS3250_SRC_SWAP_UV;
106 case V4L2_PIX_FMT_NV12:
107 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;
109 case V4L2_PIX_FMT_NV21:
110 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;
112 case V4L2_PIX_FMT_YUV420:
113 reg |= EXYNOS3250_MODE_SEL_420_3P;
120 writel(reg, regs + EXYNOS3250_JPGCMOD);
123 void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)
127 reg = readl(regs + EXYNOS3250_JPGCMOD);
129 reg |= EXYNOS3250_MODE_Y16;
131 reg &= ~EXYNOS3250_MODE_Y16_MASK;
132 writel(reg, regs + EXYNOS3250_JPGCMOD);
135 void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)
139 if (mode == S5P_JPEG_ENCODE)
140 m = EXYNOS3250_PROC_MODE_COMPR;
142 m = EXYNOS3250_PROC_MODE_DECOMPR;
143 reg = readl(regs + EXYNOS3250_JPGMOD);
144 reg &= ~EXYNOS3250_PROC_MODE_MASK;
146 writel(reg, regs + EXYNOS3250_JPGMOD);
149 void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
154 case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
155 m = EXYNOS3250_SUBSAMPLING_MODE_444;
157 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
158 m = EXYNOS3250_SUBSAMPLING_MODE_422;
160 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
161 m = EXYNOS3250_SUBSAMPLING_MODE_420;
165 reg = readl(regs + EXYNOS3250_JPGMOD);
166 reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;
168 writel(reg, regs + EXYNOS3250_JPGMOD);
171 unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
173 return readl(regs + EXYNOS3250_JPGMOD) &
174 EXYNOS3250_SUBSAMPLING_MODE_MASK;
177 void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)
181 reg = dri & EXYNOS3250_JPGDRI_MASK;
182 writel(reg, regs + EXYNOS3250_JPGDRI);
185 void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
189 reg = readl(regs + EXYNOS3250_QHTBL);
190 reg &= ~EXYNOS3250_QT_NUM_MASK(t);
191 reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &
192 EXYNOS3250_QT_NUM_MASK(t);
193 writel(reg, regs + EXYNOS3250_QHTBL);
196 void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
200 reg = readl(regs + EXYNOS3250_QHTBL);
201 reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);
202 /* this driver uses table 0 for all color components */
203 reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &
204 EXYNOS3250_HT_NUM_AC_MASK(t);
205 writel(reg, regs + EXYNOS3250_QHTBL);
208 void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
212 reg = readl(regs + EXYNOS3250_QHTBL);
213 reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);
214 /* this driver uses table 0 for all color components */
215 reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &
216 EXYNOS3250_HT_NUM_DC_MASK(t);
217 writel(reg, regs + EXYNOS3250_QHTBL);
220 void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)
224 reg = y & EXYNOS3250_JPGY_MASK;
225 writel(reg, regs + EXYNOS3250_JPGY);
228 void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)
232 reg = x & EXYNOS3250_JPGX_MASK;
233 writel(reg, regs + EXYNOS3250_JPGX);
236 unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
238 return readl(regs + EXYNOS3250_JPGY);
241 unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
243 return readl(regs + EXYNOS3250_JPGX);
246 void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
250 reg = readl(regs + EXYNOS3250_JPGINTSE);
251 reg |= (EXYNOS3250_JPEG_DONE_EN |
252 EXYNOS3250_WDMA_DONE_EN |
253 EXYNOS3250_RDMA_DONE_EN |
254 EXYNOS3250_ENC_STREAM_INT_EN |
255 EXYNOS3250_CORE_DONE_EN |
256 EXYNOS3250_ERR_INT_EN |
257 EXYNOS3250_HEAD_INT_EN);
258 writel(reg, regs + EXYNOS3250_JPGINTSE);
261 void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
265 reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
266 writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
269 void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
274 case V4L2_PIX_FMT_RGB32:
275 reg = EXYNOS3250_OUT_FMT_ARGB8888;
277 case V4L2_PIX_FMT_BGR32:
278 reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
280 case V4L2_PIX_FMT_RGB565:
281 reg = EXYNOS3250_OUT_FMT_RGB565;
283 case V4L2_PIX_FMT_RGB565X:
284 reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
286 case V4L2_PIX_FMT_YUYV:
287 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
289 case V4L2_PIX_FMT_YVYU:
290 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
291 EXYNOS3250_OUT_SWAP_UV;
293 case V4L2_PIX_FMT_UYVY:
294 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
296 case V4L2_PIX_FMT_VYUY:
297 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
298 EXYNOS3250_OUT_SWAP_UV;
300 case V4L2_PIX_FMT_NV12:
301 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
303 case V4L2_PIX_FMT_NV21:
304 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
306 case V4L2_PIX_FMT_YUV420:
307 reg = EXYNOS3250_OUT_FMT_420_3P;
314 writel(reg, regs + EXYNOS3250_OUTFORM);
317 void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
319 writel(addr, regs + EXYNOS3250_JPG_JPGADR);
322 void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
324 writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
325 writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
326 writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
329 void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
332 u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
335 case V4L2_PIX_FMT_RGB32:
336 reg_luma = 4 * width;
338 case V4L2_PIX_FMT_RGB565:
339 case V4L2_PIX_FMT_RGB565X:
340 case V4L2_PIX_FMT_YUYV:
341 case V4L2_PIX_FMT_YVYU:
342 case V4L2_PIX_FMT_UYVY:
343 case V4L2_PIX_FMT_VYUY:
344 reg_luma = 2 * width;
346 case V4L2_PIX_FMT_NV12:
347 case V4L2_PIX_FMT_NV21:
351 case V4L2_PIX_FMT_YUV420:
353 reg_cb = reg_cr = reg_luma / 2;
359 writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
360 writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
361 writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
364 void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
365 unsigned int y_offset)
369 reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
370 EXYNOS3250_LUMA_YY_OFFSET_MASK;
371 reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
372 EXYNOS3250_LUMA_YX_OFFSET_MASK;
374 writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
376 reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
377 EXYNOS3250_CHROMA_YY_OFFSET_MASK;
378 reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
379 EXYNOS3250_CHROMA_YX_OFFSET_MASK;
381 writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
383 reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
384 EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
385 reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
386 EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
388 writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
391 void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
393 if (mode == S5P_JPEG_ENCODE) {
394 writel(EXYNOS3250_JPEG_ENC_COEF1,
395 base + EXYNOS3250_JPG_COEF(1));
396 writel(EXYNOS3250_JPEG_ENC_COEF2,
397 base + EXYNOS3250_JPG_COEF(2));
398 writel(EXYNOS3250_JPEG_ENC_COEF3,
399 base + EXYNOS3250_JPG_COEF(3));
401 writel(EXYNOS3250_JPEG_DEC_COEF1,
402 base + EXYNOS3250_JPG_COEF(1));
403 writel(EXYNOS3250_JPEG_DEC_COEF2,
404 base + EXYNOS3250_JPG_COEF(2));
405 writel(EXYNOS3250_JPEG_DEC_COEF3,
406 base + EXYNOS3250_JPG_COEF(3));
410 void exynos3250_jpeg_start(void __iomem *regs)
412 writel(1, regs + EXYNOS3250_JSTART);
415 void exynos3250_jpeg_rstart(void __iomem *regs)
417 writel(1, regs + EXYNOS3250_JRSTART);
420 unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
422 return readl(regs + EXYNOS3250_JPGINTST);
425 void exynos3250_jpeg_clear_int_status(void __iomem *regs,
428 return writel(value, regs + EXYNOS3250_JPGINTST);
431 unsigned int exynos3250_jpeg_operating(void __iomem *regs)
433 return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
436 unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
438 return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
441 void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
444 writel(size & EXYNOS3250_DEC_STREAM_MASK,
445 regs + EXYNOS3250_DEC_STREAM_SIZE);
448 void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
454 sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
457 sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
460 sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
463 sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
467 writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
468 regs + EXYNOS3250_DEC_SCALING_RATIO);
471 void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
473 time_value &= EXYNOS3250_TIMER_INIT_MASK;
475 writel(EXYNOS3250_TIMER_INT_STAT | time_value,
476 regs + EXYNOS3250_TIMER_SE);
479 unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
481 return readl(regs + EXYNOS3250_TIMER_ST);
484 void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
486 writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);