aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2018-03-14 18:38:48 -0400
committerStephen Boyd <sboyd@kernel.org>2018-03-14 18:38:48 -0400
commited0df3ce9e7591b91927879f5808d055d41dfcc8 (patch)
tree466579a6610cb0f25a0b836c27dad771367c36aa
parent7928b2cbe55b2a410a0f5c1f154610059c57b1b2 (diff)
parent4ee3fd4abeca30d530fe67972f1964f7454259d6 (diff)
Merge tag 'v4.17-rockchip-clk-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into clk-rockchip
Pull Rockchip clk driver updates from Heiko Stuebner: The rk3328 got the most love this time, preparing it for supplying actual display output in the future and actually protecting all necessary clocks. The rk3399 simply got a special 1.6GHz rate that is going to be needed for a board and the core code got a fix to actually free allocated memory in error case as well as making sure the clock-phases don't return bad values and stay the same on rate changes. * tag 'v4.17-rockchip-clk-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip: clk: rockchip: Add 1.6GHz PLL rate for rk3399 clk: rockchip: Restore the clock phase after the rate was changed clk: rockchip: Prevent calculating mmc phase if clock rate is zero clk: rockchip: Free the memory on the error path clk: rockchip: document hdmi_phy external input for rk3328 clk: rockchip: add flags for rk3328 dclk_lcdc clk: rockchip: remove ignore_unused flag from rk3328 vio_h2p clocks clk: rockchip: protect all remaining rk3328 interconnect clocks clk: rockchip: export sclk_hdmi_sfc on rk3328 clk: rockchip: remove HCLK_VIO from rk3328 dt header clk: rockchip: fix hclk_vio_niu on rk3328
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt1
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c62
-rw-r--r--drivers/clk/rockchip/clk-rk3328.c67
-rw-r--r--drivers/clk/rockchip/clk-rk3399.c1
-rw-r--r--drivers/clk/rockchip/clk.c22
-rw-r--r--include/dt-bindings/clock/rk3328-cru.h1
6 files changed, 124 insertions, 30 deletions
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
index e71c675ba5da..904ae682ea90 100644
--- a/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3328-cru.txt
@@ -32,6 +32,7 @@ clock-output-names:
32 - "clkin_i2s" - external I2S clock - optional, 32 - "clkin_i2s" - external I2S clock - optional,
33 - "gmac_clkin" - external GMAC clock - optional 33 - "gmac_clkin" - external GMAC clock - optional
34 - "phy_50m_out" - output clock of the pll in the mac phy 34 - "phy_50m_out" - output clock of the pll in the mac phy
35 - "hdmi_phy" - output clock of the hdmi phy pll - optional
35 36
36Example: Clock controller node: 37Example: Clock controller node:
37 38
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 077fcdc7908b..dc4c227732bd 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -25,6 +25,8 @@ struct rockchip_mmc_clock {
25 void __iomem *reg; 25 void __iomem *reg;
26 int id; 26 int id;
27 int shift; 27 int shift;
28 int cached_phase;
29 struct notifier_block clk_rate_change_nb;
28}; 30};
29 31
30#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw) 32#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw)
@@ -58,6 +60,12 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
58 u16 degrees; 60 u16 degrees;
59 u32 delay_num = 0; 61 u32 delay_num = 0;
60 62
63 /* See the comment for rockchip_mmc_set_phase below */
64 if (!rate) {
65 pr_err("%s: invalid clk rate\n", __func__);
66 return -EINVAL;
67 }
68
61 raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); 69 raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
62 70
63 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 71 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
@@ -84,6 +92,23 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
84 u32 raw_value; 92 u32 raw_value;
85 u32 delay; 93 u32 delay;
86 94
95 /*
96 * The below calculation is based on the output clock from
97 * MMC host to the card, which expects the phase clock inherits
98 * the clock rate from its parent, namely the output clock
99 * provider of MMC host. However, things may go wrong if
100 * (1) It is orphan.
101 * (2) It is assigned to the wrong parent.
102 *
103 * This check help debug the case (1), which seems to be the
104 * most likely problem we often face and which makes it difficult
105 * for people to debug unstable mmc tuning results.
106 */
107 if (!rate) {
108 pr_err("%s: invalid clk rate\n", __func__);
109 return -EINVAL;
110 }
111
87 nineties = degrees / 90; 112 nineties = degrees / 90;
88 remainder = (degrees % 90); 113 remainder = (degrees % 90);
89 114
@@ -139,6 +164,29 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
139 .set_phase = rockchip_mmc_set_phase, 164 .set_phase = rockchip_mmc_set_phase,
140}; 165};
141 166
167#define to_rockchip_mmc_clock(x) \
168 container_of(x, struct rockchip_mmc_clock, clk_rate_change_nb)
169static int rockchip_mmc_clk_rate_notify(struct notifier_block *nb,
170 unsigned long event, void *data)
171{
172 struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb);
173
174 /*
175 * rockchip_mmc_clk is mostly used by mmc controllers to sample
176 * the intput data, which expects the fixed phase after the tuning
177 * process. However if the clock rate is changed, the phase is stale
178 * and may break the data sampling. So here we try to restore the phase
179 * for that case.
180 */
181 if (event == PRE_RATE_CHANGE)
182 mmc_clock->cached_phase =
183 rockchip_mmc_get_phase(&mmc_clock->hw);
184 else if (event == POST_RATE_CHANGE)
185 rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase);
186
187 return NOTIFY_DONE;
188}
189
142struct clk *rockchip_clk_register_mmc(const char *name, 190struct clk *rockchip_clk_register_mmc(const char *name,
143 const char *const *parent_names, u8 num_parents, 191 const char *const *parent_names, u8 num_parents,
144 void __iomem *reg, int shift) 192 void __iomem *reg, int shift)
@@ -146,6 +194,7 @@ struct clk *rockchip_clk_register_mmc(const char *name,
146 struct clk_init_data init; 194 struct clk_init_data init;
147 struct rockchip_mmc_clock *mmc_clock; 195 struct rockchip_mmc_clock *mmc_clock;
148 struct clk *clk; 196 struct clk *clk;
197 int ret;
149 198
150 mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); 199 mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL);
151 if (!mmc_clock) 200 if (!mmc_clock)
@@ -163,7 +212,18 @@ struct clk *rockchip_clk_register_mmc(const char *name,
163 212
164 clk = clk_register(NULL, &mmc_clock->hw); 213 clk = clk_register(NULL, &mmc_clock->hw);
165 if (IS_ERR(clk)) 214 if (IS_ERR(clk))
166 kfree(mmc_clock); 215 goto err_register;
167 216
217 mmc_clock->clk_rate_change_nb.notifier_call =
218 &rockchip_mmc_clk_rate_notify;
219 ret = clk_notifier_register(clk, &mmc_clock->clk_rate_change_nb);
220 if (ret)
221 goto err_notifier;
222
223 return clk;
224err_notifier:
225 clk_unregister(clk);
226err_register:
227 kfree(mmc_clock);
168 return clk; 228 return clk;
169} 229}
diff --git a/drivers/clk/rockchip/clk-rk3328.c b/drivers/clk/rockchip/clk-rk3328.c
index b04f29774ee7..f680b421b6d5 100644
--- a/drivers/clk/rockchip/clk-rk3328.c
+++ b/drivers/clk/rockchip/clk-rk3328.c
@@ -304,7 +304,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
304 COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, 304 COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
305 RK3328_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 305 RK3328_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
306 RK3328_CLKGATE_CON(7), 1, GFLAGS), 306 RK3328_CLKGATE_CON(7), 1, GFLAGS),
307 GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED, 307 GATE(0, "aclk_core_niu", "aclk_core", 0,
308 RK3328_CLKGATE_CON(13), 0, GFLAGS), 308 RK3328_CLKGATE_CON(13), 0, GFLAGS),
309 GATE(0, "aclk_gic400", "aclk_core", CLK_IGNORE_UNUSED, 309 GATE(0, "aclk_gic400", "aclk_core", CLK_IGNORE_UNUSED,
310 RK3328_CLKGATE_CON(13), 1, GFLAGS), 310 RK3328_CLKGATE_CON(13), 1, GFLAGS),
@@ -318,7 +318,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
318 RK3328_CLKGATE_CON(6), 6, GFLAGS), 318 RK3328_CLKGATE_CON(6), 6, GFLAGS),
319 GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", CLK_SET_RATE_PARENT, 319 GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", CLK_SET_RATE_PARENT,
320 RK3328_CLKGATE_CON(14), 0, GFLAGS), 320 RK3328_CLKGATE_CON(14), 0, GFLAGS),
321 GATE(0, "aclk_gpu_niu", "aclk_gpu_pre", CLK_IGNORE_UNUSED, 321 GATE(0, "aclk_gpu_niu", "aclk_gpu_pre", 0,
322 RK3328_CLKGATE_CON(14), 1, GFLAGS), 322 RK3328_CLKGATE_CON(14), 1, GFLAGS),
323 323
324 /* PD_DDR */ 324 /* PD_DDR */
@@ -513,9 +513,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
513 RK3328_CLKGATE_CON(24), 0, GFLAGS), 513 RK3328_CLKGATE_CON(24), 0, GFLAGS),
514 GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", CLK_SET_RATE_PARENT, 514 GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", CLK_SET_RATE_PARENT,
515 RK3328_CLKGATE_CON(24), 1, GFLAGS), 515 RK3328_CLKGATE_CON(24), 1, GFLAGS),
516 GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED, 516 GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", 0,
517 RK3328_CLKGATE_CON(24), 2, GFLAGS), 517 RK3328_CLKGATE_CON(24), 2, GFLAGS),
518 GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED, 518 GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", 0,
519 RK3328_CLKGATE_CON(24), 3, GFLAGS), 519 RK3328_CLKGATE_CON(24), 3, GFLAGS),
520 520
521 COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_4plls_p, 0, 521 COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_4plls_p, 0,
@@ -535,9 +535,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
535 RK3328_CLKGATE_CON(23), 0, GFLAGS), 535 RK3328_CLKGATE_CON(23), 0, GFLAGS),
536 GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", CLK_SET_RATE_PARENT, 536 GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", CLK_SET_RATE_PARENT,
537 RK3328_CLKGATE_CON(23), 1, GFLAGS), 537 RK3328_CLKGATE_CON(23), 1, GFLAGS),
538 GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, 538 GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", 0,
539 RK3328_CLKGATE_CON(23), 2, GFLAGS), 539 RK3328_CLKGATE_CON(23), 2, GFLAGS),
540 GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED, 540 GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", 0,
541 RK3328_CLKGATE_CON(23), 3, GFLAGS), 541 RK3328_CLKGATE_CON(23), 3, GFLAGS),
542 542
543 COMPOSITE(ACLK_RKVENC, "aclk_rkvenc", mux_4plls_p, 0, 543 COMPOSITE(ACLK_RKVENC, "aclk_rkvenc", mux_4plls_p, 0,
@@ -545,9 +545,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
545 RK3328_CLKGATE_CON(6), 3, GFLAGS), 545 RK3328_CLKGATE_CON(6), 3, GFLAGS),
546 FACTOR_GATE(HCLK_RKVENC, "hclk_rkvenc", "aclk_rkvenc", 0, 1, 4, 546 FACTOR_GATE(HCLK_RKVENC, "hclk_rkvenc", "aclk_rkvenc", 0, 1, 4,
547 RK3328_CLKGATE_CON(11), 4, GFLAGS), 547 RK3328_CLKGATE_CON(11), 4, GFLAGS),
548 GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc", CLK_IGNORE_UNUSED, 548 GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc", 0,
549 RK3328_CLKGATE_CON(25), 0, GFLAGS), 549 RK3328_CLKGATE_CON(25), 0, GFLAGS),
550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", CLK_IGNORE_UNUSED, 550 GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc", 0,
551 RK3328_CLKGATE_CON(25), 1, GFLAGS), 551 RK3328_CLKGATE_CON(25), 1, GFLAGS),
552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0, 552 GATE(ACLK_H265, "aclk_h265", "aclk_rkvenc", 0,
553 RK3328_CLKGATE_CON(25), 0, GFLAGS), 553 RK3328_CLKGATE_CON(25), 0, GFLAGS),
@@ -588,7 +588,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
588 COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_4plls_p, 0, 588 COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_4plls_p, 0,
589 RK3328_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS, 589 RK3328_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS,
590 RK3328_CLKGATE_CON(5), 5, GFLAGS), 590 RK3328_CLKGATE_CON(5), 5, GFLAGS),
591 GATE(0, "clk_hdmi_sfc", "xin24m", 0, 591 GATE(SCLK_HDMI_SFC, "sclk_hdmi_sfc", "xin24m", 0,
592 RK3328_CLKGATE_CON(5), 4, GFLAGS), 592 RK3328_CLKGATE_CON(5), 4, GFLAGS),
593 593
594 COMPOSITE_NODIV(0, "clk_cif_src", mux_2plls_p, 0, 594 COMPOSITE_NODIV(0, "clk_cif_src", mux_2plls_p, 0,
@@ -602,7 +602,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
602 RK3328_CLKGATE_CON(5), 6, GFLAGS), 602 RK3328_CLKGATE_CON(5), 6, GFLAGS),
603 DIV(DCLK_HDMIPHY, "dclk_hdmiphy", "dclk_lcdc_src", 0, 603 DIV(DCLK_HDMIPHY, "dclk_hdmiphy", "dclk_lcdc_src", 0,
604 RK3328_CLKSEL_CON(40), 3, 3, DFLAGS), 604 RK3328_CLKSEL_CON(40), 3, 3, DFLAGS),
605 MUX(DCLK_LCDC, "dclk_lcdc", mux_dclk_lcdc_p, 0, 605 MUX(DCLK_LCDC, "dclk_lcdc", mux_dclk_lcdc_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
606 RK3328_CLKSEL_CON(40), 1, 1, MFLAGS), 606 RK3328_CLKSEL_CON(40), 1, 1, MFLAGS),
607 607
608 /* 608 /*
@@ -709,14 +709,14 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
709 709
710 /* PD_VOP */ 710 /* PD_VOP */
711 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3328_CLKGATE_CON(21), 10, GFLAGS), 711 GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3328_CLKGATE_CON(21), 10, GFLAGS),
712 GATE(0, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(22), 3, GFLAGS), 712 GATE(0, "aclk_rga_niu", "aclk_rga_pre", 0, RK3328_CLKGATE_CON(22), 3, GFLAGS),
713 GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK3328_CLKGATE_CON(21), 2, GFLAGS), 713 GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK3328_CLKGATE_CON(21), 2, GFLAGS),
714 GATE(0, "aclk_vop_niu", "aclk_vop_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 4, GFLAGS), 714 GATE(0, "aclk_vop_niu", "aclk_vop_pre", 0, RK3328_CLKGATE_CON(21), 4, GFLAGS),
715 715
716 GATE(ACLK_IEP, "aclk_iep", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 6, GFLAGS), 716 GATE(ACLK_IEP, "aclk_iep", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 6, GFLAGS),
717 GATE(ACLK_CIF, "aclk_cif", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 8, GFLAGS), 717 GATE(ACLK_CIF, "aclk_cif", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 8, GFLAGS),
718 GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 15, GFLAGS), 718 GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 15, GFLAGS),
719 GATE(0, "aclk_vio_niu", "aclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(22), 2, GFLAGS), 719 GATE(0, "aclk_vio_niu", "aclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 2, GFLAGS),
720 720
721 GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 3, GFLAGS), 721 GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 3, GFLAGS),
722 GATE(0, "hclk_vop_niu", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 5, GFLAGS), 722 GATE(0, "hclk_vop_niu", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 5, GFLAGS),
@@ -724,10 +724,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
724 GATE(HCLK_CIF, "hclk_cif", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 9, GFLAGS), 724 GATE(HCLK_CIF, "hclk_cif", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 9, GFLAGS),
725 GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 11, GFLAGS), 725 GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 11, GFLAGS),
726 GATE(0, "hclk_ahb1tom", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 12, GFLAGS), 726 GATE(0, "hclk_ahb1tom", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 12, GFLAGS),
727 GATE(0, "pclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 13, GFLAGS), 727 GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 13, GFLAGS),
728 GATE(0, "hclk_vio_h2p", "hclk_vio_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(21), 14, GFLAGS), 728 GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(21), 14, GFLAGS),
729 GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 0, GFLAGS), 729 GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 0, GFLAGS),
730 GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 1, GFLAGS), 730 GATE(0, "hclk_vio_niu", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 1, GFLAGS),
731 GATE(PCLK_HDMI, "pclk_hdmi", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 4, GFLAGS), 731 GATE(PCLK_HDMI, "pclk_hdmi", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 4, GFLAGS),
732 GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 5, GFLAGS), 732 GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK3328_CLKGATE_CON(22), 5, GFLAGS),
733 733
@@ -743,19 +743,19 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
743 GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 7, GFLAGS), 743 GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 7, GFLAGS),
744 GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 8, GFLAGS), 744 GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 8, GFLAGS),
745 GATE(HCLK_OTG_PMU, "hclk_otg_pmu", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 9, GFLAGS), 745 GATE(HCLK_OTG_PMU, "hclk_otg_pmu", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 9, GFLAGS),
746 GATE(0, "hclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 12, GFLAGS), 746 GATE(0, "hclk_peri_niu", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 12, GFLAGS),
747 GATE(0, "pclk_peri_niu", "hclk_peri", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(19), 13, GFLAGS), 747 GATE(0, "pclk_peri_niu", "hclk_peri", 0, RK3328_CLKGATE_CON(19), 13, GFLAGS),
748 748
749 /* PD_GMAC */ 749 /* PD_GMAC */
750 GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 0, GFLAGS), 750 GATE(ACLK_MAC2PHY, "aclk_mac2phy", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 0, GFLAGS),
751 GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 2, GFLAGS), 751 GATE(ACLK_MAC2IO, "aclk_mac2io", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 2, GFLAGS),
752 GATE(0, "aclk_gmac_niu", "aclk_gmac", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(26), 4, GFLAGS), 752 GATE(0, "aclk_gmac_niu", "aclk_gmac", 0, RK3328_CLKGATE_CON(26), 4, GFLAGS),
753 GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 1, GFLAGS), 753 GATE(PCLK_MAC2PHY, "pclk_mac2phy", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 1, GFLAGS),
754 GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 3, GFLAGS), 754 GATE(PCLK_MAC2IO, "pclk_mac2io", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 3, GFLAGS),
755 GATE(0, "pclk_gmac_niu", "pclk_gmac", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(26), 5, GFLAGS), 755 GATE(0, "pclk_gmac_niu", "pclk_gmac", 0, RK3328_CLKGATE_CON(26), 5, GFLAGS),
756 756
757 /* PD_BUS */ 757 /* PD_BUS */
758 GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 12, GFLAGS), 758 GATE(0, "aclk_bus_niu", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 12, GFLAGS),
759 GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 11, GFLAGS), 759 GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 11, GFLAGS),
760 GATE(ACLK_TSP, "aclk_tsp", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 12, GFLAGS), 760 GATE(ACLK_TSP, "aclk_tsp", "aclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 12, GFLAGS),
761 GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 0, GFLAGS), 761 GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 0, GFLAGS),
@@ -769,10 +769,10 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
769 GATE(HCLK_TSP, "hclk_tsp", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 11, GFLAGS), 769 GATE(HCLK_TSP, "hclk_tsp", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(17), 11, GFLAGS),
770 GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 7, GFLAGS), 770 GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 7, GFLAGS),
771 GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 8, GFLAGS), 771 GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 8, GFLAGS),
772 GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 13, GFLAGS), 772 GATE(0, "hclk_bus_niu", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(15), 13, GFLAGS),
773 GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(28), 0, GFLAGS), 773 GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, RK3328_CLKGATE_CON(28), 0, GFLAGS),
774 774
775 GATE(0, "pclk_bus_niu", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 14, GFLAGS), 775 GATE(0, "pclk_bus_niu", "pclk_bus", 0, RK3328_CLKGATE_CON(15), 14, GFLAGS),
776 GATE(0, "pclk_efuse", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 9, GFLAGS), 776 GATE(0, "pclk_efuse", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 9, GFLAGS),
777 GATE(0, "pclk_otp", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 4, GFLAGS), 777 GATE(0, "pclk_otp", "pclk_bus", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(28), 4, GFLAGS),
778 GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0, RK3328_CLKGATE_CON(15), 10, GFLAGS), 778 GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0, RK3328_CLKGATE_CON(15), 10, GFLAGS),
@@ -807,7 +807,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
807 GATE(0, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 5, GFLAGS), 807 GATE(0, "pclk_acodecphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 5, GFLAGS),
808 GATE(PCLK_HDMIPHY, "pclk_hdmiphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 7, GFLAGS), 808 GATE(PCLK_HDMIPHY, "pclk_hdmiphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 7, GFLAGS),
809 GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 8, GFLAGS), 809 GATE(0, "pclk_vdacphy", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(17), 8, GFLAGS),
810 GATE(0, "pclk_phy_niu", "pclk_phy_pre", CLK_IGNORE_UNUSED, RK3328_CLKGATE_CON(15), 15, GFLAGS), 810 GATE(0, "pclk_phy_niu", "pclk_phy_pre", 0, RK3328_CLKGATE_CON(15), 15, GFLAGS),
811 811
812 /* PD_MMC */ 812 /* PD_MMC */
813 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", 813 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc",
@@ -833,11 +833,16 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
833 833
834static const char *const rk3328_critical_clocks[] __initconst = { 834static const char *const rk3328_critical_clocks[] __initconst = {
835 "aclk_bus", 835 "aclk_bus",
836 "aclk_bus_niu",
836 "pclk_bus", 837 "pclk_bus",
838 "pclk_bus_niu",
837 "hclk_bus", 839 "hclk_bus",
840 "hclk_bus_niu",
838 "aclk_peri", 841 "aclk_peri",
839 "hclk_peri", 842 "hclk_peri",
843 "hclk_peri_niu",
840 "pclk_peri", 844 "pclk_peri",
845 "pclk_peri_niu",
841 "pclk_dbg", 846 "pclk_dbg",
842 "aclk_core_niu", 847 "aclk_core_niu",
843 "aclk_gic400", 848 "aclk_gic400",
@@ -861,6 +866,20 @@ static const char *const rk3328_critical_clocks[] __initconst = {
861 "aclk_rga_niu", 866 "aclk_rga_niu",
862 "pclk_vio_h2p", 867 "pclk_vio_h2p",
863 "hclk_vio_h2p", 868 "hclk_vio_h2p",
869 "aclk_vio_niu",
870 "hclk_vio_niu",
871 "aclk_vop_niu",
872 "hclk_vop_niu",
873 "aclk_gpu_niu",
874 "aclk_rkvdec_niu",
875 "hclk_rkvdec_niu",
876 "aclk_vpu_niu",
877 "hclk_vpu_niu",
878 "aclk_rkvenc_niu",
879 "hclk_rkvenc_niu",
880 "aclk_gmac_niu",
881 "pclk_gmac_niu",
882 "pclk_phy_niu",
864}; 883};
865 884
866static void __init rk3328_clk_init(struct device_node *np) 885static void __init rk3328_clk_init(struct device_node *np)
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index 6847120b61cd..3e57c6eef93d 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -57,6 +57,7 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
57 RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0), 57 RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0),
58 RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0), 58 RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0),
59 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 59 RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
60 RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
60 RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), 61 RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
61 RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), 62 RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
62 RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), 63 RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 35dbd63c2f49..3cd8ad59e0b7 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -57,6 +57,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
57 struct clk_divider *div = NULL; 57 struct clk_divider *div = NULL;
58 const struct clk_ops *mux_ops = NULL, *div_ops = NULL, 58 const struct clk_ops *mux_ops = NULL, *div_ops = NULL,
59 *gate_ops = NULL; 59 *gate_ops = NULL;
60 int ret;
60 61
61 if (num_parents > 1) { 62 if (num_parents > 1) {
62 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 63 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
@@ -74,8 +75,10 @@ static struct clk *rockchip_clk_register_branch(const char *name,
74 75
75 if (gate_offset >= 0) { 76 if (gate_offset >= 0) {
76 gate = kzalloc(sizeof(*gate), GFP_KERNEL); 77 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
77 if (!gate) 78 if (!gate) {
79 ret = -ENOMEM;
78 goto err_gate; 80 goto err_gate;
81 }
79 82
80 gate->flags = gate_flags; 83 gate->flags = gate_flags;
81 gate->reg = base + gate_offset; 84 gate->reg = base + gate_offset;
@@ -86,8 +89,10 @@ static struct clk *rockchip_clk_register_branch(const char *name,
86 89
87 if (div_width > 0) { 90 if (div_width > 0) {
88 div = kzalloc(sizeof(*div), GFP_KERNEL); 91 div = kzalloc(sizeof(*div), GFP_KERNEL);
89 if (!div) 92 if (!div) {
93 ret = -ENOMEM;
90 goto err_div; 94 goto err_div;
95 }
91 96
92 div->flags = div_flags; 97 div->flags = div_flags;
93 div->reg = base + muxdiv_offset; 98 div->reg = base + muxdiv_offset;
@@ -106,12 +111,19 @@ static struct clk *rockchip_clk_register_branch(const char *name,
106 gate ? &gate->hw : NULL, gate_ops, 111 gate ? &gate->hw : NULL, gate_ops,
107 flags); 112 flags);
108 113
114 if (IS_ERR(clk)) {
115 ret = PTR_ERR(clk);
116 goto err_composite;
117 }
118
109 return clk; 119 return clk;
120err_composite:
121 kfree(div);
110err_div: 122err_div:
111 kfree(gate); 123 kfree(gate);
112err_gate: 124err_gate:
113 kfree(mux); 125 kfree(mux);
114 return ERR_PTR(-ENOMEM); 126 return ERR_PTR(ret);
115} 127}
116 128
117struct rockchip_clk_frac { 129struct rockchip_clk_frac {
@@ -291,8 +303,10 @@ static struct clk *rockchip_clk_register_frac_branch(
291 init.num_parents = child->num_parents; 303 init.num_parents = child->num_parents;
292 304
293 mux_clk = clk_register(NULL, &frac_mux->hw); 305 mux_clk = clk_register(NULL, &frac_mux->hw);
294 if (IS_ERR(mux_clk)) 306 if (IS_ERR(mux_clk)) {
307 kfree(frac);
295 return clk; 308 return clk;
309 }
296 310
297 rockchip_clk_add_lookup(ctx, mux_clk, child->id); 311 rockchip_clk_add_lookup(ctx, mux_clk, child->id);
298 312
diff --git a/include/dt-bindings/clock/rk3328-cru.h b/include/dt-bindings/clock/rk3328-cru.h
index d2b26a4b43eb..a82a0109faff 100644
--- a/include/dt-bindings/clock/rk3328-cru.h
+++ b/include/dt-bindings/clock/rk3328-cru.h
@@ -193,7 +193,6 @@
193#define HCLK_VPU_PRE 324 193#define HCLK_VPU_PRE 324
194#define HCLK_VIO_PRE 325 194#define HCLK_VIO_PRE 325
195#define HCLK_VPU 326 195#define HCLK_VPU 326
196#define HCLK_VIO 327
197#define HCLK_BUS_PRE 328 196#define HCLK_BUS_PRE 328
198#define HCLK_PERI_PRE 329 197#define HCLK_PERI_PRE 329
199#define HCLK_H264 330 198#define HCLK_H264 330