mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-18 19:05:39 +00:00
clk: tegra: Changes for v4.7-rc1
This set of changes contains a bunch of cleanups and minor fixes along with some new clocks, mainly on Tegra210, in preparation for supporting DisplayPort and HDMI 2.0. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJXI3fsAAoJEN0jrNd/PrOho7sP/3W87IOP5Ga+0CAuiBfl3oyx 99nJMzloiHSSe9aH1w9CZJEXr47iCmfN7yoXp0xCx0CAT/6lTlnzIE9cpblvxJLY GXwxpIHDFWndmwvnBTaw5YN8C/DjfgE8KPIYArE9yvP0X1lnU0IdbcMXT5Gu31ny 9Sh9csgZNcKJyTJ4VgzVJkpHWjE5/ngcud0JfuUiQNc3VsJInGroYxdE16WeYDPq zP+5LXPEZAJu/GJPFBtySnhaBcr6Nk/HQ4X1M8/fC5ocA4TfxWZTHqXg6RyHIgJM flM69aeh0uBlK5TEX99W7OiOTpXog8HSukrjMw53lJT69uitxRkt4RLm5PStp4Gr fMClyJzujF2FTO3+TXvLnyj0MwrFvmQHboFqDJUBFJ4XFwZAZH43v9dXVFlGltib qThUiSyzljjeco6XPRLTkHNjntA3rwixCb4Lq2J8MHgf7O2DSQuCBtuBswVXKyQQ JfQAOTPNzzCXA7NWJ34pbNaM6Ex0pPJFGQs+5Mpzo5XAXc9od/79+4ht4tJSZ+hb Su5oRlv0+EU44MddKOBX5FPBbBnI6lBl8fADiM+ld9oDdlHHgkqMxlradhjIWY0Q 9uz+qjUu6VrmvkCxNe6s0yepwHYoeBpbrmRIj2ZiokXcH4kyltpL8XpOvuWhm4pP tYmTNJJmCb/hd6MZhiKv =HcjN -----END PGP SIGNATURE----- Merge tag 'tegra-for-4.7-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-next Pull tegra clk driver changes from Thierry Reding: This set of changes contains a bunch of cleanups and minor fixes along with some new clocks, mainly on Tegra210, in preparation for supporting DisplayPort and HDMI 2.0. * tag 'tegra-for-4.7-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: clk: tegra: dfll: Reformat CVB frequency table clk: tegra: dfll: Properly clean up on failure and removal clk: tegra: dfll: Make code more comprehensible clk: tegra: dfll: Reference CVB table instead of copying data clk: tegra: dfll: Update kerneldoc clk: tegra: Fix PLL_U post divider and initial rate on Tegra30 clk: tegra: Initialize PLL_C to sane rate on Tegra30 clk: tegra: Fix pllre Tegra210 and add pll_re_out1 clk: tegra: Add sor_safe clock clk: tegra: dpaux and dpaux1 are fixed factor clocks clk: tegra: Add dpaux1 clock clk: tegra: Use correct parent for dpaux clock clk: tegra: Add fixed factor peripheral clock type clk: tegra: Special-case mipi-cal parent on Tegra114 clk: tegra: Remove trailing blank line clk: tegra: Constify peripheral clock registers clk: tegra: Add interface to enable hardware control of SATA/XUSB PLLs
This commit is contained in:
commit
5bc7532497
@ -3,6 +3,7 @@ obj-y += clk-audio-sync.o
|
||||
obj-y += clk-dfll.o
|
||||
obj-y += clk-divider.o
|
||||
obj-y += clk-periph.o
|
||||
obj-y += clk-periph-fixed.o
|
||||
obj-y += clk-periph-gate.o
|
||||
obj-y += clk-pll.o
|
||||
obj-y += clk-pll-out.o
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include "clk-dfll.h"
|
||||
#include "cvb.h"
|
||||
|
||||
/*
|
||||
* DFLL control registers - access via dfll_{readl,writel}
|
||||
@ -442,8 +443,8 @@ static void dfll_tune_low(struct tegra_dfll *td)
|
||||
{
|
||||
td->tune_range = DFLL_TUNE_LOW;
|
||||
|
||||
dfll_writel(td, td->soc->tune0_low, DFLL_TUNE0);
|
||||
dfll_writel(td, td->soc->tune1, DFLL_TUNE1);
|
||||
dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune0_low, DFLL_TUNE0);
|
||||
dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune1, DFLL_TUNE1);
|
||||
dfll_wmb(td);
|
||||
|
||||
if (td->soc->set_clock_trimmers_low)
|
||||
@ -1449,7 +1450,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
|
||||
}
|
||||
v_max = dev_pm_opp_get_voltage(opp);
|
||||
|
||||
v = td->soc->min_millivolts * 1000;
|
||||
v = td->soc->cvb->min_millivolts * 1000;
|
||||
lut = find_vdd_map_entry_exact(td, v);
|
||||
if (lut < 0)
|
||||
goto out;
|
||||
@ -1461,7 +1462,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
|
||||
break;
|
||||
v_opp = dev_pm_opp_get_voltage(opp);
|
||||
|
||||
if (v_opp <= td->soc->min_millivolts * 1000)
|
||||
if (v_opp <= td->soc->cvb->min_millivolts * 1000)
|
||||
td->dvco_rate_min = dev_pm_opp_get_freq(opp);
|
||||
|
||||
for (;;) {
|
||||
@ -1490,7 +1491,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
|
||||
|
||||
if (!td->dvco_rate_min)
|
||||
dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n",
|
||||
td->soc->min_millivolts);
|
||||
td->soc->cvb->min_millivolts);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
|
@ -24,22 +24,18 @@
|
||||
|
||||
/**
|
||||
* struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver
|
||||
* @opp_dev: struct device * that holds the OPP table for the DFLL
|
||||
* @min_millivolts: minimum voltage (in mV) that the DFLL can operate
|
||||
* @tune0_low: DFLL tuning register 0 (low voltage range)
|
||||
* @tune0_high: DFLL tuning register 0 (high voltage range)
|
||||
* @tune1: DFLL tuning register 1
|
||||
* @assert_dvco_reset: fn ptr to place the DVCO in reset
|
||||
* @deassert_dvco_reset: fn ptr to release the DVCO reset
|
||||
* @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage
|
||||
* @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage
|
||||
* @dev: struct device * that holds the OPP table for the DFLL
|
||||
* @max_freq: maximum frequency supported on this SoC
|
||||
* @cvb: CPU frequency table for this SoC
|
||||
* @init_clock_trimmers: callback to initialize clock trimmers
|
||||
* @set_clock_trimmers_high: callback to tune clock trimmers for high voltage
|
||||
* @set_clock_trimmers_low: callback to tune clock trimmers for low voltage
|
||||
*/
|
||||
struct tegra_dfll_soc_data {
|
||||
struct device *dev;
|
||||
unsigned int min_millivolts;
|
||||
u32 tune0_low;
|
||||
u32 tune0_high;
|
||||
u32 tune1;
|
||||
unsigned long max_freq;
|
||||
const struct cvb_table *cvb;
|
||||
|
||||
void (*init_clock_trimmers)(void);
|
||||
void (*set_clock_trimmers_high)(void);
|
||||
void (*set_clock_trimmers_low)(void);
|
||||
|
@ -71,6 +71,7 @@ enum clk_id {
|
||||
tegra_clk_disp2_8,
|
||||
tegra_clk_dp2,
|
||||
tegra_clk_dpaux,
|
||||
tegra_clk_dpaux1,
|
||||
tegra_clk_dsialp,
|
||||
tegra_clk_dsia_mux,
|
||||
tegra_clk_dsiblp,
|
||||
@ -306,6 +307,7 @@ enum clk_id {
|
||||
tegra_clk_xusb_ss_div2,
|
||||
tegra_clk_xusb_ssp_src,
|
||||
tegra_clk_sclk_mux,
|
||||
tegra_clk_sor_safe,
|
||||
tegra_clk_max,
|
||||
};
|
||||
|
||||
|
120
drivers/clk/tegra/clk-periph-fixed.c
Normal file
120
drivers/clk/tegra/clk-periph-fixed.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
static inline struct tegra_clk_periph_fixed *
|
||||
to_tegra_clk_periph_fixed(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct tegra_clk_periph_fixed, hw);
|
||||
}
|
||||
|
||||
static int tegra_clk_periph_fixed_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
|
||||
u32 mask = 1 << (fixed->num % 32), value;
|
||||
|
||||
value = readl(fixed->base + fixed->regs->enb_reg);
|
||||
if (value & mask) {
|
||||
value = readl(fixed->base + fixed->regs->rst_reg);
|
||||
if ((value & mask) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_clk_periph_fixed_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
|
||||
u32 mask = 1 << (fixed->num % 32);
|
||||
|
||||
writel(mask, fixed->base + fixed->regs->enb_set_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_clk_periph_fixed_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
|
||||
u32 mask = 1 << (fixed->num % 32);
|
||||
|
||||
writel(mask, fixed->base + fixed->regs->enb_clr_reg);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
|
||||
unsigned long long rate;
|
||||
|
||||
rate = (unsigned long long)parent_rate * fixed->mul;
|
||||
do_div(rate, fixed->div);
|
||||
|
||||
return (unsigned long)rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops tegra_clk_periph_fixed_ops = {
|
||||
.is_enabled = tegra_clk_periph_fixed_is_enabled,
|
||||
.enable = tegra_clk_periph_fixed_enable,
|
||||
.disable = tegra_clk_periph_fixed_disable,
|
||||
.recalc_rate = tegra_clk_periph_fixed_recalc_rate,
|
||||
};
|
||||
|
||||
struct clk *tegra_clk_register_periph_fixed(const char *name,
|
||||
const char *parent,
|
||||
unsigned long flags,
|
||||
void __iomem *base,
|
||||
unsigned int mul,
|
||||
unsigned int div,
|
||||
unsigned int num)
|
||||
{
|
||||
const struct tegra_clk_periph_regs *regs;
|
||||
struct tegra_clk_periph_fixed *fixed;
|
||||
struct clk_init_data init;
|
||||
struct clk *clk;
|
||||
|
||||
regs = get_reg_bank(num);
|
||||
if (!regs)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
|
||||
if (!fixed)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent ? &parent : NULL;
|
||||
init.num_parents = parent ? 1 : 0;
|
||||
init.ops = &tegra_clk_periph_fixed_ops;
|
||||
|
||||
fixed->base = base;
|
||||
fixed->regs = regs;
|
||||
fixed->mul = mul;
|
||||
fixed->div = div;
|
||||
fixed->num = num;
|
||||
|
||||
fixed->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &fixed->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(fixed);
|
||||
|
||||
return clk;
|
||||
}
|
@ -134,7 +134,7 @@ struct clk *tegra_clk_register_periph_gate(const char *name,
|
||||
struct tegra_clk_periph_gate *gate;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
struct tegra_clk_periph_regs *pregs;
|
||||
const struct tegra_clk_periph_regs *pregs;
|
||||
|
||||
pregs = get_reg_bank(clk_num);
|
||||
if (!pregs)
|
||||
|
@ -145,7 +145,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
struct tegra_clk_periph_regs *bank;
|
||||
const struct tegra_clk_periph_regs *bank;
|
||||
bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV);
|
||||
|
||||
if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) {
|
||||
|
@ -2013,6 +2013,52 @@ struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
|
||||
struct clk *tegra_clk_register_pllre_tegra210(const char *name,
|
||||
const char *parent_name, void __iomem *clk_base,
|
||||
void __iomem *pmc, unsigned long flags,
|
||||
struct tegra_clk_pll_params *pll_params,
|
||||
spinlock_t *lock, unsigned long parent_rate)
|
||||
{
|
||||
u32 val;
|
||||
struct tegra_clk_pll *pll;
|
||||
struct clk *clk;
|
||||
|
||||
pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate);
|
||||
|
||||
if (pll_params->adjust_vco)
|
||||
pll_params->vco_min = pll_params->adjust_vco(pll_params,
|
||||
parent_rate);
|
||||
|
||||
pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
|
||||
if (IS_ERR(pll))
|
||||
return ERR_CAST(pll);
|
||||
|
||||
/* program minimum rate by default */
|
||||
|
||||
val = pll_readl_base(pll);
|
||||
if (val & PLL_BASE_ENABLE)
|
||||
WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) &
|
||||
BIT(pll_params->iddq_bit_idx));
|
||||
else {
|
||||
val = 0x4 << divm_shift(pll);
|
||||
val |= 0x41 << divn_shift(pll);
|
||||
pll_writel_base(val, pll);
|
||||
}
|
||||
|
||||
/* disable lock override */
|
||||
|
||||
val = pll_readl_misc(pll);
|
||||
val &= ~BIT(29);
|
||||
pll_writel_misc(val, pll);
|
||||
|
||||
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
|
||||
&tegra_clk_pllre_ops);
|
||||
if (IS_ERR(clk))
|
||||
kfree(pll);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static int clk_plle_tegra210_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct tegra_clk_pll *pll = to_clk_pll(hw);
|
||||
|
@ -107,4 +107,3 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
|
||||
*dt_clk = clk;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,7 +803,7 @@ static struct tegra_periph_init_data gate_clks[] = {
|
||||
GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0),
|
||||
GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0),
|
||||
GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0),
|
||||
GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0),
|
||||
GATE("mipi-cal", "clk72mhz", 56, 0, tegra_clk_mipi_cal, 0),
|
||||
GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0),
|
||||
GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0),
|
||||
GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0),
|
||||
@ -821,7 +821,6 @@ static struct tegra_periph_init_data gate_clks[] = {
|
||||
GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0),
|
||||
GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0),
|
||||
GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0),
|
||||
GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0),
|
||||
GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0),
|
||||
GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0),
|
||||
GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0),
|
||||
@ -877,7 +876,7 @@ static void __init periph_clk_init(void __iomem *clk_base,
|
||||
struct clk **dt_clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(periph_clks); i++) {
|
||||
struct tegra_clk_periph_regs *bank;
|
||||
const struct tegra_clk_periph_regs *bank;
|
||||
struct tegra_periph_init_data *data;
|
||||
|
||||
data = periph_clks + i;
|
||||
|
@ -743,7 +743,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true },
|
||||
[tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true },
|
||||
[tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true },
|
||||
[tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true },
|
||||
[tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true },
|
||||
[tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true },
|
||||
[tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true },
|
||||
@ -1237,6 +1236,11 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
|
||||
&emc_lock);
|
||||
clks[TEGRA114_CLK_MC] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base,
|
||||
CLK_SET_RATE_PARENT, 56,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA114_CLK_MIPI_CAL] = clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
|
||||
data = &tegra_periph_clk_list[i];
|
||||
clk = tegra_clk_register_periph(data->name,
|
||||
|
@ -47,32 +47,32 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
|
||||
},
|
||||
.speedo_scale = 100,
|
||||
.voltage_scale = 1000,
|
||||
.cvb_table = {
|
||||
{204000000UL, {1112619, -29295, 402} },
|
||||
{306000000UL, {1150460, -30585, 402} },
|
||||
{408000000UL, {1190122, -31865, 402} },
|
||||
{510000000UL, {1231606, -33155, 402} },
|
||||
{612000000UL, {1274912, -34435, 402} },
|
||||
{714000000UL, {1320040, -35725, 402} },
|
||||
{816000000UL, {1366990, -37005, 402} },
|
||||
{918000000UL, {1415762, -38295, 402} },
|
||||
{1020000000UL, {1466355, -39575, 402} },
|
||||
{1122000000UL, {1518771, -40865, 402} },
|
||||
{1224000000UL, {1573009, -42145, 402} },
|
||||
{1326000000UL, {1629068, -43435, 402} },
|
||||
{1428000000UL, {1686950, -44715, 402} },
|
||||
{1530000000UL, {1746653, -46005, 402} },
|
||||
{1632000000UL, {1808179, -47285, 402} },
|
||||
{1734000000UL, {1871526, -48575, 402} },
|
||||
{1836000000UL, {1936696, -49855, 402} },
|
||||
{1938000000UL, {2003687, -51145, 402} },
|
||||
{2014500000UL, {2054787, -52095, 402} },
|
||||
{2116500000UL, {2124957, -53385, 402} },
|
||||
{2218500000UL, {2196950, -54665, 402} },
|
||||
{2320500000UL, {2270765, -55955, 402} },
|
||||
{2422500000UL, {2346401, -57235, 402} },
|
||||
{2524500000UL, {2437299, -58535, 402} },
|
||||
{0, { 0, 0, 0} },
|
||||
.entries = {
|
||||
{ 204000000UL, { 1112619, -29295, 402 } },
|
||||
{ 306000000UL, { 1150460, -30585, 402 } },
|
||||
{ 408000000UL, { 1190122, -31865, 402 } },
|
||||
{ 510000000UL, { 1231606, -33155, 402 } },
|
||||
{ 612000000UL, { 1274912, -34435, 402 } },
|
||||
{ 714000000UL, { 1320040, -35725, 402 } },
|
||||
{ 816000000UL, { 1366990, -37005, 402 } },
|
||||
{ 918000000UL, { 1415762, -38295, 402 } },
|
||||
{ 1020000000UL, { 1466355, -39575, 402 } },
|
||||
{ 1122000000UL, { 1518771, -40865, 402 } },
|
||||
{ 1224000000UL, { 1573009, -42145, 402 } },
|
||||
{ 1326000000UL, { 1629068, -43435, 402 } },
|
||||
{ 1428000000UL, { 1686950, -44715, 402 } },
|
||||
{ 1530000000UL, { 1746653, -46005, 402 } },
|
||||
{ 1632000000UL, { 1808179, -47285, 402 } },
|
||||
{ 1734000000UL, { 1871526, -48575, 402 } },
|
||||
{ 1836000000UL, { 1936696, -49855, 402 } },
|
||||
{ 1938000000UL, { 2003687, -51145, 402 } },
|
||||
{ 2014500000UL, { 2054787, -52095, 402 } },
|
||||
{ 2116500000UL, { 2124957, -53385, 402 } },
|
||||
{ 2218500000UL, { 2196950, -54665, 402 } },
|
||||
{ 2320500000UL, { 2270765, -55955, 402 } },
|
||||
{ 2422500000UL, { 2346401, -57235, 402 } },
|
||||
{ 2524500000UL, { 2437299, -58535, 402 } },
|
||||
{ 0UL, { 0, 0, 0 } },
|
||||
},
|
||||
.cpu_dfll_data = {
|
||||
.tune0_low = 0x005020ff,
|
||||
@ -84,9 +84,8 @@ static const struct cvb_table tegra124_cpu_cvb_tables[] = {
|
||||
|
||||
static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
|
||||
{
|
||||
int process_id, speedo_id, speedo_value;
|
||||
int process_id, speedo_id, speedo_value, err;
|
||||
struct tegra_dfll_soc_data *soc;
|
||||
const struct cvb_table *cvb;
|
||||
|
||||
process_id = tegra_sku_info.cpu_process_id;
|
||||
speedo_id = tegra_sku_info.cpu_speedo_id;
|
||||
@ -108,23 +107,41 @@ static int tegra124_dfll_fcpu_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cvb = tegra_cvb_build_opp_table(tegra124_cpu_cvb_tables,
|
||||
ARRAY_SIZE(tegra124_cpu_cvb_tables),
|
||||
process_id, speedo_id, speedo_value,
|
||||
cpu_max_freq_table[speedo_id],
|
||||
soc->dev);
|
||||
if (IS_ERR(cvb)) {
|
||||
dev_err(&pdev->dev, "couldn't build OPP table: %ld\n",
|
||||
PTR_ERR(cvb));
|
||||
return PTR_ERR(cvb);
|
||||
soc->max_freq = cpu_max_freq_table[speedo_id];
|
||||
|
||||
soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables,
|
||||
ARRAY_SIZE(tegra124_cpu_cvb_tables),
|
||||
process_id, speedo_id, speedo_value,
|
||||
soc->max_freq);
|
||||
if (IS_ERR(soc->cvb)) {
|
||||
dev_err(&pdev->dev, "couldn't add OPP table: %ld\n",
|
||||
PTR_ERR(soc->cvb));
|
||||
return PTR_ERR(soc->cvb);
|
||||
}
|
||||
|
||||
soc->min_millivolts = cvb->min_millivolts;
|
||||
soc->tune0_low = cvb->cpu_dfll_data.tune0_low;
|
||||
soc->tune0_high = cvb->cpu_dfll_data.tune0_high;
|
||||
soc->tune1 = cvb->cpu_dfll_data.tune1;
|
||||
err = tegra_dfll_register(pdev, soc);
|
||||
if (err < 0) {
|
||||
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
|
||||
return err;
|
||||
}
|
||||
|
||||
return tegra_dfll_register(pdev, soc);
|
||||
platform_set_drvdata(pdev, soc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev);
|
||||
int err;
|
||||
|
||||
err = tegra_dfll_unregister(pdev);
|
||||
if (err < 0)
|
||||
dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err);
|
||||
|
||||
tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id tegra124_dfll_fcpu_of_match[] = {
|
||||
@ -140,7 +157,7 @@ static const struct dev_pm_ops tegra124_dfll_pm_ops = {
|
||||
|
||||
static struct platform_driver tegra124_dfll_fcpu_driver = {
|
||||
.probe = tegra124_dfll_fcpu_probe,
|
||||
.remove = tegra_dfll_unregister,
|
||||
.remove = tegra124_dfll_fcpu_remove,
|
||||
.driver = {
|
||||
.name = "tegra124-dfll",
|
||||
.of_match_table = tegra124_dfll_fcpu_of_match,
|
||||
|
@ -1155,6 +1155,10 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
|
||||
1, 2);
|
||||
clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base,
|
||||
1, 17, 181);
|
||||
clks[TEGRA124_CLK_DPAUX] = clk;
|
||||
|
||||
clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
|
||||
clk_base + PLLD_MISC, 30, 0, &pll_d_lock);
|
||||
clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk;
|
||||
|
@ -92,6 +92,7 @@
|
||||
#define PLLE_AUX 0x48c
|
||||
#define PLLRE_BASE 0x4c4
|
||||
#define PLLRE_MISC0 0x4c8
|
||||
#define PLLRE_OUT1 0x4cc
|
||||
#define PLLDP_BASE 0x590
|
||||
#define PLLDP_MISC 0x594
|
||||
|
||||
@ -175,6 +176,19 @@
|
||||
#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
|
||||
#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
|
||||
|
||||
#define SATA_PLL_CFG0 0x490
|
||||
#define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
|
||||
#define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2)
|
||||
#define SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
|
||||
#define SATA_PLL_CFG0_SEQ_ENABLE BIT(24)
|
||||
|
||||
#define XUSBIO_PLL_CFG0 0x51c
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
|
||||
#define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2)
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6)
|
||||
#define XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
|
||||
#define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
|
||||
|
||||
#define UTMIPLL_HW_PWRDN_CFG0 0x52c
|
||||
#define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31)
|
||||
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25)
|
||||
@ -416,6 +430,51 @@ static const char *mux_pllmcp_clkm[] = {
|
||||
#define PLLU_MISC0_WRITE_MASK 0xbfffffff
|
||||
#define PLLU_MISC1_WRITE_MASK 0x00000007
|
||||
|
||||
void tegra210_xusb_pll_hw_control_enable(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
|
||||
val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
|
||||
XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
|
||||
val |= XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
|
||||
XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
|
||||
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_control_enable);
|
||||
|
||||
void tegra210_xusb_pll_hw_sequence_start(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
|
||||
val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
|
||||
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_sequence_start);
|
||||
|
||||
void tegra210_sata_pll_hw_control_enable(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
|
||||
val &= ~SATA_PLL_CFG0_PADPLL_RESET_SWCTL;
|
||||
val |= SATA_PLL_CFG0_PADPLL_USE_LOCKDET |
|
||||
SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ;
|
||||
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_control_enable);
|
||||
|
||||
void tegra210_sata_pll_hw_sequence_start(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
|
||||
val |= SATA_PLL_CFG0_SEQ_ENABLE;
|
||||
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_sequence_start);
|
||||
|
||||
static inline void _pll_misc_chk_default(void __iomem *base,
|
||||
struct tegra_clk_pll_params *params,
|
||||
u8 misc_num, u32 default_val, u32 mask)
|
||||
@ -2092,6 +2151,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true },
|
||||
[tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true },
|
||||
[tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true },
|
||||
[tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true },
|
||||
[tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true },
|
||||
[tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true },
|
||||
[tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
|
||||
@ -2403,6 +2463,18 @@ static __init void tegra210_periph_clk_init(void __iomem *clk_base,
|
||||
1, 2);
|
||||
clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base,
|
||||
1, 17, 181);
|
||||
clks[TEGRA210_CLK_DPAUX] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_fixed("dpaux1", "pll_p", 0, clk_base,
|
||||
1, 17, 207);
|
||||
clks[TEGRA210_CLK_DPAUX1] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_fixed("sor_safe", "pll_p", 0, clk_base,
|
||||
1, 17, 222);
|
||||
clks[TEGRA210_CLK_SOR_SAFE] = clk;
|
||||
|
||||
/* pll_d_dsi_out */
|
||||
clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
|
||||
clk_base + PLLD_MISC0, 21, 0, &pll_d_lock);
|
||||
@ -2582,8 +2654,10 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
clks[TEGRA210_CLK_PLL_D_OUT0] = clk;
|
||||
|
||||
/* PLLRE */
|
||||
clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
|
||||
0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq);
|
||||
clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref",
|
||||
clk_base, pmc, 0,
|
||||
&pll_re_vco_params,
|
||||
&pll_re_lock, pll_ref_freq);
|
||||
clk_register_clkdev(clk, "pll_re_vco", NULL);
|
||||
clks[TEGRA210_CLK_PLL_RE_VCO] = clk;
|
||||
|
||||
@ -2593,6 +2667,15 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
clk_register_clkdev(clk, "pll_re_out", NULL);
|
||||
clks[TEGRA210_CLK_PLL_RE_OUT] = clk;
|
||||
|
||||
clk = tegra_clk_register_divider("pll_re_out1_div", "pll_re_vco",
|
||||
clk_base + PLLRE_OUT1, 0,
|
||||
TEGRA_DIVIDER_ROUND_UP,
|
||||
8, 8, 1, NULL);
|
||||
clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div",
|
||||
clk_base + PLLRE_OUT1, 1, 0,
|
||||
CLK_SET_RATE_PARENT, 0, NULL);
|
||||
clks[TEGRA210_CLK_PLL_RE_OUT1] = clk;
|
||||
|
||||
/* PLLE */
|
||||
clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref",
|
||||
clk_base, 0, &pll_e_params, NULL);
|
||||
|
@ -339,11 +339,11 @@ static const struct pdiv_map pllu_p[] = {
|
||||
};
|
||||
|
||||
static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
|
||||
{ 12000000, 480000000, 960, 12, 1, 12 },
|
||||
{ 13000000, 480000000, 960, 13, 1, 12 },
|
||||
{ 16800000, 480000000, 400, 7, 1, 5 },
|
||||
{ 19200000, 480000000, 200, 4, 1, 3 },
|
||||
{ 26000000, 480000000, 960, 26, 1, 12 },
|
||||
{ 12000000, 480000000, 960, 12, 2, 12 },
|
||||
{ 13000000, 480000000, 960, 13, 2, 12 },
|
||||
{ 16800000, 480000000, 400, 7, 2, 5 },
|
||||
{ 19200000, 480000000, 200, 4, 2, 3 },
|
||||
{ 26000000, 480000000, 960, 26, 2, 12 },
|
||||
{ 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
@ -1372,6 +1372,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
|
||||
{ TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 },
|
||||
{ TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 },
|
||||
{ TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 },
|
||||
{ TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
|
||||
{ TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 },
|
||||
{ TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 },
|
||||
{ TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 },
|
||||
@ -1379,6 +1380,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
|
||||
{ TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 },
|
||||
{ TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
|
||||
{ TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
|
||||
{ TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
|
||||
/* must be the last entry */
|
||||
{ TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ static int (*special_reset_assert)(unsigned long);
|
||||
static int (*special_reset_deassert)(unsigned long);
|
||||
static unsigned int num_special_reset;
|
||||
|
||||
static struct tegra_clk_periph_regs periph_regs[] = {
|
||||
static const struct tegra_clk_periph_regs periph_regs[] = {
|
||||
[0] = {
|
||||
.enb_reg = CLK_OUT_ENB_L,
|
||||
.enb_set_reg = CLK_OUT_ENB_SET_L,
|
||||
@ -182,7 +182,7 @@ static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct tegra_clk_periph_regs *get_reg_bank(int clkid)
|
||||
const struct tegra_clk_periph_regs *get_reg_bank(int clkid)
|
||||
{
|
||||
int reg_bank = clkid / 32;
|
||||
|
||||
|
@ -386,6 +386,12 @@ struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
|
||||
struct tegra_clk_pll_params *pll_params,
|
||||
spinlock_t *lock, unsigned long parent_rate);
|
||||
|
||||
struct clk *tegra_clk_register_pllre_tegra210(const char *name,
|
||||
const char *parent_name, void __iomem *clk_base,
|
||||
void __iomem *pmc, unsigned long flags,
|
||||
struct tegra_clk_pll_params *pll_params,
|
||||
spinlock_t *lock, unsigned long parent_rate);
|
||||
|
||||
struct clk *tegra_clk_register_plle_tegra114(const char *name,
|
||||
const char *parent_name,
|
||||
void __iomem *clk_base, unsigned long flags,
|
||||
@ -496,7 +502,7 @@ struct tegra_clk_periph_gate {
|
||||
u8 flags;
|
||||
int clk_num;
|
||||
int *enable_refcnt;
|
||||
struct tegra_clk_periph_regs *regs;
|
||||
const struct tegra_clk_periph_regs *regs;
|
||||
};
|
||||
|
||||
#define to_clk_periph_gate(_hw) \
|
||||
@ -516,6 +522,23 @@ struct clk *tegra_clk_register_periph_gate(const char *name,
|
||||
const char *parent_name, u8 gate_flags, void __iomem *clk_base,
|
||||
unsigned long flags, int clk_num, int *enable_refcnt);
|
||||
|
||||
struct tegra_clk_periph_fixed {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
const struct tegra_clk_periph_regs *regs;
|
||||
unsigned int mul;
|
||||
unsigned int div;
|
||||
unsigned int num;
|
||||
};
|
||||
|
||||
struct clk *tegra_clk_register_periph_fixed(const char *name,
|
||||
const char *parent,
|
||||
unsigned long flags,
|
||||
void __iomem *base,
|
||||
unsigned int mul,
|
||||
unsigned int div,
|
||||
unsigned int num);
|
||||
|
||||
/**
|
||||
* struct clk-periph - peripheral clock
|
||||
*
|
||||
@ -716,7 +739,7 @@ void tegra_init_from_table(struct tegra_clk_init_table *tbl,
|
||||
void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
|
||||
struct clk *clks[], int clk_max);
|
||||
|
||||
struct tegra_clk_periph_regs *get_reg_bank(int clkid);
|
||||
const struct tegra_clk_periph_regs *get_reg_bank(int clkid);
|
||||
struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
|
||||
|
||||
struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
|
||||
|
@ -61,29 +61,28 @@ static int round_voltage(int mv, const struct rail_alignment *align, int up)
|
||||
return mv;
|
||||
}
|
||||
|
||||
static int build_opp_table(const struct cvb_table *d,
|
||||
int speedo_value,
|
||||
unsigned long max_freq,
|
||||
struct device *opp_dev)
|
||||
static int build_opp_table(struct device *dev, const struct cvb_table *table,
|
||||
int speedo_value, unsigned long max_freq)
|
||||
{
|
||||
const struct rail_alignment *align = &table->alignment;
|
||||
int i, ret, dfll_mv, min_mv, max_mv;
|
||||
const struct cvb_table_freq_entry *table = NULL;
|
||||
const struct rail_alignment *align = &d->alignment;
|
||||
|
||||
min_mv = round_voltage(d->min_millivolts, align, UP);
|
||||
max_mv = round_voltage(d->max_millivolts, align, DOWN);
|
||||
min_mv = round_voltage(table->min_millivolts, align, UP);
|
||||
max_mv = round_voltage(table->max_millivolts, align, DOWN);
|
||||
|
||||
for (i = 0; i < MAX_DVFS_FREQS; i++) {
|
||||
table = &d->cvb_table[i];
|
||||
if (!table->freq || (table->freq > max_freq))
|
||||
const struct cvb_table_freq_entry *entry = &table->entries[i];
|
||||
|
||||
if (!entry->freq || (entry->freq > max_freq))
|
||||
break;
|
||||
|
||||
dfll_mv = get_cvb_voltage(
|
||||
speedo_value, d->speedo_scale, &table->coefficients);
|
||||
dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align);
|
||||
dfll_mv = get_cvb_voltage(speedo_value, table->speedo_scale,
|
||||
&entry->coefficients);
|
||||
dfll_mv = round_cvb_voltage(dfll_mv, table->voltage_scale,
|
||||
align);
|
||||
dfll_mv = clamp(dfll_mv, min_mv, max_mv);
|
||||
|
||||
ret = dev_pm_opp_add(opp_dev, table->freq, dfll_mv * 1000);
|
||||
ret = dev_pm_opp_add(dev, entry->freq, dfll_mv * 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -92,7 +91,7 @@ static int build_opp_table(const struct cvb_table *d,
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_cvb_build_opp_table - build OPP table from Tegra CVB tables
|
||||
* tegra_cvb_add_opp_table - build OPP table from Tegra CVB tables
|
||||
* @cvb_tables: array of CVB tables
|
||||
* @sz: size of the previously mentioned array
|
||||
* @process_id: process id of the HW module
|
||||
@ -108,26 +107,42 @@ static int build_opp_table(const struct cvb_table *d,
|
||||
* given @opp_dev. Returns a pointer to the struct cvb_table that matched
|
||||
* or an ERR_PTR on failure.
|
||||
*/
|
||||
const struct cvb_table *tegra_cvb_build_opp_table(
|
||||
const struct cvb_table *cvb_tables,
|
||||
size_t sz, int process_id,
|
||||
int speedo_id, int speedo_value,
|
||||
unsigned long max_rate,
|
||||
struct device *opp_dev)
|
||||
const struct cvb_table *
|
||||
tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables,
|
||||
size_t count, int process_id, int speedo_id,
|
||||
int speedo_value, unsigned long max_freq)
|
||||
{
|
||||
int i, ret;
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < sz; i++) {
|
||||
const struct cvb_table *d = &cvb_tables[i];
|
||||
for (i = 0; i < count; i++) {
|
||||
const struct cvb_table *table = &tables[i];
|
||||
|
||||
if (d->speedo_id != -1 && d->speedo_id != speedo_id)
|
||||
continue;
|
||||
if (d->process_id != -1 && d->process_id != process_id)
|
||||
if (table->speedo_id != -1 && table->speedo_id != speedo_id)
|
||||
continue;
|
||||
|
||||
ret = build_opp_table(d, speedo_value, max_rate, opp_dev);
|
||||
return ret ? ERR_PTR(ret) : d;
|
||||
if (table->process_id != -1 && table->process_id != process_id)
|
||||
continue;
|
||||
|
||||
ret = build_opp_table(dev, table, speedo_value, max_freq);
|
||||
return ret ? ERR_PTR(ret) : table;
|
||||
}
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
void tegra_cvb_remove_opp_table(struct device *dev,
|
||||
const struct cvb_table *table,
|
||||
unsigned long max_freq)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < MAX_DVFS_FREQS; i++) {
|
||||
const struct cvb_table_freq_entry *entry = &table->entries[i];
|
||||
|
||||
if (!entry->freq || (entry->freq > max_freq))
|
||||
break;
|
||||
|
||||
dev_pm_opp_remove(dev, entry->freq);
|
||||
}
|
||||
}
|
||||
|
@ -53,15 +53,16 @@ struct cvb_table {
|
||||
|
||||
int speedo_scale;
|
||||
int voltage_scale;
|
||||
struct cvb_table_freq_entry cvb_table[MAX_DVFS_FREQS];
|
||||
struct cvb_table_freq_entry entries[MAX_DVFS_FREQS];
|
||||
struct cvb_cpu_dfll_data cpu_dfll_data;
|
||||
};
|
||||
|
||||
const struct cvb_table *tegra_cvb_build_opp_table(
|
||||
const struct cvb_table *cvb_tables,
|
||||
size_t sz, int process_id,
|
||||
int speedo_id, int speedo_value,
|
||||
unsigned long max_rate,
|
||||
struct device *opp_dev);
|
||||
const struct cvb_table *
|
||||
tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables,
|
||||
size_t count, int process_id, int speedo_id,
|
||||
int speedo_value, unsigned long max_freq);
|
||||
void tegra_cvb_remove_opp_table(struct device *dev,
|
||||
const struct cvb_table *table,
|
||||
unsigned long max_freq);
|
||||
|
||||
#endif
|
||||
|
@ -346,7 +346,7 @@
|
||||
#define TEGRA210_CLK_PLL_P_OUT_HSIO 316
|
||||
#define TEGRA210_CLK_PLL_P_OUT_XUSB 317
|
||||
#define TEGRA210_CLK_XUSB_SSP_SRC 318
|
||||
/* 319 */
|
||||
#define TEGRA210_CLK_PLL_RE_OUT1 319
|
||||
/* 320 */
|
||||
/* 321 */
|
||||
/* 322 */
|
||||
|
@ -121,4 +121,9 @@ static inline void tegra_cpu_clock_resume(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void tegra210_xusb_pll_hw_control_enable(void);
|
||||
extern void tegra210_xusb_pll_hw_sequence_start(void);
|
||||
extern void tegra210_sata_pll_hw_control_enable(void);
|
||||
extern void tegra210_sata_pll_hw_sequence_start(void);
|
||||
|
||||
#endif /* __LINUX_CLK_TEGRA_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user