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

Jorge Ramirez jorge.ramirez-ortiz at linaro.org
Fri May 5 17:55:20 UTC 2017


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?

>
>>> +#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)
> Use BIT()

ack

>
>>> +#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)
> Superfluous parenthesis.

ack
>
>>> +/* 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]; }
> Uh what ? Needed ?

nope....will remove the silly structure :)


>
>>> +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;
> Just use #define FOO_REG_BAR 0xf00 , drop this structure stuff ...

100% in agreement.

>
>>> +};
>>> +
>>> +#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

>
>>> +	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?
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).

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

>
>>> +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)



>
>>> +	/* 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
>



More information about the U-Boot mailing list