Line data Source code
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/pci.h>
33 : #include <linux/slab.h>
34 : #include <linux/acpi.h>
35 : /*
36 : * BIOS.
37 : */
38 :
39 : #define AMD_VBIOS_SIGNATURE " 761295520"
40 : #define AMD_VBIOS_SIGNATURE_OFFSET 0x30
41 : #define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE)
42 : #define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE)
43 : #define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA)
44 : #define AMD_VBIOS_LENGTH(p) ((p)[2] << 9)
45 :
46 : /* Check if current bios is an ATOM BIOS.
47 : * Return true if it is ATOM BIOS. Otherwise, return false.
48 : */
49 0 : static bool check_atom_bios(uint8_t *bios, size_t size)
50 : {
51 : uint16_t tmp, bios_header_start;
52 :
53 0 : if (!bios || size < 0x49) {
54 0 : DRM_INFO("vbios mem is null or mem size is wrong\n");
55 0 : return false;
56 : }
57 :
58 0 : if (!AMD_IS_VALID_VBIOS(bios)) {
59 0 : DRM_INFO("BIOS signature incorrect %x %x\n", bios[0], bios[1]);
60 0 : return false;
61 : }
62 :
63 0 : bios_header_start = bios[0x48] | (bios[0x49] << 8);
64 0 : if (!bios_header_start) {
65 0 : DRM_INFO("Can't locate bios header\n");
66 0 : return false;
67 : }
68 :
69 0 : tmp = bios_header_start + 4;
70 0 : if (size < tmp) {
71 0 : DRM_INFO("BIOS header is broken\n");
72 0 : return false;
73 : }
74 :
75 0 : if (!memcmp(bios + tmp, "ATOM", 4) ||
76 0 : !memcmp(bios + tmp, "MOTA", 4)) {
77 0 : DRM_DEBUG("ATOMBIOS detected\n");
78 0 : return true;
79 : }
80 :
81 : return false;
82 : }
83 :
84 : /* If you boot an IGP board with a discrete card as the primary,
85 : * the IGP rom is not accessible via the rom bar as the IGP rom is
86 : * part of the system bios. On boot, the system bios puts a
87 : * copy of the igp rom at the start of vram if a discrete card is
88 : * present.
89 : */
90 0 : static bool igp_read_bios_from_vram(struct amdgpu_device *adev)
91 : {
92 : uint8_t __iomem *bios;
93 : resource_size_t vram_base;
94 0 : resource_size_t size = 256 * 1024; /* ??? */
95 :
96 0 : if (!(adev->flags & AMD_IS_APU))
97 0 : if (amdgpu_device_need_post(adev))
98 : return false;
99 :
100 : /* FB BAR not enabled */
101 0 : if (pci_resource_len(adev->pdev, 0) == 0)
102 : return false;
103 :
104 0 : adev->bios = NULL;
105 0 : vram_base = pci_resource_start(adev->pdev, 0);
106 0 : bios = ioremap_wc(vram_base, size);
107 0 : if (!bios) {
108 : return false;
109 : }
110 :
111 0 : adev->bios = kmalloc(size, GFP_KERNEL);
112 0 : if (!adev->bios) {
113 0 : iounmap(bios);
114 0 : return false;
115 : }
116 0 : adev->bios_size = size;
117 0 : memcpy_fromio(adev->bios, bios, size);
118 0 : iounmap(bios);
119 :
120 0 : if (!check_atom_bios(adev->bios, size)) {
121 0 : kfree(adev->bios);
122 0 : return false;
123 : }
124 :
125 : return true;
126 : }
127 :
128 0 : bool amdgpu_read_bios(struct amdgpu_device *adev)
129 : {
130 : uint8_t __iomem *bios;
131 : size_t size;
132 :
133 0 : adev->bios = NULL;
134 : /* XXX: some cards may return 0 for rom size? ddx has a workaround */
135 0 : bios = pci_map_rom(adev->pdev, &size);
136 0 : if (!bios) {
137 : return false;
138 : }
139 :
140 0 : adev->bios = kzalloc(size, GFP_KERNEL);
141 0 : if (adev->bios == NULL) {
142 0 : pci_unmap_rom(adev->pdev, bios);
143 0 : return false;
144 : }
145 0 : adev->bios_size = size;
146 0 : memcpy_fromio(adev->bios, bios, size);
147 0 : pci_unmap_rom(adev->pdev, bios);
148 :
149 0 : if (!check_atom_bios(adev->bios, size)) {
150 0 : kfree(adev->bios);
151 0 : return false;
152 : }
153 :
154 : return true;
155 : }
156 :
157 0 : static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev)
158 : {
159 0 : u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0};
160 : int len;
161 :
162 0 : if (!adev->asic_funcs || !adev->asic_funcs->read_bios_from_rom)
163 : return false;
164 :
165 : /* validate VBIOS signature */
166 0 : if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false)
167 : return false;
168 0 : header[AMD_VBIOS_SIGNATURE_END] = 0;
169 :
170 0 : if ((!AMD_IS_VALID_VBIOS(header)) ||
171 0 : 0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET],
172 : AMD_VBIOS_SIGNATURE,
173 : strlen(AMD_VBIOS_SIGNATURE)))
174 : return false;
175 :
176 : /* valid vbios, go on */
177 0 : len = AMD_VBIOS_LENGTH(header);
178 0 : len = ALIGN(len, 4);
179 0 : adev->bios = kmalloc(len, GFP_KERNEL);
180 0 : if (!adev->bios) {
181 0 : DRM_ERROR("no memory to allocate for BIOS\n");
182 0 : return false;
183 : }
184 0 : adev->bios_size = len;
185 :
186 : /* read complete BIOS */
187 0 : amdgpu_asic_read_bios_from_rom(adev, adev->bios, len);
188 :
189 0 : if (!check_atom_bios(adev->bios, len)) {
190 0 : kfree(adev->bios);
191 0 : return false;
192 : }
193 :
194 : return true;
195 : }
196 :
197 0 : static bool amdgpu_read_platform_bios(struct amdgpu_device *adev)
198 : {
199 0 : phys_addr_t rom = adev->pdev->rom;
200 0 : size_t romlen = adev->pdev->romlen;
201 : void __iomem *bios;
202 :
203 0 : adev->bios = NULL;
204 :
205 0 : if (!rom || romlen == 0)
206 : return false;
207 :
208 0 : adev->bios = kzalloc(romlen, GFP_KERNEL);
209 0 : if (!adev->bios)
210 : return false;
211 :
212 0 : bios = ioremap(rom, romlen);
213 0 : if (!bios)
214 : goto free_bios;
215 :
216 0 : memcpy_fromio(adev->bios, bios, romlen);
217 0 : iounmap(bios);
218 :
219 0 : if (!check_atom_bios(adev->bios, romlen))
220 : goto free_bios;
221 :
222 0 : adev->bios_size = romlen;
223 :
224 0 : return true;
225 : free_bios:
226 0 : kfree(adev->bios);
227 0 : return false;
228 : }
229 :
230 : #ifdef CONFIG_ACPI
231 : /* ATRM is used to get the BIOS on the discrete cards in
232 : * dual-gpu systems.
233 : */
234 : /* retrieve the ROM in 4k blocks */
235 : #define ATRM_BIOS_PAGE 4096
236 : /**
237 : * amdgpu_atrm_call - fetch a chunk of the vbios
238 : *
239 : * @atrm_handle: acpi ATRM handle
240 : * @bios: vbios image pointer
241 : * @offset: offset of vbios image data to fetch
242 : * @len: length of vbios image data to fetch
243 : *
244 : * Executes ATRM to fetch a chunk of the discrete
245 : * vbios image on PX systems (all asics).
246 : * Returns the length of the buffer fetched.
247 : */
248 : static int amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
249 : int offset, int len)
250 : {
251 : acpi_status status;
252 : union acpi_object atrm_arg_elements[2], *obj;
253 : struct acpi_object_list atrm_arg;
254 : struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
255 :
256 : atrm_arg.count = 2;
257 : atrm_arg.pointer = &atrm_arg_elements[0];
258 :
259 : atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
260 : atrm_arg_elements[0].integer.value = offset;
261 :
262 : atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
263 : atrm_arg_elements[1].integer.value = len;
264 :
265 : status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
266 : if (ACPI_FAILURE(status)) {
267 : printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
268 : return -ENODEV;
269 : }
270 :
271 : obj = (union acpi_object *)buffer.pointer;
272 : memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
273 : len = obj->buffer.length;
274 : kfree(buffer.pointer);
275 : return len;
276 : }
277 :
278 : static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
279 : {
280 : int ret;
281 : int size = 256 * 1024;
282 : int i;
283 : struct pci_dev *pdev = NULL;
284 : acpi_handle dhandle, atrm_handle;
285 : acpi_status status;
286 : bool found = false;
287 :
288 : /* ATRM is for the discrete card only */
289 : if (adev->flags & AMD_IS_APU)
290 : return false;
291 :
292 : while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
293 : dhandle = ACPI_HANDLE(&pdev->dev);
294 : if (!dhandle)
295 : continue;
296 :
297 : status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
298 : if (ACPI_SUCCESS(status)) {
299 : found = true;
300 : break;
301 : }
302 : }
303 :
304 : if (!found) {
305 : while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
306 : dhandle = ACPI_HANDLE(&pdev->dev);
307 : if (!dhandle)
308 : continue;
309 :
310 : status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
311 : if (ACPI_SUCCESS(status)) {
312 : found = true;
313 : break;
314 : }
315 : }
316 : }
317 :
318 : if (!found)
319 : return false;
320 :
321 : adev->bios = kmalloc(size, GFP_KERNEL);
322 : if (!adev->bios) {
323 : dev_err(adev->dev, "Unable to allocate bios\n");
324 : return false;
325 : }
326 :
327 : for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
328 : ret = amdgpu_atrm_call(atrm_handle,
329 : adev->bios,
330 : (i * ATRM_BIOS_PAGE),
331 : ATRM_BIOS_PAGE);
332 : if (ret < ATRM_BIOS_PAGE)
333 : break;
334 : }
335 :
336 : if (!check_atom_bios(adev->bios, size)) {
337 : kfree(adev->bios);
338 : return false;
339 : }
340 : adev->bios_size = size;
341 : return true;
342 : }
343 : #else
344 : static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
345 : {
346 : return false;
347 : }
348 : #endif
349 :
350 0 : static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev)
351 : {
352 0 : if (adev->flags & AMD_IS_APU)
353 0 : return igp_read_bios_from_vram(adev);
354 : else
355 0 : return (!adev->asic_funcs || !adev->asic_funcs->read_disabled_bios) ?
356 0 : false : amdgpu_asic_read_disabled_bios(adev);
357 : }
358 :
359 : #ifdef CONFIG_ACPI
360 : static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
361 : {
362 : struct acpi_table_header *hdr;
363 : acpi_size tbl_size;
364 : UEFI_ACPI_VFCT *vfct;
365 : unsigned offset;
366 :
367 : if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
368 : return false;
369 : tbl_size = hdr->length;
370 : if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
371 : dev_info(adev->dev, "ACPI VFCT table present but broken (too short #1),skipping\n");
372 : return false;
373 : }
374 :
375 : vfct = (UEFI_ACPI_VFCT *)hdr;
376 : offset = vfct->VBIOSImageOffset;
377 :
378 : while (offset < tbl_size) {
379 : GOP_VBIOS_CONTENT *vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + offset);
380 : VFCT_IMAGE_HEADER *vhdr = &vbios->VbiosHeader;
381 :
382 : offset += sizeof(VFCT_IMAGE_HEADER);
383 : if (offset > tbl_size) {
384 : dev_info(adev->dev, "ACPI VFCT image header truncated,skipping\n");
385 : return false;
386 : }
387 :
388 : offset += vhdr->ImageLength;
389 : if (offset > tbl_size) {
390 : dev_info(adev->dev, "ACPI VFCT image truncated,skipping\n");
391 : return false;
392 : }
393 :
394 : if (vhdr->ImageLength &&
395 : vhdr->PCIBus == adev->pdev->bus->number &&
396 : vhdr->PCIDevice == PCI_SLOT(adev->pdev->devfn) &&
397 : vhdr->PCIFunction == PCI_FUNC(adev->pdev->devfn) &&
398 : vhdr->VendorID == adev->pdev->vendor &&
399 : vhdr->DeviceID == adev->pdev->device) {
400 : adev->bios = kmemdup(&vbios->VbiosContent,
401 : vhdr->ImageLength,
402 : GFP_KERNEL);
403 :
404 : if (!check_atom_bios(adev->bios, vhdr->ImageLength)) {
405 : kfree(adev->bios);
406 : return false;
407 : }
408 : adev->bios_size = vhdr->ImageLength;
409 : return true;
410 : }
411 : }
412 :
413 : dev_info(adev->dev, "ACPI VFCT table present but broken (too short #2),skipping\n");
414 : return false;
415 : }
416 : #else
417 : static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
418 : {
419 : return false;
420 : }
421 : #endif
422 :
423 0 : bool amdgpu_get_bios(struct amdgpu_device *adev)
424 : {
425 0 : if (amdgpu_atrm_get_bios(adev)) {
426 : dev_info(adev->dev, "Fetched VBIOS from ATRM\n");
427 : goto success;
428 : }
429 :
430 0 : if (amdgpu_acpi_vfct_bios(adev)) {
431 : dev_info(adev->dev, "Fetched VBIOS from VFCT\n");
432 : goto success;
433 : }
434 :
435 0 : if (igp_read_bios_from_vram(adev)) {
436 0 : dev_info(adev->dev, "Fetched VBIOS from VRAM BAR\n");
437 0 : goto success;
438 : }
439 :
440 0 : if (amdgpu_read_bios(adev)) {
441 0 : dev_info(adev->dev, "Fetched VBIOS from ROM BAR\n");
442 0 : goto success;
443 : }
444 :
445 0 : if (amdgpu_read_bios_from_rom(adev)) {
446 0 : dev_info(adev->dev, "Fetched VBIOS from ROM\n");
447 0 : goto success;
448 : }
449 :
450 0 : if (amdgpu_read_disabled_bios(adev)) {
451 0 : dev_info(adev->dev, "Fetched VBIOS from disabled ROM BAR\n");
452 0 : goto success;
453 : }
454 :
455 0 : if (amdgpu_read_platform_bios(adev)) {
456 0 : dev_info(adev->dev, "Fetched VBIOS from platform\n");
457 0 : goto success;
458 : }
459 :
460 0 : dev_err(adev->dev, "Unable to locate a BIOS ROM\n");
461 0 : return false;
462 :
463 : success:
464 0 : adev->is_atom_fw = (adev->asic_type >= CHIP_VEGA10) ? true : false;
465 0 : return true;
466 : }
467 :
468 : /* helper function for soc15 and onwards to read bios from rom */
469 0 : bool amdgpu_soc15_read_bios_from_rom(struct amdgpu_device *adev,
470 : u8 *bios, u32 length_bytes)
471 : {
472 : u32 *dw_ptr;
473 : u32 i, length_dw;
474 : u32 rom_offset;
475 : u32 rom_index_offset;
476 : u32 rom_data_offset;
477 :
478 0 : if (bios == NULL)
479 : return false;
480 0 : if (length_bytes == 0)
481 : return false;
482 : /* APU vbios image is part of sbios image */
483 0 : if (adev->flags & AMD_IS_APU)
484 : return false;
485 0 : if (!adev->smuio.funcs ||
486 0 : !adev->smuio.funcs->get_rom_index_offset ||
487 0 : !adev->smuio.funcs->get_rom_data_offset)
488 : return false;
489 :
490 0 : dw_ptr = (u32 *)bios;
491 0 : length_dw = ALIGN(length_bytes, 4) / 4;
492 :
493 0 : rom_index_offset =
494 : adev->smuio.funcs->get_rom_index_offset(adev);
495 0 : rom_data_offset =
496 0 : adev->smuio.funcs->get_rom_data_offset(adev);
497 :
498 0 : if (adev->nbio.funcs &&
499 0 : adev->nbio.funcs->get_rom_offset) {
500 0 : rom_offset = adev->nbio.funcs->get_rom_offset(adev);
501 0 : rom_offset = rom_offset << 17;
502 : } else {
503 : rom_offset = 0;
504 : }
505 :
506 : /* set rom index to rom_offset */
507 0 : WREG32(rom_index_offset, rom_offset);
508 : /* read out the rom data */
509 0 : for (i = 0; i < length_dw; i++)
510 0 : dw_ptr[i] = RREG32(rom_data_offset);
511 :
512 : return true;
513 : }
|