rockchip: clk: rk3399: update driver for spl

Add ddr clock setting, add rockchip_get_pmucru API,
and enable of-platdata support.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Added rockchip tag and fix pmuclk_init() build warning:
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Kever Yang 2017-02-13 17:38:56 +08:00 committed by Simon Glass
parent fa72de1045
commit 5ae2fd9724
5 changed files with 125 additions and 15 deletions

View File

@ -63,6 +63,13 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
*/
void *rockchip_get_cru(void);
/**
* rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
*
* @return pointer to registers, or -ve error on error
*/
void *rockchip_get_pmucru(void);
struct rk3288_cru;
struct rk3288_grf;

View File

@ -15,6 +15,11 @@ struct rk3399_clk_priv {
ulong rate;
};
struct rk3399_pmuclk_priv {
struct rk3399_pmucru *pmucru;
ulong rate;
};
struct rk3399_pmucru {
u32 ppll_con[6];
u32 reserved[0x1a];

View File

@ -31,3 +31,24 @@ void *rockchip_get_cru(void)
return priv->cru;
}
static int rockchip_get_pmucruclk(struct udevice **devp)
{
return uclass_get_device_by_driver(UCLASS_CLK,
DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp);
}
void *rockchip_get_pmucru(void)
{
struct rk3399_pmuclk_priv *priv;
struct udevice *dev;
int ret;
ret = rockchip_get_pmucruclk(&dev);
if (ret)
return ERR_PTR(ret);
priv = dev_get_priv(dev);
return priv->pmucru;
}

View File

@ -7,7 +7,9 @@
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
@ -18,10 +20,16 @@
DECLARE_GLOBAL_DATA_PTR;
struct rk3399_pmuclk_priv {
struct rk3399_pmucru *pmucru;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_plat {
struct dtd_rockchip_rk3399_cru dtd;
};
struct rk3399_pmuclk_plat {
struct dtd_rockchip_rk3399_pmucru dtd;
};
#endif
struct pll_div {
u32 refdiv;
u32 fbdiv;
@ -381,6 +389,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
return 0;
}
#ifdef CONFIG_SPL_BUILD
static void rkclk_init(struct rk3399_cru *cru)
{
u32 aclk_div;
@ -456,6 +465,7 @@ static void rkclk_init(struct rk3399_cru *cru)
hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
}
#endif
void rk3399_configure_cpu(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq)
@ -709,6 +719,44 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
return rk3399_mmc_get_clk(cru, clk_id);
}
#define PMUSGRF_DDR_RGN_CON16 0xff330040
static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
ulong set_rate)
{
struct pll_div dpll_cfg;
/* IC ECO bug, need to set this register */
writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
/* clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
switch (set_rate) {
case 200*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
break;
case 300*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
break;
case 666*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
break;
case 800*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
break;
case 933*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
break;
default:
error("Unsupported SDRAM frequency!,%ld\n", set_rate);
}
rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
return set_rate;
}
static ulong rk3399_clk_get_rate(struct clk *clk)
{
struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@ -763,6 +811,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case DCLK_VOP1:
ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
break;
case SCLK_DDRCLK:
ret = rk3399_ddr_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}
@ -777,19 +828,26 @@ static struct clk_ops rk3399_clk_ops = {
static int rk3399_clk_probe(struct udevice *dev)
{
#ifdef CONFIG_SPL_BUILD
struct rk3399_clk_priv *priv = dev_get_priv(dev);
rkclk_init(priv->cru);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_plat *plat = dev_get_platdata(dev);
priv->cru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
#endif
rkclk_init(priv->cru);
#endif
return 0;
}
static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3399_cru *)dev_get_addr(dev);
#endif
return 0;
}
@ -811,7 +869,7 @@ static const struct udevice_id rk3399_clk_ids[] = {
};
U_BOOT_DRIVER(clk_rk3399) = {
.name = "clk_rk3399",
.name = "rockchip_rk3399_cru",
.id = UCLASS_CLK,
.of_match = rk3399_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
@ -819,6 +877,9 @@ U_BOOT_DRIVER(clk_rk3399) = {
.ops = &rk3399_clk_ops,
.bind = rk3399_clk_bind,
.probe = rk3399_clk_probe,
#if CONFIG_IS_ENABLED(OF_PLATDATA)
.platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
#endif
};
static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
@ -930,6 +991,7 @@ static struct clk_ops rk3399_pmuclk_ops = {
.set_rate = rk3399_pmuclk_set_rate,
};
#ifndef CONFIG_SPL_BUILD
static void pmuclk_init(struct rk3399_pmucru *pmucru)
{
u32 pclk_div;
@ -939,27 +1001,35 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru)
/* configure pmu pclk */
pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f);
rk_clrsetreg(&pmucru->pmucru_clksel[0],
PMU_PCLK_DIV_CON_MASK,
pclk_div << PMU_PCLK_DIV_CON_SHIFT);
}
#endif
static int rk3399_pmuclk_probe(struct udevice *dev)
{
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
pmuclk_init(priv->pmucru);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
priv->pmucru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
#endif
#ifndef CONFIG_SPL_BUILD
pmuclk_init(priv->pmucru);
#endif
return 0;
}
static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev);
#endif
return 0;
}
@ -969,11 +1039,14 @@ static const struct udevice_id rk3399_pmuclk_ids[] = {
};
U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
.name = "pmuclk_rk3399",
.name = "rockchip_rk3399_pmucru",
.id = UCLASS_CLK,
.of_match = rk3399_pmuclk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
.ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
.ops = &rk3399_pmuclk_ops,
.probe = rk3399_pmuclk_probe,
#if CONFIG_IS_ENABLED(OF_PLATDATA)
.platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
#endif
};

View File

@ -122,6 +122,10 @@
#define SCLK_DPHY_RX0_CFG 165
#define SCLK_RMII_SRC 166
#define SCLK_PCIEPHY_REF100M 167
#define SCLK_USBPHY0_480M_SRC 168
#define SCLK_USBPHY1_480M_SRC 169
#define SCLK_DDRCLK 170
#define SCLK_TESTOUT2 171
#define DCLK_VOP0 180
#define DCLK_VOP1 181
@ -589,13 +593,13 @@
#define SRST_P_SPI0 214
#define SRST_P_SPI1 215
#define SRST_P_SPI2 216
#define SRST_P_SPI3 217
#define SRST_P_SPI4 218
#define SRST_P_SPI4 217
#define SRST_P_SPI5 218
#define SRST_SPI0 219
#define SRST_SPI1 220
#define SRST_SPI2 221
#define SRST_SPI3 222
#define SRST_SPI4 223
#define SRST_SPI4 222
#define SRST_SPI5 223
/* cru_softrst_con14 */
#define SRST_I2S0_8CH 224
@ -717,8 +721,8 @@
#define SRST_H_CM0S_NOC 3
#define SRST_DBG_CM0S 4
#define SRST_PO_CM0S 5
#define SRST_P_SPI6 6
#define SRST_SPI6 7
#define SRST_P_SPI3 6
#define SRST_SPI3 7
#define SRST_P_TIMER_0_1 8
#define SRST_P_TIMER_0 9
#define SRST_P_TIMER_1 10