All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] i386: CS5535 chip support - cpu
@ 2005-12-07 19:42 Jordan Crouse
  2005-12-09 15:01 ` Ben Gardner
  2005-12-10  8:44 ` [PATCH 1/3] " Pavel Machek
  0 siblings, 2 replies; 7+ messages in thread
From: Jordan Crouse @ 2005-12-07 19:42 UTC (permalink / raw)
  To: gardner.ben; +Cc: linux-kernel, info-linux

Greetings Ben - 

> - verifies the existence of the CS5535 by checking the DIVIL signature
> - configures UART1 as a NS16550A

I'm confused by all this.  Not so much your code, which is correct, but 
your reason for doing all of this in the first place.  On a somewhat sane
BIOS, it should have already set up all your descriptors and GPIO pins
long before the kernel booted.  Not that you should trust blindly the BIOS 
in all  things, but as long as this is handled for you, you might as well take
advantage of it. 

Now, if your particular board has its own very good reasons for handling
this, then thats fine, but I don't think this should be accepted as CS5535
support, because it stands a fairly good chance of causing trouble over
the larger set of Geode devices.   I'll certainly listen to arguments
to the contrary, though.

> -  (optionally) enables UART2 and configures it as a NS16550A

This is similar to code that has previously been submitted, and is attached
below.  Please review and comment.

> - (optionally) enables the SMBus/I2C interface

Is there any reason why you can't use the PCI devices instead?  Granted, 
the SMBUS and GPIO are part of a multi-function device  (which has a higher
annoyance level),  but it still seems better then passing around the global
variables that you read from the MSR.  Also, PCI has the advantage of being
a much cleaner and well traveled path, which is always nice.

Regards,
Jordan

-- 
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>


GEODE:  Support second UART on CS5535

The CS5535 has a muxed serial port that can either be used to drive GPIO pins
or a second 16550 UART.  This code enables the UART via a command line option.

Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
---

 drivers/serial/Kconfig       |   11 ++++++
 drivers/serial/Makefile      |    1 +
 drivers/serial/cs5535_uart.c |   83 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ad47c1b..0b1bb39 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -616,6 +616,17 @@ config SERIAL_AU1X00_CONSOLE
 	  If you have an Alchemy AU1X00 processor (MIPS based) and you want
 	  to use a console on a serial port, say Y.  Otherwise, say N.
 
+config SERIAL_GEODE_UART2
+	bool "Enable AMD CS5535 UART2 as a serial port"
+	depends on MGEODE_LX
+	default y
+	select SERIAL_CORE
+	help
+	  Select this to allow the user to select the secondary CS5535 UART
+	  as a 16550 serial port instead of the default DDC interface. The
+	  UART2 can be selected by specifying geodeuart2 on the command
+	  line.
+
 config SERIAL_CORE
 	tristate
 
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index d7c7c71..16dee50 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/
 obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
 obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
 obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_GEODE_UART2) += cs5535_uart.o
diff --git a/drivers/serial/cs5535_uart.c b/drivers/serial/cs5535_uart.c
new file mode 100644
index 0000000..d77c178
--- /dev/null
+++ b/drivers/serial/cs5535_uart.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2005 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+/* The CS5535 companion chip has two UARTs.  This code enables the second
+   UART so other devices can use it.  We do it here so we can expose the
+   port early enough for serial debugging
+*/
+
+/* Note - this does not check to see if the CS5535 actually exists */
+
+#define LO(b)  (((1 << b) << 16) | 0x0000)
+#define HI(b)  ((0x0000 << 16) | (1 << b))
+
+static u32 outtab[16] __initdata =
+{
+	0x00,HI(4), 0x04,HI(4), 0x08,HI(4),
+	0x0c,LO(4), 0x10,HI(4), 0x14,LO(4),
+	0x18,LO(4), 0x1C,LO(4)
+};
+
+static u32 intab[16] __initdata = {
+	0x20,HI(3), 0x24,LO(3), 0x28,LO(3),
+	0x2C,LO(3), 0x34,HI(3), 0x38,LO(3),
+     0x40,LO(3), 0x44,LO(3)
+};
+
+static int __init init_cs5535_uart2(char *str)
+{
+	u32 lo = 0, hi = 0;
+	u32 base; u32 i;
+
+	/* Enable UART2 instead of DDC */
+
+	rdmsr(0x51400014, lo, hi);
+	lo &= 0xFF8FFFFF;
+	lo |= 0x00500000;   /* 0x2F8 ttyS1 */
+	wrmsr(0x51400014, lo, hi);
+
+	/* Set up the UART registers */
+	wrmsr(0x5140003E, 0x12, 0x00);
+
+	rdmsr(0x5140000C, lo, hi);
+	base = (u32)(lo & 0xFF00);
+
+	/* Enable the GPIO pins (in and out) */
+
+	for(i = 0; i < 16; i += 2) {
+		outl(outtab[i + 1], base + outtab[i]);
+		outl(intab[i + 1], base + intab[i]);
+	}
+
+	/* Enable the IRQ */
+
+	rdmsr(0x51400021,lo,hi);
+	lo &= 0x0FFFFFFF;
+	lo |= 0x30000000; /* IRQ 3 */
+	wrmsr(0x51400021,lo,hi);
+}
+
+__setup("geodeuart2", init_cs5535_uart2);


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] i386: CS5535 chip support - cpu
  2005-12-07 19:42 [PATCH 1/3] i386: CS5535 chip support - cpu Jordan Crouse
@ 2005-12-09 15:01 ` Ben Gardner
  2005-12-09 22:47   ` Jordan Crouse
  2005-12-10  8:44 ` [PATCH 1/3] " Pavel Machek
  1 sibling, 1 reply; 7+ messages in thread
From: Ben Gardner @ 2005-12-09 15:01 UTC (permalink / raw)
  To: Jordan Crouse; +Cc: linux-kernel, info-linux

Hi Jordan,

Sorry it took so long for me to respond.

On 12/7/05, Jordan Crouse <jordan.crouse@amd.com> wrote:
> Greetings Ben -
>
> > - verifies the existence of the CS5535 by checking the DIVIL signature
> > - configures UART1 as a NS16550A
>
> I'm confused by all this.  Not so much your code, which is correct, but
> your reason for doing all of this in the first place.  On a somewhat sane
> BIOS, it should have already set up all your descriptors and GPIO pins
> long before the kernel booted.  Not that you should trust blindly the BIOS
> in all  things, but as long as this is handled for you, you might as well take
> advantage of it.

I think your phrase "somewhat sane BIOS" sums up the problem nicely.
I threw in the UART1 config because UART2 has problems. Paranoia.
I'm not sure that the UART1 config is needed, so I'm willing to scrap
it, or wrap it in a config option.

If you are interested in my experience with UART2, see the kernel
buzilla report #5677.

> Now, if your particular board has its own very good reasons for handling
> this, then thats fine, but I don't think this should be accepted as CS5535
> support, because it stands a fairly good chance of causing trouble over
> the larger set of Geode devices.   I'll certainly listen to arguments
> to the contrary, though.

I'm curious as to what trouble this could cause?

> > -  (optionally) enables UART2 and configures it as a NS16550A
>
> This is similar to code that has previously been submitted, and is attached
> below.  Please review and comment.

Your patch looks like it would also solve the UART2 problem.
What I still don't understand is why UART2 works fine in DOS and in
linux 2.6.13-rc6-mm1, but not in the current kernel - in short, why is
this needed?
My guess (not based on any data) is that a BIOS call (initiated by
Linux) uses the DDC, but doesn't restore the GPIO to its original
state. So, again, a BIOS problem.

Anyway, I recommend adding sanity checks on MSR_DIVIL_GLD_CAP and
MSR_LBAR_GPIO before writing to the IO port.  The code as-is may cause
problems on a non-cs5535 board.

> > - (optionally) enables the SMBus/I2C interface
>
> Is there any reason why you can't use the PCI devices instead?  Granted,
> the SMBUS and GPIO are part of a multi-function device  (which has a higher
> annoyance level),  but it still seems better then passing around the global
> variables that you read from the MSR.  Also, PCI has the advantage of being
> a much cleaner and well traveled path, which is always nice.

I agree that PCI would work much cleaner.
I plan to revisit the GPIO & SMB drivers and get them to use PCI, but
that may not happen for a while.

> Regards,
> Jordan

Thanks for your input.
Ben

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: i386: CS5535 chip support - cpu
  2005-12-09 15:01 ` Ben Gardner
@ 2005-12-09 22:47   ` Jordan Crouse
  0 siblings, 0 replies; 7+ messages in thread
From: Jordan Crouse @ 2005-12-09 22:47 UTC (permalink / raw)
  To: Ben Gardner; +Cc: linux-kernel, info-linux

On 09/12/05 09:01 -0600, Ben Gardner wrote:
> 
> I think your phrase "somewhat sane BIOS" sums up the problem nicely.
> I threw in the UART1 config because UART2 has problems. Paranoia.
> I'm not sure that the UART1 config is needed, so I'm willing to scrap
> it, or wrap it in a config option.
> 
> If you are interested in my experience with UART2, see the kernel
> buzilla report #5677.

> My guess (not based on any data) is that a BIOS call (initiated by
> Linux) uses the DDC, but doesn't restore the GPIO to its original
> state. So, again, a BIOS problem.

Reading BZ 5677, I get some perspective on your issue now.  I would agree
that the data sounds like something is subverting the GPIO pins for its
own use, and definately DDC is the logical conclusion.

Ok, so now with a bit of perspective on the issue, then I think that 
adding code to win back the serial port is useful, but it should be wrapped
in a config or command line option, so that users can decide for themselves.
After all, DDC is useful too (if you're an X user).  

> > Now, if your particular board has its own very good reasons for handling
> > this, then thats fine, but I don't think this should be accepted as CS5535
> > support, because it stands a fairly good chance of causing trouble over
> > the larger set of Geode devices.   I'll certainly listen to arguments
> > to the contrary, though.
> 
> I'm curious as to what trouble this could cause?

I'm mainly worried about resource conflicts and such, especially with the
first serial port.  I'm less worried about the second port (as you could
see from my code), but on the particular platform where that
code was most useful, we had a fixed set of features so we knew we be more
carefree.  Certainly, on the big development platforms with a full BIOS,
the code would be far more worriesome.

> Your patch looks like it would also solve the UART2 problem.
> What I still don't understand is why UART2 works fine in DOS and in
> linux 2.6.13-rc6-mm1, but not in the current kernel - in short, why is
> this needed?

Our internal BIOS defaults to DDC on the second CS5535/CS5536 serial
port, which normally isn't any big deal, because the first port is 
available, and if worse comes to worse, I can always switch over to LPC.

But on platforms like the Thin Client RDK, which is more like a production
platform, there aren't any physical serial ports populated.  So in order to
get access, our systems guys made a little dongle that plugged into
the VGA port and split out the DDC lines and turned them into a serial
connection.  And this code was born to turn off the default DDC and
enable the serial port.

> Anyway, I recommend adding sanity checks on MSR_DIVIL_GLD_CAP and
> MSR_LBAR_GPIO before writing to the IO port.  The code as-is may cause
> problems on a non-cs5535 board.

Thats a great point.  Actually, we should check for both CS5535 and 
CS5536, since the code will work on both.. :)

> Thanks for your input.

Thanks for your interest.
Jordan

-- 
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] i386: CS5535 chip support - cpu
  2005-12-07 19:42 [PATCH 1/3] i386: CS5535 chip support - cpu Jordan Crouse
  2005-12-09 15:01 ` Ben Gardner
@ 2005-12-10  8:44 ` Pavel Machek
  1 sibling, 0 replies; 7+ messages in thread
From: Pavel Machek @ 2005-12-10  8:44 UTC (permalink / raw)
  To: Jordan Crouse; +Cc: gardner.ben, linux-kernel, info-linux

On Wed 07-12-05 12:42:26, Jordan Crouse wrote:
> +/* Note - this does not check to see if the CS5535 actually exists */
> +
> +#define LO(b)  (((1 << b) << 16) | 0x0000)
> +#define HI(b)  ((0x0000 << 16) | (1 << b))
> +

What kind of ninja mutant macros are these?

> +static u32 intab[16] __initdata = {
> +	0x20,HI(3), 0x24,LO(3), 0x28,LO(3),
> +	0x2C,LO(3), 0x34,HI(3), 0x38,LO(3),
> +     0x40,LO(3), 0x44,LO(3)
> +};

Can't you just use values here, without the macros?

							Pavel
-- 
Thanks, Sharp!

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] i386: CS5535 chip support - cpu
  2005-12-07 18:12 ` Adrian Bunk
