#define super_state_to_src_shift(m, s) ((m->width * s))
 #define super_state_to_src_mask(m) (((1 << m->width) - 1))
 
+#define CCLK_SRC_PLLP_OUT0 4
+#define CCLK_SRC_PLLP_OUT4 5
+
 static u8 clk_super_get_parent(struct clk_hw *hw)
 {
        struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
                if (index == mux->div2_index)
                        index = mux->pllx_index;
        }
+
+       /* enable PLLP branches to CPU before selecting PLLP source */
+       if ((mux->flags & TEGRA210_CPU_CLK) &&
+           (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4))
+               tegra_clk_set_pllp_out_cpu(true);
+
        val &= ~((super_state_to_src_mask(mux)) << shift);
        val |= (index & (super_state_to_src_mask(mux))) << shift;
 
        writel_relaxed(val, mux->reg);
        udelay(2);
 
+       /* disable PLLP branches to CPU if not used */
+       if ((mux->flags & TEGRA210_CPU_CLK) &&
+           index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4)
+               tegra_clk_set_pllp_out_cpu(false);
+
 out:
        if (mux->lock)
                spin_unlock_irqrestore(mux->lock, flags);
 
                                        gen_info->num_cclk_g_parents,
                                        CLK_SET_RATE_PARENT,
                                        clk_base + CCLKG_BURST_POLICY,
-                                       0, 4, 8, 0, NULL);
+                                       TEGRA210_CPU_CLK, 4, 8, 0, NULL);
                } else {
                        clk = tegra_clk_register_super_mux("cclk_g",
                                        gen_info->cclk_g_parents,
        dt_clk = tegra_lookup_dt_id(tegra_clk_cclk_lp, tegra_clks);
        if (dt_clk) {
                if (gen_info->gen == gen5) {
+                       /*
+                        * TEGRA210_CPU_CLK flag is not needed for cclk_lp as
+                        * cluster switching is not currently supported on
+                        * Tegra210 and also cpu_lp is not used.
+                        */
                        clk = tegra_clk_register_super_mux("cclk_lp",
                                        gen_info->cclk_lp_parents,
                                        gen_info->num_cclk_lp_parents,
 
 #define CLK_OUT_ENB_W                  0x364
 #define CLK_OUT_ENB_X                  0x280
 #define CLK_OUT_ENB_Y                  0x298
+#define CLK_ENB_PLLP_OUT_CPU           BIT(31)
 #define CLK_OUT_ENB_SET_L              0x320
 #define CLK_OUT_ENB_CLR_L              0x324
 #define CLK_OUT_ENB_SET_H              0x328
        }
 }
 
+void tegra_clk_set_pllp_out_cpu(bool enable)
+{
+       u32 val;
+
+       val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
+       if (enable)
+               val |= CLK_ENB_PLLP_OUT_CPU;
+       else
+               val &= ~CLK_ENB_PLLP_OUT_CPU;
+
+       writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
+}
+
 struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
 {
        clk_base = regs;
 
  * Flags:
  * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
  *     that this is LP cluster clock.
+ * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
+ * super mux parent using PLLP branches. To use PLLP branches to CPU, need
+ * to configure additional bit PLLP_OUT_CPU in the clock registers.
  */
 struct tegra_clk_super_mux {
        struct clk_hw   hw;
 #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
 
 #define TEGRA_DIVIDER_2 BIT(0)
+#define TEGRA210_CPU_CLK BIT(1)
 
 extern const struct clk_ops tegra_clk_super_ops;
 struct clk *tegra_clk_register_super_mux(const char *name,
 int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
                 u8 frac_width, u8 flags);
 void tegra_clk_osc_resume(void __iomem *clk_base);
+void tegra_clk_set_pllp_out_cpu(bool enable);
 
 
 /* Combined read fence with delay */