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