[coreboot-gerrit] New patch to review for coreboot: 198bd9a usbdebug: Support second EHCI controller with Debug Port

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Wed Jun 12 10:44:26 CEST 2013


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3438

-gerrit

commit 198bd9aea53b314c128b5891a0505b9a862099c6
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Tue Jun 11 23:43:08 2013 +0300

    usbdebug: Support second EHCI controller with Debug Port
    
    Nowadays, chipsets or boards do not only have one USB port with the
    capabilities of a debug port but several ones. Some of these ports are
    easier accessible than others, so making them configurable is also necessary.
    
    If southbridge has HAVE_USBDEBUG_OPTIONS, mainboard Kconfig can override
    USBDEBUG_DEV and USBDEBUG_FN to use the controller with USB Debug Port
    available externally.
    
    Change-Id: I079643870104fbc64091a54e1bfd56ad24422c9f
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/arch/x86/include/arch/io.h                     |  2 ++
 src/console/Kconfig                                |  8 ++++++--
 src/console/usbdebug_console.c                     |  2 +-
 src/include/usbdebug.h                             |  3 +++
 src/southbridge/amd/agesa/hudson/enable_usbdebug.c |  9 +++++---
 src/southbridge/amd/sb600/enable_usbdebug.c        |  4 +++-
 src/southbridge/amd/sb700/enable_usbdebug.c        | 14 +++++++------
 src/southbridge/amd/sb800/enable_usbdebug.c        |  9 +++++---
 src/southbridge/intel/bd82x6x/Kconfig              | 10 ++++++++-
 src/southbridge/intel/i82801gx/usb_debug.c         | 24 +++++++++++++++++++---
 src/southbridge/intel/lynxpoint/Kconfig            | 10 ++++++++-
 src/southbridge/nvidia/ck804/enable_usbdebug.c     |  6 ++++--
 src/southbridge/nvidia/mcp55/enable_usbdebug.c     |  6 ++++--
 src/southbridge/sis/sis966/enable_usbdebug.c       |  6 ++++--
 14 files changed, 86 insertions(+), 27 deletions(-)

