diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c index 70d9423b3..e6d39a1dd 100644 --- a/plat/rockchip/rk3399/drivers/dram/dfs.c +++ b/plat/rockchip/rk3399/drivers/dram/dfs.c @@ -1964,9 +1964,6 @@ uint32_t dram_set_odt_pd(uint32_t arg0, uint32_t arg1, uint32_t arg2) static void m0_configure_ddr(struct pll_div pll_div, uint32_t ddr_index) { - /* set PARAM to M0_FUNC_DRAM */ - mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_DRAM); - mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON0, FBDIV(pll_div.fbdiv)); mmio_write_32(M0_PARAM_ADDR + PARAM_DPLL_CON1, POSTDIV2(pll_div.postdiv2) | POSTDIV1(pll_div.postdiv1) | @@ -1976,6 +1973,7 @@ static void m0_configure_ddr(struct pll_div pll_div, uint32_t ddr_index) mmio_write_32(M0_PARAM_ADDR + PARAM_FREQ_SELECT, ddr_index << 4); dmbst(); + m0_configure_execute_addr(M0_BINCODE_BASE); } static uint32_t prepare_ddr_timing(uint32_t mhz) diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c index 2a80bcb31..dd97581db 100644 --- a/plat/rockchip/rk3399/drivers/dram/suspend.c +++ b/plat/rockchip/rk3399/drivers/dram/suspend.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -656,6 +658,30 @@ __pmusramfunc static void pmusram_restore_pll(int pll_id, uint32_t *src) ; } +__pmusramfunc static void pmusram_enable_watchdog(void) +{ + /* Make the watchdog use the first global reset. */ + mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 1 << 1); + + /* + * This gives the system ~8 seconds before reset. The pclk for the + * watchdog is 4MHz on reset. The value of 0x9 in WDT_TORR means that + * the watchdog will wait for 0x1ffffff cycles before resetting. + */ + mmio_write_32(WDT0_BASE + 4, 0x9); + + /* Enable the watchdog */ + mmio_setbits_32(WDT0_BASE, 0x1); + + /* Magic reset the watchdog timer value for WDT_CRR. */ + mmio_write_32(WDT0_BASE + 0xc, 0x76); + + secure_watchdog_ungate(); + + /* The watchdog is in PD_ALIVE, so deidle it. */ + mmio_clrbits_32(PMU_BASE + PMU_BUS_CLR, PMU_CLR_ALIVE); +} + void dmc_suspend(void) { struct rk3399_sdram_params *sdram_params = &sdram_config; @@ -726,6 +752,9 @@ __pmusramfunc void dmc_resume(void) uint32_t channel_mask = 0; uint32_t channel; + pmusram_enable_watchdog(); + pmu_sgrf_rst_hld_release(); + restore_pmu_rsthold(); sram_secure_timer_init(); /* diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile b/plat/rockchip/rk3399/drivers/m0/Makefile index f6bdbf271..79e09f0ef 100644 --- a/plat/rockchip/rk3399/drivers/m0/Makefile +++ b/plat/rockchip/rk3399/drivers/m0/Makefile @@ -12,6 +12,7 @@ ARCH := cortex-m0 # Build platform PLAT_M0 ?= rk3399m0 +PLAT_M0_PMU ?= rk3399m0pmu ifeq (${V},0) Q=@ @@ -26,11 +27,10 @@ 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 \ +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 @@ -54,12 +54,19 @@ define SOURCES_TO_OBJS $(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 @@ -92,18 +99,27 @@ define MAKE_OBJS $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN))) endef -.DEFAULT_GOAL := $(BIN) +.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) $(LINKERFILE) +$(ELF) : $(OBJS) $(OBJS_COMMON) $(LINKERFILE) @echo " LD $@" - $(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) + $(Q)$(CC) -o $@ $(COMMON_FLAGS) $(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) $(OBJS) $(OBJS_COMMON) -$(BIN) : $(ELF) +%.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))) diff --git a/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h index 472cbc961..176af3ae9 100644 --- a/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h +++ b/plat/rockchip/rk3399/drivers/m0/include/rk3399_mcu.h @@ -25,8 +25,6 @@ typedef unsigned int uint32_t; #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); diff --git a/plat/rockchip/rk3399/drivers/m0/src/dram.c b/plat/rockchip/rk3399/drivers/m0/src/dram.c index c6a9259d2..b939a9605 100644 --- a/plat/rockchip/rk3399/drivers/m0/src/dram.c +++ b/plat/rockchip/rk3399/drivers/m0/src/dram.c @@ -55,7 +55,7 @@ static void ddr_set_pll(void) mmio_write_32(CRU_BASE + CRU_DPLL_CON3, PLL_MODE(PLL_NORMAL_MODE)); } -void handle_dram(void) +__attribute__((noreturn)) void main(void) { mmio_setbits_32(PHY_REG(0, 927), (1 << 22)); mmio_setbits_32(PHY_REG(1, 927), (1 << 22)); @@ -76,4 +76,9 @@ void handle_dram(void) 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"); } diff --git a/plat/rockchip/rk3399/drivers/m0/src/main.c b/plat/rockchip/rk3399/drivers/m0/src/main.c deleted file mode 100644 index 0ed818d2f..000000000 --- a/plat/rockchip/rk3399/drivers/m0/src/main.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#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/plat/rockchip/rk3399/drivers/m0/src/startup.c b/plat/rockchip/rk3399/drivers/m0/src/startup.c index 68f5b2dce..dba031370 100644 --- a/plat/rockchip/rk3399/drivers/m0/src/startup.c +++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c @@ -7,7 +7,7 @@ #include "rk3399_mcu.h" /* Stack configuration */ -#define STACK_SIZE 0x00000100 +#define STACK_SIZE 0x00000040 __attribute__ ((section(".co_stack"))) unsigned long pstack[STACK_SIZE]; diff --git a/plat/rockchip/rk3399/drivers/m0/src/suspend.c b/plat/rockchip/rk3399/drivers/m0/src/suspend.c index af29a1114..39dfd1138 100644 --- a/plat/rockchip/rk3399/drivers/m0/src/suspend.c +++ b/plat/rockchip/rk3399/drivers/m0/src/suspend.c @@ -11,18 +11,52 @@ #define SCR_SLEEPDEEP_SHIFT (1 << 2) -void handle_suspend(void) +__attribute__((noreturn)) void 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); - return; + break; } } - /* m0 enter deep sleep mode */ - mmio_setbits_32(M0_SCR, SCR_SLEEPDEEP_SHIFT); + /* + * 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"); } diff --git a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c index 61849e500..3f258b789 100644 --- a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c +++ b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c @@ -21,14 +21,6 @@ void m0_init(void) mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7)); mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), WMSK_BIT(12)); - /* 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)); - /* document is wrong, PMU_CRU_GATEDIS_CON0 do not need set MASK BIT */ mmio_setbits_32(PMUCRU_BASE + PMUCRU_GATEDIS_CON0, 0x02); @@ -46,6 +38,17 @@ void m0_init(void) mmio_write_32(PMUCRU_BASE + PMUCRU_CLKGATE_CON2, WMSK_BIT(5)); } +void m0_configure_execute_addr(uintptr_t addr) +{ + /* set the execute address for M0 */ + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3), + BITS_WITH_WMASK((addr >> 12) & 0xffff, + 0xffff, 0)); + mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7), + BITS_WITH_WMASK((addr >> 28) & 0xf, + 0xf, 0)); +} + void m0_start(void) { /* enable clocks for M0 */ diff --git a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.h b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.h index b313ec6af..cb323c482 100644 --- a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.h +++ b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.h @@ -11,13 +11,18 @@ #define M0_BINCODE_BASE ((uintptr_t)rk3399m0_bin) #define M0_PARAM_ADDR (M0_BINCODE_BASE + PARAM_ADDR) +#define M0PMU_BINCODE_BASE ((uintptr_t)rk3399m0pmu_bin) /* pmu_fw.c */ extern char rk3399m0_bin[]; extern char rk3399m0_bin_end[]; +extern char rk3399m0pmu_bin[]; +extern char rk3399m0pmu_bin_end[]; + extern void m0_init(void); extern void m0_start(void); extern void m0_stop(void); extern void m0_wait_done(void); +extern void m0_configure_execute_addr(uintptr_t addr); #endif /* __M0_CTL_H__ */ diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index ed1ea8b63..04446d606 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -836,6 +836,7 @@ static void sys_slp_config(void) BIT_WITH_WMSK(PMU_CLR_GIC2_CORE_L_HW)); slp_mode_cfg = BIT(PMU_PWR_MODE_EN) | + BIT(PMU_WKUP_RST_EN) | BIT(PMU_INPUT_CLAMP_EN) | BIT(PMU_POWER_OFF_REQ_CFG) | BIT(PMU_CPU0_PD_EN) | @@ -853,7 +854,6 @@ static void sys_slp_config(void) BIT(PMU_DDRIO0_RET_DE_REQ) | BIT(PMU_DDRIO1_RET_EN) | BIT(PMU_DDRIO1_RET_DE_REQ) | - BIT(PMU_DDRIO_RET_HW_DE_REQ) | BIT(PMU_CENTER_PD_EN) | BIT(PMU_PERILP_PD_EN) | BIT(PMU_CLK_PERILP_SRC_GATE_EN) | @@ -1064,12 +1064,6 @@ static void resume_gpio(void) } } -static void m0_configure_suspend(void) -{ - /* set PARAM to M0_FUNC_SUSPEND */ - mmio_write_32(M0_PARAM_ADDR + PARAM_M0_FUNC, M0_FUNC_SUSPEND); -} - void sram_save(void) { size_t text_size = (char *)&__bl31_sram_text_real_end - @@ -1344,7 +1338,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) set_pmu_rsthold(); sys_slp_config(); - m0_configure_suspend(); + m0_configure_execute_addr(M0PMU_BINCODE_BASE); m0_start(); pmu_sgrf_rst_hld(); @@ -1374,7 +1368,7 @@ int rockchip_soc_sys_pwr_dm_suspend(void) mmio_setbits_32(PMU_BASE + PMU_PWRDN_CON, BIT(PMU_SCU_B_PWRDWN_EN)); wdt_register_save(); - secure_watchdog_disable(); + secure_watchdog_gate(); /* * Disabling PLLs/PWM/DVFS is approaching WFI which is @@ -1403,6 +1397,7 @@ int rockchip_soc_sys_pwr_dm_resume(void) plat_rockchip_restore_gpio(); cru_register_restore(); grf_register_restore(); + wdt_register_restore(); resume_uart(); resume_apio(); resume_gpio(); @@ -1412,10 +1407,8 @@ int rockchip_soc_sys_pwr_dm_resume(void) udelay(300); enable_dvfs_plls(); - secure_watchdog_enable(); secure_sgrf_init(); secure_sgrf_ddr_rgn_init(); - wdt_register_restore(); /* restore clk_ddrc_bpll_src_en gate */ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(3), @@ -1466,12 +1459,10 @@ int rockchip_soc_sys_pwr_dm_resume(void) udelay(1); } - pmu_sgrf_rst_hld_release(); pmu_scu_b_pwrup(); pmu_power_domains_resume(); restore_abpll(); - restore_pmu_rsthold(); clr_hw_idle(BIT(PMU_CLR_CENTER1) | BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_MSCH0) | diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c index d299116c6..a09ad21e8 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c @@ -5,9 +5,9 @@ */ /* convoluted way to make sure that the define is pasted just the right way */ -#define _INCBIN(file, sym) \ +#define _INCBIN(file, sym, sec) \ __asm__( \ - ".section .sram.incbin\n" \ + ".section " #sec "\n" \ ".global " #sym "\n" \ ".type " #sym ", %object\n" \ ".align 4\n" \ @@ -18,6 +18,7 @@ #sym "_end:\n" \ ) -#define INCBIN(file, sym) _INCBIN(file, sym) +#define INCBIN(file, sym, sec) _INCBIN(file, sym, sec) -INCBIN(RK3399M0FW, rk3399m0_bin); +INCBIN(RK3399M0FW, rk3399m0_bin, ".sram.incbin"); +INCBIN(RK3399M0PMUFW, rk3399m0pmu_bin, ".pmusram.incbin"); diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c index 589d833c8..1937b1380 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.c +++ b/plat/rockchip/rk3399/drivers/secure/secure.c @@ -77,7 +77,7 @@ static void sgrf_ddr_rgn_config(uint32_t rgn, BIT_WITH_WMSK(rgn)); } -void secure_watchdog_disable(void) +void secure_watchdog_gate(void) { /** * Disable CA53 and CM0 wdt pclk @@ -89,7 +89,7 @@ void secure_watchdog_disable(void) BIT_WITH_WMSK(PCLK_WDT_CM0_GATE_SHIFT)); } -void secure_watchdog_enable(void) +__pmusramfunc void secure_watchdog_ungate(void) { /** * Enable CA53 and CM0 wdt pclk diff --git a/plat/rockchip/rk3399/drivers/secure/secure.h b/plat/rockchip/rk3399/drivers/secure/secure.h index 334805d0d..8e80f2b92 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.h +++ b/plat/rockchip/rk3399/drivers/secure/secure.h @@ -95,8 +95,8 @@ #define PCLK_WDT_CM0_GATE_SHIFT 10 /* export secure operating APIs */ -void secure_watchdog_disable(void); -void secure_watchdog_enable(void); +void secure_watchdog_gate(void); +__pmusramfunc void secure_watchdog_ungate(void); void secure_timer_init(void); void secure_sgrf_init(void); void secure_sgrf_ddr_rgn_init(void); diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index 7dd0b72e2..741adde66 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -43,6 +43,9 @@ const unsigned char rockchip_power_domain_tree_desc[] = { /* sleep data for pll suspend */ static struct deepsleep_data_s slp_data; +/* sleep data that needs to be accessed from pmusram */ +__pmusramdata struct pmu_sleep_data pmu_slp_data; + static void set_pll_slow_mode(uint32_t pll_id) { if (pll_id == PPLL_ID) @@ -229,9 +232,9 @@ void set_pmu_rsthold(void) uint32_t rstnhold_cofig0; uint32_t rstnhold_cofig1; - slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE + + pmu_slp_data.pmucru_rstnhold_con0 = mmio_read_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0); - slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE + + pmu_slp_data.pmucru_rstnhold_con1 = mmio_read_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1); rstnhold_cofig0 = BIT_WITH_WMSK(PRESETN_NOC_PMU_HOLD) | BIT_WITH_WMSK(PRESETN_INTMEM_PMU_HOLD) | @@ -257,12 +260,33 @@ void set_pmu_rsthold(void) mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, rstnhold_cofig1); } -void restore_pmu_rsthold(void) +void pmu_sgrf_rst_hld(void) +{ + mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), + CRU_PMU_SGRF_RST_HOLD); +} + +/* + * When system reset in running state, we want the cpus to be reboot + * from maskrom (system reboot), + * the pmusgrf reset-hold bits needs to be released. + * When system wake up from system deep suspend, some soc will be reset + * when waked up, + * we want the bootcpu to be reboot from pmusram, + * the pmusgrf reset-hold bits needs to be held. + */ +__pmusramfunc void pmu_sgrf_rst_hld_release(void) +{ + mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), + CRU_PMU_SGRF_RST_RLS); +} + +__pmusramfunc void restore_pmu_rsthold(void) { mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON0, - slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK); + pmu_slp_data.pmucru_rstnhold_con0 | REG_SOC_WMSK); mmio_write_32(PMUCRU_BASE + PMUCRU_RSTNHOLD_CON1, - slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK); + pmu_slp_data.pmucru_rstnhold_con1 | REG_SOC_WMSK); } /** diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index 6100d9558..bc4193392 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -134,6 +134,9 @@ struct deepsleep_data_s { uint32_t plls_con[END_PLL_ID][PLL_CON_COUNT]; uint32_t cru_gate_con[CRU_GATE_COUNT]; uint32_t pmucru_gate_con[PMUCRU_GATE_COUNT]; +}; + +struct pmu_sleep_data { uint32_t pmucru_rstnhold_con0; uint32_t pmucru_rstnhold_con1; }; @@ -263,27 +266,6 @@ struct deepsleep_data_s { #define PMUCRU_GATEDIS_CON0 0x0130 #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), - * the pmusgrf reset-hold bits needs to be released. - * When system wake up from system deep suspend, some soc will be reset - * when waked up, - * we want the bootcpu to be reboot from pmusram, - * the pmusgrf reset-hold bits needs to be held. - */ -static inline void pmu_sgrf_rst_hld_release(void) -{ - mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), - CRU_PMU_SGRF_RST_RLS); -} - -static inline void pmu_sgrf_rst_hld(void) -{ - mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), - CRU_PMU_SGRF_RST_HOLD); -} - /* export related and operating SoC APIs */ void __dead2 soc_global_soft_reset(void); void disable_dvfs_plls(void); @@ -296,5 +278,7 @@ void clk_gate_con_save(void); void clk_gate_con_disable(void); void clk_gate_con_restore(void); void set_pmu_rsthold(void); -void restore_pmu_rsthold(void); +void pmu_sgrf_rst_hld(void); +__pmusramfunc void pmu_sgrf_rst_hld_release(void); +__pmusramfunc void restore_pmu_rsthold(void); #endif /* __SOC_H__ */ diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S index 85f4dc334..528c15002 100644 --- a/plat/rockchip/rk3399/include/plat.ld.S +++ b/plat/rockchip/rk3399/include/plat.ld.S @@ -77,14 +77,21 @@ SECTIONS ASSERT(. == ALIGN(64 * 1024), ".pmusram.entry request 64K aligned."); *(.pmusram.entry) + __bl31_pmusram_text_start = .; *(.pmusram.text) *(.pmusram.rodata) __bl31_pmusram_text_end = .; + + /* M0 start address request 4K align */ + . = ALIGN(4096); + __pmusram_incbin_start = .; + *(.pmusram.incbin) + __pmusram_incbin_end = .; + __bl31_pmusram_data_start = .; *(.pmusram.data) __bl31_pmusram_data_end = .; - } >PMUSRAM } diff --git a/plat/rockchip/rk3399/include/shared/m0_param.h b/plat/rockchip/rk3399/include/shared/m0_param.h index 3edbf89b7..044e797af 100644 --- a/plat/rockchip/rk3399/include/shared/m0_param.h +++ b/plat/rockchip/rk3399/include/shared/m0_param.h @@ -7,13 +7,6 @@ #ifndef __M0_PARAM_H__ #define __M0_PARAM_H__ -#ifndef __LINKER__ -enum { - M0_FUNC_SUSPEND = 0, - M0_FUNC_DRAM = 1, -}; -#endif /* __LINKER__ */ - #define PARAM_ADDR 0xc0 #define PARAM_M0_FUNC 0x00 diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 1997dfc48..fc386f05a 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -82,12 +82,15 @@ BUILD_M0 := ${BUILD_PLAT}/m0 RK3399M0FW=${BUILD_M0}/${PLAT_M0}.bin $(eval $(call add_define,RK3399M0FW)) +RK3399M0PMUFW=${BUILD_M0}/${PLAT_M0}pmu.bin +$(eval $(call add_define,RK3399M0PMUFW)) + HDCPFW=${RK_PLAT_SOC}/drivers/dp/hdcp.bin $(eval $(call add_define,HDCPFW)) # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin export CCACHE_EXTRAFILES -${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW) +${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW) ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW) ${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)