Caesar Wang | b400374 | 2016-10-12 08:10:12 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. |
| 3 | * |
dp-arm | fa3cf0b | 2017-05-03 09:38:09 +0100 | [diff] [blame] | 4 | * SPDX-License-Identifier: BSD-3-Clause |
Caesar Wang | b400374 | 2016-10-12 08:10:12 +0800 | [diff] [blame] | 5 | */ |
| 6 | |
Xing Zheng | b4bcc1d | 2017-02-24 16:26:11 +0800 | [diff] [blame] | 7 | #include <pmu_regs.h> |
Xing Zheng | 93280b7 | 2016-10-26 21:25:26 +0800 | [diff] [blame] | 8 | #include "rk3399_mcu.h" |
Caesar Wang | b400374 | 2016-10-12 08:10:12 +0800 | [diff] [blame] | 9 | |
Xing Zheng | 93280b7 | 2016-10-26 21:25:26 +0800 | [diff] [blame] | 10 | #define M0_SCR 0xe000ed10 /* System Control Register (SCR) */ |
| 11 | |
| 12 | #define SCR_SLEEPDEEP_SHIFT (1 << 2) |
| 13 | |
Christoph Müllner | df76b44 | 2019-04-15 21:42:29 +0200 | [diff] [blame] | 14 | __attribute__((noreturn)) void m0_main(void) |
Xing Zheng | 93280b7 | 2016-10-26 21:25:26 +0800 | [diff] [blame] | 15 | { |
| 16 | unsigned int status_value; |
| 17 | |
Lin Huang | 00960ba | 2018-04-20 15:55:21 +0800 | [diff] [blame] | 18 | /* |
| 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 Zheng | 93280b7 | 2016-10-26 21:25:26 +0800 | [diff] [blame] | 24 | 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 Huang | 00960ba | 2018-04-20 15:55:21 +0800 | [diff] [blame] | 28 | break; |
Xing Zheng | 93280b7 | 2016-10-26 21:25:26 +0800 | [diff] [blame] | 29 | } |
Caesar Wang | b400374 | 2016-10-12 08:10:12 +0800 | [diff] [blame] | 30 | } |
| 31 | |
Lin Huang | 00960ba | 2018-04-20 15:55:21 +0800 | [diff] [blame] | 32 | /* |
| 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 Wang | b400374 | 2016-10-12 08:10:12 +0800 | [diff] [blame] | 62 | } |