diff options
author | Matt Turner <mattst88@gmail.com> | 2010-06-08 16:11:32 -0400 |
---|---|---|
committer | Matt Turner <mattst88@gmail.com> | 2010-08-13 19:49:20 -0400 |
commit | 1a8d33433c7663ffd52d8cbaa188dc7527e30a3a (patch) | |
tree | 546514d086668776b3758be1211c4e788aa9adae | |
parent | 200c2c410f4ef592173e645ad448739ccaedc32b (diff) | |
download | glint-1a8d33433c7663ffd52d8cbaa188dc7527e30a3a.tar.gz |
drm/glint: detect VRAM size
Signed-off-by: Matt Turner <mattst88@gmail.com>
-rw-r--r-- | drivers/gpu/drm/glint/glint.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/glint/glint_device.c | 72 | ||||
-rw-r--r-- | drivers/gpu/drm/glint/glint_drv.h | 6 |
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" |