[PATCH v2 0/7] Add Starfive JH7110 Cadence USB driver

Add Starfive JH7110 Cadence USB driver and related PHY driver. So the codes can be used in visionfive2 and star64 7110 board.
The driver is almost the same with kernel driver.
Test with Star64 JH7110 board USB 3.0 + USB 2.0 host. The code can work.
- Star64 using USB 3.0 and USB 2.0 host must add below board dts setting.
1. usb pin setting usb_pins: usb0-0 { driver-vbus-pin { pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS, GPOEN_ENABLE, GPI_NONE)>; bias-disable; input-disable; input-schmitt-disable; slew-rate = <0>; }; };
2. related dts node setting. &pcie0 { status = "disabled"; };
&pciephy0 { starfive,sys-syscon = <&sys_syscon 0x18>; starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>; status = "okay"; };
&usb0 { pinctrl-names = "default"; pinctrl-0 = <&usb_pins>; status = "okay"; };
&usb_cdns3 { phys = <&usbphy0>, <&pciephy0>; phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; dr_mode = "host"; status = "okay"; };
- previous version v1: https://patchwork.ozlabs.org/project/uboot/cover/20240504150358.19600-1-mind...
- patch description.
patch1: Add set phy mode function in cdns3 core driver which is used by Starfive JH7110. patch2-3: USB and PCIe 2.0 (usb 3.0) PHY drivier patch4: Cadence USB wrapper driver. patch5: Add JH7110 USB default overcurrent pin. patch6-8 dts, config and maintainers update.
- change: v2: - patch 1 Move the added code to cdns3_core_init_role(). Must set PHY mode before calling cdns3 role start function. - patch 1-4 correct the code format.(follow Marek's comments.) - patch 2 Add set 125M clock in PHY init function. - Add new patch5.
Minda Chen (8): usb: cdns3: Set USB PHY mode in cdns3_core_init_role() phy: starfive: Add Starfive JH7110 USB 2.0 PHY driver phy: starfive: Add Starfive JH7110 PCIe 2.0 PHY driver usb: cdns: starfive: Add cdns USB driver pinctrl: starfive: Setup USB default disable overcurrent pin configs: starfive: Add visionfive2 cadence USB configuration dts: starfive: Add JH7110 Cadence USB dts node MAINTAINERS: Update Starfive visionfive2 maintain files.
.../dts/jh7110-starfive-visionfive-2.dtsi | 5 + arch/riscv/dts/jh7110.dtsi | 52 +++++ board/starfive/visionfive2/MAINTAINERS | 2 + configs/starfive_visionfive2_defconfig | 9 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 21 ++ drivers/phy/starfive/Makefile | 7 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 ++++++++++++++++++ drivers/phy/starfive/phy-jh7110-usb2.c | 135 ++++++++++++ drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +- drivers/usb/cdns3/Kconfig | 7 + drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 ++++++++++++++++ drivers/usb/cdns3/core.c | 25 +++ 15 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
base-commit: 8937bb265a7f2251c1bd999784a4ef10e9c6080d

USB PHY maybe need to set PHY mode in different USB dr mode. So translate to generic PHY mode and call generic_phy_set_mode().
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- drivers/usb/cdns3/core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 12a741c6ea..1e863bed89 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -107,6 +107,7 @@ static int cdns3_core_init_role(struct cdns3 *cdns) { struct udevice *dev = cdns->dev; enum usb_dr_mode best_dr_mode; + int mode = PHY_MODE_INVALID; enum usb_dr_mode dr_mode; int ret = 0;
@@ -173,6 +174,30 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
cdns->dr_mode = dr_mode;
+ if (cdns->dr_mode == USB_DR_MODE_HOST) { + mode = PHY_MODE_USB_HOST; + } else if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) { + mode = PHY_MODE_USB_DEVICE; + } else if (cdns->dr_mode == USB_DR_MODE_OTG) { + mode = PHY_MODE_USB_OTG; + } else { + dev_err(dev, "Unknown dr mode %d\n", cdns->dr_mode); + ret = -EINVAL; + goto err; + } + + ret = generic_phy_set_mode(&cdns->usb2_phy, mode, 0); + if (ret) { + dev_err(dev, "Set usb 2.0 PHY mode failed %d\n", ret); + goto err; + } + + ret = generic_phy_set_mode(&cdns->usb3_phy, mode, 0); + if (ret) { + dev_err(dev, "Set usb 3.0 PHY mode failed %d\n", ret); + goto err; + } + ret = cdns3_drd_update_mode(cdns); if (ret) goto err;

Hi,
On 04/07/2024 08:50, Minda Chen wrote:
USB PHY maybe need to set PHY mode in different USB dr mode. So translate to generic PHY mode and call generic_phy_set_mode().
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/usb/cdns3/core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 12a741c6ea..1e863bed89 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -107,6 +107,7 @@ static int cdns3_core_init_role(struct cdns3 *cdns) { struct udevice *dev = cdns->dev; enum usb_dr_mode best_dr_mode;
- int mode = PHY_MODE_INVALID; enum usb_dr_mode dr_mode; int ret = 0;
@@ -173,6 +174,30 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
cdns->dr_mode = dr_mode;
- if (cdns->dr_mode == USB_DR_MODE_HOST) {
mode = PHY_MODE_USB_HOST;
- } else if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
mode = PHY_MODE_USB_DEVICE;
- } else if (cdns->dr_mode == USB_DR_MODE_OTG) {
mode = PHY_MODE_USB_OTG;
- } else {
dev_err(dev, "Unknown dr mode %d\n", cdns->dr_mode);
ret = -EINVAL;
goto err;
- }
- ret = generic_phy_set_mode(&cdns->usb2_phy, mode, 0);
- if (ret) {
dev_err(dev, "Set usb 2.0 PHY mode failed %d\n", ret);
goto err;
- }
- ret = generic_phy_set_mode(&cdns->usb3_phy, mode, 0);
- if (ret) {
dev_err(dev, "Set usb 3.0 PHY mode failed %d\n", ret);
goto err;
- }
Should we be doing the above inside cdns3_drd_update_mode() so that the PHY can be put in the correct state even during role switches?
ret = cdns3_drd_update_mode(cdns); if (ret) goto err;

Hi,
On 04/07/2024 08:50, Minda Chen wrote:
USB PHY maybe need to set PHY mode in different USB dr mode. So translate to generic PHY mode and call generic_phy_set_mode().
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/usb/cdns3/core.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 12a741c6ea..1e863bed89 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -107,6 +107,7 @@ static int cdns3_core_init_role(struct cdns3 *cdns) { struct udevice *dev = cdns->dev; enum usb_dr_mode best_dr_mode;
- int mode = PHY_MODE_INVALID; enum usb_dr_mode dr_mode; int ret = 0;
@@ -173,6 +174,30 @@ static int cdns3_core_init_role(struct cdns3 *cdns)
cdns->dr_mode = dr_mode;
- if (cdns->dr_mode == USB_DR_MODE_HOST) {
mode = PHY_MODE_USB_HOST;
- } else if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
mode = PHY_MODE_USB_DEVICE;
- } else if (cdns->dr_mode == USB_DR_MODE_OTG) {
mode = PHY_MODE_USB_OTG;
- } else {
dev_err(dev, "Unknown dr mode %d\n", cdns->dr_mode);
ret = -EINVAL;
goto err;
- }
- ret = generic_phy_set_mode(&cdns->usb2_phy, mode, 0);
- if (ret) {
dev_err(dev, "Set usb 2.0 PHY mode failed %d\n", ret);
goto err;
- }
- ret = generic_phy_set_mode(&cdns->usb3_phy, mode, 0);
- if (ret) {
dev_err(dev, "Set usb 3.0 PHY mode failed %d\n", ret);
goto err;
- }
Should we be doing the above inside cdns3_drd_update_mode() so that the PHY can be put in the correct state even during role switches?
OK, Thanks.
ret = cdns3_drd_update_mode(cdns); if (ret) goto err;
-- cheers, -roger

Add Starfive JH7110 USB 2.0 PHY driver, which is generic PHY driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 14 +++ drivers/phy/starfive/Makefile | 6 ++ drivers/phy/starfive/phy-jh7110-usb2.c | 135 +++++++++++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8f767877e7..0c4d63a01f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -307,5 +307,6 @@ source "drivers/phy/cadence/Kconfig" source "drivers/phy/ti/Kconfig" source "drivers/phy/qcom/Kconfig" source "drivers/phy/renesas/Kconfig" +source "drivers/phy/starfive/Kconfig"
endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 7a2b764492..6ac867350c 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -44,3 +44,4 @@ obj-y += cadence/ obj-y += ti/ obj-y += qcom/ obj-y += renesas/ +obj-y += starfive/ diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig new file mode 100644 index 0000000000..11a819f8b2 --- /dev/null +++ b/drivers/phy/starfive/Kconfig @@ -0,0 +1,14 @@ +# +# Phy drivers for Starfive platforms +# + +menu "Starfive PHY driver" + +config PHY_STARFIVE_JH7110_USB2 + bool "Starfive JH7110 USB 2.0 PHY driver" + select PHY + help + Enable this to support the Starfive JH7110 USB 2.0 PHY. + Generic PHY driver JH7110 USB 2.0. + +endmenu diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile new file mode 100644 index 0000000000..a405a75e34 --- /dev/null +++ b/drivers/phy/starfive/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2023 Starfive +# + +obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-usb2.c b/drivers/phy/starfive/phy-jh7110-usb2.c new file mode 100644 index 0000000000..d48c9f8a74 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-usb2.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * StarFive JH7110 USB 2.0 PHY driver + * + * Copyright (C) 2024 StarFive Technology Co., Ltd. + * Author: Minda Chen minda.chen@starfivetech.com + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <generic-phy.h> +#include <regmap.h> +#include <soc.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/err.h> + +#define USB_LS_KEEPALIVE_OFF 0x4 +#define USB_LS_KEEPALIVE_ENABLE BIT(4) +#define USB_PHY_CLK_RATE 125000000 + +struct jh7110_usb2_phy { + struct phy *phy; + void __iomem *regs; + struct clk *usb_125m_clk; + struct clk *app_125m; + enum phy_mode mode; +}; + +static void usb2_set_ls_keepalive(struct jh7110_usb2_phy *phy, bool set) +{ + /* Host mode enable the LS speed keep-alive signal */ + if (set) + clrsetbits_le32(phy->regs + USB_LS_KEEPALIVE_OFF, + USB_LS_KEEPALIVE_ENABLE, + USB_LS_KEEPALIVE_ENABLE); + else + clrsetbits_le32(phy->regs + USB_LS_KEEPALIVE_OFF, + USB_LS_KEEPALIVE_ENABLE, 0); +} + +static int usb2_phy_set_mode(struct phy *_phy, + enum phy_mode mode, int submode) +{ + struct udevice *dev = _phy->dev; + struct jh7110_usb2_phy *phy = dev_get_priv(dev); + + if (mode == phy->mode) + return 0; + + switch (mode) { + case PHY_MODE_USB_HOST: + case PHY_MODE_USB_DEVICE: + case PHY_MODE_USB_OTG: + dev_dbg(dev, "Changing phy to %d\n", mode); + phy->mode = mode; + usb2_set_ls_keepalive(phy, (mode != PHY_MODE_USB_DEVICE)); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int jh7110_usb2_phy_init(struct phy *_phy) +{ + struct udevice *dev = _phy->dev; + struct jh7110_usb2_phy *phy = dev_get_priv(dev); + int ret; + + ret = clk_set_rate(phy->usb_125m_clk, USB_PHY_CLK_RATE); + if (ret < 0) { + dev_err(dev, "Failed to set 125m clock\n"); + return ret; + } + + return clk_prepare_enable(phy->app_125m); +} + +static int jh7110_usb2_phy_exit(struct phy *_phy) +{ + struct udevice *dev = _phy->dev; + struct jh7110_usb2_phy *phy = dev_get_priv(dev); + + clk_disable_unprepare(phy->app_125m); + + return 0; +} + +struct phy_ops jh7110_usb2_phy_ops = { + .init = jh7110_usb2_phy_init, + .exit = jh7110_usb2_phy_exit, + .set_mode = usb2_phy_set_mode, +}; + +int jh7110_usb2_phy_probe(struct udevice *dev) +{ + struct jh7110_usb2_phy *phy = dev_get_priv(dev); + + phy->regs = dev_read_addr_ptr(dev); + if (!phy->regs) + return -EINVAL; + + phy->usb_125m_clk = devm_clk_get(dev, "125m"); + if (IS_ERR(phy->usb_125m_clk)) { + dev_err(dev, "Failed to get 125m clock\n"); + return PTR_ERR(phy->usb_125m_clk); + } + + phy->app_125m = devm_clk_get(dev, "app_125m"); + if (IS_ERR(phy->app_125m)) { + dev_err(dev, "Failed to get app 125m clock\n"); + return PTR_ERR(phy->app_125m); + } + + return 0; +} + +static const struct udevice_id jh7110_usb2_phy[] = { + { .compatible = "starfive,jh7110-usb-phy"}, + {}, +}; + +U_BOOT_DRIVER(jh7110_usb2_phy) = { + .name = "jh7110_usb2_phy", + .id = UCLASS_PHY, + .of_match = jh7110_usb2_phy, + .probe = jh7110_usb2_phy_probe, + .ops = &jh7110_usb2_phy_ops, + .priv_auto = sizeof(struct jh7110_usb2_phy), +};

On 04/07/2024 08:50, Minda Chen wrote:
Add Starfive JH7110 USB 2.0 PHY driver, which is generic PHY driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 14 +++ drivers/phy/starfive/Makefile | 6 ++ drivers/phy/starfive/phy-jh7110-usb2.c | 135 +++++++++++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 8f767877e7..0c4d63a01f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -307,5 +307,6 @@ source "drivers/phy/cadence/Kconfig" source "drivers/phy/ti/Kconfig" source "drivers/phy/qcom/Kconfig" source "drivers/phy/renesas/Kconfig" +source "drivers/phy/starfive/Kconfig"
endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 7a2b764492..6ac867350c 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -44,3 +44,4 @@ obj-y += cadence/ obj-y += ti/ obj-y += qcom/ obj-y += renesas/ +obj-y += starfive/ diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig new file mode 100644 index 0000000000..11a819f8b2 --- /dev/null +++ b/drivers/phy/starfive/Kconfig @@ -0,0 +1,14 @@ +# +# Phy drivers for Starfive platforms
PHY?
+#
+menu "Starfive PHY driver"
+config PHY_STARFIVE_JH7110_USB2
- bool "Starfive JH7110 USB 2.0 PHY driver"
- select PHY
- help
Enable this to support the Starfive JH7110 USB 2.0 PHY.
Generic PHY driver JH7110 USB 2.0.
+endmenu diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile new file mode 100644 index 0000000000..a405a75e34 --- /dev/null +++ b/drivers/phy/starfive/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2023 Starfive +#
+obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-usb2.c b/drivers/phy/starfive/phy-jh7110-usb2.c new file mode 100644 index 0000000000..d48c9f8a74 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-usb2.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- StarFive JH7110 USB 2.0 PHY driver
- Copyright (C) 2024 StarFive Technology Co., Ltd.
- Author: Minda Chen minda.chen@starfivetech.com
- */
+#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <generic-phy.h> +#include <regmap.h> +#include <soc.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/err.h>
+#define USB_LS_KEEPALIVE_OFF 0x4 +#define USB_LS_KEEPALIVE_ENABLE BIT(4) +#define USB_PHY_CLK_RATE 125000000
+struct jh7110_usb2_phy {
- struct phy *phy;
- void __iomem *regs;
- struct clk *usb_125m_clk;
- struct clk *app_125m;
- enum phy_mode mode;
+};
+static void usb2_set_ls_keepalive(struct jh7110_usb2_phy *phy, bool set) +{
- /* Host mode enable the LS speed keep-alive signal */
- if (set)
clrsetbits_le32(phy->regs + USB_LS_KEEPALIVE_OFF,
USB_LS_KEEPALIVE_ENABLE,
USB_LS_KEEPALIVE_ENABLE);
- else
clrsetbits_le32(phy->regs + USB_LS_KEEPALIVE_OFF,
USB_LS_KEEPALIVE_ENABLE, 0);
+}
+static int usb2_phy_set_mode(struct phy *_phy,
enum phy_mode mode, int submode)
+{
- struct udevice *dev = _phy->dev;
- struct jh7110_usb2_phy *phy = dev_get_priv(dev);
- if (mode == phy->mode)
return 0;
- switch (mode) {
- case PHY_MODE_USB_HOST:
- case PHY_MODE_USB_DEVICE:
- case PHY_MODE_USB_OTG:
dev_dbg(dev, "Changing phy to %d\n", mode);
phy->mode = mode;
usb2_set_ls_keepalive(phy, (mode != PHY_MODE_USB_DEVICE));
break;
- default:
return -EINVAL;
- }
- return 0;
+}
+static int jh7110_usb2_phy_init(struct phy *_phy) +{
- struct udevice *dev = _phy->dev;
- struct jh7110_usb2_phy *phy = dev_get_priv(dev);
- int ret;
- ret = clk_set_rate(phy->usb_125m_clk, USB_PHY_CLK_RATE);
- if (ret < 0) {
dev_err(dev, "Failed to set 125m clock\n");
return ret;
- }
- return clk_prepare_enable(phy->app_125m);
+}
+static int jh7110_usb2_phy_exit(struct phy *_phy) +{
- struct udevice *dev = _phy->dev;
- struct jh7110_usb2_phy *phy = dev_get_priv(dev);
- clk_disable_unprepare(phy->app_125m);
- return 0;
+}
+struct phy_ops jh7110_usb2_phy_ops = {
- .init = jh7110_usb2_phy_init,
- .exit = jh7110_usb2_phy_exit,
- .set_mode = usb2_phy_set_mode,
+};
+int jh7110_usb2_phy_probe(struct udevice *dev) +{
- struct jh7110_usb2_phy *phy = dev_get_priv(dev);
- phy->regs = dev_read_addr_ptr(dev);
- if (!phy->regs)
return -EINVAL;
- phy->usb_125m_clk = devm_clk_get(dev, "125m");
- if (IS_ERR(phy->usb_125m_clk)) {
dev_err(dev, "Failed to get 125m clock\n");
return PTR_ERR(phy->usb_125m_clk);
- }
- phy->app_125m = devm_clk_get(dev, "app_125m");
- if (IS_ERR(phy->app_125m)) {
dev_err(dev, "Failed to get app 125m clock\n");
return PTR_ERR(phy->app_125m);
- }
- return 0;
+}
+static const struct udevice_id jh7110_usb2_phy[] = {
- { .compatible = "starfive,jh7110-usb-phy"},
- {},
+};
+U_BOOT_DRIVER(jh7110_usb2_phy) = {
- .name = "jh7110_usb2_phy",
- .id = UCLASS_PHY,
- .of_match = jh7110_usb2_phy,
- .probe = jh7110_usb2_phy_probe,
- .ops = &jh7110_usb2_phy_ops,
- .priv_auto = sizeof(struct jh7110_usb2_phy),
how about space instead of tab?
+};
Reviewed-by: Roger Quadros rogerq@kernel.org

Add Starfive JH7110 PCIe 2.0 PHY driver, which is generic PHY driver and can be used as USB 3.0 driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- drivers/phy/starfive/Kconfig | 7 + drivers/phy/starfive/Makefile | 1 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 +++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig index 11a819f8b2..5d49684bc7 100644 --- a/drivers/phy/starfive/Kconfig +++ b/drivers/phy/starfive/Kconfig @@ -4,6 +4,13 @@
menu "Starfive PHY driver"
+config PHY_STARFIVE_JH7110_PCIE + bool "Starfive JH7110 PCIe 2.0 PHY driver" + select PHY + help + Enable this to support the Starfive JH7110 PCIE 2.0/USB 3.0 PHY. + Generic PHY driver JH7110 USB 3.0/ PCIe 2.0. + config PHY_STARFIVE_JH7110_USB2 bool "Starfive JH7110 USB 2.0 PHY driver" select PHY diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile index a405a75e34..82f25aa21b 100644 --- a/drivers/phy/starfive/Makefile +++ b/drivers/phy/starfive/Makefile @@ -3,4 +3,5 @@ # Copyright (C) 2023 Starfive #
+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c new file mode 100644 index 0000000000..57d5d8bf53 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-pcie.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * StarFive JH7110 PCIe 2.0 PHY driver + * + * Copyright (C) 2024 StarFive Technology Co., Ltd. + * Author: Minda Chen minda.chen@starfivetech.com + */ +#include <asm/io.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <generic-phy.h> +#include <regmap.h> +#include <soc.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/err.h> + +#define PCIE_KVCO_LEVEL_OFF 0x28 +#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c +#define PCIE_USB3_PHY_SS_MODE BIT(4) +#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80 +#define PHY_KVCO_FINE_TUNE_LEVEL 0x91 +#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc + +#define USB_PDRSTN_SPLIT BIT(17) + +#define PCIE_USB3_PHY_MODE BIT(20) +#define PCIE_PHY_MODE_MASK GENMASK(21, 20) +#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2) +#define PCIE_BUS_WIDTH BIT(3) +#define PCIE_USB3_RATE_MASK GENMASK(6, 5) +#define PCIE_USB3_RX_STANDBY_MASK BIT(7) +#define PCIE_USB3_PHY_ENABLE BIT(4) + +struct jh7110_pcie_phy { + struct phy *phy; + struct regmap *stg_syscon; + struct regmap *sys_syscon; + void __iomem *regs; + u32 sys_phy_connect; + u32 stg_pcie_mode; + u32 stg_pcie_usb; + enum phy_mode mode; +}; + +static int phy_pcie_mode_set(struct jh7110_pcie_phy *data, bool usb_mode) +{ + unsigned int phy_mode, width, usb3_phy, ss_mode; + + /* default is PCIe mode */ + if (!data->stg_syscon || !data->sys_syscon) { + if (usb_mode) { + dev_err(data->phy->dev, "doesn't support usb3 mode\n"); + return -EINVAL; + } + return 0; + } + + if (usb_mode) { + phy_mode = PCIE_USB3_PHY_MODE; + width = 0; + usb3_phy = PCIE_USB3_PHY_ENABLE; + ss_mode = PCIE_USB3_PHY_SS_MODE; + } else { + phy_mode = 0; + width = PCIE_BUS_WIDTH; + usb3_phy = 0; + ss_mode = 0; + } + + regmap_update_bits(data->stg_syscon, data->stg_pcie_mode, + PCIE_PHY_MODE_MASK, phy_mode); + regmap_update_bits(data->stg_syscon, data->stg_pcie_usb, + PCIE_USB3_BUS_WIDTH_MASK, width); + regmap_update_bits(data->stg_syscon, data->stg_pcie_usb, + PCIE_USB3_PHY_ENABLE, usb3_phy); + clrsetbits_le32(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF, + PCIE_USB3_PHY_SS_MODE, ss_mode); + + regmap_update_bits(data->sys_syscon, data->sys_phy_connect, + USB_PDRSTN_SPLIT, 0); + + return 0; +} + +static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy) +{ + /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */ + writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF); + writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF); +} + +static int jh7110_pcie_phy_set_mode(struct phy *_phy, + enum phy_mode mode, int submode) +{ + struct udevice *dev = _phy->dev; + struct jh7110_pcie_phy *phy = dev_get_priv(dev); + int ret; + + if (mode == phy->mode) + return 0; + + switch (mode) { + case PHY_MODE_USB_HOST: + case PHY_MODE_USB_DEVICE: + case PHY_MODE_USB_OTG: + ret = phy_pcie_mode_set(phy, 1); + if (ret) + return ret; + break; + case PHY_MODE_PCIE: + phy_pcie_mode_set(phy, 0); + break; + default: + return -EINVAL; + } + + dev_dbg(_phy->dev, "Changing phy mode to %d\n", mode); + phy->mode = mode; + + return 0; +} + +static const struct phy_ops jh7110_pcie_phy_ops = { + .set_mode = jh7110_pcie_phy_set_mode, +}; + +static int starfive_pcie_phy_get_syscon(struct udevice *dev) +{ + struct jh7110_pcie_phy *phy = dev_get_priv(dev); + struct ofnode_phandle_args sys_phandle, stg_phandle; + int ret; + + /* get corresponding syscon phandle */ + ret = dev_read_phandle_with_args(dev, "starfive,sys-syscon", NULL, 1, 0, + &sys_phandle); + + if (ret < 0) { + dev_err(dev, "Can't get sys cfg phandle: %d\n", ret); + return ret; + } + + ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 2, 0, + &stg_phandle); + + if (ret < 0) { + dev_err(dev, "Can't get stg cfg phandle: %d\n", ret); + return ret; + } + + phy->sys_syscon = syscon_node_to_regmap(sys_phandle.node); + if (!IS_ERR_OR_NULL(phy->sys_syscon)) { + /* get syscon register offset */ + phy->sys_phy_connect = sys_phandle.args[0]; + } else { + phy->sys_syscon = NULL; + } + + phy->stg_syscon = syscon_node_to_regmap(stg_phandle.node); + if (!IS_ERR_OR_NULL(phy->stg_syscon)) { + phy->stg_pcie_mode = stg_phandle.args[0]; + phy->stg_pcie_usb = stg_phandle.args[1]; + } else { + phy->stg_syscon = NULL; + } + + return 0; +} + +int jh7110_pcie_phy_probe(struct udevice *dev) +{ + struct jh7110_pcie_phy *phy = dev_get_priv(dev); + int rc; + + phy->regs = dev_read_addr_ptr(dev); + if (!phy->regs) + return -EINVAL; + + rc = starfive_pcie_phy_get_syscon(dev); + if (rc) + return rc; + + phy_kvco_gain_set(phy); + + return 0; +} + +static const struct udevice_id jh7110_pcie_phy[] = { + { .compatible = "starfive,jh7110-pcie-phy"}, + {}, +}; + +U_BOOT_DRIVER(jh7110_pcie_phy) = { + .name = "jh7110_pcie_phy", + .id = UCLASS_PHY, + .of_match = jh7110_pcie_phy, + .probe = jh7110_pcie_phy_probe, + .ops = &jh7110_pcie_phy_ops, + .priv_auto = sizeof(struct jh7110_pcie_phy), +}; +

On 04/07/2024 08:50, Minda Chen wrote:
Add Starfive JH7110 PCIe 2.0 PHY driver, which is generic PHY driver and can be used as USB 3.0 driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/phy/starfive/Kconfig | 7 + drivers/phy/starfive/Makefile | 1 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 +++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig index 11a819f8b2..5d49684bc7 100644 --- a/drivers/phy/starfive/Kconfig +++ b/drivers/phy/starfive/Kconfig @@ -4,6 +4,13 @@
menu "Starfive PHY driver"
+config PHY_STARFIVE_JH7110_PCIE
bool "Starfive JH7110 PCIe 2.0 PHY driver"
select PHY
help
Enable this to support the Starfive JH7110 PCIE 2.0/USB 3.0 PHY.
Generic PHY driver JH7110 USB 3.0/ PCIe 2.0.
Should be aligned to previous line.
config PHY_STARFIVE_JH7110_USB2 bool "Starfive JH7110 USB 2.0 PHY driver" select PHY diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile index a405a75e34..82f25aa21b 100644 --- a/drivers/phy/starfive/Makefile +++ b/drivers/phy/starfive/Makefile @@ -3,4 +3,5 @@ # Copyright (C) 2023 Starfive #
+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c new file mode 100644 index 0000000000..57d5d8bf53 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-pcie.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- StarFive JH7110 PCIe 2.0 PHY driver
- Copyright (C) 2024 StarFive Technology Co., Ltd.
- Author: Minda Chen minda.chen@starfivetech.com
- */
+#include <asm/io.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <generic-phy.h> +#include <regmap.h> +#include <soc.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/err.h>
+#define PCIE_KVCO_LEVEL_OFF 0x28 +#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c +#define PCIE_USB3_PHY_SS_MODE BIT(4)
extra tab?
+#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80 +#define PHY_KVCO_FINE_TUNE_LEVEL 0x91 +#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
+#define USB_PDRSTN_SPLIT BIT(17)
+#define PCIE_USB3_PHY_MODE BIT(20) +#define PCIE_PHY_MODE_MASK GENMASK(21, 20) +#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2) +#define PCIE_BUS_WIDTH BIT(3) +#define PCIE_USB3_RATE_MASK GENMASK(6, 5) +#define PCIE_USB3_RX_STANDBY_MASK BIT(7) +#define PCIE_USB3_PHY_ENABLE BIT(4)
Why not use define and use regmap_fields? You are already using regmap.
+struct jh7110_pcie_phy {
- struct phy *phy;
- struct regmap *stg_syscon;
- struct regmap *sys_syscon;
- void __iomem *regs;
- u32 sys_phy_connect;
- u32 stg_pcie_mode;
- u32 stg_pcie_usb;
- enum phy_mode mode;
+};
+static int phy_pcie_mode_set(struct jh7110_pcie_phy *data, bool usb_mode) +{
- unsigned int phy_mode, width, usb3_phy, ss_mode;
- /* default is PCIe mode */
- if (!data->stg_syscon || !data->sys_syscon) {
if (usb_mode) {
dev_err(data->phy->dev, "doesn't support usb3 mode\n");
return -EINVAL;
}
return 0;
- }
- if (usb_mode) {
phy_mode = PCIE_USB3_PHY_MODE;
width = 0;
usb3_phy = PCIE_USB3_PHY_ENABLE;
ss_mode = PCIE_USB3_PHY_SS_MODE;
- } else {
phy_mode = 0;
width = PCIE_BUS_WIDTH;
usb3_phy = 0;
ss_mode = 0;
- }
- regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
PCIE_PHY_MODE_MASK, phy_mode);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_BUS_WIDTH_MASK, width);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_PHY_ENABLE, usb3_phy);
- clrsetbits_le32(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF,
PCIE_USB3_PHY_SS_MODE, ss_mode);
- regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
USB_PDRSTN_SPLIT, 0);
- return 0;
+}
+static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy) +{
- /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
- writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF);
- writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF);
+}
+static int jh7110_pcie_phy_set_mode(struct phy *_phy,
enum phy_mode mode, int submode)
+{
- struct udevice *dev = _phy->dev;
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int ret;
- if (mode == phy->mode)
return 0;
- switch (mode) {
- case PHY_MODE_USB_HOST:
- case PHY_MODE_USB_DEVICE:
- case PHY_MODE_USB_OTG:
ret = phy_pcie_mode_set(phy, 1);
if (ret)
return ret;
break;
- case PHY_MODE_PCIE:
phy_pcie_mode_set(phy, 0);
break;
- default:
return -EINVAL;
- }
- dev_dbg(_phy->dev, "Changing phy mode to %d\n", mode);
- phy->mode = mode;
- return 0;
+}
+static const struct phy_ops jh7110_pcie_phy_ops = {
- .set_mode = jh7110_pcie_phy_set_mode,
+};
+static int starfive_pcie_phy_get_syscon(struct udevice *dev) +{
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- struct ofnode_phandle_args sys_phandle, stg_phandle;
- int ret;
- /* get corresponding syscon phandle */
- ret = dev_read_phandle_with_args(dev, "starfive,sys-syscon", NULL, 1, 0,
&sys_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get sys cfg phandle: %d\n", ret);
return ret;
- }
- ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 2, 0,
&stg_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get stg cfg phandle: %d\n", ret);
return ret;
- }
- phy->sys_syscon = syscon_node_to_regmap(sys_phandle.node);
- if (!IS_ERR_OR_NULL(phy->sys_syscon)) {
/* get syscon register offset */
phy->sys_phy_connect = sys_phandle.args[0];
- } else {
phy->sys_syscon = NULL;
Why not error out if you could not get the sys_syscon regmap?
- }
- phy->stg_syscon = syscon_node_to_regmap(stg_phandle.node);
- if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
phy->stg_pcie_mode = stg_phandle.args[0];
phy->stg_pcie_usb = stg_phandle.args[1];
- } else {
phy->stg_syscon = NULL;
same here?
- }
- return 0;
+}
+int jh7110_pcie_phy_probe(struct udevice *dev) +{
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int rc;
- phy->regs = dev_read_addr_ptr(dev);
- if (!phy->regs)
return -EINVAL;
- rc = starfive_pcie_phy_get_syscon(dev);
- if (rc)
return rc;
- phy_kvco_gain_set(phy);
- return 0;
+}
+static const struct udevice_id jh7110_pcie_phy[] = {
- { .compatible = "starfive,jh7110-pcie-phy"},
- {},
+};
+U_BOOT_DRIVER(jh7110_pcie_phy) = {
- .name = "jh7110_pcie_phy",
- .id = UCLASS_PHY,
- .of_match = jh7110_pcie_phy,
- .probe = jh7110_pcie_phy_probe,
- .ops = &jh7110_pcie_phy_ops,
- .priv_auto = sizeof(struct jh7110_pcie_phy),
need space instead of tab?
+};

