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