Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / platform / s5p-jpeg / jpeg-hw-exynos3250.c
1 /* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h
2  *
3  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * Author: Jacek Anaszewski <j.anaszewski@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 #include <linux/delay.h>
16
17 #include "jpeg-core.h"
18 #include "jpeg-regs.h"
19 #include "jpeg-hw-exynos3250.h"
20
21 void exynos3250_jpeg_reset(void __iomem *regs)
22 {
23         u32 reg = 1;
24         int count = 1000;
25
26         writel(1, regs + EXYNOS3250_SW_RESET);
27         /* no other way but polling for when JPEG IP becomes operational */
28         while (reg != 0 && --count > 0) {
29                 udelay(1);
30                 cpu_relax();
31                 reg = readl(regs + EXYNOS3250_SW_RESET);
32         }
33
34         reg = 0;
35         count = 1000;
36
37         while (reg != 1 && --count > 0) {
38                 writel(1, regs + EXYNOS3250_JPGDRI);
39                 udelay(1);
40                 cpu_relax();
41                 reg = readl(regs + EXYNOS3250_JPGDRI);
42         }
43
44         writel(0, regs + EXYNOS3250_JPGDRI);
45 }
46
47 void exynos3250_jpeg_poweron(void __iomem *regs)
48 {
49         writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
50 }
51
52 void exynos3250_jpeg_set_dma_num(void __iomem *regs)
53 {
54         writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &
55                         EXYNOS3250_WDMA_ISSUE_NUM_MASK) |
56                ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &
57                         EXYNOS3250_RDMA_ISSUE_NUM_MASK) |
58                ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &
59                         EXYNOS3250_ISSUE_GATHER_NUM_MASK),
60                 regs + EXYNOS3250_DMA_ISSUE_NUM);
61 }
62
63 void exynos3250_jpeg_clk_set(void __iomem *base)
64 {
65         u32 reg;
66
67         reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;
68
69         writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);
70 }
71
72 void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)
73 {
74         u32 reg;
75
76         reg = readl(regs + EXYNOS3250_JPGCMOD) &
77                         EXYNOS3250_MODE_Y16_MASK;
78
79         switch (fmt) {
80         case V4L2_PIX_FMT_RGB32:
81                 reg |= EXYNOS3250_MODE_SEL_ARGB8888;
82                 break;
83         case V4L2_PIX_FMT_BGR32:
84                 reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;
85                 break;
86         case V4L2_PIX_FMT_RGB565:
87                 reg |= EXYNOS3250_MODE_SEL_RGB565;
88                 break;
89         case V4L2_PIX_FMT_RGB565X:
90                 reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;
91                 break;
92         case V4L2_PIX_FMT_YUYV:
93                 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;
94                 break;
95         case V4L2_PIX_FMT_YVYU:
96                 reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |
97                         EXYNOS3250_SRC_SWAP_UV;
98                 break;
99         case V4L2_PIX_FMT_UYVY:
100                 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;
101                 break;
102         case V4L2_PIX_FMT_VYUY:
103                 reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |
104                         EXYNOS3250_SRC_SWAP_UV;
105                 break;
106         case V4L2_PIX_FMT_NV12:
107                 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;
108                 break;
109         case V4L2_PIX_FMT_NV21:
110                 reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;
111                 break;
112         case V4L2_PIX_FMT_YUV420:
113                 reg |= EXYNOS3250_MODE_SEL_420_3P;
114                 break;
115         default:
116                 break;
117
118         }
119
120         writel(reg, regs + EXYNOS3250_JPGCMOD);
121 }
122
123 void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)
124 {
125         u32 reg;
126
127         reg = readl(regs + EXYNOS3250_JPGCMOD);
128         if (y16)
129                 reg |= EXYNOS3250_MODE_Y16;
130         else
131                 reg &= ~EXYNOS3250_MODE_Y16_MASK;
132         writel(reg, regs + EXYNOS3250_JPGCMOD);
133 }
134
135 void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)
136 {
137         u32 reg, m;
138
139         if (mode == S5P_JPEG_ENCODE)
140                 m = EXYNOS3250_PROC_MODE_COMPR;
141         else
142                 m = EXYNOS3250_PROC_MODE_DECOMPR;
143         reg = readl(regs + EXYNOS3250_JPGMOD);
144         reg &= ~EXYNOS3250_PROC_MODE_MASK;
145         reg |= m;
146         writel(reg, regs + EXYNOS3250_JPGMOD);
147 }
148
149 void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
150 {
151         u32 reg, m = 0;
152
153         switch (mode) {
154         case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
155                 m = EXYNOS3250_SUBSAMPLING_MODE_444;
156                 break;
157         case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
158                 m = EXYNOS3250_SUBSAMPLING_MODE_422;
159                 break;
160         case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
161                 m = EXYNOS3250_SUBSAMPLING_MODE_420;
162                 break;
163         }
164
165         reg = readl(regs + EXYNOS3250_JPGMOD);
166         reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;
167         reg |= m;
168         writel(reg, regs + EXYNOS3250_JPGMOD);
169 }
170
171 unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
172 {
173         return readl(regs + EXYNOS3250_JPGMOD) &
174                                 EXYNOS3250_SUBSAMPLING_MODE_MASK;
175 }
176
177 void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)
178 {
179         u32 reg;
180
181         reg = dri & EXYNOS3250_JPGDRI_MASK;
182         writel(reg, regs + EXYNOS3250_JPGDRI);
183 }
184
185 void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
186 {
187         unsigned long reg;
188
189         reg = readl(regs + EXYNOS3250_QHTBL);
190         reg &= ~EXYNOS3250_QT_NUM_MASK(t);
191         reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &
192                                         EXYNOS3250_QT_NUM_MASK(t);
193         writel(reg, regs + EXYNOS3250_QHTBL);
194 }
195
196 void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
197 {
198         unsigned long reg;
199
200         reg = readl(regs + EXYNOS3250_QHTBL);
201         reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);
202         /* this driver uses table 0 for all color components */
203         reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &
204                                         EXYNOS3250_HT_NUM_AC_MASK(t);
205         writel(reg, regs + EXYNOS3250_QHTBL);
206 }
207
208 void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
209 {
210         unsigned long reg;
211
212         reg = readl(regs + EXYNOS3250_QHTBL);
213         reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);
214         /* this driver uses table 0 for all color components */
215         reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &
216                                         EXYNOS3250_HT_NUM_DC_MASK(t);
217         writel(reg, regs + EXYNOS3250_QHTBL);
218 }
219
220 void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)
221 {
222         u32 reg;
223
224         reg = y & EXYNOS3250_JPGY_MASK;
225         writel(reg, regs + EXYNOS3250_JPGY);
226 }
227
228 void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)
229 {
230         u32 reg;
231
232         reg = x & EXYNOS3250_JPGX_MASK;
233         writel(reg, regs + EXYNOS3250_JPGX);
234 }
235
236 #if 0   /* Currently unused */
237 unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
238 {
239         return readl(regs + EXYNOS3250_JPGY);
240 }
241
242 unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
243 {
244         return readl(regs + EXYNOS3250_JPGX);
245 }
246 #endif
247
248 void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
249 {
250         u32 reg;
251
252         reg = readl(regs + EXYNOS3250_JPGINTSE);
253         reg |= (EXYNOS3250_JPEG_DONE_EN |
254                 EXYNOS3250_WDMA_DONE_EN |
255                 EXYNOS3250_RDMA_DONE_EN |
256                 EXYNOS3250_ENC_STREAM_INT_EN |
257                 EXYNOS3250_CORE_DONE_EN |
258                 EXYNOS3250_ERR_INT_EN |
259                 EXYNOS3250_HEAD_INT_EN);
260         writel(reg, regs + EXYNOS3250_JPGINTSE);
261 }
262
263 void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
264 {
265         u32 reg;
266
267         reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
268         writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
269 }
270
271 void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
272 {
273         u32 reg;
274
275         switch (fmt) {
276         case V4L2_PIX_FMT_RGB32:
277                 reg = EXYNOS3250_OUT_FMT_ARGB8888;
278                 break;
279         case V4L2_PIX_FMT_BGR32:
280                 reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
281                 break;
282         case V4L2_PIX_FMT_RGB565:
283                 reg = EXYNOS3250_OUT_FMT_RGB565;
284                 break;
285         case V4L2_PIX_FMT_RGB565X:
286                 reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
287                 break;
288         case V4L2_PIX_FMT_YUYV:
289                 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
290                 break;
291         case V4L2_PIX_FMT_YVYU:
292                 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
293                         EXYNOS3250_OUT_SWAP_UV;
294                 break;
295         case V4L2_PIX_FMT_UYVY:
296                 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
297                 break;
298         case V4L2_PIX_FMT_VYUY:
299                 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
300                         EXYNOS3250_OUT_SWAP_UV;
301                 break;
302         case V4L2_PIX_FMT_NV12:
303                 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
304                 break;
305         case V4L2_PIX_FMT_NV21:
306                 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
307                 break;
308         case V4L2_PIX_FMT_YUV420:
309                 reg = EXYNOS3250_OUT_FMT_420_3P;
310                 break;
311         default:
312                 reg = 0;
313                 break;
314         }
315
316         writel(reg, regs + EXYNOS3250_OUTFORM);
317 }
318
319 void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
320 {
321         writel(addr, regs + EXYNOS3250_JPG_JPGADR);
322 }
323
324 void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
325 {
326         writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
327         writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
328         writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
329 }
330
331 void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
332                             unsigned int width)
333 {
334         u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
335
336         switch (img_fmt) {
337         case V4L2_PIX_FMT_RGB32:
338                 reg_luma = 4 * width;
339                 break;
340         case V4L2_PIX_FMT_RGB565:
341         case V4L2_PIX_FMT_RGB565X:
342         case V4L2_PIX_FMT_YUYV:
343         case V4L2_PIX_FMT_YVYU:
344         case V4L2_PIX_FMT_UYVY:
345         case V4L2_PIX_FMT_VYUY:
346                 reg_luma = 2 * width;
347                 break;
348         case V4L2_PIX_FMT_NV12:
349         case V4L2_PIX_FMT_NV21:
350                 reg_luma = width;
351                 reg_cb = reg_luma;
352                 break;
353         case V4L2_PIX_FMT_YUV420:
354                 reg_luma = width;
355                 reg_cb = reg_cr = reg_luma / 2;
356                 break;
357         default:
358                 break;
359         }
360
361         writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
362         writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
363         writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
364 }
365
366 void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
367                                 unsigned int y_offset)
368 {
369         u32 reg;
370
371         reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
372                         EXYNOS3250_LUMA_YY_OFFSET_MASK;
373         reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
374                         EXYNOS3250_LUMA_YX_OFFSET_MASK;
375
376         writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
377
378         reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
379                         EXYNOS3250_CHROMA_YY_OFFSET_MASK;
380         reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
381                         EXYNOS3250_CHROMA_YX_OFFSET_MASK;
382
383         writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
384
385         reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
386                         EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
387         reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
388                         EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
389
390         writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
391 }
392
393 void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
394 {
395         if (mode == S5P_JPEG_ENCODE) {
396                 writel(EXYNOS3250_JPEG_ENC_COEF1,
397                                         base + EXYNOS3250_JPG_COEF(1));
398                 writel(EXYNOS3250_JPEG_ENC_COEF2,
399                                         base + EXYNOS3250_JPG_COEF(2));
400                 writel(EXYNOS3250_JPEG_ENC_COEF3,
401                                         base + EXYNOS3250_JPG_COEF(3));
402         } else {
403                 writel(EXYNOS3250_JPEG_DEC_COEF1,
404                                         base + EXYNOS3250_JPG_COEF(1));
405                 writel(EXYNOS3250_JPEG_DEC_COEF2,
406                                         base + EXYNOS3250_JPG_COEF(2));
407                 writel(EXYNOS3250_JPEG_DEC_COEF3,
408                                         base + EXYNOS3250_JPG_COEF(3));
409         }
410 }
411
412 void exynos3250_jpeg_start(void __iomem *regs)
413 {
414         writel(1, regs + EXYNOS3250_JSTART);
415 }
416
417 void exynos3250_jpeg_rstart(void __iomem *regs)
418 {
419         writel(1, regs + EXYNOS3250_JRSTART);
420 }
421
422 unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
423 {
424         return readl(regs + EXYNOS3250_JPGINTST);
425 }
426
427 void exynos3250_jpeg_clear_int_status(void __iomem *regs,
428                                                 unsigned int value)
429 {
430         return writel(value, regs + EXYNOS3250_JPGINTST);
431 }
432
433 unsigned int exynos3250_jpeg_operating(void __iomem *regs)
434 {
435         return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
436 }
437
438 unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
439 {
440         return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
441 }
442
443 void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
444                                                 unsigned int size)
445 {
446         writel(size & EXYNOS3250_DEC_STREAM_MASK,
447                                 regs + EXYNOS3250_DEC_STREAM_SIZE);
448 }
449
450 void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
451                                                 unsigned int sratio)
452 {
453         switch (sratio) {
454         case 1:
455         default:
456                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
457                 break;
458         case 2:
459                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
460                 break;
461         case 4:
462                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
463                 break;
464         case 8:
465                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
466                 break;
467         }
468
469         writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
470                                 regs + EXYNOS3250_DEC_SCALING_RATIO);
471 }
472
473 void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
474 {
475         time_value &= EXYNOS3250_TIMER_INIT_MASK;
476
477         writel(EXYNOS3250_TIMER_INT_STAT | time_value,
478                                         regs + EXYNOS3250_TIMER_SE);
479 }
480
481 unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
482 {
483         return readl(regs + EXYNOS3250_TIMER_ST);
484 }
485
486 void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
487 {
488         writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);
489 }