* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
@ 2008-06-23 11:24 Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
To: u-boot
Add high speed support to USB code. Extracted from Juniper Networks patch.
I know that the mergewindow is closed but wanted to get feedback on these
patches if possible.
Signed-off-by: Tor Krill <tor@excito.com>
---
common/cmd_usb.c | 3 ++-
common/usb.c | 30 +++++++++++++++++++++++++-----
include/usb.h | 16 +++++++++-------
include/usb_defs.h | 10 ++++++++++
4 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 9be86b8..03282f6 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -276,7 +276,8 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre)
pre[index++]= has_child ? '|' : ' ';
pre[index]=0;
printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
- dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2);
+ (dev->speed == USB_SPEED_LOW) ? "1.5MBit/s" : (dev->speed == USB_SPEED_FULL)
+ ? "12MBit/s" : "480MBit/s", dev->config.MaxPower * 2);
if (strlen(dev->mf) ||
strlen(dev->prod) ||
strlen(dev->serial))
diff --git a/common/usb.c b/common/usb.c
index a0107dc..44f35bc 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -793,6 +793,11 @@ int usb_new_device(struct usb_device *dev)
case 16: dev->maxpacketsize = 1; break;
case 32: dev->maxpacketsize = 2; break;
case 64: dev->maxpacketsize = 3; break;
+ case 512: dev->maxpacketsize = 6; break;
+ default:
+ printf("XXX bMaxPacketSize0 unsupported (%u)\n",
+ dev->descriptor.bMaxPacketSize0);
+ break;
}
dev->devnum = addr;
@@ -981,8 +986,10 @@ static int hub_port_reset(struct usb_device *dev, int port,
}
portstatus = le16_to_cpu(portsts.wPortStatus);
portchange = le16_to_cpu(portsts.wPortChange);
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+ USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus ,portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+ portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ? "High" :
+ "Full");
USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d\n",
(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
@@ -1026,8 +1033,10 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
portstatus = le16_to_cpu(portsts.wPortStatus);
portchange = le16_to_cpu(portsts.wPortChange);
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus, portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+ USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus, portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+ portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ? "High" :
+ "Full");
/* Clear the connection change status */
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
@@ -1052,10 +1061,21 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
/* Allocate a new device struct for it */
usb=usb_alloc_new_device();
- usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+ switch (portstatus & USB_PORT_STAT_SPEED) {
+ case 0:
+ usb->speed = USB_SPEED_FULL;
+ break;
+ case USB_PORT_STAT_LOW_SPEED:
+ usb->speed = USB_SPEED_LOW;
+ break;
+ case USB_PORT_STAT_HIGH_SPEED:
+ usb->speed = USB_SPEED_HIGH;
+ break;
+ }
dev->children[port] = usb;
usb->parent=dev;
+ usb->portnr = port + 1;
/* Run it through the hoops (find a driver, etc) */
if (usb_new_device(usb)) {
/* Woops, disable the port */
diff --git a/include/usb.h b/include/usb.h
index 5a6ffdd..410f9cf 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -132,7 +132,7 @@ struct usb_config_descriptor {
struct usb_device {
int devnum; /* Device number on USB bus */
- int slow; /* Slow device? */
+ int speed; /* full/low/high */
char mf[32]; /* manufacturer */
char prod[32]; /* product */
char serial[32]; /* serial number */
@@ -161,6 +161,7 @@ struct usb_device {
unsigned long status;
int act_len; /* transfered bytes */
int maxchild; /* Number of ports if hub */
+ int portnr;
struct usb_device *parent;
struct usb_device *children[USB_MAXCHILDREN];
};
@@ -171,7 +172,7 @@ struct usb_device {
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \
- defined(CONFIG_USB_ISP116X_HCD)
+ defined(CONFIG_USB_ISP116X_HCD) || defined (CONFIG_USB_EHCI)
int usb_lowlevel_init(void);
int usb_lowlevel_stop(void);
@@ -264,7 +265,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
* - endpoint number (4 bits)
* - current Data0/1 state (1 bit)
* - direction (1 bit)
- * - speed (1 bit)
+ * - speed (2 bits)
* - max packet size (2 bits: 8, 16, 32 or 64)
* - pipe type (2 bits: control, interrupt, bulk, isochronous)
*
@@ -280,7 +281,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
* - device: bits 8-14
* - endpoint: bits 15-18
* - Data0/1: bit 19
- * - speed: bit 26 (0 = Full, 1 = Low Speed)
+ * - speed: bits 26-27 (0 = Full, 1 = Low, 2 = High)
* - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
*
* Why? Because it's arbitrary, and whatever encoding we select is really
@@ -290,8 +291,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
*/
/* Create various pipes... */
#define create_pipe(dev,endpoint) \
- (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize)
-#define default_pipe(dev) ((dev)->slow <<26)
+ (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->speed << 26) | (dev)->maxpacketsize)
+#define default_pipe(dev) ((dev)->speed << 26)
#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint))
#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
@@ -323,7 +324,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
#define usb_pipedata(pipe) (((pipe) >> 19) & 1)
-#define usb_pipeslow(pipe) (((pipe) >> 26) & 1)
+#define usb_pipespeed(pipe) (((pipe) >> 26) & 3)
+#define usb_pipeslow(pipe) (usb_pipespeed(pipe) == USB_SPEED_LOW)
#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT)
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 353019f..8032e57 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -80,6 +80,12 @@
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
+/* USB device speeds */
+#define USB_SPEED_FULL 0x0 /* 12Mbps */
+#define USB_SPEED_LOW 0x1 /* 1.5Mbps */
+#define USB_SPEED_HIGH 0x2 /* 480Mbps */
+#define USB_SPEED_RESERVED 0x3
+
/* Descriptor types */
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
@@ -202,6 +208,7 @@
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
+#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
@@ -216,6 +223,9 @@
#define USB_PORT_STAT_RESET 0x0010
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
+#define USB_PORT_STAT_HIGH_SPEED 0x0400 /* support for EHCI */
+#define USB_PORT_STAT_SPEED \
+ (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
/* wPortChange bits */
#define USB_PORT_STAT_C_CONNECTION 0x0001
--
1.5.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
@ 2008-06-23 11:24 ` Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
` (2 more replies)
2008-07-07 7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
2008-07-10 15:00 ` Markus Klotzbücher
2 siblings, 3 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
To: u-boot
Add basic functionality for ehci bulk and control messages
Signed-off-by: Tor Krill <tor@excito.com>
---
drivers/usb/Makefile | 3 +
drivers/usb/usb_ehci.h | 106 +++++++
drivers/usb/usb_ehci_core.c | 633 +++++++++++++++++++++++++++++++++++++++++++
drivers/usb/usb_ehci_core.h | 29 ++
4 files changed, 771 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/usb_ehci.h
create mode 100644 drivers/usb/usb_ehci_core.c
create mode 100644 drivers/usb/usb_ehci_core.h
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 252b00e..838c52c 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -32,6 +32,9 @@ COBJS-y += usbdcore.o
COBJS-y += usbdcore_ep0.o
COBJS-y += usbdcore_mpc8xx.o
COBJS-y += usbdcore_omap1510.o
+COBJS-$(CONFIG_USB_EHCI) += usb_ehci_core.o
+COBJS-$(CONFIG_USB_EHCI_FSL) += usb_ehci_fsl.o
+COBJS-$(CONFIG_USB_EHCI_PCI) += usb_ehci_pci.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/usb/usb_ehci.h b/drivers/usb/usb_ehci.h
new file mode 100644
index 0000000..0695038
--- /dev/null
+++ b/drivers/usb/usb_ehci.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef USB_EHCI_H
+#define USB_EHCI_H
+
+/*
+ * Register Space.
+ */
+struct ehci_hccr {
+ uint8_t cr_caplength;
+ uint16_t cr_hciversion;
+ uint32_t cr_hcsparams;
+ uint32_t cr_hccparams;
+ uint8_t cr_hcsp_portrt[8];
+};
+
+struct ehci_hcor {
+ uint32_t or_usbcmd;
+ uint32_t or_usbsts;
+ uint32_t or_usbintr;
+ uint32_t or_frindex;
+ uint32_t or_ctrldssegment;
+ uint32_t or_periodiclistbase;
+ uint32_t or_asynclistaddr;
+ uint32_t _reserved_[9];
+ uint32_t or_configflag;
+ uint32_t or_portsc[2];
+ uint32_t or_systune;
+};
+
+#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current */
+#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect */
+#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect */
+#define EHCI_PS_PTC 0x000f0000 /* RW port test control */
+#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */
+#define EHCI_PS_PO 0x00002000 /* RW port owner */
+#define EHCI_PS_PP 0x00001000 /* RW,RO port power */
+#define EHCI_PS_LS 0x00000c00 /* RO line status */
+#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
+#define EHCI_PS_PR 0x00000100 /* RW port reset */
+#define EHCI_PS_SUSP 0x00000080 /* RW suspend */
+#define EHCI_PS_FPR 0x00000040 /* RW force port resume */
+#define EHCI_PS_OCC 0x00000020 /* RWC over current change */
+#define EHCI_PS_OCA 0x00000010 /* RO over current active */
+#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */
+#define EHCI_PS_PE 0x00000004 /* RW port enable */
+#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */
+#define EHCI_PS_CS 0x00000001 /* RO connect status */
+#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
+
+/*
+ * Schedule Interface Space.
+ *
+ * IMPORTANT: Software must ensure that no interface data structure
+ * reachable by the EHCI host controller spans a 4K page boundary!
+ *
+ * Periodic transfers (i.e. isochronous and interrupt transfers) are
+ * not supported.
+ */
+
+/* Queue Element Transfer Descriptor (qTD). */
+struct qTD {
+ uint32_t qt_next;
+#define QT_NEXT_TERMINATE 1
+ uint32_t qt_altnext;
+ uint32_t qt_token;
+ uint32_t qt_buffer[5];
+};
+
+/* Queue Head (QH). */
+struct QH {
+ uint32_t qh_link;
+#define QH_LINK_TERMINATE 1
+#define QH_LINK_TYPE_ITD 0
+#define QH_LINK_TYPE_QH 2
+#define QH_LINK_TYPE_SITD 4
+#define QH_LINK_TYPE_FSTN 6
+ uint32_t qh_endpt1;
+ uint32_t qh_endpt2;
+ uint32_t qh_curtd;
+ struct qTD qh_overlay;
+};
+
+/* Low level intit functions */
+
+int ehci_hcd_init (void);
+int ehci_hcd_stop (void);
+#endif /* USB_EHCI_H */
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c
new file mode 100644
index 0000000..dfffb01
--- /dev/null
+++ b/drivers/usb/usb_ehci_core.c
@@ -0,0 +1,633 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * Copyright (c) 2008, Excito Elektronik i Sk?ne AB
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <asm/io.h>
+#include "usb_ehci.h"
+
+int rootdev;
+struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
+volatile struct ehci_hcor *hcor;
+
+static uint16_t portreset;
+static struct QH qh_list __attribute__ ((aligned (32)));
+
+static struct {
+ uint8_t hub[8];
+ uint8_t device[18];
+ uint8_t config[9];
+ uint8_t interface[9];
+ uint8_t endpoint[7];
+} descr = {
+ { /* HUB */
+ sizeof (descr.hub), /* bDescLength */
+ 0x29, /* bDescriptorType: hub descriptor */
+ 2, /* bNrPorts -- runtime modified */
+ 0, 0, /* wHubCharacteristics -- runtime modified */
+ 0xff, /* bPwrOn2PwrGood */
+ 0, /* bHubCntrCurrent */
+ 0 /* DeviceRemovable XXX at most 7 ports! XXX */
+ }
+ , { /* DEVICE */
+ sizeof (descr.device), /* bLength */
+ 1, /* bDescriptorType: UDESC_DEVICE */
+ 0x00, 0x02, /* bcdUSB: v2.0 */
+ 9, /* bDeviceClass: UDCLASS_HUB */
+ 0, /* bDeviceSubClass: UDSUBCLASS_HUB */
+ 1, /* bDeviceProtocol: UDPROTO_HSHUBSTT */
+ 64, /* bMaxPacketSize: 64 bytes */
+ 0x00, 0x00, /* idVendor */
+ 0x00, 0x00, /* idProduct */
+ 0x00, 0x01, /* bcdDevice */
+ 1, /* iManufacturer */
+ 2, /* iProduct */
+ 0, /* iSerialNumber */
+ 1 /* bNumConfigurations: 1 */
+ }
+ , { /* CONFIG */
+ sizeof (descr.config), /* bLength */
+ 2, /* bDescriptorType: UDESC_CONFIG */
+ sizeof (descr.config) + sizeof (descr.interface) +
+ sizeof (descr.endpoint), 0,
+ /* wTotalLength */
+ 1, /* bNumInterface */
+ 1, /* bConfigurationValue */
+ 0, /* iConfiguration */
+ 0x40, /* bmAttributes: UC_SELF_POWERED */
+ 0 /* bMaxPower */
+ }
+ , { /* INTERFACE */
+ sizeof (descr.interface), /* bLength */
+ 4, /* bDescriptorType: UDESC_INTERFACE */
+ 0, /* bInterfaceNumber */
+ 0, /* bAlternateSetting */
+ 1, /* bNumEndpoints */
+ 9, /* bInterfaceClass: UICLASS_HUB */
+ 0, /* bInterfaceSubClass: UISUBCLASS_HUB */
+ 0, /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
+ 0 /* iInterface */
+ }
+ , { /* ENDPOINT */
+ sizeof (descr.endpoint), /* bLength */
+ 5, /* bDescriptorType: UDESC_ENDPOINT */
+ 0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
+ 3, /* bmAttributes: UE_INTERRUPT */
+ 8, 0, /* wMaxPacketSize */
+ 255 /* bInterval */
+ }
+};
+
+static void *ehci_alloc (size_t sz, size_t align)
+{
+ static struct QH qh __attribute__ ((aligned (32)));
+ static struct qTD td[3] __attribute__ ((aligned (32)));
+ static int ntds = 0;
+ void *p;
+
+ switch (sz) {
+ case sizeof (struct QH):
+ p = &qh;
+ ntds = 0;
+ break;
+ case sizeof (struct qTD):
+ if (ntds == 3) {
+ debug ("out of TDs");
+ return (NULL);
+ }
+ p = &td[ntds];
+ ntds++;
+ break;
+ default:
+ debug ("unknown allocation size");
+ return (NULL);
+ }
+
+ memset (p, sz, 0);
+ return (p);
+}
+
+static void ehci_free (void *p, size_t sz)
+{
+}
+
+static int ehci_td_buffer (struct qTD *td, void *buf, size_t sz)
+{
+ uint32_t addr, delta, next;
+ int idx;
+
+ addr = (uint32_t) buf;
+ idx = 0;
+ while (idx < 5) {
+ td->qt_buffer[idx] = cpu_to_le32 (addr);
+ next = (addr + 4096) & ~4095;
+ delta = next - addr;
+ if (delta >= sz)
+ break;
+ sz -= delta;
+ addr = next;
+ idx++;
+ }
+
+ if (idx == 5) {
+ debug ("out of buffer pointers (%u bytes left)", sz);
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+ehci_submit_async (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length, struct devrequest *req)
+{
+ struct QH *qh;
+ struct qTD *td;
+ volatile struct qTD *vtd;
+ unsigned long ts;
+ uint32_t *tdp;
+ uint32_t endpt, token, usbsts;
+ uint32_t c, toggle;
+
+ debug ("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p", dev, pipe,
+ buffer, length, req);
+ if (req != NULL)
+ debug ("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u",
+ req->request, req->request,
+ req->requesttype, req->requesttype,
+ le16_to_cpu (req->value), le16_to_cpu (req->value),
+ le16_to_cpu (req->index), le16_to_cpu (req->index));
+
+ qh = ehci_alloc (sizeof (struct QH), 32);
+ if (qh == NULL) {
+ debug ("unable to allocate QH");
+ return (-1);
+ }
+ qh->qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+ c = (usb_pipespeed (pipe) != USB_SPEED_HIGH &&
+ usb_pipeendpoint (pipe) == 0) ? 1 : 0;
+ endpt = (8 << 28) |
+ (c << 27) |
+ (usb_maxpacket (dev, pipe) << 16) |
+ (0 << 15) |
+ (1 << 14) |
+ (usb_pipespeed (pipe) << 12) |
+ (usb_pipeendpoint (pipe) << 8) |
+ (0 << 7) | (usb_pipedevice (pipe) << 0);
+ qh->qh_endpt1 = cpu_to_le32 (endpt);
+ endpt = (1 << 30) |
+ (dev->portnr << 23) |
+ (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
+ qh->qh_endpt2 = cpu_to_le32 (endpt);
+ qh->qh_overlay.qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+ qh->qh_overlay.qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+
+ td = NULL;
+ tdp = &qh->qh_overlay.qt_next;
+
+ toggle =
+ usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+
+ if (req != NULL) {
+ td = ehci_alloc (sizeof (struct qTD), 32);
+ if (td == NULL) {
+ debug ("unable to allocate SETUP td");
+ goto fail;
+ }
+ td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+ td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+ token = (0 << 31) |
+ (sizeof (*req) << 16) |
+ (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
+ td->qt_token = cpu_to_le32 (token);
+ if (ehci_td_buffer (td, req, sizeof (*req)) != 0) {
+ debug ("unable construct SETUP td");
+ ehci_free (td, sizeof (*td));
+ goto fail;
+ }
+ *tdp = cpu_to_le32 ((uint32_t) td);
+ tdp = &td->qt_next;
+ toggle = 1;
+ }
+
+ if (length > 0 || req == NULL) {
+ td = ehci_alloc (sizeof (struct qTD), 32);
+ if (td == NULL) {
+ debug ("unable to allocate DATA td");
+ goto fail;
+ }
+ td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+ td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+ token = (toggle << 31) |
+ (length << 16) |
+ ((req == NULL ? 1 : 0) << 15) |
+ (0 << 12) |
+ (3 << 10) |
+ ((usb_pipein (pipe) ? 1 : 0) << 8) | (0x80 << 0);
+ td->qt_token = cpu_to_le32 (token);
+ if (ehci_td_buffer (td, buffer, length) != 0) {
+ debug ("unable construct DATA td");
+ ehci_free (td, sizeof (*td));
+ goto fail;
+ }
+ *tdp = cpu_to_le32 ((uint32_t) td);
+ tdp = &td->qt_next;
+ }
+
+ if (req != NULL) {
+ td = ehci_alloc (sizeof (struct qTD), 32);
+ if (td == NULL) {
+ debug ("unable to allocate ACK td");
+ goto fail;
+ }
+ td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+ td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+ token = (toggle << 31) |
+ (0 << 16) |
+ (1 << 15) |
+ (0 << 12) |
+ (3 << 10) |
+ ((usb_pipein (pipe) ? 0 : 1) << 8) | (0x80 << 0);
+ td->qt_token = cpu_to_le32 (token);
+ *tdp = cpu_to_le32 ((uint32_t) td);
+ tdp = &td->qt_next;
+ }
+
+ qh_list.qh_link = cpu_to_le32 ((uint32_t) qh | QH_LINK_TYPE_QH);
+
+ usbsts = le32_to_cpu (hcor->or_usbsts);
+ hcor->or_usbsts = cpu_to_le32 (usbsts & 0x3f);
+
+ /* Enable async. schedule. */
+ hcor->or_usbcmd |= cpu_to_le32 (0x20);
+ while ((hcor->or_usbsts & cpu_to_le32 (0x8000)) == 0)
+ udelay (1);
+
+ /* Wait for TDs to be processed. */
+ ts = get_timer (0);
+ vtd = td;
+ do {
+ token = le32_to_cpu (vtd->qt_token);
+ if (!(token & 0x80))
+ break;
+ } while (get_timer (ts) < CFG_HZ);
+
+ /* Disable async schedule. */
+ hcor->or_usbcmd &= ~cpu_to_le32 (0x20);
+ while ((hcor->or_usbsts & cpu_to_le32 (0x8000)) != 0)
+ udelay (1);
+
+ qh_list.qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+
+ token = le32_to_cpu (qh->qh_overlay.qt_token);
+ if (!(token & 0x80)) {
+ // debug ("TOKEN=%#x", token);
+ switch (token & 0xfc) {
+ case 0:
+ toggle = token >> 31;
+ usb_settoggle (dev, usb_pipeendpoint (pipe),
+ usb_pipeout (pipe), toggle);
+ dev->status = 0;
+ break;
+ case 0x40:
+ dev->status = USB_ST_STALLED;
+ break;
+ case 0xa0:
+ case 0x20:
+ dev->status = USB_ST_BUF_ERR;
+ break;
+ case 0x50:
+ case 0x10:
+ dev->status = USB_ST_BABBLE_DET;
+ break;
+ default:
+ dev->status = USB_ST_CRC_ERR;
+ break;
+ }
+ dev->act_len = length - ((token >> 16) & 0x7fff);
+ } else {
+ dev->act_len = 0;
+ debug ("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x",
+ dev->devnum, le32_to_cpu (hcor->or_usbsts),
+ le32_to_cpu (hcor->or_portsc[0]),
+ le32_to_cpu (hcor->or_portsc[1]));
+ }
+
+ return ((dev->status != USB_ST_NOT_PROC) ? 0 : -1);
+
+ fail:
+ td = (void *)le32_to_cpu (qh->qh_overlay.qt_next);
+ while (td != (void *)QT_NEXT_TERMINATE) {
+ qh->qh_overlay.qt_next = td->qt_next;
+ ehci_free (td, sizeof (*td));
+ td = (void *)le32_to_cpu (qh->qh_overlay.qt_next);
+ }
+ ehci_free (qh, sizeof (*qh));
+ return (-1);
+}
+
+static __inline int min3 (int a, int b, int c)
+{
+
+ if (b < a)
+ a = b;
+ if (c < a)
+ a = c;
+ return (a);
+}
+
+static int
+ehci_submit_root (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length, struct devrequest *req)
+{
+ uint8_t tmpbuf[4];
+ void *srcptr;
+ int len, srclen;
+ uint32_t reg;
+
+ srclen = 0;
+ srcptr = NULL;
+
+ debug ("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
+ req->request, req->request,
+ req->requesttype, req->requesttype,
+ le16_to_cpu (req->value), le16_to_cpu (req->index));
+
+#define C(a,b) (((b) << 8) | (a))
+
+ switch (C (req->request, req->requesttype)) {
+ case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE):
+ switch (le16_to_cpu (req->value) >> 8) {
+ case USB_DT_DEVICE:
+ srcptr = descr.device;
+ srclen = sizeof (descr.device);
+ break;
+ case USB_DT_CONFIG:
+ srcptr = descr.config;
+ srclen = sizeof (descr.config) +
+ sizeof (descr.interface) + sizeof (descr.endpoint);
+ break;
+ case USB_DT_STRING:
+ switch (le16_to_cpu (req->value) & 0xff) {
+ case 0: /* Language */
+ srcptr = "\4\3\1\0";
+ srclen = 4;
+ break;
+ case 1: /* Vendor */
+ srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
+ srclen = 14;
+ break;
+ case 2: /* Product */
+ srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
+ srclen = 42;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ default:
+ debug ("unknown value %x", le16_to_cpu (req->value));
+ goto unknown;
+ }
+ break;
+ case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB):
+ switch (le16_to_cpu (req->value) >> 8) {
+ case USB_DT_HUB:
+ srcptr = descr.hub;
+ srclen = sizeof (descr.hub);
+ break;
+ default:
+ debug ("unknown value %x", le16_to_cpu (req->value));
+ goto unknown;
+ }
+ break;
+ case C (USB_REQ_SET_ADDRESS, USB_RECIP_DEVICE):
+ rootdev = le16_to_cpu (req->value);
+ break;
+ case C (USB_REQ_SET_CONFIGURATION, USB_RECIP_DEVICE):
+ /* Nothing to do */
+ break;
+ case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB):
+ tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
+ tmpbuf[1] = 0;
+ srcptr = tmpbuf;
+ srclen = 2;
+ break;
+ case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT):
+ memset (tmpbuf, 0, 4);
+ reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+ if (reg & EHCI_PS_CS)
+ tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
+ if (reg & EHCI_PS_PE)
+ tmpbuf[0] |= USB_PORT_STAT_ENABLE;
+ if (reg & EHCI_PS_SUSP)
+ tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
+ if (reg & EHCI_PS_OCA)
+ tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
+ if (reg & EHCI_PS_PR)
+ tmpbuf[0] |= USB_PORT_STAT_RESET;
+ if (reg & EHCI_PS_PP)
+ tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
+ tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
+
+ if (reg & EHCI_PS_CSC)
+ tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
+ if (reg & EHCI_PS_PEC)
+ tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
+ if (reg & EHCI_PS_OCC)
+ tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
+ if (portreset & (1 << le16_to_cpu (req->index)))
+ tmpbuf[2] |= USB_PORT_STAT_C_RESET;
+ srcptr = tmpbuf;
+ srclen = 4;
+ break;
+ case C (USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_RT_PORT):
+ reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+ reg &= ~EHCI_PS_CLEAR;
+ switch (le16_to_cpu (req->value)) {
+ case USB_PORT_FEAT_POWER:
+ reg |= EHCI_PS_PP;
+ break;
+ case USB_PORT_FEAT_RESET:
+ if (EHCI_PS_IS_LOWSPEED (reg)) {
+ /* Low speed device, give up ownership. */
+ reg |= EHCI_PS_PO;
+ break;
+ }
+ /* Start reset sequence. */
+ reg &= ~EHCI_PS_PE;
+ reg |= EHCI_PS_PR;
+ hcor->or_portsc[le16_to_cpu (req->index) - 1] =
+ cpu_to_le32 (reg);
+ /* Wait for reset to complete. */
+ udelay (500000);
+ /* Terminate reset sequence. */
+ reg &= ~EHCI_PS_PR;
+ /* TODO: is it only fsl chip that requires this
+ * manual setting of port enable?
+ */
+ reg |= EHCI_PS_PE;
+ hcor->or_portsc[le16_to_cpu (req->index) - 1] =
+ cpu_to_le32 (reg);
+ /* Wait for HC to complete reset. */
+ udelay (2000);
+ reg =
+ le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+ reg &= ~EHCI_PS_CLEAR;
+ if ((reg & EHCI_PS_PE) == 0) {
+ /* Not a high speed device, give up ownership. */
+ reg |= EHCI_PS_PO;
+ break;
+ }
+ portreset |= 1 << le16_to_cpu (req->index);
+ break;
+ default:
+ debug ("unknown feature %x", le16_to_cpu (req->value));
+ goto unknown;
+ }
+ hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
+ break;
+ case C (USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RT_PORT):
+ reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+ reg &= ~EHCI_PS_CLEAR;
+ switch (le16_to_cpu (req->value)) {
+ case USB_PORT_FEAT_ENABLE:
+ reg &= ~EHCI_PS_PE;
+ break;
+ case USB_PORT_FEAT_C_CONNECTION:
+ reg |= EHCI_PS_CSC;
+ break;
+ case USB_PORT_FEAT_C_RESET:
+ portreset &= ~(1 << le16_to_cpu (req->index));
+ break;
+ default:
+ debug ("unknown feature %x", le16_to_cpu (req->value));
+ goto unknown;
+ }
+ hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
+ break;
+ default:
+ debug ("Unknown request %x",
+ C (req->request, req->requesttype));
+ goto unknown;
+ }
+
+#undef C
+
+ len = min3 (srclen, le16_to_cpu (req->length), length);
+ if (srcptr != NULL && len > 0)
+ memcpy (buffer, srcptr, len);
+ dev->act_len = len;
+ dev->status = 0;
+ return (0);
+
+ unknown:
+ debug ("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
+ req->requesttype, req->request, le16_to_cpu (req->value),
+ le16_to_cpu (req->index), le16_to_cpu (req->length));
+
+ dev->act_len = 0;
+ dev->status = USB_ST_STALLED;
+ return (-1);
+}
+
+int usb_lowlevel_stop (void)
+{
+ return ehci_hcd_stop ();
+}
+
+int usb_lowlevel_init (void)
+{
+ uint32_t reg;
+
+ if (ehci_hcd_init () != 0) {
+ return -1;
+ }
+
+ /* Set head of reclaim list */
+ memset (&qh_list, 0, sizeof (qh_list));
+ qh_list.qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+ qh_list.qh_endpt1 = cpu_to_le32 ((1 << 15) | (USB_SPEED_HIGH << 12));
+ qh_list.qh_curtd = cpu_to_le32 (QT_NEXT_TERMINATE);
+ qh_list.qh_overlay.qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+ qh_list.qh_overlay.qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+ qh_list.qh_overlay.qt_token = cpu_to_le32 (0x40);
+
+ /* Set async. queue head pointer. */
+ hcor->or_asynclistaddr = cpu_to_le32 ((uint32_t) & qh_list);
+
+ reg = le32_to_cpu (hccr->cr_hcsparams);
+ descr.hub[2] = reg & 0xf;
+ if (reg & 0x10000) /* Port Indicators */
+ descr.hub[3] |= 0x80;
+ if (reg & 0x10) /* Port Power Control */
+ descr.hub[3] |= 0x01;
+
+ /* take control over the ports */
+ hcor->or_configflag |= cpu_to_le32 (1);
+
+ /* Start the host controller. */
+ hcor->or_usbcmd |= cpu_to_le32 (1);
+
+ rootdev = 0;
+
+ return 0;
+}
+
+int
+submit_bulk_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length)
+{
+
+ if (usb_pipetype (pipe) != PIPE_BULK) {
+ debug ("non-bulk pipe (type=%lu)", usb_pipetype (pipe));
+ return (-1);
+ }
+ return (ehci_submit_async (dev, pipe, buffer, length, NULL));
+}
+
+int
+submit_control_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length, struct devrequest *setup)
+{
+
+ if (usb_pipetype (pipe) != PIPE_CONTROL) {
+ debug ("non-control pipe (type=%lu)", usb_pipetype (pipe));
+ return (-1);
+ }
+
+ if (usb_pipedevice (pipe) == rootdev) {
+ if (rootdev == 0)
+ dev->speed = USB_SPEED_HIGH;
+ return (ehci_submit_root (dev, pipe, buffer, length, setup));
+ }
+ return (ehci_submit_async (dev, pipe, buffer, length, setup));
+}
+
+int
+submit_int_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length, int interval)
+{
+
+ debug ("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe,
+ buffer, length, interval);
+ return (-1);
+}
diff --git a/drivers/usb/usb_ehci_core.h b/drivers/usb/usb_ehci_core.h
new file mode 100644
index 0000000..88e91b9
--- /dev/null
+++ b/drivers/usb/usb_ehci_core.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * Copyright (c) 2008, Excito Elektronik i Sk?ne AB
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef USB_EHCI_CORE_H
+#define USB_EHCI_CORE_H
+
+extern int rootdev;
+extern struct ehci_hccr *hccr;
+extern volatile struct ehci_hcor *hcor;
+
+#endif
--
1.5.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
@ 2008-06-23 11:24 ` Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver Tor Krill
2008-06-23 12:59 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality michael
[not found] ` <49267DEB.5020903@gandalf.sssup.it>
2 siblings, 1 reply; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
To: u-boot
Add hcd driver for Freescale 8313 and possibly others. Supports
built in UTMI PHY and has a hardcoded clock setting.
Signed-off-by: Tor Krill <tor@excito.com>
---
drivers/usb/usb_ehci_fsl.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
drivers/usb/usb_ehci_fsl.h | 82 ++++++++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/usb_ehci_fsl.c
create mode 100644 drivers/usb/usb_ehci_fsl.h
diff --git a/drivers/usb/usb_ehci_fsl.c b/drivers/usb/usb_ehci_fsl.c
new file mode 100644
index 0000000..6c03773
--- /dev/null
+++ b/drivers/usb/usb_ehci_fsl.c
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2008, Excito Elektronik i Sk?ne AB
+ *
+ * Author: Tor Krill tor at excito.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <usb.h>
+#include <mpc83xx.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include "usb_ehci.h"
+#include "usb_ehci_fsl.h"
+#include "usb_ehci_core.h"
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ *
+ * Excerpts from linux ehci fsl driver.
+ */
+int ehci_hcd_init (void)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ uint32_t addr, temp;
+
+ addr = (uint32_t) & (im->usb[0]);
+ hccr = (struct ehci_hccr *)(addr + FSL_SKIP_PCI);
+ hcor = (struct ehci_hcor *)((uint32_t) hccr + hccr->cr_caplength);
+
+ /* Configure clock */
+ clrsetbits_be32 (&(im->clk.sccr), MPC83XX_SCCR_USB_MASK,
+ MPC83XX_SCCR_USB_DRCM_11);
+
+ /* Confgure interface. */
+ temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+ out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp
+ | REFSEL_16MHZ | UTMI_PHY_EN);
+
+ /* Wait for clock to stabilize */
+ do {
+ temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+ udelay (1000);
+ } while (!(temp & PHY_CLK_VALID));
+
+ /* Set to Host mode */
+ temp = in_le32 ((void *)(addr + FSL_SOC_USB_USBMODE));
+ out_le32 ((void *)(addr + FSL_SOC_USB_USBMODE), temp | CM_HOST);
+
+ out_be32 ((void *)(addr + FSL_SOC_USB_SNOOP1), SNOOP_SIZE_2GB);
+ out_be32 ((void *)(addr + FSL_SOC_USB_SNOOP2),
+ 0x80000000 | SNOOP_SIZE_2GB);
+
+ /* Init phy */
+ /* TODO: handle different phys? */
+ out_le32 (&(hcor->or_portsc[0]), PORT_PTS_UTMI);
+
+ /* Enable interface. */
+ temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+ out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp | USB_EN);
+
+ out_be32 ((void *)(addr + FSL_SOC_USB_PRICTRL), 0x0000000c);
+ out_be32 ((void *)(addr + FSL_SOC_USB_AGECNTTHRSH), 0x00000040);
+ out_be32 ((void *)(addr + FSL_SOC_USB_SICTRL), 0x00000001);
+
+ /* Enable interface. */
+ temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+ out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp | USB_EN);
+
+ temp = in_le32 ((void *)(addr + FSL_SOC_USB_USBMODE));
+
+ return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop (void)
+{
+ return 0;
+}
diff --git a/drivers/usb/usb_ehci_fsl.h b/drivers/usb/usb_ehci_fsl.h
new file mode 100644
index 0000000..dd7ee2e
--- /dev/null
+++ b/drivers/usb/usb_ehci_fsl.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2005 freescale semiconductor
+ * Copyright (c) 2005 MontaVista Software
+ * Copyright (c) 2008 Excito Elektronik i Sk?ne AB
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _EHCI_FSL_H
+#define _EHCI_FSL_H
+/* Global offsets */
+#define FSL_SKIP_PCI 0x100
+
+/* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_ULPIVP 0x170
+#define FSL_SOC_USB_PORTSC1 0x184
+#define PORT_PTS_MSK (3<<30)
+#define PORT_PTS_UTMI (0<<30)
+#define PORT_PTS_ULPI (2<<30)
+#define PORT_PTS_SERIAL (3<<30)
+#define PORT_PTS_PTW (1<<28)
+
+/* USBMODE Register bits */
+#define CM_IDLE (0<<0)
+#define CM_RESERVED (1<<0)
+#define CM_DEVICE (2<<0)
+#define CM_HOST (3<<0)
+#define USBMODE_RESERVED_2 (0<<2)
+#define SLOM (1<<3)
+#define SDIS (1<<4)
+
+/* CONTROL Register bits */
+#define ULPI_INT_EN (1<<0)
+#define WU_INT_EN (1<<1)
+#define USB_EN (1<<2)
+#define LSF_EN (1<<3)
+#define KEEP_OTG_ON (1<<4)
+#define OTG_PORT (1<<5)
+#define REFSEL_12MHZ (0<<6)
+#define REFSEL_16MHZ (1<<6)
+#define REFSEL_48MHZ (2<<6)
+#define PLL_RESET (1<<8)
+#define UTMI_PHY_EN (1<<9)
+#define PHY_CLK_SEL_UTMI (0<<10)
+#define PHY_CLK_SEL_ULPI (1<<10)
+#define CLKIN_SEL_USB_CLK (0<<11)
+#define CLKIN_SEL_USB_CLK2 (1<<11)
+#define CLKIN_SEL_SYS_CLK (2<<11)
+#define CLKIN_SEL_SYS_CLK2 (3<<11)
+#define RESERVED_18 (0<<13)
+#define RESERVED_17 (0<<14)
+#define RESERVED_16 (0<<15)
+#define WU_INT (1<<16)
+#define PHY_CLK_VALID (1<<17)
+
+#define FSL_SOC_USB_PORTSC2 0x188
+#define FSL_SOC_USB_USBMODE 0x1a8
+#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
+#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
+#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
+#define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */
+#define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */
+#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
+#define SNOOP_SIZE_2GB 0x1e
+
+/* System Clock Control Register */
+#define MPC83XX_SCCR_USB_MASK 0x00f00000
+#define MPC83XX_SCCR_USB_DRCM_11 0x00300000
+#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
+#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
+
+#endif /* _EHCI_FSL_H */
--
1.5.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
@ 2008-06-23 11:24 ` Tor Krill
0 siblings, 0 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
To: u-boot
Readds Juniper Networks original Philips PCI driver. (Untested)
Signed-off-by: Tor Krill <tor@excito.com>
---
drivers/usb/usb_ehci_pci.c | 135 ++++++++++++++++++++++++++++++++++++++++++++
drivers/usb/usb_ehci_pci.h | 37 ++++++++++++
2 files changed, 172 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/usb_ehci_pci.c
create mode 100644 drivers/usb/usb_ehci_pci.h
diff --git a/drivers/usb/usb_ehci_pci.c b/drivers/usb/usb_ehci_pci.c
new file mode 100644
index 0000000..d652122
--- /dev/null
+++ b/drivers/usb/usb_ehci_pci.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <usb.h>
+#include "usb_ehci.h"
+#include "usb_ehci_pci.h"
+#include "usb_ehci_core.h"
+
+#ifdef EHCI_DEBUG
+static void dump_pci_reg (pci_dev_t dev, int ofs)
+{
+ uint32_t reg;
+
+ pci_read_config_dword (dev, ofs, ®);
+ printf ("\t0x%02x: %08x\n", ofs, reg);
+}
+
+static void dump_pci (int enh, pci_dev_t dev)
+{
+ int ofs;
+
+ debug ("\n%s", (enh) ? "EHCI" : "OHCI");
+ for (ofs = 0; ofs < 0x44; ofs += 4)
+ dump_pci_reg (dev, ofs);
+ if (enh)
+ dump_pci_reg (dev, 0x60);
+ dump_pci_reg (dev, 0xdc);
+ dump_pci_reg (dev, 0xe0);
+ if (enh) {
+ dump_pci_reg (dev, 0xe4);
+ dump_pci_reg (dev, 0xe8);
+ }
+}
+
+static void dump_regs (void)
+{
+
+ debug ("usbcmd=%#x, usbsts=%#x, usbintr=%#x,\n\tfrindex=%#x, "
+ "ctrldssegment=%#x, periodiclistbase=%#x,\n\tasynclistaddr=%#x, "
+ "configflag=%#x,\n\tportsc[1]=%#x, portsc[2]=%#x, systune=%#x",
+ swap_32 (hcor->or_usbcmd), swap_32 (hcor->or_usbsts),
+ swap_32 (hcor->or_usbintr), swap_32 (hcor->or_frindex),
+ swap_32 (hcor->or_ctrldssegment),
+ swap_32 (hcor->or_periodiclistbase),
+ swap_32 (hcor->or_asynclistaddr), swap_32 (hcor->or_configflag),
+ swap_32 (hcor->or_portsc[0]), swap_32 (hcor->or_portsc[1]),
+ swap_32 (hcor->or_systune));
+}
+
+static void dump_TD (struct qTD *td)
+{
+
+ debug ("%p: qt_next=%#x, qt_altnext=%#x, qt_token=%#x, "
+ "qt_buffer={%#x,%#x,%#x,%#x,%#x}", td, swap_32 (td->qt_next),
+ swap_32 (td->qt_altnext), swap_32 (td->qt_token),
+ swap_32 (td->qt_buffer[0]), swap_32 (td->qt_buffer[1]),
+ swap_32 (td->qt_buffer[2]), swap_32 (td->qt_buffer[3]),
+ swap_32 (td->qt_buffer[4]));
+}
+
+static void dump_QH (struct QH *qh)
+{
+
+ debug ("%p: qh_link=%#x, qh_endpt1=%#x, qh_endpt2=%#x, qh_curtd=%#x",
+ qh, swap_32 (qh->qh_link), swap_32 (qh->qh_endpt1),
+ swap_32 (qh->qh_endpt2), swap_32 (qh->qh_curtd));
+ dump_TD (&qh->qh_overlay);
+}
+#endif
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init (void)
+{
+ pci_dev_t dev;
+ uint32_t addr;
+
+ dev = pci_find_device (0x1131, 0x1561, 0);
+ if (dev != -1) {
+ volatile uint32_t *hcreg;
+
+ pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &addr);
+ hcreg = (uint32_t *) (addr + 8);
+ *hcreg = swap_32 (1);
+ udelay (100);
+ }
+
+ dev = pci_find_device (0x1131, 0x1562, 0);
+ if (dev == -1) {
+ printf ("EHCI host controller not found\n");
+ return (-1);
+ }
+
+ pci_read_config_dword (dev, EHCI_PCICS_USBBASE, &addr);
+ hccr = (void *)addr;
+
+ addr += hccr->cr_caplength;
+ hcor = (void *)addr;
+
+ /* Latte/Espresso USB hardware bug workaround */
+ hcor->or_systune |= swap_32 (3);
+
+ return (0);
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop (void)
+{
+
+ return (0);
+}
diff --git a/drivers/usb/usb_ehci_pci.h b/drivers/usb/usb_ehci_pci.h
new file mode 100644
index 0000000..6a4d16e
--- /dev/null
+++ b/drivers/usb/usb_ehci_pci.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI Configuration Space.
+ */
+#define EHCI_PCICS_BASEC PCI_CLASS_CODE
+#define EHCI_PCICS_SCC PCI_CLASS_SUB_CODE
+#define EHCI_PCICS_PI PCI_CLASS_PROG
+#define EHCI_PCICS_USBBASE PCI_BASE_ADDRESS_0
+#define EHCI_PCICS_SBRN 0x60
+#define EHCI_PCICS_FLADJ 0x61
+#define EHCI_PCICS_PORTWAKECAP 0x62
+
+#define EHCI_PCICS_USBLEGSUP
+#define EHCI_PCICS_USBLEGCTLSTS
+
+#define EHCI_PCI_BASEC 0x0c /* Serial Bus Controller. */
+#define EHCI_PCI_SCC 0x03 /* USB Host Controller. */
+#define EHCI_PCI_PI 0x20 /* USB 2.0 Host Controller. */
--
1.5.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
@ 2008-06-23 12:59 ` michael
[not found] ` <49267DEB.5020903@gandalf.sssup.it>
2 siblings, 0 replies; 12+ messages in thread
From: michael @ 2008-06-23 12:59 UTC (permalink / raw)
To: u-boot
Hi,
Tor Krill wrote:
> +static uint16_t portreset;
> +static struct QH qh_list __attribute__ ((aligned (32)));
> +
> +static struct {
> + uint8_t hub[8];
> + uint8_t device[18];
> + uint8_t config[9];
> + uint8_t interface[9];
> + uint8_t endpoint[7];
> +} descr = {
> + { /* HUB */
> + sizeof (descr.hub), /* bDescLength */
> + 0x29, /* bDescriptorType: hub descriptor */
> + 2, /* bNrPorts -- runtime modified */
> + 0, 0, /* wHubCharacteristics -- runtime modified */
> + 0xff, /* bPwrOn2PwrGood */
> + 0, /* bHubCntrCurrent */
> + 0 /* DeviceRemovable XXX at most 7 ports! XXX */
> + }
> + , { /* DEVICE */
> + sizeof (descr.device), /* bLength */
> + 1, /* bDescriptorType: UDESC_DEVICE */
> + 0x00, 0x02, /* bcdUSB: v2.0 */
> + 9, /* bDeviceClass: UDCLASS_HUB */
> + 0, /* bDeviceSubClass: UDSUBCLASS_HUB */
> + 1, /* bDeviceProtocol: UDPROTO_HSHUBSTT */
> + 64, /* bMaxPacketSize: 64 bytes */
> + 0x00, 0x00, /* idVendor */
> + 0x00, 0x00, /* idProduct */
> + 0x00, 0x01, /* bcdDevice */
> + 1, /* iManufacturer */
> + 2, /* iProduct */
> + 0, /* iSerialNumber */
> + 1 /* bNumConfigurations: 1 */
> + }
> + , { /* CONFIG */
> + sizeof (descr.config), /* bLength */
> + 2, /* bDescriptorType: UDESC_CONFIG */
> + sizeof (descr.config) + sizeof (descr.interface) +
> + sizeof (descr.endpoint), 0,
> + /* wTotalLength */
> + 1, /* bNumInterface */
> + 1, /* bConfigurationValue */
> + 0, /* iConfiguration */
> + 0x40, /* bmAttributes: UC_SELF_POWERED */
> + 0 /* bMaxPower */
> + }
> + , { /* INTERFACE */
> + sizeof (descr.interface), /* bLength */
> + 4, /* bDescriptorType: UDESC_INTERFACE */
> + 0, /* bInterfaceNumber */
> + 0, /* bAlternateSetting */
> + 1, /* bNumEndpoints */
> + 9, /* bInterfaceClass: UICLASS_HUB */
> + 0, /* bInterfaceSubClass: UISUBCLASS_HUB */
> + 0, /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
> + 0 /* iInterface */
> + }
> + , { /* ENDPOINT */
> + sizeof (descr.endpoint), /* bLength */
> + 5, /* bDescriptorType: UDESC_ENDPOINT */
> + 0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
> + 3, /* bmAttributes: UE_INTERRUPT */
> + 8, 0, /* wMaxPacketSize */
> + 255 /* bInterval */
> + }
> +};
> +
>
I prefer using:
struct usb_device_descriptor device = {
sizeof(struct usb_device_descriptor), /* bLength */
1, /* bDescriptorType: UDESC_DEVICE */
0x0002, /* bcdUSB: v2.0 */
9, /* bDeviceClass: UDCLASS_HUB */
0, /* bDeviceSubClass: UDSUBCLASS_HUB */
1, /* bDeviceProtocol: UDPROTO_HSHUBSTT */
64, /* bMaxPacketSize: 64 bytes */
0x0000, /* idVendor */
0x0000, /* idProduct */
0x0001, /* bcdDevice */
1, /* iManufacturer */
2, /* iProduct */
0, /* iSerialNumber */
1 /* bNumConfigurations: 1 */
};
struct usb_interface_descriptor interface = {
sizeof(struct usb_interface_descriptor), /* bLength */
4, /* bDescriptorType: UDESC_INTERFACE */
0, /* bInterfaceNumber */
0, /* bAlternateSetting */
1, /* bNumEndpoints */
9, /* bInterfaceClass: UICLASS_HUB */
0, /* bInterfaceSubClass: UISUBCLASS_HUB */
0, /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
0 /* iInterface */
};
struct usb_endpoint_descriptor endpoint = {
sizeof(struct usb_endpoint_descriptor), /* bLength */
5, /* bDescriptorType: UDESC_ENDPOINT */
0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
3, /* bmAttributes: UE_INTERRUPT */
8, 0, /* wMaxPacketSize */
255 /* bInterval */
};
struct usb_hub_descriptor hub = {
sizeof(struct usb_hub_descriptor), /* bDescLength */
0x29, /* bDescriptorType: hub
descriptor */
2, /* bNrPorts -- runtime modified */
0, 0, /* wHubCharacteristics */
0xff, /* bPwrOn2PwrGood */
{}, /* bHubCntrCurrent */
{} /* at most 7 ports! XXX */
};
Why don't use somenthing like this? (see up)
> +static int
> +ehci_submit_root (struct usb_device *dev, unsigned long pipe, void *buffer,
> + int length, struct devrequest *req)
> +{
> + uint8_t tmpbuf[4];
> + void *srcptr;
> + int len, srclen;
> + uint32_t reg;
> +
> + srclen = 0;
> + srcptr = NULL;
> +
> + debug ("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
> + req->request, req->request,
> + req->requesttype, req->requesttype,
> + le16_to_cpu (req->value), le16_to_cpu (req->index));
> +
> +#define C(a,b) (((b) << 8) | (a))
> +
> + switch (C (req->request, req->requesttype)) {
> + case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE):
> + switch (le16_to_cpu (req->value) >> 8) {
> + case USB_DT_DEVICE:
> + srcptr = descr.device;
> + srclen = sizeof (descr.device);
> + break;
> + case USB_DT_CONFIG:
> + srcptr = descr.config;
> + srclen = sizeof (descr.config) +
> + sizeof (descr.interface) + sizeof (descr.endpoint);
> + break;
> + case USB_DT_STRING:
> + switch (le16_to_cpu (req->value) & 0xff) {
> + case 0: /* Language */
> + srcptr = "\4\3\1\0";
> + srclen = 4;
> + break;
> + case 1: /* Vendor */
> + srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
> + srclen = 14;
> + break;
> + case 2: /* Product */
> + srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
> + srclen = 42;
> + break;
> + default:
> + goto unknown;
> + }
> + break;
> + default:
> + debug ("unknown value %x", le16_to_cpu (req->value));
> + goto unknown;
> + }
> + break;
> + case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB):
> + switch (le16_to_cpu (req->value) >> 8) {
> + case USB_DT_HUB:
> + srcptr = descr.hub;
> + srclen = sizeof (descr.hub);
> + break;
> + default:
> + debug ("unknown value %x", le16_to_cpu (req->value));
> + goto unknown;
> + }
> + break;
> + case C (USB_REQ_SET_ADDRESS, USB_RECIP_DEVICE):
> + rootdev = le16_to_cpu (req->value);
> + break;
> + case C (USB_REQ_SET_CONFIGURATION, USB_RECIP_DEVICE):
> + /* Nothing to do */
> + break;
> + case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB):
> + tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
> + tmpbuf[1] = 0;
> + srcptr = tmpbuf;
> + srclen = 2;
> + break;
> + case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT):
> + memset (tmpbuf, 0, 4);
> + reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> + if (reg & EHCI_PS_CS)
> + tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
> + if (reg & EHCI_PS_PE)
> + tmpbuf[0] |= USB_PORT_STAT_ENABLE;
> + if (reg & EHCI_PS_SUSP)
> + tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
> + if (reg & EHCI_PS_OCA)
> + tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
> + if (reg & EHCI_PS_PR)
> + tmpbuf[0] |= USB_PORT_STAT_RESET;
> + if (reg & EHCI_PS_PP)
> + tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
> + tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
> +
> + if (reg & EHCI_PS_CSC)
> + tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
> + if (reg & EHCI_PS_PEC)
> + tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
> + if (reg & EHCI_PS_OCC)
> + tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
> + if (portreset & (1 << le16_to_cpu (req->index)))
> + tmpbuf[2] |= USB_PORT_STAT_C_RESET;
> + srcptr = tmpbuf;
> + srclen = 4;
> + break;
> + case C (USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> + reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> + reg &= ~EHCI_PS_CLEAR;
> + switch (le16_to_cpu (req->value)) {
> + case USB_PORT_FEAT_POWER:
> + reg |= EHCI_PS_PP;
> + break;
> + case USB_PORT_FEAT_RESET:
> + if (EHCI_PS_IS_LOWSPEED (reg)) {
> + /* Low speed device, give up ownership. */
> + reg |= EHCI_PS_PO;
> + break;
> + }
> + /* Start reset sequence. */
> + reg &= ~EHCI_PS_PE;
> + reg |= EHCI_PS_PR;
> + hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> + cpu_to_le32 (reg);
> + /* Wait for reset to complete. */
> + udelay (500000);
> + /* Terminate reset sequence. */
> + reg &= ~EHCI_PS_PR;
> + /* TODO: is it only fsl chip that requires this
> + * manual setting of port enable?
> + */
> + reg |= EHCI_PS_PE;
> + hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> + cpu_to_le32 (reg);
> + /* Wait for HC to complete reset. */
> + udelay (2000);
> + reg =
> + le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> + reg &= ~EHCI_PS_CLEAR;
> + if ((reg & EHCI_PS_PE) == 0) {
> + /* Not a high speed device, give up ownership. */
> + reg |= EHCI_PS_PO;
> + break;
> + }
> + portreset |= 1 << le16_to_cpu (req->index);
> + break;
> + default:
> + debug ("unknown feature %x", le16_to_cpu (req->value));
> + goto unknown;
> + }
> + hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
> + break;
> + case C (USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> + reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> + reg &= ~EHCI_PS_CLEAR;
> + switch (le16_to_cpu (req->value)) {
> + case USB_PORT_FEAT_ENABLE:
> + reg &= ~EHCI_PS_PE;
> + break;
> + case USB_PORT_FEAT_C_CONNECTION:
> + reg |= EHCI_PS_CSC;
> + break;
> + case USB_PORT_FEAT_C_RESET:
> + portreset &= ~(1 << le16_to_cpu (req->index));
> + break;
> + default:
> + debug ("unknown feature %x", le16_to_cpu (req->value));
> + goto unknown;
> + }
> + hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
> + break;
> + default:
> + debug ("Unknown request %x",
> + C (req->request, req->requesttype));
> + goto unknown;
> + }
> +
> +#undef C
> +
> + len = min3 (srclen, le16_to_cpu (req->length), length);
> + if (srcptr != NULL && len > 0)
> + memcpy (buffer, srcptr, len);
> + dev->act_len = len;
> + dev->status = 0;
> + return (0);
> +
> + unknown:
> + debug ("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
> + req->requesttype, req->request, le16_to_cpu (req->value),
> + le16_to_cpu (req->index), le16_to_cpu (req->length));
> +
> + dev->act_len = 0;
> + dev->status = USB_ST_STALLED;
> + return (-1);
> +}
> +
>
This code can be change according with this one.
static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
void *buffer, int length, struct devrequest
*req)
{
uint8_t tmpbuf[4];
u16 typeReq;
void *srcptr;
int len, srclen;
uint32_t reg;
srclen = 0;
srcptr = NULL;
DBG("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
req->request, req->request,
req->requesttype, req->requesttype,
swap_16(req->value), swap_16(req->index));
typeReq = req->request << 8 | req->requesttype;
switch (typeReq) {
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch(swap_16(req->value) >> 8) {
case USB_DT_DEVICE:
srcptr = &device;
srclen = sizeof(struct usb_device_descriptor);
break;
case USB_DT_CONFIG:
srcptr = &config;
srclen = sizeof(config) +
sizeof(struct usb_interface_descriptor) +
sizeof(struct usb_hub_descriptor);
break;
case USB_DT_STRING:
switch (swap_16(req->value) & 0xff) {
case 0: /* Language */
srcptr = "\4\3\1\0";
srclen = 4;
break;
case 1: /* Vendor */
srcptr = "\20\3P\0h\0i\0l\0i\0p\0s\0";
srclen = 16;
break;
case 2: /* Product */
srcptr = "\12\3E\0H\0C\0I\0";
srclen = 10;
break;
default:
goto unknown;
}
break;
default:
DBG("unknown value %x", swap_16(req->value));
goto unknown;
}
break;
case USB_REQ_GET_DESCRIPTOR | (( USB_DIR_IN | USB_RT_HUB) << 8):
switch (swap_16(req->value) >> 8) {
case USB_DT_HUB:
srcptr = &hub;
srclen = sizeof(hub);
break;
default:
DBG("unknown value %x", swap_16(req->value));
goto unknown;
}
break;
case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
rootdev = swap_16(req->value);
break;
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
/* Nothing to do */
break;
case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
tmpbuf[1] = 0;
srcptr = tmpbuf;
srclen = 2;
break;
case DeviceRequest | USB_REQ_GET_STATUS:
memset(tmpbuf, 0, 4);
reg = swap_32(hcor->or_portsc[swap_16(req->index) - 1]);
if (reg & EHCI_PS_CS)
tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
if (reg & EHCI_PS_PE)
tmpbuf[0] |= USB_PORT_STAT_ENABLE;
if (reg & EHCI_PS_SUSP)
tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
if (reg & EHCI_PS_OCA)
tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
if (reg & EHCI_PS_PR)
tmpbuf[0] |= USB_PORT_STAT_RESET;
if (reg & EHCI_PS_PP)
...
All the struct are defined in u-boot and you can reuse that one, I think.
Regards Michael
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
@ 2008-07-07 7:21 ` Markus Klotzbücher
2008-07-10 15:00 ` Markus Klotzbücher
2 siblings, 0 replies; 12+ messages in thread
From: Markus Klotzbücher @ 2008-07-07 7:21 UTC (permalink / raw)
To: u-boot
Hi Tor,
Tor Krill <tor@excito.com> writes:
> Add high speed support to USB code. Extracted from Juniper Networks patch.
>
> I know that the mergewindow is closed but wanted to get feedback on these
> patches if possible.
Thanks for the patches! I just got back from holiday, so it'll take a
couple of days for reviewing.
Thank you for your patience.
Viele Gr??e / Best regards
Markus Klotzb?cher
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
2008-07-07 7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
@ 2008-07-10 15:00 ` Markus Klotzbücher
2008-07-10 15:22 ` Tor Krill
2 siblings, 1 reply; 12+ messages in thread
From: Markus Klotzbücher @ 2008-07-10 15:00 UTC (permalink / raw)
To: u-boot
Hi Tor,
Tor Krill <tor@excito.com> writes:
> Add high speed support to USB code. Extracted from Juniper Networks patch.
>
> I know that the mergewindow is closed but wanted to get feedback on these
> patches if possible.
Thanks again for fixing this up. AFAIK patches look fine, only two
things:
- please address the issues pointed out by Michael, especially removal
of the "C" macro.
- Secondly it would be nice if we could have a short README.ehci or
similar which explains what works and what not, and what needs to be
done to add further board/HC support.
Thank you in advance.
Best regards
Markus Klotzb?cher
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
2008-07-10 15:00 ` Markus Klotzbücher
@ 2008-07-10 15:22 ` Tor Krill
2008-09-03 7:02 ` [U-Boot] " Markus Klotzbücher
0 siblings, 1 reply; 12+ messages in thread
From: Tor Krill @ 2008-07-10 15:22 UTC (permalink / raw)
To: u-boot
On 7/10/2008, "Markus Klotzb?cher" <mk@denx.de> wrote:
>Hi Tor,
Hi Markus,
>Tor Krill <tor@excito.com> writes:
>
>> Add high speed support to USB code. Extracted from Juniper Networks patch.
>>
>> I know that the mergewindow is closed but wanted to get feedback on these
>> patches if possible.
>
>Thanks again for fixing this up. AFAIK patches look fine, only two
> things:
>
>- please address the issues pointed out by Michael, especially removal
> of the "C" macro.
>
>- Secondly it would be nice if we could have a short README.ehci or
> similar which explains what works and what not, and what needs to be
> done to add further board/HC support.
>
>Thank you in advance.
Thank you for reviewing. I will try fix things up and resubmit later.
Best Regards,
/Tor
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
2008-07-10 15:22 ` Tor Krill
@ 2008-09-03 7:02 ` Markus Klotzbücher
0 siblings, 0 replies; 12+ messages in thread
From: Markus Klotzbücher @ 2008-09-03 7:02 UTC (permalink / raw)
To: u-boot
Hi Tor,
On Thu, Jul 10, 2008 at 05:22:18PM +0200, Tor Krill wrote:
> On 7/10/2008, "Markus Klotzb?cher" <mk@denx.de> wrote:
> >Tor Krill <tor@excito.com> writes:
> >
> >> Add high speed support to USB code. Extracted from Juniper Networks patch.
> >>
> >> I know that the mergewindow is closed but wanted to get feedback on these
> >> patches if possible.
> >
> >Thanks again for fixing this up. AFAIK patches look fine, only two
> > things:
> >
> >- please address the issues pointed out by Michael, especially removal
> > of the "C" macro.
> >
> >- Secondly it would be nice if we could have a short README.ehci or
> > similar which explains what works and what not, and what needs to be
> > done to add further board/HC support.
> >
> >Thank you in advance.
>
> Thank you for reviewing. I will try fix things up and resubmit
> later.
Any news about this? I'd very much like to get your patches merged...
Best regards
Markus Klotzb?cher
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de")
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
[not found] ` <49267DEB.5020903@gandalf.sssup.it>
@ 2008-11-25 8:20 ` Remy Bohmer
[not found] ` <20081125083937.GA10745@x61.spaceport9>
1 sibling, 0 replies; 12+ messages in thread
From: Remy Bohmer @ 2008-11-25 8:20 UTC (permalink / raw)
To: u-boot
Hello Michael,
> I have redone the patch. What do you think?
> I can't test them. They compile.
Besides the not-tested part I replied to you about yesterday, can you
please post these patches in the proper format. (inlined, signed-off
etc)
See http://www.denx.de/wiki/U-Boot/Patches
Kind Regards,
Remy
>
> Regards Michael
>
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great
> prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH 2/4][RFC] Add ehci core functionality
[not found] ` <492BE407.7030309@gandalf.sssup.it>
@ 2008-11-25 12:12 ` Wolfgang Denk
2008-11-25 12:22 ` michael
0 siblings, 1 reply; 12+ messages in thread
From: Wolfgang Denk @ 2008-11-25 12:12 UTC (permalink / raw)
To: u-boot
Dear michael,
In message <492BE407.7030309@gandalf.sssup.it> you wrote:
> SGksCgpNYXJrdXMgS2xvdHpiw7xjaGVyIHdyb3RlOgo+IE9uIEZyaSwgTm92IDIxLCAyMDA4IGF0
> IDEwOjIyOjUxQU0gKzAxMDAsIG1pY2hhZWwgd3JvdGU6Cj4gICAKPj4gSGksCj4+Cj4+IEkgaGF2
> ZSByZWRvbmUgdGhlIHBhdGNoLiBXaGF0IGRvIHlvdSB0aGluaz8KPj4KPj4gSSBjYW4ndCB0ZXN0
> IHRoZW0uIFRoZXkgY29tcGlsZS4KPj4gICAgIAo+Cj4gTm90IGZvciBtZSAoYm9hcmQgaXMgc2Vx
> dW9pYSk6Cj4KPiBtYWtlIC1DIGNvbW1vbi8KPiBtYWtlWzFdOiBFbnRlcmluZyBkaXJlY3Rvcnkg
> YC9ob21lL21rL3NyYy9naXQvdS1ib290L2NvbW1vbicKPiBwcGNfNHh4RlAtZ2NjIC1nICAtT3Mg
> ICAtZlBJQyAtZmZpeGVkLXIxNCAtbWVhYmkgLWZuby1zdHJpY3QtYWxpYXNpbmcgLURfX0tFUk5F
> TF9fIC1EVEVYVF9CQVNFPTB4RkZGQTAwMDAgLUkvaG9tZS9tay9zcmMvZ2l0L3UtYm9vdC9pbmNs
> dWRlIC1mbm8tYnVpbHRpbiAtZmZyZWVzdGFuZGluZyAtbm9zdGRpbmMgLWlzeXN0ZW0gL2hvbWUv
> bWsvZWxka3MvZWxkay00LjIvdXNyL2Jpbi8uLi9saWIvZ2NjL3Bvd2VycGMtbGludXgvNC4yLjIv
> aW5jbHVkZSAtcGlwZSAgLURDT05GSUdfUFBDIC1EX19wb3dlcnBjX18gLURDT05GSUdfNHh4IC1m
> Zml4ZWQtcjIgLW1zdHJpbmcgLW1zb2Z0LWZsb2F0IC1XYSwtbTQ0MCAtbWNwdT00NDAgLURDT05G
> SUdfNDQwPTEgLVdhbGwgLVdzdHJpY3QtcHJvdG90eXBlcyAtZm5vLXN0YWNrLXByb3RlY3RvciAt
> YyAtbyB1c2IubyB1c2IuYwo+IHVzYi5jOiBJbiBmdW5jdGlvbiAndXNiX2h1Yl9wb3J0X2Nvbm5l
> Y3RfY2hhbmdlJzoKPiB1c2IuYzoxMTI5OiBlcnJvcjogJ3N0cnVjdCB1c2JfZGV2aWNlJyBoYXMg
> bm8gbWVtYmVyIG5hbWVkICdzbG93Jwo+IG1ha2VbMV06ICoqKiBbdXNiLm9dIEVycm9yIDEKPiBt
> YWtlWzFdOiBUYXJnZXQgYGFsbCcgbm90IHJlbWFkZSBiZWNhdXNlIG9mIGVycm9ycy4KPgo+IEJl
> c3QgcmVnYXJkcwo+IE1hcmt1cwo+Cj4gICAKCkNhbiB5b3UgcGxlYXNlIHNlbmQgeW91ciBjb25m
> aWd1cmF0aW9uPwoKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
> LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVGhpcyBTRi5OZXQgZW1haWwgaXMgc3BvbnNv
> cmVkIGJ5IHRoZSBNb2JsaW4gWW91ciBNb3ZlIERldmVsb3BlcidzIGNoYWxsZW5nZQpCdWlsZCB0
> aGUgY29vbGVzdCBMaW51eCBiYXNlZCBhcHBsaWNhdGlvbnMgd2l0aCBNb2JsaW4gU0RLICYgd2lu
> IGdyZWF0IHByaXplcwpHcmFuZCBwcml6ZSBpcyBhIHRyaXAgZm9yIHR3byB0byBhbiBPcGVuIFNv
> dXJjZSBldmVudCBhbnl3aGVyZSBpbiB0aGUgd29ybGQKaHR0cDovL21vYmxpbi1jb250ZXN0Lm9y
> Zy9yZWRpcmVjdC5waHA/YmFubmVyX2lkPTEwMCZ1cmw9LwpfX19fX19fX19fX19fX19fX19fX19f
> X19fX19fX19fX19fX19fX19fX19fX19fXwpVLUJvb3QtVXNlcnMgbWFpbGluZyBsaXN0ClUtQm9v
> dC1Vc2Vyc0BsaXN0cy5zb3VyY2Vmb3JnZS5uZXQKaHR0cHM6Ly9saXN0cy5zb3VyY2Vmb3JnZS5u
> ZXQvbGlzdHMvbGlzdGluZm8vdS1ib290LXVzZXJzCg==
Please stop posting base64 encoded stuff. Send plain text only.
And please stop sending to the old sourceforge list. The mailing list
address is u-boot at lists.denx.de
> Markus Klotzb?cher wrote:
...
> > Not for me (board is sequoia):
...
>Can you please send your configuration?
Markus explicitely mentioned that he was using the "sequoia" board
configuration. What else would you need?
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
You don't need a weatherman to know which way the wind blows.
- Bob Dylan
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH 2/4][RFC] Add ehci core functionality
2008-11-25 12:12 ` [U-Boot] " Wolfgang Denk
@ 2008-11-25 12:22 ` michael
0 siblings, 0 replies; 12+ messages in thread
From: michael @ 2008-11-25 12:22 UTC (permalink / raw)
To: u-boot
Wolfgang Denk wrote:
> Dear michael,
>
>> Can you please send your configuration?
>
> Markus explicitely mentioned that he was using the "sequoia" board
> configuration. What else would you need?
>
>
Ok, I read a lot of mail, and I'm preparing a clean patch set. I'm sorry
Markus.
> Best regards,
>
> Wolfgang Denk
>
>
Regards Michael
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-11-25 12:22 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver Tor Krill
2008-06-23 12:59 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality michael
[not found] ` <49267DEB.5020903@gandalf.sssup.it>
2008-11-25 8:20 ` [U-Boot] " Remy Bohmer
[not found] ` <20081125083937.GA10745@x61.spaceport9>
[not found] ` <492BE407.7030309@gandalf.sssup.it>
2008-11-25 12:12 ` [U-Boot] " Wolfgang Denk
2008-11-25 12:22 ` michael
2008-07-07 7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
2008-07-10 15:00 ` Markus Klotzbücher
2008-07-10 15:22 ` Tor Krill
2008-09-03 7:02 ` [U-Boot] " Markus Klotzbücher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox