aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0007-drm-amdgpu-Use-new-read-bios-from-rom-callback.patch
diff options
context:
space:
mode:
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.patch153
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
+