diff mbox series

[2/5] driver: usb: add EHCI driver for hi3787cv200 SoC

Message ID 1493905630-8788-2-git-send-email-jorge.ramirez-ortiz@linaro.org
State New
Headers show
Series [1/5] ARM64: poplar: add device tree bindings | expand

Commit Message

Jorge Ramirez-Ortiz May 4, 2017, 1:47 p.m. UTC
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@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

Comments

Tom Rini May 5, 2017, 2:32 p.m. UTC | #1
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@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@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-ortiz@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
Marek Vasut May 5, 2017, 3:34 p.m. UTC | #2
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@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@linaro.org>
>> + *
>> + * SPDX-License-Identifier:	GPL-2.0+
>> + */
>> +
>> +#ifndef __HI3798cv200_H__
>> +#define __HI3798cv200_H__

This should be a separate patch ..

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

>> +#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.

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

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

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

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

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

>> +	/* 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
>
Jorge Ramirez-Ortiz May 5, 2017, 5:55 p.m. UTC | #3
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@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@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@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@lists.denx.de
>>> https://lists.denx.de/listinfo/u-boot
>
Marek Vasut May 5, 2017, 11:05 p.m. UTC | #4
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@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@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@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@lists.denx.de
>>>> https://lists.denx.de/listinfo/u-boot
>>
>
Jorge Ramirez-Ortiz May 7, 2017, 10:56 a.m. UTC | #5
On 05/06/2017 01:05 AM, Marek Vasut wrote:
> 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@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@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.

sure.
I suppose that what are really saying is that the usb driver has to be 
upstreamed after the architecture and not before if such a dependency 
exists (ie not using the device tree)

ok



>
> [...]
>
>>>>> +};
>>>>> +
>>>>> +#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 ?

yes I think so. the driver is basically platform initialization code and 
the generic driver.
the problem I have is that there is not usb host support in the kernel 
for it so we dont have a device node in the tree.

should I commit the linux kernel device tree (first patch in the series) 
and then add the node when I push the DM usb driver?

>
>>>>> +    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@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.


ok

>
>> 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.

yeah I think it is just adding a node in the tree

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


ok
thanks for the review
>
>>>>> +    /* 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
>
Marek Vasut May 7, 2017, 12:34 p.m. UTC | #6
On 05/07/2017 12:56 PM, Jorge Ramirez wrote:
> On 05/06/2017 01:05 AM, Marek Vasut wrote:
>> 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@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@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.
> 
> sure.
> I suppose that what are really saying is that the usb driver has to be
> upstreamed after the architecture and not before if such a dependency
> exists (ie not using the device tree)

Yes, you can be asked to change stuff in the arch code , at which point
you might have to modify the (dead, but accepted) usb code.

If you can move arch stuff to arch code, even better. Then you might
even be able to use ehci-generic.

>> [...]
>>
>>>>>> +};
>>>>>> +
>>>>>> +#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 ?
> 
> yes I think so. the driver is basically platform initialization code and
> the generic driver.
> the problem I have is that there is not usb host support in the kernel
> for it so we dont have a device node in the tree.
> 
> should I commit the linux kernel device tree (first patch in the series)
> and then add the node when I push the DM usb driver?

Ideally check the bindings with Rob Herring, otherwise I don't care.
If you contribute to kernel too, awesome.

[...]
Jorge Ramirez-Ortiz May 8, 2017, 9:15 a.m. UTC | #7
On 05/07/2017 02:34 PM, Marek Vasut wrote:
> On 05/07/2017 12:56 PM, Jorge Ramirez wrote:
>> On 05/06/2017 01:05 AM, Marek Vasut wrote:
>>> 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@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@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.
>> sure.
>> I suppose that what are really saying is that the usb driver has to be
>> upstreamed after the architecture and not before if such a dependency
>> exists (ie not using the device tree)
> Yes, you can be asked to change stuff in the arch code , at which point
> you might have to modify the (dead, but accepted) usb code.
>
> If you can move arch stuff to arch code, even better. Then you might
> even be able to use ehci-generic.

yes, that is what I ended up doing. thanks for the suggestion.

>
>>> [...]
>>>
>>>>>>> +};
>>>>>>> +
>>>>>>> +#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 ?
>> yes I think so. the driver is basically platform initialization code and
>> the generic driver.
>> the problem I have is that there is not usb host support in the kernel
>> for it so we dont have a device node in the tree.
>>
>> should I commit the linux kernel device tree (first patch in the series)
>> and then add the node when I push the DM usb driver?
> Ideally check the bindings with Rob Herring, otherwise I don't care.
> If you contribute to kernel too, awesome.

in v2 I pushed the bindings to allow me to use the ehci-generic driver.

the kernel team working on this platform will push a more detailed node 
definition to korg - usb host is still under development - at which 
point I'll merge it back.
I hope that this is acceptable?


>
> [...]
>
Marek Vasut May 8, 2017, 10:21 a.m. UTC | #8
On 05/08/2017 11:15 AM, Jorge Ramirez wrote:
> On 05/07/2017 02:34 PM, Marek Vasut wrote:
>> On 05/07/2017 12:56 PM, Jorge Ramirez wrote:
>>> On 05/06/2017 01:05 AM, Marek Vasut wrote:
>>>> 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@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@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.
>>> sure.
>>> I suppose that what are really saying is that the usb driver has to be
>>> upstreamed after the architecture and not before if such a dependency
>>> exists (ie not using the device tree)
>> Yes, you can be asked to change stuff in the arch code , at which point
>> you might have to modify the (dead, but accepted) usb code.
>>
>> If you can move arch stuff to arch code, even better. Then you might
>> even be able to use ehci-generic.
> 
> yes, that is what I ended up doing. thanks for the suggestion.
> 
>>
>>>> [...]
>>>>
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +#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 ?
>>> yes I think so. the driver is basically platform initialization code and
>>> the generic driver.
>>> the problem I have is that there is not usb host support in the kernel
>>> for it so we dont have a device node in the tree.
>>>
>>> should I commit the linux kernel device tree (first patch in the series)
>>> and then add the node when I push the DM usb driver?
>> Ideally check the bindings with Rob Herring, otherwise I don't care.
>> If you contribute to kernel too, awesome.
> 
> in v2 I pushed the bindings to allow me to use the ehci-generic driver.
> 
> the kernel team working on this platform will push a more detailed node
> definition to korg - usb host is still under development - at which
> point I'll merge it back.
> I hope that this is acceptable?

Works for me if you don't invent weird stuff in the bindings and keep
them reasonably in sync. Thanks
diff mbox series

Patch

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@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-ortiz@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