]>
Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
2c3fb08b | 2 | /* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h |
bb677f3a AP |
3 | * |
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | |
5 | * http://www.samsung.com | |
6 | * | |
66e988e9 | 7 | * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> |
bb677f3a | 8 | */ |
bb677f3a AP |
9 | |
10 | #include <linux/io.h> | |
15f4bc3b | 11 | #include <linux/videodev2.h> |
bb677f3a | 12 | |
9f7b62d9 | 13 | #include "jpeg-core.h" |
bb677f3a | 14 | #include "jpeg-regs.h" |
9f7b62d9 | 15 | #include "jpeg-hw-s5p.h" |
bb677f3a | 16 | |
9f7b62d9 | 17 | void s5p_jpeg_reset(void __iomem *regs) |
bb677f3a AP |
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 | ||
9f7b62d9 | 30 | void s5p_jpeg_poweron(void __iomem *regs) |
bb677f3a AP |
31 | { |
32 | writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); | |
33 | } | |
34 | ||
9f7b62d9 | 35 | void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) |
bb677f3a AP |
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 | ||
9f7b62d9 | 51 | void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) |
bb677f3a AP |
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 | ||
9f7b62d9 | 66 | void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) |
bb677f3a AP |
67 | { |
68 | unsigned long reg, m; | |
69 | ||
15f4bc3b | 70 | if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) |
bb677f3a | 71 | m = S5P_SUBSAMPLING_MODE_420; |
15f4bc3b SN |
72 | else |
73 | m = S5P_SUBSAMPLING_MODE_422; | |
74 | ||
bb677f3a AP |
75 | reg = readl(regs + S5P_JPGMOD); |
76 | reg &= ~S5P_SUBSAMPLING_MODE_MASK; | |
77 | reg |= m; | |
78 | writel(reg, regs + S5P_JPGMOD); | |
79 | } | |
80 | ||
9f7b62d9 | 81 | unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) |
15f4bc3b SN |
82 | { |
83 | return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; | |
84 | } | |
85 | ||
9f7b62d9 | 86 | void s5p_jpeg_dri(void __iomem *regs, unsigned int dri) |
bb677f3a AP |
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 | ||
9f7b62d9 | 101 | void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) |
bb677f3a AP |
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 | ||
9f7b62d9 | 111 | void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t) |
bb677f3a AP |
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 | ||
9f7b62d9 | 122 | void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t) |
bb677f3a AP |
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 | ||
9f7b62d9 | 133 | void s5p_jpeg_y(void __iomem *regs, unsigned int y) |
bb677f3a AP |
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 | ||
9f7b62d9 | 148 | void s5p_jpeg_x(void __iomem *regs, unsigned int x) |
bb677f3a AP |
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 | ||
9f7b62d9 | 163 | void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable) |
bb677f3a AP |
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 | ||
9f7b62d9 | 174 | void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable) |
bb677f3a AP |
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 | ||
9f7b62d9 | 185 | void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) |
bb677f3a AP |
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 | ||
9f7b62d9 | 196 | int s5p_jpeg_timer_stat(void __iomem *regs) |
bb677f3a AP |
197 | { |
198 | return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) | |
199 | >> S5P_TIMER_INT_STAT_SHIFT); | |
200 | } | |
201 | ||
9f7b62d9 | 202 | void s5p_jpeg_clear_timer_stat(void __iomem *regs) |
bb677f3a AP |
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 | ||
9f7b62d9 | 211 | void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size) |
bb677f3a AP |
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 | ||
9f7b62d9 | 222 | int s5p_jpeg_enc_stream_stat(void __iomem *regs) |
bb677f3a AP |
223 | { |
224 | return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & | |
225 | S5P_ENC_STREAM_INT_STAT_MASK); | |
226 | } | |
227 | ||
9f7b62d9 | 228 | void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs) |
bb677f3a AP |
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 | ||
9f7b62d9 | 237 | void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format) |
bb677f3a AP |
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 | ||
9f7b62d9 | 252 | void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) |
bb677f3a AP |
253 | { |
254 | writel(addr, regs + S5P_JPG_JPGADR); | |
255 | } | |
256 | ||
9f7b62d9 | 257 | void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) |
bb677f3a AP |
258 | { |
259 | writel(addr, regs + S5P_JPG_IMGADR); | |
260 | } | |
261 | ||
9f7b62d9 | 262 | void s5p_jpeg_coef(void __iomem *regs, unsigned int i, |
bb677f3a AP |
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 | ||
9f7b62d9 | 273 | void s5p_jpeg_start(void __iomem *regs) |
bb677f3a AP |
274 | { |
275 | writel(1, regs + S5P_JSTART); | |
276 | } | |
277 | ||
9f7b62d9 | 278 | int s5p_jpeg_result_stat_ok(void __iomem *regs) |
bb677f3a AP |
279 | { |
280 | return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) | |
281 | >> S5P_RESULT_STAT_SHIFT); | |
282 | } | |
283 | ||
9f7b62d9 | 284 | int s5p_jpeg_stream_stat_ok(void __iomem *regs) |
bb677f3a AP |
285 | { |
286 | return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) | |
287 | >> S5P_STREAM_STAT_SHIFT); | |
288 | } | |
289 | ||
9f7b62d9 | 290 | void s5p_jpeg_clear_int(void __iomem *regs) |
bb677f3a | 291 | { |
c4382699 | 292 | readl(regs + S5P_JPGINTST); |
bb677f3a | 293 | writel(S5P_INT_RELEASE, regs + S5P_JPGCOM); |
0cd9b21e | 294 | readl(regs + S5P_JPGOPR); |
bb677f3a AP |
295 | } |
296 | ||
9f7b62d9 | 297 | unsigned int s5p_jpeg_compressed_size(void __iomem *regs) |
bb677f3a AP |
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 | } |