[U-Boot] [PATCH 1/2 v2] misc: Add simple driver to enable the legacy UART on Winbond Super IO chips

On most x86 boards, the legacy serial ports (io address 0x3f8/0x2f8) are provided by a superio chip connected to the LPC bus. We must program the superio chip so that serial ports are available for us.
Signed-off-by: Stefan Roese sr@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org --- v2: - Address Bin's comments: - Make description more generic, so that other functions of this Winbond super IO chip may be integrated - Lowercase hex value - Minor changes to the comments
drivers/misc/Kconfig | 8 ++++++++ drivers/misc/Makefile | 1 + drivers/misc/winbond_w83627.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/winbond_w83627.h | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 drivers/misc/winbond_w83627.c create mode 100644 include/winbond_w83627.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b92da4e..dfd804f 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -112,4 +112,12 @@ config RESET effect a reset. The uclass will try all available drivers when reset_walk() is called.
+config WINBOND_W83627 + bool "Enable Winbond Super I/O driver" + help + If you say Y here, you will get support for the Winbond + W83627 Super I/O driver. This can be used to enable the + legacy UART or other devices in the Winbond Super IO chips + on X86 platforms. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index aa137f5..15505bf 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o obj-$(CONFIG_RESET) += reset-uclass.o obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o +obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o diff --git a/drivers/misc/winbond_w83627.c b/drivers/misc/winbond_w83627.c new file mode 100644 index 0000000..59db7d9 --- /dev/null +++ b/drivers/misc/winbond_w83627.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2016 Stefan Roese sr@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/pnp_def.h> + +#define WINBOND_ENTRY_KEY 0x87 +#define WINBOND_EXIT_KEY 0xaa + +/* Enable configuration: pass entry key '0x87' into index port dev twice */ +static void pnp_enter_conf_state(u16 dev) +{ + u16 port = dev >> 8; + + outb(WINBOND_ENTRY_KEY, port); + outb(WINBOND_ENTRY_KEY, port); +} + +/* Disable configuration: pass exit key '0xAA' into index port dev */ +static void pnp_exit_conf_state(u16 dev) +{ + u16 port = dev >> 8; + + outb(WINBOND_EXIT_KEY, port); +} + +/* Bring up early serial debugging output before the RAM is initialized */ +void winbond_enable_serial(uint dev, uint iobase, uint irq) +{ + pnp_enter_conf_state(dev); + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); + pnp_set_iobase(dev, PNP_IDX_IO0, iobase); + pnp_set_irq(dev, PNP_IDX_IRQ0, irq); + pnp_set_enable(dev, 1); + pnp_exit_conf_state(dev); +} diff --git a/include/winbond_w83627.h b/include/winbond_w83627.h new file mode 100644 index 0000000..ac3bec6 --- /dev/null +++ b/include/winbond_w83627.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 Stefan Roese sr@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _WINBOND_W83627_H_ +#define _WINBOND_W83627_H_ + +/* I/O address of Winbond Super IO chip */ +#define WINBOND_IO_PORT 0x2e + +/* Logical device number */ +#define W83627DHG_FDC 0 /* Floppy */ +#define W83627DHG_PP 1 /* Parallel port */ +#define W83627DHG_SP1 2 /* Com1 */ +#define W83627DHG_SP2 3 /* Com2 */ +#define W83627DHG_KBC 5 /* PS/2 keyboard & mouse */ +#define W83627DHG_SPI 6 /* Serial peripheral interface */ +#define W83627DHG_WDTO_PLED 8 /* WDTO#, PLED */ +#define W83627DHG_ACPI 10 /* ACPI */ +#define W83627DHG_HWM 11 /* Hardware monitor */ +#define W83627DHG_PECI_SST 12 /* PECI, SST */ + +/** + * Configure the base I/O port of the specified serial device and enable the + * serial device. + * + * @dev: high 8 bits = super I/O port, low 8 bits = logical device number + * @iobase: processor I/O port address to assign to this serial device + * @irq: processor IRQ number to assign to this serial device + */ +void winbond_enable_serial(uint dev, uint iobase, uint irq); + +#endif /* _WINBOND_W83627_H_ */

This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org --- arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c index b64a3a9..471d592 100644 --- a/arch/x86/cpu/baytrail/early_uart.c +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -59,11 +59,15 @@ static void x86_pci_write_config32(int dev, unsigned int where, u32 value) }
/* This can be called after memory-mapped PCI is working */ -int setup_early_uart(void) +int setup_internal_uart(int enable) { - /* Enable the legacy UART hardware. */ + /* Enable or disable the legacy UART hardware */ x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, - 1); + enable); + + /* All done for the disable part, so just return */ + if (!enable) + return 0;
/* * Set up the pads to the UART function. This allows the signals to diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index dbf8e95..cc5c953 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -45,7 +45,7 @@ void dram_init_banksize(void); int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */ -int setup_early_uart(void); +int setup_internal_uart(int enable);
void setup_pcat_compatibility(void);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 875c96a..29fa060 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -111,7 +111,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) #endif
#ifdef CONFIG_DEBUG_UART - setup_early_uart(); + setup_internal_uart(1); #endif
fsp_hdr = find_fsp_header();

Hi Stefan,
On Tue, Jan 19, 2016 at 9:05 PM, Stefan Roese sr@denx.de wrote:
This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c index b64a3a9..471d592 100644 --- a/arch/x86/cpu/baytrail/early_uart.c +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -59,11 +59,15 @@ static void x86_pci_write_config32(int dev, unsigned int where, u32 value) }
/* This can be called after memory-mapped PCI is working */ -int setup_early_uart(void) +int setup_internal_uart(int enable) {
/* Enable the legacy UART hardware. */
/* Enable or disable the legacy UART hardware */ x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT,
1);
enable);
/* All done for the disable part, so just return */
if (!enable)
return 0; /* * Set up the pads to the UART function. This allows the signals to
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index dbf8e95..cc5c953 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -45,7 +45,7 @@ void dram_init_banksize(void); int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */ -int setup_early_uart(void); +int setup_internal_uart(int enable);
void setup_pcat_compatibility(void);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 875c96a..29fa060 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -111,7 +111,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) #endif
#ifdef CONFIG_DEBUG_UART
setup_early_uart();
setup_internal_uart(1);
#endif
fsp_hdr = find_fsp_header();
--
There is one more instance of setup_early_uart() in README.x86 that needs to be changed.
Other than that, Reviewed-by: Bin Meng bmeng.cn@gmail.com
Regards, Bin

This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org --- v2: - Also change reference in README.x86
arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- doc/README.x86 | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c index b64a3a9..471d592 100644 --- a/arch/x86/cpu/baytrail/early_uart.c +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -59,11 +59,15 @@ static void x86_pci_write_config32(int dev, unsigned int where, u32 value) }
/* This can be called after memory-mapped PCI is working */ -int setup_early_uart(void) +int setup_internal_uart(int enable) { - /* Enable the legacy UART hardware. */ + /* Enable or disable the legacy UART hardware */ x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, - 1); + enable); + + /* All done for the disable part, so just return */ + if (!enable) + return 0;
/* * Set up the pads to the UART function. This allows the signals to diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index dbf8e95..cc5c953 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -45,7 +45,7 @@ void dram_init_banksize(void); int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */ -int setup_early_uart(void); +int setup_internal_uart(int enable);
void setup_pcat_compatibility(void);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 875c96a..29fa060 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -111,7 +111,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) #endif
#ifdef CONFIG_DEBUG_UART - setup_early_uart(); + setup_internal_uart(1); #endif
fsp_hdr = find_fsp_header(); diff --git a/doc/README.x86 b/doc/README.x86 index 36aaef0..6d9cb10 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -706,7 +706,7 @@ the board, then you can use post_code() calls from C or assembler to monitor boot progress. This can be good for debugging.
If not, you can try to get serial working as early as possible. The early -debug serial port may be useful here. See setup_early_uart() for an example. +debug serial port may be useful here. See setup_internal_uart() for an example.
During the U-Boot porting, one of the important steps is to write correct PIRQ routing information in the board device tree. Without it, device drivers in the

