[U-Boot] [PATCH 00/21] STiH410-B2260: add reset, usb and fastboot support

From: Patrice Chotard patrice.chotard@st.com
This series adds : _ add reset driver _ update existing sdhci driver to use reset framework _ add usb phy driver _ add ehci support _ add ohci support _ add xhci support _ add fastboot support
With all this feature enable, it's now possible to _ boot on usb mass storage device _ boot from kernel image and dtb previously loaded using tftp _ update mmc partiton using fastboot
Patrice Chotard (21): reset: Add STi reset support mmc: sti_sdhci: Rework sti_mmc_core_config() ARM: dts: stih410-family: Add missing reset_names for mmc1 node mmc: sti_sdhci: Use reset framework phy: Add STi phy usb support usb: ehci: Add STi ehci support STiH410-B2260: enable USB related flags usb: ohci: Add STi ohci support STiH410-B2260: enable OHCI related flags usb: xhci: Add STi xhci support STiH410-B2260: enable XHCI related flags STiH410-B2260: Enabling USB Host Networking usb: dwc3: Add dwc3 support for STi STiH410-B2260: enable DWC3 support board: STiH410-B2260: add fastboot support STiH410-B2260: enable USB download gadget related flags STiH410-B2260: enable FASTBOOT related flags STiH410-B2260: enable OF_LIBFDT_OVERLAY STiH410-B2260: enable CMD_EXT4_WRITE STiH410-B2260: enable CMD_GPT STiH410-B2260: enable CMD_PART
arch/arm/Kconfig | 1 + arch/arm/dts/stih407-family.dtsi | 1 + arch/arm/include/asm/arch-stih410/sys_proto.h | 11 + board/st/stih410-b2260/board.c | 44 ++++ configs/stih410-b2260_defconfig | 33 +++ drivers/mmc/sti_sdhci.c | 60 +++-- drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/sti-reset.c | 321 ++++++++++++++++++++++++++ drivers/usb/Kconfig | 4 + drivers/usb/dwc3/Kconfig | 8 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-sti.c | 137 +++++++++++ drivers/usb/host/Kconfig | 26 +++ drivers/usb/host/Makefile | 3 + drivers/usb/host/ehci-sti.c | 91 ++++++++ drivers/usb/host/ohci-sti.c | 90 ++++++++ drivers/usb/host/xhci-sti.c | 156 +++++++++++++ drivers/usb/phy/Kconfig | 11 + drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 +++++++++++++ include/configs/stih410-b2260.h | 16 ++ include/dwc3-sti-uboot.h | 50 ++++ 23 files changed, 1210 insertions(+), 22 deletions(-) create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h create mode 100644 drivers/reset/sti-reset.c create mode 100644 drivers/usb/dwc3/dwc3-sti.c create mode 100644 drivers/usb/host/ehci-sti.c create mode 100644 drivers/usb/host/ohci-sti.c create mode 100644 drivers/usb/host/xhci-sti.c create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c create mode 100644 include/dwc3-sti-uboot.h

From: Patrice Chotard patrice.chotard@st.com
This patch adds a reset controller implementation for STMicroelectronics STi family SoCs; it allows a group of related reset like controls found in multiple system configuration registers to be represented by a single controller device.
Driver code has been mainly extracted from kernel drivers/reset/sti/reset-stih407.c
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/Kconfig | 1 + configs/stih410-b2260_defconfig | 1 + drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/sti-reset.c | 321 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 332 insertions(+) create mode 100644 drivers/reset/sti-reset.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 20434dc..af5157e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1100,6 +1100,7 @@ config ARCH_STI select DM_SERIAL select BLK select DM_MMC + select DM_RESET help Support for STMicroelectronics STiH407/10 SoC family. This SoC is used on Linaro 96Board STiH410-B2260 diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 4e6942f..9ee2fe4 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -20,6 +20,7 @@ CONFIG_SYSCON=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_STI=y CONFIG_PINCTRL=y +CONFIG_STI_RESET=y CONFIG_STI_ASC_SERIAL=y CONFIG_SYSRESET=y CONFIG_TIMER=y diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index c42b0bc..fa77ee4 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -20,6 +20,14 @@ config SANDBOX_RESET simply accepts requests to reset various HW modules without actually doing anything beyond a little error checking.
+config STI_RESET + bool "Enable the STi reset" + depends on ARCH_STI + help + Support for reset controllers on STMicroelectronics STiH407 family SoCs. + Say Y if you want to control reset signals provided by system config + block. + config TEGRA_CAR_RESET bool "Enable Tegra CAR-based reset driver" depends on TEGRA_CAR diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 5c4305c..2b96396 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_DM_RESET) += reset-uclass.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset.o obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset-test.o +obj-$(CONFIG_STI_RESET) += sti-reset.o obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c new file mode 100644 index 0000000..7ce4605 --- /dev/null +++ b/drivers/reset/sti-reset.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <wait_bit.h> +#include <dm.h> +#include <reset-uclass.h> +#include <regmap.h> +#include <syscon.h> +#include <dt-bindings/reset/stih407-resets.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_reset { + const struct syscfg_reset_controller_data *data; +}; + +/** + * Reset channel description for a system configuration register based + * reset controller. + * + * @compatible: Compatible string of the syscon containing this + * channel's control and ack (status) bits. + * @reset_offset: Reset register offset in sysconf bank. + * @reset_bit: Bit number in reset register. + * @ack_offset: Ack reset register offset in syscon bank. + * @ack_bit: Bit number in Ack reset register. + */ + +struct syscfg_reset_channel_data { + const char *compatible; + int reset_offset; + int reset_bit; + int ack_offset; + int ack_bit; +}; + +/** + * Description of a system configuration register based reset controller. + * + * @wait_for_ack: The controller will wait for reset assert and de-assert to + * be "ack'd" in a channel's ack field. + * @active_low: Are the resets in this controller active low, i.e. clearing + * the reset bit puts the hardware into reset. + * @nr_channels: The number of reset channels in this controller. + * @channels: An array of reset channel descriptions. + */ +struct syscfg_reset_controller_data { + bool wait_for_ack; + bool active_low; + int nr_channels; + const struct syscfg_reset_channel_data *channels; +}; + +/* STiH407 Peripheral powerdown definitions. */ +static const char stih407_core[] = "st,stih407-core-syscfg"; +static const char stih407_sbc_reg[] = "st,stih407-sbc-reg-syscfg"; +static const char stih407_lpm[] = "st,stih407-lpm-syscfg"; + +#define _SYSCFG_RST_CH(_c, _rr, _rb, _ar, _ab) \ + { .compatible = _c, \ + .reset_offset = _rr, \ + .reset_bit = _rb, \ + .ack_offset = _ar, \ + .ack_bit = _ab, } + +#define _SYSCFG_RST_CH_NO_ACK(_c, _rr, _rb) \ + { .compatible = _c, \ + .reset_offset = _rr, \ + .reset_bit = _rb, } + +#define STIH407_SRST_CORE(_reg, _bit) \ + _SYSCFG_RST_CH_NO_ACK(stih407_core, _reg, _bit) + +#define STIH407_SRST_SBC(_reg, _bit) \ + _SYSCFG_RST_CH_NO_ACK(stih407_sbc_reg, _reg, _bit) + +#define STIH407_SRST_LPM(_reg, _bit) \ + _SYSCFG_RST_CH_NO_ACK(stih407_lpm, _reg, _bit) + +#define STIH407_PDN_0(_bit) \ + _SYSCFG_RST_CH(stih407_core, SYSCFG_5000, _bit, SYSSTAT_5500, _bit) +#define STIH407_PDN_1(_bit) \ + _SYSCFG_RST_CH(stih407_core, SYSCFG_5001, _bit, SYSSTAT_5501, _bit) +#define STIH407_PDN_ETH(_bit, _stat) \ + _SYSCFG_RST_CH(stih407_sbc_reg, SYSCFG_4032, _bit, SYSSTAT_4520, _stat) + +/* Powerdown requests control 0 */ +#define SYSCFG_5000 0x0 +#define SYSSTAT_5500 0x7d0 +/* Powerdown requests control 1 (High Speed Links) */ +#define SYSCFG_5001 0x4 +#define SYSSTAT_5501 0x7d4 + +/* Ethernet powerdown/status/reset */ +#define SYSCFG_4032 0x80 +#define SYSSTAT_4520 0x820 +#define SYSCFG_4002 0x8 + +static const struct syscfg_reset_channel_data stih407_powerdowns[] = { + [STIH407_EMISS_POWERDOWN] = STIH407_PDN_0(1), + [STIH407_NAND_POWERDOWN] = STIH407_PDN_0(0), + [STIH407_USB3_POWERDOWN] = STIH407_PDN_1(6), + [STIH407_USB2_PORT1_POWERDOWN] = STIH407_PDN_1(5), + [STIH407_USB2_PORT0_POWERDOWN] = STIH407_PDN_1(4), + [STIH407_PCIE1_POWERDOWN] = STIH407_PDN_1(3), + [STIH407_PCIE0_POWERDOWN] = STIH407_PDN_1(2), + [STIH407_SATA1_POWERDOWN] = STIH407_PDN_1(1), + [STIH407_SATA0_POWERDOWN] = STIH407_PDN_1(0), + [STIH407_ETH1_POWERDOWN] = STIH407_PDN_ETH(0, 2), +}; + +/* Reset Generator control 0/1 */ +#define SYSCFG_5128 0x200 +#define SYSCFG_5131 0x20c +#define SYSCFG_5132 0x210 + +#define LPM_SYSCFG_1 0x4 /* Softreset IRB & SBC UART */ + +static const struct syscfg_reset_channel_data stih407_softresets[] = { + [STIH407_ETH1_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 4), + [STIH407_MMC1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 3), + [STIH407_USB2_PORT0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 28), + [STIH407_USB2_PORT1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 29), + [STIH407_PICOPHY_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 30), + [STIH407_IRB_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 6), + [STIH407_PCIE0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 6), + [STIH407_PCIE1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 15), + [STIH407_SATA0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 7), + [STIH407_SATA1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 16), + [STIH407_MIPHY0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 4), + [STIH407_MIPHY1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 13), + [STIH407_MIPHY2_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 22), + [STIH407_SATA0_PWR_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 5), + [STIH407_SATA1_PWR_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 14), + [STIH407_DELTA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 3), + [STIH407_BLITTER_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 10), + [STIH407_HDTVOUT_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 11), + [STIH407_HDQVDP_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 12), + [STIH407_VDP_AUX_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 14), + [STIH407_COMPO_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 15), + [STIH407_HDMI_TX_PHY_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 21), + [STIH407_JPEG_DEC_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 23), + [STIH407_VP8_DEC_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 24), + [STIH407_GPU_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 30), + [STIH407_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 0), + [STIH407_ERAM_HVA_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5132, 1), + [STIH407_LPM_SOFTRESET] = STIH407_SRST_SBC(SYSCFG_4002, 2), + [STIH407_KEYSCAN_SOFTRESET] = STIH407_SRST_LPM(LPM_SYSCFG_1, 8), + [STIH407_ST231_AUD_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 26), + [STIH407_ST231_DMU_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 27), + [STIH407_ST231_GP0_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5131, 28), + [STIH407_ST231_GP1_SOFTRESET] = STIH407_SRST_CORE(SYSCFG_5128, 2), +}; + +/* PicoPHY reset/control */ +#define SYSCFG_5061 0x0f4 + +static const struct syscfg_reset_channel_data stih407_picophyresets[] = { + [STIH407_PICOPHY0_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 5), + [STIH407_PICOPHY1_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 6), + [STIH407_PICOPHY2_RESET] = STIH407_SRST_CORE(SYSCFG_5061, 7), +}; + +static const struct +syscfg_reset_controller_data stih407_powerdown_controller = { + .wait_for_ack = true, + .nr_channels = ARRAY_SIZE(stih407_powerdowns), + .channels = stih407_powerdowns, +}; + +static const struct +syscfg_reset_controller_data stih407_softreset_controller = { + .wait_for_ack = false, + .active_low = true, + .nr_channels = ARRAY_SIZE(stih407_softresets), + .channels = stih407_softresets, +}; + +static const struct +syscfg_reset_controller_data stih407_picophyreset_controller = { + .wait_for_ack = false, + .nr_channels = ARRAY_SIZE(stih407_picophyresets), + .channels = stih407_picophyresets, +}; + +phys_addr_t sti_reset_get_regmap(const char *compatible) +{ + struct udevice *syscon; + struct regmap *regmap; + int node, ret; + + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, + compatible); + if (node < 0) { + error("unable to find %s node\n", compatible); + return node; + } + + ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, node, &syscon); + if (ret) { + error("%s: uclass_get_device_by_of_offset failed: %d\n", + __func__, ret); + return ret; + } + + regmap = syscon_get_regmap(syscon); + if (!regmap) { + error("unable to get regmap for %s\n", syscon->name); + return -ENODEV; + } + + return regmap->base; +} + +static int sti_reset_program_hw(struct reset_ctl *reset_ctl, int assert) +{ + struct udevice *dev = reset_ctl->dev; + struct syscfg_reset_controller_data *reset_desc = + (struct syscfg_reset_controller_data *)(dev->driver_data); + struct syscfg_reset_channel_data ch; + phys_addr_t base; + u32 ctrl_val = reset_desc->active_low ? !assert : !!assert; + void __iomem *reg; + + + /* check if reset id is inside available range */ + if (reset_ctl->id >= reset_desc->nr_channels) + return -EINVAL; + + /* get reset sysconf register base address */ + base = sti_reset_get_regmap(reset_desc->channels[reset_ctl->id].compatible); + + ch = reset_desc->channels[reset_ctl->id]; + reg = (void __iomem *)base + ch.reset_offset; + + if (ctrl_val) + generic_set_bit(ch.reset_bit, reg); + else + generic_clear_bit(ch.reset_bit, reg); + + if (!reset_desc->wait_for_ack) + return 0; + + reg = (void __iomem *)base + ch.ack_offset; + if (wait_for_bit(__func__, reg, BIT(ch.ack_bit), ctrl_val, + 1000, false)) { + error("Stuck on waiting ack reset_ctl=%p dev=%p id=%lu\n", + reset_ctl, reset_ctl->dev, reset_ctl->id); + + return -ETIMEDOUT; + } + + return 0; +} + +static int sti_reset_request(struct reset_ctl *reset_ctl) +{ + return 0; +} + +static int sti_reset_free(struct reset_ctl *reset_ctl) +{ + return 0; +} + +static int sti_reset_assert(struct reset_ctl *reset_ctl) +{ + return sti_reset_program_hw(reset_ctl, true); +} + +static int sti_reset_deassert(struct reset_ctl *reset_ctl) +{ + return sti_reset_program_hw(reset_ctl, false); +} + +struct reset_ops sti_reset_ops = { + .request = sti_reset_request, + .free = sti_reset_free, + .rst_assert = sti_reset_assert, + .rst_deassert = sti_reset_deassert, +}; + +static int sti_reset_probe(struct udevice *dev) +{ + struct sti_reset *priv = dev_get_priv(dev); + + priv->data = (void *)dev_get_driver_data(dev); + + return 0; +} + +static const struct udevice_id sti_reset_ids[] = { + { + .compatible = "st,stih407-picophyreset", + .data = (ulong)&stih407_picophyreset_controller, + }, + { + .compatible = "st,stih407-powerdown", + .data = (ulong)&stih407_powerdown_controller, + }, + { + .compatible = "st,stih407-softreset", + .data = (ulong)&stih407_softreset_controller, + }, + { } +}; + +U_BOOT_DRIVER(sti_reset) = { + .name = "sti_reset", + .id = UCLASS_RESET, + .of_match = sti_reset_ids, + .probe = sti_reset_probe, + .priv_auto_alloc_size = sizeof(struct sti_reset), + .ops = &sti_reset_ops, +};

Hi.
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This patch adds a reset controller implementation for STMicroelectronics STi family SoCs; it allows a group of related reset like controls found in multiple system configuration registers to be represented by a single controller device.
Driver code has been mainly extracted from kernel drivers/reset/sti/reset-stih407.c
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/Kconfig | 1 + configs/stih410-b2260_defconfig | 1 + drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/sti-reset.c | 321 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 332 insertions(+) create mode 100644 drivers/reset/sti-reset.c
Instead of using fdt_node_offset_by_compatible() do you have a way to get the offset using a phandle or similar?
Regards, Simon

From: Patrice Chotard patrice.chotard@st.com
Use struct udevice* as input parameter. Previous parameters are retrieved through plat and priv data.
This to prepare to use the reset framework.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/mmc/sti_sdhci.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c index 2a07082..d6c4d67 100644 --- a/drivers/mmc/sti_sdhci.c +++ b/drivers/mmc/sti_sdhci.c @@ -16,6 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; struct sti_sdhci_plat { struct mmc_config cfg; struct mmc mmc; + int instance; };
/* @@ -26,8 +27,8 @@ struct sti_sdhci_plat {
/** * sti_mmc_core_config: configure the Arasan HC - * @regbase: base address - * @mmc_instance: mmc instance id + * @dev : udevice + * * Description: this function is to configure the Arasan MMC HC. * This should be called when the system starts in case of, on the SoC, * it is needed to configure the host controller. @@ -36,33 +37,35 @@ struct sti_sdhci_plat { * W/o these settings the SDHCI could configure and use the embedded controller * with limited features. */ -static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +static void sti_mmc_core_config(struct udevice *dev) { + struct sti_sdhci_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); unsigned long *sysconf;
/* only MMC1 has a reset line */ - if (mmc_instance) { + if (plat->instance) { sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + ST_MMC_CCONFIG_REG_5); generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); }
writel(STI_FLASHSS_MMC_CORE_CONFIG_1, - regbase + FLASHSS_MMC_CORE_CONFIG_1); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1);
- if (mmc_instance) { + if (plat->instance) { writel(STI_FLASHSS_MMC_CORE_CONFIG2, - regbase + FLASHSS_MMC_CORE_CONFIG_2); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2); writel(STI_FLASHSS_MMC_CORE_CONFIG3, - regbase + FLASHSS_MMC_CORE_CONFIG_3); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3); } else { writel(STI_FLASHSS_SDCARD_CORE_CONFIG2, - regbase + FLASHSS_MMC_CORE_CONFIG_2); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2); writel(STI_FLASHSS_SDCARD_CORE_CONFIG3, - regbase + FLASHSS_MMC_CORE_CONFIG_3); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3); } writel(STI_FLASHSS_MMC_CORE_CONFIG4, - regbase + FLASHSS_MMC_CORE_CONFIG_4); + host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4); }
static int sti_sdhci_probe(struct udevice *dev) @@ -70,7 +73,7 @@ static int sti_sdhci_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sti_sdhci_plat *plat = dev_get_platdata(dev); struct sdhci_host *host = dev_get_priv(dev); - int ret, mmc_instance; + int ret;
/* * identify current mmc instance, mmc1 has a reset, not mmc0 @@ -79,11 +82,11 @@ static int sti_sdhci_probe(struct udevice *dev) */
if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) - mmc_instance = 1; + plat->instance = 1; else - mmc_instance = 0; + plat->instance = 0;
- sti_mmc_core_config((const u32) host->ioaddr, mmc_instance); + sti_mmc_core_config(dev);
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_32BIT_DMA_ADDR |

On 03/18/2017 01:25 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Use struct udevice* as input parameter. Previous parameters are retrieved through plat and priv data.
This to prepare to use the reset framework.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/mmc/sti_sdhci.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c index 2a07082..d6c4d67 100644 --- a/drivers/mmc/sti_sdhci.c +++ b/drivers/mmc/sti_sdhci.c @@ -16,6 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; struct sti_sdhci_plat { struct mmc_config cfg; struct mmc mmc;
- int instance;
};
/* @@ -26,8 +27,8 @@ struct sti_sdhci_plat {
/**
- sti_mmc_core_config: configure the Arasan HC
- @regbase: base address
- @mmc_instance: mmc instance id
- @dev : udevice
- Description: this function is to configure the Arasan MMC HC.
- This should be called when the system starts in case of, on the SoC,
- it is needed to configure the host controller.
@@ -36,33 +37,35 @@ struct sti_sdhci_plat {
- W/o these settings the SDHCI could configure and use the embedded controller
- with limited features.
*/ -static void sti_mmc_core_config(const u32 regbase, int mmc_instance) +static void sti_mmc_core_config(struct udevice *dev) {
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
struct sdhci_host *host = dev_get_priv(dev); unsigned long *sysconf;
/* only MMC1 has a reset line */
- if (mmc_instance) {
if (plat->instance) { sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + ST_MMC_CCONFIG_REG_5); generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); }
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
regbase + FLASHSS_MMC_CORE_CONFIG_1);
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1);
- if (mmc_instance) {
- if (plat->instance) { writel(STI_FLASHSS_MMC_CORE_CONFIG2,
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_MMC_CORE_CONFIG3,host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
regbase + FLASHSS_MMC_CORE_CONFIG_3);
} else { writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
regbase + FLASHSS_MMC_CORE_CONFIG_2);
writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
regbase + FLASHSS_MMC_CORE_CONFIG_3);
} writel(STI_FLASHSS_MMC_CORE_CONFIG4,host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
regbase + FLASHSS_MMC_CORE_CONFIG_4);
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4);
}
static int sti_sdhci_probe(struct udevice *dev) @@ -70,7 +73,7 @@ static int sti_sdhci_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sti_sdhci_plat *plat = dev_get_platdata(dev); struct sdhci_host *host = dev_get_priv(dev);
- int ret, mmc_instance;
int ret;
/*
- identify current mmc instance, mmc1 has a reset, not mmc0
@@ -79,11 +82,11 @@ static int sti_sdhci_probe(struct udevice *dev) */
if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL))
mmc_instance = 1;
elseplat->instance = 1;
mmc_instance = 0;
plat->instance = 0;
- sti_mmc_core_config((const u32) host->ioaddr, mmc_instance);
sti_mmc_core_config(dev);
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_32BIT_DMA_ADDR |

From: Patrice Chotard patrice.chotard@st.com
reset-names property is needed to use the reset API for STi sdhci driver.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/dts/stih407-family.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/stih407-family.dtsi b/arch/arm/dts/stih407-family.dtsi index af66b53..452ac1c 100644 --- a/arch/arm/dts/stih407-family.dtsi +++ b/arch/arm/dts/stih407-family.dtsi @@ -563,6 +563,7 @@ clocks = <&clk_s_c0_flexgen CLK_MMC_1>, <&clk_s_c0_flexgen CLK_RX_ICN_HVA>; resets = <&softreset STIH407_MMC1_SOFTRESET>; + reset-names = "softreset"; bus-width = <4>; };

On 03/18/2017 01:25 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
reset-names property is needed to use the reset API for STi sdhci driver.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
arch/arm/dts/stih407-family.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/dts/stih407-family.dtsi b/arch/arm/dts/stih407-family.dtsi index af66b53..452ac1c 100644 --- a/arch/arm/dts/stih407-family.dtsi +++ b/arch/arm/dts/stih407-family.dtsi @@ -563,6 +563,7 @@ clocks = <&clk_s_c0_flexgen CLK_MMC_1>, <&clk_s_c0_flexgen CLK_RX_ICN_HVA>; resets = <&softreset STIH407_MMC1_SOFTRESET>;
};reset-names = "softreset"; bus-width = <4>;

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/mmc/sti_sdhci.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c index d6c4d67..8b1b2c0 100644 --- a/drivers/mmc/sti_sdhci.c +++ b/drivers/mmc/sti_sdhci.c @@ -8,6 +8,7 @@ #include <common.h> #include <dm.h> #include <mmc.h> +#include <reset-uclass.h> #include <sdhci.h> #include <asm/arch/sdhci.h>
@@ -16,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; struct sti_sdhci_plat { struct mmc_config cfg; struct mmc mmc; + struct reset_ctl reset; int instance; };
@@ -37,17 +39,19 @@ struct sti_sdhci_plat { * W/o these settings the SDHCI could configure and use the embedded controller * with limited features. */ -static void sti_mmc_core_config(struct udevice *dev) +static int sti_mmc_core_config(struct udevice *dev) { struct sti_sdhci_plat *plat = dev_get_platdata(dev); struct sdhci_host *host = dev_get_priv(dev); - unsigned long *sysconf; + int ret;
/* only MMC1 has a reset line */ if (plat->instance) { - sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE + - ST_MMC_CCONFIG_REG_5); - generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf); + ret = reset_deassert(&plat->reset); + if (ret < 0) { + error("MMC1 deassert failed: %d", ret); + return ret; + } }
writel(STI_FLASHSS_MMC_CORE_CONFIG_1, @@ -66,6 +70,8 @@ static void sti_mmc_core_config(struct udevice *dev) } writel(STI_FLASHSS_MMC_CORE_CONFIG4, host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4); + + return 0; }
static int sti_sdhci_probe(struct udevice *dev) @@ -80,13 +86,20 @@ static int sti_sdhci_probe(struct udevice *dev) * MMC0 is wired to the SD slot, * MMC1 is wired on the high speed connector */ - - if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) + if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) { plat->instance = 1; - else + ret = reset_get_by_name(dev, "softreset", &plat->reset); + if (ret) { + error("can't get reset for %s (%d)", dev->name, ret); + return ret; + } + } else { plat->instance = 0; + }
- sti_mmc_core_config(dev); + ret = sti_mmc_core_config(dev); + if (ret) + return ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_32BIT_DMA_ADDR |

On 03/18/2017 01:25 AM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
drivers/mmc/sti_sdhci.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c index d6c4d67..8b1b2c0 100644 --- a/drivers/mmc/sti_sdhci.c +++ b/drivers/mmc/sti_sdhci.c @@ -8,6 +8,7 @@ #include <common.h> #include <dm.h> #include <mmc.h> +#include <reset-uclass.h> #include <sdhci.h> #include <asm/arch/sdhci.h>
@@ -16,6 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; struct sti_sdhci_plat { struct mmc_config cfg; struct mmc mmc;
- struct reset_ctl reset; int instance;
};
@@ -37,17 +39,19 @@ struct sti_sdhci_plat {
- W/o these settings the SDHCI could configure and use the embedded controller
- with limited features.
*/ -static void sti_mmc_core_config(struct udevice *dev) +static int sti_mmc_core_config(struct udevice *dev) { struct sti_sdhci_plat *plat = dev_get_platdata(dev); struct sdhci_host *host = dev_get_priv(dev);
- unsigned long *sysconf;
int ret;
/* only MMC1 has a reset line */ if (plat->instance) {
sysconf = (unsigned long *)(STIH410_SYSCONF5_BASE +
ST_MMC_CCONFIG_REG_5);
generic_set_bit(SYSCONF_MMC1_ENABLE_BIT, sysconf);
ret = reset_deassert(&plat->reset);
if (ret < 0) {
error("MMC1 deassert failed: %d", ret);
return ret;
}
}
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
@@ -66,6 +70,8 @@ static void sti_mmc_core_config(struct udevice *dev) } writel(STI_FLASHSS_MMC_CORE_CONFIG4, host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4);
- return 0;
}
static int sti_sdhci_probe(struct udevice *dev) @@ -80,13 +86,20 @@ static int sti_sdhci_probe(struct udevice *dev) * MMC0 is wired to the SD slot, * MMC1 is wired on the high speed connector */
- if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL))
- if (fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "resets", NULL)) { plat->instance = 1;
- else
ret = reset_get_by_name(dev, "softreset", &plat->reset);
if (ret) {
error("can't get reset for %s (%d)", dev->name, ret);
return ret;
}
- } else { plat->instance = 0;
- }
- sti_mmc_core_config(dev);
ret = sti_mmc_core_config(dev);
if (ret)
return ret;
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_32BIT_DMA_ADDR |

From: Patrice Chotard patrice.chotard@st.com
This is the generic phy driver for the picoPHY ports used by USB2 and USB3 Host controllers available on STiH407 SoC families.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 1 + drivers/usb/Kconfig | 4 + drivers/usb/phy/Kconfig | 11 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 9ee2fe4..ade618f 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y CONFIG_REGMAP=y CONFIG_SYSCON=y +CONFIG_MISC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_STI=y CONFIG_PINCTRL=y diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index da3ec2f..e30c9d6 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -94,4 +94,8 @@ endif
source "drivers/usb/gadget/Kconfig"
+comment "USB PHY" + +source "drivers/usb/phy/Kconfig" + endif diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig new file mode 100644 index 0000000..1a86c6e --- /dev/null +++ b/drivers/usb/phy/Kconfig @@ -0,0 +1,11 @@ +menu "USB PHY drivers" + +config STI_PHY_USB + bool "STMicroelectronics USB2 picoPHY driver for STiH407 family" + default n + help + This is the generic phy driver for the picoPHY ports + used by USB2 and USB3 Host controllers available on + STiH407 SoC families. + +endmenu diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 4e548c2..b50fb5a 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_TWL4030_USB) += twl4030.o obj-$(CONFIG_OMAP_USB_PHY) += omap_usb_phy.o obj-$(CONFIG_ROCKCHIP_USB2_PHY) += rockchip_usb2_phy.o +obj-$(CONFIG_STI_PHY_USB) += sti_phy_usb.o diff --git a/drivers/usb/phy/sti_phy_usb.c b/drivers/usb/phy/sti_phy_usb.c new file mode 100644 index 0000000..214d7ff --- /dev/null +++ b/drivers/usb/phy/sti_phy_usb.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <bitfield.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <regmap.h> +#include <reset-uclass.h> +#include <syscon.h> +#include <wait_bit.h> + +#include <linux/bitops.h> +#include <linux/compat.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Default PHY_SEL and REFCLKSEL configuration */ +#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6 + +/* ports parameters overriding */ +#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc + +#define PHYPARAM_REG 1 +#define PHYCTRL_REG 2 +#define PHYPARAM_NB 3 + +struct sti_phy_usb { + struct regmap *regmap; + struct reset_ctl global_ctl; + struct reset_ctl port_ctl; + int param; + int ctrl; +}; + +static int sti_phy_usb_deassert(struct sti_phy_usb *phy) +{ + int ret; + + ret = reset_deassert(&phy->global_ctl); + if (ret < 0) { + error("PHY global deassert failed: %d", ret); + return ret; + } + + ret = reset_deassert(&phy->port_ctl); + if (ret < 0) + error("PHY port deassert failed: %d", ret); + + return ret; +} + +static void sti_phy_usb_init(struct sti_phy_usb *phy) +{ + void __iomem *reg; + u32 val; + + /* set ctrl picophy value */ + reg = (void __iomem *)phy->regmap->base + phy->ctrl; + val = readl(reg); + /* CTRL_PORT mask is 0x1f */ + bitfield_replace(val, 0, 5, STIH407_USB_PICOPHY_CTRL_PORT_CONF); + writel(val, reg); + + /* set ports parameters overriding */ + reg = (void __iomem *)phy->regmap->base + phy->param; + val = readl(reg); + /* PARAM_DEF mask is 0xffffffff */ + bitfield_replace(val, 0, 31, STIH407_USB_PICOPHY_PARAM_DEF); + writel(val, reg); +} + +int sti_phy_usb_probe(struct udevice *dev) +{ + struct sti_phy_usb *priv = dev_get_priv(dev); + struct udevice *syscon; + struct fdtdec_phandle_args syscfg_phandle; + u32 cells[PHYPARAM_NB]; + int ret, count; + + /* get corresponding syscon phandle */ + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, + "st,syscfg", NULL, 0, 0, + &syscfg_phandle); + if (ret < 0) { + error("Can't get syscfg phandle: %d\n", ret); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node, + &syscon); + if (ret) { + error("unable to find syscon device (%d)\n", ret); + return ret; + } + + priv->regmap = syscon_get_regmap(syscon); + if (!priv->regmap) { + error("unable to find regmap\n"); + return -ENODEV; + } + + /* get phy param offset */ + count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, + "st,syscfg", cells, + ARRAY_SIZE(cells)); + + if (count < 0) { + error("Bad PHY st,syscfg property %d\n", count); + return -EINVAL; + } + + if (count > PHYPARAM_NB) { + error("Unsupported PHY param count %d\n", count); + return -EINVAL; + } + + priv->param = cells[PHYPARAM_REG]; + priv->ctrl = cells[PHYCTRL_REG]; + + /* get global reset control */ + ret = reset_get_by_name(dev, "global", &priv->global_ctl); + if (ret) { + error("can't get global reset for %s (%d)", dev->name, ret); + return ret; + } + + /* get port reset control */ + ret = reset_get_by_name(dev, "port", &priv->port_ctl); + if (ret) { + error("can't get port reset for %s (%d)", dev->name, ret); + return ret; + } + + sti_phy_usb_init(priv); + + return sti_phy_usb_deassert(priv); +} + +static const struct udevice_id sti_phy_usb_ids[] = { + { .compatible = "st,stih407-usb2-phy" }, + { } +}; + +U_BOOT_DRIVER(sti_phy_usb) = { + .name = "sti_phy_usb", + .id = UCLASS_MISC, + .of_match = sti_phy_usb_ids, + .probe = sti_phy_usb_probe, + .priv_auto_alloc_size = sizeof(struct sti_phy_usb), +};

On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This is the generic phy driver for the picoPHY ports used by USB2 and USB3 Host controllers available on STiH407 SoC families.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + drivers/usb/Kconfig | 4 + drivers/usb/phy/Kconfig | 11 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 9ee2fe4..ade618f 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y CONFIG_REGMAP=y CONFIG_SYSCON=y +CONFIG_MISC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_STI=y CONFIG_PINCTRL=y diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index da3ec2f..e30c9d6 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -94,4 +94,8 @@ endif
source "drivers/usb/gadget/Kconfig"
+comment "USB PHY"
+source "drivers/usb/phy/Kconfig"
endif diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig new file mode 100644 index 0000000..1a86c6e --- /dev/null +++ b/drivers/usb/phy/Kconfig @@ -0,0 +1,11 @@ +menu "USB PHY drivers"
+config STI_PHY_USB
- bool "STMicroelectronics USB2 picoPHY driver for STiH407 family"
- default n
- help
This is the generic phy driver for the picoPHY ports
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
+endmenu diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 4e548c2..b50fb5a 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_TWL4030_USB) += twl4030.o obj-$(CONFIG_OMAP_USB_PHY) += omap_usb_phy.o obj-$(CONFIG_ROCKCHIP_USB2_PHY) += rockchip_usb2_phy.o +obj-$(CONFIG_STI_PHY_USB) += sti_phy_usb.o diff --git a/drivers/usb/phy/sti_phy_usb.c b/drivers/usb/phy/sti_phy_usb.c new file mode 100644 index 0000000..214d7ff --- /dev/null +++ b/drivers/usb/phy/sti_phy_usb.c @@ -0,0 +1,158 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <bitfield.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <regmap.h> +#include <reset-uclass.h> +#include <syscon.h> +#include <wait_bit.h>
+#include <linux/bitops.h> +#include <linux/compat.h>
+DECLARE_GLOBAL_DATA_PTR;
+/* Default PHY_SEL and REFCLKSEL configuration */ +#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6
+/* ports parameters overriding */ +#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc
+#define PHYPARAM_REG 1 +#define PHYCTRL_REG 2 +#define PHYPARAM_NB 3
+struct sti_phy_usb {
- struct regmap *regmap;
- struct reset_ctl global_ctl;
- struct reset_ctl port_ctl;
- int param;
- int ctrl;
+};
+static int sti_phy_usb_deassert(struct sti_phy_usb *phy) +{
- int ret;
- ret = reset_deassert(&phy->global_ctl);
- if (ret < 0) {
error("PHY global deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&phy->port_ctl);
- if (ret < 0)
error("PHY port deassert failed: %d", ret);
- return ret;
+}
+static void sti_phy_usb_init(struct sti_phy_usb *phy) +{
- void __iomem *reg;
- u32 val;
- /* set ctrl picophy value */
- reg = (void __iomem *)phy->regmap->base + phy->ctrl;
- val = readl(reg);
- /* CTRL_PORT mask is 0x1f */
- bitfield_replace(val, 0, 5, STIH407_USB_PICOPHY_CTRL_PORT_CONF);
- writel(val, reg);
- /* set ports parameters overriding */
- reg = (void __iomem *)phy->regmap->base + phy->param;
- val = readl(reg);
- /* PARAM_DEF mask is 0xffffffff */
- bitfield_replace(val, 0, 31, STIH407_USB_PICOPHY_PARAM_DEF);
is that clrsetbits_le32() here ?
- writel(val, reg);
+}
+int sti_phy_usb_probe(struct udevice *dev) +{
- struct sti_phy_usb *priv = dev_get_priv(dev);
- struct udevice *syscon;
- struct fdtdec_phandle_args syscfg_phandle;
- u32 cells[PHYPARAM_NB];
- int ret, count;
- /* get corresponding syscon phandle */
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
"st,syscfg", NULL, 0, 0,
&syscfg_phandle);
- if (ret < 0) {
error("Can't get syscfg phandle: %d\n", ret);
return ret;
- }
- ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node,
&syscon);
- if (ret) {
error("unable to find syscon device (%d)\n", ret);
return ret;
- }
- priv->regmap = syscon_get_regmap(syscon);
- if (!priv->regmap) {
error("unable to find regmap\n");
return -ENODEV;
- }
- /* get phy param offset */
- count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
"st,syscfg", cells,
ARRAY_SIZE(cells));
- if (count < 0) {
error("Bad PHY st,syscfg property %d\n", count);
return -EINVAL;
- }
- if (count > PHYPARAM_NB) {
error("Unsupported PHY param count %d\n", count);
return -EINVAL;
- }
- priv->param = cells[PHYPARAM_REG];
- priv->ctrl = cells[PHYCTRL_REG];
- /* get global reset control */
- ret = reset_get_by_name(dev, "global", &priv->global_ctl);
- if (ret) {
error("can't get global reset for %s (%d)", dev->name, ret);
return ret;
- }
- /* get port reset control */
- ret = reset_get_by_name(dev, "port", &priv->port_ctl);
- if (ret) {
error("can't get port reset for %s (%d)", dev->name, ret);
return ret;
- }
- sti_phy_usb_init(priv);
- return sti_phy_usb_deassert(priv);
+}
+static const struct udevice_id sti_phy_usb_ids[] = {
- { .compatible = "st,stih407-usb2-phy" },
- { }
+};
+U_BOOT_DRIVER(sti_phy_usb) = {
- .name = "sti_phy_usb",
- .id = UCLASS_MISC,
- .of_match = sti_phy_usb_ids,
- .probe = sti_phy_usb_probe,
- .priv_auto_alloc_size = sizeof(struct sti_phy_usb),
+};

Hi Marek
On 03/17/2017 05:38 PM, Marek Vasut wrote:
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This is the generic phy driver for the picoPHY ports used by USB2 and USB3 Host controllers available on STiH407 SoC families.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + drivers/usb/Kconfig | 4 + drivers/usb/phy/Kconfig | 11 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 9ee2fe4..ade618f 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y CONFIG_REGMAP=y CONFIG_SYSCON=y +CONFIG_MISC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_STI=y CONFIG_PINCTRL=y diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index da3ec2f..e30c9d6 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -94,4 +94,8 @@ endif
source "drivers/usb/gadget/Kconfig"
+comment "USB PHY"
+source "drivers/usb/phy/Kconfig"
endif diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig new file mode 100644 index 0000000..1a86c6e --- /dev/null +++ b/drivers/usb/phy/Kconfig @@ -0,0 +1,11 @@ +menu "USB PHY drivers"
+config STI_PHY_USB
- bool "STMicroelectronics USB2 picoPHY driver for STiH407 family"
- default n
- help
This is the generic phy driver for the picoPHY ports
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
+endmenu diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 4e548c2..b50fb5a 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_TWL4030_USB) += twl4030.o obj-$(CONFIG_OMAP_USB_PHY) += omap_usb_phy.o obj-$(CONFIG_ROCKCHIP_USB2_PHY) += rockchip_usb2_phy.o +obj-$(CONFIG_STI_PHY_USB) += sti_phy_usb.o diff --git a/drivers/usb/phy/sti_phy_usb.c b/drivers/usb/phy/sti_phy_usb.c new file mode 100644 index 0000000..214d7ff --- /dev/null +++ b/drivers/usb/phy/sti_phy_usb.c @@ -0,0 +1,158 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <bitfield.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <regmap.h> +#include <reset-uclass.h> +#include <syscon.h> +#include <wait_bit.h>
+#include <linux/bitops.h> +#include <linux/compat.h>
+DECLARE_GLOBAL_DATA_PTR;
+/* Default PHY_SEL and REFCLKSEL configuration */ +#define STIH407_USB_PICOPHY_CTRL_PORT_CONF 0x6
+/* ports parameters overriding */ +#define STIH407_USB_PICOPHY_PARAM_DEF 0x39a4dc
+#define PHYPARAM_REG 1 +#define PHYCTRL_REG 2 +#define PHYPARAM_NB 3
+struct sti_phy_usb {
- struct regmap *regmap;
- struct reset_ctl global_ctl;
- struct reset_ctl port_ctl;
- int param;
- int ctrl;
+};
+static int sti_phy_usb_deassert(struct sti_phy_usb *phy) +{
- int ret;
- ret = reset_deassert(&phy->global_ctl);
- if (ret < 0) {
error("PHY global deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&phy->port_ctl);
- if (ret < 0)
error("PHY port deassert failed: %d", ret);
- return ret;
+}
+static void sti_phy_usb_init(struct sti_phy_usb *phy) +{
- void __iomem *reg;
- u32 val;
- /* set ctrl picophy value */
- reg = (void __iomem *)phy->regmap->base + phy->ctrl;
- val = readl(reg);
- /* CTRL_PORT mask is 0x1f */
- bitfield_replace(val, 0, 5, STIH407_USB_PICOPHY_CTRL_PORT_CONF);
- writel(val, reg);
- /* set ports parameters overriding */
- reg = (void __iomem *)phy->regmap->base + phy->param;
- val = readl(reg);
- /* PARAM_DEF mask is 0xffffffff */
- bitfield_replace(val, 0, 31, STIH407_USB_PICOPHY_PARAM_DEF);
is that clrsetbits_le32() here ?
yes, it's more elegant, i will update the 2 instance of bitfield_replace()
- writel(val, reg);
+}
+int sti_phy_usb_probe(struct udevice *dev) +{
- struct sti_phy_usb *priv = dev_get_priv(dev);
- struct udevice *syscon;
- struct fdtdec_phandle_args syscfg_phandle;
- u32 cells[PHYPARAM_NB];
- int ret, count;
- /* get corresponding syscon phandle */
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
"st,syscfg", NULL, 0, 0,
&syscfg_phandle);
- if (ret < 0) {
error("Can't get syscfg phandle: %d\n", ret);
return ret;
- }
- ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node,
&syscon);
- if (ret) {
error("unable to find syscon device (%d)\n", ret);
return ret;
- }
- priv->regmap = syscon_get_regmap(syscon);
- if (!priv->regmap) {
error("unable to find regmap\n");
return -ENODEV;
- }
- /* get phy param offset */
- count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
"st,syscfg", cells,
ARRAY_SIZE(cells));
- if (count < 0) {
error("Bad PHY st,syscfg property %d\n", count);
return -EINVAL;
- }
- if (count > PHYPARAM_NB) {
error("Unsupported PHY param count %d\n", count);
return -EINVAL;
- }
- priv->param = cells[PHYPARAM_REG];
- priv->ctrl = cells[PHYCTRL_REG];
- /* get global reset control */
- ret = reset_get_by_name(dev, "global", &priv->global_ctl);
- if (ret) {
error("can't get global reset for %s (%d)", dev->name, ret);
return ret;
- }
- /* get port reset control */
- ret = reset_get_by_name(dev, "port", &priv->port_ctl);
- if (ret) {
error("can't get port reset for %s (%d)", dev->name, ret);
return ret;
- }
- sti_phy_usb_init(priv);
- return sti_phy_usb_deassert(priv);
+}
+static const struct udevice_id sti_phy_usb_ids[] = {
- { .compatible = "st,stih407-usb2-phy" },
- { }
+};
+U_BOOT_DRIVER(sti_phy_usb) = {
- .name = "sti_phy_usb",
- .id = UCLASS_MISC,
- .of_match = sti_phy_usb_ids,
- .probe = sti_phy_usb_probe,
- .priv_auto_alloc_size = sizeof(struct sti_phy_usb),
+};

Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This is the generic phy driver for the picoPHY ports used by USB2 and USB3 Host controllers available on STiH407 SoC families.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + drivers/usb/Kconfig | 4 + drivers/usb/phy/Kconfig | 11 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c
Really we should have a UCLASS_USB_PHY for this. Can you work up a simple implementation as a starting point?
Regards, Simon

Hi Simon
On 03/22/2017 02:06 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This is the generic phy driver for the picoPHY ports used by USB2 and USB3 Host controllers available on STiH407 SoC families.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + drivers/usb/Kconfig | 4 + drivers/usb/phy/Kconfig | 11 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c
Really we should have a UCLASS_USB_PHY for this. Can you work up a simple implementation as a starting point?
Yes, no problem, i will add a usb phy implementation in my next series
Patrice
Regards, Simon

From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI + bool "Support for STMicroelectronics on-chip EHCI USB controller" + depends on ARCH_STI + select STI_PHY_USB + default y + ---help--- + Enables support for the on-chip EHCI controller on + STMicroelectronics SoCs. + config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_ehci_priv { + struct ehci_ctrl ctrl; + struct reset_ctl power_ctl; + struct reset_ctl softreset_ctl; +}; + +static int sti_ehci_probe(struct udevice *dev) +{ + struct sti_ehci_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr = priv->ctrl.hccr; + struct ehci_hcor *hcor; + struct udevice *dev_phy; + int ret, phy_node; + + hccr = (struct ehci_hccr *)dev_get_addr(dev); + + if (hccr == (void *)FDT_ADDR_T_NONE) + return -EINVAL; + + ret = reset_get_by_name(dev, "power", &priv->power_ctl); + if (ret) { + error("can't get power reset for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl); + if (ret) { + error("can't get soft reset for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_deassert(&priv->power_ctl); + if (ret < 0) { + error("EHCI power reset deassert failed: %d", ret); + return ret; + } + + ret = reset_deassert(&priv->softreset_ctl); + if (ret < 0) { + error("EHCI soft reset deassert failed: %d", ret); + return ret; + } + + /* get phy node */ + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys"); + if (phy_node <= 0) { + error("Not found usb phy device\n"); + return -ENODEV; + } + + /* probe associated phy */ + ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); + + hcor = (struct ehci_hcor *)((phys_addr_t)hccr + + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); + + return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); +} + +static const struct udevice_id sti_usb_ids[] = { + { .compatible = "st,st-ehci-300x" }, + { } +}; + +U_BOOT_DRIVER(ehci_sti) = { + .name = "ehci_sti", + .id = UCLASS_USB, + .of_match = sti_usb_ids, + .probe = sti_ehci_probe, + .remove = ehci_deregister, + .ops = &ehci_usb_ops, + .priv_auto_alloc_size = sizeof(struct sti_ehci_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};

On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
- bool "Support for STMicroelectronics on-chip EHCI USB controller"
- depends on ARCH_STI
- select STI_PHY_USB
- default y
- ---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
- struct ehci_ctrl ctrl;
- struct reset_ctl power_ctl;
- struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
- struct sti_ehci_priv *priv = dev_get_priv(dev);
- struct ehci_hccr *hccr = priv->ctrl.hccr;
- struct ehci_hcor *hcor;
- struct udevice *dev_phy;
- int ret, phy_node;
- hccr = (struct ehci_hccr *)dev_get_addr(dev);
- if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
- ret = reset_get_by_name(dev, "power", &priv->power_ctl);
- if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
power or reset ? I think the error messages could use some improvement, the code looks mostly OK.
return ret;
- }
- ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
- if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_deassert(&priv->power_ctl);
- if (ret < 0) {
error("EHCI power reset deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&priv->softreset_ctl);
- if (ret < 0) {
error("EHCI soft reset deassert failed: %d", ret);
return ret;
- }
- /* get phy node */
- phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
- if (phy_node <= 0) {
error("Not found usb phy device\n");
"USB PHY DT node not found."
return -ENODEV;
- }
- /* probe associated phy */
- ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
- hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
- return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+static const struct udevice_id sti_usb_ids[] = {
- { .compatible = "st,st-ehci-300x" },
- { }
+};
+U_BOOT_DRIVER(ehci_sti) = {
- .name = "ehci_sti",
- .id = UCLASS_USB,
- .of_match = sti_usb_ids,
- .probe = sti_ehci_probe,
- .remove = ehci_deregister,
You should put the core into reset state on removal ...
- .ops = &ehci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct sti_ehci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};

Hi Marek
On 03/17/2017 05:40 PM, Marek Vasut wrote:
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
- bool "Support for STMicroelectronics on-chip EHCI USB controller"
- depends on ARCH_STI
- select STI_PHY_USB
- default y
- ---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
- struct ehci_ctrl ctrl;
- struct reset_ctl power_ctl;
- struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
- struct sti_ehci_priv *priv = dev_get_priv(dev);
- struct ehci_hccr *hccr = priv->ctrl.hccr;
- struct ehci_hcor *hcor;
- struct udevice *dev_phy;
- int ret, phy_node;
- hccr = (struct ehci_hccr *)dev_get_addr(dev);
- if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
- ret = reset_get_by_name(dev, "power", &priv->power_ctl);
- if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
power or reset ? I think the error messages could use some improvement, the code looks mostly OK.
Right, i will be clearer :-)
return ret;
- }
- ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
- if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_deassert(&priv->power_ctl);
- if (ret < 0) {
error("EHCI power reset deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&priv->softreset_ctl);
- if (ret < 0) {
error("EHCI soft reset deassert failed: %d", ret);
return ret;
- }
- /* get phy node */
- phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
- if (phy_node <= 0) {
error("Not found usb phy device\n");
"USB PHY DT node not found."
Ok
return -ENODEV;
- }
- /* probe associated phy */
- ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
- hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
- return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+static const struct udevice_id sti_usb_ids[] = {
- { .compatible = "st,st-ehci-300x" },
- { }
+};
+U_BOOT_DRIVER(ehci_sti) = {
- .name = "ehci_sti",
- .id = UCLASS_USB,
- .of_match = sti_usb_ids,
- .probe = sti_ehci_probe,
- .remove = ehci_deregister,
You should put the core into reset state on removal ...
Right, i will add a specific remove callback
Thanks
- .ops = &ehci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct sti_ehci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};

Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
return ret;
}
ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
}
ret = reset_deassert(&priv->power_ctl);
if (ret < 0) {
error("EHCI power reset deassert failed: %d", ret);
return ret;
}
ret = reset_deassert(&priv->softreset_ctl);
if (ret < 0) {
error("EHCI soft reset deassert failed: %d", ret);
return ret;
}
/* get phy node */
phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
if (phy_node <= 0) {
error("Not found usb phy device\n");
return -ENODEV;
}
/* probe associated phy */
ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
Instead of the above two calls, can you use uclass_get_device_by_phandle()?
hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+static const struct udevice_id sti_usb_ids[] = {
{ .compatible = "st,st-ehci-300x" },
{ }
+};
+U_BOOT_DRIVER(ehci_sti) = {
.name = "ehci_sti",
.id = UCLASS_USB,
.of_match = sti_usb_ids,
.probe = sti_ehci_probe,
.remove = ehci_deregister,
.ops = &ehci_usb_ops,
.priv_auto_alloc_size = sizeof(struct sti_ehci_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
1.9.1
Regards, Simon

Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
return ret;
}
ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
}
ret = reset_deassert(&priv->power_ctl);
if (ret < 0) {
error("EHCI power reset deassert failed: %d", ret);
return ret;
}
ret = reset_deassert(&priv->softreset_ctl);
if (ret < 0) {
error("EHCI soft reset deassert failed: %d", ret);
return ret;
}
/* get phy node */
phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
if (phy_node <= 0) {
error("Not found usb phy device\n");
return -ENODEV;
}
/* probe associated phy */
ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
Instead of the above two calls, can you use uclass_get_device_by_phandle()?
Yes, agree, i will also apply this to ohci-sti.c and xhci-sti.c which are similar .
Thanks
Patrice
hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+static const struct udevice_id sti_usb_ids[] = {
{ .compatible = "st,st-ehci-300x" },
{ }
+};
+U_BOOT_DRIVER(ehci_sti) = {
.name = "ehci_sti",
.id = UCLASS_USB,
.of_match = sti_usb_ids,
.probe = sti_ehci_probe,
.remove = ehci_deregister,
.ops = &ehci_usb_ops,
.priv_auto_alloc_size = sizeof(struct sti_ehci_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
1.9.1
Regards, Simon

Hi Patrice,
On 23 March 2017 at 03:59, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
I mean that generally when a device needs another device this is expressed by adding a phandle in the client device's node, or perhaps some sort of name. That way it is possible (e.g.) to specify *which* reset rather than hard-coding it.
Regards. Simon

Hi Simon
On 04/01/2017 06:21 AM, Simon Glass wrote:
Hi Patrice,
On 23 March 2017 at 03:59, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
I mean that generally when a device needs another device this is expressed by adding a phandle in the client device's node, or perhaps some sort of name. That way it is possible (e.g.) to specify *which* reset rather than hard-coding it.
Agree with you, but i get one constraint. For this ehci IP, there are 2 resets (power and softreset). I must identify each other to be able to assert/deassert them in the correct order.
I checked other U-boot drivers which already used reset, and all of them are using reset_get_by_name().
Patrice
Regards. Simon

Hi Patrice,
On 3 April 2017 at 03:39, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 04/01/2017 06:21 AM, Simon Glass wrote:
Hi Patrice,
On 23 March 2017 at 03:59, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
I mean that generally when a device needs another device this is expressed by adding a phandle in the client device's node, or perhaps some sort of name. That way it is possible (e.g.) to specify *which* reset rather than hard-coding it.
Agree with you, but i get one constraint. For this ehci IP, there are 2 resets (power and softreset). I must identify each other to be able to assert/deassert them in the correct order.
One of those sounds like a reset. The other sounds like a regulator.
I checked other U-boot drivers which already used reset, and all of them are using reset_get_by_name().
OK well it was a suggestion so will leave it to you. Is that how Linux does it also?
Regards, Simon

Hi Simon
On 04/09/2017 09:27 PM, Simon Glass wrote:
Hi Patrice,
On 3 April 2017 at 03:39, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 04/01/2017 06:21 AM, Simon Glass wrote:
Hi Patrice,
On 23 March 2017 at 03:59, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ehci controller available on STMicrolectronics SoCs. ehci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/usb/host/ehci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only.
+config USB_EHCI_STI
bool "Support for STMicroelectronics on-chip EHCI USB controller"
depends on ARCH_STI
select STI_PHY_USB
default y
---help---
Enables support for the on-chip EHCI controller on
STMicroelectronics SoCs.
config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..89ca66a --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,91 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+struct sti_ehci_priv {
struct ehci_ctrl ctrl;
struct reset_ctl power_ctl;
struct reset_ctl softreset_ctl;
+};
+static int sti_ehci_probe(struct udevice *dev) +{
struct sti_ehci_priv *priv = dev_get_priv(dev);
struct ehci_hccr *hccr = priv->ctrl.hccr;
struct ehci_hcor *hcor;
struct udevice *dev_phy;
int ret, phy_node;
hccr = (struct ehci_hccr *)dev_get_addr(dev);
if (hccr == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
I mean that generally when a device needs another device this is expressed by adding a phandle in the client device's node, or perhaps some sort of name. That way it is possible (e.g.) to specify *which* reset rather than hard-coding it.
Agree with you, but i get one constraint. For this ehci IP, there are 2 resets (power and softreset). I must identify each other to be able to assert/deassert them in the correct order.
One of those sounds like a reset. The other sounds like a regulator.
I checked other U-boot drivers which already used reset, and all of them are using reset_get_by_name().
OK well it was a suggestion so will leave it to you. Is that how Linux does it also?
Yes, i reproduce exactly what is done in Linux.
Patrice
Regards, Simon

On 18 April 2017 at 00:56, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 04/09/2017 09:27 PM, Simon Glass wrote:
Hi Patrice,
On 3 April 2017 at 03:39, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 04/01/2017 06:21 AM, Simon Glass wrote:
Hi Patrice,
On 23 March 2017 at 03:59, Patrice CHOTARD patrice.chotard@st.com wrote:
Hi Simon
On 03/22/2017 02:05 PM, Simon Glass wrote:
Hi,
On 17 March 2017 at 10:25, patrice.chotard@st.com wrote: > From: Patrice Chotard patrice.chotard@st.com > > Add support for on-chip ehci controller available > on STMicrolectronics SoCs. > ehci support will be then available on both type A > USB 2.0 connectors. > > Signed-off-by: Patrice Chotard patrice.chotard@st.com > --- > drivers/usb/host/Kconfig | 9 +++++ > drivers/usb/host/Makefile | 1 + > drivers/usb/host/ehci-sti.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 101 insertions(+) > create mode 100644 drivers/usb/host/ehci-sti.c > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > index 5129a57..d66f49e 100644 > --- a/drivers/usb/host/Kconfig > +++ b/drivers/usb/host/Kconfig > @@ -120,6 +120,15 @@ config USB_EHCI_MSM > This driver supports combination of Chipidea USB controller > and Synapsys USB PHY in host mode only. > > +config USB_EHCI_STI > + bool "Support for STMicroelectronics on-chip EHCI USB controller" > + depends on ARCH_STI > + select STI_PHY_USB > + default y > + ---help--- > + Enables support for the on-chip EHCI controller on > + STMicroelectronics SoCs. > + > config USB_EHCI_ZYNQ > bool "Support for Xilinx Zynq on-chip EHCI USB controller" > depends on ARCH_ZYNQ > diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile > index 58c0cf5..303aa32 100644 > --- a/drivers/usb/host/Makefile > +++ b/drivers/usb/host/Makefile > @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o > obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o > obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o > obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o > +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o > obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o > obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o > obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o > diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c > new file mode 100644 > index 0000000..89ca66a > --- /dev/null > +++ b/drivers/usb/host/ehci-sti.c > @@ -0,0 +1,91 @@ > +/* > + * Copyright (c) 2017 > + * Patrice Chotard patrice.chotard@st.com > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/io.h> > +#include <dm.h> > +#include <errno.h> > +#include "ehci.h" > +#include <reset-uclass.h> > +#include <usb.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct sti_ehci_priv { > + struct ehci_ctrl ctrl; > + struct reset_ctl power_ctl; > + struct reset_ctl softreset_ctl; > +}; > + > +static int sti_ehci_probe(struct udevice *dev) > +{ > + struct sti_ehci_priv *priv = dev_get_priv(dev); > + struct ehci_hccr *hccr = priv->ctrl.hccr; > + struct ehci_hcor *hcor; > + struct udevice *dev_phy; > + int ret, phy_node; > + > + hccr = (struct ehci_hccr *)dev_get_addr(dev); > + > + if (hccr == (void *)FDT_ADDR_T_NONE) > + return -EINVAL; > + > + ret = reset_get_by_name(dev, "power", &priv->power_ctl);
This is OK, but can you instead access it via a phandle in the device's node?
Sorry i didn't get your point. Why getting it using a phandle ?
I mean that generally when a device needs another device this is expressed by adding a phandle in the client device's node, or perhaps some sort of name. That way it is possible (e.g.) to specify *which* reset rather than hard-coding it.
Agree with you, but i get one constraint. For this ehci IP, there are 2 resets (power and softreset). I must identify each other to be able to assert/deassert them in the correct order.
One of those sounds like a reset. The other sounds like a regulator.
I checked other U-boot drivers which already used reset, and all of them are using reset_get_by_name().
OK well it was a suggestion so will leave it to you. Is that how Linux does it also?
Yes, i reproduce exactly what is done in Linux.
Reviewed-by: Simon Glass sjg@chromium.org

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index ade618f..c2c7256 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -8,6 +8,7 @@ CONFIG_FIT_VERBOSE=y CONFIG_SYS_PROMPT="stih410-b2260 => " # CONFIG_CMD_IMLS is not set CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_CMD_EXT2=y @@ -25,4 +26,8 @@ CONFIG_STI_RESET=y CONFIG_STI_ASC_SERIAL=y CONFIG_SYSRESET=y CONFIG_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_STORAGE=y CONFIG_SPL_OF_LIBFDT=y

From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ohci controller available on STMicrolectronics SoCs. Ohci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-sti.c | 90 +++++++++++++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 3 ++ 4 files changed, 103 insertions(+) create mode 100644 drivers/usb/host/ohci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d66f49e..33ded5d 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -168,6 +168,15 @@ config USB_OHCI_GENERIC ---help--- Enables support for generic OHCI controller.
+config USB_OHCI_STI + bool "Support for STMicroelectronics OHCI USB controller" + depends on ARCH_STI + depends on OF_CONTROL + depends on DM_USB + select USB_HOST + ---help--- + Enables support for the on-chip OHCI controller on STMicroelectronics SoCs. + endif # USB_OHCI_HCD
config USB_UHCI_HCD diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 303aa32..b78e632 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o +obj-$(CONFIG_USB_OHCI_STI) += ohci-sti.o
# echi obj-$(CONFIG_USB_EHCI) += ehci-hcd.o diff --git a/drivers/usb/host/ohci-sti.c b/drivers/usb/host/ohci-sti.c new file mode 100644 index 0000000..62b63cd --- /dev/null +++ b/drivers/usb/host/ohci-sti.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ohci.h" +#include <reset-uclass.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if !defined(CONFIG_USB_OHCI_NEW) +# error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW" +#endif + +struct sti_ohci_priv { + ohci_t ohci; + struct reset_ctl power_ctl; + struct reset_ctl softreset_ctl; +}; + +static int ohci_usb_probe(struct udevice *dev) +{ + struct sti_ohci_priv *priv = dev_get_priv(dev); + struct ohci_regs *regs; + struct udevice *dev_phy; + int ret, phy_node; + + regs = (struct ohci_regs *)dev_get_addr(dev); + if (regs == (void *)FDT_ADDR_T_NONE) + return -EINVAL; + + ret = reset_get_by_name(dev, "power", &priv->power_ctl); + if (ret) { + error("can't get power reset for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl); + if (ret) { + error("can't get soft reset for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_deassert(&priv->power_ctl); + if (ret < 0) { + error("OHCI power reset deassert failed: %d", ret); + return ret; + } + + ret = reset_deassert(&priv->softreset_ctl); + if (ret < 0) { + error("OHCI soft reset deassert failed: %d", ret); + return ret; + } + + /* get phy node */ + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys"); + if (phy_node <= 0) { + error("Not found usb phy device\n"); + return -ENODEV; + } + + /* probe associated phy node */ + ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); + + return ohci_register(dev, regs); +} + +static const struct udevice_id sti_usb_ids[] = { + { .compatible = "st,st-ohci-300x" }, + { } +}; + +U_BOOT_DRIVER(ohci_sti) = { + .name = "ohci_sti", + .id = UCLASS_USB, + .of_match = sti_usb_ids, + .probe = ohci_usb_probe, + .remove = ohci_deregister, + .ops = &ohci_usb_ops, + .priv_auto_alloc_size = sizeof(struct sti_ohci_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index 28e2f7f..4a5da82 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -57,4 +57,7 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_USB_OHCI_NEW +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 + #endif /* __CONFIG_H */

On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ohci controller available on STMicrolectronics SoCs. Ohci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-sti.c | 90 +++++++++++++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 3 ++ 4 files changed, 103 insertions(+) create mode 100644 drivers/usb/host/ohci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d66f49e..33ded5d 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -168,6 +168,15 @@ config USB_OHCI_GENERIC ---help--- Enables support for generic OHCI controller.
+config USB_OHCI_STI
- bool "Support for STMicroelectronics OHCI USB controller"
- depends on ARCH_STI
- depends on OF_CONTROL
- depends on DM_USB
- select USB_HOST
- ---help---
Enables support for the on-chip OHCI controller on STMicroelectronics SoCs.
endif # USB_OHCI_HCD
config USB_UHCI_HCD diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 303aa32..b78e632 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o +obj-$(CONFIG_USB_OHCI_STI) += ohci-sti.o
# echi obj-$(CONFIG_USB_EHCI) += ehci-hcd.o diff --git a/drivers/usb/host/ohci-sti.c b/drivers/usb/host/ohci-sti.c new file mode 100644 index 0000000..62b63cd --- /dev/null +++ b/drivers/usb/host/ohci-sti.c @@ -0,0 +1,90 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ohci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+#if !defined(CONFIG_USB_OHCI_NEW) +# error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW" +#endif
+struct sti_ohci_priv {
- ohci_t ohci;
- struct reset_ctl power_ctl;
- struct reset_ctl softreset_ctl;
+};
+static int ohci_usb_probe(struct udevice *dev) +{
- struct sti_ohci_priv *priv = dev_get_priv(dev);
- struct ohci_regs *regs;
- struct udevice *dev_phy;
- int ret, phy_node;
- regs = (struct ohci_regs *)dev_get_addr(dev);
- if (regs == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
- ret = reset_get_by_name(dev, "power", &priv->power_ctl);
- if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
- if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_deassert(&priv->power_ctl);
- if (ret < 0) {
error("OHCI power reset deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&priv->softreset_ctl);
- if (ret < 0) {
error("OHCI soft reset deassert failed: %d", ret);
return ret;
- }
- /* get phy node */
- phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
- if (phy_node <= 0) {
error("Not found usb phy device\n");
return -ENODEV;
- }
- /* probe associated phy node */
- ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
- return ohci_register(dev, regs);
+}
+static const struct udevice_id sti_usb_ids[] = {
- { .compatible = "st,st-ohci-300x" },
- { }
+};
+U_BOOT_DRIVER(ohci_sti) = {
- .name = "ohci_sti",
- .id = UCLASS_USB,
- .of_match = sti_usb_ids,
- .probe = ohci_usb_probe,
- .remove = ohci_deregister,
- .ops = &ohci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct sti_ohci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index 28e2f7f..4a5da82 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -57,4 +57,7 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_USB_OHCI_NEW +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
Is this max_root_ports still needed ? :(
btw this board-thing should likely be split into separate patch
#endif /* __CONFIG_H */

Hi Marek
On 03/17/2017 05:41 PM, Marek Vasut wrote:
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip ohci controller available on STMicrolectronics SoCs. Ohci support will be then available on both type A USB 2.0 connectors.
Signed-off-by: Patrice Chotard patrice.chotard@st.com
drivers/usb/host/Kconfig | 9 +++++ drivers/usb/host/Makefile | 1 + drivers/usb/host/ohci-sti.c | 90 +++++++++++++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 3 ++ 4 files changed, 103 insertions(+) create mode 100644 drivers/usb/host/ohci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d66f49e..33ded5d 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -168,6 +168,15 @@ config USB_OHCI_GENERIC ---help--- Enables support for generic OHCI controller.
+config USB_OHCI_STI
- bool "Support for STMicroelectronics OHCI USB controller"
- depends on ARCH_STI
- depends on OF_CONTROL
- depends on DM_USB
- select USB_HOST
- ---help---
Enables support for the on-chip OHCI controller on STMicroelectronics SoCs.
endif # USB_OHCI_HCD
config USB_UHCI_HCD diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 303aa32..b78e632 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_USB_OHCI_EP93XX) += ohci-ep93xx.o obj-$(CONFIG_USB_OHCI_SUNXI) += ohci-sunxi.o obj-$(CONFIG_USB_OHCI_LPC32XX) += ohci-lpc32xx.o obj-$(CONFIG_USB_OHCI_GENERIC) += ohci-generic.o +obj-$(CONFIG_USB_OHCI_STI) += ohci-sti.o
# echi obj-$(CONFIG_USB_EHCI) += ehci-hcd.o diff --git a/drivers/usb/host/ohci-sti.c b/drivers/usb/host/ohci-sti.c new file mode 100644 index 0000000..62b63cd --- /dev/null +++ b/drivers/usb/host/ohci-sti.c @@ -0,0 +1,90 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ohci.h" +#include <reset-uclass.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+#if !defined(CONFIG_USB_OHCI_NEW) +# error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW" +#endif
+struct sti_ohci_priv {
- ohci_t ohci;
- struct reset_ctl power_ctl;
- struct reset_ctl softreset_ctl;
+};
+static int ohci_usb_probe(struct udevice *dev) +{
- struct sti_ohci_priv *priv = dev_get_priv(dev);
- struct ohci_regs *regs;
- struct udevice *dev_phy;
- int ret, phy_node;
- regs = (struct ohci_regs *)dev_get_addr(dev);
- if (regs == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
- ret = reset_get_by_name(dev, "power", &priv->power_ctl);
- if (ret) {
error("can't get power reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl);
- if (ret) {
error("can't get soft reset for %s (%d)", dev->name, ret);
return ret;
- }
- ret = reset_deassert(&priv->power_ctl);
- if (ret < 0) {
error("OHCI power reset deassert failed: %d", ret);
return ret;
- }
- ret = reset_deassert(&priv->softreset_ctl);
- if (ret < 0) {
error("OHCI soft reset deassert failed: %d", ret);
return ret;
- }
- /* get phy node */
- phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys");
- if (phy_node <= 0) {
error("Not found usb phy device\n");
return -ENODEV;
- }
- /* probe associated phy node */
- ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy);
- return ohci_register(dev, regs);
+}
+static const struct udevice_id sti_usb_ids[] = {
- { .compatible = "st,st-ohci-300x" },
- { }
+};
+U_BOOT_DRIVER(ohci_sti) = {
- .name = "ohci_sti",
- .id = UCLASS_USB,
- .of_match = sti_usb_ids,
- .probe = ohci_usb_probe,
- .remove = ohci_deregister,
- .ops = &ohci_usb_ops,
- .priv_auto_alloc_size = sizeof(struct sti_ohci_priv),
- .flags = DM_FLAG_ALLOC_PRIV_DMA,
+}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index 28e2f7f..4a5da82 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -57,4 +57,7 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_USB_OHCI_NEW +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
Is this max_root_ports still needed ? :(
Yes it's still needed
btw this board-thing should likely be split into separate patch
Ok i will extract board config from this patch
#endif /* __CONFIG_H */

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index c2c7256..46c20e1 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -29,5 +29,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_STI=y CONFIG_USB_STORAGE=y CONFIG_SPL_OF_LIBFDT=y

From: Patrice Chotard patrice.chotard@st.com
Add support for on-chip DWC3 controller available on STMicrolectronics STiH407 family SoCs. On B2260 board, the type AB USB connector is managed by a DWC3 IP. As USB3 signals are not wired, only USB2 is supported.
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- drivers/usb/host/Kconfig | 8 +++ drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-sti.c | 156 ++++++++++++++++++++++++++++++++++++++++ include/configs/stih410-b2260.h | 1 + 4 files changed, 166 insertions(+) create mode 100644 drivers/usb/host/xhci-sti.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 33ded5d..58b64df 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -37,6 +37,14 @@ config USB_XHCI_ROCKCHIP help Enables support for the on-chip xHCI controller on Rockchip SoCs.
+config USB_XHCI_STI + bool "Support for STMicroelectronics STiH407 family on-chip xHCI USB controller" + depends on ARCH_STI + default y + help + Enables support for the on-chip xHCI controller on STMicroelectronics + STiH407 family SoCs. + config USB_XHCI_ZYNQMP bool "Support for Xilinx ZynqMP on-chip xHCI USB controller" depends on ARCH_ZYNQMP diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index b78e632..40ff830 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o +obj-$(CONFIG_USB_XHCI_STI) += xhci-sti.o
# designware obj-$(CONFIG_USB_DWC2) += dwc2.o diff --git a/drivers/usb/host/xhci-sti.c b/drivers/usb/host/xhci-sti.c new file mode 100644 index 0000000..00f17ce --- /dev/null +++ b/drivers/usb/host/xhci-sti.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <reset-uclass.h> +#include <usb.h> + +#include <linux/usb/dwc3.h> + +#include "xhci.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_xhci_platdata { + struct reset_ctl powerdown_ctl; + struct reset_ctl softreset_ctl; + phys_addr_t dwc3_regs; +}; + +struct sti_xhci_priv { + struct xhci_ctrl ctrl; +}; + + +static int sti_xhci_ofdata_to_platdata(struct udevice *dev) +{ + struct sti_xhci_platdata *plat = dev_get_platdata(dev); + struct udevice *dev_phy; + int ret; + int phy_node; + int dwc3_node; + u32 reg[2]; + + /* get powerdown reset */ + ret = reset_get_by_name(dev, "powerdown", &plat->powerdown_ctl); + if (ret) { + error("can't get powerdown reset for %s (%d)", dev->name, ret); + return ret; + } + + /* get softreset reset */ + ret = reset_get_by_name(dev, "softreset", &plat->softreset_ctl); + if (ret) { + error("can't get soft reset for %s (%d)", dev->name, ret); + return ret; + } + + /* deassert both powerdown and softreset */ + ret = reset_deassert(&plat->powerdown_ctl); + if (ret < 0) { + error("DWC3 powerdown reset deassert failed: %d", ret); + return ret; + } + + ret = reset_deassert(&plat->softreset_ctl); + if (ret < 0) { + error("DWC3 soft reset deassert failed: %d", ret); + return ret; + } + + /* check if dwc3 subnode is present */ + dwc3_node = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev)); + if (dwc3_node <= 0) { + error("Can't find subnode for st_dwc3 glue driver\n"); + return -ENODEV; + } + + if (fdt_node_check_compatible(gd->fdt_blob, dwc3_node, + "snps,dwc3") != 0) { + error("Can't find dwv3 subnode for st_dwc3 glue driver\n"); + return -ENODEV; + } + + /* + * now parse the dwc3 node + * first get the phy node: only usb2-phy, no need to get usb3-phy as + * usb3 is not wired + */ + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dwc3_node, "phys"); + if (phy_node <= 0) { + error("Can't find usb phy device\n"); + return -ENODEV; + } + + /* get the dwc3 register space base address */ + if (fdtdec_get_int_array(gd->fdt_blob, dwc3_node, "reg", reg, + ARRAY_SIZE(reg))) { + debug("dwc3 node has bad/missing 'reg' property\n"); + return -FDT_ERR_NOTFOUND; + } + plat->dwc3_regs = reg[0]; + + /* probe associated phy */ + return uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); +}; + +static int sti_xhci_core_init(struct dwc3 *dwc3_reg) +{ + int ret; + + ret = dwc3_core_init(dwc3_reg); + if (ret) { + debug("failed to initialize core\n"); + return ret; + } + + /* We are hard-coding DWC3 core to Host Mode */ + dwc3_set_mode(dwc3_reg, DWC3_GCTL_PRTCAP_HOST); + + return 0; +} + +static int sti_dwc3_probe(struct udevice *dev) +{ + struct sti_xhci_platdata *plat = dev_get_platdata(dev); + struct xhci_hcor *hcor; + struct xhci_hccr *hccr; + struct dwc3 *dwc3_reg; + + hccr = (struct xhci_hccr *)plat->dwc3_regs; + hcor = (struct xhci_hcor *)((phys_addr_t)hccr + + HC_LENGTH(xhci_readl(&(hccr)->cr_capbase))); + + dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET); + + sti_xhci_core_init(dwc3_reg); + + return xhci_register(dev, hccr, hcor); +} + +static const struct udevice_id sti_dwc3_ids[] = { + { .compatible = "st,stih407-dwc3" }, + { } +}; + +U_BOOT_DRIVER(xhci_sti) = { + .name = "xhci_sti", + .id = UCLASS_USB, + .of_match = sti_dwc3_ids, + .ofdata_to_platdata = sti_xhci_ofdata_to_platdata, + .probe = sti_dwc3_probe, + .remove = xhci_deregister, + .ops = &xhci_usb_ops, + .priv_auto_alloc_size = sizeof(struct sti_xhci_priv), + .platdata_auto_alloc_size = sizeof(struct sti_xhci_platdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index 4a5da82..bbf64d7 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -59,5 +59,6 @@
#define CONFIG_USB_OHCI_NEW #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 +#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#endif /* __CONFIG_H */

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 46c20e1..835f982 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -28,6 +28,8 @@ CONFIG_SYSRESET=y CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_STI=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 2 ++ include/configs/stih410-b2260.h | 12 ++++++++++++ 2 files changed, 14 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 835f982..fd13ea3 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -9,6 +9,8 @@ CONFIG_SYS_PROMPT="stih410-b2260 => " # CONFIG_CMD_IMLS is not set CONFIG_CMD_MMC=y CONFIG_CMD_USB=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_PING=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_CMD_EXT2=y diff --git a/include/configs/stih410-b2260.h b/include/configs/stih410-b2260.h index bbf64d7..0a52af3 100644 --- a/include/configs/stih410-b2260.h +++ b/include/configs/stih410-b2260.h @@ -57,8 +57,20 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
+/* USB Configs */ #define CONFIG_USB_OHCI_NEW #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
+#define CONFIG_USB_HOST_ETHER +#define CONFIG_USB_ETHER_ASIX +#define CONFIG_USB_ETHER_MCS7830 +#define CONFIG_USB_ETHER_SMSC95XX + +/* NET Configs */ +#define CONFIG_BOOTP_SUBNETMASK +#define CONFIG_BOOTP_GATEWAY +#define CONFIG_BOOTP_HOSTNAME +#define CONFIG_BOOTP_BOOTPATH + #endif /* __CONFIG_H */

From: Patrice Chotard patrice.chotard@st.com
This patch adds the ST glue logic to manage the DWC3 HC on STiH407 SoC family. It configures the internal glue logic and syscfg registers.
Part of this code been extracted from kernel.org driver (drivers/usb/dwc3/dwc3-st.c)
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- arch/arm/include/asm/arch-stih410/sys_proto.h | 11 +++ drivers/usb/dwc3/Kconfig | 8 ++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-sti.c | 137 ++++++++++++++++++++++++++ include/dwc3-sti-uboot.h | 50 ++++++++++ 5 files changed, 207 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h create mode 100644 drivers/usb/dwc3/dwc3-sti.c create mode 100644 include/dwc3-sti-uboot.h
diff --git a/arch/arm/include/asm/arch-stih410/sys_proto.h b/arch/arm/include/asm/arch-stih410/sys_proto.h new file mode 100644 index 0000000..5c40d3b --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sys_proto.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_SYS_PROTO_H +#define _ASM_ARCH_SYS_PROTO_H + +#endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index e93398f..51a7a00 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -37,6 +37,14 @@ config USB_DWC3_OMAP
Say 'Y' here if you have one such device
+config USB_DWC3_STI + bool "STMicroelectronics STiH407 family glue driver" + help + STMicroelectronics STiH407 family SoCs use this IP for + USB2/3 functionality. + + Say 'Y' here if you have one such device + menu "PHY Subsystem"
config USB_DWC3_PHY_OMAP diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2964bae..753912d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG) += samsung_usb_phy.o +obj-$(CONFIG_USB_DWC3_STI) += dwc3-sti.o diff --git a/drivers/usb/dwc3/dwc3-sti.c b/drivers/usb/dwc3/dwc3-sti.c new file mode 100644 index 0000000..5ff3e76 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-sti.c @@ -0,0 +1,137 @@ +/* + * dwc3-sti.c - STiH407 family DWC3 specific Glue layer + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/io.h> +#include <common.h> +#include <dm.h> +#include <dwc3-sti-uboot.h> +#include <fdtdec.h> +#include <regmap.h> +#include <syscon.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +__weak int __board_usb_init(int index, enum usb_init_type init) +{ + return 0; +} +/*int board_usb_init(int index, enum usb_init_type init)*/ +/* __attribute__((weak, alias("__board_usb_init")));*/ + +static int sti_dwc3_drd_init(struct sti_dwc3_platdata *plat) +{ + unsigned long val; + + val = readl(plat->syscfg_base + plat->syscfg_offset); + + val &= USB3_CONTROL_MASK; + + switch (plat->mode) { + case USB_DR_MODE_PERIPHERAL: + val &= ~(USB3_DELAY_VBUSVALID + | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) + | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 + | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); + + val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID; + break; + + case USB_DR_MODE_HOST: + val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID + | USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3) + | USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2 + | USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2); + + val |= USB3_DELAY_VBUSVALID; + break; + + default: + error("Unsupported mode of operation %d\n", plat->mode); + return -EINVAL; + } + return writel(val, plat->syscfg_base + plat->syscfg_offset); +} + +static void sti_dwc3_init(struct sti_dwc3_platdata *plat) +{ + unsigned long reg; + + reg = readl(plat->glue_base + CLKRST_CTRL); + + reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION; + reg &= ~SW_PIPEW_RESET_N; + + writel(reg, plat->glue_base + CLKRST_CTRL); + + /* configure mux for vbus, powerpresent and bvalid signals */ + reg = readl(plat->glue_base + USB2_VBUS_MNGMNT_SEL1); + + reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) | + SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) | + SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG); + + writel(reg, plat->glue_base + USB2_VBUS_MNGMNT_SEL1); + + reg = readl(plat->glue_base + CLKRST_CTRL); + reg |= SW_PIPEW_RESET_N; + writel(reg, plat->glue_base + CLKRST_CTRL); +} + +int sti_dwc3_glue_init(enum usb_dr_mode mode) +{ + struct sti_dwc3_platdata plat; + struct fdtdec_phandle_args syscfg_phandle; + struct udevice *syscon; + struct regmap *regmap; + int node, ret; + const void *blob = gd->fdt_blob; + u32 reg[4]; + + /* find the dwc3 node */ + node = fdt_node_offset_by_compatible(blob, -1, "st,stih407-dwc3"); + + ret = fdtdec_get_int_array(blob, node, "reg", reg, ARRAY_SIZE(reg)); + if (ret) { + error("unable to find st,stih407-dwc3 reg property(%d)\n", ret); + return ret; + } + + plat.glue_base = reg[0]; + plat.syscfg_offset = reg[2]; + plat.mode = mode; + + /* get corresponding syscon phandle */ + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, + "st,syscfg", NULL, 0, 0, + &syscfg_phandle); + if (ret < 0) { + error("Can't get syscfg phandle: %d\n", ret); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node, + &syscon); + if (ret) { + error("unable to find syscon device (%d)\n", ret); + return ret; + } + + /* get syscfg-reg base address */ + regmap = syscon_get_regmap(syscon); + if (!regmap) { + error("unable to find regmap\n"); + return -ENODEV; + } + plat.syscfg_base = regmap->base; + + sti_dwc3_drd_init(&plat); + sti_dwc3_init(&plat); + + return 0; +} diff --git a/include/dwc3-sti-uboot.h b/include/dwc3-sti-uboot.h new file mode 100644 index 0000000..c7bb770 --- /dev/null +++ b/include/dwc3-sti-uboot.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard patrice.chotard@st.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DWC3_STI_UBOOT_H_ +#define __DWC3_STI_UBOOT_H_ + +#include <linux/usb/otg.h> + +/* glue registers */ +#define CLKRST_CTRL 0x00 +#define AUX_CLK_EN BIT(0) +#define SW_PIPEW_RESET_N BIT(4) +#define EXT_CFG_RESET_N BIT(8) + +#define XHCI_REVISION BIT(12) + +#define USB2_VBUS_MNGMNT_SEL1 0x2C +#define USB2_VBUS_UTMIOTG 0x1 + +#define SEL_OVERRIDE_VBUSVALID(n) (n << 0) +#define SEL_OVERRIDE_POWERPRESENT(n) (n << 4) +#define SEL_OVERRIDE_BVALID(n) (n << 8) + +/* Static DRD configuration */ +#define USB3_CONTROL_MASK 0xf77 + +#define USB3_DEVICE_NOT_HOST BIT(0) +#define USB3_FORCE_VBUSVALID BIT(1) +#define USB3_DELAY_VBUSVALID BIT(2) +#define USB3_SEL_FORCE_OPMODE BIT(4) +#define USB3_FORCE_OPMODE(n) (n << 5) +#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) +#define USB3_FORCE_DPPULLDOWN2 BIT(9) +#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) +#define USB3_FORCE_DMPULLDOWN2 BIT(11) + +struct sti_dwc3_platdata { + phys_addr_t syscfg_base; + phys_addr_t glue_base; + phys_addr_t syscfg_offset; + enum usb_dr_mode mode; +}; + +int sti_dwc3_glue_init(enum usb_dr_mode mode); + +#endif /* __DWC3_STI_UBOOT_H_ */

On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This patch adds the ST glue logic to manage the DWC3 HC on STiH407 SoC family. It configures the internal glue logic and syscfg registers.
Part of this code been extracted from kernel.org driver (drivers/usb/dwc3/dwc3-st.c)
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/include/asm/arch-stih410/sys_proto.h | 11 +++ drivers/usb/dwc3/Kconfig | 8 ++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-sti.c | 137 ++++++++++++++++++++++++++ include/dwc3-sti-uboot.h | 50 ++++++++++ 5 files changed, 207 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h create mode 100644 drivers/usb/dwc3/dwc3-sti.c create mode 100644 include/dwc3-sti-uboot.h
diff --git a/arch/arm/include/asm/arch-stih410/sys_proto.h b/arch/arm/include/asm/arch-stih410/sys_proto.h new file mode 100644 index 0000000..5c40d3b --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sys_proto.h @@ -0,0 +1,11 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _ASM_ARCH_SYS_PROTO_H +#define _ASM_ARCH_SYS_PROTO_H
+#endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index e93398f..51a7a00 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -37,6 +37,14 @@ config USB_DWC3_OMAP
Say 'Y' here if you have one such device
+config USB_DWC3_STI
- bool "STMicroelectronics STiH407 family glue driver"
- help
STMicroelectronics STiH407 family SoCs use this IP for
USB2/3 functionality.
Say 'Y' here if you have one such device
menu "PHY Subsystem"
config USB_DWC3_PHY_OMAP diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2964bae..753912d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG) += samsung_usb_phy.o +obj-$(CONFIG_USB_DWC3_STI) += dwc3-sti.o diff --git a/drivers/usb/dwc3/dwc3-sti.c b/drivers/usb/dwc3/dwc3-sti.c new file mode 100644 index 0000000..5ff3e76 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-sti.c @@ -0,0 +1,137 @@ +/*
- dwc3-sti.c - STiH407 family DWC3 specific Glue layer
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <asm/io.h> +#include <common.h> +#include <dm.h> +#include <dwc3-sti-uboot.h> +#include <fdtdec.h> +#include <regmap.h> +#include <syscon.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+__weak int __board_usb_init(int index, enum usb_init_type init) +{
- return 0;
+} +/*int board_usb_init(int index, enum usb_init_type init)*/ +/* __attribute__((weak, alias("__board_usb_init")));*/
+static int sti_dwc3_drd_init(struct sti_dwc3_platdata *plat) +{
- unsigned long val;
- val = readl(plat->syscfg_base + plat->syscfg_offset);
- val &= USB3_CONTROL_MASK;
- switch (plat->mode) {
- case USB_DR_MODE_PERIPHERAL:
val &= ~(USB3_DELAY_VBUSVALID
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID;
break;
- case USB_DR_MODE_HOST:
val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
val |= USB3_DELAY_VBUSVALID;
break;
- default:
error("Unsupported mode of operation %d\n", plat->mode);
return -EINVAL;
- }
- return writel(val, plat->syscfg_base + plat->syscfg_offset);
+}
+static void sti_dwc3_init(struct sti_dwc3_platdata *plat) +{
- unsigned long reg;
- reg = readl(plat->glue_base + CLKRST_CTRL);
- reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION;
- reg &= ~SW_PIPEW_RESET_N;
- writel(reg, plat->glue_base + CLKRST_CTRL);
- /* configure mux for vbus, powerpresent and bvalid signals */
- reg = readl(plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
- reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) |
SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) |
SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG);
- writel(reg, plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
- reg = readl(plat->glue_base + CLKRST_CTRL);
- reg |= SW_PIPEW_RESET_N;
- writel(reg, plat->glue_base + CLKRST_CTRL);
setbits_le32() ?
+}
+int sti_dwc3_glue_init(enum usb_dr_mode mode) +{
- struct sti_dwc3_platdata plat;
- struct fdtdec_phandle_args syscfg_phandle;
- struct udevice *syscon;
- struct regmap *regmap;
- int node, ret;
- const void *blob = gd->fdt_blob;
- u32 reg[4];
- /* find the dwc3 node */
- node = fdt_node_offset_by_compatible(blob, -1, "st,stih407-dwc3");
- ret = fdtdec_get_int_array(blob, node, "reg", reg, ARRAY_SIZE(reg));
- if (ret) {
error("unable to find st,stih407-dwc3 reg property(%d)\n", ret);
return ret;
- }
- plat.glue_base = reg[0];
- plat.syscfg_offset = reg[2];
- plat.mode = mode;
- /* get corresponding syscon phandle */
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node,
"st,syscfg", NULL, 0, 0,
&syscfg_phandle);
- if (ret < 0) {
error("Can't get syscfg phandle: %d\n", ret);
return ret;
- }
- ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node,
&syscon);
- if (ret) {
error("unable to find syscon device (%d)\n", ret);
return ret;
- }
- /* get syscfg-reg base address */
- regmap = syscon_get_regmap(syscon);
- if (!regmap) {
error("unable to find regmap\n");
return -ENODEV;
- }
- plat.syscfg_base = regmap->base;
- sti_dwc3_drd_init(&plat);
- sti_dwc3_init(&plat);
- return 0;
+} diff --git a/include/dwc3-sti-uboot.h b/include/dwc3-sti-uboot.h new file mode 100644 index 0000000..c7bb770 --- /dev/null +++ b/include/dwc3-sti-uboot.h @@ -0,0 +1,50 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __DWC3_STI_UBOOT_H_ +#define __DWC3_STI_UBOOT_H_
+#include <linux/usb/otg.h>
+/* glue registers */ +#define CLKRST_CTRL 0x00 +#define AUX_CLK_EN BIT(0) +#define SW_PIPEW_RESET_N BIT(4) +#define EXT_CFG_RESET_N BIT(8)
+#define XHCI_REVISION BIT(12)
+#define USB2_VBUS_MNGMNT_SEL1 0x2C +#define USB2_VBUS_UTMIOTG 0x1
+#define SEL_OVERRIDE_VBUSVALID(n) (n << 0) +#define SEL_OVERRIDE_POWERPRESENT(n) (n << 4) +#define SEL_OVERRIDE_BVALID(n) (n << 8)
+/* Static DRD configuration */ +#define USB3_CONTROL_MASK 0xf77
+#define USB3_DEVICE_NOT_HOST BIT(0) +#define USB3_FORCE_VBUSVALID BIT(1) +#define USB3_DELAY_VBUSVALID BIT(2) +#define USB3_SEL_FORCE_OPMODE BIT(4) +#define USB3_FORCE_OPMODE(n) (n << 5)
The (n) should be in parenthesis ...
+#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) +#define USB3_FORCE_DPPULLDOWN2 BIT(9) +#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) +#define USB3_FORCE_DMPULLDOWN2 BIT(11)
+struct sti_dwc3_platdata {
- phys_addr_t syscfg_base;
- phys_addr_t glue_base;
- phys_addr_t syscfg_offset;
- enum usb_dr_mode mode;
+};
+int sti_dwc3_glue_init(enum usb_dr_mode mode);
+#endif /* __DWC3_STI_UBOOT_H_ */

Hi Marek
On 03/17/2017 05:42 PM, Marek Vasut wrote:
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This patch adds the ST glue logic to manage the DWC3 HC on STiH407 SoC family. It configures the internal glue logic and syscfg registers.
Part of this code been extracted from kernel.org driver (drivers/usb/dwc3/dwc3-st.c)
Signed-off-by: Patrice Chotard patrice.chotard@st.com
arch/arm/include/asm/arch-stih410/sys_proto.h | 11 +++ drivers/usb/dwc3/Kconfig | 8 ++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-sti.c | 137 ++++++++++++++++++++++++++ include/dwc3-sti-uboot.h | 50 ++++++++++ 5 files changed, 207 insertions(+) create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h create mode 100644 drivers/usb/dwc3/dwc3-sti.c create mode 100644 include/dwc3-sti-uboot.h
diff --git a/arch/arm/include/asm/arch-stih410/sys_proto.h b/arch/arm/include/asm/arch-stih410/sys_proto.h new file mode 100644 index 0000000..5c40d3b --- /dev/null +++ b/arch/arm/include/asm/arch-stih410/sys_proto.h @@ -0,0 +1,11 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _ASM_ARCH_SYS_PROTO_H +#define _ASM_ARCH_SYS_PROTO_H
+#endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index e93398f..51a7a00 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -37,6 +37,14 @@ config USB_DWC3_OMAP
Say 'Y' here if you have one such device
+config USB_DWC3_STI
- bool "STMicroelectronics STiH407 family glue driver"
- help
STMicroelectronics STiH407 family SoCs use this IP for
USB2/3 functionality.
Say 'Y' here if you have one such device
menu "PHY Subsystem"
config USB_DWC3_PHY_OMAP diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 2964bae..753912d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_PHY_OMAP) += ti_usb_phy.o obj-$(CONFIG_USB_DWC3_PHY_SAMSUNG) += samsung_usb_phy.o +obj-$(CONFIG_USB_DWC3_STI) += dwc3-sti.o diff --git a/drivers/usb/dwc3/dwc3-sti.c b/drivers/usb/dwc3/dwc3-sti.c new file mode 100644 index 0000000..5ff3e76 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-sti.c @@ -0,0 +1,137 @@ +/*
- dwc3-sti.c - STiH407 family DWC3 specific Glue layer
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <asm/io.h> +#include <common.h> +#include <dm.h> +#include <dwc3-sti-uboot.h> +#include <fdtdec.h> +#include <regmap.h> +#include <syscon.h> +#include <usb.h>
+DECLARE_GLOBAL_DATA_PTR;
+__weak int __board_usb_init(int index, enum usb_init_type init) +{
- return 0;
+} +/*int board_usb_init(int index, enum usb_init_type init)*/ +/* __attribute__((weak, alias("__board_usb_init")));*/
+static int sti_dwc3_drd_init(struct sti_dwc3_platdata *plat) +{
- unsigned long val;
- val = readl(plat->syscfg_base + plat->syscfg_offset);
- val &= USB3_CONTROL_MASK;
- switch (plat->mode) {
- case USB_DR_MODE_PERIPHERAL:
val &= ~(USB3_DELAY_VBUSVALID
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
val |= USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID;
break;
- case USB_DR_MODE_HOST:
val &= ~(USB3_DEVICE_NOT_HOST | USB3_FORCE_VBUSVALID
| USB3_SEL_FORCE_OPMODE | USB3_FORCE_OPMODE(0x3)
| USB3_SEL_FORCE_DPPULLDOWN2 | USB3_FORCE_DPPULLDOWN2
| USB3_SEL_FORCE_DMPULLDOWN2 | USB3_FORCE_DMPULLDOWN2);
val |= USB3_DELAY_VBUSVALID;
break;
- default:
error("Unsupported mode of operation %d\n", plat->mode);
return -EINVAL;
- }
- return writel(val, plat->syscfg_base + plat->syscfg_offset);
+}
+static void sti_dwc3_init(struct sti_dwc3_platdata *plat) +{
- unsigned long reg;
- reg = readl(plat->glue_base + CLKRST_CTRL);
- reg |= AUX_CLK_EN | EXT_CFG_RESET_N | XHCI_REVISION;
- reg &= ~SW_PIPEW_RESET_N;
- writel(reg, plat->glue_base + CLKRST_CTRL);
- /* configure mux for vbus, powerpresent and bvalid signals */
- reg = readl(plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
- reg |= SEL_OVERRIDE_VBUSVALID(USB2_VBUS_UTMIOTG) |
SEL_OVERRIDE_POWERPRESENT(USB2_VBUS_UTMIOTG) |
SEL_OVERRIDE_BVALID(USB2_VBUS_UTMIOTG);
- writel(reg, plat->glue_base + USB2_VBUS_MNGMNT_SEL1);
- reg = readl(plat->glue_base + CLKRST_CTRL);
- reg |= SW_PIPEW_RESET_N;
- writel(reg, plat->glue_base + CLKRST_CTRL);
setbits_le32() ?
Ok, i will use setbits_le32 instead
+}
+int sti_dwc3_glue_init(enum usb_dr_mode mode) +{
- struct sti_dwc3_platdata plat;
- struct fdtdec_phandle_args syscfg_phandle;
- struct udevice *syscon;
- struct regmap *regmap;
- int node, ret;
- const void *blob = gd->fdt_blob;
- u32 reg[4];
- /* find the dwc3 node */
- node = fdt_node_offset_by_compatible(blob, -1, "st,stih407-dwc3");
- ret = fdtdec_get_int_array(blob, node, "reg", reg, ARRAY_SIZE(reg));
- if (ret) {
error("unable to find st,stih407-dwc3 reg property(%d)\n", ret);
return ret;
- }
- plat.glue_base = reg[0];
- plat.syscfg_offset = reg[2];
- plat.mode = mode;
- /* get corresponding syscon phandle */
- ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, node,
"st,syscfg", NULL, 0, 0,
&syscfg_phandle);
- if (ret < 0) {
error("Can't get syscfg phandle: %d\n", ret);
return ret;
- }
- ret = uclass_get_device_by_of_offset(UCLASS_SYSCON, syscfg_phandle.node,
&syscon);
- if (ret) {
error("unable to find syscon device (%d)\n", ret);
return ret;
- }
- /* get syscfg-reg base address */
- regmap = syscon_get_regmap(syscon);
- if (!regmap) {
error("unable to find regmap\n");
return -ENODEV;
- }
- plat.syscfg_base = regmap->base;
- sti_dwc3_drd_init(&plat);
- sti_dwc3_init(&plat);
- return 0;
+} diff --git a/include/dwc3-sti-uboot.h b/include/dwc3-sti-uboot.h new file mode 100644 index 0000000..c7bb770 --- /dev/null +++ b/include/dwc3-sti-uboot.h @@ -0,0 +1,50 @@ +/*
- Copyright (c) 2017
- Patrice Chotard patrice.chotard@st.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __DWC3_STI_UBOOT_H_ +#define __DWC3_STI_UBOOT_H_
+#include <linux/usb/otg.h>
+/* glue registers */ +#define CLKRST_CTRL 0x00 +#define AUX_CLK_EN BIT(0) +#define SW_PIPEW_RESET_N BIT(4) +#define EXT_CFG_RESET_N BIT(8)
+#define XHCI_REVISION BIT(12)
+#define USB2_VBUS_MNGMNT_SEL1 0x2C +#define USB2_VBUS_UTMIOTG 0x1
+#define SEL_OVERRIDE_VBUSVALID(n) (n << 0) +#define SEL_OVERRIDE_POWERPRESENT(n) (n << 4) +#define SEL_OVERRIDE_BVALID(n) (n << 8)
+/* Static DRD configuration */ +#define USB3_CONTROL_MASK 0xf77
+#define USB3_DEVICE_NOT_HOST BIT(0) +#define USB3_FORCE_VBUSVALID BIT(1) +#define USB3_DELAY_VBUSVALID BIT(2) +#define USB3_SEL_FORCE_OPMODE BIT(4) +#define USB3_FORCE_OPMODE(n) (n << 5)
The (n) should be in parenthesis ...
+#define USB3_SEL_FORCE_DPPULLDOWN2 BIT(8) +#define USB3_FORCE_DPPULLDOWN2 BIT(9) +#define USB3_SEL_FORCE_DMPULLDOWN2 BIT(10) +#define USB3_FORCE_DMPULLDOWN2 BIT(11)
+struct sti_dwc3_platdata {
- phys_addr_t syscfg_base;
- phys_addr_t glue_base;
- phys_addr_t syscfg_offset;
- enum usb_dr_mode mode;
+};
+int sti_dwc3_glue_init(enum usb_dr_mode mode);
+#endif /* __DWC3_STI_UBOOT_H_ */

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index fd13ea3..6deca22 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -35,5 +35,8 @@ CONFIG_USB_XHCI_DWC3=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_STI=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GADGET=y +CONFIG_USB_DWC3_STI=y CONFIG_USB_STORAGE=y CONFIG_SPL_OF_LIBFDT=y

From: Patrice Chotard patrice.chotard@st.com
Add usb_gadget_handle_interrupts(), board_usb_init(), board_usb_cleanup() and g_dnl_board_usb_cable_connected() callbacks needed for FASTBOOT support
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- board/st/stih410-b2260/board.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/board/st/stih410-b2260/board.c b/board/st/stih410-b2260/board.c index 0c06bca..363c016 100644 --- a/board/st/stih410-b2260/board.c +++ b/board/st/stih410-b2260/board.c @@ -7,6 +7,9 @@ */
#include <common.h> +#include <dwc3-sti-uboot.h> +#include <dwc3-uboot.h> +#include <usb.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -26,3 +29,44 @@ int board_init(void) { return 0; } + +#ifdef CONFIG_USB_DWC3 +static struct dwc3_device dwc3_device_data = { + .maximum_speed = USB_SPEED_HIGH, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, +}; + +int usb_gadget_handle_interrupts(int index) +{ + dwc3_uboot_handle_interrupt(index); + return 0; +} + +int board_usb_init(int index, enum usb_init_type init) +{ + int node; + const void *blob = gd->fdt_blob; + + /* find the snps,dwc3 node */ + node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3"); + + dwc3_device_data.base = fdtdec_get_addr(blob, node, "reg"); + + /* init dwc3 glue with mode forced to PERIPHERAL */ + sti_dwc3_glue_init(USB_DR_MODE_PERIPHERAL); + + return dwc3_uboot_init(&dwc3_device_data); +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + dwc3_uboot_exit(index); + return 0; +} + +int g_dnl_board_usb_cable_connected(void) +{ + return 1; +} +#endif

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 6deca22..839da4d 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -39,4 +39,9 @@ CONFIG_USB_DWC3=y CONFIG_USB_DWC3_GADGET=y CONFIG_USB_DWC3_STI=y CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_G_DNL_MANUFACTURER="STMicroelectronics" +CONFIG_G_DNL_VENDOR_NUM=0x483 +CONFIG_G_DNL_PRODUCT_NUM=0x7270 CONFIG_SPL_OF_LIBFDT=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 839da4d..f79173c 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -6,6 +6,14 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y # CONFIG_DISPLAY_CPUINFO is not set CONFIG_SYS_PROMPT="stih410-b2260 => " +CONFIG_FASTBOOT=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_CMD_FASTBOOT=y +CONFIG_ANDROID_BOOT_IMAGE=y +CONFIG_FASTBOOT_BUF_ADDR=0x40000000 +CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 # CONFIG_CMD_IMLS is not set CONFIG_CMD_MMC=y CONFIG_CMD_USB=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index f79173c..83a1e3c 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -52,4 +52,5 @@ CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_G_DNL_MANUFACTURER="STMicroelectronics" CONFIG_G_DNL_VENDOR_NUM=0x483 CONFIG_G_DNL_PRODUCT_NUM=0x7270 +CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_SPL_OF_LIBFDT=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 83a1e3c..90de12a 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y CONFIG_OF_CONTROL=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 90de12a..4c6a0a1 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -15,6 +15,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 # CONFIG_CMD_IMLS is not set +CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y

From: Patrice Chotard patrice.chotard@st.com
Signed-off-by: Patrice Chotard patrice.chotard@st.com --- configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 4c6a0a1..c1113fc 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0 # CONFIG_CMD_IMLS is not set CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y

On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Just squash all the config patches into a single patch please ...
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 4c6a0a1..c1113fc 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0 # CONFIG_CMD_IMLS is not set CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y

Hi Marek
On 03/17/2017 05:42 PM, Marek Vasut wrote:
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
Just squash all the config patches into a single patch please ...
Ok sure
Signed-off-by: Patrice Chotard patrice.chotard@st.com
configs/stih410-b2260_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig index 4c6a0a1..c1113fc 100644 --- a/configs/stih410-b2260_defconfig +++ b/configs/stih410-b2260_defconfig @@ -17,6 +17,7 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0 # CONFIG_CMD_IMLS is not set CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y CONFIG_CMD_PING=y

A v2 has been sent with Marek's remarks fixes.
Patrice
On 03/17/2017 05:25 PM, patrice.chotard@st.com wrote:
From: Patrice Chotard patrice.chotard@st.com
This series adds : _ add reset driver _ update existing sdhci driver to use reset framework _ add usb phy driver _ add ehci support _ add ohci support _ add xhci support _ add fastboot support
With all this feature enable, it's now possible to _ boot on usb mass storage device _ boot from kernel image and dtb previously loaded using tftp _ update mmc partiton using fastboot
Patrice Chotard (21): reset: Add STi reset support mmc: sti_sdhci: Rework sti_mmc_core_config() ARM: dts: stih410-family: Add missing reset_names for mmc1 node mmc: sti_sdhci: Use reset framework phy: Add STi phy usb support usb: ehci: Add STi ehci support STiH410-B2260: enable USB related flags usb: ohci: Add STi ohci support STiH410-B2260: enable OHCI related flags usb: xhci: Add STi xhci support STiH410-B2260: enable XHCI related flags STiH410-B2260: Enabling USB Host Networking usb: dwc3: Add dwc3 support for STi STiH410-B2260: enable DWC3 support board: STiH410-B2260: add fastboot support STiH410-B2260: enable USB download gadget related flags STiH410-B2260: enable FASTBOOT related flags STiH410-B2260: enable OF_LIBFDT_OVERLAY STiH410-B2260: enable CMD_EXT4_WRITE STiH410-B2260: enable CMD_GPT STiH410-B2260: enable CMD_PART
arch/arm/Kconfig | 1 + arch/arm/dts/stih407-family.dtsi | 1 + arch/arm/include/asm/arch-stih410/sys_proto.h | 11 + board/st/stih410-b2260/board.c | 44 ++++ configs/stih410-b2260_defconfig | 33 +++ drivers/mmc/sti_sdhci.c | 60 +++-- drivers/reset/Kconfig | 8 + drivers/reset/Makefile | 1 + drivers/reset/sti-reset.c | 321 ++++++++++++++++++++++++++ drivers/usb/Kconfig | 4 + drivers/usb/dwc3/Kconfig | 8 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-sti.c | 137 +++++++++++ drivers/usb/host/Kconfig | 26 +++ drivers/usb/host/Makefile | 3 + drivers/usb/host/ehci-sti.c | 91 ++++++++ drivers/usb/host/ohci-sti.c | 90 ++++++++ drivers/usb/host/xhci-sti.c | 156 +++++++++++++ drivers/usb/phy/Kconfig | 11 + drivers/usb/phy/Makefile | 1 + drivers/usb/phy/sti_phy_usb.c | 158 +++++++++++++ include/configs/stih410-b2260.h | 16 ++ include/dwc3-sti-uboot.h | 50 ++++ 23 files changed, 1210 insertions(+), 22 deletions(-) create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h create mode 100644 drivers/reset/sti-reset.c create mode 100644 drivers/usb/dwc3/dwc3-sti.c create mode 100644 drivers/usb/host/ehci-sti.c create mode 100644 drivers/usb/host/ohci-sti.c create mode 100644 drivers/usb/host/xhci-sti.c create mode 100644 drivers/usb/phy/Kconfig create mode 100644 drivers/usb/phy/sti_phy_usb.c create mode 100644 include/dwc3-sti-uboot.h
participants (5)
-
Jaehoon Chung
-
Marek Vasut
-
Patrice CHOTARD
-
patrice.chotard@st.com
-
Simon Glass