1977001aaSXing Zheng /*
2977001aaSXing Zheng * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3977001aaSXing Zheng *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5977001aaSXing Zheng */
6977001aaSXing Zheng
71830f790SXing Zheng #include <pmu_regs.h>
8977001aaSXing Zheng #include "rk3399_mcu.h"
9977001aaSXing Zheng
10977001aaSXing Zheng #define M0_SCR 0xe000ed10 /* System Control Register (SCR) */
11977001aaSXing Zheng
12977001aaSXing Zheng #define SCR_SLEEPDEEP_SHIFT (1 << 2)
13977001aaSXing Zheng
m0_main(void)14af81a91fSChristoph Müllner __attribute__((noreturn)) void m0_main(void)
15977001aaSXing Zheng {
16977001aaSXing Zheng unsigned int status_value;
17977001aaSXing Zheng
18ff4735cfSLin Huang /*
19ff4735cfSLin Huang * PMU sometimes doesn't clear power mode bit as it's supposed to due
20ff4735cfSLin Huang * to a hardware bug. Make the M0 clear it manually to be sure,
21ff4735cfSLin Huang * otherwise interrupts some cases with concurrent wake interrupts
22ff4735cfSLin Huang * we stay asleep forever.
23ff4735cfSLin Huang */
24977001aaSXing Zheng while (1) {
25977001aaSXing Zheng status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
26977001aaSXing Zheng if (status_value) {
27977001aaSXing Zheng mmio_clrbits_32(PMU_BASE + PMU_PWRMODE_CON, 0x01);
28ff4735cfSLin Huang break;
29977001aaSXing Zheng }
30977001aaSXing Zheng }
31977001aaSXing Zheng
32ff4735cfSLin Huang /*
33*1b491eeaSElyes Haouas * FSM power sequence is .. -> ST_INPUT_CLAMP(step.17) -> .. ->
34ff4735cfSLin Huang * ST_WAKEUP_RESET -> ST_EXT_PWRUP-> ST_RELEASE_CLAMP ->
35ff4735cfSLin Huang * ST_24M_OSC_EN -> .. -> ST_WAKEUP_RESET_CLR(step.26) -> ..,
36ff4735cfSLin Huang * INPUT_CLAMP and WAKEUP_RESET will hold the SOC not affect by
37ff4735cfSLin Huang * power or other single glitch, but WAKEUP_RESET need work with 24MHz,
38ff4735cfSLin Huang * so between RELEASE_CLAMP and 24M_OSC_EN, there have a chance
39ff4735cfSLin Huang * that glitch will affect SOC, and mess up SOC status, so we
40ff4735cfSLin Huang * addressmap_shared software clamp between ST_INPUT_CLAMP and
41ff4735cfSLin Huang * ST_WAKEUP_RESET_CLR to avoid this happen.
42ff4735cfSLin Huang */
43ff4735cfSLin Huang while (1) {
44ff4735cfSLin Huang status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
45ff4735cfSLin Huang if (status_value >= 17) {
46ff4735cfSLin Huang mmio_setbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
47ff4735cfSLin Huang break;
48ff4735cfSLin Huang }
49ff4735cfSLin Huang
50ff4735cfSLin Huang }
51ff4735cfSLin Huang
52ff4735cfSLin Huang while (1) {
53ff4735cfSLin Huang status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
54ff4735cfSLin Huang if (status_value >= 26) {
55ff4735cfSLin Huang mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
56ff4735cfSLin Huang break;
57ff4735cfSLin Huang }
58ff4735cfSLin Huang }
59ff4735cfSLin Huang
60ff4735cfSLin Huang for (;;)
61ff4735cfSLin Huang __asm__ volatile ("wfi");
62977001aaSXing Zheng }
63