jpeg-hw.h revision bb677f3ac434cb1708938f1e76a41d9098affd05
1/* linux/drivers/media/video/s5p-jpeg/jpeg-hw.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 *		http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@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#ifndef JPEG_HW_H_
13#define JPEG_HW_H_
14
15#include <linux/io.h>
16
17#include "jpeg-hw.h"
18#include "jpeg-regs.h"
19
20#define S5P_JPEG_MIN_WIDTH		32
21#define S5P_JPEG_MIN_HEIGHT		32
22#define S5P_JPEG_MAX_WIDTH		8192
23#define S5P_JPEG_MAX_HEIGHT		8192
24#define S5P_JPEG_ENCODE			0
25#define S5P_JPEG_DECODE			1
26#define S5P_JPEG_RAW_IN_565		0
27#define S5P_JPEG_RAW_IN_422		1
28#define S5P_JPEG_SUBSAMPLING_422	0
29#define S5P_JPEG_SUBSAMPLING_420	1
30#define S5P_JPEG_RAW_OUT_422		0
31#define S5P_JPEG_RAW_OUT_420		1
32
33static inline void jpeg_reset(void __iomem *regs)
34{
35	unsigned long reg;
36
37	writel(1, regs + S5P_JPG_SW_RESET);
38	reg = readl(regs + S5P_JPG_SW_RESET);
39	/* no other way but polling for when JPEG IP becomes operational */
40	while (reg != 0) {
41		cpu_relax();
42		reg = readl(regs + S5P_JPG_SW_RESET);
43	}
44}
45
46static inline void jpeg_poweron(void __iomem *regs)
47{
48	writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
49}
50
51static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
52{
53	unsigned long reg, m;
54
55	m = S5P_MOD_SEL_565;
56	if (mode == S5P_JPEG_RAW_IN_565)
57		m = S5P_MOD_SEL_565;
58	else if (mode == S5P_JPEG_RAW_IN_422)
59		m = S5P_MOD_SEL_422;
60
61	reg = readl(regs + S5P_JPGCMOD);
62	reg &= ~S5P_MOD_SEL_MASK;
63	reg |= m;
64	writel(reg, regs + S5P_JPGCMOD);
65}
66
67static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
68{
69	unsigned long reg;
70
71	reg = readl(regs + S5P_JPGCMOD);
72	if (y16)
73		reg |= S5P_MODE_Y16;
74	else
75		reg &= ~S5P_MODE_Y16_MASK;
76	writel(reg, regs + S5P_JPGCMOD);
77}
78
79static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
80{
81	unsigned long reg, m;
82
83	m = S5P_PROC_MODE_DECOMPR;
84	if (mode == S5P_JPEG_ENCODE)
85		m = S5P_PROC_MODE_COMPR;
86	else
87		m = S5P_PROC_MODE_DECOMPR;
88	reg = readl(regs + S5P_JPGMOD);
89	reg &= ~S5P_PROC_MODE_MASK;
90	reg |= m;
91	writel(reg, regs + S5P_JPGMOD);
92}
93
94static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned long mode)
95{
96	unsigned long reg, m;
97
98	m = S5P_SUBSAMPLING_MODE_422;
99	if (mode == S5P_JPEG_SUBSAMPLING_422)
100		m = S5P_SUBSAMPLING_MODE_422;
101	else if (mode == S5P_JPEG_SUBSAMPLING_420)
102		m = S5P_SUBSAMPLING_MODE_420;
103	reg = readl(regs + S5P_JPGMOD);
104	reg &= ~S5P_SUBSAMPLING_MODE_MASK;
105	reg |= m;
106	writel(reg, regs + S5P_JPGMOD);
107}
108
109static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
110{
111	unsigned long reg;
112
113	reg = readl(regs + S5P_JPGDRI_U);
114	reg &= ~0xff;
115	reg |= (dri >> 8) & 0xff;
116	writel(reg, regs + S5P_JPGDRI_U);
117
118	reg = readl(regs + S5P_JPGDRI_L);
119	reg &= ~0xff;
120	reg |= dri & 0xff;
121	writel(reg, regs + S5P_JPGDRI_L);
122}
123
124static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
125{
126	unsigned long reg;
127
128	reg = readl(regs + S5P_JPG_QTBL);
129	reg &= ~S5P_QT_NUMt_MASK(t);
130	reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
131	writel(reg, regs + S5P_JPG_QTBL);
132}
133
134static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
135{
136	unsigned long reg;
137
138	reg = readl(regs + S5P_JPG_HTBL);
139	reg &= ~S5P_HT_NUMt_AC_MASK(t);
140	/* this driver uses table 0 for all color components */
141	reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
142	writel(reg, regs + S5P_JPG_HTBL);
143}
144
145static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
146{
147	unsigned long reg;
148
149	reg = readl(regs + S5P_JPG_HTBL);
150	reg &= ~S5P_HT_NUMt_DC_MASK(t);
151	/* this driver uses table 0 for all color components */
152	reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
153	writel(reg, regs + S5P_JPG_HTBL);
154}
155
156static inline void jpeg_y(void __iomem *regs, unsigned int y)
157{
158	unsigned long reg;
159
160	reg = readl(regs + S5P_JPGY_U);
161	reg &= ~0xff;
162	reg |= (y >> 8) & 0xff;
163	writel(reg, regs + S5P_JPGY_U);
164
165	reg = readl(regs + S5P_JPGY_L);
166	reg &= ~0xff;
167	reg |= y & 0xff;
168	writel(reg, regs + S5P_JPGY_L);
169}
170
171static inline void jpeg_x(void __iomem *regs, unsigned int x)
172{
173	unsigned long reg;
174
175	reg = readl(regs + S5P_JPGX_U);
176	reg &= ~0xff;
177	reg |= (x >> 8) & 0xff;
178	writel(reg, regs + S5P_JPGX_U);
179
180	reg = readl(regs + S5P_JPGX_L);
181	reg &= ~0xff;
182	reg |= x & 0xff;
183	writel(reg, regs + S5P_JPGX_L);
184}
185
186static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
187{
188	unsigned long reg;
189
190	reg = readl(regs + S5P_JPGINTSE);
191	reg &= ~S5P_RSTm_INT_EN_MASK;
192	if (enable)
193		reg |= S5P_RSTm_INT_EN;
194	writel(reg, regs + S5P_JPGINTSE);
195}
196
197static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
198{
199	unsigned long reg;
200
201	reg = readl(regs + S5P_JPGINTSE);
202	reg &= ~S5P_DATA_NUM_INT_EN_MASK;
203	if (enable)
204		reg |= S5P_DATA_NUM_INT_EN;
205	writel(reg, regs + S5P_JPGINTSE);
206}
207
208static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
209{
210	unsigned long reg;
211
212	reg = readl(regs + S5P_JPGINTSE);
213	reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
214	if (enbl)
215		reg |= S5P_FINAL_MCU_NUM_INT_EN;
216	writel(reg, regs + S5P_JPGINTSE);
217}
218
219static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
220{
221	unsigned long reg;
222
223	reg = readl(regs + S5P_JPG_TIMER_SE);
224	reg |= S5P_TIMER_INT_EN;
225	reg &= ~S5P_TIMER_INIT_MASK;
226	reg |= val & S5P_TIMER_INIT_MASK;
227	writel(reg, regs + S5P_JPG_TIMER_SE);
228}
229
230static inline void jpeg_timer_disable(void __iomem *regs)
231{
232	unsigned long reg;
233
234	reg = readl(regs + S5P_JPG_TIMER_SE);
235	reg &= ~S5P_TIMER_INT_EN_MASK;
236	writel(reg, regs + S5P_JPG_TIMER_SE);
237}
238
239static inline int jpeg_timer_stat(void __iomem *regs)
240{
241	return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
242		     >> S5P_TIMER_INT_STAT_SHIFT);
243}
244
245static inline void jpeg_clear_timer_stat(void __iomem *regs)
246{
247	unsigned long reg;
248
249	reg = readl(regs + S5P_JPG_TIMER_SE);
250	reg &= ~S5P_TIMER_INT_STAT_MASK;
251	writel(reg, regs + S5P_JPG_TIMER_SE);
252}
253
254static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
255{
256	unsigned long reg;
257
258	reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
259	reg &= ~S5P_ENC_STREAM_BOUND_MASK;
260	reg |= S5P_ENC_STREAM_INT_EN;
261	reg |= size & S5P_ENC_STREAM_BOUND_MASK;
262	writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
263}
264
265static inline int jpeg_enc_stream_stat(void __iomem *regs)
266{
267	return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
268		     S5P_ENC_STREAM_INT_STAT_MASK);
269}
270
271static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
272{
273	unsigned long reg;
274
275	reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
276	reg &= ~S5P_ENC_STREAM_INT_MASK;
277	writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
278}
279
280static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
281{
282	unsigned long reg, f;
283
284	f = S5P_DEC_OUT_FORMAT_422;
285	if (format == S5P_JPEG_RAW_OUT_422)
286		f = S5P_DEC_OUT_FORMAT_422;
287	else if (format == S5P_JPEG_RAW_OUT_420)
288		f = S5P_DEC_OUT_FORMAT_420;
289	reg = readl(regs + S5P_JPG_OUTFORM);
290	reg &= ~S5P_DEC_OUT_FORMAT_MASK;
291	reg |= f;
292	writel(reg, regs + S5P_JPG_OUTFORM);
293}
294
295static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
296{
297	writel(addr, regs + S5P_JPG_JPGADR);
298}
299
300static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr)
301{
302	writel(addr, regs + S5P_JPG_IMGADR);
303}
304
305static inline void jpeg_coef(void __iomem *regs, unsigned int i,
306			     unsigned int j, unsigned int coef)
307{
308	unsigned long reg;
309
310	reg = readl(regs + S5P_JPG_COEF(i));
311	reg &= ~S5P_COEFn_MASK(j);
312	reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
313	writel(reg, regs + S5P_JPG_COEF(i));
314}
315
316static inline void jpeg_start(void __iomem *regs)
317{
318	writel(1, regs + S5P_JSTART);
319}
320
321static inline int jpeg_result_stat_ok(void __iomem *regs)
322{
323	return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
324		     >> S5P_RESULT_STAT_SHIFT);
325}
326
327static inline int jpeg_stream_stat_ok(void __iomem *regs)
328{
329	return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
330		      >> S5P_STREAM_STAT_SHIFT);
331}
332
333static inline void jpeg_clear_int(void __iomem *regs)
334{
335	unsigned long reg;
336
337	reg = readl(regs + S5P_JPGINTST);
338	writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
339	reg = readl(regs + S5P_JPGOPR);
340}
341
342static inline unsigned int jpeg_compressed_size(void __iomem *regs)
343{
344	unsigned long jpeg_size = 0;
345
346	jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
347	jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
348	jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
349
350	return (unsigned int)jpeg_size;
351}
352
353#endif /* JPEG_HW_H_ */
354