summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKever Yang <kever.yang@rock-chips.com>2017-02-13 09:38:56 (GMT)
committerSimon Glass <sjg@chromium.org>2017-03-16 22:03:43 (GMT)
commit5ae2fd97242d4eea97aeabe8801bb8592b37a8fe (patch)
treeef81d978357c082ea9f6d6601fcfa8e2edc63747
parentfa72de10452c51ee32f8278cdfabd38a6aafc7f8 (diff)
downloadu-boot-fsl-qoriq-5ae2fd97242d4eea97aeabe8801bb8592b37a8fe.tar.xz
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>
-rw-r--r--arch/arm/include/asm/arch-rockchip/clock.h7
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rk3399.h5
-rw-r--r--arch/arm/mach-rockchip/rk3399/clk_rk3399.c21
-rw-r--r--drivers/clk/rockchip/clk_rk3399.c91
-rw-r--r--include/dt-bindings/clock/rk3399-cru.h16
5 files changed, 125 insertions, 15 deletions
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h
index 804c77b..6f7e755 100644
--- a/arch/arm/include/asm/arch-rockchip/clock.h
+++ b/arch/arm/include/asm/arch-rockchip/clock.h
@@ -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;
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
index 98fba2b..cf830d0 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3399.h
@@ -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];
diff --git a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
index ce706a6..cf5b8c9 100644
--- a/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
+++ b/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
@@ -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;
+}
diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c
index 2e87e4b..922ce7e 100644
--- a/drivers/clk/rockchip/clk_rk3399.c
+++ b/drivers/clk/rockchip/clk_rk3399.c
@@ -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
};
diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 0a86aec..d4bdcc6 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -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