suspend.c (07731019c59c06e257aac351d774b2292c251dde) | suspend.c (ee55ae6194a5439bde3a3b8ee0abda63c610e740) |
---|---|
1/* 2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. 3 * http://www.samsung.com 4 * 5 * EXYNOS - Suspend support 6 * 7 * Based on arch/arm/mach-s3c2410/pm.c 8 * Copyright (c) 2006 Simtec Electronics --- 43 unchanged lines hidden (view full) --- 52struct exynos_wkup_irq { 53 unsigned int hwirq; 54 u32 mask; 55}; 56 57struct exynos_pm_data { 58 const struct exynos_wkup_irq *wkup_irq; 59 unsigned int wake_disable_mask; | 1/* 2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. 3 * http://www.samsung.com 4 * 5 * EXYNOS - Suspend support 6 * 7 * Based on arch/arm/mach-s3c2410/pm.c 8 * Copyright (c) 2006 Simtec Electronics --- 43 unchanged lines hidden (view full) --- 52struct exynos_wkup_irq { 53 unsigned int hwirq; 54 u32 mask; 55}; 56 57struct exynos_pm_data { 58 const struct exynos_wkup_irq *wkup_irq; 59 unsigned int wake_disable_mask; |
60 unsigned int *release_ret_regs; |
|
60 61 void (*pm_prepare)(void); 62 void (*pm_resume_prepare)(void); 63 void (*pm_resume)(void); 64 int (*pm_suspend)(void); 65 int (*cpu_suspend)(unsigned long); 66}; 67 --- 21 unchanged lines hidden (view full) --- 89}; 90 91static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { 92 { 43, BIT(1) }, /* RTC alarm */ 93 { 44, BIT(2) }, /* RTC tick */ 94 { /* sentinel */ }, 95}; 96 | 61 62 void (*pm_prepare)(void); 63 void (*pm_resume_prepare)(void); 64 void (*pm_resume)(void); 65 int (*pm_suspend)(void); 66 int (*cpu_suspend)(unsigned long); 67}; 68 --- 21 unchanged lines hidden (view full) --- 90}; 91 92static const struct exynos_wkup_irq exynos5250_wkup_irq[] = { 93 { 43, BIT(1) }, /* RTC alarm */ 94 { 44, BIT(2) }, /* RTC tick */ 95 { /* sentinel */ }, 96}; 97 |
98static unsigned int exynos_release_ret_regs[] = { 99 S5P_PAD_RET_MAUDIO_OPTION, 100 S5P_PAD_RET_GPIO_OPTION, 101 S5P_PAD_RET_UART_OPTION, 102 S5P_PAD_RET_MMCA_OPTION, 103 S5P_PAD_RET_MMCB_OPTION, 104 S5P_PAD_RET_EBIA_OPTION, 105 S5P_PAD_RET_EBIB_OPTION, 106 REG_TABLE_END, 107}; 108 109static unsigned int exynos3250_release_ret_regs[] = { 110 S5P_PAD_RET_MAUDIO_OPTION, 111 S5P_PAD_RET_GPIO_OPTION, 112 S5P_PAD_RET_UART_OPTION, 113 S5P_PAD_RET_MMCA_OPTION, 114 S5P_PAD_RET_MMCB_OPTION, 115 S5P_PAD_RET_EBIA_OPTION, 116 S5P_PAD_RET_EBIB_OPTION, 117 S5P_PAD_RET_MMC2_OPTION, 118 S5P_PAD_RET_SPI_OPTION, 119 REG_TABLE_END, 120}; 121 122static unsigned int exynos5420_release_ret_regs[] = { 123 EXYNOS_PAD_RET_DRAM_OPTION, 124 EXYNOS_PAD_RET_MAUDIO_OPTION, 125 EXYNOS_PAD_RET_JTAG_OPTION, 126 EXYNOS5420_PAD_RET_GPIO_OPTION, 127 EXYNOS5420_PAD_RET_UART_OPTION, 128 EXYNOS5420_PAD_RET_MMCA_OPTION, 129 EXYNOS5420_PAD_RET_MMCB_OPTION, 130 EXYNOS5420_PAD_RET_MMCC_OPTION, 131 EXYNOS5420_PAD_RET_HSI_OPTION, 132 EXYNOS_PAD_RET_EBIA_OPTION, 133 EXYNOS_PAD_RET_EBIB_OPTION, 134 EXYNOS5420_PAD_RET_SPI_OPTION, 135 EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION, 136 REG_TABLE_END, 137}; 138 |
|
97static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) 98{ 99 const struct exynos_wkup_irq *wkup_irq; 100 101 if (!pm_data->wkup_irq) 102 return -ENOENT; 103 wkup_irq = pm_data->wkup_irq; 104 --- 236 unchanged lines hidden (view full) --- 341 EXYNOS5420_CPU_STATE); 342 343 exynos_pm_enter_sleep_mode(); 344 345 /* ensure at least INFORM0 has the resume address */ 346 if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) 347 pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0); 348 | 139static int exynos_irq_set_wake(struct irq_data *data, unsigned int state) 140{ 141 const struct exynos_wkup_irq *wkup_irq; 142 143 if (!pm_data->wkup_irq) 144 return -ENOENT; 145 wkup_irq = pm_data->wkup_irq; 146 --- 236 unchanged lines hidden (view full) --- 383 EXYNOS5420_CPU_STATE); 384 385 exynos_pm_enter_sleep_mode(); 386 387 /* ensure at least INFORM0 has the resume address */ 388 if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) 389 pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0); 390 |
349 tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION); 350 tmp &= ~EXYNOS5_USE_RETENTION; 351 pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION); | 391 tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0)); 392 tmp &= ~EXYNOS_L2_USE_RETENTION; 393 pmu_raw_writel(tmp, EXYNOS_L2_OPTION(0)); |
352 353 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); 354 tmp |= EXYNOS5420_UFS; 355 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); 356 357 tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); 358 tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; 359 pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); --- 35 unchanged lines hidden (view full) --- 395 pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, 396 S5P_CENTRAL_SEQ_OPTION); 397 else 398 pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, 399 S5P_CENTRAL_SEQ_OPTION); 400 return 0; 401} 402 | 394 395 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); 396 tmp |= EXYNOS5420_UFS; 397 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); 398 399 tmp = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); 400 tmp &= ~EXYNOS5420_L2RSTDISABLE_VALUE; 401 pmu_raw_writel(tmp, EXYNOS5420_ARM_COMMON_OPTION); --- 35 unchanged lines hidden (view full) --- 437 pmu_raw_writel(EXYNOS5420_ARM_USE_STANDBY_WFI0, 438 S5P_CENTRAL_SEQ_OPTION); 439 else 440 pmu_raw_writel(EXYNOS5420_KFC_USE_STANDBY_WFI0, 441 S5P_CENTRAL_SEQ_OPTION); 442 return 0; 443} 444 |
445static void exynos_pm_release_retention(void) 446{ 447 unsigned int i; 448 449 for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++) 450 pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR, 451 pm_data->release_ret_regs[i]); 452} 453 |
|
403static void exynos_pm_resume(void) 404{ 405 u32 cpuid = read_cpuid_part(); 406 407 if (exynos_pm_central_resume()) 408 goto early_wakeup; 409 | 454static void exynos_pm_resume(void) 455{ 456 u32 cpuid = read_cpuid_part(); 457 458 if (exynos_pm_central_resume()) 459 goto early_wakeup; 460 |
461 /* For release retention */ 462 exynos_pm_release_retention(); 463 |
|
410 if (cpuid == ARM_CPU_PART_CORTEX_A9) 411 scu_enable(S5P_VA_SCU); 412 413 if (call_firmware_op(resume) == -ENOSYS 414 && cpuid == ARM_CPU_PART_CORTEX_A9) 415 exynos_cpu_restore_register(); 416 417early_wakeup: --- 5 unchanged lines hidden (view full) --- 423 424static void exynos3250_pm_resume(void) 425{ 426 u32 cpuid = read_cpuid_part(); 427 428 if (exynos_pm_central_resume()) 429 goto early_wakeup; 430 | 464 if (cpuid == ARM_CPU_PART_CORTEX_A9) 465 scu_enable(S5P_VA_SCU); 466 467 if (call_firmware_op(resume) == -ENOSYS 468 && cpuid == ARM_CPU_PART_CORTEX_A9) 469 exynos_cpu_restore_register(); 470 471early_wakeup: --- 5 unchanged lines hidden (view full) --- 477 478static void exynos3250_pm_resume(void) 479{ 480 u32 cpuid = read_cpuid_part(); 481 482 if (exynos_pm_central_resume()) 483 goto early_wakeup; 484 |
485 /* For release retention */ 486 exynos_pm_release_retention(); 487 |
|
431 pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); 432 433 if (call_firmware_op(resume) == -ENOSYS 434 && cpuid == ARM_CPU_PART_CORTEX_A9) 435 exynos_cpu_restore_register(); 436 437early_wakeup: 438 --- 21 unchanged lines hidden (view full) --- 460 sysram_base_addr + EXYNOS5420_CPU_STATE); 461 462 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, 463 S5P_CENTRAL_SEQ_OPTION); 464 465 if (exynos_pm_central_resume()) 466 goto early_wakeup; 467 | 488 pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); 489 490 if (call_firmware_op(resume) == -ENOSYS 491 && cpuid == ARM_CPU_PART_CORTEX_A9) 492 exynos_cpu_restore_register(); 493 494early_wakeup: 495 --- 21 unchanged lines hidden (view full) --- 517 sysram_base_addr + EXYNOS5420_CPU_STATE); 518 519 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, 520 S5P_CENTRAL_SEQ_OPTION); 521 522 if (exynos_pm_central_resume()) 523 goto early_wakeup; 524 |
525 /* For release retention */ 526 exynos_pm_release_retention(); 527 |
|
468 pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3); 469 470early_wakeup: 471 472 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); 473 tmp &= ~EXYNOS5420_UFS; 474 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); 475 --- 96 unchanged lines hidden (view full) --- 572 .prepare = exynos_suspend_prepare, 573 .finish = exynos_suspend_finish, 574 .valid = suspend_valid_only_mem, 575}; 576 577static const struct exynos_pm_data exynos3250_pm_data = { 578 .wkup_irq = exynos3250_wkup_irq, 579 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), | 528 pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3); 529 530early_wakeup: 531 532 tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); 533 tmp &= ~EXYNOS5420_UFS; 534 pmu_raw_writel(tmp, EXYNOS5420_SFR_AXI_CGDIS1); 535 --- 96 unchanged lines hidden (view full) --- 632 .prepare = exynos_suspend_prepare, 633 .finish = exynos_suspend_finish, 634 .valid = suspend_valid_only_mem, 635}; 636 637static const struct exynos_pm_data exynos3250_pm_data = { 638 .wkup_irq = exynos3250_wkup_irq, 639 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), |
640 .release_ret_regs = exynos3250_release_ret_regs, |
|
580 .pm_suspend = exynos_pm_suspend, 581 .pm_resume = exynos3250_pm_resume, 582 .pm_prepare = exynos3250_pm_prepare, 583 .cpu_suspend = exynos3250_cpu_suspend, 584}; 585 586static const struct exynos_pm_data exynos4_pm_data = { 587 .wkup_irq = exynos4_wkup_irq, 588 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), | 641 .pm_suspend = exynos_pm_suspend, 642 .pm_resume = exynos3250_pm_resume, 643 .pm_prepare = exynos3250_pm_prepare, 644 .cpu_suspend = exynos3250_cpu_suspend, 645}; 646 647static const struct exynos_pm_data exynos4_pm_data = { 648 .wkup_irq = exynos4_wkup_irq, 649 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), |
650 .release_ret_regs = exynos_release_ret_regs, |
|
589 .pm_suspend = exynos_pm_suspend, 590 .pm_resume = exynos_pm_resume, 591 .pm_prepare = exynos_pm_prepare, 592 .cpu_suspend = exynos_cpu_suspend, 593}; 594 595static const struct exynos_pm_data exynos5250_pm_data = { 596 .wkup_irq = exynos5250_wkup_irq, 597 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), | 651 .pm_suspend = exynos_pm_suspend, 652 .pm_resume = exynos_pm_resume, 653 .pm_prepare = exynos_pm_prepare, 654 .cpu_suspend = exynos_cpu_suspend, 655}; 656 657static const struct exynos_pm_data exynos5250_pm_data = { 658 .wkup_irq = exynos5250_wkup_irq, 659 .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), |
660 .release_ret_regs = exynos_release_ret_regs, |
|
598 .pm_suspend = exynos_pm_suspend, 599 .pm_resume = exynos_pm_resume, 600 .pm_prepare = exynos_pm_prepare, 601 .cpu_suspend = exynos_cpu_suspend, 602}; 603 604static const struct exynos_pm_data exynos5420_pm_data = { 605 .wkup_irq = exynos5250_wkup_irq, 606 .wake_disable_mask = (0x7F << 7) | (0x1F << 1), | 661 .pm_suspend = exynos_pm_suspend, 662 .pm_resume = exynos_pm_resume, 663 .pm_prepare = exynos_pm_prepare, 664 .cpu_suspend = exynos_cpu_suspend, 665}; 666 667static const struct exynos_pm_data exynos5420_pm_data = { 668 .wkup_irq = exynos5250_wkup_irq, 669 .wake_disable_mask = (0x7F << 7) | (0x1F << 1), |
670 .release_ret_regs = exynos5420_release_ret_regs, |
|
607 .pm_resume_prepare = exynos5420_prepare_pm_resume, 608 .pm_resume = exynos5420_pm_resume, 609 .pm_suspend = exynos5420_pm_suspend, 610 .pm_prepare = exynos5420_pm_prepare, 611 .cpu_suspend = exynos5420_cpu_suspend, 612}; 613 614static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { --- 54 unchanged lines hidden --- | 671 .pm_resume_prepare = exynos5420_prepare_pm_resume, 672 .pm_resume = exynos5420_pm_resume, 673 .pm_suspend = exynos5420_pm_suspend, 674 .pm_prepare = exynos5420_pm_prepare, 675 .cpu_suspend = exynos5420_cpu_suspend, 676}; 677 678static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { --- 54 unchanged lines hidden --- |