[U-Boot] [PATCH v2 3/4] spi: sunxi: Add CLK support to Allwinner SPI driver

Andre Przywara andre.przywara at arm.com
Tue Feb 12 10:41:13 UTC 2019


From: Jagan Teki <jagan at amarulasolutions.com>

Add support for DM_CLK driven clocks and reset gates.

Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/spi/sun4i_spi.c | 83 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 66 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/sun4i_spi.c b/drivers/spi/sun4i_spi.c
index 61a5f3522e..c24b834227 100644
--- a/drivers/spi/sun4i_spi.c
+++ b/drivers/spi/sun4i_spi.c
@@ -19,7 +19,9 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
+#include <reset.h>
 #include <spi.h>
 #include <errno.h>
 #include <fdt_support.h>
@@ -114,6 +116,9 @@ struct sun4i_spi_platdata {
 
 struct sun4i_spi_priv {
 	struct sun4i_spi_regs *regs;
+	struct clk ahb_clk;
+	struct clk mod_clk;
+	struct reset_ctl rst_ctl;
 	u32 freq;
 	u32 mode;
 
@@ -239,23 +244,48 @@ static int sun4i_spi_parse_pins(struct udevice *dev)
 	return 0;
 }
 
-static void sun4i_spi_enable_clock(void)
+static int sun4i_spi_enable_clock(struct udevice *dev)
 {
-	struct sunxi_ccm_reg *const ccm =
-		(struct sunxi_ccm_reg *const)SUNXI_CCM_BASE;
+	struct sun4i_spi_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = clk_enable(&priv->ahb_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable ahb clock (ret=%d)\n", ret);
+		return ret;
+	}
+
+	ret = clk_enable(&priv->mod_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable mod clock (ret=%d)\n", ret);
+		goto err_ahb;
+	}
 
-	setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
-	writel((1 << 31), &ccm->spi0_clk_cfg);
+	if (reset_valid(&priv->rst_ctl))
+		ret = reset_deassert(&priv->rst_ctl);
+	if (ret) {
+		dev_err(dev, "failed to deassert reset gate (ret=%d)\n", ret);
+		goto err_mod;
+	}
+
+	return 0;
+
+err_mod:
+	clk_disable(&priv->mod_clk);
+err_ahb:
+	clk_disable(&priv->ahb_clk);
+
+	return ret;
 }
 
-static void sun4i_spi_disable_clock(void)
+static void sun4i_spi_disable_clock(struct udevice *dev)
 {
-	struct sunxi_ccm_reg *const ccm =
-		(struct sunxi_ccm_reg *const)SUNXI_CCM_BASE;
-
-	writel(0, &ccm->spi0_clk_cfg);
-	clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
+	struct sun4i_spi_priv *priv = dev_get_priv(dev);
 
+	clk_disable(&priv->ahb_clk);
+	clk_disable(&priv->mod_clk);
+	if (reset_valid(&priv->rst_ctl))
+		reset_assert(&priv->rst_ctl);
 }
 
 static int sun4i_spi_ofdata_to_platdata(struct udevice *bus)
@@ -274,12 +304,31 @@ static int sun4i_spi_ofdata_to_platdata(struct udevice *bus)
 	return 0;
 }
 
-static int sun4i_spi_probe(struct udevice *bus)
+static int sun4i_spi_probe(struct udevice *dev)
 {
-	struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
-	struct sun4i_spi_priv *priv = dev_get_priv(bus);
+	struct sun4i_spi_platdata *plat = dev_get_platdata(dev);
+	struct sun4i_spi_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = clk_get_by_name(dev, "ahb", &priv->ahb_clk);
+	if (ret) {
+		dev_err(dev, "failed to get ahb clock\n");
+		return ret;
+	}
+
+	ret = clk_get_by_name(dev, "mod", &priv->mod_clk);
+	if (ret) {
+		dev_err(dev, "failed to get mod clock\n");
+		return ret;
+	}
+
+	ret = reset_get_by_index(dev, 0, &priv->rst_ctl);
+	if (ret && ret != -ENOENT) {
+		dev_err(dev, "failed to get reset gate\n");
+		return ret;
+	}
 
-	sun4i_spi_parse_pins(bus);
+	sun4i_spi_parse_pins(dev);
 
 	priv->regs = (struct sun4i_spi_regs *)(uintptr_t)plat->base_addr;
 	priv->freq = plat->max_hz;
@@ -291,7 +340,7 @@ static int sun4i_spi_claim_bus(struct udevice *dev)
 {
 	struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
 
-	sun4i_spi_enable_clock();
+	sun4i_spi_enable_clock(dev->parent);
 
 	writel(SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP |
 	       SUN4I_CTL_CS_MANUAL | SUN4I_CTL_CS_ACTIVE_LOW,
@@ -309,7 +358,7 @@ static int sun4i_spi_release_bus(struct udevice *dev)
 	reg &= ~SUN4I_CTL_ENABLE;
 	writel(reg, &priv->regs->ctl);
 
-	sun4i_spi_disable_clock();
+	sun4i_spi_disable_clock(dev->parent);
 
 	return 0;
 }
-- 
2.14.5



More information about the U-Boot mailing list