1 /* 2 * Copyright (c) 2022 Renesas Electronics Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/init.h> 8 #include <zephyr/linker/linker-defs.h> 9 #include <zephyr/logging/log.h> 10 #include <zephyr/sys/reboot.h> 11 #include <string.h> 12 #include <DA1469xAB.h> 13 #include <da1469x_clock.h> 14 #include <da1469x_otp.h> 15 #include <da1469x_pd.h> 16 #include <da1469x_pdc.h> 17 #include <da1469x_trimv.h> 18 #include <da1469x_sleep.h> 19 20 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); 21 22 #define REMAP_ADR0_QSPI 0x2 23 24 #define FLASH_REGION_SIZE_32M 0 25 #define FLASH_REGION_SIZE_16M 1 26 #define FLASH_REGION_SIZE_8M 2 27 #define FLASH_REGION_SIZE_4M 3 28 #define FLASH_REGION_SIZE_2M 4 29 #define FLASH_REGION_SIZE_1M 5 30 #define FLASH_REGION_SIZE_05M 6 31 #define FLASH_REGION_SIZE_025M 7 32 33 #if defined(CONFIG_BOOTLOADER_MCUBOOT) 34 #define MAGIC 0xaabbccdd 35 static uint32_t z_renesas_cache_configured; 36 #endif 37 sys_arch_reboot(int type)38void sys_arch_reboot(int type) 39 { 40 if (type == SYS_REBOOT_WARM) { 41 NVIC_SystemReset(); 42 } else if (type == SYS_REBOOT_COLD) { 43 if ((SYS_WDOG->WATCHDOG_REG & SYS_WDOG_WATCHDOG_REG_WDOG_VAL_NEG_Msk) == 0) { 44 /* Cannot write WATCHDOG_REG while WRITE_BUSY */ 45 while ((SYS_WDOG->WATCHDOG_REG & 46 SYS_WDOG_WATCHDOG_CTRL_REG_WRITE_BUSY_Msk) != 0) { 47 } 48 /* Write WATCHDOG_REG */ 49 SYS_WDOG->WATCHDOG_REG = BIT(SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Pos); 50 51 GPREG->RESET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk; 52 SYS_WDOG->WATCHDOG_CTRL_REG &= 53 ~SYS_WDOG_WATCHDOG_CTRL_REG_WDOG_FREEZE_EN_Msk; 54 } 55 /* Wait */ 56 for (;;) { 57 __NOP(); 58 } 59 } 60 } 61 62 #if defined(CONFIG_BOOTLOADER_MCUBOOT) z_renesas_configure_cache(void)63static void z_renesas_configure_cache(void) 64 { 65 uint32_t cache_start; 66 uint32_t region_size; 67 uint32_t reg_region_size; 68 uint32_t reg_cache_len; 69 70 if (z_renesas_cache_configured == MAGIC) { 71 return; 72 } 73 74 cache_start = (uint32_t)&_vector_start; 75 region_size = (uint32_t)&__rom_region_end - cache_start; 76 77 /* Disable cache before configuring it */ 78 CACHE->CACHE_CTRL2_REG = 0; 79 CRG_TOP->SYS_CTRL_REG &= ~CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk; 80 81 /* Disable MRM unit */ 82 CACHE->CACHE_MRM_CTRL_REG = 0; 83 CACHE->CACHE_MRM_TINT_REG = 0; 84 CACHE->CACHE_MRM_MISSES_THRES_REG = 0; 85 86 if (region_size > MB(16)) { 87 reg_region_size = FLASH_REGION_SIZE_32M; 88 } else if (region_size > MB(8)) { 89 reg_region_size = FLASH_REGION_SIZE_16M; 90 } else if (region_size > MB(4)) { 91 reg_region_size = FLASH_REGION_SIZE_8M; 92 } else if (region_size > MB(2)) { 93 reg_region_size = FLASH_REGION_SIZE_4M; 94 } else if (region_size > MB(1)) { 95 reg_region_size = FLASH_REGION_SIZE_2M; 96 } else if (region_size > KB(512)) { 97 reg_region_size = FLASH_REGION_SIZE_1M; 98 } else if (region_size > KB(256)) { 99 reg_region_size = FLASH_REGION_SIZE_05M; 100 } else { 101 reg_region_size = FLASH_REGION_SIZE_025M; 102 } 103 CACHE->CACHE_FLASH_REG = 104 (cache_start >> 16) << CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Pos | 105 ((cache_start & 0xffff) >> 2) << CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Pos | 106 reg_region_size << CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Pos; 107 108 reg_cache_len = CLAMP(reg_region_size / KB(64), 0, 0x1ff); 109 CACHE->CACHE_CTRL2_REG = (CACHE->CACHE_FLASH_REG & ~CACHE_CACHE_CTRL2_REG_CACHE_LEN_Msk) | 110 reg_cache_len; 111 112 /* Copy IVT from flash to start of RAM. 113 * It will be remapped at 0x0 so it can be used after SW Reset 114 */ 115 memcpy(&_image_ram_start, &_vector_start, 0x200); 116 117 /* Configure remapping */ 118 CRG_TOP->SYS_CTRL_REG = (CRG_TOP->SYS_CTRL_REG & ~CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Msk) | 119 CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk | 120 CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Msk | 121 REMAP_ADR0_QSPI; 122 123 z_renesas_cache_configured = MAGIC; 124 125 /* Trigger SW Reset to apply cache configuration */ 126 CRG_TOP->SYS_CTRL_REG |= CRG_TOP_SYS_CTRL_REG_SW_RESET_Msk; 127 } 128 #endif /* CONFIG_HAS_FLASH_LOAD_OFFSET */ 129 soc_reset_hook(void)130void soc_reset_hook(void) 131 { 132 #if defined(CONFIG_PM) 133 uint32_t *ivt; 134 #endif 135 136 #if defined(CONFIG_BOOTLOADER_MCUBOOT) 137 z_renesas_configure_cache(); 138 #endif 139 140 #if defined(CONFIG_PM) 141 /* IVT is always placed in reserved space at the start of RAM which 142 * is then remapped to 0x0 and retained. Generic reset handler is 143 * changed to custom routine since next time ARM core is reset we 144 * need to determine whether it was a regular reset or a wakeup from 145 * extended sleep and ARM core state needs to be restored. 146 */ 147 ivt = (uint32_t *)_image_ram_start; 148 ivt[1] = (uint32_t)da1469x_wakeup_handler; 149 #endif 150 } 151 152 /* defined in power.c */ 153 extern int renesas_da1469x_pm_init(void); 154 soc_early_init_hook(void)155void soc_early_init_hook(void) 156 { 157 /* Freeze watchdog until configured */ 158 GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk; 159 SYS_WDOG->WATCHDOG_REG = SYS_WDOG_WATCHDOG_REG_WDOG_VAL_Msk; 160 161 /* Reset clock dividers to 0 */ 162 CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk | 163 CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk); 164 165 CRG_TOP->PMU_CTRL_REG |= (CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Msk | 166 CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Msk | 167 CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Msk | 168 CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk); 169 170 #if defined(CONFIG_PM) 171 /* Enable cache retainability */ 172 CRG_TOP->PMU_CTRL_REG |= CRG_TOP_PMU_CTRL_REG_RETAIN_CACHE_Msk; 173 #endif 174 175 /* 176 * Due to crosstalk issues any power rail can potentially 177 * issue a fake event. This is typically observed upon 178 * switching power sources, that is DCDC <--> LDOs <--> Retention LDOs. 179 */ 180 CRG_TOP->BOD_CTRL_REG &= ~(CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Msk | 181 CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Msk | 182 CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Msk | 183 CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Msk | 184 CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Msk | 185 CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Msk | 186 CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Msk); 187 188 da1469x_otp_init(); 189 da1469x_trimv_init_from_otp(); 190 191 da1469x_pd_init(); 192 193 /* 194 * Take PD_SYS control. 195 */ 196 da1469x_pd_acquire(MCU_PD_DOMAIN_SYS); 197 da1469x_pd_acquire(MCU_PD_DOMAIN_TIM); 198 199 da1469x_pdc_reset(); 200 #if CONFIG_PM 201 renesas_da1469x_pm_init(); 202 #endif 203 } 204