Merge branch 'pci/mjg-rom' into for-linus
* pci/mjg-rom: radeon: Attempt to use platform-provided ROM image nouveau: Attempt to use platform-provided ROM image PCI: Add PCI ROM helper for platform-provided ROM images
This commit is contained in:
commit
a1259041e6
|
@ -248,6 +248,22 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_bios_shadow_platform(struct nouveau_bios *bios)
|
||||
{
|
||||
struct pci_dev *pdev = nv_device(bios)->pdev;
|
||||
size_t size;
|
||||
|
||||
void __iomem *rom = pci_platform_rom(pdev, &size);
|
||||
if (rom && size) {
|
||||
bios->data = kmalloc(size, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
memcpy_fromio(bios->data, rom, size);
|
||||
bios->size = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
|
||||
{
|
||||
|
@ -288,6 +304,7 @@ nouveau_bios_shadow(struct nouveau_bios *bios)
|
|||
{ "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
|
||||
{ "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
|
||||
{ "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
|
||||
{ "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL },
|
||||
{}
|
||||
};
|
||||
struct methods *mthd, *best;
|
||||
|
|
|
@ -99,6 +99,29 @@ static bool radeon_read_bios(struct radeon_device *rdev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool radeon_read_platform_bios(struct radeon_device *rdev)
|
||||
{
|
||||
uint8_t __iomem *bios;
|
||||
size_t size;
|
||||
|
||||
rdev->bios = NULL;
|
||||
|
||||
bios = pci_platform_rom(rdev->pdev, &size);
|
||||
if (!bios) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||
return false;
|
||||
}
|
||||
rdev->bios = kmemdup(bios, size, GFP_KERNEL);
|
||||
if (rdev->bios == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/* ATRM is used to get the BIOS on the discrete cards in
|
||||
* dual-gpu systems.
|
||||
|
@ -620,6 +643,9 @@ bool radeon_get_bios(struct radeon_device *rdev)
|
|||
if (r == false) {
|
||||
r = radeon_read_disabled_bios(rdev);
|
||||
}
|
||||
if (r == false) {
|
||||
r = radeon_read_platform_bios(rdev);
|
||||
}
|
||||
if (r == false || rdev->bios == NULL) {
|
||||
DRM_ERROR("Unable to locate a BIOS ROM\n");
|
||||
rdev->bios = NULL;
|
||||
|
|
|
@ -100,27 +100,6 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
|
|||
return min((size_t)(image - rom), size);
|
||||
}
|
||||
|
||||
static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
loff_t start;
|
||||
|
||||
/* assign the ROM an address if it doesn't have one */
|
||||
if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE))
|
||||
return 0;
|
||||
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
|
||||
if (*size == 0)
|
||||
return 0;
|
||||
|
||||
/* Enable ROM space decodes */
|
||||
if (pci_enable_rom(pdev))
|
||||
return 0;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_map_rom - map a PCI ROM to kernel space
|
||||
* @pdev: pointer to pci device struct
|
||||
|
@ -135,7 +114,7 @@ static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size)
|
|||
void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
loff_t start = 0;
|
||||
loff_t start;
|
||||
void __iomem *rom;
|
||||
|
||||
/*
|
||||
|
@ -154,21 +133,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
|||
return (void __iomem *)(unsigned long)
|
||||
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
} else {
|
||||
start = pci_find_rom(pdev, size);
|
||||
/* assign the ROM an address if it doesn't have one */
|
||||
if (res->parent == NULL &&
|
||||
pci_assign_resource(pdev,PCI_ROM_RESOURCE))
|
||||
return NULL;
|
||||
start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||
if (*size == 0)
|
||||
return NULL;
|
||||
|
||||
/* Enable ROM space decodes */
|
||||
if (pci_enable_rom(pdev))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some devices may provide ROMs via a source other than the BAR
|
||||
*/
|
||||
if (!start && pdev->rom && pdev->romlen) {
|
||||
*size = pdev->romlen;
|
||||
return phys_to_virt(pdev->rom);
|
||||
}
|
||||
|
||||
if (!start)
|
||||
return NULL;
|
||||
|
||||
rom = ioremap(start, *size);
|
||||
if (!rom) {
|
||||
/* restore enable if ioremap fails */
|
||||
|
@ -202,8 +181,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
|||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
||||
return;
|
||||
|
||||
if (!pdev->rom || !pdev->romlen)
|
||||
iounmap(rom);
|
||||
iounmap(rom);
|
||||
|
||||
/* Disable again before continuing, leave enabled if pci=rom */
|
||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
|
||||
|
@ -227,7 +205,24 @@ void pci_cleanup_rom(struct pci_dev *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_platform_rom - provides a pointer to any ROM image provided by the
|
||||
* platform
|
||||
* @pdev: pointer to pci device struct
|
||||
* @size: pointer to receive size of pci window over ROM
|
||||
*/
|
||||
void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size)
|
||||
{
|
||||
if (pdev->rom && pdev->romlen) {
|
||||
*size = pdev->romlen;
|
||||
return phys_to_virt((phys_addr_t)pdev->rom);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pci_map_rom);
|
||||
EXPORT_SYMBOL(pci_unmap_rom);
|
||||
EXPORT_SYMBOL_GPL(pci_enable_rom);
|
||||
EXPORT_SYMBOL_GPL(pci_disable_rom);
|
||||
EXPORT_SYMBOL(pci_platform_rom);
|
||||
|
|
|
@ -916,6 +916,7 @@ void pci_disable_rom(struct pci_dev *pdev);
|
|||
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
|
||||
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
|
||||
size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
|
||||
void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size);
|
||||
|
||||
/* Power management related routines */
|
||||
int pci_save_state(struct pci_dev *dev);
|
||||
|
|
Loading…
Reference in New Issue