[coreboot] r3290 - trunk/coreboot-v2/src/southbridge/intel/i3100

svn at coreboot.org svn at coreboot.org
Wed May 7 23:57:13 CEST 2008


Author: eswierk
Date: 2008-05-07 23:57:12 +0200 (Wed, 07 May 2008)
New Revision: 3290

Modified:
   trunk/coreboot-v2/src/southbridge/intel/i3100/i3100_lpc.c
Log:
Implement GPIO configuration routines for the Intel 3100 southbridge,
allowing you to specify per-mainboard GPIO settings.

Signed-off-by: Ed Swierk <eswierk at arastra.com>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>



Modified: trunk/coreboot-v2/src/southbridge/intel/i3100/i3100_lpc.c
===================================================================
--- trunk/coreboot-v2/src/southbridge/intel/i3100/i3100_lpc.c	2008-05-07 20:43:15 UTC (rev 3289)
+++ trunk/coreboot-v2/src/southbridge/intel/i3100/i3100_lpc.c	2008-05-07 21:57:12 UTC (rev 3290)
@@ -111,10 +111,32 @@
 	device_t dev, struct resource *res, config_t *config)
 {
 	u32 gpio_use_sel, gpio_use_sel2;
+	int i;
 
-	gpio_use_sel  = 0x1b0ce7c3;
-	gpio_use_sel2 = 0x00000107;
-	outl(gpio_use_sel,  res->base + 0x00);
+	gpio_use_sel = inl(res->base + 0x00) | 0x0000c603;
+	gpio_use_sel2 = inl(res->base + 0x30) | 0x00000100;
+	for (i = 0; i < 64; i++) {
+		int val;
+		switch (config->gpio[i] & I3100_GPIO_USE_MASK) {
+		case I3100_GPIO_USE_AS_NATIVE:
+			val = 0;
+			break;
+		case I3100_GPIO_USE_AS_GPIO:
+			val = 1;
+			break;
+		default:
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_use_sel &= ~(1 << i);
+			gpio_use_sel |= (val << i);
+		} else {
+			gpio_use_sel2 &= ~(1 << (i - 32));
+			gpio_use_sel2 |= (val << (i - 32));
+		}
+	}
+	outl(gpio_use_sel, res->base + 0x00);
 	outl(gpio_use_sel2, res->base + 0x30);
 }
 
@@ -122,10 +144,32 @@
 	device_t dev, struct resource *res, config_t *config)
 {
 	u32 gpio_io_sel, gpio_io_sel2;
+	int i;
 
-	gpio_io_sel  = 0xed00ffff;
-	gpio_io_sel2 = 0x00000307;
-	outl(gpio_io_sel,  res->base + 0x04);
+	gpio_io_sel = inl(res->base + 0x04);
+	gpio_io_sel2 = inl(res->base + 0x34);
+	for (i = 0; i < 64; i++) {
+		int val;
+		switch (config->gpio[i] & I3100_GPIO_SEL_MASK) {
+		case I3100_GPIO_SEL_OUTPUT:
+			val = 0;
+			break;
+		case I3100_GPIO_SEL_INPUT:
+			val = 1;
+			break;
+		default:
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_io_sel &= ~(1 << i);
+			gpio_io_sel |= (val << i);
+		} else {
+			gpio_io_sel2 &= ~(1 << (i - 32));
+			gpio_io_sel2 |= (val << (i - 32));
+		}
+	}
+	outl(gpio_io_sel, res->base + 0x04);
 	outl(gpio_io_sel2, res->base + 0x34);
 }
 
@@ -134,22 +178,68 @@
 {
 	u32 gpio_lvl, gpio_lvl2;
 	u32 gpio_blink;
+	int i;
 
-	gpio_lvl   = 0x00030000;
-	gpio_blink = 0x00000000;
-	gpio_lvl2  = 0x00000300;
-	outl(gpio_lvl,   res->base + 0x0c);
+	gpio_lvl = inl(res->base + 0x0c);
+	gpio_blink = inl(res->base + 0x18);
+	gpio_lvl2 = inl(res->base + 0x38);
+	for (i = 0; i < 64; i++) {
+		int val, blink;
+		switch (config->gpio[i] & I3100_GPIO_LVL_MASK) {
+		case I3100_GPIO_LVL_LOW:
+			val = 0;
+			blink = 0;
+			break;
+		case I3100_GPIO_LVL_HIGH:
+			val = 1;
+			blink = 0;
+			break;
+		case I3100_GPIO_LVL_BLINK:
+			val = 1;
+			blink = 1;
+			break;
+		default:
+			continue;
+		}
+		/* The caller is responsible for not playing with unimplemented bits */
+		if (i < 32) {
+			gpio_lvl &= ~(1 << i);
+			gpio_blink &= ~(1 << i);
+			gpio_lvl |= (val << i);
+			gpio_blink |= (blink << i);
+		} else {
+			gpio_lvl2 &= ~(1 << (i - 32));
+			gpio_lvl2 |= (val << (i - 32));
+		}
+	}
+	outl(gpio_lvl, res->base + 0x0c);
 	outl(gpio_blink, res->base + 0x18);
-	outl(gpio_lvl2,  res->base + 0x38);
+	outl(gpio_lvl2, res->base + 0x38);
 }
 
 static void set_i3100_gpio_inv(
 	device_t dev, struct resource *res, config_t *config)
 {
 	u32 gpio_inv;
+	int i;
 
-	gpio_inv   = 0x00006000;
-	outl(gpio_inv,   res->base + 0x2c);
+	gpio_inv = inl(res->base + 0x2c);
+	for (i = 0; i < 32; i++) {
+		int val;
+		switch (config->gpio[i] & I3100_GPIO_INV_MASK) {
+		case I3100_GPIO_INV_OFF:
+			val = 0;
+			break;
+		case I3100_GPIO_INV_ON:
+			val = 1;
+			break;
+		default:
+			continue;
+		}
+		gpio_inv &= ~(1 << i);
+		gpio_inv |= (val << i);
+	}
+	outl(gpio_inv, res->base + 0x2c);
 }
 
 static void i3100_pirq_init(device_t dev)





More information about the coreboot mailing list