Dear Kuo-Jung Su,

> From: Kuo-Jung Su <dant...@faraday-tech.com>
> 
> There is at least one non-EHCI compliant controller (i.e. Faraday EHCI)
> known to implement a non-standard TDI stuff.
> Futhermore, it not only leave reserved and CONFIGFLAG registers
> un-implemented but also has their address spaces removed.
> 
> And thus, we need weak-aliased functions to both TDI stuff
> and PORTSC registers for interface abstraction.
> 
> Signed-off-by: Kuo-Jung Su <dant...@faraday-tech.com>
> CC: Marek Vasut <ma...@denx.de>
> ---
> Changes for v5:
>    - Split up from Faraday EHCI patch
> 
> Changes for v2 - v4:
>    - See 'usb: ehci: add Faraday USB 2.0 EHCI support'
> 
>  drivers/usb/host/ehci-hcd.c |  100
> +++++++++++++++++++++++++++---------------- 1 file changed, 64
> insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index c816878..b334173 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -117,10 +117,50 @@ static struct descriptor {
>  };
> 
>  #if defined(CONFIG_EHCI_IS_TDI)
> -#define ehci_is_TDI()        (1)
> -#else
> -#define ehci_is_TDI()        (0)
> +# define ehci_is_TDI()       (1)
> +
> +/* put TDI/ARC silicon into EHCI mode */
> +void __ehci_tdi_reset(struct ehci_hcor *hcor)
> +{
> +     uint32_t tmp, *reg_ptr;
> +
> +     reg_ptr = (uint32_t *)((uint8_t *) + USBMODE);
> +     tmp = ehci_readl(reg_ptr);
> +     tmp |= USBMODE_CM_HC;
> +#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
> +     tmp |= USBMODE_BE;
>  #endif
> +     ehci_writel(reg_ptr, tmp);
> +}
> +
> +void ehci_tdi_reset(struct ehci_hcor *hcor)
> +     __attribute__((weak, alias("__ehci_tdi_reset")));

Just wrap this into simple

__weak void ehci_tdi_reset(struct ehci_hcor *hcor)
{
        ...body of __ehci_tdi_reset() above ...
}

it's the same thing as those two functions above, but without so much code ;-)

if it doesn't work, include <linux/compiler.h>, same below.

> +int __ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
> +{
> +     int ret = 0;
> +
> +     switch (PORTSC_PSPD(portsc)) {
> +     case PORTSC_PSPD_FS:
> +             break;
> +     case PORTSC_PSPD_LS:
> +             ret = USB_PORT_STAT_LOW_SPEED;
> +             break;
> +     case PORTSC_PSPD_HS:
> +     default:
> +             ret = USB_PORT_STAT_HIGH_SPEED;
> +             break;
> +     }
> +
> +     return ret;
> +}
> +
> +int ehci_port_speed(struct ehci_hcor *hcor, unsigned int portsc)
> +     __attribute__((weak, alias("__ehci_port_speed")));
> +
> +#else  /* CONFIG_EHCI_IS_TDI */
> +# define ehci_is_TDI()       (0)
> +#endif /* CONFIG_EHCI_IS_TDI */
> 
>  void __ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
>  {
> @@ -149,8 +189,6 @@ static int handshake(uint32_t *ptr, uint32_t mask,
> uint32_t done, int usec) static int ehci_reset(int index)
>  {
>       uint32_t cmd;
> -     uint32_t tmp;
> -     uint32_t *reg_ptr;
>       int ret = 0;
> 
>       cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
> @@ -163,15 +201,8 @@ static int ehci_reset(int index)
>               goto out;
>       }
> 
> -     if (ehci_is_TDI()) {
> -             reg_ptr = (uint32_t *)((u8 *)ehcic[index].hcor + USBMODE);
> -             tmp = ehci_readl(reg_ptr);
> -             tmp |= USBMODE_CM_HC;
> -#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
> -             tmp |= USBMODE_BE;
> -#endif
> -             ehci_writel(reg_ptr, tmp);
> -     }
> +     if (ehci_is_TDI())
> +             ehci_tdi_reset(ehcic[index].hcor);
> 
>  #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
>       cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
> @@ -597,6 +628,18 @@ static inline int min3(int a, int b, int c)
>       return a;
>  }
> 
> +uint32_t *__ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
> +{
> +     if (port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
> +             printf("The request port(%d) is not configured\n", port);
> +             return NULL;
> +     }
> +
> +     return (uint32_t *)&hcor->or_portsc[port];
> +}
> +uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
> +     __attribute__((weak, alias("__ehci_get_portsc_register")));
> +
>  int
>  ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
>                int length, struct devrequest *req)
> @@ -609,13 +652,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
> long pipe, void *buffer, uint32_t *status_reg;
>       struct ehci_ctrl *ctrl = dev->controller;
> 
> -     if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
> -             printf("The request port(%d) is not configured\n",
> -                     le16_to_cpu(req->index) - 1);
> +     status_reg = ehci_get_portsc_register(ctrl->hcor,
> +             le16_to_cpu(req->index) - 1);
> +     if (!status_reg)
>               return -1;
> -     }
> -     status_reg = (uint32_t *)&ctrl->hcor->or_portsc[
> -                                             le16_to_cpu(req->index) - 1];
>       srclen = 0;
> 
>       debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
> @@ -709,23 +749,10 @@ ehci_submit_root(struct usb_device *dev, unsigned
> long pipe, void *buffer, tmpbuf[0] |= USB_PORT_STAT_RESET;
>               if (reg & EHCI_PS_PP)
>                       tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
> -
> -             if (ehci_is_TDI()) {
> -                     switch (PORTSC_PSPD(reg)) {
> -                     case PORTSC_PSPD_FS:
> -                             break;
> -                     case PORTSC_PSPD_LS:
> -                             tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
> -                             break;
> -                     case PORTSC_PSPD_HS:
> -                     default:
> -                             tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
> -                             break;
> -                     }
> -             } else {
> +             if (ehci_is_TDI())
> +                     tmpbuf[1] |= ehci_port_speed(ctrl->hcor, reg) >> 8;
> +             else
>                       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)
> @@ -954,6 +981,7 @@ int usb_lowlevel_init(int index, void **controller)
>       cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
>       cmd |= FLAG_CF;
>       ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
> +

This is redundant ;-)

>       /* unblock posted write */
>       cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
>       mdelay(5);
> --
> 1.7.9.5

Best regards,
Marek Vasut
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to