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 22 void 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: */ 215 avp_halt: 216 reg = EVENT_MODE_STOP | EVENT_JTAG; 217 writel(reg, flow->halt_cop_events); 218 goto avp_halt; 219 220 do_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 */ 233 void wb_end(void) 234 { 235 } 236