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
49743 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, if dynamic critical region is not enabled,
100
* the vbios image is also put at the start of VRAM in the VF.
101
*/
102
static 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
154
bool 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
182
static 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
222
static 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;
250
free_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
*/
274
static 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
304
static 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
361
static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
362
{
363
return false;
364
}
365
#endif
366
367
static 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
374
static 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
431
static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
432
{
433
return false;
434
}
435
#endif
436
437
static 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
462
success:
463
return true;
464
}
465
466
static 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
473
static 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
527
success:
528
return true;
529
}
530
531
bool 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 */
547
bool 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
}
592
593