OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [arm/] [mach-omap1/] [pm.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * linux/arch/arm/mach-omap1/pm.c
3
 *
4
 * OMAP Power Management Routines
5
 *
6
 * Original code for the SA11x0:
7
 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8
 *
9
 * Modified for the PXA250 by Nicolas Pitre:
10
 * Copyright (c) 2002 Monta Vista Software, Inc.
11
 *
12
 * Modified for the OMAP1510 by David Singleton:
13
 * Copyright (c) 2002 Monta Vista Software, Inc.
14
 *
15
 * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16
 *
17
 * This program is free software; you can redistribute it and/or modify it
18
 * under the terms of the GNU General Public License as published by the
19
 * Free Software Foundation; either version 2 of the License, or (at your
20
 * option) any later version.
21
 *
22
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 *
33
 * You should have received a copy of the GNU General Public License along
34
 * with this program; if not, write to the Free Software Foundation, Inc.,
35
 * 675 Mass Ave, Cambridge, MA 02139, USA.
36
 */
37
 
38
#include <linux/suspend.h>
39
#include <linux/sched.h>
40
#include <linux/proc_fs.h>
41
#include <linux/interrupt.h>
42
#include <linux/sysfs.h>
43
#include <linux/module.h>
44
 
45
#include <asm/io.h>
46
#include <asm/irq.h>
47
#include <asm/atomic.h>
48
#include <asm/mach/time.h>
49
#include <asm/mach/irq.h>
50
#include <asm/mach-types.h>
51
 
52
#include <asm/arch/cpu.h>
53
#include <asm/arch/irqs.h>
54
#include <asm/arch/clock.h>
55
#include <asm/arch/sram.h>
56
#include <asm/arch/tc.h>
57
#include <asm/arch/pm.h>
58
#include <asm/arch/mux.h>
59
#include <asm/arch/dma.h>
60
#include <asm/arch/dsp_common.h>
61
#include <asm/arch/dmtimer.h>
62
 
63
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
64
static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
65
static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
66
static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
67
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
68
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
69
 
70
static unsigned short enable_dyn_sleep = 1;
71
 
72
static ssize_t omap_pm_sleep_while_idle_show(struct kset *kset, char *buf)
73
{
74
        return sprintf(buf, "%hu\n", enable_dyn_sleep);
75
}
76
 
77
static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset,
78
                                              const char * buf,
79
                                              size_t n)
80
{
81
        unsigned short value;
82
        if (sscanf(buf, "%hu", &value) != 1 ||
83
            (value != 0 && value != 1)) {
84
                printk(KERN_ERR "idle_sleep_store: Invalid value\n");
85
                return -EINVAL;
86
        }
87
        enable_dyn_sleep = value;
88
        return n;
89
}
90
 
91
static struct subsys_attribute sleep_while_idle_attr = {
92
        .attr   = {
93
                .name = __stringify(sleep_while_idle),
94
                .mode = 0644,
95
        },
96
        .show   = omap_pm_sleep_while_idle_show,
97
        .store  = omap_pm_sleep_while_idle_store,
98
};
99
 
100
extern struct kset power_subsys;
101
static void (*omap_sram_idle)(void) = NULL;
102
static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
103
 
104
/*
105
 * Let's power down on idle, but only if we are really
106
 * idle, because once we start down the path of
107
 * going idle we continue to do idle even if we get
108
 * a clock tick interrupt . .
109
 */