On 04/07/2024 08:50, Minda Chen wrote:
Add Starfive JH7110 PCIe 2.0 PHY driver, which is generic PHY driver and can be used as USB 3.0 driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/phy/starfive/Kconfig | 7 + drivers/phy/starfive/Makefile | 1 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 +++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig index 11a819f8b2..5d49684bc7 100644 --- a/drivers/phy/starfive/Kconfig +++ b/drivers/phy/starfive/Kconfig @@ -4,6 +4,13 @@
menu "Starfive PHY driver"
+config PHY_STARFIVE_JH7110_PCIE
bool "Starfive JH7110 PCIe 2.0 PHY driver"
select PHY
help
Enable this to support the Starfive JH7110 PCIE 2.0/USB 3.0 PHY.
Generic PHY driver JH7110 USB 3.0/ PCIe 2.0.
Should be aligned to previous line.
config PHY_STARFIVE_JH7110_USB2 bool "Starfive JH7110 USB 2.0 PHY driver" select PHY diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile index a405a75e34..82f25aa21b 100644 --- a/drivers/phy/starfive/Makefile +++ b/drivers/phy/starfive/Makefile @@ -3,4 +3,5 @@ # Copyright (C) 2023 Starfive #
+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c new file mode 100644 index 0000000000..57d5d8bf53 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-pcie.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- StarFive JH7110 PCIe 2.0 PHY driver
- Copyright (C) 2024 StarFive Technology Co., Ltd.
- Author: Minda Chen minda.chen@starfivetech.com */ #include
+<asm/io.h> #include <dm.h> #include <dm/device_compat.h> #include +<errno.h> #include <generic-phy.h> #include <regmap.h> #include +<soc.h> #include <syscon.h> #include <linux/bitops.h> #include +<linux/err.h>
+#define PCIE_KVCO_LEVEL_OFF 0x28 +#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c +#define PCIE_USB3_PHY_SS_MODE BIT(4)
extra tab?
+#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80 +#define PHY_KVCO_FINE_TUNE_LEVEL 0x91 +#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
+#define USB_PDRSTN_SPLIT BIT(17)
+#define PCIE_USB3_PHY_MODE BIT(20) +#define PCIE_PHY_MODE_MASK GENMASK(21, 20) +#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2) +#define PCIE_BUS_WIDTH BIT(3) +#define PCIE_USB3_RATE_MASK GENMASK(6, 5) +#define PCIE_USB3_RX_STANDBY_MASK BIT(7) +#define PCIE_USB3_PHY_ENABLE BIT(4)
Why not use define and use regmap_fields? You are already using regmap.
+struct jh7110_pcie_phy {
- struct phy *phy;
- struct regmap *stg_syscon;
- struct regmap *sys_syscon;
- void __iomem *regs;
- u32 sys_phy_connect;
- u32 stg_pcie_mode;
- u32 stg_pcie_usb;
- enum phy_mode mode;
+};
+static int phy_pcie_mode_set(struct jh7110_pcie_phy *data, bool +usb_mode) {
- unsigned int phy_mode, width, usb3_phy, ss_mode;
- /* default is PCIe mode */
- if (!data->stg_syscon || !data->sys_syscon) {
if (usb_mode) {
dev_err(data->phy->dev, "doesn't support usb3 mode\n");
return -EINVAL;
}
return 0;
- }
- if (usb_mode) {
phy_mode = PCIE_USB3_PHY_MODE;
width = 0;
usb3_phy = PCIE_USB3_PHY_ENABLE;
ss_mode = PCIE_USB3_PHY_SS_MODE;
- } else {
phy_mode = 0;
width = PCIE_BUS_WIDTH;
usb3_phy = 0;
ss_mode = 0;
- }
- regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
PCIE_PHY_MODE_MASK, phy_mode);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_BUS_WIDTH_MASK, width);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_PHY_ENABLE, usb3_phy);
- clrsetbits_le32(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF,
PCIE_USB3_PHY_SS_MODE, ss_mode);
- regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
USB_PDRSTN_SPLIT, 0);
- return 0;
+}
+static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy) {
- /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
- writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs +
PCIE_KVCO_LEVEL_OFF);
- writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs +
+PCIE_KVCO_TUNE_SIGNAL_OFF); }
+static int jh7110_pcie_phy_set_mode(struct phy *_phy,
enum phy_mode mode, int submode) {
- struct udevice *dev = _phy->dev;
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int ret;
- if (mode == phy->mode)
return 0;
- switch (mode) {
- case PHY_MODE_USB_HOST:
- case PHY_MODE_USB_DEVICE:
- case PHY_MODE_USB_OTG:
ret = phy_pcie_mode_set(phy, 1);
if (ret)
return ret;
break;
- case PHY_MODE_PCIE:
phy_pcie_mode_set(phy, 0);
break;
- default:
return -EINVAL;
- }
- dev_dbg(_phy->dev, "Changing phy mode to %d\n", mode);
- phy->mode = mode;
- return 0;
+}
+static const struct phy_ops jh7110_pcie_phy_ops = {
- .set_mode = jh7110_pcie_phy_set_mode,
+};
+static int starfive_pcie_phy_get_syscon(struct udevice *dev) {
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- struct ofnode_phandle_args sys_phandle, stg_phandle;
- int ret;
- /* get corresponding syscon phandle */
- ret = dev_read_phandle_with_args(dev, "starfive,sys-syscon", NULL, 1, 0,
&sys_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get sys cfg phandle: %d\n", ret);
return ret;
- }
- ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 2, 0,
&stg_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get stg cfg phandle: %d\n", ret);
return ret;
- }
- phy->sys_syscon = syscon_node_to_regmap(sys_phandle.node);
- if (!IS_ERR_OR_NULL(phy->sys_syscon)) {
/* get syscon register offset */
phy->sys_phy_connect = sys_phandle.args[0];
- } else {
phy->sys_syscon = NULL;
Why not error out if you could not get the sys_syscon regmap?
The syscon is optional in USB2.0 only case.
- }
- phy->stg_syscon = syscon_node_to_regmap(stg_phandle.node);
- if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
phy->stg_pcie_mode = stg_phandle.args[0];
phy->stg_pcie_usb = stg_phandle.args[1];
- } else {
phy->stg_syscon = NULL;
same here?
- }
- return 0;
+}
+int jh7110_pcie_phy_probe(struct udevice *dev) {
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int rc;
- phy->regs = dev_read_addr_ptr(dev);
- if (!phy->regs)
return -EINVAL;
- rc = starfive_pcie_phy_get_syscon(dev);
- if (rc)
return rc;
- phy_kvco_gain_set(phy);
- return 0;
+}
+static const struct udevice_id jh7110_pcie_phy[] = {
- { .compatible = "starfive,jh7110-pcie-phy"},
- {},
+};
+U_BOOT_DRIVER(jh7110_pcie_phy) = {
- .name = "jh7110_pcie_phy",
- .id = UCLASS_PHY,
- .of_match = jh7110_pcie_phy,
- .probe = jh7110_pcie_phy_probe,
- .ops = &jh7110_pcie_phy_ops,
- .priv_auto = sizeof(struct jh7110_pcie_phy),
need space instead of tab?
+};
-- cheers, -roger

