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