diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 743e65c..9a05e6c 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -39,6 +39,9 @@ RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE } +#ifdef PLAT_EXTRA_LD_SCRIPT +#include +#endif SECTIONS { diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c index 40cd29e..ff47016 100644 --- a/plat/rockchip/common/aarch64/platform_common.c +++ b/plat/rockchip/common/aarch64/platform_common.c @@ -68,6 +68,7 @@ coh_limit - coh_start, \ MT_DEVICE | MT_RW | MT_SECURE); \ mmap_add(plat_rk_mmap); \ + rockchip_plat_sram_mmu_el##_el(); \ init_xlat_tables(); \ \ enable_mmu_el ## _el(0); \ diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c index 47a245a..b073bde 100644 --- a/plat/rockchip/common/bl31_plat_setup.c +++ b/plat/rockchip/common/bl31_plat_setup.c @@ -115,10 +115,6 @@ bl32_ep_info = *from_bl2->bl32_ep_info; bl33_ep_info = *from_bl2->bl33_ep_info; - /* - * The code for resuming cpu from suspend must be excuted in pmusram. - * Copy the code into pmusram. - */ plat_rockchip_pmusram_prepare(); /* there may have some board sepcific message need to initialize */ diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index ad01266..a093e79 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -37,6 +37,14 @@ #include #include +#define __sramdata __attribute__((section(".sram.data"))) +#define __sramconst __attribute__((section(".sram.rodata"))) +#define __sramfunc __attribute__((section(".sram.text"))) \ + __attribute__((noinline)) + +extern uint32_t __bl31_sram_text_start, __bl31_sram_text_end; +extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end; + /****************************************************************************** * For rockchip socs pm ops ******************************************************************************/ @@ -135,6 +143,10 @@ extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT]; extern const mmap_region_t plat_rk_mmap[]; + +void rockchip_plat_sram_mmu_el3(void); +void plat_rockchip_mem_prepare(void); + #endif /* __ASSEMBLY__ */ /****************************************************************************** diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index d28100d..e926345 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -317,18 +317,6 @@ rockchip_ops->system_off(); } -static void -__dead2 rockchip_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) -{ - if ((RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) && - (rockchip_ops)) { - if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE && - rockchip_ops->sys_pwr_down_wfi) - rockchip_ops->sys_pwr_down_wfi(target_state); - } - psci_power_down_wfi(); -} - /******************************************************************************* * Export the platform handlers via plat_rockchip_psci_pm_ops. The rockchip * standard @@ -341,7 +329,6 @@ .pwr_domain_suspend = rockchip_pwr_domain_suspend, .pwr_domain_on_finish = rockchip_pwr_domain_on_finish, .pwr_domain_suspend_finish = rockchip_pwr_domain_suspend_finish, - .pwr_domain_pwr_down_wfi = rockchip_pwr_domain_pwr_down_wfi, .system_reset = rockchip_system_reset, .system_off = rockchip_system_poweroff, .validate_power_state = rockchip_validate_power_state, diff --git a/plat/rockchip/common/pmusram/pmu_sram.c b/plat/rockchip/common/pmusram/pmu_sram.c index bea4875..5c6a6e6 100644 --- a/plat/rockchip/common/pmusram/pmu_sram.c +++ b/plat/rockchip/common/pmusram/pmu_sram.c @@ -24,7 +24,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include +#include /***************************************************************************** * sram only surpport 32-bits access @@ -36,3 +39,33 @@ for (i = 0; i < bytes; i++) dst[i] = src[i]; } + +void rockchip_plat_sram_mmu_el3(void) +{ +#ifdef PLAT_EXTRA_LD_SCRIPT + size_t sram_size; + + /* sram.text size */ + sram_size = (char *)&__bl31_sram_text_end - + (char *)&__bl31_sram_text_start; + mmap_add_region((unsigned long)&__bl31_sram_text_start, + (unsigned long)&__bl31_sram_text_start, + sram_size, MT_MEMORY | MT_RO | MT_SECURE); + + /* sram.data size */ + sram_size = (char *)&__bl31_sram_data_end - + (char *)&__bl31_sram_data_start; + mmap_add_region((unsigned long)&__bl31_sram_data_start, + (unsigned long)&__bl31_sram_data_start, + sram_size, MT_MEMORY | MT_RW | MT_SECURE); +#else + /* TODO: Support other SoCs, Just support RK3399 now */ + return; +#endif +} + +void plat_rockchip_mem_prepare(void) +{ + /* The code for resuming cpu from suspend must be excuted in pmusram */ + plat_rockchip_pmusram_prepare(); +} diff --git a/plat/rockchip/common/pmusram/pmu_sram.h b/plat/rockchip/common/pmusram/pmu_sram.h index f290461..ec2d341 100644 --- a/plat/rockchip/common/pmusram/pmu_sram.h +++ b/plat/rockchip/common/pmusram/pmu_sram.h @@ -45,16 +45,6 @@ #ifndef __ASSEMBLY__ -/* - * The struct is used in pmu_cpus_on.S which - * gets the data of the struct by the following index - * #define PSRAM_DT_SP 0x0 - * #define PSRAM_DT_DDR_FUNC 0x8 - * #define PSRAM_DT_DDR_DATA 0x10 - * #define PSRAM_DT_DDRFLAG 0x18 - * #define PSRAM_DT_SYS_MODE 0x1c - * #define PSRAM_DT_MPIDR 0x20 - */ struct psram_data_t { uint64_t sp; uint64_t ddr_func; @@ -76,6 +66,7 @@ CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR, assert_psram_dt_mpidr_offset_mistmatch); void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes); + #endif /* __ASSEMBLY__ */ #endif diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile new file mode 100644 index 0000000..8adc47e --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/Makefile @@ -0,0 +1,156 @@ +# +# 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=@ + CHECKCODE_ARGS += --no-summary --terse +else + Q= +endif +export Q + +# All PHONY definition +.PHONY: all clean distclean ${ARCH} +all: ${ARCH} + +.SUFFIXES: + +INCLUDES += -Iinclude/ + +# NOTE: Add C source files here +C_SOURCES := src/startup.c \ + src/main.c + +# Flags definition +CFLAGS := -g +ASFLAGS := -g -Wa,--gdwarf-2 + +ASFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3 +CFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3 + +LDFLAGS := -mcpu=$(ARCH) -mthumb -g -nostartfiles -O3 +LDFLAGS += -Wl,--gc-sections -Wl,--build-id=none + +# Cross tool +CC := ${M0_CROSS_COMPILE}gcc +CPP := ${M0_CROSS_COMPILE}cpp +AS := ${M0_CROSS_COMPILE}gcc +AR := ${M0_CROSS_COMPILE}ar +LD := ${M0_CROSS_COMPILE}ld +OC := ${M0_CROSS_COMPILE}objcopy +OD := ${M0_CROSS_COMPILE}objdump +NM := ${M0_CROSS_COMPILE}nm +PP := ${M0_CROSS_COMPILE}gcc -E ${CFLAGS} + +# 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 + +BUILD_DIR := ${BUILD_PLAT}/obj +BIN_DIR := ${BUILD_PLAT}/bin +SOURCES := $(C_SOURCES) +OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))) +LINKERFILE := src/rk3399m0.ld +MAPFILE := $(BIN_DIR)/$(PLAT_M0).map +ELF := $(BIN_DIR)/$(PLAT_M0).elf +BIN := $(BIN_DIR)/$(PLAT_M0).bin + +# Function definition related compilation +define MAKE_C +$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) + +$(OBJ) : $(2) + @echo " CC $$<" + $$(Q)$$(CC) $$(CFLAGS) $$(INCLUDES) -c $$< -o $$@ +endef + +define MAKE_S +$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) + +$(OBJ) : $(2) + @echo " AS $$<" + $$(Q)$$(AS) $$(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 + +$(BIN_DIR) : + $(Q)mkdir -p "$@" + +$(BUILD_DIR) : $(BIN_DIR) + $(Q)mkdir -p "$@" + +$(ELF) : $(OBJS) $(LINKERFILE) + @echo " LD $@" + $(Q)$(CC) -o $@ $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) \ + $(OBJS) + +$(BIN) : $(ELF) + @echo " BIN $@" + $(Q)$(OC) -O binary $< $@ + +.PHONY : ${ARCH} +${ARCH} : $(BUILD_DIR) $(BIN) + +$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1))) + +# Other common compilation entries +clean: + @echo " CLEAN" + ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0} + ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)* + +distclean: + @echo " DISTCLEAN" + ${Q}rm -rf ${BUILD_BASE}/${PLAT_M0} + ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT_M0)* diff --git a/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h new file mode 100644 index 0000000..7ea40fa --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h @@ -0,0 +1,41 @@ +/* + * 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__ + +#define readl(c) ({unsigned int __v = \ + (*(volatile unsigned int *)(c)); __v; }) +#define writel(v, c) ((*(volatile unsigned int *) (c)) = (v)) + +#define MCU_BASE 0x40000000 +#define PMU_BASE (MCU_BASE + 0x07310000) + +#endif /* __RK3399_MCU_H__ */ diff --git a/plat/rockchip/rk3399/drivers/m0/src/main.c b/plat/rockchip/rk3399/drivers/m0/src/main.c new file mode 100644 index 0000000..2e583c7 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/src/main.c @@ -0,0 +1,71 @@ +/* + * 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" + +#define PMU_PWRMODE_CON 0x20 +#define PMU_POWER_ST 0x78 + +#define M0_SCR 0xe000ed10 /* System Control Register (SCR) */ + +#define SCR_SLEEPDEEP_SHIFT (1 << 2) + +static void system_wakeup(void) +{ + unsigned int status_value; + unsigned int mode_con; + + while (1) { + status_value = readl(PMU_BASE + PMU_POWER_ST); + if (status_value) { + mode_con = readl(PMU_BASE + PMU_PWRMODE_CON); + writel(mode_con & (~0x01), + PMU_BASE + PMU_PWRMODE_CON); + return; + } + } +} + +int main(void) +{ + unsigned int reg_src; + + system_wakeup(); + + reg_src = readl(M0_SCR); + + /* m0 enter deep sleep mode */ + writel(reg_src | SCR_SLEEPDEEP_SHIFT, M0_SCR); + + for (;;) + __asm volatile("wfi"); + + return 0; +} diff --git a/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld new file mode 100644 index 0000000..0b7b124 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/src/rk3399m0.ld @@ -0,0 +1,46 @@ +/* + * 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. + */ + +OUTPUT_FORMAT("elf32-littlearm") + +SECTIONS { + .m0_bin 0 : { + KEEP(*(.isr_vector)) + ASSERT(. == 0xc0, "ISR vector has the wrong size."); + *(.text*) + *(.rodata*) + *(.data*) + *(.bss*) + . = ALIGN(8); + *(.co_stack*) + } + + /DISCARD/ : { *(.comment) *(.note*) } +} diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c new file mode 100644 index 0000000..47561fd --- /dev/null +++ b/plat/rockchip/rk3399/drivers/m0/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/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 07a5b1e..8d3f482 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -48,6 +48,7 @@ #include #include #include +#include DEFINE_BAKERY_LOCK(rockchip_pd_lock); @@ -436,7 +437,7 @@ void plat_rockchip_pmusram_prepare(void) { uint32_t *sram_dst, *sram_src; - size_t sram_size = 2; + size_t sram_size; /* * pmu sram code and data prepare @@ -840,8 +841,6 @@ BIT(PMU_SCU_PD_EN) | BIT(PMU_CCI_PD_EN) | BIT(PMU_CLK_CORE_SRC_GATE_EN) | - BIT(PMU_PERILP_PD_EN) | - BIT(PMU_CLK_PERILP_SRC_GATE_EN) | BIT(PMU_ALIVE_USE_LF) | BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) | @@ -1058,6 +1057,38 @@ } } +static void m0_clock_init(void) +{ + /* enable clocks for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, + BITS_WITH_WMASK(0x0, 0x2f, 0)); + + /* switch the parent to xin24M and div == 1 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKSEL_CON0, + BIT_WITH_WMSK(15) | BITS_WITH_WMASK(0x0, 0x1f, 8)); + + /* start M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0, + BITS_WITH_WMASK(0x0, 0x24, 0)); + + /* gating disable for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, BIT_WITH_WMSK(1)); +} + +static void m0_reset(void) +{ + /* stop M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_SOFTRST_CON0, + BITS_WITH_WMASK(0x24, 0x24, 0)); + + /* recover gating bit for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, WMSK_BIT(1)); + + /* disable clocks for M0 */ + mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, + BITS_WITH_WMASK(0x2f, 0x2f, 0)); +} + static int sys_pwr_domain_suspend(void) { uint32_t wait_cnt = 0; @@ -1071,12 +1102,12 @@ BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | - BIT(PMU_CLR_PERILP) | - BIT(PMU_CLR_PMU) | - BIT(PMU_CLR_PERILPM0) | BIT(PMU_CLR_GIC)); sys_slp_config(); + + m0_clock_init(); + pmu_sgrf_rst_hld(); mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), @@ -1111,6 +1142,7 @@ disable_dvfs_plls(); disable_pwms(); disable_nodvfs_plls(); + suspend_apio(); suspend_gpio(); @@ -1186,12 +1218,12 @@ BIT(PMU_CLR_CCIM0) | BIT(PMU_CLR_CCIM1) | BIT(PMU_CLR_CENTER) | - BIT(PMU_CLR_PERILP) | - BIT(PMU_CLR_PMU) | BIT(PMU_CLR_GIC)); plat_rockchip_gic_cpuif_enable(); + m0_reset(); + return 0; } @@ -1236,42 +1268,6 @@ while (1) ; } -static void __dead2 sys_pwr_down_wfi(const psci_power_state_t *target_state) -{ - uint32_t wakeup_status; - - /* - * Check wakeup status and abort suspend early if we see a wakeup - * event. - * - * NOTE: technically I we're supposed to just execute a wfi here and - * we'll either execute a normal suspend/resume or the wfi will be - * treated as a no-op if a wake event was present and caused an abort - * of the suspend/resume. For some reason that's not happening and if - * we execute the wfi while a wake event is pending then the whole - * system wedges. - * - * Until the above is solved this extra check prevents system wedges in - * most cases but there is still a small race condition between checking - * PMU_WAKEUP_STATUS and executing wfi. If a wake event happens in - * there then we will die. - */ - wakeup_status = mmio_read_32(PMU_BASE + PMU_WAKEUP_STATUS); - if (wakeup_status) { - WARN("early wake, will not enter power mode.\n"); - - mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, 0); - - disable_mmu_icache_el3(); - bl31_warm_entrypoint(); - - while (1) - ; - } else { - /* Enter WFI */ - psci_power_down_wfi(); - } -} static struct rockchip_pm_ops_cb pm_ops = { .cores_pwr_dm_on = cores_pwr_domain_on, @@ -1287,7 +1283,6 @@ .sys_pwr_dm_resume = sys_pwr_domain_resume, .sys_gbl_soft_reset = soc_soft_reset, .system_off = soc_system_off, - .sys_pwr_down_wfi = sys_pwr_down_wfi, }; void plat_rockchip_pmu_init(void) diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c new file mode 100644 index 0000000..01f08e6 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c @@ -0,0 +1,47 @@ +/* + * 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. + */ + +/* convoluted way to make sure that the define is pasted just the right way */ +#define _INCBIN(file, sym) \ + __asm__( \ + ".section .sram.incbin\n" \ + ".global " #sym "\n" \ + ".type " #sym ", %object\n" \ + ".align 4\n" \ + #sym ":\n" \ + ".incbin \"" #file "\"\n" \ + ".size " #sym ", .-" #sym "\n" \ + ".global " #sym "_end\n" \ + #sym "_end:\n" \ + ) + +#define INCBIN(file, sym) _INCBIN(file, sym) + +INCBIN(RK3399M0FW, rk3399m0_bin); diff --git a/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h new file mode 100644 index 0000000..78b350a --- /dev/null +++ b/plat/rockchip/rk3399/drivers/pmu/rk3399m0.h @@ -0,0 +1,40 @@ +/* + * 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 __RK3399M0_H__ +#define __RK3399M0_H__ + +/* pmu_fw.c */ +extern char rk3399m0_bin[]; +extern char rk3399m0_bin_end[]; + +#define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin) + +#endif /* __RK3399M0_H__ */ diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index 6af7a2e..e99db19 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include /* Table of regions to map using the MMU. */ @@ -387,6 +388,20 @@ ; } +static void soc_m0_init(void) +{ + /* secure config for pmu M0 */ + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7)); + + /* set the execute address for M0 */ + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3), + BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff, + 0xffff, 0)); + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7), + BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf, + 0xf, 0)); +} + void plat_rockchip_soc_init(void) { secure_timer_init(); @@ -394,4 +409,5 @@ sgrf_init(); soc_global_soft_reset_init(); plat_rockchip_gpio_init(); + soc_m0_init(); } diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index d4c2b69..9693f57 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -293,6 +293,18 @@ #define GRF_DDRC1_CON0 0xe388 #define GRF_DDRC1_CON1 0xe38c +#define PMUCRU_CLKSEL_CON0 0x0080 +#define PMUCRU_CLKGATE_CON2 0x0108 +#define PMUCRU_SOFTRST_CON0 0x0110 +#define PMUCRU_GATEDIS_CON0 0x0130 + +#define SGRF_SOC_CON6 0x0e018 +#define SGRF_PERILP_CON0 0x08100 +#define SGRF_PERILP_CON(n) (SGRF_PERILP_CON0 + (n) * 4) +#define SGRF_PMU_CON0 0x0c100 +#define SGRF_PMU_CON(n) (SGRF_PMU_CON0 + (n) * 4) +#define PMUCRU_SOFTRST_CON(n) (PMUCRU_SOFTRST_CON0 + (n) * 4) + /* * When system reset in running state, we want the cpus to be reboot * from maskrom (system reboot), diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S new file mode 100644 index 0000000..1614fba --- /dev/null +++ b/plat/rockchip/rk3399/include/plat.ld.S @@ -0,0 +1,76 @@ +/* + * 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_PLAT_LD_S__ +#define __ROCKCHIP_PLAT_LD_S__ + +MEMORY { + SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE +} + +SECTIONS +{ + . = SRAM_BASE; + ASSERT(. == ALIGN(4096), + "SRAM_BASE address is not aligned on a page boundary.") + + /* + * The SRAM space allocation for RK3399 + * ---------------- + * | m0 code bin + * ---------------- + * | sram text + * ---------------- + * | sram data + * ---------------- + */ + .incbin_sram : ALIGN(4096) { + __sram_incbin_start = .; + *(.sram.incbin) + . = ALIGN(4096); + __sram_incbin_end = .; + } >SRAM + + .text_sram : ALIGN(4096) { + __bl31_sram_text_start = .; + *(.sram.text) + *(.sram.rodata) + . = ALIGN(4096); + __bl31_sram_text_end = .; + } >SRAM + + .data_sram : ALIGN(4096) { + __bl31_sram_data_start = .; + *(.sram.data) + . = ALIGN(4096); + __bl31_sram_data_end = .; + } >SRAM +} + +#endif /* __ROCKCHIP_PLAT_LD_S__ */ diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 3627857..604de9c 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -76,9 +76,28 @@ ${RK_PLAT_SOC}/plat_sip_calls.c \ ${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ + ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \ ${RK_PLAT_SOC}/drivers/pwm/pwm.c \ ${RK_PLAT_SOC}/drivers/soc/soc.c \ ${RK_PLAT_SOC}/drivers/dram/dram.c \ ${RK_PLAT_SOC}/drivers/dram/dram_spec_timing.c ENABLE_PLAT_COMPAT := 0 + +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) + +# M0 source build +PLAT_M0 := ${PLAT}m0 + +RK3399M0FW=${BUILD_PLAT}/m0/bin/${PLAT_M0}.bin +$(eval $(call add_define,RK3399M0FW)) + +# CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin +export CCACHE_EXTRAFILES +${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW) +${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW) + +.PHONY: $(RK3399M0FW) +$(RK3399M0FW): + $(MAKE) -C ${RK_PLAT_SOC}/drivers/m0 \ + BUILD_PLAT=$(abspath ${BUILD_PLAT}/m0)