summaryrefslogtreecommitdiff
path: root/src/smi_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/smi_driver.c')
-rw-r--r--src/smi_driver.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/smi_driver.c b/src/smi_driver.c
index 7219612..c0e72e4 100644
--- a/src/smi_driver.c
+++ b/src/smi_driver.c
@@ -1423,6 +1423,55 @@ SMI_MapMmio(ScrnInfoPtr pScrn)
return (TRUE);
}
+/* HACK - In some cases the BIOS hasn't filled in the "scratchpad
+ registers" (SR71) with the right amount of memory installed (e.g. MIPS
+ platform). Probe it manually. */
+static unsigned long
+SMI_ProbeMem(ScrnInfoPtr pScrn, unsigned long mem_skip, unsigned long mem_max)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+ unsigned long mem_probe = 1024*1024;
+ unsigned long aperture_base;
+ void* mem;
+
+ ENTER();
+
+ aperture_base = PCI_REGION_BASE(pSmi->PciInfo, 0, REGION_MEM) + mem_skip;
+ mem_max = min(mem_max , PCI_REGION_SIZE(pSmi->PciInfo, 0) - mem_skip);
+
+#ifndef XSERVER_LIBPCIACCESS
+ mem = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pSmi->PciTag,
+ aperture_base, mem_max);
+
+ if(!mem)
+ LEAVE(0);
+#else
+ if(pci_device_map_range(pSmi->PciInfo, aperture_base, mem_max,
+ PCI_DEV_MAP_FLAG_WRITABLE, &mem))
+ LEAVE(0);
+#endif
+
+ while(mem_probe <= mem_max){
+ MMIO_OUT32(mem, mem_probe-4, 0x55555555);
+ if(MMIO_IN32(mem, mem_probe-4) != 0x55555555)
+ break;
+
+ MMIO_OUT32(mem, mem_probe-4, 0xAAAAAAAA);
+ if(MMIO_IN32(mem, mem_probe-4) != 0xAAAAAAAA)
+ break;
+
+ mem_probe <<= 1;
+ }
+
+#ifndef XSERVER_LIBPCIACCESS
+ xf86UnMapVidMem(pScrn->scrnIndex, mem, mem_max);
+#else
+ pci_device_unmap_range(pSmi->PciInfo, mem, mem_max);
+#endif
+
+ LEAVE(mem_probe >> 1);
+}
+
static Bool
SMI_DetectMem(ScrnInfoPtr pScrn)
{
@@ -1452,6 +1501,9 @@ SMI_DetectMem(ScrnInfoPtr pScrn)
pSmi->videoRAMKBytes = lynx3d_table[config >> 6] * 1024 +
512;
break;
+ case SMI_LYNXEMplus:
+ pSmi->videoRAMKBytes = SMI_ProbeMem(pScrn, 0, 0x400000) / 1024;
+ break;
case SMI_LYNX3DM:
pSmi->videoRAMKBytes = lynx3dm_table[config >> 6] * 1024;
break;