diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch b/common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch new file mode 100644 index 00000000..43ed61bb --- /dev/null +++ b/common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch @@ -0,0 +1,153 @@ +From 4886ec68e93f0151fc681cf6f792fe1acba03814 Mon Sep 17 00:00:00 2001 +From: "monk.liu" <Monk.Liu@amd.com> +Date: Thu, 29 Oct 2015 15:33:06 +0800 +Subject: [PATCH 0007/1110] drm/amdgpu: Use new read bios from rom callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Read the vbios directly from the rom. In some cases, +e.g., virtualization, the rom is not available via +the BAR or other means. Access it directly. + +This is an updated version of Monks original patch which +uses family specific callbacks and unifies some of the +validation checking. + +Reviewed-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> +Signed-off-by: Monk Liu <Monk.Liu@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 58 +++++++++++++++++++++++++++----- + 1 file changed, 50 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +index c44c0c6..80add22 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +@@ -35,6 +35,13 @@ + * BIOS. + */ + ++#define AMD_VBIOS_SIGNATURE " 761295520" ++#define AMD_VBIOS_SIGNATURE_OFFSET 0x30 ++#define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE) ++#define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE) ++#define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA) ++#define AMD_VBIOS_LENGTH(p) ((p)[2] << 9) ++ + /* If you boot an IGP board with a discrete card as the primary, + * the IGP rom is not accessible via the rom bar as the IGP rom is + * part of the system bios. On boot, the system bios puts a +@@ -58,7 +65,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) + return false; + } + +- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { ++ if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { + iounmap(bios); + return false; + } +@@ -74,7 +81,7 @@ static bool igp_read_bios_from_vram(struct amdgpu_device *adev) + + bool amdgpu_read_bios(struct amdgpu_device *adev) + { +- uint8_t __iomem *bios, val1, val2; ++ uint8_t __iomem *bios, val[2]; + size_t size; + + adev->bios = NULL; +@@ -84,10 +91,10 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) + return false; + } + +- val1 = readb(&bios[0]); +- val2 = readb(&bios[1]); ++ val[0] = readb(&bios[0]); ++ val[1] = readb(&bios[1]); + +- if (size == 0 || val1 != 0x55 || val2 != 0xaa) { ++ if (size == 0 || !AMD_IS_VALID_VBIOS(val)) { + pci_unmap_rom(adev->pdev, bios); + return false; + } +@@ -101,6 +108,38 @@ bool amdgpu_read_bios(struct amdgpu_device *adev) + return true; + } + ++static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) ++{ ++ u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0}; ++ int len; ++ ++ if (!adev->asic_funcs->read_bios_from_rom) ++ return false; ++ ++ /* validate VBIOS signature */ ++ if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false) ++ return false; ++ header[AMD_VBIOS_SIGNATURE_END] = 0; ++ ++ if ((!AMD_IS_VALID_VBIOS(header)) || ++ 0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET], ++ AMD_VBIOS_SIGNATURE, ++ strlen(AMD_VBIOS_SIGNATURE))) ++ return false; ++ ++ /* valid vbios, go on */ ++ len = AMD_VBIOS_LENGTH(header); ++ len = ALIGN(len, 4); ++ adev->bios = kmalloc(len, GFP_KERNEL); ++ if (!adev->bios) { ++ DRM_ERROR("no memory to allocate for BIOS\n"); ++ return false; ++ } ++ ++ /* read complete BIOS */ ++ return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len); ++} ++ + static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) + { + uint8_t __iomem *bios; +@@ -113,7 +152,7 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) + return false; + } + +- if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { ++ if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { + return false; + } + adev->bios = kmemdup(bios, size, GFP_KERNEL); +@@ -230,7 +269,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) + break; + } + +- if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { ++ if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) { + kfree(adev->bios); + return false; + } +@@ -320,6 +359,9 @@ bool amdgpu_get_bios(struct amdgpu_device *adev) + if (r == false) + r = amdgpu_read_bios(adev); + if (r == false) { ++ r = amdgpu_read_bios_from_rom(adev); ++ } ++ if (r == false) { + r = amdgpu_read_disabled_bios(adev); + } + if (r == false) { +@@ -330,7 +372,7 @@ bool amdgpu_get_bios(struct amdgpu_device *adev) + adev->bios = NULL; + return false; + } +- if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { ++ if (!AMD_IS_VALID_VBIOS(adev->bios)) { + printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]); + goto free_bios; + } +-- +2.7.4 + |