110
void omap_pm_idle(void)
111
{
112
        extern __u32 arm_idlect1_mask;
113
        __u32 use_idlect1 = arm_idlect1_mask;
114
#ifndef CONFIG_OMAP_MPU_TIMER
115
        int do_sleep;
116
#endif
117
 
118
        local_irq_disable();
119
        local_fiq_disable();
120
        if (need_resched()) {
121
                local_fiq_enable();
122
                local_irq_enable();
123
                return;
124
        }
125
 
126
        /*
127
         * Since an interrupt may set up a timer, we don't want to
128
         * reprogram the hardware timer with interrupts enabled.
129
         * Re-enable interrupts only after returning from idle.
130
         */
131
        timer_dyn_reprogram();
132
 
133
#ifdef CONFIG_OMAP_MPU_TIMER
134
#warning Enable 32kHz OS timer in order to allow sleep states in idle
135
        use_idlect1 = use_idlect1 & ~(1 << 9);
136
#else
137
 
138
        do_sleep = 0;
139
        while (enable_dyn_sleep) {
140
 
141
#ifdef CONFIG_CBUS_TAHVO_USB
142
                extern int vbus_active;
143
                /* Clock requirements? */
144
                if (vbus_active)
145
                        break;
146
#endif
147
                do_sleep = 1;
148
                break;
149
        }
150
 
151
#ifdef CONFIG_OMAP_DM_TIMER
152
        use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
153
#endif
154
 
155
        if (omap_dma_running())
156
                use_idlect1 &= ~(1 << 6);
157
 
158
        /* We should be able to remove the do_sleep variable and multiple
159
         * tests above as soon as drivers, timer and DMA code have been fixed.
160
         * Even the sleep block count should become obsolete. */
161
        if ((use_idlect1 != ~0) || !do_sleep) {
162
 
163
                __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
164
                if (cpu_is_omap15xx())
165
                        use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
166
                else
167
                        use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
168
                omap_writel(use_idlect1, ARM_IDLECT1);
169
                __asm__ volatile ("mcr  p15, 0, r0, c7, c0, 4");
170
                omap_writel(saved_idlect1, ARM_IDLECT1);
171
 
172
                local_fiq_enable();
173
                local_irq_enable();
174
                return;
175
        }
176
        omap_sram_suspend(omap_readl(ARM_IDLECT1),
177
                          omap_readl(ARM_IDLECT2));
178
#endif
179
 
180
        local_fiq_enable();
181
        local_irq_enable();
182
}
183
 
184
/*
185
 * Configuration of the wakeup event is board specific. For the
186
 * moment we put it into this helper function. Later it may move
187
 * to board specific files.
188
 */
189
static void omap_pm_wakeup_setup(void)
190
{
191
        u32 level1_wake = 0;
192
        u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
193
 
194
        /*
195
         * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
196
         * and the L2 wakeup interrupts: keypad and UART2. Note that the
197
         * drivers must still separately call omap_set_gpio_wakeup() to
198
         * wake up to a GPIO interrupt.
199
         */
200
        if (cpu_is_omap730())
201
                level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
202
                        OMAP_IRQ_BIT(INT_730_IH2_IRQ);
203
        else if (cpu_is_omap15xx())
204
                level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
205
                        OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
206
        else if (cpu_is_omap16xx())
207
                level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
208
                        OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
209
 
210
        omap_writel(~level1_wake, OMAP_IH1_MIR);
211
 
212
        if (cpu_is_omap730()) {
213
                omap_writel(~level2_wake, OMAP_IH2_0_MIR);
214
                omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
215
                                OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
216
                                OMAP_IH2_1_MIR);
217
        } else if (cpu_is_omap15xx()) {
218
                level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
219
                omap_writel(~level2_wake,  OMAP_IH2_MIR);
220
        } else if (cpu_is_omap16xx()) {
221
                level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
222
                omap_writel(~level2_wake, OMAP_IH2_0_MIR);
223
 
224
                /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
225
                omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
226
                            OMAP_IH2_1_MIR);
227
                omap_writel(~0x0, OMAP_IH2_2_MIR);
228
                omap_writel(~0x0, OMAP_IH2_3_MIR);
229
        }
230
 
231
        /*  New IRQ agreement, recalculate in cascade order */
232
        omap_writel(1, OMAP_IH2_CONTROL);
233
        omap_writel(1, OMAP_IH1_CONTROL);
234
}
235
 
236
#define EN_DSPCK        13      /* ARM_CKCTL */
237
#define EN_APICK        6       /* ARM_IDLECT2 */
238
#define DSP_EN          1       /* ARM_RSTCT1 */
239
 
240
void omap_pm_suspend(void)
241
{
242
        unsigned long arg0 = 0, arg1 = 0;
243
 
244
        printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
245
 
246
        omap_serial_wake_trigger(1);
247
 
248
        if (!cpu_is_omap15xx())
249
                omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
250
 
251
        /*
252
         * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
253
         */
254
 
255
        local_irq_disable();
256
        local_fiq_disable();
257
 
258
        /*
259
         * Step 2: save registers
260
         *
261
         * The omap is a strange/beautiful device. The caches, memory
262
         * and register state are preserved across power saves.
263
         * We have to save and restore very little register state to
264
         * idle the omap.
265
         *
266
         * Save interrupt, MPUI, ARM and UPLD control registers.
267
         */
268
 
269
        if (cpu_is_omap730()) {
270
                MPUI730_SAVE(OMAP_IH1_MIR);
271
                MPUI730_SAVE(OMAP_IH2_0_MIR);
272
                MPUI730_SAVE(OMAP_IH2_1_MIR);
273
                MPUI730_SAVE(MPUI_CTRL);
274
                MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
275
                MPUI730_SAVE(MPUI_DSP_API_CONFIG);
276
                MPUI730_SAVE(EMIFS_CONFIG);
277
                MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
278
 
279
        } else if (cpu_is_omap15xx()) {
280
                MPUI1510_SAVE(OMAP_IH1_MIR);
281
                MPUI1510_SAVE(OMAP_IH2_MIR);
282
                MPUI1510_SAVE(MPUI_CTRL);
283
                MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
284
                MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
285
                MPUI1510_SAVE(EMIFS_CONFIG);
286
                MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
287
        } else if (cpu_is_omap16xx()) {
288
                MPUI1610_SAVE(OMAP_IH1_MIR);
289
                MPUI1610_SAVE(OMAP_IH2_0_MIR);
290
                MPUI1610_SAVE(OMAP_IH2_1_MIR);
291
                MPUI1610_SAVE(OMAP_IH2_2_MIR);
292
                MPUI1610_SAVE(OMAP_IH2_3_MIR);
293
                MPUI1610_SAVE(MPUI_CTRL);
294
                MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
295
                MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
296
                MPUI1610_SAVE(EMIFS_CONFIG);
297
                MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
298
        }
299
 
300
        ARM_SAVE(ARM_CKCTL);
301
        ARM_SAVE(ARM_IDLECT1);
302
        ARM_SAVE(ARM_IDLECT2);
303
        if (!(cpu_is_omap15xx()))
304
                ARM_SAVE(ARM_IDLECT3);
305
        ARM_SAVE(ARM_EWUPCT);
306
        ARM_SAVE(ARM_RSTCT1);
307
        ARM_SAVE(ARM_RSTCT2);
308
        ARM_SAVE(ARM_SYSST);
309
        ULPD_SAVE(ULPD_CLOCK_CTRL);
310
        ULPD_SAVE(ULPD_STATUS_REQ);
311
 
312
        /* (Step 3 removed - we now allow deep sleep by default) */
313
 
314
        /*
315
         * Step 4: OMAP DSP Shutdown
316
         */
317
 
318
        /* stop DSP */
319
        omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
320
 
321
                /* shut down dsp_ck */
322
        if (!cpu_is_omap730())
323
                omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
324
 
325
        /* temporarily enabling api_ck to access DSP registers */
326
        omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
327
 
328
        /* save DSP registers */
329
        DSP_SAVE(DSP_IDLECT2);
330
 
331
        /* Stop all DSP domain clocks */
332
        __raw_writew(0, DSP_IDLECT2);
333
 
334
        /*
335
         * Step 5: Wakeup Event Setup
336
         */
337
 
338
        omap_pm_wakeup_setup();
339
 
340
        /*
341
         * Step 6: ARM and Traffic controller shutdown
342
         */
343
 
344
        /* disable ARM watchdog */
345
        omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
346
        omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
347
 
348
        /*
349
         * Step 6b: ARM and Traffic controller shutdown
350
         *
351
         * Step 6 continues here. Prepare jump to power management
352
         * assembly code in internal SRAM.
353
         *
354
         * Since the omap_cpu_suspend routine has been copied to
355
         * SRAM, we'll do an indirect procedure call to it and pass the
356
         * contents of arm_idlect1 and arm_idlect2 so it can restore
357
         * them when it wakes up and it will return.
358
         */
359
 
360
        arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
361
        arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
362
 
363
        /*
364
         * Step 6c: ARM and Traffic controller shutdown
365
         *
366
         * Jump to assembly code. The processor will stay there
367
         * until wake up.
368
         */
369
        omap_sram_suspend(arg0, arg1);
370
 
371
        /*
372
         * If we are here, processor is woken up!
373
         */
374
 
375
        /*
376
         * Restore DSP clocks
377
         */
378
 
379
        /* again temporarily enabling api_ck to access DSP registers */
380
        omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
381
 
382
        /* Restore DSP domain clocks */
383
        DSP_RESTORE(DSP_IDLECT2);
384
 
385
        /*
386
         * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
387
         */
388
 
389
        if (!(cpu_is_omap15xx()))
390
                ARM_RESTORE(ARM_IDLECT3);
391
        ARM_RESTORE(ARM_CKCTL);
392
        ARM_RESTORE(ARM_EWUPCT);
393
        ARM_RESTORE(ARM_RSTCT1);
394
        ARM_RESTORE(ARM_RSTCT2);
395
        ARM_RESTORE(ARM_SYSST);
396
        ULPD_RESTORE(ULPD_CLOCK_CTRL);
397
        ULPD_RESTORE(ULPD_STATUS_REQ);
398
 
399
        if (cpu_is_omap730()) {
400
                MPUI730_RESTORE(EMIFS_CONFIG);
401
                MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
402
                MPUI730_RESTORE(OMAP_IH1_MIR);
403
                MPUI730_RESTORE(OMAP_IH2_0_MIR);
404
                MPUI730_RESTORE(OMAP_IH2_1_MIR);
405
        } else if (cpu_is_omap15xx()) {
406
                MPUI1510_RESTORE(MPUI_CTRL);
407
                MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
408
                MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
409
                MPUI1510_RESTORE(EMIFS_CONFIG);
410
                MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
411
                MPUI1510_RESTORE(OMAP_IH1_MIR);
412
                MPUI1510_RESTORE(OMAP_IH2_MIR);
413
        } else if (cpu_is_omap16xx()) {
414
                MPUI1610_RESTORE(MPUI_CTRL);
415
                MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
416
                MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
417
                MPUI1610_RESTORE(EMIFS_CONFIG);
418
                MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
419
 
420
                MPUI1610_RESTORE(OMAP_IH1_MIR);
421
                MPUI1610_RESTORE(OMAP_IH2_0_MIR);
422
                MPUI1610_RESTORE(OMAP_IH2_1_MIR);
423
                MPUI1610_RESTORE(OMAP_IH2_2_MIR);
424
                MPUI1610_RESTORE(OMAP_IH2_3_MIR);
425
        }
426
 
427
        if (!cpu_is_omap15xx())
428
                omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
429
 
430
        /*
431
         * Re-enable interrupts
432
         */
433
 
434
        local_irq_enable();
435
        local_fiq_enable();
436
 
437
        omap_serial_wake_trigger(0);
438
 
439
        printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
440
}
441
 
442
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
443
static int g_read_completed;
444
 
445
/*
446
 * Read system PM registers for debugging
447
 */
448
static int omap_pm_read_proc(
449
        char *page_buffer,
450
        char **my_first_byte,
451
        off_t virtual_start,
452
        int length,
453
        int *eof,
454
        void *data)
455
{
456
        int my_buffer_offset = 0;
457
        char * const my_base = page_buffer;
458
 
459
        ARM_SAVE(ARM_CKCTL);
460
        ARM_SAVE(ARM_IDLECT1);
461
        ARM_SAVE(ARM_IDLECT2);
462
        if (!(cpu_is_omap15xx()))
463
                ARM_SAVE(ARM_IDLECT3);
464
        ARM_SAVE(ARM_EWUPCT);
465
        ARM_SAVE(ARM_RSTCT1);
466
        ARM_SAVE(ARM_RSTCT2);
467
        ARM_SAVE(ARM_SYSST);
468
 
469
        ULPD_SAVE(ULPD_IT_STATUS);
470
        ULPD_SAVE(ULPD_CLOCK_CTRL);
471
        ULPD_SAVE(ULPD_SOFT_REQ);
472
        ULPD_SAVE(ULPD_STATUS_REQ);
473
        ULPD_SAVE(ULPD_DPLL_CTRL);
474
        ULPD_SAVE(ULPD_POWER_CTRL);
475
 
476
        if (cpu_is_omap730()) {
477
                MPUI730_SAVE(MPUI_CTRL);
478
                MPUI730_SAVE(MPUI_DSP_STATUS);
479
                MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
480
                MPUI730_SAVE(MPUI_DSP_API_CONFIG);
481
                MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
482
                MPUI730_SAVE(EMIFS_CONFIG);
483
        } else if (cpu_is_omap15xx()) {
484
                MPUI1510_SAVE(MPUI_CTRL);
485
                MPUI1510_SAVE(MPUI_DSP_STATUS);
486
                MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
487
                MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
488
                MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
489
                MPUI1510_SAVE(EMIFS_CONFIG);
490
        } else if (cpu_is_omap16xx()) {
491
                MPUI1610_SAVE(MPUI_CTRL);
492
                MPUI1610_SAVE(MPUI_DSP_STATUS);
493
                MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
494
                MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
495
                MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
496
                MPUI1610_SAVE(EMIFS_CONFIG);
497
        }
498
 
499
        if (virtual_start == 0) {
500
                g_read_completed = 0;
501
 
502
                my_buffer_offset += sprintf(my_base + my_buffer_offset,
503
                   "ARM_CKCTL_REG:            0x%-8x     \n"
504
                   "ARM_IDLECT1_REG:          0x%-8x     \n"
505
                   "ARM_IDLECT2_REG:          0x%-8x     \n"
506
                   "ARM_IDLECT3_REG:          0x%-8x     \n"
507
                   "ARM_EWUPCT_REG:           0x%-8x     \n"
508
                   "ARM_RSTCT1_REG:           0x%-8x     \n"
509
                   "ARM_RSTCT2_REG:           0x%-8x     \n"
510
                   "ARM_SYSST_REG:            0x%-8x     \n"
511
                   "ULPD_IT_STATUS_REG:       0x%-4x     \n"
512
                   "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
513
                   "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
514
                   "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
515
                   "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
516
                   "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
517
                   ARM_SHOW(ARM_CKCTL),
518
                   ARM_SHOW(ARM_IDLECT1),
519
                   ARM_SHOW(ARM_IDLECT2),
520
                   ARM_SHOW(ARM_IDLECT3),
521
                   ARM_SHOW(ARM_EWUPCT),
522
                   ARM_SHOW(ARM_RSTCT1),
523
                   ARM_SHOW(ARM_RSTCT2),
524
                   ARM_SHOW(ARM_SYSST),
525
                   ULPD_SHOW(ULPD_IT_STATUS),
526
                   ULPD_SHOW(ULPD_CLOCK_CTRL),
527
                   ULPD_SHOW(ULPD_SOFT_REQ),
528
                   ULPD_SHOW(ULPD_DPLL_CTRL),
529
                   ULPD_SHOW(ULPD_STATUS_REQ),
530
                   ULPD_SHOW(ULPD_POWER_CTRL));
531
 
532
                if (cpu_is_omap730()) {
533
                        my_buffer_offset += sprintf(my_base + my_buffer_offset,
534
                           "MPUI730_CTRL_REG         0x%-8x \n"
535
                           "MPUI730_DSP_STATUS_REG:      0x%-8x \n"
536
                           "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
537
                           "MPUI730_DSP_API_CONFIG_REG:  0x%-8x \n"
538
                           "MPUI730_SDRAM_CONFIG_REG:    0x%-8x \n"
539
                           "MPUI730_EMIFS_CONFIG_REG:    0x%-8x \n",
540
                           MPUI730_SHOW(MPUI_CTRL),
541
                           MPUI730_SHOW(MPUI_DSP_STATUS),
542
                           MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
543
                           MPUI730_SHOW(MPUI_DSP_API_CONFIG),
544
                           MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
545
                           MPUI730_SHOW(EMIFS_CONFIG));
546
                } else if (cpu_is_omap15xx()) {
547
                        my_buffer_offset += sprintf(my_base + my_buffer_offset,
548
                           "MPUI1510_CTRL_REG             0x%-8x \n"
549
                           "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
550
                           "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
551
                           "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
552
                           "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
553
                           "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
554
                           MPUI1510_SHOW(MPUI_CTRL),
555
                           MPUI1510_SHOW(MPUI_DSP_STATUS),
556
                           MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
557
                           MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
558
                           MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
559
                           MPUI1510_SHOW(EMIFS_CONFIG));
560
                } else if (cpu_is_omap16xx()) {
561
                        my_buffer_offset += sprintf(my_base + my_buffer_offset,
562
                           "MPUI1610_CTRL_REG             0x%-8x \n"
563
                           "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
564
                           "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
565
                           "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
566
                           "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
567
                           "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
568
                           MPUI1610_SHOW(MPUI_CTRL),
569
                           MPUI1610_SHOW(MPUI_DSP_STATUS),
570
                           MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
571
                           MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
572
                           MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
573
                           MPUI1610_SHOW(EMIFS_CONFIG));
574
                }
575
 
576
                g_read_completed++;
577
        } else if (g_read_completed >= 1) {
578
                 *eof = 1;
579
                 return 0;
580
        }
581
        g_read_completed++;
582
 
583
        *my_first_byte = page_buffer;
584
        return  my_buffer_offset;
585
}
586
 
