* 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
                return false;
        }
 
-       if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
+       if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) {
                iounmap(bios);
                return false;
        }
 
 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;
                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;
        }
        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;
                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);
                        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;
        }
                r = igp_read_bios_from_vram(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);
        }
                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;
        }