diff options
| -rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 47 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/sleep34xx.S | 143 |
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 */ |
| 73 | u16 pm34xx_errata; | 66 | u16 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 */ | 308 | static void omap34xx_do_sram_idle(unsigned long save_state) |
| 316 | static 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 | ||
| 339 | void omap_sram_idle(void) | 313 | void 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 | |||
| 218 | l1_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 | |||
| 244 | clean_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 |
| 468 | skipl2reen: | 437 | skipl2reen: |
| 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 | ||
| 509 | ttbr_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 | ||
| 515 | usettbr0: | ||
| 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 | */ | ||
| 569 | restoremmu_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 |
| 720 | sdrc_power: | 591 | sdrc_power: |
| 721 | .word SDRC_POWER_V | 592 | .word SDRC_POWER_V |
| 722 | ttbrbit_mask: | ||
| 723 | .word 0xFFFFC000 | ||
| 724 | table_index_mask: | ||
| 725 | .word 0xFFF00000 | ||
| 726 | table_entry: | ||
| 727 | .word 0x00000C02 | ||
| 728 | cache_pred_disable_mask: | ||
| 729 | .word 0xFFFFE7FB | ||
| 730 | control_stat: | 593 | control_stat: |
| 731 | .word CONTROL_STAT | 594 | .word CONTROL_STAT |
| 732 | control_mem_rta: | 595 | control_mem_rta: |
