Patchwork [U-Boot,v3,11/14] tegra20: Remove CPU init code from tegra20 u-boot

login
register
mail settings
Submitter Allen Martin
Date June 8, 2012, 9:16 p.m.
Message ID <1339190167-20320-12-git-send-email-amartin@nvidia.com>
Download mbox | patch
Permalink /patch/163855/
State Superseded
Headers show

Comments

Allen Martin - June 8, 2012, 9:16 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  |  258 +----------------------------------
 arch/arm/cpu/tegra20-common/board.c |   23 +---
 include/configs/tegra20-common.h    |    4 -
 4 files changed, 4 insertions(+), 283 deletions(-)
Simon Glass - June 9, 2012, 7:19 p.m.
Hi Allen,

On Fri, Jun 8, 2012 at 2:16 PM, Allen Martin <amartin@nvidia.com> wrote:

> 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  |  258
> +----------------------------------
>  arch/arm/cpu/tegra20-common/board.c |   23 +---
>  include/configs/tegra20-common.h    |    4 -
>  4 files changed, 4 insertions(+), 283 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 5b88c55..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_TEGRA20)
>  /*
>  * 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 /* !Tegra20 */
>
>        /* 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 6ff71e0..2d4705a 100644
> --- a/arch/arm/cpu/tegra20-common/ap20.c
> +++ b/arch/arm/cpu/tegra20-common/ap20.c
> @@ -20,16 +20,11 @@
>  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>  * MA 02111-1307 USA
>  */
> -
>  #include <asm/io.h>
> -#include <asm/arch/tegra20.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,235 +63,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_simple *pll =
> -               &clkrst->crc_pll_simple[CLOCK_ID_XCPU -
> CLOCK_ID_FIRST_SIMPLE];
> -       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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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;
> @@ -332,7 +99,7 @@ static u32 get_odmdata(void)
>        return odmdata;
>  }
>
> -void init_pmc_scratch(void)
> +static void init_pmc_scratch(void)
>  {
>        struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE;
>        u32 odmdata;
> @@ -347,27 +114,8 @@ void init_pmc_scratch(void)
>        writel(odmdata, &pmc->pmc_scratch20);
>  }
>
> -void tegra20_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();
>
> There is a FIXME comment immediately after this:

/* FIXME: should have ap20's L2 disabled too? */

Does this still apply?

diff --git a/arch/arm/cpu/tegra20-common/board.c
> b/arch/arm/cpu/tegra20-common/board.c
> index 70e5373..74610e5 100644
> --- a/arch/arm/cpu/tegra20-common/board.c
> +++ b/arch/arm/cpu/tegra20-common/board.c
> @@ -23,12 +23,12 @@
>
>  #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>
>  #include <asm/arch/sys_proto.h>
>  #include <asm/arch/tegra20.h>
> +#include <asm/arch/warmboot.h>
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> @@ -85,27 +85,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 */
> -       tegra20_start();
> -
> -       /* We didn't do this init in start.S, so do it now */
> -       cpu_init_cp15();
> -
> -       /* Initialize essential common plls */
> -       clock_early_init();
>

What happens to clock_early_init() with this patch? Is it called somewhere
else?


> -
> -       return 0;
> -}
> -#endif
> -
>  static int uart_configs[] = {
>  #if defined(CONFIG_TEGRA20_UARTA_UAA_UAB)
>        FUNCMUX_UART1_UAA_UAB,
> diff --git a/include/configs/tegra20-common.h
> b/include/configs/tegra20-common.h
> index 17c710e..6272570 100644
> --- a/include/configs/tegra20-common.h
> +++ b/include/configs/tegra20-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/tegra20.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 */
>
> --
> 1.7.9.5
>
>
Regards,
Simon
Allen Martin - June 11, 2012, 10:53 p.m.
On Sat, Jun 09, 2012 at 12:19:48PM -0700, Simon Glass wrote:
> Hi Allen,
> 
> On Fri, Jun 8, 2012 at 2:16 PM, Allen Martin <amartin@nvidia.com<mailto:amartin@nvidia.com>> wrote:
> This code is now included in the tegra20 SPL
> 
> Signed-off-by: Allen Martin <amartin@nvidia.com<mailto:amartin@nvidia.com>>
> ---
>  arch/arm/cpu/armv7/start.S          |    2 -
>  arch/arm/cpu/tegra20-common/ap20.c  |  258 +----------------------------------
>  arch/arm/cpu/tegra20-common/board.c |   23 +---
>  include/configs/tegra20-common.h    |    4 -
>  4 files changed, 4 insertions(+), 283 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 5b88c55..786152f 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -347,27 +114,8 @@ void init_pmc_scratch(void)
>        writel(odmdata, &pmc->pmc_scratch20);
>  }
> 
> -void tegra20_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();
> 
> There is a FIXME comment immediately after this:
> 
> /* FIXME: should have ap20's L2 disabled too? */
> 
> Does this still apply?

I'm not sure what the origin of that comment was, but AFAIK the L2
will always be disabled on reset until we explicitly enable it, so I'm
not sure what the comment is referring to.

