diff options
author | Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> | 2013-10-16 14:37:53 +0530 |
---|---|---|
committer | Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> | 2013-11-15 10:36:51 +0530 |
commit | ce91e6a2827c0921be774c7ba9bfd3056778b57d (patch) | |
tree | 8008447a1cc285fbf3fb501582d786ff89b42a25 | |
parent | 8e5245abc8bdfbfc9438cc2e56f80ef8e394259f (diff) | |
download | SLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.zip SLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.tar.gz SLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.tar.bz2 |
usb-xhci: add xhci support
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
-rw-r--r-- | lib/libusb/Makefile | 3 | ||||
-rw-r--r-- | lib/libusb/usb-core.c | 2 | ||||
-rw-r--r-- | lib/libusb/usb-xhci.c | 105 | ||||
-rw-r--r-- | lib/libusb/usb-xhci.h | 108 | ||||
-rw-r--r-- | lib/libusb/usb.code | 9 | ||||
-rw-r--r-- | lib/libusb/usb.h | 4 | ||||
-rw-r--r-- | lib/libusb/usb.in | 1 | ||||
-rw-r--r-- | slof/fs/devices/pci-class_0c.fs | 8 | ||||
-rw-r--r-- | slof/fs/pci-class-code-names.fs | 3 | ||||
-rw-r--r-- | slof/fs/usb/usb-static.fs | 14 |
10 files changed, 250 insertions, 7 deletions
diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile index 9e009a4..ee065be 100644 --- a/lib/libusb/Makefile +++ b/lib/libusb/Makefile @@ -22,7 +22,8 @@ TARGET = ../libusb.a all: $(TARGET) -SRCS = usb-core.c usb-ohci.c usb-ehci.c usb-slof.c usb-key.c usb-hid.c usb-hub.c +SRCS = usb-core.c usb-ohci.c usb-ehci.c usb-slof.c usb-key.c usb-hid.c \ + usb-hub.c usb-xhci.c OBJS = $(SRCS:%.c=%.o) diff --git a/lib/libusb/usb-core.c b/lib/libusb/usb-core.c index b169e74..6c40913 100644 --- a/lib/libusb/usb-core.c +++ b/lib/libusb/usb-core.c @@ -182,7 +182,7 @@ void usb_hcd_exit(void *_hcidev) struct usb_hcd_dev *hcidev = _hcidev; dprintf("%s: enter \n", __func__); - if (!hcidev || !hcidev->ops) { + if (!hcidev) { printf("Device Error"); return; } diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c new file mode 100644 index 0000000..c6022f9 --- /dev/null +++ b/lib/libusb/usb-xhci.c @@ -0,0 +1,105 @@ +/***************************************************************************** + * Copyright (c) 2013 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ + +#include <string.h> +#include "usb.h" +#include "usb-core.h" +#include "usb-xhci.h" +#include "tools.h" +#include "paflof.h" + +#undef XHCI_DEBUG +//#define XHCI_DEBUG +#ifdef XHCI_DEBUG +#define dprintf(_x ...) do { printf("%s: ", __func__); printf(_x); } while (0) +#else +#define dprintf(_x ...) do { } while (0) +#endif + +static void dump_xhci_regs(struct xhci_hcd *xhcd) +{ +#ifdef XHCI_DEBUG + struct xhci_cap_regs *cap; + struct xhci_op_regs *op; + struct xhci_run_regs *run; + + cap = xhcd->cap_regs; + op = xhcd->op_regs; + run = xhcd->run_regs; + + dprintf("\n"); + dprintf(" - CAPLENGTH %02X\n", read_reg8 (&cap->caplength)); + dprintf(" - HCIVERSION %04X\n", read_reg16(&cap->hciversion)); + dprintf(" - HCSPARAMS1 %08X\n", read_reg32(&cap->hcsparams1)); + dprintf(" - HCSPARAMS2 %08X\n", read_reg32(&cap->hcsparams2)); + dprintf(" - HCSPARAMS3 %08X\n", read_reg32(&cap->hcsparams3)); + dprintf(" - HCCPARAMS %08X\n", read_reg32(&cap->hccparams)); + dprintf(" - DBOFF %08X\n", read_reg32(&cap->dboff)); + dprintf(" - RTSOFF %08X\n", read_reg32(&cap->rtsoff)); + dprintf("\n"); + + dprintf(" - USBCMD %08X\n", read_reg32(&op->usbcmd)); + dprintf(" - USBSTS %08X\n", read_reg32(&op->usbsts)); + dprintf(" - PAGESIZE %08X\n", read_reg32(&op->pagesize)); + dprintf(" - DNCTRL %08X\n", read_reg32(&op->dnctrl)); + dprintf(" - CRCR %016llX\n", read_reg64(&op->crcr)); + dprintf(" - DCBAAP %016llX\n", read_reg64(&op->dcbaap)); + dprintf(" - CONFIG %08X\n", read_reg32(&op->config)); + dprintf("\n"); + + dprintf(" - MFINDEX %08X\n", read_reg32(&run->mfindex)); + dprintf("\n"); +#endif +} + +static void xhci_init(struct usb_hcd_dev *hcidev) +{ + struct xhci_hcd *xhcd; + + printf(" XHCI: Initializing\n"); + dprintf("%s: device base address %p\n", __func__, hcidev->base); + + hcidev->base = (void *)((uint64_t)hcidev->base & ~7); + xhcd = SLOF_alloc_mem(sizeof(*xhcd)); + if (!xhcd) { + printf("usb-xhci: Unable to allocate memory\n"); + return; + } + memset(xhcd, 0, sizeof(*xhcd)); + + hcidev->nextaddr = 1; + hcidev->priv = xhcd; + xhcd->hcidev = hcidev; + xhcd->cap_regs = (struct xhci_cap_regs *)(hcidev->base); + xhcd->op_regs = (struct xhci_op_regs *)(hcidev->base + + read_reg8(&xhcd->cap_regs->caplength)); + xhcd->run_regs = (struct xhci_run_regs *)(hcidev->base + + read_reg32(&xhcd->cap_regs->rtsoff)); + xhcd->db_regs = (struct xhci_db_regs *)(hcidev->base + + read_reg32(&xhcd->cap_regs->dboff)); + +#ifdef XHCI_DEBUG + dump_xhci_regs(xhcd); +#endif +} + +struct usb_hcd_ops xhci_ops = { + .name = "xhci-hcd", + .init = xhci_init, + .usb_type = USB_XHCI, + .next = NULL, +}; + +void usb_xhci_register(void) +{ + usb_hcd_register(&xhci_ops); +} diff --git a/lib/libusb/usb-xhci.h b/lib/libusb/usb-xhci.h new file mode 100644 index 0000000..02e83f7 --- /dev/null +++ b/lib/libusb/usb-xhci.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * Copyright (c) 2013 IBM Corporation + * All rights reserved. + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * IBM Corporation - initial implementation + *****************************************************************************/ +/* + * Definitions for XHCI Controller - Revision 1.0 (5/21/10) + * + */ + +#ifndef USB_XHCI_H +#define USB_XHCI_H + +#include <stdint.h> +#include "usb-core.h" + +/* 5.3 Host Controller Capability Registers + * Table 19 + */ +struct xhci_cap_regs { + uint8_t caplength; + uint8_t reserved; + uint16_t hciversion; + uint32_t hcsparams1; + uint32_t hcsparams2; + uint32_t hcsparams3; + uint32_t hccparams; + uint32_t dboff; + uint32_t rtsoff; +} __attribute__ ((packed)); + +/* Table 27: Host Controller USB Port Register Set */ +struct xhci_port_regs { + uint32_t portsc; + uint32_t portpmsc; + uint32_t portli; + uint32_t reserved; +} __attribute__ ((packed)); + +/* 5.4 Host Controller Operational Registers + * Table 26 + */ +struct xhci_op_regs { + uint32_t usbcmd; + uint32_t usbsts; + uint32_t pagesize; + uint8_t reserved[8]; /* 0C - 13 */ + uint32_t dnctrl; /* Device notification control */ + uint64_t crcr; /* Command ring control */ + uint8_t reserved1[16]; /* 20 - 2F */ + uint64_t dcbaap; /* Device Context Base Address Array Pointer */ + uint8_t config; /* Configure */ + uint8_t reserved2[964]; /* 3C - 3FF */ + /* USB Port register set */ +#define XHCI_PORT_MAX 256 + struct xhci_port_regs prs[XHCI_PORT_MAX]; +} __attribute__ ((packed)); + +/* + * 5.5.2 Interrupter Register Set + * Table 42: Interrupter Registers + */ +struct xhci_int_regs { + uint32_t iman; + uint32_t imod; + uint32_t erstsz; + uint32_t reserved; + uint64_t erstba; + uint64_t erdp; +} __attribute__ ((packed)); + +/* 5.5 Host Controller Runtime Registers */ +struct xhci_run_regs { + uint32_t mfindex; /* microframe index */ + uint8_t reserved[28]; +#define XHCI_IRS_MAX + struct xhci_int_regs irs[XHCI_IRS_MAX]; +} __attribute__ ((packed)); + +/* 5.6 Doorbell Registers*/ +struct xhci_db_regs { + uint32_t db[256]; +} __attribute__ ((packed)); + +struct xhci_hcd { + struct xhci_cap_regs *cap_regs; + struct xhci_op_regs *op_regs; + struct xhci_run_regs *run_regs; + struct xhci_db_regs *db_regs; + struct usb_hcd_dev *hcidev; + struct usb_pipe *freelist; + struct usb_pipe *end; + void *pool; + long pool_phys; +}; + +struct xhci_pipe { + struct usb_pipe pipe; + long qh_phys; +}; + +#endif /* USB_XHCI_H */ diff --git a/lib/libusb/usb.code b/lib/libusb/usb.code index 81e548d..fd92d9e 100644 --- a/lib/libusb/usb.code +++ b/lib/libusb/usb.code @@ -35,6 +35,15 @@ PRIM(USB_X2d_EHCI_X2d_REGISTER) MIRP /************************************************/ +/* Register with the usb-core */ +/* SLOF: USB-XHCI-REGISTER ( -- ) */ +/* LIBNEWUSB: usb_xhci_register(void) */ +/************************************************/ +PRIM(USB_X2d_XHCI_X2d_REGISTER) + usb_xhci_register(); +MIRP + +/************************************************/ /* Initialize hcidev with the usb-core */ /* SLOF: USB-HCD-INIT ( hcidev -- ) */ /* LIBNEWUSB: usb_hcd_init(hcidev) */ diff --git a/lib/libusb/usb.h b/lib/libusb/usb.h index 2be0a7d..fba19d2 100644 --- a/lib/libusb/usb.h +++ b/lib/libusb/usb.h @@ -25,6 +25,10 @@ extern void usb_ohci_register(void); /*******************************************/ extern void usb_ehci_register(void); /*******************************************/ +/* SLOF: USB-XHCI-REGISTER */ +/*******************************************/ +extern void usb_xhci_register(void); +/*******************************************/ /* SLOF: USB-HCD-INIT */ /*******************************************/ extern void usb_hcd_init(void *hcidev); diff --git a/lib/libusb/usb.in b/lib/libusb/usb.in index dc7b7a9..7ceba7d 100644 --- a/lib/libusb/usb.in +++ b/lib/libusb/usb.in @@ -15,6 +15,7 @@ cod(USB-OHCI-REGISTER) cod(USB-EHCI-REGISTER) +cod(USB-XHCI-REGISTER) cod(USB-HCD-INIT) cod(USB-HCD-EXIT) cod(USB-HID-INIT) diff --git a/slof/fs/devices/pci-class_0c.fs b/slof/fs/devices/pci-class_0c.fs index 9ee2bde..9c47325 100644 --- a/slof/fs/devices/pci-class_0c.fs +++ b/slof/fs/devices/pci-class_0c.fs @@ -55,10 +55,10 @@ CONSTANT /hci-dev handle-usb-class set-ehci-alias ENDOF -\ 0330 OF \ XHCI controller -\ handle-usb-class -\ set-xhci-alias -\ ENDOF + 0330 OF \ XHCI controller + handle-usb-class + set-xhci-alias + ENDOF ENDCASE ; diff --git a/slof/fs/pci-class-code-names.fs b/slof/fs/pci-class-code-names.fs index 4156fba..f3a4945 100644 --- a/slof/fs/pci-class-code-names.fs +++ b/slof/fs/pci-class-code-names.fs @@ -174,7 +174,8 @@ 0200 OF s" ssa" ENDOF 0300 OF s" usb-uhci" ENDOF 0310 OF s" usb-ohci" ENDOF - 0320 OF s" usb-ehci" ENDOF + 0320 OF s" usb-ehci" ENDOF + 0330 OF s" usb-xhci" ENDOF 0380 OF s" usb" ENDOF 03FE OF s" usb-device" ENDOF 0400 OF s" fibre-channel" ENDOF diff --git a/slof/fs/usb/usb-static.fs b/slof/fs/usb/usb-static.fs index 73a7176..726ef6d 100644 --- a/slof/fs/usb/usb-static.fs +++ b/slof/fs/usb/usb-static.fs @@ -71,5 +71,19 @@ THEN LOOP + xhci-alias-num 1 >= IF + USB-XHCI-REGISTER + THEN + + xhci-alias-num 0 ?DO + " xhci" i $cathex find-device + " get-hci-dev" get-node find-method + IF + execute usb-enumerate + ELSE + ." get-base-address method not found for xhci" i . cr + THEN + LOOP + 0 set-node \ FIXME Setting it back ; |