Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / platform / s5p-jpeg / jpeg-hw-exynos4.c
1 /* Copyright (c) 2013 Samsung Electronics Co., Ltd.
2  *              http://www.samsung.com/
3  *
4  * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
5  *
6  * Register interface file for JPEG driver on Exynos4x12.
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 #include <linux/io.h>
13 #include <linux/delay.h>
14
15 #include "jpeg-core.h"
16 #include "jpeg-hw-exynos4.h"
17 #include "jpeg-regs.h"
18
19 void exynos4_jpeg_sw_reset(void __iomem *base)
20 {
21         unsigned int reg;
22
23         reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
24         writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
25
26         udelay(100);
27
28         writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
29 }
30
31 void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
32 {
33         unsigned int reg;
34
35         reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
36         /* set exynos4_jpeg mod register */
37         if (mode == S5P_JPEG_DECODE) {
38                 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
39                                         EXYNOS4_DEC_MODE,
40                         base + EXYNOS4_JPEG_CNTL_REG);
41         } else {/* encode */
42                 writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
43                                         EXYNOS4_ENC_MODE,
44                         base + EXYNOS4_JPEG_CNTL_REG);
45         }
46 }
47
48 void exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt)
49 {
50         unsigned int reg;
51
52         reg = readl(base + EXYNOS4_IMG_FMT_REG) &
53                         EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */
54
55         switch (img_fmt) {
56         case V4L2_PIX_FMT_GREY:
57                 reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP;
58                 break;
59         case V4L2_PIX_FMT_RGB32:
60                 reg = reg | EXYNOS4_ENC_RGB_IMG |
61                                 EXYNOS4_RGB_IP_RGB_32BIT_IMG;
62                 break;
63         case V4L2_PIX_FMT_RGB565:
64                 reg = reg | EXYNOS4_ENC_RGB_IMG |
65                                 EXYNOS4_RGB_IP_RGB_16BIT_IMG;
66                 break;
67         case V4L2_PIX_FMT_NV24:
68                 reg = reg | EXYNOS4_ENC_YUV_444_IMG |
69                                 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
70                                 EXYNOS4_SWAP_CHROMA_CBCR;
71                 break;
72         case V4L2_PIX_FMT_NV42:
73                 reg = reg | EXYNOS4_ENC_YUV_444_IMG |
74                                 EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
75                                 EXYNOS4_SWAP_CHROMA_CRCB;
76                 break;
77         case V4L2_PIX_FMT_YUYV:
78                 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
79                                 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
80                                 EXYNOS4_SWAP_CHROMA_CBCR;
81                 break;
82
83         case V4L2_PIX_FMT_YVYU:
84                 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
85                                 EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
86                                 EXYNOS4_SWAP_CHROMA_CRCB;
87                 break;
88         case V4L2_PIX_FMT_NV16:
89                 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
90                                 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
91                                 EXYNOS4_SWAP_CHROMA_CBCR;
92                 break;
93         case V4L2_PIX_FMT_NV61:
94                 reg = reg | EXYNOS4_DEC_YUV_422_IMG |
95                                 EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
96                                 EXYNOS4_SWAP_CHROMA_CRCB;
97                 break;
98         case V4L2_PIX_FMT_NV12:
99                 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
100                                 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
101                                 EXYNOS4_SWAP_CHROMA_CBCR;
102                 break;
103         case V4L2_PIX_FMT_NV21:
104                 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
105                                 EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
106                                 EXYNOS4_SWAP_CHROMA_CRCB;
107                 break;
108         case V4L2_PIX_FMT_YUV420:
109                 reg = reg | EXYNOS4_DEC_YUV_420_IMG |
110                                 EXYNOS4_YUV_420_IP_YUV_420_3P_IMG |
111                                 EXYNOS4_SWAP_CHROMA_CBCR;
112                 break;
113         default:
114                 break;
115
116         }
117
118         writel(reg, base + EXYNOS4_IMG_FMT_REG);
119 }
120
121 void exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt)
122 {
123         unsigned int reg;
124
125         reg = readl(base + EXYNOS4_IMG_FMT_REG) &
126                         ~EXYNOS4_ENC_FMT_MASK; /* clear enc format */
127
128         switch (out_fmt) {
129         case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
130                 reg = reg | EXYNOS4_ENC_FMT_GRAY;
131                 break;
132
133         case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
134                 reg = reg | EXYNOS4_ENC_FMT_YUV_444;
135                 break;
136
137         case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
138                 reg = reg | EXYNOS4_ENC_FMT_YUV_422;
139                 break;
140
141         case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
142                 reg = reg | EXYNOS4_ENC_FMT_YUV_420;
143                 break;
144
145         default:
146                 break;
147         }
148
149         writel(reg, base + EXYNOS4_IMG_FMT_REG);
150 }
151
152 void exynos4_jpeg_set_interrupt(void __iomem *base)
153 {
154         writel(EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
155 }
156
157 unsigned int exynos4_jpeg_get_int_status(void __iomem *base)
158 {
159         unsigned int    int_status;
160
161         int_status = readl(base + EXYNOS4_INT_STATUS_REG);
162
163         return int_status;
164 }
165
166 unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base)
167 {
168         unsigned int fifo_status;
169
170         fifo_status = readl(base + EXYNOS4_FIFO_STATUS_REG);
171
172         return fifo_status;
173 }
174
175 void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value)
176 {
177         unsigned int    reg;
178
179         reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN;
180
181         if (value == 1)
182                 writel(reg | EXYNOS4_HUF_TBL_EN,
183                                         base + EXYNOS4_JPEG_CNTL_REG);
184         else
185                 writel(reg & ~EXYNOS4_HUF_TBL_EN,
186                                         base + EXYNOS4_JPEG_CNTL_REG);
187 }
188
189 void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value)
190 {
191         unsigned int    reg;
192
193         reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN);
194
195         if (value == 1)
196                 writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
197         else
198                 writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
199 }
200
201 void exynos4_jpeg_set_stream_buf_address(void __iomem *base,
202                                          unsigned int address)
203 {
204         writel(address, base + EXYNOS4_OUT_MEM_BASE_REG);
205 }
206
207 void exynos4_jpeg_set_stream_size(void __iomem *base,
208                 unsigned int x_value, unsigned int y_value)
209 {
210         writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */
211         writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value),
212                         base + EXYNOS4_JPEG_IMG_SIZE_REG);
213 }
214
215 void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
216                                 struct s5p_jpeg_addr *exynos4_jpeg_addr)
217 {
218         writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG);
219         writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG);
220         writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG);
221 }
222
223 void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
224                 enum exynos4_jpeg_img_quality_level level)
225 {
226         unsigned int    reg;
227
228         reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 |
229                 EXYNOS4_Q_TBL_COMP3_1 |
230                 EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 |
231                 EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 |
232                 EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1;
233
234         writel(reg, base + EXYNOS4_TBL_SEL_REG);
235 }
236
237 void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
238 {
239         if (fmt == V4L2_PIX_FMT_GREY)
240                 writel(0xd2, base + EXYNOS4_HUFF_CNT_REG);
241         else
242                 writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG);
243 }
244
245 unsigned int exynos4_jpeg_get_stream_size(void __iomem *base)
246 {
247         unsigned int size;
248
249         size = readl(base + EXYNOS4_BITSTREAM_SIZE_REG);
250         return size;
251 }
252
253 void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
254 {
255         writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG);
256 }
257
258 void exynos4_jpeg_get_frame_size(void __iomem *base,
259                         unsigned int *width, unsigned int *height)
260 {
261         *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) &
262                                 EXYNOS4_DECODED_SIZE_MASK);
263         *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) &
264                                 EXYNOS4_DECODED_SIZE_MASK;
265 }
266
267 unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base)
268 {
269         return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) &
270                                 EXYNOS4_JPEG_DECODED_IMG_FMT_MASK;
271 }
272
273 void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size)
274 {
275         writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG);
276 }