|
@@ -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
|
|
|
};
|