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>
This commit is contained in:
Stefan Reinauer
2013-05-02 16:16:41 -07:00
committed by Stefan Reinauer
parent 441a4baf87
commit 8992e53c23
16 changed files with 142 additions and 58 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -30,7 +30,6 @@
#ifndef __EHCI_PRIVATE_H
#define __EHCI_PRIVATE_H
#include <pci.h>
#include <usb/usb.h>
#define USBBASE 0x10

View File

@@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/
//#define USB_DEBUG
#include <libpayload.h>
#include "ehci.h"
#include "ehci_private.h"

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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))

View File

@@ -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)

View File

@@ -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

View File

@@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/
//#define USB_DEBUG
#include <usb/usb.h>
#include "generic_hub.h"

View File

@@ -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;
}

View File

@@ -27,6 +27,7 @@
* SUCH DAMAGE.
*/
//#define USB_DEBUG
#include <endian.h>
#include <usb/usb.h>
#include <usb/usbmsc.h>

View File

@@ -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)
{

View File

@@ -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