Patchwork [U-Boot,v2,09/10] tegra20: Remove CPU init code from tegra20 u-boot

login
register
mail settings
Submitter Allen Martin
Date June 5, 2012, 9:20 p.m.
Message ID <1338931225-12246-10-git-send-email-amartin@nvidia.com>
Download mbox | patch
Permalink /patch/163172/
State Superseded
Headers show

Comments

Allen Martin - June 5, 2012, 9:20 p.m.
This code is now included in the tegra20 SPL

Signed-off-by: Allen Martin <amartin@nvidia.com>
---
 arch/arm/cpu/armv7/start.S          |    2 -
 arch/arm/cpu/tegra20-common/ap20.c  |  262 +----------------------------------
 arch/arm/cpu/tegra20-common/board.c |   27 +---
 include/configs/tegra2-common.h     |    4 -
 4 files changed, 8 insertions(+), 287 deletions(-)
Stephen Warren - June 6, 2012, 4:51 p.m.
On 06/05/2012 03:20 PM, Allen Martin wrote:
> This code is now included in the tegra20 SPL

> @@ -323,34 +91,10 @@ void init_pmc_scratch(void)
>  
>  	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
>  	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
> -
> -#ifdef CONFIG_TEGRA2_LP0
> -	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
> -	warmboot_save_sdram_params();
> -#endif
>  }

Is that change intended, or was it a rebase mistake?

> diff --git a/arch/arm/cpu/tegra20-common/board.c b/arch/arm/cpu/tegra20-common/board.c

> @@ -69,6 +68,11 @@ int dram_init(void)
>  {
>  	/* We do not initialise DRAM here. We just query the size */
>  	gd->ram_size = query_sdram_size();
> +
> +#ifdef CONFIG_TEGRA2_LP0
> +	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
> +	warmboot_save_sdram_params();
> +#endif

Hmmm. That's more than just removing the code that's now in the AVP
directory. Separate patch? The patch description also doesn't say why
this change is necessary.
Allen Martin - June 6, 2012, 7:42 p.m.
On Wed, Jun 06, 2012 at 09:51:09AM -0700, Stephen Warren wrote:
> On 06/05/2012 03:20 PM, Allen Martin wrote:
> > This code is now included in the tegra20 SPL
> 
> > @@ -323,34 +91,10 @@ void init_pmc_scratch(void)
> >  
> >  	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
> >  	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
> > -
> > -#ifdef CONFIG_TEGRA2_LP0
> > -	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
> > -	warmboot_save_sdram_params();
> > -#endif
> >  }
> 
> Is that change intended, or was it a rebase mistake?
> 
> > diff --git a/arch/arm/cpu/tegra20-common/board.c b/arch/arm/cpu/tegra20-common/board.c
> 
> > @@ -69,6 +68,11 @@ int dram_init(void)
> >  {
> >  	/* We do not initialise DRAM here. We just query the size */
> >  	gd->ram_size = query_sdram_size();
> > +
> > +#ifdef CONFIG_TEGRA2_LP0
> > +	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
> > +	warmboot_save_sdram_params();
> > +#endif
> 
> Hmmm. That's more than just removing the code that's now in the AVP
> directory. Separate patch? The patch description also doesn't say why
> this change is necessary.

This code was added since v1 of the patch series, and I had to move it
because when I fixed it so we could use the normal lowlevel_init it
gets called before the devicetree is initialized.

I rolled it into this patch, but you're probably right, it would make
more sense to be in it's own patch with a proper description.

-Allen

Patch

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 261835b..786152f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -133,7 +133,6 @@  reset:
 	orr	r0, r0, #0xd3
 	msr	cpsr,r0
 
-#if !defined(CONFIG_TEGRA2)
 /*
  * Setup vector:
  * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
@@ -149,7 +148,6 @@  reset:
 	ldr	r0, =_start
 	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
 #endif
-#endif	/* !Tegra2 */
 
 	/* the mask ROM code should have PLL and others stable */
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
diff --git a/arch/arm/cpu/tegra20-common/ap20.c b/arch/arm/cpu/tegra20-common/ap20.c
index 698bfd0..299f698 100644
--- a/arch/arm/cpu/tegra20-common/ap20.c
+++ b/arch/arm/cpu/tegra20-common/ap20.c
@@ -20,16 +20,10 @@ 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
-
 #include <asm/io.h>
-#include <asm/arch/tegra2.h>
-#include <asm/arch/ap20.h>
-#include <asm/arch/clk_rst.h>
-#include <asm/arch/clock.h>
 #include <asm/arch/fuse.h>
 #include <asm/arch/gp_padctrl.h>
 #include <asm/arch/pmc.h>
-#include <asm/arch/pinmux.h>
 #include <asm/arch/scu.h>
 #include <asm/arch/warmboot.h>
 #include <common.h>
@@ -68,233 +62,7 @@  int tegra_get_chip_type(void)
 	return TEGRA_SOC_UNKNOWN;
 }
 
-/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
-static int ap20_cpu_is_cortexa9(void)
-{
-	u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
-	return id == (PG_UP_TAG_0_PID_CPU & 0xff);
-}
-
-void init_pllx(void)
-{
-	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU];
-	u32 reg;
-
-	/* If PLLX is already enabled, just return */
-	if (readl(&pll->pll_base) & PLL_ENABLE_MASK)
-		return;
-
-	/* Set PLLX_MISC */
-	writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc);
-
-	/* Use 12MHz clock here */
-	reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT);
-	reg |= 1000 << PLL_DIVN_SHIFT;
-	writel(reg, &pll->pll_base);
-
-	reg |= PLL_ENABLE_MASK;
-	writel(reg, &pll->pll_base);
-
-	reg &= ~PLL_BYPASS_MASK;
-	writel(reg, &pll->pll_base);
-}
-
-static void enable_cpu_clock(int enable)
-{
-	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 clk;
-
-	/*
-	 * NOTE:
-	 * Regardless of whether the request is to enable or disable the CPU
-	 * clock, every processor in the CPU complex except the master (CPU 0)
-	 * will have it's clock stopped because the AVP only talks to the
-	 * master. The AVP does not know (nor does it need to know) that there
-	 * are multiple processors in the CPU complex.
-	 */
-
-	if (enable) {
-		/* Initialize PLLX */
-		init_pllx();
-
-		/* Wait until all clocks are stable */
-		udelay(PLL_STABILIZATION_DELAY);
-
-		writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
-		writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
-	}
-
-	/*
-	 * Read the register containing the individual CPU clock enables and
-	 * always stop the clock to CPU 1.
-	 */
-	clk = readl(&clkrst->crc_clk_cpu_cmplx);
-	clk |= 1 << CPU1_CLK_STP_SHIFT;
-
-	/* Stop/Unstop the CPU clock */
-	clk &= ~CPU0_CLK_STP_MASK;
-	clk |= !enable << CPU0_CLK_STP_SHIFT;
-	writel(clk, &clkrst->crc_clk_cpu_cmplx);
-
-	clock_enable(PERIPH_ID_CPU);
-}
-
-static int is_cpu_powered(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-
-	return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
-}
-
-static void remove_cpu_io_clamps(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-	u32 reg;
-
-	/* Remove the clamps on the CPU I/O signals */
-	reg = readl(&pmc->pmc_remove_clamping);
-	reg |= CPU_CLMP;
-	writel(reg, &pmc->pmc_remove_clamping);
-
-	/* Give I/O signals time to stabilize */
-	udelay(IO_STABILIZATION_DELAY);
-}
-
-static void powerup_cpu(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-	u32 reg;
-	int timeout = IO_STABILIZATION_DELAY;
-
-	if (!is_cpu_powered()) {
-		/* Toggle the CPU power state (OFF -> ON) */
-		reg = readl(&pmc->pmc_pwrgate_toggle);
-		reg &= PARTID_CP;
-		reg |= START_CP;
-		writel(reg, &pmc->pmc_pwrgate_toggle);
-
-		/* Wait for the power to come up */
-		while (!is_cpu_powered()) {
-			if (timeout-- == 0)
-				printf("CPU failed to power up!\n");
-			else
-				udelay(10);
-		}
-
-		/*
-		 * Remove the I/O clamps from CPU power partition.
-		 * Recommended only on a Warm boot, if the CPU partition gets
-		 * power gated. Shouldn't cause any harm when called after a
-		 * cold boot according to HW, probably just redundant.
-		 */
-		remove_cpu_io_clamps();
-	}
-}
-
-static void enable_cpu_power_rail(void)
-{
-	struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-	u32 reg;
-
-	reg = readl(&pmc->pmc_cntrl);
-	reg |= CPUPWRREQ_OE;
-	writel(reg, &pmc->pmc_cntrl);
-
-	/*
-	 * The TI PMU65861C needs a 3.75ms delay between enabling
-	 * the power rail and enabling the CPU clock.  This delay
-	 * between SM1EN and SM1 is for switching time + the ramp
-	 * up of the voltage to the CPU (VDD_CPU from PMU).
-	 */
-	udelay(3750);
-}
-
-static void reset_A9_cpu(int reset)
-{
-	/*
-	* NOTE:  Regardless of whether the request is to hold the CPU in reset
-	*        or take it out of reset, every processor in the CPU complex
-	*        except the master (CPU 0) will be held in reset because the
-	*        AVP only talks to the master. The AVP does not know that there
-	*        are multiple processors in the CPU complex.
-	*/
-
-	/* Hold CPU 1 in reset, and CPU 0 if asked */
-	reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1);
-	reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug,
-			       reset);
-
-	/* Enable/Disable master CPU reset */
-	reset_set_enable(PERIPH_ID_CPU, reset);
-}
-
-static void clock_enable_coresight(int enable)
-{
-	u32 rst, src;
-
-	clock_set_enable(PERIPH_ID_CORESIGHT, enable);
-	reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
-
-	if (enable) {
-		/*
-		 * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by
-		 *  1.5, giving an effective frequency of 144MHz.
-		 * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor
-		 *  (bits 7:0), so 00000001b == 1.5 (n+1 + .5)
-		 */
-		src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000);
-		clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);
-
-		/* Unlock the CPU CoreSight interfaces */
-		rst = 0xC5ACCE55;
-		writel(rst, CSITE_CPU_DBG0_LAR);
-		writel(rst, CSITE_CPU_DBG1_LAR);
-	}
-}
-
-void start_cpu(u32 reset_vector)
-{
-	/* Enable VDD_CPU */
-	enable_cpu_power_rail();
-
-	/* Hold the CPUs in reset */
-	reset_A9_cpu(1);
-
-	/* Disable the CPU clock */
-	enable_cpu_clock(0);
-
-	/* Enable CoreSight */
-	clock_enable_coresight(1);
-
-	/*
-	 * Set the entry point for CPU execution from reset,
-	 *  if it's a non-zero value.
-	 */
-	if (reset_vector)
-		writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
-
-	/* Enable the CPU clock */
-	enable_cpu_clock(1);
-
-	/* If the CPU doesn't already have power, power it up */
-	powerup_cpu();
-
-	/* Take the CPU out of reset */
-	reset_A9_cpu(0);
-}
-
-
-void halt_avp(void)
-{
-	for (;;) {
-		writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \
-			| HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)),
-			FLOW_CTLR_HALT_COP_EVENTS);
-	}
-}
-
-void enable_scu(void)
+static void enable_scu(void)
 {
 	struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE;
 	u32 reg;
@@ -312,7 +80,7 @@  void enable_scu(void)
 	writel(reg, &scu->scu_ctrl);
 }
 
