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