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 <string.h>
10 #include <DA1469xAB.h>
11 #include <da1469x_clock.h>
12 #include <da1469x_otp.h>
13 #include <da1469x_pd.h>
14 #include <da1469x_pdc.h>
15 #include <da1469x_trimv.h>
16 #include <cmsis_core.h>
17 
18 #define REMAP_ADR0_QSPI           0x2
19 
20 #define FLASH_REGION_SIZE_32M     0
21 #define FLASH_REGION_SIZE_16M     1
22 #define FLASH_REGION_SIZE_8M      2
23 #define FLASH_REGION_SIZE_4M      3
24 #define FLASH_REGION_SIZE_2M      4
25 #define FLASH_REGION_SIZE_1M      5
26 #define FLASH_REGION_SIZE_05M     6
27 #define FLASH_REGION_SIZE_025M    7
28 
29 #if defined(CONFIG_BOOTLOADER_MCUBOOT)
30 #define MAGIC 0xaabbccdd
31 static uint32_t z_renesas_cache_configured;
32 #endif
33 
sys_arch_reboot(int type)34 void sys_arch_reboot(int type)
35 {
36 	ARG_UNUSED(type);
37 
38 	NVIC_SystemReset();
39 }
40 
41 #if defined(CONFIG_BOOTLOADER_MCUBOOT)
z_renesas_configure_cache(void)42 static void z_renesas_configure_cache(void)
43 {
44 	uint32_t cache_start;
45 	uint32_t region_size;
46 	uint32_t reg_region_size;
47 	uint32_t reg_cache_len;
48 
49 	if (z_renesas_cache_configured == MAGIC) {
50 		return;
51 	}
52 
53 	cache_start = (uint32_t)&_vector_start;
54 	region_size = (uint32_t)&__rom_region_end - cache_start;
55 
56 	/* Disable cache before configuring it */
57 	CACHE->CACHE_CTRL2_REG = 0;
58 	CRG_TOP->SYS_CTRL_REG &= ~CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk;
59 
60 	/* Disable MRM unit */
61 	CACHE->CACHE_MRM_CTRL_REG = 0;
62 	CACHE->CACHE_MRM_TINT_REG = 0;
63 	CACHE->CACHE_MRM_MISSES_THRES_REG = 0;
64 
65 	if (region_size > MB(16)) {
66 		reg_region_size = FLASH_REGION_SIZE_32M;
67 	} else if (region_size > MB(8)) {
68 		reg_region_size = FLASH_REGION_SIZE_16M;
69 	} else if (region_size > MB(4)) {
70 		reg_region_size = FLASH_REGION_SIZE_8M;
71 	} else if (region_size > MB(2)) {
72 		reg_region_size = FLASH_REGION_SIZE_4M;
73 	} else if (region_size > MB(1)) {
74 		reg_region_size = FLASH_REGION_SIZE_2M;
75 	} else if (region_size > KB(512)) {
76 		reg_region_size = FLASH_REGION_SIZE_1M;
77 	} else if (region_size > KB(256)) {
78 		reg_region_size = FLASH_REGION_SIZE_05M;
79 	} else {
80 		reg_region_size = FLASH_REGION_SIZE_025M;
81 	}
82 	CACHE->CACHE_FLASH_REG =
83 		(cache_start >> 16) << CACHE_CACHE_FLASH_REG_FLASH_REGION_BASE_Pos |
84 		((cache_start & 0xffff) >> 2) << CACHE_CACHE_FLASH_REG_FLASH_REGION_OFFSET_Pos |
85 		reg_region_size << CACHE_CACHE_FLASH_REG_FLASH_REGION_SIZE_Pos;
86 
87 	reg_cache_len = CLAMP(reg_region_size / KB(64), 0, 0x1ff);
88 	CACHE->CACHE_CTRL2_REG = (CACHE->CACHE_FLASH_REG & ~CACHE_CACHE_CTRL2_REG_CACHE_LEN_Msk) |
89 				 reg_cache_len;
90 
91 	/* Copy IVT from flash to start of RAM.
92 	 * It will be remapped at 0x0 so it can be used after SW Reset
93 	 */
94 	memcpy(&_image_ram_start, &_vector_start, 0x200);
95 
96 	/* Configure remapping */
97 	CRG_TOP->SYS_CTRL_REG = (CRG_TOP->SYS_CTRL_REG & ~CRG_TOP_SYS_CTRL_REG_REMAP_ADR0_Msk) |
98 				CRG_TOP_SYS_CTRL_REG_CACHERAM_MUX_Msk |
99 				CRG_TOP_SYS_CTRL_REG_REMAP_INTVECT_Msk |
100 				REMAP_ADR0_QSPI;
101 
102 	z_renesas_cache_configured = MAGIC;
103 
104 	/* Trigger SW Reset to apply cache configuration */
105 	CRG_TOP->SYS_CTRL_REG |= CRG_TOP_SYS_CTRL_REG_SW_RESET_Msk;
106 }
107 #endif /* CONFIG_HAS_FLASH_LOAD_OFFSET */
108 
z_arm_platform_init(void)109 void z_arm_platform_init(void)
110 {
111 #if defined(CONFIG_BOOTLOADER_MCUBOOT)
112 	z_renesas_configure_cache();
113 #endif
114 }
115 
renesas_da1469x_init(void)116 static int renesas_da1469x_init(void)
117 {
118 	/* Freeze watchdog until configured */
119 	GPREG->SET_FREEZE_REG = GPREG_SET_FREEZE_REG_FRZ_SYS_WDOG_Msk;
120 
121 	/* Reset clock dividers to 0 */
122 	CRG_TOP->CLK_AMBA_REG &= ~(CRG_TOP_CLK_AMBA_REG_HCLK_DIV_Msk |
123 				CRG_TOP_CLK_AMBA_REG_PCLK_DIV_Msk);
124 
125 	CRG_TOP->PMU_CTRL_REG |= (CRG_TOP_PMU_CTRL_REG_TIM_SLEEP_Msk   |
126 				CRG_TOP_PMU_CTRL_REG_PERIPH_SLEEP_Msk  |
127 				CRG_TOP_PMU_CTRL_REG_COM_SLEEP_Msk     |
128 				CRG_TOP_PMU_CTRL_REG_RADIO_SLEEP_Msk);
129 
130 	/* PDC should take care of PD_SYS */
131 	CRG_TOP->PMU_CTRL_REG &= ~CRG_TOP_PMU_CTRL_REG_SYS_SLEEP_Msk;
132 
133 	/*
134 	 *	Due to crosstalk issues any power rail can potentially
135 	 *	issue a fake event. This is typically observed upon
136 	 *	switching power sources, that is DCDC <--> LDOs <--> Retention LDOs.
137 	 */
138 	CRG_TOP->BOD_CTRL_REG &= ~(CRG_TOP_BOD_CTRL_REG_BOD_V14_EN_Msk |
139 				CRG_TOP_BOD_CTRL_REG_BOD_V18F_EN_Msk   |
140 				CRG_TOP_BOD_CTRL_REG_BOD_VDD_EN_Msk    |
141 				CRG_TOP_BOD_CTRL_REG_BOD_V18P_EN_Msk   |
142 				CRG_TOP_BOD_CTRL_REG_BOD_V18_EN_Msk    |
143 				CRG_TOP_BOD_CTRL_REG_BOD_V30_EN_Msk    |
144 				CRG_TOP_BOD_CTRL_REG_BOD_VBAT_EN_Msk);
145 
146 	da1469x_pdc_reset();
147 
148 	da1469x_otp_init();
149 	da1469x_trimv_init_from_otp();
150 
151 	da1469x_pd_init();
152 	da1469x_pd_acquire(MCU_PD_DOMAIN_SYS);
153 	da1469x_pd_acquire(MCU_PD_DOMAIN_TIM);
154 	da1469x_pd_acquire(MCU_PD_DOMAIN_COM);
155 
156 	return 0;
157 }
158 
159 SYS_INIT(renesas_da1469x_init, PRE_KERNEL_1, 0);
160