* [U-Boot] [PATCH v2 1/8] rockchip: move clock drivers into a subdirectory
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-23 2:08 ` Simon Glass
2016-07-22 21:51 ` [U-Boot] [PATCH v2 2/8] rockchip: remove log2 reimplementation from clock drivers Heiko Stuebner
` (7 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
With the number of Rockchip clock drivers increasing, don't clutter up
the core drivers/clk directory with them and instead move them out of
the way into a separate subdirectory.
Suggested-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/clk/Makefile | 3 +-
drivers/clk/clk_rk3036.c | 386 -----------------
drivers/clk/clk_rk3288.c | 851 --------------------------------------
drivers/clk/rockchip/Makefile | 8 +
drivers/clk/rockchip/clk_rk3036.c | 386 +++++++++++++++++
drivers/clk/rockchip/clk_rk3288.c | 851 ++++++++++++++++++++++++++++++++++++++
6 files changed, 1246 insertions(+), 1239 deletions(-)
delete mode 100644 drivers/clk/clk_rk3036.c
delete mode 100644 drivers/clk/clk_rk3288.c
create mode 100644 drivers/clk/rockchip/Makefile
create mode 100644 drivers/clk/rockchip/clk_rk3036.c
create mode 100644 drivers/clk/rockchip/clk_rk3288.c
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7a8891..3cbdd54 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -6,8 +6,7 @@
#
obj-$(CONFIG_CLK) += clk-uclass.o clk_fixed_rate.o
-obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
-obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
+obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_SANDBOX) += clk_sandbox.o
obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
diff --git a/drivers/clk/clk_rk3036.c b/drivers/clk/clk_rk3036.c
deleted file mode 100644
index 6202c9d..0000000
--- a/drivers/clk/clk_rk3036.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * (C) Copyright 2015 Google, Inc
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <clk-uclass.h>
-#include <dm.h>
-#include <errno.h>
-#include <syscon.h>
-#include <asm/io.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cru_rk3036.h>
-#include <asm/arch/hardware.h>
-#include <dm/lists.h>
-#include <dt-bindings/clock/rk3036-cru.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct rk3036_clk_priv {
- struct rk3036_cru *cru;
- ulong rate;
-};
-
-enum {
- VCO_MAX_HZ = 2400U * 1000000,
- VCO_MIN_HZ = 600 * 1000000,
- OUTPUT_MAX_HZ = 2400U * 1000000,
- OUTPUT_MIN_HZ = 24 * 1000000,
-};
-
-#define RATE_TO_DIV(input_rate, output_rate) \
- ((input_rate) / (output_rate) - 1);
-
-#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
-
-#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
- .refdiv = _refdiv,\
- .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
- .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
- _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
- OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
- #hz "Hz cannot be hit with PLL "\
- "divisors on line " __stringify(__LINE__));
-
-/* use interge mode*/
-static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
-static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
-
-static inline unsigned int log2(unsigned int value)
-{
- return fls(value) - 1;
-}
-
-void *rockchip_get_cru(void)
-{
- struct udevice *dev;
- fdt_addr_t addr;
- int ret;
-
- ret = uclass_get_device(UCLASS_CLK, 0, &dev);
- if (ret)
- return ERR_PTR(ret);
-
- addr = dev_get_addr(dev);
- if (addr == FDT_ADDR_T_NONE)
- return ERR_PTR(-EINVAL);
-
- return (void *)addr;
-}
-
-static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
- const struct pll_div *div)
-{
- int pll_id = rk_pll_id(clk_id);
- struct rk3036_pll *pll = &cru->pll[pll_id];
-
- /* All PLLs have same VCO and output frequency range restrictions. */
- uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
- uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
-
- debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, postdiv2=%d,\
- vco=%u Hz, output=%u Hz\n",
- pll, div->fbdiv, div->refdiv, div->postdiv1,
- div->postdiv2, vco_hz, output_hz);
- assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
- output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
-
- /* use interger mode */
- rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
-
- rk_clrsetreg(&pll->con0,
- PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
- (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
- rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
- PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
- (div->postdiv2 << PLL_POSTDIV2_SHIFT |
- div->refdiv << PLL_REFDIV_SHIFT));
-
- /* waiting for pll lock */
- while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
- udelay(1);
-
- return 0;
-}
-
-static void rkclk_init(struct rk3036_cru *cru)
-{
- u32 aclk_div;
- u32 hclk_div;
- u32 pclk_div;
-
- /* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- APLL_MODE_MASK << APLL_MODE_SHIFT,
- GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
- APLL_MODE_SLOW << APLL_MODE_SHIFT);
-
- /* init pll */
- rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
- rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
-
- /*
- * select apll as core clock pll source and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
- * core hz : apll = 1:1
- */
- aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
- assert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);
-
- pclk_div = APLL_HZ / CORE_PERI_HZ - 1;
- assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
-
- rk_clrsetreg(&cru->cru_clksel_con[0],
- CORE_CLK_PLL_SEL_MASK << CORE_CLK_PLL_SEL_SHIFT |
- CORE_DIV_CON_MASK << CORE_DIV_CON_SHIFT,
- CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
- 0 << CORE_DIV_CON_SHIFT);
-
- rk_clrsetreg(&cru->cru_clksel_con[1],
- CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT |
- CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT,
- aclk_div << CORE_ACLK_DIV_SHIFT |
- pclk_div << CORE_PERI_DIV_SHIFT);
-
- /*
- * select apll as cpu clock pll source and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
- */
- aclk_div = APLL_HZ / CPU_ACLK_HZ - 1;
- assert((aclk_div + 1) * CPU_ACLK_HZ == APLL_HZ && aclk_div < 0x1f);
-
- pclk_div = APLL_HZ / CPU_PCLK_HZ - 1;
- assert((pclk_div + 1) * CPU_PCLK_HZ == APLL_HZ && pclk_div < 0x7);
-
- hclk_div = APLL_HZ / CPU_HCLK_HZ - 1;
- assert((hclk_div + 1) * CPU_HCLK_HZ == APLL_HZ && hclk_div < 0x3);
-
- rk_clrsetreg(&cru->cru_clksel_con[0],
- CPU_CLK_PLL_SEL_MASK << CPU_CLK_PLL_SEL_SHIFT |
- ACLK_CPU_DIV_MASK << ACLK_CPU_DIV_SHIFT,
- CPU_CLK_PLL_SEL_APLL << CPU_CLK_PLL_SEL_SHIFT |
- aclk_div << ACLK_CPU_DIV_SHIFT);
-
- rk_clrsetreg(&cru->cru_clksel_con[1],
- CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
- CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
- pclk_div << CPU_PCLK_DIV_SHIFT |
- hclk_div << CPU_HCLK_DIV_SHIFT);
-
- /*
- * select gpll as peri clock pll source and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
- */
- aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
- assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
-
- hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
- assert((1 << hclk_div) * PERI_HCLK_HZ ==
- PERI_ACLK_HZ && (pclk_div < 0x4));
-
- pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
- assert((1 << pclk_div) * PERI_PCLK_HZ ==
- PERI_ACLK_HZ && pclk_div < 0x8);
-
- rk_clrsetreg(&cru->cru_clksel_con[10],
- PERI_PLL_SEL_MASK << PERI_PLL_SEL_SHIFT |
- PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
- PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
- PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
- PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
- pclk_div << PERI_PCLK_DIV_SHIFT |
- hclk_div << PERI_HCLK_DIV_SHIFT |
- aclk_div << PERI_ACLK_DIV_SHIFT);
-
- /* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- APLL_MODE_MASK << APLL_MODE_SHIFT,
- GPLL_MODE_NORM << GPLL_MODE_SHIFT |
- APLL_MODE_NORM << APLL_MODE_SHIFT);
-}
-
-/* Get pll rate by id */
-static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
- enum rk_clk_id clk_id)
-{
- uint32_t refdiv, fbdiv, postdiv1, postdiv2;
- uint32_t con;
- int pll_id = rk_pll_id(clk_id);
- struct rk3036_pll *pll = &cru->pll[pll_id];
- static u8 clk_shift[CLK_COUNT] = {
- 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,
- GPLL_MODE_SHIFT, 0xff
- };
- static u8 clk_mask[CLK_COUNT] = {
- 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,
- GPLL_MODE_MASK, 0xff
- };
- uint shift;
- uint mask;
-
- con = readl(&cru->cru_mode_con);
- shift = clk_shift[clk_id];
- mask = clk_mask[clk_id];
-
- switch ((con >> shift) & mask) {
- case GPLL_MODE_SLOW:
- return OSC_HZ;
- case GPLL_MODE_NORM:
-
- /* normal mode */
- con = readl(&pll->con0);
- postdiv1 = (con >> PLL_POSTDIV1_SHIFT) & PLL_POSTDIV1_MASK;
- fbdiv = (con >> PLL_FBDIV_SHIFT) & PLL_FBDIV_MASK;
- con = readl(&pll->con1);
- postdiv2 = (con >> PLL_POSTDIV2_SHIFT) & PLL_POSTDIV2_MASK;
- refdiv = (con >> PLL_REFDIV_SHIFT) & PLL_REFDIV_MASK;
- return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
- case GPLL_MODE_DEEP:
- default:
- return 32768;
- }
-}
-
-static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
- int periph)
-{
- uint src_rate;
- uint div, mux;
- u32 con;
-
- switch (periph) {
- case HCLK_EMMC:
- con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
- div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
- break;
- case HCLK_SDIO:
- con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
- div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
- return DIV_TO_RATE(src_rate, div);
-}
-
-static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
- int periph, uint freq)
-{
- int src_clk_div;
- int mux;
-
- debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
-
- /* mmc clock auto divide 2 in internal */
- src_clk_div = (clk_general_rate / 2 + freq - 1) / freq;
-
- if (src_clk_div > 0x7f) {
- src_clk_div = (OSC_HZ / 2 + freq - 1) / freq;
- mux = EMMC_SEL_24M;
- } else {
- mux = EMMC_SEL_GPLL;
- }
-
- switch (periph) {
- case HCLK_EMMC:
- rk_clrsetreg(&cru->cru_clksel_con[12],
- EMMC_PLL_MASK << EMMC_PLL_SHIFT |
- EMMC_DIV_MASK << EMMC_DIV_SHIFT,
- mux << EMMC_PLL_SHIFT |
- (src_clk_div - 1) << EMMC_DIV_SHIFT);
- break;
- case HCLK_SDIO:
- rk_clrsetreg(&cru->cru_clksel_con[11],
- MMC0_PLL_MASK << MMC0_PLL_SHIFT |
- MMC0_DIV_MASK << MMC0_DIV_SHIFT,
- mux << MMC0_PLL_SHIFT |
- (src_clk_div - 1) << MMC0_DIV_SHIFT);
- break;
- default:
- return -EINVAL;
- }
-
- return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
-}
-
-static ulong rk3036_clk_get_rate(struct clk *clk)
-{
- struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
-
- switch (clk->id) {
- case 0 ... 63:
- return rkclk_pll_get_rate(priv->cru, clk->id);
- default:
- return -ENOENT;
- }
-}
-
-static ulong rk3036_clk_set_rate(struct clk *clk, ulong rate)
-{
- struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
- ulong new_rate, gclk_rate;
-
- gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
- switch (clk->id) {
- case 0 ... 63:
- return 0;
- case HCLK_EMMC:
- new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
- clk->id, rate);
- break;
- default:
- return -ENOENT;
- }
-
- return new_rate;
-}
-
-static struct clk_ops rk3036_clk_ops = {
- .get_rate = rk3036_clk_get_rate,
- .set_rate = rk3036_clk_set_rate,
-};
-
-static int rk3036_clk_probe(struct udevice *dev)
-{
- struct rk3036_clk_priv *priv = dev_get_priv(dev);
-
- priv->cru = (struct rk3036_cru *)dev_get_addr(dev);
- rkclk_init(priv->cru);
-
- return 0;
-}
-
-static int rk3036_clk_bind(struct udevice *dev)
-{
- int ret;
-
- /* The reset driver does not have a device node, so bind it here */
- ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
- if (ret)
- debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
-
- return 0;
-}
-
-static const struct udevice_id rk3036_clk_ids[] = {
- { .compatible = "rockchip,rk3036-cru" },
- { }
-};
-
-U_BOOT_DRIVER(clk_rk3036) = {
- .name = "clk_rk3036",
- .id = UCLASS_CLK,
- .of_match = rk3036_clk_ids,
- .priv_auto_alloc_size = sizeof(struct rk3036_clk_priv),
- .ops = &rk3036_clk_ops,
- .bind = rk3036_clk_bind,
- .probe = rk3036_clk_probe,
-};
diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/clk_rk3288.c
deleted file mode 100644
index e00feb0..0000000
--- a/drivers/clk/clk_rk3288.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * (C) Copyright 2015 Google, Inc
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#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>
-#include <asm/arch/cru_rk3288.h>
-#include <asm/arch/grf_rk3288.h>
-#include <asm/arch/hardware.h>
-#include <dt-bindings/clock/rk3288-cru.h>
-#include <dm/device-internal.h>
-#include <dm/lists.h>
-#include <dm/uclass-internal.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct rk3288_clk_plat {
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
- struct dtd_rockchip_rk3288_cru dtd;
-#endif
-};
-
-struct rk3288_clk_priv {
- struct rk3288_grf *grf;
- struct rk3288_cru *cru;
- ulong rate;
-};
-
-struct pll_div {
- u32 nr;
- u32 nf;
- u32 no;
-};
-
-enum {
- VCO_MAX_HZ = 2200U * 1000000,
- VCO_MIN_HZ = 440 * 1000000,
- OUTPUT_MAX_HZ = 2200U * 1000000,
- OUTPUT_MIN_HZ = 27500000,
- FREF_MAX_HZ = 2200U * 1000000,
- FREF_MIN_HZ = 269 * 1000,
-};
-
-enum {
- /* PLL CON0 */
- PLL_OD_MASK = 0x0f,
-
- /* PLL CON1 */
- PLL_NF_MASK = 0x1fff,
-
- /* PLL CON2 */
- PLL_BWADJ_MASK = 0x0fff,
-
- /* PLL CON3 */
- PLL_RESET_SHIFT = 5,
-
- /* CLKSEL0 */
- CORE_SEL_PLL_MASK = 1,
- CORE_SEL_PLL_SHIFT = 15,
- A17_DIV_MASK = 0x1f,
- A17_DIV_SHIFT = 8,
- MP_DIV_MASK = 0xf,
- MP_DIV_SHIFT = 4,
- M0_DIV_MASK = 0xf,
- M0_DIV_SHIFT = 0,
-
- /* CLKSEL1: pd bus clk pll sel: codec or general */
- PD_BUS_SEL_PLL_MASK = 15,
- PD_BUS_SEL_CPLL = 0,
- PD_BUS_SEL_GPLL,
-
- /* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */
- PD_BUS_PCLK_DIV_SHIFT = 12,
- PD_BUS_PCLK_DIV_MASK = 7,
-
- /* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
- PD_BUS_HCLK_DIV_SHIFT = 8,
- PD_BUS_HCLK_DIV_MASK = 3,
-
- /* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */
- PD_BUS_ACLK_DIV0_SHIFT = 3,
- PD_BUS_ACLK_DIV0_MASK = 0x1f,
- PD_BUS_ACLK_DIV1_SHIFT = 0,
- PD_BUS_ACLK_DIV1_MASK = 0x7,
-
- /*
- * CLKSEL10
- * peripheral bus pclk div:
- * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1
- */
- PERI_SEL_PLL_MASK = 1,
- PERI_SEL_PLL_SHIFT = 15,
- PERI_SEL_CPLL = 0,
- PERI_SEL_GPLL,
-
- PERI_PCLK_DIV_SHIFT = 12,
- PERI_PCLK_DIV_MASK = 3,
-
- /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
- PERI_HCLK_DIV_SHIFT = 8,
- PERI_HCLK_DIV_MASK = 3,
-
- /*
- * peripheral bus aclk div:
- * aclk_periph = periph_clk_src / (peri_aclk_div_con + 1)
- */
- PERI_ACLK_DIV_SHIFT = 0,
- PERI_ACLK_DIV_MASK = 0x1f,
-
- SOCSTS_DPLL_LOCK = 1 << 5,
- SOCSTS_APLL_LOCK = 1 << 6,
- SOCSTS_CPLL_LOCK = 1 << 7,
- SOCSTS_GPLL_LOCK = 1 << 8,
- SOCSTS_NPLL_LOCK = 1 << 9,
-};
-
-#define RATE_TO_DIV(input_rate, output_rate) \
- ((input_rate) / (output_rate) - 1);
-
-#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
-
-#define PLL_DIVISORS(hz, _nr, _no) {\
- .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
- _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
- (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
- "divisors on line " __stringify(__LINE__));
-
-/* Keep divisors as low as possible to reduce jitter and power usage */
-static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
-static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
-static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
-
-void *rockchip_get_cru(void)
-{
- struct rk3288_clk_priv *priv;
- struct udevice *dev;
- int ret;
-
- ret = rockchip_get_clk(&dev);
- if (ret)
- return ERR_PTR(ret);
-
- priv = dev_get_priv(dev);
-
- return priv->cru;
-}
-
-static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
- const struct pll_div *div)
-{
- int pll_id = rk_pll_id(clk_id);
- struct rk3288_pll *pll = &cru->pll[pll_id];
- /* All PLLs have same VCO and output frequency range restrictions. */
- uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
- uint output_hz = vco_hz / div->no;
-
- debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
- (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
- assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
- output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
- (div->no == 1 || !(div->no % 2)));
-
- /* enter reset */
- rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
-
- rk_clrsetreg(&pll->con0,
- CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
- ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
- rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
- rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
-
- udelay(10);
-
- /* return from reset */
- rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
-
- return 0;
-}
-
-static inline unsigned int log2(unsigned int value)
-{
- return fls(value) - 1;
-}
-
-static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
- unsigned int hz)
-{
- static const struct pll_div dpll_cfg[] = {
- {.nf = 25, .nr = 2, .no = 1},
- {.nf = 400, .nr = 9, .no = 2},
- {.nf = 500, .nr = 9, .no = 2},
- {.nf = 100, .nr = 3, .no = 1},
- };
- int cfg;
-
- switch (hz) {
- case 300000000:
- cfg = 0;
- break;
- case 533000000: /* actually 533.3P MHz */
- cfg = 1;
- break;
- case 666000000: /* actually 666.6P MHz */
- cfg = 2;
- break;
- case 800000000:
- cfg = 3;
- break;
- default:
- debug("Unsupported SDRAM frequency");
- return -EINVAL;
- }
-
- /* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
- DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
-
- rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
-
- /* wait for pll lock */
- while (!(readl(&grf->soc_status[1]) & SOCSTS_DPLL_LOCK))
- udelay(1);
-
- /* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
- DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
-
- return 0;
-}
-
-#ifndef CONFIG_SPL_BUILD
-#define VCO_MAX_KHZ 2200000
-#define VCO_MIN_KHZ 440000
-#define FREF_MAX_KHZ 2200000
-#define FREF_MIN_KHZ 269
-
-static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div)
-{
- uint ref_khz = OSC_HZ / 1000, nr, nf = 0;
- uint fref_khz;
- uint diff_khz, best_diff_khz;
- const uint max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4;
- uint vco_khz;
- uint no = 1;
- uint freq_khz = freq_hz / 1000;
-
- if (!freq_hz) {
- printf("%s: the frequency can not be 0 Hz\n", __func__);
- return -EINVAL;
- }
-
- no = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
- if (ext_div) {
- *ext_div = DIV_ROUND_UP(no, max_no);
- no = DIV_ROUND_UP(no, *ext_div);
- }
-
- /* only even divisors (and 1) are supported */
- if (no > 1)
- no = DIV_ROUND_UP(no, 2) * 2;
-
- vco_khz = freq_khz * no;
- if (ext_div)
- vco_khz *= *ext_div;
-
- if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) {
- printf("%s: Cannot find out a supported VCO for Frequency (%luHz).\n",
- __func__, freq_hz);
- return -1;
- }
-
- div->no = no;
-
- best_diff_khz = vco_khz;
- for (nr = 1; nr < max_nr && best_diff_khz; nr++) {
- fref_khz = ref_khz / nr;
- if (fref_khz < FREF_MIN_KHZ)
- break;
- if (fref_khz > FREF_MAX_KHZ)
- continue;
-
- nf = vco_khz / fref_khz;
- if (nf >= max_nf)
- continue;
- diff_khz = vco_khz - nf * fref_khz;
- if (nf + 1 < max_nf && diff_khz > fref_khz / 2) {
- nf++;
- diff_khz = fref_khz - diff_khz;
- }
-
- if (diff_khz >= best_diff_khz)
- continue;
-
- best_diff_khz = diff_khz;
- div->nr = nr;
- div->nf = nf;
- }
-
- if (best_diff_khz > 4 * 1000) {
- printf("%s: Failed to match output frequency %lu, difference is %u Hz, exceed 4MHZ\n",
- __func__, freq_hz, best_diff_khz * 1000);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int rockchip_mac_set_clk(struct rk3288_cru *cru,
- int periph, uint freq)
-{
- /* Assuming mac_clk is fed by an external clock */
- rk_clrsetreg(&cru->cru_clksel_con[21],
- RMII_EXTCLK_MASK << RMII_EXTCLK_SHIFT,
- RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT);
-
- return 0;
-}
-
-static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
- int periph, unsigned int rate_hz)
-{
- struct pll_div npll_config = {0};
- u32 lcdc_div;
- int ret;
-
- ret = pll_para_config(rate_hz, &npll_config, &lcdc_div);
- if (ret)
- return ret;
-
- rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
- NPLL_MODE_SLOW << NPLL_MODE_SHIFT);
- rkclk_set_pll(cru, CLK_NEW, &npll_config);
-
- /* waiting for pll lock */
- while (1) {
- if (readl(&grf->soc_status[1]) & SOCSTS_NPLL_LOCK)
- break;
- udelay(1);
- }
-
- rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
- NPLL_MODE_NORMAL << NPLL_MODE_SHIFT);
-
- /* vop dclk source clk: npll,dclk_div: 1 */
- switch (periph) {
- case DCLK_VOP0:
- rk_clrsetreg(&cru->cru_clksel_con[27], 0xff << 8 | 3 << 0,
- (lcdc_div - 1) << 8 | 2 << 0);
- break;
- case DCLK_VOP1:
- rk_clrsetreg(&cru->cru_clksel_con[29], 0xff << 8 | 3 << 6,
- (lcdc_div - 1) << 8 | 2 << 6);
- break;
- }
-
- return 0;
-}
-#endif
-
-#ifdef CONFIG_SPL_BUILD
-static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
-{
- u32 aclk_div;
- u32 hclk_div;
- u32 pclk_div;
-
- /* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- CPLL_MODE_MASK << CPLL_MODE_SHIFT,
- GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
- CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
-
- /* init pll */
- rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
- rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
-
- /* waiting for pll lock */
- while ((readl(&grf->soc_status[1]) &
- (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
- (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
- udelay(1);
-
- /*
- * pd_bus clock pll source selection and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
- */
- aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1;
- assert((aclk_div + 1) * PD_BUS_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
- hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1;
- assert((hclk_div + 1) * PD_BUS_HCLK_HZ ==
- PD_BUS_ACLK_HZ && (hclk_div < 0x4) && (hclk_div != 0x2));
-
- pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1;
- assert((pclk_div + 1) * PD_BUS_PCLK_HZ ==
- PD_BUS_ACLK_HZ && pclk_div < 0x7);
-
- rk_clrsetreg(&cru->cru_clksel_con[1],
- PD_BUS_PCLK_DIV_MASK << PD_BUS_PCLK_DIV_SHIFT |
- PD_BUS_HCLK_DIV_MASK << PD_BUS_HCLK_DIV_SHIFT |
- PD_BUS_ACLK_DIV0_MASK << PD_BUS_ACLK_DIV0_SHIFT |
- PD_BUS_ACLK_DIV1_MASK << PD_BUS_ACLK_DIV1_SHIFT,
- pclk_div << PD_BUS_PCLK_DIV_SHIFT |
- hclk_div << PD_BUS_HCLK_DIV_SHIFT |
- aclk_div << PD_BUS_ACLK_DIV0_SHIFT |
- 0 << 0);
-
- /*
- * peri clock pll source selection and
- * set up dependent divisors for PCLK/HCLK and ACLK clocks.
- */
- aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
- assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
-
- hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
- assert((1 << hclk_div) * PERI_HCLK_HZ ==
- PERI_ACLK_HZ && (hclk_div < 0x4));
-
- pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
- assert((1 << pclk_div) * PERI_PCLK_HZ ==
- PERI_ACLK_HZ && (pclk_div < 0x4));
-
- rk_clrsetreg(&cru->cru_clksel_con[10],
- PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
- PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
- PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
- PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
- pclk_div << PERI_PCLK_DIV_SHIFT |
- hclk_div << PERI_HCLK_DIV_SHIFT |
- aclk_div << PERI_ACLK_DIV_SHIFT);
-
- /* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- GPLL_MODE_MASK << GPLL_MODE_SHIFT |
- CPLL_MODE_MASK << CPLL_MODE_SHIFT,
- GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
- CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
-}
-#endif
-
-void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
-{
- /* pll enter slow-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- APLL_MODE_MASK << APLL_MODE_SHIFT,
- APLL_MODE_SLOW << APLL_MODE_SHIFT);
-
- rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
-
- /* waiting for pll lock */
- while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK))
- udelay(1);
-
- /*
- * core clock pll source selection and
- * set up dependent divisors for MPAXI/M0AXI and ARM clocks.
- * core clock select apll, apll clk = 1800MHz
- * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz
- */
- rk_clrsetreg(&cru->cru_clksel_con[0],
- CORE_SEL_PLL_MASK << CORE_SEL_PLL_SHIFT |
- A17_DIV_MASK << A17_DIV_SHIFT |
- MP_DIV_MASK << MP_DIV_SHIFT |
- M0_DIV_MASK << M0_DIV_SHIFT,
- 0 << A17_DIV_SHIFT |
- 3 << MP_DIV_SHIFT |
- 1 << M0_DIV_SHIFT);
-
- /*
- * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
- * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
- */
- rk_clrsetreg(&cru->cru_clksel_con[37],
- CLK_L2RAM_DIV_MASK << CLK_L2RAM_DIV_SHIFT |
- ATCLK_CORE_DIV_CON_MASK << ATCLK_CORE_DIV_CON_SHIFT |
- PCLK_CORE_DBG_DIV_MASK >> PCLK_CORE_DBG_DIV_SHIFT,
- 1 << CLK_L2RAM_DIV_SHIFT |
- 3 << ATCLK_CORE_DIV_CON_SHIFT |
- 3 << PCLK_CORE_DBG_DIV_SHIFT);
-
- /* PLL enter normal-mode */
- rk_clrsetreg(&cru->cru_mode_con,
- APLL_MODE_MASK << APLL_MODE_SHIFT,
- APLL_MODE_NORMAL << APLL_MODE_SHIFT);
-}
-
-/* Get pll rate by id */
-static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
- enum rk_clk_id clk_id)
-{
- uint32_t nr, no, nf;
- uint32_t con;
- int pll_id = rk_pll_id(clk_id);
- struct rk3288_pll *pll = &cru->pll[pll_id];
- static u8 clk_shift[CLK_COUNT] = {
- 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
- GPLL_MODE_SHIFT, NPLL_MODE_SHIFT
- };
- uint shift;
-
- con = readl(&cru->cru_mode_con);
- shift = clk_shift[clk_id];
- switch ((con >> shift) & APLL_MODE_MASK) {
- case APLL_MODE_SLOW:
- return OSC_HZ;
- case APLL_MODE_NORMAL:
- /* normal mode */
- con = readl(&pll->con0);
- no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
- nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
- con = readl(&pll->con1);
- nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
-
- return (24 * nf / (nr * no)) * 1000000;
- case APLL_MODE_DEEP:
- default:
- return 32768;
- }
-}
-
-static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
- int periph)
-{
- uint src_rate;
- uint div, mux;
- u32 con;
-
- switch (periph) {
- case HCLK_EMMC:
- con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
- div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
- break;
- case HCLK_SDMMC:
- con = readl(&cru->cru_clksel_con[11]);
- mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
- div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
- break;
- case HCLK_SDIO0:
- con = readl(&cru->cru_clksel_con[12]);
- mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK;
- div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : gclk_rate;
- return DIV_TO_RATE(src_rate, div);
-}
-
-static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
- int periph, uint freq)
-{
- int src_clk_div;
- int mux;
-
- debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
- src_clk_div = RATE_TO_DIV(gclk_rate, freq);
-
- if (src_clk_div > 0x3f) {
- src_clk_div = RATE_TO_DIV(OSC_HZ, freq);
- mux = EMMC_PLL_SELECT_24MHZ;
- assert((int)EMMC_PLL_SELECT_24MHZ ==
- (int)MMC0_PLL_SELECT_24MHZ);
- } else {
- mux = EMMC_PLL_SELECT_GENERAL;
- assert((int)EMMC_PLL_SELECT_GENERAL ==
- (int)MMC0_PLL_SELECT_GENERAL);
- }
- switch (periph) {
- case HCLK_EMMC:
- rk_clrsetreg(&cru->cru_clksel_con[12],
- EMMC_PLL_MASK << EMMC_PLL_SHIFT |
- EMMC_DIV_MASK << EMMC_DIV_SHIFT,
- mux << EMMC_PLL_SHIFT |
- (src_clk_div - 1) << EMMC_DIV_SHIFT);
- break;
- case HCLK_SDMMC:
- rk_clrsetreg(&cru->cru_clksel_con[11],
- MMC0_PLL_MASK << MMC0_PLL_SHIFT |
- MMC0_DIV_MASK << MMC0_DIV_SHIFT,
- mux << MMC0_PLL_SHIFT |
- (src_clk_div - 1) << MMC0_DIV_SHIFT);
- break;
- case HCLK_SDIO0:
- rk_clrsetreg(&cru->cru_clksel_con[12],
- SDIO0_PLL_MASK << SDIO0_PLL_SHIFT |
- SDIO0_DIV_MASK << SDIO0_DIV_SHIFT,
- mux << SDIO0_PLL_SHIFT |
- (src_clk_div - 1) << SDIO0_DIV_SHIFT);
- break;
- default:
- return -EINVAL;
- }
-
- return rockchip_mmc_get_clk(cru, gclk_rate, periph);
-}
-
-static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate,
- int periph)
-{
- uint div, mux;
- u32 con;
-
- switch (periph) {
- case SCLK_SPI0:
- con = readl(&cru->cru_clksel_con[25]);
- mux = (con >> SPI0_PLL_SHIFT) & SPI0_PLL_MASK;
- div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
- break;
- case SCLK_SPI1:
- con = readl(&cru->cru_clksel_con[25]);
- mux = (con >> SPI1_PLL_SHIFT) & SPI1_PLL_MASK;
- div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
- break;
- case SCLK_SPI2:
- con = readl(&cru->cru_clksel_con[39]);
- mux = (con >> SPI2_PLL_SHIFT) & SPI2_PLL_MASK;
- div = (con >> SPI2_DIV_SHIFT) & SPI2_DIV_MASK;
- break;
- default:
- return -EINVAL;
- }
- assert(mux == SPI0_PLL_SELECT_GENERAL);
-
- return DIV_TO_RATE(gclk_rate, div);
-}
-
-static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
- int periph, uint freq)
-{
- int src_clk_div;
-
- debug("%s: clk_general_rate=%u\n", __func__, gclk_rate);
- src_clk_div = RATE_TO_DIV(gclk_rate, freq);
- switch (periph) {
- case SCLK_SPI0:
- rk_clrsetreg(&cru->cru_clksel_con[25],
- SPI0_PLL_MASK << SPI0_PLL_SHIFT |
- SPI0_DIV_MASK << SPI0_DIV_SHIFT,
- SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT |
- src_clk_div << SPI0_DIV_SHIFT);
- break;
- case SCLK_SPI1:
- rk_clrsetreg(&cru->cru_clksel_con[25],
- SPI1_PLL_MASK << SPI1_PLL_SHIFT |
- SPI1_DIV_MASK << SPI1_DIV_SHIFT,
- SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT |
- src_clk_div << SPI1_DIV_SHIFT);
- break;
- case SCLK_SPI2:
- rk_clrsetreg(&cru->cru_clksel_con[39],
- SPI2_PLL_MASK << SPI2_PLL_SHIFT |
- SPI2_DIV_MASK << SPI2_DIV_SHIFT,
- SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT |
- src_clk_div << SPI2_DIV_SHIFT);
- break;
- default:
- return -EINVAL;
- }
-
- return rockchip_spi_get_clk(cru, gclk_rate, periph);
-}
-
-static ulong rk3288_clk_get_rate(struct clk *clk)
-{
- struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
- ulong new_rate, gclk_rate;
-
- gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
- switch (clk->id) {
- case 0 ... 63:
- new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
- break;
- case HCLK_EMMC:
- case HCLK_SDMMC:
- case HCLK_SDIO0:
- new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
- break;
- case SCLK_SPI0:
- case SCLK_SPI1:
- case SCLK_SPI2:
- new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, clk->id);
- break;
- case PCLK_I2C0:
- case PCLK_I2C1:
- case PCLK_I2C2:
- case PCLK_I2C3:
- case PCLK_I2C4:
- case PCLK_I2C5:
- return gclk_rate;
- default:
- return -ENOENT;
- }
-
- return new_rate;
-}
-
-static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
-{
- struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
- struct rk3288_cru *cru = priv->cru;
- ulong new_rate, gclk_rate;
-
- gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
- switch (clk->id) {
- case CLK_DDR:
- new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate);
- break;
- case HCLK_EMMC:
- case HCLK_SDMMC:
- case HCLK_SDIO0:
- new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate);
- break;
- case SCLK_SPI0:
- case SCLK_SPI1:
- case SCLK_SPI2:
- new_rate = rockchip_spi_set_clk(cru, gclk_rate, clk->id, rate);
- break;
-#ifndef CONFIG_SPL_BUILD
- case SCLK_MAC:
- new_rate = rockchip_mac_set_clk(priv->cru, clk->id, rate);
- break;
- case DCLK_VOP0:
- case DCLK_VOP1:
- new_rate = rockchip_vop_set_clk(cru, priv->grf, clk->id, rate);
- break;
- case SCLK_EDP_24M:
- /* clk_edp_24M source: 24M */
- rk_setreg(&cru->cru_clksel_con[28], 1 << 15);
-
- /* rst edp */
- rk_setreg(&cru->cru_clksel_con[6], 1 << 15);
- udelay(1);
- rk_clrreg(&cru->cru_clksel_con[6], 1 << 15);
- new_rate = rate;
- break;
- case ACLK_VOP0:
- case ACLK_VOP1: {
- u32 div;
-
- /* vop aclk source clk: cpll */
- div = CPLL_HZ / rate;
- assert((div - 1 < 64) && (div * rate == CPLL_HZ));
-
- switch (clk->id) {
- case ACLK_VOP0:
- rk_clrsetreg(&cru->cru_clksel_con[31],
- 3 << 6 | 0x1f << 0,
- 0 << 6 | (div - 1) << 0);
- break;
- case ACLK_VOP1:
- rk_clrsetreg(&cru->cru_clksel_con[31],
- 3 << 14 | 0x1f << 8,
- 0 << 14 | (div - 1) << 8);
- break;
- }
- new_rate = rate;
- break;
- }
- case PCLK_HDMI_CTRL:
- /* enable pclk hdmi ctrl */
- rk_clrreg(&cru->cru_clkgate_con[16], 1 << 9);
-
- /* software reset hdmi */
- rk_setreg(&cru->cru_clkgate_con[7], 1 << 9);
- udelay(1);
- rk_clrreg(&cru->cru_clkgate_con[7], 1 << 9);
- new_rate = rate;
- break;
-#endif
- default:
- return -ENOENT;
- }
-
- return new_rate;
-}
-
-static struct clk_ops rk3288_clk_ops = {
- .get_rate = rk3288_clk_get_rate,
- .set_rate = rk3288_clk_set_rate,
-};
-
-static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
-{
-#if !CONFIG_IS_ENABLED(OF_PLATDATA)
- struct rk3288_clk_priv *priv = dev_get_priv(dev);
-
- priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
-#endif
-
- return 0;
-}
-
-static int rk3288_clk_probe(struct udevice *dev)
-{
- struct rk3288_clk_priv *priv = dev_get_priv(dev);
-
- priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
- if (IS_ERR(priv->grf))
- return PTR_ERR(priv->grf);
-#ifdef CONFIG_SPL_BUILD
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
- struct rk3288_clk_plat *plat = dev_get_platdata(dev);
-
- priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
-#endif
- rkclk_init(priv->cru, priv->grf);
-#endif
-
- return 0;
-}
-
-static int rk3288_clk_bind(struct udevice *dev)
-{
- int ret;
-
- /* The reset driver does not have a device node, so bind it here */
- ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
- if (ret)
- debug("Warning: No RK3288 reset driver: ret=%d\n", ret);
-
- return 0;
-}
-
-static const struct udevice_id rk3288_clk_ids[] = {
- { .compatible = "rockchip,rk3288-cru" },
- { }
-};
-
-U_BOOT_DRIVER(rockchip_rk3288_cru) = {
- .name = "rockchip_rk3288_cru",
- .id = UCLASS_CLK,
- .of_match = rk3288_clk_ids,
- .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
- .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
- .ops = &rk3288_clk_ops,
- .bind = rk3288_clk_bind,
- .ofdata_to_platdata = rk3288_clk_ofdata_to_platdata,
- .probe = rk3288_clk_probe,
-};
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
new file mode 100644
index 0000000..acfd858
--- /dev/null
+++ b/drivers/clk/rockchip/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2016 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
new file mode 100644
index 0000000..6202c9d
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -0,0 +1,386 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3036.h>
+#include <asm/arch/hardware.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3036-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3036_clk_priv {
+ struct rk3036_cru *cru;
+ ulong rate;
+};
+
+enum {
+ VCO_MAX_HZ = 2400U * 1000000,
+ VCO_MIN_HZ = 600 * 1000000,
+ OUTPUT_MAX_HZ = 2400U * 1000000,
+ OUTPUT_MIN_HZ = 24 * 1000000,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\
+ _Static_assert(((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ) *\
+ OSC_HZ / (_refdiv * _postdiv1 * _postdiv2) == hz,\
+ #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* use interge mode*/
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
+static inline unsigned int log2(unsigned int value)
+{
+ return fls(value) - 1;
+}
+
+void *rockchip_get_cru(void)
+{
+ struct udevice *dev;
+ fdt_addr_t addr;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_CLK, 0, &dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ addr = dev_get_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return ERR_PTR(-EINVAL);
+
+ return (void *)addr;
+}
+
+static int rkclk_set_pll(struct rk3036_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3036_pll *pll = &cru->pll[pll_id];
+
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
+ uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
+
+ debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, postdiv2=%d,\
+ vco=%u Hz, output=%u Hz\n",
+ pll, div->fbdiv, div->refdiv, div->postdiv1,
+ div->postdiv2, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
+
+ /* use interger mode */
+ rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+ (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
+ PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+ div->refdiv << PLL_REFDIV_SHIFT));
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ udelay(1);
+
+ return 0;
+}
+
+static void rkclk_init(struct rk3036_cru *cru)
+{
+ u32 aclk_div;
+ u32 hclk_div;
+ u32 pclk_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ APLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+
+ /*
+ * select apll as core clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ * core hz : apll = 1:1
+ */
+ aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);
+
+ pclk_div = APLL_HZ / CORE_PERI_HZ - 1;
+ assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_CLK_PLL_SEL_MASK << CORE_CLK_PLL_SEL_SHIFT |
+ CORE_DIV_CON_MASK << CORE_DIV_CON_SHIFT,
+ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+ 0 << CORE_DIV_CON_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CORE_ACLK_DIV_MASK << CORE_ACLK_DIV_SHIFT |
+ CORE_PERI_DIV_MASK << CORE_PERI_DIV_SHIFT,
+ aclk_div << CORE_ACLK_DIV_SHIFT |
+ pclk_div << CORE_PERI_DIV_SHIFT);
+
+ /*
+ * select apll as cpu clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = APLL_HZ / CPU_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CPU_ACLK_HZ == APLL_HZ && aclk_div < 0x1f);
+
+ pclk_div = APLL_HZ / CPU_PCLK_HZ - 1;
+ assert((pclk_div + 1) * CPU_PCLK_HZ == APLL_HZ && pclk_div < 0x7);
+
+ hclk_div = APLL_HZ / CPU_HCLK_HZ - 1;
+ assert((hclk_div + 1) * CPU_HCLK_HZ == APLL_HZ && hclk_div < 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CPU_CLK_PLL_SEL_MASK << CPU_CLK_PLL_SEL_SHIFT |
+ ACLK_CPU_DIV_MASK << ACLK_CPU_DIV_SHIFT,
+ CPU_CLK_PLL_SEL_APLL << CPU_CLK_PLL_SEL_SHIFT |
+ aclk_div << ACLK_CPU_DIV_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
+ CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
+ pclk_div << CPU_PCLK_DIV_SHIFT |
+ hclk_div << CPU_HCLK_DIV_SHIFT);
+
+ /*
+ * select gpll as peri clock pll source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && pclk_div < 0x8);
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PLL_SEL_MASK << PERI_PLL_SEL_SHIFT |
+ PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+ PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+ PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ GPLL_MODE_NORM << GPLL_MODE_SHIFT |
+ APLL_MODE_NORM << APLL_MODE_SHIFT);
+}
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3036_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t refdiv, fbdiv, postdiv1, postdiv2;
+ uint32_t con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3036_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,
+ GPLL_MODE_SHIFT, 0xff
+ };
+ static u8 clk_mask[CLK_COUNT] = {
+ 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,
+ GPLL_MODE_MASK, 0xff
+ };
+ uint shift;
+ uint mask;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ mask = clk_mask[clk_id];
+
+ switch ((con >> shift) & mask) {
+ case GPLL_MODE_SLOW:
+ return OSC_HZ;
+ case GPLL_MODE_NORM:
+
+ /* normal mode */
+ con = readl(&pll->con0);
+ postdiv1 = (con >> PLL_POSTDIV1_SHIFT) & PLL_POSTDIV1_MASK;
+ fbdiv = (con >> PLL_FBDIV_SHIFT) & PLL_FBDIV_MASK;
+ con = readl(&pll->con1);
+ postdiv2 = (con >> PLL_POSTDIV2_SHIFT) & PLL_POSTDIV2_MASK;
+ refdiv = (con >> PLL_REFDIV_SHIFT) & PLL_REFDIV_MASK;
+ return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+ case GPLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3036_cru *cru, uint clk_general_rate,
+ int periph)
+{
+ uint src_rate;
+ uint div, mux;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
+ div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ break;
+ case HCLK_SDIO:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
+ div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
+ return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3036_cru *cru, uint clk_general_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+ int mux;
+
+ debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
+
+ /* mmc clock auto divide 2 in internal */
+ src_clk_div = (clk_general_rate / 2 + freq - 1) / freq;
+
+ if (src_clk_div > 0x7f) {
+ src_clk_div = (OSC_HZ / 2 + freq - 1) / freq;
+ mux = EMMC_SEL_24M;
+ } else {
+ mux = EMMC_SEL_GPLL;
+ }
+
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_PLL_MASK << EMMC_PLL_SHIFT |
+ EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ mux << EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDIO:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_PLL_MASK << MMC0_PLL_SHIFT |
+ MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ mux << MMC0_PLL_SHIFT |
+ (src_clk_div - 1) << MMC0_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+}
+
+static ulong rk3036_clk_get_rate(struct clk *clk)
+{
+ struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0 ... 63:
+ return rkclk_pll_get_rate(priv->cru, clk->id);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rk3036_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3036_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 0 ... 63:
+ return 0;
+ case HCLK_EMMC:
+ new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
+ clk->id, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3036_clk_ops = {
+ .get_rate = rk3036_clk_get_rate,
+ .set_rate = rk3036_clk_set_rate,
+};
+
+static int rk3036_clk_probe(struct udevice *dev)
+{
+ struct rk3036_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3036_cru *)dev_get_addr(dev);
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rk3036_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
+ if (ret)
+ debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rk3036_clk_ids[] = {
+ { .compatible = "rockchip,rk3036-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(clk_rk3036) = {
+ .name = "clk_rk3036",
+ .id = UCLASS_CLK,
+ .of_match = rk3036_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3036_clk_priv),
+ .ops = &rk3036_clk_ops,
+ .bind = rk3036_clk_bind,
+ .probe = rk3036_clk_probe,
+};
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
new file mode 100644
index 0000000..e00feb0
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -0,0 +1,851 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#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>
+#include <asm/arch/cru_rk3288.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/hardware.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3288_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3288_cru dtd;
+#endif
+};
+
+struct rk3288_clk_priv {
+ struct rk3288_grf *grf;
+ struct rk3288_cru *cru;
+ ulong rate;
+};
+
+struct pll_div {
+ u32 nr;
+ u32 nf;
+ u32 no;
+};
+
+enum {
+ VCO_MAX_HZ = 2200U * 1000000,
+ VCO_MIN_HZ = 440 * 1000000,
+ OUTPUT_MAX_HZ = 2200U * 1000000,
+ OUTPUT_MIN_HZ = 27500000,
+ FREF_MAX_HZ = 2200U * 1000000,
+ FREF_MIN_HZ = 269 * 1000,
+};
+
+enum {
+ /* PLL CON0 */
+ PLL_OD_MASK = 0x0f,
+
+ /* PLL CON1 */
+ PLL_NF_MASK = 0x1fff,
+
+ /* PLL CON2 */
+ PLL_BWADJ_MASK = 0x0fff,
+
+ /* PLL CON3 */
+ PLL_RESET_SHIFT = 5,
+
+ /* CLKSEL0 */
+ CORE_SEL_PLL_MASK = 1,
+ CORE_SEL_PLL_SHIFT = 15,
+ A17_DIV_MASK = 0x1f,
+ A17_DIV_SHIFT = 8,
+ MP_DIV_MASK = 0xf,
+ MP_DIV_SHIFT = 4,
+ M0_DIV_MASK = 0xf,
+ M0_DIV_SHIFT = 0,
+
+ /* CLKSEL1: pd bus clk pll sel: codec or general */
+ PD_BUS_SEL_PLL_MASK = 15,
+ PD_BUS_SEL_CPLL = 0,
+ PD_BUS_SEL_GPLL,
+
+ /* pd bus pclk div: pclk = pd_bus_aclk /(div + 1) */
+ PD_BUS_PCLK_DIV_SHIFT = 12,
+ PD_BUS_PCLK_DIV_MASK = 7,
+
+ /* pd bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
+ PD_BUS_HCLK_DIV_SHIFT = 8,
+ PD_BUS_HCLK_DIV_MASK = 3,
+
+ /* pd bus aclk div: pd_bus_aclk = pd_bus_src_clk /(div0 * div1) */
+ PD_BUS_ACLK_DIV0_SHIFT = 3,
+ PD_BUS_ACLK_DIV0_MASK = 0x1f,
+ PD_BUS_ACLK_DIV1_SHIFT = 0,
+ PD_BUS_ACLK_DIV1_MASK = 0x7,
+
+ /*
+ * CLKSEL10
+ * peripheral bus pclk div:
+ * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1
+ */
+ PERI_SEL_PLL_MASK = 1,
+ PERI_SEL_PLL_SHIFT = 15,
+ PERI_SEL_CPLL = 0,
+ PERI_SEL_GPLL,
+
+ PERI_PCLK_DIV_SHIFT = 12,
+ PERI_PCLK_DIV_MASK = 3,
+
+ /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */
+ PERI_HCLK_DIV_SHIFT = 8,
+ PERI_HCLK_DIV_MASK = 3,
+
+ /*
+ * peripheral bus aclk div:
+ * aclk_periph = periph_clk_src / (peri_aclk_div_con + 1)
+ */
+ PERI_ACLK_DIV_SHIFT = 0,
+ PERI_ACLK_DIV_MASK = 0x1f,
+
+ SOCSTS_DPLL_LOCK = 1 << 5,
+ SOCSTS_APLL_LOCK = 1 << 6,
+ SOCSTS_CPLL_LOCK = 1 << 7,
+ SOCSTS_GPLL_LOCK = 1 << 8,
+ SOCSTS_NPLL_LOCK = 1 << 9,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+ .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+ _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+ (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* Keep divisors as low as possible to reduce jitter and power usage */
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+
+void *rockchip_get_cru(void)
+{
+ struct rk3288_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
+
+static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3288_pll *pll = &cru->pll[pll_id];
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+ uint output_hz = vco_hz / div->no;
+
+ debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+ (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+ (div->no == 1 || !(div->no % 2)));
+
+ /* enter reset */
+ rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
+ ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+ rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+ rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+ udelay(10);
+
+ /* return from reset */
+ rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ return 0;
+}
+
+static inline unsigned int log2(unsigned int value)
+{
+ return fls(value) - 1;
+}
+
+static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
+ unsigned int hz)
+{
+ static const struct pll_div dpll_cfg[] = {
+ {.nf = 25, .nr = 2, .no = 1},
+ {.nf = 400, .nr = 9, .no = 2},
+ {.nf = 500, .nr = 9, .no = 2},
+ {.nf = 100, .nr = 3, .no = 1},
+ };
+ int cfg;
+
+ switch (hz) {
+ case 300000000:
+ cfg = 0;
+ break;
+ case 533000000: /* actually 533.3P MHz */
+ cfg = 1;
+ break;
+ case 666000000: /* actually 666.6P MHz */
+ cfg = 2;
+ break;
+ case 800000000:
+ cfg = 3;
+ break;
+ default:
+ debug("Unsupported SDRAM frequency");
+ return -EINVAL;
+ }
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+ rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
+
+ /* wait for pll lock */
+ while (!(readl(&grf->soc_status[1]) & SOCSTS_DPLL_LOCK))
+ udelay(1);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
+
+ return 0;
+}
+
+#ifndef CONFIG_SPL_BUILD
+#define VCO_MAX_KHZ 2200000
+#define VCO_MIN_KHZ 440000
+#define FREF_MAX_KHZ 2200000
+#define FREF_MIN_KHZ 269
+
+static int pll_para_config(ulong freq_hz, struct pll_div *div, uint *ext_div)
+{
+ uint ref_khz = OSC_HZ / 1000, nr, nf = 0;
+ uint fref_khz;
+ uint diff_khz, best_diff_khz;
+ const uint max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4;
+ uint vco_khz;
+ uint no = 1;
+ uint freq_khz = freq_hz / 1000;
+
+ if (!freq_hz) {
+ printf("%s: the frequency can not be 0 Hz\n", __func__);
+ return -EINVAL;
+ }
+
+ no = DIV_ROUND_UP(VCO_MIN_KHZ, freq_khz);
+ if (ext_div) {
+ *ext_div = DIV_ROUND_UP(no, max_no);
+ no = DIV_ROUND_UP(no, *ext_div);
+ }
+
+ /* only even divisors (and 1) are supported */
+ if (no > 1)
+ no = DIV_ROUND_UP(no, 2) * 2;
+
+ vco_khz = freq_khz * no;
+ if (ext_div)
+ vco_khz *= *ext_div;
+
+ if (vco_khz < VCO_MIN_KHZ || vco_khz > VCO_MAX_KHZ || no > max_no) {
+ printf("%s: Cannot find out a supported VCO for Frequency (%luHz).\n",
+ __func__, freq_hz);
+ return -1;
+ }
+
+ div->no = no;
+
+ best_diff_khz = vco_khz;
+ for (nr = 1; nr < max_nr && best_diff_khz; nr++) {
+ fref_khz = ref_khz / nr;
+ if (fref_khz < FREF_MIN_KHZ)
+ break;
+ if (fref_khz > FREF_MAX_KHZ)
+ continue;
+
+ nf = vco_khz / fref_khz;
+ if (nf >= max_nf)
+ continue;
+ diff_khz = vco_khz - nf * fref_khz;
+ if (nf + 1 < max_nf && diff_khz > fref_khz / 2) {
+ nf++;
+ diff_khz = fref_khz - diff_khz;
+ }
+
+ if (diff_khz >= best_diff_khz)
+ continue;
+
+ best_diff_khz = diff_khz;
+ div->nr = nr;
+ div->nf = nf;
+ }
+
+ if (best_diff_khz > 4 * 1000) {
+ printf("%s: Failed to match output frequency %lu, difference is %u Hz, exceed 4MHZ\n",
+ __func__, freq_hz, best_diff_khz * 1000);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rockchip_mac_set_clk(struct rk3288_cru *cru,
+ int periph, uint freq)
+{
+ /* Assuming mac_clk is fed by an external clock */
+ rk_clrsetreg(&cru->cru_clksel_con[21],
+ RMII_EXTCLK_MASK << RMII_EXTCLK_SHIFT,
+ RMII_EXTCLK_SELECT_EXT_CLK << RMII_EXTCLK_SHIFT);
+
+ return 0;
+}
+
+static int rockchip_vop_set_clk(struct rk3288_cru *cru, struct rk3288_grf *grf,
+ int periph, unsigned int rate_hz)
+{
+ struct pll_div npll_config = {0};
+ u32 lcdc_div;
+ int ret;
+
+ ret = pll_para_config(rate_hz, &npll_config, &lcdc_div);
+ if (ret)
+ return ret;
+
+ rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
+ NPLL_MODE_SLOW << NPLL_MODE_SHIFT);
+ rkclk_set_pll(cru, CLK_NEW, &npll_config);
+
+ /* waiting for pll lock */
+ while (1) {
+ if (readl(&grf->soc_status[1]) & SOCSTS_NPLL_LOCK)
+ break;
+ udelay(1);
+ }
+
+ rk_clrsetreg(&cru->cru_mode_con, NPLL_MODE_MASK << NPLL_MODE_SHIFT,
+ NPLL_MODE_NORMAL << NPLL_MODE_SHIFT);
+
+ /* vop dclk source clk: npll,dclk_div: 1 */
+ switch (periph) {
+ case DCLK_VOP0:
+ rk_clrsetreg(&cru->cru_clksel_con[27], 0xff << 8 | 3 << 0,
+ (lcdc_div - 1) << 8 | 2 << 0);
+ break;
+ case DCLK_VOP1:
+ rk_clrsetreg(&cru->cru_clksel_con[29], 0xff << 8 | 3 << 6,
+ (lcdc_div - 1) << 8 | 2 << 6);
+ break;
+ }
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
+{
+ u32 aclk_div;
+ u32 hclk_div;
+ u32 pclk_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
+
+ /* waiting for pll lock */
+ while ((readl(&grf->soc_status[1]) &
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+ udelay(1);
+
+ /*
+ * pd_bus clock pll source selection and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PD_BUS_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+ hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1;
+ assert((hclk_div + 1) * PD_BUS_HCLK_HZ ==
+ PD_BUS_ACLK_HZ && (hclk_div < 0x4) && (hclk_div != 0x2));
+
+ pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1;
+ assert((pclk_div + 1) * PD_BUS_PCLK_HZ ==
+ PD_BUS_ACLK_HZ && pclk_div < 0x7);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ PD_BUS_PCLK_DIV_MASK << PD_BUS_PCLK_DIV_SHIFT |
+ PD_BUS_HCLK_DIV_MASK << PD_BUS_HCLK_DIV_SHIFT |
+ PD_BUS_ACLK_DIV0_MASK << PD_BUS_ACLK_DIV0_SHIFT |
+ PD_BUS_ACLK_DIV1_MASK << PD_BUS_ACLK_DIV1_SHIFT,
+ pclk_div << PD_BUS_PCLK_DIV_SHIFT |
+ hclk_div << PD_BUS_HCLK_DIV_SHIFT |
+ aclk_div << PD_BUS_ACLK_DIV0_SHIFT |
+ 0 << 0);
+
+ /*
+ * peri clock pll source selection and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+ PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+ PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
+ CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
+}
+#endif
+
+void rk3288_clk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf)
+{
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ APLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+
+ /* waiting for pll lock */
+ while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK))
+ udelay(1);
+
+ /*
+ * core clock pll source selection and
+ * set up dependent divisors for MPAXI/M0AXI and ARM clocks.
+ * core clock select apll, apll clk = 1800MHz
+ * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz
+ */
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_SEL_PLL_MASK << CORE_SEL_PLL_SHIFT |
+ A17_DIV_MASK << A17_DIV_SHIFT |
+ MP_DIV_MASK << MP_DIV_SHIFT |
+ M0_DIV_MASK << M0_DIV_SHIFT,
+ 0 << A17_DIV_SHIFT |
+ 3 << MP_DIV_SHIFT |
+ 1 << M0_DIV_SHIFT);
+
+ /*
+ * set up dependent divisors for L2RAM/ATCLK and PCLK clocks.
+ * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz
+ */
+ rk_clrsetreg(&cru->cru_clksel_con[37],
+ CLK_L2RAM_DIV_MASK << CLK_L2RAM_DIV_SHIFT |
+ ATCLK_CORE_DIV_CON_MASK << ATCLK_CORE_DIV_CON_SHIFT |
+ PCLK_CORE_DBG_DIV_MASK >> PCLK_CORE_DBG_DIV_SHIFT,
+ 1 << CLK_L2RAM_DIV_SHIFT |
+ 3 << ATCLK_CORE_DIV_CON_SHIFT |
+ 3 << PCLK_CORE_DBG_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ APLL_MODE_MASK << APLL_MODE_SHIFT,
+ APLL_MODE_NORMAL << APLL_MODE_SHIFT);
+}
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t nr, no, nf;
+ uint32_t con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3288_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT, NPLL_MODE_SHIFT
+ };
+ uint shift;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ switch ((con >> shift) & APLL_MODE_MASK) {
+ case APLL_MODE_SLOW:
+ return OSC_HZ;
+ case APLL_MODE_NORMAL:
+ /* normal mode */
+ con = readl(&pll->con0);
+ no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
+ nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
+ con = readl(&pll->con1);
+ nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
+
+ return (24 * nf / (nr * no)) * 1000000;
+ case APLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3288_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint src_rate;
+ uint div, mux;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con >> EMMC_PLL_SHIFT) & EMMC_PLL_MASK;
+ div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ break;
+ case HCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ mux = (con >> MMC0_PLL_SHIFT) & MMC0_PLL_MASK;
+ div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ break;
+ case HCLK_SDIO0:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con >> SDIO0_PLL_SHIFT) & SDIO0_PLL_MASK;
+ div = (con >> SDIO0_DIV_SHIFT) & SDIO0_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ src_rate = mux == EMMC_PLL_SELECT_24MHZ ? OSC_HZ : gclk_rate;
+ return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3288_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+ int mux;
+
+ debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+ src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+
+ if (src_clk_div > 0x3f) {
+ src_clk_div = RATE_TO_DIV(OSC_HZ, freq);
+ mux = EMMC_PLL_SELECT_24MHZ;
+ assert((int)EMMC_PLL_SELECT_24MHZ ==
+ (int)MMC0_PLL_SELECT_24MHZ);
+ } else {
+ mux = EMMC_PLL_SELECT_GENERAL;
+ assert((int)EMMC_PLL_SELECT_GENERAL ==
+ (int)MMC0_PLL_SELECT_GENERAL);
+ }
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_PLL_MASK << EMMC_PLL_SHIFT |
+ EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ mux << EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_PLL_MASK << MMC0_PLL_SHIFT |
+ MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ mux << MMC0_PLL_SHIFT |
+ (src_clk_div - 1) << MMC0_DIV_SHIFT);
+ break;
+ case HCLK_SDIO0:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ SDIO0_PLL_MASK << SDIO0_PLL_SHIFT |
+ SDIO0_DIV_MASK << SDIO0_DIV_SHIFT,
+ mux << SDIO0_PLL_SHIFT |
+ (src_clk_div - 1) << SDIO0_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rockchip_spi_get_clk(struct rk3288_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div, mux;
+ u32 con;
+
+ switch (periph) {
+ case SCLK_SPI0:
+ con = readl(&cru->cru_clksel_con[25]);
+ mux = (con >> SPI0_PLL_SHIFT) & SPI0_PLL_MASK;
+ div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
+ break;
+ case SCLK_SPI1:
+ con = readl(&cru->cru_clksel_con[25]);
+ mux = (con >> SPI1_PLL_SHIFT) & SPI1_PLL_MASK;
+ div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
+ break;
+ case SCLK_SPI2:
+ con = readl(&cru->cru_clksel_con[39]);
+ mux = (con >> SPI2_PLL_SHIFT) & SPI2_PLL_MASK;
+ div = (con >> SPI2_DIV_SHIFT) & SPI2_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+ assert(mux == SPI0_PLL_SELECT_GENERAL);
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+
+ debug("%s: clk_general_rate=%u\n", __func__, gclk_rate);
+ src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+ switch (periph) {
+ case SCLK_SPI0:
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI0_PLL_MASK << SPI0_PLL_SHIFT |
+ SPI0_DIV_MASK << SPI0_DIV_SHIFT,
+ SPI0_PLL_SELECT_GENERAL << SPI0_PLL_SHIFT |
+ src_clk_div << SPI0_DIV_SHIFT);
+ break;
+ case SCLK_SPI1:
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI1_PLL_MASK << SPI1_PLL_SHIFT |
+ SPI1_DIV_MASK << SPI1_DIV_SHIFT,
+ SPI1_PLL_SELECT_GENERAL << SPI1_PLL_SHIFT |
+ src_clk_div << SPI1_DIV_SHIFT);
+ break;
+ case SCLK_SPI2:
+ rk_clrsetreg(&cru->cru_clksel_con[39],
+ SPI2_PLL_MASK << SPI2_PLL_SHIFT |
+ SPI2_DIV_MASK << SPI2_DIV_SHIFT,
+ SPI2_PLL_SELECT_GENERAL << SPI2_PLL_SHIFT |
+ src_clk_div << SPI2_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_spi_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3288_clk_get_rate(struct clk *clk)
+{
+ struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 0 ... 63:
+ new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO0:
+ new_rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ case SCLK_SPI2:
+ new_rate = rockchip_spi_get_clk(priv->cru, gclk_rate, clk->id);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_I2C4:
+ case PCLK_I2C5:
+ return gclk_rate;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rk3288_cru *cru = priv->cru;
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case CLK_DDR:
+ new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO0:
+ new_rate = rockchip_mmc_set_clk(cru, gclk_rate, clk->id, rate);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ case SCLK_SPI2:
+ new_rate = rockchip_spi_set_clk(cru, gclk_rate, clk->id, rate);
+ break;
+#ifndef CONFIG_SPL_BUILD
+ case SCLK_MAC:
+ new_rate = rockchip_mac_set_clk(priv->cru, clk->id, rate);
+ break;
+ case DCLK_VOP0:
+ case DCLK_VOP1:
+ new_rate = rockchip_vop_set_clk(cru, priv->grf, clk->id, rate);
+ break;
+ case SCLK_EDP_24M:
+ /* clk_edp_24M source: 24M */
+ rk_setreg(&cru->cru_clksel_con[28], 1 << 15);
+
+ /* rst edp */
+ rk_setreg(&cru->cru_clksel_con[6], 1 << 15);
+ udelay(1);
+ rk_clrreg(&cru->cru_clksel_con[6], 1 << 15);
+ new_rate = rate;
+ break;
+ case ACLK_VOP0:
+ case ACLK_VOP1: {
+ u32 div;
+
+ /* vop aclk source clk: cpll */
+ div = CPLL_HZ / rate;
+ assert((div - 1 < 64) && (div * rate == CPLL_HZ));
+
+ switch (clk->id) {
+ case ACLK_VOP0:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ 3 << 6 | 0x1f << 0,
+ 0 << 6 | (div - 1) << 0);
+ break;
+ case ACLK_VOP1:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ 3 << 14 | 0x1f << 8,
+ 0 << 14 | (div - 1) << 8);
+ break;
+ }
+ new_rate = rate;
+ break;
+ }
+ case PCLK_HDMI_CTRL:
+ /* enable pclk hdmi ctrl */
+ rk_clrreg(&cru->cru_clkgate_con[16], 1 << 9);
+
+ /* software reset hdmi */
+ rk_setreg(&cru->cru_clkgate_con[7], 1 << 9);
+ udelay(1);
+ rk_clrreg(&cru->cru_clkgate_con[7], 1 << 9);
+ new_rate = rate;
+ break;
+#endif
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3288_clk_ops = {
+ .get_rate = rk3288_clk_get_rate,
+ .set_rate = rk3288_clk_set_rate,
+};
+
+static int rk3288_clk_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3288_cru *)dev_get_addr(dev);
+#endif
+
+ return 0;
+}
+
+static int rk3288_clk_probe(struct udevice *dev)
+{
+ struct rk3288_clk_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
+#ifdef CONFIG_SPL_BUILD
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+
+ priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
+ rkclk_init(priv->cru, priv->grf);
+#endif
+
+ return 0;
+}
+
+static int rk3288_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
+ if (ret)
+ debug("Warning: No RK3288 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rk3288_clk_ids[] = {
+ { .compatible = "rockchip,rk3288-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_cru) = {
+ .name = "rockchip_rk3288_cru",
+ .id = UCLASS_CLK,
+ .of_match = rk3288_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3288_clk_priv),
+ .platdata_auto_alloc_size = sizeof(struct rk3288_clk_plat),
+ .ops = &rk3288_clk_ops,
+ .bind = rk3288_clk_bind,
+ .ofdata_to_platdata = rk3288_clk_ofdata_to_platdata,
+ .probe = rk3288_clk_probe,
+};
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 1/8] rockchip: move clock drivers into a subdirectory
2016-07-22 21:51 ` [U-Boot] [PATCH v2 1/8] rockchip: move clock drivers into a subdirectory Heiko Stuebner
@ 2016-07-23 2:08 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2016-07-23 2:08 UTC (permalink / raw)
To: u-boot
Hi Heiiko,
On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> With the number of Rockchip clock drivers increasing, don't clutter up
> the core drivers/clk directory with them and instead move them out of
> the way into a separate subdirectory.
>
> Suggested-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> drivers/clk/Makefile | 3 +-
> drivers/clk/clk_rk3036.c | 386 -----------------
> drivers/clk/clk_rk3288.c | 851 --------------------------------------
> drivers/clk/rockchip/Makefile | 8 +
> drivers/clk/rockchip/clk_rk3036.c | 386 +++++++++++++++++
> drivers/clk/rockchip/clk_rk3288.c | 851 ++++++++++++++++++++++++++++++++++++++
> 6 files changed, 1246 insertions(+), 1239 deletions(-)
> delete mode 100644 drivers/clk/clk_rk3036.c
> delete mode 100644 drivers/clk/clk_rk3288.c
> create mode 100644 drivers/clk/rockchip/Makefile
> create mode 100644 drivers/clk/rockchip/clk_rk3036.c
> create mode 100644 drivers/clk/rockchip/clk_rk3288.c
Can you please cc the other Rockchip people? Also did you use patman?
It should show as a rename I think.
Regards,
Simon
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 2/8] rockchip: remove log2 reimplementation from clock drivers
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 1/8] rockchip: move clock drivers into a subdirectory Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-23 2:08 ` Simon Glass
2016-07-22 21:51 ` [U-Boot] [PATCH v2 3/8] rockchip: rk3188: Add header files for PMU and GRF Heiko Stuebner
` (6 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
The already available ilog2 function does exactly the same in the common
case than the log2 function the current clock-driver reimplement.
So, simply move to that one.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/clk/rockchip/clk_rk3036.c | 10 +++-------
drivers/clk/rockchip/clk_rk3288.c | 10 +++-------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/rockchip/clk_rk3036.c b/drivers/clk/rockchip/clk_rk3036.c
index 6202c9d..8899b0c 100644
--- a/drivers/clk/rockchip/clk_rk3036.c
+++ b/drivers/clk/rockchip/clk_rk3036.c
@@ -15,6 +15,7 @@
#include <asm/arch/hardware.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3036-cru.h>
+#include <linux/log2.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -48,11 +49,6 @@ enum {
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
-static inline unsigned int log2(unsigned int value)
-{
- return fls(value) - 1;
-}
-
void *rockchip_get_cru(void)
{
struct udevice *dev;
@@ -177,11 +173,11 @@ static void rkclk_init(struct rk3036_cru *cru)
aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
- hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
assert((1 << hclk_div) * PERI_HCLK_HZ ==
PERI_ACLK_HZ && (pclk_div < 0x4));
- pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
assert((1 << pclk_div) * PERI_PCLK_HZ ==
PERI_ACLK_HZ && pclk_div < 0x8);
diff --git a/drivers/clk/rockchip/clk_rk3288.c b/drivers/clk/rockchip/clk_rk3288.c
index e00feb0..c07203d 100644
--- a/drivers/clk/rockchip/clk_rk3288.c
+++ b/drivers/clk/rockchip/clk_rk3288.c
@@ -20,6 +20,7 @@
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
+#include <linux/log2.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -186,11 +187,6 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
return 0;
}
-static inline unsigned int log2(unsigned int value)
-{
- return fls(value) - 1;
-}
-
static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf,
unsigned int hz)
{
@@ -421,11 +417,11 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf)
aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
- hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
assert((1 << hclk_div) * PERI_HCLK_HZ ==
PERI_ACLK_HZ && (hclk_div < 0x4));
- pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
assert((1 << pclk_div) * PERI_PCLK_HZ ==
PERI_ACLK_HZ && (pclk_div < 0x4));
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 3/8] rockchip: rk3188: Add header files for PMU and GRF
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 1/8] rockchip: move clock drivers into a subdirectory Heiko Stuebner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 2/8] rockchip: remove log2 reimplementation from clock drivers Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 4/8] rockchip: rk3188: Add pinctrl driver Heiko Stuebner
` (5 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
PMU is the power management unit and GRF is the general register file. Both
are heavily used in U-Boot. Add header files with register definitions.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Simon Glass <sjg@chromium.org>
---
arch/arm/include/asm/arch-rockchip/grf_rk3188.h | 589 ++++++++++++++++++++++++
arch/arm/include/asm/arch-rockchip/pmu_rk3188.h | 36 ++
2 files changed, 625 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3188.h
create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3188.h b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
new file mode 100644
index 0000000..ce7bac5
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3188.h
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _ASM_ARCH_GRF_RK3188_H
+#define _ASM_ARCH_GRF_RK3188_H
+
+struct rk3188_grf_gpio_lh {
+ u32 l;
+ u32 h;
+};
+
+struct rk3188_grf {
+ struct rk3188_grf_gpio_lh gpio_dir[4];
+ struct rk3188_grf_gpio_lh gpio_do[4];
+ struct rk3188_grf_gpio_lh gpio_en[4];
+
+ u32 reserved[2];
+ u32 gpio0c_iomux;
+ u32 gpio0d_iomux;
+
+ u32 gpio1a_iomux;
+ u32 gpio1b_iomux;
+ u32 gpio1c_iomux;
+ u32 gpio1d_iomux;
+
+ u32 gpio2a_iomux;
+ u32 gpio2b_iomux;
+ u32 gpio2c_iomux;
+ u32 gpio2d_iomux;
+
+ u32 gpio3a_iomux;
+ u32 gpio3b_iomux;
+ u32 gpio3c_iomux;
+ u32 gpio3d_iomux;
+
+ u32 soc_con0;
+ u32 soc_con1;
+ u32 soc_con2;
+ u32 soc_status0;
+
+ u32 busdmac_con[3];
+ u32 peridmac_con[4];
+
+ u32 cpu_con[6];
+ u32 reserved0[2];
+
+ u32 ddrc_con0;
+ u32 ddrc_stat;
+
+ u32 io_con[5];
+ u32 soc_status1;
+
+ u32 uoc0_con[4];
+ u32 uoc1_con[4];
+ u32 uoc2_con[2];
+ u32 reserved1;
+ u32 uoc3_con[2];
+ u32 hsic_stat;
+ u32 os_reg[8];
+
+ u32 gpio0_p[3];
+ u32 gpio1_p[3][4];
+
+ u32 flash_data_p;
+ u32 flash_cmd_p;
+};
+check_member(rk3188_grf, flash_cmd_p, 0x01a4);
+
+/* GRF_GPIO0D_IOMUX */
+enum {
+ GPIO0D7_SHIFT = 14,
+ GPIO0D7_MASK = 1,
+ GPIO0D7_GPIO = 0,
+ GPIO0D7_SPI1_CSN0,
+
+ GPIO0D6_SHIFT = 12,
+ GPIO0D6_MASK = 1,
+ GPIO0D6_GPIO = 0,
+ GPIO0D6_SPI1_CLK,
+
+ GPIO0D5_SHIFT = 10,
+ GPIO0D5_MASK = 1,
+ GPIO0D5_GPIO = 0,
+ GPIO0D5_SPI1_TXD,
+
+ GPIO0D4_SHIFT = 8,
+ GPIO0D4_MASK = 1,
+ GPIO0D4_GPIO = 0,
+ GPIO0D4_SPI0_RXD,
+
+ GPIO0D3_SHIFT = 6,
+ GPIO0D3_MASK = 3,
+ GPIO0D3_GPIO = 0,
+ GPIO0D3_FLASH_CSN3,
+ GPIO0D3_EMMC_RSTN_OUT,
+
+ GPIO0D2_SHIFT = 4,
+ GPIO0D2_MASK = 3,
+ GPIO0D2_GPIO = 0,
+ GPIO0D2_FLASH_CSN2,
+ GPIO0D2_EMMC_CMD,
+
+ GPIO0D1_SHIFT = 2,
+ GPIO0D1_MASK = 1,
+ GPIO0D1_GPIO = 0,
+ GPIO0D1_FLASH_CSN1,
+
+ GPIO0D0_SHIFT = 0,
+ GPIO0D0_MASK = 3,
+ GPIO0D0_GPIO = 0,
+ GPIO0D0_FLASH_DQS,
+ GPIO0D0_EMMC_CLKOUT
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+ GPIO1A7_SHIFT = 14,
+ GPIO1A7_MASK = 3,
+ GPIO1A7_GPIO = 0,
+ GPIO1A7_UART1_RTS_N,
+ GPIO1A7_SPI0_CSN0,
+
+ GPIO1A6_SHIFT = 12,
+ GPIO1A6_MASK = 3,
+ GPIO1A6_GPIO = 0,
+ GPIO1A6_UART1_CTS_N,
+ GPIO1A6_SPI0_CLK,
+
+ GPIO1A5_SHIFT = 10,
+ GPIO1A5_MASK = 3,
+ GPIO1A5_GPIO = 0,
+ GPIO1A5_UART1_SOUT,
+ GPIO1A5_SPI0_TXD,
+
+ GPIO1A4_SHIFT = 8,
+ GPIO1A4_MASK = 3,
+ GPIO1A4_GPIO = 0,
+ GPIO1A4_UART1_SIN,
+ GPIO1A4_SPI0_RXD,
+
+ GPIO1A3_SHIFT = 6,
+ GPIO1A3_MASK = 1,
+ GPIO1A3_GPIO = 0,
+ GPIO1A3_UART0_RTS_N,
+
+ GPIO1A2_SHIFT = 4,
+ GPIO1A2_MASK = 1,
+ GPIO1A2_GPIO = 0,
+ GPIO1A2_UART0_CTS_N,
+
+ GPIO1A1_SHIFT = 2,
+ GPIO1A1_MASK = 1,
+ GPIO1A1_GPIO = 0,
+ GPIO1A1_UART0_SOUT,
+
+ GPIO1A0_SHIFT = 0,
+ GPIO1A0_MASK = 1,
+ GPIO1A0_GPIO = 0,
+ GPIO1A0_UART0_SIN,
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+ GPIO1B7_SHIFT = 14,
+ GPIO1B7_MASK = 1,
+ GPIO1B7_GPIO = 0,
+ GPIO1B7_SPI0_CSN1,
+
+ GPIO1B6_SHIFT = 12,
+ GPIO1B6_MASK = 3,
+ GPIO1B6_GPIO = 0,
+ GPIO1B6_SPDIF_TX,
+ GPIO1B6_SPI1_CSN1,
+
+ GPIO1B5_SHIFT = 10,
+ GPIO1B5_MASK = 3,
+ GPIO1B5_GPIO = 0,
+ GPIO1B5_UART3_RTS_N,
+ GPIO1B5_RESERVED,
+
+ GPIO1B4_SHIFT = 8,
+ GPIO1B4_MASK = 3,
+ GPIO1B4_GPIO = 0,
+ GPIO1B4_UART3_CTS_N,
+ GPIO1B4_GPS_RFCLK,
+
+ GPIO1B3_SHIFT = 6,
+ GPIO1B3_MASK = 3,
+ GPIO1B3_GPIO = 0,
+ GPIO1B3_UART3_SOUT,
+ GPIO1B3_GPS_SIG,
+
+ GPIO1B2_SHIFT = 4,
+ GPIO1B2_MASK = 3,
+ GPIO1B2_GPIO = 0,
+ GPIO1B2_UART3_SIN,
+ GPIO1B2_GPS_MAG,
+
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 3,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_UART2_SOUT,
+ GPIO1B1_JTAG_TDO,
+
+ GPIO1B0_SHIFT = 0,
+ GPIO1B0_MASK = 3,
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_UART2_SIN,
+ GPIO1B0_JTAG_TDI,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+ GPIO1D7_SHIFT = 14,
+ GPIO1D7_MASK = 1,
+ GPIO1D7_GPIO = 0,
+ GPIO1D7_I2C4_SCL,
+
+ GPIO1D6_SHIFT = 12,
+ GPIO1D6_MASK = 1,
+ GPIO1D6_GPIO = 0,
+ GPIO1D6_I2C4_SDA,
+
+ GPIO1D5_SHIFT = 10,
+ GPIO1D5_MASK = 1,
+ GPIO1D5_GPIO = 0,
+ GPIO1D5_I2C2_SCL,
+
+ GPIO1D4_SHIFT = 8,
+ GPIO1D4_MASK = 1,
+ GPIO1D4_GPIO = 0,
+ GPIO1D4_I2C2_SDA,
+
+ GPIO1D3_SHIFT = 6,
+ GPIO1D3_MASK = 1,
+ GPIO1D3_GPIO = 0,
+ GPIO1D3_I2C1_SCL,
+
+ GPIO1D2_SHIFT = 4,
+ GPIO1D2_MASK = 1,
+ GPIO1D2_GPIO = 0,
+ GPIO1D2_I2C1_SDA,
+
+ GPIO1D1_SHIFT = 2,
+ GPIO1D1_MASK = 1,
+ GPIO1D1_GPIO = 0,
+ GPIO1D1_I2C0_SCL,
+
+ GPIO1D0_SHIFT = 0,
+ GPIO1D0_MASK = 1,
+ GPIO1D0_GPIO = 0,
+ GPIO1D0_I2C0_SDA,
+};
+
+/* GRF_GPIO3A_IOMUX */
+enum {
+ GPIO3A7_SHIFT = 14,
+ GPIO3A7_MASK = 1,
+ GPIO3A7_GPIO = 0,
+ GPIO3A7_SDMMC0_DATA3,
+
+ GPIO3A6_SHIFT = 12,
+ GPIO3A6_MASK = 1,
+ GPIO3A6_GPIO = 0,
+ GPIO3A6_SDMMC0_DATA2,
+
+ GPIO3A5_SHIFT = 10,
+ GPIO3A5_MASK = 1,
+ GPIO3A5_GPIO = 0,
+ GPIO3A5_SDMMC0_DATA1,
+
+ GPIO3A4_SHIFT = 8,
+ GPIO3A4_MASK = 1,
+ GPIO3A4_GPIO = 0,
+ GPIO3A4_SDMMC0_DATA0,
+
+ GPIO3A3_SHIFT = 6,
+ GPIO3A3_MASK = 1,
+ GPIO3A3_GPIO = 0,
+ GPIO3A3_SDMMC0_CMD,
+
+ GPIO3A2_SHIFT = 4,
+ GPIO3A2_MASK = 1,
+ GPIO3A2_GPIO = 0,
+ GPIO3A2_SDMMC0_CLKOUT,
+
+ GPIO3A1_SHIFT = 2,
+ GPIO3A1_MASK = 1,
+ GPIO3A1_GPIO = 0,
+ GPIO3A1_SDMMC0_PWREN,
+
+ GPIO3A0_SHIFT = 0,
+ GPIO3A0_MASK = 1,
+ GPIO3A0_GPIO = 0,
+ GPIO3A0_SDMMC0_RSTN,
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+ GPIO3B7_SHIFT = 14,
+ GPIO3B7_MASK = 3,
+ GPIO3B7_GPIO = 0,
+ GPIO3B7_CIF_DATA11,
+ GPIO3B7_I2C3_SCL,
+
+ GPIO3B6_SHIFT = 12,
+ GPIO3B6_MASK = 3,
+ GPIO3B6_GPIO = 0,
+ GPIO3B6_CIF_DATA10,
+ GPIO3B6_I2C3_SDA,
+
+ GPIO3B5_SHIFT = 10,
+ GPIO3B5_MASK = 3,
+ GPIO3B5_GPIO = 0,
+ GPIO3B5_CIF_DATA1,
+ GPIO3B5_HSADC_DATA9,
+
+ GPIO3B4_SHIFT = 8,
+ GPIO3B4_MASK = 3,
+ GPIO3B4_GPIO = 0,
+ GPIO3B4_CIF_DATA0,
+ GPIO3B4_HSADC_DATA8,
+
+ GPIO3B3_SHIFT = 6,
+ GPIO3B3_MASK = 1,
+ GPIO3B3_GPIO = 0,
+ GPIO3B3_CIF_CLKOUT,
+
+ GPIO3B2_SHIFT = 4,
+ GPIO3B2_MASK = 1,
+ GPIO3B2_GPIO = 0,
+ /* no muxes */
+
+ GPIO3B1_SHIFT = 2,
+ GPIO3B1_MASK = 1,
+ GPIO3B1_GPIO = 0,
+ GPIO3B1_SDMMC0_WRITE_PRT,
+
+ GPIO3B0_SHIFT = 0,
+ GPIO3B0_MASK = 1,
+ GPIO3B0_GPIO = 0,
+ GPIO3B0_SDMMC_DETECT_N,
+};
+
+/* GRF_GPIO3C_IOMUX */
+enum {
+ GPIO3C7_SHIFT = 14,
+ GPIO3C7_MASK = 3,
+ GPIO3C7_GPIO = 0,
+ GPIO3C7_SDMMC1_WRITE_PRT,
+ GPIO3C7_RMII_CRS_DVALID,
+ GPIO3C7_RESERVED,
+
+ GPIO3C6_SHIFT = 12,
+ GPIO3C6_MASK = 3,
+ GPIO3C6_GPIO = 0,
+ GPIO3C6_SDMMC1_DECTN,
+ GPIO3C6_RMII_RX_ERR,
+ GPIO3C6_RESERVED,
+
+ GPIO3C5_SHIFT = 10,
+ GPIO3C5_MASK = 3,
+ GPIO3C5_GPIO = 0,
+ GPIO3C5_SDMMC1_CLKOUT,
+ GPIO3C5_RMII_CLKOUT,
+ GPIO3C5_RMII_CLKIN,
+
+ GPIO3C4_SHIFT = 8,
+ GPIO3C4_MASK = 3,
+ GPIO3C4_GPIO = 0,
+ GPIO3C4_SDMMC1_DATA3,
+ GPIO3C4_RMII_RXD1,
+ GPIO3C4_RESERVED,
+
+ GPIO3C3_SHIFT = 6,
+ GPIO3C3_MASK = 3,
+ GPIO3C3_GPIO = 0,
+ GPIO3C3_SDMMC1_DATA2,
+ GPIO3C3_RMII_RXD0,
+ GPIO3C3_RESERVED,
+
+ GPIO3C2_SHIFT = 4,
+ GPIO3C2_MASK = 3,
+ GPIO3C2_GPIO = 0,
+ GPIO3C2_SDMMC1_DATA1,
+ GPIO3C2_RMII_TXD0,
+ GPIO3C2_RESERVED,
+
+ GPIO3C1_SHIFT = 2,
+ GPIO3C1_MASK = 3,
+ GPIO3C1_GPIO = 0,
+ GPIO3C1_SDMMC1_DATA0,
+ GPIO3C1_RMII_TXD1,
+ GPIO3C1_RESERVED,
+
+ GPIO3C0_SHIFT = 0,
+ GPIO3C0_MASK = 3,
+ GPIO3C0_GPIO = 0,
+ GPIO3C0_SDMMC1_CMD,
+ GPIO3C0_RMII_TX_EN,
+ GPIO3C0_RESERVED,
+};
+
+/* GRF_GPIO3D_IOMUX */
+enum {
+ GPIO3D6_SHIFT = 12,
+ GPIO3D6_MASK = 3,
+ GPIO3D6_GPIO = 0,
+ GPIO3D6_PWM_3,
+ GPIO3D6_JTAG_TMS,
+ GPIO3D6_HOST_DRV_VBUS,
+
+ GPIO3D5_SHIFT = 10,
+ GPIO3D5_MASK = 3,
+ GPIO3D5_GPIO = 0,
+ GPIO3D5_PWM_2,
+ GPIO3D5_JTAG_TCK,
+ GPIO3D5_OTG_DRV_VBUS,
+
+ GPIO3D4_SHIFT = 8,
+ GPIO3D4_MASK = 3,
+ GPIO3D4_GPIO = 0,
+ GPIO3D4_PWM_1,
+ GPIO3D4_JTAG_TRSTN,
+
+ GPIO3D3_SHIFT = 6,
+ GPIO3D3_MASK = 3,
+ GPIO3D3_GPIO = 0,
+ GPIO3D3_PWM_0,
+
+ GPIO3D2_SHIFT = 4,
+ GPIO3D2_MASK = 3,
+ GPIO3D2_GPIO = 0,
+ GPIO3D2_SDMMC1_INT_N,
+
+ GPIO3D1_SHIFT = 2,
+ GPIO3D1_MASK = 3,
+ GPIO3D1_GPIO = 0,
+ GPIO3D1_SDMMC1_BACKEND_PWR,
+ GPIO3D1_MII_MDCLK,
+
+ GPIO3D0_SHIFT = 0,
+ GPIO3D0_MASK = 3,
+ GPIO3D0_GPIO = 0,
+ GPIO3D0_SDMMC1_PWR_EN,
+ GPIO3D0_MII_MD,
+};
+
+/* GRF_SOC_CON0 */
+enum {
+ HSADC_CLK_DIR_SHIFT = 15,
+ HSADC_CLK_DIR_MASK = 1,
+
+ HSADC_SEL_SHIFT = 14,
+ HSADC_SEL_MASK = 1,
+
+ NOC_REMAP_SHIFT = 12,
+ NOC_REMAP_MASK = 1,
+
+ EMMC_FLASH_SEL_SHIFT = 11,
+ EMMC_FLASH_SEL_MASK = 1,
+
+ TZPC_REVISION_SHIFT = 7,
+ TZPC_REVISION_MASK = 0xf,
+
+ L2CACHE_ACC_SHIFT = 5,
+ L2CACHE_ACC_MASK = 3,
+
+ L2RD_WAIT_SHIFT = 3,
+ L2RD_WAIT_MASK = 3,
+
+ IMEMRD_WAIT_SHIFT = 1,
+ IMEMRD_WAIT_MASK = 3,
+};
+
+/* GRF_SOC_CON1 */
+enum {
+ RKI2C4_SEL_SHIFT = 15,
+ RKI2C4_SEL_MASK = 1,
+
+ RKI2C3_SEL_SHIFT = 14,
+ RKI2C3_SEL_MASK = 1,
+
+ RKI2C2_SEL_SHIFT = 13,
+ RKI2C2_SEL_MASK = 1,
+
+ RKI2C1_SEL_SHIFT = 12,
+ RKI2C1_SEL_MASK = 1,
+
+ RKI2C0_SEL_SHIFT = 11,
+ RKI2C0_SEL_MASK = 1,
+
+ VCODEC_SEL_SHIFT = 10,
+ VCODEC_SEL_MASK = 1,
+
+ PERI_EMEM_PAUSE_SHIFT = 9,
+ PERI_EMEM_PAUSE_MASK = 1,
+
+ PERI_USB_PAUSE_SHIFT = 8,
+ PERI_USB_PAUSE_MASK = 1,
+
+ SMC_MUX_MODE_0_SHIFT = 6,
+ SMC_MUX_MODE_0_MASK = 1,
+
+ SMC_SRAM_MW_0_SHIFT = 4,
+ SMC_SRAM_MW_0_MASK = 3,
+
+ SMC_REMAP_0_SHIFT = 3,
+ SMC_REMAP_0_MASK = 1,
+
+ SMC_A_GT_M0_SYNC_SHIFT = 2,
+ SMC_A_GT_M0_SYNC_MASK = 1,
+
+ EMAC_SPEED_SHIFT = 1,
+ EMAC_SPEEC_MASK = 1,
+
+ EMAC_MODE_SHIFT = 0,
+ EMAC_MODE_MASK = 1,
+};
+
+/* GRF_SOC_CON2 */
+enum {
+ SDIO_CLK_OUT_SR_SHIFT = 15,
+ SDIO_CLK_OUT_SR_MASK = 1,
+
+ MEM_EMA_L2C_SHIFT = 11,
+ MEM_EMA_L2C_MASK = 7,
+
+ MEM_EMA_A9_SHIFT = 8,
+ MEM_EMA_A9_MASK = 7,
+
+ MSCH4_MAINDDR3_SHIFT = 7,
+ MSCH4_MAINDDR3_MASK = 1,
+ MSCH4_MAINDDR3_DDR3 = 1,
+
+ EMAC_NEWRCV_EN_SHIFT = 6,
+ EMAC_NEWRCV_EN_MASK = 1,
+
+ SW_ADDR15_EN_SHIFT = 5,
+ SW_ADDR15_EN_MASK = 1,
+
+ SW_ADDR16_EN_SHIFT = 4,
+ SW_ADDR16_EN_MASK = 1,
+
+ SW_ADDR17_EN_SHIFT = 3,
+ SW_ADDR17_EN_MASK = 1,
+
+ BANK2_TO_RANK_EN_SHIFT = 2,
+ BANK2_TO_RANK_EN_MASK = 1,
+
+ RANK_TO_ROW15_EN_SHIFT = 1,
+ RANK_TO_ROW15_EN_MASK = 1,
+
+ UPCTL_C_ACTIVE_IN_SHIFT = 0,
+ UPCTL_C_ACTIVE_IN_MASK = 1,
+ UPCTL_C_ACTIVE_IN_MAY = 0,
+ UPCTL_C_ACTIVE_IN_WILL,
+};
+
+/* GRF_DDRC_CON0 */
+enum {
+ DDR_16BIT_EN_SHIFT = 15,
+ DDR_16BIT_EN_MASK = 1,
+
+ DTO_LB_SHIFT = 11,
+ DTO_LB_MASK = 3,
+
+ DTO_TE_SHIFT = 9,
+ DTO_TE_MASK = 3,
+
+ DTO_PDR_SHIFT = 7,
+ DTO_PDR_MASK = 3,
+
+ DTO_PDD_SHIFT = 5,
+ DTO_PDD_MASK = 3,
+
+ DTO_IOM_SHIFT = 3,
+ DTO_IOM_MASK = 3,
+
+ DTO_OE_SHIFT = 1,
+ DTO_OE_MASK = 3,
+
+ ATO_AE_SHIFT = 0,
+ ATO_AE_MASK = 1,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h b/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
new file mode 100644
index 0000000..d3feac3
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_PMU_RK3188_H
+#define _ASM_ARCH_PMU_RK3188_H
+
+struct rk3188_pmu {
+ u32 wakeup_cfg[2];
+ u32 pwrdn_con;
+ u32 pwrdn_st;
+
+ u32 int_con;
+ u32 int_st;
+ u32 misc_con;
+
+ u32 osc_cnt;
+ u32 pll_cnt;
+ u32 pmu_cnt;
+ u32 ddrio_pwron_cnt;
+ u32 wakeup_rst_clr_cnt;
+ u32 scu_pwrdwn_cnt;
+ u32 scu_pwrup_cnt;
+ u32 misc_con1;
+ u32 gpio0_con;
+
+ u32 sys_reg[4];
+ u32 reserved0[4];
+ u32 stop_int_dly;
+ u32 gpio0_p[2];
+};
+check_member(rk3188_pmu, gpio0_p[1], 0x0068);
+
+#endif
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 4/8] rockchip: rk3188: Add pinctrl driver
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (2 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 3/8] rockchip: rk3188: Add header files for PMU and GRF Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 5/8] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings Heiko Stuebner
` (4 subsequent siblings)
8 siblings, 0 replies; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
Add a driver which supports pin multiplexing setup for the most commonly
used peripherals.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Simon Glass <sjg@chromium.org>
---
drivers/pinctrl/Kconfig | 9 +
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl_rk3188.c | 613 ++++++++++++++++++++++++++++++
3 files changed, 623 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3188.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 2972dba..0d8ee19 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -141,6 +141,15 @@ config ROCKCHIP_RK3288_PINCTRL
definitions and pin control functions for each available multiplex
function.
+config ROCKCHIP_RK3188_PINCTRL
+ bool "Rockchip pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3188 SoCs. The driver
+ is controlled by a device tree node which contains both the GPIO
+ definitions and pin control functions for each available multiplex
+ function.
+
config PINCTRL_SANDBOX
bool "Sandbox pinctrl driver"
depends on SANDBOX
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 64e9587..7768628 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -6,4 +6,5 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3188_PINCTRL) += pinctrl_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o
diff --git a/drivers/pinctrl/rockchip/pinctrl_rk3188.c b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
new file mode 100644
index 0000000..f98356d
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl_rk3188.c
@@ -0,0 +1,613 @@
+/*
+ * Pinctrl driver for Rockchip RK3188 SoCs
+ * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pmu_rk3188.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3188_pinctrl_priv {
+ struct rk3188_grf *grf;
+ struct rk3188_pmu *pmu;
+ int num_banks;
+};
+
+/**
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY BIT(0)
+
+/**
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ * an initial offset value the relevant source offset can be reset
+ * to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+ u8 type;
+ s16 offset;
+};
+
+/**
+ * @reg: register offset of the gpio bank
+ * @nr_pins: number of pins in this bank
+ * @bank_num: number of the bank, to account for holes
+ * @name: name of the bank
+ * @iomux: array describing the 4 iomux sources of the bank
+ */
+struct rockchip_pin_bank {
+ u16 reg;
+ u8 nr_pins;
+ u8 bank_num;
+ char *name;
+ struct rockchip_iomux iomux[4];
+};
+
+#define PIN_BANK(id, pins, label) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ }, \
+ }
+
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
+ }
+
+#ifndef CONFIG_SPL_BUILD
+static struct rockchip_pin_bank rk3188_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
+ PIN_BANK(1, 32, "gpio1"),
+ PIN_BANK(2, 32, "gpio2"),
+ PIN_BANK(3, 32, "gpio3"),
+};
+#endif
+
+static void pinctrl_rk3188_pwm_config(struct rk3188_grf *grf, int pwm_id)
+{
+ switch (pwm_id) {
+ case PERIPH_ID_PWM0:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D3_MASK << GPIO3D3_SHIFT,
+ GPIO3D3_PWM_0 << GPIO3D3_SHIFT);
+ break;
+ case PERIPH_ID_PWM1:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D4_MASK << GPIO3D4_SHIFT,
+ GPIO3D4_PWM_1 << GPIO3D4_SHIFT);
+ break;
+ case PERIPH_ID_PWM2:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D5_MASK << GPIO3D5_SHIFT,
+ GPIO3D5_PWM_2 << GPIO3D5_SHIFT);
+ break;
+ case PERIPH_ID_PWM3:
+ rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D6_MASK << GPIO3D6_SHIFT,
+ GPIO3D6_PWM_3 << GPIO3D6_SHIFT);
+ break;
+ default:
+ debug("pwm id = %d iomux error!\n", pwm_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3188_i2c_config(struct rk3188_grf *grf,
+ struct rk3188_pmu *pmu, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D1_MASK << GPIO1D1_SHIFT |
+ GPIO1D0_MASK << GPIO1D0_SHIFT,
+ GPIO1D1_I2C0_SCL << GPIO1D1_SHIFT |
+ GPIO1D0_I2C0_SDA << GPIO1D0_SHIFT);
+ /* enable new i2c controller */
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C0_SEL_SHIFT,
+ 1 << RKI2C0_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D3_MASK << GPIO1D3_SHIFT |
+ GPIO1D2_MASK << GPIO1D2_SHIFT,
+ GPIO1D3_I2C1_SCL << GPIO1D2_SHIFT |
+ GPIO1D2_I2C1_SDA << GPIO1D2_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C1_SEL_SHIFT,
+ 1 << RKI2C1_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D5_MASK << GPIO1D5_SHIFT |
+ GPIO1D4_MASK << GPIO1D4_SHIFT,
+ GPIO1D5_I2C2_SCL << GPIO1D5_SHIFT |
+ GPIO1D4_I2C2_SDA << GPIO1D4_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C2_SEL_SHIFT,
+ 1 << RKI2C2_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C3:
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GPIO3B7_MASK << GPIO3B7_SHIFT |
+ GPIO3B6_MASK << GPIO3B6_SHIFT,
+ GPIO3B7_I2C3_SCL << GPIO3B7_SHIFT |
+ GPIO3B6_I2C3_SDA << GPIO3B6_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C3_SEL_SHIFT,
+ 1 << RKI2C3_SEL_SHIFT);
+ break;
+ case PERIPH_ID_I2C4:
+ rk_clrsetreg(&grf->gpio1d_iomux,
+ GPIO1D7_MASK << GPIO1D7_SHIFT |
+ GPIO1D6_MASK << GPIO1D6_SHIFT,
+ GPIO1D7_I2C4_SCL << GPIO1D7_SHIFT |
+ GPIO1D6_I2C4_SDA << GPIO1D6_SHIFT);
+ rk_clrsetreg(&grf->soc_con1, 1 << RKI2C4_SEL_SHIFT,
+ 1 << RKI2C4_SEL_SHIFT);
+ break;
+ default:
+ debug("i2c id = %d iomux error!\n", i2c_id);
+ break;
+ }
+}
+
+static int pinctrl_rk3188_spi_config(struct rk3188_grf *grf,
+ enum periph_id spi_id, int cs)
+{
+ switch (spi_id) {
+ case PERIPH_ID_SPI0:
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A7_MASK << GPIO1A7_SHIFT,
+ GPIO1A7_SPI0_CSN0 << GPIO1A7_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B7_MASK << GPIO1B7_SHIFT,
+ GPIO1B7_SPI0_CSN1 << GPIO1B7_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A4_MASK << GPIO1A4_SHIFT |
+ GPIO1A5_MASK << GPIO1A5_SHIFT |
+ GPIO1A6_MASK << GPIO1A6_SHIFT,
+ GPIO1A4_SPI0_RXD << GPIO1A4_SHIFT |
+ GPIO1A5_SPI0_TXD << GPIO1A5_SHIFT |
+ GPIO1A6_SPI0_CLK << GPIO1A6_SHIFT);
+ break;
+ case PERIPH_ID_SPI1:
+ switch (cs) {
+ case 0:
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D7_MASK << GPIO0D7_SHIFT,
+ GPIO0D7_SPI1_CSN0 << GPIO0D7_SHIFT);
+ break;
+ case 1:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B6_MASK << GPIO1B6_SHIFT,
+ GPIO1B6_SPI1_CSN1 << GPIO1B6_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D4_MASK << GPIO0D4_SHIFT |
+ GPIO0D5_MASK << GPIO0D5_SHIFT |
+ GPIO0D6_MASK << GPIO0D6_SHIFT,
+ GPIO0D4_SPI0_RXD << GPIO0D4_SHIFT |
+ GPIO0D5_SPI1_TXD << GPIO0D5_SHIFT |
+ GPIO0D6_SPI1_CLK << GPIO0D6_SHIFT);
+ break;
+ default:
+ goto err;
+ }
+
+ return 0;
+err:
+ debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
+ return -ENOENT;
+}
+
+static void pinctrl_rk3188_uart_config(struct rk3188_grf *grf, int uart_id)
+{
+ switch (uart_id) {
+ case PERIPH_ID_UART0:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A3_MASK << GPIO1A3_SHIFT |
+ GPIO1A2_MASK << GPIO1A2_SHIFT |
+ GPIO1A1_MASK << GPIO1A1_SHIFT |
+ GPIO1A0_MASK << GPIO1A0_SHIFT,
+ GPIO1A3_UART0_RTS_N << GPIO1A3_SHIFT |
+ GPIO1A2_UART0_CTS_N << GPIO1A2_SHIFT |
+ GPIO1A1_UART0_SOUT << GPIO1A1_SHIFT |
+ GPIO1A0_UART0_SIN << GPIO1A0_SHIFT);
+ break;
+ case PERIPH_ID_UART1:
+ rk_clrsetreg(&grf->gpio1a_iomux,
+ GPIO1A7_MASK << GPIO1A7_SHIFT |
+ GPIO1A6_MASK << GPIO1A6_SHIFT |
+ GPIO1A5_MASK << GPIO1A5_SHIFT |
+ GPIO1A4_MASK << GPIO1A4_SHIFT,
+ GPIO1A7_UART1_RTS_N << GPIO1A7_SHIFT |
+ GPIO1A6_UART1_CTS_N << GPIO1A6_SHIFT |
+ GPIO1A5_UART1_SOUT << GPIO1A5_SHIFT |
+ GPIO1A4_UART1_SIN << GPIO1A4_SHIFT);
+ break;
+ case PERIPH_ID_UART2:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK << GPIO1B1_SHIFT |
+ GPIO1B0_MASK << GPIO1B0_SHIFT,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+ break;
+ case PERIPH_ID_UART3:
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B5_MASK << GPIO1B5_SHIFT |
+ GPIO1B4_MASK << GPIO1B4_SHIFT |
+ GPIO1B3_MASK << GPIO1B3_SHIFT |
+ GPIO1B2_MASK << GPIO1B2_SHIFT,
+ GPIO1B5_UART3_RTS_N << GPIO1B5_SHIFT |
+ GPIO1B4_UART3_CTS_N << GPIO1B4_SHIFT |
+ GPIO1B3_UART3_SOUT << GPIO1B3_SHIFT |
+ GPIO1B2_UART3_SIN << GPIO1B2_SHIFT);
+ break;
+ default:
+ debug("uart id = %d iomux error!\n", uart_id);
+ break;
+ }
+}
+
+static void pinctrl_rk3188_sdmmc_config(struct rk3188_grf *grf, int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->soc_con0, 1 << EMMC_FLASH_SEL_SHIFT,
+ 1 << EMMC_FLASH_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio0d_iomux,
+ GPIO0D2_MASK << GPIO0D2_SHIFT |
+ GPIO0D0_MASK << GPIO0D0_SHIFT,
+ GPIO0D2_EMMC_CMD << GPIO0D2_SHIFT |
+ GPIO0D0_EMMC_CLKOUT << GPIO0D0_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GPIO3B0_MASK << GPIO3B0_SHIFT,
+ GPIO3B0_SDMMC_DETECT_N << GPIO3B0_SHIFT);
+ rk_clrsetreg(&grf->gpio3a_iomux,
+ GPIO3A7_MASK << GPIO3A7_SHIFT |
+ GPIO3A6_MASK << GPIO3A6_SHIFT |
+ GPIO3A5_MASK << GPIO3A5_SHIFT |
+ GPIO3A4_MASK << GPIO3A4_SHIFT |
+ GPIO3A3_MASK << GPIO3A3_SHIFT |
+ GPIO3A3_MASK << GPIO3A2_SHIFT,
+ GPIO3A7_SDMMC0_DATA3 << GPIO3A7_SHIFT |
+ GPIO3A6_SDMMC0_DATA2 << GPIO3A6_SHIFT |
+ GPIO3A5_SDMMC0_DATA1 << GPIO3A5_SHIFT |
+ GPIO3A4_SDMMC0_DATA0 << GPIO3A4_SHIFT |
+ GPIO3A3_SDMMC0_CMD << GPIO3A3_SHIFT |
+ GPIO3A2_SDMMC0_CLKOUT << GPIO3A2_SHIFT);
+ break;
+ default:
+ debug("mmc id = %d iomux error!\n", mmc_id);
+ break;
+ }
+}
+
+static int rk3188_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_PWM0:
+ case PERIPH_ID_PWM1:
+ case PERIPH_ID_PWM2:
+ case PERIPH_ID_PWM3:
+ case PERIPH_ID_PWM4:
+ pinctrl_rk3188_pwm_config(priv->grf, func);
+ break;
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ case PERIPH_ID_I2C3:
+ case PERIPH_ID_I2C4:
+ case PERIPH_ID_I2C5:
+ pinctrl_rk3188_i2c_config(priv->grf, priv->pmu, func);
+ break;
+ case PERIPH_ID_SPI0:
+ case PERIPH_ID_SPI1:
+ case PERIPH_ID_SPI2:
+ pinctrl_rk3188_spi_config(priv->grf, func, flags);
+ break;
+ case PERIPH_ID_UART0:
+ case PERIPH_ID_UART1:
+ case PERIPH_ID_UART2:
+ case PERIPH_ID_UART3:
+ case PERIPH_ID_UART4:
+ pinctrl_rk3188_uart_config(priv->grf, func);
+ break;
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3188_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3188_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 44:
+ return PERIPH_ID_SPI0;
+ case 45:
+ return PERIPH_ID_SPI1;
+ case 46:
+ return PERIPH_ID_SPI2;
+ case 60:
+ return PERIPH_ID_I2C0;
+ case 62: /* Note strange order */
+ return PERIPH_ID_I2C1;
+ case 61:
+ return PERIPH_ID_I2C2;
+ case 63:
+ return PERIPH_ID_I2C3;
+ case 64:
+ return PERIPH_ID_I2C4;
+ case 65:
+ return PERIPH_ID_I2C5;
+ }
+
+ return -ENOENT;
+}
+
+static int rk3188_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3188_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+ return rk3188_pinctrl_request(dev, func, 0);
+}
+
+#ifndef CONFIG_SPL_BUILD
+int rk3188_pinctrl_get_pin_info(struct rk3188_pinctrl_priv *priv,
+ int banknum, int ind, u32 **addrp, uint *shiftp,
+ uint *maskp)
+{
+ struct rockchip_pin_bank *bank = &rk3188_pin_banks[banknum];
+ uint muxnum;
+ u32 *addr;
+
+ for (muxnum = 0; muxnum < 4; muxnum++) {
+ struct rockchip_iomux *mux = &bank->iomux[muxnum];
+
+ if (ind >= 8) {
+ ind -= 8;
+ continue;
+ }
+
+ addr = &priv->grf->gpio0c_iomux - 2;
+ addr += mux->offset;
+ *shiftp = ind & 7;
+ *maskp = 3;
+ *shiftp *= 2;
+
+ debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
+ *maskp, *shiftp);
+ *addrp = addr;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int rk3188_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
+ int index)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ uint shift;
+ uint mask;
+ u32 *addr;
+ int ret;
+
+ ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+ &mask);
+ if (ret)
+ return ret;
+ return (readl(addr) & mask) >> shift;
+}
+
+static int rk3188_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
+ int muxval, int flags)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ uint shift, ind = index;
+ uint mask;
+ u32 *addr;
+ int ret;
+
+ debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
+ ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
+ &mask);
+ if (ret)
+ return ret;
+ rk_clrsetreg(addr, mask << shift, muxval << shift);
+
+ /* Handle pullup/pulldown */
+ if (flags) {
+ uint val = 0;
+
+ if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
+ val = 1;
+ else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
+ val = 2;
+
+ ind = index >> 3;
+
+ if (banknum == 0 && index < 12) {
+ addr = &priv->pmu->gpio0_p[ind];
+ shift = (index & 7) * 2;
+ } else if (banknum == 0 && index >= 12) {
+ addr = &priv->grf->gpio0_p[ind - 1];
+ /*
+ * The bits in the grf-registers have an inverse
+ * ordering with the lowest pin being in bits 15:14
+ * and the highest pin in bits 1:0 .
+ */
+ shift = (7 - (index & 7)) * 2;
+ } else {
+ addr = &priv->grf->gpio1_p[banknum - 1][ind];
+ shift = (7 - (index & 7)) * 2;
+ }
+ debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
+ shift);
+ rk_clrsetreg(addr, 3 << shift, val << shift);
+ }
+
+ return 0;
+}
+
+static int rk3188_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+ const void *blob = gd->fdt_blob;
+ int pcfg_node, ret, flags, count, i;
+ u32 cell[60], *ptr;
+
+ debug("%s: %s %s\n", __func__, dev->name, config->name);
+ ret = fdtdec_get_int_array_count(blob, config->of_offset,
+ "rockchip,pins", cell,
+ ARRAY_SIZE(cell));
+ if (ret < 0) {
+ debug("%s: bad array %d\n", __func__, ret);
+ return -EINVAL;
+ }
+ count = ret;
+ for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
+ pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
+ if (pcfg_node < 0)
+ return -EINVAL;
+ flags = pinctrl_decode_pin_config(blob, pcfg_node);
+ if (flags < 0)
+ return flags;
+
+ ret = rk3188_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
+ flags);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+static struct pinctrl_ops rk3188_pinctrl_ops = {
+#ifndef CONFIG_SPL_BUILD
+ .set_state = rk3188_pinctrl_set_state,
+ .get_gpio_mux = rk3188_pinctrl_get_gpio_mux,
+#endif
+ .set_state_simple = rk3188_pinctrl_set_state_simple,
+ .request = rk3188_pinctrl_request,
+ .get_periph_id = rk3188_pinctrl_get_periph_id,
+};
+
+static int rk3188_pinctrl_bind(struct udevice *dev)
+{
+ /* scan child GPIO banks */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static int rk3188_pinctrl_parse_tables(struct rk3188_pinctrl_priv *priv,
+ struct rockchip_pin_bank *banks,
+ int count)
+{
+ struct rockchip_pin_bank *bank;
+ uint reg, muxnum, banknum;
+
+ reg = 0;
+ for (banknum = 0; banknum < count; banknum++) {
+ bank = &banks[banknum];
+ bank->reg = reg;
+ debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
+ for (muxnum = 0; muxnum < 4; muxnum++) {
+ struct rockchip_iomux *mux = &bank->iomux[muxnum];
+
+ mux->offset = reg;
+ reg += 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int rk3188_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+ debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
+#ifndef CONFIG_SPL_BUILD
+ ret = rk3188_pinctrl_parse_tables(priv, rk3188_pin_banks,
+ ARRAY_SIZE(rk3188_pin_banks));
+#endif
+
+ return ret;
+}
+
+static const struct udevice_id rk3188_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3188-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3188) = {
+ .name = "pinctrl_rk3188",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3188_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3188_pinctrl_priv),
+ .ops = &rk3188_pinctrl_ops,
+ .bind = rk3188_pinctrl_bind,
+ .probe = rk3188_pinctrl_probe,
+};
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 5/8] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (3 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 4/8] rockchip: rk3188: Add pinctrl driver Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-23 2:08 ` Simon Glass
2016-07-22 21:51 ` [U-Boot] [PATCH v2 6/8] rockchip: rk3188: Add clock driver Heiko Stuebner
` (3 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
Bring in required device clock binding files from Linux.
The clock trees for rk3066 and rk3188 are largely similar, which makes
them share the common parts in a shared header. While we focus on rk3188
for now, bring in both headers already for completeness sake.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
include/dt-bindings/clock/rk3066a-cru.h | 32 ++++
include/dt-bindings/clock/rk3188-cru-common.h | 248 ++++++++++++++++++++++++++
include/dt-bindings/clock/rk3188-cru.h | 48 +++++
3 files changed, 328 insertions(+)
create mode 100644 include/dt-bindings/clock/rk3066a-cru.h
create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h
create mode 100644 include/dt-bindings/clock/rk3188-cru.h
diff --git a/include/dt-bindings/clock/rk3066a-cru.h b/include/dt-bindings/clock/rk3066a-cru.h
new file mode 100644
index 0000000..549ae6a
--- /dev/null
+++ b/include/dt-bindings/clock/rk3066a-cru.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
+
+#include <dt-bindings/clock/rk3188-cru-common.h>
+
+/* soft-reset indices */
+#define SRST_SRST1 0
+#define SRST_SRST2 1
+
+#define SRST_L2MEM 18
+#define SRST_I2S0 23
+#define SRST_I2S1 24
+#define SRST_I2S2 25
+#define SRST_TIMER2 29
+
+#define SRST_GPIO4 36
+#define SRST_GPIO6 38
+
+#define SRST_TSADC 92
+
+#define SRST_HDMI 96
+#define SRST_HDMI_APB 97
+#define SRST_CIF1 111
+
+#endif
diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
new file mode 100644
index 0000000..f07c4a4
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
+
+/* core clocks from */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_GPLL 4
+#define CORE_PERI 5
+#define CORE_L2C 6
+#define ARMCLK 7
+
+/* sclk gates (special clocks) */
+#define SCLK_UART0 64
+#define SCLK_UART1 65
+#define SCLK_UART2 66
+#define SCLK_UART3 67
+#define SCLK_MAC 68
+#define SCLK_SPI0 69
+#define SCLK_SPI1 70
+#define SCLK_SARADC 71
+#define SCLK_SDMMC 72
+#define SCLK_SDIO 73
+#define SCLK_EMMC 74
+#define SCLK_I2S0 75
+#define SCLK_I2S1 76
+#define SCLK_I2S2 77
+#define SCLK_SPDIF 78
+#define SCLK_CIF0 79
+#define SCLK_CIF1 80
+#define SCLK_OTGPHY0 81
+#define SCLK_OTGPHY1 82
+#define SCLK_HSADC 83
+#define SCLK_TIMER0 84
+#define SCLK_TIMER1 85
+#define SCLK_TIMER2 86
+#define SCLK_TIMER3 87
+#define SCLK_TIMER4 88
+#define SCLK_TIMER5 89
+#define SCLK_TIMER6 90
+#define SCLK_JTAG 91
+#define SCLK_SMC 92
+#define SCLK_TSADC 93
+
+#define DCLK_LCDC0 190
+#define DCLK_LCDC1 191
+
+/* aclk gates */
+#define ACLK_DMA1 192
+#define ACLK_DMA2 193
+#define ACLK_GPS 194
+#define ACLK_LCDC0 195
+#define ACLK_LCDC1 196
+#define ACLK_GPU 197
+#define ACLK_SMC 198
+#define ACLK_CIF 199
+#define ACLK_IPP 200
+#define ACLK_RGA 201
+#define ACLK_CIF0 202
+
+/* pclk gates */
+#define PCLK_GRF 320
+#define PCLK_PMU 321
+#define PCLK_TIMER0 322
+#define PCLK_TIMER1 323
+#define PCLK_TIMER2 324
+#define PCLK_TIMER3 325
+#define PCLK_PWM01 326
+#define PCLK_PWM23 327
+#define PCLK_SPI0 328
+#define PCLK_SPI1 329
+#define PCLK_SARADC 330
+#define PCLK_WDT 331
+#define PCLK_UART0 332
+#define PCLK_UART1 333
+#define PCLK_UART2 334
+#define PCLK_UART3 335
+#define PCLK_I2C0 336
+#define PCLK_I2C1 337
+#define PCLK_I2C2 338
+#define PCLK_I2C3 339
+#define PCLK_I2C4 340
+#define PCLK_GPIO0 341
+#define PCLK_GPIO1 342
+#define PCLK_GPIO2 343
+#define PCLK_GPIO3 344
+#define PCLK_GPIO4 345
+#define PCLK_GPIO6 346
+#define PCLK_EFUSE 347
+#define PCLK_TZPC 348
+#define PCLK_TSADC 349
+
+/* hclk gates */
+#define HCLK_SDMMC 448
+#define HCLK_SDIO 449
+#define HCLK_EMMC 450
+#define HCLK_OTG0 451
+#define HCLK_EMAC 452
+#define HCLK_SPDIF 453
+#define HCLK_I2S0 454
+#define HCLK_I2S1 455
+#define HCLK_I2S2 456
+#define HCLK_OTG1 457
+#define HCLK_HSIC 458
+#define HCLK_HSADC 459
+#define HCLK_PIDF 460
+#define HCLK_LCDC0 461
+#define HCLK_LCDC1 462
+#define HCLK_ROM 463
+#define HCLK_CIF0 464
+#define HCLK_IPP 465
+#define HCLK_RGA 466
+#define HCLK_NANDC0 467
+
+#define CLK_NR_CLKS (HCLK_NANDC0 + 1)
+
+/* soft-reset indices */
+#define SRST_MCORE 2
+#define SRST_CORE0 3
+#define SRST_CORE1 4
+#define SRST_MCORE_DBG 7
+#define SRST_CORE0_DBG 8
+#define SRST_CORE1_DBG 9
+#define SRST_CORE0_WDT 12
+#define SRST_CORE1_WDT 13
+#define SRST_STRC_SYS 14
+#define SRST_L2C 15
+
+#define SRST_CPU_AHB 17
+#define SRST_AHB2APB 19
+#define SRST_DMA1 20
+#define SRST_INTMEM 21
+#define SRST_ROM 22
+#define SRST_SPDIF 26
+#define SRST_TIMER0 27
+#define SRST_TIMER1 28
+#define SRST_EFUSE 30
+
+#define SRST_GPIO0 32
+#define SRST_GPIO1 33
+#define SRST_GPIO2 34
+#define SRST_GPIO3 35
+
+#define SRST_UART0 39
+#define SRST_UART1 40
+#define SRST_UART2 41
+#define SRST_UART3 42
+#define SRST_I2C0 43
+#define SRST_I2C1 44
+#define SRST_I2C2 45
+#define SRST_I2C3 46
+#define SRST_I2C4 47
+
+#define SRST_PWM0 48
+#define SRST_PWM1 49
+#define SRST_DAP_PO 50
+#define SRST_DAP 51
+#define SRST_DAP_SYS 52
+#define SRST_TPIU_ATB 53
+#define SRST_PMU_APB 54
+#define SRST_GRF 55
+#define SRST_PMU 56
+#define SRST_PERI_AXI 57
+#define SRST_PERI_AHB 58
+#define SRST_PERI_APB 59
+#define SRST_PERI_NIU 60
+#define SRST_CPU_PERI 61
+#define SRST_EMEM_PERI 62
+#define SRST_USB_PERI 63
+
+#define SRST_DMA2 64
+#define SRST_SMC 65
+#define SRST_MAC 66
+#define SRST_NANC0 68
+#define SRST_USBOTG0 69
+#define SRST_USBPHY0 70
+#define SRST_OTGC0 71
+#define SRST_USBOTG1 72
+#define SRST_USBPHY1 73
+#define SRST_OTGC1 74
+#define SRST_HSADC 76
+#define SRST_PIDFILTER 77
+#define SRST_DDR_MSCH 79
+
+#define SRST_TZPC 80
+#define SRST_SDMMC 81
+#define SRST_SDIO 82
+#define SRST_EMMC 83
+#define SRST_SPI0 84
+#define SRST_SPI1 85
+#define SRST_WDT 86
+#define SRST_SARADC 87
+#define SRST_DDRPHY 88
+#define SRST_DDRPHY_APB 89
+#define SRST_DDRCTL 90
+#define SRST_DDRCTL_APB 91
+#define SRST_DDRPUB 93
+
+#define SRST_VIO0_AXI 98
+#define SRST_VIO0_AHB 99
+#define SRST_LCDC0_AXI 100
+#define SRST_LCDC0_AHB 101
+#define SRST_LCDC0_DCLK 102
+#define SRST_LCDC1_AXI 103
+#define SRST_LCDC1_AHB 104
+#define SRST_LCDC1_DCLK 105
+#define SRST_IPP_AXI 106
+#define SRST_IPP_AHB 107
+#define SRST_RGA_AXI 108
+#define SRST_RGA_AHB 109
+#define SRST_CIF0 110
+
+#define SRST_VCODEC_AXI 112
+#define SRST_VCODEC_AHB 113
+#define SRST_VIO1_AXI 114
+#define SRST_VCODEC_CPU 115
+#define SRST_VCODEC_NIU 116
+#define SRST_GPU 120
+#define SRST_GPU_NIU 122
+#define SRST_TFUN_ATB 125
+#define SRST_TFUN_APB 126
+#define SRST_CTI4_APB 127
+
+#define SRST_TPIU_APB 128
+#define SRST_TRACE 129
+#define SRST_CORE_DBG 130
+#define SRST_DBG_APB 131
+#define SRST_CTI0 132
+#define SRST_CTI0_APB 133
+#define SRST_CTI1 134
+#define SRST_CTI1_APB 135
+#define SRST_PTM_CORE0 136
+#define SRST_PTM_CORE1 137
+#define SRST_PTM0 138
+#define SRST_PTM0_ATB 139
+#define SRST_PTM1 140
+#define SRST_PTM1_ATB 141
+#define SRST_CTM 142
+#define SRST_TS 143
+
+#endif
diff --git a/include/dt-bindings/clock/rk3188-cru.h b/include/dt-bindings/clock/rk3188-cru.h
new file mode 100644
index 0000000..b6960b0
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
+
+#include <dt-bindings/clock/rk3188-cru-common.h>
+
+/* soft-reset indices */
+#define SRST_PTM_CORE2 0
+#define SRST_PTM_CORE3 1
+#define SRST_CORE2 5
+#define SRST_CORE3 6
+#define SRST_CORE2_DBG 10
+#define SRST_CORE3_DBG 11
+
+#define SRST_TIMER2 16
+#define SRST_TIMER4 23
+#define SRST_I2S0 24
+#define SRST_TIMER5 25
+#define SRST_TIMER3 29
+#define SRST_TIMER6 31
+
+#define SRST_PTM3 36
+#define SRST_PTM3_ATB 37
+
+#define SRST_GPS 67
+#define SRST_HSICPHY 75
+#define SRST_TIMER 78
+
+#define SRST_PTM2 92
+#define SRST_CORE2_WDT 94
+#define SRST_CORE3_WDT 95
+
+#define SRST_PTM2_ATB 111
+
+#define SRST_HSIC 117
+#define SRST_CTI2 118
+#define SRST_CTI2_APB 119
+#define SRST_GPU_BRIDGE 121
+#define SRST_CTI3 123
+#define SRST_CTI3_APB 124
+
+#endif
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 5/8] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings
2016-07-22 21:51 ` [U-Boot] [PATCH v2 5/8] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings Heiko Stuebner
@ 2016-07-23 2:08 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2016-07-23 2:08 UTC (permalink / raw)
To: u-boot
On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> Bring in required device clock binding files from Linux.
> The clock trees for rk3066 and rk3188 are largely similar, which makes
> them share the common parts in a shared header. While we focus on rk3188
> for now, bring in both headers already for completeness sake.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> include/dt-bindings/clock/rk3066a-cru.h | 32 ++++
> include/dt-bindings/clock/rk3188-cru-common.h | 248 ++++++++++++++++++++++++++
> include/dt-bindings/clock/rk3188-cru.h | 48 +++++
> 3 files changed, 328 insertions(+)
> create mode 100644 include/dt-bindings/clock/rk3066a-cru.h
> create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h
> create mode 100644 include/dt-bindings/clock/rk3188-cru.h
Acked-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 6/8] rockchip: rk3188: Add clock driver
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (4 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 5/8] rockchip: rk3188: Bring in rk3066/rk3188 clock bindings Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-23 2:08 ` Simon Glass
2016-07-22 21:51 ` [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support Heiko Stuebner
` (2 subsequent siblings)
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
Add a driver for setting up and modifying the various PLLs and peripheral
clocks on the RK3188.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/include/asm/arch-rockchip/cru_rk3188.h | 183 +++++++++
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk_rk3188.c | 493 ++++++++++++++++++++++++
3 files changed, 677 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3188.h
create mode 100644 drivers/clk/rockchip/clk_rk3188.c
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3188.h b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
new file mode 100644
index 0000000..8d1daec
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3188.h
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_CRU_RK3188_H
+#define _ASM_ARCH_CRU_RK3188_H
+
+#define OSC_HZ (24 * 1000 * 1000)
+
+#define APLL_HZ (1608 * 1000000)
+#define GPLL_HZ (594 * 1000000)
+#define CPLL_HZ (384 * 1000000)
+
+/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
+#define CPU_ACLK_HZ 297000000
+#define CPU_HCLK_HZ 148500000
+#define CPU_PCLK_HZ 74250000
+#define CPU_H2P_HZ 74250000
+
+#define PERI_ACLK_HZ 148500000
+#define PERI_HCLK_HZ 148500000
+#define PERI_PCLK_HZ 74250000
+
+struct rk3188_cru {
+ struct rk3188_pll {
+ u32 con0;
+ u32 con1;
+ u32 con2;
+ u32 con3;
+ } pll[4];
+ u32 cru_mode_con;
+ u32 cru_clksel_con[35];
+ u32 cru_clkgate_con[10];
+ u32 reserved1[2];
+ u32 cru_glb_srst_fst_value;
+ u32 cru_glb_srst_snd_value;
+ u32 reserved2[2];
+ u32 cru_softrst_con[9];
+ u32 cru_misc_con;
+ u32 reserved3[2];
+ u32 cru_glb_cnt_th;
+};
+check_member(rk3188_cru, cru_glb_cnt_th, 0x0140);
+
+/* CRU_CLKSEL0_CON */
+enum {
+ /* a9_core_div: core = core_src / (a9_core_div + 1) */
+ A9_CORE_DIV_SHIFT = 9,
+ A9_CORE_DIV_MASK = 0x1f,
+ CORE_PLL_SHIFT = 8,
+ CORE_PLL_MASK = 1,
+ CORE_PLL_SELECT_APLL = 0,
+ CORE_PLL_SELECT_GPLL,
+
+ /* core peri div: core:core_peri = 2:1, 4:1, 8:1 or 16:1 */
+ CORE_PERI_DIV_SHIFT = 6,
+ CORE_PERI_DIV_MASK = 3,
+
+ /* aclk_cpu pll selection */
+ CPU_ACLK_PLL_SHIFT = 5,
+ CPU_ACLK_PLL_MASK = 1,
+ CPU_ACLK_PLL_SELECT_APLL = 0,
+ CPU_ACLK_PLL_SELECT_GPLL,
+
+ /* a9_cpu_div: aclk_cpu = cpu_src / (a9_cpu_div + 1) */
+ A9_CPU_DIV_SHIFT = 0,
+ A9_CPU_DIV_MASK = 0x1f,
+};
+
+/* CRU_CLKSEL1_CON */
+enum {
+ /* ahb2apb_pclk_div: hclk_cpu:pclk_cpu = 1:1, 2:1 or 4:1 */
+ AHB2APB_DIV_SHIFT = 14,
+ AHB2APB_DIV_MASK = 3,
+
+ /* cpu_pclk_div: aclk_cpu:pclk_cpu = 1:1, 2:1, 4:1 or 8:1 */
+ CPU_PCLK_DIV_SHIFT = 12,
+ CPU_PCLK_DIV_MASK = 3,
+
+ /* cpu_hclk_div: aclk_cpu:hclk_cpu = 1:1, 2:1 or 4:1 */
+ CPU_HCLK_DIV_SHIFT = 8,
+ CPU_HCLK_DIV_MASK = 3,
+
+ /* core_aclk_div: cire:aclk_core = 1:1, 2:1, 3:1, 4:1 or 8:1 */
+ CORE_ACLK_DIV_SHIFT = 3,
+ CORE_ACLK_DIV_MASK = 7,
+};
+
+/* CRU_CLKSEL10_CON */
+enum {
+ PERI_SEL_PLL_MASK = 1,
+ PERI_SEL_PLL_SHIFT = 15,
+ PERI_SEL_CPLL = 0,
+ PERI_SEL_GPLL,
+
+ /* peri pclk div: aclk_bus:pclk_bus = 1:1, 2:1, 4:1 or 8:1 */
+ PERI_PCLK_DIV_SHIFT = 12,
+ PERI_PCLK_DIV_MASK = 3,
+
+ /* peripheral bus hclk div:aclk_bus: hclk_bus = 1:1, 2:1 or 4:1 */
+ PERI_HCLK_DIV_SHIFT = 8,
+ PERI_HCLK_DIV_MASK = 3,
+
+ /* peri aclk div: aclk_peri = periph_src / (peri_aclk_div + 1) */
+ PERI_ACLK_DIV_SHIFT = 0,
+ PERI_ACLK_DIV_MASK = 0x1f,
+};
+/* CRU_CLKSEL11_CON */
+enum {
+ HSICPHY_DIV_SHIFT = 8,
+ HSICPHY_DIV_MASK = 0x3f,
+
+ MMC0_DIV_SHIFT = 0,
+ MMC0_DIV_MASK = 0x3f,
+};
+
+/* CRU_CLKSEL12_CON */
+enum {
+ UART_PLL_SHIFT = 15,
+ UART_PLL_MASK = 1,
+ UART_PLL_SELECT_GENERAL = 0,
+ UART_PLL_SELECT_CODEC,
+
+ EMMC_DIV_SHIFT = 8,
+ EMMC_DIV_MASK = 0x3f,
+
+ SDIO_DIV_SHIFT = 0,
+ SDIO_DIV_MASK = 0x3f,
+};
+
+/* CRU_CLKSEL25_CON */
+enum {
+ SPI1_DIV_SHIFT = 8,
+ SPI1_DIV_MASK = 0x7f,
+
+ SPI0_DIV_SHIFT = 0,
+ SPI0_DIV_MASK = 0x7f,
+};
+
+/* CRU_MODE_CON */
+enum {
+ GPLL_MODE_SHIFT = 12,
+ GPLL_MODE_MASK = 3,
+ GPLL_MODE_SLOW = 0,
+ GPLL_MODE_NORMAL,
+ GPLL_MODE_DEEP,
+
+ CPLL_MODE_SHIFT = 8,
+ CPLL_MODE_MASK = 3,
+ CPLL_MODE_SLOW = 0,
+ CPLL_MODE_NORMAL,
+ CPLL_MODE_DEEP,
+
+ DPLL_MODE_SHIFT = 4,
+ DPLL_MODE_MASK = 3,
+ DPLL_MODE_SLOW = 0,
+ DPLL_MODE_NORMAL,
+ DPLL_MODE_DEEP,
+
+ APLL_MODE_SHIFT = 0,
+ APLL_MODE_MASK = 3,
+ APLL_MODE_SLOW = 0,
+ APLL_MODE_NORMAL,
+ APLL_MODE_DEEP,
+};
+
+/* CRU_APLL_CON0 */
+enum {
+ CLKR_SHIFT = 8,
+ CLKR_MASK = 0x3f,
+
+ CLKOD_SHIFT = 0,
+ CLKOD_MASK = 0x3f,
+};
+
+/* CRU_APLL_CON1 */
+enum {
+ CLKF_SHIFT = 0,
+ CLKF_MASK = 0x1fff,
+};
+
+#endif
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index acfd858..cf922b4 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -5,4 +5,5 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
diff --git a/drivers/clk/rockchip/clk_rk3188.c b/drivers/clk/rockchip/clk_rk3188.c
new file mode 100644
index 0000000..6a6f4c2
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3188.c
@@ -0,0 +1,493 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#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>
+#include <asm/arch/cru_rk3188.h>
+#include <asm/arch/grf_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <dt-bindings/clock/rk3188-cru.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+#include <linux/log2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum rk3188_clk_type {
+ RK3188_CRU,
+ RK3188A_CRU,
+};
+
+struct rk3188_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3188_cru dtd;
+#endif
+};
+
+struct rk3188_clk_priv {
+ struct rk3188_grf *grf;
+ struct rk3188_cru *cru;
+ ulong rate;
+ bool has_bwadj;
+};
+
+struct pll_div {
+ u32 nr;
+ u32 nf;
+ u32 no;
+};
+
+enum {
+ VCO_MAX_HZ = 2200U * 1000000,
+ VCO_MIN_HZ = 440 * 1000000,
+ OUTPUT_MAX_HZ = 2200U * 1000000,
+ OUTPUT_MIN_HZ = 30 * 1000000,
+ FREF_MAX_HZ = 2200U * 1000000,
+ FREF_MIN_HZ = 30 * 1000,
+};
+
+enum {
+ /* PLL CON0 */
+ PLL_OD_MASK = 0x0f,
+
+ /* PLL CON1 */
+ PLL_NF_MASK = 0x1fff,
+
+ /* PLL CON2 */
+ PLL_BWADJ_MASK = 0x0fff,
+
+ /* PLL CON3 */
+ PLL_RESET_SHIFT = 5,
+
+ /* GRF_SOC_STATUS0 */
+ SOCSTS_DPLL_LOCK = 1 << 5,
+ SOCSTS_APLL_LOCK = 1 << 6,
+ SOCSTS_CPLL_LOCK = 1 << 7,
+ SOCSTS_GPLL_LOCK = 1 << 8,
+};
+
+#define RATE_TO_DIV(input_rate, output_rate) \
+ ((input_rate) / (output_rate) - 1);
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+ .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+ _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+ (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__));
+
+/* Keep divisors as low as possible to reduce jitter and power usage */
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+
+void *rockchip_get_cru(void)
+{
+ struct rk3188_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
+
+static int rkclk_set_pll(struct rk3188_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div, bool has_bwadj)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3188_pll *pll = &cru->pll[pll_id];
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+ uint output_hz = vco_hz / div->no;
+
+ debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
+ (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+ (div->no == 1 || !(div->no % 2)));
+
+ /* enter reset */
+ rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
+ ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+ rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+
+ if (has_bwadj)
+ rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+ udelay(10);
+
+ /* return from reset */
+ rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
+
+ return 0;
+}
+
+static void rkclk_init(struct rk3188_cru *cru, struct rk3188_grf *grf,
+ bool has_bwadj)
+{
+ u32 aclk_div, hclk_div, pclk_div, h2p_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg, has_bwadj);
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg, has_bwadj);
+
+ /* waiting for pll lock */
+ while ((readl(&grf->soc_status0) &
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+ udelay(1);
+
+ /*
+ * cpu clock pll source selection and
+ * reparent aclk_cpu_pre from apll to gpll
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = RATE_TO_DIV(GPLL_HZ, CPU_ACLK_HZ);
+ assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CPU_ACLK_PLL_MASK << CPU_ACLK_PLL_SHIFT |
+ A9_CPU_DIV_MASK << A9_CPU_DIV_SHIFT,
+ CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
+ aclk_div << A9_CPU_DIV_SHIFT);
+
+ hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
+ assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
+ pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
+ assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
+ h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
+ assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ AHB2APB_DIV_MASK << AHB2APB_DIV_SHIFT |
+ CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
+ CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
+ h2p_div << AHB2APB_DIV_SHIFT |
+ pclk_div << CPU_PCLK_DIV_SHIFT |
+ hclk_div << CPU_HCLK_DIV_SHIFT);
+
+ /*
+ * peri clock pll source selection and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
+ PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
+ PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
+ PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK << GPLL_MODE_SHIFT |
+ CPLL_MODE_MASK << CPLL_MODE_SHIFT,
+ GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
+ CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
+}
+
+/* Get pll rate by id */
+static uint32_t rkclk_pll_get_rate(struct rk3188_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ uint32_t nr, no, nf;
+ uint32_t con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3188_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT
+ };
+ uint shift;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ switch ((con >> shift) & APLL_MODE_MASK) {
+ case APLL_MODE_SLOW:
+ return OSC_HZ;
+ case APLL_MODE_NORMAL:
+ /* normal mode */
+ con = readl(&pll->con0);
+ no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
+ nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
+ con = readl(&pll->con1);
+ nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
+
+ return (24 * nf / (nr * no)) * 1000000;
+ case APLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
+ break;
+ case HCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
+ break;
+ case HCLK_SDIO:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = (con >> SDIO_DIV_SHIFT) & SDIO_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+
+ debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+ src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+ assert(src_clk_div <= 0x3f);
+
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_DIV_MASK << EMMC_DIV_SHIFT,
+ src_clk_div << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_DIV_MASK << MMC0_DIV_SHIFT,
+ src_clk_div << MMC0_DIV_SHIFT);
+ break;
+ case HCLK_SDIO:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ SDIO_DIV_MASK << SDIO_DIV_SHIFT,
+ src_clk_div << SDIO_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rockchip_spi_get_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case SCLK_SPI0:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
+ break;
+ case SCLK_SPI1:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rockchip_spi_set_clk(struct rk3188_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div = RATE_TO_DIV(gclk_rate, freq);
+
+ switch (periph) {
+ case SCLK_SPI0:
+ assert(src_clk_div <= SPI0_DIV_MASK);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI0_DIV_MASK << SPI0_DIV_SHIFT,
+ src_clk_div << SPI0_DIV_SHIFT);
+ break;
+ case SCLK_SPI1:
+ assert(src_clk_div <= SPI1_DIV_MASK);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI1_DIV_MASK << SPI1_DIV_SHIFT,
+ src_clk_div << SPI1_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_spi_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3188_clk_get_rate(struct clk *clk)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 1 ... 4:
+ new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ new_rate = rockchip_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
+ clk->id);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rockchip_spi_get_clk(priv->cru, PERI_PCLK_HZ,
+ clk->id);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_I2C4:
+ return gclk_rate;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static ulong rk3188_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rk3188_cru *cru = priv->cru;
+ ulong new_rate;
+
+ switch (clk->id) {
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ new_rate = rockchip_mmc_set_clk(cru, PERI_HCLK_HZ,
+ clk->id, rate);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rockchip_spi_set_clk(cru, PERI_PCLK_HZ,
+ clk->id, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3188_clk_ops = {
+ .get_rate = rk3188_clk_get_rate,
+ .set_rate = rk3188_clk_set_rate,
+};
+
+static int rk3188_clk_ofdata_to_platdata(struct udevice *dev)
+{
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3188_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3188_cru *)dev_get_addr(dev);
+#endif
+
+ return 0;
+}
+
+static int rk3188_clk_probe(struct udevice *dev)
+{
+ struct rk3188_clk_priv *priv = dev_get_priv(dev);
+ enum rk3188_clk_type type = dev_get_driver_data(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
+ priv->has_bwadj = (type == RK3188A_CRU) ? 1 : 0;
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3188_clk_plat *plat = dev_get_platdata(dev);
+
+ priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
+
+ /* we don't have a spl yet, so call rkclk_init at the regular time */
+ rkclk_init(priv->cru, priv->grf, priv->has_bwadj);
+
+ return 0;
+}
+
+static int rk3188_clk_bind(struct udevice *dev)
+{
+ int ret;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "rk3188_sysreset", "reset", &dev);
+ if (ret)
+ debug("Warning: No rk3188 reset driver: ret=%d\n", ret);
+
+ return 0;
+}
+
+static const struct udevice_id rk3188_clk_ids[] = {
+ { .compatible = "rockchip,rk3188-cru", .data = RK3188_CRU },
+ { .compatible = "rockchip,rk3188a-cru", .data = RK3188A_CRU },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_cru) = {
+ .name = "rockchip_rk3188_cru",
+ .id = UCLASS_CLK,
+ .of_match = rk3188_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3188_clk_priv),
+ .platdata_auto_alloc_size = sizeof(struct rk3188_clk_plat),
+ .ops = &rk3188_clk_ops,
+ .bind = rk3188_clk_bind,
+ .ofdata_to_platdata = rk3188_clk_ofdata_to_platdata,
+ .probe = rk3188_clk_probe,
+};
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 6/8] rockchip: rk3188: Add clock driver
2016-07-22 21:51 ` [U-Boot] [PATCH v2 6/8] rockchip: rk3188: Add clock driver Heiko Stuebner
@ 2016-07-23 2:08 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2016-07-23 2:08 UTC (permalink / raw)
To: u-boot
On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> Add a driver for setting up and modifying the various PLLs and peripheral
> clocks on the RK3188.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> arch/arm/include/asm/arch-rockchip/cru_rk3188.h | 183 +++++++++
> drivers/clk/rockchip/Makefile | 1 +
> drivers/clk/rockchip/clk_rk3188.c | 493 ++++++++++++++++++++++++
> 3 files changed, 677 insertions(+)
> create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3188.h
> create mode 100644 drivers/clk/rockchip/clk_rk3188.c
Acked-by: Simon Glass <sjg@chromium.org>
Do you actually using CONFIG_OF_PLATDATA?
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (5 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 6/8] rockchip: rk3188: Add clock driver Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-22 21:54 ` Heiko Stübner
2016-07-22 21:51 ` [U-Boot] [PATCH v2 8/8] rockchip: rk3188: Radxa Rock board Heiko Stuebner
2016-07-28 3:42 ` [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Simon Glass
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
Add the core architecture code for the rk3188.
It doesn't support the SPL yet, as because of some
unknown error it doesn't start yet.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/dts/rk3188.dtsi | 631 ++++++++++++++++++++++++++
arch/arm/dts/rk3xxx.dtsi | 431 ++++++++++++++++++
arch/arm/mach-rockchip/Kconfig | 11 +
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rk3188/Kconfig | 9 +
arch/arm/mach-rockchip/rk3188/Makefile | 9 +
arch/arm/mach-rockchip/rk3188/clk_rk3188.c | 17 +
arch/arm/mach-rockchip/rk3188/reset_rk3188.c | 47 ++
arch/arm/mach-rockchip/rk3188/syscon_rk3188.c | 24 +
include/configs/rk3188_common.h | 95 ++++
tools/rkcommon.c | 1 +
11 files changed, 1276 insertions(+)
create mode 100644 arch/arm/dts/rk3188.dtsi
create mode 100644 arch/arm/dts/rk3xxx.dtsi
create mode 100644 arch/arm/mach-rockchip/rk3188/Kconfig
create mode 100644 arch/arm/mach-rockchip/rk3188/Makefile
create mode 100644 arch/arm/mach-rockchip/rk3188/clk_rk3188.c
create mode 100644 arch/arm/mach-rockchip/rk3188/reset_rk3188.c
create mode 100644 arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
create mode 100644 include/configs/rk3188_common.h
diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
new file mode 100644
index 0000000..ef1b962
--- /dev/null
+++ b/arch/arm/dts/rk3188.dtsi
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3188-cru.h>
+#include "rk3xxx.dtsi"
+
+/ {
+ compatible = "rockchip,rk3188";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+
+ cpu0: cpu at 0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ operating-points = <
+ /* kHz uV */
+ 1608000 1350000
+ 1416000 1250000
+ 1200000 1150000
+ 1008000 1075000
+ 816000 975000
+ 600000 950000
+ 504000 925000
+ 312000 875000
+ >;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu at 1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ cpu at 2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x2>;
+ };
+ cpu at 3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x3>;
+ };
+ };
+
+ sram: sram at 10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x8000>;
+
+ smp-sram at 0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x0 0x50>;
+ };
+ };
+
+ i2s0: i2s at 1011a000 {
+ compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
+ reg = <0x1011a000 0x2000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+ dma-names = "tx", "rx";
+ clock-names = "i2s_hclk", "i2s_clk";
+ clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ status = "disabled";
+ };
+
+ spdif: sound at 1011e000 {
+ compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+ reg = <0x1011e000 0x2000>;
+ #sound-dai-cells = <0>;
+ clock-names = "hclk", "mclk";
+ clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+ dmas = <&dmac1_s 8>;
+ dma-names = "tx";
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx>;
+ status = "disabled";
+ };
+
+ cru: clock-controller at 20000000 {
+ compatible = "rockchip,rk3188-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ efuse: efuse at 20010000 {
+ compatible = "rockchip,rockchip-efuse";
+ reg = <0x20010000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage at 17 {
+ reg = <0x17 0x1>;
+ };
+ };
+
+ usbphy: phy {
+ compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ usbphy0: usb-phy at 10c {
+ #phy-cells = <0>;
+ reg = <0x10c>;
+ clocks = <&cru SCLK_OTGPHY0>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ };
+
+ usbphy1: usb-phy at 11c {
+ #phy-cells = <0>;
+ reg = <0x11c>;
+ clocks = <&cru SCLK_OTGPHY1>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ };
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3188-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmu>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0 at 2000a000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2000a000 0x100>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1 at 2003c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003c000 0x100>;
+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2 at 2003e000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003e000 0x100>;
+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio3 at 20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg_pull_up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg_pull_down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg_pull_none {
+ bias-disable;
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <RK_GPIO0 24 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <RK_GPIO0 26 RK_FUNC_2 &pcfg_pull_up>;
+ };
+
+ emmc_rst: emmc-rst {
+ rockchip,pins = <RK_GPIO0 27 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ /*
+ * The data pins are shared between nandc and emmc and
+ * not accessible through pinctrl. Also they should've
+ * been already set correctly by firmware, as
+ * flash/emmc is the boot-device.
+ */
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_2 &pcfg_pull_none>, /* tx_en */
+ <RK_GPIO3 17 RK_FUNC_2 &pcfg_pull_none>, /* txd1 */
+ <RK_GPIO3 18 RK_FUNC_2 &pcfg_pull_none>, /* txd0 */
+ <RK_GPIO3 19 RK_FUNC_2 &pcfg_pull_none>, /* rxd0 */
+ <RK_GPIO3 20 RK_FUNC_2 &pcfg_pull_none>, /* rxd1 */
+ <RK_GPIO3 21 RK_FUNC_2 &pcfg_pull_none>, /* mac_clk */
+ <RK_GPIO3 22 RK_FUNC_2 &pcfg_pull_none>, /* rx_err */
+ <RK_GPIO3 23 RK_FUNC_2 &pcfg_pull_none>; /* crs_dvalid */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <RK_GPIO3 24 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 25 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <RK_GPIO1 24 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 25 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <RK_GPIO1 26 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <RK_GPIO1 28 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <RK_GPIO3 14 RK_FUNC_2 &pcfg_pull_none>,
+ <RK_GPIO3 15 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <RK_GPIO1 30 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 31 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_out: pwm0-out {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_out: pwm1-out {
+ rockchip,pins = <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_out: pwm2-out {
+ rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_out: pwm3-out {
+ rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <RK_GPIO1 5 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <RK_GPIO1 15 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <RK_GPIO0 30 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <RK_GPIO0 31 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <RK_GPIO0 28 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <RK_GPIO0 29 RK_FUNC_1 &pcfg_pull_up>;
+ };
+ spi1_cs1: spi1-cs1 {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_2 &pcfg_pull_up>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_up>,
+ <RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd0 {
+ sd0_clk: sd0-clk {
+ rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_cd: sd0-cd {
+ rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_wp: sd0-wp {
+ rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_pwr: sd0-pwr {
+ rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ sd1 {
+ sd1_clk: sd1-clk {
+ rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_cd: sd1-cd {
+ rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_wp: sd1-wp {
+ rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <RK_GPIO1 16 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 17 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 18 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 19 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 20 RK_FUNC_1 &pcfg_pull_none>,
+ <RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spdif {
+ spdif_tx: spdif-tx {
+ rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+ };
+};
+
+&emac {
+ compatible = "rockchip,rk3188-emac";
+};
+
+&global_timer {
+ interrupts = <GIC_PPI 11 0xf04>;
+};
+
+&grf {
+ compatible = "rockchip,rk3188-grf", "syscon";
+};
+
+&local_timer {
+ interrupts = <GIC_PPI 13 0xf04>;
+};
+
+&i2c0 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+ compatible = "rockchip,rk3188-i2c";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+};
+
+&pmu {
+ compatible = "rockchip,rk3188-pmu", "syscon";
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+ compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+};
+
+&wdt {
+ compatible = "rockchip,rk3188-wdt", "snps,dw-wdt";
+};
diff --git a/arch/arm/dts/rk3xxx.dtsi b/arch/arm/dts/rk3xxx.dtsi
new file mode 100644
index 0000000..15a62d9
--- /dev/null
+++ b/arch/arm/dts/rk3xxx.dtsi
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko@sntech.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ aliases {
+ ethernet0 = &emac;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ mshc0 = &emmc;
+ mshc1 = &mmc0;
+ mshc2 = &mmc1;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ };
+
+ amba {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dmac1_s: dma-controller at 20018000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20018000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ };
+
+ dmac1_ns: dma-controller at 2001c000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x2001c000 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA1>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ dmac2: dma-controller at 20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-broken-no-flushp;
+ clocks = <&cru ACLK_DMA2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ #clock-cells = <0>;
+ clock-output-names = "xin24m";
+ };
+
+ L2: l2-cache-controller at 10138000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10138000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ scu at 1013c000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x1013c000 0x100>;
+ };
+
+ global_timer: global-timer at 1013c200 {
+ compatible = "arm,cortex-a9-global-timer";
+ reg = <0x1013c200 0x20>;
+ interrupts = <GIC_PPI 11 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ local_timer: local-timer at 1013c600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x1013c600 0x20>;
+ interrupts = <GIC_PPI 13 0x304>;
+ clocks = <&cru CORE_PERI>;
+ };
+
+ gic: interrupt-controller at 1013d000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0x1013d000 0x1000>,
+ <0x1013c100 0x0100>;
+ };
+
+ uart0: serial at 10124000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10124000 0x400>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ status = "disabled";
+ };
+
+ uart1: serial at 10126000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x10126000 0x400>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ status = "disabled";
+ };
+
+ usb_otg: usb at 10180000 {
+ compatible = "rockchip,rk3066-usb", "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG0>;
+ clock-names = "otg";
+ dr_mode = "otg";
+ g-np-tx-fifo-size = <16>;
+ g-rx-fifo-size = <275>;
+ g-tx-fifo-size = <256 128 128 64 64 32>;
+ g-use-dma;
+ phys = <&usbphy0>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ usb_host: usb at 101c0000 {
+ compatible = "snps,dwc2";
+ reg = <0x101c0000 0x40000>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_OTG1>;
+ clock-names = "otg";
+ dr_mode = "host";
+ phys = <&usbphy1>;
+ phy-names = "usb2-phy";
+ status = "disabled";
+ };
+
+ emac: ethernet at 10204000 {
+ compatible = "snps,arc-emac";
+ reg = <0x10204000 0x3c>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru HCLK_EMAC>, <&cru SCLK_MAC>;
+ clock-names = "hclk", "macref";
+ max-speed = <100>;
+ phy-mode = "rmii";
+
+ status = "disabled";
+ };
+
+ mmc0: dwmmc at 10214000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10214000 0x1000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ mmc1: dwmmc at 10218000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x10218000 0x1000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc at 1021c000 {
+ compatible = "rockchip,rk2928-dw-mshc";
+ reg = <0x1021c000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <256>;
+ status = "disabled";
+ };
+
+ pmu: pmu at 20004000 {
+ compatible = "rockchip,rk3066-pmu", "syscon";
+ reg = <0x20004000 0x100>;
+ };
+
+ grf: grf at 20008000 {
+ compatible = "syscon";
+ reg = <0x20008000 0x200>;
+ };
+
+ i2c0: i2c at 2002d000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002d000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C0>;
+
+ status = "disabled";
+ };
+
+ i2c1: i2c at 2002f000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2002f000 0x1000>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C1>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ pwm0: pwm at 20030000 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030000 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ pwm1: pwm at 20030010 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20030010 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM01>;
+ status = "disabled";
+ };
+
+ wdt: watchdog at 2004c000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x2004c000 0x100>;
+ clocks = <&cru PCLK_WDT>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ pwm2: pwm at 20050020 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ pwm3: pwm at 20050030 {
+ compatible = "rockchip,rk2928-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ clocks = <&cru PCLK_PWM23>;
+ status = "disabled";
+ };
+
+ i2c2: i2c at 20056000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C2>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c3: i2c at 2005a000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005a000 0x1000>;
+ interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C3>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ i2c4: i2c at 2005e000 {
+ compatible = "rockchip,rk3066-i2c";
+ reg = <0x2005e000 0x1000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rockchip,grf = <&grf>;
+
+ clocks = <&cru PCLK_I2C4>;
+ clock-names = "i2c";
+
+ status = "disabled";
+ };
+
+ uart2: serial at 20064000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20064000 0x400>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-frequency = <24000000>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ status = "disabled";
+ };
+
+ uart3: serial at 20068000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x20068000 0x400>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <1>;
+ clock-names = "baudclk", "apb_pclk";
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ status = "disabled";
+ };
+
+ saradc: saradc at 2006c000 {
+ compatible = "rockchip,saradc";
+ reg = <0x2006c000 0x100>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ status = "disabled";
+ };
+
+ spi0: spi at 20070000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20070000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 10>, <&dmac2 11>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
+ spi1: spi at 20074000 {
+ compatible = "rockchip,rk3066-spi";
+ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+ clock-names = "spiclk", "apb_pclk";
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0x20074000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dmas = <&dmac2 12>, <&dmac2 13>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 362dc28..c47e16c 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -11,6 +11,16 @@ config ROCKCHIP_RK3036
select SUPPORT_SPL
select SPL
+config ROCKCHIP_RK3188
+ bool "Support Rockchip RK3188"
+ select CPU_V7
+ help
+ The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
+ including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
+ video interfaces, several memory options and video codec support.
+ Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
+ UART, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3288
bool "Support Rockchip RK3288"
select CPU_V7
@@ -43,6 +53,7 @@ config ROCKCHIP_RK3399
select ARM64
source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3188/Kconfig"
source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3399/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 722b582..cabc91b 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -15,4 +15,5 @@ ifndef CONFIG_ARM64
obj-y += rk_timer.o
endif
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
diff --git a/arch/arm/mach-rockchip/rk3188/Kconfig b/arch/arm/mach-rockchip/rk3188/Kconfig
new file mode 100644
index 0000000..7ec9364
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/Kconfig
@@ -0,0 +1,9 @@
+if ROCKCHIP_RK3188
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3188/Makefile b/arch/arm/mach-rockchip/rk3188/Makefile
new file mode 100644
index 0000000..2ffbd15
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3188.o
+obj-y += reset_rk3188.o
+obj-y += syscon_rk3188.o
diff --git a/arch/arm/mach-rockchip/rk3188/clk_rk3188.c b/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
new file mode 100644
index 0000000..902524f
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3188_cru), devp);
+}
diff --git a/arch/arm/mach-rockchip/rk3188/reset_rk3188.c b/arch/arm/mach-rockchip/rk3188/reset_rk3188.c
new file mode 100644
index 0000000..65a1465
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/reset_rk3188.c
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3188.h>
+#include <asm/arch/hardware.h>
+#include <linux/err.h>
+
+int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct rk3188_cru *cru = rockchip_get_cru();
+
+ if (IS_ERR(cru))
+ return PTR_ERR(cru);
+ switch (type) {
+ case SYSRESET_WARM:
+ writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+ writel(0xeca8, &cru->cru_glb_srst_snd_value);
+ break;
+ case SYSRESET_COLD:
+ writel(RK_CLRBITS(0xffff), &cru->cru_mode_con);
+ writel(0xfdb9, &cru->cru_glb_srst_fst_value);
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops rk3188_sysreset = {
+ .request = rk3188_sysreset_request,
+};
+
+U_BOOT_DRIVER(sysreset_rk3188) = {
+ .name = "rk3188_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3188_sysreset,
+};
diff --git a/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c b/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
new file mode 100644
index 0000000..05c36bd
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rk3188_syscon_ids[] = {
+ { .compatible = "rockchip,rk3188-noc", .data = ROCKCHIP_SYSCON_NOC },
+ { .compatible = "rockchip,rk3188-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3188-pmu", .data = ROCKCHIP_SYSCON_PMU },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3188) = {
+ .name = "rk3188_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids,
+};
diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h
new file mode 100644
index 0000000..7bd5b63
--- /dev/null
+++ b/include/configs/rk3188_common.h
@@ -0,0 +1,95 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3188_COMMON_H
+#define __CONFIG_RK3188_COMMON_H
+
+#define CONFIG_SYS_CACHELINE_SIZE 32
+
+#include <asm/arch/hardware.h>
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_NR_DRAM_BANKS 1
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_MALLOC_LEN (32 << 20)
+#define CONFIG_SYS_CBSIZE 1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SYS_THUMB_BUILD
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define CONFIG_SYS_TIMER_RATE (24 * 1000 * 1000)
+#define CONFIG_SYS_TIMER_BASE 0x2000e000 /* TIMER3 */
+#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
+#define CONFIG_SYS_TIMER_COUNTS_DOWN
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_TEXT_BASE 0x60000000
+#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
+#define CONFIG_SYS_LOAD_ADDR 0x60800800
+
+#define CONFIG_ROCKCHIP_MAX_INIT_SIZE 0x8000 - 0x800
+#define CONFIG_ROCKCHIP_CHIP_TAG "RK31"
+
+#define CONFIG_ROCKCHIP_COMMON
+
+/* #define CONFIG_SILENT_CONSOLE
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_SYS_CONSOLE_IS_IN_ENV
+# define CONFIG_CONSOLE_MUX
+#endif */
+
+/* MMC/SD IP block */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_SDHCI
+#define CONFIG_DWMMC
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_FAT_WRITE
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_PART
+
+#define CONFIG_SYS_SDRAM_BASE 0x60000000
+#define CONFIG_NR_DRAM_BANKS 1
+#define SDRAM_BANK_SIZE (2UL << 30)
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "scriptaddr=0x60000000\0" \
+ "pxefile_addr_r=0x60100000\0" \
+ "fdt_addr_r=0x61f00000\0" \
+ "kernel_addr_r=0x62000000\0" \
+ "ramdisk_addr_r=0x64000000\0"
+
+/* First try to boot from SD (index 0), then eMMC (index 1 */
+#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 0) \
+ func(MMC, mmc, 1)
+
+#include <config_distro_bootcmd.h>
+
+/* Linux fails to load the fdt if it's loaded above 512M on rk3188 boards, so
+ * limit the fdt reallocation to that */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "fdt_high=0x7fffffff\0" \
+ "initrd_high=0x7fffffff\0" \
+ ENV_MEM_LAYOUT_SETTINGS \
+ ROCKCHIP_DEVICE_SETTINGS \
+ BOOTENV
+#endif
+
+#endif
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 0a072aa..0f38b15 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -55,6 +55,7 @@ struct spl_info {
static struct spl_info spl_infos[] = {
{ "rk3036", "RK30", 0x1000 },
+ { "rk3188", "RK31", 0x8000 - 0x800 },
{ "rk3288", "RK32", 0x8000 },
{ "rk3399", "RK33", 0x20000 },
};
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support
2016-07-22 21:51 ` [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support Heiko Stuebner
@ 2016-07-22 21:54 ` Heiko Stübner
2016-07-23 2:08 ` Simon Glass
0 siblings, 1 reply; 18+ messages in thread
From: Heiko Stübner @ 2016-07-22 21:54 UTC (permalink / raw)
To: u-boot
Am Freitag, 22. Juli 2016, 23:51:11 schrieb Heiko Stuebner:
> Add the core architecture code for the rk3188.
> It doesn't support the SPL yet, as because of some
> unknown error it doesn't start yet.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> arch/arm/dts/rk3188.dtsi | 631
> ++++++++++++++++++++++++++ arch/arm/dts/rk3xxx.dtsi |
> 431 ++++++++++++++++++ arch/arm/mach-rockchip/Kconfig | 11
> +
> arch/arm/mach-rockchip/Makefile | 1 +
> arch/arm/mach-rockchip/rk3188/Kconfig | 9 +
> arch/arm/mach-rockchip/rk3188/Makefile | 9 +
> arch/arm/mach-rockchip/rk3188/clk_rk3188.c | 17 +
> arch/arm/mach-rockchip/rk3188/reset_rk3188.c | 47 ++
> arch/arm/mach-rockchip/rk3188/syscon_rk3188.c | 24 +
> include/configs/rk3188_common.h | 95 ++++
> tools/rkcommon.c | 1 +
> 11 files changed, 1276 insertions(+)
> create mode 100644 arch/arm/dts/rk3188.dtsi
> create mode 100644 arch/arm/dts/rk3xxx.dtsi
> create mode 100644 arch/arm/mach-rockchip/rk3188/Kconfig
> create mode 100644 arch/arm/mach-rockchip/rk3188/Makefile
> create mode 100644 arch/arm/mach-rockchip/rk3188/clk_rk3188.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/reset_rk3188.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
> create mode 100644 include/configs/rk3188_common.h
>
> diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
> new file mode 100644
> index 0000000..ef1b962
> --- /dev/null
> +++ b/arch/arm/dts/rk3188.dtsi
> @@ -0,0 +1,631 @@
> +/*
> + * Copyright (c) 2013 MundoReader S.L.
> + * Author: Heiko Stuebner <heiko@sntech.de>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + * a) This file is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License, or (at your option) any later version.
> + *
> + * This file is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + * b) Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
it seems I forgot more license-header conversions in these new two patches.
Sorry about that.
Heiko
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support
2016-07-22 21:54 ` Heiko Stübner
@ 2016-07-23 2:08 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2016-07-23 2:08 UTC (permalink / raw)
To: u-boot
On 22 July 2016 at 15:54, Heiko St?bner <heiko@sntech.de> wrote:
> Am Freitag, 22. Juli 2016, 23:51:11 schrieb Heiko Stuebner:
>> Add the core architecture code for the rk3188.
>> It doesn't support the SPL yet, as because of some
>> unknown error it doesn't start yet.
>>
>> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>> ---
>> arch/arm/dts/rk3188.dtsi | 631
>> ++++++++++++++++++++++++++ arch/arm/dts/rk3xxx.dtsi |
>> 431 ++++++++++++++++++ arch/arm/mach-rockchip/Kconfig | 11
>> +
>> arch/arm/mach-rockchip/Makefile | 1 +
>> arch/arm/mach-rockchip/rk3188/Kconfig | 9 +
>> arch/arm/mach-rockchip/rk3188/Makefile | 9 +
>> arch/arm/mach-rockchip/rk3188/clk_rk3188.c | 17 +
>> arch/arm/mach-rockchip/rk3188/reset_rk3188.c | 47 ++
>> arch/arm/mach-rockchip/rk3188/syscon_rk3188.c | 24 +
>> include/configs/rk3188_common.h | 95 ++++
>> tools/rkcommon.c | 1 +
>> 11 files changed, 1276 insertions(+)
>> create mode 100644 arch/arm/dts/rk3188.dtsi
>> create mode 100644 arch/arm/dts/rk3xxx.dtsi
>> create mode 100644 arch/arm/mach-rockchip/rk3188/Kconfig
>> create mode 100644 arch/arm/mach-rockchip/rk3188/Makefile
>> create mode 100644 arch/arm/mach-rockchip/rk3188/clk_rk3188.c
>> create mode 100644 arch/arm/mach-rockchip/rk3188/reset_rk3188.c
>> create mode 100644 arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
>> create mode 100644 include/configs/rk3188_common.h
>>
>> diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
>> new file mode 100644
>> index 0000000..ef1b962
>> --- /dev/null
>> +++ b/arch/arm/dts/rk3188.dtsi
>> @@ -0,0 +1,631 @@
>> +/*
>> + * Copyright (c) 2013 MundoReader S.L.
>> + * Author: Heiko Stuebner <heiko@sntech.de>
>> + *
>> + * This file is dual-licensed: you can use it either under the terms
>> + * of the GPL or the X11 license, at your option. Note that this dual
>> + * licensing only applies to this file, and not this project as a
>> + * whole.
>> + *
>> + * a) This file is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of the
>> + * License, or (at your option) any later version.
>> + *
>> + * This file is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * Or, alternatively,
>> + *
>> + * b) Permission is hereby granted, free of charge, to any person
>> + * obtaining a copy of this software and associated documentation
>> + * files (the "Software"), to deal in the Software without
>> + * restriction, including without limitation the rights to use,
>> + * copy, modify, merge, publish, distribute, sublicense, and/or
>> + * sell copies of the Software, and to permit persons to whom the
>> + * Software is furnished to do so, subject to the following
>> + * conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be
>> + * included in all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> + * OTHER DEALINGS IN THE SOFTWARE.
>> + */
>
> it seems I forgot more license-header conversions in these new two patches.
> Sorry about that.
Acked-by: Simon Glass <sjg@chromium.org>
Regards,
Simon
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 8/8] rockchip: rk3188: Radxa Rock board
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (6 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 7/8] rockchip: rk3188: add core support Heiko Stuebner
@ 2016-07-22 21:51 ` Heiko Stuebner
2016-07-23 2:08 ` Simon Glass
2016-07-28 3:42 ` [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Simon Glass
8 siblings, 1 reply; 18+ messages in thread
From: Heiko Stuebner @ 2016-07-22 21:51 UTC (permalink / raw)
To: u-boot
The Rock is a RK3188 based single board computer by Radxa.
Currently it still relies on the proprietary DDR init and
cannot use the generic SPL, but at least is able to boot
a linux kernel and system up to a regular login prompt.
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
arch/arm/dts/Makefile | 1 +
arch/arm/dts/rk3188-radxarock.dts | 406 ++++++++++++++++++++++++++++++++++
arch/arm/mach-rockchip/rk3188/Kconfig | 11 +
board/radxa/rock/Kconfig | 15 ++
board/radxa/rock/MAINTAINERS | 6 +
board/radxa/rock/Makefile | 7 +
board/radxa/rock/rock.c | 32 +++
configs/rock_defconfig | 68 ++++++
include/configs/rock.h | 20 ++
9 files changed, 566 insertions(+)
create mode 100644 arch/arm/dts/rk3188-radxarock.dts
create mode 100644 board/radxa/rock/Kconfig
create mode 100644 board/radxa/rock/MAINTAINERS
create mode 100644 board/radxa/rock/Makefile
create mode 100644 board/radxa/rock/rock.c
create mode 100644 configs/rock_defconfig
create mode 100644 include/configs/rock.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3f5b2bf..cf286a7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -28,6 +28,7 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
exynos5422-odroidxu3.dtb
dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+ rk3188-radxarock.dtb \
rk3288-firefly.dtb \
rk3288-jerry.dtb \
rk3288-rock2-square.dtb \
diff --git a/arch/arm/dts/rk3188-radxarock.dts b/arch/arm/dts/rk3188-radxarock.dts
new file mode 100644
index 0000000..3de9191
--- /dev/null
+++ b/arch/arm/dts/rk3188-radxarock.dts
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3188.dtsi"
+
+/ {
+ model = "Radxa Rock";
+ compatible = "radxa,rock", "rockchip,rk3188";
+
+ chosen {
+/* stdout-path = &uart2; */
+ stdout-path = "serial2:115200n8";
+ };
+
+ config {
+ u-boot,dm-pre-reloc;
+ u-boot,boot-led = "rock:red:power";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x80000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ power {
+ gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "GPIO Key Power";
+ linux,input-type = <1>;
+ wakeup-source;
+ debounce-interval = <100>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ green {
+ label = "rock:green:user1";
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ blue {
+ label = "rock:blue:user2";
+ gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ sleep {
+ label = "rock:red:power";
+ gpios = <&gpio0 15 0>;
+ default-state = "off";
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SPDIF";
+
+ simple-audio-card,dai-link at 1 { /* S/PDIF - S/PDIF */
+ cpu { sound-dai = <&spdif>; };
+ codec { sound-dai = <&spdif_out>; };
+ };
+ };
+
+ spdif_out: spdif-out {
+ compatible = "linux,spdif-dit";
+ #sound-dai-cells = <0>;
+ };
+
+ ir_recv: gpio-ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio0 10 1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_recv_pin>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-name = "otg-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sd0: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "sdmmc-supply";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 1 GPIO_ACTIVE_LOW>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vsys: vsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+};
+
+&emac {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&emac_xfer>, <&emac_mdio>, <&phy_int>;
+
+ phy = <&phy0>;
+ phy-supply = <&vcc_rmii>;
+
+ phy0: ethernet-phy at 0 {
+ reg = <0>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&cpu0 {
+ cpu0-supply = <&vdd_arm>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ rtc at 51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ #clock-cells = <0>;
+ clock-output-names = "xin32k";
+ };
+
+ act8846: act8846 at 5a {
+ compatible = "active-semi,act8846";
+ reg = <0x5a>;
+ status = "okay";
+ system-power-controller;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&act8846_dvs0_ctl>;
+
+ vp1-supply = <&vsys>;
+ vp2-supply = <&vsys>;
+ vp3-supply = <&vsys>;
+ vp4-supply = <&vsys>;
+ inl1-supply = <&vcc_io>;
+ inl2-supply = <&vsys>;
+ inl3-supply = <&vsys>;
+
+ regulators {
+ vcc_ddr: REG1 {
+ regulator-name = "VCC_DDR";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ vdd_log: REG2 {
+ regulator-name = "VDD_LOG";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vdd_arm: REG3 {
+ regulator-name = "VDD_ARM";
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ vcc_io: REG4 {
+ regulator-name = "VCC_IO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vdd_10: REG5 {
+ regulator-name = "VDD_10";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ };
+
+ vdd_hdmi: REG6 {
+ regulator-name = "VDD_HDMI";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ regulator-always-on;
+ };
+
+ vcc18: REG7 {
+ regulator-name = "VCC_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcca_33: REG8 {
+ regulator-name = "VCCA_33";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_rmii: REG9 {
+ regulator-name = "VCC_RMII";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vccio_wl: REG10 {
+ regulator-name = "VCCIO_WL";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_18: REG11 {
+ regulator-name = "VCC18_IO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc28: REG12 {
+ regulator-name = "VCC_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&mmc0 {
+ num-slots = <1>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+ vmmc-supply = <&vcc_sd0>;
+
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pinctrl {
+ pcfg_output_low: pcfg-output-low {
+ output-low;
+ };
+
+ act8846 {
+ act8846_dvs0_ctl: act8846-dvs0-ctl {
+ rockchip,pins = <RK_GPIO3 27 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <RK_GPIO0 0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ lan8720a {
+ phy_int: phy-int {
+ rockchip,pins = <RK_GPIO3 26 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ ir-receiver {
+ ir_recv_pin: ir-recv-pin {
+ rockchip,pins = <RK_GPIO0 10 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ otg_vbus_drv: otg-vbus-drv {
+ rockchip,pins = <2 31 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&spdif {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/mach-rockchip/rk3188/Kconfig b/arch/arm/mach-rockchip/rk3188/Kconfig
index 7ec9364..ecf0ec6 100644
--- a/arch/arm/mach-rockchip/rk3188/Kconfig
+++ b/arch/arm/mach-rockchip/rk3188/Kconfig
@@ -1,9 +1,20 @@
if ROCKCHIP_RK3188
+config TARGET_ROCK
+ bool "Radxa Rock"
+ help
+ Rock is a RK3188-based development board with 2 USB and 1 otg
+ ports, HDMI, TV-out, micro-SD card, audio, WiFi and 100MBit
+ Ethernet, It also includes on-board nand and 1GB of SDRAM.
+ Expansion connectors provide access to display pins, I2C, SPI,
+ UART and GPIOs.
+
config SYS_SOC
default "rockchip"
config SYS_MALLOC_F_LEN
default 0x0800
+source "board/radxa/rock/Kconfig"
+
endif
diff --git a/board/radxa/rock/Kconfig b/board/radxa/rock/Kconfig
new file mode 100644
index 0000000..855b9b6
--- /dev/null
+++ b/board/radxa/rock/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_ROCK
+
+config SYS_BOARD
+ default "rock"
+
+config SYS_VENDOR
+ default "radxa"
+
+config SYS_CONFIG_NAME
+ default "rock"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+endif
diff --git a/board/radxa/rock/MAINTAINERS b/board/radxa/rock/MAINTAINERS
new file mode 100644
index 0000000..d44e7b8
--- /dev/null
+++ b/board/radxa/rock/MAINTAINERS
@@ -0,0 +1,6 @@
+RADXA_ROCK
+M: Simon Glass <sjg@chromium.org>
+S: Maintained
+F: board/radxa/rock
+F: include/configs/rock.h
+F: configs/rock_defconfig
diff --git a/board/radxa/rock/Makefile b/board/radxa/rock/Makefile
new file mode 100644
index 0000000..fe94b60
--- /dev/null
+++ b/board/radxa/rock/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Heiko Stuebner
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rock.o
diff --git a/board/radxa/rock/rock.c b/board/radxa/rock/rock.c
new file mode 100644
index 0000000..33db137
--- /dev/null
+++ b/board/radxa/rock/rock.c
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ rockchip_timer_init();
+ ret = rockchip_get_clk(&dev);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ gd->ram_size = 0x40000000;
+
+ return 0;
+}
diff --git a/configs/rock_defconfig b/configs/rock_defconfig
new file mode 100644
index 0000000..749d993
--- /dev/null
+++ b/configs/rock_defconfig
@@ -0,0 +1,68 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_RK3188=y
+CONFIG_TARGET_ROCK=y
+CONFIG_SPL_STACK_R_ADDR=0x80000
+CONFIG_DEFAULT_DEVICE_TREE="rk3188-radxarock"
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_BOOTZ=y
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_SYSRESET=y
+CONFIG_DM_MMC=y
+CONFIG_ROCKCHIP_DWMMC=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+# CONFIG_SPL_PINCTRL_FULL is not set
+CONFIG_ROCKCHIP_RK3188_PINCTRL=y
+CONFIG_DM_PMIC=y
+# CONFIG_SPL_PMIC_CHILDREN is not set
+CONFIG_PMIC_ACT8846=y
+CONFIG_DM_REGULATOR=y
+CONFIG_REGULATOR_ACT8846=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_BASE=0x20064000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_USE_PRIVATE_LIBGCC=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_ERRNO_STR=y
diff --git a/include/configs/rock.h b/include/configs/rock.h
new file mode 100644
index 0000000..1407938
--- /dev/null
+++ b/include/configs/rock.h
@@ -0,0 +1,20 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdin=serial\0" \
+ "stdout=serial\0" \
+ "stderr=serial\0"
+
+#include <configs/rk3188_common.h>
+
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_SPL_MMC_SUPPORT
+
+#endif
--
2.8.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 8/8] rockchip: rk3188: Radxa Rock board
2016-07-22 21:51 ` [U-Boot] [PATCH v2 8/8] rockchip: rk3188: Radxa Rock board Heiko Stuebner
@ 2016-07-23 2:08 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2016-07-23 2:08 UTC (permalink / raw)
To: u-boot
On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> The Rock is a RK3188 based single board computer by Radxa.
> Currently it still relies on the proprietary DDR init and
> cannot use the generic SPL, but at least is able to boot
> a linux kernel and system up to a regular login prompt.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> arch/arm/dts/Makefile | 1 +
> arch/arm/dts/rk3188-radxarock.dts | 406 ++++++++++++++++++++++++++++++++++
> arch/arm/mach-rockchip/rk3188/Kconfig | 11 +
> board/radxa/rock/Kconfig | 15 ++
> board/radxa/rock/MAINTAINERS | 6 +
> board/radxa/rock/Makefile | 7 +
> board/radxa/rock/rock.c | 32 +++
> configs/rock_defconfig | 68 ++++++
> include/configs/rock.h | 20 ++
> 9 files changed, 566 insertions(+)
> create mode 100644 arch/arm/dts/rk3188-radxarock.dts
> create mode 100644 board/radxa/rock/Kconfig
> create mode 100644 board/radxa/rock/MAINTAINERS
> create mode 100644 board/radxa/rock/Makefile
> create mode 100644 board/radxa/rock/rock.c
> create mode 100644 configs/rock_defconfig
> create mode 100644 include/configs/rock.h
Acked-by: Simon Glass <sjg@chromium.org>
When you come back to this can you please add info to the README on
how to run on this board?
- SImon
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support
2016-07-22 21:51 [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Heiko Stuebner
` (7 preceding siblings ...)
2016-07-22 21:51 ` [U-Boot] [PATCH v2 8/8] rockchip: rk3188: Radxa Rock board Heiko Stuebner
@ 2016-07-28 3:42 ` Simon Glass
2016-07-28 10:34 ` Heiko Stübner
8 siblings, 1 reply; 18+ messages in thread
From: Simon Glass @ 2016-07-28 3:42 UTC (permalink / raw)
To: u-boot
Hi Heiko,
On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> Second version. Simon already applied the cleanup patches from my
> first version. I've tried to address Simons comments and hopefully
> haven't overlooked any.
>
> SPL is still missing, so following Simons comment from earlier
> it cannot go in yet, but maybe the first two cleanups can.
Re the first patch, if you can resend it as a 'move' patch then I can
apply it. Please base on u-boot-rockchip/master.
For rk3188, yes I would prefer to wait until we have the proper SPL.
It sounds like you are close? I don't have an rk3188 board - I could
get a TV box with that chip but I'm not sure if it would work for
development.
>
> changes in v2:
> - move clock drivers to subdirectory
> - use already available log2 function in clock drivers
> - SPDX header in clock bindings
> - showcase rk3188 arch code and rock board
>
> Heiko Stuebner (10):
> rockchip: move clock drivers into a subdirectory
> rockchip: remove log2 reimplementation from clock drivers
> rockchip: rk3188: Add header files for PMU and GRF
> rockchip: rk3188: Add pinctrl driver
> rockchip: rk3188: Bring in rk3066/rk3188 clock bindings
> rockchip: rk3188: Add clock driver
> rockchip: rk3188: add core support
> rockchip: rk3188: Radxa Rock board
> add unfinished SPL support
> hacks to make my rock netboot a fit image
>
> arch/arm/dts/Makefile | 1 +
> arch/arm/dts/rk3188-radxarock.dts | 406 +++++++++++
> arch/arm/dts/rk3188.dtsi | 631 ++++++++++++++++++
> arch/arm/dts/rk3xxx.dtsi | 431 ++++++++++++
> arch/arm/include/asm/arch-rockchip/cru_rk3188.h | 183 +++++
> arch/arm/include/asm/arch-rockchip/grf_rk3188.h | 589 ++++++++++++++++
> arch/arm/include/asm/arch-rockchip/pmu_rk3188.h | 36 +
> arch/arm/mach-rockchip/Kconfig | 11 +
> arch/arm/mach-rockchip/Makefile | 2 +
> arch/arm/mach-rockchip/rk3188-board-spl.c | 190 ++++++
> arch/arm/mach-rockchip/rk3188/Kconfig | 20 +
> arch/arm/mach-rockchip/rk3188/Makefile | 10 +
> arch/arm/mach-rockchip/rk3188/clk_rk3188.c | 17 +
> arch/arm/mach-rockchip/rk3188/reset_rk3188.c | 47 ++
> arch/arm/mach-rockchip/rk3188/sdram_rk3188.c | 839 +++++++++++++++++++++++
> arch/arm/mach-rockchip/rk3188/syscon_rk3188.c | 24 +
> board/radxa/rock/Kconfig | 15 +
> board/radxa/rock/MAINTAINERS | 6 +
> board/radxa/rock/Makefile | 7 +
> board/radxa/rock/rock.c | 32 +
> configs/rock_defconfig | 80 +++
> drivers/clk/Makefile | 3 +-
> drivers/clk/clk_rk3036.c | 386 -----------
> drivers/clk/clk_rk3288.c | 851 ------------------------
> drivers/clk/rockchip/Makefile | 9 +
> drivers/clk/rockchip/clk_rk3036.c | 382 +++++++++++
> drivers/clk/rockchip/clk_rk3188.c | 493 ++++++++++++++
> drivers/clk/rockchip/clk_rk3288.c | 847 +++++++++++++++++++++++
> drivers/pinctrl/Kconfig | 9 +
> drivers/pinctrl/rockchip/Makefile | 1 +
> drivers/pinctrl/rockchip/pinctrl_rk3188.c | 613 +++++++++++++++++
> drivers/usb/host/dwc2.c | 4 +-
> include/configs/rk3188_common.h | 109 +++
> include/configs/rock.h | 66 ++
> include/dt-bindings/clock/rk3066a-cru.h | 32 +
> include/dt-bindings/clock/rk3188-cru-common.h | 248 +++++++
> include/dt-bindings/clock/rk3188-cru.h | 48 ++
> tools/rkcommon.c | 1 +
> 38 files changed, 6438 insertions(+), 1241 deletions(-)
> create mode 100644 arch/arm/dts/rk3188-radxarock.dts
> create mode 100644 arch/arm/dts/rk3188.dtsi
> create mode 100644 arch/arm/dts/rk3xxx.dtsi
> create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3188.h
> create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3188.h
> create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
> create mode 100644 arch/arm/mach-rockchip/rk3188-board-spl.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/Kconfig
> create mode 100644 arch/arm/mach-rockchip/rk3188/Makefile
> create mode 100644 arch/arm/mach-rockchip/rk3188/clk_rk3188.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/reset_rk3188.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/sdram_rk3188.c
> create mode 100644 arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
> create mode 100644 board/radxa/rock/Kconfig
> create mode 100644 board/radxa/rock/MAINTAINERS
> create mode 100644 board/radxa/rock/Makefile
> create mode 100644 board/radxa/rock/rock.c
> create mode 100644 configs/rock_defconfig
> delete mode 100644 drivers/clk/clk_rk3036.c
> delete mode 100644 drivers/clk/clk_rk3288.c
> create mode 100644 drivers/clk/rockchip/Makefile
> create mode 100644 drivers/clk/rockchip/clk_rk3036.c
> create mode 100644 drivers/clk/rockchip/clk_rk3188.c
> create mode 100644 drivers/clk/rockchip/clk_rk3288.c
> create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3188.c
> create mode 100644 include/configs/rk3188_common.h
> create mode 100644 include/configs/rock.h
> create mode 100644 include/dt-bindings/clock/rk3066a-cru.h
> create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h
> create mode 100644 include/dt-bindings/clock/rk3188-cru.h
>
> --
> 2.8.1
>
Regards,
Simon
^ permalink raw reply [flat|nested] 18+ messages in thread* [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support
2016-07-28 3:42 ` [U-Boot] [PATCH v2 0/8] basic rockchip rk3188 support Simon Glass
@ 2016-07-28 10:34 ` Heiko Stübner
0 siblings, 0 replies; 18+ messages in thread
From: Heiko Stübner @ 2016-07-28 10:34 UTC (permalink / raw)
To: u-boot
Hi Simon,
Am Mittwoch, 27. Juli 2016, 21:42:47 schrieb Simon Glass:
> On 22 July 2016 at 15:51, Heiko Stuebner <heiko@sntech.de> wrote:
> > Second version. Simon already applied the cleanup patches from my
> > first version. I've tried to address Simons comments and hopefully
> > haven't overlooked any.
> >
> > SPL is still missing, so following Simons comment from earlier
> > it cannot go in yet, but maybe the first two cleanups can.
>
> Re the first patch, if you can resend it as a 'move' patch then I can
> apply it. Please base on u-boot-rockchip/master.
ok, I can do that :-)
> For rk3188, yes I would prefer to wait until we have the proper SPL.
> It sounds like you are close? I don't have an rk3188 board - I could
> get a TV box with that chip but I'm not sure if it would work for
> development.
I wouldn't call it close, but it's moving along somewhat and we figure out the
special requirements step by step. As for yout getting a box, I guess the
worst part is finding serial pin testpoints. For booting the rk3188 seems to be
the easiest of them all - if you plug in a suitably prepared card, it will
always prefer this one over everything else.
Heiko
> > changes in v2:
> > - move clock drivers to subdirectory
> > - use already available log2 function in clock drivers
> > - SPDX header in clock bindings
> > - showcase rk3188 arch code and rock board
> >
> > Heiko Stuebner (10):
> > rockchip: move clock drivers into a subdirectory
> > rockchip: remove log2 reimplementation from clock drivers
> > rockchip: rk3188: Add header files for PMU and GRF
> > rockchip: rk3188: Add pinctrl driver
> > rockchip: rk3188: Bring in rk3066/rk3188 clock bindings
> > rockchip: rk3188: Add clock driver
> > rockchip: rk3188: add core support
> > rockchip: rk3188: Radxa Rock board
> > add unfinished SPL support
> > hacks to make my rock netboot a fit image
> >
> > arch/arm/dts/Makefile | 1 +
> > arch/arm/dts/rk3188-radxarock.dts | 406 +++++++++++
> > arch/arm/dts/rk3188.dtsi | 631 ++++++++++++++++++
> > arch/arm/dts/rk3xxx.dtsi | 431 ++++++++++++
> > arch/arm/include/asm/arch-rockchip/cru_rk3188.h | 183 +++++
> > arch/arm/include/asm/arch-rockchip/grf_rk3188.h | 589 ++++++++++++++++
> > arch/arm/include/asm/arch-rockchip/pmu_rk3188.h | 36 +
> > arch/arm/mach-rockchip/Kconfig | 11 +
> > arch/arm/mach-rockchip/Makefile | 2 +
> > arch/arm/mach-rockchip/rk3188-board-spl.c | 190 ++++++
> > arch/arm/mach-rockchip/rk3188/Kconfig | 20 +
> > arch/arm/mach-rockchip/rk3188/Makefile | 10 +
> > arch/arm/mach-rockchip/rk3188/clk_rk3188.c | 17 +
> > arch/arm/mach-rockchip/rk3188/reset_rk3188.c | 47 ++
> > arch/arm/mach-rockchip/rk3188/sdram_rk3188.c | 839
> > +++++++++++++++++++++++ arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
> > | 24 +
> > board/radxa/rock/Kconfig | 15 +
> > board/radxa/rock/MAINTAINERS | 6 +
> > board/radxa/rock/Makefile | 7 +
> > board/radxa/rock/rock.c | 32 +
> > configs/rock_defconfig | 80 +++
> > drivers/clk/Makefile | 3 +-
> > drivers/clk/clk_rk3036.c | 386 -----------
> > drivers/clk/clk_rk3288.c | 851
> > ------------------------ drivers/clk/rockchip/Makefile
> > | 9 +
> > drivers/clk/rockchip/clk_rk3036.c | 382 +++++++++++
> > drivers/clk/rockchip/clk_rk3188.c | 493 ++++++++++++++
> > drivers/clk/rockchip/clk_rk3288.c | 847
> > +++++++++++++++++++++++ drivers/pinctrl/Kconfig
> > | 9 +
> > drivers/pinctrl/rockchip/Makefile | 1 +
> > drivers/pinctrl/rockchip/pinctrl_rk3188.c | 613 +++++++++++++++++
> > drivers/usb/host/dwc2.c | 4 +-
> > include/configs/rk3188_common.h | 109 +++
> > include/configs/rock.h | 66 ++
> > include/dt-bindings/clock/rk3066a-cru.h | 32 +
> > include/dt-bindings/clock/rk3188-cru-common.h | 248 +++++++
> > include/dt-bindings/clock/rk3188-cru.h | 48 ++
> > tools/rkcommon.c | 1 +
> > 38 files changed, 6438 insertions(+), 1241 deletions(-)
> > create mode 100644 arch/arm/dts/rk3188-radxarock.dts
> > create mode 100644 arch/arm/dts/rk3188.dtsi
> > create mode 100644 arch/arm/dts/rk3xxx.dtsi
> > create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3188.h
> > create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3188.h
> > create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3188.h
> > create mode 100644 arch/arm/mach-rockchip/rk3188-board-spl.c
> > create mode 100644 arch/arm/mach-rockchip/rk3188/Kconfig
> > create mode 100644 arch/arm/mach-rockchip/rk3188/Makefile
> > create mode 100644 arch/arm/mach-rockchip/rk3188/clk_rk3188.c
> > create mode 100644 arch/arm/mach-rockchip/rk3188/reset_rk3188.c
> > create mode 100644 arch/arm/mach-rockchip/rk3188/sdram_rk3188.c
> > create mode 100644 arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
> > create mode 100644 board/radxa/rock/Kconfig
> > create mode 100644 board/radxa/rock/MAINTAINERS
> > create mode 100644 board/radxa/rock/Makefile
> > create mode 100644 board/radxa/rock/rock.c
> > create mode 100644 configs/rock_defconfig
> > delete mode 100644 drivers/clk/clk_rk3036.c
> > delete mode 100644 drivers/clk/clk_rk3288.c
> > create mode 100644 drivers/clk/rockchip/Makefile
> > create mode 100644 drivers/clk/rockchip/clk_rk3036.c
> > create mode 100644 drivers/clk/rockchip/clk_rk3188.c
> > create mode 100644 drivers/clk/rockchip/clk_rk3288.c
> > create mode 100644 drivers/pinctrl/rockchip/pinctrl_rk3188.c
> > create mode 100644 include/configs/rk3188_common.h
> > create mode 100644 include/configs/rock.h
> > create mode 100644 include/dt-bindings/clock/rk3066a-cru.h
> > create mode 100644 include/dt-bindings/clock/rk3188-cru-common.h
> > create mode 100644 include/dt-bindings/clock/rk3188-cru.h
> >
> > --
> > 2.8.1
>
> Regards,
> Simon
^ permalink raw reply [flat|nested] 18+ messages in thread