|
32 | 32 | #include <linux/pci.h> |
33 | 33 | #include <linux/slab.h> |
34 | 34 | #include <linux/acpi.h> |
| 35 | +#include <linux/firmware.h> |
35 | 36 | /* |
36 | 37 | * BIOS. |
37 | 38 | */ |
@@ -156,6 +157,46 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) |
156 | 157 | return true; |
157 | 158 | } |
158 | 159 |
|
| 160 | +static bool amdgpu_bios_firmware(struct amdgpu_device *adev) |
| 161 | +{ |
| 162 | + const struct firmware* vbios_firmware; |
| 163 | + const char* vbios_name = "vbios/renoir.bin"; |
| 164 | + const size_t vbios_size = 32 << PAGE_SHIFT; |
| 165 | + int ret; |
| 166 | + DRM_INFO("amdgpu_bios_firmware()\n"); |
| 167 | + ret = request_firmware(&vbios_firmware, vbios_name, adev->dev); |
| 168 | + if (ret) { |
| 169 | + DRM_ERROR("failed to load '%s': %d\n", vbios_name, ret); |
| 170 | + return false; |
| 171 | + } |
| 172 | + |
| 173 | + if (!AMD_IS_VALID_VBIOS(vbios_firmware->data)) { |
| 174 | + DRM_ERROR("vbios file '%s' signature incorrect %x %x\n", |
| 175 | + vbios_name, vbios_firmware->data[0], vbios_firmware->data[1]); |
| 176 | + release_firmware(vbios_firmware); |
| 177 | + return false; |
| 178 | + } |
| 179 | + |
| 180 | + if (vbios_firmware->size > vbios_size) { |
| 181 | + DRM_ERROR("vbios file '%s' size too large, %zu > %zu\n", |
| 182 | + vbios_name, vbios_firmware->size, vbios_size); |
| 183 | + release_firmware(vbios_firmware); |
| 184 | + return false; |
| 185 | + } |
| 186 | + |
| 187 | + adev->bios = kzalloc(vbios_size, GFP_KERNEL); |
| 188 | + if (adev->bios == NULL) { |
| 189 | + DRM_ERROR("no memory to allocate for BIOS\n"); |
| 190 | + release_firmware(vbios_firmware); |
| 191 | + return false; |
| 192 | + } |
| 193 | + |
| 194 | + adev->bios_size = vbios_size; |
| 195 | + memcpy_fromio(adev->bios, vbios_firmware->data, vbios_firmware->size); |
| 196 | + release_firmware(vbios_firmware); |
| 197 | + return true; |
| 198 | +} |
| 199 | + |
159 | 200 | static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) |
160 | 201 | { |
161 | 202 | u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0}; |
@@ -444,6 +485,11 @@ static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) |
444 | 485 |
|
445 | 486 | bool amdgpu_get_bios(struct amdgpu_device *adev) |
446 | 487 | { |
| 488 | + if (amdgpu_bios_firmware(adev)) { |
| 489 | + dev_info(adev->dev, "Fetched VBIOS from firmware file\n"); |
| 490 | + goto success; |
| 491 | + } |
| 492 | + |
447 | 493 | if (amdgpu_atrm_get_bios(adev)) { |
448 | 494 | dev_info(adev->dev, "Fetched VBIOS from ATRM\n"); |
449 | 495 | goto success; |
|
0 commit comments