From mboxrd@z Thu Jan 1 00:00:00 1970 From: Philipp Tomsich Date: Wed, 29 Mar 2017 13:31:26 +0200 Subject: [U-Boot] [PATCH v2 1/6] rockchip: clk: rk3399: add clock support for SCLK_SPI1 and SCLK_SPI5 In-Reply-To: <1490787091-21008-1-git-send-email-philipp.tomsich@theobroma-systems.com> References: <1490787091-21008-1-git-send-email-philipp.tomsich@theobroma-systems.com> Message-ID: <1490787091-21008-2-git-send-email-philipp.tomsich@theobroma-systems.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 Tested-by: Jakob Unterwurzacher Tested-by: Klaus Goger --- Changes in v2: - fixes a wrong macro usage, which caused the SPI module input clock frequency to be significantly higher than intended - frequencies have now been validated using an oscilloscope (keep in mind that all frequencies are derived from a 99MHz module input clock) at the following measurement points (assuming the other fix for the usage of DIV_RATE from the series): * 1 MHz ... 0.99 MHz * 5 MHz ... 4.95 MHz * 10 MHz ... 9.9 MHz * 30 MHz ... 33 MHz * 50 MHz ... 49.5 MHz 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..9150183 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), + SPI_CLK_REG_VALUE(1, src_clk_div)); + break; + case SCLK_SPI5: + rk_clrsetreg(&cru->clksel_con[58], SPI_CLK_REG_MASK(5), + SPI_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