[PATCH 0/4] phy: sun4i-usb: Allwinner D1 Support

This series updates the USB PHY driver to support the Allwinner D1, which is a new RISC-V SoC. First it cleans up a couple of things that tie the driver to the existing ARM port, and then it adds the new PHY variant to the driver. Patches 3-4 are effectively the same as changes made to the Linux driver.
After this series, the driver still uses the VBUS and ID pin options from arch/arm/mach-sunxi/Kconfig. Those options will be replaced by devicetree properties in a separate series.
Andre Przywara (1): phy: sun4i-usb: Rework HCI PHY (aka "pmu_unk1") handling
Samuel Holland (3): sunxi: Move INITIAL_USB_SCAN_DELAY to driver Kconfig phy: sun4i-usb: Drop use of arch-specific headers phy: sun4i-usb: Add D1 variant
arch/arm/mach-sunxi/Kconfig | 9 ------ drivers/phy/allwinner/Kconfig | 10 ++++++ drivers/phy/allwinner/phy-sun4i-usb.c | 44 +++++++++++++++------------ 3 files changed, 34 insertions(+), 29 deletions(-)

This option is used only by the phy-sun4i-usb driver, which does not inherently depend on the ARM architecture.
Signed-off-by: Samuel Holland samuel@sholland.org ---
arch/arm/mach-sunxi/Kconfig | 9 --------- drivers/phy/allwinner/Kconfig | 10 ++++++++++ 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 71a7f8dcee06..4a833d37a841 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -679,15 +679,6 @@ config MMC_SUNXI_SLOT_EXTRA slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable support for this.
-config INITIAL_USB_SCAN_DELAY - int "delay initial usb scan by x ms to allow builtin devices to init" - default 0 - ---help--- - Some boards have on board usb devices which need longer than the - USB spec's 1 second to connect from board powerup. Set this config - option to a non 0 value to add an extra delay before the first usb - bus scan. - config USB0_VBUS_PIN string "Vbus enable pin for usb0 (otg)" default "" diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig index d3ff82f73a00..f8f1e99c4f52 100644 --- a/drivers/phy/allwinner/Kconfig +++ b/drivers/phy/allwinner/Kconfig @@ -13,6 +13,16 @@ config PHY_SUN4I_USB This driver controls the entire USB PHY block, both the USB OTG parts, as well as the 2 regular USB 2 host PHYs.
+config INITIAL_USB_SCAN_DELAY + int "Delay initial USB scan by x ms to allow builtin devices to init" + depends on PHY_SUN4I_USB + default 0 + help + Some boards have on board usb devices which need longer than + the USB spec's 1 second to connect from board powerup. Set + this option to a nonzero value to add an extra delay before + the first USB bus scan. + config PHY_SUN50I_USB3 bool "Allwinner sun50i USB3 PHY driver" depends on ARCH_SUNXI

On Fri, Jul 15, 2022 at 9:39 AM Samuel Holland samuel@sholland.org wrote:
This option is used only by the phy-sun4i-usb driver, which does not inherently depend on the ARM architecture.
Signed-off-by: Samuel Holland samuel@sholland.org
Reviewed-by: Jagan Teki jagan@amarulasolutions.com

Since commit 089ffd0aedb7 ("phy: sun4i-usb: Use CLK and RESET support") neither of these headers is used. Dropping them allows the driver to be architecture-independent.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/phy/allwinner/phy-sun4i-usb.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index aef2cb8f6f82..6a965e704d43 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -20,8 +20,6 @@ #include <reset.h> #include <asm/gpio.h> #include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/cpu.h> #include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/delay.h>

On Fri, Jul 15, 2022 at 9:39 AM Samuel Holland samuel@sholland.org wrote:
Since commit 089ffd0aedb7 ("phy: sun4i-usb: Use CLK and RESET support") neither of these headers is used. Dropping them allows the driver to be architecture-independent.
Signed-off-by: Samuel Holland samuel@sholland.org
Reviewed-by: Jagan Teki jagan@amarulasolutions.com

From: Andre Przywara andre.przywara@arm.com
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 ---
drivers/phy/allwinner/phy-sun4i-usb.c | 32 ++++++++++++--------------- 1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 6a965e704d43..73e660edc37d 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -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), };

On Fri, Jul 15, 2022 at 9:39 AM Samuel Holland samuel@sholland.org wrote:
From: Andre Przywara andre.przywara@arm.com
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

D1 has a register layout like A100 and H616, with the moved SIDDQ bit. Unlike H616 it does not have any dependencies between PHY instances.
Signed-off-by: Samuel Holland samuel@sholland.org ---
drivers/phy/allwinner/phy-sun4i-usb.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 73e660edc37d..2e969ab91e35 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -610,6 +610,15 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = { .phy0_dual_route = true, };
+static const struct sun4i_usb_phy_cfg sun20i_d1_cfg = { + .num_phys = 2, + .type = sun50i_h6_phy, + .phyctl_offset = REG_PHYCTL_A33, + .dedicated_clocks = true, + .hci_phy_ctl_clear = PHY_CTL_SIDDQ, + .phy0_dual_route = true, +}; + static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { .num_phys = 2, .type = sun50i_a64_phy, @@ -641,6 +650,7 @@ static const struct udevice_id sun4i_usb_phy_ids[] = { { .compatible = "allwinner,sun8i-h3-usb-phy", .data = (ulong)&sun8i_h3_cfg }, { .compatible = "allwinner,sun8i-r40-usb-phy", .data = (ulong)&sun8i_r40_cfg }, { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = (ulong)&sun8i_v3s_cfg }, + { .compatible = "allwinner,sun20i-d1-usb-phy", .data = (ulong)&sun20i_d1_cfg }, { .compatible = "allwinner,sun50i-a64-usb-phy", .data = (ulong)&sun50i_a64_cfg}, { .compatible = "allwinner,sun50i-h6-usb-phy", .data = (ulong)&sun50i_h6_cfg}, { }

On Fri, Jul 15, 2022 at 9:39 AM Samuel Holland samuel@sholland.org wrote:
D1 has a register layout like A100 and H616, with the moved SIDDQ bit. Unlike H616 it does not have any dependencies between PHY instances.
Signed-off-by: Samuel Holland samuel@sholland.org
Reviewed-by: Jagan Teki jagan@amarulasolutions.com
participants (2)
-
Jagan Teki
-
Samuel Holland