[U-Boot] [PATCH 3/6] clk: rk3399: update driver for spl

Kever Yang kever.yang at rock-chips.com
Wed Jan 18 13:16:11 CET 2017


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

Signed-off-by: Kever Yang <kever.yang at rock-chips.com>
---

 arch/arm/include/asm/arch-rockchip/clock.h      |  7 ++
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h |  5 ++
 arch/arm/mach-rockchip/rk3399/clk_rk3399.c      | 21 ++++++
 drivers/clk/rockchip/clk_rk3399.c               | 89 ++++++++++++++++++++++---
 include/dt-bindings/clock/rk3399-cru.h          | 16 +++--
 5 files changed, 123 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..8e3860b 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)
@@ -939,7 +1000,6 @@ 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);
@@ -949,17 +1009,25 @@ 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 +1037,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
-- 
1.9.1



More information about the U-Boot mailing list