I'm attaching a patch which does fix some of the problems with 3Dfx video boards on big endian systems (like PowerPC). First, it introduces setting bit 20 ("Host byte word swizzle", from the Voodoo3 register docs) in the srcFormat register setting, for the do_putc() and do_putcs() accelerated text operations, making accelerated text mode work properly. Second, it enables PCI resource BAR #2 (the IO port range) for the 3Dfx video board, making video mode switching work correctly. I may just go ahead and remove the register writes for that though, since according to the register docs, writing to the same offset in the register memory range for the 3Dfx does the same thing, plus it removes the issue of IO port accesses on a non-primary PCI bus (where its port IO register window is not at 0).
-- Derrik Pates [EMAIL PROTECTED] [EMAIL PROTECTED]
--- /usr/src/linux/drivers/video/tdfxfb.c 2002-02-25 14:38:07.000000000 -0500 +++ tdfxfb.c 2002-12-14 09:52:08.000000000 -0500 @@ -762,7 +762,12 @@ tdfx_outl(SRCXY, 0); tdfx_outl(DSTXY, xx | (yy << 16)); tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (ROP_COPY << 24)); +#if defined(__BIG_ENDIAN__) + /* Add the bit to automatically reorder bytes on BE systems. -- dpates */ + tdfx_outl(SRCFORMAT, 0x400000 | 0x100000); +#elif defined(__LITTLE_ENDIAN__) tdfx_outl(SRCFORMAT, 0x400000); +#endif tdfx_outl(DSTFORMAT, fmt); tdfx_outl(DSTSIZE, fontwidth(p) | (fontheight(p) << 16)); i=fontheight(p); @@ -820,7 +825,12 @@ tdfx_outl(COMMAND_3D, COMMAND_3D_NOP); tdfx_outl(COLORFORE, fgx); tdfx_outl(COLORBACK, bgx); +#if defined(__BIG_ENDIAN__) + /* Add the bit to automatically reorder bytes for BE systems. -- dpates */ + tdfx_outl(SRCFORMAT, 0x400000 | 0x100000); +#elif defined(__LITTLE_ENDIAN__) tdfx_outl(SRCFORMAT, 0x400000); +#endif tdfx_outl(DSTFORMAT, fmt); tdfx_outl(DSTSIZE, w | (h << 16)); tdfx_outl(SRCXY, 0); @@ -1951,6 +1976,10 @@ return -ENXIO; } + /* make sure PCI resource 2 (IO port range) is turned on. of course, if + * this is on a secondary PCI bus (where the IO range isn't at the + * global 0-offset point), things _will_ break. */ + pci_enable_device_bars (pdev, 1<<2); fb_info.iobase = pci_resource_start (pdev, 2); printk("fb: %s memory = %ldK\n", name, fb_info.bufbase_size >> 10);