[U-Boot] [PATCH v2 0/5] Submit upstream changes made while porting a customer board to mainline

Those changes are intended to easy the process of using U-Boot mainline with rv1108 based boards.
Please give them a good review and if possible, merge them as they are in use for some time on our custom tree and working fine.
Changes in v2: - new patch - split bounce buffer change on a new patch
Otavio Salvador (5): clk_rv1108: Sync with vendor tree rv1108: Enable BOUNCE_BUFFER rv1108: Enable eMMC support rv1108: Make USB OTG functional rv1108: Add support for default distro_bootcmd
arch/arm/dts/rv1108.dtsi | 74 ++- .../include/asm/arch-rockchip/cru_rv1108.h | 143 +++++- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/rv1108-board.c | 81 ++++ drivers/clk/rockchip/clk_rv1108.c | 457 +++++++++++++++++- include/configs/rv1108_common.h | 18 + include/dt-bindings/clock/rv1108-cru.h | 154 ++++-- 7 files changed, 877 insertions(+), 51 deletions(-) create mode 100644 arch/arm/mach-rockchip/rv1108-board.c

Make adjustments to the rv1108 clock driver in order to align it with the internal Rockchip version.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br ---
Changes in v2: None
.../include/asm/arch-rockchip/cru_rv1108.h | 143 +++++- drivers/clk/rockchip/clk_rv1108.c | 457 +++++++++++++++++- include/dt-bindings/clock/rv1108-cru.h | 154 ++++-- 3 files changed, 706 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h index 3cc2ed0187..4ce8caa40f 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h @@ -11,7 +11,11 @@ #define OSC_HZ (24 * 1000 * 1000)
#define APLL_HZ (600 * 1000000) -#define GPLL_HZ (594 * 1000000) +#define GPLL_HZ (1188 * 1000000) +#define ACLK_PERI_HZ (148500000) +#define HCLK_PERI_HZ (148500000) +#define PCLK_PERI_HZ (74250000) +#define ACLK_BUS_HZ (148500000)
struct rv1108_clk_priv { struct rv1108_cru *cru; @@ -80,6 +84,11 @@ enum { WORK_MODE_NORMAL = 1, DSMPD_SHIFT = 3, DSMPD_MASK = 1 << DSMPD_SHIFT, + INTEGER_MODE = 1, + GLOBAL_POWER_DOWN_SHIFT = 0, + GLOBAL_POWER_DOWN_MASK = 1 << GLOBAL_POWER_DOWN_SHIFT, + GLOBAL_POWER_DOWN = 1, + GLOBAL_POWER_UP = 0,
/* CLKSEL0_CON */ CORE_PLL_SEL_SHIFT = 8, @@ -90,11 +99,77 @@ enum { CORE_CLK_DIV_SHIFT = 0, CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
+ /* CLKSEL_CON1 */ + PCLK_DBG_DIV_CON_SHIFT = 4, + PCLK_DBG_DIV_CON_MASK = 0xf << PCLK_DBG_DIV_CON_SHIFT, + ACLK_CORE_DIV_CON_SHIFT = 0, + ACLK_CORE_DIV_CON_MASK = 7 << ACLK_CORE_DIV_CON_SHIFT, + + /* CLKSEL_CON2 */ + ACLK_BUS_PLL_SEL_SHIFT = 8, + ACLK_BUS_PLL_SEL_MASK = 3 << ACLK_BUS_PLL_SEL_SHIFT, + ACLK_BUS_PLL_SEL_GPLL = 0, + ACLK_BUS_PLL_SEL_APLL = 1, + ACLK_BUS_PLL_SEL_DPLL = 2, + ACLK_BUS_DIV_CON_SHIFT = 0, + ACLK_BUS_DIV_CON_MASK = 0x1f << ACLK_BUS_DIV_CON_SHIFT, + ACLK_BUS_DIV_CON_WIDTH = 5, + + /* CLKSEL_CON3 */ + PCLK_BUS_DIV_CON_SHIFT = 8, + PCLK_BUS_DIV_CON_MASK = 0x1f << PCLK_BUS_DIV_CON_SHIFT, + HCLK_BUS_DIV_CON_SHIFT = 0, + HCLK_BUS_DIV_CON_MASK = 0x1f, + + /* CLKSEL_CON4 */ + CLK_DDR_PLL_SEL_SHIFT = 8, + CLK_DDR_PLL_SEL_MASK = 0x3 << CLK_DDR_PLL_SEL_SHIFT, + CLK_DDR_DIV_CON_SHIFT = 0, + CLK_DDR_DIV_CON_MASK = 0x3 << CLK_DDR_DIV_CON_SHIFT, + + /* CLKSEL_CON19 */ + CLK_I2C1_PLL_SEL_SHIFT = 15, + CLK_I2C1_PLL_SEL_MASK = 1 << CLK_I2C1_PLL_SEL_SHIFT, + CLK_I2C1_PLL_SEL_DPLL = 0, + CLK_I2C1_PLL_SEL_GPLL = 1, + CLK_I2C1_DIV_CON_SHIFT = 8, + CLK_I2C1_DIV_CON_MASK = 0x7f << CLK_I2C1_DIV_CON_SHIFT, + CLK_I2C0_PLL_SEL_SHIFT = 7, + CLK_I2C0_PLL_SEL_MASK = 1 << CLK_I2C0_PLL_SEL_SHIFT, + CLK_I2C0_DIV_CON_SHIFT = 0, + CLK_I2C0_DIV_CON_MASK = 0x7f, + I2C_DIV_CON_WIDTH = 7, + + /* CLKSEL_CON20 */ + CLK_I2C3_PLL_SEL_SHIFT = 15, + CLK_I2C3_PLL_SEL_MASK = 1 << CLK_I2C3_PLL_SEL_SHIFT, + CLK_I2C3_PLL_SEL_DPLL = 0, + CLK_I2C3_PLL_SEL_GPLL = 1, + CLK_I2C3_DIV_CON_SHIFT = 8, + CLK_I2C3_DIV_CON_MASK = 0x7f << CLK_I2C3_DIV_CON_SHIFT, + CLK_I2C2_PLL_SEL_SHIFT = 7, + CLK_I2C2_PLL_SEL_MASK = 1 << CLK_I2C2_PLL_SEL_SHIFT, + CLK_I2C2_DIV_CON_SHIFT = 0, + CLK_I2C2_DIV_CON_MASK = 0x7f, + /* CLKSEL_CON22 */ CLK_SARADC_DIV_CON_SHIFT= 0, CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), CLK_SARADC_DIV_CON_WIDTH= 10,
+ /* CLKSEL_CON23 */ + ACLK_PERI_PLL_SEL_SHIFT = 15, + ACLK_PERI_PLL_SEL_MASK = 1 << ACLK_PERI_PLL_SEL_SHIFT, + ACLK_PERI_PLL_SEL_GPLL = 0, + ACLK_PERI_PLL_SEL_DPLL = 1, + PCLK_PERI_DIV_CON_SHIFT = 10, + PCLK_PERI_DIV_CON_MASK = 0x1f << PCLK_PERI_DIV_CON_SHIFT, + HCLK_PERI_DIV_CON_SHIFT = 5, + HCLK_PERI_DIV_CON_MASK = 0x1f << HCLK_PERI_DIV_CON_SHIFT, + ACLK_PERI_DIV_CON_SHIFT = 0, + ACLK_PERI_DIV_CON_MASK = 0x1f, + PERI_DIV_CON_WIDTH = 5, + /* CLKSEL24_CON */ MAC_PLL_SEL_SHIFT = 12, MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT, @@ -105,6 +180,16 @@ enum { MAC_CLK_DIV_MASK = 0x1f, MAC_CLK_DIV_SHIFT = 0,
+ /* CLKSEL25_CON */ + EMMC_PLL_SEL_SHIFT = 12, + EMMC_PLL_SEL_MASK = 3 << EMMC_PLL_SEL_SHIFT, + EMMC_PLL_SEL_DPLL = 0, + EMMC_PLL_SEL_GPLL, + + /* CLKSEL26_CON */ + EMMC_CLK_DIV_SHIFT = 8, + EMMC_CLK_DIV_MASK = 0xff << EMMC_CLK_DIV_SHIFT, + /* CLKSEL27_CON */ SFC_PLL_SEL_SHIFT = 7, SFC_PLL_SEL_MASK = 1 << SFC_PLL_SEL_SHIFT, @@ -112,5 +197,61 @@ enum { SFC_PLL_SEL_GPLL = 1, SFC_CLK_DIV_SHIFT = 0, SFC_CLK_DIV_MASK = 0x3f << SFC_CLK_DIV_SHIFT, + + /* CLKSEL28_CON */ + ACLK_VIO1_PLL_SEL_SHIFT = 14, + ACLK_VIO1_PLL_SEL_MASK = 3 << ACLK_VIO1_PLL_SEL_SHIFT, + VIO_PLL_SEL_DPLL = 0, + VIO_PLL_SEL_GPLL = 1, + ACLK_VIO1_CLK_DIV_SHIFT = 8, + ACLK_VIO1_CLK_DIV_MASK = 0x1f << ACLK_VIO1_CLK_DIV_SHIFT, + CLK_VIO_DIV_CON_WIDTH = 5, + ACLK_VIO0_PLL_SEL_SHIFT = 6, + ACLK_VIO0_PLL_SEL_MASK = 3 << ACLK_VIO0_PLL_SEL_SHIFT, + ACLK_VIO0_CLK_DIV_SHIFT = 0, + ACLK_VIO0_CLK_DIV_MASK = 0x1f << ACLK_VIO0_CLK_DIV_SHIFT, + + /* CLKSEL29_CON */ + PCLK_VIO_CLK_DIV_SHIFT = 8, + PCLK_VIO_CLK_DIV_MASK = 0x1f << PCLK_VIO_CLK_DIV_SHIFT, + HCLK_VIO_CLK_DIV_SHIFT = 0, + HCLK_VIO_CLK_DIV_MASK = 0x1f << HCLK_VIO_CLK_DIV_SHIFT, + + /* CLKSEL32_CON */ + DCLK_VOP_SEL_SHIFT = 7, + DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT, + DCLK_VOP_SEL_HDMI = 0, + DCLK_VOP_SEL_PLL = 1, + DCLK_VOP_PLL_SEL_SHIFT = 6, + DCLK_VOP_PLL_SEL_MASK = 1 << DCLK_VOP_PLL_SEL_SHIFT, + DCLK_VOP_PLL_SEL_GPLL = 0, + DCLK_VOP_PLL_SEL_DPLL = 1, + DCLK_VOP_CLK_DIV_SHIFT = 0, + DCLK_VOP_CLK_DIV_MASK = 0x3f << DCLK_VOP_CLK_DIV_SHIFT, + DCLK_VOP_DIV_CON_WIDTH = 6, + + /* SOFTRST1_CON*/ + DDRPHY_SRSTN_CLKDIV_REQ_SHIFT = 0, + DDRPHY_SRSTN_CLKDIV_REQ = 1, + DDRPHY_SRSTN_CLKDIV_DIS = 0, + DDRPHY_SRSTN_CLKDIV_REQ_MASK = 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT, + DDRPHY_SRSTN_REQ_SHIFT = 1, + DDRPHY_SRSTN_REQ = 1, + DDRPHY_SRSTN_DIS = 0, + DDRPHY_SRSTN_REQ_MASK = 1 << DDRPHY_SRSTN_REQ_SHIFT, + DDRPHY_PSRSTN_REQ_SHIFT = 2, + DDRPHY_PSRSTN_REQ = 1, + DDRPHY_PSRSTN_DIS = 0, + DDRPHY_PSRSTN_REQ_MASK = 1 << DDRPHY_PSRSTN_REQ_SHIFT, + + /* SOFTRST2_CON*/ + DDRUPCTL_PSRSTN_REQ_SHIFT = 0, + DDRUPCTL_PSRSTN_REQ = 1, + DDRUPCTL_PSRSTN_DIS = 0, + DDRUPCTL_PSRSTN_REQ_MASK = 1 << DDRUPCTL_PSRSTN_REQ_SHIFT, + DDRUPCTL_NSRSTN_REQ_SHIFT = 1, + DDRUPCTL_NSRSTN_REQ = 1, + DDRUPCTL_NSRSTN_DIS = 0, + DDRUPCTL_NSRSTN_REQ_MASK = 1 << DDRUPCTL_NSRSTN_REQ_SHIFT, }; #endif diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c index 1f9f534b28..3603568ee7 100644 --- a/drivers/clk/rockchip/clk_rv1108.c +++ b/drivers/clk/rockchip/clk_rv1108.c @@ -35,6 +35,9 @@ enum { #hz "Hz cannot be hit with PLL "\ "divisors on line " __stringify(__LINE__));
+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); + /* use integer mode */ static inline int rv1108_pll_id(enum rk_clk_id clk_id) { @@ -57,6 +60,58 @@ static inline int rv1108_pll_id(enum rk_clk_id clk_id) return id; }
+static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id, + const struct pll_div *div) +{ + int pll_id = rv1108_pll_id(clk_id); + struct rv1108_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: fb=%d, ref=%d, pst1=%d, pst2=%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); + + /* + * When power on or changing PLL setting, + * we must force PLL into slow mode to ensure output stable clock. + */ + rk_clrsetreg(&pll->con3, WORK_MODE_MASK, + WORK_MODE_SLOW << WORK_MODE_SHIFT); + + /* use integer mode */ + rk_setreg(&pll->con3, 1 << DSMPD_SHIFT); + /* Power down */ + rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT); + + rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT); + rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK, + (div->postdiv1 << POSTDIV1_SHIFT | + div->postdiv2 << POSTDIV2_SHIFT | + div->refdiv << REFDIV_SHIFT)); + rk_clrsetreg(&pll->con2, FRACDIV_MASK, + (div->refdiv << REFDIV_SHIFT)); + + /* Power Up */ + rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT); + + /* waiting for pll lock */ + while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT)) + udelay(1); + + /* + * set PLL into normal mode. + */ + rk_clrsetreg(&pll->con3, WORK_MODE_MASK, + WORK_MODE_NORMAL << WORK_MODE_SHIFT); + + return 0; +} + static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, enum rk_clk_id clk_id) { @@ -74,7 +129,7 @@ static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK; postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT; postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT; - refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT; + refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK; freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; } else { freq = OSC_HZ; @@ -154,6 +209,322 @@ static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz) return rv1108_saradc_get_clk(cru); }
+static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + + val = readl(&cru->clksel_con[28]); + div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT, + CLK_VIO_DIV_CON_WIDTH); + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[28], + ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK, + (src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) | + (VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT)); + + return rv1108_aclk_vio1_get_clk(cru); +} + +static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + + val = readl(&cru->clksel_con[28]); + div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT, + CLK_VIO_DIV_CON_WIDTH); + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[28], + ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK, + (src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) | + (VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT)); + + /*HCLK_VIO default div = 4*/ + rk_clrsetreg(&cru->clksel_con[29], + HCLK_VIO_CLK_DIV_MASK, + 3 << HCLK_VIO_CLK_DIV_SHIFT); + /*PCLK_VIO default div = 4*/ + rk_clrsetreg(&cru->clksel_con[29], + PCLK_VIO_CLK_DIV_MASK, + 3 << PCLK_VIO_CLK_DIV_SHIFT); + + return rv1108_aclk_vio0_get_clk(cru); +} + +static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + + val = readl(&cru->clksel_con[32]); + div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT, + DCLK_VOP_DIV_CON_WIDTH); + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1; + assert(src_clk_div < 64); + + rk_clrsetreg(&cru->clksel_con[32], + DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK | + DCLK_VOP_SEL_SHIFT, + (src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) | + (DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) | + (DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT)); + + return rv1108_dclk_vop_get_clk(cru); +} + +static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + val = readl(&cru->clksel_con[2]); + div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT, + ACLK_BUS_DIV_CON_WIDTH); + + return DIV_TO_RATE(parent_rate, div); +} + +static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[2], + ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK, + (src_clk_div << ACLK_BUS_DIV_CON_SHIFT) | + (ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT)); + + return rv1108_aclk_bus_get_clk(cru); +} + +static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + val = readl(&cru->clksel_con[23]); + div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT, + PERI_DIV_CON_WIDTH); + + return DIV_TO_RATE(parent_rate, div); +} + +static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + val = readl(&cru->clksel_con[23]); + div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT, + PERI_DIV_CON_WIDTH); + + return DIV_TO_RATE(parent_rate, div); +} + +static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru) +{ + u32 div, val; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + val = readl(&cru->clksel_con[23]); + div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT, + PERI_DIV_CON_WIDTH); + + return DIV_TO_RATE(parent_rate, div); +} + +static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[23], + ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK, + (src_clk_div << ACLK_PERI_DIV_CON_SHIFT) | + (ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT)); + + return rv1108_aclk_peri_get_clk(cru); +} + +static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[23], + HCLK_PERI_DIV_CON_MASK, + (src_clk_div << HCLK_PERI_DIV_CON_SHIFT)); + + return rv1108_hclk_peri_get_clk(cru); +} + +static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{ + int src_clk_div; + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1; + assert(src_clk_div < 32); + + rk_clrsetreg(&cru->clksel_con[23], + PCLK_PERI_DIV_CON_MASK, + (src_clk_div << PCLK_PERI_DIV_CON_SHIFT)); + + return rv1108_pclk_peri_get_clk(cru); +} + +static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id) +{ + u32 div, con; + + switch (clk_id) { + case SCLK_I2C0_PMU: + con = readl(&cru->clksel_con[19]); + div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT, + I2C_DIV_CON_WIDTH); + break; + case SCLK_I2C1: + con = readl(&cru->clksel_con[19]); + div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT, + I2C_DIV_CON_WIDTH); + break; + case SCLK_I2C2: + con = readl(&cru->clksel_con[20]); + div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT, + I2C_DIV_CON_WIDTH); + break; + case SCLK_I2C3: + con = readl(&cru->clksel_con[20]); + div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT, + I2C_DIV_CON_WIDTH); + break; + default: + printf("do not support this i2c bus\n"); + return -EINVAL; + } + + return DIV_TO_RATE(GPLL_HZ, div); +} + +static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz) +{ + int src_clk_div; + + /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/ + src_clk_div = GPLL_HZ / hz; + assert(src_clk_div - 1 <= 127); + + switch (clk_id) { + case SCLK_I2C0_PMU: + rk_clrsetreg(&cru->clksel_con[19], + CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK, + (src_clk_div << CLK_I2C0_DIV_CON_SHIFT) | + (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT)); + break; + case SCLK_I2C1: + rk_clrsetreg(&cru->clksel_con[19], + CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK, + (src_clk_div << CLK_I2C1_DIV_CON_SHIFT) | + (CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT)); + break; + case SCLK_I2C2: + rk_clrsetreg(&cru->clksel_con[20], + CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK, + (src_clk_div << CLK_I2C2_DIV_CON_SHIFT) | + (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT)); + break; + case SCLK_I2C3: + rk_clrsetreg(&cru->clksel_con[20], + CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK, + (src_clk_div << CLK_I2C3_DIV_CON_SHIFT) | + (CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT)); + break; + default: + printf("do not support this i2c bus\n"); + return -EINVAL; + } + + return rv1108_i2c_get_clk(cru, clk_id); +} + +static ulong rv1108_mmc_get_clk(struct clk *clk) +{ + struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1108_cru *cru = priv->cru; + u32 div, con; + + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + + con = readl(&cru->clksel_con[26]); + div = (con & EMMC_CLK_DIV_MASK) >> EMMC_CLK_DIV_SHIFT; + + + debug("%s id %ld get_clk %ld\n", __func__, clk->id, DIV_TO_RATE(parent_rate, div)); + + return DIV_TO_RATE(parent_rate, div); + +} + +static ulong rv1108_mmc_set_clk(struct clk *clk, ulong set_rate) +{ + struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); + struct rv1108_cru *cru = priv->cru; + int src_clk_div; + + ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + src_clk_div = DIV_ROUND_UP(parent_rate, set_rate); + + if (src_clk_div > 127) { + src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); + } + + debug("%s id %ld src_clk_div %d\n", __func__, clk->id, src_clk_div); + + rk_clrsetreg(&cru->clksel_con[26], + EMMC_CLK_DIV_MASK , (src_clk_div -1) << EMMC_CLK_DIV_SHIFT); + + rk_clrsetreg(&cru->clksel_con[25], + EMMC_PLL_SEL_MASK , EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT); + + return rv1108_mmc_get_clk(clk); +} + + static ulong rv1108_clk_get_rate(struct clk *clk) { struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); @@ -163,6 +534,31 @@ static ulong rv1108_clk_get_rate(struct clk *clk) return rkclk_pll_get_rate(priv->cru, clk->id); case SCLK_SARADC: return rv1108_saradc_get_clk(priv->cru); + case ACLK_VIO0: + return rv1108_aclk_vio0_get_clk(priv->cru); + case ACLK_VIO1: + return rv1108_aclk_vio1_get_clk(priv->cru); + case DCLK_VOP: + return rv1108_dclk_vop_get_clk(priv->cru); + case ACLK_PRE: + return rv1108_aclk_bus_get_clk(priv->cru); + case ACLK_PERI: + return rv1108_aclk_peri_get_clk(priv->cru); + case HCLK_PERI: + return rv1108_hclk_peri_get_clk(priv->cru); + case PCLK_PERI: + return rv1108_pclk_peri_get_clk(priv->cru); + case SCLK_I2C0_PMU: + case SCLK_I2C1: + case SCLK_I2C2: + case SCLK_I2C3: + return rv1108_i2c_get_clk(priv->cru, clk->id); + case HCLK_SDMMC: + case HCLK_EMMC: + case SCLK_SDMMC: + case SCLK_EMMC: + case SCLK_EMMC_SAMPLE: + return rv1108_mmc_get_clk(clk); default: return -ENOENT; } @@ -183,6 +579,39 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate) case SCLK_SARADC: new_rate = rv1108_saradc_set_clk(priv->cru, rate); break; + case ACLK_VIO0: + new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate); + break; + case ACLK_VIO1: + new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate); + break; + case DCLK_VOP: + new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate); + break; + case ACLK_PRE: + new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate); + break; + case ACLK_PERI: + new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate); + break; + case HCLK_PERI: + new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate); + break; + case PCLK_PERI: + new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate); + break; + case SCLK_I2C0_PMU: + case SCLK_I2C1: + case SCLK_I2C2: + case SCLK_I2C3: + new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate); + break; + case HCLK_SDMMC: + case HCLK_EMMC: + case SCLK_SDMMC: + case SCLK_EMMC: + new_rate = rv1108_mmc_set_clk(clk, rate); + break; default: return -ENOENT; } @@ -197,14 +626,34 @@ static const struct clk_ops rv1108_clk_ops = {
static void rkclk_init(struct rv1108_cru *cru) { - unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM); - unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR); - unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL); + unsigned int apll, dpll, gpll; + unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri; + + aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2); + aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2); + hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2); + pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2); + rv1108_aclk_vio0_set_clk(cru, 297000000); + rv1108_aclk_vio1_set_clk(cru, 297000000); + + /* configure apll */ + rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); + rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); + aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ); + aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ); + hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ); + pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ); + + apll = rkclk_pll_get_rate(cru, CLK_ARM); + dpll = rkclk_pll_get_rate(cru, CLK_DDR); + gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK, 0 << MAC_CLK_DIV_SHIFT);
printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll); + printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n", + aclk_bus, aclk_peri, hclk_peri, pclk_peri); }
static int rv1108_clk_ofdata_to_platdata(struct udevice *dev) diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h index 9219a50a24..04e0a59f4b 100644 --- a/include/dt-bindings/clock/rv1108-cru.h +++ b/include/dt-bindings/clock/rv1108-cru.h @@ -14,7 +14,6 @@ #define ARMCLK 3
/* sclk gates (special clocks) */ -#define SCLK_MAC 64 #define SCLK_SPI0 65 #define SCLK_NANDC 67 #define SCLK_SDMMC 68 @@ -35,20 +34,77 @@ #define SCLK_SDMMC_SAMPLE 84 #define SCLK_SDIO_SAMPLE 85 #define SCLK_EMMC_SAMPLE 86 -#define SCLK_MAC_RX 87 -#define SCLK_MAC_TX 88 -#define SCLK_MACREF 89 -#define SCLK_MACREF_OUT 90 -#define SCLK_SARADC 91 +#define SCLK_VENC_CORE 87 +#define SCLK_HEVC_CORE 88 +#define SCLK_HEVC_CABAC 89 +#define SCLK_PWM0_PMU 90 +#define SCLK_I2C0_PMU 91 +#define SCLK_WIFI 92 +#define SCLK_CIFOUT 93 +#define SCLK_MIPI_CSI_OUT 94 +#define SCLK_CIF0 95 +#define SCLK_CIF1 96 +#define SCLK_CIF2 97 +#define SCLK_CIF3 98 +#define SCLK_DSP 99 +#define SCLK_DSP_IOP 100 +#define SCLK_DSP_EPP 101 +#define SCLK_DSP_EDP 102 +#define SCLK_DSP_EDAP 103 +#define SCLK_CVBS_HOST 104 +#define SCLK_HDMI_SFR 105 +#define SCLK_HDMI_CEC 106 +#define SCLK_CRYPTO 107 +#define SCLK_SPI 108 +#define SCLK_SARADC 109 +#define SCLK_TSADC 110 +#define SCLK_MAC_PRE 111 +#define SCLK_MAC 112 +#define SCLK_MAC_RX 113 +#define SCLK_MAC_REF 114 +#define SCLK_MAC_REFOUT 115 +#define SCLK_DSP_PFM 116 +#define SCLK_RGA 117 +#define SCLK_I2C1 118 +#define SCLK_I2C2 119 +#define SCLK_I2C3 120 +#define SCLK_PWM 121 +#define SCLK_ISP 122 +#define SCLK_USBPHY 123 +#define SCLK_I2S0_SRC 124 +#define SCLK_I2S1_SRC 125 +#define SCLK_I2S2_SRC 126 +#define SCLK_UART0_SRC 127 +#define SCLK_UART1_SRC 128 +#define SCLK_UART2_SRC 129 +#define SCLK_MAC_TX 130 +#define SCLK_MACREF 131 +#define SCLK_MACREF_OUT 132
+#define DCLK_VOP_SRC 185 +#define DCLK_HDMIPHY 186 +#define DCLK_VOP 187
/* aclk gates */ #define ACLK_DMAC 192 #define ACLK_PRE 193 #define ACLK_CORE 194 #define ACLK_ENMCORE 195 -#define ACLK_GMAC 196 - +#define ACLK_RKVENC 196 +#define ACLK_RKVDEC 197 +#define ACLK_VPU 198 +#define ACLK_CIF0 199 +#define ACLK_VIO0 200 +#define ACLK_VIO1 201 +#define ACLK_VOP 202 +#define ACLK_IEP 203 +#define ACLK_RGA 204 +#define ACLK_ISP 205 +#define ACLK_CIF1 206 +#define ACLK_CIF2 207 +#define ACLK_CIF3 208 +#define ACLK_PERI 209 +#define ACLK_GMAC 210
/* pclk gates */ #define PCLK_GPIO1 256 @@ -67,12 +123,24 @@ #define PCLK_PWM 269 #define PCLK_TIMER 270 #define PCLK_PERI 271 -#define PCLK_GMAC 272 -#define PCLK_SARADC 273 +#define PCLK_GPIO0_PMU 272 +#define PCLK_I2C0_PMU 273 +#define PCLK_PWM0_PMU 274 +#define PCLK_ISP 275 +#define PCLK_VIO 276 +#define PCLK_MIPI_DSI 277 +#define PCLK_HDMI_CTRL 278 +#define PCLK_SARADC 279 +#define PCLK_DSP_CFG 280 +#define PCLK_BUS 281 +#define PCLK_EFUSE0 282 +#define PCLK_EFUSE1 283 +#define PCLK_WDT 284 +#define PCLK_GMAC 285
/* hclk gates */ #define HCLK_I2S0_8CH 320 -#define HCLK_I2S1_8CH 321 +#define HCLK_I2S1_2CH 321 #define HCLK_I2S2_2CH 322 #define HCLK_NANDC 323 #define HCLK_SDMMC 324 @@ -80,20 +148,37 @@ #define HCLK_EMMC 326 #define HCLK_PERI 327 #define HCLK_SFC 328 +#define HCLK_RKVENC 329 +#define HCLK_RKVDEC 330 +#define HCLK_CIF0 331 +#define HCLK_VIO 332 +#define HCLK_VOP 333 +#define HCLK_IEP 334 +#define HCLK_RGA 335 +#define HCLK_ISP 336 +#define HCLK_CRYPTO_MST 337 +#define HCLK_CRYPTO_SLV 338 +#define HCLK_HOST0 339 +#define HCLK_OTG 340 +#define HCLK_CIF1 341 +#define HCLK_CIF2 342 +#define HCLK_CIF3 343 +#define HCLK_BUS 344 +#define HCLK_VPU 345
-#define CLK_NR_CLKS (HCLK_SFC + 1) +#define CLK_NR_CLKS (HCLK_VPU + 1)
/* reset id */ -#define SRST_CORE_PO_AD 0 +#define SRST_CORE_PO_AD 0 #define SRST_CORE_AD 1 #define SRST_L2_AD 2 -#define SRST_CPU_NIU_AD 3 +#define SRST_CPU_NIU_AD 3 #define SRST_CORE_PO 4 #define SRST_CORE 5 -#define SRST_L2 6 +#define SRST_L2 6 #define SRST_CORE_DBG 8 #define PRST_DBG 9 -#define RST_DAP 10 +#define RST_DAP 10 #define PRST_DBG_NIU 11 #define ARST_STRC_SYS_AD 15
@@ -160,9 +245,9 @@ #define HRST_SYSBUS 75 #define PRST_USBGRF 76
-#define ARST_PERIPH_NIU 80 -#define HRST_PERIPH_NIU 81 -#define PRST_PERIPH_NIU 82 +#define ARST_PERIPH_NIU 80 +#define HRST_PERIPH_NIU 81 +#define PRST_PERIPH_NIU 82 #define HRST_PERIPH 83 #define HRST_SDMMC 84 #define HRST_SDIO 85 @@ -180,28 +265,11 @@ #define HRST_HOST0_AUX 96 #define HRST_HOST0_ARB 97 #define SRST_HOST0_EHCIPHY 98 -#define SRST_HOST0_UTMI 99 +#define SRST_HOST0_UTMI 99 #define SRST_USBPOR 100 #define SRST_UTMI0 101 #define SRST_UTMI1 102
-#define ARST_VIO0_NIU 102 -#define ARST_VIO1_NIU 103 -#define HRST_VIO_NIU 104 -#define PRST_VIO_NIU 105 -#define ARST_VOP 106 -#define HRST_VOP 107 -#define DRST_VOP 108 -#define ARST_IEP 109 -#define HRST_IEP 110 -#define ARST_RGA 111 -#define HRST_RGA 112 -#define SRST_RGA 113 -#define PRST_CVBS 114 -#define PRST_HDMI 115 -#define SRST_HDMI 116 -#define PRST_MIPI_DSI 117 - #define ARST_ISP_NIU 118 #define HRST_ISP_NIU 119 #define HRST_ISP 120 @@ -227,21 +295,21 @@ #define HRST_VPU_NIU 141 #define ARST_VPU 142 #define HRST_VPU 143 -#define ARST_RKVDEC_NIU 144 -#define HRST_RKVDEC_NIU 145 +#define ARST_RKVDEC_NIU 144 +#define HRST_RKVDEC_NIU 145 #define ARST_RKVDEC 146 #define HRST_RKVDEC 147 #define SRST_RKVDEC_CABAC 148 #define SRST_RKVDEC_CORE 149 -#define ARST_RKVENC_NIU 150 -#define HRST_RKVENC_NIU 151 +#define ARST_RKVENC_NIU 150 +#define HRST_RKVENC_NIU 151 #define ARST_RKVENC 152 #define HRST_RKVENC 153 #define SRST_RKVENC_CORE 154
#define SRST_DSP_CORE 156 #define SRST_DSP_SYS 157 -#define SRST_DSP_GLOBAL 158 +#define SRST_DSP_GLOBAL 158 #define SRST_DSP_OECM 159 #define PRST_DSP_IOP_NIU 160 #define ARST_DSP_EPP_NIU 161 @@ -259,7 +327,7 @@ #define SRST_PMU_I2C0 173 #define PRST_PMU_I2C0 174 #define PRST_PMU_GPIO0 175 -#define PRST_PMU_INTMEM 176 +#define PRST_PMU_INTMEM 176 #define PRST_PMU_PWM0 177 #define SRST_PMU_PWM0 178 #define PRST_PMU_GRF 179

