GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
#
|
||||
# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
# Cross Compile
|
||||
M0_CROSS_COMPILE ?= arm-none-eabi-
|
||||
|
||||
# Build architecture
|
||||
ARCH := cortex-m0
|
||||
|
||||
# Build platform
|
||||
PLAT_M0 ?= rk3399m0
|
||||
PLAT_M0_PMU ?= rk3399m0pmu
|
||||
|
||||
ifeq (${V},0)
|
||||
Q=@
|
||||
else
|
||||
Q=
|
||||
endif
|
||||
export Q
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
INCLUDES += -Iinclude/ \
|
||||
-I../../include/shared/
|
||||
|
||||
# NOTE: Add C source files here
|
||||
C_SOURCES_COMMON := src/startup.c
|
||||
C_SOURCES := src/dram.c \
|
||||
src/stopwatch.c
|
||||
C_SOURCES_PMU := src/suspend.c
|
||||
|
||||
# Flags definition
|
||||
COMMON_FLAGS := -g -mcpu=$(ARCH) -mthumb -Wall -O3 -nostdlib -mfloat-abi=soft
|
||||
CFLAGS := -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-common
|
||||
ASFLAGS := -Wa,--gdwarf-2
|
||||
LDFLAGS := -Wl,--gc-sections -Wl,--build-id=none
|
||||
|
||||
# Cross tool
|
||||
CC := ${M0_CROSS_COMPILE}gcc
|
||||
CPP := ${M0_CROSS_COMPILE}cpp
|
||||
AR := ${M0_CROSS_COMPILE}ar
|
||||
OC := ${M0_CROSS_COMPILE}objcopy
|
||||
OD := ${M0_CROSS_COMPILE}objdump
|
||||
NM := ${M0_CROSS_COMPILE}nm
|
||||
|
||||
# NOTE: The line continuation '\' is required in the next define otherwise we
|
||||
# end up with a line-feed characer at the end of the last c filename.
|
||||
# Also bare this issue in mind if extending the list of supported filetypes.
|
||||
define SOURCES_TO_OBJS
|
||||
$(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
|
||||
$(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
|
||||
endef
|
||||
|
||||
SOURCES_COMMON := $(C_SOURCES_COMMON)
|
||||
SOURCES := $(C_SOURCES)
|
||||
SOURCES_PMU := $(C_SOURCES_PMU)
|
||||
OBJS_COMMON := $(addprefix $(BUILD)/,$(call SOURCES_TO_OBJS,$(SOURCES_COMMON)))
|
||||
OBJS := $(addprefix $(BUILD)/,$(call SOURCES_TO_OBJS,$(SOURCES)))
|
||||
OBJS_PMU := $(addprefix $(BUILD)/,$(call SOURCES_TO_OBJS,$(SOURCES_PMU)))
|
||||
LINKERFILE := $(BUILD)/$(PLAT_M0).ld
|
||||
MAPFILE := $(BUILD)/$(PLAT_M0).map
|
||||
MAPFILE_PMU := $(BUILD)/$(PLAT_M0_PMU).map
|
||||
ELF := $(BUILD)/$(PLAT_M0).elf
|
||||
ELF_PMU := $(BUILD)/$(PLAT_M0_PMU).elf
|
||||
BIN := $(BUILD)/$(PLAT_M0).bin
|
||||
BIN_PMU := $(BUILD)/$(PLAT_M0_PMU).bin
|
||||
LINKERFILE_SRC := src/$(PLAT_M0).ld.S
|
||||
|
||||
# Function definition related compilation
|
||||
define MAKE_C
|
||||
$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
|
||||
-include $(patsubst %.o,%.d,$(OBJ))
|
||||
|
||||
$(OBJ) : $(2)
|
||||
@echo " CC $$<"
|
||||
$$(Q)$$(CC) $$(COMMON_FLAGS) $$(CFLAGS) $$(INCLUDES) -MMD -MT $$@ -c $$< -o $$@
|
||||
endef
|
||||
|
||||
define MAKE_S
|
||||
$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
|
||||
|
||||
$(OBJ) : $(2)
|
||||
@echo " AS $$<"
|
||||
$$(Q)$$(CC) -x assembler-with-cpp $$(COMMON_FLAGS) $$(ASFLAGS) -c $$< -o $$@
|
||||
endef
|
||||
|
||||
define MAKE_OBJS
|
||||
$(eval C_OBJS := $(filter %.c,$(2)))
|
||||
$(eval REMAIN := $(filter-out %.c,$(2)))
|
||||
$(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
|
||||
|
||||
$(eval S_OBJS := $(filter %.S,$(REMAIN)))
|
||||
$(eval REMAIN := $(filter-out %.S,$(REMAIN)))
|
||||
$(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
|
||||
|
||||
$(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
|
||||
endef
|
||||
|
||||
.PHONY: all
|
||||
all: $(BIN) $(BIN_PMU)
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
$(LINKERFILE): $(LINKERFILE_SRC)
|
||||
$(CC) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $<
|
||||
-include $(LINKERFILE).d
|
||||
|
||||
$(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE)
|
||||
@echo " LD $@"
|
||||
$(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON)
|
||||
|
||||
%.bin : %.elf
|
||||
@echo " BIN $@"
|
||||
$(Q)$(OC) -O binary $< $@
|
||||
|
||||
$(ELF_PMU) : $(OBJS_COMMON) $(OBJS_PMU) $(LINKERFILE)
|
||||
@echo " LD $@"
|
||||
$(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE_PMU) -Wl,-T$(LINKERFILE) $(OBJS_PMU) $(OBJS_COMMON)
|
||||
|
||||
$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_COMMON),$(1)))
|
||||
$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1)))
|
||||
$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES_PMU),$(1)))
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ADDRESSMAP_H
|
||||
#define ADDRESSMAP_H
|
||||
|
||||
#include <addressmap_shared.h>
|
||||
|
||||
/* Registers base address for M0 */
|
||||
#define MMIO_BASE 0x40000000
|
||||
|
||||
#endif /* ADDRESSMAP_H */
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef RK3399_MCU_H
|
||||
#define RK3399_MCU_H
|
||||
|
||||
#include <addressmap.h>
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
#define mmio_read_32(c) ({unsigned int __v = \
|
||||
(*(volatile unsigned int *)(c)); __v; })
|
||||
#define mmio_write_32(c, v) ((*(volatile unsigned int *)(c)) = (v))
|
||||
|
||||
#define mmio_clrbits_32(addr, clear) \
|
||||
mmio_write_32(addr, (mmio_read_32(addr) & ~(clear)))
|
||||
#define mmio_setbits_32(addr, set) \
|
||||
mmio_write_32(addr, (mmio_read_32(addr)) | (set))
|
||||
#define mmio_clrsetbits_32(addr, clear, set) \
|
||||
mmio_write_32(addr, (mmio_read_32(addr) & ~(clear)) | (set))
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void stopwatch_init_usecs_expire(unsigned int usecs);
|
||||
int stopwatch_expired(void);
|
||||
void stopwatch_reset(void);
|
||||
|
||||
#endif /* RK3399_MCU_H */
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <dram_regs.h>
|
||||
#include <m0_param.h>
|
||||
#include <pmu_bits.h>
|
||||
#include <pmu_regs.h>
|
||||
#include "misc_regs.h"
|
||||
#include "rk3399_mcu.h"
|
||||
|
||||
static uint32_t gatedis_con0;
|
||||
|
||||
static void idle_port(void)
|
||||
{
|
||||
gatedis_con0 = mmio_read_32(PMUCRU_BASE + PMU_CRU_GATEDIS_CON0);
|
||||
mmio_write_32(PMUCRU_BASE + PMU_CRU_GATEDIS_CON0, 0x3fffffff);
|
||||
|
||||
mmio_setbits_32(PMU_BASE + PMU_BUS_IDLE_REQ,
|
||||
(1 << PMU_IDLE_REQ_MSCH0) | (1 << PMU_IDLE_REQ_MSCH1));
|
||||
while ((mmio_read_32(PMU_BASE + PMU_BUS_IDLE_ST) &
|
||||
((1 << PMU_IDLE_ST_MSCH1) | (1 << PMU_IDLE_ST_MSCH0))) !=
|
||||
((1 << PMU_IDLE_ST_MSCH1) | (1 << PMU_IDLE_ST_MSCH0)))
|
||||
continue;
|
||||
}
|
||||
|
||||
static void deidle_port(void)
|
||||
{
|
||||
mmio_clrbits_32(PMU_BASE + PMU_BUS_IDLE_REQ,
|
||||
(1 << PMU_IDLE_REQ_MSCH0) | (1 << PMU_IDLE_REQ_MSCH1));
|
||||
while (mmio_read_32(PMU_BASE + PMU_BUS_IDLE_ST) &
|
||||
((1 << PMU_IDLE_ST_MSCH1) | (1 << PMU_IDLE_ST_MSCH0)))
|
||||
continue;
|
||||
|
||||
/* document is wrong, PMU_CRU_GATEDIS_CON0 do not need set MASK BIT */
|
||||
mmio_write_32(PMUCRU_BASE + PMU_CRU_GATEDIS_CON0, gatedis_con0);
|
||||
}
|
||||
|
||||
static void ddr_set_pll(void)
|
||||
{
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_MODE(PLL_SLOW_MODE));
|
||||
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_POWER_DOWN(1));
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON0,
|
||||
mmio_read_32(PARAM_ADDR + PARAM_DPLL_CON0));
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON1,
|
||||
mmio_read_32(PARAM_ADDR + PARAM_DPLL_CON1));
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_POWER_DOWN(0));
|
||||
|
||||
while ((mmio_read_32(CRU_BASE + CRU_DPLL_CON2) & (1u << 31)) == 0)
|
||||
continue;
|
||||
|
||||
mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_MODE(PLL_NORMAL_MODE));
|
||||
}
|
||||
|
||||
__attribute__((noreturn)) void m0_main(void)
|
||||
{
|
||||
mmio_setbits_32(PHY_REG(0, 927), (1 << 22));
|
||||
mmio_setbits_32(PHY_REG(1, 927), (1 << 22));
|
||||
idle_port();
|
||||
|
||||
mmio_write_32(CIC_BASE + CIC_CTRL0,
|
||||
(((0x3 << 4) | (1 << 2) | 1) << 16) |
|
||||
(1 << 2) | 1 |
|
||||
mmio_read_32(PARAM_ADDR + PARAM_FREQ_SELECT));
|
||||
while ((mmio_read_32(CIC_BASE + CIC_STATUS0) & (1 << 2)) == 0)
|
||||
continue;
|
||||
|
||||
ddr_set_pll();
|
||||
mmio_write_32(CIC_BASE + CIC_CTRL0, 0x20002);
|
||||
while ((mmio_read_32(CIC_BASE + CIC_STATUS0) & (1 << 0)) == 0)
|
||||
continue;
|
||||
|
||||
deidle_port();
|
||||
mmio_clrbits_32(PHY_REG(0, 927), (1 << 22));
|
||||
mmio_clrbits_32(PHY_REG(1, 927), (1 << 22));
|
||||
|
||||
mmio_write_32(PARAM_ADDR + PARAM_M0_DONE, M0_DONE_FLAG);
|
||||
|
||||
for (;;)
|
||||
__asm__ volatile ("wfi");
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <m0_param.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm")
|
||||
|
||||
SECTIONS {
|
||||
.m0_bin 0 : {
|
||||
KEEP(*(.isr_vector))
|
||||
ASSERT(. == 0xc0, "ISR vector has the wrong size.");
|
||||
ASSERT(. == PARAM_ADDR, "M0 params should go right behind ISR table.");
|
||||
. += PARAM_M0_SIZE;
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.data*)
|
||||
*(.bss*)
|
||||
. = ALIGN(8);
|
||||
*(.co_stack*)
|
||||
}
|
||||
|
||||
/DISCARD/ : { *(.comment) *(.note*) }
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "rk3399_mcu.h"
|
||||
|
||||
/* Stack configuration */
|
||||
#define STACK_SIZE 0x00000040
|
||||
__attribute__ ((section(".co_stack")))
|
||||
unsigned long pstack[STACK_SIZE];
|
||||
|
||||
/* Macro definition */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
/* System exception vector handler */
|
||||
__attribute__ ((used))
|
||||
void WEAK reset_handler(void);
|
||||
void WEAK nmi_handler(void);
|
||||
void WEAK hardware_fault_handler(void);
|
||||
void WEAK svc_handler(void);
|
||||
void WEAK pend_sv_handler(void);
|
||||
void WEAK systick_handler(void);
|
||||
|
||||
extern int m0_main(void);
|
||||
|
||||
/* Function prototypes */
|
||||
static void default_reset_handler(void);
|
||||
static void default_handler(void);
|
||||
|
||||
/*
|
||||
* The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x00000000.
|
||||
*/
|
||||
__attribute__ ((used, section(".isr_vector")))
|
||||
void (* const g_pfnVectors[])(void) = {
|
||||
/* core Exceptions */
|
||||
(void *)&pstack[STACK_SIZE], /* the initial stack pointer */
|
||||
reset_handler,
|
||||
nmi_handler,
|
||||
hardware_fault_handler,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
svc_handler,
|
||||
0, 0,
|
||||
pend_sv_handler,
|
||||
systick_handler,
|
||||
|
||||
/* external exceptions */
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied m0_main() routine is called.
|
||||
*/
|
||||
static void default_reset_handler(void)
|
||||
{
|
||||
/* call the application's entry point */
|
||||
m0_main();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*/
|
||||
#pragma weak reset_handler = default_reset_handler
|
||||
#pragma weak nmi_handler = default_handler
|
||||
#pragma weak hardware_fault_handler = default_handler
|
||||
#pragma weak svc_handler = default_handler
|
||||
#pragma weak pend_sv_handler = default_handler
|
||||
#pragma weak systick_handler = default_handler
|
||||
|
||||
/**
|
||||
* This is the code that gets called when the processor receives
|
||||
* an unexpected interrupt. This simply enters an infinite loop,
|
||||
* preserving the system state for examination by a debugger.
|
||||
*/
|
||||
static void default_handler(void)
|
||||
{
|
||||
/* go into an infinite loop. */
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <m0_param.h>
|
||||
#include "rk3399_mcu.h"
|
||||
|
||||
/* use 24MHz SysTick */
|
||||
#define US_TO_CYCLE(US) (US * 24)
|
||||
|
||||
#define SYST_CST 0xe000e010
|
||||
/* enable counter */
|
||||
#define ENABLE (1 << 0)
|
||||
/* count down to 0 does not cause SysTick exception to pend */
|
||||
#define TICKINT (1 << 1)
|
||||
/* core clock used for SysTick */
|
||||
#define CLKSOURCE (1 << 2)
|
||||
|
||||
#define COUNTFLAG (1 << 16)
|
||||
#define SYST_RVR 0xe000e014
|
||||
#define MAX_VALUE 0xffffff
|
||||
#define MAX_USECS (MAX_VALUE / US_TO_CYCLE(1))
|
||||
#define SYST_CVR 0xe000e018
|
||||
#define SYST_CALIB 0xe000e01c
|
||||
|
||||
unsigned int remaining_usecs;
|
||||
|
||||
static inline void stopwatch_set_usecs(void)
|
||||
{
|
||||
unsigned int cycle;
|
||||
unsigned int usecs = MIN(MAX_USECS, remaining_usecs);
|
||||
|
||||
remaining_usecs -= usecs;
|
||||
cycle = US_TO_CYCLE(usecs);
|
||||
mmio_write_32(SYST_RVR, cycle);
|
||||
mmio_write_32(SYST_CVR, 0);
|
||||
|
||||
mmio_write_32(SYST_CST, ENABLE | TICKINT | CLKSOURCE);
|
||||
}
|
||||
|
||||
void stopwatch_init_usecs_expire(unsigned int usecs)
|
||||
{
|
||||
/*
|
||||
* Enter an inifite loop if the stopwatch is in use. This will allow the
|
||||
* state to be analyzed with a debugger.
|
||||
*/
|
||||
if (mmio_read_32(SYST_CST) & ENABLE)
|
||||
while (1)
|
||||
;
|
||||
|
||||
remaining_usecs = usecs;
|
||||
stopwatch_set_usecs();
|
||||
}
|
||||
|
||||
int stopwatch_expired(void)
|
||||
{
|
||||
int val = mmio_read_32(SYST_CST);
|
||||
if ((val & COUNTFLAG) || !(val & ENABLE)) {
|
||||
if (!remaining_usecs)
|
||||
return 1;
|
||||
|
||||
stopwatch_set_usecs();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stopwatch_reset(void)
|
||||
{
|
||||
mmio_clrbits_32(SYST_CST, ENABLE);
|
||||
remaining_usecs = 0;
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <pmu_regs.h>
|
||||
#include "rk3399_mcu.h"
|
||||
|
||||
#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */
|
||||
|
||||
#define SCR_SLEEPDEEP_SHIFT (1 << 2)
|
||||
|
||||
__attribute__((noreturn)) void m0_main(void)
|
||||
{
|
||||
unsigned int status_value;
|
||||
|
||||
/*
|
||||
* PMU sometimes doesn't clear power mode bit as it's supposed to due
|
||||
* to a hardware bug. Make the M0 clear it manually to be sure,
|
||||
* otherwise interrupts some cases with concurrent wake interrupts
|
||||
* we stay asleep forever.
|
||||
*/
|
||||
while (1) {
|
||||
status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
|
||||
if (status_value) {
|
||||
mmio_clrbits_32(PMU_BASE + PMU_PWRMODE_CON, 0x01);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FSM power secquence is .. -> ST_INPUT_CLAMP(step.17) -> .. ->
|
||||
* ST_WAKEUP_RESET -> ST_EXT_PWRUP-> ST_RELEASE_CLAMP ->
|
||||
* ST_24M_OSC_EN -> .. -> ST_WAKEUP_RESET_CLR(step.26) -> ..,
|
||||
* INPUT_CLAMP and WAKEUP_RESET will hold the SOC not affect by
|
||||
* power or other single glitch, but WAKEUP_RESET need work with 24MHz,
|
||||
* so between RELEASE_CLAMP and 24M_OSC_EN, there have a chance
|
||||
* that glitch will affect SOC, and mess up SOC status, so we
|
||||
* addressmap_shared software clamp between ST_INPUT_CLAMP and
|
||||
* ST_WAKEUP_RESET_CLR to avoid this happen.
|
||||
*/
|
||||
while (1) {
|
||||
status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
|
||||
if (status_value >= 17) {
|
||||
mmio_setbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (1) {
|
||||
status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST);
|
||||
if (status_value >= 26) {
|
||||
mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, 0x02);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
__asm__ volatile ("wfi");
|
||||
}
|
||||
Reference in New Issue
Block a user