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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJWJjSRAAoJEN0jrNd/PrOh9vEP/0fhpVjrPPhnTSAMbdIA6kkB 5TThz2ja2AyoFTXyPS1SO77LPbk55LXuuTxcEiYDK5kokK8QcbIcYSEWQcbUsYEo 3gPiFVegmOcp1IZgJhU9RAQmqfWuQJuNYcWpHHFsz2otyVqlGWIyX6n1UzT47nmw zYvTFGmke28LMt9GnOR1X8ma3rnefYQw+ZcxSinzXhansKAfXtXpr0ixfCpSlqZl 7f+mSs5GW8QgJdm5ml4Y7BIk7Fopkr9ic4Js70OxbFmqKu9EU2p4bExFXmdfMQbU gq/jd/ZJQjlbNAluGBb7vjzHKN9InjzkxkNHyode8vix411z5Xx2TelYUbayNMh+ fCyn7Sr4tG2u4OZapH1zYV3YgIW08zQSpdkuq/J/8RuAN35WDYQMld4V7jHt7l0p 6Z/yVsM2llFwpmLu5DgeVYRXLt/3ConBwcAEn3EnEpQHXJXa9BBD6D3Uv7ErVAyJ aKN5p8Ix91/rX6JCa2g5tNTRs1arn5TfDQ2nJpGUmN4/SRMVb6L/ezmcPhqrDXVd Cp6xfvRS4TloYxuGbxpmpP+Hwev+GVN0AfEq3jpA7EmOvRLeexnVHhsnIvMbnEqw ucigNua0nWEqF0PechSpIIEp0rcdqD70kqNkTK/fzaWXPlg9GyI7W83JsDFh7PF1 2caoSL9E6jPE5F8L6NMz =4qKy -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
eae14465de
7 changed files with 170 additions and 120 deletions
|
@ -468,56 +468,6 @@ static unsigned long dfll_scale_dvco_rate(int scale_bits,
|
||||||
return (u64)dvco_rate * (scale_bits + 1) / DFLL_FREQ_REQ_SCALE_MAX;
|
return (u64)dvco_rate * (scale_bits + 1) / DFLL_FREQ_REQ_SCALE_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
* DFLL mode switching
|
||||||
*/
|
*/
|
||||||
|
@ -1006,24 +956,25 @@ static unsigned long dfll_clk_recalc_rate(struct clk_hw *hw,
|
||||||
return td->last_unrounded_rate;
|
return td->last_unrounded_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long dfll_clk_round_rate(struct clk_hw *hw,
|
/* Must use determine_rate since it allows for rates exceeding 2^31-1 */
|
||||||
unsigned long rate,
|
static int dfll_clk_determine_rate(struct clk_hw *hw,
|
||||||
unsigned long *parent_rate)
|
struct clk_rate_request *clk_req)
|
||||||
{
|
{
|
||||||
struct tegra_dfll *td = clk_hw_to_dfll(hw);
|
struct tegra_dfll *td = clk_hw_to_dfll(hw);
|
||||||
struct dfll_rate_req req;
|
struct dfll_rate_req req;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = dfll_calculate_rate_request(td, &req, rate);
|
ret = dfll_calculate_rate_request(td, &req, clk_req->rate);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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
|
* the output rate will be voltage controlled anyway, and cpufreq
|
||||||
* freaks out if any rounding happens.
|
* freaks out if any rounding happens.
|
||||||
*/
|
*/
|
||||||
return rate;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
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,
|
.enable = dfll_clk_enable,
|
||||||
.disable = dfll_clk_disable,
|
.disable = dfll_clk_disable,
|
||||||
.recalc_rate = dfll_clk_recalc_rate,
|
.recalc_rate = dfll_clk_recalc_rate,
|
||||||
.round_rate = dfll_clk_round_rate,
|
.determine_rate = dfll_clk_determine_rate,
|
||||||
.set_rate = dfll_clk_set_rate,
|
.set_rate = dfll_clk_set_rate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1101,6 +1052,55 @@ static void dfll_unregister_clk(struct tegra_dfll *td)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#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)
|
static int attr_enable_get(void *data, u64 *val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,18 +125,29 @@ static struct tegra_audio2x_clk_initdata audio2x_clks[] = {
|
||||||
|
|
||||||
void __init tegra_audio_clk_init(void __iomem *clk_base,
|
void __init tegra_audio_clk_init(void __iomem *clk_base,
|
||||||
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
|
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
|
||||||
struct tegra_clk_pll_params *pll_a_params)
|
struct tegra_audio_clk_info *audio_info,
|
||||||
|
unsigned int num_plls)
|
||||||
{
|
{
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct clk **dt_clk;
|
struct clk **dt_clk;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* PLLA */
|
if (!audio_info || num_plls < 1) {
|
||||||
dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks);
|
pr_err("No audio data passed to tegra_audio_clk_init\n");
|
||||||
if (dt_clk) {
|
WARN_ON(1);
|
||||||
clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base,
|
return;
|
||||||
pmc_base, 0, pll_a_params, NULL);
|
}
|
||||||
*dt_clk = clk;
|
|
||||||
|
for (i = 0; i < num_plls; i++) {
|
||||||
|
struct tegra_audio_clk_info *info = &audio_info[i];
|
||||||
|
|
||||||
|
dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks);
|
||||||
|
if (dt_clk) {
|
||||||
|
clk = tegra_clk_register_pll(info->name, info->parent,
|
||||||
|
clk_base, pmc_base, 0, info->pll_params,
|
||||||
|
NULL);
|
||||||
|
*dt_clk = clk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PLLA_OUT0 */
|
/* PLLA_OUT0 */
|
||||||
|
|
|
@ -933,6 +933,10 @@ static u32 mux_pllm_pllc2_c_c3_pllp_plla_idx[] = {
|
||||||
[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
|
[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct tegra_audio_clk_info tegra114_audio_plls[] = {
|
||||||
|
{ "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
|
||||||
|
};
|
||||||
|
|
||||||
static struct clk **clks;
|
static struct clk **clks;
|
||||||
|
|
||||||
static unsigned long osc_freq;
|
static unsigned long osc_freq;
|
||||||
|
@ -1481,7 +1485,9 @@ static void __init tegra114_clock_init(struct device_node *np)
|
||||||
tegra114_fixed_clk_init(clk_base);
|
tegra114_fixed_clk_init(clk_base);
|
||||||
tegra114_pll_init(clk_base, pmc_base);
|
tegra114_pll_init(clk_base, pmc_base);
|
||||||
tegra114_periph_clk_init(clk_base, pmc_base);
|
tegra114_periph_clk_init(clk_base, pmc_base);
|
||||||
tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params);
|
tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks,
|
||||||
|
tegra114_audio_plls,
|
||||||
|
ARRAY_SIZE(tegra114_audio_plls));
|
||||||
tegra_pmc_clk_init(pmc_base, tegra114_clks);
|
tegra_pmc_clk_init(pmc_base, tegra114_clks);
|
||||||
tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
|
tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
|
||||||
&pll_x_params);
|
&pll_x_params);
|
||||||
|
|
|
@ -1417,6 +1417,10 @@ static struct tegra_clk_init_table tegra132_init_table[] __initdata = {
|
||||||
{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
|
{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct tegra_audio_clk_info tegra124_audio_plls[] = {
|
||||||
|
{ "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
|
* tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs
|
||||||
*
|
*
|
||||||
|
@ -1555,7 +1559,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
|
||||||
tegra_fixed_clk_init(tegra124_clks);
|
tegra_fixed_clk_init(tegra124_clks);
|
||||||
tegra124_pll_init(clk_base, pmc_base);
|
tegra124_pll_init(clk_base, pmc_base);
|
||||||
tegra124_periph_clk_init(clk_base, pmc_base);
|
tegra124_periph_clk_init(clk_base, pmc_base);
|
||||||
tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params);
|
tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
|
||||||
|
tegra124_audio_plls,
|
||||||
|
ARRAY_SIZE(tegra124_audio_plls));
|
||||||
tegra_pmc_clk_init(pmc_base, tegra124_clks);
|
tegra_pmc_clk_init(pmc_base, tegra124_clks);
|
||||||
|
|
||||||
/* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
|
/* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */
|
||||||
|
|
|
@ -1405,6 +1405,10 @@ static const struct of_device_id pmc_match[] __initconst = {
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct tegra_audio_clk_info tegra30_audio_plls[] = {
|
||||||
|
{ "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
|
||||||
|
};
|
||||||
|
|
||||||
static void __init tegra30_clock_init(struct device_node *np)
|
static void __init tegra30_clock_init(struct device_node *np)
|
||||||
{
|
{
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
|
@ -1442,7 +1446,9 @@ static void __init tegra30_clock_init(struct device_node *np)
|
||||||
tegra30_pll_init();
|
tegra30_pll_init();
|
||||||
tegra30_super_clk_init();
|
tegra30_super_clk_init();
|
||||||
tegra30_periph_clk_init();
|
tegra30_periph_clk_init();
|
||||||
tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params);
|
tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks,
|
||||||
|
tegra30_audio_plls,
|
||||||
|
ARRAY_SIZE(tegra30_audio_plls));
|
||||||
tegra_pmc_clk_init(pmc_base, tegra30_clks);
|
tegra_pmc_clk_init(pmc_base, tegra30_clks);
|
||||||
|
|
||||||
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
|
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct div_nmp {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct clk_pll_params - PLL parameters
|
* struct tegra_clk_pll_params - PLL parameters
|
||||||
*
|
*
|
||||||
* @input_min: Minimum input frequency
|
* @input_min: Minimum input frequency
|
||||||
* @input_max: Maximum input frequency
|
* @input_max: Maximum input frequency
|
||||||
|
@ -168,9 +168,45 @@ struct div_nmp {
|
||||||
* @base_reg: PLL base reg offset
|
* @base_reg: PLL base reg offset
|
||||||
* @misc_reg: PLL misc reg offset
|
* @misc_reg: PLL misc reg offset
|
||||||
* @lock_reg: PLL lock reg offset
|
* @lock_reg: PLL lock reg offset
|
||||||
* @lock_bit_idx: Bit index for PLL lock status
|
* @lock_mask: Bitmask for PLL lock status
|
||||||
* @lock_enable_bit_idx: Bit index to enable PLL lock
|
* @lock_enable_bit_idx: Bit index to enable PLL lock
|
||||||
|
* @iddq_reg: PLL IDDQ register offset
|
||||||
|
* @iddq_bit_idx: Bit index to enable PLL IDDQ
|
||||||
|
* @aux_reg: AUX register offset
|
||||||
|
* @dyn_ramp_reg: Dynamic ramp control register offset
|
||||||
|
* @ext_misc_reg: Miscellaneous control register offsets
|
||||||
|
* @pmc_divnm_reg: n, m divider PMC override register offset (PLLM)
|
||||||
|
* @pmc_divp_reg: p divider PMC override register offset (PLLM)
|
||||||
|
* @flags: PLL flags
|
||||||
|
* @stepa_shift: Dynamic ramp step A field shift
|
||||||
|
* @stepb_shift: Dynamic ramp step B field shift
|
||||||
* @lock_delay: Delay in us if PLL lock is not used
|
* @lock_delay: Delay in us if PLL lock is not used
|
||||||
|
* @max_p: maximum value for the p divider
|
||||||
|
* @pdiv_tohw: mapping of p divider to register values
|
||||||
|
* @div_nmp: offsets and widths on n, m and p fields
|
||||||
|
* @freq_table: array of frequencies supported by PLL
|
||||||
|
* @fixed_rate: PLL rate if it is fixed
|
||||||
|
*
|
||||||
|
* Flags:
|
||||||
|
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
|
||||||
|
* PLL locking. If not set it will use lock_delay value to wait.
|
||||||
|
* TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
|
||||||
|
* to be programmed to change output frequency of the PLL.
|
||||||
|
* TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
|
||||||
|
* to be programmed to change output frequency of the PLL.
|
||||||
|
* TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
|
||||||
|
* to be programmed to change output frequency of the PLL.
|
||||||
|
* TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
|
||||||
|
* that it is PLLU and invert post divider value.
|
||||||
|
* TEGRA_PLLM - PLLM has additional override settings in PMC. This
|
||||||
|
* flag indicates that it is PLLM and use override settings.
|
||||||
|
* TEGRA_PLL_FIXED - We are not supposed to change output frequency
|
||||||
|
* of some plls.
|
||||||
|
* TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
|
||||||
|
* TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
|
||||||
|
* base register.
|
||||||
|
* TEGRA_PLL_BYPASS - PLL has bypass bit
|
||||||
|
* TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
|
||||||
*/
|
*/
|
||||||
struct tegra_clk_pll_params {
|
struct tegra_clk_pll_params {
|
||||||
unsigned long input_min;
|
unsigned long input_min;
|
||||||
|
@ -203,49 +239,6 @@ struct tegra_clk_pll_params {
|
||||||
unsigned long fixed_rate;
|
unsigned long fixed_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* struct tegra_clk_pll - Tegra PLL clock
|
|
||||||
*
|
|
||||||
* @hw: handle between common and hardware-specifix interfaces
|
|
||||||
* @clk_base: address of CAR controller
|
|
||||||
* @pmc: address of PMC, required to read override bits
|
|
||||||
* @freq_table: array of frequencies supported by PLL
|
|
||||||
* @params: PLL parameters
|
|
||||||
* @flags: PLL flags
|
|
||||||
* @fixed_rate: PLL rate if it is fixed
|
|
||||||
* @lock: register lock
|
|
||||||
*
|
|
||||||
* Flags:
|
|
||||||
* TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
|
|
||||||
* PLL locking. If not set it will use lock_delay value to wait.
|
|
||||||
* TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
|
|
||||||
* to be programmed to change output frequency of the PLL.
|
|
||||||
* TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
|
|
||||||
* to be programmed to change output frequency of the PLL.
|
|
||||||
* TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
|
|
||||||
* to be programmed to change output frequency of the PLL.
|
|
||||||
* TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
|
|
||||||
* that it is PLLU and invert post divider value.
|
|
||||||
* TEGRA_PLLM - PLLM has additional override settings in PMC. This
|
|
||||||
* flag indicates that it is PLLM and use override settings.
|
|
||||||
* TEGRA_PLL_FIXED - We are not supposed to change output frequency
|
|
||||||
* of some plls.
|
|
||||||
* TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
|
|
||||||
* TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
|
|
||||||
* base register.
|
|
||||||
* TEGRA_PLL_BYPASS - PLL has bypass bit
|
|
||||||
* TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
|
|
||||||
*/
|
|
||||||
struct tegra_clk_pll {
|
|
||||||
struct clk_hw hw;
|
|
||||||
void __iomem *clk_base;
|
|
||||||
void __iomem *pmc;
|
|
||||||
spinlock_t *lock;
|
|
||||||
struct tegra_clk_pll_params *params;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
|
|
||||||
|
|
||||||
#define TEGRA_PLL_USE_LOCK BIT(0)
|
#define TEGRA_PLL_USE_LOCK BIT(0)
|
||||||
#define TEGRA_PLL_HAS_CPCON BIT(1)
|
#define TEGRA_PLL_HAS_CPCON BIT(1)
|
||||||
#define TEGRA_PLL_SET_LFCON BIT(2)
|
#define TEGRA_PLL_SET_LFCON BIT(2)
|
||||||
|
@ -258,6 +251,40 @@ struct tegra_clk_pll {
|
||||||
#define TEGRA_PLL_BYPASS BIT(9)
|
#define TEGRA_PLL_BYPASS BIT(9)
|
||||||
#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
|
#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tegra_clk_pll - Tegra PLL clock
|
||||||
|
*
|
||||||
|
* @hw: handle between common and hardware-specifix interfaces
|
||||||
|
* @clk_base: address of CAR controller
|
||||||
|
* @pmc: address of PMC, required to read override bits
|
||||||
|
* @lock: register lock
|
||||||
|
* @params: PLL parameters
|
||||||
|
*/
|
||||||
|
struct tegra_clk_pll {
|
||||||
|
struct clk_hw hw;
|
||||||
|
void __iomem *clk_base;
|
||||||
|
void __iomem *pmc;
|
||||||
|
spinlock_t *lock;
|
||||||
|
struct tegra_clk_pll_params *params;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tegra_audio_clk_info - Tegra Audio Clk Information
|
||||||
|
*
|
||||||
|
* @name: name for the audio pll
|
||||||
|
* @pll_params: pll_params for audio pll
|
||||||
|
* @clk_id: clk_ids for the audio pll
|
||||||
|
* @parent: name of the parent of the audio pll
|
||||||
|
*/
|
||||||
|
struct tegra_audio_clk_info {
|
||||||
|
char *name;
|
||||||
|
struct tegra_clk_pll_params *pll_params;
|
||||||
|
int clk_id;
|
||||||
|
char *parent;
|
||||||
|
};
|
||||||
|
|
||||||
extern const struct clk_ops tegra_clk_pll_ops;
|
extern const struct clk_ops tegra_clk_pll_ops;
|
||||||
extern const struct clk_ops tegra_clk_plle_ops;
|
extern const struct clk_ops tegra_clk_plle_ops;
|
||||||
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
|
struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
|
||||||
|
@ -610,7 +637,8 @@ void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
|
||||||
|
|
||||||
void tegra_audio_clk_init(void __iomem *clk_base,
|
void tegra_audio_clk_init(void __iomem *clk_base,
|
||||||
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
|
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
|
||||||
struct tegra_clk_pll_params *pll_params);
|
struct tegra_audio_clk_info *audio_info,
|
||||||
|
unsigned int num_plls);
|
||||||
|
|
||||||
void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
|
void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
|
||||||
struct tegra_clk *tegra_clks,
|
struct tegra_clk *tegra_clks,
|
||||||
|
|
|
@ -78,13 +78,6 @@ static int build_opp_table(const struct cvb_table *d,
|
||||||
if (!table->freq || (table->freq > max_freq))
|
if (!table->freq || (table->freq > max_freq))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME after clk_round_rate/clk_determine_rate prototypes
|
|
||||||
* have been updated
|
|
||||||
*/
|
|
||||||
if (table->freq & (1<<31))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dfll_mv = get_cvb_voltage(
|
dfll_mv = get_cvb_voltage(
|
||||||
speedo_value, d->speedo_scale, &table->coefficients);
|
speedo_value, d->speedo_scale, &table->coefficients);
|
||||||
dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align);
|
dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align);
|
||||||
|
|
Loading…
Add table
Reference in a new issue