public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH] phy: phy-imx8mq-usb: Add support for i.MX8MP USB PHY
@ 2022-04-01  1:18 Marek Vasut
  2022-04-07 22:21 ` Tim Harvey
  0 siblings, 1 reply; 2+ messages in thread
From: Marek Vasut @ 2022-04-01  1:18 UTC (permalink / raw)
  To: u-boot; +Cc: Marek Vasut, Fabio Estevam, Peng Fan, Stefano Babic

Add initial support for i.MX8MP USB PHY, i.MX8MP USB is similar to
the i.MX8MQ, except for clock and power domain design customization.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Peng Fan <peng.fan@nxp.com>
Cc: Stefano Babic <sbabic@denx.de>
---
 drivers/phy/Kconfig          |  6 ++--
 drivers/phy/phy-imx8mq-usb.c | 66 +++++++++++++++++++++++++++++++++---
 2 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index d79798429b1..c01d9e09b90 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -275,11 +275,11 @@ config PHY_MTK_TPHY
 	  so you can easily distinguish them by banks layout.
 
 config PHY_IMX8MQ_USB
-	bool "NXP i.MX8MQ USB PHY Driver"
+	bool "NXP i.MX8MQ/i.MX8MP USB PHY Driver"
 	depends on PHY
-	depends on IMX8MQ
+	depends on IMX8MQ || IMX8MP
 	help
-	  Support the USB3.0 PHY in NXP i.MX8MQ SoC
+	  Support the USB3.0 PHY in NXP i.MX8MQ or i.MX8MP SoC
 
 config PHY_XILINX_ZYNQMP
 	tristate "Xilinx ZynqMP PHY driver"
diff --git a/drivers/phy/phy-imx8mq-usb.c b/drivers/phy/phy-imx8mq-usb.c
index afbc7ad8dd4..69f01de5553 100644
--- a/drivers/phy/phy-imx8mq-usb.c
+++ b/drivers/phy/phy-imx8mq-usb.c
@@ -9,7 +9,9 @@
 #include <dm.h>
 #include <errno.h>
 #include <generic-phy.h>
+#include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <clk.h>
 
@@ -68,17 +70,22 @@
 #define PHY_STS0_FSVPLUS		BIT(3)
 #define PHY_STS0_FSVMINUS		BIT(2)
 
+enum imx8mpq_phy_type {
+	IMX8MQ_PHY,
+	IMX8MP_PHY,
+};
+
 struct imx8mq_usb_phy {
 #if CONFIG_IS_ENABLED(CLK)
 	struct clk phy_clk;
 #endif
 	void __iomem *base;
+	enum imx8mpq_phy_type type;
 };
 
 static const struct udevice_id imx8mq_usb_phy_of_match[] = {
-	{
-		.compatible = "fsl,imx8mq-usb-phy",
-	},
+	{ .compatible = "fsl,imx8mq-usb-phy", .data = IMX8MQ_PHY },
+	{ .compatible = "fsl,imx8mp-usb-phy", .data = IMX8MP_PHY },
 	{},
 };
 
@@ -111,6 +118,56 @@ static int imx8mq_usb_phy_init(struct phy *usb_phy)
 	return 0;
 }
 
+static int imx8mp_usb_phy_init(struct phy *usb_phy)
+{
+	struct udevice *dev = usb_phy->dev;
+	struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev);
+	u32 value;
+
+	/* USB3.0 PHY signal fsel for 24M ref */
+	value = readl(imx_phy->base + PHY_CTRL0);
+	value &= ~PHY_CTRL0_FSEL_MASK;
+	value |= FIELD_PREP(PHY_CTRL0_FSEL_MASK, PHY_CTRL0_FSEL_24M);
+	writel(value, imx_phy->base + PHY_CTRL0);
+
+	/* Disable alt_clk_en and use internal MPLL clocks */
+	value = readl(imx_phy->base + PHY_CTRL6);
+	value &= ~(PHY_CTRL6_ALT_CLK_SEL | PHY_CTRL6_ALT_CLK_EN);
+	writel(value, imx_phy->base + PHY_CTRL6);
+
+	value = readl(imx_phy->base + PHY_CTRL1);
+	value &= ~(PHY_CTRL1_VDATSRCENB0 | PHY_CTRL1_VDATDETENB0);
+	value |= PHY_CTRL1_RESET | PHY_CTRL1_ATERESET;
+	writel(value, imx_phy->base + PHY_CTRL1);
+
+	value = readl(imx_phy->base + PHY_CTRL0);
+	value |= PHY_CTRL0_REF_SSP_EN;
+	writel(value, imx_phy->base + PHY_CTRL0);
+
+	value = readl(imx_phy->base + PHY_CTRL2);
+	value |= PHY_CTRL2_TXENABLEN0 | PHY_CTRL2_OTG_DISABLE;
+	writel(value, imx_phy->base + PHY_CTRL2);
+
+	udelay(10);
+
+	value = readl(imx_phy->base + PHY_CTRL1);
+	value &= ~(PHY_CTRL1_RESET | PHY_CTRL1_ATERESET);
+	writel(value, imx_phy->base + PHY_CTRL1);
+
+	return 0;
+}
+
+static int imx8mpq_usb_phy_init(struct phy *usb_phy)
+{
+	struct udevice *dev = usb_phy->dev;
+	struct imx8mq_usb_phy *imx_phy = dev_get_priv(dev);
+
+	if (imx_phy->type == IMX8MP_PHY)
+		return imx8mp_usb_phy_init(usb_phy);
+	else
+		return imx8mq_usb_phy_init(usb_phy);
+}
+
 static int imx8mq_usb_phy_power_on(struct phy *usb_phy)
 {
 	struct udevice *dev = usb_phy->dev;
@@ -158,7 +215,7 @@ static int imx8mq_usb_phy_exit(struct phy *usb_phy)
 }
 
 struct phy_ops imx8mq_usb_phy_ops = {
-	.init = imx8mq_usb_phy_init,
+	.init = imx8mpq_usb_phy_init,
 	.power_on = imx8mq_usb_phy_power_on,
 	.power_off = imx8mq_usb_phy_power_off,
 	.exit = imx8mq_usb_phy_exit,
@@ -168,6 +225,7 @@ int imx8mq_usb_phy_probe(struct udevice *dev)
 {
 	struct imx8mq_usb_phy *priv = dev_get_priv(dev);
 
+	priv->type = dev_get_driver_data(dev);
 	priv->base = dev_read_addr_ptr(dev);
 
 	if (!priv->base)
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-04-07 22:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-04-01  1:18 [PATCH] phy: phy-imx8mq-usb: Add support for i.MX8MP USB PHY Marek Vasut
2022-04-07 22:21 ` Tim Harvey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox