Hi
Am 26.08.26 um 19:30 schrieb Christian Zigotzky:
On 26 August 2026 at 05:23 pm, Thomas Zimmermann <[email protected]> wrote:
Hi
Could be that we have to enable access to the ROM first. That's why it returns
only 0xffff. Does the card display output when you switch on the computer?
Best regards
Thomas
- - -
Hello Thomas,
No, the card doesn’t display output when I switch on the computer.
Attached you'll find another patch that also enables ROM access in the
PCI config options. I took the code out of the old matroxfb driver
without further testing. Please try and report back on the results.
Best regards
Thomas
Cheers,
Christian
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, (HRB 36809, AG Nürnberg)
From 101ee2c18a64101978091006b797a7c327d295ff Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann <[email protected]>
Date: Wed, 26 Aug 2026 11:03:11 +0200
Subject: [PATCH] [v2] mgag200: go looking for PInS in the video BIOS ROM on
non-x86
---
drivers/gpu/drm/mgag200/mgag200_g200.c | 38 ++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c
index 9e6b4618fadd..57f87dfd26ec 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -239,7 +239,7 @@ static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
};
struct mga_device *mdev = &g200->base;
struct drm_device *dev = &mdev->base;
- const unsigned char *pins;
+ const unsigned char *pins = NULL;
unsigned int pins_len, version;
int offset;
int tmp;
@@ -250,16 +250,34 @@ static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
return;
+#if defined(CONFIG_X86)
/* Get the PInS offset. */
if (size < MGA_BIOS_OFFSET + 2)
return;
offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
+ if (size < offset + 6)
+ return;
/* Get PInS data structure. */
+ pins = bios + offset;
+#else
+ /*
+ * On OpenFirmware systems (PPC, MIPS, SPARC) the offset isn't stored
+ * at the end of the BIOS image. Look for the PInS header instead.
+ */
+ for (offset = 0 ; offset < size - 6; ++offset) {
+ const unsigned char *buf = bios + offset;
+
+ if (buf[0] == 0x2e && buf[1] == 0x41 && ((buf[2] == 64) || (buf[2] == 128))) {
+ pins = buf;
+ break;
+ }
+ }
- if (size < offset + 6)
+ if (!pins)
return;
- pins = bios + offset;
+#endif
+
if (pins[0] == 0x2e && pins[1] == 0x41) {
version = pins[5];
pins_len = pins[2];
@@ -320,6 +338,8 @@ static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200,
}
}
+#define PCI_MGA_OPTION_BIOSEN 0x40000000
+
static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200)
{
struct mga_device *mdev = &g200->base;
@@ -328,11 +348,20 @@ static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200)
unsigned char __iomem *rom;
unsigned char *bios;
size_t size;
+ u32 opt;
+ u32 biosbase;
+ u32 fbbase;
g200->pclk_min = 50000;
g200->pclk_max = 230000;
g200->ref_clk = 27050;
+ pci_read_config_dword(pdev, PCI_MGA_OPTION, &opt);
+ pci_write_config_dword(pdev, PCI_MGA_OPTION, opt | PCI_MGA_OPTION_BIOSEN);
+ pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &biosbase);
+ pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &fbbase);
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS, (fbbase & PCI_ROM_ADDRESS_MASK) | PCI_ROM_ADDRESS_ENABLE);
+
rom = pci_map_rom(pdev, &size);
if (!rom)
return;
@@ -351,6 +380,9 @@ static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200)
vfree(bios);
out:
pci_unmap_rom(pdev, rom);
+
+ pci_write_config_dword(pdev, PCI_ROM_ADDRESS, biosbase);
+ pci_write_config_dword(pdev, PCI_MGA_OPTION, opt);
}
static const struct mgag200_device_funcs mgag200_g200_device_funcs = {
--
2.55.0