1 /* linux/drivers/media/platform/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 
13 #include <linux/io.h>
14 #include <linux/videodev2.h>
15 
16 #include "jpeg-core.h"
17 #include "jpeg-regs.h"
18 #include "jpeg-hw-s5p.h"
19 
s5p_jpeg_reset(void __iomem * regs)20 void s5p_jpeg_reset(void __iomem *regs)
21 {
22 	unsigned long reg;
23 
24 	writel(1, regs + S5P_JPG_SW_RESET);
25 	reg = readl(regs + S5P_JPG_SW_RESET);
26 	/* no other way but polling for when JPEG IP becomes operational */
27 	while (reg != 0) {
28 		cpu_relax();
29 		reg = readl(regs + S5P_JPG_SW_RESET);
30 	}
31 }
32 
s5p_jpeg_poweron(void __iomem * regs)33 void s5p_jpeg_poweron(void __iomem *regs)
34 {
35 	writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
36 }
37 
s5p_jpeg_input_raw_mode(void __iomem * regs,unsigned long mode)38 void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
39 {
40 	unsigned long reg, m;
41 
42 	m = S5P_MOD_SEL_565;
43 	if (mode == S5P_JPEG_RAW_IN_565)
44 		m = S5P_MOD_SEL_565;
45 	else if (mode == S5P_JPEG_RAW_IN_422)
46 		m = S5P_MOD_SEL_422;
47 
48 	reg = readl(regs + S5P_JPGCMOD);
49 	reg &= ~S5P_MOD_SEL_MASK;
50 	reg |= m;
51 	writel(reg, regs + S5P_JPGCMOD);
52 }
53 
s5p_jpeg_proc_mode(void __iomem * regs,unsigned long mode)54 void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode)
55 {
56 	unsigned long reg, m;
57 
58 	m = S5P_PROC_MODE_DECOMPR;
59 	if (mode == S5P_JPEG_ENCODE)
60 		m = S5P_PROC_MODE_COMPR;
61 	else
62 		m = S5P_PROC_MODE_DECOMPR;
63 	reg = readl(regs + S5P_JPGMOD);
64 	reg &= ~S5P_PROC_MODE_MASK;
65 	reg |= m;
66 	writel(reg, regs + S5P_JPGMOD);
67 }
68 
s5p_jpeg_subsampling_mode(void __iomem * regs,unsigned int mode)69 void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
70 {
71 	unsigned long reg, m;
72 
73 	if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
74 		m = S5P_SUBSAMPLING_MODE_420;
75 	else
76 		m = S5P_SUBSAMPLING_MODE_422;
77 
78 	reg = readl(regs + S5P_JPGMOD);
79 	reg &= ~S5P_SUBSAMPLING_MODE_MASK;
80 	reg |= m;
81 	writel(reg, regs + S5P_JPGMOD);
82 }
83 
s5p_jpeg_get_subsampling_mode(void __iomem * regs)84 unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs)
85 {
86 	return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
87 }
88 
s5p_jpeg_dri(void __iomem * regs,unsigned int dri)89 void s5p_jpeg_dri(void __iomem *regs, unsigned int dri)
90 {
91 	unsigned long reg;
92 
93 	reg = readl(regs + S5P_JPGDRI_U);
94 	reg &= ~0xff;
95 	reg |= (dri >> 8) & 0xff;
96 	writel(reg, regs + S5P_JPGDRI_U);
97 
98 	reg = readl(regs + S5P_JPGDRI_L);
99 	reg &= ~0xff;
100 	reg |= dri & 0xff;
101 	writel(reg, regs + S5P_JPGDRI_L);
102 }
103 
s5p_jpeg_qtbl(void __iomem * regs,unsigned int t,unsigned int n)104 void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
105 {
106 	unsigned long reg;
107 
108 	reg = readl(regs + S5P_JPG_QTBL);
109 	reg &= ~S5P_QT_NUMt_MASK(t);
110 	reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
111 	writel(reg, regs + S5P_JPG_QTBL);
112 }
113 
s5p_jpeg_htbl_ac(void __iomem * regs,unsigned int t)114 void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
115 {
116 	unsigned long reg;
117 
118 	reg = readl(regs + S5P_JPG_HTBL);
119 	reg &= ~S5P_HT_NUMt_AC_MASK(t);
120 	/* this driver uses table 0 for all color components */
121 	reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
122 	writel(reg, regs + S5P_JPG_HTBL);
123 }
124 
s5p_jpeg_htbl_dc(void __iomem * regs,unsigned int t)125 void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
126 {
127 	unsigned long reg;
128 
129 	reg = readl(regs + S5P_JPG_HTBL);
130 	reg &= ~S5P_HT_NUMt_DC_MASK(t);
131 	/* this driver uses table 0 for all color components */
132 	reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
133 	writel(reg, regs + S5P_JPG_HTBL);
134 }
135 
s5p_jpeg_y(void __iomem * regs,unsigned int y)136 void s5p_jpeg_y(void __iomem *regs, unsigned int y)
137 {
138 	unsigned long reg;
139 
140 	reg = readl(regs + S5P_JPGY_U);
141 	reg &= ~0xff;
142 	reg |= (y >> 8) & 0xff;
143 	writel(reg, regs + S5P_JPGY_U);
144 
145 	reg = readl(regs + S5P_JPGY_L);
146 	reg &= ~0xff;
147 	reg |= y & 0xff;
148 	writel(reg, regs + S5P_JPGY_L);
149 }
150 
s5p_jpeg_x(void __iomem * regs,unsigned int x)151 void s5p_jpeg_x(void __iomem *regs, unsigned int x)
152 {
153 	unsigned long reg;
154 
155 	reg = readl(regs + S5P_JPGX_U);
156 	reg &= ~0xff;
157 	reg |= (x >> 8) & 0xff;
158 	writel(reg, regs + S5P_JPGX_U);
159 
160 	reg = readl(regs + S5P_JPGX_L);
161 	reg &= ~0xff;
162 	reg |= x & 0xff;
163 	writel(reg, regs + S5P_JPGX_L);
164 }
165 
s5p_jpeg_rst_int_enable(void __iomem * regs,bool enable)166 void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable)
167 {
168 	unsigned long reg;
169 
170 	reg = readl(regs + S5P_JPGINTSE);
171 	reg &= ~S5P_RSTm_INT_EN_MASK;
172 	if (enable)
173 		reg |= S5P_RSTm_INT_EN;
174 	writel(reg, regs + S5P_JPGINTSE);
175 }
176 
s5p_jpeg_data_num_int_enable(void __iomem * regs,bool enable)177 void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable)
178 {
179 	unsigned long reg;
180 
181 	reg = readl(regs + S5P_JPGINTSE);
182 	reg &= ~S5P_DATA_NUM_INT_EN_MASK;
183 	if (enable)
184 		reg |= S5P_DATA_NUM_INT_EN;
185 	writel(reg, regs + S5P_JPGINTSE);
186 }
187 
s5p_jpeg_final_mcu_num_int_enable(void __iomem * regs,bool enbl)188 void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
189 {
190 	unsigned long reg;
191 
192 	reg = readl(regs + S5P_JPGINTSE);
193 	reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
194 	if (enbl)
195 		reg |= S5P_FINAL_MCU_NUM_INT_EN;
196 	writel(reg, regs + S5P_JPGINTSE);
197 }
198 
s5p_jpeg_timer_stat(void __iomem * regs)199 int s5p_jpeg_timer_stat(void __iomem *regs)
200 {
201 	return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
202 		     >> S5P_TIMER_INT_STAT_SHIFT);
203 }
204 
s5p_jpeg_clear_timer_stat(void __iomem * regs)205 void s5p_jpeg_clear_timer_stat(void __iomem *regs)
206 {
207 	unsigned long reg;
208 
209 	reg = readl(regs + S5P_JPG_TIMER_SE);
210 	reg &= ~S5P_TIMER_INT_STAT_MASK;
211 	writel(reg, regs + S5P_JPG_TIMER_SE);
212 }
213 
s5p_jpeg_enc_stream_int(void __iomem * regs,unsigned long size)214 void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
215 {
216 	unsigned long reg;
217 
218 	reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
219 	reg &= ~S5P_ENC_STREAM_BOUND_MASK;
220 	reg |= S5P_ENC_STREAM_INT_EN;
221 	reg |= size & S5P_ENC_STREAM_BOUND_MASK;
222 	writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
223 }
224 
s5p_jpeg_enc_stream_stat(void __iomem * regs)225 int s5p_jpeg_enc_stream_stat(void __iomem *regs)
226 {
227 	return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
228 		     S5P_ENC_STREAM_INT_STAT_MASK);
229 }
230 
s5p_jpeg_clear_enc_stream_stat(void __iomem * regs)231 void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs)
232 {
233 	unsigned long reg;
234 
235 	reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
236 	reg &= ~S5P_ENC_STREAM_INT_MASK;
237 	writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
238 }
239 
s5p_jpeg_outform_raw(void __iomem * regs,unsigned long format)240 void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format)
241 {
242 	unsigned long reg, f;
243 
244 	f = S5P_DEC_OUT_FORMAT_422;
245 	if (format == S5P_JPEG_RAW_OUT_422)
246 		f = S5P_DEC_OUT_FORMAT_422;
247 	else if (format == S5P_JPEG_RAW_OUT_420)
248 		f = S5P_DEC_OUT_FORMAT_420;
249 	reg = readl(regs + S5P_JPG_OUTFORM);
250 	reg &= ~S5P_DEC_OUT_FORMAT_MASK;
251 	reg |= f;
252 	writel(reg, regs + S5P_JPG_OUTFORM);
253 }
254 
s5p_jpeg_jpgadr(void __iomem * regs,unsigned long addr)255 void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr)
256 {
257 	writel(addr, regs + S5P_JPG_JPGADR);
258 }
259 
s5p_jpeg_imgadr(void __iomem * regs,unsigned long addr)260 void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr)
261 {
262 	writel(addr, regs + S5P_JPG_IMGADR);
263 }
264 
s5p_jpeg_coef(void __iomem * regs,unsigned int i,unsigned int j,unsigned int coef)265 void s5p_jpeg_coef(void __iomem *regs, unsigned int i,
266 			     unsigned int j, unsigned int coef)
267 {
268 	unsigned long reg;
269 
270 	reg = readl(regs + S5P_JPG_COEF(i));
271 	reg &= ~S5P_COEFn_MASK(j);
272 	reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
273 	writel(reg, regs + S5P_JPG_COEF(i));
274 }
275 
s5p_jpeg_start(void __iomem * regs)276 void s5p_jpeg_start(void __iomem *regs)
277 {
278 	writel(1, regs + S5P_JSTART);
279 }
280 
s5p_jpeg_result_stat_ok(void __iomem * regs)281 int s5p_jpeg_result_stat_ok(void __iomem *regs)
282 {
283 	return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
284 		     >> S5P_RESULT_STAT_SHIFT);
285 }
286 
s5p_jpeg_stream_stat_ok(void __iomem * regs)287 int s5p_jpeg_stream_stat_ok(void __iomem *regs)
288 {
289 	return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
290 		      >> S5P_STREAM_STAT_SHIFT);
291 }
292 
s5p_jpeg_clear_int(void __iomem * regs)293 void s5p_jpeg_clear_int(void __iomem *regs)
294 {
295 	readl(regs + S5P_JPGINTST);
296 	writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
297 	readl(regs + S5P_JPGOPR);
298 }
299 
s5p_jpeg_compressed_size(void __iomem * regs)300 unsigned int s5p_jpeg_compressed_size(void __iomem *regs)
301 {
302 	unsigned long jpeg_size = 0;
303 
304 	jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
305 	jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
306 	jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
307 
308 	return (unsigned int)jpeg_size;
309 }
310