Message ID | 20250407-b4-k1-usb3-v3-2-v1-5-bf0bcc41c9ba@whut.edu.cn (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add USB3.0 PHY and host controller support for SpacemiT K1 SoC | expand |
On 07/04/2025 14:38, Ze Huang wrote: > Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY. Currently, > only USB mode is supported; PCIe support is not included in this change. > > Signed-off-by: Ze Huang <huangze@whut.edu.cn> > --- > drivers/phy/spacemit/Kconfig | 8 ++ > drivers/phy/spacemit/Makefile | 1 + > drivers/phy/spacemit/phy-k1-combphy.c | 229 ++++++++++++++++++++++++++++++++++ > 3 files changed, 238 insertions(+) > > diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig > index f0c2a33f53cc810e71c6140ae957aa68a2b6ff0c..12749aba756329cf64fb9199055ba484fe05f3ab 100644 > --- a/drivers/phy/spacemit/Kconfig > +++ b/drivers/phy/spacemit/Kconfig > @@ -10,3 +10,11 @@ config PHY_SPACEMIT_K1_USB2 > help > Enable this to support K1 USB 2.0 PHY driver. This driver takes care of > enabling and clock setup and will be used by K1 udc/ehci/otg driver. > + > +config PHY_SPACEMIT_K1_COMBPHY > + tristate "SpacemiT K1 PCIe/USB3 combo PHY support" > + depends on OF > + select GENERIC_PHY > + default ARCH_SPACEMIT && USB_DWC3_SPACEMIT > + help > + USB3/PCIe Combo PHY Support for SpacemiT K1 SoC Missing depends on ARCH_SPACEMIT || COMPILE_TEST ... > + priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops); > + if (IS_ERR(priv->phy)) > + return dev_err_probe(dev, PTR_ERR(priv->phy), > + "failed to create combphy\n"); > + > + dev_set_drvdata(dev, priv); > + phy_set_drvdata(priv->phy, priv); Both make no sense. Look what this function does. Best regards, Krzysztof
On 4/7/25 9:28 PM, Krzysztof Kozlowski wrote: > On 07/04/2025 14:38, Ze Huang wrote: >> Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY. Currently, >> only USB mode is supported; PCIe support is not included in this change. >> >> Signed-off-by: Ze Huang <huangze@whut.edu.cn> >> --- >> drivers/phy/spacemit/Kconfig | 8 ++ >> drivers/phy/spacemit/Makefile | 1 + >> drivers/phy/spacemit/phy-k1-combphy.c | 229 ++++++++++++++++++++++++++++++++++ >> 3 files changed, 238 insertions(+) >> >> diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig >> index f0c2a33f53cc810e71c6140ae957aa68a2b6ff0c..12749aba756329cf64fb9199055ba484fe05f3ab 100644 >> --- a/drivers/phy/spacemit/Kconfig >> +++ b/drivers/phy/spacemit/Kconfig >> @@ -10,3 +10,11 @@ config PHY_SPACEMIT_K1_USB2 >> help >> Enable this to support K1 USB 2.0 PHY driver. This driver takes care of >> enabling and clock setup and will be used by K1 udc/ehci/otg driver. >> + >> +config PHY_SPACEMIT_K1_COMBPHY >> + tristate "SpacemiT K1 PCIe/USB3 combo PHY support" >> + depends on OF >> + select GENERIC_PHY >> + default ARCH_SPACEMIT && USB_DWC3_SPACEMIT >> + help >> + USB3/PCIe Combo PHY Support for SpacemiT K1 SoC > Missing depends on ARCH_SPACEMIT || COMPILE_TEST Will fix, thanks! > > ... > > >> + priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops); >> + if (IS_ERR(priv->phy)) >> + return dev_err_probe(dev, PTR_ERR(priv->phy), >> + "failed to create combphy\n"); >> + >> + dev_set_drvdata(dev, priv); >> + phy_set_drvdata(priv->phy, priv); > Both make no sense. Look what this function does. It does seem redundant at first glance, but pdev->dev is the parent of phy->dev. pdev->dev->driver_data will be used in spacemit_combphy_xlate() phy->dev->driver_data will be used in phy_ops functions I've checked some other drivers that did the same: - phy-zynqmp.c at lines 990 and 1026 - phy-rockchip-samsung-hdptx.c at lines 1989 and 2000 > > Best regards, > Krzysztof > >
On 09/04/2025 11:43, Ze Huang wrote: >>> + priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops); >>> + if (IS_ERR(priv->phy)) >>> + return dev_err_probe(dev, PTR_ERR(priv->phy), >>> + "failed to create combphy\n"); >>> + >>> + dev_set_drvdata(dev, priv); >>> + phy_set_drvdata(priv->phy, priv); >> Both make no sense. Look what this function does. > > It does seem redundant at first glance, but pdev->dev is the parent of > phy->dev. > pdev->dev->driver_data will be used in spacemit_combphy_xlate() > phy->dev->driver_data will be used in phy_ops functions > > I've checked some other drivers that did the same: > - phy-zynqmp.c at lines 990 and 1026 > - phy-rockchip-samsung-hdptx.c at lines 1989 and 2000 Indeed, right. It's fine. Best regards, Krzysztof
Hi Ze,
> +static int spacemit_combphy_init_usb(struct spacemit_combphy_priv *priv)
The USB3 phy driver is updated in the vendor's tree.
https://gitee.com/bianbu-linux/linux-6.6/commit/1c0b3b4b9c77d22ca886c8a4c44e62b5891f8abc
You can submit v2 together with the change of lfps_thres (writes 0x58 register)
without adding new properties for dt node.
B.R.
This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.
本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
On 4/9/25 7:38 PM, Pan Junzhong wrote: > Hi Ze, > >> +static int spacemit_combphy_init_usb(struct spacemit_combphy_priv *priv) > The USB3 phy driver is updated in the vendor's tree. > https://gitee.com/bianbu-linux/linux-6.6/commit/1c0b3b4b9c77d22ca886c8a4c44e62b5891f8abc > > You can submit v2 together with the change of lfps_thres (writes 0x58 register) > without adding new properties for dt node. OK, thanks! > B.R. > > > This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking. > > 本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。
diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig index f0c2a33f53cc810e71c6140ae957aa68a2b6ff0c..12749aba756329cf64fb9199055ba484fe05f3ab 100644 --- a/drivers/phy/spacemit/Kconfig +++ b/drivers/phy/spacemit/Kconfig @@ -10,3 +10,11 @@ config PHY_SPACEMIT_K1_USB2 help Enable this to support K1 USB 2.0 PHY driver. This driver takes care of enabling and clock setup and will be used by K1 udc/ehci/otg driver. + +config PHY_SPACEMIT_K1_COMBPHY + tristate "SpacemiT K1 PCIe/USB3 combo PHY support" + depends on OF + select GENERIC_PHY + default ARCH_SPACEMIT && USB_DWC3_SPACEMIT + help + USB3/PCIe Combo PHY Support for SpacemiT K1 SoC diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile index fec0b425a948541b39b814caef0b05e1e002d92f..1fd0c65f2c5cd10ea2f70e43e62c70588d1ffae9 100644 --- a/drivers/phy/spacemit/Makefile +++ b/drivers/phy/spacemit/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PHY_SPACEMIT_K1_COMBPHY) += phy-k1-combphy.o obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o diff --git a/drivers/phy/spacemit/phy-k1-combphy.c b/drivers/phy/spacemit/phy-k1-combphy.c new file mode 100644 index 0000000000000000000000000000000000000000..a4b6e77fc2b4eb5d2c45d4e76294083509a3fc9d --- /dev/null +++ b/drivers/phy/spacemit/phy-k1-combphy.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Spacemit K1 PCIE/USB3 PHY driver + * + * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd + * Copyright (C) 2025 Ze Huang <huangze@whut.edu.cn> + */ + +#include <dt-bindings/phy/phy.h> +#include <linux/clk.h> +#include <linux/iopoll.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/reset.h> +#include <linux/usb/of.h> + +#define COMBPHY_USB_REG1 0x68 +#define COMBPHY_USB_REG1_VAL 0x00 +#define COMBPHY_USB_REG2 0x48 +#define COMBPHY_USB_REG2_VAL 0x603a2276 +#define COMBPHY_USB_REG3 0x08 +#define COMBPHY_USB_REG3_VAL 0x97c +#define COMBPHY_USB_REG4 0x18 +#define COMBPHY_USB_REG4_VAL 0x00 +#define COMBPHY_USB_PLL_REG 0x08 +#define COMBPHY_USB_PLL_MASK 0x01 +#define COMBPHY_USB_PLL_VAL 0x01 + +#define COMBPHY_MODE_SEL BIT(3) +#define COMBPHY_WAIT_TIMEOUT 1000 + +struct spacemit_combphy_priv { + struct device *dev; + struct phy *phy; + struct reset_control *phy_rst; + void __iomem *phy_ctrl; + void __iomem *phy_sel; + u8 type; +}; + +static void spacemit_reg_update(void __iomem *reg, u32 offset, u32 mask, u32 val) +{ + u32 tmp; + + tmp = readl(reg + offset); + tmp = (tmp & ~(mask)) | val; + writel(tmp, reg + offset); +} + +static int spacemit_combphy_wait_ready(struct spacemit_combphy_priv *priv, + u32 offset, u32 mask, u32 val) +{ + u32 reg_val; + int ret = 0; + + ret = read_poll_timeout(readl, reg_val, (reg_val & mask) == val, + 1000, COMBPHY_WAIT_TIMEOUT * 1000, false, + priv->phy_ctrl + offset); + + return ret; +} + +static int spacemit_combphy_set_mode(struct spacemit_combphy_priv *priv) +{ + int ret = 0; + + switch (priv->type) { + case PHY_TYPE_USB3: + spacemit_reg_update(priv->phy_sel, 0, 0, COMBPHY_MODE_SEL); + break; + default: + dev_err(priv->dev, "PHY type %x not supported\n", priv->type); + ret = -EINVAL; + break; + } + + return ret; +} + +static int spacemit_combphy_init_usb(struct spacemit_combphy_priv *priv) +{ + void __iomem *base = priv->phy_ctrl; + int ret; + + writel(COMBPHY_USB_REG1_VAL, base + COMBPHY_USB_REG1); + writel(COMBPHY_USB_REG2_VAL, base + COMBPHY_USB_REG2); + writel(COMBPHY_USB_REG3_VAL, base + COMBPHY_USB_REG3); + writel(COMBPHY_USB_REG4_VAL, base + COMBPHY_USB_REG4); + + ret = spacemit_combphy_wait_ready(priv, COMBPHY_USB_PLL_REG, + COMBPHY_USB_PLL_MASK, + COMBPHY_USB_PLL_VAL); + if (ret) + dev_err(priv->dev, "USB3 PHY init timeout!\n"); + + return ret; +} + +static int spacemit_combphy_init(struct phy *phy) +{ + struct spacemit_combphy_priv *priv = phy_get_drvdata(phy); + int ret; + + ret = spacemit_combphy_set_mode(priv); + if (ret) { + dev_err(priv->dev, "failed to set mode for PHY type %x\n", + priv->type); + goto out; + } + + ret = reset_control_deassert(priv->phy_rst); + if (ret) { + dev_err(priv->dev, "failed to deassert rst\n"); + goto err_rst; + } + + switch (priv->type) { + case PHY_TYPE_USB3: + ret = spacemit_combphy_init_usb(priv); + break; + default: + dev_err(priv->dev, "PHY type %x not supported\n", priv->type); + ret = -EINVAL; + break; + } + + if (ret) + goto err_rst; + + return 0; + +err_rst: + reset_control_assert(priv->phy_rst); +out: + return ret; +} + +static int spacemit_combphy_exit(struct phy *phy) +{ + struct spacemit_combphy_priv *priv = phy_get_drvdata(phy); + + reset_control_assert(priv->phy_rst); + + return 0; +} + +static struct phy *spacemit_combphy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct spacemit_combphy_priv *priv = dev_get_drvdata(dev); + + if (args->args_count != 1) { + dev_err(dev, "invalid number of arguments\n"); + return ERR_PTR(-EINVAL); + } + + if (priv->type != PHY_NONE && priv->type != args->args[0]) + dev_warn(dev, "PHY type %d is selected to override %d\n", + args->args[0], priv->type); + + priv->type = args->args[0]; + + if (args->args_count > 1) + dev_dbg(dev, "combo phy idx: %d selected", args->args[1]); + + return priv->phy; +} + +static const struct phy_ops spacemit_combphy_ops = { + .init = spacemit_combphy_init, + .exit = spacemit_combphy_exit, + .owner = THIS_MODULE, +}; + +static int spacemit_combphy_probe(struct platform_device *pdev) +{ + struct spacemit_combphy_priv *priv; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->phy_ctrl = devm_platform_ioremap_resource_byname(pdev, "phy_ctrl"); + if (IS_ERR(priv->phy_ctrl)) + return PTR_ERR(priv->phy_ctrl); + + priv->phy_sel = devm_platform_ioremap_resource_byname(pdev, "phy_sel"); + if (IS_ERR(priv->phy_sel)) + return PTR_ERR(priv->phy_sel); + + priv->type = PHY_NONE; + priv->dev = dev; + + priv->phy_rst = devm_reset_control_get(dev, NULL); + if (IS_ERR(priv->phy_rst)) + return dev_err_probe(dev, PTR_ERR(priv->phy_rst), + "failed to get phy reset\n"); + + priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops); + if (IS_ERR(priv->phy)) + return dev_err_probe(dev, PTR_ERR(priv->phy), + "failed to create combphy\n"); + + dev_set_drvdata(dev, priv); + phy_set_drvdata(priv->phy, priv); + phy_provider = devm_of_phy_provider_register(dev, spacemit_combphy_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id spacemit_combphy_of_match[] = { + { .compatible = "spacemit,k1-combphy", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spacemit_combphy_of_match); + +static struct platform_driver spacemit_combphy_driver = { + .probe = spacemit_combphy_probe, + .driver = { + .name = "spacemit-k1-combphy", + .of_match_table = spacemit_combphy_of_match, + }, +}; +module_platform_driver(spacemit_combphy_driver); + +MODULE_DESCRIPTION("Spacemit PCIE/USB3.0 COMBO PHY driver"); +MODULE_LICENSE("GPL");
Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY. Currently, only USB mode is supported; PCIe support is not included in this change. Signed-off-by: Ze Huang <huangze@whut.edu.cn> --- drivers/phy/spacemit/Kconfig | 8 ++ drivers/phy/spacemit/Makefile | 1 + drivers/phy/spacemit/phy-k1-combphy.c | 229 ++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+)