ARM: tegra: Finish suspend.h -> pm.h rename
[linux-2.6.git] / arch / arm / mach-tegra / pm-t2.c
1 /*
2  * arch/arm/mach-tegra/pm-t2.c
3  *
4  * Tegra 2 LP0 scratch register preservation
5  *
6  * Copyright (c) 2009-2010, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/gpio.h>
25 #include <linux/init.h>
26 #include <linux/io.h>
27
28 #include <mach/iomap.h>
29 #include <mach/irqs.h>
30
31 #include "gpio-names.h"
32
33 #define PMC_SCRATCH3    0x5c
34 #define PMC_SCRATCH5    0x64
35 #define PMC_SCRATCH6    0x68
36 #define PMC_SCRATCH7    0x6c
37 #define PMC_SCRATCH8    0x70
38 #define PMC_SCRATCH9    0x74
39 #define PMC_SCRATCH10   0x78
40 #define PMC_SCRATCH11   0x7c
41 #define PMC_SCRATCH12   0x80
42 #define PMC_SCRATCH13   0x84
43 #define PMC_SCRATCH14   0x88
44 #define PMC_SCRATCH15   0x8c
45 #define PMC_SCRATCH16   0x90
46 #define PMC_SCRATCH17   0x94
47 #define PMC_SCRATCH18   0x98
48 #define PMC_SCRATCH19   0x9c
49 #define PMC_SCRATCH20   0xa0
50 #define PMC_SCRATCH21   0xa4
51 #define PMC_SCRATCH22   0xa8
52 #define PMC_SCRATCH23   0xac
53 #define PMC_SCRATCH25   0x100
54 #define PMC_SCRATCH35   0x128
55 #define PMC_SCRATCH36   0x12c
56 #define PMC_SCRATCH40   0x13c
57
58 struct pmc_scratch_field {
59         unsigned long addr;
60         unsigned int mask;
61         int shift_src;
62         int shift_dst;
63 };
64
65 #define field(reg, start, end, dst)                                     \
66         {                                                               \
67                 .addr = (reg),                                          \
68                 .mask = 0xfffffffful >> (31 - ((end) - (start))),       \
69                 .shift_src = (start),                                   \
70                 .shift_dst = (dst),                                     \
71         }
72
73 static const struct pmc_scratch_field pllx[] __initdata = {
74         field(TEGRA_CLK_RESET_BASE + 0xe0, 20, 22, 15), /* PLLX_DIVP */
75         field(TEGRA_CLK_RESET_BASE + 0xe0, 8, 17, 5), /* PLLX_DIVN */
76         field(TEGRA_CLK_RESET_BASE + 0xe0, 0, 4, 0), /* PLLX_DIVM */
77         field(TEGRA_CLK_RESET_BASE + 0xe4, 8, 11, 22), /* PLLX_CPCON */
78         field(TEGRA_CLK_RESET_BASE + 0xe4, 4, 7, 18), /* PLLX_LFCON */
79         field(TEGRA_APB_MISC_BASE + 0x8e4, 24, 27, 27), /* XM2CFGC_VREF_DQ */
80         field(TEGRA_APB_MISC_BASE + 0x8c8, 3, 3, 26), /* XM2CFGC_SCHMT_EN */
81         field(TEGRA_APB_MISC_BASE + 0x8d0, 2, 2, 31), /* XM2CLKCFG_PREEMP_EN */
82 };
83
84 static const struct pmc_scratch_field emc_0[] __initdata = {
85         field(TEGRA_EMC_BASE + 0x3c, 0, 4, 27), /* R2W */
86         field(TEGRA_EMC_BASE + 0x34, 0, 5, 15), /* RAS */
87         field(TEGRA_EMC_BASE + 0x2c, 0, 5, 0), /* RC */
88         field(TEGRA_EMC_BASE + 0x30, 0, 8, 6), /* RFC */
89         field(TEGRA_EMC_BASE + 0x38, 0, 5, 21), /* RP */
90 };
91
92 static const struct pmc_scratch_field emc_1[] __initdata = {
93         field(TEGRA_EMC_BASE + 0x44, 0, 4, 5), /* R2P */
94         field(TEGRA_EMC_BASE + 0x4c, 0, 5, 15), /* RD_RCD */
95         field(TEGRA_EMC_BASE + 0x54, 0, 3, 27), /* RRD */
96         field(TEGRA_EMC_BASE + 0x48, 0, 4, 10), /* W2P */
97         field(TEGRA_EMC_BASE + 0x40, 0, 4, 0), /* W2R */
98         field(TEGRA_EMC_BASE + 0x50, 0, 5, 21), /* WR_RCD */
99 };
100
101 static const struct pmc_scratch_field emc_2[] __initdata = {
102         field(TEGRA_EMC_BASE + 0x2b8, 2, 2, 31), /* CLKCHANGE_SR_ENABLE */
103         field(TEGRA_EMC_BASE + 0x2b8, 10, 10, 30), /* USE_ADDR_CLK */
104         field(TEGRA_EMC_BASE + 0x80, 0, 4, 25), /* PCHG2PDEN */
105         field(TEGRA_EMC_BASE + 0x64, 0, 3, 12), /* QRST */
106         field(TEGRA_EMC_BASE + 0x68, 0, 3, 16), /* QSAFE */
107         field(TEGRA_EMC_BASE + 0x60, 0, 3, 8), /* QUSE */
108         field(TEGRA_EMC_BASE + 0x6c, 0, 4, 20), /* RDV */
109         field(TEGRA_EMC_BASE + 0x58, 0, 3, 0), /* REXT */
110         field(TEGRA_EMC_BASE + 0x5c, 0, 3, 4), /* WDV */
111 };
112
113 static const struct pmc_scratch_field emc_3[] __initdata = {
114         field(TEGRA_EMC_BASE + 0x74, 0, 3, 16), /* BURST_REFRESH_NUM */
115         field(TEGRA_EMC_BASE + 0x7c, 0, 3, 24), /* PDEX2RD */
116         field(TEGRA_EMC_BASE + 0x78, 0, 3, 20), /* PDEX2WR */
117         field(TEGRA_EMC_BASE + 0x70, 0, 4, 0), /* REFRESH_LO */
118         field(TEGRA_EMC_BASE + 0x70, 5, 15, 5), /* REFRESH */
119         field(TEGRA_EMC_BASE + 0xa0, 0, 3, 28), /* TCLKSTABLE */
120 };
121
122 static const struct pmc_scratch_field emc_4[] __initdata = {
123         field(TEGRA_EMC_BASE + 0x84, 0, 4, 0), /* ACT2PDEN */
124         field(TEGRA_EMC_BASE + 0x88, 0, 4, 5), /* AR2PDEN */
125         field(TEGRA_EMC_BASE + 0x8c, 0, 5, 10), /* RW2PDEN */
126         field(TEGRA_EMC_BASE + 0x94, 0, 3, 28), /* TCKE */
127         field(TEGRA_EMC_BASE + 0x90, 0, 11, 16), /* TXSR */
128 };
129
130 static const struct pmc_scratch_field emc_5[] __initdata = {
131         field(TEGRA_EMC_BASE + 0x8, 10, 10, 30), /* AP_REQ_BUSY_CTRL */
132         field(TEGRA_EMC_BASE + 0x8, 24, 24, 31), /* CFG_PRIORITY */
133         field(TEGRA_EMC_BASE + 0x8, 2, 2, 26), /* FORCE_UPDATE */
134         field(TEGRA_EMC_BASE + 0x8, 4, 4, 27), /* MRS_WAIT */
135         field(TEGRA_EMC_BASE + 0x8, 5, 5, 28), /* PERIODIC_QRST */
136         field(TEGRA_EMC_BASE + 0x8, 9, 9, 29), /* READ_DQM_CTRL */
137         field(TEGRA_EMC_BASE + 0x8, 0, 0, 24), /* READ_MUX */
138         field(TEGRA_EMC_BASE + 0x8, 1, 1, 25), /* WRITE_MUX */
139         field(TEGRA_EMC_BASE + 0xa4, 0, 3, 6), /* TCLKSTOP */
140         field(TEGRA_EMC_BASE + 0xa8, 0, 13, 10), /* TREFBW */
141         field(TEGRA_EMC_BASE + 0x9c, 0, 5, 0), /* TRPAB */
142 };
143
144 static const struct pmc_scratch_field emc_6[] __initdata = {
145         field(TEGRA_EMC_BASE + 0xfc, 0, 1, 0), /* DQSIB_DLY_MSB_BYTE_0 */
146         field(TEGRA_EMC_BASE + 0xfc, 8, 9, 2), /* DQSIB_DLY_MSB_BYTE_1 */
147         field(TEGRA_EMC_BASE + 0xfc, 16, 17, 4), /* DQSIB_DLY_MSB_BYTE_2 */
148         field(TEGRA_EMC_BASE + 0xfc, 24, 25, 6), /* DQSIB_DLY_MSB_BYTE_3 */
149         field(TEGRA_EMC_BASE + 0x110, 0, 1, 8), /* QUSE_DLY_MSB_BYTE_0 */
150         field(TEGRA_EMC_BASE + 0x110, 8, 9, 10), /* QUSE_DLY_MSB_BYTE_1 */
151         field(TEGRA_EMC_BASE + 0x110, 16, 17, 12), /* QUSE_DLY_MSB_BYTE_2 */
152         field(TEGRA_EMC_BASE + 0x110, 24, 25, 14), /* QUSE_DLY_MSB_BYTE_3 */
153         field(TEGRA_EMC_BASE + 0xac, 0, 3, 22), /* QUSE_EXTRA */
154         field(TEGRA_EMC_BASE + 0x98, 0, 5, 16), /* TFAW */
155         field(TEGRA_APB_MISC_BASE + 0x8e4, 5, 5, 30), /* XM2CFGC_VREF_DQ_EN */
156         field(TEGRA_APB_MISC_BASE + 0x8e4, 16, 19, 26), /* XM2CFGC_VREF_DQS */
157 };
158
159 static const struct pmc_scratch_field emc_dqsib_dly[] __initdata = {
160         field(TEGRA_EMC_BASE + 0xf8, 0, 31, 0), /* DQSIB_DLY_BYTE_0 - DQSIB_DLY_BYTE_3*/
161 };
162
163 static const struct pmc_scratch_field emc_quse_dly[] __initdata = {
164         field(TEGRA_EMC_BASE + 0x10c, 0, 31, 0), /* QUSE_DLY_BYTE_0 - QUSE_DLY_BYTE_3*/
165 };
166
167 static const struct pmc_scratch_field emc_clktrim[] __initdata = {
168         field(TEGRA_EMC_BASE + 0x2d0, 0, 29, 0), /* DATA0_CLKTRIM - DATA3_CLKTRIM +
169                                         * MCLK_ADDR_CLKTRIM */
170 };
171
172 static const struct pmc_scratch_field emc_autocal_fbio[] __initdata = {
173         field(TEGRA_EMC_BASE + 0x2a4, 29, 29, 29), /* AUTO_CAL_ENABLE */
174         field(TEGRA_EMC_BASE + 0x2a4, 30, 30, 30), /* AUTO_CAL_OVERRIDE */
175         field(TEGRA_EMC_BASE + 0x2a4, 8, 12, 14), /* AUTO_CAL_PD_OFFSET */
176         field(TEGRA_EMC_BASE + 0x2a4, 0, 4, 9), /* AUTO_CAL_PU_OFFSET */
177         field(TEGRA_EMC_BASE + 0x2a4, 16, 25, 19), /* AUTO_CAL_STEP */
178         field(TEGRA_EMC_BASE + 0xf4, 16, 16, 0), /* CFG_DEN_EARLY */
179         field(TEGRA_EMC_BASE + 0x104, 8, 8, 8), /* CTT_TERMINATION */
180         field(TEGRA_EMC_BASE + 0x104, 7, 7, 7), /* DIFFERENTIAL_DQS */
181         field(TEGRA_EMC_BASE + 0x104, 9, 9, 31), /* DQS_PULLD */
182         field(TEGRA_EMC_BASE + 0x104, 0, 1, 4), /* DRAM_TYPE */
183         field(TEGRA_EMC_BASE + 0x104, 4, 4, 6), /* DRAM_WIDTH */
184         field(TEGRA_EMC_BASE + 0x114, 0, 2, 1), /* CFG_QUSE_LATE */
185 };
186
187 static const struct pmc_scratch_field emc_autocal_interval[] __initdata = {
188         field(TEGRA_EMC_BASE + 0x2a8, 0, 27, 0), /* AUTOCAL_INTERVAL */
189         field(TEGRA_EMC_BASE + 0x2b8, 1, 1, 29), /* CLKCHANGE_PD_ENABLE */
190         field(TEGRA_EMC_BASE + 0x2b8, 0, 0, 28), /* CLKCHANGE_REQ_ENABLE */
191         field(TEGRA_EMC_BASE + 0x2b8, 8, 9, 30), /* PIN_CONFIG */
192 };
193
194 static const struct pmc_scratch_field emc_cfgs[] __initdata = {
195         field(TEGRA_EMC_BASE + 0x10, 8, 9, 3), /* EMEM_BANKWIDTH */
196         field(TEGRA_EMC_BASE + 0x10, 0, 2, 0), /* EMEM_COLWIDTH */
197         field(TEGRA_EMC_BASE + 0x10, 16, 19, 5), /* EMEM_DEVSIZE */
198         field(TEGRA_EMC_BASE + 0x10, 24, 25, 9), /* EMEM_NUMDEV */
199         field(TEGRA_EMC_BASE + 0xc, 24, 24, 21), /* AUTO_PRE_RD */
200         field(TEGRA_EMC_BASE + 0xc, 25, 25, 22), /* AUTO_PRE_WR */
201         field(TEGRA_EMC_BASE + 0xc, 16, 16, 20), /* CLEAR_AP_PREV_SPREQ */
202         field(TEGRA_EMC_BASE + 0xc, 29, 29, 23), /* DRAM_ACPD */
203         field(TEGRA_EMC_BASE + 0xc, 30, 30, 24), /* DRAM_CLKSTOP_PDSR_ONLY */
204         field(TEGRA_EMC_BASE + 0xc, 31, 31, 25), /* DRAM_CLKSTOP */
205         field(TEGRA_EMC_BASE + 0xc, 8, 15, 12), /* PRE_IDLE_CYCLES */
206         field(TEGRA_EMC_BASE + 0xc, 0, 0, 11), /* PRE_IDLE_EN */
207         field(TEGRA_EMC_BASE + 0x2bc, 28, 29, 28), /* CFG_DLL_LOCK_LIMIT */
208         field(TEGRA_EMC_BASE + 0x2bc, 6, 7, 30), /* CFG_DLL_MODE */
209         field(TEGRA_MC_BASE + 0x10c, 0, 0, 26), /* LL_CTRL */
210         field(TEGRA_MC_BASE + 0x10c, 1, 1, 27), /* LL_SEND_BOTH */
211 };
212
213 static const struct pmc_scratch_field emc_adr_cfg1[] __initdata = {
214         field(TEGRA_EMC_BASE + 0x14, 8, 9, 8), /* EMEM1_BANKWIDTH */
215         field(TEGRA_EMC_BASE + 0x14, 0, 2, 5), /* EMEM1_COLWIDTH */
216         field(TEGRA_EMC_BASE + 0x14, 16, 19, 10), /* EMEM1_DEVSIZE */
217         field(TEGRA_EMC_BASE + 0x2dc, 24, 28, 0), /* TERM_DRVUP */
218         field(TEGRA_APB_MISC_BASE + 0x8d4, 0, 3, 14), /* XM2COMP_VREF_SEL */
219         field(TEGRA_APB_MISC_BASE + 0x8d8, 16, 18, 21), /* XM2VTTGEN_CAL_DRVDN */
220         field(TEGRA_APB_MISC_BASE + 0x8d8, 24, 26, 18), /* XM2VTTGEN_CAL_DRVUP */
221         field(TEGRA_APB_MISC_BASE + 0x8d8, 1, 1, 30), /* XM2VTTGEN_SHORT_PWRGND */
222         field(TEGRA_APB_MISC_BASE + 0x8d8, 0, 0, 31), /* XM2VTTGEN_SHORT */
223         field(TEGRA_APB_MISC_BASE + 0x8d8, 12, 14, 24), /* XM2VTTGEN_VAUXP_LEVEL */
224         field(TEGRA_APB_MISC_BASE + 0x8d8, 8, 10, 27), /* XM2VTTGEN_VCLAMP_LEVEL */
225 };
226
227 static const struct pmc_scratch_field emc_digital_dll[] __initdata = {
228         field(TEGRA_EMC_BASE + 0x2bc, 1, 1, 23), /* DLI_TRIMMER_EN */
229         field(TEGRA_EMC_BASE + 0x2bc, 0, 0, 22), /* DLL_EN */
230         field(TEGRA_EMC_BASE + 0x2bc, 5, 5, 27), /* DLL_LOWSPEED */
231         field(TEGRA_EMC_BASE + 0x2bc, 2, 2, 24), /* DLL_OVERRIDE_EN */
232         field(TEGRA_EMC_BASE + 0x2bc, 8, 11, 28), /* DLL_UDSET */
233         field(TEGRA_EMC_BASE + 0x2bc, 4, 4, 26), /* PERBYTE_TRIMMER_OVERRIDE */
234         field(TEGRA_EMC_BASE + 0x2bc, 3, 3, 25), /* USE_SINGLE_DLL */
235         field(TEGRA_MC_BASE + 0xc, 0, 21, 0), /* EMEM_SIZE_KB */
236 };
237
238 static const struct pmc_scratch_field emc_dqs_clktrim[] __initdata = {
239         field(TEGRA_EMC_BASE + 0x2d4, 0, 29, 0), /* DQS0_CLKTRIM - DQS3 + MCLK*/
240         field(TEGRA_APB_MISC_BASE + 0x8e4, 3, 3, 31), /* XM2CFGC_CTT_HIZ_EN */
241         field(TEGRA_APB_MISC_BASE + 0x8e4, 4, 4, 30), /* XM2CFGC_VREF_DQS_EN */
242 };
243
244 static const struct pmc_scratch_field emc_dq_clktrim[] __initdata = {
245         field(TEGRA_EMC_BASE + 0x2d8, 0, 29, 0),
246         field(TEGRA_APB_MISC_BASE + 0x8e4, 2, 2, 30), /* XM2CFGC_PREEMP_EN */
247         field(TEGRA_APB_MISC_BASE + 0x8e4, 0, 0, 31), /* XM2CFGC_RX_FT_REC_EN */
248 };
249
250 static const struct pmc_scratch_field emc_dll_xform_dqs[] __initdata = {
251         field(TEGRA_EMC_BASE + 0x2bc, 16, 25, 20), /* CFG_DLL_OVERRIDE_VAL */
252         field(TEGRA_EMC_BASE + 0x2c0, 0, 4, 0), /* DQS_MULT */
253         field(TEGRA_EMC_BASE + 0x2c0, 8, 22, 5), /* DQS_OFFS */
254         field(TEGRA_MC_BASE + 0x10c, 31, 31, 30), /* LL_DRAM_INTERLEAVE */
255 };
256
257 static const struct pmc_scratch_field emc_odt_rw[] __initdata = {
258         field(TEGRA_EMC_BASE + 0x2c4, 0, 4, 0), /* QUSE_MULT */
259         field(TEGRA_EMC_BASE + 0x2c4, 8, 22, 5), /* QUSE_OFF */
260         field(TEGRA_EMC_BASE + 0xb4, 31, 31, 29), /* DISABLE_ODT_DURING_READ */
261         field(TEGRA_EMC_BASE + 0xb4, 30, 30, 28), /* B4_READ */
262         field(TEGRA_EMC_BASE + 0xb4, 0, 2, 25), /* RD_DELAY */
263         field(TEGRA_EMC_BASE + 0xb0, 31, 31, 24), /* ENABLE_ODT_DURING_WRITE */
264         field(TEGRA_EMC_BASE + 0xb0, 30, 30, 23), /* B4_WRITE */
265         field(TEGRA_EMC_BASE + 0xb0, 0, 2, 20), /* WR_DELAY */
266 };
267
268 static const struct pmc_scratch_field arbitration_xbar[] __initdata = {
269         field(TEGRA_AHB_GIZMO_BASE + 0xdc, 0, 31, 0),
270 };
271
272 static const struct pmc_scratch_field emc_zcal[] __initdata = {
273         field(TEGRA_EMC_BASE + 0x2e0, 0, 23, 0), /* ZCAL_REF_INTERVAL */
274         field(TEGRA_EMC_BASE + 0x2e4, 0, 7, 24), /* ZCAL_WAIT_CNT */
275 };
276
277 static const struct pmc_scratch_field emc_ctt_term[] __initdata = {
278         field(TEGRA_EMC_BASE + 0x2dc, 15, 19, 26), /* TERM_DRVDN */
279         field(TEGRA_EMC_BASE + 0x2dc, 8, 12, 21), /* TERM_OFFSET */
280         field(TEGRA_EMC_BASE + 0x2dc, 31, 31, 31), /* TERM_OVERRIDE */
281         field(TEGRA_EMC_BASE + 0x2dc, 0, 2, 18), /* TERM_SLOPE */
282         field(TEGRA_EMC_BASE + 0x2e8, 16, 23, 8), /* ZQ_MRW_MA */
283         field(TEGRA_EMC_BASE + 0x2e8, 0, 7, 0), /* ZQ_MRW_OP */
284 };
285
286 static const struct pmc_scratch_field xm2_cfgd[] __initdata = {
287         field(TEGRA_APB_MISC_BASE + 0x8e8, 16, 18, 9), /* CFGD0_DLYIN_TRM */
288         field(TEGRA_APB_MISC_BASE + 0x8e8, 20, 22, 6), /* CFGD1_DLYIN_TRM */
289         field(TEGRA_APB_MISC_BASE + 0x8e8, 24, 26, 3), /* CFGD2_DLYIN_TRM */
290         field(TEGRA_APB_MISC_BASE + 0x8e8, 28, 30, 0), /* CFGD3_DLYIN_TRM */
291         field(TEGRA_APB_MISC_BASE + 0x8e8, 3, 3, 12), /* XM2CFGD_CTT_HIZ_EN */
292         field(TEGRA_APB_MISC_BASE + 0x8e8, 2, 2, 13), /* XM2CFGD_PREEMP_EN */
293         field(TEGRA_APB_MISC_BASE + 0x8e8, 0, 0, 14), /* CM2CFGD_RX_FT_REC_EN */
294 };
295
296 struct pmc_scratch_reg {
297         const struct pmc_scratch_field *fields;
298         void __iomem *scratch_addr;
299         int num_fields;
300 };
301
302 #define scratch(offs, field_list)                                       \
303         {                                                               \
304                 .scratch_addr = IO_ADDRESS(TEGRA_PMC_BASE) + offs,      \
305                 .fields = field_list,                                   \
306                 .num_fields = ARRAY_SIZE(field_list),                   \
307         }
308
309 static const struct pmc_scratch_reg scratch[] __initdata = {
310         scratch(PMC_SCRATCH3, pllx),
311         scratch(PMC_SCRATCH5, emc_0),
312         scratch(PMC_SCRATCH6, emc_1),
313         scratch(PMC_SCRATCH7, emc_2),
314         scratch(PMC_SCRATCH8, emc_3),
315         scratch(PMC_SCRATCH9, emc_4),
316         scratch(PMC_SCRATCH10, emc_5),
317         scratch(PMC_SCRATCH11, emc_6),
318         scratch(PMC_SCRATCH12, emc_dqsib_dly),
319         scratch(PMC_SCRATCH13, emc_quse_dly),
320         scratch(PMC_SCRATCH14, emc_clktrim),
321         scratch(PMC_SCRATCH15, emc_autocal_fbio),
322         scratch(PMC_SCRATCH16, emc_autocal_interval),
323         scratch(PMC_SCRATCH17, emc_cfgs),
324         scratch(PMC_SCRATCH18, emc_adr_cfg1),
325         scratch(PMC_SCRATCH19, emc_digital_dll),
326         scratch(PMC_SCRATCH20, emc_dqs_clktrim),
327         scratch(PMC_SCRATCH21, emc_dq_clktrim),
328         scratch(PMC_SCRATCH22, emc_dll_xform_dqs),
329         scratch(PMC_SCRATCH23, emc_odt_rw),
330         scratch(PMC_SCRATCH25, arbitration_xbar),
331         scratch(PMC_SCRATCH35, emc_zcal),
332         scratch(PMC_SCRATCH36, emc_ctt_term),
333         scratch(PMC_SCRATCH40, xm2_cfgd),
334 };
335
336 void __init tegra2_lp0_suspend_init(void)
337 {
338         int i;
339         int j;
340         unsigned int v;
341         unsigned int r;
342
343         for (i = 0; i < ARRAY_SIZE(scratch); i++) {
344                 r = 0;
345
346                 for (j = 0; j < scratch[i].num_fields; j++) {
347                         v = readl(IO_ADDRESS(scratch[i].fields[j].addr));
348                         v >>= scratch[i].fields[j].shift_src;
349                         v &= scratch[i].fields[j].mask;
350                         v <<= scratch[i].fields[j].shift_dst;
351                         r |= v;
352                 }
353
354                 __raw_writel(r, scratch[i].scratch_addr);
355         }
356         wmb();
357 }