Hi
On 2018/11/21 上午2:55, Otavio Salvador wrote:
Make adjustments to the rv1108 clock driver in order to align it with the internal Rockchip version.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2: None
.../include/asm/arch-rockchip/cru_rv1108.h | 143 +++++- drivers/clk/rockchip/clk_rv1108.c | 457 +++++++++++++++++- include/dt-bindings/clock/rv1108-cru.h | 154 ++++-- 3 files changed, 706 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h index 3cc2ed0187..4ce8caa40f 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h @@ -11,7 +11,11 @@ #define OSC_HZ (24 * 1000 * 1000)
#define APLL_HZ (600 * 1000000) -#define GPLL_HZ (594 * 1000000) +#define GPLL_HZ (1188 * 1000000) +#define ACLK_PERI_HZ (148500000) +#define HCLK_PERI_HZ (148500000) +#define PCLK_PERI_HZ (74250000) +#define ACLK_BUS_HZ (148500000)
struct rv1108_clk_priv { struct rv1108_cru *cru; @@ -80,6 +84,11 @@ enum { WORK_MODE_NORMAL = 1, DSMPD_SHIFT = 3, DSMPD_MASK = 1 << DSMPD_SHIFT,
INTEGER_MODE = 1,
GLOBAL_POWER_DOWN_SHIFT = 0,
GLOBAL_POWER_DOWN_MASK = 1 << GLOBAL_POWER_DOWN_SHIFT,
GLOBAL_POWER_DOWN = 1,
GLOBAL_POWER_UP = 0,
/* CLKSEL0_CON */ CORE_PLL_SEL_SHIFT = 8,
@@ -90,11 +99,77 @@ enum { CORE_CLK_DIV_SHIFT = 0, CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
/* CLKSEL_CON1 */
PCLK_DBG_DIV_CON_SHIFT = 4,
PCLK_DBG_DIV_CON_MASK = 0xf << PCLK_DBG_DIV_CON_SHIFT,
ACLK_CORE_DIV_CON_SHIFT = 0,
ACLK_CORE_DIV_CON_MASK = 7 << ACLK_CORE_DIV_CON_SHIFT,
/* CLKSEL_CON2 */
ACLK_BUS_PLL_SEL_SHIFT = 8,
ACLK_BUS_PLL_SEL_MASK = 3 << ACLK_BUS_PLL_SEL_SHIFT,
ACLK_BUS_PLL_SEL_GPLL = 0,
ACLK_BUS_PLL_SEL_APLL = 1,
ACLK_BUS_PLL_SEL_DPLL = 2,
ACLK_BUS_DIV_CON_SHIFT = 0,
ACLK_BUS_DIV_CON_MASK = 0x1f << ACLK_BUS_DIV_CON_SHIFT,
ACLK_BUS_DIV_CON_WIDTH = 5,
/* CLKSEL_CON3 */
PCLK_BUS_DIV_CON_SHIFT = 8,
PCLK_BUS_DIV_CON_MASK = 0x1f << PCLK_BUS_DIV_CON_SHIFT,
HCLK_BUS_DIV_CON_SHIFT = 0,
HCLK_BUS_DIV_CON_MASK = 0x1f,
/* CLKSEL_CON4 */
CLK_DDR_PLL_SEL_SHIFT = 8,
CLK_DDR_PLL_SEL_MASK = 0x3 << CLK_DDR_PLL_SEL_SHIFT,
CLK_DDR_DIV_CON_SHIFT = 0,
CLK_DDR_DIV_CON_MASK = 0x3 << CLK_DDR_DIV_CON_SHIFT,
/* CLKSEL_CON19 */
CLK_I2C1_PLL_SEL_SHIFT = 15,
CLK_I2C1_PLL_SEL_MASK = 1 << CLK_I2C1_PLL_SEL_SHIFT,
CLK_I2C1_PLL_SEL_DPLL = 0,
CLK_I2C1_PLL_SEL_GPLL = 1,
CLK_I2C1_DIV_CON_SHIFT = 8,
CLK_I2C1_DIV_CON_MASK = 0x7f << CLK_I2C1_DIV_CON_SHIFT,
CLK_I2C0_PLL_SEL_SHIFT = 7,
CLK_I2C0_PLL_SEL_MASK = 1 << CLK_I2C0_PLL_SEL_SHIFT,
CLK_I2C0_DIV_CON_SHIFT = 0,
CLK_I2C0_DIV_CON_MASK = 0x7f,
I2C_DIV_CON_WIDTH = 7,
/* CLKSEL_CON20 */
CLK_I2C3_PLL_SEL_SHIFT = 15,
CLK_I2C3_PLL_SEL_MASK = 1 << CLK_I2C3_PLL_SEL_SHIFT,
CLK_I2C3_PLL_SEL_DPLL = 0,
CLK_I2C3_PLL_SEL_GPLL = 1,
CLK_I2C3_DIV_CON_SHIFT = 8,
CLK_I2C3_DIV_CON_MASK = 0x7f << CLK_I2C3_DIV_CON_SHIFT,
CLK_I2C2_PLL_SEL_SHIFT = 7,
CLK_I2C2_PLL_SEL_MASK = 1 << CLK_I2C2_PLL_SEL_SHIFT,
CLK_I2C2_DIV_CON_SHIFT = 0,
CLK_I2C2_DIV_CON_MASK = 0x7f,
/* CLKSEL_CON22 */ CLK_SARADC_DIV_CON_SHIFT= 0, CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), CLK_SARADC_DIV_CON_WIDTH= 10,
/* CLKSEL_CON23 */
ACLK_PERI_PLL_SEL_SHIFT = 15,
ACLK_PERI_PLL_SEL_MASK = 1 << ACLK_PERI_PLL_SEL_SHIFT,
ACLK_PERI_PLL_SEL_GPLL = 0,
ACLK_PERI_PLL_SEL_DPLL = 1,
PCLK_PERI_DIV_CON_SHIFT = 10,
PCLK_PERI_DIV_CON_MASK = 0x1f << PCLK_PERI_DIV_CON_SHIFT,
HCLK_PERI_DIV_CON_SHIFT = 5,
HCLK_PERI_DIV_CON_MASK = 0x1f << HCLK_PERI_DIV_CON_SHIFT,
ACLK_PERI_DIV_CON_SHIFT = 0,
ACLK_PERI_DIV_CON_MASK = 0x1f,
PERI_DIV_CON_WIDTH = 5,
/* CLKSEL24_CON */ MAC_PLL_SEL_SHIFT = 12, MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT,
@@ -105,6 +180,16 @@ enum { MAC_CLK_DIV_MASK = 0x1f, MAC_CLK_DIV_SHIFT = 0,
- /* CLKSEL25_CON */
- EMMC_PLL_SEL_SHIFT = 12,
- EMMC_PLL_SEL_MASK = 3 << EMMC_PLL_SEL_SHIFT,
- EMMC_PLL_SEL_DPLL = 0,
- EMMC_PLL_SEL_GPLL,
- /* CLKSEL26_CON */
- EMMC_CLK_DIV_SHIFT = 8,
- EMMC_CLK_DIV_MASK = 0xff << EMMC_CLK_DIV_SHIFT,
- /* CLKSEL27_CON */ SFC_PLL_SEL_SHIFT = 7, SFC_PLL_SEL_MASK = 1 << SFC_PLL_SEL_SHIFT,
@@ -112,5 +197,61 @@ enum { SFC_PLL_SEL_GPLL = 1, SFC_CLK_DIV_SHIFT = 0, SFC_CLK_DIV_MASK = 0x3f << SFC_CLK_DIV_SHIFT,
- /* CLKSEL28_CON */
- ACLK_VIO1_PLL_SEL_SHIFT = 14,
- ACLK_VIO1_PLL_SEL_MASK = 3 << ACLK_VIO1_PLL_SEL_SHIFT,
- VIO_PLL_SEL_DPLL = 0,
- VIO_PLL_SEL_GPLL = 1,
- ACLK_VIO1_CLK_DIV_SHIFT = 8,
- ACLK_VIO1_CLK_DIV_MASK = 0x1f << ACLK_VIO1_CLK_DIV_SHIFT,
- CLK_VIO_DIV_CON_WIDTH = 5,
- ACLK_VIO0_PLL_SEL_SHIFT = 6,
- ACLK_VIO0_PLL_SEL_MASK = 3 << ACLK_VIO0_PLL_SEL_SHIFT,
- ACLK_VIO0_CLK_DIV_SHIFT = 0,
- ACLK_VIO0_CLK_DIV_MASK = 0x1f << ACLK_VIO0_CLK_DIV_SHIFT,
- /* CLKSEL29_CON */
- PCLK_VIO_CLK_DIV_SHIFT = 8,
- PCLK_VIO_CLK_DIV_MASK = 0x1f << PCLK_VIO_CLK_DIV_SHIFT,
- HCLK_VIO_CLK_DIV_SHIFT = 0,
- HCLK_VIO_CLK_DIV_MASK = 0x1f << HCLK_VIO_CLK_DIV_SHIFT,
- /* CLKSEL32_CON */
- DCLK_VOP_SEL_SHIFT = 7,
- DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT,
- DCLK_VOP_SEL_HDMI = 0,
- DCLK_VOP_SEL_PLL = 1,
- DCLK_VOP_PLL_SEL_SHIFT = 6,
- DCLK_VOP_PLL_SEL_MASK = 1 << DCLK_VOP_PLL_SEL_SHIFT,
- DCLK_VOP_PLL_SEL_GPLL = 0,
- DCLK_VOP_PLL_SEL_DPLL = 1,
- DCLK_VOP_CLK_DIV_SHIFT = 0,
- DCLK_VOP_CLK_DIV_MASK = 0x3f << DCLK_VOP_CLK_DIV_SHIFT,
- DCLK_VOP_DIV_CON_WIDTH = 6,
- /* SOFTRST1_CON*/
- DDRPHY_SRSTN_CLKDIV_REQ_SHIFT = 0,
- DDRPHY_SRSTN_CLKDIV_REQ = 1,
- DDRPHY_SRSTN_CLKDIV_DIS = 0,
- DDRPHY_SRSTN_CLKDIV_REQ_MASK = 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT,
- DDRPHY_SRSTN_REQ_SHIFT = 1,
- DDRPHY_SRSTN_REQ = 1,
- DDRPHY_SRSTN_DIS = 0,
- DDRPHY_SRSTN_REQ_MASK = 1 << DDRPHY_SRSTN_REQ_SHIFT,
- DDRPHY_PSRSTN_REQ_SHIFT = 2,
- DDRPHY_PSRSTN_REQ = 1,
- DDRPHY_PSRSTN_DIS = 0,
- DDRPHY_PSRSTN_REQ_MASK = 1 << DDRPHY_PSRSTN_REQ_SHIFT,
- /* SOFTRST2_CON*/
- DDRUPCTL_PSRSTN_REQ_SHIFT = 0,
- DDRUPCTL_PSRSTN_REQ = 1,
- DDRUPCTL_PSRSTN_DIS = 0,
- DDRUPCTL_PSRSTN_REQ_MASK = 1 << DDRUPCTL_PSRSTN_REQ_SHIFT,
- DDRUPCTL_NSRSTN_REQ_SHIFT = 1,
- DDRUPCTL_NSRSTN_REQ = 1,
- DDRUPCTL_NSRSTN_DIS = 0,
- DDRUPCTL_NSRSTN_REQ_MASK = 1 << DDRUPCTL_NSRSTN_REQ_SHIFT, }; #endif
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c index 1f9f534b28..3603568ee7 100644 --- a/drivers/clk/rockchip/clk_rv1108.c +++ b/drivers/clk/rockchip/clk_rv1108.c @@ -35,6 +35,9 @@ enum { #hz "Hz cannot be hit with PLL "\ "divisors on line " __stringify(__LINE__));
+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);
- /* use integer mode */ static inline int rv1108_pll_id(enum rk_clk_id clk_id) {
@@ -57,6 +60,58 @@ static inline int rv1108_pll_id(enum rk_clk_id clk_id) return id; }
+static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div)
+{
- int pll_id = rv1108_pll_id(clk_id);
- struct rv1108_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: fb=%d, ref=%d, pst1=%d, pst2=%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);
- /*
* When power on or changing PLL setting,
* we must force PLL into slow mode to ensure output stable clock.
*/
- rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
WORK_MODE_SLOW << WORK_MODE_SHIFT);
- /* use integer mode */
- rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
- /* Power down */
- rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
- rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
- rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
(div->postdiv1 << POSTDIV1_SHIFT |
div->postdiv2 << POSTDIV2_SHIFT |
div->refdiv << REFDIV_SHIFT));
- rk_clrsetreg(&pll->con2, FRACDIV_MASK,
(div->refdiv << REFDIV_SHIFT));
- /* Power Up */
- rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
- /* waiting for pll lock */
- while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
udelay(1);
- /*
* set PLL into normal mode.
*/
- rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
WORK_MODE_NORMAL << WORK_MODE_SHIFT);
- return 0;
+}
- static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, enum rk_clk_id clk_id) {
@@ -74,7 +129,7 @@ static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK; postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT; postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; } else { freq = OSC_HZ;refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK;
@@ -154,6 +209,322 @@ static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz) return rv1108_saradc_get_clk(cru); }
+static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[28]);
- div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
CLK_VIO_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[28],
ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
(src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
(VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
- return rv1108_aclk_vio1_get_clk(cru);
+}
+static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[28]);
- div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
CLK_VIO_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[28],
ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
(src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
(VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
- /*HCLK_VIO default div = 4*/
- rk_clrsetreg(&cru->clksel_con[29],
HCLK_VIO_CLK_DIV_MASK,
3 << HCLK_VIO_CLK_DIV_SHIFT);
- /*PCLK_VIO default div = 4*/
- rk_clrsetreg(&cru->clksel_con[29],
PCLK_VIO_CLK_DIV_MASK,
3 << PCLK_VIO_CLK_DIV_SHIFT);
- return rv1108_aclk_vio0_get_clk(cru);
+}
+static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[32]);
- div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
DCLK_VOP_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 64);
- rk_clrsetreg(&cru->clksel_con[32],
DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
DCLK_VOP_SEL_SHIFT,
(src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
(DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
(DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
- return rv1108_dclk_vop_get_clk(cru);
+}
+static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[2]);
- div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
ACLK_BUS_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[2],
ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
(src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
(ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
- return rv1108_aclk_bus_get_clk(cru);
+}
+static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
(src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
(ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
- return rv1108_aclk_peri_get_clk(cru);
+}
+static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
HCLK_PERI_DIV_CON_MASK,
(src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
- return rv1108_hclk_peri_get_clk(cru);
+}
+static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
PCLK_PERI_DIV_CON_MASK,
(src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
- return rv1108_pclk_peri_get_clk(cru);
+}
+static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id) +{
- u32 div, con;
- switch (clk_id) {
- case SCLK_I2C0_PMU:
con = readl(&cru->clksel_con[19]);
div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
break;
- case SCLK_I2C1:
con = readl(&cru->clksel_con[19]);
div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
break;
- case SCLK_I2C2:
con = readl(&cru->clksel_con[20]);
div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
break;
- case SCLK_I2C3:
con = readl(&cru->clksel_con[20]);
div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
break;
- default:
printf("do not support this i2c bus\n");
return -EINVAL;
- }
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz) +{
- int src_clk_div;
- /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
- src_clk_div = GPLL_HZ / hz;
- assert(src_clk_div - 1 <= 127);
- switch (clk_id) {
- case SCLK_I2C0_PMU:
rk_clrsetreg(&cru->clksel_con[19],
CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
(src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
break;
- case SCLK_I2C1:
rk_clrsetreg(&cru->clksel_con[19],
CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
(src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
break;
- case SCLK_I2C2:
rk_clrsetreg(&cru->clksel_con[20],
CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
(src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
break;
- case SCLK_I2C3:
rk_clrsetreg(&cru->clksel_con[20],
CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
(src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
break;
- default:
printf("do not support this i2c bus\n");
return -EINVAL;
- }
- return rv1108_i2c_get_clk(cru, clk_id);
+}
+static ulong rv1108_mmc_get_clk(struct clk *clk) +{
- struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
- struct rv1108_cru *cru = priv->cru;
- u32 div, con;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- con = readl(&cru->clksel_con[26]);
- div = (con & EMMC_CLK_DIV_MASK) >> EMMC_CLK_DIV_SHIFT;
- debug("%s id %ld get_clk %ld\n", __func__, clk->id, DIV_TO_RATE(parent_rate, div));
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_mmc_set_clk(struct clk *clk, ulong set_rate) +{
- struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
- struct rv1108_cru *cru = priv->cru;
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, set_rate);
- if (src_clk_div > 127) {
src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
- }
- debug("%s id %ld src_clk_div %d\n", __func__, clk->id, src_clk_div);
- rk_clrsetreg(&cru->clksel_con[26],
EMMC_CLK_DIV_MASK , (src_clk_div -1) << EMMC_CLK_DIV_SHIFT);
- rk_clrsetreg(&cru->clksel_con[25],
EMMC_PLL_SEL_MASK , EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT);
- return rv1108_mmc_get_clk(clk);
+}
- static ulong rv1108_clk_get_rate(struct clk *clk) { struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
@@ -163,6 +534,31 @@ static ulong rv1108_clk_get_rate(struct clk *clk) return rkclk_pll_get_rate(priv->cru, clk->id); case SCLK_SARADC: return rv1108_saradc_get_clk(priv->cru);
- case ACLK_VIO0:
return rv1108_aclk_vio0_get_clk(priv->cru);
- case ACLK_VIO1:
return rv1108_aclk_vio1_get_clk(priv->cru);
- case DCLK_VOP:
return rv1108_dclk_vop_get_clk(priv->cru);
- case ACLK_PRE:
return rv1108_aclk_bus_get_clk(priv->cru);
- case ACLK_PERI:
return rv1108_aclk_peri_get_clk(priv->cru);
- case HCLK_PERI:
return rv1108_hclk_peri_get_clk(priv->cru);
- case PCLK_PERI:
return rv1108_pclk_peri_get_clk(priv->cru);
- case SCLK_I2C0_PMU:
- case SCLK_I2C1:
- case SCLK_I2C2:
- case SCLK_I2C3:
return rv1108_i2c_get_clk(priv->cru, clk->id);
- case HCLK_SDMMC:
- case HCLK_EMMC:
- case SCLK_SDMMC:
- case SCLK_EMMC:
- case SCLK_EMMC_SAMPLE:
default: return -ENOENT; }return rv1108_mmc_get_clk(clk);
@@ -183,6 +579,39 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate) case SCLK_SARADC: new_rate = rv1108_saradc_set_clk(priv->cru, rate); break;
- case ACLK_VIO0:
new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
break;
- case ACLK_VIO1:
new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
break;
- case DCLK_VOP:
new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
break;
- case ACLK_PRE:
new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
break;
- case ACLK_PERI:
new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
break;
- case HCLK_PERI:
new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
break;
- case PCLK_PERI:
new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
break;
- case SCLK_I2C0_PMU:
- case SCLK_I2C1:
- case SCLK_I2C2:
- case SCLK_I2C3:
new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
break;
- case HCLK_SDMMC:
- case HCLK_EMMC:
- case SCLK_SDMMC:
- case SCLK_EMMC:
new_rate = rv1108_mmc_set_clk(clk, rate);
default: return -ENOENT; }break;
@@ -197,14 +626,34 @@ static const struct clk_ops rv1108_clk_ops = {
static void rkclk_init(struct rv1108_cru *cru) {
- unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
- unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
- unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
unsigned int apll, dpll, gpll;
unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
rv1108_aclk_vio0_set_clk(cru, 297000000);
rv1108_aclk_vio1_set_clk(cru, 297000000);
/* configure apll */
rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
apll = rkclk_pll_get_rate(cru, CLK_ARM);
dpll = rkclk_pll_get_rate(cru, CLK_DDR);
gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK, 0 << MAC_CLK_DIV_SHIFT);
printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
aclk_bus, aclk_peri, hclk_peri, pclk_peri);
}
static int rv1108_clk_ofdata_to_platdata(struct udevice *dev)
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h index 9219a50a24..04e0a59f4b 100644 --- a/include/dt-bindings/clock/rv1108-cru.h +++ b/include/dt-bindings/clock/rv1108-cru.h @@ -14,7 +14,6 @@ #define ARMCLK 3
/* sclk gates (special clocks) */ -#define SCLK_MAC 64 #define SCLK_SPI0 65 #define SCLK_NANDC 67 #define SCLK_SDMMC 68 @@ -35,20 +34,77 @@ #define SCLK_SDMMC_SAMPLE 84 #define SCLK_SDIO_SAMPLE 85 #define SCLK_EMMC_SAMPLE 86 -#define SCLK_MAC_RX 87 -#define SCLK_MAC_TX 88 -#define SCLK_MACREF 89 -#define SCLK_MACREF_OUT 90 -#define SCLK_SARADC 91 +#define SCLK_VENC_CORE 87 +#define SCLK_HEVC_CORE 88 +#define SCLK_HEVC_CABAC 89 +#define SCLK_PWM0_PMU 90 +#define SCLK_I2C0_PMU 91 +#define SCLK_WIFI 92 +#define SCLK_CIFOUT 93 +#define SCLK_MIPI_CSI_OUT 94 +#define SCLK_CIF0 95 +#define SCLK_CIF1 96 +#define SCLK_CIF2 97 +#define SCLK_CIF3 98 +#define SCLK_DSP 99 +#define SCLK_DSP_IOP 100 +#define SCLK_DSP_EPP 101 +#define SCLK_DSP_EDP 102 +#define SCLK_DSP_EDAP 103 +#define SCLK_CVBS_HOST 104 +#define SCLK_HDMI_SFR 105 +#define SCLK_HDMI_CEC 106 +#define SCLK_CRYPTO 107 +#define SCLK_SPI 108 +#define SCLK_SARADC 109 +#define SCLK_TSADC 110 +#define SCLK_MAC_PRE 111 +#define SCLK_MAC 112 +#define SCLK_MAC_RX 113 +#define SCLK_MAC_REF 114 +#define SCLK_MAC_REFOUT 115 +#define SCLK_DSP_PFM 116 +#define SCLK_RGA 117 +#define SCLK_I2C1 118 +#define SCLK_I2C2 119 +#define SCLK_I2C3 120 +#define SCLK_PWM 121 +#define SCLK_ISP 122 +#define SCLK_USBPHY 123 +#define SCLK_I2S0_SRC 124 +#define SCLK_I2S1_SRC 125 +#define SCLK_I2S2_SRC 126 +#define SCLK_UART0_SRC 127 +#define SCLK_UART1_SRC 128 +#define SCLK_UART2_SRC 129 +#define SCLK_MAC_TX 130 +#define SCLK_MACREF 131 +#define SCLK_MACREF_OUT 132
+#define DCLK_VOP_SRC 185 +#define DCLK_HDMIPHY 186 +#define DCLK_VOP 187
/* aclk gates */ #define ACLK_DMAC 192 #define ACLK_PRE 193 #define ACLK_CORE 194 #define ACLK_ENMCORE 195 -#define ACLK_GMAC 196
+#define ACLK_RKVENC 196 +#define ACLK_RKVDEC 197 +#define ACLK_VPU 198 +#define ACLK_CIF0 199 +#define ACLK_VIO0 200 +#define ACLK_VIO1 201 +#define ACLK_VOP 202 +#define ACLK_IEP 203 +#define ACLK_RGA 204 +#define ACLK_ISP 205 +#define ACLK_CIF1 206 +#define ACLK_CIF2 207 +#define ACLK_CIF3 208 +#define ACLK_PERI 209 +#define ACLK_GMAC 210
/* pclk gates */ #define PCLK_GPIO1 256 @@ -67,12 +123,24 @@ #define PCLK_PWM 269 #define PCLK_TIMER 270 #define PCLK_PERI 271 -#define PCLK_GMAC 272 -#define PCLK_SARADC 273 +#define PCLK_GPIO0_PMU 272 +#define PCLK_I2C0_PMU 273 +#define PCLK_PWM0_PMU 274 +#define PCLK_ISP 275 +#define PCLK_VIO 276 +#define PCLK_MIPI_DSI 277 +#define PCLK_HDMI_CTRL 278 +#define PCLK_SARADC 279 +#define PCLK_DSP_CFG 280 +#define PCLK_BUS 281 +#define PCLK_EFUSE0 282 +#define PCLK_EFUSE1 283 +#define PCLK_WDT 284 +#define PCLK_GMAC 285
/* hclk gates */ #define HCLK_I2S0_8CH 320 -#define HCLK_I2S1_8CH 321 +#define HCLK_I2S1_2CH 321 #define HCLK_I2S2_2CH 322 #define HCLK_NANDC 323 #define HCLK_SDMMC 324 @@ -80,20 +148,37 @@ #define HCLK_EMMC 326 #define HCLK_PERI 327 #define HCLK_SFC 328 +#define HCLK_RKVENC 329 +#define HCLK_RKVDEC 330 +#define HCLK_CIF0 331 +#define HCLK_VIO 332 +#define HCLK_VOP 333 +#define HCLK_IEP 334 +#define HCLK_RGA 335 +#define HCLK_ISP 336 +#define HCLK_CRYPTO_MST 337 +#define HCLK_CRYPTO_SLV 338 +#define HCLK_HOST0 339 +#define HCLK_OTG 340 +#define HCLK_CIF1 341 +#define HCLK_CIF2 342 +#define HCLK_CIF3 343 +#define HCLK_BUS 344 +#define HCLK_VPU 345
-#define CLK_NR_CLKS (HCLK_SFC + 1) +#define CLK_NR_CLKS (HCLK_VPU + 1)
/* reset id */ -#define SRST_CORE_PO_AD 0 +#define SRST_CORE_PO_AD 0 #define SRST_CORE_AD 1 #define SRST_L2_AD 2 -#define SRST_CPU_NIU_AD 3 +#define SRST_CPU_NIU_AD 3 #define SRST_CORE_PO 4 #define SRST_CORE 5 -#define SRST_L2 6 +#define SRST_L2 6 #define SRST_CORE_DBG 8 #define PRST_DBG 9 -#define RST_DAP 10 +#define RST_DAP 10 #define PRST_DBG_NIU 11 #define ARST_STRC_SYS_AD 15
@@ -160,9 +245,9 @@ #define HRST_SYSBUS 75 #define PRST_USBGRF 76
-#define ARST_PERIPH_NIU 80 -#define HRST_PERIPH_NIU 81 -#define PRST_PERIPH_NIU 82 +#define ARST_PERIPH_NIU 80 +#define HRST_PERIPH_NIU 81 +#define PRST_PERIPH_NIU 82 #define HRST_PERIPH 83 #define HRST_SDMMC 84 #define HRST_SDIO 85 @@ -180,28 +265,11 @@ #define HRST_HOST0_AUX 96 #define HRST_HOST0_ARB 97 #define SRST_HOST0_EHCIPHY 98 -#define SRST_HOST0_UTMI 99 +#define SRST_HOST0_UTMI 99 #define SRST_USBPOR 100 #define SRST_UTMI0 101 #define SRST_UTMI1 102
-#define ARST_VIO0_NIU 102 -#define ARST_VIO1_NIU 103 -#define HRST_VIO_NIU 104 -#define PRST_VIO_NIU 105 -#define ARST_VOP 106 -#define HRST_VOP 107 -#define DRST_VOP 108 -#define ARST_IEP 109 -#define HRST_IEP 110 -#define ARST_RGA 111 -#define HRST_RGA 112 -#define SRST_RGA 113 -#define PRST_CVBS 114 -#define PRST_HDMI 115 -#define SRST_HDMI 116 -#define PRST_MIPI_DSI 117
Why these display devices removed?
- #define ARST_ISP_NIU 118 #define HRST_ISP_NIU 119 #define HRST_ISP 120
@@ -227,21 +295,21 @@ #define HRST_VPU_NIU 141 #define ARST_VPU 142 #define HRST_VPU 143 -#define ARST_RKVDEC_NIU 144 -#define HRST_RKVDEC_NIU 145 +#define ARST_RKVDEC_NIU 144 +#define HRST_RKVDEC_NIU 145 #define ARST_RKVDEC 146 #define HRST_RKVDEC 147 #define SRST_RKVDEC_CABAC 148 #define SRST_RKVDEC_CORE 149 -#define ARST_RKVENC_NIU 150 -#define HRST_RKVENC_NIU 151 +#define ARST_RKVENC_NIU 150 +#define HRST_RKVENC_NIU 151 #define ARST_RKVENC 152 #define HRST_RKVENC 153 #define SRST_RKVENC_CORE 154
#define SRST_DSP_CORE 156 #define SRST_DSP_SYS 157 -#define SRST_DSP_GLOBAL 158 +#define SRST_DSP_GLOBAL 158 #define SRST_DSP_OECM 159 #define PRST_DSP_IOP_NIU 160 #define ARST_DSP_EPP_NIU 161 @@ -259,7 +327,7 @@ #define SRST_PMU_I2C0 173 #define PRST_PMU_I2C0 174 #define PRST_PMU_GPIO0 175 -#define PRST_PMU_INTMEM 176 +#define PRST_PMU_INTMEM 176 #define PRST_PMU_PWM0 177 #define SRST_PMU_PWM0 178 #define PRST_PMU_GRF 179

On Mon, Nov 26, 2018 at 11:43 PM Andy Yan andy.yan@rock-chips.com wrote:
On 2018/11/21 上午2:55, Otavio Salvador wrote:
-#define ARST_VIO0_NIU 102 -#define ARST_VIO1_NIU 103 -#define HRST_VIO_NIU 104 -#define PRST_VIO_NIU 105 -#define ARST_VOP 106 -#define HRST_VOP 107 -#define DRST_VOP 108 -#define ARST_IEP 109 -#define HRST_IEP 110 -#define ARST_RGA 111 -#define HRST_RGA 112 -#define SRST_RGA 113 -#define PRST_CVBS 114 -#define PRST_HDMI 115 -#define SRST_HDMI 116 -#define PRST_MIPI_DSI 117
Why these display devices removed?
Good catch, it was a leftover change. I am reverting this for next patchset.

Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you. Thank you!
``` diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h index 60a5db2..d220d0d 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h @@ -186,6 +186,7 @@ enum { EMMC_PLL_SEL_MASK = 3 << EMMC_PLL_SEL_SHIFT, EMMC_PLL_SEL_DPLL = 0, EMMC_PLL_SEL_GPLL, + EMMC_PLL_SEL_OSC,
/* CLKSEL26_CON */ EMMC_CLK_DIV_SHIFT = 8, diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c index d95fe739..b758240 100644 --- a/drivers/clk/rockchip/clk_rv1108.c +++ b/drivers/clk/rockchip/clk_rv1108.c @@ -484,49 +484,53 @@ static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz) return rv1108_i2c_get_clk(cru, clk_id); }
-static ulong rv1108_mmc_get_clk(struct clk *clk) +static ulong rv1108_mmc_get_clk(struct rv1108_cru *cru) { - struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); - struct rv1108_cru *cru = priv->cru; u32 div, con; - - ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + ulong mmc_clk;
con = readl(&cru->clksel_con[26]); - div = (con & EMMC_CLK_DIV_MASK) >> EMMC_CLK_DIV_SHIFT; - + div = bitfield_extract(con, EMMC_CLK_DIV_SHIFT, 8);
- debug("%s id %ld get_clk %ld\n", __func__, clk->id, DIV_TO_RATE(parent_rate, div)); + con = readl(&cru->clksel_con[25]);
- return DIV_TO_RATE(parent_rate, div); + if ((con & EMMC_PLL_SEL_MASK) >> EMMC_PLL_SEL_SHIFT == EMMC_PLL_SEL_OSC) + mmc_clk = DIV_TO_RATE(OSC_HZ, div) / 2; + else + mmc_clk = DIV_TO_RATE(GPLL_HZ, div) / 2;
+ debug("%s div %d get_clk %ld\n", __func__, div, mmc_clk); + return mmc_clk; }
-static ulong rv1108_mmc_set_clk(struct clk *clk, ulong set_rate) +static ulong rv1108_mmc_set_clk(struct rv1108_cru *cru, ulong rate) { - struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); - struct rv1108_cru *cru = priv->cru; - int src_clk_div; + int div; + u32 pll_rate;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); - src_clk_div = DIV_ROUND_UP(parent_rate, set_rate); + div = DIV_ROUND_UP(rkclk_pll_get_rate(cru, CLK_GENERAL), rate);
- if (src_clk_div > 127) { - src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); + if (div < 127) { + debug("%s source gpll\n", __func__); + rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK, + (EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT)); + pll_rate = rkclk_pll_get_rate(cru, CLK_GENERAL); + } else { + debug("%s source 24m\n", __func__); + rk_clrsetreg(&cru->clksel_con[25], EMMC_PLL_SEL_MASK, + (EMMC_PLL_SEL_OSC << EMMC_PLL_SEL_SHIFT)); + pll_rate = OSC_HZ; }
- debug("%s id %ld src_clk_div %d\n", __func__, clk->id, src_clk_div); + div = DIV_ROUND_UP(pll_rate / 2, rate); + rk_clrsetreg(&cru->clksel_con[26], EMMC_CLK_DIV_MASK, + ((div - 1) << EMMC_CLK_DIV_SHIFT));
- rk_clrsetreg(&cru->clksel_con[26], - EMMC_CLK_DIV_MASK , (src_clk_div -1) << EMMC_CLK_DIV_SHIFT); + debug("%s set_rate %ld div %d\n", __func__, rate, div);
- rk_clrsetreg(&cru->clksel_con[25], - EMMC_PLL_SEL_MASK , EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT); - - return rv1108_mmc_get_clk(clk); + return DIV_TO_RATE(pll_rate, div); }
- static ulong rv1108_clk_get_rate(struct clk *clk) { struct rv1108_clk_priv *priv = dev_get_priv(clk->dev); @@ -555,12 +559,10 @@ static ulong rv1108_clk_get_rate(struct clk *clk) case SCLK_I2C2: case SCLK_I2C3: return rv1108_i2c_get_clk(priv->cru, clk->id); - case HCLK_SDMMC: case HCLK_EMMC: - case SCLK_SDMMC: case SCLK_EMMC: case SCLK_EMMC_SAMPLE: - return rv1108_mmc_get_clk(clk); + return rv1108_mmc_get_clk(priv->cru); default: return -ENOENT; } @@ -608,11 +610,9 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate) case SCLK_I2C3: new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate); break; - case HCLK_SDMMC: case HCLK_EMMC: - case SCLK_SDMMC: case SCLK_EMMC: - new_rate = rv1108_mmc_set_clk(clk, rate); + new_rate = rv1108_mmc_set_clk(priv->cru, rate); break; default: return -ENOENT; (END) ```
vicent.chi@rock-chips.com
From: Andy Yan Date: 2018-11-27 09:43 To: Otavio Salvador; U-Boot Mailing List CC: Jason Zhu; Vicent Chi; Albert Aribaud; Philipp Tomsich; Simon Glass; zhangqing Subject: Re: [PATCH v2 1/5] clk_rv1108: Sync with vendor tree Hi
On 2018/11/21 上午2:55, Otavio Salvador wrote:
Make adjustments to the rv1108 clock driver in order to align it with the internal Rockchip version.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2: None
.../include/asm/arch-rockchip/cru_rv1108.h | 143 +++++- drivers/clk/rockchip/clk_rv1108.c | 457 +++++++++++++++++- include/dt-bindings/clock/rv1108-cru.h | 154 ++++-- 3 files changed, 706 insertions(+), 48 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h index 3cc2ed0187..4ce8caa40f 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h @@ -11,7 +11,11 @@ #define OSC_HZ (24 * 1000 * 1000)
#define APLL_HZ (600 * 1000000) -#define GPLL_HZ (594 * 1000000) +#define GPLL_HZ (1188 * 1000000) +#define ACLK_PERI_HZ (148500000) +#define HCLK_PERI_HZ (148500000) +#define PCLK_PERI_HZ (74250000) +#define ACLK_BUS_HZ (148500000)
struct rv1108_clk_priv { struct rv1108_cru *cru; @@ -80,6 +84,11 @@ enum { WORK_MODE_NORMAL = 1, DSMPD_SHIFT = 3, DSMPD_MASK = 1 << DSMPD_SHIFT,
INTEGER_MODE = 1,
GLOBAL_POWER_DOWN_SHIFT = 0,
GLOBAL_POWER_DOWN_MASK = 1 << GLOBAL_POWER_DOWN_SHIFT,
GLOBAL_POWER_DOWN = 1,
GLOBAL_POWER_UP = 0,
/* CLKSEL0_CON */ CORE_PLL_SEL_SHIFT = 8,
@@ -90,11 +99,77 @@ enum { CORE_CLK_DIV_SHIFT = 0, CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
/* CLKSEL_CON1 */
PCLK_DBG_DIV_CON_SHIFT = 4,
PCLK_DBG_DIV_CON_MASK = 0xf << PCLK_DBG_DIV_CON_SHIFT,
ACLK_CORE_DIV_CON_SHIFT = 0,
ACLK_CORE_DIV_CON_MASK = 7 << ACLK_CORE_DIV_CON_SHIFT,
/* CLKSEL_CON2 */
ACLK_BUS_PLL_SEL_SHIFT = 8,
ACLK_BUS_PLL_SEL_MASK = 3 << ACLK_BUS_PLL_SEL_SHIFT,
ACLK_BUS_PLL_SEL_GPLL = 0,
ACLK_BUS_PLL_SEL_APLL = 1,
ACLK_BUS_PLL_SEL_DPLL = 2,
ACLK_BUS_DIV_CON_SHIFT = 0,
ACLK_BUS_DIV_CON_MASK = 0x1f << ACLK_BUS_DIV_CON_SHIFT,
ACLK_BUS_DIV_CON_WIDTH = 5,
/* CLKSEL_CON3 */
PCLK_BUS_DIV_CON_SHIFT = 8,
PCLK_BUS_DIV_CON_MASK = 0x1f << PCLK_BUS_DIV_CON_SHIFT,
HCLK_BUS_DIV_CON_SHIFT = 0,
HCLK_BUS_DIV_CON_MASK = 0x1f,
/* CLKSEL_CON4 */
CLK_DDR_PLL_SEL_SHIFT = 8,
CLK_DDR_PLL_SEL_MASK = 0x3 << CLK_DDR_PLL_SEL_SHIFT,
CLK_DDR_DIV_CON_SHIFT = 0,
CLK_DDR_DIV_CON_MASK = 0x3 << CLK_DDR_DIV_CON_SHIFT,
/* CLKSEL_CON19 */
CLK_I2C1_PLL_SEL_SHIFT = 15,
CLK_I2C1_PLL_SEL_MASK = 1 << CLK_I2C1_PLL_SEL_SHIFT,
CLK_I2C1_PLL_SEL_DPLL = 0,
CLK_I2C1_PLL_SEL_GPLL = 1,
CLK_I2C1_DIV_CON_SHIFT = 8,
CLK_I2C1_DIV_CON_MASK = 0x7f << CLK_I2C1_DIV_CON_SHIFT,
CLK_I2C0_PLL_SEL_SHIFT = 7,
CLK_I2C0_PLL_SEL_MASK = 1 << CLK_I2C0_PLL_SEL_SHIFT,
CLK_I2C0_DIV_CON_SHIFT = 0,
CLK_I2C0_DIV_CON_MASK = 0x7f,
I2C_DIV_CON_WIDTH = 7,
/* CLKSEL_CON20 */
CLK_I2C3_PLL_SEL_SHIFT = 15,
CLK_I2C3_PLL_SEL_MASK = 1 << CLK_I2C3_PLL_SEL_SHIFT,
CLK_I2C3_PLL_SEL_DPLL = 0,
CLK_I2C3_PLL_SEL_GPLL = 1,
CLK_I2C3_DIV_CON_SHIFT = 8,
CLK_I2C3_DIV_CON_MASK = 0x7f << CLK_I2C3_DIV_CON_SHIFT,
CLK_I2C2_PLL_SEL_SHIFT = 7,
CLK_I2C2_PLL_SEL_MASK = 1 << CLK_I2C2_PLL_SEL_SHIFT,
CLK_I2C2_DIV_CON_SHIFT = 0,
CLK_I2C2_DIV_CON_MASK = 0x7f,
/* CLKSEL_CON22 */ CLK_SARADC_DIV_CON_SHIFT= 0, CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0), CLK_SARADC_DIV_CON_WIDTH= 10,
/* CLKSEL_CON23 */
ACLK_PERI_PLL_SEL_SHIFT = 15,
ACLK_PERI_PLL_SEL_MASK = 1 << ACLK_PERI_PLL_SEL_SHIFT,
ACLK_PERI_PLL_SEL_GPLL = 0,
ACLK_PERI_PLL_SEL_DPLL = 1,
PCLK_PERI_DIV_CON_SHIFT = 10,
PCLK_PERI_DIV_CON_MASK = 0x1f << PCLK_PERI_DIV_CON_SHIFT,
HCLK_PERI_DIV_CON_SHIFT = 5,
HCLK_PERI_DIV_CON_MASK = 0x1f << HCLK_PERI_DIV_CON_SHIFT,
ACLK_PERI_DIV_CON_SHIFT = 0,
ACLK_PERI_DIV_CON_MASK = 0x1f,
PERI_DIV_CON_WIDTH = 5,
/* CLKSEL24_CON */ MAC_PLL_SEL_SHIFT = 12, MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT,
@@ -105,6 +180,16 @@ enum { MAC_CLK_DIV_MASK = 0x1f, MAC_CLK_DIV_SHIFT = 0,
- /* CLKSEL25_CON */
- EMMC_PLL_SEL_SHIFT = 12,
- EMMC_PLL_SEL_MASK = 3 << EMMC_PLL_SEL_SHIFT,
- EMMC_PLL_SEL_DPLL = 0,
- EMMC_PLL_SEL_GPLL,
- /* CLKSEL26_CON */
- EMMC_CLK_DIV_SHIFT = 8,
- EMMC_CLK_DIV_MASK = 0xff << EMMC_CLK_DIV_SHIFT,
- /* CLKSEL27_CON */ SFC_PLL_SEL_SHIFT = 7, SFC_PLL_SEL_MASK = 1 << SFC_PLL_SEL_SHIFT,
@@ -112,5 +197,61 @@ enum { SFC_PLL_SEL_GPLL = 1, SFC_CLK_DIV_SHIFT = 0, SFC_CLK_DIV_MASK = 0x3f << SFC_CLK_DIV_SHIFT,
- /* CLKSEL28_CON */
- ACLK_VIO1_PLL_SEL_SHIFT = 14,
- ACLK_VIO1_PLL_SEL_MASK = 3 << ACLK_VIO1_PLL_SEL_SHIFT,
- VIO_PLL_SEL_DPLL = 0,
- VIO_PLL_SEL_GPLL = 1,
- ACLK_VIO1_CLK_DIV_SHIFT = 8,
- ACLK_VIO1_CLK_DIV_MASK = 0x1f << ACLK_VIO1_CLK_DIV_SHIFT,
- CLK_VIO_DIV_CON_WIDTH = 5,
- ACLK_VIO0_PLL_SEL_SHIFT = 6,
- ACLK_VIO0_PLL_SEL_MASK = 3 << ACLK_VIO0_PLL_SEL_SHIFT,
- ACLK_VIO0_CLK_DIV_SHIFT = 0,
- ACLK_VIO0_CLK_DIV_MASK = 0x1f << ACLK_VIO0_CLK_DIV_SHIFT,
- /* CLKSEL29_CON */
- PCLK_VIO_CLK_DIV_SHIFT = 8,
- PCLK_VIO_CLK_DIV_MASK = 0x1f << PCLK_VIO_CLK_DIV_SHIFT,
- HCLK_VIO_CLK_DIV_SHIFT = 0,
- HCLK_VIO_CLK_DIV_MASK = 0x1f << HCLK_VIO_CLK_DIV_SHIFT,
- /* CLKSEL32_CON */
- DCLK_VOP_SEL_SHIFT = 7,
- DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT,
- DCLK_VOP_SEL_HDMI = 0,
- DCLK_VOP_SEL_PLL = 1,
- DCLK_VOP_PLL_SEL_SHIFT = 6,
- DCLK_VOP_PLL_SEL_MASK = 1 << DCLK_VOP_PLL_SEL_SHIFT,
- DCLK_VOP_PLL_SEL_GPLL = 0,
- DCLK_VOP_PLL_SEL_DPLL = 1,
- DCLK_VOP_CLK_DIV_SHIFT = 0,
- DCLK_VOP_CLK_DIV_MASK = 0x3f << DCLK_VOP_CLK_DIV_SHIFT,
- DCLK_VOP_DIV_CON_WIDTH = 6,
- /* SOFTRST1_CON*/
- DDRPHY_SRSTN_CLKDIV_REQ_SHIFT = 0,
- DDRPHY_SRSTN_CLKDIV_REQ = 1,
- DDRPHY_SRSTN_CLKDIV_DIS = 0,
- DDRPHY_SRSTN_CLKDIV_REQ_MASK = 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT,
- DDRPHY_SRSTN_REQ_SHIFT = 1,
- DDRPHY_SRSTN_REQ = 1,
- DDRPHY_SRSTN_DIS = 0,
- DDRPHY_SRSTN_REQ_MASK = 1 << DDRPHY_SRSTN_REQ_SHIFT,
- DDRPHY_PSRSTN_REQ_SHIFT = 2,
- DDRPHY_PSRSTN_REQ = 1,
- DDRPHY_PSRSTN_DIS = 0,
- DDRPHY_PSRSTN_REQ_MASK = 1 << DDRPHY_PSRSTN_REQ_SHIFT,
- /* SOFTRST2_CON*/
- DDRUPCTL_PSRSTN_REQ_SHIFT = 0,
- DDRUPCTL_PSRSTN_REQ = 1,
- DDRUPCTL_PSRSTN_DIS = 0,
- DDRUPCTL_PSRSTN_REQ_MASK = 1 << DDRUPCTL_PSRSTN_REQ_SHIFT,
- DDRUPCTL_NSRSTN_REQ_SHIFT = 1,
- DDRUPCTL_NSRSTN_REQ = 1,
- DDRUPCTL_NSRSTN_DIS = 0,
- DDRUPCTL_NSRSTN_REQ_MASK = 1 << DDRUPCTL_NSRSTN_REQ_SHIFT, }; #endif
diff --git a/drivers/clk/rockchip/clk_rv1108.c b/drivers/clk/rockchip/clk_rv1108.c index 1f9f534b28..3603568ee7 100644 --- a/drivers/clk/rockchip/clk_rv1108.c +++ b/drivers/clk/rockchip/clk_rv1108.c @@ -35,6 +35,9 @@ enum { #hz "Hz cannot be hit with PLL "\ "divisors on line " __stringify(__LINE__));
+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);
- /* use integer mode */ static inline int rv1108_pll_id(enum rk_clk_id clk_id) {
@@ -57,6 +60,58 @@ static inline int rv1108_pll_id(enum rk_clk_id clk_id) return id; }
+static int rkclk_set_pll(struct rv1108_cru *cru, enum rk_clk_id clk_id,
- const struct pll_div *div)
+{
- int pll_id = rv1108_pll_id(clk_id);
- struct rv1108_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: fb=%d, ref=%d, pst1=%d, pst2=%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);
- /*
- When power on or changing PLL setting,
- we must force PLL into slow mode to ensure output stable clock.
- */
- rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
WORK_MODE_SLOW << WORK_MODE_SHIFT);
- /* use integer mode */
- rk_setreg(&pll->con3, 1 << DSMPD_SHIFT);
- /* Power down */
- rk_setreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
- rk_clrsetreg(&pll->con0, FBDIV_MASK, div->fbdiv << FBDIV_SHIFT);
- rk_clrsetreg(&pll->con1, POSTDIV1_MASK | POSTDIV2_MASK | REFDIV_MASK,
(div->postdiv1 << POSTDIV1_SHIFT |
div->postdiv2 << POSTDIV2_SHIFT |
div->refdiv << REFDIV_SHIFT));
- rk_clrsetreg(&pll->con2, FRACDIV_MASK,
(div->refdiv << REFDIV_SHIFT));
- /* Power Up */
- rk_clrreg(&pll->con3, 1 << GLOBAL_POWER_DOWN_SHIFT);
- /* waiting for pll lock */
- while (readl(&pll->con2) & (1 << LOCK_STA_SHIFT))
- udelay(1);
- /*
- set PLL into normal mode.
- */
- rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
WORK_MODE_NORMAL << WORK_MODE_SHIFT);
- return 0;
+}
- static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, enum rk_clk_id clk_id) {
@@ -74,7 +129,7 @@ static uint32_t rkclk_pll_get_rate(struct rv1108_cru *cru, fbdiv = (con0 >> FBDIV_SHIFT) & FBDIV_MASK; postdiv1 = (con1 & POSTDIV1_MASK) >> POSTDIV1_SHIFT; postdiv2 = (con1 & POSTDIV2_MASK) >> POSTDIV2_SHIFT;
- refdiv = (con1 & REFDIV_MASK) >> REFDIV_SHIFT;
- refdiv = (con1 >> REFDIV_SHIFT) & REFDIV_MASK; freq = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000; } else { freq = OSC_HZ;
@@ -154,6 +209,322 @@ static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz) return rv1108_saradc_get_clk(cru); }
+static ulong rv1108_aclk_vio1_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[28]);
- div = bitfield_extract(val, ACLK_VIO1_CLK_DIV_SHIFT,
CLK_VIO_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_aclk_vio1_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[28],
ACLK_VIO1_CLK_DIV_MASK | ACLK_VIO1_PLL_SEL_MASK,
(src_clk_div << ACLK_VIO1_CLK_DIV_SHIFT) |
(VIO_PLL_SEL_GPLL << ACLK_VIO1_PLL_SEL_SHIFT));
- return rv1108_aclk_vio1_get_clk(cru);
+}
+static ulong rv1108_aclk_vio0_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[28]);
- div = bitfield_extract(val, ACLK_VIO0_CLK_DIV_SHIFT,
CLK_VIO_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_aclk_vio0_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[28],
ACLK_VIO0_CLK_DIV_MASK | ACLK_VIO0_PLL_SEL_MASK,
(src_clk_div << ACLK_VIO0_CLK_DIV_SHIFT) |
(VIO_PLL_SEL_GPLL << ACLK_VIO0_PLL_SEL_SHIFT));
- /*HCLK_VIO default div = 4*/
- rk_clrsetreg(&cru->clksel_con[29],
HCLK_VIO_CLK_DIV_MASK,
3 << HCLK_VIO_CLK_DIV_SHIFT);
- /*PCLK_VIO default div = 4*/
- rk_clrsetreg(&cru->clksel_con[29],
PCLK_VIO_CLK_DIV_MASK,
3 << PCLK_VIO_CLK_DIV_SHIFT);
- return rv1108_aclk_vio0_get_clk(cru);
+}
+static ulong rv1108_dclk_vop_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- val = readl(&cru->clksel_con[32]);
- div = bitfield_extract(val, DCLK_VOP_CLK_DIV_SHIFT,
DCLK_VOP_DIV_CON_WIDTH);
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_dclk_vop_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz) - 1;
- assert(src_clk_div < 64);
- rk_clrsetreg(&cru->clksel_con[32],
DCLK_VOP_CLK_DIV_MASK | DCLK_VOP_PLL_SEL_MASK |
DCLK_VOP_SEL_SHIFT,
(src_clk_div << DCLK_VOP_CLK_DIV_SHIFT) |
(DCLK_VOP_PLL_SEL_GPLL << DCLK_VOP_PLL_SEL_SHIFT) |
(DCLK_VOP_SEL_PLL << DCLK_VOP_SEL_SHIFT));
- return rv1108_dclk_vop_get_clk(cru);
+}
+static ulong rv1108_aclk_bus_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[2]);
- div = bitfield_extract(val, ACLK_BUS_DIV_CON_SHIFT,
ACLK_BUS_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_aclk_bus_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[2],
ACLK_BUS_DIV_CON_MASK | ACLK_BUS_PLL_SEL_MASK,
(src_clk_div << ACLK_BUS_DIV_CON_SHIFT) |
(ACLK_BUS_PLL_SEL_GPLL << ACLK_BUS_PLL_SEL_SHIFT));
- return rv1108_aclk_bus_get_clk(cru);
+}
+static ulong rv1108_aclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, ACLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_hclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, HCLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_pclk_peri_get_clk(struct rv1108_cru *cru) +{
- u32 div, val;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- val = readl(&cru->clksel_con[23]);
- div = bitfield_extract(val, PCLK_PERI_DIV_CON_SHIFT,
PERI_DIV_CON_WIDTH);
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_aclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
ACLK_PERI_DIV_CON_MASK | ACLK_PERI_PLL_SEL_MASK,
(src_clk_div << ACLK_PERI_DIV_CON_SHIFT) |
(ACLK_PERI_PLL_SEL_GPLL << ACLK_PERI_PLL_SEL_SHIFT));
- return rv1108_aclk_peri_get_clk(cru);
+}
+static ulong rv1108_hclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
HCLK_PERI_DIV_CON_MASK,
(src_clk_div << HCLK_PERI_DIV_CON_SHIFT));
- return rv1108_hclk_peri_get_clk(cru);
+}
+static ulong rv1108_pclk_peri_set_clk(struct rv1108_cru *cru, uint hz) +{
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, hz) - 1;
- assert(src_clk_div < 32);
- rk_clrsetreg(&cru->clksel_con[23],
PCLK_PERI_DIV_CON_MASK,
(src_clk_div << PCLK_PERI_DIV_CON_SHIFT));
- return rv1108_pclk_peri_get_clk(cru);
+}
+static ulong rv1108_i2c_get_clk(struct rv1108_cru *cru, ulong clk_id) +{
- u32 div, con;
- switch (clk_id) {
- case SCLK_I2C0_PMU:
- con = readl(&cru->clksel_con[19]);
- div = bitfield_extract(con, CLK_I2C0_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
- break;
- case SCLK_I2C1:
- con = readl(&cru->clksel_con[19]);
- div = bitfield_extract(con, CLK_I2C1_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
- break;
- case SCLK_I2C2:
- con = readl(&cru->clksel_con[20]);
- div = bitfield_extract(con, CLK_I2C2_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
- break;
- case SCLK_I2C3:
- con = readl(&cru->clksel_con[20]);
- div = bitfield_extract(con, CLK_I2C3_DIV_CON_SHIFT,
I2C_DIV_CON_WIDTH);
- break;
- default:
- printf("do not support this i2c bus\n");
- return -EINVAL;
- }
- return DIV_TO_RATE(GPLL_HZ, div);
+}
+static ulong rv1108_i2c_set_clk(struct rv1108_cru *cru, ulong clk_id, uint hz) +{
- int src_clk_div;
- /* i2c0,4,8 src clock from ppll, i2c1,2,3,5,6,7 src clock from gpll*/
- src_clk_div = GPLL_HZ / hz;
- assert(src_clk_div - 1 <= 127);
- switch (clk_id) {
- case SCLK_I2C0_PMU:
- rk_clrsetreg(&cru->clksel_con[19],
CLK_I2C0_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
(src_clk_div << CLK_I2C0_DIV_CON_SHIFT) |
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
- break;
- case SCLK_I2C1:
- rk_clrsetreg(&cru->clksel_con[19],
CLK_I2C1_DIV_CON_MASK | CLK_I2C1_PLL_SEL_MASK,
(src_clk_div << CLK_I2C1_DIV_CON_SHIFT) |
(CLK_I2C1_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT));
- break;
- case SCLK_I2C2:
- rk_clrsetreg(&cru->clksel_con[20],
CLK_I2C2_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
(src_clk_div << CLK_I2C2_DIV_CON_SHIFT) |
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
- break;
- case SCLK_I2C3:
- rk_clrsetreg(&cru->clksel_con[20],
CLK_I2C3_DIV_CON_MASK | CLK_I2C3_PLL_SEL_MASK,
(src_clk_div << CLK_I2C3_DIV_CON_SHIFT) |
(CLK_I2C3_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT));
- break;
- default:
- printf("do not support this i2c bus\n");
- return -EINVAL;
- }
- return rv1108_i2c_get_clk(cru, clk_id);
+}
+static ulong rv1108_mmc_get_clk(struct clk *clk) +{
- struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
- struct rv1108_cru *cru = priv->cru;
- u32 div, con;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- con = readl(&cru->clksel_con[26]);
- div = (con & EMMC_CLK_DIV_MASK) >> EMMC_CLK_DIV_SHIFT;
- debug("%s id %ld get_clk %ld\n", __func__, clk->id, DIV_TO_RATE(parent_rate, div));
- return DIV_TO_RATE(parent_rate, div);
+}
+static ulong rv1108_mmc_set_clk(struct clk *clk, ulong set_rate) +{
- struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
- struct rv1108_cru *cru = priv->cru;
- int src_clk_div;
- ulong parent_rate = rkclk_pll_get_rate(cru, CLK_GENERAL);
- src_clk_div = DIV_ROUND_UP(parent_rate, set_rate);
- if (src_clk_div > 127) {
- src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
- }
- debug("%s id %ld src_clk_div %d\n", __func__, clk->id, src_clk_div);
- rk_clrsetreg(&cru->clksel_con[26],
EMMC_CLK_DIV_MASK , (src_clk_div -1) << EMMC_CLK_DIV_SHIFT);
- rk_clrsetreg(&cru->clksel_con[25],
EMMC_PLL_SEL_MASK , EMMC_PLL_SEL_GPLL << EMMC_PLL_SEL_SHIFT);
- return rv1108_mmc_get_clk(clk);
+}
- static ulong rv1108_clk_get_rate(struct clk *clk) { struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
@@ -163,6 +534,31 @@ static ulong rv1108_clk_get_rate(struct clk *clk) return rkclk_pll_get_rate(priv->cru, clk->id); case SCLK_SARADC: return rv1108_saradc_get_clk(priv->cru);
- case ACLK_VIO0:
- return rv1108_aclk_vio0_get_clk(priv->cru);
- case ACLK_VIO1:
- return rv1108_aclk_vio1_get_clk(priv->cru);
- case DCLK_VOP:
- return rv1108_dclk_vop_get_clk(priv->cru);
- case ACLK_PRE:
- return rv1108_aclk_bus_get_clk(priv->cru);
- case ACLK_PERI:
- return rv1108_aclk_peri_get_clk(priv->cru);
- case HCLK_PERI:
- return rv1108_hclk_peri_get_clk(priv->cru);
- case PCLK_PERI:
- return rv1108_pclk_peri_get_clk(priv->cru);
- case SCLK_I2C0_PMU:
- case SCLK_I2C1:
- case SCLK_I2C2:
- case SCLK_I2C3:
- return rv1108_i2c_get_clk(priv->cru, clk->id);
- case HCLK_SDMMC:
- case HCLK_EMMC:
- case SCLK_SDMMC:
- case SCLK_EMMC:
- case SCLK_EMMC_SAMPLE:
- return rv1108_mmc_get_clk(clk); default: return -ENOENT; }
@@ -183,6 +579,39 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate) case SCLK_SARADC: new_rate = rv1108_saradc_set_clk(priv->cru, rate); break;
- case ACLK_VIO0:
- new_rate = rv1108_aclk_vio0_set_clk(priv->cru, rate);
- break;
- case ACLK_VIO1:
- new_rate = rv1108_aclk_vio1_set_clk(priv->cru, rate);
- break;
- case DCLK_VOP:
- new_rate = rv1108_dclk_vop_set_clk(priv->cru, rate);
- break;
- case ACLK_PRE:
- new_rate = rv1108_aclk_bus_set_clk(priv->cru, rate);
- break;
- case ACLK_PERI:
- new_rate = rv1108_aclk_peri_set_clk(priv->cru, rate);
- break;
- case HCLK_PERI:
- new_rate = rv1108_hclk_peri_set_clk(priv->cru, rate);
- break;
- case PCLK_PERI:
- new_rate = rv1108_pclk_peri_set_clk(priv->cru, rate);
- break;
- case SCLK_I2C0_PMU:
- case SCLK_I2C1:
- case SCLK_I2C2:
- case SCLK_I2C3:
- new_rate = rv1108_i2c_set_clk(priv->cru, clk->id, rate);
- break;
- case HCLK_SDMMC:
- case HCLK_EMMC:
- case SCLK_SDMMC:
- case SCLK_EMMC:
- new_rate = rv1108_mmc_set_clk(clk, rate);
- break; default: return -ENOENT; }
@@ -197,14 +626,34 @@ static const struct clk_ops rv1108_clk_ops = {
static void rkclk_init(struct rv1108_cru *cru) {
- unsigned int apll = rkclk_pll_get_rate(cru, CLK_ARM);
- unsigned int dpll = rkclk_pll_get_rate(cru, CLK_DDR);
- unsigned int gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
unsigned int apll, dpll, gpll;
unsigned int aclk_bus, aclk_peri, hclk_peri, pclk_peri;
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ / 2);
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ / 2);
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ / 2);
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ / 2);
rv1108_aclk_vio0_set_clk(cru, 297000000);
rv1108_aclk_vio1_set_clk(cru, 297000000);
/* configure apll */
rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
aclk_bus = rv1108_aclk_bus_set_clk(cru, ACLK_BUS_HZ);
aclk_peri = rv1108_aclk_peri_set_clk(cru, ACLK_PERI_HZ);
hclk_peri = rv1108_hclk_peri_set_clk(cru, HCLK_PERI_HZ);
pclk_peri = rv1108_pclk_peri_set_clk(cru, PCLK_PERI_HZ);
apll = rkclk_pll_get_rate(cru, CLK_ARM);
dpll = rkclk_pll_get_rate(cru, CLK_DDR);
gpll = rkclk_pll_get_rate(cru, CLK_GENERAL);
rk_clrsetreg(&cru->clksel_con[0], CORE_CLK_DIV_MASK, 0 << MAC_CLK_DIV_SHIFT);
printf("APLL: %d DPLL:%d GPLL:%d\n", apll, dpll, gpll);
printf("ACLK_BUS: %d ACLK_PERI:%d HCLK_PERI:%d PCLK_PERI:%d\n",
aclk_bus, aclk_peri, hclk_peri, pclk_peri);
}
static int rv1108_clk_ofdata_to_platdata(struct udevice *dev)
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h index 9219a50a24..04e0a59f4b 100644 --- a/include/dt-bindings/clock/rv1108-cru.h +++ b/include/dt-bindings/clock/rv1108-cru.h @@ -14,7 +14,6 @@ #define ARMCLK 3
/* sclk gates (special clocks) */ -#define SCLK_MAC 64 #define SCLK_SPI0 65 #define SCLK_NANDC 67 #define SCLK_SDMMC 68 @@ -35,20 +34,77 @@ #define SCLK_SDMMC_SAMPLE 84 #define SCLK_SDIO_SAMPLE 85 #define SCLK_EMMC_SAMPLE 86 -#define SCLK_MAC_RX 87 -#define SCLK_MAC_TX 88 -#define SCLK_MACREF 89 -#define SCLK_MACREF_OUT 90 -#define SCLK_SARADC 91 +#define SCLK_VENC_CORE 87 +#define SCLK_HEVC_CORE 88 +#define SCLK_HEVC_CABAC 89 +#define SCLK_PWM0_PMU 90 +#define SCLK_I2C0_PMU 91 +#define SCLK_WIFI 92 +#define SCLK_CIFOUT 93 +#define SCLK_MIPI_CSI_OUT 94 +#define SCLK_CIF0 95 +#define SCLK_CIF1 96 +#define SCLK_CIF2 97 +#define SCLK_CIF3 98 +#define SCLK_DSP 99 +#define SCLK_DSP_IOP 100 +#define SCLK_DSP_EPP 101 +#define SCLK_DSP_EDP 102 +#define SCLK_DSP_EDAP 103 +#define SCLK_CVBS_HOST 104 +#define SCLK_HDMI_SFR 105 +#define SCLK_HDMI_CEC 106 +#define SCLK_CRYPTO 107 +#define SCLK_SPI 108 +#define SCLK_SARADC 109 +#define SCLK_TSADC 110 +#define SCLK_MAC_PRE 111 +#define SCLK_MAC 112 +#define SCLK_MAC_RX 113 +#define SCLK_MAC_REF 114 +#define SCLK_MAC_REFOUT 115 +#define SCLK_DSP_PFM 116 +#define SCLK_RGA 117 +#define SCLK_I2C1 118 +#define SCLK_I2C2 119 +#define SCLK_I2C3 120 +#define SCLK_PWM 121 +#define SCLK_ISP 122 +#define SCLK_USBPHY 123 +#define SCLK_I2S0_SRC 124 +#define SCLK_I2S1_SRC 125 +#define SCLK_I2S2_SRC 126 +#define SCLK_UART0_SRC 127 +#define SCLK_UART1_SRC 128 +#define SCLK_UART2_SRC 129 +#define SCLK_MAC_TX 130 +#define SCLK_MACREF 131 +#define SCLK_MACREF_OUT 132
+#define DCLK_VOP_SRC 185 +#define DCLK_HDMIPHY 186 +#define DCLK_VOP 187
/* aclk gates */ #define ACLK_DMAC 192 #define ACLK_PRE 193 #define ACLK_CORE 194 #define ACLK_ENMCORE 195 -#define ACLK_GMAC 196
+#define ACLK_RKVENC 196 +#define ACLK_RKVDEC 197 +#define ACLK_VPU 198 +#define ACLK_CIF0 199 +#define ACLK_VIO0 200 +#define ACLK_VIO1 201 +#define ACLK_VOP 202 +#define ACLK_IEP 203 +#define ACLK_RGA 204 +#define ACLK_ISP 205 +#define ACLK_CIF1 206 +#define ACLK_CIF2 207 +#define ACLK_CIF3 208 +#define ACLK_PERI 209 +#define ACLK_GMAC 210
/* pclk gates */ #define PCLK_GPIO1 256 @@ -67,12 +123,24 @@ #define PCLK_PWM 269 #define PCLK_TIMER 270 #define PCLK_PERI 271 -#define PCLK_GMAC 272 -#define PCLK_SARADC 273 +#define PCLK_GPIO0_PMU 272 +#define PCLK_I2C0_PMU 273 +#define PCLK_PWM0_PMU 274 +#define PCLK_ISP 275 +#define PCLK_VIO 276 +#define PCLK_MIPI_DSI 277 +#define PCLK_HDMI_CTRL 278 +#define PCLK_SARADC 279 +#define PCLK_DSP_CFG 280 +#define PCLK_BUS 281 +#define PCLK_EFUSE0 282 +#define PCLK_EFUSE1 283 +#define PCLK_WDT 284 +#define PCLK_GMAC 285
/* hclk gates */ #define HCLK_I2S0_8CH 320 -#define HCLK_I2S1_8CH 321 +#define HCLK_I2S1_2CH 321 #define HCLK_I2S2_2CH 322 #define HCLK_NANDC 323 #define HCLK_SDMMC 324 @@ -80,20 +148,37 @@ #define HCLK_EMMC 326 #define HCLK_PERI 327 #define HCLK_SFC 328 +#define HCLK_RKVENC 329 +#define HCLK_RKVDEC 330 +#define HCLK_CIF0 331 +#define HCLK_VIO 332 +#define HCLK_VOP 333 +#define HCLK_IEP 334 +#define HCLK_RGA 335 +#define HCLK_ISP 336 +#define HCLK_CRYPTO_MST 337 +#define HCLK_CRYPTO_SLV 338 +#define HCLK_HOST0 339 +#define HCLK_OTG 340 +#define HCLK_CIF1 341 +#define HCLK_CIF2 342 +#define HCLK_CIF3 343 +#define HCLK_BUS 344 +#define HCLK_VPU 345
-#define CLK_NR_CLKS (HCLK_SFC + 1) +#define CLK_NR_CLKS (HCLK_VPU + 1)
/* reset id */ -#define SRST_CORE_PO_AD 0 +#define SRST_CORE_PO_AD 0 #define SRST_CORE_AD 1 #define SRST_L2_AD 2 -#define SRST_CPU_NIU_AD 3 +#define SRST_CPU_NIU_AD 3 #define SRST_CORE_PO 4 #define SRST_CORE 5 -#define SRST_L2 6 +#define SRST_L2 6 #define SRST_CORE_DBG 8 #define PRST_DBG 9 -#define RST_DAP 10 +#define RST_DAP 10 #define PRST_DBG_NIU 11 #define ARST_STRC_SYS_AD 15
@@ -160,9 +245,9 @@ #define HRST_SYSBUS 75 #define PRST_USBGRF 76
-#define ARST_PERIPH_NIU 80 -#define HRST_PERIPH_NIU 81 -#define PRST_PERIPH_NIU 82 +#define ARST_PERIPH_NIU 80 +#define HRST_PERIPH_NIU 81 +#define PRST_PERIPH_NIU 82 #define HRST_PERIPH 83 #define HRST_SDMMC 84 #define HRST_SDIO 85 @@ -180,28 +265,11 @@ #define HRST_HOST0_AUX 96 #define HRST_HOST0_ARB 97 #define SRST_HOST0_EHCIPHY 98 -#define SRST_HOST0_UTMI 99 +#define SRST_HOST0_UTMI 99 #define SRST_USBPOR 100 #define SRST_UTMI0 101 #define SRST_UTMI1 102
-#define ARST_VIO0_NIU 102 -#define ARST_VIO1_NIU 103 -#define HRST_VIO_NIU 104 -#define PRST_VIO_NIU 105 -#define ARST_VOP 106 -#define HRST_VOP 107 -#define DRST_VOP 108 -#define ARST_IEP 109 -#define HRST_IEP 110 -#define ARST_RGA 111 -#define HRST_RGA 112 -#define SRST_RGA 113 -#define PRST_CVBS 114 -#define PRST_HDMI 115 -#define SRST_HDMI 116 -#define PRST_MIPI_DSI 117
Why these display devices removed?
- #define ARST_ISP_NIU 118 #define HRST_ISP_NIU 119 #define HRST_ISP 120
@@ -227,21 +295,21 @@ #define HRST_VPU_NIU 141 #define ARST_VPU 142 #define HRST_VPU 143 -#define ARST_RKVDEC_NIU 144 -#define HRST_RKVDEC_NIU 145 +#define ARST_RKVDEC_NIU 144 +#define HRST_RKVDEC_NIU 145 #define ARST_RKVDEC 146 #define HRST_RKVDEC 147 #define SRST_RKVDEC_CABAC 148 #define SRST_RKVDEC_CORE 149 -#define ARST_RKVENC_NIU 150 -#define HRST_RKVENC_NIU 151 +#define ARST_RKVENC_NIU 150 +#define HRST_RKVENC_NIU 151 #define ARST_RKVENC 152 #define HRST_RKVENC 153 #define SRST_RKVENC_CORE 154
#define SRST_DSP_CORE 156 #define SRST_DSP_SYS 157 -#define SRST_DSP_GLOBAL 158 +#define SRST_DSP_GLOBAL 158 #define SRST_DSP_OECM 159 #define PRST_DSP_IOP_NIU 160 #define ARST_DSP_EPP_NIU 161 @@ -259,7 +327,7 @@ #define SRST_PMU_I2C0 173 #define PRST_PMU_I2C0 174 #define PRST_PMU_GPIO0 175 -#define PRST_PMU_INTMEM 176 +#define PRST_PMU_INTMEM 176 #define PRST_PMU_PWM0 177 #define SRST_PMU_PWM0 178 #define PRST_PMU_GRF 179

Hello Vicent,
On Fri, Nov 30, 2018 at 1:39 AM vicent.chi@rock-chips.com vicent.chi@rock-chips.com wrote:
Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you.
The patch you quote below does not match with the files you attached it seems. Would you mind send me the patch?

Hello Vicent,
On Fri, Nov 30, 2018 at 7:58 AM Otavio Salvador otavio@ossystems.com.br wrote:
On Fri, Nov 30, 2018 at 1:39 AM vicent.chi@rock-chips.com vicent.chi@rock-chips.com wrote:
Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you.
The patch you quote below does not match with the files you attached it seems. Would you mind send me the patch?
I succeed in applying it here. I will run it on a few boards before sending the new patch revision. Thanks again for your support on this.

Otavio,
On 30.11.2018, at 11:37, Otavio Salvador otavio.salvador@ossystems.com.br wrote:
Hello Vicent,
On Fri, Nov 30, 2018 at 7:58 AM Otavio Salvador otavio@ossystems.com.br wrote:
On Fri, Nov 30, 2018 at 1:39 AM vicent.chi@rock-chips.com vicent.chi@rock-chips.com wrote:
Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you.
The patch you quote below does not match with the files you attached it seems. Would you mind send me the patch?
I succeed in applying it here. I will run it on a few boards before sending the new patch revision. Thanks again for your support on this.
I’ll wait for v3 before doing anything further with the series then. I had this queued for a PR this weekend (as the end of the merge-window is getting close), but can pick this also next week (I really need to get this in quickly after rc1 or it will slip to the next merge-window).
Thanks, Philipp.

On Fri, Nov 30, 2018 at 9:18 AM Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
On 30.11.2018, at 11:37, Otavio Salvador otavio.salvador@ossystems.com.br wrote: On Fri, Nov 30, 2018 at 7:58 AM Otavio Salvador otavio@ossystems.com.br wrote:
On Fri, Nov 30, 2018 at 1:39 AM vicent.chi@rock-chips.com vicent.chi@rock-chips.com wrote:
Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you.
The patch you quote below does not match with the files you attached it seems. Would you mind send me the patch?
I succeed in applying it here. I will run it on a few boards before sending the new patch revision. Thanks again for your support on this.
I’ll wait for v3 before doing anything further with the series then. I had this queued for a PR this weekend (as the end of the merge-window is getting close), but can pick this also next week (I really need to get this in quickly after rc1 or it will slip to the next merge-window).
Sure, I will be sending this and also our customer board (on top of this) later today or tomorrow.

On 30.11.2018, at 12:24, Otavio Salvador otavio.salvador@ossystems.com.br wrote:
On Fri, Nov 30, 2018 at 9:18 AM Philipp Tomsich philipp.tomsich@theobroma-systems.com wrote:
On 30.11.2018, at 11:37, Otavio Salvador otavio.salvador@ossystems.com.br wrote: On Fri, Nov 30, 2018 at 7:58 AM Otavio Salvador otavio@ossystems.com.br wrote:
On Fri, Nov 30, 2018 at 1:39 AM vicent.chi@rock-chips.com vicent.chi@rock-chips.com wrote:
Hi Otavio Salvador: Fixed a problem of rv1108 emmc clock configuration. I am afraid that the code between us is not synchronized, so I also send the modified files to you.
The patch you quote below does not match with the files you attached it seems. Would you mind send me the patch?
I succeed in applying it here. I will run it on a few boards before sending the new patch revision. Thanks again for your support on this.
I’ll wait for v3 before doing anything further with the series then. I had this queued for a PR this weekend (as the end of the merge-window is getting close), but can pick this also next week (I really need to get this in quickly after rc1 or it will slip to the next merge-window).
Sure, I will be sending this and also our customer board (on top of this) later today or tomorrow.
I’ll try to hold off with my PR until then, so Tom can pick all changes in a single go.
Thanks, Philipp.

In order to be able to build the Rockchip eMMC driver on rv1108, the BOUNCE_BUFFER option needs to be selected. Select it like it is done on the other Rockchip SoC common files.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br ---
Changes in v2: - new patch
include/configs/rv1108_common.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h index 2ab3b85e0c..cc0384e2f4 100644 --- a/include/configs/rv1108_common.h +++ b/include/configs/rv1108_common.h @@ -17,6 +17,9 @@ #define CONFIG_SYS_TIMER_BASE 0x10350020 #define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
+/* MMC/SD IP block */ +#define CONFIG_BOUNCE_BUFFER + #define CONFIG_SYS_SDRAM_BASE 0x60000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x100000) #define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x2000000)

Hi
On 2018/11/21 上午2:55, Otavio Salvador wrote:
In order to be able to build the Rockchip eMMC driver on rv1108, the BOUNCE_BUFFER option needs to be selected. Select it like it is done on the other Rockchip SoC common files.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2:
new patch
include/configs/rv1108_common.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h index 2ab3b85e0c..cc0384e2f4 100644 --- a/include/configs/rv1108_common.h +++ b/include/configs/rv1108_common.h @@ -17,6 +17,9 @@ #define CONFIG_SYS_TIMER_BASE 0x10350020 #define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
+/* MMC/SD IP block */ +#define CONFIG_BOUNCE_BUFFER
- #define CONFIG_SYS_SDRAM_BASE 0x60000000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x100000) #define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x2000000)
Reviewed-by: Andy Yan andy.yan@rock-chips.com

This adds the pinctrl handles to enable the use of eMMC on custom boards (as minievk) and makes it easier for later addition.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br ---
Changes in v2: - split bounce buffer change on a new patch
arch/arm/dts/rv1108.dtsi | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi index acfd97e18d..23a44bfaca 100644 --- a/arch/arm/dts/rv1108.dtsi +++ b/arch/arm/dts/rv1108.dtsi @@ -427,6 +427,35 @@ }; };
+ emmc { + emmc_clk: emmc-clk { + rockchip,pins = <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none_drv_8ma>; + }; + + emmc_cmd: emmc-cmd { + rockchip,pins = <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>; + }; + + emmc_pwren: emmc-pwren { + rockchip,pins = <2 RK_PC2 RK_FUNC_2 &pcfg_pull_none>; + }; + + emmc_bus1: emmc-bus1 { + rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>; + }; + + emmc_bus8: emmc-bus8 { + rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA1 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA2 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA3 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA5 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA6 RK_FUNC_2 &pcfg_pull_up_drv_8ma>, + <2 RK_PA7 RK_FUNC_2 &pcfg_pull_up_drv_8ma>; + }; + }; + sdmmc { sdmmc_clk: sdmmc-clk { rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;

On Tue, Nov 20, 2018 at 4:56 PM Otavio Salvador otavio@ossystems.com.br wrote:
This adds the pinctrl handles to enable the use of eMMC on custom boards (as minievk) and makes it easier for later addition.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Andy, did you review it? Is there someone which would be more appropriate for me to send the patches?

Hi:
On 2018/11/27 上午12:18, Otavio Salvador wrote:
On Tue, Nov 20, 2018 at 4:56 PM Otavio Salvador otavio@ossystems.com.br wrote:
This adds the pinctrl handles to enable the use of eMMC on custom boards (as minievk) and makes it easier for later addition.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Andy, did you review it? Is there someone which would be more appropriate for me to send the patches?
Thte whole series will to through Dr. Philipp Tomsich

On 27.11.2018, at 02:56, Andy Yan andy.yan@rock-chips.com wrote:
Hi:
On 2018/11/27 上午12:18, Otavio Salvador wrote:
On Tue, Nov 20, 2018 at 4:56 PM Otavio Salvador otavio@ossystems.com.br wrote:
This adds the pinctrl handles to enable the use of eMMC on custom boards (as minievk) and makes it easier for later addition.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Andy, did you review it? Is there someone which would be more appropriate for me to send the patches?
Thte whole series will to through Dr. Philipp Tomsich
And I’ve been reading the reviews as you sent them out. Thanks for helping out on reviewing these… as I don’t have the RV1108 documentation I rely on others to provide feedback.
Cheers, Philipp.

Hi:
The subject should be something like: "Arm: dts: rockchip: add emmc pinctrl for rv1108"
On 2018/11/21 上午2:55, Otavio Salvador wrote:
This adds the pinctrl handles to enable the use of eMMC on custom boards (as minievk) and makes it easier for later addition.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2:
split bounce buffer change on a new patch
arch/arm/dts/rv1108.dtsi | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi index acfd97e18d..23a44bfaca 100644 --- a/arch/arm/dts/rv1108.dtsi +++ b/arch/arm/dts/rv1108.dtsi @@ -427,6 +427,35 @@ }; };
emmc {
emmc_clk: emmc-clk {
rockchip,pins = <2 RK_PB6 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
};
emmc_cmd: emmc-cmd {
rockchip,pins = <2 RK_PB4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
};
emmc_pwren: emmc-pwren {
rockchip,pins = <2 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
};
emmc_bus1: emmc-bus1 {
rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
};
emmc_bus8: emmc-bus8 {
rockchip,pins = <2 RK_PA0 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA1 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA2 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA3 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA4 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA5 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA6 RK_FUNC_2 &pcfg_pull_up_drv_8ma>,
<2 RK_PA7 RK_FUNC_2 &pcfg_pull_up_drv_8ma>;
};
};
- sdmmc { sdmmc_clk: sdmmc-clk { rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>;

On Mon, Nov 26, 2018 at 11:51 PM Andy Yan andy.yan@rock-chips.com wrote:
The subject should be something like: "Arm: dts: rockchip: add emmc pinctrl for rv1108"
Thanks, I am preparing a v3 and will send it soon.

Like it is done for other Rockchip SoCs, introduce a board_usb_init() function so that USB OTG can be functional on rv1108 too.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br ---
Changes in v2: None
arch/arm/dts/rv1108.dtsi | 45 ++++++++++++++- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/rv1108-board.c | 81 +++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-rockchip/rv1108-board.c
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi index 23a44bfaca..215d885225 100644 --- a/arch/arm/dts/rv1108.dtsi +++ b/arch/arm/dts/rv1108.dtsi @@ -121,8 +121,35 @@ };
grf: syscon@10300000 { - compatible = "rockchip,rv1108-grf", "syscon"; + compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd"; reg = <0x10300000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy: usb2-phy@100 { + compatible = "rockchip,rv1108-usb2phy"; + reg = <0x100 0x0c>; + clocks = <&cru SCLK_USBPHY>; + clock-names = "phyclk"; + #clock-cells = <0>; + clock-output-names = "usbphy"; + rockchip,usbgrf = <&usbgrf>; + status = "disabled"; + + u2phy_otg: otg-port { + interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "otg-mux"; + #phy-cells = <0>; + status = "disabled"; + }; + + u2phy_host: host-port { + interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + }; };
saradc: saradc@1038c000 { @@ -141,6 +168,11 @@ reg = <0x20060000 0x1000>; };
+ usbgrf: syscon@202a0000 { + compatible = "rockchip,rv1108-usbgrf", "syscon"; + reg = <0x202a0000 0x1000>; + }; + cru: clock-controller@20200000 { compatible = "rockchip,rv1108-cru"; reg = <0x20200000 0x1000>; @@ -200,12 +232,19 @@ };
usb20_otg: usb@30180000 { - compatible = "rockchip,rv1108-usb", "rockchip,rk3288-usb", + compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x30180000 0x40000>; interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; - hnp-srp-disable; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; status = "disabled"; };
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 05706c472a..368302e1da 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o +obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108-board.o endif
obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o diff --git a/arch/arm/mach-rockchip/rv1108-board.c b/arch/arm/mach-rockchip/rv1108-board.c new file mode 100644 index 0000000000..3412f2c063 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1108-board.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2015 Google, Inc + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +#include <usb.h> +#include <usb/dwc2_udc.h> + +static struct dwc2_plat_otg_data rv1108_otg_data = { + .rx_fifo_sz = 512, + .np_tx_fifo_sz = 16, + .tx_fifo_sz = 128, +}; + +int board_usb_init(int index, enum usb_init_type init) +{ + const void *blob = gd->fdt_blob; + bool matched = false; + int node, phy_node; + u32 grf_phy_offset; + const char *mode; + + /* find the usb_otg node */ + node = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3066-usb"); + while (node > 0) { + mode = fdt_getprop(blob, node, "dr_mode", NULL); + if (mode && strcmp(mode, "otg") == 0) { + matched = true; + break; + } + + node = fdt_node_offset_by_compatible(blob, node, + "rockchip,rk3066-usb"); + } + + if (!matched) { + debug("usb_otg device not found\n"); + return -ENODEV; + } + + rv1108_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); + + node = fdtdec_lookup_phandle(blob, node, "phys"); + if (node <= 0) { + debug("phys node not found\n"); + return -ENODEV; + } + + phy_node = fdt_parent_offset(blob, node); + if (phy_node <= 0) { + debug("usb phy node not found\n"); + return -ENODEV; + } + + rv1108_otg_data.phy_of_node = phy_node; + grf_phy_offset = fdtdec_get_addr(blob, node, "reg"); + + /* find the grf node */ + node = fdt_node_offset_by_compatible(blob, -1, + "rockchip,rv1108-grf"); + if (node <= 0) { + debug("grf node not found\n"); + return -ENODEV; + } + + rv1108_otg_data.regs_phy = grf_phy_offset + fdtdec_get_addr(blob, node, + "reg"); + + return dwc2_udc_probe(&rv1108_otg_data); +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + return 0; +} +#endif

Hi:
On 2018/11/21 上午2:55, Otavio Salvador wrote:
Like it is done for other Rockchip SoCs, introduce a board_usb_init() function so that USB OTG can be functional on rv1108 too.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2: None
arch/arm/dts/rv1108.dtsi | 45 ++++++++++++++- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/rv1108-board.c | 81 +++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-rockchip/rv1108-board.c
It's better to split dtsi and .c file
diff --git a/arch/arm/dts/rv1108.dtsi b/arch/arm/dts/rv1108.dtsi index 23a44bfaca..215d885225 100644 --- a/arch/arm/dts/rv1108.dtsi +++ b/arch/arm/dts/rv1108.dtsi @@ -121,8 +121,35 @@ };
grf: syscon@10300000 {
compatible = "rockchip,rv1108-grf", "syscon";
compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd";
reg = <0x10300000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
u2phy: usb2-phy@100 {
compatible = "rockchip,rv1108-usb2phy";
reg = <0x100 0x0c>;
clocks = <&cru SCLK_USBPHY>;
clock-names = "phyclk";
#clock-cells = <0>;
clock-output-names = "usbphy";
rockchip,usbgrf = <&usbgrf>;
status = "disabled";
u2phy_otg: otg-port {
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "otg-mux";
#phy-cells = <0>;
status = "disabled";
};
u2phy_host: host-port {
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "linestate";
#phy-cells = <0>;
status = "disabled";
};
};
};
saradc: saradc@1038c000 {
@@ -141,6 +168,11 @@ reg = <0x20060000 0x1000>; };
- usbgrf: syscon@202a0000 {
compatible = "rockchip,rv1108-usbgrf", "syscon";
reg = <0x202a0000 0x1000>;
- };
- cru: clock-controller@20200000 { compatible = "rockchip,rv1108-cru"; reg = <0x20200000 0x1000>;
@@ -200,12 +232,19 @@ };
usb20_otg: usb@30180000 {
compatible = "rockchip,rv1108-usb", "rockchip,rk3288-usb",
reg = <0x30180000 0x40000>; interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb", "snps,dwc2";
hnp-srp-disable;
clocks = <&cru HCLK_OTG>;
dr_mode = "otg";clock-names = "otg";
g-np-tx-fifo-size = <16>;
g-rx-fifo-size = <280>;
g-tx-fifo-size = <256 128 128 64 32 16>;
g-use-dma;
phys = <&u2phy_otg>;
status = "disabled"; };phy-names = "usb2-phy";
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 05706c472a..368302e1da 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o +obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108-board.o endif
obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o diff --git a/arch/arm/mach-rockchip/rv1108-board.c b/arch/arm/mach-rockchip/rv1108-board.c new file mode 100644 index 0000000000..3412f2c063 --- /dev/null +++ b/arch/arm/mach-rockchip/rv1108-board.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2015 Google, Inc
- */
+#include <common.h>
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG) +#include <usb.h> +#include <usb/dwc2_udc.h>
+static struct dwc2_plat_otg_data rv1108_otg_data = {
- .rx_fifo_sz = 512,
- .np_tx_fifo_sz = 16,
- .tx_fifo_sz = 128,
+};
+int board_usb_init(int index, enum usb_init_type init) +{
- const void *blob = gd->fdt_blob;
- bool matched = false;
- int node, phy_node;
- u32 grf_phy_offset;
- const char *mode;
- /* find the usb_otg node */
- node = fdt_node_offset_by_compatible(blob, -1, "rockchip,rk3066-usb");
- while (node > 0) {
mode = fdt_getprop(blob, node, "dr_mode", NULL);
if (mode && strcmp(mode, "otg") == 0) {
matched = true;
break;
}
node = fdt_node_offset_by_compatible(blob, node,
"rockchip,rk3066-usb");
- }
- if (!matched) {
debug("usb_otg device not found\n");
return -ENODEV;
- }
- rv1108_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
- node = fdtdec_lookup_phandle(blob, node, "phys");
- if (node <= 0) {
debug("phys node not found\n");
return -ENODEV;
- }
- phy_node = fdt_parent_offset(blob, node);
- if (phy_node <= 0) {
debug("usb phy node not found\n");
return -ENODEV;
- }
- rv1108_otg_data.phy_of_node = phy_node;
- grf_phy_offset = fdtdec_get_addr(blob, node, "reg");
- /* find the grf node */
- node = fdt_node_offset_by_compatible(blob, -1,
"rockchip,rv1108-grf");
- if (node <= 0) {
debug("grf node not found\n");
return -ENODEV;
- }
- rv1108_otg_data.regs_phy = grf_phy_offset + fdtdec_get_addr(blob, node,
"reg");
- return dwc2_udc_probe(&rv1108_otg_data);
+}
+int board_usb_cleanup(int index, enum usb_init_type init) +{
- return 0;
+} +#endif

This allow easier integration of RV1108 based boards on generic distributions and build systems.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br ---
Changes in v2: None
include/configs/rv1108_common.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h index cc0384e2f4..16d4e2e355 100644 --- a/include/configs/rv1108_common.h +++ b/include/configs/rv1108_common.h @@ -28,3 +28,18 @@ #define CONFIG_USB_OHCI_NEW #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 #endif + +#ifndef CONFIG_SPL_BUILD +#define ENV_MEM_LAYOUT_SETTINGS \ + "scriptaddr=0x60000000\0" \ + "fdt_addr_r=0x61f00000\0" \ + "kernel_addr_r=0x62000000\0" \ + "ramdisk_addr_r=0x64000000\0" + +#include <config_distro_bootcmd.h> +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ + "partitions=" PARTS_DEFAULT \ + BOOTENV +#endif

Hi:
On 2018/11/21 上午2:55, Otavio Salvador wrote:
This allow easier integration of RV1108 based boards on generic distributions and build systems.
Signed-off-by: Otavio Salvador otavio@ossystems.com.br
Changes in v2: None
include/configs/rv1108_common.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/include/configs/rv1108_common.h b/include/configs/rv1108_common.h index cc0384e2f4..16d4e2e355 100644 --- a/include/configs/rv1108_common.h +++ b/include/configs/rv1108_common.h @@ -28,3 +28,18 @@ #define CONFIG_USB_OHCI_NEW #define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1 #endif
+#ifndef CONFIG_SPL_BUILD +#define ENV_MEM_LAYOUT_SETTINGS \
- "scriptaddr=0x60000000\0" \
- "fdt_addr_r=0x61f00000\0" \
- "kernel_addr_r=0x62000000\0" \
- "ramdisk_addr_r=0x64000000\0"
+#include <config_distro_bootcmd.h> +#define CONFIG_EXTRA_ENV_SETTINGS \
- ENV_MEM_LAYOUT_SETTINGS \
- "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
- "partitions=" PARTS_DEFAULT \
- BOOTENV
+#endif
Reviewed-by: Andy Yan andy.yan@rock-chips.com
participants (5)
-
Andy Yan
-
Otavio Salvador
-
Otavio Salvador
-
Philipp Tomsich
-
vicent.chi@rock-chips.com