diff options
author | Michael Turquette <mturquette@baylibre.com> | 2015-10-20 17:49:11 +0200 |
---|---|---|
committer | Michael Turquette <mturquette@baylibre.com> | 2015-10-20 17:49:11 +0200 |
commit | eae14465de250be75021659789f138a70a553ac5 (patch) | |
tree | 6dfe124d0ad901c24d63515af740baa837fb68b2 /drivers/clk/tegra/clk-dfll.c | |
parent | clk: keystone: fix a trivial typo (diff) | |
parent | clk: tegra: Modify tegra_audio_clk_init to accept more plls (diff) | |
download | linux-eae14465de250be75021659789f138a70a553ac5.tar.xz linux-eae14465de250be75021659789f138a70a553ac5.zip |
Merge tag 'tegra-for-4.4-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-next
clk: tegra: Changes for v4.4-rc1
This contains a patch that allows the DFLL to use clock rates higher
than 2^31-1 Hz by using the ->determine_rate() operation instead of the
->round_rate() operation. Other than that there's a couple of cleanups
in preparation for Tegra210 support.
Diffstat (limited to 'drivers/clk/tegra/clk-dfll.c')
-rw-r--r-- | drivers/clk/tegra/clk-dfll.c | 114 |
1 files changed, 57 insertions, 57 deletions
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index c4e3a52e225b..86a307b17eb0 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -469,56 +469,6 @@ static unsigned long dfll_scale_dvco_rate(int scale_bits, } /* - * Monitor control - */ - -/** - * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq - * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield - * @ref_rate: DFLL reference clock rate - * - * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles - * per second. Returns the converted value. - */ -static u64 dfll_calc_monitored_rate(u32 monitor_data, - unsigned long ref_rate) -{ - return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE); -} - -/** - * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor - * @td: DFLL instance - * - * If the DFLL is enabled, return the last rate reported by the DFLL's - * internal monitoring hardware. This works in both open-loop and - * closed-loop mode, and takes the output scaler setting into account. - * Assumes that the monitor was programmed to monitor frequency before - * the sample period started. If the driver believes that the DFLL is - * currently uninitialized or disabled, it will return 0, since - * otherwise the DFLL monitor data register will return the last - * measured rate from when the DFLL was active. - */ -static u64 dfll_read_monitor_rate(struct tegra_dfll *td) -{ - u32 v, s; - u64 pre_scaler_rate, post_scaler_rate; - - if (!dfll_is_running(td)) - return 0; - - v = dfll_readl(td, DFLL_MONITOR_DATA); - v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT; - pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate); - - s = dfll_readl(td, DFLL_FREQ_REQ); - s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT; - post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate); - - return post_scaler_rate; -} - -/* * DFLL mode switching */ @@ -1006,24 +956,25 @@ static unsigned long dfll_clk_recalc_rate(struct clk_hw *hw, return td->last_unrounded_rate; } -static long dfll_clk_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +/* Must use determine_rate since it allows for rates exceeding 2^31-1 */ +static int dfll_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *clk_req) { struct tegra_dfll *td = clk_hw_to_dfll(hw); struct dfll_rate_req req; int ret; - ret = dfll_calculate_rate_request(td, &req, rate); + ret = dfll_calculate_rate_request(td, &req, clk_req->rate); if (ret) return ret; /* - * Don't return the rounded rate, since it doesn't really matter as + * Don't set the rounded rate, since it doesn't really matter as * the output rate will be voltage controlled anyway, and cpufreq * freaks out if any rounding happens. */ - return rate; + + return 0; } static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -1039,7 +990,7 @@ static const struct clk_ops dfll_clk_ops = { .enable = dfll_clk_enable, .disable = dfll_clk_disable, .recalc_rate = dfll_clk_recalc_rate, - .round_rate = dfll_clk_round_rate, + .determine_rate = dfll_clk_determine_rate, .set_rate = dfll_clk_set_rate, }; @@ -1101,6 +1052,55 @@ static void dfll_unregister_clk(struct tegra_dfll *td) */ #ifdef CONFIG_DEBUG_FS +/* + * Monitor control + */ + +/** + * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq + * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield + * @ref_rate: DFLL reference clock rate + * + * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles + * per second. Returns the converted value. + */ +static u64 dfll_calc_monitored_rate(u32 monitor_data, + unsigned long ref_rate) +{ + return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE); +} + +/** + * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor + * @td: DFLL instance + * + * If the DFLL is enabled, return the last rate reported by the DFLL's + * internal monitoring hardware. This works in both open-loop and + * closed-loop mode, and takes the output scaler setting into account. + * Assumes that the monitor was programmed to monitor frequency before + * the sample period started. If the driver believes that the DFLL is + * currently uninitialized or disabled, it will return 0, since + * otherwise the DFLL monitor data register will return the last + * measured rate from when the DFLL was active. + */ +static u64 dfll_read_monitor_rate(struct tegra_dfll *td) +{ + u32 v, s; + u64 pre_scaler_rate, post_scaler_rate; + + if (!dfll_is_running(td)) + return 0; + + v = dfll_readl(td, DFLL_MONITOR_DATA); + v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT; + pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate); + + s = dfll_readl(td, DFLL_FREQ_REQ); + s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT; + post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate); + + return post_scaler_rate; +} static int attr_enable_get(void *data, u64 *val) { |