[PATCH 4/7] imx8mp: power-domain: Expose high performance PLL clock
Sumit Garg
sumit.garg at linaro.org
Tue Feb 20 14:10:53 CET 2024
PCIe PHY can use it when there is no external refclock provided.
Signed-off-by: Sumit Garg <sumit.garg at linaro.org>
---
drivers/power/domain/imx8mp-hsiomix.c | 79 +++++++++++++++++++++++++--
1 file changed, 73 insertions(+), 6 deletions(-)
diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c
index 62145e0261b..4cefe642724 100644
--- a/drivers/power/domain/imx8mp-hsiomix.c
+++ b/drivers/power/domain/imx8mp-hsiomix.c
@@ -9,6 +9,8 @@
#include <dm.h>
#include <dm/device.h>
#include <dm/device_compat.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
#include <power-domain-uclass.h>
#include <dt-bindings/power/imx8mp-power.h>
@@ -18,6 +20,15 @@
#define USB_CLOCK_MODULE_EN BIT(1)
#define PCIE_PHY_APB_RST BIT(4)
#define PCIE_PHY_INIT_RST BIT(5)
+#define GPR_REG1 0x4
+#define PLL_LOCK BIT(13)
+#define GPR_REG2 0x8
+#define P_PLL_MASK GENMASK(5, 0)
+#define M_PLL_MASK GENMASK(15, 6)
+#define S_PLL_MASK GENMASK(18, 16)
+#define GPR_REG3 0xc
+#define PLL_CKE BIT(17)
+#define PLL_RST BIT(31)
struct imx8mp_hsiomix_priv {
void __iomem *base;
@@ -31,6 +42,53 @@ struct imx8mp_hsiomix_priv {
struct power_domain pd_pcie_phy;
};
+static int hsio_pll_enable(struct udevice *dev)
+{
+ struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev);
+ unsigned long start;
+ u32 val;
+
+ /* Setup HSIO PLL */
+ val = readl(priv->base + GPR_REG2);
+ val &= ~(P_PLL_MASK | M_PLL_MASK | S_PLL_MASK);
+ val |= (FIELD_PREP(P_PLL_MASK, 12) | FIELD_PREP(M_PLL_MASK, 800) |
+ FIELD_PREP(S_PLL_MASK, 4));
+ writel(val, priv->base + GPR_REG2);
+
+ /* de-assert PLL reset */
+ setbits_le32(priv->base + GPR_REG3, PLL_RST);
+
+ /* enable PLL */
+ setbits_le32(priv->base + GPR_REG3, PLL_CKE);
+
+ /* Check if PLL is locked */
+ start = get_timer(0);
+ for (;;) {
+ if (readl(priv->base + GPR_REG1) & PLL_LOCK)
+ break;
+
+ if (get_timer(start) > 100) {
+ dev_err(dev, "failed to lock HSIO PLL\n");
+ return -ETIMEDOUT;
+ }
+
+ udelay(10);
+ }
+
+ return 0;
+}
+
+static void hsio_pll_disable(struct udevice *dev)
+{
+ struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev);
+
+ /* de-assert PLL reset */
+ clrbits_le32(priv->base + GPR_REG3, PLL_RST);
+
+ /* enable PLL */
+ clrbits_le32(priv->base + GPR_REG3, PLL_CKE);
+}
+
static int imx8mp_hsiomix_on(struct power_domain *power_domain)
{
struct udevice *dev = power_domain->dev;
@@ -69,16 +127,23 @@ static int imx8mp_hsiomix_on(struct power_domain *power_domain)
if (ret)
goto err_clk_pcie;
- if (power_domain->id == IMX8MP_HSIOBLK_PD_USB)
+ if (power_domain->id == IMX8MP_HSIOBLK_PD_USB) {
setbits_le32(priv->base + GPR_REG0, USB_CLOCK_MODULE_EN);
- else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE)
+ } else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE) {
setbits_le32(priv->base + GPR_REG0, PCIE_CLOCK_MODULE_EN);
- else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE_PHY)
+ } else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE_PHY) {
setbits_le32(priv->base + GPR_REG0, PCIE_PHY_APB_RST |
PCIE_PHY_INIT_RST);
+ ret = hsio_pll_enable(dev);
+ if (ret)
+ goto err_hsio_pll;
+ }
+
return 0;
+err_hsio_pll:
+ clk_disable(&priv->clk_pcie);
err_clk_pcie:
clk_disable(&priv->clk_usb);
err_clk_usb:
@@ -93,13 +158,15 @@ static int imx8mp_hsiomix_off(struct power_domain *power_domain)
struct udevice *dev = power_domain->dev;
struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev);
- if (power_domain->id == IMX8MP_HSIOBLK_PD_USB)
+ if (power_domain->id == IMX8MP_HSIOBLK_PD_USB) {
clrbits_le32(priv->base + GPR_REG0, USB_CLOCK_MODULE_EN);
- else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE)
+ } else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE) {
clrbits_le32(priv->base + GPR_REG0, PCIE_CLOCK_MODULE_EN);
- else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE_PHY)
+ } else if (power_domain->id == IMX8MP_HSIOBLK_PD_PCIE_PHY) {
clrbits_le32(priv->base + GPR_REG0, PCIE_PHY_APB_RST |
PCIE_PHY_INIT_RST);
+ hsio_pll_disable(dev);
+ }
clk_disable(&priv->clk_usb);
clk_disable(&priv->clk_pcie);
--
2.34.1
More information about the U-Boot
mailing list