[PATCH] Detect if the OLPC DCON was detected by the BIOS
Jordan Crouse
jordan.crouse at amd.unroutablecom
Wed Nov 29 11:14:54 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