blob: 9ad2fa26a1775e57aa41520174b2a971b23e628f [file] [log] [blame]
Caesar Wangb4003742016-10-12 08:10:12 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Caesar Wangb4003742016-10-12 08:10:12 +08005 */
6
Xing Zhengb4bcc1d2017-02-24 16:26:11 +08007#include <pmu_regs.h>
Xing Zheng93280b72016-10-26 21:25:26 +08008#include "rk3399_mcu.h"
Caesar Wangb4003742016-10-12 08:10:12 +08009
Xing Zheng93280b72016-10-26 21:25:26 +080010#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */
11
12#define SCR_SLEEPDEEP_SHIFT (1 << 2)
13
Christoph Müllnerdf76b442019-04-15 21:42:29 +020014__attribute__((noreturn)) void m0_main(void)
Xing Zheng93280b72016-10-26 21:25:26 +080015{
16 unsigned int status_value;
17
Lin Huang00960ba2018-04-20 15:55:21 +080018 /*
19 * PMU sometimes doesn't clear power mode bit as it's supposed to due
20 * to a hardware bug. Make the M0 clear it manually to be sure,
21 * otherwise interrupts some cases with concurrent wake interrupts
22 * we stay asleep forever.
23 */
Xing Zheng93280b72016-10-26 21:25:26 +080024 while (1) {
25 status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
26 if (status_value) {
27 mmio_clrbits_32(PMU_BASE + PMU_PWRMODE_CON, 0x01);
Lin Huang00960ba2018-04-20 15:55:21 +080028 break;
Xing Zheng93280b72016-10-26 21:25:26 +080029 }
Caesar Wangb4003742016-10-12 08:10:12 +080030 }
31
Lin Huang00960ba2018-04-20 15:55:21 +080032 /*
33 * FSM power secquence is .. -> ST_INPUT_CLAMP(step.17) -> .. ->
34 * ST_WAKEUP_RESET -> ST_EXT_PWRUP-> ST_RELEASE_CLAMP ->
35 * ST_24M_OSC_EN -> .. -> ST_WAKEUP_RESET_CLR(step.26) -> ..,
36 * INPUT_CLAMP and WAKEUP_RESET will hold the SOC not affect by
37 * power or other single glitch, but WAKEUP_RESET need work with 24MHz,
38 * so between RELEASE_CLAMP and 24M_OSC_EN, there have a chance
39 * that glitch will affect SOC, and mess up SOC status, so we
40 * addressmap_shared software clamp between ST_INPUT_CLAMP and
41 * ST_WAKEUP_RESET_CLR to avoid this happen.
42 */
43 while (1) {
44 status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
45 if (status_value >= 17) {
46 mmio_setbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
47 break;
48 }
49
50 }
51
52 while (1) {
53 status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
54 if (status_value >= 26) {
55 mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
56 break;
57 }
58 }
59
60 for (;;)
61 __asm__ volatile ("wfi");
Caesar Wangb4003742016-10-12 08:10:12 +080062}