• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * vpu.h
3  *
4  * linux device driver for VPU.
5  *
6  * Copyright (C) 2006 - 2013  CHIPS&MEDIA INC.
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 as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  */
19 
20 #ifndef __VPU_DRV_H__
21 #define __VPU_DRV_H__
22 
23 #include <linux/fs.h>
24 #include <linux/types.h>
25 #include <linux/compat.h>
26 #include <linux/dma-buf.h>
27 
28 #define MAX_INST_HANDLE_SIZE	        (32*1024)
29 #define MAX_NUM_INSTANCE                4
30 #define MAX_NUM_VPU_CORE                1
31 
32 #define W4_CMD_INIT_VPU				(0x0001)
33 #define W4_CMD_SLEEP_VPU				(0x0400)
34 #define W4_CMD_WAKEUP_VPU			(0x0800)
35 
36 /* GXM: 2000/10 = 200M */
37 #define HevcEnc_L0()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
38 			 (3 << 25) | (1 << 16) | (3 << 9) | (1 << 0))
39 /* GXM: 2000/8 = 250M */
40 #define HevcEnc_L1()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
41 			 (1 << 25) | (1 << 16) | (1 << 9) | (1 << 0))
42 /* GXM: 2000/7 = 285M */
43 #define HevcEnc_L2()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
44 			 (4 << 25) | (0 << 16) | (4 << 9) | (0 << 0))
45 /*GXM: 2000/6 = 333M */
46 #define HevcEnc_L3()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
47 			 (2 << 25) | (1 << 16) | (2 << 9) | (1 << 0))
48 /* GXM: 2000/5 = 400M */
49 #define HevcEnc_L4()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
50 			 (3 << 25) | (0 << 16) | (3 << 9) | (0 << 0))
51 /* GXM: 2000/4 = 500M */
52 #define HevcEnc_L5()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
53 			 (1 << 25) | (0 << 16) | (1 << 9) | (0 << 0))
54 /* GXM: 2000/3 = 667M */
55 #define HevcEnc_L6()   WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
56 			 (2 << 25) | (0 << 16) | (2 << 9) | (0 << 0))
57 
58 #define HevcEnc_clock_enable(level) \
59 	do { \
60 		WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
61 			READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \
62 			& (~(1 << 8)) & (~(1 << 24))); \
63 		if (level == 0)  \
64 			HevcEnc_L0(); \
65 		else if (level == 1)  \
66 			HevcEnc_L1(); \
67 		else if (level == 2)  \
68 			HevcEnc_L2(); \
69 		else if (level == 3)  \
70 			HevcEnc_L3(); \
71 		else if (level == 4)  \
72 			HevcEnc_L4(); \
73 		else if (level == 5)  \
74 			HevcEnc_L5(); \
75 		else if (level == 6)  \
76 			HevcEnc_L6(); \
77 		WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
78 			READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \
79 			| (1 << 8) | (1 << 24)); \
80 	} while (0)
81 
82 #define HevcEnc_clock_disable() \
83 	WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \
84 	READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \
85 		& (~(1 << 8)) & (~(1 << 24)))
86 
87 /* ACLK 667MHZ */
88 #define HevcEnc_MoreClock_enable() \
89 	do { \
90 		WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL2, \
91 			READ_HHI_REG(HHI_WAVE420L_CLK_CNTL2) \
92 			& (~(1 << 8))); \
93 		WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL2, \
94 			(2 << 9) | (0 << 0)); \
95 		WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL2, \
96 			READ_HHI_REG(HHI_WAVE420L_CLK_CNTL2) \
97 			| (1 << 8)); \
98 	} while (0)
99 
100 #define HevcEnc_MoreClock_disable() \
101 	WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL2, \
102 	READ_HHI_REG(HHI_WAVE420L_CLK_CNTL2) \
103 		& (~(1 << 8)))
104 
105 typedef enum
106 {
107     AMVENC_YUV422_SINGLE = 0,
108     AMVENC_YUV444_SINGLE,
109     AMVENC_NV21,
110     AMVENC_NV12,
111     AMVENC_YUV420,
112     AMVENC_YUV444_PLANE,
113     AMVENC_RGB888,
114     AMVENC_RGB888_PLANE,
115     AMVENC_RGB565,
116     AMVENC_RGBA8888,
117     AMVENC_FRAME_FMT
118 } AMVEncFrameFmt;
119 
120 #ifdef CONFIG_COMPAT
121 struct compat_vpudrv_buffer_t {
122 	u32 size;
123 	u32 cached;
124 	compat_ulong_t phys_addr;
125 	compat_ulong_t base; /* kernel logical address in use kernel */
126 	compat_ulong_t virt_addr; /* virtual user space address */
127 };
128 #endif
129 
130 struct vpudrv_buffer_t {
131 	u32 size;
132 	u32 cached;
133 	ulong phys_addr;
134 	ulong base; /* kernel logical address in use kernel */
135 	ulong virt_addr; /* virtual user space address */
136 };
137 
138 struct vpu_bit_firmware_info_t {
139 	u32 size; /* size of this structure*/
140 	u32 core_idx;
141 	u32 reg_base_offset;
142 	u16 bit_code[512];
143 };
144 
145 struct vpudrv_inst_info_t {
146 	u32 core_idx;
147 	u32 inst_idx;
148 	s32 inst_open_count;	/* for output only*/
149 };
150 
151 struct vpudrv_intr_info_t {
152 	u32 timeout;
153 	s32 intr_reason;
154 };
155 
156 struct vpu_drv_context_t {
157 	struct fasync_struct *async_queue;
158 	ulong interrupt_reason;
159 	u32 open_count; /*!<< device reference count. Not instance count */
160 };
161 
162 /* To track the allocated memory buffer */
163 struct vpudrv_buffer_pool_t {
164 	struct list_head list;
165 	struct vpudrv_buffer_t vb;
166 	struct file *filp;
167 };
168 
169 /* To track the instance index and buffer in instance pool */
170 struct vpudrv_instanace_list_t {
171 	struct list_head list;
172 	ulong inst_idx;
173 	ulong core_idx;
174 	struct file *filp;
175 };
176 
177 struct vpudrv_instance_pool_t {
178 	u8 codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
179 };
180 
181 struct vpu_dma_buf_info_t {
182     u32 width;
183     u32 height;
184     AMVEncFrameFmt fmt;
185     u32 num_planes;
186     s32 fd[3];
187 };
188 
189 struct vpu_dma_cfg {
190 	int fd;
191 	void *dev;
192 	void *vaddr;
193 	void *paddr;
194 	struct dma_buf *dbuf;
195 	struct dma_buf_attachment *attach;
196 	struct sg_table *sg;
197 	enum dma_data_direction dir;
198 };
199 
200 #define VPUDRV_BUF_LEN struct vpudrv_buffer_t
201 #define VPUDRV_BUF_LEN32 struct compat_vpudrv_buffer_t
202 #define VPUDRV_INST_LEN struct vpudrv_inst_info_t
203 
204 #define VDI_MAGIC  'V'
205 #define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY \
206 	_IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN)
207 
208 #define VDI_IOCTL_FREE_PHYSICALMEMORY \
209 	_IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN)
210 
211 #define VDI_IOCTL_WAIT_INTERRUPT \
212 	_IOW(VDI_MAGIC, 2, struct vpudrv_intr_info_t)
213 
214 #define VDI_IOCTL_SET_CLOCK_GATE \
215 	_IOW(VDI_MAGIC, 3, u32)
216 
217 #define VDI_IOCTL_RESET \
218 	_IOW(VDI_MAGIC, 4, u32)
219 
220 #define VDI_IOCTL_GET_INSTANCE_POOL \
221 	_IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN)
222 
223 #define VDI_IOCTL_GET_COMMON_MEMORY \
224 	_IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN)
225 
226 #define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO \
227 	_IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN)
228 
229 #define VDI_IOCTL_OPEN_INSTANCE \
230 	_IOW(VDI_MAGIC, 9, VPUDRV_INST_LEN)
231 
232 #define VDI_IOCTL_CLOSE_INSTANCE \
233 	_IOW(VDI_MAGIC, 10, VPUDRV_INST_LEN)
234 
235 #define VDI_IOCTL_GET_INSTANCE_NUM \
236 	_IOW(VDI_MAGIC, 11, VPUDRV_INST_LEN)
237 
238 #define VDI_IOCTL_GET_REGISTER_INFO \
239 	_IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN)
240 
241 #define VDI_IOCTL_FLUSH_BUFFER \
242 	_IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN)
243 
244 #define VDI_IOCTL_CONFIG_DMA \
245         _IOW(VDI_MAGIC, 14, struct vpu_dma_buf_info_t)
246 
247 #define VDI_IOCTL_UNMAP_DMA \
248         _IOW(VDI_MAGIC, 15, u32)
249 
250 #ifdef CONFIG_COMPAT
251 #define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32 \
252 	_IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN32)
253 
254 #define VDI_IOCTL_FREE_PHYSICALMEMORY32 \
255 	_IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN32)
256 
257 #define VDI_IOCTL_GET_INSTANCE_POOL32 \
258 	_IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN32)
259 
260 #define VDI_IOCTL_GET_COMMON_MEMORY32 \
261 	_IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN32)
262 
263 #define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32 \
264 	_IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN32)
265 
266 #define VDI_IOCTL_GET_REGISTER_INFO32 \
267 	_IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN32)
268 
269 #define VDI_IOCTL_FLUSH_BUFFER32 \
270 	_IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN32)
271 #endif
272 
273 enum {
274 	W4_INT_INIT_VPU = 0,
275 	W4_INT_DEC_PIC_HDR = 1,
276 	W4_INT_SET_PARAM = 1,
277 	W4_INT_ENC_INIT_SEQ = 1,
278 	W4_INT_FINI_SEQ = 2,
279 	W4_INT_DEC_PIC = 3,
280 	W4_INT_ENC_PIC = 3,
281 	W4_INT_SET_FRAMEBUF = 4,
282 	W4_INT_FLUSH_DEC = 5,
283 	W4_INT_ENC_SLICE_INT = 7,
284 	W4_INT_GET_FW_VERSION = 8,
285 	W4_INT_QUERY_DEC = 9,
286 	W4_INT_SLEEP_VPU = 10,
287 	W4_INT_WAKEUP_VPU = 11,
288 	W4_INT_CHANGE_INT = 12,
289 	W4_INT_CREATE_INSTANCE = 14,
290 	W4_INT_BSBUF_EMPTY = 15,
291     /*!<< Bitstream buffer empty[dec]/full[enc] */
292 };
293 
294 /* WAVE4 registers */
295 #define VPU_REG_BASE_ADDR	0xc8810000
296 #define VPU_REG_SIZE	(0x4000 * MAX_NUM_VPU_CORE)
297 
298 #define W4_REG_BASE					0x0000
299 #define W4_VPU_BUSY_STATUS			(W4_REG_BASE + 0x0070)
300 #define W4_VPU_INT_REASON_CLEAR			(W4_REG_BASE + 0x0034)
301 #define W4_VPU_VINT_CLEAR				(W4_REG_BASE + 0x003C)
302 #define W4_VPU_VPU_INT_STS			(W4_REG_BASE + 0x0044)
303 #define W4_VPU_INT_REASON				(W4_REG_BASE + 0x004c)
304 
305 #define W4_RET_SUCCESS					(W4_REG_BASE + 0x0110)
306 #define W4_RET_FAIL_REASON			(W4_REG_BASE + 0x0114)
307 
308 /* WAVE4 INIT, WAKEUP */
309 #define W4_PO_CONF					(W4_REG_BASE + 0x0000)
310 #define W4_VCPU_CUR_PC					(W4_REG_BASE + 0x0004)
311 
312 #define W4_VPU_VINT_ENABLE			(W4_REG_BASE + 0x0048)
313 
314 #define W4_VPU_RESET_REQ				(W4_REG_BASE + 0x0050)
315 #define W4_VPU_RESET_STATUS			(W4_REG_BASE + 0x0054)
316 
317 #define W4_VPU_REMAP_CTRL				(W4_REG_BASE + 0x0060)
318 #define W4_VPU_REMAP_VADDR			(W4_REG_BASE + 0x0064)
319 #define W4_VPU_REMAP_PADDR			(W4_REG_BASE + 0x0068)
320 #define W4_VPU_REMAP_CORE_START			(W4_REG_BASE + 0x006C)
321 #define W4_VPU_BUSY_STATUS			(W4_REG_BASE + 0x0070)
322 
323 #define W4_HW_OPTION					(W4_REG_BASE + 0x0124)
324 #define W4_CODE_SIZE					(W4_REG_BASE + 0x011C)
325 /* Note: W4_INIT_CODE_BASE_ADDR should be aligned to 4KB */
326 #define W4_ADDR_CODE_BASE			(W4_REG_BASE + 0x0118)
327 #define W4_CODE_PARAM					(W4_REG_BASE + 0x0120)
328 #define W4_INIT_VPU_TIME_OUT_CNT		(W4_REG_BASE + 0x0134)
329 
330 /* WAVE4 Wave4BitIssueCommand */
331 #define W4_CORE_INDEX					(W4_REG_BASE + 0x0104)
332 #define W4_INST_INDEX					(W4_REG_BASE + 0x0108)
333 #define W4_COMMAND					(W4_REG_BASE + 0x0100)
334 #define W4_VPU_HOST_INT_REQ			(W4_REG_BASE + 0x0038)
335 
336 #define W4_BS_RD_PTR					(W4_REG_BASE + 0x0130)
337 #define W4_BS_WR_PTR					(W4_REG_BASE + 0x0134)
338 #define W4_SRC_ADDR_Y                                   (W4_REG_BASE + 0x0174)
339 #define W4_SRC_ADDR_U                                   (W4_REG_BASE + 0x0178)
340 #define W4_SRC_ADDR_V                                   (W4_REG_BASE + 0x017C)
341 
342 #define W4_RET_ENC_PIC_BYTE			(W4_REG_BASE + 0x01C8)
343 
344 #define W4_REMAP_CODE_INDEX			 0
345 
346 #define ReadVpuRegister(addr) \
347 	readl((void __iomem *)(s_vpu_register.virt_addr \
348 	+ s_bit_firmware_info[core].reg_base_offset + addr))
349 
350 #define WriteVpuRegister(addr, val) \
351 	writel((u32)val, (void __iomem *)(s_vpu_register.virt_addr \
352 	+ s_bit_firmware_info[core].reg_base_offset + addr))
353 
354 #define WriteVpu(addr, val) writel((u32)val, (void __iomem *)addr)
355 #endif
356