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

Simon Glass sjg at chromium.org
Sat Jun 9 21:19:48 CEST 2012


Hi Allen,

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

> This code is now included in the tegra20 SPL
>
> Signed-off-by: Allen Martin <amartin at 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


More information about the U-Boot mailing list