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 14*ff4735cfSLin Huang __attribute__((noreturn)) void main(void) 15977001aaSXing Zheng { 16977001aaSXing Zheng unsigned int status_value; 17977001aaSXing Zheng 18*ff4735cfSLin Huang /* 19*ff4735cfSLin Huang * PMU sometimes doesn't clear power mode bit as it's supposed to due 20*ff4735cfSLin Huang * to a hardware bug. Make the M0 clear it manually to be sure, 21*ff4735cfSLin Huang * otherwise interrupts some cases with concurrent wake interrupts 22*ff4735cfSLin Huang * we stay asleep forever. 23*ff4735cfSLin 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); 28*ff4735cfSLin Huang break; 29977001aaSXing Zheng } 30977001aaSXing Zheng } 31977001aaSXing Zheng 32*ff4735cfSLin Huang /* 33*ff4735cfSLin Huang * FSM power secquence is .. -> ST_INPUT_CLAMP(step.17) -> .. -> 34*ff4735cfSLin Huang * ST_WAKEUP_RESET -> ST_EXT_PWRUP-> ST_RELEASE_CLAMP -> 35*ff4735cfSLin Huang * ST_24M_OSC_EN -> .. -> ST_WAKEUP_RESET_CLR(step.26) -> .., 36*ff4735cfSLin Huang * INPUT_CLAMP and WAKEUP_RESET will hold the SOC not affect by 37*ff4735cfSLin Huang * power or other single glitch, but WAKEUP_RESET need work with 24MHz, 38*ff4735cfSLin Huang * so between RELEASE_CLAMP and 24M_OSC_EN, there have a chance 39*ff4735cfSLin Huang * that glitch will affect SOC, and mess up SOC status, so we 40*ff4735cfSLin Huang * addressmap_shared software clamp between ST_INPUT_CLAMP and 41*ff4735cfSLin Huang * ST_WAKEUP_RESET_CLR to avoid this happen. 42*ff4735cfSLin Huang */ 43*ff4735cfSLin Huang while (1) { 44*ff4735cfSLin Huang status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST); 45*ff4735cfSLin Huang if (status_value >= 17) { 46*ff4735cfSLin Huang mmio_setbits_32(PMU_BASE + PMU_SFT_CON, 0x02); 47*ff4735cfSLin Huang break; 48*ff4735cfSLin Huang } 49*ff4735cfSLin Huang 50*ff4735cfSLin Huang } 51*ff4735cfSLin Huang 52*ff4735cfSLin Huang while (1) { 53*ff4735cfSLin Huang status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST); 54*ff4735cfSLin Huang if (status_value >= 26) { 55*ff4735cfSLin Huang mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 0x02); 56*ff4735cfSLin Huang break; 57*ff4735cfSLin Huang } 58*ff4735cfSLin Huang } 59*ff4735cfSLin Huang 60*ff4735cfSLin Huang for (;;) 61*ff4735cfSLin Huang __asm__ volatile ("wfi"); 62977001aaSXing Zheng } 63