ARM: tegra: Implement clk_m
On currently supported SoCs, clk_m always runs at the same frequency as the oscillator input. However newer SoC generations such as Tegra210 no longer have that restriction. Prepare for that by separating clk_m from the oscillator clock and allow SoC code to override the clk_m rate. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
parent
70bcb43e7d
commit
c043c0259c
@ -44,6 +44,9 @@ enum {
|
||||
/* return the current oscillator clock frequency */
|
||||
enum clock_osc_freq clock_get_osc_freq(void);
|
||||
|
||||
/* return the clk_m frequency */
|
||||
unsigned int clk_m_get_rate(unsigned int parent_rate);
|
||||
|
||||
/**
|
||||
* Start PLL using the provided configuration parameters.
|
||||
*
|
||||
@ -338,8 +341,8 @@ void arch_timer_init(void);
|
||||
|
||||
void tegra30_set_up_pllp(void);
|
||||
|
||||
/* Number of PLL-based clocks (i.e. not OSC or 32KHz) */
|
||||
#define CLOCK_ID_PLL_COUNT (CLOCK_ID_COUNT - 2)
|
||||
/* Number of PLL-based clocks (i.e. not OSC, MCLK or 32KHz) */
|
||||
#define CLOCK_ID_PLL_COUNT (CLOCK_ID_COUNT - 3)
|
||||
|
||||
struct clk_pll_info {
|
||||
u32 m_shift:5; /* DIVM_SHIFT */
|
||||
|
@ -38,6 +38,7 @@ enum clock_id {
|
||||
/* These are the base clocks (inputs to the Tegra SOC) */
|
||||
CLOCK_ID_32KHZ,
|
||||
CLOCK_ID_OSC,
|
||||
CLOCK_ID_CLK_M,
|
||||
|
||||
CLOCK_ID_COUNT, /* number of PLLs */
|
||||
CLOCK_ID_DISPLAY2, /* placeholder */
|
||||
|
@ -30,6 +30,7 @@ enum clock_id {
|
||||
/* These are the base clocks (inputs to the Tegra SoC) */
|
||||
CLOCK_ID_32KHZ,
|
||||
CLOCK_ID_OSC,
|
||||
CLOCK_ID_CLK_M,
|
||||
|
||||
CLOCK_ID_COUNT, /* number of PLLs */
|
||||
|
||||
|
@ -29,6 +29,7 @@ enum clock_id {
|
||||
/* These are the base clocks (inputs to the Tegra SOC) */
|
||||
CLOCK_ID_32KHZ,
|
||||
CLOCK_ID_OSC,
|
||||
CLOCK_ID_CLK_M,
|
||||
|
||||
CLOCK_ID_COUNT, /* number of clocks */
|
||||
CLOCK_ID_NONE = -1,
|
||||
|
@ -30,6 +30,7 @@ enum clock_id {
|
||||
/* These are the base clocks (inputs to the Tegra SoC) */
|
||||
CLOCK_ID_32KHZ,
|
||||
CLOCK_ID_OSC,
|
||||
CLOCK_ID_CLK_M,
|
||||
|
||||
CLOCK_ID_COUNT, /* number of PLLs */
|
||||
|
||||
|
@ -38,6 +38,7 @@ enum clock_id {
|
||||
/* These are the base clocks (inputs to the Tegra SOC) */
|
||||
CLOCK_ID_32KHZ,
|
||||
CLOCK_ID_OSC,
|
||||
CLOCK_ID_CLK_M,
|
||||
|
||||
CLOCK_ID_COUNT, /* number of PLLs */
|
||||
CLOCK_ID_DISPLAY2, /* Tegra3, placeholder */
|
||||
|
@ -461,6 +461,11 @@ void reset_cmplx_set_enable(int cpu, int which, int reset)
|
||||
writel(mask, &clkrst->crc_cpu_cmplx_clr);
|
||||
}
|
||||
|
||||
unsigned int __weak clk_m_get_rate(unsigned int parent_rate)
|
||||
{
|
||||
return parent_rate;
|
||||
}
|
||||
|
||||
unsigned clock_get_rate(enum clock_id clkid)
|
||||
{
|
||||
struct clk_pll *pll;
|
||||
@ -472,6 +477,9 @@ unsigned clock_get_rate(enum clock_id clkid)
|
||||
if (clkid == CLOCK_ID_OSC)
|
||||
return parent_rate;
|
||||
|
||||
if (clkid == CLOCK_ID_CLK_M)
|
||||
return clk_m_get_rate(parent_rate);
|
||||
|
||||
pll = get_pll(clkid);
|
||||
if (!pll)
|
||||
return 0;
|
||||
@ -622,8 +630,10 @@ void clock_init(void)
|
||||
pll_rate[CLOCK_ID_XCPU] = clock_get_rate(CLOCK_ID_XCPU);
|
||||
pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
|
||||
pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
|
||||
pll_rate[CLOCK_ID_CLK_M] = clock_get_rate(CLOCK_ID_CLK_M);
|
||||
|
||||
debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
|
||||
debug("CLKM = %d\n", pll_rate[CLOCK_ID_CLK_M]);
|
||||
debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]);
|
||||
debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
|
||||
debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
|
||||
|
@ -998,6 +998,17 @@ void clock_early_init(void)
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
unsigned int clk_m_get_rate(unsigned parent_rate)
|
||||
{
|
||||
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
|
||||
u32 value, div;
|
||||
|
||||
value = readl(&clkrst->crc_spare_reg0);
|
||||
div = ((value >> 2) & 0x3) + 1;
|
||||
|
||||
return parent_rate / div;
|
||||
}
|
||||
|
||||
void arch_timer_init(void)
|
||||
{
|
||||
struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;
|
||||
|
Loading…
Reference in New Issue
Block a user