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