2023-05-11 21:21:49

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v4 0/3] arm64: meson: support Amlogic A1 USB OTG controller

This patch series introduces full support for the Amlogic A1 USB controller
in OTG mode (peripheral and host modes switching).

Previously, Amlogic's patch series [1] was applied to the upstream tree,
but it only had USB host mode support.
Furthermore, the device tree patchset [2] wasn't merged due to a missing
clk driver.
Patchset [2] has been completely reworked:
- changed register base offsets to proper values
- introduced dwc2 in peripheral mode
- OTG mode support
- the SoB of Amlogic authors still remain

Testing:
- USB OTG role switching between gadget and host - OK
- Peripheral mode - OK (tested with adb shell/push/pop)
- Host mode - OK (tested only USB enumeration and detection)

Changes v4 since v3 at [5]:
- remove the dtsi patchset from series because it is dependent on the
A1 clock bindings, which are not resolved yet; this is due to the
fact that the A1 clock drivers are currently under review
- remove the patchset for phy as it has already been applied by Vinod
to phy/next at [6]

Changes v3 since v2 at [4]:
- if reset_control_reset() fails during phy_exit() callback
execution, do not disable clkin, instead, return an error
immediately
- provide proper 'phy-names' for the dwc2 device tree node as
'usb2-phy' instead of 'usb2_phy' (replace underscore with dash)

Changes v2 since v1 at [3]:
- as Martin suggested in v1, this commit completely removes
the 'otg_switch_supported' parameter from dwc3_meson_g12a_drvdata;
this parameter is no longer necessary as all IP versions now
support OTG switching
- this commit moves the USB PHY clkin enable/disable calls to
the PHY init/exit routines

Links:
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
[3] https://lore.kernel.org/all/[email protected]/
[4] https://lore.kernel.org/all/[email protected]/
[5] https://lore.kernel.org/all/[email protected]/
[6] https://lore.kernel.org/all/ZFjAmCcc%2F35MhcuI@matsya/

Dmitry Rokosov (3):
usb: dwc2: support dwc2 IP for Amlogic A1 SoC family
dt-bindings: usb: dwc2: add support for Amlogic A1 SoC USB peripheral
usb: dwc3-meson-g12a: support OTG switch for all IP versions

.../devicetree/bindings/usb/dwc2.yaml | 1 +
drivers/usb/dwc2/params.c | 21 +++++++++++++++++++
drivers/usb/dwc3/dwc3-meson-g12a.c | 16 +++-----------
3 files changed, 25 insertions(+), 13 deletions(-)

--
2.36.0



2023-05-11 21:22:06

by Dmitry Rokosov

[permalink] [raw]
Subject: [PATCH v4 3/3] usb: dwc3-meson-g12a: support OTG switch for all IP versions

From now, the Amlogic A1 USB controller is capable of switching between
host and gadget modes based on the status of the OTG_ID signal or via
manual USB role change.
Previously, only the Amlogic A1 IP version did not use OTG support for
host only mode, but this is no longer applicable.
Therefore, the 'otg_switch_supported' option can now be removed as
it is no longer required.

Signed-off-by: Dmitry Rokosov <[email protected]>
Reviewed-by: Neil Armstrong <[email protected]>
Reviewed-by: Martin Blumenstingl <[email protected]>
---
drivers/usb/dwc3/dwc3-meson-g12a.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index b282ad0e69c6..a13afdb219e8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -140,7 +140,6 @@ static const char * const meson_a1_phy_names[] = {
struct dwc3_meson_g12a;

struct dwc3_meson_g12a_drvdata {
- bool otg_switch_supported;
bool otg_phy_host_port_disable;
struct clk_bulk_data *clks;
int num_clks;
@@ -189,7 +188,6 @@ static int dwc3_meson_gxl_usb_post_init(struct dwc3_meson_g12a *priv);
*/

static const struct dwc3_meson_g12a_drvdata gxl_drvdata = {
- .otg_switch_supported = true,
.otg_phy_host_port_disable = true,
.clks = meson_gxl_clocks,
.num_clks = ARRAY_SIZE(meson_g12a_clocks),
@@ -203,7 +201,6 @@ static const struct dwc3_meson_g12a_drvdata gxl_drvdata = {
};

static const struct dwc3_meson_g12a_drvdata gxm_drvdata = {
- .otg_switch_supported = true,
.otg_phy_host_port_disable = true,
.clks = meson_gxl_clocks,
.num_clks = ARRAY_SIZE(meson_g12a_clocks),
@@ -217,7 +214,6 @@ static const struct dwc3_meson_g12a_drvdata gxm_drvdata = {
};

static const struct dwc3_meson_g12a_drvdata axg_drvdata = {
- .otg_switch_supported = true,
.clks = meson_gxl_clocks,
.num_clks = ARRAY_SIZE(meson_gxl_clocks),
.phy_names = meson_a1_phy_names,
@@ -230,7 +226,6 @@ static const struct dwc3_meson_g12a_drvdata axg_drvdata = {
};

static const struct dwc3_meson_g12a_drvdata g12a_drvdata = {
- .otg_switch_supported = true,
.clks = meson_g12a_clocks,
.num_clks = ARRAY_SIZE(meson_g12a_clocks),
.phy_names = meson_g12a_phy_names,
@@ -242,7 +237,6 @@ static const struct dwc3_meson_g12a_drvdata g12a_drvdata = {
};

static const struct dwc3_meson_g12a_drvdata a1_drvdata = {
- .otg_switch_supported = false,
.clks = meson_a1_clocks,
.num_clks = ARRAY_SIZE(meson_a1_clocks),
.phy_names = meson_a1_phy_names,
@@ -307,7 +301,7 @@ static int dwc3_meson_g12a_usb2_init_phy(struct dwc3_meson_g12a *priv, int i,
U2P_R0_POWER_ON_RESET,
U2P_R0_POWER_ON_RESET);

- if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
+ if (i == USB2_OTG_PHY) {
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
@@ -490,7 +484,7 @@ static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
{
int ret;

- if (!priv->drvdata->otg_switch_supported || !priv->phys[USB2_OTG_PHY])
+ if (!priv->phys[USB2_OTG_PHY])
return -EINVAL;

if (mode == PHY_MODE_USB_HOST)
@@ -589,9 +583,6 @@ static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
int ret, irq;
struct device *dev = &pdev->dev;

- if (!priv->drvdata->otg_switch_supported)
- return 0;
-
if (priv->otg_mode == USB_DR_MODE_OTG) {
/* Ack irq before registering */
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
@@ -841,8 +832,7 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int i;

- if (priv->drvdata->otg_switch_supported)
- usb_role_switch_unregister(priv->role_switch);
+ usb_role_switch_unregister(priv->role_switch);

of_platform_depopulate(dev);

--
2.36.0