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