diff options
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
| -rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 126 |
1 files changed, 28 insertions, 98 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 7b03426c72a3..75c0cd13ad8e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
| @@ -32,13 +32,11 @@ | |||
| 32 | #include <plat/sram.h> | 32 | #include <plat/sram.h> |
| 33 | #include <plat/clockdomain.h> | 33 | #include <plat/clockdomain.h> |
| 34 | #include <plat/powerdomain.h> | 34 | #include <plat/powerdomain.h> |
| 35 | #include <plat/control.h> | ||
| 36 | #include <plat/serial.h> | 35 | #include <plat/serial.h> |
| 37 | #include <plat/sdrc.h> | 36 | #include <plat/sdrc.h> |
| 38 | #include <plat/prcm.h> | 37 | #include <plat/prcm.h> |
| 39 | #include <plat/gpmc.h> | 38 | #include <plat/gpmc.h> |
| 40 | #include <plat/dma.h> | 39 | #include <plat/dma.h> |
| 41 | #include <plat/dmtimer.h> | ||
| 42 | 40 | ||
| 43 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
| 44 | 42 | ||
| @@ -49,16 +47,12 @@ | |||
| 49 | #include "prm.h" | 47 | #include "prm.h" |
| 50 | #include "pm.h" | 48 | #include "pm.h" |
| 51 | #include "sdrc.h" | 49 | #include "sdrc.h" |
| 50 | #include "control.h" | ||
| 52 | 51 | ||
| 53 | /* Scratchpad offsets */ | 52 | /* Scratchpad offsets */ |
| 54 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0x31 | 53 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 |
| 55 | #define OMAP343X_TABLE_VALUE_OFFSET 0x30 | 54 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 |
| 56 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32 | 55 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 |
| 57 | |||
| 58 | u32 enable_off_mode; | ||
| 59 | u32 sleep_while_idle; | ||
| 60 | u32 wakeup_timer_seconds; | ||
| 61 | u32 wakeup_timer_milliseconds; | ||
| 62 | 56 | ||
| 63 | struct power_state { | 57 | struct power_state { |
| 64 | struct powerdomain *pwrdm; | 58 | struct powerdomain *pwrdm; |
| @@ -316,7 +310,7 @@ static void restore_control_register(u32 val) | |||
| 316 | /* Function to restore the table entry that was modified for enabling MMU */ | 310 | /* Function to restore the table entry that was modified for enabling MMU */ |
| 317 | static void restore_table_entry(void) | 311 | static void restore_table_entry(void) |
| 318 | { | 312 | { |
| 319 | u32 *scratchpad_address; | 313 | void __iomem *scratchpad_address; |
| 320 | u32 previous_value, control_reg_value; | 314 | u32 previous_value, control_reg_value; |
| 321 | u32 *address; | 315 | u32 *address; |
| 322 | 316 | ||
| @@ -351,7 +345,6 @@ void omap_sram_idle(void) | |||
| 351 | int core_next_state = PWRDM_POWER_ON; | 345 | int core_next_state = PWRDM_POWER_ON; |
| 352 | int core_prev_state, per_prev_state; | 346 | int core_prev_state, per_prev_state; |
| 353 | u32 sdrc_pwr = 0; | 347 | u32 sdrc_pwr = 0; |
| 354 | int per_state_modified = 0; | ||
| 355 | 348 | ||
| 356 | if (!_omap_sram_idle) | 349 | if (!_omap_sram_idle) |
| 357 | return; | 350 | return; |
| @@ -385,9 +378,9 @@ void omap_sram_idle(void) | |||
| 385 | /* Enable IO-PAD and IO-CHAIN wakeups */ | 378 | /* Enable IO-PAD and IO-CHAIN wakeups */ |
| 386 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); | 379 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); |
| 387 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); | 380 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); |
| 388 | if (omap3_has_io_wakeup() && \ | 381 | if (omap3_has_io_wakeup() && |
| 389 | (per_next_state < PWRDM_POWER_ON || | 382 | (per_next_state < PWRDM_POWER_ON || |
| 390 | core_next_state < PWRDM_POWER_ON)) { | 383 | core_next_state < PWRDM_POWER_ON)) { |
| 391 | prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); | 384 | prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); |
| 392 | omap3_enable_io_chain(); | 385 | omap3_enable_io_chain(); |
| 393 | } | 386 | } |
| @@ -395,20 +388,12 @@ void omap_sram_idle(void) | |||
| 395 | /* PER */ | 388 | /* PER */ |
| 396 | if (per_next_state < PWRDM_POWER_ON) { | 389 | if (per_next_state < PWRDM_POWER_ON) { |
| 397 | omap_uart_prepare_idle(2); | 390 | omap_uart_prepare_idle(2); |
| 391 | omap_uart_prepare_idle(3); | ||
| 398 | omap2_gpio_prepare_for_idle(per_next_state); | 392 | omap2_gpio_prepare_for_idle(per_next_state); |
| 399 | if (per_next_state == PWRDM_POWER_OFF) { | 393 | if (per_next_state == PWRDM_POWER_OFF) |
| 400 | if (core_next_state == PWRDM_POWER_ON) { | ||
| 401 | per_next_state = PWRDM_POWER_RET; | ||
| 402 | pwrdm_set_next_pwrst(per_pwrdm, per_next_state); | ||
| 403 | per_state_modified = 1; | ||
| 404 | } else | ||
| 405 | omap3_per_save_context(); | 394 | omap3_per_save_context(); |
| 406 | } | ||
| 407 | } | 395 | } |
| 408 | 396 | ||
| 409 | if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON) | ||
| 410 | omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]); | ||
| 411 | |||
| 412 | /* CORE */ | 397 | /* CORE */ |
| 413 | if (core_next_state < PWRDM_POWER_ON) { | 398 | if (core_next_state < PWRDM_POWER_ON) { |
| 414 | omap_uart_prepare_idle(0); | 399 | omap_uart_prepare_idle(0); |
| @@ -475,8 +460,7 @@ void omap_sram_idle(void) | |||
| 475 | if (per_prev_state == PWRDM_POWER_OFF) | 460 | if (per_prev_state == PWRDM_POWER_OFF) |
| 476 | omap3_per_restore_context(); | 461 | omap3_per_restore_context(); |
| 477 | omap_uart_resume_idle(2); | 462 | omap_uart_resume_idle(2); |
| 478 | if (per_state_modified) | 463 | omap_uart_resume_idle(3); |
| 479 | pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); | ||
| 480 | } | 464 | } |
| 481 | 465 | ||
| 482 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 466 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
| @@ -501,51 +485,6 @@ int omap3_can_sleep(void) | |||
| 501 | return 1; | 485 | return 1; |
| 502 | } | 486 | } |
| 503 | 487 | ||
| 504 | /* This sets pwrdm state (other than mpu & core. Currently only ON & | ||
| 505 | * RET are supported. Function is assuming that clkdm doesn't have | ||
| 506 | * hw_sup mode enabled. */ | ||
| 507 | int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | ||
| 508 | { | ||
| 509 | u32 cur_state; | ||
| 510 | int sleep_switch = 0; | ||
| 511 | int ret = 0; | ||
| 512 | |||
| 513 | if (pwrdm == NULL || IS_ERR(pwrdm)) | ||
| 514 | return -EINVAL; | ||
| 515 | |||
| 516 | while (!(pwrdm->pwrsts & (1 << state))) { | ||
| 517 | if (state == PWRDM_POWER_OFF) | ||
| 518 | return ret; | ||
| 519 | state--; | ||
| 520 | } | ||
| 521 | |||
| 522 | cur_state = pwrdm_read_next_pwrst(pwrdm); | ||
| 523 | if (cur_state == state) | ||
| 524 | return ret; | ||
| 525 | |||
| 526 | if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { | ||
| 527 | omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); | ||
| 528 | sleep_switch = 1; | ||
| 529 | pwrdm_wait_transition(pwrdm); | ||
| 530 | } | ||
| 531 | |||
| 532 | ret = pwrdm_set_next_pwrst(pwrdm, state); | ||
| 533 | if (ret) { | ||
| 534 | printk(KERN_ERR "Unable to set state of powerdomain: %s\n", | ||
| 535 | pwrdm->name); | ||
| 536 | goto err; | ||
| 537 | } | ||
| 538 | |||
| 539 | if (sleep_switch) { | ||
| 540 | omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); | ||
| 541 | pwrdm_wait_transition(pwrdm); | ||
| 542 | pwrdm_state_switch(pwrdm); | ||
| 543 | } | ||
| 544 | |||
| 545 | err: | ||
| 546 | return ret; | ||
| 547 | } | ||
| 548 | |||
| 549 | static void omap3_pm_idle(void) | 488 | static void omap3_pm_idle(void) |
| 550 | { | 489 | { |
| 551 | local_irq_disable(); | 490 | local_irq_disable(); |
| @@ -567,23 +506,6 @@ out: | |||
| 567 | #ifdef CONFIG_SUSPEND | 506 | #ifdef CONFIG_SUSPEND |
| 568 | static suspend_state_t suspend_state; | 507 | static suspend_state_t suspend_state; |
| 569 | 508 | ||
| 570 | static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
| 571 | { | ||
| 572 | u32 tick_rate, cycles; | ||
| 573 | |||
| 574 | if (!seconds && !milliseconds) | ||
| 575 | return; | ||
| 576 | |||
| 577 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
| 578 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
| 579 | omap_dm_timer_stop(gptimer_wakeup); | ||
| 580 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
| 581 | |||
| 582 | pr_info("PM: Resume timer in %u.%03u secs" | ||
| 583 | " (%d ticks at %d ticks/sec.)\n", | ||
| 584 | seconds, milliseconds, cycles, tick_rate); | ||
| 585 | } | ||
| 586 | |||
| 587 | static int omap3_pm_prepare(void) | 509 | static int omap3_pm_prepare(void) |
| 588 | { | 510 | { |
| 589 | disable_hlt(); | 511 | disable_hlt(); |
| @@ -604,7 +526,7 @@ static int omap3_pm_suspend(void) | |||
| 604 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); | 526 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); |
| 605 | /* Set ones wanted by suspend */ | 527 | /* Set ones wanted by suspend */ |
| 606 | list_for_each_entry(pwrst, &pwrst_list, node) { | 528 | list_for_each_entry(pwrst, &pwrst_list, node) { |
| 607 | if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) | 529 | if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) |
| 608 | goto restore; | 530 | goto restore; |
| 609 | if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) | 531 | if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) |
| 610 | goto restore; | 532 | goto restore; |
| @@ -625,7 +547,7 @@ restore: | |||
| 625 | pwrst->pwrdm->name, pwrst->next_state); | 547 | pwrst->pwrdm->name, pwrst->next_state); |
| 626 | ret = -1; | 548 | ret = -1; |
| 627 | } | 549 | } |
| 628 | set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); | 550 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); |
| 629 | } | 551 | } |
| 630 | if (ret) | 552 | if (ret) |
| 631 | printk(KERN_ERR "Could not enter target state in pm_suspend\n"); | 553 | printk(KERN_ERR "Could not enter target state in pm_suspend\n"); |
| @@ -756,6 +678,14 @@ static void __init omap3_d2d_idle(void) | |||
| 756 | 678 | ||
| 757 | static void __init prcm_setup_regs(void) | 679 | static void __init prcm_setup_regs(void) |
| 758 | { | 680 | { |
| 681 | u32 omap3630_auto_uart4_mask = cpu_is_omap3630() ? | ||
| 682 | OMAP3630_AUTO_UART4_MASK : 0; | ||
| 683 | u32 omap3630_en_uart4_mask = cpu_is_omap3630() ? | ||
| 684 | OMAP3630_EN_UART4_MASK : 0; | ||
| 685 | u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ? | ||
| 686 | OMAP3630_GRPSEL_UART4_MASK : 0; | ||
| 687 | |||
| 688 | |||
| 759 | /* XXX Reset all wkdeps. This should be done when initializing | 689 | /* XXX Reset all wkdeps. This should be done when initializing |
| 760 | * powerdomains */ | 690 | * powerdomains */ |
| 761 | prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP); | 691 | prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP); |
| @@ -842,6 +772,7 @@ static void __init prcm_setup_regs(void) | |||
| 842 | CM_AUTOIDLE); | 772 | CM_AUTOIDLE); |
| 843 | 773 | ||
| 844 | cm_write_mod_reg( | 774 | cm_write_mod_reg( |
| 775 | omap3630_auto_uart4_mask | | ||
| 845 | OMAP3430_AUTO_GPIO6_MASK | | 776 | OMAP3430_AUTO_GPIO6_MASK | |
| 846 | OMAP3430_AUTO_GPIO5_MASK | | 777 | OMAP3430_AUTO_GPIO5_MASK | |
| 847 | OMAP3430_AUTO_GPIO4_MASK | | 778 | OMAP3430_AUTO_GPIO4_MASK | |
| @@ -918,14 +849,16 @@ static void __init prcm_setup_regs(void) | |||
| 918 | OMAP3430_DSS_MOD, PM_WKEN); | 849 | OMAP3430_DSS_MOD, PM_WKEN); |
| 919 | 850 | ||
| 920 | /* Enable wakeups in PER */ | 851 | /* Enable wakeups in PER */ |
| 921 | prm_write_mod_reg(OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | | 852 | prm_write_mod_reg(omap3630_en_uart4_mask | |
| 853 | OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK | | ||
| 922 | OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | | 854 | OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK | |
| 923 | OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK | | 855 | OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK | |
| 924 | OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | | 856 | OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK | |
| 925 | OMAP3430_EN_MCBSP4_MASK, | 857 | OMAP3430_EN_MCBSP4_MASK, |
| 926 | OMAP3430_PER_MOD, PM_WKEN); | 858 | OMAP3430_PER_MOD, PM_WKEN); |
| 927 | /* and allow them to wake up MPU */ | 859 | /* and allow them to wake up MPU */ |
| 928 | prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2_MASK | | 860 | prm_write_mod_reg(omap3630_grpsel_uart4_mask | |
| 861 | OMAP3430_GRPSEL_GPIO2_MASK | | ||
| 929 | OMAP3430_GRPSEL_GPIO3_MASK | | 862 | OMAP3430_GRPSEL_GPIO3_MASK | |
| 930 | OMAP3430_GRPSEL_GPIO4_MASK | | 863 | OMAP3430_GRPSEL_GPIO4_MASK | |
| 931 | OMAP3430_GRPSEL_GPIO5_MASK | | 864 | OMAP3430_GRPSEL_GPIO5_MASK | |
| @@ -974,7 +907,7 @@ void omap3_pm_off_mode_enable(int enable) | |||
| 974 | 907 | ||
| 975 | list_for_each_entry(pwrst, &pwrst_list, node) { | 908 | list_for_each_entry(pwrst, &pwrst_list, node) { |
| 976 | pwrst->next_state = state; | 909 | pwrst->next_state = state; |
| 977 | set_pwrdm_state(pwrst->pwrdm, state); | 910 | omap_set_pwrdm_state(pwrst->pwrdm, state); |
| 978 | } | 911 | } |
| 979 | } | 912 | } |
| 980 | 913 | ||
| @@ -1019,7 +952,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | |||
| 1019 | if (pwrdm_has_hdwr_sar(pwrdm)) | 952 | if (pwrdm_has_hdwr_sar(pwrdm)) |
| 1020 | pwrdm_enable_hdwr_sar(pwrdm); | 953 | pwrdm_enable_hdwr_sar(pwrdm); |
| 1021 | 954 | ||
| 1022 | return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); | 955 | return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); |
| 1023 | } | 956 | } |
| 1024 | 957 | ||
| 1025 | /* | 958 | /* |
| @@ -1029,9 +962,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | |||
| 1029 | */ | 962 | */ |
| 1030 | static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) | 963 | static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) |
| 1031 | { | 964 | { |
| 1032 | clkdm_clear_all_wkdeps(clkdm); | ||
| 1033 | clkdm_clear_all_sleepdeps(clkdm); | ||
| 1034 | |||
| 1035 | if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) | 965 | if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) |
| 1036 | omap2_clkdm_allow_idle(clkdm); | 966 | omap2_clkdm_allow_idle(clkdm); |
| 1037 | else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && | 967 | else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && |
