Loading drivers/clk/tegra/clk-periph-gate.c +47 −33 Original line number Original line Diff line number Diff line Loading @@ -48,36 +48,45 @@ static int clk_periph_is_enabled(struct clk_hw *hw) return state; return state; } } static int clk_periph_enable(struct clk_hw *hw) static void clk_periph_enable_locked(struct clk_hw *hw) { { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); gate->enable_refcnt[gate->clk_num]++; if (gate->enable_refcnt[gate->clk_num] > 1) { spin_unlock_irqrestore(&periph_ref_lock, flags); return 0; } write_enb_set(periph_clk_to_bit(gate), gate); write_enb_set(periph_clk_to_bit(gate), gate); udelay(2); udelay(2); if (!(gate->flags & TEGRA_PERIPH_NO_RESET) && !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) { if (read_rst(gate) & periph_clk_to_bit(gate)) { udelay(5); /* reset propogation delay */ write_rst_clr(periph_clk_to_bit(gate), gate); } } if (gate->flags & TEGRA_PERIPH_WAR_1005168) { if (gate->flags & TEGRA_PERIPH_WAR_1005168) { writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); udelay(1); udelay(1); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); } } } static void clk_periph_disable_locked(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); /* * If peripheral is in the APB bus then read the APB bus to * flush the write operation in apb bus. This will avoid the * peripheral access after disabling clock */ if (gate->flags & TEGRA_PERIPH_ON_APB) tegra_read_chipid(); write_enb_clr(periph_clk_to_bit(gate), gate); } static int clk_periph_enable(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); if (!gate->enable_refcnt[gate->clk_num]++) clk_periph_enable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); Loading @@ -91,21 +100,28 @@ static void clk_periph_disable(struct clk_hw *hw) spin_lock_irqsave(&periph_ref_lock, flags); spin_lock_irqsave(&periph_ref_lock, flags); gate->enable_refcnt[gate->clk_num]--; WARN_ON(!gate->enable_refcnt[gate->clk_num]); if (gate->enable_refcnt[gate->clk_num] > 0) { if (--gate->enable_refcnt[gate->clk_num] == 0) clk_periph_disable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); return; } } static void clk_periph_disable_unused(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); /* /* * If peripheral is in the APB bus then read the APB bus to * Some clocks are duplicated and some of them are marked as critical, * flush the write operation in apb bus. This will avoid the * like fuse and fuse_burn for example, thus the enable_refcnt will * peripheral access after disabling clock * be non-zero here if the "unused" duplicate is disabled by CCF. */ */ if (gate->flags & TEGRA_PERIPH_ON_APB) if (!gate->enable_refcnt[gate->clk_num]) tegra_read_chipid(); clk_periph_disable_locked(hw); write_enb_clr(periph_clk_to_bit(gate), gate); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); } } Loading @@ -114,6 +130,7 @@ const struct clk_ops tegra_clk_periph_gate_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, }; }; struct clk *tegra_clk_register_periph_gate(const char *name, struct clk *tegra_clk_register_periph_gate(const char *name, Loading Loading @@ -148,9 +165,6 @@ struct clk *tegra_clk_register_periph_gate(const char *name, gate->enable_refcnt = enable_refcnt; gate->enable_refcnt = enable_refcnt; gate->regs = pregs; gate->regs = pregs; if (read_enb(gate) & periph_clk_to_bit(gate)) enable_refcnt[clk_num]++; /* Data in .init is copied by clk_register(), so stack variable OK */ /* Data in .init is copied by clk_register(), so stack variable OK */ gate->hw.init = &init; gate->hw.init = &init; Loading drivers/clk/tegra/clk-periph.c +11 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,15 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); gate_ops->disable(gate_hw); } } static void clk_periph_disable_unused(struct clk_hw *hw) { struct tegra_clk_periph *periph = to_clk_periph(hw); const struct clk_ops *gate_ops = periph->gate_ops; struct clk_hw *gate_hw = &periph->gate.hw; gate_ops->disable_unused(gate_hw); } static void clk_periph_restore_context(struct clk_hw *hw) static void clk_periph_restore_context(struct clk_hw *hw) { { struct tegra_clk_periph *periph = to_clk_periph(hw); struct tegra_clk_periph *periph = to_clk_periph(hw); Loading @@ -126,6 +135,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, .restore_context = clk_periph_restore_context, }; }; Loading @@ -135,6 +145,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, .restore_context = clk_periph_restore_context, }; }; Loading drivers/clk/tegra/clk-pll.c +7 −5 Original line number Original line Diff line number Diff line Loading @@ -558,6 +558,9 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, u32 p_div = 0; u32 p_div = 0; int ret; int ret; if (!rate) return -EINVAL; switch (parent_rate) { switch (parent_rate) { case 12000000: case 12000000: case 26000000: case 26000000: Loading Loading @@ -1131,6 +1134,7 @@ static int clk_pllu_enable(struct clk_hw *hw) if (pll->lock) if (pll->lock) spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags); if (!clk_pll_is_enabled(hw)) _clk_pll_enable(hw); _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); ret = clk_pll_wait_for_lock(pll); Loading Loading @@ -1748,14 +1752,12 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) return -EINVAL; return -EINVAL; } } if (clk_pll_is_enabled(hw)) return 0; input_rate = clk_hw_get_rate(__clk_get_hw(osc)); input_rate = clk_hw_get_rate(__clk_get_hw(osc)); if (pll->lock) if (pll->lock) spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags); if (!clk_pll_is_enabled(hw)) _clk_pll_enable(hw); _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); ret = clk_pll_wait_for_lock(pll); Loading drivers/clk/tegra/clk-tegra-periph.c +3 −3 Original line number Original line Diff line number Diff line Loading @@ -712,9 +712,9 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, TEGRA_PERIPH_NO_RESET, tegra_clk_extern1), MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, TEGRA_PERIPH_NO_RESET, tegra_clk_extern2), MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, TEGRA_PERIPH_NO_RESET, tegra_clk_extern3), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), Loading drivers/clk/tegra/clk-tegra-super-cclk.c +14 −2 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,8 @@ #define SUPER_CDIV_ENB BIT(31) #define SUPER_CDIV_ENB BIT(31) #define TSENSOR_SLOWDOWN BIT(23) static struct tegra_clk_super_mux *cclk_super; static struct tegra_clk_super_mux *cclk_super; static bool cclk_on_pllx; static bool cclk_on_pllx; Loading @@ -47,10 +49,20 @@ static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate, static unsigned long cclk_super_recalc_rate(struct clk_hw *hw, static unsigned long cclk_super_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) unsigned long parent_rate) { { struct tegra_clk_super_mux *super = to_clk_super_mux(hw); u32 val = readl_relaxed(super->reg); unsigned int div2; /* check whether thermal throttling is active */ if (val & TSENSOR_SLOWDOWN) div2 = 1; else div2 = 0; if (cclk_super_get_parent(hw) == PLLX_INDEX) if (cclk_super_get_parent(hw) == PLLX_INDEX) return parent_rate; return parent_rate >> div2; return tegra_clk_super_ops.recalc_rate(hw, parent_rate); return tegra_clk_super_ops.recalc_rate(hw, parent_rate) >> div2; } } static int cclk_super_determine_rate(struct clk_hw *hw, static int cclk_super_determine_rate(struct clk_hw *hw, Loading Loading
drivers/clk/tegra/clk-periph-gate.c +47 −33 Original line number Original line Diff line number Diff line Loading @@ -48,36 +48,45 @@ static int clk_periph_is_enabled(struct clk_hw *hw) return state; return state; } } static int clk_periph_enable(struct clk_hw *hw) static void clk_periph_enable_locked(struct clk_hw *hw) { { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); gate->enable_refcnt[gate->clk_num]++; if (gate->enable_refcnt[gate->clk_num] > 1) { spin_unlock_irqrestore(&periph_ref_lock, flags); return 0; } write_enb_set(periph_clk_to_bit(gate), gate); write_enb_set(periph_clk_to_bit(gate), gate); udelay(2); udelay(2); if (!(gate->flags & TEGRA_PERIPH_NO_RESET) && !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) { if (read_rst(gate) & periph_clk_to_bit(gate)) { udelay(5); /* reset propogation delay */ write_rst_clr(periph_clk_to_bit(gate), gate); } } if (gate->flags & TEGRA_PERIPH_WAR_1005168) { if (gate->flags & TEGRA_PERIPH_WAR_1005168) { writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); udelay(1); udelay(1); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); } } } static void clk_periph_disable_locked(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); /* * If peripheral is in the APB bus then read the APB bus to * flush the write operation in apb bus. This will avoid the * peripheral access after disabling clock */ if (gate->flags & TEGRA_PERIPH_ON_APB) tegra_read_chipid(); write_enb_clr(periph_clk_to_bit(gate), gate); } static int clk_periph_enable(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); if (!gate->enable_refcnt[gate->clk_num]++) clk_periph_enable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); Loading @@ -91,21 +100,28 @@ static void clk_periph_disable(struct clk_hw *hw) spin_lock_irqsave(&periph_ref_lock, flags); spin_lock_irqsave(&periph_ref_lock, flags); gate->enable_refcnt[gate->clk_num]--; WARN_ON(!gate->enable_refcnt[gate->clk_num]); if (gate->enable_refcnt[gate->clk_num] > 0) { if (--gate->enable_refcnt[gate->clk_num] == 0) clk_periph_disable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); return; } } static void clk_periph_disable_unused(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); unsigned long flags = 0; spin_lock_irqsave(&periph_ref_lock, flags); /* /* * If peripheral is in the APB bus then read the APB bus to * Some clocks are duplicated and some of them are marked as critical, * flush the write operation in apb bus. This will avoid the * like fuse and fuse_burn for example, thus the enable_refcnt will * peripheral access after disabling clock * be non-zero here if the "unused" duplicate is disabled by CCF. */ */ if (gate->flags & TEGRA_PERIPH_ON_APB) if (!gate->enable_refcnt[gate->clk_num]) tegra_read_chipid(); clk_periph_disable_locked(hw); write_enb_clr(periph_clk_to_bit(gate), gate); spin_unlock_irqrestore(&periph_ref_lock, flags); spin_unlock_irqrestore(&periph_ref_lock, flags); } } Loading @@ -114,6 +130,7 @@ const struct clk_ops tegra_clk_periph_gate_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, }; }; struct clk *tegra_clk_register_periph_gate(const char *name, struct clk *tegra_clk_register_periph_gate(const char *name, Loading Loading @@ -148,9 +165,6 @@ struct clk *tegra_clk_register_periph_gate(const char *name, gate->enable_refcnt = enable_refcnt; gate->enable_refcnt = enable_refcnt; gate->regs = pregs; gate->regs = pregs; if (read_enb(gate) & periph_clk_to_bit(gate)) enable_refcnt[clk_num]++; /* Data in .init is copied by clk_register(), so stack variable OK */ /* Data in .init is copied by clk_register(), so stack variable OK */ gate->hw.init = &init; gate->hw.init = &init; Loading
drivers/clk/tegra/clk-periph.c +11 −0 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,15 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); gate_ops->disable(gate_hw); } } static void clk_periph_disable_unused(struct clk_hw *hw) { struct tegra_clk_periph *periph = to_clk_periph(hw); const struct clk_ops *gate_ops = periph->gate_ops; struct clk_hw *gate_hw = &periph->gate.hw; gate_ops->disable_unused(gate_hw); } static void clk_periph_restore_context(struct clk_hw *hw) static void clk_periph_restore_context(struct clk_hw *hw) { { struct tegra_clk_periph *periph = to_clk_periph(hw); struct tegra_clk_periph *periph = to_clk_periph(hw); Loading @@ -126,6 +135,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, .restore_context = clk_periph_restore_context, }; }; Loading @@ -135,6 +145,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .enable = clk_periph_enable, .disable = clk_periph_disable, .disable = clk_periph_disable, .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, .restore_context = clk_periph_restore_context, }; }; Loading
drivers/clk/tegra/clk-pll.c +7 −5 Original line number Original line Diff line number Diff line Loading @@ -558,6 +558,9 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, u32 p_div = 0; u32 p_div = 0; int ret; int ret; if (!rate) return -EINVAL; switch (parent_rate) { switch (parent_rate) { case 12000000: case 12000000: case 26000000: case 26000000: Loading Loading @@ -1131,6 +1134,7 @@ static int clk_pllu_enable(struct clk_hw *hw) if (pll->lock) if (pll->lock) spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags); if (!clk_pll_is_enabled(hw)) _clk_pll_enable(hw); _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); ret = clk_pll_wait_for_lock(pll); Loading Loading @@ -1748,14 +1752,12 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) return -EINVAL; return -EINVAL; } } if (clk_pll_is_enabled(hw)) return 0; input_rate = clk_hw_get_rate(__clk_get_hw(osc)); input_rate = clk_hw_get_rate(__clk_get_hw(osc)); if (pll->lock) if (pll->lock) spin_lock_irqsave(pll->lock, flags); spin_lock_irqsave(pll->lock, flags); if (!clk_pll_is_enabled(hw)) _clk_pll_enable(hw); _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); ret = clk_pll_wait_for_lock(pll); Loading
drivers/clk/tegra/clk-tegra-periph.c +3 −3 Original line number Original line Diff line number Diff line Loading @@ -712,9 +712,9 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, TEGRA_PERIPH_NO_RESET, tegra_clk_extern1), MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, TEGRA_PERIPH_NO_RESET, tegra_clk_extern2), MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, TEGRA_PERIPH_NO_RESET, tegra_clk_extern3), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), Loading
drivers/clk/tegra/clk-tegra-super-cclk.c +14 −2 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,8 @@ #define SUPER_CDIV_ENB BIT(31) #define SUPER_CDIV_ENB BIT(31) #define TSENSOR_SLOWDOWN BIT(23) static struct tegra_clk_super_mux *cclk_super; static struct tegra_clk_super_mux *cclk_super; static bool cclk_on_pllx; static bool cclk_on_pllx; Loading @@ -47,10 +49,20 @@ static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate, static unsigned long cclk_super_recalc_rate(struct clk_hw *hw, static unsigned long cclk_super_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) unsigned long parent_rate) { { struct tegra_clk_super_mux *super = to_clk_super_mux(hw); u32 val = readl_relaxed(super->reg); unsigned int div2; /* check whether thermal throttling is active */ if (val & TSENSOR_SLOWDOWN) div2 = 1; else div2 = 0; if (cclk_super_get_parent(hw) == PLLX_INDEX) if (cclk_super_get_parent(hw) == PLLX_INDEX) return parent_rate; return parent_rate >> div2; return tegra_clk_super_ops.recalc_rate(hw, parent_rate); return tegra_clk_super_ops.recalc_rate(hw, parent_rate) >> div2; } } static int cclk_super_determine_rate(struct clk_hw *hw, static int cclk_super_determine_rate(struct clk_hw *hw, Loading