OLD | NEW |
1 /* | 1 /* |
2 * (C) Copyright 2010-2011 | 2 * (C) Copyright 2010-2011 |
3 * NVIDIA Corporation <www.nvidia.com> | 3 * NVIDIA Corporation <www.nvidia.com> |
4 * | 4 * |
5 * See file CREDITS for list of people who contributed to this | 5 * See file CREDITS for list of people who contributed to this |
6 * project. | 6 * project. |
7 * | 7 * |
8 * This program is free software; you can redistribute it and/or | 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 | 9 * modify it under the terms of the GNU General Public License as |
10 * published by the Free Software Foundation; either version 2 of | 10 * published by the Free Software Foundation; either version 2 of |
11 * the License, or (at your option) any later version. | 11 * the License, or (at your option) any later version. |
12 * | 12 * |
13 * This program is distributed in the hope that it will be useful, | 13 * This program is distributed in the hope that it will be useful, |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 * GNU General Public License for more details. | 16 * GNU General Public License for more details. |
17 * | 17 * |
18 * You should have received a copy of the GNU General Public License | 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 | 19 * along with this program; if not, write to the Free Software |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
21 * MA 02111-1307 USA | 21 * MA 02111-1307 USA |
22 */ | 22 */ |
23 | 23 |
24 #include "ap20.h" | 24 #include "ap20.h" |
25 #include <asm/io.h> | 25 #include <asm/io.h> |
26 #include <asm/arch/tegra2.h> | 26 #include <asm/arch/tegra2.h> |
27 #include <asm/arch/clk_rst.h> | 27 #include <asm/arch/clk_rst.h> |
| 28 #include <asm/arch/clock.h> |
28 #include <asm/arch/pmc.h> | 29 #include <asm/arch/pmc.h> |
29 #include <asm/arch/pinmux.h> | 30 #include <asm/arch/pinmux.h> |
30 #include <asm/arch/scu.h> | 31 #include <asm/arch/scu.h> |
31 #include <common.h> | 32 #include <common.h> |
32 | 33 |
33 u32 s_first_boot = 1; | 34 u32 s_first_boot = 1; |
34 | 35 |
35 void init_pllx(void) | 36 void init_pllx(void) |
36 { | 37 { |
37 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 38 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; |
| 39 struct clk_pll *pll = &clkrst->crc_pll[CLOCK_PLL_ID_XCPU]; |
38 u32 reg; | 40 u32 reg; |
39 | 41 |
40 /* If PLLX is already enabled, just return */ | 42 /* If PLLX is already enabled, just return */ |
41 » reg = readl(&clkrst->crc_pllx_base); | 43 » reg = readl(&pll->pll_base); |
42 » if (reg & PLL_ENABLE) | 44 » if (reg & PLL_ENABLE_BIT) |
43 return; | 45 return; |
44 | 46 |
45 /* Set PLLX_MISC */ | 47 /* Set PLLX_MISC */ |
46 reg = CPCON; /* CPCON[11:8] = 0001 */ | 48 reg = CPCON; /* CPCON[11:8] = 0001 */ |
47 » writel(reg, &clkrst->crc_pllx_misc); | 49 » writel(reg, &pll->pll_misc); |
48 | 50 |
49 /* Use 12MHz clock here */ | 51 /* Use 12MHz clock here */ |
50 » reg = (PLL_BYPASS | PLL_DIVM); | 52 » reg = (PLL_BYPASS_BIT | PLL_DIVM_VALUE); |
51 reg |= (1000 << 8); /* DIVN = 0x3E8 */ | 53 reg |= (1000 << 8); /* DIVN = 0x3E8 */ |
52 » writel(reg, &clkrst->crc_pllx_base); | 54 » writel(reg, &pll->pll_base); |
53 | 55 |
54 » reg |= PLL_ENABLE; | 56 » reg |= PLL_ENABLE_BIT; |
55 » writel(reg, &clkrst->crc_pllx_base); | 57 » writel(reg, &pll->pll_base); |
56 | 58 |
57 » reg &= ~PLL_BYPASS; | 59 » reg &= ~PLL_BYPASS_BIT; |
58 » writel(reg, &clkrst->crc_pllx_base); | 60 » writel(reg, &pll->pll_base); |
59 } | 61 } |
60 | 62 |
61 static void enable_cpu_clock(int enable) | 63 static void enable_cpu_clock(int enable) |
62 { | 64 { |
63 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 65 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; |
64 » u32 reg, clk; | 66 » u32 clk; |
65 | 67 |
66 /* | 68 /* |
67 * NOTE: | 69 * NOTE: |
68 * Regardless of whether the request is to enable or disable the CPU | 70 * Regardless of whether the request is to enable or disable the CPU |
69 * clock, every processor in the CPU complex except the master (CPU 0) | 71 * clock, every processor in the CPU complex except the master (CPU 0) |
70 * will have it's clock stopped because the AVP only talks to the | 72 * will have it's clock stopped because the AVP only talks to the |
71 * master. The AVP does not know (nor does it need to know) that there | 73 * master. The AVP does not know (nor does it need to know) that there |
72 * are multiple processors in the CPU complex. | 74 * are multiple processors in the CPU complex. |
73 */ | 75 */ |
74 | 76 |
75 if (enable) { | 77 if (enable) { |
76 /* Initialize PLLX */ | 78 /* Initialize PLLX */ |
77 init_pllx(); | 79 init_pllx(); |
78 | 80 |
79 /* Wait until all clocks are stable */ | 81 /* Wait until all clocks are stable */ |
80 udelay(PLL_STABILIZATION_DELAY); | 82 udelay(PLL_STABILIZATION_DELAY); |
81 | 83 |
82 writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); | 84 writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); |
83 writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); | 85 writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); |
84 } | 86 } |
85 | 87 |
86 /* Fetch the register containing the main CPU complex clock enable */ | |
87 reg = readl(&clkrst->crc_clk_out_enb_l); | |
88 reg |= CLK_ENB_CPU; | |
89 | |
90 /* | 88 /* |
91 * Read the register containing the individual CPU clock enables and | 89 * Read the register containing the individual CPU clock enables and |
92 * always stop the clock to CPU 1. | 90 * always stop the clock to CPU 1. |
93 */ | 91 */ |
94 clk = readl(&clkrst->crc_clk_cpu_cmplx); | 92 clk = readl(&clkrst->crc_clk_cpu_cmplx); |
95 clk |= CPU1_CLK_STP; | 93 clk |= CPU1_CLK_STP; |
96 | 94 |
97 if (enable) { | 95 if (enable) { |
98 /* Unstop the CPU clock */ | 96 /* Unstop the CPU clock */ |
99 clk &= ~CPU0_CLK_STP; | 97 clk &= ~CPU0_CLK_STP; |
100 } else { | 98 } else { |
101 /* Stop the CPU clock */ | 99 /* Stop the CPU clock */ |
102 clk |= CPU0_CLK_STP; | 100 clk |= CPU0_CLK_STP; |
103 } | 101 } |
104 | 102 |
105 writel(clk, &clkrst->crc_clk_cpu_cmplx); | 103 writel(clk, &clkrst->crc_clk_cpu_cmplx); |
106 » writel(reg, &clkrst->crc_clk_out_enb_l); | 104 » clock_enable(PERIPH_ID_CPU); |
107 } | 105 } |
108 | 106 |
109 static int is_cpu_powered(void) | 107 static int is_cpu_powered(void) |
110 { | 108 { |
111 struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; | 109 struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; |
112 | 110 |
113 return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; | 111 return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; |
114 } | 112 } |
115 | 113 |
116 static void remove_cpu_io_clamps(void) | 114 static void remove_cpu_io_clamps(void) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 * the power rail and enabling the CPU clock. This delay | 170 * the power rail and enabling the CPU clock. This delay |
173 * between SM1EN and SM1 is for switching time + the ramp | 171 * between SM1EN and SM1 is for switching time + the ramp |
174 * up of the voltage to the CPU (VDD_CPU from PMU). | 172 * up of the voltage to the CPU (VDD_CPU from PMU). |
175 */ | 173 */ |
176 udelay(3750); | 174 udelay(3750); |
177 } | 175 } |
178 | 176 |
179 static void reset_A9_cpu(int reset) | 177 static void reset_A9_cpu(int reset) |
180 { | 178 { |
181 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 179 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; |
182 » u32 reg, cpu; | 180 » u32 cpu; |
183 | 181 |
184 /* | 182 /* |
185 * NOTE: Regardless of whether the request is to hold the CPU in reset | 183 * NOTE: Regardless of whether the request is to hold the CPU in reset |
186 * or take it out of reset, every processor in the CPU complex | 184 * or take it out of reset, every processor in the CPU complex |
187 * except the master (CPU 0) will be held in reset because the | 185 * except the master (CPU 0) will be held in reset because the |
188 * AVP only talks to the master. The AVP does not know that there | 186 * AVP only talks to the master. The AVP does not know that there |
189 * are multiple processors in the CPU complex. | 187 * are multiple processors in the CPU complex. |
190 */ | 188 */ |
191 | 189 |
192 /* Hold CPU 1 in reset */ | 190 /* Hold CPU 1 in reset */ |
193 cpu = SET_DBGRESET1 | SET_DERESET1 | SET_CPURESET1; | 191 cpu = SET_DBGRESET1 | SET_DERESET1 | SET_CPURESET1; |
194 writel(cpu, &clkrst->crc_cpu_cmplx_set); | 192 writel(cpu, &clkrst->crc_cpu_cmplx_set); |
195 | 193 |
196 reg = readl(&clkrst->crc_rst_dev_l); | |
197 if (reset) { | 194 if (reset) { |
198 /* Now place CPU0 into reset */ | 195 /* Now place CPU0 into reset */ |
199 cpu |= SET_DBGRESET0 | SET_DERESET0 | SET_CPURESET0; | 196 cpu |= SET_DBGRESET0 | SET_DERESET0 | SET_CPURESET0; |
200 writel(cpu, &clkrst->crc_cpu_cmplx_set); | 197 writel(cpu, &clkrst->crc_cpu_cmplx_set); |
201 | |
202 /* Enable master CPU reset */ | |
203 reg |= SWR_CPU_RST; | |
204 } else { | 198 } else { |
205 /* Take CPU0 out of reset */ | 199 /* Take CPU0 out of reset */ |
206 cpu = CLR_DBGRESET0 | CLR_DERESET0 | CLR_CPURESET0; | 200 cpu = CLR_DBGRESET0 | CLR_DERESET0 | CLR_CPURESET0; |
207 writel(cpu, &clkrst->crc_cpu_cmplx_clr); | 201 writel(cpu, &clkrst->crc_cpu_cmplx_clr); |
208 | |
209 /* Disable master CPU reset */ | |
210 reg &= ~SWR_CPU_RST; | |
211 } | 202 } |
212 | 203 |
213 » writel(reg, &clkrst->crc_rst_dev_l); | 204 » /* Enable/Disable master CPU reset */ |
| 205 » reset_set_enable(PERIPH_ID_CPU, reset); |
214 } | 206 } |
215 | 207 |
216 static void clock_enable_coresight(int enable) | 208 static void clock_enable_coresight(int enable) |
217 { | 209 { |
218 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; | 210 struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; |
219 » u32 rst, clk, src; | 211 » u32 rst, src; |
220 | 212 |
221 » rst = readl(&clkrst->crc_rst_dev_u); | 213 » clock_set_enable(PERIPH_ID_CORESIGHT, enable); |
222 » clk = readl(&clkrst->crc_clk_out_enb_u); | 214 » reset_set_enable(PERIPH_ID_CORESIGHT, !enable); |
223 | |
224 » if (enable) { | |
225 » » rst &= ~SWR_CSITE_RST; | |
226 » » clk |= CLK_ENB_CSITE; | |
227 » } else { | |
228 » » rst |= SWR_CSITE_RST; | |
229 » » clk &= ~CLK_ENB_CSITE; | |
230 » } | |
231 | |
232 » writel(clk, &clkrst->crc_clk_out_enb_u); | |
233 » writel(rst, &clkrst->crc_rst_dev_u); | |
234 | 215 |
235 if (enable) { | 216 if (enable) { |
236 /* | 217 /* |
237 * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by | 218 * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by |
238 * 1.5, giving an effective frequency of 144MHz. | 219 * 1.5, giving an effective frequency of 144MHz. |
239 * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor | 220 * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor |
240 * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) | 221 * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) |
241 */ | 222 */ |
242 src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); | 223 src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); |
243 writel(src, &clkrst->crc_clk_src_csite); | 224 writel(src, &clkrst->crc_clk_src_csite); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 330 } |
350 | 331 |
351 #ifdef CONFIG_ENABLE_CORTEXA9 | 332 #ifdef CONFIG_ENABLE_CORTEXA9 |
352 /* take the mpcore out of reset */ | 333 /* take the mpcore out of reset */ |
353 cpu_start(); | 334 cpu_start(); |
354 | 335 |
355 /* configure cache */ | 336 /* configure cache */ |
356 cache_configure(); | 337 cache_configure(); |
357 #endif | 338 #endif |
358 } | 339 } |
OLD | NEW |