From 28c1d44af69705936f00826e0b60fb6aec95f008 Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Fri, 31 Jul 2026 21:19:11 +0900 Subject: [PATCH] fbdev: tdfxfb: Attempt to detect if the card wasn't booted Until now a card had to have been booted by its video BIOS otherwise the driver would probe, create the fb etc but there would be no output on the display. There doesn't seem to be a documented way work out if the BIOS ran or not. Checking if the values in registers match what is in the config table in the BIOS seems to be the only option. On my 16MB Voodoo 3 3000 checking the contents of the draminit0 register versus what is in the config table seems to be enough. Signed-off-by: Daniel Palmer Signed-off-by: Helge Deller --- drivers/video/fbdev/tdfxfb.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index fad365c00628..913624ebf805 100644 --- a/drivers/video/fbdev/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -414,6 +414,34 @@ static bool tdfxfb_get_bios_cfg(struct pci_dev *pdev, return false; } +/* + * 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. + */ +static int tdfxfb_hw_init(struct fb_info *info, struct pci_dev *pdev) +{ + struct tdfx_par *par = info->par; + struct tdfx_bios_cfg cfg; + bool have_cfg = tdfxfb_get_bios_cfg(pdev, &cfg); + + /* + * Can't tell if the card is booted or not, + * also cannot boot it. Card might not function. + */ + if (!have_cfg) + return 0; + + /* Card is, probably, already configured. */ + if (tdfx_inl(par, DRAMINIT0) == le32_to_cpu(cfg.draminit0)) + return 0; + + dev_err(&pdev->dev, + "Card hasn't booted and is unusable\n"); + + return -ENODEV; +} + static void do_write_regs(struct fb_info *info, struct banshee_reg *reg) { struct tdfx_par *par = info->par; @@ -1509,6 +1537,9 @@ static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_err_regbase; } + if (tdfxfb_hw_init(info, pdev)) + goto out_err_regbase; + info->fix.smem_start = pci_resource_start(pdev, 1); info->fix.smem_len = do_lfb_size(default_par, pdev->device); if (!info->fix.smem_len) {