@ 2005-12-07 19:31   ` Ben Gardner
  0 siblings, 0 replies; 7+ messages in thread
From: Ben Gardner @ 2005-12-07 19:31 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: Andrew Morton, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 621 bytes --]

Configures the DIVIL component of the AMD CS5535 (Geode companion device).

This patch does the following:
 - verifies the existence of the CS5535 by checking the DIVIL signature
 - configures UART1 as a NS16550A
 - (optionally) enables UART2 and configures it as a NS16550A
 - (optionally) enables the SMBus/I2C interface

Signed-off-by: Ben Gardner <bgardner@wabtec.com>
---

Thanks for the feedback, Adrian.
Attached is a new patch with that error corrected.

Ben

On 12/7/05, Adrian Bunk <bunk@stusta.de> wrote:
> Please use CONFIG_CS5535_{SMB,UART2} in cs5535.c instead of setting
> EXTRA_CFLAGS.

[-- Attachment #2: cs5535-cpu.patch.txt --]
[-- Type: text/plain, Size: 7615 bytes --]

 arch/i386/Kconfig         |   27 ++++++
 arch/i386/kernel/Makefile |    2 
 arch/i386/kernel/cs5535.c |  190 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 219 insertions(+)

Index: linux-2.6.15-rc5-mm1/arch/i386/kernel/cs5535.c
===================================================================
--- /dev/null
+++ linux-2.6.15-rc5-mm1/arch/i386/kernel/cs5535.c
@@ -0,0 +1,190 @@
+/**
+ * linux/arch/i386/kernel/cs5535.c
+ *
+ *  Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ *  AMD CS5535 Companion Device support (AMD Geode processor).
+ *
+ *  This does early configuration of the UARTs, SMB port, and GPIO.
+ *
+ *  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; version 2 of the License.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+
+#define NAME			"cs5535"
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("AMD CS5535 Driver");
+MODULE_LICENSE("GPL");
+
+/* GPIO base address (from MSR_LBAR_GPIO; MSR 5140000Ch, bits 15:0) */
+u32 cs5535_gpio_base;
+u32 cs5535_gpio_mask;
+EXPORT_SYMBOL(cs5535_gpio_base);
+EXPORT_SYMBOL(cs5535_gpio_mask);
+
+#define MSR_DIVIL_GLD_CAP	0x51400000
+#define DEVID_DIVIL		0x2DF0
+
+#define MSR_LBAR_SMB		0x5140000B
+#define MSR_LBAR_GPIO		0x5140000C
+
+#define MSR_UART1_CONF		0x5140003a
+#define MSR_UART2_CONF		0x5140003e
+
+#define MSR_DIVIL_LEG_IO	0x51400014
+#define MSR_DIVIL_BALL_OPT	0x51400015
+#define MSR_IRQ_MAPY_H		0x51400021
+
+struct gpio_reg_val {
+	u32 reg;
+	u32 val;
+};
+
+#ifdef CONFIG_CS5535_SMB
+static const struct gpio_reg_val gpio_smb[] __initdata =
+{
+	{ 0x04, 0x0000c000 },		/* enable OUTPUT */
+	{ 0x08, 0x0000c000 },		/* enable OpenDrain */
+	{ 0x10, 0x0000c000 },		/* enable OUT_AUX1 */
+	{ 0x14, 0xc0000000UL },		/* disable OUT_AUX2 */
+	{ 0x20, 0x0000c000 },		/* enable INPUT */
+	{ 0x34, 0x0000c000 },		/* enable IN_AUX1 */
+};
+#endif
+
+/* don't touch GPIO 3 & 4 unless UART2 is enabled */
+#ifdef CONFIG_CS5535_UART2
+#define RMSK	0x03180318
+#else
+#define RMSK	0x03000300
+#endif
+
+static const struct gpio_reg_val gpio_uarts[] __initdata =
+{
+	{ 0x00, 0x03180000 & RMSK },	/* output val */
+	{ 0x04, 0x02080110 & RMSK },	/* output enable */
+	{ 0x08, 0x02080110 & RMSK },	/* open-drain enable */
+	{ 0x0c, 0x03180000 & RMSK },	/* invert output */
+	{ 0x10, 0x02080110 & RMSK },	/* Out-Aux-1 */
+	{ 0x14, 0x03180000 & RMSK },	/* Out-Aux-2 */
+	{ 0x18, 0x03180000 & RMSK },	/* Pull-Up */
+	{ 0x1c, 0x03180000 & RMSK },	/* Pull-Down */
+	{ 0x20, 0x01100208 & RMSK },	/* Input enable */
+	{ 0x24, 0x03180000 & RMSK },	/* invert */
+	{ 0x28, 0x03180000 & RMSK },	/* filter */
+	{ 0x2c, 0x03180000 & RMSK },	/* event-count */
+	{ 0x34, 0x01100208 & RMSK },	/* in-aux1 */
+	{ 0x38, 0x03180000 & RMSK },	/* events */
+	{ 0x40, 0x03180000 & RMSK },	/* Input Pos Edge */
+	{ 0x44, 0x03180000 & RMSK },	/* Input Neg Edge */
+};
+
+static int __init init_cs5535_divil(void)
+{
+	u32 low32;
+	u32 high32;
+	int idx;
+
+	/* Check the DIVIL device ID for validation */
+	rdmsr(MSR_DIVIL_GLD_CAP, low32, high32);
+	if ((high32 != 0) || ((low32 >> 8) != DEVID_DIVIL)) {
+		printk(KERN_WARNING NAME ": DIVIL device not found\n");
+		return -ENODEV;
+	}
+
+	/* Grab the GPIO I/O range */
+	rdmsr(MSR_LBAR_GPIO, low32, high32);
+	cs5535_gpio_base = low32 & 0x0000ff00;
+
+	/* Check the mask and whether GPIO is enabled */
+	if (high32 != 0x0000f001) {
+		/* TODO: enable GPIO IO mappings via LBAR */
+		printk(KERN_WARNING NAME ": GPIO not enabled\n");
+		return -ENODEV;
+	}
+
+	/* GPIO pins 31-29,23 are reserved, 22-16 are used for LPC,
+	 * 9,8 are used for UART1 */
+	cs5535_gpio_mask =  ~0xe0ff0300UL;
+
+#ifdef CONFIG_CS5535_SMB
+	/* GPIO pins 14 & 15 are used for SMBus */
+	cs5535_gpio_mask &= ~0x0000c000UL;
+
+	/* Grab & reserve the SMB I/O range */
+	rdmsr(MSR_LBAR_SMB, low32, high32);
+
+	/* Check the mask and whether SMB is enabled */
+	if (high32 != 0x0000F001) {
+		/* TODO: enable SMB IO mappings via LBAR */
+		printk(KERN_WARNING NAME ": SMBus not enabled\n");
+		return -ENODEV;
+	}
+
+	/* Configure GPIO 14 & 15 to do SMB/ACB/I2C */
+	for (idx = 0; idx < ARRAY_SIZE(gpio_smb); idx++) {
+		outl(gpio_smb[idx].val,
+		     gpio_smb[idx].reg + cs5535_gpio_base);
+	}
+#endif	/* CS5535_SMB */
+
+	/* Configure GPIO to do UART1 and maybe UART2 */
+	for (idx = 0; idx < ARRAY_SIZE(gpio_uarts); idx++) {
+		outl(gpio_uarts[idx].val,
+		     gpio_uarts[idx].reg + cs5535_gpio_base);
+	}
+
+	/* Set UART1 base address to 0x3f8 */
+	rdmsr(MSR_DIVIL_LEG_IO, low32, high32);
+	low32 &= 0xfff8ffffUL;		/* UART1 base IO */
+	low32 |= 0x00070000;		/* 0x3F8 */
+	wrmsr(MSR_DIVIL_LEG_IO, low32, high32);
+
+	/* Set UART1 interrupt to 4 */
+	rdmsr(MSR_IRQ_MAPY_H, low32, high32);
+	low32 &= 0xf0ffffffUL;		/* UART1 is on MAPY-14 */
+	low32 |= 0x04000000;		/* IRQ 4 */
+	wrmsr(MSR_IRQ_MAPY_H, low32, high32);
+
+	/* Set up UART1 as a NS15560A */
+	wrmsr(MSR_UART1_CONF, 0x12, 0);
+
+#ifdef CONFIG_CS5535_UART2
+	/* GPIO pins 3 & 4 are used for UART2 */
+	cs5535_gpio_mask &= ~0x00000018UL;
+
+	/* Set UART2 base address to 0x2f8 */
+	rdmsr(MSR_DIVIL_LEG_IO, low32, high32);
+	low32 &= 0xff8fffffUL;		/* UART2 base IO */
+	low32 |= 0x00500000;		/* 0x2F8 */
+	wrmsr(MSR_DIVIL_LEG_IO, low32, high32);
+
+	/* Set UART1 interrupt to 3 */
+	rdmsr(MSR_IRQ_MAPY_H, low32, high32);
+	low32 &= 0x0fffffffUL;		/* UART2 is on MAPY-15 */
+	low32 |= 0x30000000;		/* IRQ 3 */
+	wrmsr(MSR_IRQ_MAPY_H, low32, high32);
+
+	/* Set up UART2 as a NS15560A */
+	wrmsr(MSR_UART2_CONF, 0x12, 0);
+#endif	/* CS5535_UART2 */
+
+	printk(KERN_INFO NAME ": GPIO=%#x Mask=%#x\n",
+	       cs5535_gpio_base, cs5535_gpio_mask);
+
+	return 0;
+}
+
+subsys_initcall(init_cs5535_divil);
+
Index: linux-2.6.15-rc5-mm1/arch/i386/Kconfig
===================================================================
--- linux-2.6.15-rc5-mm1.orig/arch/i386/Kconfig
+++ linux-2.6.15-rc5-mm1/arch/i386/Kconfig
@@ -336,6 +336,33 @@ config I8K
 	  Say Y if you intend to run this kernel on a Dell Inspiron 8000.
 	  Say N otherwise.
 
+config CS5535
+	tristate "AMD CS5535 (Geode Companion Device) support"
+	help
+	  This provides basic support for the CS5535 Companion Chip for
+	  the AMD Geode processor.
+
+	  If you don't know what to do here, say N.
+
+config CS5535_SMB
+	bool "Enable CS5535 SMBus/Access.Bus/I2C"
+	depends on CS5535
+	default y
+	help
+	  Choosing this will configure the CS5535 GPIO pins 14 & 15 for SMB.
+	  Select I2C_CS5535 under i2c to build the SMB/I2C driver.
+
+	  Say Y if you intend to use the SMBus.
+
+config CS5535_UART2
+	bool "Enable UART2"
+	depends on CS5535
+	default y
+	help
+	  By default, CS5535 GPIO pins 3 & 4 are configured for DDC.
+
+	  Say Y to configure them as UART2 instead.
+
 config X86_REBOOTFIXUPS
 	bool "Enable X86 board specific fixups for reboot"
 	depends on X86
Index: linux-2.6.15-rc5-mm1/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.15-rc5-mm1.orig/arch/i386/kernel/Makefile
+++ linux-2.6.15-rc5-mm1/arch/i386/kernel/Makefile
@@ -42,6 +42,8 @@ EXTRA_AFLAGS   := -traditional
 
 obj-$(CONFIG_SCx200)		+= scx200.o
 
+obj-$(CONFIG_CS5535)		+= cs5535.o
+
 # vsyscall.o contains the vsyscall DSO images as __initdata.
 # We must build both images before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/3] i386: CS5535 chip support - cpu
  2005-12-07 17:31 Ben Gardner
@ 2005-12-07 18:12 ` Adrian Bunk
  2005-12-07 19:31   ` Ben Gardner
  0 siblings, 1 reply; 7+ messages in thread
From: Adrian Bunk @ 2005-12-07 18:12 UTC (permalink / raw)
  To: Ben Gardner; +Cc: Andrew Morton, lm-sensors, linux-kernel

On Wed, Dec 07, 2005 at 11:31:09AM -0600, Ben Gardner wrote:
>...
> --- linux-2.6.14.orig/arch/i386/kernel/Makefile
> +++ linux-2.6.14/arch/i386/kernel/Makefile
> @@ -42,6 +42,14 @@ EXTRA_AFLAGS   := -traditional
>  
>  obj-$(CONFIG_SCx200)		+= scx200.o
>  
> +obj-$(CONFIG_CS5535)		+= cs5535.o
> +ifeq ($(CONFIG_CS5535_SMB), y)
> +EXTRA_CFLAGS += -DCS5535_SMB
> +endif
> +ifeq ($(CONFIG_CS5535_UART2), y)
> +EXTRA_CFLAGS += -DCS5535_UART2
> +endif
>...

Please use CONFIG_CS5535_{SMB,UART2} in cs5535.c instead of setting 
EXTRA_CFLAGS.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] i386: CS5535 chip support - cpu
@ 2005-12-07 17:31 Ben Gardner
  2005-12-07 18:12 ` Adrian Bunk
  0 siblings, 1 reply; 7+ messages in thread
