aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2013-05-02 16:16:41 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-11-25 23:31:52 +0100
commit8992e53c23cb088efbdafbf3e2ba77e7d8778d71 (patch)
tree1eba559ee986c4994b63e75d9647fc733ae833f6
parent441a4baf87ada2608a109a203a5d8040f6dc2b0d (diff)
libpayload: Add USB support for non-PCI controllers
Restructure USB stack to not depend on PCI, and make PCI stub available on x86, but provide fixed BARs for ARM (Exynos 5) Change-Id: Iee7c8b134c22b661a9a515e24943470c9dbadd1f Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: https://gerrit.chromium.org/gerrit/49970 Reviewed-on: http://review.coreboot.org/4175 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
-rw-r--r--payloads/libpayload/Config.in28
-rw-r--r--payloads/libpayload/drivers/usb/ehci.c41
-rw-r--r--payloads/libpayload/drivers/usb/ehci.h3
-rw-r--r--payloads/libpayload/drivers/usb/ehci_private.h1
-rw-r--r--payloads/libpayload/drivers/usb/ehci_rh.c2
-rw-r--r--payloads/libpayload/drivers/usb/ohci.c24
-rw-r--r--payloads/libpayload/drivers/usb/ohci.h5
-rw-r--r--payloads/libpayload/drivers/usb/ohci_private.h1
-rw-r--r--payloads/libpayload/drivers/usb/uhci.c11
-rw-r--r--payloads/libpayload/drivers/usb/uhci.h4
-rw-r--r--payloads/libpayload/drivers/usb/usbhub.c2
-rw-r--r--payloads/libpayload/drivers/usb/usbinit.c33
-rw-r--r--payloads/libpayload/drivers/usb/usbmsc.c1
-rw-r--r--payloads/libpayload/drivers/usb/xhci.c36
-rw-r--r--payloads/libpayload/drivers/usb/xhci.h5
-rw-r--r--payloads/libpayload/include/usb/usb.h3
16 files changed, 142 insertions, 58 deletions
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index 6610f8f785..bb5176f712 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -326,7 +326,7 @@ config USB
config USB_UHCI
bool "Support for USB UHCI controllers"
- depends on USB
+ depends on USB && ARCH_X86
help
Select this option if you are going to use USB 1.1 on an Intel based
system.
@@ -335,7 +335,7 @@ config USB_OHCI
bool "Support for USB OHCI controllers"
depends on USB
help
- Select this option if you are going to use USB 1.1 on an AMD based
+ Select this option if you are going to use USB 1.1 on a non-Intel based
system.
config USB_EHCI
@@ -382,6 +382,30 @@ config USB_GEN_HUB
bool
default n if (!USB_HUB && !USB_XHCI)
default y if (USB_HUB || USB_XHCI)
+config USB_PCI
+ bool
+ default y if ARCH_X86
+ default n
+
+config USB_MEMORY
+ bool
+ default y if ARCH_ARMV7
+ default n
+
+config USB_OHCI_BASE_ADDRESS
+ hex
+ depends on USB_MEMORY && USB_OHCI
+ default 0x12120000
+
+config USB_EHCI_BASE_ADDRESS
+ hex
+ depends on USB_MEMORY && USB_EHCI
+ default 0x12110000
+
+config USB_XHCI_BASE_ADDRESS
+ hex
+ depends on USB_MEMORY && USB_XHCI
+ default 0x12000000
endmenu
diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c
index f5c14d5031..e61e806345 100644
--- a/payloads/libpayload/drivers/usb/ehci.c
+++ b/payloads/libpayload/drivers/usb/ehci.c
@@ -69,7 +69,7 @@ static void dump_td(u32 addr)
usb_debug("+---------------------------------------------------+\n");
}
-#ifdef USB_DEBUG
+#if 0 && defined(USB_DEBUG)
static void dump_qh(ehci_qh_t *cur)
{
qtd_t *tmp_qtd = NULL;
@@ -724,7 +724,7 @@ static u8 *ehci_poll_intr_queue(void *const queue)
}
hci_t *
-ehci_init (pcidev_t addr)
+ehci_init (void *bar)
{
int i;
hci_t *controller = new_controller ();
@@ -736,15 +736,6 @@ ehci_init (pcidev_t addr)
if(!controller->instance)
fatal("Not enough memory creating USB controller instance.\n");
-#define PCI_COMMAND 4
-#define PCI_COMMAND_IO 1
-#define PCI_COMMAND_MEMORY 2
-#define PCI_COMMAND_MASTER 4
-
- u32 pci_command = pci_read_config32(addr, PCI_COMMAND);
- pci_command = (pci_command | PCI_COMMAND_MEMORY) & ~PCI_COMMAND_IO ;
- pci_write_config32(addr, PCI_COMMAND, pci_command);
-
controller->type = EHCI;
controller->start = ehci_start;
@@ -760,8 +751,7 @@ ehci_init (pcidev_t addr)
controller->create_intr_queue = ehci_create_intr_queue;
controller->destroy_intr_queue = ehci_destroy_intr_queue;
controller->poll_intr_queue = ehci_poll_intr_queue;
- controller->bus_address = addr;
- controller->reg_base = pci_read_config32 (controller->bus_address, USBBASE);
+ controller->reg_base = (u32)(unsigned long)bar;
for (i = 0; i < 128; i++) {
controller->devices[i] = 0;
}
@@ -770,9 +760,6 @@ ehci_init (pcidev_t addr)
EHCI_INST(controller)->capabilities = phys_to_virt(controller->reg_base);
EHCI_INST(controller)->operation = (hc_op_t *)(phys_to_virt(controller->reg_base) + EHCI_INST(controller)->capabilities->caplength);
- /* default value for frame length adjust */
- pci_write_config8(addr, FLADJ, FLADJ_framelength(60000));
-
/* Set the high address word (aka segment) if controller is 64-bit */
if (EHCI_INST(controller)->capabilities->hccparams & 1)
EHCI_INST(controller)->operation->ctrldssegment = 0;
@@ -818,3 +805,25 @@ ehci_init (pcidev_t addr)
return controller;
}
+
+#ifdef CONFIG_USB_PCI
+hci_t *
+ehci_pci_init (pcidev_t addr)
+{
+ hci_t *controller;
+ u32 reg_base;
+
+ u32 pci_command = pci_read_config32(addr, PCI_COMMAND);
+ pci_command = (pci_command | PCI_COMMAND_MEMORY) & ~PCI_COMMAND_IO ;
+ pci_write_config32(addr, PCI_COMMAND, pci_command);
+
+ reg_base = pci_read_config32 (addr, USBBASE);
+
+ /* default value for frame length adjust */
+ pci_write_config8(addr, FLADJ, FLADJ_framelength(60000));
+
+ controller = ehci_init((void *)(unsigned long)reg_base);
+
+ return controller;
+}
+#endif
diff --git a/payloads/libpayload/drivers/usb/ehci.h b/payloads/libpayload/drivers/usb/ehci.h
index c66643c702..c1b1fa9f70 100644
--- a/payloads/libpayload/drivers/usb/ehci.h
+++ b/payloads/libpayload/drivers/usb/ehci.h
@@ -33,7 +33,8 @@
#include <pci.h>
#include <usb/usb.h>
-hci_t *ehci_init (pcidev_t addr);
+hci_t *ehci_pci_init (pcidev_t addr);
+hci_t *ehci_init (void *bar);
void ehci_rh_init (usbdev_t *dev);
diff --git a/payloads/libpayload/drivers/usb/ehci_private.h b/payloads/libpayload/drivers/usb/ehci_private.h
index 3365be1977..986ee791bf 100644
--- a/payloads/libpayload/drivers/usb/ehci_private.h
+++ b/payloads/libpayload/drivers/usb/ehci_private.h
@@ -30,7 +30,6 @@
#ifndef __EHCI_PRIVATE_H
#define __EHCI_PRIVATE_H
-#include <pci.h>
#include <usb/usb.h>
#define USBBASE 0x10
diff --git a/payloads/libpayload/drivers/usb/ehci_rh.c b/payloads/libpayload/drivers/usb/ehci_rh.c
index 89828040d1..5c4daeda8a 100644
--- a/payloads/libpayload/drivers/usb/ehci_rh.c
+++ b/payloads/libpayload/drivers/usb/ehci_rh.c
@@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/
+//#define USB_DEBUG
+
#include <libpayload.h>
#include "ehci.h"
#include "ehci_private.h"
diff --git a/payloads/libpayload/drivers/usb/ohci.c b/payloads/libpayload/drivers/usb/ohci.c
index 95db5f4af8..edd275bb19 100644
--- a/payloads/libpayload/drivers/usb/ohci.c
+++ b/payloads/libpayload/drivers/usb/ohci.c
@@ -136,7 +136,7 @@ ohci_reinit (hci_t *controller)
{
}
-#ifdef USB_DEBUG
+#if 0 && defined(USB_DEBUG)
/* Section 4.3.3 */
static const char *completion_codes[] = {
"No error",
@@ -167,7 +167,7 @@ static const char *direction[] = {
#endif
hci_t *
-ohci_init (pcidev_t addr)
+ohci_init (void *bar)
{
int i;
@@ -201,10 +201,7 @@ ohci_init (pcidev_t addr)
init_device_entry (controller, 0);
OHCI_INST (controller)->roothub = controller->devices[0];
- controller->bus_address = addr;
- /* regarding OHCI spec, Appendix A, BAR_OHCI register description, Table A-4
- * BASE ADDRESS only [31-12] bits. All other usually 0, but not all */
- controller->reg_base = pci_read_config32 (controller->bus_address, 0x10) & 0xfffff000; // OHCI mandates MMIO, so bit 0 is clear
+ controller->reg_base = (u32)(unsigned long)bar;
OHCI_INST (controller)->opreg = (opreg_t*)phys_to_virt(controller->reg_base);
usb_debug("OHCI Version %x.%x\n", (OHCI_INST (controller)->opreg->HcRevision >> 4) & 0xf, OHCI_INST (controller)->opreg->HcRevision & 0xf);
@@ -255,6 +252,21 @@ ohci_init (pcidev_t addr)
return controller;
}
+#ifdef CONFIG_USB_PCI
+hci_t *
+ohci_pci_init (pcidev_t addr)
+{
+ u32 reg_base;
+
+ /* regarding OHCI spec, Appendix A, BAR_OHCI register description, Table A-4
+ * BASE ADDRESS only [31-12] bits. All other usually 0, but not all.
+ * OHCI mandates MMIO, so bit 0 is clear */
+ reg_base = pci_read_config32 (addr, 0x10) & 0xfffff000;
+
+ return ohci_init((void *)(unsigned long)reg_base);
+}
+#endif
+
static void
ohci_shutdown (hci_t *controller)
{
diff --git a/payloads/libpayload/drivers/usb/ohci.h b/payloads/libpayload/drivers/usb/ohci.h
index f5011676a1..9c31d9c015 100644
--- a/payloads/libpayload/drivers/usb/ohci.h
+++ b/payloads/libpayload/drivers/usb/ohci.h
@@ -33,8 +33,9 @@
#include <pci.h>
#include <usb/usb.h>
- hci_t *ohci_init (pcidev_t addr);
+hci_t *ohci_pci_init (pcidev_t addr);
+hci_t *ohci_init (void *bar);
- void ohci_rh_init (usbdev_t *dev);
+void ohci_rh_init (usbdev_t *dev);
#endif
diff --git a/payloads/libpayload/drivers/usb/ohci_private.h b/payloads/libpayload/drivers/usb/ohci_private.h
index a32203c582..b6eaf6b449 100644
--- a/payloads/libpayload/drivers/usb/ohci_private.h
+++ b/payloads/libpayload/drivers/usb/ohci_private.h
@@ -30,7 +30,6 @@
#ifndef __OHCI_PRIVATE_H
#define __OHCI_PRIVATE_H
-#include <pci.h>
#include <usb/usb.h>
#define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
diff --git a/payloads/libpayload/drivers/usb/uhci.c b/payloads/libpayload/drivers/usb/uhci.c
index f9c361de22..b81b911eef 100644
--- a/payloads/libpayload/drivers/usb/uhci.c
+++ b/payloads/libpayload/drivers/usb/uhci.c
@@ -147,7 +147,7 @@ uhci_reinit (hci_t *controller)
}
hci_t *
-uhci_init (pcidev_t addr)
+uhci_pci_init (pcidev_t addr)
{
int i;
u16 reg16;
@@ -182,16 +182,17 @@ uhci_init (pcidev_t addr)
init_device_entry (controller, 0);
UHCI_INST (controller)->roothub = controller->devices[0];
- controller->bus_address = addr;
- controller->reg_base = pci_read_config32 (controller->bus_address, 0x20) & ~1; /* ~1 clears the register type indicator that is set to 1 for IO space */
+ /* ~1 clears the register type indicator that is set to 1
+ * for IO space */
+ controller->reg_base = pci_read_config32 (addr, 0x20) & ~1;
/* kill legacy support handler */
uhci_stop (controller);
mdelay (1);
uhci_reg_write16 (controller, USBSTS, 0x3f);
- reg16 = pci_read_config16(controller->bus_address, 0xc0);
+ reg16 = pci_read_config16(addr, 0xc0);
reg16 &= 0xdf80;
- pci_write_config16 (controller->bus_address, 0xc0, reg16);
+ pci_write_config16 (addr, 0xc0, reg16);
UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t)); /* 4kb aligned to 4kb */
if (! UHCI_INST (controller)->framelistptr)
diff --git a/payloads/libpayload/drivers/usb/uhci.h b/payloads/libpayload/drivers/usb/uhci.h
index 2ef3f0b499..6bb5c17528 100644
--- a/payloads/libpayload/drivers/usb/uhci.h
+++ b/payloads/libpayload/drivers/usb/uhci.h
@@ -33,8 +33,8 @@
#include <pci.h>
#include <usb/usb.h>
- hci_t *uhci_init (pcidev_t addr);
+hci_t *uhci_pci_init (pcidev_t addr);
- void uhci_rh_init (usbdev_t *dev);
+void uhci_rh_init (usbdev_t *dev);
#endif
diff --git a/payloads/libpayload/drivers/usb/usbhub.c b/payloads/libpayload/drivers/usb/usbhub.c
index 20e064e872..4e077f6848 100644
--- a/payloads/libpayload/drivers/usb/usbhub.c
+++ b/payloads/libpayload/drivers/usb/usbhub.c
@@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/
+//#define USB_DEBUG
+
#include <usb/usb.h>
#include "generic_hub.h"
diff --git a/payloads/libpayload/drivers/usb/usbinit.c b/payloads/libpayload/drivers/usb/usbinit.c
index 76653ff0d0..f74a833584 100644
--- a/payloads/libpayload/drivers/usb/usbinit.c
+++ b/payloads/libpayload/drivers/usb/usbinit.c
@@ -27,6 +27,7 @@
* SUCH DAMAGE.
*/
+//#define USB_DEBUG
#include <libpayload-config.h>
#include <usb/usb.h>
#include "uhci.h"
@@ -35,6 +36,7 @@
#include "xhci.h"
#include <usb/usbdisk.h>
+#ifdef CONFIG_USB_PCI
/**
* Initializes USB controller attached to PCI
*
@@ -58,8 +60,6 @@ static int usb_controller_initialize(int bus, int dev, int func)
prog_if = (class >> 8) & 0xff;
/* enable busmaster */
-#define PCI_COMMAND 4
-#define PCI_COMMAND_MASTER 4
if (devclass == 0xc03) {
u32 pci_command;
@@ -73,7 +73,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
case 0x00:
#ifdef CONFIG_USB_UHCI
usb_debug("UHCI controller\n");
- uhci_init (pci_device);
+ uhci_pci_init (pci_device);
#else
usb_debug("UHCI controller (not supported)\n");
#endif
@@ -82,7 +82,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
case 0x10:
#ifdef CONFIG_USB_OHCI
usb_debug("OHCI controller\n");
- ohci_init(pci_device);
+ ohci_pci_init(pci_device);
#else
usb_debug("OHCI controller (not supported)\n");
#endif
@@ -91,7 +91,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
case 0x20:
#ifdef CONFIG_USB_EHCI
usb_debug("EHCI controller\n");
- ehci_init(pci_device);
+ ehci_pci_init(pci_device);
#else
usb_debug("EHCI controller (not supported)\n");
#endif
@@ -100,7 +100,7 @@ static int usb_controller_initialize(int bus, int dev, int func)
case 0x30:
#ifdef CONFIG_USB_XHCI
usb_debug("xHCI controller\n");
- xhci_init(pci_device);
+ xhci_pci_init(pci_device);
#else
usb_debug("xHCI controller (not supported)\n");
#endif
@@ -154,12 +154,33 @@ static void usb_scan_pci_bus(int bus)
}
}
}
+#endif
+
+#ifdef CONFIG_USB_MEMORY
+static void usb_scan_memory(void)
+{
+#ifdef CONFIG_USB_XHCI
+ xhci_init((void *)(unsigned long)CONFIG_USB_XHCI_BASE_ADDRESS);
+#endif
+#ifdef CONFIG_USB_EHCI
+ ehci_init((void *)(unsigned long)CONFIG_USB_EHCI_BASE_ADDRESS);
+#endif
+#ifdef CONFIG_USB_OHCI
+ ohci_init((void *)(unsigned long)CONFIG_USB_OHCI_BASE_ADDRESS);
+#endif
+}
+#endif
/**
* Initialize all USB controllers attached to PCI.
*/
int usb_initialize(void)
{
+#ifdef CONFIG_USB_PCI
usb_scan_pci_bus(0);
+#endif
+#ifdef CONFIG_USB_MEMORY
+ usb_scan_memory();
+#endif
return 0;
}
diff --git a/payloads/libpayload/drivers/usb/usbmsc.c b/payloads/libpayload/drivers/usb/usbmsc.c
index 16af44888e..ad7e82f3b0 100644
--- a/payloads/libpayload/drivers/usb/usbmsc.c
+++ b/payloads/libpayload/drivers/usb/usbmsc.c
@@ -27,6 +27,7 @@
* SUCH DAMAGE.
*/
+//#define USB_DEBUG
#include <endian.h>
#include <usb/usb.h>
#include <usb/usbmsc.h>
diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c
index 51f9422ceb..aa2fe579a2 100644
--- a/payloads/libpayload/drivers/usb/xhci.c
+++ b/payloads/libpayload/drivers/usb/xhci.c
@@ -143,7 +143,7 @@ xhci_wait_ready(xhci_t *const xhci)
}
hci_t *
-xhci_init (const pcidev_t addr)
+xhci_init (const void *bar)
{
int i;
@@ -192,14 +192,7 @@ xhci_init (const pcidev_t addr)
goto _free_xhci;
}
- /* Now, gather information and check for compatibility */
-
- controller->bus_address = addr;
- controller->reg_base = pci_read_config32(addr, REG_BAR0) & ~0xf;
- if (pci_read_config32(addr, REG_BAR1) > 0) {
- xhci_debug("We don't do 64bit addressing\n");
- goto _free_xhci;
- }
+ controller->reg_base = (u32)(unsigned long)bar;
xhci->capreg = phys_to_virt(controller->reg_base);
xhci->opreg = ((void *)xhci->capreg) + xhci->capreg->caplength;
@@ -270,7 +263,6 @@ xhci_init (const pcidev_t addr)
}
/* Now start working on the hardware */
-
if (xhci_wait_ready(xhci))
goto _free_xhci;
@@ -279,8 +271,6 @@ xhci_init (const pcidev_t addr)
xhci_reset(controller);
xhci_reinit(controller);
- xhci_switch_ppt_ports(addr);
-
xhci->roothub->controller = controller;
xhci->roothub->init = xhci_rh_init;
xhci->roothub->init(xhci->roothub);
@@ -308,6 +298,28 @@ _free_controller:
return NULL;
}
+#ifdef CONFIG_USB_PCI
+hci_t *
+xhci_pci_init (pcidev_t addr)
+{
+ u32 reg_addr;
+ hci_t controller;
+
+ reg_addr = (u32)phys_to_virt(pci_read_config32 (addr, 0x10) & ~0xf);
+ //controller->reg_base = pci_read_config32 (addr, 0x14) & ~0xf;
+ if (pci_read_config32 (addr, 0x14) > 0) {
+ fatal("We don't do 64bit addressing.\n");
+ }
+
+ controller = xhci_init((void *)(unsigned long)reg_addr);
+ controller->bus_address = addr;
+
+ xhci_switch_ppt_ports(addr);
+
+ return controller;
+}
+#endif
+
static void
xhci_reset(hci_t *const controller)
{
diff --git a/payloads/libpayload/drivers/usb/xhci.h b/payloads/libpayload/drivers/usb/xhci.h
index b900b12200..b76c9829b3 100644
--- a/payloads/libpayload/drivers/usb/xhci.h
+++ b/payloads/libpayload/drivers/usb/xhci.h
@@ -33,8 +33,9 @@
#include <pci.h>
#include <usb/usb.h>
- hci_t *xhci_init (pcidev_t addr);
+hci_t *xhci_pci_init (pcidev_t addr);
+hci_t *xhci_init (void *bar);
- void xhci_rh_init (usbdev_t *dev);
+void xhci_rh_init (usbdev_t *dev);
#endif
diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h
index ab457088f8..a351690418 100644
--- a/payloads/libpayload/include/usb/usb.h
+++ b/payloads/libpayload/include/usb/usb.h
@@ -30,7 +30,7 @@
#ifndef __USB_H
#define __USB_H
#include <libpayload.h>
-#include <pci.h>
+#include <pci/pci.h>
typedef enum { host_to_device = 0, device_to_host = 1 } dev_req_dir;
typedef enum { standard_type = 0, class_type = 1, vendor_type =
@@ -118,7 +118,6 @@ typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type;
struct usbdev_hc {
hci_t *next;
- pcidev_t bus_address;
u32 reg_base;
hc_type type;
usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable