forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/arch/arm/mach-exynos/suspend.c
....@@ -3,7 +3,7 @@
33 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
44 // http://www.samsung.com
55 //
6
-// EXYNOS - Suspend support
6
+// Exynos - Suspend support
77 //
88 // Based on arch/arm/mach-s3c2410/pm.c
99 // Copyright (c) 2006 Simtec Electronics
....@@ -30,9 +30,8 @@
3030 #include <asm/smp_scu.h>
3131 #include <asm/suspend.h>
3232
33
-#include <plat/pm-common.h>
34
-
3533 #include "common.h"
34
+#include "smc.h"
3635
3736 #define REG_TABLE_END (-1U)
3837
....@@ -59,10 +58,17 @@
5958 int (*cpu_suspend)(unsigned long);
6059 };
6160
62
-static const struct exynos_pm_data *pm_data __ro_after_init;
61
+/* Used only on Exynos542x/5800 */
62
+struct exynos_pm_state {
63
+ int cpu_state;
64
+ unsigned int pmu_spare3;
65
+ void __iomem *sysram_base;
66
+ phys_addr_t sysram_phys;
67
+ bool secure_firmware;
68
+};
6369
64
-static int exynos5420_cpu_state;
65
-static unsigned int exynos_pmu_spare3;
70
+static const struct exynos_pm_data *pm_data __ro_after_init;
71
+static struct exynos_pm_state pm_state;
6672
6773 /*
6874 * GIC wake-up support
....@@ -87,6 +93,11 @@
8793 { 44, BIT(2) }, /* RTC tick */
8894 { /* sentinel */ },
8995 };
96
+
97
+static u32 exynos_read_eint_wakeup_mask(void)
98
+{
99
+ return pmu_raw_readl(EXYNOS_EINT_WAKEUP_MASK);
100
+}
90101
91102 static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
92103 {
....@@ -257,9 +268,7 @@
257268 unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
258269 unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
259270
260
- writel_relaxed(0x0, sysram_base_addr + EXYNOS5420_CPU_STATE);
261
-
262
- if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM)) {
271
+ if (IS_ENABLED(CONFIG_EXYNOS_MCPM)) {
263272 mcpm_set_entry_vector(cpu, cluster, exynos_cpu_resume);
264273 mcpm_cpu_suspend();
265274 }
....@@ -272,9 +281,11 @@
272281
273282 static void exynos_pm_set_wakeup_mask(void)
274283 {
275
- /* Set wake-up mask registers */
276
- pmu_raw_writel(exynos_get_eint_wake_mask(), EXYNOS_EINT_WAKEUP_MASK);
277
- pmu_raw_writel(exynos_irqwake_intmask & ~(1 << 31), S5P_WAKEUP_MASK);
284
+ /*
285
+ * Set wake-up mask registers
286
+ * EXYNOS_EINT_WAKEUP_MASK is set by pinctrl driver in late suspend.
287
+ */
288
+ pmu_raw_writel(exynos_irqwake_intmask & ~BIT(31), S5P_WAKEUP_MASK);
278289 }
279290
280291 static void exynos_pm_enter_sleep_mode(void)
....@@ -321,7 +332,7 @@
321332 /* Set wake-up mask registers */
322333 exynos_pm_set_wakeup_mask();
323334
324
- exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
335
+ pm_state.pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
325336 /*
326337 * The cpu state needs to be saved and restored so that the
327338 * secondary CPUs will enter low power start. Though the U-Boot
....@@ -329,13 +340,18 @@
329340 * needs to restore it back in case, the primary cpu fails to
330341 * suspend for any reason.
331342 */
332
- exynos5420_cpu_state = readl_relaxed(sysram_base_addr +
333
- EXYNOS5420_CPU_STATE);
343
+ pm_state.cpu_state = readl_relaxed(pm_state.sysram_base +
344
+ EXYNOS5420_CPU_STATE);
345
+ writel_relaxed(0x0, pm_state.sysram_base + EXYNOS5420_CPU_STATE);
346
+ if (pm_state.secure_firmware)
347
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(pm_state.sysram_phys +
348
+ EXYNOS5420_CPU_STATE),
349
+ 0, 0);
334350
335351 exynos_pm_enter_sleep_mode();
336352
337353 /* ensure at least INFORM0 has the resume address */
338
- if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
354
+ if (IS_ENABLED(CONFIG_EXYNOS_MCPM))
339355 pmu_raw_writel(__pa_symbol(mcpm_entry_point), S5P_INFORM0);
340356
341357 tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0));
....@@ -439,7 +455,7 @@
439455 mpidr = read_cpuid_mpidr();
440456 cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
441457
442
- if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
458
+ if (IS_ENABLED(CONFIG_EXYNOS_MCPM))
443459 WARN_ON(mcpm_cpu_powered_up());
444460
445461 if (IS_ENABLED(CONFIG_HW_PERF_EVENTS) && cluster != 0) {
....@@ -467,8 +483,13 @@
467483 EXYNOS5_ARM_CORE0_SYS_PWR_REG);
468484
469485 /* Restore the sysram cpu state register */
470
- writel_relaxed(exynos5420_cpu_state,
471
- sysram_base_addr + EXYNOS5420_CPU_STATE);
486
+ writel_relaxed(pm_state.cpu_state,
487
+ pm_state.sysram_base + EXYNOS5420_CPU_STATE);
488
+ if (pm_state.secure_firmware)
489
+ exynos_smc(SMC_CMD_REG,
490
+ SMC_REG_ID_SFR_W(pm_state.sysram_phys +
491
+ EXYNOS5420_CPU_STATE),
492
+ EXYNOS_AFTR_MAGIC, 0);
472493
473494 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL,
474495 S5P_CENTRAL_SEQ_OPTION);
....@@ -476,7 +497,7 @@
476497 if (exynos_pm_central_resume())
477498 goto early_wakeup;
478499
479
- pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
500
+ pmu_raw_writel(pm_state.pmu_spare3, S5P_PMU_SPARE3);
480501
481502 early_wakeup:
482503
....@@ -502,27 +523,24 @@
502523
503524 static int exynos_suspend_enter(suspend_state_t state)
504525 {
526
+ u32 eint_wakeup_mask = exynos_read_eint_wakeup_mask();
505527 int ret;
506528
507
- s3c_pm_debug_init();
529
+ pr_debug("%s: suspending the system...\n", __func__);
508530
509
- S3C_PMDBG("%s: suspending the system...\n", __func__);
510
-
511
- S3C_PMDBG("%s: wakeup masks: %08x,%08x\n", __func__,
512
- exynos_irqwake_intmask, exynos_get_eint_wake_mask());
531
+ pr_debug("%s: wakeup masks: %08x,%08x\n", __func__,
532
+ exynos_irqwake_intmask, eint_wakeup_mask);
513533
514534 if (exynos_irqwake_intmask == -1U
515
- && exynos_get_eint_wake_mask() == -1U) {
535
+ && eint_wakeup_mask == EXYNOS_EINT_WAKEUP_MASK_DISABLED) {
516536 pr_err("%s: No wake-up sources!\n", __func__);
517537 pr_err("%s: Aborting sleep\n", __func__);
518538 return -EINVAL;
519539 }
520540
521
- s3c_pm_save_uarts();
522541 if (pm_data->pm_prepare)
523542 pm_data->pm_prepare();
524543 flush_cache_all();
525
- s3c_pm_check_store();
526544
527545 ret = call_firmware_op(suspend);
528546 if (ret == -ENOSYS)
....@@ -532,14 +550,11 @@
532550
533551 if (pm_data->pm_resume_prepare)
534552 pm_data->pm_resume_prepare();
535
- s3c_pm_restore_uarts();
536553
537
- S3C_PMDBG("%s: wakeup stat: %08x\n", __func__,
554
+ pr_debug("%s: wakeup stat: %08x\n", __func__,
538555 pmu_raw_readl(S5P_WAKEUP_STAT));
539556
540
- s3c_pm_check_restore();
541
-
542
- S3C_PMDBG("%s: resuming the system...\n", __func__);
557
+ pr_debug("%s: resuming the system...\n", __func__);
543558
544559 return 0;
545560 }
....@@ -562,16 +577,12 @@
562577 return ret;
563578 }
564579
565
- s3c_pm_check_prepare();
566
-
567580 return 0;
568581 }
569582
570583 static void exynos_suspend_finish(void)
571584 {
572585 int ret;
573
-
574
- s3c_pm_check_cleanup();
575586
576587 ret = regulator_suspend_finish();
577588 if (ret)
....@@ -675,4 +686,16 @@
675686
676687 register_syscore_ops(&exynos_pm_syscore_ops);
677688 suspend_set_ops(&exynos_suspend_ops);
689
+
690
+ /*
691
+ * Applicable as of now only to Exynos542x. If booted under secure
692
+ * firmware, the non-secure region of sysram should be used.
693
+ */
694
+ if (exynos_secure_firmware_available()) {
695
+ pm_state.sysram_phys = sysram_base_phys;
696
+ pm_state.sysram_base = sysram_ns_base_addr;
697
+ pm_state.secure_firmware = true;
698
+ } else {
699
+ pm_state.sysram_base = sysram_base_addr;
700
+ }
678701 }