On 04/07/2024 08:50, Minda Chen wrote:
Add Starfive JH7110 PCIe 2.0 PHY driver, which is generic PHY driver and can be used as USB 3.0 driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/phy/starfive/Kconfig | 7 + drivers/phy/starfive/Makefile | 1 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 +++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
diff --git a/drivers/phy/starfive/Kconfig b/drivers/phy/starfive/Kconfig index 11a819f8b2..5d49684bc7 100644 --- a/drivers/phy/starfive/Kconfig +++ b/drivers/phy/starfive/Kconfig @@ -4,6 +4,13 @@
menu "Starfive PHY driver"
+config PHY_STARFIVE_JH7110_PCIE
bool "Starfive JH7110 PCIe 2.0 PHY driver"
select PHY
help
Enable this to support the Starfive JH7110 PCIE 2.0/USB 3.0 PHY.
Generic PHY driver JH7110 USB 3.0/ PCIe 2.0.
config PHY_STARFIVE_JH7110_USB2 bool "Starfive JH7110 USB 2.0 PHY driver" select PHY diff --git a/drivers/phy/starfive/Makefile b/drivers/phy/starfive/Makefile index a405a75e34..82f25aa21b 100644 --- a/drivers/phy/starfive/Makefile +++ b/drivers/phy/starfive/Makefile @@ -3,4 +3,5 @@ # Copyright (C) 2023 Starfive #
+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o obj-$(CONFIG_PHY_STARFIVE_JH7110_USB2) += phy-jh7110-usb2.o diff --git a/drivers/phy/starfive/phy-jh7110-pcie.c b/drivers/phy/starfive/phy-jh7110-pcie.c new file mode 100644 index 0000000000..57d5d8bf53 --- /dev/null +++ b/drivers/phy/starfive/phy-jh7110-pcie.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- StarFive JH7110 PCIe 2.0 PHY driver
- Copyright (C) 2024 StarFive Technology Co., Ltd.
- Author: Minda Chen minda.chen@starfivetech.com
- */
+#include <asm/io.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <errno.h> +#include <generic-phy.h> +#include <regmap.h> +#include <soc.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/err.h>
+#define PCIE_KVCO_LEVEL_OFF 0x28 +#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c +#define PCIE_USB3_PHY_SS_MODE BIT(4) +#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80 +#define PHY_KVCO_FINE_TUNE_LEVEL 0x91 +#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
+#define USB_PDRSTN_SPLIT BIT(17)
+#define PCIE_USB3_PHY_MODE BIT(20) +#define PCIE_PHY_MODE_MASK GENMASK(21, 20) +#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2) +#define PCIE_BUS_WIDTH BIT(3) +#define PCIE_USB3_RATE_MASK GENMASK(6, 5) +#define PCIE_USB3_RX_STANDBY_MASK BIT(7) +#define PCIE_USB3_PHY_ENABLE BIT(4)
+struct jh7110_pcie_phy {
- struct phy *phy;
- struct regmap *stg_syscon;
- struct regmap *sys_syscon;
- void __iomem *regs;
- u32 sys_phy_connect;
- u32 stg_pcie_mode;
- u32 stg_pcie_usb;
- enum phy_mode mode;
+};
+static int phy_pcie_mode_set(struct jh7110_pcie_phy *data, bool usb_mode) +{
- unsigned int phy_mode, width, usb3_phy, ss_mode;
- /* default is PCIe mode */
- if (!data->stg_syscon || !data->sys_syscon) {
if (usb_mode) {
dev_err(data->phy->dev, "doesn't support usb3 mode\n");
return -EINVAL;
}
return 0;
- }
- if (usb_mode) {
phy_mode = PCIE_USB3_PHY_MODE;
width = 0;
usb3_phy = PCIE_USB3_PHY_ENABLE;
ss_mode = PCIE_USB3_PHY_SS_MODE;
- } else {
phy_mode = 0;
width = PCIE_BUS_WIDTH;
usb3_phy = 0;
ss_mode = 0;
- }
- regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
PCIE_PHY_MODE_MASK, phy_mode);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_BUS_WIDTH_MASK, width);
- regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
PCIE_USB3_PHY_ENABLE, usb3_phy);
- clrsetbits_le32(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF,
PCIE_USB3_PHY_SS_MODE, ss_mode);
- regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
USB_PDRSTN_SPLIT, 0);
- return 0;
+}
+static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy) +{
- /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
- writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF);
- writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF);
+}
+static int jh7110_pcie_phy_set_mode(struct phy *_phy,
enum phy_mode mode, int submode)
+{
- struct udevice *dev = _phy->dev;
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int ret;
- if (mode == phy->mode)
return 0;
- switch (mode) {
- case PHY_MODE_USB_HOST:
- case PHY_MODE_USB_DEVICE:
- case PHY_MODE_USB_OTG:
ret = phy_pcie_mode_set(phy, 1);
if (ret)
return ret;
break;
- case PHY_MODE_PCIE:
phy_pcie_mode_set(phy, 0);
break;
- default:
return -EINVAL;
- }
- dev_dbg(_phy->dev, "Changing phy mode to %d\n", mode);
- phy->mode = mode;
- return 0;
+}
+static const struct phy_ops jh7110_pcie_phy_ops = {
- .set_mode = jh7110_pcie_phy_set_mode,
+};
+static int starfive_pcie_phy_get_syscon(struct udevice *dev) +{
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- struct ofnode_phandle_args sys_phandle, stg_phandle;
- int ret;
- /* get corresponding syscon phandle */
- ret = dev_read_phandle_with_args(dev, "starfive,sys-syscon", NULL, 1, 0,
&sys_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get sys cfg phandle: %d\n", ret);
return ret;
- }
- ret = dev_read_phandle_with_args(dev, "starfive,stg-syscon", NULL, 2, 0,
&stg_phandle);
- if (ret < 0) {
dev_err(dev, "Can't get stg cfg phandle: %d\n", ret);
return ret;
- }
- phy->sys_syscon = syscon_node_to_regmap(sys_phandle.node);
- if (!IS_ERR_OR_NULL(phy->sys_syscon)) {
/* get syscon register offset */
phy->sys_phy_connect = sys_phandle.args[0];
- } else {
phy->sys_syscon = NULL;
- }
- phy->stg_syscon = syscon_node_to_regmap(stg_phandle.node);
- if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
phy->stg_pcie_mode = stg_phandle.args[0];
phy->stg_pcie_usb = stg_phandle.args[1];
- } else {
phy->stg_syscon = NULL;
- }
- return 0;
+}
+int jh7110_pcie_phy_probe(struct udevice *dev) +{
- struct jh7110_pcie_phy *phy = dev_get_priv(dev);
- int rc;
- phy->regs = dev_read_addr_ptr(dev);
- if (!phy->regs)
return -EINVAL;
- rc = starfive_pcie_phy_get_syscon(dev);
- if (rc)
return rc;
- phy_kvco_gain_set(phy);
- return 0;
+}
+static const struct udevice_id jh7110_pcie_phy[] = {
- { .compatible = "starfive,jh7110-pcie-phy"},
- {},
+};
+U_BOOT_DRIVER(jh7110_pcie_phy) = {
- .name = "jh7110_pcie_phy",
- .id = UCLASS_PHY,
- .of_match = jh7110_pcie_phy,
- .probe = jh7110_pcie_phy_probe,
- .ops = &jh7110_pcie_phy_ops,
- .priv_auto = sizeof(struct jh7110_pcie_phy),
+};
Please drop the new blank line at the end.