-void init_pmc_scratch(void)
+static void init_pmc_scratch(void)
 {
 	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
 	int i;
@@ -323,34 +91,10 @@  void init_pmc_scratch(void)
 
 	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
 	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
-
-#ifdef CONFIG_TEGRA2_LP0
-	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
-	warmboot_save_sdram_params();
-#endif
 }
 
-void tegra2_start(void)
+void lowlevel_init(void)
 {
-	struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-
-	/* If we are the AVP, start up the first Cortex-A9 */
-	if (!ap20_cpu_is_cortexa9()) {
-		/* enable JTAG */
-		writel(0xC0, &pmt->pmt_cfg_ctl);
-
-		/*
-		 * If we are ARM7 - give it a different stack. We are about to
-		 * start up the A9 which will want to use this one.
-		 */
-		asm volatile("mov	sp, %0\n"
-			: : "r"(AVP_EARLY_BOOT_STACK_LIMIT));
-
-		start_cpu((u32)_start);
-		halt_avp();
-		/* not reached */
-	}
-
 	/* Init PMC scratch memory */
 	init_pmc_scratch();
 
diff --git a/arch/arm/cpu/tegra20-common/board.c b/arch/arm/cpu/tegra20-common/board.c
index a50b1b9..458a928 100644
--- a/arch/arm/cpu/tegra20-common/board.c
+++ b/arch/arm/cpu/tegra20-common/board.c
@@ -23,7 +23,6 @@ 
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/ap20.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/funcmux.h>
 #include <asm/arch/pmc.h>
@@ -69,6 +68,11 @@  int dram_init(void)
 {
 	/* We do not initialise DRAM here. We just query the size */
 	gd->ram_size = query_sdram_size();
+
+#ifdef CONFIG_TEGRA2_LP0
+	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
+	warmboot_save_sdram_params();
+#endif
 	return 0;
 }
 
@@ -80,27 +84,6 @@  int checkboard(void)
 }
 #endif	/* CONFIG_DISPLAY_BOARDINFO */
 
-#ifdef CONFIG_ARCH_CPU_INIT
-/*
- * Note this function is executed by the ARM7TDMI AVP. It does not return
- * in this case. It is also called once the A9 starts up, but does nothing in
- * that case.
- */
-int arch_cpu_init(void)
-{
-	/* Fire up the Cortex A9 */
-	tegra2_start();
-
-	/* We didn't do this init in start.S, so do it now */
-	cpu_init_cp15();
-
-	/* Initialize essential common plls */
-	clock_early_init();
-
-	return 0;
-}
-#endif
-
 /**
  * Set up the specified uarts
  *
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 8e2732a..28a9082 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -43,8 +43,6 @@ 
 
 #define CONFIG_SYS_CACHELINE_SIZE	32
 
-#define CONFIG_ARCH_CPU_INIT		/* Fire up the A9 core */
-
 #include <asm/arch/tegra2.h>		/* get chip and board defs */
 
 /*
@@ -53,8 +51,6 @@ 
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
-#define CONFIG_SKIP_LOWLEVEL_INIT
-
 #define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs */
 #define CONFIG_OF_LIBFDT		/* enable passing of devicetree */