GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / media / platform / s5p-jpeg / jpeg-hw-s5p.c
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 }