blob: eaed0b794f215d1a2f47f884bc1d237584f1a156
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 | |
27 | #define MAX_INST_HANDLE_SIZE (32*1024) |
28 | #define MAX_NUM_INSTANCE 4 |
29 | #define MAX_NUM_VPU_CORE 1 |
30 | |
31 | #define W4_CMD_INIT_VPU (0x0001) |
32 | #define W4_CMD_SLEEP_VPU (0x0400) |
33 | #define W4_CMD_WAKEUP_VPU (0x0800) |
34 | |
35 | /* GXM: 2000/10 = 200M */ |
36 | #define HevcEnc_L0() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
37 | (3 << 25) | (1 << 16) | (3 << 9) | (1 << 0)) |
38 | /* GXM: 2000/8 = 250M */ |
39 | #define HevcEnc_L1() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
40 | (1 << 25) | (1 << 16) | (1 << 9) | (1 << 0)) |
41 | /* GXM: 2000/7 = 285M */ |
42 | #define HevcEnc_L2() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
43 | (4 << 25) | (0 << 16) | (4 << 9) | (0 << 0)) |
44 | /*GXM: 2000/6 = 333M */ |
45 | #define HevcEnc_L3() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
46 | (2 << 25) | (1 << 16) | (2 << 9) | (1 << 0)) |
47 | /* GXM: 2000/5 = 400M */ |
48 | #define HevcEnc_L4() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
49 | (3 << 25) | (0 << 16) | (3 << 9) | (0 << 0)) |
50 | /* GXM: 2000/4 = 500M */ |
51 | #define HevcEnc_L5() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
52 | (1 << 25) | (0 << 16) | (1 << 9) | (0 << 0)) |
53 | /* GXM: 2000/3 = 667M */ |
54 | #define HevcEnc_L6() WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
55 | (2 << 25) | (0 << 16) | (2 << 9) | (0 << 0)) |
56 | |
57 | #define HevcEnc_clock_enable(level) \ |
58 | do { \ |
59 | WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
60 | READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ |
61 | & (~(1 << 8)) & (~(1 << 24))); \ |
62 | if (level == 0) \ |
63 | HevcEnc_L0(); \ |
64 | else if (level == 1) \ |
65 | HevcEnc_L1(); \ |
66 | else if (level == 2) \ |
67 | HevcEnc_L2(); \ |
68 | else if (level == 3) \ |
69 | HevcEnc_L3(); \ |
70 | else if (level == 4) \ |
71 | HevcEnc_L4(); \ |
72 | else if (level == 5) \ |
73 | HevcEnc_L5(); \ |
74 | else if (level == 6) \ |
75 | HevcEnc_L6(); \ |
76 | WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
77 | READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ |
78 | | (1 << 8) | (1 << 24)); \ |
79 | } while (0) |
80 | |
81 | #define HevcEnc_clock_disable() \ |
82 | WRITE_HHI_REG(HHI_WAVE420L_CLK_CNTL, \ |
83 | READ_HHI_REG(HHI_WAVE420L_CLK_CNTL) \ |
84 | & (~(1 << 8)) & (~(1 << 24))); |
85 | |
86 | struct compat_vpudrv_buffer_t { |
87 | u32 size; |
88 | u32 cached; |
89 | compat_ulong_t phys_addr; |
90 | compat_ulong_t base; /* kernel logical address in use kernel */ |
91 | compat_ulong_t virt_addr; /* virtual user space address */ |
92 | }; |
93 | |
94 | struct vpudrv_buffer_t { |
95 | u32 size; |
96 | u32 cached; |
97 | ulong phys_addr; |
98 | ulong base; /* kernel logical address in use kernel */ |
99 | ulong virt_addr; /* virtual user space address */ |
100 | }; |
101 | |
102 | struct vpu_bit_firmware_info_t { |
103 | u32 size; /* size of this structure*/ |
104 | u32 core_idx; |
105 | u32 reg_base_offset; |
106 | u16 bit_code[512]; |
107 | }; |
108 | |
109 | struct vpudrv_inst_info_t { |
110 | u32 core_idx; |
111 | u32 inst_idx; |
112 | s32 inst_open_count; /* for output only*/ |
113 | }; |
114 | |
115 | struct vpudrv_intr_info_t { |
116 | u32 timeout; |
117 | s32 intr_reason; |
118 | }; |
119 | |
120 | struct vpu_drv_context_t { |
121 | struct fasync_struct *async_queue; |
122 | ulong interrupt_reason; |
123 | u32 open_count; /*!<< device reference count. Not instance count */ |
124 | }; |
125 | |
126 | /* To track the allocated memory buffer */ |
127 | struct vpudrv_buffer_pool_t { |
128 | struct list_head list; |
129 | struct vpudrv_buffer_t vb; |
130 | struct file *filp; |
131 | }; |
132 | |
133 | /* To track the instance index and buffer in instance pool */ |
134 | struct vpudrv_instanace_list_t { |
135 | struct list_head list; |
136 | ulong inst_idx; |
137 | ulong core_idx; |
138 | struct file *filp; |
139 | }; |
140 | |
141 | struct vpudrv_instance_pool_t { |
142 | u8 codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE]; |
143 | }; |
144 | |
145 | #define VPUDRV_BUF_LEN struct vpudrv_buffer_t |
146 | #define VPUDRV_BUF_LEN32 struct compat_vpudrv_buffer_t |
147 | #define VPUDRV_INST_LEN struct vpudrv_inst_info_t |
148 | |
149 | #define VDI_MAGIC 'V' |
150 | #define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY \ |
151 | _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN) |
152 | |
153 | #define VDI_IOCTL_FREE_PHYSICALMEMORY \ |
154 | _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN) |
155 | |
156 | #define VDI_IOCTL_WAIT_INTERRUPT \ |
157 | _IOW(VDI_MAGIC, 2, struct vpudrv_intr_info_t) |
158 | |
159 | #define VDI_IOCTL_SET_CLOCK_GATE \ |
160 | _IOW(VDI_MAGIC, 3, u32) |
161 | |
162 | #define VDI_IOCTL_RESET \ |
163 | _IOW(VDI_MAGIC, 4, u32) |
164 | |
165 | #define VDI_IOCTL_GET_INSTANCE_POOL \ |
166 | _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN) |
167 | |
168 | #define VDI_IOCTL_GET_COMMON_MEMORY \ |
169 | _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN) |
170 | |
171 | #define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO \ |
172 | _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN) |
173 | |
174 | #define VDI_IOCTL_OPEN_INSTANCE \ |
175 | _IOW(VDI_MAGIC, 9, VPUDRV_INST_LEN) |
176 | |
177 | #define VDI_IOCTL_CLOSE_INSTANCE \ |
178 | _IOW(VDI_MAGIC, 10, VPUDRV_INST_LEN) |
179 | |
180 | #define VDI_IOCTL_GET_INSTANCE_NUM \ |
181 | _IOW(VDI_MAGIC, 11, VPUDRV_INST_LEN) |
182 | |
183 | #define VDI_IOCTL_GET_REGISTER_INFO \ |
184 | _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN) |
185 | |
186 | #define VDI_IOCTL_FLUSH_BUFFER \ |
187 | _IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN) |
188 | |
189 | #define VDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY32 \ |
190 | _IOW(VDI_MAGIC, 0, VPUDRV_BUF_LEN32) |
191 | |
192 | #define VDI_IOCTL_FREE_PHYSICALMEMORY32 \ |
193 | _IOW(VDI_MAGIC, 1, VPUDRV_BUF_LEN32) |
194 | |
195 | #define VDI_IOCTL_GET_INSTANCE_POOL32 \ |
196 | _IOW(VDI_MAGIC, 5, VPUDRV_BUF_LEN32) |
197 | |
198 | #define VDI_IOCTL_GET_COMMON_MEMORY32 \ |
199 | _IOW(VDI_MAGIC, 6, VPUDRV_BUF_LEN32) |
200 | |
201 | #define VDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO32 \ |
202 | _IOW(VDI_MAGIC, 8, VPUDRV_BUF_LEN32) |
203 | |
204 | #define VDI_IOCTL_GET_REGISTER_INFO32 \ |
205 | _IOW(VDI_MAGIC, 12, VPUDRV_BUF_LEN32) |
206 | |
207 | #define VDI_IOCTL_FLUSH_BUFFER32 \ |
208 | _IOW(VDI_MAGIC, 13, VPUDRV_BUF_LEN32) |
209 | |
210 | enum { |
211 | W4_INT_INIT_VPU = 0, |
212 | W4_INT_DEC_PIC_HDR = 1, |
213 | W4_INT_SET_PARAM = 1, |
214 | W4_INT_ENC_INIT_SEQ = 1, |
215 | W4_INT_FINI_SEQ = 2, |
216 | W4_INT_DEC_PIC = 3, |
217 | W4_INT_ENC_PIC = 3, |
218 | W4_INT_SET_FRAMEBUF = 4, |
219 | W4_INT_FLUSH_DEC = 5, |
220 | W4_INT_ENC_SLICE_INT = 7, |
221 | W4_INT_GET_FW_VERSION = 8, |
222 | W4_INT_QUERY_DEC = 9, |
223 | W4_INT_SLEEP_VPU = 10, |
224 | W4_INT_WAKEUP_VPU = 11, |
225 | W4_INT_CHANGE_INT = 12, |
226 | W4_INT_CREATE_INSTANCE = 14, |
227 | W4_INT_BSBUF_EMPTY = 15, |
228 | /*!<< Bitstream buffer empty[dec]/full[enc] */ |
229 | }; |
230 | |
231 | /* WAVE4 registers */ |
232 | #define VPU_REG_BASE_ADDR 0xc8810000 |
233 | #define VPU_REG_SIZE (0x4000 * MAX_NUM_VPU_CORE) |
234 | |
235 | #define W4_REG_BASE 0x0000 |
236 | #define W4_VPU_BUSY_STATUS (W4_REG_BASE + 0x0070) |
237 | #define W4_VPU_INT_REASON_CLEAR (W4_REG_BASE + 0x0034) |
238 | #define W4_VPU_VINT_CLEAR (W4_REG_BASE + 0x003C) |
239 | #define W4_VPU_VPU_INT_STS (W4_REG_BASE + 0x0044) |
240 | #define W4_VPU_INT_REASON (W4_REG_BASE + 0x004c) |
241 | |
242 | #define W4_RET_SUCCESS (W4_REG_BASE + 0x0110) |
243 | #define W4_RET_FAIL_REASON (W4_REG_BASE + 0x0114) |
244 | |
245 | /* WAVE4 INIT, WAKEUP */ |
246 | #define W4_PO_CONF (W4_REG_BASE + 0x0000) |
247 | #define W4_VCPU_CUR_PC (W4_REG_BASE + 0x0004) |
248 | |
249 | #define W4_VPU_VINT_ENABLE (W4_REG_BASE + 0x0048) |
250 | |
251 | #define W4_VPU_RESET_REQ (W4_REG_BASE + 0x0050) |
252 | #define W4_VPU_RESET_STATUS (W4_REG_BASE + 0x0054) |
253 | |
254 | #define W4_VPU_REMAP_CTRL (W4_REG_BASE + 0x0060) |
255 | #define W4_VPU_REMAP_VADDR (W4_REG_BASE + 0x0064) |
256 | #define W4_VPU_REMAP_PADDR (W4_REG_BASE + 0x0068) |
257 | #define W4_VPU_REMAP_CORE_START (W4_REG_BASE + 0x006C) |
258 | #define W4_VPU_BUSY_STATUS (W4_REG_BASE + 0x0070) |
259 | |
260 | #define W4_HW_OPTION (W4_REG_BASE + 0x0124) |
261 | #define W4_CODE_SIZE (W4_REG_BASE + 0x011C) |
262 | /* Note: W4_INIT_CODE_BASE_ADDR should be aligned to 4KB */ |
263 | #define W4_ADDR_CODE_BASE (W4_REG_BASE + 0x0118) |
264 | #define W4_CODE_PARAM (W4_REG_BASE + 0x0120) |
265 | #define W4_INIT_VPU_TIME_OUT_CNT (W4_REG_BASE + 0x0134) |
266 | |
267 | /* WAVE4 Wave4BitIssueCommand */ |
268 | #define W4_CORE_INDEX (W4_REG_BASE + 0x0104) |
269 | #define W4_INST_INDEX (W4_REG_BASE + 0x0108) |
270 | #define W4_COMMAND (W4_REG_BASE + 0x0100) |
271 | #define W4_VPU_HOST_INT_REQ (W4_REG_BASE + 0x0038) |
272 | |
273 | #define W4_BS_RD_PTR (W4_REG_BASE + 0x0130) |
274 | #define W4_BS_WR_PTR (W4_REG_BASE + 0x0134) |
275 | #define W4_RET_ENC_PIC_BYTE (W4_REG_BASE + 0x01C8) |
276 | |
277 | #define W4_REMAP_CODE_INDEX 0 |
278 | |
279 | #define ReadVpuRegister(addr) \ |
280 | readl((void __iomem *)(s_vpu_register.virt_addr \ |
281 | + s_bit_firmware_info[core].reg_base_offset + addr)) |
282 | |
283 | #define WriteVpuRegister(addr, val) \ |
284 | writel((u32)val, (void __iomem *)(s_vpu_register.virt_addr \ |
285 | + s_bit_firmware_info[core].reg_base_offset + addr)) |
286 | |
287 | #define WriteVpu(addr, val) writel((u32)val, (void __iomem *)addr) |
288 | #endif |
289 |