Add cdns USB3 wrapper driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- drivers/usb/cdns3/Kconfig | 7 ++ drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 +++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig index 35b61497d9..f8f363982b 100644 --- a/drivers/usb/cdns3/Kconfig +++ b/drivers/usb/cdns3/Kconfig @@ -55,4 +55,11 @@ config USB_CDNS3_TI help Say 'Y' here if you are building for Texas Instruments platforms that contain Cadence USB3 controller core. E.g.: J721e. + +config USB_CDNS3_STARFIVE + tristate "Cadence USB3 support on Starfive platforms" + default USB_CDNS3 + help + Say 'Y' here if you are building for Starfive platforms + that contain Cadence USB3 controller core. E.g.: JH7110. endif diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile index 18d7190755..03d1eadb2f 100644 --- a/drivers/usb/cdns3/Makefile +++ b/drivers/usb/cdns3/Makefile @@ -9,3 +9,5 @@ cdns3-$(CONFIG_$(SPL_)USB_CDNS3_GADGET) += gadget.o ep0.o cdns3-$(CONFIG_$(SPL_)USB_CDNS3_HOST) += host.o
obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o + +obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c new file mode 100644 index 0000000000..660833fb5b --- /dev/null +++ b/drivers/usb/cdns3/cdns3-starfive.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller + * + * Copyright (C) 2024 StarFive Technology Co., Ltd. + * + * Author: Minda Chen minda.chen@starfivetech.com + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <linux/bitops.h> +#include <linux/usb/otg.h> +#include <reset.h> +#include <regmap.h> +#include <syscon.h> +#include <malloc.h> + +#include "core.h" + +#define USB_STRAP_HOST BIT(17) +#define USB_STRAP_DEVICE BIT(18) +#define USB_STRAP_MASK GENMASK(18, 16) + +#define USB_SUSPENDM_HOST BIT(19) +#define USB_SUSPENDM_MASK BIT(19) + +#define USB_MISC_CFG_MASK GENMASK(23, 20) +#define USB_SUSPENDM_BYPS BIT(20) +#define USB_PLL_EN BIT(22) +#define USB_REFCLK_MODE BIT(23) + +struct cdns_starfive { + struct udevice *dev; + struct regmap *stg_syscon; + struct reset_ctl_bulk resets; + struct clk_bulk clks; + u32 stg_usb_mode; + enum usb_dr_mode mode; +}; + +static void cdns_mode_init(struct cdns_starfive *data, enum usb_dr_mode mode) +{ + unsigned int strap, suspendm; + + regmap_update_bits(data->stg_syscon, data->stg_usb_mode, + USB_MISC_CFG_MASK, + USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE); + + switch (mode) { + case USB_DR_MODE_HOST: + strap = USB_STRAP_HOST; + suspendm = USB_SUSPENDM_HOST; + break; + + case USB_DR_MODE_PERIPHERAL: + strap = USB_STRAP_DEVICE; + suspendm = 0; + break; + default: + return; + } + + regmap_update_bits(data->stg_syscon, data->stg_usb_mode, + USB_STRAP_MASK, strap); + regmap_update_bits(data->stg_syscon, data->stg_usb_mode, + USB_SUSPENDM_MASK, suspendm); +} + +static void cdns_clk_rst_deinit(struct cdns_starfive *data) +{ + reset_assert_bulk(&data->resets); + clk_disable_bulk(&data->clks); +} + +static int cdns_clk_rst_init(struct cdns_starfive *data) +{ + int ret; + + ret = clk_get_bulk(data->dev, &data->clks); + if (ret) + return ret; + + ret = reset_get_bulk(data->dev, &data->resets); + if (ret) + goto err_clk; + + ret = clk_enable_bulk(&data->clks); + if (ret) + goto err_en_clk; + + ret = reset_deassert_bulk(&data->resets); + if (ret) + goto err_reset; + + return 0; + +err_reset: + clk_disable_bulk(&data->clks); +err_en_clk: + reset_release_bulk(&data->resets); +err_clk: + clk_release_bulk(&data->clks); + + return ret; +} + +static int cdns_starfive_get_syscon(struct cdns_starfive *data) +{ + struct ofnode_phandle_args phandle; + int ret; + + ret = dev_read_phandle_with_args(data->dev, "starfive,stg-syscon", NULL, 1, 0, + &phandle); + + if (ret < 0) { + dev_err(data->dev, "Can't get stg cfg phandle: %d\n", ret); + return ret; + } + + data->stg_syscon = syscon_node_to_regmap(phandle.node); + if (IS_ERR(data->stg_syscon)) { + dev_err(data->dev, "fail to get regmap: %d\n", (int)PTR_ERR(data->stg_syscon)); + return PTR_ERR(data->stg_syscon); + } + data->stg_usb_mode = phandle.args[0]; + + return 0; +} + +static int cdns_starfive_probe(struct udevice *dev) +{ + struct cdns_starfive *data = dev_get_plat(dev); + enum usb_dr_mode dr_mode; + ofnode node; + int ret; + + data->dev = dev; + + ret = cdns_starfive_get_syscon(data); + + if (ret) + return ret; + + node = ofnode_by_compatible(dev_ofnode(dev), "cdns,usb3"); + if (!ofnode_valid(node)) { + dev_err(dev, "failed to get usb node\n"); + return -ENODEV; + } + + dr_mode = usb_get_dr_mode(node); + + data->mode = dr_mode; + cdns_mode_init(data, dr_mode); + + return cdns_clk_rst_init(data); +} + +static int cdns_starfive_remove(struct udevice *dev) +{ + struct cdns_starfive *data = dev_get_plat(dev); + + cdns_clk_rst_deinit(data); + return 0; +} + +static const struct udevice_id cdns_starfive_of_match[] = { + { .compatible = "starfive,jh7110-usb", }, + {}, +}; + +U_BOOT_DRIVER(cdns_starfive) = { + .name = "cdns-starfive", + .id = UCLASS_NOP, + .of_match = cdns_starfive_of_match, + .bind = cdns3_bind, + .probe = cdns_starfive_probe, + .remove = cdns_starfive_remove, + .plat_auto = sizeof(struct cdns_starfive), + .flags = DM_FLAG_OS_PREPARE, +};

