diff options
author | eiichiro.oiwa.nm@hitachi.com <eiichiro.oiwa.nm@hitachi.com> | 2006-09-28 13:55:47 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-10-18 11:36:11 -0700 |
commit | b5e4efe7e061ff52ac97b9fa45acca529d8daeea (patch) | |
tree | 39937f2f6c50525abc0111dca1de91030568e6d5 /drivers/pci | |
parent | bacedce32b171cd461a7da3160ad794e2240c67a (diff) | |
download | linux-3.10-b5e4efe7e061ff52ac97b9fa45acca529d8daeea.tar.gz linux-3.10-b5e4efe7e061ff52ac97b9fa45acca529d8daeea.tar.bz2 linux-3.10-b5e4efe7e061ff52ac97b9fa45acca529d8daeea.zip |
PCI: Turn pci_fixup_video into generic for embedded VGA
pci_fixup_video turns into generic code because there are many platforms need this fixup
for embedded VGA as well as x86. The Video BIOS integrates into System BIOS on a machine
has embedded VGA although embedded VGA generally don't have PCI ROM. As a result,
embedded VGA need the way that the sysfs rom points to the Video BIOS of System
RAM (0xC0000). PCI-to-PCI Bridge Architecture specification describes the condition whether
or not PCI ROM forwards VGA compatible memory address. fixup_video suits this specification.
Although the Video ROM generally implements in x86 code regardless of platform, some
application such as X Window System can run this code by dosemu86. Therefore,
pci_fixup_video should turn into generic code.
Signed-off-by: Eiichiro Oiwa <eiichiro.oiwa.nm@hitachi.com>
Acked-by: Alan Cox <alan@redhat.com>
Acked-by: Jesse Barnes <jesse.barnes@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/quirks.c | 45 | ||||
-rw-r--r-- | drivers/pci/rom.c | 5 |
2 files changed, 49 insertions, 1 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1d2ccda946f..371ab8821f1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1619,6 +1619,51 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); +/* + * Fixup to mark boot BIOS video selected by BIOS before it changes + * + * From information provided by "Jon Smirl" <jonsmirl@gmail.com> + * + * The standard boot ROM sequence for an x86 machine uses the BIOS + * to select an initial video card for boot display. This boot video + * card will have it's BIOS copied to C0000 in system RAM. + * IORESOURCE_ROM_SHADOW is used to associate the boot video + * card with this copy. On laptops this copy has to be used since + * the main ROM may be compressed or combined with another image. + * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW + * is marked here since the boot video device will be the only enabled + * video device at this point. + */ + +static void __devinit fixup_video(struct pci_dev *pdev) +{ + struct pci_dev *bridge; + struct pci_bus *bus; + u16 config; + + if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) + return; + + /* Is VGA routed to us? */ + bus = pdev->bus; + while (bus) { + bridge = bus->self; + if (bridge) { + pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, + &config); + if (!(config & PCI_BRIDGE_CTL_VGA)) + return; + } + bus = bus->parent; + } + pci_read_config_word(pdev, PCI_COMMAND, &config); + if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; + printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video); + static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index f5ee7ce16fa..43e4a49f2cc 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -71,7 +71,10 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) void __iomem *image; int last_image; - /* IORESOURCE_ROM_SHADOW only set on x86 */ + /* + * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control + * register is set for embedded VGA. + */ if (res->flags & IORESOURCE_ROM_SHADOW) { /* primary video rom always starts here */ start = (loff_t)0xC0000; |