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