Hi Simon,
On Tue, Jan 19, 2016 at 9:24 PM, Stefan Roese sr@denx.de wrote:
This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
v2:
- Also change reference in README.x86
arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- doc/README.x86 | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c index b64a3a9..471d592 100644 --- a/arch/x86/cpu/baytrail/early_uart.c +++ b/arch/x86/cpu/baytrail/early_uart.c @@ -59,11 +59,15 @@ static void x86_pci_write_config32(int dev, unsigned int where, u32 value) }
/* This can be called after memory-mapped PCI is working */ -int setup_early_uart(void) +int setup_internal_uart(int enable) {
/* Enable the legacy UART hardware. */
/* Enable or disable the legacy UART hardware */ x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT,
1);
enable);
/* All done for the disable part, so just return */
if (!enable)
return 0; /* * Set up the pads to the UART function. This allows the signals to
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index dbf8e95..cc5c953 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -45,7 +45,7 @@ void dram_init_banksize(void); int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */ -int setup_early_uart(void); +int setup_internal_uart(int enable);
void setup_pcat_compatibility(void);
diff --git a/arch/x86/lib/fsp/fsp_support.c b/arch/x86/lib/fsp/fsp_support.c index 875c96a..29fa060 100644 --- a/arch/x86/lib/fsp/fsp_support.c +++ b/arch/x86/lib/fsp/fsp_support.c @@ -111,7 +111,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf) #endif
#ifdef CONFIG_DEBUG_UART
setup_early_uart();
setup_internal_uart(1);
#endif
fsp_hdr = find_fsp_header();
diff --git a/doc/README.x86 b/doc/README.x86 index 36aaef0..6d9cb10 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -706,7 +706,7 @@ the board, then you can use post_code() calls from C or assembler to monitor boot progress. This can be good for debugging.
If not, you can try to get serial working as early as possible. The early -debug serial port may be useful here. See setup_early_uart() for an example. +debug serial port may be useful here. See setup_internal_uart() for an example.
During the U-Boot porting, one of the important steps is to write correct PIRQ routing information in the board device tree. Without it, device drivers in the --
Do you have any comments about Stefan's series? If not, I am going to apply it soon.
Regards, Bin

On 24 January 2016 at 19:50, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Jan 19, 2016 at 9:24 PM, Stefan Roese sr@denx.de wrote:
This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
v2:
- Also change reference in README.x86
arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- doc/README.x86 | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

On Tue, Jan 26, 2016 at 4:37 AM, Simon Glass sjg@chromium.org wrote:
On 24 January 2016 at 19:50, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Tue, Jan 19, 2016 at 9:24 PM, Stefan Roese sr@denx.de wrote:
This patch adds a parameter to the function setup_early_uart() to either enable or disable the internal BayTrail legacy UART. Since the name setup_early_uart() does not match its functionality any more, lets rename it to setup_internal_uart() as well in this patch.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
v2:
- Also change reference in README.x86
arch/x86/cpu/baytrail/early_uart.c | 10 +++++++--- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp/fsp_support.c | 2 +- doc/README.x86 | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org
applied to u-boot-x86/master, thanks!

On Tue, Jan 19, 2016 at 9:05 PM, Stefan Roese sr@denx.de wrote:
On most x86 boards, the legacy serial ports (io address 0x3f8/0x2f8) are provided by a superio chip connected to the LPC bus. We must program the superio chip so that serial ports are available for us.
Signed-off-by: Stefan Roese sr@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
v2:
- Address Bin's comments:
- Make description more generic, so that other functions of this Winbond super IO chip may be integrated
- Lowercase hex value
- Minor changes to the comments
drivers/misc/Kconfig | 8 ++++++++ drivers/misc/Makefile | 1 + drivers/misc/winbond_w83627.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/winbond_w83627.h | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 drivers/misc/winbond_w83627.c create mode 100644 include/winbond_w83627.h
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Tue, Jan 19, 2016 at 9:15 PM, Bin Meng bmeng.cn@gmail.com wrote:
On Tue, Jan 19, 2016 at 9:05 PM, Stefan Roese sr@denx.de wrote:
On most x86 boards, the legacy serial ports (io address 0x3f8/0x2f8) are provided by a superio chip connected to the LPC bus. We must program the superio chip so that serial ports are available for us.
Signed-off-by: Stefan Roese sr@denx.de Cc: Bin Meng bmeng.cn@gmail.com Cc: Simon Glass sjg@chromium.org
v2:
- Address Bin's comments:
- Make description more generic, so that other functions of this Winbond super IO chip may be integrated
- Lowercase hex value
- Minor changes to the comments
drivers/misc/Kconfig | 8 ++++++++ drivers/misc/Makefile | 1 + drivers/misc/winbond_w83627.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/winbond_w83627.h | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 drivers/misc/winbond_w83627.c create mode 100644 include/winbond_w83627.h
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86/master, thanks!
participants (3)
-
Bin Meng
-
Simon Glass
-
Stefan Roese