summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/arm720t
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2014-02-17 14:22:02 -0500
committerTom Rini <trini@ti.com>2014-02-17 14:22:02 -0500
commitc4d376fd1c2bce8d64cec0431dd3f24957b6dec4 (patch)
treede17e3a67fa4a48f3b9571bff2399cb0a24558bc /arch/arm/cpu/arm720t
parentb1ad03c242dae3712b9be66026f5d8c6f919c00b (diff)
parent5e77a745b24d9b98aa635293972f04fd6f0c6b38 (diff)
downloadblackbird-obmc-uboot-c4d376fd1c2bce8d64cec0431dd3f24957b6dec4.tar.gz
blackbird-obmc-uboot-c4d376fd1c2bce8d64cec0431dd3f24957b6dec4.zip
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'arch/arm/cpu/arm720t')
-rw-r--r--arch/arm/cpu/arm720t/tegra-common/cpu.c75
-rw-r--r--arch/arm/cpu/arm720t/tegra-common/cpu.h12
-rw-r--r--arch/arm/cpu/arm720t/tegra114/cpu.c48
-rw-r--r--arch/arm/cpu/arm720t/tegra124/Makefile8
-rw-r--r--arch/arm/cpu/arm720t/tegra124/config.mk7
-rw-r--r--arch/arm/cpu/arm720t/tegra124/cpu.c265
-rw-r--r--arch/arm/cpu/arm720t/tegra30/cpu.c14
7 files changed, 346 insertions, 83 deletions
diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.c b/arch/arm/cpu/arm720t/tegra-common/cpu.c
index 72c69b914c..2c5cd63917 100644
--- a/arch/arm/cpu/arm720t/tegra-common/cpu.c
+++ b/arch/arm/cpu/arm720t/tegra-common/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2014, 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,
@@ -112,24 +112,38 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
},
+
+ /*
+ * T124: 700 MHz
+ *
+ * Register Field Bits Width
+ * ------------------------------
+ * PLLX_BASE p 23:20 4
+ * PLLX_BASE n 15: 8 8
+ * PLLX_BASE m 7: 0 8
+ */
+ {
+ { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */
+ { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */
+ { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
+ { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
+ },
};
-void adjust_pllp_out_freqs(void)
+static inline void pllx_set_iddq(void)
{
+#if defined(CONFIG_TEGRA124)
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
- struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_PERIPH];
u32 reg;
- /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
- reg = readl(&pll->pll_out[0]); /* OUTA, contains OUT2 / OUT1 */
- reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
- | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
- writel(reg, &pll->pll_out[0]);
-
- reg = readl(&pll->pll_out[1]); /* OUTB, contains OUT4 / OUT3 */
- reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
- | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
- writel(reg, &pll->pll_out[1]);
+ /* Disable IDDQ */
+ reg = readl(&clkrst->crc_pllx_misc3);
+ reg &= ~PLLX_IDDQ_MASK;
+ writel(reg, &clkrst->crc_pllx_misc3);
+ udelay(2);
+ debug("%s: IDDQ: PLLX IDDQ = 0x%08X\n", __func__,
+ readl(&clkrst->crc_pllx_misc3));
+#endif
}
int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
@@ -146,6 +160,8 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
debug(" pllx_set_rate entry\n");
+ pllx_set_iddq();
+
/* Set BYPASS, m, n and p to PLLX_BASE */
reg = PLL_BYPASS_MASK | (divm << PLL_DIVM_SHIFT);
reg |= ((divn << PLL_DIVN_SHIFT) | (divp << PLL_DIVP_SHIFT));
@@ -162,18 +178,23 @@ int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
reg |= (1 << PLL_DCCON_SHIFT);
writel(reg, &pll->pll_misc);
- /* Enable PLLX */
- reg = readl(&pll->pll_base);
- reg |= PLL_ENABLE_MASK;
-
/* Disable BYPASS */
+ reg = readl(&pll->pll_base);
reg &= ~PLL_BYPASS_MASK;
writel(reg, &pll->pll_base);
+ debug("pllx_set_rate: base = 0x%08X\n", reg);
/* Set lock_enable to PLLX_MISC */
reg = readl(&pll->pll_misc);
reg |= PLL_LOCK_ENABLE_MASK;
writel(reg, &pll->pll_misc);
+ debug("pllx_set_rate: misc = 0x%08X\n", reg);
+
+ /* Enable PLLX last, once it's all configured */
+ reg = readl(&pll->pll_base);
+ reg |= PLL_ENABLE_MASK;
+ writel(reg, &pll->pll_base);
+ debug("pllx_set_rate: base final = 0x%08X\n", reg);
return 0;
}
@@ -207,12 +228,6 @@ void init_pllx(void)
/* set pllx */
sel = &tegra_pll_x_table[chip_sku][osc];
pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon);
-
- /* adjust PLLP_out1-4 on T3x/T114 */
- if (soc_type >= CHIPID_TEGRA30) {
- debug(" init_pllx: adjusting PLLP out freqs\n");
- adjust_pllp_out_freqs();
- }
}
void enable_cpu_clock(int enable)
@@ -334,7 +349,6 @@ void reset_A9_cpu(int reset)
void clock_enable_coresight(int enable)
{
u32 rst, src = 2;
- int soc_type;
debug("clock_enable_coresight entry\n");
clock_set_enable(PERIPH_ID_CORESIGHT, enable);
@@ -343,20 +357,11 @@ void clock_enable_coresight(int enable)
if (enable) {
/*
* Put CoreSight on PLLP_OUT0 and divide it down as per
- * PLLP base frequency based on SoC type (T20/T30/T114).
+ * PLLP base frequency based on SoC type (T20/T30+).
* Clock divider request would setup CSITE clock as 144MHz
* for PLLP base 216MHz and 204MHz for PLLP base 408MHz
*/
-
- soc_type = tegra_get_chip();
- if (soc_type == CHIPID_TEGRA30 || soc_type == CHIPID_TEGRA114)
- src = CLK_DIVIDER(NVBL_PLLP_KHZ, 204000);
- else if (soc_type == CHIPID_TEGRA20)
- src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
- else
- printf("%s: Unknown SoC type %X!\n",
- __func__, soc_type);
-
+ src = CLK_DIVIDER(NVBL_PLLP_KHZ, CSITE_KHZ);
clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
/* Unlock the CPU CoreSight interfaces */
diff --git a/arch/arm/cpu/arm720t/tegra-common/cpu.h b/arch/arm/cpu/arm720t/tegra-common/cpu.h
index 60412c7f87..b4ca44fce1 100644
--- a/arch/arm/cpu/arm720t/tegra-common/cpu.h
+++ b/arch/arm/cpu/arm720t/tegra-common/cpu.h
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2010-2011
+ * (C) Copyright 2010-2014
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
@@ -11,9 +11,12 @@
#define IO_STABILIZATION_DELAY (1000)
#if defined(CONFIG_TEGRA20)
-#define NVBL_PLLP_KHZ (216000)
-#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114)
-#define NVBL_PLLP_KHZ (408000)
+#define NVBL_PLLP_KHZ 216000
+#define CSITE_KHZ 144000
+#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) || \
+ defined(CONFIG_TEGRA124)
+#define NVBL_PLLP_KHZ 408000
+#define CSITE_KHZ 204000
#else
#error "Unknown Tegra chip!"
#endif
@@ -68,3 +71,4 @@ int tegra_get_chip(void);
int tegra_get_sku_info(void);
int tegra_get_chip_sku(void);
void adjust_pllp_out_freqs(void);
+void pmic_enable_cpu_vdd(void);
diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c b/arch/arm/cpu/arm720t/tegra114/cpu.c
index 51ecff794f..d10b96a1d4 100644
--- a/arch/arm/cpu/arm720t/tegra114/cpu.c
+++ b/arch/arm/cpu/arm720t/tegra114/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2014, 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,
@@ -68,7 +68,7 @@ static void enable_cpu_clocks(void)
/* Wait for PLL-X to lock */
do {
reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
- } while ((reg & (1 << 27)) == 0);
+ } while ((reg & PLL_LOCK_MASK) == 0);
/* Wait until all clocks are stable */
udelay(PLL_STABILIZATION_DELAY);
@@ -126,18 +126,6 @@ void t114_init_clocks(void)
/* Set active CPU cluster to G */
clrbits_le32(&flow->cluster_control, 1);
- /*
- * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run
- * at 108 MHz. This is glitch free as only the source is changed, no
- * special precaution needed.
- */
- val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
- (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
- writel(val, &clkrst->crc_sclk_brst_pol);
-
writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
debug("Setting up PLLX\n");
@@ -204,45 +192,43 @@ void t114_init_clocks(void)
debug("t114_init_clocks exit\n");
}
-static int is_partition_powered(u32 mask)
+static bool is_partition_powered(u32 partid)
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
/* Get power gate status */
reg = readl(&pmc->pmc_pwrgate_status);
- return (reg & mask) == mask;
+ return !!(reg & (1 << partid));
}
-static int is_clamp_enabled(u32 mask)
+static bool is_clamp_enabled(u32 partid)
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
- /* Get clamp status. TODO: Add pmc_clamp_status alias to pmc.h */
- reg = readl(&pmc->pmc_pwrgate_timer_on);
- return (reg & mask) == mask;
+ /* Get clamp status. */
+ reg = readl(&pmc->pmc_clamp_status);
+ return !!(reg & (1 << partid));
}
-static void power_partition(u32 status, u32 partid)
+static void power_partition(u32 partid)
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
- debug("%s: status = %08X, part ID = %08X\n", __func__, status, partid);
+ debug("%s: part ID = %08X\n", __func__, partid);
/* Is the partition already on? */
- if (!is_partition_powered(status)) {
+ if (!is_partition_powered(partid)) {
/* No, toggle the partition power state (OFF -> ON) */
debug("power_partition, toggling state\n");
- clrbits_le32(&pmc->pmc_pwrgate_toggle, 0x1F);
- setbits_le32(&pmc->pmc_pwrgate_toggle, partid);
- setbits_le32(&pmc->pmc_pwrgate_toggle, START_CP);
+ writel(START_CP | partid, &pmc->pmc_pwrgate_toggle);
/* Wait for the power to come up */
- while (!is_partition_powered(status))
+ while (!is_partition_powered(partid))
;
/* Wait for the clamp status to be cleared */
- while (is_clamp_enabled(status))
+ while (is_clamp_enabled(partid))
;
/* Give I/O signals time to stabilize */
@@ -257,13 +243,13 @@ void powerup_cpus(void)
/* We boot to the fast cluster */
debug("powerup_cpus entry: G cluster\n");
/* Power up the fast cluster rail partition */
- power_partition(CRAIL, CRAILID);
+ power_partition(CRAIL);
/* Power up the fast cluster non-CPU partition */
- power_partition(C0NC, C0NCID);
+ power_partition(C0NC);
/* Power up the fast cluster CPU0 partition */
- power_partition(CE0, CE0ID);
+ power_partition(CE0);
}
void start_cpu(u32 reset_vector)
diff --git a/arch/arm/cpu/arm720t/tegra124/Makefile b/arch/arm/cpu/arm720t/tegra124/Makefile
new file mode 100644
index 0000000000..61abf45d3d
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra124/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2013-2014
+# NVIDIA Corporation <www.nvidia.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += cpu.o
diff --git a/arch/arm/cpu/arm720t/tegra124/config.mk b/arch/arm/cpu/arm720t/tegra124/config.mk
new file mode 100644
index 0000000000..5e10701f0e
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra124/config.mk
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2010-2013
+# NVIDIA Corporation <www.nvidia.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#/
+USE_PRIVATE_LIBGCC = yes
diff --git a/arch/arm/cpu/arm720t/tegra124/cpu.c b/arch/arm/cpu/arm720t/tegra124/cpu.c
new file mode 100644
index 0000000000..c03aaf17e9
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra124/cpu.c
@@ -0,0 +1,265 @@
+/*
+ * (C) Copyright 2013
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/ahb.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/flow.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/pmc.h>
+#include <asm/arch-tegra/ap.h>
+#include "../tegra-common/cpu.h"
+
+/* Tegra124-specific CPU init code */
+
+static void enable_cpu_power_rail(void)
+{
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+
+ debug("enable_cpu_power_rail entry\n");
+
+ /* un-tristate PWR_I2C SCL/SDA, rest of the defaults are correct */
+ pinmux_tristate_disable(PINGRP_PWR_I2C_SCL);
+ pinmux_tristate_disable(PINGRP_PWR_I2C_SDA);
+
+ pmic_enable_cpu_vdd();
+
+ /*
+ * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz),
+ * set it for 5ms as per SysEng (102MHz*5ms = 510000 (7C830h).
+ */
+ writel(0x7C830, &pmc->pmc_cpupwrgood_timer);
+
+ /* Set polarity to 0 (normal) and enable CPUPWRREQ_OE */
+ clrbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_POL);
+ setbits_le32(&pmc->pmc_cntrl, CPUPWRREQ_OE);
+}
+
+static void enable_cpu_clocks(void)
+{
+ struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 reg;
+
+ debug("enable_cpu_clocks entry\n");
+
+ /* Wait for PLL-X to lock */
+ do {
+ reg = readl(&clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
+ debug("%s: PLLX base = 0x%08X\n", __func__, reg);
+ } while ((reg & PLL_LOCK_MASK) == 0);
+
+ debug("%s: PLLX locked, delay for stable clocks\n", __func__);
+ /* Wait until all clocks are stable */
+ udelay(PLL_STABILIZATION_DELAY);
+
+ debug("%s: Setting CCLK_BURST and DIVIDER\n", __func__);
+ writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
+ writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
+
+ debug("%s: Enabling clock to all CPUs\n", __func__);
+ /* Enable the clock to all CPUs */
+ reg = CLR_CPU3_CLK_STP | CLR_CPU2_CLK_STP | CLR_CPU1_CLK_STP |
+ CLR_CPU0_CLK_STP;
+ writel(reg, &clkrst->crc_clk_cpu_cmplx_clr);
+
+ debug("%s: Enabling main CPU complex clocks\n", __func__);
+ /* Always enable the main CPU complex clocks */
+ clock_enable(PERIPH_ID_CPU);
+ clock_enable(PERIPH_ID_CPULP);
+ clock_enable(PERIPH_ID_CPUG);
+
+ debug("%s: Done\n", __func__);
+}
+
+static void remove_cpu_resets(void)
+{
+ struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 reg;
+
+ debug("remove_cpu_resets entry\n");
+
+ /* Take the slow and fast partitions out of reset */
+ reg = CLR_NONCPURESET;
+ writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr);
+ writel(reg, &clkrst->crc_rst_cpug_cmplx_clr);
+
+ /* Clear the SW-controlled reset of the slow cluster */
+ reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 |
+ CLR_L2RESET | CLR_PRESETDBG;
+ writel(reg, &clkrst->crc_rst_cpulp_cmplx_clr);
+
+ /* Clear the SW-controlled reset of the fast cluster */
+ reg = CLR_CPURESET0 | CLR_DBGRESET0 | CLR_CORERESET0 | CLR_CXRESET0 |
+ CLR_CPURESET1 | CLR_DBGRESET1 | CLR_CORERESET1 | CLR_CXRESET1 |
+ CLR_CPURESET2 | CLR_DBGRESET2 | CLR_CORERESET2 | CLR_CXRESET2 |
+ CLR_CPURESET3 | CLR_DBGRESET3 | CLR_CORERESET3 | CLR_CXRESET3 |
+ CLR_L2RESET | CLR_PRESETDBG;
+ writel(reg, &clkrst->crc_rst_cpug_cmplx_clr);
+}
+
+/**
+ * The Tegra124 requires some special clock initialization, including setting up
+ * the DVC I2C, turning on MSELECT and selecting the G CPU cluster
+ */
+void tegra124_init_clocks(void)
+{
+ struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 val;
+
+ debug("tegra124_init_clocks entry\n");
+
+ /* Set active CPU cluster to G */
+ clrbits_le32(&flow->cluster_control, 1);
+
+ /* Change the oscillator drive strength */
+ val = readl(&clkrst->crc_osc_ctrl);
+ val &= ~OSC_XOFS_MASK;
+ val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
+ writel(val, &clkrst->crc_osc_ctrl);
+
+ /* Update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot */
+ val = readl(&pmc->pmc_osc_edpd_over);
+ val &= ~PMC_XOFS_MASK;
+ val |= (OSC_DRIVE_STRENGTH << PMC_XOFS_SHIFT);
+ writel(val, &pmc->pmc_osc_edpd_over);
+
+ /* Set HOLD_CKE_LOW_EN to 1 */
+ setbits_le32(&pmc->pmc_cntrl2, HOLD_CKE_LOW_EN);
+
+ debug("Setting up PLLX\n");
+ init_pllx();
+
+ val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT);
+ writel(val, &clkrst->crc_clk_sys_rate);
+
+ /* Enable clocks to required peripherals. TBD - minimize this list */
+ debug("Enabling clocks\n");
+
+ clock_set_enable(PERIPH_ID_CACHE2, 1);
+ clock_set_enable(PERIPH_ID_GPIO, 1);
+ clock_set_enable(PERIPH_ID_TMR, 1);
+ clock_set_enable(PERIPH_ID_CPU, 1);
+ clock_set_enable(PERIPH_ID_EMC, 1);
+ clock_set_enable(PERIPH_ID_I2C5, 1);
+ clock_set_enable(PERIPH_ID_APBDMA, 1);
+ clock_set_enable(PERIPH_ID_MEM, 1);
+ clock_set_enable(PERIPH_ID_CORESIGHT, 1);
+ clock_set_enable(PERIPH_ID_MSELECT, 1);
+ clock_set_enable(PERIPH_ID_DVFS, 1);
+
+ /*
+ * Set MSELECT clock source as PLLP (00), and ask for a clock
+ * divider that would set the MSELECT clock at 102MHz for a
+ * PLLP base of 408MHz.
+ */
+ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0,
+ CLK_DIVIDER(NVBL_PLLP_KHZ, 102000));
+
+ /* Give clock time to stabilize */
+ udelay(IO_STABILIZATION_DELAY);
+
+ /* I2C5 (DVC) gets CLK_M and a divisor of 17 */
+ clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16);
+
+ /* Give clock time to stabilize */
+ udelay(IO_STABILIZATION_DELAY);
+
+ /* Take required peripherals out of reset */
+ debug("Taking periphs out of reset\n");
+ reset_set_enable(PERIPH_ID_CACHE2, 0);
+ reset_set_enable(PERIPH_ID_GPIO, 0);
+ reset_set_enable(PERIPH_ID_TMR, 0);
+ reset_set_enable(PERIPH_ID_COP, 0);
+ reset_set_enable(PERIPH_ID_EMC, 0);
+ reset_set_enable(PERIPH_ID_I2C5, 0);
+ reset_set_enable(PERIPH_ID_APBDMA, 0);
+ reset_set_enable(PERIPH_ID_MEM, 0);
+ reset_set_enable(PERIPH_ID_CORESIGHT, 0);
+ reset_set_enable(PERIPH_ID_MSELECT, 0);
+ reset_set_enable(PERIPH_ID_DVFS, 0);
+
+ debug("tegra124_init_clocks exit\n");
+}
+
+static bool is_partition_powered(u32 partid)
+{
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+ u32 reg;
+
+ /* Get power gate status */
+ reg = readl(&pmc->pmc_pwrgate_status);
+ return !!(reg & (1 << partid));
+}
+
+static void power_partition(u32 partid)
+{
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+
+ debug("%s: part ID = %08X\n", __func__, partid);
+ /* Is the partition already on? */
+ if (!is_partition_powered(partid)) {
+ /* No, toggle the partition power state (OFF -> ON) */
+ debug("power_partition, toggling state\n");
+ writel(START_CP | partid, &pmc->pmc_pwrgate_toggle);
+
+ /* Wait for the power to come up */
+ while (!is_partition_powered(partid))
+ ;
+
+ /* Give I/O signals time to stabilize */
+ udelay(IO_STABILIZATION_DELAY);
+ }
+}
+
+void powerup_cpus(void)
+{
+ debug("powerup_cpus entry\n");
+
+ /* We boot to the fast cluster */
+ debug("powerup_cpus entry: G cluster\n");
+
+ /* Power up the fast cluster rail partition */
+ debug("powerup_cpus: CRAIL\n");
+ power_partition(CRAIL);
+
+ /* Power up the fast cluster non-CPU partition */
+ debug("powerup_cpus: C0NC\n");
+ power_partition(C0NC);
+
+ /* Power up the fast cluster CPU0 partition */
+ debug("powerup_cpus: CE0\n");
+ power_partition(CE0);
+
+ debug("powerup_cpus: done\n");
+}
+
+void start_cpu(u32 reset_vector)
+{
+ struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
+
+ debug("start_cpu entry, reset_vector = %x\n", reset_vector);
+
+ tegra124_init_clocks();
+
+ /* Set power-gating timer multiplier */
+ clrbits_le32(&pmc->pmc_pwrgate_timer_mult, TIMER_MULT_MASK);
+ setbits_le32(&pmc->pmc_pwrgate_timer_mult, MULT_8);
+
+ enable_cpu_power_rail();
+ enable_cpu_clocks();
+ clock_enable_coresight(1);
+ remove_cpu_resets();
+ writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
+ powerup_cpus();
+ debug("start_cpu exit, should continue @ reset_vector\n");
+}
diff --git a/arch/arm/cpu/arm720t/tegra30/cpu.c b/arch/arm/cpu/arm720t/tegra30/cpu.c
index e162357484..a80648389c 100644
--- a/arch/arm/cpu/arm720t/tegra30/cpu.c
+++ b/arch/arm/cpu/arm720t/tegra30/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2014, 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,
@@ -84,18 +84,6 @@ void t30_init_clocks(void)
/* Set active CPU cluster to G */
clrbits_le32(flow->cluster_control, 1 << 0);
- /*
- * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run
- * at 108 MHz. This is glitch free as only the source is changed, no
- * special precaution needed.
- */
- val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
- (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
- (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
- writel(val, &clkrst->crc_sclk_brst_pol);
-
writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div);
val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) |
OpenPOWER on IntegriCloud