Re: uninitialized PCI VGA cards and matroxfb

Petr Vandrovec Ing. VTEI (VANDROVE@vc.cvut.cz)
Thu, 17 Jun 1999 12:33:43 MET-1


Hi Dave,
> I'm trying to setup my my dual head (TNT2 and Matrox Millennium II) using
> Linux's Framebuffer subsystem. I specifically want X on the primary video
> card (TNT2/vesafb) and a plain text console on the matroxfb.
It should work...
> While trying to enable this setup, I found that my BIOS doesn't initialize
> the secondary video card. This caused the matroxfb to crash when it tried
> to access the Millennium II's framebuffer/registers.
I hope that it only complaints 'matroxfb: cannot ioremap...' without oopsing.
> After playing with the kernel, I could enable the memory for the secondary
> video card with this piece of code from arch/i386/kernel/bios32.c ("dev"
> is the secondary VGA card in question):
It is guarded by (class != VGA) && (class != IDE) because of devices of
these classes use hardwired I/O port under normal conditions.
matroxfb enables I/O and MMIO itself after correctly configuring rest of
hardware (disabling VGA I/O ports).
> And this function would enable the secondary video card's bus mastering
> capability:
> pci_set_master(dev);
I do not think that Millennium II is busmaster capable.
> It's IRQ is 0, and it's three base_address registers appear to be
> suspiciously incorrect:
> Memory at ff000000 (32-bit, prefetchable)
> Memory at ffffc000 (32-bit, non-prefetchable)
> Memory at ff800000 (32-bit, non-prefetchable)
Yes, no-one initialized them.
> I'm currently trying to figure out what to do next. Working inside the
> kernel is rather new to me, and I don't know way around the PCI subsystem
> either. So if I made a mistake, or you think I'm doing something wrong,
> please enlighten me.
You are OK. Throw your BIOS away. BIOS MUST assign addresses to all
devices in the box. It MUST NOT enable secondary video adapters, but
must assign addresses to them.
> In short, any assistance would be greatly appreciated! :-)
> 00:13.0 VGA compatible controller: Matrox Graphics, Inc. MGA 2164W [Millennium II]
> Subsystem: Unknown device 102b:1000
> Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
> Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> Interrupt: pin A routed to IRQ 0
> Region 0: Memory at ff000000 (32-bit, prefetchable) [disabled]
> Region 1: Memory at ffffc000 (32-bit, non-prefetchable) [disabled]
> Region 2: Memory at ff800000 (32-bit, non-prefetchable) [disabled]
It is unfortunate, that you did not send full output, so I do not know, which
regions are unused... Go to file linux/arch/i386/kernel/bios32.c before
function pcibios_fixup_io_addr and add here (code untested...):

/* cut... */
static void __init pcibios_fixup_mem_addr(struct pci_dev* dev, int idx) {
static unsigned int base = 0x88000000; /* should be free */
unsigned int reg = PCI_BASE_ADDRESS0 + 4*idx;
unsigned int bus = dev->bus->number;
unsigned int devfn = dev->devfn;
unsigned short cmd;
unsigned int size, addr, try;

if ((bus != 0) || (devfn != 0x98)) return; /* not 00:13.0 */
if (idx > 2) return; /* only base0,1,2 */
pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY);
pcibios_write_config_dword(bus, devfn, reg, ~0);
pcibios_read_config_dword(bus, devfn, reg, &size);
size = (~(size & ~15)) + 1;
base = (base + (size - 1)) & ~size;
/* I hope that bottom four bits are read only */
pcibios_write_config_dword(bus, devfn, reg, base);
printk(KERN_INFO "PCI: MMIO %02x:%02x [%d] relocated at %08X\n",
bus, devfn, idx, base);
base += size;
pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
}
/* & paste... */

and then search for call to 'pcibios_fixup_io_addr(drv, i);' :

\Begin
pcibios_fixup_io_addr(dev, i);
- } else if (a & PCI_BASE_ADDRESS_MEM_MASK)
+ } else if (a & PCI_BASE_ADDRESS_MEM_MASK) {
has_mem = 1;
+ pcibios_fixup_mem_addr(dev, i);
+ }
}
/*
\End

Maybe it helps you... But you should bug your motherboard/BIOS author
for fix. BTW, if someone before matroxfb enables I/O and/or MMIO on
Matrox, you must add 'video=matrox:init' parameter to kernel command-line,
otherwise matroxfb thinks that VGA BIOS initialized Matrox properly.
Best regards,
Petr Vandrovec
vandrove@vc.cvut.cz

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/