From c2b9aa98bf44e9537222c5c8d6ea365d5220f2e4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 30 Mar 2020 11:27:23 +0200 Subject: generic-phy: add generic_phy_get_by_node() Add generic_phy_get_by_node() to get a PHY phandle from a node instead of a udevice. Signed-off-by: Neil Armstrong Reviewed-by: Tom Rini [narmstrong: fixed by including ofnode.h in generic-phy.h] --- drivers/phy/phy-uclass.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index e201a90c8c8..e463b0b400e 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -31,20 +31,20 @@ static int generic_phy_xlate_offs_flags(struct phy *phy, return 0; } -int generic_phy_get_by_index(struct udevice *dev, int index, - struct phy *phy) +int generic_phy_get_by_node(ofnode node, int index, struct phy *phy) { struct ofnode_phandle_args args; struct phy_ops *ops; struct udevice *phydev; int i, ret; - debug("%s(dev=%p, index=%d, phy=%p)\n", __func__, dev, index, phy); + debug("%s(node=%s, index=%d, phy=%p)\n", + __func__, ofnode_get_name(node), index, phy); assert(phy); phy->dev = NULL; - ret = dev_read_phandle_with_args(dev, "phys", "#phy-cells", 0, index, - &args); + ret = ofnode_parse_phandle_with_args(node, "phys", "#phy-cells", 0, + index, &args); if (ret) { debug("%s: dev_read_phandle_with_args failed: err=%d\n", __func__, ret); @@ -90,6 +90,12 @@ err: return ret; } +int generic_phy_get_by_index(struct udevice *dev, int index, + struct phy *phy) +{ + return generic_phy_get_by_node(dev_ofnode(dev), index, phy); +} + int generic_phy_get_by_name(struct udevice *dev, const char *phy_name, struct phy *phy) { -- cgit v1.3.1 From 838c0af9d25daa6f783acf0091deca0512baf0df Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 30 Mar 2020 11:27:24 +0200 Subject: phy: meson-gxl-usb: add set_mode call to force switch to peripheral mode Add set_mode function in the Amlogic GXL PHYs that will be called by the arch code to switch PHYs from/to gadget mode. Signed-off-by: Neil Armstrong --- arch/arm/include/asm/arch-meson/usb-gx.h | 16 ++++++++++++ drivers/phy/meson-gxl-usb2.c | 30 +++++++++++++++++----- drivers/phy/meson-gxl-usb3.c | 44 +++++++++++++++++++++++--------- 3 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 arch/arm/include/asm/arch-meson/usb-gx.h (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-meson/usb-gx.h b/arch/arm/include/asm/arch-meson/usb-gx.h new file mode 100644 index 00000000000..aeb8e0c6739 --- /dev/null +++ b/arch/arm/include/asm/arch-meson/usb-gx.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 BayLibre SAS + * Author: Neil Armstrong + */ +#ifndef _ARCH_MESON_USB_GX_H_ +#define _ARCH_MESON_USB_GX_H_ + +#include +#include + +/* TOFIX add set_mode to struct phy_ops */ +void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode); +void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode); + +#endif diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c index c98d12b627d..b4f4c3c76b9 100644 --- a/drivers/phy/meson-gxl-usb2.c +++ b/drivers/phy/meson-gxl-usb2.c @@ -17,6 +17,9 @@ #include #include #include +#include + +#include #include #include @@ -121,15 +124,30 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv) udelay(RESET_COMPLETE_TIME); } -static void -phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv) +void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode) { + struct udevice *dev = phy->dev; + struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev); uint val; regmap_read(priv->regmap, U2P_R0, &val); - val |= U2P_R0_DM_PULLDOWN; - val |= U2P_R0_DP_PULLDOWN; - val &= ~U2P_R0_ID_PULLUP; + + switch (mode) { + case USB_DR_MODE_UNKNOWN: + case USB_DR_MODE_HOST: + case USB_DR_MODE_OTG: + val |= U2P_R0_DM_PULLDOWN; + val |= U2P_R0_DP_PULLDOWN; + val &= ~U2P_R0_ID_PULLUP; + break; + + case USB_DR_MODE_PERIPHERAL: + val &= ~U2P_R0_DM_PULLDOWN; + val &= ~U2P_R0_DP_PULLDOWN; + val |= U2P_R0_ID_PULLUP; + break; + } + regmap_write(priv->regmap, U2P_R0, val); phy_meson_gxl_usb2_reset(priv); @@ -146,7 +164,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy) val &= ~U2P_R0_POWER_ON_RESET; regmap_write(priv->regmap, U2P_R0, val); - phy_meson_gxl_usb2_set_host_mode(priv); + phy_meson_gxl_usb2_set_mode(phy, USB_DR_MODE_HOST); #if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->phy_supply) { diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c index c2a8593b39f..9de55bb5df0 100644 --- a/drivers/phy/meson-gxl-usb3.c +++ b/drivers/phy/meson-gxl-usb3.c @@ -16,6 +16,9 @@ #include #include #include +#include + +#include #include #include @@ -93,20 +96,35 @@ struct phy_meson_gxl_usb3_priv { #endif }; -static int -phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv) +void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode) { + struct udevice *dev = phy->dev; + struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev); uint val; - regmap_read(priv->regmap, USB_R0, &val); - val &= ~USB_R0_U2D_ACT; - regmap_write(priv->regmap, USB_R0, val); - - regmap_read(priv->regmap, USB_R4, &val); - val &= ~USB_R4_P21_SLEEP_M0; - regmap_write(priv->regmap, USB_R4, val); - - return 0; + switch (mode) { + case USB_DR_MODE_UNKNOWN: + case USB_DR_MODE_HOST: + case USB_DR_MODE_OTG: + regmap_read(priv->regmap, USB_R0, &val); + val &= ~USB_R0_U2D_ACT; + regmap_write(priv->regmap, USB_R0, val); + + regmap_read(priv->regmap, USB_R4, &val); + val &= ~USB_R4_P21_SLEEP_M0; + regmap_write(priv->regmap, USB_R4, val); + break; + + case USB_DR_MODE_PERIPHERAL: + regmap_read(priv->regmap, USB_R0, &val); + val |= USB_R0_U2D_ACT; + regmap_write(priv->regmap, USB_R0, val); + + regmap_read(priv->regmap, USB_R4, &val); + val |= USB_R4_P21_SLEEP_M0; + regmap_write(priv->regmap, USB_R4, val); + break; + } } static int phy_meson_gxl_usb3_power_on(struct phy *phy) @@ -122,7 +140,9 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy) val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff); regmap_write(priv->regmap, USB_R5, val); - return phy_meson_gxl_usb3_set_host_mode(priv); + phy_meson_gxl_usb3_set_mode(phy, USB_DR_MODE_HOST); + + return 0; } static int phy_meson_gxl_usb3_power_off(struct phy *phy) -- cgit v1.3.1