summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/console/Kconfig19
-rw-r--r--src/include/usbdebug.h10
-rw-r--r--src/lib/usbdebug.c32
-rw-r--r--src/southbridge/amd/agesa/hudson/enable_usbdebug.c18
-rw-r--r--src/southbridge/amd/sb600/enable_usbdebug.c13
-rw-r--r--src/southbridge/amd/sb700/enable_usbdebug.c26
-rw-r--r--src/southbridge/amd/sb800/enable_usbdebug.c18
-rw-r--r--src/southbridge/intel/common/usb_debug.c16
-rw-r--r--src/southbridge/nvidia/ck804/enable_usbdebug.c14
-rw-r--r--src/southbridge/nvidia/mcp55/enable_usbdebug.c14
-rw-r--r--src/southbridge/sis/sis966/enable_usbdebug.c14
11 files changed, 132 insertions, 62 deletions
diff --git a/src/console/Kconfig b/src/console/Kconfig
index b753be4023..38f51e361b 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -143,6 +143,13 @@ config SPKMODEM
# Use "select HAVE_USBDEBUG" on southbridges which have Debug Port code.
config HAVE_USBDEBUG
+ bool
+ default y if HAVE_USBDEBUG_OPTIONS
+ default n
+
+# Use "select HAVE_USBDEBUG_OPTIONS" on southbridges with multiple
+# EHCI controllers or multiple ports with Debug Port capability
+config HAVE_USBDEBUG_OPTIONS
def_bool n
config USBDEBUG
@@ -166,6 +173,18 @@ config USBDEBUG
If unsure, say N.
+config USBDEBUG_HCD_INDEX
+ int "Index for EHCI controller to use with usbdebug"
+ default 0
+ depends on USBDEBUG
+ help
+ Some boards have multiple EHCI controllers with possibly only
+ one having the Debug Port capability on an external USB port.
+
+ Mapping of this index to PCI device functions is southbridge
+ specific and mainboard level Kconfig should already provide
+ a working default value here.
+
config USBDEBUG_DEFAULT_PORT
int "Default USB port to use as Debug Port"
default 0
diff --git a/src/include/usbdebug.h b/src/include/usbdebug.h
index 2728be0e4f..926d6585d0 100644
--- a/src/include/usbdebug.h
+++ b/src/include/usbdebug.h
@@ -22,6 +22,13 @@
#define USBDEBUG_H
#define EHCI_BAR_INDEX 0x10
+#define PCI_EHCI_CLASSCODE 0x0c0320 /* USB2.0 with EHCI controller */
+
+typedef u32 pci_devfn_t;
+pci_devfn_t pci_ehci_dbg_dev(unsigned hcd_idx);
+unsigned long pci_ehci_base_regs(pci_devfn_t dev);
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port);
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base);
#ifndef __PRE_RAM__
#if !CONFIG_USBDEBUG
@@ -42,9 +49,6 @@ void pci_ehci_read_resources(struct device *dev);
struct dbgp_pipe;
-void enable_usbdebug(unsigned int port);
-void set_debug_port(unsigned port);
-
int usbdebug_init(void);
struct dbgp_pipe *dbgp_console_output(void);
diff --git a/src/lib/usbdebug.c b/src/lib/usbdebug.c
index c9247881f0..a319da92b8 100644
--- a/src/lib/usbdebug.c
+++ b/src/lib/usbdebug.c
@@ -22,6 +22,7 @@
#include <console/console.h>
#include <arch/io.h>
#include <device/pci.h>
+#include <device/pci_def.h>
#include <arch/byteorder.h>
#include <cpu/x86/car.h>
#include <string.h>
@@ -401,6 +402,20 @@ static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port)
return -1; //-ENOTCONN;
}
+#if defined(__PRE_RAM__) || !CONFIG_EARLY_CONSOLE
+static void enable_usbdebug(void)
+{
+ pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
+ pci_ehci_dbg_enable(dbg_dev, CONFIG_EHCI_BAR);
+}
+#endif
+
+static void set_debug_port(unsigned int port)
+{
+ pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
+ pci_ehci_dbg_set_port(dbg_dev, port);
+}
+
static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_info *info)
{
struct ehci_caps *ehci_caps;
@@ -751,7 +766,9 @@ static void pci_ehci_set_resources(struct device *dev)
void pci_ehci_read_resources(struct device *dev)
{
- if (!ehci_drv_ops) {
+ pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
+
+ if (!ehci_drv_ops && pci_match_simple_dev(dev, dbg_dev)) {
memcpy(&ehci_dbg_ops, dev->ops, sizeof(ehci_dbg_ops));
ehci_drv_ops = dev->ops;
ehci_dbg_ops.set_resources = pci_ehci_set_resources;
@@ -765,6 +782,17 @@ void pci_ehci_read_resources(struct device *dev)
}
#endif
+unsigned long pci_ehci_base_regs(pci_devfn_t sdev)
+{
+#ifdef __SIMPLE_DEVICE__
+ unsigned long base = pci_read_config32(sdev, EHCI_BAR_INDEX) & ~0x0f;
+#else
+ device_t dev = dev_find_slot(PCI_DEV2SEGBUS(sdev), PCI_DEV2DEVFN(sdev));
+ unsigned long base = pci_read_config32(dev, EHCI_BAR_INDEX) & ~0x0f;
+#endif
+ return base + HC_LENGTH(read32(base));
+}
+
int dbgp_ep_is_active(struct dbgp_pipe *pipe)
{
return (pipe->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);
@@ -785,7 +813,7 @@ int usbdebug_init(void)
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
#if defined(__PRE_RAM__) || !CONFIG_EARLY_CONSOLE
- enable_usbdebug(0);
+ enable_usbdebug();
#endif
return usbdebug_init_(CONFIG_EHCI_BAR, CONFIG_EHCI_DEBUG_OFFSET, dbg_info);
}
diff --git a/src/southbridge/amd/agesa/hudson/enable_usbdebug.c b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
index 6fa17817f9..459df6ffad 100644
--- a/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
+++ b/src/southbridge/amd/agesa/hudson/enable_usbdebug.c
@@ -30,12 +30,16 @@
#define HUDSON_DEVN_BASE 0
#endif
-#define EHCI_EOR 0x20
#define DEBUGPORT_MISC_CONTROL 0x80
-void set_debug_port(unsigned int port)
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
{
- u32 base_regs = CONFIG_EHCI_BAR + EHCI_EOR;
+ return PCI_DEV(0, HUDSON_DEVN_BASE + 0x12, 2);
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
+{
+ u32 base_regs = pci_ehci_base_regs(dev);
u32 reg32;
/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
@@ -47,14 +51,12 @@ void set_debug_port(unsigned int port)
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
/* 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),
- PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
}
diff --git a/src/southbridge/amd/sb600/enable_usbdebug.c b/src/southbridge/amd/sb600/enable_usbdebug.c
index 40c53aecfa..09fce2f145 100644
--- a/src/southbridge/amd/sb600/enable_usbdebug.c
+++ b/src/southbridge/amd/sb600/enable_usbdebug.c
@@ -26,18 +26,21 @@
#include <device/pci_def.h>
#include "sb600.h"
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, 0x13, 5); /* USB EHCI, D19:F5 */
+}
+
/* Required for successful build, but currently empty. */
-void set_debug_port(unsigned int port)
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
/* TODO: Allow changing the physical USB port used as Debug Port. */
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
- pci_devfn_t dev = PCI_DEV(0, 0x13, 5); /* USB EHCI, D19:F5 */
-
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
diff --git a/src/southbridge/amd/sb700/enable_usbdebug.c b/src/southbridge/amd/sb700/enable_usbdebug.c
index 0712d2af2d..3d44a1ac0c 100644
--- a/src/southbridge/amd/sb700/enable_usbdebug.c
+++ b/src/southbridge/amd/sb700/enable_usbdebug.c
@@ -27,12 +27,21 @@
#include <device/pci_def.h>
#include "sb700.h"
-#define EHCI_EOR 0x20
#define DEBUGPORT_MISC_CONTROL 0x80
-void set_debug_port(unsigned int port)
+/*
+ * 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.
+ */
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, 0x12, 2);
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
- u32 base_regs = CONFIG_EHCI_BAR + EHCI_EOR;
+ u32 base_regs = pci_ehci_base_regs(dev);
u32 reg32;
/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
@@ -43,17 +52,10 @@ void set_debug_port(unsigned int port)
write32(base_regs + 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)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
- pci_devfn_t dev = PCI_DEV(0, 0x12, 2); /* USB EHCI, D18:F2 */
-
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
diff --git a/src/southbridge/amd/sb800/enable_usbdebug.c b/src/southbridge/amd/sb800/enable_usbdebug.c
index 6422fa2295..92778698f2 100644
--- a/src/southbridge/amd/sb800/enable_usbdebug.c
+++ b/src/southbridge/amd/sb800/enable_usbdebug.c
@@ -30,12 +30,16 @@
#define SB800_DEVN_BASE 0
#endif
-#define EHCI_EOR 0x20
#define DEBUGPORT_MISC_CONTROL 0x80
-void set_debug_port(unsigned int port)
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
{
- u32 base_regs = CONFIG_EHCI_BAR + EHCI_EOR;
+ return PCI_DEV(0, SB800_DEVN_BASE + 0x12, 2);
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
+{
+ u32 base_regs = pci_ehci_base_regs(dev);
u32 reg32;
/* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
@@ -47,14 +51,12 @@ void set_debug_port(unsigned int port)
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
/* 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),
- PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
}
diff --git a/src/southbridge/intel/common/usb_debug.c b/src/southbridge/intel/common/usb_debug.c
index 6b934f4fa0..3fed2ab854 100644
--- a/src/southbridge/intel/common/usb_debug.c
+++ b/src/southbridge/intel/common/usb_debug.c
@@ -26,25 +26,29 @@
#include <usbdebug.h>
#include <device/pci_def.h>
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, 0x1d, 7);
+}
+
/* Required for successful build, but currently empty. */
-void set_debug_port(unsigned int port)
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
/* Not needed, the ICH* southbridges hardcode physical USB port 1. */
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
u32 dbgctl;
- pci_devfn_t dev = PCI_DEV(0, 0x1d, 7); /* USB EHCI, D29:F7 */
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
/* Force ownership of the Debug Port to the EHCI controller. */
- dbgctl = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET);
+ dbgctl = read32(base + CONFIG_EHCI_DEBUG_OFFSET);
dbgctl |= (1 << 30);
- write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
+ write32(base + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
}
diff --git a/src/southbridge/nvidia/ck804/enable_usbdebug.c b/src/southbridge/nvidia/ck804/enable_usbdebug.c
index d65fea212d..d98bc984fb 100644
--- a/src/southbridge/nvidia/ck804/enable_usbdebug.c
+++ b/src/southbridge/nvidia/ck804/enable_usbdebug.c
@@ -36,10 +36,14 @@
#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
#endif
-void set_debug_port(unsigned int port)
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
u32 dword;
- pci_devfn_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
/* Write the port number to 0x74[15:12]. */
dword = pci_read_config32(dev, 0x74);
@@ -48,12 +52,10 @@ void set_debug_port(unsigned int port)
pci_write_config32(dev, 0x74, dword);
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
- pci_devfn_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
-
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
diff --git a/src/southbridge/nvidia/mcp55/enable_usbdebug.c b/src/southbridge/nvidia/mcp55/enable_usbdebug.c
index f629c505c3..b0afec28a4 100644
--- a/src/southbridge/nvidia/mcp55/enable_usbdebug.c
+++ b/src/southbridge/nvidia/mcp55/enable_usbdebug.c
@@ -30,10 +30,14 @@
#include <device/pci_def.h>
#include "mcp55.h"
-void set_debug_port(unsigned int port)
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
u32 dword;
- pci_devfn_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
/* Write the port number to 0x74[15:12]. */
dword = pci_read_config32(dev, 0x74);
@@ -42,12 +46,10 @@ void set_debug_port(unsigned int port)
pci_write_config32(dev, 0x74, dword);
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
- pci_devfn_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
-
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
diff --git a/src/southbridge/sis/sis966/enable_usbdebug.c b/src/southbridge/sis/sis966/enable_usbdebug.c
index 04384ba9ac..0d7503d66e 100644
--- a/src/southbridge/sis/sis966/enable_usbdebug.c
+++ b/src/southbridge/sis/sis966/enable_usbdebug.c
@@ -32,10 +32,14 @@
#include <device/pci_def.h>
#include "sis966.h"
-void set_debug_port(unsigned int port)
+pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
+{
+ return PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+}
+
+void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
{
u32 dword;
- pci_devfn_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
/* Write the port number to 0x74[15:12]. */
dword = pci_read_config32(dev, 0x74);
@@ -44,12 +48,10 @@ void set_debug_port(unsigned int port)
pci_write_config32(dev, 0x74, dword);
}
-void enable_usbdebug(unsigned int port)
+void pci_ehci_dbg_enable(pci_devfn_t dev, unsigned long base)
{
- pci_devfn_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
-
/* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+ pci_write_config32(dev, EHCI_BAR_INDEX, base);
/* Enable access to the EHCI memory space registers. */
pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);