--- drivers/gpu/drm/radeon/radeon_bios.c 2010-02-24 19:52:17.000000000 +0100 +++ /usr/src/linux/drivers/gpu/drm/radeon/radeon_bios.c 2010-02-27 18:38:09.000000000 +0100 @@ -29,6 +29,7 @@ #include "radeon_reg.h" #include "radeon.h" #include "atom.h" +#include /* * BIOS. @@ -50,6 +51,7 @@ vram_base = drm_get_resource_start(rdev->ddev, 0); bios = ioremap(vram_base, size); if (!bios) { + DRM_ERROR("No bios\n"); return false; } @@ -59,6 +61,7 @@ } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) { + DRM_ERROR("alloc fail\n"); iounmap(bios); return false; } @@ -67,6 +70,41 @@ return true; } +static bool radeon_read_bios_from_firmware(struct radeon_device *rdev) +{ + const uint8_t __iomem *bios; + resource_size_t size; + const struct firmware *fw = NULL; + + request_firmware(&fw, "radeon/vbios.bin", rdev->dev); + if (!fw) { + DRM_ERROR("No bios\n"); + return false; + } + size = fw->size; + bios = fw->data; + + if (!bios) { + DRM_ERROR("No bios\n"); + return false; + } + + if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + DRM_ERROR("wrong sig\n"); + release_firmware(fw); + return false; + } + rdev->bios = kmalloc(size, GFP_KERNEL); + if (rdev->bios == NULL) { + DRM_ERROR("alloc fail\n"); + release_firmware(fw); + return false; + } + memcpy(rdev->bios, bios, size); + release_firmware(fw); + return true; +} + static bool radeon_read_bios(struct radeon_device *rdev) { uint8_t __iomem *bios; @@ -401,6 +439,9 @@ r = radeon_read_bios(rdev); if (r == false) { r = radeon_read_disabled_bios(rdev); + if (r == false) { + r = radeon_read_bios_from_firmware(rdev); + } } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n");