diff --git a/src/arch/x86/include/arch/io.h b/src/arch/x86/include/arch/io.h
index 29c8339..552c99d 100644
--- a/src/arch/x86/include/arch/io.h
+++ b/src/arch/x86/include/arch/io.h
@@ -203,6 +203,8 @@ static inline int log2f(int value)
 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
 	((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
 
+/* Translation from devicetree path.pci.devfn to PCI_DEV(). */
+#define PCI_DEVFN2DEV(devfn)	((devfn&0xff)<<12)
 
 #define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
 
diff --git a/src/console/Kconfig b/src/console/Kconfig
index dc41fd3..831e568 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -127,9 +127,13 @@ config SPKMODEM
 
 # Use "select HAVE_USBDEBUG" on southbridges which have Debug Port code.
 config HAVE_USBDEBUG
-	def_bool n
+	bool
+	default y if HAVE_USBDEBUG_OPTIONS
+	default n
 
-config USBDEBUG
+# Use "select HAVE_USBDEBUG_OPTIONS" on southbridges with multiple
+# EHCI controllers having Debug Port capability
+config HAVE_USBDEBUG_OPTIONS
 	def_bool n
 
 config USBDEBUG
diff --git a/src/console/usbdebug_console.c b/src/console/usbdebug_console.c
index ab21ec4..9df8ff2 100644
--- a/src/console/usbdebug_console.c
+++ b/src/console/usbdebug_console.c
@@ -77,7 +77,7 @@ void pci_ehci_read_resources(struct device *dev)
 {
 	printk(BIOS_DEBUG, "%s EHCI controller\n", dev_path(dev));
 
-	if (!ehci_drv_ops) {
+	if (!ehci_drv_ops && dev->path.pci.devfn == ehci_dbg_devfn) {
 		memcpy(&ehci_dbg_ops, dev->ops, sizeof(ehci_dbg_ops));
 		ehci_drv_ops = dev->ops;
 		ehci_dbg_ops.set_resources = pci_ehci_set_resources;
diff --git a/src/include/usbdebug.h b/src/include/usbdebug.h
index 961481a..3099116 100644
--- a/src/include/usbdebug.h
+++ b/src/include/usbdebug.h
@@ -22,6 +22,9 @@
 #define USBDEBUG_H
 
 #define EHCI_BAR_INDEX		0x10
+#define PCI_EHCI_CLASSCODE 	0x0c0320	/* USB2.0 with EHCI controller */
+
+extern const unsigned ehci_dbg_devfn;
 
 #ifndef __PRE_RAM__
 #if !CONFIG_USBDEBUG
diff --git a/src/southbridge/amd/agesa/hudson/enable_usbdebug.c b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
index af900a3..c4f5ba4 100644
--- a/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
+++ b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
@@ -34,6 +34,8 @@
 #define EHCI_EOR		(CONFIG_EHCI_BAR + 0x20)
 #define DEBUGPORT_MISC_CONTROL	(EHCI_EOR + 0x80)
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(HUDSON_DEVN_BASE + 0x12, 2);
+
 void set_debug_port(unsigned int port)
 {
 	u32 reg32;
@@ -49,12 +51,13 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
+
 	/* Enable all of the USB controllers */
 	outb(0xEF, PM_INDEX);
 	outb(0x7F, PM_DATA);
 
-	pci_write_config32(PCI_DEV(0, HUDSON_DEVN_BASE + 0x12, 2),
-			   EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-	pci_write_config8(PCI_DEV(0, HUDSON_DEVN_BASE + 0x12, 2), 0x04, 0x6);	/* mem space enabe */
+	pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+	pci_write_config8(dev, 0x04, 0x6);	/* mem space enabe */
 	set_debug_port(port);
 }
diff --git a/src/southbridge/amd/sb600/enable_usbdebug.c b/src/southbridge/amd/sb600/enable_usbdebug.c
index b1963ba..ae9312c 100644
--- a/src/southbridge/amd/sb600/enable_usbdebug.c
+++ b/src/southbridge/amd/sb600/enable_usbdebug.c
@@ -27,6 +27,8 @@
 #include <device/pci_def.h>
 #include "sb600.h"
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(0x13, 5); /* USB EHCI, D19:F5 */
+
 /* Required for successful build, but currently empty. */
 void set_debug_port(unsigned int port)
 {
@@ -35,7 +37,7 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
-	device_t dev = PCI_DEV(0, 0x13, 5); /* USB EHCI, D19:F5 */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Select the requested physical USB port (1-15) as the Debug Port. */
 	set_debug_port(port);
diff --git a/src/southbridge/amd/sb700/enable_usbdebug.c b/src/southbridge/amd/sb700/enable_usbdebug.c
index f7fdf06..c7f082b 100644
--- a/src/southbridge/amd/sb700/enable_usbdebug.c
+++ b/src/southbridge/amd/sb700/enable_usbdebug.c
@@ -31,6 +31,13 @@
 #define EHCI_EOR		(CONFIG_EHCI_BAR + 0x20)
 #define DEBUGPORT_MISC_CONTROL	(EHCI_EOR + 0x80)
 
+/*
+ * Note: The SB700 has two EHCI devices, D18:F2 and D19:F2.
+ * This code currently only supports the first one, i.e., USB Debug devices
+ * attached to physical USB ports belonging to the first EHCI device.
+ */
+const unsigned ehci_dbg_devfn = PCI_DEVFN(0x12, 2);
+
 void set_debug_port(unsigned int port)
 {
 	u32 reg32;
@@ -43,14 +50,9 @@ void set_debug_port(unsigned int port)
 	write32(DEBUGPORT_MISC_CONTROL, reg32);
 }
 
-/*
- * Note: The SB700 has two EHCI devices, D18:F2 and D19:F2.
- * This code currently only supports the first one, i.e., USB Debug devices
- * attached to physical USB ports belonging to the first EHCI device.
- */
 void enable_usbdebug(unsigned int port)
 {
-	device_t dev = PCI_DEV(0, 0x12, 2); /* USB EHCI, D18:F2 */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Set the EHCI BAR address. */
 	pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
diff --git a/src/southbridge/amd/sb800/enable_usbdebug.c b/src/southbridge/amd/sb800/enable_usbdebug.c
index 98e9bb0..4370f4c 100644
--- a/src/southbridge/amd/sb800/enable_usbdebug.c
+++ b/src/southbridge/amd/sb800/enable_usbdebug.c
@@ -34,6 +34,8 @@
 #define EHCI_EOR		(CONFIG_EHCI_BAR + 0x20)
 #define DEBUGPORT_MISC_CONTROL	(EHCI_EOR + 0x80)
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(SB800_DEVN_BASE + 0x12, 2);
+
 void set_debug_port(unsigned int port)
 {
 	u32 reg32;
@@ -49,12 +51,13 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
+
 	/* Enable all of the USB controllers */
 	outb(0xEF, PM_INDEX);
 	outb(0x7F, PM_DATA);
 
-	pci_write_config32(PCI_DEV(0, SB800_DEVN_BASE + 0x12, 2),
-			   EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-	pci_write_config8(PCI_DEV(0, SB800_DEVN_BASE + 0x12, 2), 0x04, 0x6);	/* mem space enabe */
+	pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+	pci_write_config8(dev, 0x04, 0x6);	/* mem space enabe */
 	set_debug_port(port);
 }
diff --git a/src/southbridge/intel/bd82x6x/Kconfig b/src/southbridge/intel/bd82x6x/Kconfig
index 79c812e..bd77115 100644
--- a/src/southbridge/intel/bd82x6x/Kconfig
+++ b/src/southbridge/intel/bd82x6x/Kconfig
@@ -29,7 +29,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
 	def_bool y
 	select IOAPIC
 	select HAVE_HARD_RESET
-	select HAVE_USBDEBUG
+	select HAVE_USBDEBUG_OPTIONS
 	select HAVE_SMI_HANDLER
 	select USE_WATCHDOG_ON_BOOT
 	select PCIEXP_ASPM
@@ -85,4 +85,12 @@ config LOCK_MANAGEMENT_ENGINE
 
 	  If unsure, say N.
 
+config USBDEBUG_DEV
+	int
+	default 29
+
+config USBDEBUG_FUNC
+	int
+	default 7
+
 endif
diff --git a/src/southbridge/intel/i82801gx/usb_debug.c b/src/southbridge/intel/i82801gx/usb_debug.c
index 008c153..4546dbb 100644
--- a/src/southbridge/intel/i82801gx/usb_debug.c
+++ b/src/southbridge/intel/i82801gx/usb_debug.c
@@ -27,16 +27,34 @@
 #include <usbdebug.h>
 #include <device/pci_def.h>
 
+#if CONFIG_HAVE_USBDEBUG_OPTIONS
+const unsigned ehci_dbg_devfn = PCI_DEVFN(CONFIG_USBDEBUG_DEV, CONFIG_USBDEBUG_FUNC);
+#else
+const unsigned ehci_dbg_devfn = PCI_DEVFN(0x1d, 7);
+#endif
+
 /* Required for successful build, but currently empty. */
 void set_debug_port(unsigned int port)
 {
 	/* Not needed, the ICH* southbridges hardcode physical USB port 1. */
 }
-
 void enable_usbdebug(unsigned int port)
 {
-	u32 dbgctl;
-	device_t dev = PCI_DEV(0, 0x1d, 7); /* USB EHCI, D29:F7 */
+	u32 dbgctl, class;
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
+
+	class = pci_read_config32(dev, PCI_CLASS_REVISION) >> 8;
+	if (class != PCI_EHCI_CLASSCODE) {
+		/* If we enter here before RCBA programming, EHCI function may
+		 * appear with the highest function number instead.
+		 */
+		dev |= PCI_DEV(0, 0, 7);
+		class = pci_read_config32(dev, PCI_CLASS_REVISION) >> 8;
+	}
+
+	/* Bail out. No console to complain in. */
+	if (class != PCI_EHCI_CLASSCODE)
+		return;
 
 	/* Set the EHCI BAR address. */
 	pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig
index f79e963..cc5139b 100644
--- a/src/southbridge/intel/lynxpoint/Kconfig
+++ b/src/southbridge/intel/lynxpoint/Kconfig
@@ -26,7 +26,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
 	def_bool y
 	select IOAPIC
 	select HAVE_HARD_RESET
-	select HAVE_USBDEBUG
+	select HAVE_USBDEBUG_OPTIONS
 	select USE_WATCHDOG_ON_BOOT
 	select PCIEXP_ASPM
 	select PCIEXP_COMMON_CLOCK
@@ -58,4 +58,12 @@ config SERIRQ_CONTINUOUS_MODE
 	  If you set this option to y, the serial IRQ machine will be
 	  operated in continuous mode.
 
+config USBDEBUG_DEV
+	int
+	default 29
+
+config USBDEBUG_FUNC
+	int
+	default 7
+
 endif
diff --git a/src/southbridge/nvidia/ck804/enable_usbdebug.c b/src/southbridge/nvidia/ck804/enable_usbdebug.c
index 1842a33..fc22f9f 100644
--- a/src/southbridge/nvidia/ck804/enable_usbdebug.c
+++ b/src/southbridge/nvidia/ck804/enable_usbdebug.c
@@ -37,10 +37,12 @@
 #define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
 #endif
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+
 void set_debug_port(unsigned int port)
 {
 	u32 dword;
-	device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Write the port number to 0x74[15:12]. */
 	dword = pci_read_config32(dev, 0x74);
@@ -51,7 +53,7 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
-	device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Mark the requested physical USB port (1-15) as the Debug Port. */
 	set_debug_port(port);
diff --git a/src/southbridge/nvidia/mcp55/enable_usbdebug.c b/src/southbridge/nvidia/mcp55/enable_usbdebug.c
index cb32944..ef016e2 100644
--- a/src/southbridge/nvidia/mcp55/enable_usbdebug.c
+++ b/src/southbridge/nvidia/mcp55/enable_usbdebug.c
@@ -31,10 +31,12 @@
 #include <device/pci_def.h>
 #include "mcp55.h"
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+
 void set_debug_port(unsigned int port)
 {
 	u32 dword;
-	device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Write the port number to 0x74[15:12]. */
 	dword = pci_read_config32(dev, 0x74);
@@ -45,7 +47,7 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
-	device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Mark the requested physical USB port (1-15) as the Debug Port. */
 	set_debug_port(port);
diff --git a/src/southbridge/sis/sis966/enable_usbdebug.c b/src/southbridge/sis/sis966/enable_usbdebug.c
index e4252e3..6545296 100644
--- a/src/southbridge/sis/sis966/enable_usbdebug.c
+++ b/src/southbridge/sis/sis966/enable_usbdebug.c
@@ -33,10 +33,12 @@
 #include <device/pci_def.h>
 #include "sis966.h"
 
+const unsigned ehci_dbg_devfn = PCI_DEVFN(SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+
 void set_debug_port(unsigned int port)
 {
 	u32 dword;
-	device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Write the port number to 0x74[15:12]. */
 	dword = pci_read_config32(dev, 0x74);
@@ -47,7 +49,7 @@ void set_debug_port(unsigned int port)
 
 void enable_usbdebug(unsigned int port)
 {
-	device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+	device_t dev = PCI_DEVFN2DEV(ehci_dbg_devfn);
 
 	/* Mark the requested physical USB port (1-15) as the Debug Port. */
 	set_debug_port(port);



More information about the coreboot-gerrit mailing list