[U-Boot] [PATCH 2/5] driver: usb: add EHCI driver for hi3787cv200 SoC

Marek Vasut marex at denx.de
Fri May 5 23:05:36 UTC 2017


On 05/05/2017 07:55 PM, Jorge Ramirez wrote:
> On 05/05/2017 05:34 PM, Marek Vasut wrote:
>> On 05/05/2017 04:32 PM, Tom Rini wrote:
>>> On Thu, May 04, 2017 at 03:47:07PM +0200, Jorge Ramirez-Ortiz wrote:
>>>
>>> CC'ing Marek...
>>>
>>>> Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz at linaro.org>
>>>> ---
>>>>   .../arm/include/asm/arch-hi3798cv200/hi3798cv200.h |  93 ++++++++++
>>>>   drivers/usb/host/Kconfig                           |   6 +
>>>>   drivers/usb/host/Makefile                          |   1 +
>>>>   drivers/usb/host/ehci-hi3798cv200.c                | 196
>>>> +++++++++++++++++++++
>>>>   4 files changed, 296 insertions(+)
>>>>   create mode 100644
>>>> arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
>>>>   create mode 100644 drivers/usb/host/ehci-hi3798cv200.c
>>>>
>>>> diff --git a/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
>>>> b/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
>>>> new file mode 100644
>>>> index 0000000..c67fda1
>>>> --- /dev/null
>>>> +++ b/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
>>>> @@ -0,0 +1,93 @@
>>>> +/*
>>>> + * (C) Copyright 2017 Linaro
>>>> + * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz at linaro.org>
>>>> + *
>>>> + * SPDX-License-Identifier:    GPL-2.0+
>>>> + */
>>>> +
>>>> +#ifndef __HI3798cv200_H__
>>>> +#define __HI3798cv200_H__
>> This should be a separate patch ..
> hi Marek
> 
> to be clear, are you asking a single patch containing hi3798cv200.h?

Yes, this is arch stuff and is not in any way part of the USB driver IMO.

[...]

>>>> +};
>>>> +
>>>> +#endif
>>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>>> index 0bf8274..a749d0e 100644
>>>> --- a/drivers/usb/host/Kconfig
>>>> +++ b/drivers/usb/host/Kconfig
>>>> @@ -128,6 +128,12 @@ config USB_EHCI_ZYNQ
>>>>       ---help---
>>>>         Enable support for Zynq on-chip EHCI USB controller
>>>>   +config USB_EHCI_POPLAR
>>>> +    bool "Support for HI3798cv200 EHCI USB controller"
>> Does HI stand for Hitachi ?
> 
> Hisilicon

Don't we already have some hisilicon stuff in the tree ? Maybe some
96board ?

In fact, could this driver be replaced by ehci-generic ?

>>>> +    default y
>>>> +    ---help---
>>>> +      Enable support for Poplar on-chip EHCI USB controller
>>>> +
>>>>   config USB_EHCI_GENERIC
>>>>       bool "Support for generic EHCI USB controller"
>>>>       depends on OF_CONTROL
>>>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>>>> index 58c0cf5..3661636 100644
>>>> --- a/drivers/usb/host/Makefile
>>>> +++ b/drivers/usb/host/Makefile
>>>> @@ -52,6 +52,7 @@ obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
>>>>   obj-$(CONFIG_USB_EHCI_VF) += ehci-vf.o
>>>>   obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o
>>>>   obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
>>>> +obj-$(CONFIG_USB_EHCI_POPLAR) += ehci-hi3798cv200.o
>>>>     # xhci
>>>>   obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
>>>> diff --git a/drivers/usb/host/ehci-hi3798cv200.c
>>>> b/drivers/usb/host/ehci-hi3798cv200.c
>>>> new file mode 100644
>>>> index 0000000..c535de1
>>>> --- /dev/null
>>>> +++ b/drivers/usb/host/ehci-hi3798cv200.c
>>>> @@ -0,0 +1,196 @@
>>>> +/*
>>>> + * (C) Copyright 2017 Linaro
>>>> + * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz at linaro.org>
>>>> + *
>>>> + * SPDX-License-Identifier:    GPL-2.0+
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <asm/arch/hi3798cv200.h>
>>>> +#include <asm/io.h>
>>>> +
>>>> +#include "ehci.h"
>>>> +
>>>> +static struct hi3798cv200_ehci_ctrl_regs *ctrl = (void *)
>>>> HI3798CV200_EHCI_CTRL;
>> This should use DM
> 
> it there a strong requirement for this?

Yes, USB is huge which means your system had enough resources. Adding DM
to it doesn't hurt and makes things easier.

> there a number of ehci drivers like this one already in the tree so I am
> just wondering if i would be possible to merge it as (just so we can
> focus in the network driver next).

No.

> otherwise - if you think this will be a maintenance issue for you - sure
> I'll start looking into it.

Should be pretty easy to convert.

>>>> +static void inno_phy_config_2p_1(void)
>>>> +{
>>>> +    u32 reg;
>>>> +    /* write 0x4 to addr 0x06
>>>> +    * config 2P PHY clk output
>>>> +    * delay 1ms for waiting PLL stable
>>>> +    */
>>>> +    reg = TEST_WRDATA|TEST_ADDR|TEST_WREN|TEST_RSTN;
>>>> +    writel(reg, &ctrl->peri_usb0);
>>>> +    reg = TEST_WRDATA|TEST_ADDR|TEST_WREN|TEST_RSTN|TEST_CLK;
>>>> +    writel(reg, &ctrl->peri_usb0);
>>>> +    reg = TEST_WRDATA|TEST_ADDR|TEST_WREN|TEST_RSTN;
>>>> +    writel(reg, &ctrl->peri_usb0);
>>>> +    mdelay(1);
>>>> +
>>>> +    /* write 0x1c to addr 0x00
>>>> +    * 0x00[0] = 0 : close EOP pre-emphasis
>>>> +    * 0x00[2] = 1 : open Data pre-emphasis
>>>> +    */
>>>> +    writel(0xa1001c, &ctrl->peri_usb0);
>>>> +    writel(0xe1001c, &ctrl->peri_usb0);
>>>> +    writel(0xa1001c, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /* write 0x07 to 0x06
>>>> +    * {0x06[1:0],0x05[7]} = 110 : Rcomp = 150mV , increase DC level
>>>> +    */
>>>> +    writel(0xa00607, &ctrl->peri_usb0);
>>>> +    writel(0xe00607, &ctrl->peri_usb0);
>>>> +    writel(0xa00607, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /* write 0x00 to addr 0x07
>>>> +    * 0x07[1] = 0 : Keep Rcomp working
>>>> +    */
>>>> +    writel(0xa10700, &ctrl->peri_usb0);
>>>> +    writel(0xe10700, &ctrl->peri_usb0);
>>>> +    writel(0xa10700, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /* write 0xab to 0x0a
>>>> +    * 0x0a[7:5] = 101 : Icomp = 212mV , increase current drive
>>>> +    */
>>>> +    writel(0xa00aab, &ctrl->peri_usb0);
>>>> +    writel(0xe00aab, &ctrl->peri_usb0);
>>>> +    writel(0xa00aab, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /* write 0x40 to addr 0x11
>>>> +    * 0x11[6:5] = 10 : sovle EMI problem, rx_active will
>>>> +    * not stay at 1 when error packets received
>>>> +    */
>>>> +    writel(0xa11140, &ctrl->peri_usb0);
>>>> +    writel(0xe11140, &ctrl->peri_usb0);
>>>> +    writel(0xa11140, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /* write 0x41 to addr 0x10
>>>> +    * 0x10[0] = 1 : Comp Mode Select
>>>> +    */
>>>> +    writel(0xa11041, &ctrl->peri_usb0);
>>>> +    writel(0xe11041, &ctrl->peri_usb0);
>>>> +    writel(0xa11041, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +
>>>> +    /*
>>>> +    * {0x00a[0],0x009[7:6]} = 110 : Eye Diagram Adjust
>>>> +    * {0x10a[0],0x109[7:6]} = 000 : Eye Diagram Adjust
>>>> +    */
>>>> +    writel(0xa0098c, &ctrl->peri_usb0);
>>>> +    writel(0xe0098c, &ctrl->peri_usb0);
>>>> +    writel(0xa0098c, &ctrl->peri_usb0);
>>>> +    writel(0xa10a0a, &ctrl->peri_usb0);
>>>> +    writel(0xe10a0a, &ctrl->peri_usb0);
>>>> +    writel(0xa10a0a, &ctrl->peri_usb0);
>>>> +    udelay(20);
>>>> +}
>>>> +
>>>> +#ifndef CONFIG_DM_USB
>>>> +int ehci_hcd_init(int index, enum usb_init_type init,
>>>> +        struct ehci_hccr **hccr, struct ehci_hcor **hcor)
>>>> +{
>>>> +    int reg;
>>>> +
>>>> +    *hccr = (struct ehci_hccr *) REG_BASE_EHCI;
>>>> +    *hcor = (struct ehci_hcor *)( (void *) REG_BASE_EHCI +
>>>> +            HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
>>>> +
>>>> +    /* reset controller bus/utmi/roothub  */
>>>> +    reg = readl(&ctrl->peri_crg46);
>>>> +    reg |= (USB2_BUS_SRST_REQ
>>>> +        | USB2_UTMI0_SRST_REQ
>>>> +        | USB2_HST_PHY_SYST_REQ
>>>> +        | USB2_OTG_PHY_SYST_REQ);
>>>> +    writel(reg, &ctrl->peri_crg46);
>>>> +    udelay(200);
>> Can the ulpi-phy code we have help here ? Also, clrsetbits_le32() and
>> co ...
> 
> ack for the bit instructions. will fix.
> the usb-2 controller doest seem to have a ULPI phy (I couldn't find it
> in the device tree or in the docs but I might be wrong..I'll find out to
> be sure)

Please re-check , this init sequence looks weird.

>>>> +    /* reset phy por/utmi */
>>>> +    reg = readl(&ctrl->peri_crg47);
>>>> +    reg |= (USB2_PHY01_SRST_REQ
>>>> +        | USB2_PHY01_SRST_TREQ1);
>>>> +    writel(reg, &ctrl->peri_crg47);
>>>> +    udelay(200);
>>>> +
>>>> +    reg = readl(&ctrl->peri_usb3);
>>>> +    reg |= ULPI_BYPASS_EN_PORT0;
>>>> +    reg &= ~(WORDINTERFACE);
>>>> +    reg &= ~(SS_BURST16_EN);
>>>> +    writel(reg, &ctrl->peri_usb3);
>>>> +    udelay(100);
>>>> +
>>>> +    /* open ref clk */
>>>> +    reg = readl(&ctrl->peri_crg47);
>>>> +    reg |= (USB2_PHY01_REF_CKEN);
>>>> +    writel(reg, &ctrl->peri_crg47);
>>>> +    udelay(300);
>>>> +
>>>> +    /* cancel power on reset */
>>>> +    reg = readl(&ctrl->peri_crg47);
>>>> +    reg &= ~(USB2_PHY01_SRST_REQ);
>>>> +    writel(reg, &ctrl->peri_crg47);
>>>> +    udelay(500);
>>>> +
>>>> +    inno_phy_config_2p_1();
>>>> +
>>>> +    /* cancel port reset
>>>> +     * delay 10ms for waiting comp circuit stable
>>>> +    */
>>>> +    reg = readl(&ctrl->peri_crg47);
>>>> +    reg &= ~(USB2_PHY01_SRST_TREQ1);
>>>> +    writel(reg, &ctrl->peri_crg47);
>>>> +    mdelay(10);
>>>> +
>>>> +    /* open controller clk */
>>>> +    reg = readl(&ctrl->peri_crg46);
>>>> +    reg |= (USB2_BUS_CKEN
>>>> +        | USB2_OHCI48M_CKEN
>>>> +        | USB2_OHCI12M_CKEN
>>>> +        | USB2_OTG_UTMI_CKEN
>>>> +        | USB2_HST_PHY_CKEN
>>>> +        | USB2_UTMI0_CKEN);
>>>> +    writel(reg, &ctrl->peri_crg46);
>>>> +    udelay(200);
>>>> +
>>>> +    /* cancel control reset */
>>>> +    reg = readl(&ctrl->peri_crg46);
>>>> +    reg &= ~(USB2_BUS_SRST_REQ
>>>> +        | USB2_UTMI0_SRST_REQ
>>>> +        | USB2_HST_PHY_SYST_REQ
>>>> +        | USB2_OTG_PHY_SYST_REQ);
>>>> +    writel(reg, &ctrl->peri_crg46);
>>>> +    udelay(200);
>>>> +
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +int ehci_hcd_stop(int index)
>>>> +{
>>>> +    int reg;
>>>> +
>>>> +    reg = readl(&ctrl->peri_crg46);
>>>> +    reg |= (USB2_BUS_SRST_REQ
>>>> +        | USB2_UTMI0_SRST_REQ
>>>> +        | USB2_HST_PHY_SYST_REQ);
>>>> +    writel(reg, &ctrl->peri_crg46);
>>>> +
>>>> +    udelay(200);
>>>> +
>>>> +    reg = readl(&ctrl->peri_crg47);
>>>> +    reg |= (USB2_PHY01_SRST_REQ
>>>> +        | USB2_PHY01_SRST_TREQ1);
>>>> +    writel(reg, &ctrl->peri_crg47);
>>>> +
>>>> +    udelay(100);
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +#else
>>>> +error "CONFIG_DM_USB not supported for hi3798cv200"
>>>> +#endif
>>>> -- 
>>>> 2.7.4
>>>>
>>>> _______________________________________________
>>>> U-Boot mailing list
>>>> U-Boot at lists.denx.de
>>>> https://lists.denx.de/listinfo/u-boot
>>
> 


-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list