]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/tegra2/warmboot_avp.c
tx25: Use generic gpio_* calls
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / tegra2 / warmboot_avp.c
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
38 void 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: */
230 avp_halt:
231         reg = EVENT_MODE_STOP | EVENT_JTAG;
232         writel(reg, flow->halt_cop_events);
233         goto avp_halt;
234
235 do_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  */
248 void wb_end(void)
249 {
250 }