[U-Boot] [PATCH 06/10] spi: sun4i: Add CLK support

Jagan Teki jagan at amarulasolutions.com
Sat Feb 9 13:14:56 UTC 2019


Add CLK support to enable AHB and MOD SPI clocks on sun4i_spi driver.

Note, that the code will enable and disable clock in claim and release
calls to make proper clock and reset handling between claiming and
releasing SPI bus.

Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 drivers/spi/sun4i_spi.c | 56 +++++++++++++++++++++++++++++++++++------
 1 file changed, 48 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/sun4i_spi.c b/drivers/spi/sun4i_spi.c
index d3cf25db6f..aeed68764c 100644
--- a/drivers/spi/sun4i_spi.c
+++ b/drivers/spi/sun4i_spi.c
@@ -19,6 +19,7 @@
  */
 
 #include <common.h>
+#include <clk.h>
 #include <dm.h>
 #include <spi.h>
 #include <errno.h>
@@ -29,8 +30,6 @@
 #include <asm/gpio.h>
 #include <asm/io.h>
 
-#include <asm/arch/clock.h>
-
 #include <linux/iopoll.h>
 
 #define SUN4I_RXDATA_REG	0x00
@@ -133,6 +132,7 @@ struct sun4i_spi_platdata {
 
 struct sun4i_spi_priv {
 	struct sun4i_spi_variant *variant;
+	struct clk clk_ahb, clk_mod;
 	u32 base_addr;
 	u32 freq;
 	u32 mode;
@@ -263,13 +263,34 @@ static int sun4i_spi_parse_pins(struct udevice *dev)
 	return 0;
 }
 
-static inline void sun4i_spi_enable_clock(void)
+static inline int sun4i_spi_set_clock(struct udevice *dev, bool enable)
 {
-	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;
+
+	if (!enable) {
+		clk_disable(&priv->clk_ahb);
+		clk_disable(&priv->clk_mod);
+		return 0;
+	}
 
-	setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
-	writel((1 << 31), &ccm->spi0_clk_cfg);
+	ret = clk_enable(&priv->clk_ahb);
+	if (ret) {
+		dev_err(dev, "failed to enable ahb clock (ret=%d)\n", ret);
+		return ret;
+	}
+
+	ret = clk_enable(&priv->clk_mod);
+	if (ret) {
+		dev_err(dev, "failed to enable mod clock (ret=%d)\n", ret);
+		goto err_ahb;
+	}
+
+	return 0;
+
+err_ahb:
+	clk_disable(&priv->clk_ahb);
+	return ret;
 }
 
 static int sun4i_spi_ofdata_to_platdata(struct udevice *bus)
@@ -293,8 +314,20 @@ static int sun4i_spi_probe(struct udevice *bus)
 {
 	struct sun4i_spi_platdata *plat = dev_get_platdata(bus);
 	struct sun4i_spi_priv *priv = dev_get_priv(bus);
+	int ret;
+
+	ret = clk_get_by_name(bus, "ahb", &priv->clk_ahb);
+	if (ret) {
+		dev_err(dev, "failed to get ahb clock\n");
+		return ret;
+	}
+
+	ret = clk_get_by_name(bus, "mod", &priv->clk_mod);
+	if (ret) {
+		dev_err(dev, "failed to get mod clock\n");
+		return ret;
+	}
 
-	sun4i_spi_enable_clock();
 	sun4i_spi_parse_pins(bus);
 
 	priv->variant = plat->variant;
@@ -308,6 +341,11 @@ static int sun4i_spi_claim_bus(struct udevice *dev)
 {
 	struct sun4i_spi_priv *priv = dev_get_priv(dev->parent);
 	struct sun4i_spi_variant *variant = priv->variant;
+	int ret;
+
+	ret = sun4i_spi_set_clock(dev->parent, true);
+	if (ret)
+		return ret;
 
 	setbits_le32(priv->base_addr + variant->regs[SPI_GCR],
 		     SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER |
@@ -328,6 +366,8 @@ static int sun4i_spi_release_bus(struct udevice *dev)
 	clrbits_le32(priv->base_addr + variant->regs[SPI_GCR],
 		     SUN4I_CTL_ENABLE);
 
+	sun4i_spi_set_clock(dev->parent, false);
+
 	return 0;
 }
 
-- 
2.18.0.321.gffc6fa0e3



More information about the U-Boot mailing list