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-or...@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-or...@linaro.org>
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + */
> +
> +#ifndef __HI3798cv200_H__
> +#define __HI3798cv200_H__
> +
> +#define REG_BASE_CRG                 0xF8A22000
> +#define REG_BASE_SCTL                        0xF8000000
> +#define REG_BASE_CRG                 0xF8A22000
> +#define REG_BASE_PERI_CTRL           0xF8A20000
> +
> +/* DEVICES */
> +#define REG_BASE_UART0                       0xF8B00000
> +#define REG_BASE_EHCI                        0XF9890000
> +#define REG_BASE_MCI                 0xF9830000
> +#define REG_BASE_MMC0                        0xF9830000
> +
> +/* SC */
> +#define REG_SC_CTRL                  0x0000
> +#define REG_SC_SYSRES                        0x0004
> +#define REG_SC_GEN0                  0x0080
> +#define REG_SC_GEN1                  0x0084
> +#define REG_SC_GEN2                  0x0088
> +#define REG_SC_GEN12                 0x00B0
> +
> +/* USB EHCI driver */
> +#define PERI_USB0                    (0xF8A20000 + 0x120)
> +#define PERI_USB1                    (0xF8A20000 + 0x124)
> +#define PERI_USB3                    (0xF8A20000 + 0x12c)
> +#define PERI_USB4                    (0xF8A20000 + 0x130)
> +
> +#define WORDINTERFACE                        (1 << 0)
> +#define ULPI_BYPASS_EN_PORT0         (1 << 3)
> +#define SS_BURST16_EN                        (1 << 9)
> +#define TEST_WRDATA                  (0x4)
> +#define TEST_ADDR                    (0x6 << 8)
> +#define TEST_WREN                    (1 << 21)
> +#define TEST_CLK                     (1 << 22)
> +#define TEST_RSTN                    (1 << 23)
> +
> +#define PERI_CRG46                   (0xF8A22000 + 0xb8)
> +#define USB2_BUS_CKEN                        (1<<0)
> +#define USB2_OHCI48M_CKEN            (1<<1)
> +#define USB2_OHCI12M_CKEN            (1<<2)
> +#define USB2_OTG_UTMI_CKEN           (1<<3)
> +#define USB2_HST_PHY_CKEN            (1<<4)
> +#define USB2_UTMI0_CKEN                      (1<<5)
> +#define USB2_BUS_SRST_REQ            (1<<12)
> +#define USB2_UTMI0_SRST_REQ          (1<<13)
> +#define USB2_HST_PHY_SYST_REQ                (1<<16)
> +#define USB2_OTG_PHY_SYST_REQ                (1<<17)
> +#define USB2_CLK48_SEL                       (1<<20)
> +
> +#define PERI_CRG47                   (0xF8A22000 + 0xbc)
> +#define USB2_PHY01_REF_CKEN          (1 << 0)
> +#define USB2_PHY2_REF_CKEN           (1 << 2)
> +#define USB2_PHY01_SRST_REQ          (1 << 4)
> +#define USB2_PHY2_SRST_REQ           (1 << 6)
> +#define USB2_PHY01_SRST_TREQ0                (1 << 8)
> +#define USB2_PHY01_SRST_TREQ1                (1 << 9)
> +#define USB2_PHY2_SRST_TREQ          (1 << 10)
> +#define USB2_PHY01_REFCLK_SEL                (1 << 12)
> +#define USB2_PHY2_REFCLK_SEL         (1 << 14)
> +
> +#define REG_START_MODE                       0x0000
> +#define REG_PERI_STAT                        0x0004
> +#define REG_PERI_CTRL                        0x0008
> +#define REG_PERI_CRG26                       0x00A8
> +#define NF_BOOTBW_MASK                       (1<<12)
> +
> +#define HI3798CV200_EHCI_CTRL                (PERI_USB0)
> +
> +/* Generate padding data ranges with unique identifiers. */
> +#define ___cat(a,b)             a##b
> +#define __cat(a,b)              ___cat(a,b)
> +#define __padding(__words) struct { __u32 __cat(__pad, 
> __COUNTER__)[__words]; }
> +
> +struct hi3798cv200_ehci_ctrl_regs {
> +     u32 peri_usb0;
> +     u32 peri_usb1;
> +     u32 peri_usb2;
> +     u32 peri_usb3;
> +     u32 peri_usb4;
> +     __padding(0x7e1);
> +     u32 peri_crg46;
> +     u32 peri_crg47;
> +};
> +
> +#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"
> +     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-or...@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;
> +
> +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);
> +
> +     /* 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@lists.denx.de
> https://lists.denx.de/listinfo/u-boot

-- 
Tom

Attachment: signature.asc
Description: Digital signature

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to