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

Simon Glass sjg at chromium.org
Sat Apr 1 04:23:10 UTC 2017


Hi Philipp,

On 28 March 2017 at 02:58, Philipp Tomsich
<philipp.tomsich at theobroma-systems.com> wrote:
> 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;

I'm really not keen on this macro pasting as it makes it hard to find things.

Can we instead have something like:

static const u8 spi_shift[] = {
   CLK_SPI0_PLL_SEL_SHIFT,
   CLK_SPI1_PLL_SEL_SHIFT,
  ...
};

and then read it from the array? Since there are multiple pieces you might want:

struct spi_reg_layout {
   u8 sel_shift;
   u8 div_shift;
   u8 sel_mask;
   u8 div_mask;
};

static const struct spi_reg_layout spi_reg_layout[] = {
   { ... },
   { ... },

This is how Tegra does things, for example.

> +
> +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
>

Regards,
Simon


More information about the U-Boot mailing list