phy: sun4i-usb: Rework HCI PHY (aka "pmu_unk1") handling
authorAndre Przywara <andre.przywara@arm.com>
Fri, 15 Jul 2022 04:09:21 +0000 (23:09 -0500)
committerAndre Przywara <andre.przywara@arm.com>
Mon, 18 Jul 2022 22:48:30 +0000 (23:48 +0100)
As Icenowy pointed out, newer manuals (starting with H6) actually
document the register block at offset 0x800 as "HCI controller and PHY
interface", also describe the bits in our "PMU_UNK1" register.
Let's put proper names to those "unknown" variables and symbols.

While we are at it, generalise the existing code by allowing a bitmap
of bits to clear and set, to cover newer SoCs: The A100 and H616 use a
different bit for the SIDDQ control.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/phy/allwinner/phy-sun4i-usb.c

index 6a965e704d433f7c57a0962d7728ff7fb4871b36..73e660edc37d48f20ded7778c702f12509f573ba 100644 (file)
@@ -32,7 +32,8 @@
 #define REG_PHYTUNE                    0x0c
 #define REG_PHYCTL_A33                 0x10
 #define REG_PHY_OTGCTL                 0x20
-#define REG_PMU_UNK1                   0x10
+
+#define REG_HCI_PHY_CTL                        0x10
 
 /* Common Control Bits for Both PHYs */
 #define PHY_PLL_BW                     0x03
@@ -63,6 +64,7 @@
 /* A83T specific control bits for PHY0 */
 #define PHY_CTL_VBUSVLDEXT             BIT(5)
 #define PHY_CTL_SIDDQ                  BIT(3)
+#define PHY_CTL_H3_SIDDQ               BIT(1)
 
 /* A83T specific control bits for PHY2 HSIC */
 #define SUNXI_EHCI_HS_FORCE            BIT(20)
@@ -87,9 +89,9 @@ struct sun4i_usb_phy_cfg {
        int num_phys;
        enum sun4i_usb_phy_type type;
        u32 disc_thresh;
+       u32 hci_phy_ctl_clear;
        u8 phyctl_offset;
        bool dedicated_clocks;
-       bool enable_pmu_unk1;
        bool phy0_dual_route;
        int missing_phys;
 };
@@ -275,6 +277,12 @@ static int sun4i_usb_phy_init(struct phy *phy)
                return ret;
        }
 
+       if (usb_phy->pmu && data->cfg->hci_phy_ctl_clear) {
+               val = readl(usb_phy->pmu + REG_HCI_PHY_CTL);
+               val &= ~data->cfg->hci_phy_ctl_clear;
+               writel(val, usb_phy->pmu + REG_HCI_PHY_CTL);
+       }
+
        if (data->cfg->type == sun8i_a83t_phy ||
            data->cfg->type == sun50i_h6_phy) {
                if (phy->id == 0) {
@@ -284,11 +292,6 @@ static int sun4i_usb_phy_init(struct phy *phy)
                        writel(val, data->base + data->cfg->phyctl_offset);
                }
        } else {
-               if (usb_phy->pmu && data->cfg->enable_pmu_unk1) {
-                       val = readl(usb_phy->pmu + REG_PMU_UNK1);
-                       writel(val & ~2, usb_phy->pmu + REG_PMU_UNK1);
-               }
-
                if (usb_phy->id == 0)
                        sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN,
                                            PHY_RES45_CAL_DATA,
@@ -528,7 +531,6 @@ static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A10,
        .dedicated_clocks = false,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
@@ -537,7 +539,6 @@ static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
        .disc_thresh = 2,
        .phyctl_offset = REG_PHYCTL_A10,
        .dedicated_clocks = false,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
@@ -546,7 +547,6 @@ static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A10,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
@@ -555,7 +555,6 @@ static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
        .disc_thresh = 2,
        .phyctl_offset = REG_PHYCTL_A10,
        .dedicated_clocks = false,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
@@ -564,7 +563,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A10,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
@@ -573,7 +571,6 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = false,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_a83t_cfg = {
@@ -589,7 +586,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = true,
+       .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
        .phy0_dual_route = true,
 };
 
@@ -599,7 +596,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = true,
+       .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
        .phy0_dual_route = true,
 };
 
@@ -609,7 +606,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = true,
+       .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
        .phy0_dual_route = true,
 };
 
@@ -619,7 +616,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = true,
+       .hci_phy_ctl_clear = PHY_CTL_H3_SIDDQ,
        .phy0_dual_route = true,
 };
 
@@ -629,7 +626,6 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
        .disc_thresh = 3,
        .phyctl_offset = REG_PHYCTL_A33,
        .dedicated_clocks = true,
-       .enable_pmu_unk1 = true,
        .phy0_dual_route = true,
        .missing_phys = BIT(1) | BIT(2),
 };