From 9eb4872909286f250128f59588abd848c744bcf7 Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Tue, 4 Apr 2017 14:57:32 +0200 Subject: import: Cortex-M0 sources from upstream ATF Imported from hash 3944adca5943a050ca7e7e9cc802a9ae04dec186 --- Makefile | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/addressmap.h | 39 +++++++++++++++ include/rk3399_mcu.h | 58 ++++++++++++++++++++++ src/dram.c | 103 +++++++++++++++++++++++++++++++++++++++ src/main.c | 51 ++++++++++++++++++++ src/rk3399m0.ld.S | 50 +++++++++++++++++++ src/startup.c | 116 ++++++++++++++++++++++++++++++++++++++++++++ src/stopwatch.c | 98 +++++++++++++++++++++++++++++++++++++ src/suspend.c | 52 ++++++++++++++++++++ 9 files changed, 700 insertions(+) create mode 100644 Makefile create mode 100644 include/addressmap.h create mode 100644 include/rk3399_mcu.h create mode 100644 src/dram.c create mode 100644 src/main.c create mode 100644 src/rk3399m0.ld.S create mode 100644 src/startup.c create mode 100644 src/stopwatch.c create mode 100644 src/suspend.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b2dac4a --- /dev/null +++ b/Makefile @@ -0,0 +1,133 @@ +# +# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# Cross Compile +M0_CROSS_COMPILE ?= arm-none-eabi- + +# Build architecture +ARCH := cortex-m0 + +# Build platform +PLAT_M0 ?= rk3399m0 + +ifeq (${V},0) + Q=@ +else + Q= +endif +export Q + +.SUFFIXES: + +INCLUDES += -Iinclude/ \ + -I../../include/shared/ + +# NOTE: Add C source files here +C_SOURCES := src/startup.c \ + src/main.c \ + src/suspend.c \ + src/dram.c \ + src/stopwatch.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 := $(C_SOURCES) +OBJS := $(addprefix $(BUILD)/,$(call SOURCES_TO_OBJS,$(SOURCES))) +LINKERFILE := $(BUILD)/$(PLAT_M0).ld +MAPFILE := $(BUILD)/$(PLAT_M0).map +ELF := $(BUILD)/$(PLAT_M0).elf +BIN := $(BUILD)/$(PLAT_M0).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 + +.DEFAULT_GOAL := $(BIN) + +$(LINKERFILE): $(LINKERFILE_SRC) + $(CC) $(COMMON_FLAGS) $(INCLUDES) -P -E -D__LINKER__ -MMD -MF $@.d -MT $@ -o $@ $< +-include $(LINKERFILE).d + +$(ELF) : $(OBJS) $(LINKERFILE) + @echo " LD $@" + $(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) + +$(BIN) : $(ELF) + @echo " BIN $@" + $(Q)$(OC) -O binary $< $@ + +$(eval $(call MAKE_OBJS,$(BUILD),$(SOURCES),$(1))) diff --git a/include/addressmap.h b/include/addressmap.h new file mode 100644 index 0000000..715d8c1 --- /dev/null +++ b/include/addressmap.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ROCKCHIP_RK3399_M0_INCLUDE_SHARED_ADDRESSMAP_H__ +#define __ROCKCHIP_RK3399_M0_INCLUDE_SHARED_ADDRESSMAP_H__ + +#include + +/* Registers base address for M0 */ +#define MMIO_BASE 0x40000000 + +#endif /* __ROCKCHIP_RK3399_M0_INCLUDE_SHARED_ADDRESSMAP_H__ */ diff --git a/include/rk3399_mcu.h b/include/rk3399_mcu.h new file mode 100644 index 0000000..b6ea3e8 --- /dev/null +++ b/include/rk3399_mcu.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __RK3399_MCU_H__ +#define __RK3399_MCU_H__ + +#include + +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 handle_suspend(void); +void handle_dram(void); +void stopwatch_init_usecs_expire(unsigned int usecs); +int stopwatch_expired(void); +void stopwatch_reset(void); + +#endif /* __RK3399_MCU_H__ */ diff --git a/src/dram.c b/src/dram.c new file mode 100644 index 0000000..bd46843 --- /dev/null +++ b/src/dram.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#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)); +} + +void handle_dram(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)); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..95659c4 --- /dev/null +++ b/src/main.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "rk3399_mcu.h" + +__attribute__((noreturn)) void main(void) +{ + switch (mmio_read_32(PARAM_ADDR + PARAM_M0_FUNC)) { + case M0_FUNC_SUSPEND: + handle_suspend(); + break; + case M0_FUNC_DRAM: + handle_dram(); + break; + default: + break; + } + + mmio_write_32(PARAM_ADDR + PARAM_M0_DONE, M0_DONE_FLAG); + + for (;;) + __asm__ volatile ("wfi"); +} diff --git a/src/rk3399m0.ld.S b/src/rk3399m0.ld.S new file mode 100644 index 0000000..cb224f0 --- /dev/null +++ b/src/rk3399m0.ld.S @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +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*) } +} diff --git a/src/startup.c b/src/startup.c new file mode 100644 index 0000000..47561fd --- /dev/null +++ b/src/startup.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rk3399_mcu.h" + +/* Stack configuration */ +#define STACK_SIZE 0x00000100 +__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 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 main() routine is called. + */ +static void default_reset_handler(void) +{ + /* call the application's entry point */ + 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) + ; +} diff --git a/src/stopwatch.c b/src/stopwatch.c new file mode 100644 index 0000000..4f4a961 --- /dev/null +++ b/src/stopwatch.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#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; +} diff --git a/src/suspend.c b/src/suspend.c new file mode 100644 index 0000000..71be71d --- /dev/null +++ b/src/suspend.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "rk3399_mcu.h" + +#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */ + +#define SCR_SLEEPDEEP_SHIFT (1 << 2) + +void handle_suspend(void) +{ + unsigned int status_value; + + while (1) { + status_value = mmio_read_32(PMU_BASE + PMU_POWER_ST); + if (status_value) { + mmio_clrbits_32(PMU_BASE + PMU_PWRMODE_CON, 0x01); + return; + } + } + + /* m0 enter deep sleep mode */ + mmio_setbits_32(M0_SCR, SCR_SLEEPDEEP_SHIFT); +} -- cgit v1.2.3