[PATCH] Detect if the OLPC DCON was detected by the BIOS

Jordan Crouse jordan.crouse at amd.com
Tue Nov 7 22:37:11 EST 2006


Commit:     21330ae883083e08be81fe4732d969d9eb5e97e9
Parent:     bfdb29ee13d7caa4424914e215b2fcaac5caec99
commit 21330ae883083e08be81fe4732d969d9eb5e97e9
Author:     Jordan Crouse <jordan.crouse at amd.com>
AuthorDate: Mon Sep 18 10:38:21 2006 -0600
Commit:     Jordan Crouse <jordan.crouse at amd.com>
CommitDate: Tue Oct 3 13:48:10 2006 -0600

    [PATCH] Detect if the OLPC DCON was detected by the BIOS
    
    If the OLPC DCON is present, then we'll adjust the mode database
    accordingly (since there is really only 1 mode available anyway).
    
    Signed-off-by: Jordan Crouse <jordan.crouse at amd.com>
---
 arch/i386/Kconfig               |    7 +++++++
 arch/i386/kernel/Makefile       |    1 +
 arch/i386/kernel/olpc.c         |   38 ++++++++++++++++++++++++++++++++++++++
 drivers/video/geode/gxfb_core.c |   37 ++++++++++++++++++++++++++++++++++---
 drivers/video/modedb.c          |    4 +++-
 5 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index d8935d9..c3035dd 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1113,6 +1113,13 @@ config K8_NB
 	def_bool y
 	depends on AGP_AMD64
 
+config OLPC
+	bool "OLPC Support"
+	default n
+	help
+	  Add support for detecting the unique features of the OLPC 
+	  Childrens Machine
+	  
 source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 1b452a1..fafdea4 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_AUDIT)		+= audit.o
 EXTRA_AFLAGS   := -traditional
 
 obj-$(CONFIG_SCx200)		+= scx200.o
+obj-$(CONFIG_OLPC)		+= olpc.o
 
 # vsyscall.o contains the vsyscall DSO images as __initdata.
 # We must build both images before we can assemble it.
diff --git a/arch/i386/kernel/olpc.c b/arch/i386/kernel/olpc.c
new file mode 100644
index 0000000..ffa4823
--- /dev/null
+++ b/arch/i386/kernel/olpc.c
@@ -0,0 +1,38 @@
+/* Support for the OLPC Childrens Machine
+ * Copyright (C) 2006, Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+
+int olpc_dcon_present;
+
+/* REV_A CMOS map:
+ * bit 440;  DCON present bit
+ */
+
+#define OLPC_CMOS_DCON_OFFSET (440 / 8)
+#define OLPC_CMOS_DCON_MASK   0x01
+
+static int __init olpc_init(void) {
+
+  unsigned char val;
+
+  /* Read the DCON present bit and set the flag accordingly */
+
+  val = CMOS_READ(OLPC_CMOS_DCON_OFFSET);
+  olpc_dcon_present = (val & OLPC_CMOS_DCON_MASK);
+
+  return 0;
+}
+
+subsys_initcall(olpc_init);
+EXPORT_SYMBOL(olpc_dcon_present);
+
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 6885f75..0f5b068 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -38,6 +38,7 @@ #include "video_gx.h"
 static char *mode_option;
 
 /* Modes relevant to the GX (taken from modedb.c) */
+
 static const struct fb_videomode gx_modedb[] __initdata = {
 	/* 640x480-60 VESA */
 	{ NULL, 60, 640, 480, 39682,  48, 16, 33, 10, 96, 2,
@@ -103,11 +104,23 @@ static const struct fb_videomode gx_mode
 	{ NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3,
 	  FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	  FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
-	{ "OLPC-1", 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
+	/* 1200x900-75 - CRT timings for the OLPC mode */
+	{ NULL, 75, 1200, 900, 8049, 104, 240, 29, 54, 136, 3,
 	  FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	  FB_VMODE_NONINTERLACED, 0 }
 };
 
+#ifdef CONFIG_OLPC
+static const struct fb_videomode gx_dcon_modedb[] __initdata = {
+	/* The only mode the DCON has is 1200x900 */
+	{ NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
+	  FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	  FB_VMODE_NONINTERLACED, 0 }
+};
+
+extern int olpc_dcon_present;
+#endif
+
 static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	if (var->xres > 1600 || var->yres > 1200)
@@ -321,6 +334,9 @@ static int __init gxfb_probe(struct pci_
 	int ret;
 	unsigned long val;
 
+	struct fb_videomode *modedb_ptr;
+	int modedb_size;
+
 	info = gxfb_init_fbinfo(&pdev->dev);
 	if (!info)
 		return -ENOMEM;
@@ -344,15 +360,30 @@ static int __init gxfb_probe(struct pci_
 	else
 		par->enable_crt = 1;
 
+	/* If the OLPC DCON is present, then we use a special
+	 * mode database (don't say we support modes that we don't).
+	 */
+
+	modedb_ptr = (struct fb_videomode *) gx_modedb;
+	modedb_size = ARRAY_SIZE(gx_modedb);
+
+#ifdef CONFIG_OLPC
+	if (olpc_dcon_present) {
+		printk(KERN_INFO "gxfb:  DCON detected.\n");
+		modedb_ptr = (struct fb_videomode *) gx_dcon_modedb;
+		modedb_size = ARRAY_SIZE(gx_dcon_modedb);
+	}
+#endif
+
 	ret = fb_find_mode(&info->var, info, mode_option,
-			   gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
+			   modedb_ptr, modedb_size, NULL, 16);
+
 	if (ret == 0 || ret == 4) {
 		dev_err(&pdev->dev, "could not find valid video mode\n");
 		ret = -EINVAL;
 		goto err;
 	}
 
-       
 	/* Clear the frame buffer of garbage. */
         memset_io(info->screen_base, 0, info->fix.smem_len);
 
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index d126790..f1ad764 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -506,7 +506,9 @@ int fb_find_mode(struct fb_var_screeninf
 	dbsize = ARRAY_SIZE(modedb);
     }
     if (!default_mode)
-	default_mode = &modedb[DEFAULT_MODEDB_INDEX];
+	    default_mode = (db == modedb) ?
+		    &modedb[DEFAULT_MODEDB_INDEX] : &db[0];
+
     if (!default_bpp)
 	default_bpp = 8;
 


More information about the Commits-kernel mailing list