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 ---