587
static void omap_pm_init_proc(void)
588
{
589
        struct proc_dir_entry *entry;
590
 
591
        entry = create_proc_read_entry("driver/omap_pm",
592
                                       S_IWUSR | S_IRUGO, NULL,
593
                                       omap_pm_read_proc, NULL);
594
}
595
 
596
#endif /* DEBUG && CONFIG_PROC_FS */
597
 
598
static void (*saved_idle)(void) = NULL;
599
 
600
/*
601
 *      omap_pm_prepare - Do preliminary suspend work.
602
 *
603
 */
604
static int omap_pm_prepare(void)
605
{
606
        /* We cannot sleep in idle until we have resumed */
607
        saved_idle = pm_idle;
608
        pm_idle = NULL;
609
 
610
        return 0;
611
}
612
 
613
 
614
/*
615
 *      omap_pm_enter - Actually enter a sleep state.
616
 *      @state:         State we're entering.
617
 *
618
 */
619
 
620
static int omap_pm_enter(suspend_state_t state)
621
{
622
        switch (state)
623
        {
624
        case PM_SUSPEND_STANDBY:
625
        case PM_SUSPEND_MEM:
626
                omap_pm_suspend();
627
                break;
628
        default:
629
                return -EINVAL;
630
        }
631
 
632
        return 0;
633
}
634
 
