diff options
-rw-r--r-- | drivers/clk/rockchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-ddr.c | 154 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-pll.c | 4 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3399.c | 56 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rockchip.c | 7 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.c | 11 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.h | 35 | ||||
-rw-r--r-- | include/dt-bindings/clock/rk3399-cru.h | 3 | ||||
-rw-r--r-- | include/soc/rockchip/rockchip_sip.h | 27 |
9 files changed, 278 insertions, 20 deletions
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index f47a2fa962d2..b5f2c8ed12e1 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -8,6 +8,7 @@ obj-y += clk-pll.o obj-y += clk-cpu.o obj-y += clk-inverter.o obj-y += clk-mmc-phase.o +obj-y += clk-ddr.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-y += clk-rk3036.o diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c new file mode 100644 index 000000000000..8feba93672c5 --- /dev/null +++ b/drivers/clk/rockchip/clk-ddr.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. + * Author: Lin Huang <hl@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/arm-smccc.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <soc/rockchip/rockchip_sip.h> +#include "clk.h" + +struct rockchip_ddrclk { + struct clk_hw hw; + void __iomem *reg_base; + int mux_offset; + int mux_shift; + int mux_width; + int div_shift; + int div_width; + int ddr_flag; + spinlock_t *lock; +}; + +#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw) + +static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); + unsigned long flags; + struct arm_smccc_res res; + + spin_lock_irqsave(ddrclk->lock, flags); + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0, + ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE, + 0, 0, 0, 0, &res); + spin_unlock_irqrestore(ddrclk->lock, flags); + + return res.a0; +} + +static unsigned long +rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct arm_smccc_res res; + + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, + ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE, + 0, 0, 0, 0, &res); + + return res.a0; +} + +static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct arm_smccc_res res; + + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0, + ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE, + 0, 0, 0, 0, &res); + + return res.a0; +} + +static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) +{ + struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); + int num_parents = clk_hw_get_num_parents(hw); + u32 val; + + val = clk_readl(ddrclk->reg_base + + ddrclk->mux_offset) >> ddrclk->mux_shift; + val &= GENMASK(ddrclk->mux_width - 1, 0); + + if (val >= num_parents) + return -EINVAL; + + return val; +} + +static const struct clk_ops rockchip_ddrclk_sip_ops = { + .recalc_rate = rockchip_ddrclk_sip_recalc_rate, + .set_rate = rockchip_ddrclk_sip_set_rate, + .round_rate = rockchip_ddrclk_sip_round_rate, + .get_parent = rockchip_ddrclk_get_parent, +}; + +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, + u8 num_parents, int mux_offset, + int mux_shift, int mux_width, + int div_shift, int div_width, + int ddr_flag, void __iomem *reg_base, + spinlock_t *lock) +{ + struct rockchip_ddrclk *ddrclk; + struct clk_init_data init; + struct clk *clk; + + ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL); + if (!ddrclk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.parent_names = parent_names; + init.num_parents = num_parents; + + init.flags = flags; + init.flags |= CLK_SET_RATE_NO_REPARENT; + + switch (ddr_flag) { + case ROCKCHIP_DDRCLK_SIP: + init.ops = &rockchip_ddrclk_sip_ops; + break; + default: + pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag); + kfree(ddrclk); + return ERR_PTR(-EINVAL); + } + + ddrclk->reg_base = reg_base; + ddrclk->lock = lock; + ddrclk->hw.init = &init; + ddrclk->mux_offset = mux_offset; + ddrclk->mux_shift = mux_shift; + ddrclk->mux_width = mux_width; + ddrclk->div_shift = div_shift; + ddrclk->div_width = div_width; + ddrclk->ddr_flag = ddr_flag; + + clk = clk_register(NULL, &ddrclk->hw); + if (IS_ERR(clk)) { + pr_err("%s: could not register ddrclk %s\n", __func__, name); + kfree(ddrclk); + return NULL; + } + + return clk; +} diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index db81e454166b..9c1373e81683 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -837,7 +837,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, u8 num_parents, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - u8 clk_pll_flags) + unsigned long flags, u8 clk_pll_flags) { const char *pll_parents[3]; struct clk_init_data init; @@ -892,7 +892,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, init.name = pll_name; /* keep all plls untouched for now */ - init.flags = CLK_IGNORE_UNUSED; + init.flags = flags | CLK_IGNORE_UNUSED; init.parent_names = &parent_names[0]; init.num_parents = 1; diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index cdfabeb9a034..8387c7a40bda 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -100,8 +100,10 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0), RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0), RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0), + RK3036_PLL_RATE( 106500000, 1, 71, 4, 4, 1, 0), RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0), RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0), + RK3036_PLL_RATE( 65000000, 1, 65, 6, 4, 1, 0), RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0), RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0), { /* sentinel */ }, @@ -118,6 +120,10 @@ PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src", "clk_core_b_bpll_src", "clk_core_b_dpll_src", "clk_core_b_gpll_src" }; +PNAME(mux_ddrclk_p) = { "clk_ddrc_lpll_src", + "clk_ddrc_bpll_src", + "clk_ddrc_dpll_src", + "clk_ddrc_gpll_src" }; PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", "gpll_aclk_cci_src", "npll_aclk_cci_src", @@ -373,6 +379,7 @@ static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = { RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11), RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10), RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10), + RK3399_CPUCLKB_RATE(2016000000, 1, 9, 9), RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9), RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9), RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8), @@ -578,7 +585,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 13, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0, RK3399_CLKSEL_CON(99), 0, RK3399_CLKGATE_CON(8), 14, GFLAGS, &rk3399_spdif_fracmux), @@ -592,7 +599,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 3, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0, RK3399_CLKSEL_CON(96), 0, RK3399_CLKGATE_CON(8), 4, GFLAGS, &rk3399_i2s0_fracmux), @@ -602,7 +609,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 6, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0, RK3399_CLKSEL_CON(97), 0, RK3399_CLKGATE_CON(8), 7, GFLAGS, &rk3399_i2s1_fracmux), @@ -612,7 +619,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0, RK3399_CLKSEL_CON(98), 0, RK3399_CLKGATE_CON(8), 10, GFLAGS, &rk3399_i2s2_fracmux), @@ -631,7 +638,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 0, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0, RK3399_CLKSEL_CON(100), 0, RK3399_CLKGATE_CON(9), 1, GFLAGS, &rk3399_uart0_fracmux), @@ -641,7 +648,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 2, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0, RK3399_CLKSEL_CON(101), 0, RK3399_CLKGATE_CON(9), 3, GFLAGS, &rk3399_uart1_fracmux), @@ -649,7 +656,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 4, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0, RK3399_CLKSEL_CON(102), 0, RK3399_CLKGATE_CON(9), 5, GFLAGS, &rk3399_uart2_fracmux), @@ -657,7 +664,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 6, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0, RK3399_CLKSEL_CON(103), 0, RK3399_CLKGATE_CON(9), 7, GFLAGS, &rk3399_uart3_fracmux), @@ -846,9 +853,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, RK3399_CLKGATE_CON(5), 4, GFLAGS), - GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, + GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", 0, RK3399_CLKGATE_CON(20), 2, GFLAGS), - GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, + GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", 0, RK3399_CLKGATE_CON(20), 10, GFLAGS), GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(20), 12, GFLAGS), @@ -1161,7 +1168,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, RK3399_CLKGATE_CON(10), 12, GFLAGS), - COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0, RK3399_CLKSEL_CON(106), 0, &rk3399_dclk_vop0_fracmux), @@ -1191,7 +1198,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS, RK3399_CLKGATE_CON(10), 13, GFLAGS), - COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(DCLK_VOP1_FRAC, "dclk_vop1_frac", "dclk_vop1_div", 0, RK3399_CLKSEL_CON(107), 0, &rk3399_dclk_vop1_fracmux), @@ -1305,7 +1312,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* testout */ MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), - COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, + COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", 0, RK3399_CLKSEL_CON(105), 0, RK3399_CLKGATE_CON(13), 9, GFLAGS), @@ -1377,6 +1384,18 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(58), 0, 5, DFLAGS, RK3368_CLKGATE_CON(13), 11, GFLAGS), + + /* ddrc */ + GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3), + 0, GFLAGS), + GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3), + 1, GFLAGS), + GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3), + 2, GFLAGS), + GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3), + 3, GFLAGS), + COMPOSITE_DDRCLK(SCLK_DDRC, "sclk_ddrc", mux_ddrclk_p, 0, + RK3399_CLKSEL_CON(6), 4, 2, 0, 0, ROCKCHIP_DDRCLK_SIP), }; static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { @@ -1398,7 +1417,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), - COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0, RK3399_PMU_CLKSEL_CON(7), 0, &rk3399_pmuclk_wifi_fracmux), @@ -1426,7 +1445,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS, RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0, RK3399_PMU_CLKSEL_CON(6), 0, RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, &rk3399_uart4_pmu_fracmux), @@ -1468,6 +1487,9 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { "aclk_cci_pre", "aclk_gic", "aclk_gic_noc", + "aclk_hdcp_noc", + "hclk_hdcp_noc", + "pclk_hdcp_noc", "pclk_perilp0", "pclk_perilp0", "hclk_perilp0", @@ -1488,6 +1510,10 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { "gpll_hclk_perilp1_src", "gpll_aclk_perilp0_src", "gpll_aclk_perihp_src", + "aclk_vio_noc", + + /* ddrc */ + "sclk_ddrc" }; static const char *const rk3399_pmucru_critical_clocks[] __initconst = { diff --git a/drivers/clk/rockchip/clk-rockchip.c b/drivers/clk/rockchip/clk-rockchip.c index 4cf838d52ef6..2c9bb81144c9 100644 --- a/drivers/clk/rockchip/clk-rockchip.c +++ b/drivers/clk/rockchip/clk-rockchip.c @@ -49,14 +49,19 @@ static void __init rk2928_gate_clk_init(struct device_node *node) } reg = of_iomap(node, 0); + if (!reg) + return; clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); - if (!clk_data) + if (!clk_data) { + iounmap(reg); return; + } clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) { kfree(clk_data); + iounmap(reg); return; } diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 7ffd134995f2..b886be30f34f 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -385,7 +385,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, list->mode_shift, list->rate_table, - list->pll_flags); + list->flags, list->pll_flags); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); @@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches( list->gate_offset, list->gate_shift, list->gate_flags, flags, &ctx->lock); break; + case branch_ddrclk: + clk = rockchip_clk_register_ddrclk( + list->name, list->flags, + list->parent_names, list->num_parents, + list->muxdiv_offset, list->mux_shift, + list->mux_width, list->div_shift, + list->div_width, list->div_flags, + ctx->reg_base, &ctx->lock); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 2194ffa8c9fd..1653edd792a5 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -238,7 +238,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, u8 num_parents, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - u8 clk_pll_flags); + unsigned long flags, u8 clk_pll_flags); struct rockchip_cpuclk_clksel { int reg; @@ -281,6 +281,20 @@ struct clk *rockchip_clk_register_mmc(const char *name, const char *const *parent_names, u8 num_parents, void __iomem *reg, int shift); +/* + * DDRCLK flags, including method of setting the rate + * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. + */ +#define ROCKCHIP_DDRCLK_SIP BIT(0) + +struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, + const char *const *parent_names, + u8 num_parents, int mux_offset, + int mux_shift, int mux_width, + int div_shift, int div_width, + int ddr_flags, void __iomem *reg_base, + spinlock_t *lock); + #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) struct clk *rockchip_clk_register_inverter(const char *name, @@ -299,6 +313,7 @@ enum rockchip_clk_branch_type { branch_mmc, branch_inverter, branch_factor, + branch_ddrclk, }; struct rockchip_clk_branch { @@ -488,6 +503,24 @@ struct rockchip_clk_branch { .child = ch, \ } +#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ + ds, dw, df) \ + { \ + .id = _id, \ + .branch_type = branch_ddrclk, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .muxdiv_offset = mo, \ + .mux_shift = ms, \ + .mux_width = mw, \ + .div_shift = ds, \ + .div_width = dw, \ + .div_flags = df, \ + .gate_offset = -1, \ + } + #define MUX(_id, cname, pnames, f, o, s, w, mf) \ { \ .id = _id, \ diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h index 50a44cffb070..220a60f20d3b 100644 --- a/include/dt-bindings/clock/rk3399-cru.h +++ b/include/dt-bindings/clock/rk3399-cru.h @@ -131,12 +131,15 @@ #define SCLK_DPHY_RX0_CFG 165 #define SCLK_RMII_SRC 166 #define SCLK_PCIEPHY_REF100M 167 +#define SCLK_DDRC 168 #define DCLK_VOP0 180 #define DCLK_VOP1 181 #define DCLK_VOP0_DIV 182 #define DCLK_VOP1_DIV 183 #define DCLK_M0_PERILP 184 +#define DCLK_VOP0_FRAC 185 +#define DCLK_VOP1_FRAC 186 #define FCLK_CM0S 190 diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h new file mode 100644 index 000000000000..7e28092c4d3d --- /dev/null +++ b/include/soc/rockchip/rockchip_sip.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd + * Author: Lin Huang <hl@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#ifndef __SOC_ROCKCHIP_SIP_H +#define __SOC_ROCKCHIP_SIP_H + +#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008 +#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00 +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01 +#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE 0x02 +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR 0x03 +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW 0x04 +#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05 +#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 +#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 + +#endif |