On 04/07/2024 08:50, Minda Chen wrote:
Add cdns USB3 wrapper driver.
Signed-off-by: Minda Chen minda.chen@starfivetech.com
drivers/usb/cdns3/Kconfig | 7 ++ drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 +++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig index 35b61497d9..f8f363982b 100644 --- a/drivers/usb/cdns3/Kconfig +++ b/drivers/usb/cdns3/Kconfig @@ -55,4 +55,11 @@ config USB_CDNS3_TI help Say 'Y' here if you are building for Texas Instruments platforms that contain Cadence USB3 controller core. E.g.: J721e.
+config USB_CDNS3_STARFIVE
- tristate "Cadence USB3 support on Starfive platforms"
- default USB_CDNS3
- help
Say 'Y' here if you are building for Starfive platforms
that contain Cadence USB3 controller core. E.g.: JH7110.
endif diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile index 18d7190755..03d1eadb2f 100644 --- a/drivers/usb/cdns3/Makefile +++ b/drivers/usb/cdns3/Makefile @@ -9,3 +9,5 @@ cdns3-$(CONFIG_$(SPL_)USB_CDNS3_GADGET) += gadget.o ep0.o cdns3-$(CONFIG_$(SPL_)USB_CDNS3_HOST) += host.o
obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o
+obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c new file mode 100644 index 0000000000..660833fb5b --- /dev/null +++ b/drivers/usb/cdns3/cdns3-starfive.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller
- Copyright (C) 2024 StarFive Technology Co., Ltd.
- Author: Minda Chen minda.chen@starfivetech.com
- */
+#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <linux/bitops.h> +#include <linux/usb/otg.h> +#include <reset.h> +#include <regmap.h> +#include <syscon.h> +#include <malloc.h>
+#include "core.h"
+#define USB_STRAP_HOST BIT(17) +#define USB_STRAP_DEVICE BIT(18) +#define USB_STRAP_MASK GENMASK(18, 16)
+#define USB_SUSPENDM_HOST BIT(19) +#define USB_SUSPENDM_MASK BIT(19)
+#define USB_MISC_CFG_MASK GENMASK(23, 20) +#define USB_SUSPENDM_BYPS BIT(20) +#define USB_PLL_EN BIT(22) +#define USB_REFCLK_MODE BIT(23)
+struct cdns_starfive {
- struct udevice *dev;
- struct regmap *stg_syscon;
- struct reset_ctl_bulk resets;
- struct clk_bulk clks;
- u32 stg_usb_mode;
- enum usb_dr_mode mode;
+};
+static void cdns_mode_init(struct cdns_starfive *data, enum usb_dr_mode mode) +{
- unsigned int strap, suspendm;
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
USB_MISC_CFG_MASK,
USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);
- switch (mode) {
- case USB_DR_MODE_HOST:
strap = USB_STRAP_HOST;
suspendm = USB_SUSPENDM_HOST;
break;
- case USB_DR_MODE_PERIPHERAL:
strap = USB_STRAP_DEVICE;
suspendm = 0;
break;
- default:
return;
- }
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
USB_STRAP_MASK, strap);
- regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
USB_SUSPENDM_MASK, suspendm);
+}
+static void cdns_clk_rst_deinit(struct cdns_starfive *data) +{
- reset_assert_bulk(&data->resets);
- clk_disable_bulk(&data->clks);
+}
+static int cdns_clk_rst_init(struct cdns_starfive *data) +{
- int ret;
- ret = clk_get_bulk(data->dev, &data->clks);
- if (ret)
return ret;
- ret = reset_get_bulk(data->dev, &data->resets);
- if (ret)
goto err_clk;
- ret = clk_enable_bulk(&data->clks);
- if (ret)
goto err_en_clk;
- ret = reset_deassert_bulk(&data->resets);
- if (ret)
goto err_reset;
- return 0;
+err_reset:
- clk_disable_bulk(&data->clks);
+err_en_clk:
- reset_release_bulk(&data->resets);
+err_clk:
- clk_release_bulk(&data->clks);
- return ret;
+}
+static int cdns_starfive_get_syscon(struct cdns_starfive *data) +{
- struct ofnode_phandle_args phandle;
- int ret;
- ret = dev_read_phandle_with_args(data->dev, "starfive,stg-syscon", NULL, 1, 0,
&phandle);
unnecessary blank line
- if (ret < 0) {
dev_err(data->dev, "Can't get stg cfg phandle: %d\n", ret);
return ret;
- }
- data->stg_syscon = syscon_node_to_regmap(phandle.node);
- if (IS_ERR(data->stg_syscon)) {
dev_err(data->dev, "fail to get regmap: %d\n", (int)PTR_ERR(data->stg_syscon));
return PTR_ERR(data->stg_syscon);
- }
Need a new blank line?
- data->stg_usb_mode = phandle.args[0];
- return 0;
+}
+static int cdns_starfive_probe(struct udevice *dev) +{
- struct cdns_starfive *data = dev_get_plat(dev);
- enum usb_dr_mode dr_mode;
- ofnode node;
- int ret;
- data->dev = dev;
- ret = cdns_starfive_get_syscon(data);
unnecessary blank new lines.
- if (ret)
return ret;
- node = ofnode_by_compatible(dev_ofnode(dev), "cdns,usb3");
- if (!ofnode_valid(node)) {
dev_err(dev, "failed to get usb node\n");
return -ENODEV;
- }
- dr_mode = usb_get_dr_mode(node);
- data->mode = dr_mode;
- cdns_mode_init(data, dr_mode);
Don't you need to release reset and enable clock before doing cdns_mode_init()?
- return cdns_clk_rst_init(data);
+}
+static int cdns_starfive_remove(struct udevice *dev) +{
- struct cdns_starfive *data = dev_get_plat(dev);
- cdns_clk_rst_deinit(data);
- return 0;
+}
+static const struct udevice_id cdns_starfive_of_match[] = {
- { .compatible = "starfive,jh7110-usb", },
- {},
+};
+U_BOOT_DRIVER(cdns_starfive) = {
- .name = "cdns-starfive",
- .id = UCLASS_NOP,
- .of_match = cdns_starfive_of_match,
- .bind = cdns3_bind,
- .probe = cdns_starfive_probe,
- .remove = cdns_starfive_remove,
- .plat_auto = sizeof(struct cdns_starfive),
- .flags = DM_FLAG_OS_PREPARE,
+};

