aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2010-06-08 16:11:32 -0400
committerMatt Turner <mattst88@gmail.com>2010-08-13 19:49:20 -0400
commit1a8d33433c7663ffd52d8cbaa188dc7527e30a3a (patch)
tree546514d086668776b3758be1211c4e788aa9adae
parent200c2c410f4ef592173e645ad448739ccaedc32b (diff)
downloadglint-1a8d33433c7663ffd52d8cbaa188dc7527e30a3a.tar.gz
drm/glint: detect VRAM size
Signed-off-by: Matt Turner <mattst88@gmail.com>
-rw-r--r--drivers/gpu/drm/glint/glint.h8
-rw-r--r--drivers/gpu/drm/glint/glint_device.c72
-rw-r--r--drivers/gpu/drm/glint/glint_drv.h6
3 files changed, 86 insertions, 0 deletions
diff --git a/drivers/gpu/drm/glint/glint.h b/drivers/gpu/drm/glint/glint.h
index 9c0a5967b3b1c6..51c8f2c7a0d15a 100644
--- a/drivers/gpu/drm/glint/glint.h
+++ b/drivers/gpu/drm/glint/glint.h
@@ -3,6 +3,12 @@
#include "glint_family.h"
+struct glint_mc {
+ resource_size_t aper_size;
+ resource_size_t aper_base;
+ u32 vram_size;
+};
+
struct glint_device {
struct device *dev;
struct drm_device *ddev;
@@ -13,6 +19,8 @@ struct glint_device {
resource_size_t rmmio_base;
resource_size_t rmmio_size;
void *rmmio;
+
+ struct glint_mc mc;
};
#endif /* __GLINT_H__ */
diff --git a/drivers/gpu/drm/glint/glint_device.c b/drivers/gpu/drm/glint/glint_device.c
index 51163f9808742f..2cf207a9f7601f 100644
--- a/drivers/gpu/drm/glint/glint_device.c
+++ b/drivers/gpu/drm/glint/glint_device.c
@@ -4,6 +4,76 @@
#include "glint.h"
#include "glint_drv.h"
+#include <video/pm3fb.h>
+
+static u32 glint_vram_init_size(struct glint_device *gdev)
+{
+ char __iomem *vram;
+ unsigned i;
+ u32 tempBypass = RREG32(PM3MemBypassWriteMask);
+ u32 temp1, temp2;
+ u32 memsize = 0;
+
+ /* work out accessible VRAM */
+ gdev->mc.aper_base = pci_resource_start(gdev->ddev->pdev, 1);
+ gdev->mc.aper_size = pci_resource_len(gdev->ddev->pdev, 1);
+
+ vram = ioremap(gdev->mc.aper_base, gdev->mc.aper_size);
+ if (!vram) {
+ GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Retrying...\n", (unsigned long)gdev->mc.aper_size / MB);
+ gdev->mc.aper_size /= 2;
+ ioremap(gdev->mc.aper_base, gdev->mc.aper_size);
+ if (!vram) {
+ GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Bailing out.\n", (unsigned long)gdev->mc.aper_size / MB);
+ return 0;
+ }
+ GLINT_INFO("ioremapped %lu MB of VRAM.\n", (unsigned long)gdev->mc.aper_size / MB);
+ }
+
+ WREG32(PM3MemBypassWriteMask, 0xffffffff);
+
+#define TEST_PATTERN 0x00345678
+ for (i = 0; i < 32; i++) {
+ iowrite32(i * TEST_PATTERN, vram + (i * MB));
+ mb();
+ temp1 = ioread32(vram + (i * MB));
+
+ /* Let's check for wrapover, write will fail at 16MB boundary */
+ if (temp1 == (i * TEST_PATTERN))
+ memsize = i;
+ else
+ break;
+ }
+ GLINT_INFO("First pass detected %u MB of VRAM\n", memsize + 1);
+
+ if (memsize + 1 == i) {
+ for (i = 0; i < 32; i++) {
+ /* Clear first 4 bytes of each of the first 32MB */
+ iowrite32(0, vram + (i * MB));
+ }
+ wmb();
+
+ for (i = 32; i < 64; i++) {
+ iowrite32(i * TEST_PATTERN, vram + (i * MB));
+ mb();
+ temp1 = ioread32(vram + (i * MB));
+ temp2 = ioread32(vram + ((i - 32) * MB));
+
+ /* different value, different RAM... */
+ if ((temp1 == (i * TEST_PATTERN)) && (temp2 == 0))
+ memsize = i;
+ else
+ break;
+ }
+ }
+ GLINT_INFO("Second pass detected %u MB of VRAM\n", memsize + 1);
+
+ WREG32(PM3MemBypassWriteMask, tempBypass);
+ iounmap(vram);
+
+ return (memsize + 1) * MB;
+}
+
int glint_device_init(struct glint_device *gdev,
struct drm_device *ddev,
struct pci_dev *pdev,
@@ -32,6 +102,8 @@ int glint_device_init(struct glint_device *gdev,
GLINT_INFO("register mmio base: 0x%08X\n", (uint32_t)gdev->rmmio_base);
GLINT_INFO("register mmio size: %u\n", (unsigned)gdev->rmmio_size);
+ gdev->mc.vram_size = glint_vram_init_size(gdev);
+
return 0;
}
diff --git a/drivers/gpu/drm/glint/glint_drv.h b/drivers/gpu/drm/glint/glint_drv.h
index 58fedbcd8c3ed8..b3f7d5501553d0 100644
--- a/drivers/gpu/drm/glint/glint_drv.h
+++ b/drivers/gpu/drm/glint/glint_drv.h
@@ -12,6 +12,12 @@
#define DRIVER_PATCHLEVEL 0
#define GLINT_INFO(fmt, arg...) DRM_INFO(DRIVER_NAME ": " fmt, ##arg)
+#define GLINT_ERROR(fmt, arg...) DRM_ERROR(DRIVER_NAME ": " fmt, ##arg)
+
+#define RREG32(reg) ioread32(((void __iomem *)gdev->rmmio) + (reg))
+#define WREG32(reg, v) iowrite32(v, ((void __iomem *)gdev->rmmio) + (reg))
+
+#define MB (1024 * 1024)
#include "glint.h"