File: | dev/pci/drm/amd/amdgpu/amdgpu_bios.c |
Warning: | line 65, column 7 The left operand of '==' is a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | ||||||||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||||||||
3 | * Copyright 2008 Red Hat Inc. | ||||||||
4 | * Copyright 2009 Jerome Glisse. | ||||||||
5 | * | ||||||||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||||||||
7 | * copy of this software and associated documentation files (the "Software"), | ||||||||
8 | * to deal in the Software without restriction, including without limitation | ||||||||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||||||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||||||||
11 | * Software is furnished to do so, subject to the following conditions: | ||||||||
12 | * | ||||||||
13 | * The above copyright notice and this permission notice shall be included in | ||||||||
14 | * all copies or substantial portions of the Software. | ||||||||
15 | * | ||||||||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||||||||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||||||||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||||||||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||||||||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||||||||
23 | * | ||||||||
24 | * Authors: Dave Airlie | ||||||||
25 | * Alex Deucher | ||||||||
26 | * Jerome Glisse | ||||||||
27 | */ | ||||||||
28 | |||||||||
29 | #include "amdgpu.h" | ||||||||
30 | #include "atom.h" | ||||||||
31 | |||||||||
32 | #include <linux/device.h> | ||||||||
33 | #include <linux/pci.h> | ||||||||
34 | #include <linux/slab.h> | ||||||||
35 | #include <linux/acpi.h> | ||||||||
36 | |||||||||
37 | #if defined(__amd64__1) || defined(__i386__) | ||||||||
38 | #include <dev/isa/isareg.h> | ||||||||
39 | #include <dev/isa/isavar.h> | ||||||||
40 | #endif | ||||||||
41 | |||||||||
42 | /* | ||||||||
43 | * BIOS. | ||||||||
44 | */ | ||||||||
45 | |||||||||
46 | #define AMD_VBIOS_SIGNATURE" 761295520" " 761295520" | ||||||||
47 | #define AMD_VBIOS_SIGNATURE_OFFSET0x30 0x30 | ||||||||
48 | #define AMD_VBIOS_SIGNATURE_SIZEsizeof(" 761295520") sizeof(AMD_VBIOS_SIGNATURE" 761295520") | ||||||||
49 | #define AMD_VBIOS_SIGNATURE_END(0x30 + sizeof(" 761295520")) (AMD_VBIOS_SIGNATURE_OFFSET0x30 + AMD_VBIOS_SIGNATURE_SIZEsizeof(" 761295520")) | ||||||||
50 | #define AMD_IS_VALID_VBIOS(p)((p)[0] == 0x55 && (p)[1] == 0xAA) ((p)[0] == 0x55 && (p)[1] == 0xAA) | ||||||||
51 | #define AMD_VBIOS_LENGTH(p)((p)[2] << 9) ((p)[2] << 9) | ||||||||
52 | |||||||||
53 | /* Check if current bios is an ATOM BIOS. | ||||||||
54 | * Return true if it is ATOM BIOS. Otherwise, return false. | ||||||||
55 | */ | ||||||||
56 | static bool_Bool check_atom_bios(uint8_t *bios, size_t size) | ||||||||
57 | { | ||||||||
58 | uint16_t tmp, bios_header_start; | ||||||||
59 | |||||||||
60 | if (!bios
| ||||||||
61 | DRM_INFO("vbios mem is null or mem size is wrong\n")printk("\0016" "[" "drm" "] " "vbios mem is null or mem size is wrong\n" ); | ||||||||
62 | return false0; | ||||||||
63 | } | ||||||||
64 | |||||||||
65 | if (!AMD_IS_VALID_VBIOS(bios)((bios)[0] == 0x55 && (bios)[1] == 0xAA)) { | ||||||||
| |||||||||
66 | DRM_INFO("BIOS signature incorrect %x %x\n", bios[0], bios[1])printk("\0016" "[" "drm" "] " "BIOS signature incorrect %x %x\n" , bios[0], bios[1]); | ||||||||
67 | return false0; | ||||||||
68 | } | ||||||||
69 | |||||||||
70 | bios_header_start = bios[0x48] | (bios[0x49] << 8); | ||||||||
71 | if (!bios_header_start) { | ||||||||
72 | DRM_INFO("Can't locate bios header\n")printk("\0016" "[" "drm" "] " "Can't locate bios header\n"); | ||||||||
73 | return false0; | ||||||||
74 | } | ||||||||
75 | |||||||||
76 | tmp = bios_header_start + 4; | ||||||||
77 | if (size < tmp) { | ||||||||
78 | DRM_INFO("BIOS header is broken\n")printk("\0016" "[" "drm" "] " "BIOS header is broken\n"); | ||||||||
79 | return false0; | ||||||||
80 | } | ||||||||
81 | |||||||||
82 | if (!memcmp(bios + tmp, "ATOM", 4)__builtin_memcmp((bios + tmp), ("ATOM"), (4)) || | ||||||||
83 | !memcmp(bios + tmp, "MOTA", 4)__builtin_memcmp((bios + tmp), ("MOTA"), (4))) { | ||||||||
84 | DRM_DEBUG("ATOMBIOS detected\n")___drm_dbg(((void *)0), DRM_UT_CORE, "ATOMBIOS detected\n"); | ||||||||
85 | return true1; | ||||||||
86 | } | ||||||||
87 | |||||||||
88 | return false0; | ||||||||
89 | } | ||||||||
90 | |||||||||
91 | /* If you boot an IGP board with a discrete card as the primary, | ||||||||
92 | * the IGP rom is not accessible via the rom bar as the IGP rom is | ||||||||
93 | * part of the system bios. On boot, the system bios puts a | ||||||||
94 | * copy of the igp rom at the start of vram if a discrete card is | ||||||||
95 | * present. | ||||||||
96 | */ | ||||||||
97 | #ifdef __linux__ | ||||||||
98 | static bool_Bool igp_read_bios_from_vram(struct amdgpu_device *adev) | ||||||||
99 | { | ||||||||
100 | uint8_t __iomem *bios; | ||||||||
101 | resource_size_t vram_base; | ||||||||
102 | resource_size_t size = 256 * 1024; /* ??? */ | ||||||||
103 | |||||||||
104 | if (!(adev->flags & AMD_IS_APU)) | ||||||||
105 | if (amdgpu_device_need_post(adev)) | ||||||||
106 | return false0; | ||||||||
107 | |||||||||
108 | /* FB BAR not enabled */ | ||||||||
109 | if (pci_resource_len(adev->pdev, 0) == 0) | ||||||||
110 | return false0; | ||||||||
111 | |||||||||
112 | adev->bios = NULL((void *)0); | ||||||||
113 | vram_base = pci_resource_start(adev->pdev, 0); | ||||||||
114 | bios = ioremap_wc(vram_base, size); | ||||||||
115 | if (!bios) { | ||||||||
116 | return false0; | ||||||||
117 | } | ||||||||
118 | |||||||||
119 | adev->bios = kmalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
120 | if (!adev->bios) { | ||||||||
121 | iounmap(bios); | ||||||||
122 | return false0; | ||||||||
123 | } | ||||||||
124 | adev->bios_size = size; | ||||||||
125 | memcpy_fromio(adev->bios, bios, size)__builtin_memcpy((adev->bios), (bios), (size)); | ||||||||
126 | iounmap(bios); | ||||||||
127 | |||||||||
128 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
129 | kfree(adev->bios); | ||||||||
130 | return false0; | ||||||||
131 | } | ||||||||
132 | |||||||||
133 | return true1; | ||||||||
134 | } | ||||||||
135 | #else | ||||||||
136 | static bool_Bool igp_read_bios_from_vram(struct amdgpu_device *adev) | ||||||||
137 | { | ||||||||
138 | uint8_t __iomem *bios; | ||||||||
139 | resource_size_t size = 256 * 1024; /* ??? */ | ||||||||
140 | bus_space_handle_t bsh; | ||||||||
141 | bus_space_tag_t bst = adev->memt; | ||||||||
142 | |||||||||
143 | if (!(adev->flags & AMD_IS_APU)) | ||||||||
144 | if (amdgpu_device_need_post(adev)) | ||||||||
145 | return false0; | ||||||||
146 | |||||||||
147 | adev->bios = NULL((void *)0); | ||||||||
148 | |||||||||
149 | if (bus_space_map(bst, adev->fb_aper_offset, size, BUS_SPACE_MAP_LINEAR0x0002, &bsh) != 0) | ||||||||
150 | return false0; | ||||||||
151 | |||||||||
152 | bios = bus_space_vaddr(adev->memt, bsh)((adev->memt)->vaddr((bsh))); | ||||||||
153 | if (bios == NULL((void *)0)) { | ||||||||
154 | bus_space_unmap(bst, bsh, size); | ||||||||
155 | return false0; | ||||||||
156 | } | ||||||||
157 | |||||||||
158 | adev->bios = kmalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
159 | if (!adev->bios) { | ||||||||
160 | bus_space_unmap(bst, bsh, size); | ||||||||
161 | return false0; | ||||||||
162 | } | ||||||||
163 | adev->bios_size = size; | ||||||||
164 | memcpy_fromio(adev->bios, bios, size)__builtin_memcpy((adev->bios), (bios), (size)); | ||||||||
165 | bus_space_unmap(bst, bsh, size); | ||||||||
166 | |||||||||
167 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
168 | kfree(adev->bios); | ||||||||
169 | return false0; | ||||||||
170 | } | ||||||||
171 | |||||||||
172 | return true1; | ||||||||
173 | } | ||||||||
174 | #endif | ||||||||
175 | |||||||||
176 | #ifdef __linux__ | ||||||||
177 | bool_Bool amdgpu_read_bios(struct amdgpu_device *adev) | ||||||||
178 | { | ||||||||
179 | uint8_t __iomem *bios; | ||||||||
180 | size_t size; | ||||||||
181 | |||||||||
182 | adev->bios = NULL((void *)0); | ||||||||
183 | /* XXX: some cards may return 0 for rom size? ddx has a workaround */ | ||||||||
184 | bios = pci_map_rom(adev->pdev, &size); | ||||||||
185 | if (!bios) { | ||||||||
186 | return false0; | ||||||||
187 | } | ||||||||
188 | |||||||||
189 | adev->bios = kzalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
190 | if (adev->bios == NULL((void *)0)) { | ||||||||
191 | pci_unmap_rom(adev->pdev, bios); | ||||||||
192 | return false0; | ||||||||
193 | } | ||||||||
194 | adev->bios_size = size; | ||||||||
195 | memcpy_fromio(adev->bios, bios, size)__builtin_memcpy((adev->bios), (bios), (size)); | ||||||||
196 | pci_unmap_rom(adev->pdev, bios); | ||||||||
197 | |||||||||
198 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
199 | kfree(adev->bios); | ||||||||
200 | return false0; | ||||||||
201 | } | ||||||||
202 | |||||||||
203 | return true1; | ||||||||
204 | } | ||||||||
205 | #else | ||||||||
206 | bool_Bool amdgpu_read_bios(struct amdgpu_device *adev) | ||||||||
207 | { | ||||||||
208 | size_t size; | ||||||||
209 | pcireg_t address, mask; | ||||||||
210 | bus_space_handle_t romh; | ||||||||
211 | int rc; | ||||||||
212 | |||||||||
213 | adev->bios = NULL((void *)0); | ||||||||
214 | /* XXX: some cards may return 0 for rom size? ddx has a workaround */ | ||||||||
215 | |||||||||
216 | address = pci_conf_read(adev->pc, adev->pa_tag, PCI_ROM_REG0x30); | ||||||||
217 | pci_conf_write(adev->pc, adev->pa_tag, PCI_ROM_REG0x30, ~PCI_ROM_ENABLE0x00000001); | ||||||||
218 | mask = pci_conf_read(adev->pc, adev->pa_tag, PCI_ROM_REG0x30); | ||||||||
219 | address |= PCI_ROM_ENABLE0x00000001; | ||||||||
220 | pci_conf_write(adev->pc, adev->pa_tag, PCI_ROM_REG0x30, address); | ||||||||
221 | |||||||||
222 | size = PCI_ROM_SIZE(mask)(((mask) & 0xfffff800) & -((mask) & 0xfffff800)); | ||||||||
223 | if (size == 0) | ||||||||
224 | return false0; | ||||||||
225 | rc = bus_space_map(adev->memt, PCI_ROM_ADDR(address)((address) & 0xfffff800), size, 0, &romh); | ||||||||
226 | if (rc != 0) { | ||||||||
227 | printf(": can't map PCI ROM (%d)\n", rc); | ||||||||
228 | return false0; | ||||||||
229 | } | ||||||||
230 | |||||||||
231 | adev->bios = kzalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
232 | adev->bios_size = size; | ||||||||
233 | bus_space_read_region_1(adev->memt, romh, 0, adev->bios, size)((adev->memt)->read_region_1((romh), (0), (adev->bios ), (size))); | ||||||||
234 | bus_space_unmap(adev->memt, romh, size); | ||||||||
235 | |||||||||
236 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
237 | kfree(adev->bios); | ||||||||
238 | return false0; | ||||||||
239 | } | ||||||||
240 | |||||||||
241 | return true1; | ||||||||
242 | } | ||||||||
243 | #endif | ||||||||
244 | |||||||||
245 | static bool_Bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) | ||||||||
246 | { | ||||||||
247 | u8 header[AMD_VBIOS_SIGNATURE_END(0x30 + sizeof(" 761295520"))+1] = {0}; | ||||||||
248 | int len; | ||||||||
249 | |||||||||
250 | if (!adev->asic_funcs || !adev->asic_funcs->read_bios_from_rom) | ||||||||
251 | return false0; | ||||||||
252 | |||||||||
253 | /* validate VBIOS signature */ | ||||||||
254 | if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header))(adev)->asic_funcs->read_bios_from_rom((adev), (&header [0]), (sizeof(header))) == false0) | ||||||||
255 | return false0; | ||||||||
256 | header[AMD_VBIOS_SIGNATURE_END(0x30 + sizeof(" 761295520"))] = 0; | ||||||||
257 | |||||||||
258 | if ((!AMD_IS_VALID_VBIOS(header)((header)[0] == 0x55 && (header)[1] == 0xAA)) || | ||||||||
259 | 0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET],__builtin_memcmp(((char *)&header[0x30]), (" 761295520"), (strlen(" 761295520"))) | ||||||||
260 | AMD_VBIOS_SIGNATURE,__builtin_memcmp(((char *)&header[0x30]), (" 761295520"), (strlen(" 761295520"))) | ||||||||
261 | strlen(AMD_VBIOS_SIGNATURE))__builtin_memcmp(((char *)&header[0x30]), (" 761295520"), (strlen(" 761295520")))) | ||||||||
262 | return false0; | ||||||||
263 | |||||||||
264 | /* valid vbios, go on */ | ||||||||
265 | len = AMD_VBIOS_LENGTH(header)((header)[2] << 9); | ||||||||
266 | len = roundup2(len, 4)(((len) + ((4) - 1)) & (~((__typeof(len))(4) - 1))); | ||||||||
267 | adev->bios = kmalloc(len, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
268 | if (!adev->bios) { | ||||||||
269 | DRM_ERROR("no memory to allocate for BIOS\n")__drm_err("no memory to allocate for BIOS\n"); | ||||||||
270 | return false0; | ||||||||
271 | } | ||||||||
272 | adev->bios_size = len; | ||||||||
273 | |||||||||
274 | /* read complete BIOS */ | ||||||||
275 | amdgpu_asic_read_bios_from_rom(adev, adev->bios, len)(adev)->asic_funcs->read_bios_from_rom((adev), (adev-> bios), (len)); | ||||||||
276 | |||||||||
277 | if (!check_atom_bios(adev->bios, len)) { | ||||||||
278 | kfree(adev->bios); | ||||||||
279 | return false0; | ||||||||
280 | } | ||||||||
281 | |||||||||
282 | return true1; | ||||||||
283 | } | ||||||||
284 | |||||||||
285 | #ifdef __linux__ | ||||||||
286 | static bool_Bool amdgpu_read_platform_bios(struct amdgpu_device *adev) | ||||||||
287 | { | ||||||||
288 | phys_addr_t rom = adev->pdev->rom; | ||||||||
289 | size_t romlen = adev->pdev->romlen; | ||||||||
290 | void __iomem *bios; | ||||||||
291 | |||||||||
292 | adev->bios = NULL((void *)0); | ||||||||
293 | |||||||||
294 | if (!rom || romlen == 0) | ||||||||
295 | return false0; | ||||||||
296 | |||||||||
297 | adev->bios = kzalloc(romlen, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
298 | if (!adev->bios) | ||||||||
299 | return false0; | ||||||||
300 | |||||||||
301 | bios = ioremap(rom, romlen); | ||||||||
302 | if (!bios) | ||||||||
303 | goto free_bios; | ||||||||
304 | |||||||||
305 | memcpy_fromio(adev->bios, bios, romlen)__builtin_memcpy((adev->bios), (bios), (romlen)); | ||||||||
306 | iounmap(bios); | ||||||||
307 | |||||||||
308 | if (!check_atom_bios(adev->bios, romlen)) | ||||||||
309 | goto free_bios; | ||||||||
310 | |||||||||
311 | adev->bios_size = romlen; | ||||||||
312 | |||||||||
313 | return true1; | ||||||||
314 | free_bios: | ||||||||
315 | kfree(adev->bios); | ||||||||
316 | return false0; | ||||||||
317 | } | ||||||||
318 | #else | ||||||||
319 | static bool_Bool amdgpu_read_platform_bios(struct amdgpu_device *adev) | ||||||||
320 | { | ||||||||
321 | #if defined(__amd64__1) || defined(__i386__) | ||||||||
322 | uint8_t __iomem *bios; | ||||||||
323 | bus_size_t size = 256 * 1024; /* ??? */ | ||||||||
324 | |||||||||
325 | adev->bios = NULL((void *)0); | ||||||||
326 | |||||||||
327 | bios = (u8 *)ISA_HOLE_VADDR(0xc0000)((void *) ((u_long)(0xc0000) - 0x0a0000 + atdevbase)); | ||||||||
328 | |||||||||
329 | adev->bios = kzalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
330 | if (adev->bios == NULL((void *)0)) | ||||||||
331 | return false0; | ||||||||
332 | |||||||||
333 | memcpy_fromio(adev->bios, bios, size)__builtin_memcpy((adev->bios), (bios), (size)); | ||||||||
334 | |||||||||
335 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
336 | kfree(adev->bios); | ||||||||
337 | return false0; | ||||||||
338 | } | ||||||||
339 | |||||||||
340 | adev->bios_size = size; | ||||||||
341 | |||||||||
342 | return true1; | ||||||||
343 | #endif | ||||||||
344 | return false0; | ||||||||
345 | } | ||||||||
346 | #endif | ||||||||
347 | |||||||||
348 | #ifdef CONFIG_ACPI1 | ||||||||
349 | /* ATRM is used to get the BIOS on the discrete cards in | ||||||||
350 | * dual-gpu systems. | ||||||||
351 | */ | ||||||||
352 | /* retrieve the ROM in 4k blocks */ | ||||||||
353 | #define ATRM_BIOS_PAGE4096 4096 | ||||||||
354 | /** | ||||||||
355 | * amdgpu_atrm_call - fetch a chunk of the vbios | ||||||||
356 | * | ||||||||
357 | * @atrm_handle: acpi ATRM handle | ||||||||
358 | * @bios: vbios image pointer | ||||||||
359 | * @offset: offset of vbios image data to fetch | ||||||||
360 | * @len: length of vbios image data to fetch | ||||||||
361 | * | ||||||||
362 | * Executes ATRM to fetch a chunk of the discrete | ||||||||
363 | * vbios image on PX systems (all asics). | ||||||||
364 | * Returns the length of the buffer fetched. | ||||||||
365 | */ | ||||||||
366 | static int amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||||||||
367 | int offset, int len) | ||||||||
368 | { | ||||||||
369 | acpi_status status; | ||||||||
370 | union acpi_object atrm_arg_elements[2], *obj; | ||||||||
371 | struct acpi_object_list atrm_arg; | ||||||||
372 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER(size_t)-1, NULL((void *)0)}; | ||||||||
373 | |||||||||
374 | atrm_arg.count = 2; | ||||||||
375 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||||||||
376 | |||||||||
377 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER1; | ||||||||
378 | atrm_arg_elements[0].integer.value = offset; | ||||||||
379 | |||||||||
380 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER1; | ||||||||
381 | atrm_arg_elements[1].integer.value = len; | ||||||||
382 | |||||||||
383 | status = acpi_evaluate_object(atrm_handle, NULL((void *)0), &atrm_arg, &buffer); | ||||||||
384 | if (ACPI_FAILURE(status)((status) != 0)) { | ||||||||
385 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||||||||
386 | return -ENODEV19; | ||||||||
387 | } | ||||||||
388 | |||||||||
389 | obj = (union acpi_object *)buffer.pointer; | ||||||||
390 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length)__builtin_memcpy((bios+offset), (obj->buffer.pointer), (obj ->buffer.length)); | ||||||||
391 | len = obj->buffer.length; | ||||||||
392 | kfree(buffer.pointer); | ||||||||
393 | return len; | ||||||||
394 | } | ||||||||
395 | |||||||||
396 | static bool_Bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) | ||||||||
397 | { | ||||||||
398 | int ret; | ||||||||
399 | int size = 256 * 1024; | ||||||||
400 | int i; | ||||||||
401 | struct pci_dev *pdev = NULL((void *)0); | ||||||||
402 | acpi_handle dhandle, atrm_handle; | ||||||||
403 | acpi_status status; | ||||||||
404 | bool_Bool found = false0; | ||||||||
405 | |||||||||
406 | /* ATRM is for the discrete card only */ | ||||||||
407 | if (adev->flags & AMD_IS_APU) | ||||||||
408 | return false0; | ||||||||
409 | |||||||||
410 | /* ATRM is for on-platform devices only */ | ||||||||
411 | if (dev_is_removable(&adev->pdev->dev)0) | ||||||||
412 | return false0; | ||||||||
413 | |||||||||
414 | #ifdef notyet | ||||||||
415 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA((0x03 << 8) | 0x00) << 8, pdev)) != NULL((void *)0)) { | ||||||||
416 | dhandle = ACPI_HANDLE(&pdev->dev)((&pdev->dev)->node); | ||||||||
417 | if (!dhandle) | ||||||||
418 | continue; | ||||||||
419 | |||||||||
420 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||||||||
421 | if (ACPI_SUCCESS(status)((status) == 0)) { | ||||||||
422 | found = true1; | ||||||||
423 | break; | ||||||||
424 | } | ||||||||
425 | } | ||||||||
426 | |||||||||
427 | if (!found) { | ||||||||
428 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER((0x03 << 8) | 0x80) << 8, pdev)) != NULL((void *)0)) { | ||||||||
429 | dhandle = ACPI_HANDLE(&pdev->dev)((&pdev->dev)->node); | ||||||||
430 | if (!dhandle) | ||||||||
431 | continue; | ||||||||
432 | |||||||||
433 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||||||||
434 | if (ACPI_SUCCESS(status)((status) == 0)) { | ||||||||
435 | found = true1; | ||||||||
436 | break; | ||||||||
437 | } | ||||||||
438 | } | ||||||||
439 | } | ||||||||
440 | #else | ||||||||
441 | { | ||||||||
442 | pdev = adev->pdev; | ||||||||
443 | dhandle = ACPI_HANDLE(&pdev->dev)((&pdev->dev)->node); | ||||||||
444 | |||||||||
445 | if (dhandle) { | ||||||||
446 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||||||||
447 | if (ACPI_SUCCESS(status)((status) == 0)) { | ||||||||
448 | found = true1; | ||||||||
449 | } | ||||||||
450 | } | ||||||||
451 | } | ||||||||
452 | #endif | ||||||||
453 | |||||||||
454 | if (!found
| ||||||||
455 | return false0; | ||||||||
456 | pci_dev_put(pdev); | ||||||||
457 | |||||||||
458 | adev->bios = kmalloc(size, GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
459 | if (!adev->bios) { | ||||||||
460 | dev_err(adev->dev, "Unable to allocate bios\n")printf("drm:pid%d:%s *ERROR* " "Unable to allocate bios\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__); | ||||||||
461 | return false0; | ||||||||
462 | } | ||||||||
463 | |||||||||
464 | for (i = 0; i < size / ATRM_BIOS_PAGE4096; i++) { | ||||||||
465 | ret = amdgpu_atrm_call(atrm_handle, | ||||||||
466 | adev->bios, | ||||||||
467 | (i * ATRM_BIOS_PAGE4096), | ||||||||
468 | ATRM_BIOS_PAGE4096); | ||||||||
469 | if (ret
| ||||||||
470 | break; | ||||||||
471 | } | ||||||||
472 | |||||||||
473 | if (!check_atom_bios(adev->bios, size)) { | ||||||||
474 | kfree(adev->bios); | ||||||||
475 | return false0; | ||||||||
476 | } | ||||||||
477 | adev->bios_size = size; | ||||||||
478 | return true1; | ||||||||
479 | } | ||||||||
480 | #else | ||||||||
481 | static inline bool_Bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) | ||||||||
482 | { | ||||||||
483 | return false0; | ||||||||
484 | } | ||||||||
485 | #endif | ||||||||
486 | |||||||||
487 | static bool_Bool amdgpu_read_disabled_bios(struct amdgpu_device *adev) | ||||||||
488 | { | ||||||||
489 | if (adev->flags & AMD_IS_APU) | ||||||||
490 | return igp_read_bios_from_vram(adev); | ||||||||
491 | else | ||||||||
492 | return (!adev->asic_funcs || !adev->asic_funcs->read_disabled_bios) ? | ||||||||
493 | false0 : amdgpu_asic_read_disabled_bios(adev)(adev)->asic_funcs->read_disabled_bios((adev)); | ||||||||
494 | } | ||||||||
495 | |||||||||
496 | #ifdef CONFIG_ACPI1 | ||||||||
497 | static bool_Bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) | ||||||||
498 | { | ||||||||
499 | struct acpi_table_header *hdr; | ||||||||
500 | acpi_size tbl_size; | ||||||||
501 | UEFI_ACPI_VFCT *vfct; | ||||||||
502 | unsigned offset; | ||||||||
503 | |||||||||
504 | if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr))((acpi_get_table("VFCT", 1, &hdr)) == 0)) | ||||||||
505 | return false0; | ||||||||
506 | tbl_size = hdr->length; | ||||||||
507 | if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { | ||||||||
508 | dev_info(adev->dev, "ACPI VFCT table present but broken (too short #1),skipping\n")do { } while(0); | ||||||||
509 | return false0; | ||||||||
510 | } | ||||||||
511 | |||||||||
512 | vfct = (UEFI_ACPI_VFCT *)hdr; | ||||||||
513 | offset = vfct->VBIOSImageOffset; | ||||||||
514 | |||||||||
515 | while (offset < tbl_size) { | ||||||||
516 | GOP_VBIOS_CONTENT *vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + offset); | ||||||||
517 | VFCT_IMAGE_HEADER *vhdr = &vbios->VbiosHeader; | ||||||||
518 | |||||||||
519 | offset += sizeof(VFCT_IMAGE_HEADER); | ||||||||
520 | if (offset > tbl_size) { | ||||||||
521 | dev_info(adev->dev, "ACPI VFCT image header truncated,skipping\n")do { } while(0); | ||||||||
522 | return false0; | ||||||||
523 | } | ||||||||
524 | |||||||||
525 | offset += vhdr->ImageLength; | ||||||||
526 | if (offset > tbl_size) { | ||||||||
527 | dev_info(adev->dev, "ACPI VFCT image truncated,skipping\n")do { } while(0); | ||||||||
528 | return false0; | ||||||||
529 | } | ||||||||
530 | |||||||||
531 | if (vhdr->ImageLength && | ||||||||
532 | vhdr->PCIBus == adev->pdev->bus->number && | ||||||||
533 | vhdr->PCIDevice == PCI_SLOT(adev->pdev->devfn)((adev->pdev->devfn) >> 3) && | ||||||||
534 | vhdr->PCIFunction == PCI_FUNC(adev->pdev->devfn)((adev->pdev->devfn) & 0x7) && | ||||||||
535 | vhdr->VendorID == adev->pdev->vendor && | ||||||||
536 | vhdr->DeviceID == adev->pdev->device) { | ||||||||
537 | adev->bios = kmemdup(&vbios->VbiosContent, | ||||||||
538 | vhdr->ImageLength, | ||||||||
539 | GFP_KERNEL(0x0001 | 0x0004)); | ||||||||
540 | |||||||||
541 | if (!check_atom_bios(adev->bios, vhdr->ImageLength)) { | ||||||||
542 | kfree(adev->bios); | ||||||||
543 | return false0; | ||||||||
544 | } | ||||||||
545 | adev->bios_size = vhdr->ImageLength; | ||||||||
546 | return true1; | ||||||||
547 | } | ||||||||
548 | } | ||||||||
549 | |||||||||
550 | dev_info(adev->dev, "ACPI VFCT table present but broken (too short #2),skipping\n")do { } while(0); | ||||||||
551 | return false0; | ||||||||
552 | } | ||||||||
553 | #else | ||||||||
554 | static inline bool_Bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) | ||||||||
555 | { | ||||||||
556 | return false0; | ||||||||
557 | } | ||||||||
558 | #endif | ||||||||
559 | |||||||||
560 | bool_Bool amdgpu_get_bios(struct amdgpu_device *adev) | ||||||||
561 | { | ||||||||
562 | if (amdgpu_atrm_get_bios(adev)) { | ||||||||
| |||||||||
563 | dev_info(adev->dev, "Fetched VBIOS from ATRM\n")do { } while(0); | ||||||||
564 | goto success; | ||||||||
565 | } | ||||||||
566 | |||||||||
567 | if (amdgpu_acpi_vfct_bios(adev)) { | ||||||||
568 | dev_info(adev->dev, "Fetched VBIOS from VFCT\n")do { } while(0); | ||||||||
569 | goto success; | ||||||||
570 | } | ||||||||
571 | |||||||||
572 | if (igp_read_bios_from_vram(adev)) { | ||||||||
573 | dev_info(adev->dev, "Fetched VBIOS from VRAM BAR\n")do { } while(0); | ||||||||
574 | goto success; | ||||||||
575 | } | ||||||||
576 | |||||||||
577 | if (amdgpu_read_bios(adev)) { | ||||||||
578 | dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n")do { } while(0); | ||||||||
579 | goto success; | ||||||||
580 | } | ||||||||
581 | |||||||||
582 | if (amdgpu_read_bios_from_rom(adev)) { | ||||||||
583 | dev_info(adev->dev, "Fetched VBIOS from ROM\n")do { } while(0); | ||||||||
584 | goto success; | ||||||||
585 | } | ||||||||
586 | |||||||||
587 | if (amdgpu_read_disabled_bios(adev)) { | ||||||||
588 | dev_info(adev->dev, "Fetched VBIOS from disabled ROM BAR\n")do { } while(0); | ||||||||
589 | goto success; | ||||||||
590 | } | ||||||||
591 | |||||||||
592 | if (amdgpu_read_platform_bios(adev)) { | ||||||||
593 | dev_info(adev->dev, "Fetched VBIOS from platform\n")do { } while(0); | ||||||||
594 | goto success; | ||||||||
595 | } | ||||||||
596 | |||||||||
597 | dev_err(adev->dev, "Unable to locate a BIOS ROM\n")printf("drm:pid%d:%s *ERROR* " "Unable to locate a BIOS ROM\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__); | ||||||||
598 | return false0; | ||||||||
599 | |||||||||
600 | success: | ||||||||
601 | adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true1 : false0; | ||||||||
602 | return true1; | ||||||||
603 | } | ||||||||
604 | |||||||||
605 | /* helper function for soc15 and onwards to read bios from rom */ | ||||||||
606 | bool_Bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev, | ||||||||
607 | u8 *bios, u32 length_bytes) | ||||||||
608 | { | ||||||||
609 | u32 *dw_ptr; | ||||||||
610 | u32 i, length_dw; | ||||||||
611 | u32 rom_offset; | ||||||||
612 | u32 rom_index_offset; | ||||||||
613 | u32 rom_data_offset; | ||||||||
614 | |||||||||
615 | if (bios == NULL((void *)0)) | ||||||||
616 | return false0; | ||||||||
617 | if (length_bytes == 0) | ||||||||
618 | return false0; | ||||||||
619 | /* APU vbios image is part of sbios image */ | ||||||||
620 | if (adev->flags & AMD_IS_APU) | ||||||||
621 | return false0; | ||||||||
622 | if (!adev->smuio.funcs || | ||||||||
623 | !adev->smuio.funcs->get_rom_index_offset || | ||||||||
624 | !adev->smuio.funcs->get_rom_data_offset) | ||||||||
625 | return false0; | ||||||||
626 | |||||||||
627 | dw_ptr = (u32 *)bios; | ||||||||
628 | length_dw = roundup2(length_bytes, 4)(((length_bytes) + ((4) - 1)) & (~((__typeof(length_bytes ))(4) - 1))) / 4; | ||||||||
629 | |||||||||
630 | rom_index_offset = | ||||||||
631 | adev->smuio.funcs->get_rom_index_offset(adev); | ||||||||
632 | rom_data_offset = | ||||||||
633 | adev->smuio.funcs->get_rom_data_offset(adev); | ||||||||
634 | |||||||||
635 | if (adev->nbio.funcs && | ||||||||
636 | adev->nbio.funcs->get_rom_offset) { | ||||||||
637 | rom_offset = adev->nbio.funcs->get_rom_offset(adev); | ||||||||
638 | rom_offset = rom_offset << 17; | ||||||||
639 | } else { | ||||||||
640 | rom_offset = 0; | ||||||||
641 | } | ||||||||
642 | |||||||||
643 | /* set rom index to rom_offset */ | ||||||||
644 | WREG32(rom_index_offset, rom_offset)amdgpu_device_wreg(adev, (rom_index_offset), (rom_offset), 0); | ||||||||
645 | /* read out the rom data */ | ||||||||
646 | for (i = 0; i < length_dw; i++) | ||||||||
647 | dw_ptr[i] = RREG32(rom_data_offset)amdgpu_device_rreg(adev, (rom_data_offset), 0); | ||||||||
648 | |||||||||
649 | return true1; | ||||||||
650 | } |
1 | /* Public domain. */ |
2 | |
3 | #ifndef _LINUX_SLAB_H |
4 | #define _LINUX_SLAB_H |
5 | |
6 | #include <sys/types.h> |
7 | #include <sys/malloc.h> |
8 | |
9 | #include <linux/types.h> |
10 | #include <linux/workqueue.h> |
11 | #include <linux/gfp.h> |
12 | |
13 | #include <linux/processor.h> /* for CACHELINESIZE */ |
14 | |
15 | #define ARCH_KMALLOC_MINALIGN64 CACHELINESIZE64 |
16 | |
17 | #define ZERO_SIZE_PTR((void *)0) NULL((void *)0) |
18 | |
19 | static inline void * |
20 | kmalloc(size_t size, int flags) |
21 | { |
22 | return malloc(size, M_DRM145, flags); |
23 | } |
24 | |
25 | static inline void * |
26 | kmalloc_array(size_t n, size_t size, int flags) |
27 | { |
28 | if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size) |
29 | return NULL((void *)0); |
30 | return malloc(n * size, M_DRM145, flags); |
31 | } |
32 | |
33 | static inline void * |
34 | kcalloc(size_t n, size_t size, int flags) |
35 | { |
36 | if (n != 0 && SIZE_MAX0xffffffffffffffffUL / n < size) |
37 | return NULL((void *)0); |
38 | return malloc(n * size, M_DRM145, flags | M_ZERO0x0008); |
39 | } |
40 | |
41 | static inline void * |
42 | kzalloc(size_t size, int flags) |
43 | { |
44 | return malloc(size, M_DRM145, flags | M_ZERO0x0008); |
45 | } |
46 | |
47 | static inline void |
48 | kfree(const void *objp) |
49 | { |
50 | free((void *)objp, M_DRM145, 0); |
51 | } |
52 | |
53 | #endif |