usb: dwc3: meson-g12a: specify phy names in soc data
authorNeil Armstrong <narmstrong@baylibre.com>
Thu, 26 Mar 2020 13:44:54 +0000 (14:44 +0100)
committerFelipe Balbi <balbi@kernel.org>
Tue, 5 May 2020 08:00:12 +0000 (11:00 +0300)
To handle the variable USB2 PHY counts on GXL and GXM SoCs, add the
possible PHY names for each SoC in the compatible match data.

Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Hanjie Lin <hanjie.lin@amlogic.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/dwc3/dwc3-meson-g12a.c

index b81d085..f49c9e2 100644 (file)
        #define USB_R5_ID_DIG_TH_MASK                           GENMASK(15, 8)
        #define USB_R5_ID_DIG_CNT_MASK                          GENMASK(23, 16)
 
-enum {
-       USB2_HOST_PHY = 0,
-       USB2_OTG_PHY,
-       USB3_HOST_PHY,
-       PHY_COUNT,
-};
-
-static const char *phy_names[PHY_COUNT] = {
-       "usb2-phy0", "usb2-phy1", "usb3-phy0",
-};
+#define PHY_COUNT                                              3
+#define USB2_OTG_PHY                                           1
 
 static struct clk_bulk_data meson_g12a_clocks[] = {
        { .id = NULL },
@@ -117,22 +109,44 @@ static struct clk_bulk_data meson_a1_clocks[] = {
        { .id = "xtal_usb_ctrl" },
 };
 
+static const char *meson_g12a_phy_names[] = {
+       "usb2-phy0", "usb2-phy1", "usb3-phy0",
+};
+
+/*
+ * Amlogic A1 has a single physical PHY, in slot 1, but still has the
+ * two U2 PHY controls register blocks like G12A.
+ * Handling the first PHY on slot 1 would need a large amount of code
+ * changes, and the current management is generic enough to handle it
+ * correctly when only the "usb2-phy1" phy is specified on-par with the
+ * DT bindings.
+ */
+static const char *meson_a1_phy_names[] = {
+       "usb2-phy0", "usb2-phy1"
+};
+
 struct dwc3_meson_g12a_drvdata {
        bool otg_switch_supported;
        struct clk_bulk_data *clks;
        int num_clks;
+       const char **phy_names;
+       int num_phys;
 };
 
 static 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,
+       .num_phys = ARRAY_SIZE(meson_g12a_phy_names),
 };
 
 static 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,
+       .num_phys = ARRAY_SIZE(meson_a1_phy_names),
 };
 
 struct dwc3_meson_g12a {
@@ -171,10 +185,13 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
        else
                priv->otg_phy_mode = PHY_MODE_USB_HOST;
 
-       for (i = 0 ; i < USB3_HOST_PHY ; ++i) {
+       for (i = 0; i < priv->drvdata->num_phys; ++i) {
                if (!priv->phys[i])
                        continue;
 
+               if (!strstr(priv->drvdata->phy_names[i], "usb2"))
+                       continue;
+
                regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
                                   U2P_R0_POWER_ON_RESET,
                                   U2P_R0_POWER_ON_RESET);
@@ -284,17 +301,19 @@ static const struct regmap_config phy_meson_g12a_usb3_regmap_conf = {
 
 static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
 {
+       const char *phy_name;
        int i;
 
-       for (i = 0 ; i < PHY_COUNT ; ++i) {
-               priv->phys[i] = devm_phy_optional_get(priv->dev, phy_names[i]);
+       for (i = 0 ; i < priv->drvdata->num_phys ; ++i) {
+               phy_name = priv->drvdata->phy_names[i];
+               priv->phys[i] = devm_phy_optional_get(priv->dev, phy_name);
                if (!priv->phys[i])
                        continue;
 
                if (IS_ERR(priv->phys[i]))
                        return PTR_ERR(priv->phys[i]);
 
-               if (i == USB3_HOST_PHY)
+               if (strstr(phy_name, "usb3"))
                        priv->usb3_ports++;
                else
                        priv->usb2_ports++;