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
19void 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
31void 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
48void 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
121void 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
152void exynos4_jpeg_set_interrupt(void __iomem *base)
153{
154	writel(EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
155}
156
157unsigned 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
166unsigned 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
175void 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
189void 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
201void 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
207void 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
215void 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
223void 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
237void 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
245unsigned 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
253void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
254{
255	writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG);
256}
257
258void 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
267unsigned 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
273void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size)
274{
275	writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG);
276}
277