635
 
636
/**
637
 *      omap_pm_finish - Finish up suspend sequence.
638
 *
639
 *      This is called after we wake back up (or if entering the sleep state
640
 *      failed).
641
 */
642
 
643
static void omap_pm_finish(void)
644
{
645
        pm_idle = saved_idle;
646
}
647
 
648
 
649
static irqreturn_t  omap_wakeup_interrupt(int irq, void *dev)
650
{
651
        return IRQ_HANDLED;
652
}
653
 
654
static struct irqaction omap_wakeup_irq = {
655
        .name           = "peripheral wakeup",
656
        .flags          = IRQF_DISABLED,
657
        .handler        = omap_wakeup_interrupt
658
};
659
 
660
 
661
 
662
static struct platform_suspend_ops omap_pm_ops ={
663
        .prepare        = omap_pm_prepare,
664
        .enter          = omap_pm_enter,
665
        .finish         = omap_pm_finish,
666
        .valid          = suspend_valid_only_mem,
667
};
668
 
669
static int __init omap_pm_init(void)
670
{
671
        int error;
672
 
673
        printk("Power Management for TI OMAP.\n");
674
 
675
        /*
676
         * We copy the assembler sleep/wakeup routines to SRAM.
677
         * These routines need to be in SRAM as that's the only
678
         * memory the MPU can see when it wakes up.
679
         */
680
        if (cpu_is_omap730()) {
681
                omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
682
                                                omap730_idle_loop_suspend_sz);
683
                omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
684
                                                   omap730_cpu_suspend_sz);
685
        } else if (cpu_is_omap15xx()) {
686
                omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
687
                                                omap1510_idle_loop_suspend_sz);
688
                omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
689
                                                   omap1510_cpu_suspend_sz);
690
        } else if (cpu_is_omap16xx()) {
691
                omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
692
                                                omap1610_idle_loop_suspend_sz);
693
                omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
694
                                                   omap1610_cpu_suspend_sz);
695
        }
696
 
697
        if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
698
                printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
699
                return -ENODEV;
700
        }
701
 
702
        pm_idle = omap_pm_idle;
703
 
704
        if (cpu_is_omap730())
705
                setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
706
        else if (cpu_is_omap16xx())
707
                setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
708
 
709
        /* Program new power ramp-up time
710
         * (0 for most boards since we don't lower voltage when in deep sleep)
711
         */
712
        omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
713
 
714
        /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
715
        omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
716
 
717
        /* Configure IDLECT3 */
718
        if (cpu_is_omap730())
719
                omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
720
        else if (cpu_is_omap16xx())
721
                omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
722
 
723
        suspend_set_ops(&omap_pm_ops);
724
 
725
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
726
        omap_pm_init_proc();
727
#endif
728
 
729
        error = subsys_create_file(&power_subsys, &sleep_while_idle_attr);
730
        if (error)
731
                printk(KERN_ERR "subsys_create_file failed: %d\n", error);
732
 
733
        if (cpu_is_omap16xx()) {
734
                /* configure LOW_PWR pin */
735
                omap_cfg_reg(T20_1610_LOW_PWR);
736
        }
737
 
738
        return 0;
739
}
740
__initcall(omap_pm_init);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.