[U-Boot] [PATCH v5 06/14] usb: dwc3: Add dwc3 glue driver support for STi

Patrice CHOTARD patrice.chotard at st.com
Mon May 15 09:24:10 UTC 2017


Hi Simon

On 05/15/2017 05:02 AM, Simon Glass wrote:
> Hi Patrice,
>
> On 10 May 2017 at 10:09,  <patrice.chotard at st.com> wrote:
>> From: Patrice Chotard <patrice.chotard at 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 at st.com>
>> ---
>> v5:     _ none
>>
>> v4:     _ none
>>
>> v3:     _ rename dwc3-sti.c to dwc3-sti-glue.c
>>         _ respect device tree hierarchy, this driver is now responsible
>>           for xhci-sti binding (done in sti_dwc3_glue_bind())
>>
>> v2:     _ use setbits_le32() instead of read, modify, write sequence
>>         _ add missing parenthesis
>>
>>  arch/arm/include/asm/arch-stih410/sys_proto.h |  11 +
>>  doc/device-tree-bindings/usb/dwc3-st.txt      |  60 ++++++
>>  drivers/usb/host/Makefile                     |   2 +-
>>  drivers/usb/host/dwc3-sti-glue.c              | 278 ++++++++++++++++++++++++++
>>  include/dwc3-sti-glue.h                       |  43 ++++
>>  5 files changed, 393 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm/include/asm/arch-stih410/sys_proto.h
>>  create mode 100644 doc/device-tree-bindings/usb/dwc3-st.txt
>>  create mode 100644 drivers/usb/host/dwc3-sti-glue.c
>>  create mode 100644 include/dwc3-sti-glue.h
>>
>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> Please see below.
>
>> 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 at 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/doc/device-tree-bindings/usb/dwc3-st.txt b/doc/device-tree-bindings/usb/dwc3-st.txt
>> new file mode 100644
>> index 0000000..a26a139
>> --- /dev/null
>> +++ b/doc/device-tree-bindings/usb/dwc3-st.txt
>> @@ -0,0 +1,60 @@
>> +ST DWC3 glue logic
>> +
>> +This file documents the parameters for the dwc3-st driver.
>> +This driver controls the glue logic used to configure the dwc3 core on
>> +STiH407 based platforms.
>> +
>> +Required properties:
>> + - compatible  : must be "st,stih407-dwc3"
>> + - reg         : glue logic base address and USB syscfg ctrl register offset
>> + - reg-names   : should be "reg-glue" and "syscfg-reg"
>> + - st,syscon   : should be phandle to system configuration node which
>> +                 encompasses the glue registers
>> + - resets      : list of phandle and reset specifier pairs. There should be two entries, one
>> +                 for the powerdown and softreset lines of the usb3 IP
>> + - reset-names : list of reset signal names. Names should be "powerdown" and "softreset"
>> +
>> + - #address-cells, #size-cells : should be '1' if the device has sub-nodes
>> +   with 'reg' property
>> +
>> + - pinctl-names        : A pinctrl state named "default" must be defined
>> +
>> + - pinctrl-0   : Pin control group
>> +
>> + - ranges      : allows valid 1:1 translation between child's address space and
>> +                 parent's address space
>> +
>> +Sub-nodes:
>> +The dwc3 core should be added as subnode to ST DWC3 glue as shown in the
>> +example below.
>> +
>> +NB: The dr_mode property is NOT optional for this driver, as the default value
>> +is "otg", which isn't supported by this SoC. Valid dr_mode values for dwc3-st are
>> +either "host" or "device".
>> +
>> +Example:
>> +
>> +st_dwc3: dwc3 at 8f94000 {
>> +       status          = "disabled";
>> +       compatible      = "st,stih407-dwc3";
>> +       reg             = <0x08f94000 0x1000>, <0x110 0x4>;
>> +       reg-names       = "reg-glue", "syscfg-reg";
>> +       st,syscfg       = <&syscfg_core>;
>> +       resets          = <&powerdown STIH407_USB3_POWERDOWN>,
>> +                         <&softreset STIH407_MIPHY2_SOFTRESET>;
>> +       reset-names     = "powerdown", "softreset";
>> +       #address-cells  = <1>;
>> +       #size-cells     = <1>;
>> +       pinctrl-names   = "default";
>> +       pinctrl-0       = <&pinctrl_usb3>;
>> +       ranges;
>> +
>> +       dwc3: dwc3 at 9900000 {
>> +               compatible      = "snps,dwc3";
>> +               reg             = <0x09900000 0x100000>;
>> +               interrupts      = <GIC_SPI 155 IRQ_TYPE_NONE>;
>> +               dr_mode         = "host";
>> +               phy-names       = "usb2-phy", "usb3-phy";
>> +               phys            = <&usb2_picophy2>, <&phy_port2 PHY_TYPE_USB3>;
>> +       };
>> +};
>
> Is this the binding used in Linux?

Yes, exactly the same

>
>> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
>> index 48a99f4..af7b7fb 100644
>> --- a/drivers/usb/host/Makefile
>> +++ b/drivers/usb/host/Makefile
>> @@ -64,7 +64,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
>> +obj-$(CONFIG_USB_XHCI_STI) += xhci-sti.o dwc3-sti-glue.o
>>
>>  # designware
>>  obj-$(CONFIG_USB_DWC2) += dwc2.o
>> diff --git a/drivers/usb/host/dwc3-sti-glue.c b/drivers/usb/host/dwc3-sti-glue.c
>> new file mode 100644
>> index 0000000..368d7ef
>> --- /dev/null
>> +++ b/drivers/usb/host/dwc3-sti-glue.c
>> @@ -0,0 +1,278 @@
>> +/*
>> + * STiH407 family DWC3 specific Glue layer
>> + *
>> + * Copyright (c) 2017
>> + * Patrice Chotard <patrice.chotard at st.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <asm/io.h>
>> +#include <common.h>
>
>
> common.h should always go first. See http://www.denx.de/wiki/U-Boot/CodingStyle

ok will fix it

>
>> +#include <dm.h>
>> +#include <dwc3-sti-glue.h>
>> +#include <errno.h>
>> +#include <fdtdec.h>
>> +#include <libfdt.h>
>> +#include <dm/lists.h>
>> +#include <regmap.h>
>> +#include <reset-uclass.h>
>> +#include <syscon.h>
>> +#include <usb.h>
>> +
>> +#include <linux/usb/dwc3.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct sti_dwc3_glue_platdata {
>
> struct comment? What do these fields mean?

ok, will add it

>
>> +       phys_addr_t syscfg_base;
>> +       phys_addr_t glue_base;
>> +       phys_addr_t syscfg_offset;
>> +       struct reset_ctl powerdown_ctl;
>> +       struct reset_ctl softreset_ctl;
>> +       enum usb_dr_mode mode;
>> +};
>> +
>> +static int sti_dwc3_glue_drd_init(struct sti_dwc3_glue_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_glue_init(struct sti_dwc3_glue_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);
>> +
>> +       setbits_le32(plat->glue_base + CLKRST_CTRL, SW_PIPEW_RESET_N);
>> +}
>> +
>> +int sti_dwc3_init(enum usb_dr_mode mode)
>> +{
>> +       struct sti_dwc3_glue_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);
>
> Can you use uclass_get_device_by_phandle()?

Ok

>
>> +       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;
>> +       }
>> +
>
> [..]
>
>> diff --git a/include/dwc3-sti-glue.h b/include/dwc3-sti-glue.h
>> new file mode 100644
>> index 0000000..2083427
>> --- /dev/null
>> +++ b/include/dwc3-sti-glue.h
>> @@ -0,0 +1,43 @@
>> +/*
>> + * Copyright (c) 2017
>> + * Patrice Chotard <patrice.chotard at 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)
>> +
>> +int sti_dwc3_init(enum usb_dr_mode mode);
>
> We really need to move the USB device stuff over the driver model. Any
> ideas on how we could do that?
>
>> +
>> +#endif /* __DWC3_STI_UBOOT_H_ */
>> --
>> 1.9.1
>>
>
> Regards,
> Simon
>


More information about the U-Boot mailing list