File: | dev/pci/drm/amd/amdgpu/amdgpu_vcn.c |
Warning: | line 153, column 47 Access to field 'data' results in a dereference of a null pointer (loaded from field 'fw') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2016 Advanced Micro Devices, Inc. | |||
3 | * All Rights Reserved. | |||
4 | * | |||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | |||
6 | * copy of this software and associated documentation files (the | |||
7 | * "Software"), to deal in the Software without restriction, including | |||
8 | * without limitation the rights to use, copy, modify, merge, publish, | |||
9 | * distribute, sub license, and/or sell copies of the Software, and to | |||
10 | * permit persons to whom the Software is furnished to do so, subject to | |||
11 | * the following conditions: | |||
12 | * | |||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
16 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
17 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
18 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
19 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
20 | * | |||
21 | * The above copyright notice and this permission notice (including the | |||
22 | * next paragraph) shall be included in all copies or substantial portions | |||
23 | * of the Software. | |||
24 | * | |||
25 | */ | |||
26 | ||||
27 | #include <linux/firmware.h> | |||
28 | #include <linux/module.h> | |||
29 | #include <linux/pci.h> | |||
30 | ||||
31 | #include "amdgpu.h" | |||
32 | #include "amdgpu_pm.h" | |||
33 | #include "amdgpu_vcn.h" | |||
34 | #include "soc15d.h" | |||
35 | ||||
36 | /* Firmware Names */ | |||
37 | #define FIRMWARE_RAVEN"amdgpu/raven_vcn.bin" "amdgpu/raven_vcn.bin" | |||
38 | #define FIRMWARE_PICASSO"amdgpu/picasso_vcn.bin" "amdgpu/picasso_vcn.bin" | |||
39 | #define FIRMWARE_RAVEN2"amdgpu/raven2_vcn.bin" "amdgpu/raven2_vcn.bin" | |||
40 | #define FIRMWARE_ARCTURUS"amdgpu/arcturus_vcn.bin" "amdgpu/arcturus_vcn.bin" | |||
41 | #define FIRMWARE_RENOIR"amdgpu/renoir_vcn.bin" "amdgpu/renoir_vcn.bin" | |||
42 | #define FIRMWARE_GREEN_SARDINE"amdgpu/green_sardine_vcn.bin" "amdgpu/green_sardine_vcn.bin" | |||
43 | #define FIRMWARE_NAVI10"amdgpu/navi10_vcn.bin" "amdgpu/navi10_vcn.bin" | |||
44 | #define FIRMWARE_NAVI14"amdgpu/navi14_vcn.bin" "amdgpu/navi14_vcn.bin" | |||
45 | #define FIRMWARE_NAVI12"amdgpu/navi12_vcn.bin" "amdgpu/navi12_vcn.bin" | |||
46 | #define FIRMWARE_SIENNA_CICHLID"amdgpu/sienna_cichlid_vcn.bin" "amdgpu/sienna_cichlid_vcn.bin" | |||
47 | #define FIRMWARE_NAVY_FLOUNDER"amdgpu/navy_flounder_vcn.bin" "amdgpu/navy_flounder_vcn.bin" | |||
48 | ||||
49 | MODULE_FIRMWARE(FIRMWARE_RAVEN); | |||
50 | MODULE_FIRMWARE(FIRMWARE_PICASSO); | |||
51 | MODULE_FIRMWARE(FIRMWARE_RAVEN2); | |||
52 | MODULE_FIRMWARE(FIRMWARE_ARCTURUS); | |||
53 | MODULE_FIRMWARE(FIRMWARE_RENOIR); | |||
54 | MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE); | |||
55 | MODULE_FIRMWARE(FIRMWARE_NAVI10); | |||
56 | MODULE_FIRMWARE(FIRMWARE_NAVI14); | |||
57 | MODULE_FIRMWARE(FIRMWARE_NAVI12); | |||
58 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID); | |||
59 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER); | |||
60 | ||||
61 | static void amdgpu_vcn_idle_work_handler(struct work_struct *work); | |||
62 | ||||
63 | int amdgpu_vcn_sw_init(struct amdgpu_device *adev) | |||
64 | { | |||
65 | unsigned long bo_size; | |||
66 | const char *fw_name; | |||
67 | const struct common_firmware_header *hdr; | |||
68 | unsigned char fw_check; | |||
69 | int i, r; | |||
70 | ||||
71 | INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler); | |||
72 | rw_init(&adev->vcn.vcn_pg_lock, "vcnpg")_rw_init_flags(&adev->vcn.vcn_pg_lock, "vcnpg", 0, ((void *)0)); | |||
73 | rw_init(&adev->vcn.vcn1_jpeg1_workaround, "vcnwa")_rw_init_flags(&adev->vcn.vcn1_jpeg1_workaround, "vcnwa" , 0, ((void *)0)); | |||
74 | atomic_set(&adev->vcn.total_submission_cnt, 0)({ typeof(*(&adev->vcn.total_submission_cnt)) __tmp = ( (0)); *(volatile typeof(*(&adev->vcn.total_submission_cnt )) *)&(*(&adev->vcn.total_submission_cnt)) = __tmp ; __tmp; }); | |||
75 | for (i = 0; i < adev->vcn.num_vcn_inst; i++) | |||
| ||||
76 | atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0)({ typeof(*(&adev->vcn.inst[i].dpg_enc_submission_cnt) ) __tmp = ((0)); *(volatile typeof(*(&adev->vcn.inst[i ].dpg_enc_submission_cnt)) *)&(*(&adev->vcn.inst[i ].dpg_enc_submission_cnt)) = __tmp; __tmp; }); | |||
77 | ||||
78 | switch (adev->asic_type) { | |||
79 | case CHIP_RAVEN: | |||
80 | if (adev->apu_flags & AMD_APU_IS_RAVEN2) | |||
81 | fw_name = FIRMWARE_RAVEN2"amdgpu/raven2_vcn.bin"; | |||
82 | else if (adev->apu_flags & AMD_APU_IS_PICASSO) | |||
83 | fw_name = FIRMWARE_PICASSO"amdgpu/picasso_vcn.bin"; | |||
84 | else | |||
85 | fw_name = FIRMWARE_RAVEN"amdgpu/raven_vcn.bin"; | |||
86 | break; | |||
87 | case CHIP_ARCTURUS: | |||
88 | fw_name = FIRMWARE_ARCTURUS"amdgpu/arcturus_vcn.bin"; | |||
89 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
90 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
91 | adev->vcn.indirect_sram = true1; | |||
92 | break; | |||
93 | case CHIP_RENOIR: | |||
94 | if (adev->apu_flags & AMD_APU_IS_RENOIR) | |||
95 | fw_name = FIRMWARE_RENOIR"amdgpu/renoir_vcn.bin"; | |||
96 | else | |||
97 | fw_name = FIRMWARE_GREEN_SARDINE"amdgpu/green_sardine_vcn.bin"; | |||
98 | ||||
99 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
100 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
101 | adev->vcn.indirect_sram = true1; | |||
102 | break; | |||
103 | case CHIP_NAVI10: | |||
104 | fw_name = FIRMWARE_NAVI10"amdgpu/navi10_vcn.bin"; | |||
105 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
106 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
107 | adev->vcn.indirect_sram = true1; | |||
108 | break; | |||
109 | case CHIP_NAVI14: | |||
110 | fw_name = FIRMWARE_NAVI14"amdgpu/navi14_vcn.bin"; | |||
111 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
112 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
113 | adev->vcn.indirect_sram = true1; | |||
114 | break; | |||
115 | case CHIP_NAVI12: | |||
116 | fw_name = FIRMWARE_NAVI12"amdgpu/navi12_vcn.bin"; | |||
117 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
118 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
119 | adev->vcn.indirect_sram = true1; | |||
120 | break; | |||
121 | case CHIP_SIENNA_CICHLID: | |||
122 | fw_name = FIRMWARE_SIENNA_CICHLID"amdgpu/sienna_cichlid_vcn.bin"; | |||
123 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
124 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
125 | adev->vcn.indirect_sram = true1; | |||
126 | break; | |||
127 | case CHIP_NAVY_FLOUNDER: | |||
128 | fw_name = FIRMWARE_NAVY_FLOUNDER"amdgpu/navy_flounder_vcn.bin"; | |||
129 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |||
130 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15))) | |||
131 | adev->vcn.indirect_sram = true1; | |||
132 | break; | |||
133 | default: | |||
134 | return -EINVAL22; | |||
135 | } | |||
136 | ||||
137 | r = request_firmware(&adev->vcn.fw, fw_name, adev->dev); | |||
138 | if (r) { | |||
139 | dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",printf("drm:pid%d:%s *ERROR* " "amdgpu_vcn: Can't load firmware \"%s\"\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , fw_name ) | |||
140 | fw_name)printf("drm:pid%d:%s *ERROR* " "amdgpu_vcn: Can't load firmware \"%s\"\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , fw_name ); | |||
141 | return r; | |||
142 | } | |||
143 | ||||
144 | r = amdgpu_ucode_validate(adev->vcn.fw); | |||
145 | if (r) { | |||
146 | dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",printf("drm:pid%d:%s *ERROR* " "amdgpu_vcn: Can't validate firmware \"%s\"\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , fw_name ) | |||
147 | fw_name)printf("drm:pid%d:%s *ERROR* " "amdgpu_vcn: Can't validate firmware \"%s\"\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , fw_name ); | |||
148 | release_firmware(adev->vcn.fw); | |||
149 | adev->vcn.fw = NULL((void *)0); | |||
150 | return r; | |||
151 | } | |||
152 | ||||
153 | hdr = (const struct common_firmware_header *)adev->vcn.fw->data; | |||
| ||||
154 | adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)); | |||
155 | ||||
156 | /* Bit 20-23, it is encode major and non-zero for new naming convention. | |||
157 | * This field is part of version minor and DRM_DISABLED_FLAG in old naming | |||
158 | * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG | |||
159 | * is zero in old naming convention, this field is always zero so far. | |||
160 | * These four bits are used to tell which naming convention is present. | |||
161 | */ | |||
162 | fw_check = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 20) & 0xf; | |||
163 | if (fw_check) { | |||
164 | unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev; | |||
165 | ||||
166 | fw_rev = le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) & 0xfff; | |||
167 | enc_minor = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 12) & 0xff; | |||
168 | enc_major = fw_check; | |||
169 | dec_ver = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 24) & 0xf; | |||
170 | vep = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 28) & 0xf; | |||
171 | DRM_INFO("Found VCN firmware Version ENC: %u.%u DEC: %u VEP: %u Revision: %u\n",printk("\0016" "[" "drm" "] " "Found VCN firmware Version ENC: %u.%u DEC: %u VEP: %u Revision: %u\n" , enc_major, enc_minor, dec_ver, vep, fw_rev) | |||
172 | enc_major, enc_minor, dec_ver, vep, fw_rev)printk("\0016" "[" "drm" "] " "Found VCN firmware Version ENC: %u.%u DEC: %u VEP: %u Revision: %u\n" , enc_major, enc_minor, dec_ver, vep, fw_rev); | |||
173 | } else { | |||
174 | unsigned int version_major, version_minor, family_id; | |||
175 | ||||
176 | family_id = le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) & 0xff; | |||
177 | version_major = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 24) & 0xff; | |||
178 | version_minor = (le32_to_cpu(hdr->ucode_version)((__uint32_t)(hdr->ucode_version)) >> 8) & 0xff; | |||
179 | DRM_INFO("Found VCN firmware Version: %u.%u Family ID: %u\n",printk("\0016" "[" "drm" "] " "Found VCN firmware Version: %u.%u Family ID: %u\n" , version_major, version_minor, family_id) | |||
180 | version_major, version_minor, family_id)printk("\0016" "[" "drm" "] " "Found VCN firmware Version: %u.%u Family ID: %u\n" , version_major, version_minor, family_id); | |||
181 | } | |||
182 | ||||
183 | bo_size = AMDGPU_VCN_STACK_SIZE(128*1024) + AMDGPU_VCN_CONTEXT_SIZE(512*1024); | |||
184 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) | |||
185 | bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8)(((((__uint32_t)(hdr->ucode_size_bytes)) + 8) + (4096 - 1) ) & ~(4096 - 1)); | |||
186 | bo_size += AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared))(((sizeof(struct amdgpu_fw_shared)) + (4096 - 1)) & ~(4096 - 1)); | |||
187 | ||||
188 | for (i = 0; i < adev->vcn.num_vcn_inst; i++) { | |||
189 | if (adev->vcn.harvest_config & (1 << i)) | |||
190 | continue; | |||
191 | ||||
192 | r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE(1 << 12), | |||
193 | AMDGPU_GEM_DOMAIN_VRAM0x4, &adev->vcn.inst[i].vcpu_bo, | |||
194 | &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr); | |||
195 | if (r) { | |||
196 | dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r)printf("drm:pid%d:%s *ERROR* " "(%d) failed to allocate vcn bo\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , r); | |||
197 | return r; | |||
198 | } | |||
199 | ||||
200 | adev->vcn.inst[i].fw_shared_cpu_addr = adev->vcn.inst[i].cpu_addr + | |||
201 | bo_size - AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared))(((sizeof(struct amdgpu_fw_shared)) + (4096 - 1)) & ~(4096 - 1)); | |||
202 | adev->vcn.inst[i].fw_shared_gpu_addr = adev->vcn.inst[i].gpu_addr + | |||
203 | bo_size - AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared))(((sizeof(struct amdgpu_fw_shared)) + (4096 - 1)) & ~(4096 - 1)); | |||
204 | ||||
205 | if (adev->vcn.indirect_sram) { | |||
206 | r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE(1 << 12), | |||
207 | AMDGPU_GEM_DOMAIN_VRAM0x4, &adev->vcn.inst[i].dpg_sram_bo, | |||
208 | &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr); | |||
209 | if (r) { | |||
210 | dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r)printf("drm:pid%d:%s *ERROR* " "VCN %d (%d) failed to allocate DPG bo\n" , ({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self))); __ci;})->ci_curproc->p_p->ps_pid, __func__ , i, r); | |||
211 | return r; | |||
212 | } | |||
213 | } | |||
214 | } | |||
215 | ||||
216 | return 0; | |||
217 | } | |||
218 | ||||
219 | int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) | |||
220 | { | |||
221 | int i, j; | |||
222 | ||||
223 | cancel_delayed_work_sync(&adev->vcn.idle_work); | |||
224 | ||||
225 | for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { | |||
226 | if (adev->vcn.harvest_config & (1 << j)) | |||
227 | continue; | |||
228 | ||||
229 | if (adev->vcn.indirect_sram) { | |||
230 | amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo, | |||
231 | &adev->vcn.inst[j].dpg_sram_gpu_addr, | |||
232 | (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr); | |||
233 | } | |||
234 | kvfree(adev->vcn.inst[j].saved_bo); | |||
235 | ||||
236 | amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo, | |||
237 | &adev->vcn.inst[j].gpu_addr, | |||
238 | (void **)&adev->vcn.inst[j].cpu_addr); | |||
239 | ||||
240 | amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec); | |||
241 | ||||
242 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) | |||
243 | amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]); | |||
244 | } | |||
245 | ||||
246 | release_firmware(adev->vcn.fw); | |||
247 | mutex_destroy(&adev->vcn.vcn1_jpeg1_workaround); | |||
248 | mutex_destroy(&adev->vcn.vcn_pg_lock); | |||
249 | ||||
250 | return 0; | |||
251 | } | |||
252 | ||||
253 | int amdgpu_vcn_suspend(struct amdgpu_device *adev) | |||
254 | { | |||
255 | unsigned size; | |||
256 | void *ptr; | |||
257 | int i; | |||
258 | ||||
259 | cancel_delayed_work_sync(&adev->vcn.idle_work); | |||
260 | ||||
261 | for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { | |||
262 | if (adev->vcn.harvest_config & (1 << i)) | |||
263 | continue; | |||
264 | if (adev->vcn.inst[i].vcpu_bo == NULL((void *)0)) | |||
265 | return 0; | |||
266 | ||||
267 | size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); | |||
268 | ptr = adev->vcn.inst[i].cpu_addr; | |||
269 | ||||
270 | adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | |||
271 | if (!adev->vcn.inst[i].saved_bo) | |||
272 | return -ENOMEM12; | |||
273 | ||||
274 | memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size)__builtin_memcpy((adev->vcn.inst[i].saved_bo), (ptr), (size )); | |||
275 | } | |||
276 | return 0; | |||
277 | } | |||
278 | ||||
279 | int amdgpu_vcn_resume(struct amdgpu_device *adev) | |||
280 | { | |||
281 | unsigned size; | |||
282 | void *ptr; | |||
283 | int i; | |||
284 | ||||
285 | for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { | |||
286 | if (adev->vcn.harvest_config & (1 << i)) | |||
287 | continue; | |||
288 | if (adev->vcn.inst[i].vcpu_bo == NULL((void *)0)) | |||
289 | return -EINVAL22; | |||
290 | ||||
291 | size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo); | |||
292 | ptr = adev->vcn.inst[i].cpu_addr; | |||
293 | ||||
294 | if (adev->vcn.inst[i].saved_bo != NULL((void *)0)) { | |||
295 | memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size)__builtin_memcpy((ptr), (adev->vcn.inst[i].saved_bo), (size )); | |||
296 | kvfree(adev->vcn.inst[i].saved_bo); | |||
297 | adev->vcn.inst[i].saved_bo = NULL((void *)0); | |||
298 | } else { | |||
299 | const struct common_firmware_header *hdr; | |||
300 | unsigned offset; | |||
301 | ||||
302 | hdr = (const struct common_firmware_header *)adev->vcn.fw->data; | |||
303 | if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | |||
304 | offset = le32_to_cpu(hdr->ucode_array_offset_bytes)((__uint32_t)(hdr->ucode_array_offset_bytes)); | |||
305 | memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,__builtin_memcpy((adev->vcn.inst[i].cpu_addr), (adev->vcn .fw->data + offset), (((__uint32_t)(hdr->ucode_size_bytes )))) | |||
306 | le32_to_cpu(hdr->ucode_size_bytes))__builtin_memcpy((adev->vcn.inst[i].cpu_addr), (adev->vcn .fw->data + offset), (((__uint32_t)(hdr->ucode_size_bytes )))); | |||
307 | size -= le32_to_cpu(hdr->ucode_size_bytes)((__uint32_t)(hdr->ucode_size_bytes)); | |||
308 | ptr += le32_to_cpu(hdr->ucode_size_bytes)((__uint32_t)(hdr->ucode_size_bytes)); | |||
309 | } | |||
310 | memset_io(ptr, 0, size)__builtin_memset((ptr), (0), (size)); | |||
311 | } | |||
312 | } | |||
313 | return 0; | |||
314 | } | |||
315 | ||||
316 | static void amdgpu_vcn_idle_work_handler(struct work_struct *work) | |||
317 | { | |||
318 | struct amdgpu_device *adev = | |||
319 | container_of(work, struct amdgpu_device, vcn.idle_work.work)({ const __typeof( ((struct amdgpu_device *)0)->vcn.idle_work .work ) *__mptr = (work); (struct amdgpu_device *)( (char *)__mptr - __builtin_offsetof(struct amdgpu_device, vcn.idle_work.work ) );}); | |||
320 | unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES2] = {0}; | |||
321 | unsigned int i, j; | |||
322 | ||||
323 | for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { | |||
324 | if (adev->vcn.harvest_config & (1 << j)) | |||
325 | continue; | |||
326 | ||||
327 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) { | |||
328 | fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]); | |||
329 | } | |||
330 | ||||
331 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15)) { | |||
332 | struct dpg_pause_state new_state; | |||
333 | ||||
334 | if (fence[j] || | |||
335 | unlikely(atomic_read(&adev->vcn.inst[j].dpg_enc_submission_cnt))__builtin_expect(!!(({ typeof(*(&adev->vcn.inst[j].dpg_enc_submission_cnt )) __tmp = *(volatile typeof(*(&adev->vcn.inst[j].dpg_enc_submission_cnt )) *)&(*(&adev->vcn.inst[j].dpg_enc_submission_cnt )); membar_datadep_consumer(); __tmp; })), 0)) | |||
336 | new_state.fw_based = VCN_DPG_STATE__PAUSE; | |||
337 | else | |||
338 | new_state.fw_based = VCN_DPG_STATE__UNPAUSE; | |||
339 | ||||
340 | adev->vcn.pause_dpg_mode(adev, j, &new_state); | |||
341 | } | |||
342 | ||||
343 | fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec); | |||
344 | fences += fence[j]; | |||
345 | } | |||
346 | ||||
347 | if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)({ typeof(*(&adev->vcn.total_submission_cnt)) __tmp = * (volatile typeof(*(&adev->vcn.total_submission_cnt)) * )&(*(&adev->vcn.total_submission_cnt)); membar_datadep_consumer (); __tmp; })) { | |||
348 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, | |||
349 | AMD_PG_STATE_GATE); | |||
350 | } else { | |||
351 | schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT(((uint64_t)(1000)) * hz / 1000)); | |||
352 | } | |||
353 | } | |||
354 | ||||
355 | void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) | |||
356 | { | |||
357 | struct amdgpu_device *adev = ring->adev; | |||
358 | ||||
359 | atomic_inc(&adev->vcn.total_submission_cnt)__sync_fetch_and_add(&adev->vcn.total_submission_cnt, 1 ); | |||
360 | cancel_delayed_work_sync(&adev->vcn.idle_work); | |||
361 | ||||
362 | mutex_lock(&adev->vcn.vcn_pg_lock)rw_enter_write(&adev->vcn.vcn_pg_lock); | |||
363 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, | |||
364 | AMD_PG_STATE_UNGATE); | |||
365 | ||||
366 | if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15)) { | |||
367 | struct dpg_pause_state new_state; | |||
368 | ||||
369 | if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) { | |||
370 | atomic_inc(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt)__sync_fetch_and_add(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt , 1); | |||
371 | new_state.fw_based = VCN_DPG_STATE__PAUSE; | |||
372 | } else { | |||
373 | unsigned int fences = 0; | |||
374 | unsigned int i; | |||
375 | ||||
376 | for (i = 0; i < adev->vcn.num_enc_rings; ++i) | |||
377 | fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]); | |||
378 | ||||
379 | if (fences || atomic_read(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt)({ typeof(*(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt )) __tmp = *(volatile typeof(*(&adev->vcn.inst[ring-> me].dpg_enc_submission_cnt)) *)&(*(&adev->vcn.inst [ring->me].dpg_enc_submission_cnt)); membar_datadep_consumer (); __tmp; })) | |||
380 | new_state.fw_based = VCN_DPG_STATE__PAUSE; | |||
381 | else | |||
382 | new_state.fw_based = VCN_DPG_STATE__UNPAUSE; | |||
383 | } | |||
384 | ||||
385 | adev->vcn.pause_dpg_mode(adev, ring->me, &new_state); | |||
386 | } | |||
387 | mutex_unlock(&adev->vcn.vcn_pg_lock)rw_exit_write(&adev->vcn.vcn_pg_lock); | |||
388 | } | |||
389 | ||||
390 | void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) | |||
391 | { | |||
392 | if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG(1 << 15) && | |||
393 | ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) | |||
394 | atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt)__sync_fetch_and_sub(&ring->adev->vcn.inst[ring-> me].dpg_enc_submission_cnt, 1); | |||
395 | ||||
396 | atomic_dec(&ring->adev->vcn.total_submission_cnt)__sync_fetch_and_sub(&ring->adev->vcn.total_submission_cnt , 1); | |||
397 | ||||
398 | schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT(((uint64_t)(1000)) * hz / 1000)); | |||
399 | } | |||
400 | ||||
401 | int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) | |||
402 | { | |||
403 | struct amdgpu_device *adev = ring->adev; | |||
404 | uint32_t tmp = 0; | |||
405 | unsigned i; | |||
406 | int r; | |||
407 | ||||
408 | /* VCN in SRIOV does not support direct register read/write */ | |||
409 | if (amdgpu_sriov_vf(adev)((adev)->virt.caps & (1 << 2))) | |||
410 | return 0; | |||
411 | ||||
412 | WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD)amdgpu_device_wreg(adev, (adev->vcn.inst[ring->me].external .scratch9), (0xCAFEDEAD), 0); | |||
413 | r = amdgpu_ring_alloc(ring, 3); | |||
414 | if (r) | |||
415 | return r; | |||
416 | amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0)((0 << 30) | ((adev->vcn.internal.scratch9) & 0xFFFF ) | ((0) & 0x3FFF) << 16)); | |||
417 | amdgpu_ring_write(ring, 0xDEADBEEF); | |||
418 | amdgpu_ring_commit(ring); | |||
419 | for (i = 0; i < adev->usec_timeout; i++) { | |||
420 | tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9)amdgpu_device_rreg(adev, (adev->vcn.inst[ring->me].external .scratch9), 0); | |||
421 | if (tmp == 0xDEADBEEF) | |||
422 | break; | |||
423 | udelay(1); | |||
424 | } | |||
425 | ||||
426 | if (i >= adev->usec_timeout) | |||
427 | r = -ETIMEDOUT60; | |||
428 | ||||
429 | return r; | |||
430 | } | |||
431 | ||||
432 | static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, | |||
433 | struct amdgpu_bo *bo, | |||
434 | struct dma_fence **fence) | |||
435 | { | |||
436 | struct amdgpu_device *adev = ring->adev; | |||
437 | struct dma_fence *f = NULL((void *)0); | |||
438 | struct amdgpu_job *job; | |||
439 | struct amdgpu_ib *ib; | |||
440 | uint64_t addr; | |||
441 | int i, r; | |||
442 | ||||
443 | r = amdgpu_job_alloc_with_ib(adev, 64, | |||
444 | AMDGPU_IB_POOL_DIRECT, &job); | |||
445 | if (r) | |||
446 | goto err; | |||
447 | ||||
448 | ib = &job->ibs[0]; | |||
449 | addr = amdgpu_bo_gpu_offset(bo); | |||
450 | ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0)((0 << 30) | ((adev->vcn.internal.data0) & 0xFFFF ) | ((0) & 0x3FFF) << 16); | |||
451 | ib->ptr[1] = addr; | |||
452 | ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0)((0 << 30) | ((adev->vcn.internal.data1) & 0xFFFF ) | ((0) & 0x3FFF) << 16); | |||
453 | ib->ptr[3] = addr >> 32; | |||
454 | ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0)((0 << 30) | ((adev->vcn.internal.cmd) & 0xFFFF) | ((0) & 0x3FFF) << 16); | |||
455 | ib->ptr[5] = 0; | |||
456 | for (i = 6; i < 16; i += 2) { | |||
457 | ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0)((0 << 30) | ((adev->vcn.internal.nop) & 0xFFFF) | ((0) & 0x3FFF) << 16); | |||
458 | ib->ptr[i+1] = 0; | |||
459 | } | |||
460 | ib->length_dw = 16; | |||
461 | ||||
462 | r = amdgpu_job_submit_direct(job, ring, &f); | |||
463 | if (r) | |||
464 | goto err_free; | |||
465 | ||||
466 | amdgpu_bo_fence(bo, f, false0); | |||
467 | amdgpu_bo_unreserve(bo); | |||
468 | amdgpu_bo_unref(&bo); | |||
469 | ||||
470 | if (fence) | |||
471 | *fence = dma_fence_get(f); | |||
472 | dma_fence_put(f); | |||
473 | ||||
474 | return 0; | |||
475 | ||||
476 | err_free: | |||
477 | amdgpu_job_free(job); | |||
478 | ||||
479 | err: | |||
480 | amdgpu_bo_unreserve(bo); | |||
481 | amdgpu_bo_unref(&bo); | |||
482 | return r; | |||
483 | } | |||
484 | ||||
485 | static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
486 | struct dma_fence **fence) | |||
487 | { | |||
488 | struct amdgpu_device *adev = ring->adev; | |||
489 | struct amdgpu_bo *bo = NULL((void *)0); | |||
490 | uint32_t *msg; | |||
491 | int r, i; | |||
492 | ||||
493 | r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE(1 << 12), | |||
494 | AMDGPU_GEM_DOMAIN_VRAM0x4, | |||
495 | &bo, NULL((void *)0), (void **)&msg); | |||
496 | if (r) | |||
497 | return r; | |||
498 | ||||
499 | msg[0] = cpu_to_le32(0x00000028)((__uint32_t)(0x00000028)); | |||
500 | msg[1] = cpu_to_le32(0x00000038)((__uint32_t)(0x00000038)); | |||
501 | msg[2] = cpu_to_le32(0x00000001)((__uint32_t)(0x00000001)); | |||
502 | msg[3] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
503 | msg[4] = cpu_to_le32(handle)((__uint32_t)(handle)); | |||
504 | msg[5] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
505 | msg[6] = cpu_to_le32(0x00000001)((__uint32_t)(0x00000001)); | |||
506 | msg[7] = cpu_to_le32(0x00000028)((__uint32_t)(0x00000028)); | |||
507 | msg[8] = cpu_to_le32(0x00000010)((__uint32_t)(0x00000010)); | |||
508 | msg[9] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
509 | msg[10] = cpu_to_le32(0x00000007)((__uint32_t)(0x00000007)); | |||
510 | msg[11] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
511 | msg[12] = cpu_to_le32(0x00000780)((__uint32_t)(0x00000780)); | |||
512 | msg[13] = cpu_to_le32(0x00000440)((__uint32_t)(0x00000440)); | |||
513 | for (i = 14; i < 1024; ++i) | |||
514 | msg[i] = cpu_to_le32(0x0)((__uint32_t)(0x0)); | |||
515 | ||||
516 | return amdgpu_vcn_dec_send_msg(ring, bo, fence); | |||
517 | } | |||
518 | ||||
519 | static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
520 | struct dma_fence **fence) | |||
521 | { | |||
522 | struct amdgpu_device *adev = ring->adev; | |||
523 | struct amdgpu_bo *bo = NULL((void *)0); | |||
524 | uint32_t *msg; | |||
525 | int r, i; | |||
526 | ||||
527 | r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE(1 << 12), | |||
528 | AMDGPU_GEM_DOMAIN_VRAM0x4, | |||
529 | &bo, NULL((void *)0), (void **)&msg); | |||
530 | if (r) | |||
531 | return r; | |||
532 | ||||
533 | msg[0] = cpu_to_le32(0x00000028)((__uint32_t)(0x00000028)); | |||
534 | msg[1] = cpu_to_le32(0x00000018)((__uint32_t)(0x00000018)); | |||
535 | msg[2] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
536 | msg[3] = cpu_to_le32(0x00000002)((__uint32_t)(0x00000002)); | |||
537 | msg[4] = cpu_to_le32(handle)((__uint32_t)(handle)); | |||
538 | msg[5] = cpu_to_le32(0x00000000)((__uint32_t)(0x00000000)); | |||
539 | for (i = 6; i < 1024; ++i) | |||
540 | msg[i] = cpu_to_le32(0x0)((__uint32_t)(0x0)); | |||
541 | ||||
542 | return amdgpu_vcn_dec_send_msg(ring, bo, fence); | |||
543 | } | |||
544 | ||||
545 | int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
546 | { | |||
547 | struct dma_fence *fence; | |||
548 | long r; | |||
549 | ||||
550 | r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL((void *)0)); | |||
551 | if (r) | |||
552 | goto error; | |||
553 | ||||
554 | r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence); | |||
555 | if (r) | |||
556 | goto error; | |||
557 | ||||
558 | r = dma_fence_wait_timeout(fence, false0, timeout); | |||
559 | if (r == 0) | |||
560 | r = -ETIMEDOUT60; | |||
561 | else if (r > 0) | |||
562 | r = 0; | |||
563 | ||||
564 | dma_fence_put(fence); | |||
565 | error: | |||
566 | return r; | |||
567 | } | |||
568 | ||||
569 | int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) | |||
570 | { | |||
571 | struct amdgpu_device *adev = ring->adev; | |||
572 | uint32_t rptr; | |||
573 | unsigned i; | |||
574 | int r; | |||
575 | ||||
576 | if (amdgpu_sriov_vf(adev)((adev)->virt.caps & (1 << 2))) | |||
577 | return 0; | |||
578 | ||||
579 | r = amdgpu_ring_alloc(ring, 16); | |||
580 | if (r) | |||
581 | return r; | |||
582 | ||||
583 | rptr = amdgpu_ring_get_rptr(ring)(ring)->funcs->get_rptr((ring)); | |||
584 | ||||
585 | amdgpu_ring_write(ring, VCN_ENC_CMD_END0x00000001); | |||
586 | amdgpu_ring_commit(ring); | |||
587 | ||||
588 | for (i = 0; i < adev->usec_timeout; i++) { | |||
589 | if (amdgpu_ring_get_rptr(ring)(ring)->funcs->get_rptr((ring)) != rptr) | |||
590 | break; | |||
591 | udelay(1); | |||
592 | } | |||
593 | ||||
594 | if (i >= adev->usec_timeout) | |||
595 | r = -ETIMEDOUT60; | |||
596 | ||||
597 | return r; | |||
598 | } | |||
599 | ||||
600 | static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
601 | struct amdgpu_bo *bo, | |||
602 | struct dma_fence **fence) | |||
603 | { | |||
604 | const unsigned ib_size_dw = 16; | |||
605 | struct amdgpu_job *job; | |||
606 | struct amdgpu_ib *ib; | |||
607 | struct dma_fence *f = NULL((void *)0); | |||
608 | uint64_t addr; | |||
609 | int i, r; | |||
610 | ||||
611 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, | |||
612 | AMDGPU_IB_POOL_DIRECT, &job); | |||
613 | if (r) | |||
614 | return r; | |||
615 | ||||
616 | ib = &job->ibs[0]; | |||
617 | addr = amdgpu_bo_gpu_offset(bo); | |||
618 | ||||
619 | ib->length_dw = 0; | |||
620 | ib->ptr[ib->length_dw++] = 0x00000018; | |||
621 | ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ | |||
622 | ib->ptr[ib->length_dw++] = handle; | |||
623 | ib->ptr[ib->length_dw++] = upper_32_bits(addr)((u32)(((addr) >> 16) >> 16)); | |||
624 | ib->ptr[ib->length_dw++] = addr; | |||
625 | ib->ptr[ib->length_dw++] = 0x0000000b; | |||
626 | ||||
627 | ib->ptr[ib->length_dw++] = 0x00000014; | |||
628 | ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ | |||
629 | ib->ptr[ib->length_dw++] = 0x0000001c; | |||
630 | ib->ptr[ib->length_dw++] = 0x00000000; | |||
631 | ib->ptr[ib->length_dw++] = 0x00000000; | |||
632 | ||||
633 | ib->ptr[ib->length_dw++] = 0x00000008; | |||
634 | ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */ | |||
635 | ||||
636 | for (i = ib->length_dw; i < ib_size_dw; ++i) | |||
637 | ib->ptr[i] = 0x0; | |||
638 | ||||
639 | r = amdgpu_job_submit_direct(job, ring, &f); | |||
640 | if (r) | |||
641 | goto err; | |||
642 | ||||
643 | if (fence) | |||
644 | *fence = dma_fence_get(f); | |||
645 | dma_fence_put(f); | |||
646 | ||||
647 | return 0; | |||
648 | ||||
649 | err: | |||
650 | amdgpu_job_free(job); | |||
651 | return r; | |||
652 | } | |||
653 | ||||
654 | static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
655 | struct amdgpu_bo *bo, | |||
656 | struct dma_fence **fence) | |||
657 | { | |||
658 | const unsigned ib_size_dw = 16; | |||
659 | struct amdgpu_job *job; | |||
660 | struct amdgpu_ib *ib; | |||
661 | struct dma_fence *f = NULL((void *)0); | |||
662 | uint64_t addr; | |||
663 | int i, r; | |||
664 | ||||
665 | r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, | |||
666 | AMDGPU_IB_POOL_DIRECT, &job); | |||
667 | if (r) | |||
668 | return r; | |||
669 | ||||
670 | ib = &job->ibs[0]; | |||
671 | addr = amdgpu_bo_gpu_offset(bo); | |||
672 | ||||
673 | ib->length_dw = 0; | |||
674 | ib->ptr[ib->length_dw++] = 0x00000018; | |||
675 | ib->ptr[ib->length_dw++] = 0x00000001; | |||
676 | ib->ptr[ib->length_dw++] = handle; | |||
677 | ib->ptr[ib->length_dw++] = upper_32_bits(addr)((u32)(((addr) >> 16) >> 16)); | |||
678 | ib->ptr[ib->length_dw++] = addr; | |||
679 | ib->ptr[ib->length_dw++] = 0x0000000b; | |||
680 | ||||
681 | ib->ptr[ib->length_dw++] = 0x00000014; | |||
682 | ib->ptr[ib->length_dw++] = 0x00000002; | |||
683 | ib->ptr[ib->length_dw++] = 0x0000001c; | |||
684 | ib->ptr[ib->length_dw++] = 0x00000000; | |||
685 | ib->ptr[ib->length_dw++] = 0x00000000; | |||
686 | ||||
687 | ib->ptr[ib->length_dw++] = 0x00000008; | |||
688 | ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */ | |||
689 | ||||
690 | for (i = ib->length_dw; i < ib_size_dw; ++i) | |||
691 | ib->ptr[i] = 0x0; | |||
692 | ||||
693 | r = amdgpu_job_submit_direct(job, ring, &f); | |||
694 | if (r) | |||
695 | goto err; | |||
696 | ||||
697 | if (fence) | |||
698 | *fence = dma_fence_get(f); | |||
699 | dma_fence_put(f); | |||
700 | ||||
701 | return 0; | |||
702 | ||||
703 | err: | |||
704 | amdgpu_job_free(job); | |||
705 | return r; | |||
706 | } | |||
707 | ||||
708 | int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) | |||
709 | { | |||
710 | struct dma_fence *fence = NULL((void *)0); | |||
711 | struct amdgpu_bo *bo = NULL((void *)0); | |||
712 | long r; | |||
713 | ||||
714 | r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE(1 << 12), | |||
715 | AMDGPU_GEM_DOMAIN_VRAM0x4, | |||
716 | &bo, NULL((void *)0), NULL((void *)0)); | |||
717 | if (r) | |||
718 | return r; | |||
719 | ||||
720 | r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL((void *)0)); | |||
721 | if (r) | |||
722 | goto error; | |||
723 | ||||
724 | r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); | |||
725 | if (r) | |||
726 | goto error; | |||
727 | ||||
728 | r = dma_fence_wait_timeout(fence, false0, timeout); | |||
729 | if (r == 0) | |||
730 | r = -ETIMEDOUT60; | |||
731 | else if (r > 0) | |||
732 | r = 0; | |||
733 | ||||
734 | error: | |||
735 | dma_fence_put(fence); | |||
736 | amdgpu_bo_unreserve(bo); | |||
737 | amdgpu_bo_unref(&bo); | |||
738 | return r; | |||
739 | } |
1 | /* Public domain. */ |
2 | |
3 | #ifndef _LINUX_FIRMWARE_H |
4 | #define _LINUX_FIRMWARE_H |
5 | |
6 | #include <sys/types.h> |
7 | #include <sys/malloc.h> |
8 | #include <sys/device.h> |
9 | #include <linux/types.h> |
10 | #include <linux/gfp.h> |
11 | |
12 | #ifndef __DECONST |
13 | #define __DECONST(type, var)((type)(__uintptr_t)(const void *)(var)) ((type)(__uintptr_t)(const void *)(var)) |
14 | #endif |
15 | |
16 | struct firmware { |
17 | size_t size; |
18 | const u8 *data; |
19 | }; |
20 | |
21 | static inline int |
22 | request_firmware(const struct firmware **fw, const char *name, |
23 | struct device *device) |
24 | { |
25 | int r; |
26 | struct firmware *f = malloc(sizeof(struct firmware), M_DRM145, |
27 | M_WAITOK0x0001 | M_ZERO0x0008); |
28 | r = loadfirmware(name, __DECONST(u_char **, &f->data)((u_char **)(__uintptr_t)(const void *)(&f->data)), &f->size); |
29 | if (r != 0) { |
30 | free(f, M_DRM145, sizeof(struct firmware)); |
31 | *fw = NULL((void *)0); |
32 | return -r; |
33 | } else { |
34 | *fw = f; |
35 | return 0; |
36 | } |
37 | } |
38 | |
39 | static inline int |
40 | request_firmware_direct(const struct firmware **fw, const char *name, |
41 | struct device *device) |
42 | { |
43 | return request_firmware(fw, name, device); |
44 | } |
45 | |
46 | #define request_firmware_nowait(a, b, c, d, e, f, g)-22 -EINVAL22 |
47 | |
48 | static inline void |
49 | release_firmware(const struct firmware *fw) |
50 | { |
51 | if (fw) |
52 | free(__DECONST(u_char *, fw->data)((u_char *)(__uintptr_t)(const void *)(fw->data)), M_DEVBUF2, fw->size); |
53 | free(__DECONST(struct firmware *, fw)((struct firmware *)(__uintptr_t)(const void *)(fw)), M_DRM145, sizeof(*fw)); |
54 | } |
55 | |
56 | #endif |