> 
> diff --git a/arch/arm/cpu/tegra20-common/board.c b/arch/arm/cpu/tegra20-common/board.c
> index 70e5373..74610e5 100644
> --- a/arch/arm/cpu/tegra20-common/board.c
> +++ b/arch/arm/cpu/tegra20-common/board.c
> @@ -23,12 +23,12 @@
> 
>  #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>
>  #include <asm/arch/sys_proto.h>
>  #include <asm/arch/tegra20.h>
> +#include <asm/arch/warmboot.h>
> 
>  DECLARE_GLOBAL_DATA_PTR;
> 
> @@ -85,27 +85,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 */
> -       tegra20_start();
> -
> -       /* We didn't do this init in start.S, so do it now */
> -       cpu_init_cp15();
> -
> -       /* Initialize essential common plls */
> -       clock_early_init();
> 
> What happens to clock_early_init() with this patch? Is it called somewhere else?

Yes, it gets called from the SPL now in board_init_r()
arch/arm/cpu/arm720t/tegra20/spl.c 

-Allen
Simon Glass - June 12, 2012, 12:15 a.m.
Hi Allen,

On Mon, Jun 11, 2012 at 3:53 PM, Allen Martin <amartin@nvidia.com> wrote:

> On Sat, Jun 09, 2012 at 12:19:48PM -0700, Simon Glass wrote:
> > Hi Allen,
> >
> > On Fri, Jun 8, 2012 at 2:16 PM, Allen Martin <amartin@nvidia.com<mailto:
> amartin@nvidia.com>> wrote:
> > This code is now included in the tegra20 SPL
> >
> > Signed-off-by: Allen Martin <amartin@nvidia.com<mailto:
> amartin@nvidia.com>>
> > ---
> >  arch/arm/cpu/armv7/start.S          |    2 -
> >  arch/arm/cpu/tegra20-common/ap20.c  |  258
> +----------------------------------
> >  arch/arm/cpu/tegra20-common/board.c |   23 +---
> >  include/configs/tegra20-common.h    |    4 -
> >  4 files changed, 4 insertions(+), 283 deletions(-)
> >
> > diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> > index 5b88c55..786152f 100644
> > --- a/arch/arm/cpu/armv7/start.S
> > +++ b/arch/arm/cpu/armv7/start.S
> > @@ -347,27 +114,8 @@ void init_pmc_scratch(void)
> >        writel(odmdata, &pmc->pmc_scratch20);
> >  }
> >
> > -void tegra20_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();
> >
> > There is a FIXME comment immediately after this:
> >
> > /* FIXME: should have ap20's L2 disabled too? */
> >
> > Does this still apply?
>
> I'm not sure what the origin of that comment was, but AFAIK the L2
> will always be disabled on reset until we explicitly enable it, so I'm
> not sure what the comment is referring to.
>

OK, neither am I.


>
> >
> > diff --git a/arch/arm/cpu/tegra20-common/board.c
> b/arch/arm/cpu/tegra20-common/board.c
> > index 70e5373..74610e5 100644
> > --- a/arch/arm/cpu/tegra20-common/board.c
> > +++ b/arch/arm/cpu/tegra20-common/board.c
> > @@ -23,12 +23,12 @@
> >
> >  #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>
> >  #include <asm/arch/sys_proto.h>
> >  #include <asm/arch/tegra20.h>
> > +#include <asm/arch/warmboot.h>
> >
> >  DECLARE_GLOBAL_DATA_PTR;
> >
> > @@ -85,27 +85,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 */
> > -       tegra20_start();
> > -
> > -       /* We didn't do this init in start.S, so do it now */
> > -       cpu_init_cp15();
> > -
> > -       /* Initialize essential common plls */
> > -       clock_early_init();
> >
> > What happens to clock_early_init() with this patch? Is it called
> somewhere else?
>
> Yes, it gets called from the SPL now in board_init_r()
> arch/arm/cpu/arm720t/tegra20/spl.c
>

OK I see. But I think clock_early_init() must be called from main U-Boot
also, in case there is no SPL (e.g. using with JTAG).


>
> -Allen
> --
> nvpublic
>

Regards,
Simon

Patch

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 5b88c55..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_TEGRA20)
 /*
  * 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	/* !Tegra20 */
 
 	/* 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 6ff71e0..2d4705a 100644
--- a/arch/arm/cpu/tegra20-common/ap20.c
+++ b/arch/arm/cpu/tegra20-common/ap20.c
@@ -20,16 +20,11 @@ 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
-
 #include <asm/io.h>
-#include <asm/arch/tegra20.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,235 +63,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_simple *pll =
-		&clkrst->crc_pll_simple[CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE];
-	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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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;
@@ -332,7 +99,7 @@  static u32 get_odmdata(void)
 	return odmdata;
 }
 
-void init_pmc_scratch(void)
+static void init_pmc_scratch(void)
 {
 	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA20_PMC_BASE;
 	u32 odmdata;
@@ -347,27 +114,8 @@  void init_pmc_scratch(void)
 	writel(odmdata, &pmc->pmc_scratch20);
 }
 
-void tegra20_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 70e5373..74610e5 100644
--- a/arch/arm/cpu/tegra20-common/board.c
+++ b/arch/arm/cpu/tegra20-common/board.c
@@ -23,12 +23,12 @@ 
 
 #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>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/tegra20.h>
+#include <asm/arch/warmboot.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -85,27 +85,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 */
-	tegra20_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
-
 static int uart_configs[] = {
 #if defined(CONFIG_TEGRA20_UARTA_UAA_UAB)
 	FUNCMUX_UART1_UAA_UAB,
diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h
index 17c710e..6272570 100644
--- a/include/configs/tegra20-common.h
+++ b/include/configs/tegra20-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/tegra20.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 */