uboot/arch/arm/cpu/armv7/tegra2/warmboot_avp.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010 - 2011
   3 * NVIDIA Corporation <www.nvidia.com>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <asm/io.h>
  26#include <asm/arch/ap20.h>
  27#include <asm/arch/clk_rst.h>
  28#include <asm/arch/clock.h>
  29#include <asm/arch/flow.h>
  30#include <asm/arch/pinmux.h>
  31#include <asm/arch/pmc.h>
  32#include <asm/arch/tegra2.h>
  33#include <asm/arch/warmboot.h>
  34#include "warmboot_avp.h"
  35
  36#define DEBUG_RESET_CORESIGHT
  37
  38void wb_start(void)
  39{
  40        struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
  41        struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
  42        struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;
  43        struct clk_rst_ctlr *clkrst =
  44                        (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
  45        union osc_ctrl_reg osc_ctrl;
  46        union pllx_base_reg pllx_base;
  47        union pllx_misc_reg pllx_misc;
  48        union scratch3_reg scratch3;
  49        u32 reg;
  50
  51        /* enable JTAG & TBE */
  52        writel(CONFIG_CTL_TBE | CONFIG_CTL_JTAG, &pmt->pmt_cfg_ctl);
  53
  54        /* Are we running where we're supposed to be? */
  55        asm volatile (
  56                "adr    %0, wb_start;"  /* reg: wb_start address */
  57                : "=r"(reg)             /* output */
  58                                        /* no input, no clobber list */
  59        );
  60
  61        if (reg != AP20_WB_RUN_ADDRESS)
  62                goto do_reset;
  63
  64        /* Are we running with AVP? */
  65        if (readl(NV_PA_PG_UP_BASE + PG_UP_TAG_0) != PG_UP_TAG_AVP)
  66                goto do_reset;
  67
  68#ifdef DEBUG_RESET_CORESIGHT
  69        /* Assert CoreSight reset */
  70        reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
  71        reg |= SWR_CSITE_RST;
  72        writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
  73#endif
  74
  75        /* TODO: Set the drive strength - maybe make this a board parameter? */
  76        osc_ctrl.word = readl(&clkrst->crc_osc_ctrl);
  77        osc_ctrl.xofs = 4;
  78        osc_ctrl.xoe = 1;
  79        writel(osc_ctrl.word, &clkrst->crc_osc_ctrl);
  80
  81        /* Power up the CPU complex if necessary */
  82        if (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU)) {
  83                reg = PWRGATE_TOGGLE_PARTID_CPU | PWRGATE_TOGGLE_START;
  84                writel(reg, &pmc->pmc_pwrgate_toggle);
  85                while (!(readl(&pmc->pmc_pwrgate_status) & PWRGATE_STATUS_CPU))
  86                        ;
  87        }
  88
  89        /* Remove the I/O clamps from the CPU power partition. */
  90        reg = readl(&pmc->pmc_remove_clamping);
  91        reg |= CPU_CLMP;
  92        writel(reg, &pmc->pmc_remove_clamping);
  93
  94        reg = EVENT_ZERO_VAL_20 | EVENT_MSEC | EVENT_MODE_STOP;
  95        writel(reg, &flow->halt_cop_events);
  96
  97        /* Assert CPU complex reset */
  98        reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
  99        reg |= CPU_RST;
 100        writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
 101
 102        /* Hold both CPUs in reset */
 103        reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_CPURESET1 | CPU_CMPLX_DERESET0 |
 104              CPU_CMPLX_DERESET1 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DBGRESET1;
 105        writel(reg, &clkrst->crc_cpu_cmplx_set);
 106
 107        /* Halt CPU1 at the flow controller for uni-processor configurations */
 108        writel(EVENT_MODE_STOP, &flow->halt_cpu1_events);
 109
 110        /*
 111         * Set the CPU reset vector. SCRATCH41 contains the physical
 112         * address of the CPU-side restoration code.
 113         */
 114        reg = readl(&pmc->pmc_scratch41);
 115        writel(reg, EXCEP_VECTOR_CPU_RESET_VECTOR);
 116
 117        /* Select CPU complex clock source */
 118        writel(CCLK_PLLP_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
 119
 120        /* Start the CPU0 clock and stop the CPU1 clock */
 121        reg = CPU_CMPLX_CPU_BRIDGE_CLKDIV_4 | CPU_CMPLX_CPU0_CLK_STP_RUN |
 122              CPU_CMPLX_CPU1_CLK_STP_STOP;
 123        writel(reg, &clkrst->crc_clk_cpu_cmplx);
 124
 125        /* Enable the CPU complex clock */
 126        reg = readl(&clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
 127        reg |= CLK_ENB_CPU;
 128        writel(reg, &clkrst->crc_clk_out_enb[TEGRA_DEV_L]);
 129
 130        /* Make sure the resets were held for at least 2 microseconds */
 131        reg = readl(TIMER_USEC_CNTR);
 132        while (readl(TIMER_USEC_CNTR) <= (reg + 2))
 133                ;
 134
 135#ifdef DEBUG_RESET_CORESIGHT
 136        /*
 137         * De-assert CoreSight reset.
 138         * NOTE: We're leaving the CoreSight clock on the oscillator for
 139         *      now. It will be restored to its original clock source
 140         *      when the CPU-side restoration code runs.
 141         */
 142        reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_U]);
 143        reg &= ~SWR_CSITE_RST;
 144        writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_U]);
 145#endif
 146
 147        /* Unlock the CPU CoreSight interfaces */
 148        reg = 0xC5ACCE55;
 149        writel(reg, CSITE_CPU_DBG0_LAR);
 150        writel(reg, CSITE_CPU_DBG1_LAR);
 151
 152        /*
 153         * Sample the microsecond timestamp again. This is the time we must
 154         * use when returning from LP0 for PLL stabilization delays.
 155         */
 156        reg = readl(TIMER_USEC_CNTR);
 157        writel(reg, &pmc->pmc_scratch1);
 158
 159        pllx_base.word = 0;
 160        pllx_misc.word = 0;
 161        scratch3.word = readl(&pmc->pmc_scratch3);
 162
 163        /* Get the OSC. For 19.2 MHz, use 19 to make the calculations easier */
 164        reg = (readl(TIMER_USEC_CFG) & USEC_CFG_DIVISOR_MASK) + 1;
 165
 166        /*
 167         * According to the TRM, for 19.2MHz OSC, the USEC_DIVISOR is 0x5f, and
 168         * USEC_DIVIDEND is 0x04. So, if USEC_DIVISOR > 26, OSC is 19.2 MHz.
 169         *
 170         * reg is used to calculate the pllx freq, which is used to determine if
 171         * to set dccon or not.
 172         */
 173        if (reg > 26)
 174                reg = 19;
 175
 176        /* PLLX_BASE.PLLX_DIVM */
 177        if (scratch3.pllx_base_divm == reg)
 178                reg = 0;
 179        else
 180                reg = 1;
 181
 182        /* PLLX_BASE.PLLX_DIVN */
 183        pllx_base.divn = scratch3.pllx_base_divn;
 184        reg = scratch3.pllx_base_divn << reg;
 185
 186        /* PLLX_BASE.PLLX_DIVP */
 187        pllx_base.divp = scratch3.pllx_base_divp;
 188        reg = reg >> scratch3.pllx_base_divp;
 189
 190        pllx_base.bypass = 1;
 191
 192        /* PLLX_MISC_DCCON must be set for pllx frequency > 600 MHz. */
 193        if (reg > 600)
 194                pllx_misc.dccon = 1;
 195
 196        /* PLLX_MISC_LFCON */
 197        pllx_misc.lfcon = scratch3.pllx_misc_lfcon;
 198
 199        /* PLLX_MISC_CPCON */
 200        pllx_misc.cpcon = scratch3.pllx_misc_cpcon;
 201
 202        writel(pllx_misc.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_misc);
 203        writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
 204
 205        pllx_base.enable = 1;
 206        writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
 207        pllx_base.bypass = 0;
 208        writel(pllx_base.word, &clkrst->crc_pll_simple[SIMPLE_PLLX].pll_base);
 209
 210        writel(0, flow->halt_cpu_events);
 211
 212        reg = CPU_CMPLX_CPURESET0 | CPU_CMPLX_DBGRESET0 | CPU_CMPLX_DERESET0;
 213        writel(reg, &clkrst->crc_cpu_cmplx_clr);
 214
 215        reg = PLLM_OUT1_RSTN_RESET_DISABLE | PLLM_OUT1_CLKEN_ENABLE |
 216              PLLM_OUT1_RATIO_VAL_8;
 217        writel(reg, &clkrst->crc_pll[CLOCK_ID_MEMORY].pll_out);
 218
 219        reg = SCLK_SWAKE_FIQ_SRC_PLLM_OUT1 | SCLK_SWAKE_IRQ_SRC_PLLM_OUT1 |
 220              SCLK_SWAKE_RUN_SRC_PLLM_OUT1 | SCLK_SWAKE_IDLE_SRC_PLLM_OUT1 |
 221              SCLK_SYS_STATE_IDLE;
 222        writel(reg, &clkrst->crc_sclk_brst_pol);
 223
 224        /* avp_resume: no return after the write */
 225        reg = readl(&clkrst->crc_rst_dev[TEGRA_DEV_L]);
 226        reg &= ~CPU_RST;
 227        writel(reg, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
 228
 229        /* avp_halt: */
 230avp_halt:
 231        reg = EVENT_MODE_STOP | EVENT_JTAG;
 232        writel(reg, flow->halt_cop_events);
 233        goto avp_halt;
 234
 235do_reset:
 236        /*
 237         * Execution comes here if something goes wrong. The chip is reset and
 238         * a cold boot is performed.
 239         */
 240        writel(SWR_TRIG_SYS_RST, &clkrst->crc_rst_dev[TEGRA_DEV_L]);
 241        goto do_reset;
 242}
 243
 244/*
 245 * wb_end() is a dummy function, and must be directly following wb_start(),
 246 * and is used to calculate the size of wb_start().
 247 */
 248void wb_end(void)
 249{
 250}
 251