For some JH7110 boards, USB host overcurent pin is not reserved, To make USB host work, overcurrent pin must be disabled. So set the pin default disabled.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c index dafba65eae..1102985ab9 100644 --- a/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c +++ b/drivers/pinctrl/starfive/pinctrl-jh7110-sys.c @@ -378,8 +378,15 @@ static int jh7110_sys_pinctrl_probe(struct udevice *dev) { struct starfive_pinctrl_soc_info *info = (struct starfive_pinctrl_soc_info *)dev_get_driver_data(dev); - - return starfive_pinctrl_probe(dev, info); + struct starfive_pinctrl_priv *priv = dev_get_priv(dev); + int ret; + + ret = starfive_pinctrl_probe(dev, info); + /* Set default the usb controller overcurrent signal. */ + if (!ret) + clrsetbits_le32(priv->base + JH7110_SYS_GPI, + GENMASK(22, 16), BIT(16)); + return ret; }
static const struct udevice_id jh7110_sys_pinctrl_ids[] = {

Add cadence USB confiuration.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- configs/starfive_visionfive2_defconfig | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig index 174ac24dc7..35137eec59 100644 --- a/configs/starfive_visionfive2_defconfig +++ b/configs/starfive_visionfive2_defconfig @@ -69,6 +69,7 @@ CONFIG_SYS_EEPROM_SIZE=512 CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=4 CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=5 CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_BIND is not set CONFIG_CMD_I2C=y CONFIG_CMD_PCI=y CONFIG_CMD_USB=y @@ -112,6 +113,8 @@ CONFIG_NVME_PCI=y CONFIG_DM_PCI_COMPAT=y CONFIG_PCI_REGION_MULTI_ENTRY=y CONFIG_PCIE_STARFIVE_JH7110=y +CONFIG_PHY_STARFIVE_JH7110_PCIE=y +CONFIG_PHY_STARFIVE_JH7110_USB2=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y @@ -127,13 +130,19 @@ CONFIG_CADENCE_QSPI=y CONFIG_SYSRESET=y CONFIG_TIMER_EARLY=y CONFIG_USB=y +CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_PCI=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_PCI=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +# CONFIG_USB_CDNS3_TI is not set CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y # CONFIG_WATCHDOG is not set # CONFIG_WATCHDOG_AUTOSTART is not set CONFIG_WDT=y

Add Jh7110 Cadence USB dts node, Visionfive2 default setting is USB 2.0 device.
Signed-off-by: Minda Chen minda.chen@starfivetech.com --- .../dts/jh7110-starfive-visionfive-2.dtsi | 5 ++ arch/riscv/dts/jh7110.dtsi | 52 +++++++++++++++++++ 2 files changed, 57 insertions(+)
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi index e11babc1cd..44785bbee3 100644 --- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi @@ -378,3 +378,8 @@ }; }; }; + +&usb_cdns3 { + dr_mode = "peripheral"; + status = "okay"; +}; diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi index 2cdc683d49..1eee924e1d 100644 --- a/arch/riscv/dts/jh7110.dtsi +++ b/arch/riscv/dts/jh7110.dtsi @@ -371,6 +371,58 @@ status = "disabled"; };
+ usb0: usb@10100000 { + compatible = "starfive,jh7110-usb"; + ranges = <0x0 0x0 0x10100000 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + starfive,stg-syscon = <&stg_syscon 0x4>; + clocks = <&stgcrg JH7110_STGCLK_USB_LPM>, + <&stgcrg JH7110_STGCLK_USB_STB>, + <&stgcrg JH7110_STGCLK_USB_APB>, + <&stgcrg JH7110_STGCLK_USB_AXI>, + <&stgcrg JH7110_STGCLK_USB_UTMI_APB>; + clock-names = "lpm", "stb", "apb", "axi", "utmi_apb"; + resets = <&stgcrg JH7110_STGRST_USB_PWRUP>, + <&stgcrg JH7110_STGRST_USB_APB>, + <&stgcrg JH7110_STGRST_USB_AXI>, + <&stgcrg JH7110_STGRST_USB_UTMI_APB>; + reset-names = "pwrup", "apb", "axi", "utmi_apb"; + + usb_cdns3: usb@0 { + compatible = "cdns,usb3"; + reg = <0x0 0x10000>, + <0x10000 0x10000>, + <0x20000 0x10000>; + reg-names = "otg", "xhci", "dev"; + interrupts = <100>, <108>, <110>; + interrupt-names = "host", "peripheral", "otg"; + phys = <&usbphy0>; + phy-names = "cdns3,usb2-phy"; + }; + }; + + usbphy0: phy@10200000 { + compatible = "starfive,jh7110-usb-phy"; + reg = <0x0 0x10200000 0x0 0x10000>; + clocks = <&syscrg JH7110_SYSCLK_USB_125M>, + <&stgcrg JH7110_STGCLK_USB_APP_125>; + clock-names = "125m", "app_125m"; + #phy-cells = <0>; + }; + + pciephy0: phy@10210000 { + compatible = "starfive,jh7110-pcie-phy"; + reg = <0x0 0x10210000 0x0 0x10000>; + #phy-cells = <0>; + }; + + pciephy1: phy@10220000 { + compatible = "starfive,jh7110-pcie-phy"; + reg = <0x0 0x10220000 0x0 0x10000>; + #phy-cells = <0>; + }; + stgcrg: clock-controller@10230000 { compatible = "starfive,jh7110-stgcrg"; reg = <0x0 0x10230000 0x0 0x10000>;

Add USB related files to Starfive visionfive2 MAINTAINERS.
Signed-off-by: Minda Chen minda.chen@starfivetech.com Reviewed-by: Marek Vasut marex@denx.de --- board/starfive/visionfive2/MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/board/starfive/visionfive2/MAINTAINERS b/board/starfive/visionfive2/MAINTAINERS index d7f638f9b4..1faf83f581 100644 --- a/board/starfive/visionfive2/MAINTAINERS +++ b/board/starfive/visionfive2/MAINTAINERS @@ -6,3 +6,5 @@ F: board/starfive/visionfive2/ F: include/configs/starfive-visionfive2.h F: configs/starfive_visionfive2_defconfig F: drivers/pci/pcie_starfive_jh7110.c +F: drivers/phy/starfive/ +F: drivers/usb/cdns3/cdns3-starfive.c

On 7/4/24 07:50, Minda Chen wrote:
Add Starfive JH7110 Cadence USB driver and related PHY driver. So the codes can be used in visionfive2 and star64 7110 board.
The driver is almost the same with kernel driver.
Test with Star64 JH7110 board USB 3.0 + USB 2.0 host. The code can work.
- Star64 using USB 3.0 and USB 2.0 host must add below board dts setting.
Does this mean a future patch for spl_fdt_fixup_star64() is needed?
Did you also have a look at the USB on the Milk V Mars CM?
Best regards
Heinrich
usb pin setting usb_pins: usb0-0 { driver-vbus-pin { pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS, GPOEN_ENABLE, GPI_NONE)>; bias-disable; input-disable; input-schmitt-disable; slew-rate = <0>; }; };
related dts node setting.
&pcie0 { status = "disabled"; };
&pciephy0 { starfive,sys-syscon = <&sys_syscon 0x18>; starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>; status = "okay"; };
&usb0 { pinctrl-names = "default"; pinctrl-0 = <&usb_pins>; status = "okay"; };
&usb_cdns3 { phys = <&usbphy0>, <&pciephy0>; phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; dr_mode = "host"; status = "okay"; };
previous version v1: https://patchwork.ozlabs.org/project/uboot/cover/20240504150358.19600-1-mind...
patch description.
patch1: Add set phy mode function in cdns3 core driver which is used by Starfive JH7110. patch2-3: USB and PCIe 2.0 (usb 3.0) PHY drivier patch4: Cadence USB wrapper driver. patch5: Add JH7110 USB default overcurrent pin. patch6-8 dts, config and maintainers update.
- change: v2:
- patch 1 Move the added code to cdns3_core_init_role(). Must set PHY mode before calling cdns3 role start function.
- patch 1-4 correct the code format.(follow Marek's comments.)
- patch 2 Add set 125M clock in PHY init function.
- Add new patch5.
Minda Chen (8): usb: cdns3: Set USB PHY mode in cdns3_core_init_role() phy: starfive: Add Starfive JH7110 USB 2.0 PHY driver phy: starfive: Add Starfive JH7110 PCIe 2.0 PHY driver usb: cdns: starfive: Add cdns USB driver pinctrl: starfive: Setup USB default disable overcurrent pin configs: starfive: Add visionfive2 cadence USB configuration dts: starfive: Add JH7110 Cadence USB dts node MAINTAINERS: Update Starfive visionfive2 maintain files.
.../dts/jh7110-starfive-visionfive-2.dtsi | 5 + arch/riscv/dts/jh7110.dtsi | 52 +++++ board/starfive/visionfive2/MAINTAINERS | 2 + configs/starfive_visionfive2_defconfig | 9 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 21 ++ drivers/phy/starfive/Makefile | 7 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 ++++++++++++++++++ drivers/phy/starfive/phy-jh7110-usb2.c | 135 ++++++++++++ drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +- drivers/usb/cdns3/Kconfig | 7 + drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 ++++++++++++++++ drivers/usb/cdns3/core.c | 25 +++ 15 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
base-commit: 8937bb265a7f2251c1bd999784a4ef10e9c6080d

On Thu, Jul 4, 2024 at 6:25 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 7/4/24 07:50, Minda Chen wrote:
Add Starfive JH7110 Cadence USB driver and related PHY driver. So the codes can be used in visionfive2 and star64 7110 board.
The driver is almost the same with kernel driver.
Test with Star64 JH7110 board USB 3.0 + USB 2.0 host. The code can work.
- Star64 using USB 3.0 and USB 2.0 host must add below board dts setting.
Does this mean a future patch for spl_fdt_fixup_star64() is needed?
As said by Hal they will be introducing a patchset to OF_UPSTREAM the JH7110 board support so we should pursue that first to get dts upstream (Linux?) aligned with U-Boot.
Did you also have a look at the USB on the Milk V Mars CM?
With Minda's advice for Star64 applied to jh7110-starfive-visionfive-2.dtsi directly as a test on Milk-V Mars CM Lite:
StarFive # usb info 1: Hub, USB Revision 3.0 - U-Boot XHCI Host Controller - Class: Hub - PacketSize: 512 Configurations: 1 - Vendor: 0x0000 Product 0x0000 Version 1.0 Configuration: 1 - Interfaces: 1 Self Powered 0mA Interface: 0 - Alternate Setting 0, Endpoints: 1 - Class Hub - Endpoint 1 In Interrupt MaxPacket 8 Interval 255ms
Best regards
Heinrich
usb pin setting usb_pins: usb0-0 { driver-vbus-pin { pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS, GPOEN_ENABLE, GPI_NONE)>; bias-disable; input-disable; input-schmitt-disable; slew-rate = <0>; }; };
related dts node setting.
&pcie0 { status = "disabled"; };
&pciephy0 { starfive,sys-syscon = <&sys_syscon 0x18>; starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>; status = "okay"; };
Question I have is: Where is the documentation for these "magical" numbers 0x18 00x148 0x1f4 ? Is this a defined constant, or else where is this in the Technical Reference Manual?
&usb0 { pinctrl-names = "default"; pinctrl-0 = <&usb_pins>; status = "okay"; };
&usb_cdns3 { phys = <&usbphy0>, <&pciephy0>; phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; dr_mode = "host"; status = "okay"; };
previous version v1: https://patchwork.ozlabs.org/project/uboot/cover/20240504150358.19600-1-mind...
patch description.
patch1: Add set phy mode function in cdns3 core driver which is used by Starfive JH7110. patch2-3: USB and PCIe 2.0 (usb 3.0) PHY drivier patch4: Cadence USB wrapper driver. patch5: Add JH7110 USB default overcurrent pin. patch6-8 dts, config and maintainers update.
- change: v2: - patch 1 Move the added code to cdns3_core_init_role(). Must set PHY mode before calling cdns3 role start function. - patch 1-4 correct the code format.(follow Marek's comments.) - patch 2 Add set 125M clock in PHY init function. - Add new patch5.
Minda Chen (8): usb: cdns3: Set USB PHY mode in cdns3_core_init_role() phy: starfive: Add Starfive JH7110 USB 2.0 PHY driver phy: starfive: Add Starfive JH7110 PCIe 2.0 PHY driver usb: cdns: starfive: Add cdns USB driver pinctrl: starfive: Setup USB default disable overcurrent pin configs: starfive: Add visionfive2 cadence USB configuration dts: starfive: Add JH7110 Cadence USB dts node MAINTAINERS: Update Starfive visionfive2 maintain files.
.../dts/jh7110-starfive-visionfive-2.dtsi | 5 + arch/riscv/dts/jh7110.dtsi | 52 +++++ board/starfive/visionfive2/MAINTAINERS | 2 + configs/starfive_visionfive2_defconfig | 9 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 21 ++ drivers/phy/starfive/Makefile | 7 + drivers/phy/starfive/phy-jh7110-pcie.c | 202 ++++++++++++++++++ drivers/phy/starfive/phy-jh7110-usb2.c | 135 ++++++++++++ drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +- drivers/usb/cdns3/Kconfig | 7 + drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 ++++++++++++++++ drivers/usb/cdns3/core.c | 25 +++ 15 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
base-commit: 8937bb265a7f2251c1bd999784a4ef10e9c6080d
Thanks very much Minda, I am happy to see some USB Host function on Milk-V Mars CM Lite here. -E Shattow

On Thu, Jul 4, 2024 at 6:25 AM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 7/4/24 07:50, Minda Chen wrote:
Add Starfive JH7110 Cadence USB driver and related PHY driver. So the codes can be used in visionfive2 and star64 7110 board.
The driver is almost the same with kernel driver.
Test with Star64 JH7110 board USB 3.0 + USB 2.0 host. The code can work.
- Star64 using USB 3.0 and USB 2.0 host must add below board dts setting.
Does this mean a future patch for spl_fdt_fixup_star64() is needed?
As said by Hal they will be introducing a patchset to OF_UPSTREAM the JH7110 board support so we should pursue that first to get dts upstream (Linux?) aligned with U-Boot.
Did you also have a look at the USB on the Milk V Mars CM?
With Minda's advice for Star64 applied to jh7110-starfive-visionfive-2.dtsi directly as a test on Milk-V Mars CM Lite:
StarFive # usb info 1: Hub, USB Revision 3.0
- U-Boot XHCI Host Controller
- Class: Hub
- PacketSize: 512 Configurations: 1
- Vendor: 0x0000 Product 0x0000 Version 1.0 Configuration: 1
- Interfaces: 1 Self Powered 0mA Interface: 0
- Alternate Setting 0, Endpoints: 1
- Class Hub
- Endpoint 1 In Interrupt MaxPacket 8 Interval 255ms
Best regards
Heinrich
- usb pin setting usb_pins: usb0-0 { driver-vbus-pin { pinmux = <GPIOMUX(25,
GPOUT_SYS_USB_DRIVE_VBUS,
GPOEN_ENABLE, GPI_NONE)>; bias-disable; input-disable; input-schmitt-disable; slew-rate = <0>; }; };
- related dts node setting.
&pcie0 { status = "disabled"; };
&pciephy0 { starfive,sys-syscon = <&sys_syscon 0x18>; starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>; status = "okay"; };
Question I have is: Where is the documentation for these "magical" numbers 0x18 00x148 0x1f4 ? Is this a defined constant, or else where is this in the Technical Reference Manual?
This is USB 3.0 configuration. 0x18 0x148 and 0x1f4 is register offset. MilkV CM is USB 2.0 host. It is not needed. And I don't know whether Vbus pin is GPIO25 in CM board. If not, I think Just set dr mode to host is OK in Milk-V CM board.
&usb0 { pinctrl-names = "default"; pinctrl-0 = <&usb_pins>; status = "okay"; };
&usb_cdns3 { phys = <&usbphy0>, <&pciephy0>; phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; dr_mode = "host"; status = "okay"; };
- previous version v1:
https://patchwork.ozlabs.org/project/uboot/cover/20240504150358.1960 0-1-minda.chen@starfivetech.com/
- patch description.
patch1: Add set phy mode function in cdns3 core driver which is used by Starfive JH7110. patch2-3: USB and PCIe 2.0 (usb 3.0) PHY drivier patch4: Cadence USB wrapper driver. patch5: Add JH7110 USB default overcurrent pin. patch6-8 dts, config and maintainers update.
- change: v2: - patch 1 Move the added code to cdns3_core_init_role(). Must set PHY mode before calling cdns3 role start function. - patch 1-4 correct the code format.(follow Marek's comments.) - patch 2 Add set 125M clock in PHY init function. - Add new patch5.
Minda Chen (8): usb: cdns3: Set USB PHY mode in cdns3_core_init_role() phy: starfive: Add Starfive JH7110 USB 2.0 PHY driver phy: starfive: Add Starfive JH7110 PCIe 2.0 PHY driver usb: cdns: starfive: Add cdns USB driver pinctrl: starfive: Setup USB default disable overcurrent pin configs: starfive: Add visionfive2 cadence USB configuration dts: starfive: Add JH7110 Cadence USB dts node MAINTAINERS: Update Starfive visionfive2 maintain files.
.../dts/jh7110-starfive-visionfive-2.dtsi | 5 + arch/riscv/dts/jh7110.dtsi | 52 +++++ board/starfive/visionfive2/MAINTAINERS | 2 + configs/starfive_visionfive2_defconfig | 9 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 21 ++ drivers/phy/starfive/Makefile | 7 + drivers/phy/starfive/phy-jh7110-pcie.c | 202
++++++++++++++++++
drivers/phy/starfive/phy-jh7110-usb2.c | 135 ++++++++++++ drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +- drivers/usb/cdns3/Kconfig | 7 + drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183
++++++++++++++++
drivers/usb/cdns3/core.c | 25 +++ 15 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
base-commit: 8937bb265a7f2251c1bd999784a4ef10e9c6080d
Thanks very much Minda, I am happy to see some USB Host function on Milk-V Mars CM Lite here. -E Shattow

On 7/4/24 07:50, Minda Chen wrote:
Add Starfive JH7110 Cadence USB driver and related PHY driver. So the codes can be used in visionfive2 and star64 7110 board.
The driver is almost the same with kernel driver.
Test with Star64 JH7110 board USB 3.0 + USB 2.0 host. The code can work.
- Star64 using USB 3.0 and USB 2.0 host must add below board dts setting.
Does this mean a future patch for spl_fdt_fixup_star64() is needed?
Did you also have a look at the USB on the Milk V Mars CM?
Best regards
Heinrich
Maybe the USB pin setting can be added to dts. But VF2 do not contain USB vbus pin defaut setting.
usb pin setting usb_pins: usb0-0 { driver-vbus-pin { pinmux = <GPIOMUX(25, GPOUT_SYS_USB_DRIVE_VBUS, GPOEN_ENABLE, GPI_NONE)>; bias-disable; input-disable; input-schmitt-disable; slew-rate = <0>; }; };
related dts node setting.
&pcie0 { status = "disabled"; };
&pciephy0 { starfive,sys-syscon = <&sys_syscon 0x18>; starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>; status = "okay"; };
&usb0 { pinctrl-names = "default"; pinctrl-0 = <&usb_pins>; status = "okay"; };
&usb_cdns3 { phys = <&usbphy0>, <&pciephy0>; phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy"; dr_mode = "host"; status = "okay"; };
- previous version v1:
https://patchwork.ozlabs.org/project/uboot/cover/20240504150358.19600-1- minda.chen@starfivetech.com/
- patch description.
patch1: Add set phy mode function in cdns3 core driver which is used by Starfive JH7110. patch2-3: USB and PCIe 2.0 (usb 3.0) PHY drivier patch4: Cadence USB wrapper driver. patch5: Add JH7110 USB default overcurrent pin. patch6-8 dts, config and maintainers update.
- change: v2:
- patch 1 Move the added code to cdns3_core_init_role(). Must set PHY mode before calling cdns3 role start function.
- patch 1-4 correct the code format.(follow Marek's comments.)
- patch 2 Add set 125M clock in PHY init function.
- Add new patch5.
Minda Chen (8): usb: cdns3: Set USB PHY mode in cdns3_core_init_role() phy: starfive: Add Starfive JH7110 USB 2.0 PHY driver phy: starfive: Add Starfive JH7110 PCIe 2.0 PHY driver usb: cdns: starfive: Add cdns USB driver pinctrl: starfive: Setup USB default disable overcurrent pin configs: starfive: Add visionfive2 cadence USB configuration dts: starfive: Add JH7110 Cadence USB dts node MAINTAINERS: Update Starfive visionfive2 maintain files.
.../dts/jh7110-starfive-visionfive-2.dtsi | 5 + arch/riscv/dts/jh7110.dtsi | 52 +++++ board/starfive/visionfive2/MAINTAINERS | 2 + configs/starfive_visionfive2_defconfig | 9 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/starfive/Kconfig | 21 ++ drivers/phy/starfive/Makefile | 7 + drivers/phy/starfive/phy-jh7110-pcie.c | 202
++++++++++++++++++
drivers/phy/starfive/phy-jh7110-usb2.c | 135 ++++++++++++ drivers/pinctrl/starfive/pinctrl-jh7110-sys.c | 11 +- drivers/usb/cdns3/Kconfig | 7 + drivers/usb/cdns3/Makefile | 2 + drivers/usb/cdns3/cdns3-starfive.c | 183 ++++++++++++++++ drivers/usb/cdns3/core.c | 25 +++ 15 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 drivers/phy/starfive/Kconfig create mode 100644 drivers/phy/starfive/Makefile create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c create mode 100644 drivers/phy/starfive/phy-jh7110-usb2.c create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
base-commit: 8937bb265a7f2251c1bd999784a4ef10e9c6080d
participants (4)
-
E Shattow
-
Heinrich Schuchardt
-
Minda Chen
-
Roger Quadros