iwlwifi: pcie: fix polling in various places
[cascardo/linux.git] / 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 = 0;
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 unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
237 {
238         return readl(regs + EXYNOS3250_JPGY);
239 }
240
241 unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
242 {
243         return readl(regs + EXYNOS3250_JPGX);
244 }
245
246 void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
247 {
248         u32 reg;
249
250         reg = readl(regs + EXYNOS3250_JPGINTSE);
251         reg |= (EXYNOS3250_JPEG_DONE_EN |
252                 EXYNOS3250_WDMA_DONE_EN |
253                 EXYNOS3250_RDMA_DONE_EN |
254                 EXYNOS3250_ENC_STREAM_INT_EN |
255                 EXYNOS3250_CORE_DONE_EN |
256                 EXYNOS3250_ERR_INT_EN |
257                 EXYNOS3250_HEAD_INT_EN);
258         writel(reg, regs + EXYNOS3250_JPGINTSE);
259 }
260
261 void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
262 {
263         u32 reg;
264
265         reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
266         writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
267 }
268
269 void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
270 {
271         u32 reg;
272
273         switch (fmt) {
274         case V4L2_PIX_FMT_RGB32:
275                 reg = EXYNOS3250_OUT_FMT_ARGB8888;
276                 break;
277         case V4L2_PIX_FMT_BGR32:
278                 reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
279                 break;
280         case V4L2_PIX_FMT_RGB565:
281                 reg = EXYNOS3250_OUT_FMT_RGB565;
282                 break;
283         case V4L2_PIX_FMT_RGB565X:
284                 reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
285                 break;
286         case V4L2_PIX_FMT_YUYV:
287                 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
288                 break;
289         case V4L2_PIX_FMT_YVYU:
290                 reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
291                         EXYNOS3250_OUT_SWAP_UV;
292                 break;
293         case V4L2_PIX_FMT_UYVY:
294                 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
295                 break;
296         case V4L2_PIX_FMT_VYUY:
297                 reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
298                         EXYNOS3250_OUT_SWAP_UV;
299                 break;
300         case V4L2_PIX_FMT_NV12:
301                 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
302                 break;
303         case V4L2_PIX_FMT_NV21:
304                 reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
305                 break;
306         case V4L2_PIX_FMT_YUV420:
307                 reg = EXYNOS3250_OUT_FMT_420_3P;
308                 break;
309         default:
310                 reg = 0;
311                 break;
312         }
313
314         writel(reg, regs + EXYNOS3250_OUTFORM);
315 }
316
317 void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
318 {
319         writel(addr, regs + EXYNOS3250_JPG_JPGADR);
320 }
321
322 void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
323 {
324         writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
325         writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
326         writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
327 }
328
329 void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
330                             unsigned int width)
331 {
332         u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
333
334         switch (img_fmt) {
335         case V4L2_PIX_FMT_RGB32:
336                 reg_luma = 4 * width;
337                 break;
338         case V4L2_PIX_FMT_RGB565:
339         case V4L2_PIX_FMT_RGB565X:
340         case V4L2_PIX_FMT_YUYV:
341         case V4L2_PIX_FMT_YVYU:
342         case V4L2_PIX_FMT_UYVY:
343         case V4L2_PIX_FMT_VYUY:
344                 reg_luma = 2 * width;
345                 break;
346         case V4L2_PIX_FMT_NV12:
347         case V4L2_PIX_FMT_NV21:
348                 reg_luma = width;
349                 reg_cb = reg_luma;
350                 break;
351         case V4L2_PIX_FMT_YUV420:
352                 reg_luma = width;
353                 reg_cb = reg_cr = reg_luma / 2;
354                 break;
355         default:
356                 break;
357         }
358
359         writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
360         writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
361         writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
362 }
363
364 void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
365                                 unsigned int y_offset)
366 {
367         u32 reg;
368
369         reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
370                         EXYNOS3250_LUMA_YY_OFFSET_MASK;
371         reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
372                         EXYNOS3250_LUMA_YX_OFFSET_MASK;
373
374         writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
375
376         reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
377                         EXYNOS3250_CHROMA_YY_OFFSET_MASK;
378         reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
379                         EXYNOS3250_CHROMA_YX_OFFSET_MASK;
380
381         writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
382
383         reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
384                         EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
385         reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
386                         EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
387
388         writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
389 }
390
391 void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
392 {
393         if (mode == S5P_JPEG_ENCODE) {
394                 writel(EXYNOS3250_JPEG_ENC_COEF1,
395                                         base + EXYNOS3250_JPG_COEF(1));
396                 writel(EXYNOS3250_JPEG_ENC_COEF2,
397                                         base + EXYNOS3250_JPG_COEF(2));
398                 writel(EXYNOS3250_JPEG_ENC_COEF3,
399                                         base + EXYNOS3250_JPG_COEF(3));
400         } else {
401                 writel(EXYNOS3250_JPEG_DEC_COEF1,
402                                         base + EXYNOS3250_JPG_COEF(1));
403                 writel(EXYNOS3250_JPEG_DEC_COEF2,
404                                         base + EXYNOS3250_JPG_COEF(2));
405                 writel(EXYNOS3250_JPEG_DEC_COEF3,
406                                         base + EXYNOS3250_JPG_COEF(3));
407         }
408 }
409
410 void exynos3250_jpeg_start(void __iomem *regs)
411 {
412         writel(1, regs + EXYNOS3250_JSTART);
413 }
414
415 void exynos3250_jpeg_rstart(void __iomem *regs)
416 {
417         writel(1, regs + EXYNOS3250_JRSTART);
418 }
419
420 unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
421 {
422         return readl(regs + EXYNOS3250_JPGINTST);
423 }
424
425 void exynos3250_jpeg_clear_int_status(void __iomem *regs,
426                                                 unsigned int value)
427 {
428         return writel(value, regs + EXYNOS3250_JPGINTST);
429 }
430
431 unsigned int exynos3250_jpeg_operating(void __iomem *regs)
432 {
433         return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
434 }
435
436 unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
437 {
438         return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
439 }
440
441 void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
442                                                 unsigned int size)
443 {
444         writel(size & EXYNOS3250_DEC_STREAM_MASK,
445                                 regs + EXYNOS3250_DEC_STREAM_SIZE);
446 }
447
448 void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
449                                                 unsigned int sratio)
450 {
451         switch (sratio) {
452         case 1:
453         default:
454                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
455                 break;
456         case 2:
457                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
458                 break;
459         case 4:
460                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
461                 break;
462         case 8:
463                 sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
464                 break;
465         }
466
467         writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
468                                 regs + EXYNOS3250_DEC_SCALING_RATIO);
469 }
470
471 void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
472 {
473         time_value &= EXYNOS3250_TIMER_INIT_MASK;
474
475         writel(EXYNOS3250_TIMER_INT_STAT | time_value,
476                                         regs + EXYNOS3250_TIMER_SE);
477 }
478
479 unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
480 {
481         return readl(regs + EXYNOS3250_TIMER_ST);
482 }
483
484 void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
485 {
486         writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);
487 }