From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Fri, 26 Apr 2013 14:19:22 +0200 Subject: [U-Boot] [PATCH v3 08/11] usb: ehci: add Faraday USB 2.0 EHCI support In-Reply-To: <1366963360-2987-9-git-send-email-dantesu@gmail.com> References: <1366963360-2987-1-git-send-email-dantesu@gmail.com> <1366963360-2987-9-git-send-email-dantesu@gmail.com> Message-ID: <201304261419.22683.marex@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Dear Kuo-Jung Su, > From: Kuo-Jung Su > > This patch add supports to both Faraday FUSBH200 and FOTG210, > these controllers slightly differ from standard EHCI specification. How do they differ? > Signed-off-by: Kuo-Jung Su > CC: Marek Vasut > --- > common/usb_hub.c | 5 ++ > drivers/usb/host/Makefile | 1 + > drivers/usb/host/ehci-faraday.c | 122 > +++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ehci-hcd.c | > 11 ++++ > drivers/usb/host/ehci.h | 5 ++ > include/usb/fotg210.h | 71 +++++++++++++++++++++++ > include/usb/fusbh200.h | 28 +++++++++ > 7 files changed, 243 insertions(+) > create mode 100644 drivers/usb/host/ehci-faraday.c > create mode 100644 include/usb/fotg210.h > create mode 100644 include/usb/fusbh200.h > > diff --git a/common/usb_hub.c b/common/usb_hub.c > index b5eeb62..26d66b8 100644 > --- a/common/usb_hub.c > +++ b/common/usb_hub.c > @@ -375,6 +375,11 @@ static int usb_hub_configure(struct usb_device *dev) > return -1; > } > > +#ifdef CONFIG_USB_EHCI_FARADAY > + /* Faraday USB 2.0 EHCI chips need a long long delay here */ Why? Do they need it only for root hub or for all the hub down the road as well? > + mdelay(250); > +#endif > + > if (usb_get_hub_status(dev, buffer) < 0) { > USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n", > dev->status); > diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile > index 87a5970..98f2a10 100644 > --- a/drivers/usb/host/Makefile > +++ b/drivers/usb/host/Makefile > @@ -43,6 +43,7 @@ COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-mpc512x.o > else > COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o > endif > +COBJS-$(CONFIG_USB_EHCI_FARADAY) += ehci-faraday.o > COBJS-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o > COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o > COBJS-$(CONFIG_USB_EHCI_MXS) += ehci-mxs.o > diff --git a/drivers/usb/host/ehci-faraday.c > b/drivers/usb/host/ehci-faraday.c new file mode 100644 > index 0000000..adf57d1 > --- /dev/null > +++ b/drivers/usb/host/ehci-faraday.c > @@ -0,0 +1,122 @@ > +/* > + * Faraday USB 2.0 EHCI Controller > + * > + * (C) Copyright 2010 Faraday Technology > + * Dante Su > + * > + * This file is released under the terms of GPL v2 and any later version. > + * See the file COPYING in the root directory of the source tree for > details. + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include "ehci.h" > + > +union ehci_faraday_regs { > + struct fusbh200_regs usb; > + struct fotg210_regs otg; > +}; > + > +static inline int ehci_hci_fotg2xx(struct ehci_hccr *hccr) > +{ > + union ehci_faraday_regs __iomem *regs = (void *)hccr; > + return !readl(®s->usb.easstr); > +} > + > +/* > + * Create the appropriate control structures to manage > + * a new EHCI host controller. > + */ > +int ehci_hcd_init(int index, struct ehci_hccr **ret_hccr, > + struct ehci_hcor **ret_hcor) > +{ > + struct ehci_hccr *hccr; > + struct ehci_hcor *hcor; > + union ehci_faraday_regs __iomem *regs; > +#ifdef CONFIG_USB_EHCI_BASE_LIST > + uint32_t base_list[] = CONFIG_USB_EHCI_BASE_LIST; > +#else > + uint32_t base_list[] = { CONFIG_USB_EHCI_BASE }; > +#endif > + > + if (index < 0 || index >= ARRAY_SIZE(base_list)) > + return -1; > + regs = (void __iomem *)base_list[index]; > + hccr = (struct ehci_hccr *)®s->usb.hccr; > + hcor = (struct ehci_hcor *)®s->usb.hcor; > + > + if (ehci_hci_fotg2xx(hccr)) { > + /* A-device bus reset */ > + /* ... Power off A-device */ > + setbits_le32(®s->otg.otgcsr, BIT_MASK(5)); Do these bits not have names? [...] > +int ehci_hcd_port_speed(struct ehci_hccr *hccr) > +{ > + int ret = 0; > + int speed; > + union ehci_faraday_regs __iomem *regs = (void *)hccr; > + > + if (ehci_hci_fotg2xx(hccr)) > + speed = (readl(®s->otg.otgcsr) >> 22) & 0x03; > + else > + speed = (readl(®s->usb.bmcsr) >> 9) & 0x03; Same here, what're these magic numbers? > + switch (speed) { > + case 0: /* full speed */ > + break; > + > + case 1: /* low speed */ > + ret = USB_PORT_STAT_LOW_SPEED; > + break; > + > + case 2: /* high speed */ > + ret = USB_PORT_STAT_HIGH_SPEED; > + break; > + > + default: > + printf("ehci-faraday: invalid device speed\n"); > + break; > + } > + > + return ret; > +} > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c > index c816878..450d217 100644 > --- a/drivers/usb/host/ehci-hcd.c > +++ b/drivers/usb/host/ehci-hcd.c > @@ -149,8 +149,10 @@ static int handshake(uint32_t *ptr, uint32_t mask, > uint32_t done, int usec) static int ehci_reset(int index) > { > uint32_t cmd; > +#ifndef CONFIG_USB_EHCI_FARADAY > uint32_t tmp; > uint32_t *reg_ptr; > +#endif > int ret = 0; > > cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd); > @@ -163,6 +165,7 @@ static int ehci_reset(int index) > goto out; > } > > +#ifndef CONFIG_USB_EHCI_FARADAY Wouldn't it suffice to set your EHCI is not TDI ? > if (ehci_is_TDI()) { > reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE); > tmp = ehci_readl(reg_ptr); > @@ -172,6 +175,7 @@ static int ehci_reset(int index) > #endif > ehci_writel(reg_ptr, tmp); > } > +#endif /* !CONFIG_USB_EHCI_FARADAY */ [...]