gxfb/lxfb: detect framebuffer size using an MSR if VSA2 isn't available
authorAndres Salomon <dilinger@queued.net>
Mon, 28 Apr 2008 09:15:30 +0000 (02:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Apr 2008 15:58:40 +0000 (08:58 -0700)
If there's no VSA2 (ie, if we're using tinybios or OpenFirmware), use the
GLIU's P2D Range Offset Descriptor to determine how much memory we have
available for the framebuffer.

Originally based on a patch by Jordan Crouse.  Tested with OpenFirmware;
Pascal informs me that tinybios has a stub that fills in P2D_RO0.

Signed-off-by: Andres Salomon <dilinger@debian.org>
Cc: Jordan Crouse <jordan.crouse@amd.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/video/geode/display_gx.c
drivers/video/geode/lxfb_ops.c
include/asm-x86/geode.h

index 1e82ecc..e759895 100644 (file)
@@ -25,7 +25,23 @@ unsigned int gx_frame_buffer_size(void)
 {
        unsigned int val;
 
-       /* FB size is reported by a virtual register */
+       if (!geode_has_vsa2()) {
+               uint32_t hi, lo;
+
+               /* The number of pages is (PMAX - PMIN)+1 */
+               rdmsr(MSR_GLIU_P2D_RO0, lo, hi);
+
+               /* PMAX */
+               val = ((hi & 0xff) << 12) | ((lo & 0xfff00000) >> 20);
+               /* PMIN */
+               val -= (lo & 0x000fffff);
+               val += 1;
+
+               /* The page size is 4k */
+               return (val << 12);
+       }
+
+       /* FB size can be obtained from the VSA II */
        /* Virtual register class = 0x02 */
        /* VG_MEM_SIZE(512Kb units) = 0x00 */
 
index e42e124..cd9d4cc 100644 (file)
@@ -329,6 +329,22 @@ unsigned int lx_framebuffer_size(void)
 {
        unsigned int val;
 
+       if (!geode_has_vsa2()) {
+               uint32_t hi, lo;
+
+               /* The number of pages is (PMAX - PMIN)+1 */
+               rdmsr(MSR_GLIU_P2D_RO0, lo, hi);
+
+               /* PMAX */
+               val = ((hi & 0xff) << 12) | ((lo & 0xfff00000) >> 20);
+               /* PMIN */
+               val -= (lo & 0x000fffff);
+               val += 1;
+
+               /* The page size is 4k */
+               return (val << 12);
+       }
+
        /* The frame buffer size is reported by a VSM in VSA II */
        /* Virtual Register Class    = 0x02                     */
        /* VG_MEM_SIZE (1MB units)   = 0x00                     */
index 4fb2f62..7154dc4 100644 (file)
@@ -30,6 +30,8 @@ extern int geode_get_dev_base(unsigned int dev);
 
 /* MSRS */
 
+#define MSR_GLIU_P2D_RO0       0x10000029
+
 #define MSR_LX_GLD_MSR_CONFIG  0x48002001
 #define MSR_LX_MSR_PADSEL      0x48002011      /* NOT 0x48000011; the data
                                                 * sheet has the wrong value */