diff options
| author | Daniel Palmer <daniel@0x0f.com> | 2026-07-31 21:19:12 +0900 |
|---|---|---|
| committer | Helge Deller <deller@gmx.de> | 2026-08-10 08:13:26 +0200 |
| commit | 08364e38dec37cb77ccc873e897c69d23b33c3e5 (patch) | |
| tree | a3992c126d59bb990b5471569209b43cb2908045 | |
| parent | 28c1d44af69705936f00826e0b60fb6aec95f008 (diff) | |
| download | linux-next-08364e38dec37cb77ccc873e897c69d23b33c3e5.tar.gz linux-next-08364e38dec37cb77ccc873e897c69d23b33c3e5.zip | |
fbdev: tdfxfb: Manually boot unbooted cards
If the card is detected as being unbooted it isn't too difficult
to use the config table in its BIOS to fire it up so do it.
Signed-off-by: Daniel Palmer <daniel@0x0f.com>
Signed-off-by: Helge Deller <deller@gmx.de>
| -rw-r--r-- | drivers/video/fbdev/tdfxfb.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index 913624ebf805..74a8dfef1d9d 100644 --- a/drivers/video/fbdev/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -67,6 +67,7 @@ #include <linux/aperture.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/delay.h> #include <linux/errno.h> #include <linux/string.h> #include <linux/mm.h> @@ -418,9 +419,13 @@ out: * Try to work out if the card was booted or not, just checks if * one of the dram config registers matches what is in the config * table if there is one. + * + * If we have a BIOS config table attempt to manually boot the + * card if needed. */ static int tdfxfb_hw_init(struct fb_info *info, struct pci_dev *pdev) { + u32 mempll, gfxpll, draminit0, draminit1, miscinit1, dram_mode; struct tdfx_par *par = info->par; struct tdfx_bios_cfg cfg; bool have_cfg = tdfxfb_get_bios_cfg(pdev, &cfg); @@ -436,10 +441,39 @@ static int tdfxfb_hw_init(struct fb_info *info, struct pci_dev *pdev) if (tdfx_inl(par, DRAMINIT0) == le32_to_cpu(cfg.draminit0)) return 0; - dev_err(&pdev->dev, - "Card hasn't booted and is unusable\n"); + dev_info(&pdev->dev, + "Manually booting card using config table\n"); + + mempll = le32_to_cpu(cfg.pllctrl1); + gfxpll = le32_to_cpu(cfg.pllctrl2); + draminit0 = le32_to_cpu(cfg.draminit0); + draminit1 = le32_to_cpu(cfg.draminit1); + miscinit1 = le32_to_cpu(cfg.miscinit1); + dram_mode = le32_to_cpu(cfg.sgrammode); + tdfx_outl(par, PCIINIT0, le32_to_cpu(cfg.pciinit0)); + tdfx_outl(par, AGPINIT, le32_to_cpu(cfg.agpinit0)); + + /* memory clock, and the graphics clock if the card wants one */ + tdfx_outl(par, PLLCTRL1, mempll); + if (gfxpll) + tdfx_outl(par, PLLCTRL2, gfxpll); + /* flush posted writes */ + tdfx_inl(par, PLLCTRL1); + /* PLL lock */ + udelay(100); + + tdfx_outl(par, MISCINIT1, miscinit1); + tdfx_outl(par, DRAMINIT0, draminit0); + tdfx_outl(par, DRAMINIT1, draminit1); + + /* SDRAM/SGRAM wake up: load the mode register */ + tdfx_outl(par, DRAMDATA, dram_mode); + tdfx_outl(par, DRAMCOMMAND, 0x10d); + + tdfx_outl(par, LFBMEMORYCONFIG, 0x00001fff); + tdfx_outl(par, MISCINIT0, le32_to_cpu(cfg.miscinit0)); - return -ENODEV; + return 0; } static void do_write_regs(struct fb_info *info, struct banshee_reg *reg) |
