aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-06-22 10:42:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-06-24 03:48:46 -0400
commit076f2cc449188b7d3d4866730afa3ac7be3e6640 (patch)
treecbedc1164f7c938982294c99a52a5fb59d16cb50 /arch/arm
parent2637ce30e145557bf89ebcf35b2d78e729e16e5a (diff)
ARM: pm: omap34xx: convert to generic suspend/resume support
Convert omap34xx to use the generic CPU suspend/resume support, rather than implementing its own version. Tested on 3430 LDP. Reviewed-by: Kevin Hilman <khilman@ti.com> Tested-by: Kevin Hilman <khilman@ti.com> Acked-by: Jean Pihet <j-pihet@ti.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/pm34xx.c47
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S143
2 files changed, 13 insertions, 177 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c155c9d1c82c..ae4017750bbe 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -40,8 +40,6 @@
40#include <plat/gpmc.h> 40#include <plat/gpmc.h>
41#include <plat/dma.h> 41#include <plat/dma.h>
42 42
43#include <asm/tlbflush.h>
44
45#include "cm2xxx_3xxx.h" 43#include "cm2xxx_3xxx.h"
46#include "cm-regbits-34xx.h" 44#include "cm-regbits-34xx.h"
47#include "prm-regbits-34xx.h" 45#include "prm-regbits-34xx.h"
@@ -64,11 +62,6 @@ static inline bool is_suspending(void)
64} 62}
65#endif 63#endif
66 64
67/* Scratchpad offsets */
68#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
69#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
70#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8
71
72/* pm34xx errata defined in pm.h */ 65/* pm34xx errata defined in pm.h */
73u16 pm34xx_errata; 66u16 pm34xx_errata;
74 67
@@ -312,28 +305,9 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
312 return IRQ_HANDLED; 305 return IRQ_HANDLED;
313} 306}
314 307
315/* Function to restore the table entry that was modified for enabling MMU */ 308static void omap34xx_do_sram_idle(unsigned long save_state)
316static void restore_table_entry(void)
317{ 309{
318 void __iomem *scratchpad_address; 310 _omap_sram_idle(omap3_arm_context, save_state);
319 u32 previous_value, control_reg_value;
320 u32 *address;
321
322 scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
323
324 /* Get address of entry that was modified */
325 address = (u32 *)__raw_readl(scratchpad_address +
326 OMAP343X_TABLE_ADDRESS_OFFSET);
327 /* Get the previous value which needs to be restored */
328 previous_value = __raw_readl(scratchpad_address +
329 OMAP343X_TABLE_VALUE_OFFSET);
330 address = __va(address);
331 *address = previous_value;
332 flush_tlb_all();
333 control_reg_value = __raw_readl(scratchpad_address
334 + OMAP343X_CONTROL_REG_VALUE_OFFSET);
335 /* This will enable caches and prediction */
336 set_cr(control_reg_value);
337} 311}
338 312
339void omap_sram_idle(void) 313void omap_sram_idle(void)
@@ -432,12 +406,15 @@ void omap_sram_idle(void)
432 sdrc_pwr = sdrc_read_reg(SDRC_POWER); 406 sdrc_pwr = sdrc_read_reg(SDRC_POWER);
433 407
434 /* 408 /*
435 * omap3_arm_context is the location where ARM registers 409 * omap3_arm_context is the location where some ARM context
436 * get saved. The restore path then reads from this 410 * get saved. The rest is placed on the stack, and restored
437 * location and restores them back. 411 * from there before resuming.
438 */ 412 */
439 _omap_sram_idle(omap3_arm_context, save_state); 413 if (save_state == 1 || save_state == 3)
440 cpu_init(); 414 cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, save_state,
415 omap34xx_do_sram_idle);
416 else
417 omap34xx_do_sram_idle(save_state);
441 418
442 /* Restore normal SDRC POWER settings */ 419 /* Restore normal SDRC POWER settings */
443 if (omap_rev() >= OMAP3430_REV_ES3_0 && 420 if (omap_rev() >= OMAP3430_REV_ES3_0 &&
@@ -445,10 +422,6 @@ void omap_sram_idle(void)
445 core_next_state == PWRDM_POWER_OFF) 422 core_next_state == PWRDM_POWER_OFF)
446 sdrc_write_reg(sdrc_pwr, SDRC_POWER); 423 sdrc_write_reg(sdrc_pwr, SDRC_POWER);
447 424
448 /* Restore table entry modified during MMU restoration */
449 if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
450 restore_table_entry();
451
452 /* CORE */ 425 /* CORE */
453 if (core_next_state < PWRDM_POWER_ON) { 426 if (core_next_state < PWRDM_POWER_ON) {
454 core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); 427 core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 12e9da2f0263..9a1349ea460a 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -211,37 +211,6 @@ save_context_wfi:
211 mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register 211 mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
212 stmia r8!, {r4-r5} @ Push parameters for restore call 212 stmia r8!, {r4-r5} @ Push parameters for restore call
213 213
214 /* Check what that target sleep state is from r1 */
215 cmp r1, #0x2 @ Only L2 lost, no need to save context
216 beq clean_caches
217
218l1_logic_lost:
219 mov r4, sp @ Store sp
220 mrs r5, spsr @ Store spsr
221 mov r6, lr @ Store lr
222 stmia r8!, {r4-r6}
223
224 mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register
225 mrc p15, 0, r5, c2, c0, 0 @ TTBR0
226 mrc p15, 0, r6, c2, c0, 1 @ TTBR1
227 mrc p15, 0, r7, c2, c0, 2 @ TTBCR
228 stmia r8!, {r4-r7}
229
230 mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register
231 mrc p15, 0, r5, c10, c2, 0 @ PRRR
232 mrc p15, 0, r6, c10, c2, 1 @ NMRR
233 stmia r8!,{r4-r6}
234
235 mrc p15, 0, r4, c13, c0, 1 @ Context ID
236 mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
237 mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
238 mrs r7, cpsr @ Store current cpsr
239 stmia r8!, {r4-r7}
240
241 mrc p15, 0, r4, c1, c0, 0 @ save control register
242 stmia r8!, {r4}
243
244clean_caches:
245 /* 214 /*
246 * jump out to kernel flush routine 215 * jump out to kernel flush routine
247 * - reuse that code is better 216 * - reuse that code is better
@@ -466,109 +435,11 @@ logic_l1_restore:
466 orr r1, r1, #2 @ re-enable L2 cache 435 orr r1, r1, #2 @ re-enable L2 cache
467 mcr p15, 0, r1, c1, c0, 1 436 mcr p15, 0, r1, c1, c0, 1
468skipl2reen: 437skipl2reen:
469 mov r1, #0
470 /*
471 * Invalidate all instruction caches to PoU
472 * and flush branch target cache
473 */
474 mcr p15, 0, r1, c7, c5, 0
475 438
476 ldr r4, scratchpad_base 439 /* Now branch to the common CPU resume function */
477 ldr r3, [r4,#0xBC] 440 b cpu_resume
478 adds r3, r3, #16
479
480 ldmia r3!, {r4-r6}
481 mov sp, r4 @ Restore sp
482 msr spsr_cxsf, r5 @ Restore spsr
483 mov lr, r6 @ Restore lr
484
485 ldmia r3!, {r4-r7}
486 mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register
487 mcr p15, 0, r5, c2, c0, 0 @ TTBR0
488 mcr p15, 0, r6, c2, c0, 1 @ TTBR1
489 mcr p15, 0, r7, c2, c0, 2 @ TTBCR
490
491 ldmia r3!,{r4-r6}
492 mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register
493 mcr p15, 0, r5, c10, c2, 0 @ PRRR
494 mcr p15, 0, r6, c10, c2, 1 @ NMRR
495
496
497 ldmia r3!,{r4-r7}
498 mcr p15, 0, r4, c13, c0, 1 @ Context ID
499 mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
500 mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
501 msr cpsr, r7 @ store cpsr
502
503 /* Enabling MMU here */
504 mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
505 /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
506 and r7, #0x7
507 cmp r7, #0x0
508 beq usettbr0
509ttbr_error:
510 /*
511 * More work needs to be done to support N[0:2] value other than 0
512 * So looping here so that the error can be detected
513 */
514 b ttbr_error
515usettbr0:
516 mrc p15, 0, r2, c2, c0, 0
517 ldr r5, ttbrbit_mask
518 and r2, r5
519 mov r4, pc
520 ldr r5, table_index_mask
521 and r4, r5 @ r4 = 31 to 20 bits of pc
522 /* Extract the value to be written to table entry */
523 ldr r1, table_entry
524 /* r1 has the value to be written to table entry*/
525 add r1, r1, r4
526 /* Getting the address of table entry to modify */
527 lsr r4, #18
528 /* r2 has the location which needs to be modified */
529 add r2, r4
530 /* Storing previous entry of location being modified */
531 ldr r5, scratchpad_base
532 ldr r4, [r2]
533 str r4, [r5, #0xC0]
534 /* Modify the table entry */
535 str r1, [r2]
536 /*
537 * Storing address of entry being modified
538 * - will be restored after enabling MMU
539 */
540 ldr r5, scratchpad_base
541 str r2, [r5, #0xC4]
542
543 mov r0, #0
544 mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
545 mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
546 mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
547 mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
548 /*
549 * Restore control register. This enables the MMU.
550 * The caches and prediction are not enabled here, they
551 * will be enabled after restoring the MMU table entry.
552 */
553 ldmia r3!, {r4}
554 /* Store previous value of control register in scratchpad */
555 str r4, [r5, #0xC8]
556 ldr r2, cache_pred_disable_mask
557 and r4, r2
558 mcr p15, 0, r4, c1, c0, 0
559 dsb
560 isb
561 ldr r0, =restoremmu_on
562 bx r0
563
564/*
565 * ==============================
566 * == Exit point from OFF mode ==
567 * ==============================
568 */
569restoremmu_on:
570 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
571 441
442 .ltorg
572 443
573/* 444/*
574 * Internal functions 445 * Internal functions
@@ -719,14 +590,6 @@ sram_base:
719 .word SRAM_BASE_P + 0x8000 590 .word SRAM_BASE_P + 0x8000
720sdrc_power: 591sdrc_power:
721 .word SDRC_POWER_V 592 .word SDRC_POWER_V
722ttbrbit_mask:
723 .word 0xFFFFC000
724table_index_mask:
725 .word 0xFFF00000
726table_entry:
727 .word 0x00000C02
728cache_pred_disable_mask:
729 .word 0xFFFFE7FB
730control_stat: 593control_stat:
731 .word CONTROL_STAT 594 .word CONTROL_STAT
732control_mem_rta: 595control_mem_rta: