[U-Boot] [PATCH 1/8] rockchip: clk: rk3399: add clock support for SCLK_SPI1 and SCLK_SPI5

Philipp Tomsich philipp.tomsich at theobroma-systems.com
Tue Mar 28 08:58:30 UTC 2017


This change adds support for configuring the module clocks for SPI1 and
SPI5 from the 594MHz GPLL.

Note that the driver (rk_spi.c) always sets this to 99MHz, but the
implemented functionality is more general and will also support
different clock configurations.

X-AffectedPlatforms: RK3399-Q7
Signed-off-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com>
Tested-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
---

 drivers/clk/rockchip/clk_rk3399.c | 69 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index f778ddf..b7c5a35 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -605,6 +605,67 @@ static ulong rk3399_i2c_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
 	return DIV_TO_RATE(GPLL_HZ, src_clk_div);
 }
 
+#define SPI_CLK_REG_MASK(bus) \
+			(CLK_SPI_PLL_DIV_CON_MASK << \
+			CLK_SPI ##bus## _PLL_DIV_CON_SHIFT | \
+			CLK_SPI_PLL_SEL_MASK << \
+			CLK_SPI ##bus## _PLL_SEL_SHIFT)
+
+#define SPI_CLK_REG_VALUE(bus, clk_div) \
+			      ((clk_div - 1) << \
+					CLK_SPI ##bus## _PLL_DIV_CON_SHIFT | \
+			      CLK_SPI_PLL_SEL_GPLL << \
+					CLK_SPI ##bus## _PLL_SEL_SHIFT)
+
+#define SPI_CLK_DIV_VALUE(con, bus) \
+			(con >> CLK_SPI ##bus## _PLL_DIV_CON_SHIFT) & \
+				CLK_SPI_PLL_DIV_CON_MASK;
+
+static ulong rk3399_spi_get_clk(struct rk3399_cru *cru, ulong clk_id)
+{
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_SPI1:
+		con = readl(&cru->clksel_con[59]);
+		div = SPI_CLK_DIV_VALUE(con, 1);
+		break;
+	case SCLK_SPI5:
+		con = readl(&cru->clksel_con[58]);
+		div = SPI_CLK_DIV_VALUE(con, 5);
+		break;
+	default:
+		error("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(GPLL_HZ, div);
+}
+
+static ulong rk3399_spi_set_clk(struct rk3399_cru *cru, ulong clk_id, uint hz)
+{
+	int src_clk_div;
+
+	src_clk_div = GPLL_HZ / hz;
+	assert((src_clk_div - 1) < 127);
+
+	switch (clk_id) {
+	case SCLK_SPI1:
+		rk_clrsetreg(&cru->clksel_con[59], SPI_CLK_REG_MASK(1),
+			     I2C_CLK_REG_VALUE(1, src_clk_div));
+		break;
+	case SCLK_SPI5:
+		rk_clrsetreg(&cru->clksel_con[58], I2C_CLK_REG_MASK(5),
+			     I2C_CLK_REG_VALUE(5, src_clk_div));
+		break;
+	default:
+		error("%s: SPI clk-id %ld not supported\n", __func__, clk_id);
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(GPLL_HZ, src_clk_div);
+}
+
 static ulong rk3399_vop_set_clk(struct rk3399_cru *cru, ulong clk_id, u32 hz)
 {
 	struct pll_div vpll_config = {0};
@@ -780,6 +841,10 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
 	case SCLK_I2C7:
 		rate = rk3399_i2c_get_clk(priv->cru, clk->id);
 		break;
+	case SCLK_SPI1:
+	case SCLK_SPI5:
+		rate = rk3399_spi_get_clk(priv->cru, clk->id);
+		break;
 	case SCLK_UART0:
 	case SCLK_UART2:
 		return 24000000;
@@ -818,6 +883,10 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
 	case SCLK_I2C7:
 		ret = rk3399_i2c_set_clk(priv->cru, clk->id, rate);
 		break;
+	case SCLK_SPI1:
+	case SCLK_SPI5:
+		ret = rk3399_spi_set_clk(priv->cru, clk->id, rate);
+		break;
 	case DCLK_VOP0:
 	case DCLK_VOP1:
 		ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
-- 
1.9.1



More information about the U-Boot mailing list