[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <aCvo6h1wF7yrrzTV@jean.localdomain>
Date: Tue, 20 May 2025 10:28:58 +0800
From: Ze Huang <huangze@...t.edu.cn>
To: Neil Armstrong <neil.armstrong@...aro.org>,
Ze Huang <huangze@...t.edu.cn>, Vinod Koul <vkoul@...nel.org>,
Kishon Vijay Abraham I <kishon@...nel.org>,
Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>, Yixun Lan <dlan@...too.org>,
Philipp Zabel <p.zabel@...gutronix.de>
Cc: linux-phy@...ts.infradead.org, devicetree@...r.kernel.org,
linux-riscv@...ts.infradead.org, spacemit@...ts.linux.dev,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v3 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3
combo PHY
On Mon, May 19, 2025 at 03:10:24PM +0200, neil.armstrong@...aro.org wrote:
> On 17/05/2025 16:25, Ze Huang wrote:
> > Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY which
> > implements PIPE3(125MHz) interface for USB3.0. Currently, only USB mode
> > is supported; PCIe support is not included in this change.
>
> Please add proper comments in the code expliciting PCIe PHY is not yet
> implemented.
>
OK, will do
> >
> > Signed-off-by: Ze Huang <huangze@...t.edu.cn>
> > ---
> > drivers/phy/spacemit/Kconfig | 8 ++
> > drivers/phy/spacemit/Makefile | 1 +
> > drivers/phy/spacemit/phy-k1-combphy.c | 248 ++++++++++++++++++++++++++++++++++
> > 3 files changed, 257 insertions(+)
> >
> > diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
> > index 0136aee2e8a2f5f484da136b26f80130794b992c..ccc6bf9ea49f4988a27f79a4dcd024b18cbd78b0 100644
> > --- a/drivers/phy/spacemit/Kconfig
> > +++ b/drivers/phy/spacemit/Kconfig
> > @@ -11,3 +11,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/xhci driver.
> > +
> > +config PHY_SPACEMIT_K1_COMBPHY
> > + tristate "SpacemiT K1 PCIe/USB3 combo PHY support"
> > + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
> > + depends on COMMON_CLK
> > + select GENERIC_PHY
> > + 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..1f2ee3351e2bb5adf04e4e2fcfdb03cd75f70847
> > --- /dev/null
> > +++ b/drivers/phy/spacemit/phy-k1-combphy.c
> > @@ -0,0 +1,248 @@
> > +// 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@...t.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_TERM_SHORT_MASK 0x3000
> > +#define COMBPHY_USB_TERM_SHORT_VAL 0x3000
> > +#define COMBPHY_USB_PLL_REG 0x08
> > +#define COMBPHY_USB_PLL_MASK 0x01
> > +#define COMBPHY_USB_PLL_VAL 0x01
> > +#define COMBPHY_USB_LFPS_REG 0x58
> > +#define COMBPHY_USB_LFPS_MASK 0x700
> > +#define COMBPHY_USB_LFPS_THRES_DEFAULT 0x03
> > +
> > +#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;
> > + bool rx_always_on;
> > + u8 lfps_threshold;
> > + 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);
> > +}
>
> With regmap you could avoid this and directly use regmap_update_bits(), same for patch 3
>
Will follow
> > +
> > +static int spacemit_combphy_wait_ready(struct spacemit_combphy_priv *priv,
> > + u32 offset, u32 mask, u32 val)
> > +{
> > + u32 reg_val;
> > +
> > + return read_poll_timeout(readl, reg_val, (reg_val & mask) == val,
> > + 1000, COMBPHY_WAIT_TIMEOUT * 1000, false,
> > + priv->phy_ctrl + offset);
> > +}
>
> It's used once, no need to add a separate function, and with regmap you could use regmap_read_poll_timeout()
>
Will follow
> > +
> > +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);
> > +
> > + dev_dbg(priv->dev, "USB3 PHY init lfps threshold %d\n", priv->lfps_threshold);
> > + spacemit_reg_update(base, COMBPHY_USB_LFPS_REG,
> > + COMBPHY_USB_LFPS_MASK,
> > + (priv->lfps_threshold << 8));
> > +
> > + if (priv->rx_always_on)
> > + spacemit_reg_update(base, COMBPHY_USB_REG4,
> > + COMBPHY_USB_TERM_SHORT_MASK,
> > + COMBPHY_USB_TERM_SHORT_VAL);
> > +
> > + if (ret)
> > + dev_err(priv->dev, "USB3 PHY init timeout!\n");
>
> You're leaving the PHY initialized, even on a timeout, is it expected ?
>
You're right. I overlooked that case.
Will move dev_err and return logic next to phy init.
Thanks!
Powered by blists - more mailing lists