On 03/17/2017 05:25 PM, patrice.chot...@st.com wrote: > From: Patrice Chotard <patrice.chot...@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.chot...@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.chot...@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), > +}; > -- Best regards, Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot