@@ -43,7 +43,7 @@
#define REG_PHYCTL_A33 0x10
#define REG_PHY_OTGCTL 0x20
-#define REG_PMU_UNK1 0x10
+#define REG_HCI_PHY_CTL 0x10
#define PHYCTL_DATA BIT(7)
@@ -82,6 +82,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)
@@ -115,9 +116,9 @@ struct sun4i_usb_phy_cfg {
int hsic_index;
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;
};
@@ -288,6 +289,12 @@ static int sun4i_usb_phy_init(struct phy *_phy)
return ret;
}
+ if (phy->pmu && data->cfg->hci_phy_ctl_clear) {
+ val = readl(phy->pmu + REG_HCI_PHY_CTL);
+ val &= ~data->cfg->hci_phy_ctl_clear;
+ writel(val, phy->pmu + REG_HCI_PHY_CTL);
+ }
+
if (data->cfg->type == sun8i_a83t_phy ||
data->cfg->type == sun50i_h6_phy) {
if (phy->index == 0) {
@@ -297,11 +304,6 @@ static int sun4i_usb_phy_init(struct phy *_phy)
writel(val, data->base + data->cfg->phyctl_offset);
}
} else {
- if (phy->pmu && data->cfg->enable_pmu_unk1) {
- val = readl(phy->pmu + REG_PMU_UNK1);
- writel(val & ~2, phy->pmu + REG_PMU_UNK1);
- }
-
/* Enable USB 45 Ohm resistor calibration */
if (phy->index == 0)
sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
@@ -863,7 +865,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 = {
@@ -872,7 +873,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 = {
@@ -881,7 +881,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 = {
@@ -890,7 +889,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 = {
@@ -899,7 +897,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 = {
@@ -908,7 +905,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 = {
@@ -925,7 +921,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,
};
@@ -935,7 +931,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,
};
@@ -945,7 +941,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,
};
@@ -955,7 +951,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,
};
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> --- drivers/phy/allwinner/phy-sun4i-usb.c | 30 ++++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-)