summaryrefslogtreecommitdiff
path: root/src/smi_driver.c
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2009-05-05 00:44:17 +0200
committerFrancisco Jerez <currojerez@riseup.net>2009-05-05 00:48:12 +0200
commit32628d9884d577d7a672c172c12b7097be276700 (patch)
tree93680f2995c5da9043799e50116b9bc30200b79c /src/smi_driver.c
parent00921b014fa0b5358c22a769cf2450cbd4bdc8a5 (diff)
Probe the amount of installed memory by trial and error on SM712.
In some cases the BIOS hasn't filled in the "scratchpad registers" (SR71) with the right amount of memory installed (e.g. MIPS platform). There seems to be no other way to do it than to test it. This should fix bug 21528.
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;