From: Ben Gardner @ 2005-12-07 17:31 UTC (permalink / raw)
  To: Andrew Morton; +Cc: lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 382 bytes --]

Configures the DIVIL component of the AMD CS5535 (Geode companion device).

This patch does the following:
 - verifies the existence of the CS5535 by checking the DIVIL signature
 - configures UART1 as a NS16550A
 - (optionally) enables UART2 and configures it as a NS16550A
 - (optionally) enables the SMBus/I2C interface

Signed-off-by: Ben Gardner <bgardner@wabtec.com>

[-- Attachment #2: cs5535-cpu.patch.txt --]
[-- Type: text/plain, Size: 7663 bytes --]

 arch/i386/Kconfig         |   27 ++++++
 arch/i386/kernel/Makefile |    8 +
 arch/i386/kernel/cs5535.c |  190 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 225 insertions(+)

Index: linux-2.6.14/arch/i386/kernel/cs5535.c
===================================================================
--- /dev/null
+++ linux-2.6.14/arch/i386/kernel/cs5535.c
@@ -0,0 +1,190 @@
+/**
+ * linux/arch/i386/kernel/cs5535.c
+ *
+ *  Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ *  AMD CS5535 Companion Device support (AMD Geode processor).
+ *
+ *  This does early configuration of the UARTs, SMB port, and GPIO.
+ *
+ *  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; version 2 of the License.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/msr.h>
+#include <asm/io.h>
+
+
+#define NAME			"cs5535"
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("AMD CS5535 Driver");
+MODULE_LICENSE("GPL");
+
+/* GPIO base address (from MSR_LBAR_GPIO; MSR 5140000Ch, bits 15:0) */
+u32 cs5535_gpio_base;
+u32 cs5535_gpio_mask;
+EXPORT_SYMBOL(cs5535_gpio_base);
+EXPORT_SYMBOL(cs5535_gpio_mask);
+
+#define MSR_DIVIL_GLD_CAP	0x51400000
+#define DEVID_DIVIL		0x2DF0
+
+#define MSR_LBAR_SMB		0x5140000B
+#define MSR_LBAR_GPIO		0x5140000C
+
+#define MSR_UART1_CONF		0x5140003a
+#define MSR_UART2_CONF		0x5140003e
+
+#define MSR_DIVIL_LEG_IO	0x51400014
+#define MSR_DIVIL_BALL_OPT	0x51400015
+#define MSR_IRQ_MAPY_H		0x51400021
+
+struct gpio_reg_val {
+	u32 reg;
+	u32 val;
+};
+
+#ifdef CS5535_SMB
+static const struct gpio_reg_val gpio_smb[] __initdata =
+{
+	{ 0x04, 0x0000c000 },		/* enable OUTPUT */
+	{ 0x08, 0x0000c000 },		/* enable OpenDrain */
+	{ 0x10, 0x0000c000 },		/* enable OUT_AUX1 */
+	{ 0x14, 0xc0000000UL },		/* disable OUT_AUX2 */
+	{ 0x20, 0x0000c000 },		/* enable INPUT */
+	{ 0x34, 0x0000c000 },		/* enable IN_AUX1 */
+};
+#endif
+
+/* don't touch GPIO 3 & 4 unless UART2 is enabled */
+#ifdef CS5535_UART2
+#define RMSK	0x03180318
+#else
+#define RMSK	0x03000300
+#endif
+
+static const struct gpio_reg_val gpio_uarts[] __initdata =
+{
+	{ 0x00, 0x03180000 & RMSK },	/* output val */
+	{ 0x04, 0x02080110 & RMSK },	/* output enable */
+	{ 0x08, 0x02080110 & RMSK },	/* open-drain enable */
+	{ 0x0c, 0x03180000 & RMSK },	/* invert output */
+	{ 0x10, 0x02080110 & RMSK },	/* Out-Aux-1 */
+	{ 0x14, 0x03180000 & RMSK },	/* Out-Aux-2 */
+	{ 0x18, 0x03180000 & RMSK },	/* Pull-Up */
+	{ 0x1c, 0x03180000 & RMSK },	/* Pull-Down */
+	{ 0x20, 0x01100208 & RMSK },	/* Input enable */
+	{ 0x24, 0x03180000 & RMSK },	/* invert */
+	{ 0x28, 0x03180000 & RMSK },	/* filter */
+	{ 0x2c, 0x03180000 & RMSK },	/* event-count */
+	{ 0x34, 0x01100208 & RMSK },	/* in-aux1 */
+	{ 0x38, 0x03180000 & RMSK },	/* events */
+	{ 0x40, 0x03180000 & RMSK },	/* Input Pos Edge */
+	{ 0x44, 0x03180000 & RMSK },	/* Input Neg Edge */
+};
+
+static int __init init_cs5535_divil(void)
+{
+	u32 low32;
+	u32 high32;
+	int idx;
+
+	/* Check the DIVIL device ID for validation */
+	rdmsr(MSR_DIVIL_GLD_CAP, low32, high32);
+	if ((high32 != 0) || ((low32 >> 8) != DEVID_DIVIL)) {
+		printk(KERN_WARNING NAME ": DIVIL device not found\n");
+		return -ENODEV;
+	}
+
+	/* Grab the GPIO I/O range */
+	rdmsr(MSR_LBAR_GPIO, low32, high32);
+	cs5535_gpio_base = low32 & 0x0000ff00;
+
+	/* Check the mask and whether GPIO is enabled */
+	if (high32 != 0x0000f001) {
+		/* TODO: enable GPIO IO mappings via LBAR */
+		printk(KERN_WARNING NAME ": GPIO not enabled\n");
+		return -ENODEV;
+	}
+
+	/* GPIO pins 31-29,23 are reserved, 22-16 are used for LPC,
+	 * 9,8 are used for UART1 */
+	cs5535_gpio_mask =  ~0xe0ff0300UL;
+
+#ifdef CS5535_SMB
+	/* GPIO pins 14 & 15 are used for SMBus */
+	cs5535_gpio_mask &= ~0x0000c000UL;
+
+	/* Grab & reserve the SMB I/O range */
+	rdmsr(MSR_LBAR_SMB, low32, high32);
+
+	/* Check the mask and whether SMB is enabled */
+	if (high32 != 0x0000F001) {
+		/* TODO: enable SMB IO mappings via LBAR */
+		printk(KERN_WARNING NAME ": SMBus not enabled\n");
+		return -ENODEV;
+	}
+
+	/* Configure GPIO 14 & 15 to do SMB/ACB/I2C */
+	for (idx = 0; idx < ARRAY_SIZE(gpio_smb); idx++) {
+		outl(gpio_smb[idx].val,
+		     gpio_smb[idx].reg + cs5535_gpio_base);
+	}
+#endif	/* CS5535_SMB */
+
+	/* Configure GPIO to do UART1 and maybe UART2 */
+	for (idx = 0; idx < ARRAY_SIZE(gpio_uarts); idx++) {
+		outl(gpio_uarts[idx].val,
+		     gpio_uarts[idx].reg + cs5535_gpio_base);
+	}
+
+	/* Set UART1 base address to 0x3f8 */
+	rdmsr(MSR_DIVIL_LEG_IO, low32, high32);
+	low32 &= 0xfff8ffffUL;		/* UART1 base IO */
+	low32 |= 0x00070000;		/* 0x3F8 */
+	wrmsr(MSR_DIVIL_LEG_IO, low32, high32);
+
+	/* Set UART1 interrupt to 4 */
+	rdmsr(MSR_IRQ_MAPY_H, low32, high32);
+	low32 &= 0xf0ffffffUL;		/* UART1 is on MAPY-14 */
+	low32 |= 0x04000000;		/* IRQ 4 */
+	wrmsr(MSR_IRQ_MAPY_H, low32, high32);
+
+	/* Set up UART1 as a NS15560A */
+	wrmsr(MSR_UART1_CONF, 0x12, 0);
+
+#ifdef CS5535_UART2
+	/* GPIO pins 3 & 4 are used for UART2 */
+	cs5535_gpio_mask &= ~0x00000018UL;
+
+	/* Set UART2 base address to 0x2f8 */
+	rdmsr(MSR_DIVIL_LEG_IO, low32, high32);
+	low32 &= 0xff8fffffUL;		/* UART2 base IO */
+	low32 |= 0x00500000;		/* 0x2F8 */
+	wrmsr(MSR_DIVIL_LEG_IO, low32, high32);
+
+	/* Set UART1 interrupt to 3 */
+	rdmsr(MSR_IRQ_MAPY_H, low32, high32);
+	low32 &= 0x0fffffffUL;		/* UART2 is on MAPY-15 */
+	low32 |= 0x30000000;		/* IRQ 3 */
+	wrmsr(MSR_IRQ_MAPY_H, low32, high32);
+
+	/* Set up UART2 as a NS15560A */
+	wrmsr(MSR_UART2_CONF, 0x12, 0);
+#endif	/* CS5535_UART2 */
+
+	printk(KERN_INFO NAME ": GPIO=%#x Mask=%#x\n",
+	       cs5535_gpio_base, cs5535_gpio_mask);
+
+	return 0;
+}
+
+subsys_initcall(init_cs5535_divil);
+
Index: linux-2.6.14/arch/i386/Kconfig
===================================================================
--- linux-2.6.14.orig/arch/i386/Kconfig
+++ linux-2.6.14/arch/i386/Kconfig
@@ -336,6 +336,33 @@ config I8K
 	  Say Y if you intend to run this kernel on a Dell Inspiron 8000.
 	  Say N otherwise.
 
+config CS5535
+	tristate "AMD CS5535 (Geode Companion Device) support"
+	help
+	  This provides basic support for the CS5535 Companion Chip for
+	  the AMD Geode processor.
+
+	  If you don't know what to do here, say N.
+
+config CS5535_SMB
+	bool "Enable CS5535 SMBus/Access.Bus/I2C"
+	depends on CS5535
+	default y
+	help
+	  Choosing this will configure the CS5535 GPIO pins 14 & 15 for SMB.
+	  Select I2C_CS5535 under i2c to build the SMB/I2C driver.
+
+	  Say Y if you intend to use the SMBus.
+
+config CS5535_UART2
+	bool "Enable UART2"
+	depends on CS5535
+	default y
+	help
+	  By default, CS5535 GPIO pins 3 & 4 are configured for DDC.
+
+	  Say Y to configure them as UART2 instead.
+
 config X86_REBOOTFIXUPS
 	bool "Enable X86 board specific fixups for reboot"
 	depends on X86
Index: linux-2.6.14/arch/i386/kernel/Makefile
===================================================================
--- linux-2.6.14.orig/arch/i386/kernel/Makefile
+++ linux-2.6.14/arch/i386/kernel/Makefile
@@ -42,6 +42,14 @@ EXTRA_AFLAGS   := -traditional
 
 obj-$(CONFIG_SCx200)		+= scx200.o
 
+obj-$(CONFIG_CS5535)		+= cs5535.o
+ifeq ($(CONFIG_CS5535_SMB), y)
+EXTRA_CFLAGS += -DCS5535_SMB
+endif
+ifeq ($(CONFIG_CS5535_UART2), y)
+EXTRA_CFLAGS += -DCS5535_UART2
+endif
+
 # vsyscall.o contains the vsyscall DSO images as __initdata.
 # We must build both images before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-12-10  8:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-07 19:42 [PATCH 1/3] i386: CS5535 chip support - cpu Jordan Crouse
2005-12-09 15:01 ` Ben Gardner
2005-12-09 22:47   ` Jordan Crouse
2005-12-10  8:44 ` [PATCH 1/3] " Pavel Machek
  -- strict thread matches above, loose matches on Subject: below --
2005-12-07 17:31 Ben Gardner
2005-12-07 18:12 ` Adrian Bunk
2005-12-07 19:31   ` Ben Gardner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.