summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i810_reg.h5
-rw-r--r--src/i830_driver.c34
2 files changed, 35 insertions, 4 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 53a063fc..9c6e0dd2 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -499,6 +499,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PGETBL_ADDR_MASK 0xFFFFF000
#define PGETBL_ENABLE_MASK 0x00000001
#define PGETBL_ENABLED 0x00000001
+/** Added in 965G, this field has the actual size of the global GTT */
+#define PGETBL_SIZE_MASK 0x0000000e
+#define PGETBL_SIZE_512KB (0 << 1)
+#define PGETBL_SIZE_256KB (1 << 1)
+#define PGETBL_SIZE_128KB (2 << 1)
/* Register containing pge table error results, p276
*/
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 39ffa542..55610f5e 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -394,7 +394,7 @@ I830DetectMemory(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
PCITAG bridge;
CARD16 gmch_ctrl;
- int memsize = 0;
+ int memsize = 0, gtt_size;
int range;
#if 0
VbeInfoBlock *vbeInfo;
@@ -403,9 +403,35 @@ I830DetectMemory(ScrnInfoPtr pScrn)
bridge = pciTag(0, 0, 0); /* This is always the host bridge */
gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);
- /* We need to reduce the stolen size, by the GTT and the popup.
- * The GTT varying according the the FbMapSize and the popup is 4KB */
- range = (pI830->FbMapSize / (1024*1024)) + 4;
+ if (IS_I965G(pI830)) {
+ /* The 965 may have a GTT that is actually larger than is necessary
+ * to cover the aperture, so check the hardware's reporting of the
+ * GTT size.
+ */
+ switch (INREG(PGETBL_CTL) & PGETBL_SIZE_MASK) {
+ case PGETBL_SIZE_512KB:
+ gtt_size = 512;
+ break;
+ case PGETBL_SIZE_256KB:
+ gtt_size = 256;
+ break;
+ case PGETBL_SIZE_128KB:
+ gtt_size = 128;
+ break;
+ default:
+ FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL));
+ }
+ } else {
+ /* Older chipsets only had GTT appropriately sized for the aperture. */
+ gtt_size = pI830->FbMapSize / (1024*1024);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "detected %d kB GTT.\n", gtt_size);
+
+ /* The stolen memory has the GTT at the top, and the 4KB popup below that.
+ * Everything else can be freely used by the graphics driver.
+ */
+ range = gtt_size + 4;
if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {