From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tom Rini Date: Fri, 5 May 2017 10:32:15 -0400 Subject: [U-Boot] [PATCH 2/5] driver: usb: add EHCI driver for hi3787cv200 SoC In-Reply-To: <1493905630-8788-2-git-send-email-jorge.ramirez-ortiz@linaro.org> References: <1493905630-8788-1-git-send-email-jorge.ramirez-ortiz@linaro.org> <1493905630-8788-2-git-send-email-jorge.ramirez-ortiz@linaro.org> Message-ID: <20170505143215.GQ12511@bill-the-cat> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Thu, May 04, 2017 at 03:47:07PM +0200, Jorge Ramirez-Ortiz wrote: CC'ing Marek... > Signed-off-by: Jorge Ramirez-Ortiz > --- > .../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 > + * > + * 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 > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > + > +#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 at lists.denx.de > https://lists.denx.de/listinfo/u-boot -- Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: