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