
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),
+};