summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/clock.c21
-rw-r--r--arch/arm/mach-tegra/tegra114/clock.c9
-rw-r--r--arch/arm/mach-tegra/tegra124/clock.c9
-rw-r--r--arch/arm/mach-tegra/tegra210/Kconfig9
-rw-r--r--arch/arm/mach-tegra/tegra210/clock.c21
5 files changed, 58 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index f9dfcd0..f75c6c6 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -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;
@@ -483,7 +491,16 @@ unsigned clock_get_rate(enum clock_id clkid)
* PLLU uses p_mask/p_shift for VCO on all but T210,
* T210 uses normal DIVP. Handled in pllinfo table.
*/
- divm <<= (base >> pllinfo->p_shift) & pllinfo->p_mask;
+#ifdef CONFIG_TEGRA210
+ /*
+ * PLLP's primary output (pllP_out0) on T210 is the VCO, and divp is
+ * not applied. pllP_out2 does have divp applied. All other pllP_outN
+ * are divided down from pllP_out0. We only support pllP_out0 in
+ * U-Boot at the time of writing this comment.
+ */
+ if (clkid != CLOCK_ID_PERIPH)
+#endif
+ divm <<= (base >> pllinfo->p_shift) & pllinfo->p_mask;
do_div(rate, divm);
return rate;
}
@@ -613,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]);
diff --git a/arch/arm/mach-tegra/tegra114/clock.c b/arch/arm/mach-tegra/tegra114/clock.c
index 5e805a7..e6ef873 100644
--- a/arch/arm/mach-tegra/tegra114/clock.c
+++ b/arch/arm/mach-tegra/tegra114/clock.c
@@ -629,6 +629,11 @@ void clock_early_init(void)
tegra30_set_up_pllp();
+ /* clear IDDQ before accessing any other PLLC registers */
+ pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL];
+ clrbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, PLLC_IDDQ);
+ udelay(2);
+
/*
* PLLC output frequency set to 600Mhz
* PLLD output frequency set to 925Mhz
@@ -679,8 +684,8 @@ void arch_timer_init(void)
struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;
u32 freq, val;
- freq = clock_get_rate(CLOCK_ID_OSC);
- debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq);
+ freq = clock_get_rate(CLOCK_ID_CLK_M);
+ debug("%s: clk_m freq is %dHz [0x%08X]\n", __func__, freq, freq);
/* ARM CNTFRQ */
asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq));
diff --git a/arch/arm/mach-tegra/tegra124/clock.c b/arch/arm/mach-tegra/tegra124/clock.c
index 61e8ab7..1e71146 100644
--- a/arch/arm/mach-tegra/tegra124/clock.c
+++ b/arch/arm/mach-tegra/tegra124/clock.c
@@ -809,6 +809,11 @@ void clock_early_init(void)
tegra30_set_up_pllp();
+ /* clear IDDQ before accessing any other PLLC registers */
+ pllinfo = &tegra_pll_info_table[CLOCK_ID_CGENERAL];
+ clrbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc, PLLC_IDDQ);
+ udelay(2);
+
/*
* PLLC output frequency set to 600Mhz
* PLLD output frequency set to 925Mhz
@@ -859,8 +864,8 @@ void arch_timer_init(void)
struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;
u32 freq, val;
- freq = clock_get_rate(CLOCK_ID_OSC);
- debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq);
+ freq = clock_get_rate(CLOCK_ID_CLK_M);
+ debug("%s: clk_m freq is %dHz [0x%08X]\n", __func__, freq, freq);
/* ARM CNTFRQ */
asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq));
diff --git a/arch/arm/mach-tegra/tegra210/Kconfig b/arch/arm/mach-tegra/tegra210/Kconfig
index bd34db7..b07363a 100644
--- a/arch/arm/mach-tegra/tegra210/Kconfig
+++ b/arch/arm/mach-tegra/tegra210/Kconfig
@@ -18,6 +18,14 @@ config TARGET_P2371_0000
HDMI, USB micro-B port, Ethernet via USB3, USB3 host port, SATA,
a GPIO expansion header, and an analog audio jack.
+config TARGET_P2371_2180
+ bool "NVIDIA Tegra210 P2371-2180 board"
+ help
+ P2371-2180 is a P2180 CPU board married to a P2597 I/O board. The
+ combination contains SoC, DRAM, eMMC, SD card slot, HDMI, USB
+ micro-B port, Ethernet via USB3, USB3 host port, SATA, PCIe, and
+ two GPIO expansion headers.
+
config TARGET_P2571
bool "NVIDIA Tegra210 P2571 base board"
help
@@ -30,6 +38,7 @@ config SYS_SOC
source "board/nvidia/e2220-1170/Kconfig"
source "board/nvidia/p2371-0000/Kconfig"
+source "board/nvidia/p2371-2180/Kconfig"
source "board/nvidia/p2571/Kconfig"
endif
diff --git a/arch/arm/mach-tegra/tegra210/clock.c b/arch/arm/mach-tegra/tegra210/clock.c
index 830a33f..6d75d37 100644
--- a/arch/arm/mach-tegra/tegra210/clock.c
+++ b/arch/arm/mach-tegra/tegra210/clock.c
@@ -998,18 +998,27 @@ 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;
u32 freq, val;
- freq = clock_get_rate(CLOCK_ID_OSC);
- debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq);
+ freq = clock_get_rate(CLOCK_ID_CLK_M);
+ debug("%s: clk_m freq is %dHz [0x%08X]\n", __func__, freq, freq);
- /* ARM CNTFRQ */
-#ifndef CONFIG_ARM64
- asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq));
-#endif
+ if (current_el() == 3)
+ asm("msr cntfrq_el0, %0\n" : : "r" (freq));
/* Only Tegra114+ has the System Counter regs */
debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq);