1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2023 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #ifdef SDK_OS_FREE_RTOS
10 #include "FreeRTOS.h"
11 #include "task.h"
12 #endif
13 #include "fsl_common.h"
14 #include "fsl_debug_console.h"
15 #include "board.h"
16 #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
17 #include "fsl_lpi2c.h"
18 #endif /* SDK_I2C_BASED_COMPONENT_USED */
19 #include "fsl_lpuart.h"
20 #include "fsl_flexspi.h"
21 #include "fsl_upower.h"
22 #include "fsl_sentinel.h"
23 #include "fsl_reset.h"
24 #include "fsl_cache.h"
25 #if defined(BOARD_USE_TPM) && BOARD_USE_TPM
26 #include "fsl_tpm.h"
27 #endif /* BOARD_USE_TPM */
28 #if defined(BOARD_USE_PCA6416A) && BOARD_USE_PCA6416A
29 #include "fsl_pca6416a.h"
30 #endif /* BOARD_USE_PCA6416A */
31 #include "fsl_trdc.h"
32 #include "fsl_mu.h"
33
34 /*******************************************************************************
35 * Definitions
36 ******************************************************************************/
37 bool dram_auto_lp_true = false;
38 uint32_t dram_ctl_143;
39 struct dram_cfg *dram_timing_cfg;
40 uint32_t dram_class;
41 /*******************************************************************************
42 * Variables
43 ******************************************************************************/
44 static uint32_t mrc_start_addr[2] = {0x4000000, 0x40000000};
45 static uint32_t mrc_end_addr[2] = {0xC000000, 0x50000000};
46
47 /* Boot Type Name(enum BOOT_TYPE) */
48 static const char *s_bootTypeNames[] = {"Single Boot Type", "Dual Boot Type", "Low Power Boot Type"};
49
50 /* TRDC */
51 static bool releasedTrdc =
52 false; /* set a flag to check whether released TRDC(whether change owner of TRDC from sentinel to m33) */
53 /* These apis from uboot source code[drivers/misc/sentinel/fuse.c] */
54 struct fsb_map_entry
55 {
56 int32_t fuse_bank;
57 uint32_t fuse_words;
58 bool redundancy;
59 };
60
61 /* Register context for LPAV FSB FUSE */
62 const struct fsb_map_entry fsb_mapping_table[] = {
63 {3, 8}, {4, 8}, {-1, 48}, /* Reserve 48 words */
64 {5, 8}, {6, 8}, {8, 4, true}, {24, 4, true}, {26, 4, true}, {27, 4, true}, {28, 8}, {29, 8}, {30, 8}, {31, 8},
65 {37, 8}, {38, 8}, {39, 8}, {40, 8}, {41, 8}, {42, 8}, {43, 8}, {44, 8}, {45, 8}, {46, 8},
66 };
67
68 /* Register context for LPAV CGC2 */
69 static uint32_t cgc2[][2] = {
70 {0x2da60014, 0x08004000}, {0x2da60020, 0x0}, {0x2da6003c, 0x18004180}, {0x2da60040, 0x48200000},
71 {0x2da60108, 0x00808080}, {0x2da60208, 0x00808080}, {0x2da60900, 0x0}, {0x2da60904, 0x0},
72 {0x2da60908, 0x0}, {0x2da60910, 0x0}, {0x2da60a00, 0x0},
73 };
74
75 /* Register context for LPAV PLL4 */
76 static uint32_t pll4[][2] = {
77 {0x2da60604, 0x80}, {0x2da60608, 0x80808081}, {0x2da6060c, 0x808080C0}, {0x2da60610, 0x00160000},
78 {0x2da60618, 0x00000001}, {0x2da6061c, 0x0}, {0x2da60620, 0x0}, {0x2da60624, 0x00001300},
79 {0x2da60600, 0x03000001}, {0x2da68614, 0xD8DE5ECC},
80 };
81
82 /* Register context for LPAV PCC5 part 1 */
83 static uint32_t pcc5_0[][2] = {
84 {0x2da70000, 0xC0000000}, {0x2da70004, 0x80000000}, {0x2da70008, 0x80000000}, {0x2da7000c, 0x80000000},
85 {0x2da70010, 0x80000000}, {0x2da70014, 0x80000000}, {0x2da70018, 0x80000000}, {0x2da7001c, 0x80000000},
86 {0x2da70020, 0x80000000}, {0x2da70024, 0x80000000}, {0x2da70028, 0x80000000}, {0x2da7002c, 0x80000000},
87 {0x2da70030, 0x80000000}, {0x2da70034, 0x80000000}, {0x2da70038, 0x80000000}, {0x2da7003c, 0x80000000},
88 {0x2da70040, 0x80000000}, {0x2da70044, 0x80000000}, {0x2da70048, 0x80000000}, {0x2da7004c, 0x80000000},
89 {0x2da70050, 0x80000000}, {0x2da70054, 0x80000000}, {0x2da70058, 0x80000000}, {0x2da7005c, 0x80000000},
90 {0x2da70060, 0x80000000}, {0x2da70064, 0x80000000}, {0x2da70068, 0x80000000}, {0x2da7006c, 0x80000000},
91 {0x2da70070, 0x80000000}, {0x2da70074, 0x80000000}, {0x2da70078, 0x80000000}, {0x2da7007c, 0x80000000},
92 {0x2da70080, 0x80000000}
93
94 };
95
96 /* Register context for LPAV PCC5 part 2 */
97 static uint32_t pcc5_1[][2] = {
98 {0x2da70084, 0x80000000}, {0x2da70088, 0x80000000}, {0x2da7008c, 0x80000000}, {0x2da700a0, 0x80000000},
99 {0x2da700a4, 0x80000000}, {0x2da700a8, 0x80000000}, {0x2da700ac, 0x80000000}, {0x2da700b0, 0x90000000},
100 {0x2da700b4, 0x80000000}, {0x2da700bc, 0x80000000}, {0x2da700c0, 0x81000005}, {0x2da700c8, 0x90400000},
101 {0x2da700cc, 0x80000000}, {0x2da700d0, 0x90000000}, {0x2da700f0, 0x92000000}, {0x2da700f4, 0x92000000},
102 {0x2da700f8, 0x97000005}, {0x2da70108, 0xD0000000}, {0x2da7010c, 0x80000000}, {0x2da70110, 0x80000000},
103 {0x2da70114, 0xC0000000},
104 };
105
106 /* Register context for LPAV SIM */
107 static uint32_t lpav_sim[][2] = {
108 {0x2da50000, 0x0}, {0x2da50004, 0x0}, {0x2da50008, 0x02112002}, {0x2da5001c, 0x0},
109 {0x2da50020, 0x0}, {0x2da50024, 0x0}, {0x2da50034, 0xFFFFFFFF},
110 };
111
112 /* DDR PHY register index for frequency diff */
113 static uint32_t freq_specific_reg_array[PHY_DIFF_NUM] = {
114 90, 92, 93, 96, 97, 100, 101, 102, 103, 104, 114, 346, 348, 349, 352, 353, 356,
115 357, 358, 359, 360, 370, 602, 604, 605, 608, 609, 612, 613, 614, 615, 616, 626, 858,
116 860, 861, 864, 865, 868, 869, 870, 871, 872, 882, 1063, 1319, 1566, 1624, 1625};
117
118 /*******************************************************************************
119 * Code
120 ******************************************************************************/
121 /* Initialize debug console. */
BOARD_InitDebugConsole(void)122 void BOARD_InitDebugConsole(void)
123 {
124 uint32_t uartClkSrcFreq;
125
126 CLOCK_SetIpSrc(BOARD_DEBUG_UART_IP_NAME, BOARD_DEBUG_UART_CLKSRC);
127 uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
128 RESET_PeripheralReset(BOARD_DEBUG_UART_RESET);
129
130 DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
131 }
132
133 /*
134 * check fusion whether available
135 * return:
136 * true: fusion is not available
137 * false: fusion is available
138 */
BOARD_IsFusionAvailable(void)139 bool BOARD_IsFusionAvailable(void)
140 {
141 return (!(SIM_SEC->SYSCTRL0 & SIM_SEC_SYSCTRL0_FUSION_DSP_RST_MASK));
142 }
143
BOARD_DumpRegs(uint32_t start_reg_addr,uint32_t end_reg_addr)144 void BOARD_DumpRegs(uint32_t start_reg_addr, uint32_t end_reg_addr)
145 {
146 #if BOARD_ENABLE_DUMP_REGS
147 uint32_t i = 0U;
148
149 for (i = start_reg_addr; i <= end_reg_addr; i += 4)
150 {
151 PRINTF("Reg 0x%x: Val = 0x%x\r\n", i, *(uint32_t *)i);
152 }
153 #endif // BOARD_ENABLE_DUMP_REGS
154 }
155
BOARD_DumpRTDRegs(void)156 void BOARD_DumpRTDRegs(void)
157 {
158 PRINTF("DUMP SIM_SEM_RTD:r\n");
159 PRINTF("* GPR0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b000)));
160 PRINTF("* GPR1 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b004)));
161 PRINTF("* DGO_CTRL0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b008)));
162 PRINTF("* DGO_CTRL1 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b00c)));
163 PRINTF("* DGO_GP0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b010)));
164 PRINTF("* DGO_GP1 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b014)));
165 PRINTF("* DGO_GP2 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b018)));
166 PRINTF("* DGO_GP3 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b01c)));
167 PRINTF("* DGO_GP4 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b020)));
168 PRINTF("* DGO_GP5 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b024)));
169 PRINTF("* DGO_GP6 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b028)));
170 PRINTF("* DGO_GP7 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b02c)));
171 PRINTF("* DGO_GP8 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b030)));
172 PRINTF("* DGO_GP9 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b034)));
173 PRINTF("* DGO_GP10 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b038)));
174 PRINTF("* DGO_GP11 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b03c)));
175 PRINTF("* DGO_GP12 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b040)));
176 PRINTF("* SYSCTRL0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b044)));
177 PRINTF("* SSRAM_ACCESS_DISABLE = 0x%x\r\n", *((volatile uint32_t *)(0x2802b048)));
178 PRINTF("* LPAV_MASTER_ALLOC_CTRL = 0x%x\r\n", *((volatile uint32_t *)(0x2802b04c)));
179 PRINTF("* LPAV_SLAVE_ALLOC_CTRL = 0x%x\r\n", *((volatile uint32_t *)(0x2802b050)));
180 PRINTF("* LPAV_DMA2_CH_ALLOC_CTRL = 0x%x\r\n", *((volatile uint32_t *)(0x2802b054)));
181 PRINTF("* LPAV_DMA2_REQ_ALLOC_CTRL = 0x%x\r\n", *((volatile uint32_t *)(0x2802b058)));
182 PRINTF("* M33_CFGSSTCALIB = 0x%x\r\n", *((volatile uint32_t *)(0x2802b05c)));
183 PRINTF("* FUSION_GPR0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b060)));
184 PRINTF("* FUSION_GPR1 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b064)));
185 PRINTF("* FUSION_GPR2 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b068)));
186 PRINTF("* RTD_INTERRUPT_MASK0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b06c)));
187 PRINTF("* APD_INTERRUPT_MASK0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b070)));
188 PRINTF("* AVD_INTERRUPT_MASK0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802b074)));
189 PRINTF("* WRITE_ASSIST_CTR = 0x%x\r\n", *((volatile uint32_t *)(0x2802b078)));
190
191 PRINTF("DUMP CGC0:r\n");
192 PRINTF("* CGC0.CM33CLK = 0x%x\r\n", *((volatile uint32_t *)(0x2802f010)));
193 PRINTF("* CGC0.FUSIONCLK = 0x%x\r\n", *((volatile uint32_t *)(0x2802f01c)));
194 PRINTF("* CGC0.CLKOUTCFG = 0x%x\r\n", *((volatile uint32_t *)(0x2802f020)));
195 PRINTF("* CGC0.SOSCCSR = 0x%x\r\n", *((volatile uint32_t *)(0x2802f104)));
196 PRINTF("* CGC0.SOSCDIV = 0x%x\r\n", *((volatile uint32_t *)(0x2802f108)));
197 PRINTF("* CGC0.FROCSR = 0x%x\r\n", *((volatile uint32_t *)(0x2802f200)));
198 PRINTF("* CGC0.LPOSCCSR = 0x%x\r\n", *((volatile uint32_t *)(0x2802f304)));
199 PRINTF("* CGC0.PLL0CSR = 0x%x\r\n", *((volatile uint32_t *)(0x2802f500)));
200 PRINTF("* CGC0.PLL0DIV_VCO = 0x%x\r\n", *((volatile uint32_t *)(0x2802f504)));
201 PRINTF("* CGC0.PLL0DIV_PFD_0 = 0x%x\r\n", *((volatile uint32_t *)(0x2802f508)));
202 PRINTF("* CGC0.PLL0CFG = 0x%x\r\n", *((volatile uint32_t *)(0x2802f510)));
203 PRINTF("* CGC0.PLL0PFDCFG = 0x%x\r\n", *((volatile uint32_t *)(0x2802f514)));
204 PRINTF("* CGC0.PLL1CSR = 0x%x\r\n", *((volatile uint32_t *)(0x2802f600)));
205
206 PRINTF("DUMP CMC0:r\n");
207 PRINTF("* CMC0.CKCTRL = 0x%x\r\n", *((volatile uint32_t *)(0x28025010)));
208 PRINTF("* CMC0.PMPROT = 0x%x\r\n", *((volatile uint32_t *)(0x28025018)));
209 PRINTF("* CMC0.PMCTRL = 0x%x\r\n", *((volatile uint32_t *)(0x28025020)));
210 PRINTF("* CMC0.SRS = 0x%x\r\n", *((volatile uint32_t *)(0x28025080)));
211 PRINTF("* CMC0.SSRS = 0x%x\r\n", *((volatile uint32_t *)(0x28025088)));
212 PRINTF("* CMC0.SRIE = 0x%x\r\n", *((volatile uint32_t *)(0x2802508c)));
213 PRINTF("* CMC0.SRIF = 0x%x\r\n", *((volatile uint32_t *)(0x28025090)));
214 PRINTF("* CMC0.MR0 = 0x%x\r\n", *((volatile uint32_t *)(0x280250a0)));
215 PRINTF("* CMC0.CORECTL = 0x%x\r\n", *((volatile uint32_t *)(0x28025110)));
216 PRINTF("* CMC0.DBGCTL = 0x%x\r\n", *((volatile uint32_t *)(0x28025120)));
217
218 PRINTF("DUMP WUU0:r\n");
219 PRINTF("* WUU0_VERID = 0x%x\r\n", *((volatile uint32_t *)(0x28028000)));
220 PRINTF("* WUU0_PARAM = 0x%x\r\n", *((volatile uint32_t *)(0x28028004)));
221 PRINTF("* WUU0_PE1 = 0x%x\r\n", *((volatile uint32_t *)(0x28028008)));
222 PRINTF("* WUU0_PE2 = 0x%x\r\n", *((volatile uint32_t *)(0x2802800c)));
223 PRINTF("* WUU0_ME = 0x%x\r\n", *((volatile uint32_t *)(0x28028018)));
224 PRINTF("* WUU0_DE = 0x%x\r\n", *((volatile uint32_t *)(0x2802801c)));
225 PRINTF("* WUU0_PF = 0x%x\r\n", *((volatile uint32_t *)(0x28028020)));
226 PRINTF("* WUU0_MF = 0x%x\r\n", *((volatile uint32_t *)(0x28028028)));
227 PRINTF("* WUU0_FILT = 0x%x\r\n", *((volatile uint32_t *)(0x28028030)));
228 PRINTF("* WUU0_PDC1 = 0x%x\r\n", *((volatile uint32_t *)(0x28028038)));
229 PRINTF("* WUU0_PDC2 = 0x%x\r\n", *((volatile uint32_t *)(0x2802803c)));
230 PRINTF("* WUU0_FDC = 0x%x\r\n", *((volatile uint32_t *)(0x28028048)));
231 PRINTF("* WUU0_PMC = 0x%x\r\n", *((volatile uint32_t *)(0x28028050)));
232 PRINTF("* WUU0_FMC = 0x%x\r\n", *((volatile uint32_t *)(0x28028058)));
233 }
234
235 /* TRDC */
BOARD_GetReleaseFlagOfTrdc(void)236 bool BOARD_GetReleaseFlagOfTrdc(void)
237 {
238 return releasedTrdc;
239 }
240
BOARD_SetReleaseFlagOfTrdc(bool flag)241 void BOARD_SetReleaseFlagOfTrdc(bool flag)
242 {
243 if (releasedTrdc != flag)
244 releasedTrdc = flag;
245 }
246
BOARD_MapFsbFuseIndex(uint32_t bank,uint32_t word,bool * redundancy)247 static uint32_t BOARD_MapFsbFuseIndex(uint32_t bank, uint32_t word, bool *redundancy)
248 {
249 int32_t size = ARRAY_SIZE(fsb_mapping_table);
250 int32_t i, word_pos = 0;
251
252 /* map the fuse from ocotp fuse map to FSB*/
253 for (i = 0; i < size; i++)
254 {
255 if (fsb_mapping_table[i].fuse_bank != -1 && fsb_mapping_table[i].fuse_bank == bank &&
256 fsb_mapping_table[i].fuse_words > word)
257 {
258 break;
259 }
260
261 word_pos += fsb_mapping_table[i].fuse_words;
262 }
263
264 if (i == size)
265 return -1; /* Failed to find */
266
267 if (fsb_mapping_table[i].redundancy)
268 {
269 *redundancy = true;
270 return (word >> 1) + word_pos;
271 }
272
273 *redundancy = false;
274 return word + word_pos;
275 }
276
277 /*
278 * return:
279 * 0: success
280 * -1: error
281 */
BOARD_FuseRead(uint32_t bank,uint32_t word,uint32_t * val)282 int32_t BOARD_FuseRead(uint32_t bank, uint32_t word, uint32_t *val)
283 {
284 int32_t word_index = -1;
285 bool redundancy = false;
286 int32_t ret = -1;
287
288 if (bank >= FUSE_BANKS || word >= FUSE_WORDS_PER_BANKS || !val)
289 {
290 return ret;
291 }
292
293 word_index = BOARD_MapFsbFuseIndex(bank, word, &redundancy);
294 if (word_index >= 0)
295 {
296 *val = *(uint32_t *)(FSB_BASE_ADDR + FSB_OTP_SHADOW + (word_index << 2));
297 if (redundancy)
298 {
299 *val = (*val >> ((word % 2) * 16)) & 0xFFFF;
300 }
301 ret = 0;
302 }
303 return ret;
304 }
305
BOARD_GetMpuSpeedGradeHz(void)306 static uint32_t BOARD_GetMpuSpeedGradeHz(void)
307 {
308 int ret;
309 uint32_t val;
310 uint32_t speed = MHZ(800);
311
312 ret = BOARD_FuseRead(3, 1, &val);
313 if (!ret)
314 {
315 val >>= 14;
316 val &= 0x3;
317
318 switch (val)
319 {
320 case 0x1:
321 speed = MHZ(900); /* 900Mhz*/
322 break;
323 default:
324 speed = MHZ(800); /* 800Mhz*/
325 }
326 }
327 return speed;
328 }
329
BOARD_GetSocVariantType(void)330 uint32_t BOARD_GetSocVariantType(void)
331 {
332 static uint32_t soc_type = 0;
333 uint32_t val;
334 int ret;
335
336 if (soc_type == 0)
337 {
338 soc_type = MPU_SOC_IMX8ULP;
339 ret = BOARD_FuseRead(3, 2, &val);
340 if (!ret)
341 {
342 bool epdc_disable = !!(val & BIT(23));
343 bool core1_disable = !!(val & BIT(15));
344 bool gpu_disable = false;
345 bool a35_900mhz = (BOARD_GetMpuSpeedGradeHz() == MHZ(900));
346
347 if ((val & (BIT(18) | BIT(19))) == (BIT(18) | BIT(19)))
348 gpu_disable = true;
349
350 if (epdc_disable && gpu_disable)
351 soc_type = core1_disable ? (soc_type + 4) : (soc_type + 3);
352 else if (epdc_disable && a35_900mhz)
353 soc_type = MPU_SOC_IMX8ULPSC;
354 else if (epdc_disable)
355 soc_type = core1_disable ? (soc_type + 2) : (soc_type + 1);
356 }
357 }
358
359 return soc_type;
360 }
361
BOARD_IsIpDisabled(ip_type_e type)362 bool BOARD_IsIpDisabled(ip_type_e type)
363 {
364 uint32_t soc_type;
365 bool result = false;
366
367 soc_type = BOARD_GetSocVariantType();
368 switch (type)
369 {
370 case IP_EPDC:
371 if (soc_type != MPU_SOC_IMX8ULP)
372 {
373 result = true; /* epdc is disabled */
374 }
375 break;
376 case IP_GPU:
377 if (soc_type == MPU_SOC_IMX8ULPD3 && soc_type == MPU_SOC_IMX8ULPS3)
378 {
379 result = true; /* gpu is disabled */
380 }
381 break;
382 case IP_MPU1:
383 if (soc_type == MPU_SOC_IMX8ULPS5 || soc_type == MPU_SOC_IMX8ULPS3)
384 {
385 result = true; /* a35_1 is disabled */
386 }
387 break;
388 default:
389 PRINTF("Not support the type 0x%x\r\n", type);
390 break;
391 }
392
393 return result;
394 }
395
396 /*
397 * RDC will be enabled defaultly when DBD_EN is fused.
398 * return:
399 * true: RDC is enabled
400 * false: RDC is not enabled
401 */
BOARD_IsRdcEnabled(void)402 bool BOARD_IsRdcEnabled(void)
403 {
404 static bool rdc_en = true; /* Default assume DBD_EN is set */
405 int32_t ret = -1;
406 static bool read_dbd_en_from_fuse = false;
407 uint32_t val = 0;
408
409 /* Read DBD_EN fuse */
410 if (read_dbd_en_from_fuse == false)
411 {
412 ret = BOARD_FuseRead(8, 1, &val);
413 if (!ret)
414 {
415 rdc_en = !!(val & 0x200); /* Only A1 sillicon uses DBD_EN */
416 read_dbd_en_from_fuse = true;
417 }
418 }
419 return rdc_en;
420 }
421
BOARD_ReleaseTRDC(void)422 void BOARD_ReleaseTRDC(void)
423 {
424 uint32_t status;
425 if ((releasedTrdc == false) && (BOARD_IsRdcEnabled() == true))
426 {
427 /* Release TRDC(transfer owner of TRDC from s400 to m33) */
428 status = SENTINEL_ReleaseRDC(TRDC_TYPE);
429 if (status == BASELINE_SUCCESS_IND)
430 {
431 releasedTrdc = true;
432 }
433 }
434 }
435
BOARD_SetTrdcGlobalConfig(void)436 void BOARD_SetTrdcGlobalConfig(void)
437 {
438 uint32_t i = 0, j = 0, m = 0, n = 0;
439 trdc_mbc_memory_block_config_t mbcBlockConfig;
440 trdc_mrc_region_descriptor_config_t mrcRegionConfig;
441 trdc_slave_memory_hardware_config_t mbcHwConfig;
442
443 BOARD_ReleaseTRDC();
444 if (releasedTrdc == true)
445 {
446 /* Ungate TRDC MRC, MBC and DAC PCC */
447 TRDC_Init(TRDC);
448
449 /* 1. Get the hardware configuration of the TRDC module */
450 trdc_hardware_config_t hwConfig;
451 TRDC_GetHardwareConfig(TRDC, &hwConfig);
452
453 /* 2. Set control policies for MRC and MBC access control configuration registers */
454 trdc_memory_access_control_config_t memAccessConfig;
455 (void)memset(&memAccessConfig, 0, sizeof(memAccessConfig));
456 #if 0
457 /* Disable all access modes for MBC and MRC access control configuration register 1-7. */
458 for (i = 0U; i < hwConfig.mbcNumber; i++)
459 {
460 for (j = 1U; j < 8U; j++)
461 {
462 TRDC_MbcSetMemoryAccessConfig(TRDC, &memAccessConfig, i, j);
463 }
464 }
465
466 for (i = 0U; i < hwConfig.mrcNumber; i++)
467 {
468 for (j = 1U; j < 8U; j++)
469 {
470 TRDC_MrcSetMemoryAccessConfig(TRDC, &memAccessConfig, i, j);
471 }
472 }
473 #endif
474
475 #if 1
476 /* Enable all access modes for MRC access control configuration register 0. */
477 memAccessConfig.nonsecureUsrX = 1U;
478 memAccessConfig.nonsecureUsrW = 1U;
479 memAccessConfig.nonsecureUsrR = 1U;
480 memAccessConfig.nonsecurePrivX = 1U;
481 memAccessConfig.nonsecurePrivW = 1U;
482 memAccessConfig.nonsecurePrivR = 1U;
483 memAccessConfig.secureUsrX = 1U;
484 memAccessConfig.secureUsrW = 1U;
485 memAccessConfig.secureUsrR = 1U;
486 memAccessConfig.securePrivX = 1U;
487 memAccessConfig.securePrivW = 1U;
488 memAccessConfig.securePrivR = 1U;
489
490 for (i = 0U; i < hwConfig.mrcNumber; i++)
491 {
492 TRDC_MrcSetMemoryAccessConfig(TRDC, &memAccessConfig, i, TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX);
493 }
494
495 for (i = 0U; i < hwConfig.mbcNumber && i < TRDC_MBC_INDEX_NUM; i++)
496 {
497 if ((i == TRDC_MBC3_INDEX) &&
498 (BOARD_IsFusionAvailable() == false)) /* skip T-MBC3 if Fusion is not available */
499 {
500 continue;
501 }
502 TRDC_MbcSetMemoryAccessConfig(TRDC, &memAccessConfig, i, TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX);
503 }
504
505 /* 3. Set the configuration for all MRC regions */
506 (void)memset(&mrcRegionConfig, 0, sizeof(mrcRegionConfig));
507 mrcRegionConfig.memoryAccessControlSelect = TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX;
508 mrcRegionConfig.valid = true;
509 mrcRegionConfig.nseEnable = false; /* secure state can access the region */
510
511 for (i = 0; i < hwConfig.mrcNumber; i++)
512 {
513 mrcRegionConfig.mrcIdx = i;
514 for (j = 0; j < hwConfig.domainNumber; j++)
515 {
516 mrcRegionConfig.domainIdx = j;
517 /* Get region number for current MRC instance */
518 n = TRDC_GetMrcRegionNumber(TRDC, i);
519
520 /*__IO uint32_t MRC_DOM0_RGD_W[8][2]; n do not more than 8 (coverity check)*/
521 if (n > 8)
522 {
523 return;
524 }
525
526 for (m = 0U; m < n; m++)
527 {
528 mrcRegionConfig.regionIdx = m;
529 mrcRegionConfig.startAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * m;
530 mrcRegionConfig.endAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * (m + 1U);
531
532 TRDC_MrcSetRegionDescriptorConfig(TRDC, &mrcRegionConfig);
533 }
534 }
535 }
536
537 /* 4. Set the configuration for all MBC slave memory blocks */
538 (void)memset(&mbcBlockConfig, 0, sizeof(mbcBlockConfig));
539 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
540 mbcBlockConfig.nseEnable = false; /* secure state can access the region */
541
542 for (i = 0U; i < hwConfig.mbcNumber && i < TRDC_MBC_INDEX_NUM; i++)
543 {
544 if ((i == TRDC_MBC3_INDEX) &&
545 (BOARD_IsFusionAvailable() == false)) /* skip T-MBC3 if Fusion is not available */
546 {
547 continue;
548 }
549 mbcBlockConfig.mbcIdx = i;
550 for (j = 0U; j < hwConfig.domainNumber; j++)
551 {
552 mbcBlockConfig.domainIdx = j;
553 for (m = 0U; m < 4; m++)
554 {
555 TRDC_GetMbcHardwareConfig(TRDC, &mbcHwConfig, i, m);
556 if (mbcHwConfig.blockNum == 0U)
557 {
558 break;
559 }
560 mbcBlockConfig.slaveMemoryIdx = m;
561 for (n = 0U; n < mbcHwConfig.blockNum; n++)
562 {
563 mbcBlockConfig.memoryBlockIdx = n;
564
565 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
566 }
567 }
568 }
569 }
570 #endif
571
572 /* for DMA1, USB0, USB1, ENET, UDSHC0, USDHC1, UDSHC2, CAMM Master(default domain id is 1), default TRDC
573 * configuration */
574 /* non secure state can access Pbridge1(MBC2_MEM1) for DMA1, USB0, USB1, ENET, UDSHC0, USDHC1, UDSHC2, CAMM
575 * Master
576 */
577 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
578 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for DMA1, USB0, USB1, ENET, UDSHC0,
579 USDHC1, UDSHC2, CAMM Master */
580 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
581 mbcBlockConfig.domainIdx = 1U; /* MBC2_DOM1 */
582 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM1_MEM1 */
583 TRDC_GetMbcHardwareConfig(TRDC, &mbcHwConfig, mbcBlockConfig.mbcIdx, mbcBlockConfig.slaveMemoryIdx);
584 for (n = 0U; n < mbcHwConfig.blockNum; n++)
585 {
586 mbcBlockConfig.memoryBlockIdx = n; /* MBC2_DOM1_MEM1_BLK_CFG_Wx */
587 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
588 }
589
590 /* non secure state can access SSRAM(MBC0_MEM2) for DMA1, USB0, USB1, ENET, UDSHC0, USDHC1, UDSHC2, CAMM Master
591 */
592 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
593 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for DMA1, USB0, USB1, ENET, UDSHC0,
594 USDHC1, UDSHC2, CAMM Master */
595 mbcBlockConfig.mbcIdx = 0U; /* MBC0 */
596 mbcBlockConfig.domainIdx = 1U; /* MBC0_DOM1 */
597 mbcBlockConfig.slaveMemoryIdx = 2U; /* MBC0_DOM1_MEM2 */
598 TRDC_GetMbcHardwareConfig(TRDC, &mbcHwConfig, mbcBlockConfig.mbcIdx, mbcBlockConfig.slaveMemoryIdx);
599 for (n = 0U; n < mbcHwConfig.blockNum; n++)
600 {
601 mbcBlockConfig.memoryBlockIdx = n; /* MBC0_DOM1_MEM2_BLK_CFG_Wx */
602 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
603 }
604
605 /* Special configurations for cortex-A35 */
606 /* non secure state can access 0x1fff8000(it is used for resource table of rpmsg) for cortex-A35 */
607 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
608 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
609 mbcBlockConfig.mbcIdx = 0U; /* MBC0 */
610 mbcBlockConfig.domainIdx = 7U; /* MBC0_DOM7 */
611 mbcBlockConfig.slaveMemoryIdx = 2U; /* MBC0_DOM7_MEM2 */
612 mbcBlockConfig.memoryBlockIdx = 31U; /* MBC0_DOM7_MEM2_BLK_CFG_W31 */
613 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
614
615 /* non secure state can access CGC0: PBrigge0 slot 47 and PCC0 slot 48 for cortex-A35 */
616 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
617 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
618 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
619 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
620 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0 */
621 mbcBlockConfig.memoryBlockIdx = 47U; /* MBC2_DOM7_MEM0_BLK_CFG_W47 */
622 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
623 mbcBlockConfig.memoryBlockIdx = 48U; /* MBC2_DOM7_MEM0_BLK_CFG_W48 */
624 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
625
626 /* non secure state can access CGC0 (Pbridge0, slot 47) for HIFI4 DSP */
627 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
628 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for HIFI4 DSP */
629 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
630 mbcBlockConfig.domainIdx = 2U; /* MBC2_DOM2 */
631 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM2_MEM0 */
632 mbcBlockConfig.memoryBlockIdx = 47U; /* MBC2_DOM2_MEM0_BLK_CFG_W47 */
633 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
634
635 /* non secure state can access PCC1(PBridge1 slot 17) and ADC1(PBridge1 slot 34) for cortex-A35 */
636 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
637 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
638 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
639 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
640 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM7_MEM1 */
641 mbcBlockConfig.memoryBlockIdx = 17U; /* MBC2_DOM7_MEM1_BLK_CFG_W17 */
642 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
643 mbcBlockConfig.memoryBlockIdx = 34U; /* MBC2_DOM7_MEM1_BLK_CFG_W34 */
644 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
645
646 /* non secure state can access iomuxc0(PBridge1 slot 33) for cortex-A35 */
647 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
648 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
649 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
650 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
651 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM7_MEM1 */
652 mbcBlockConfig.memoryBlockIdx = 33U; /* MBC2_DOM7_MEM1_BLK_CFG_W33 */
653 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
654
655 /* non secure state can access flexspi0(PBridge0 slot 57 of T-MBC2, also need setup T-MRC0) for cortex-A35 */
656 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
657 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
658 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
659 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
660 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0 */
661 mbcBlockConfig.memoryBlockIdx = 57U; /* MBC2_DOM7_MEM0_BLK_CFG_W57 */
662 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
663 mrcRegionConfig.memoryAccessControlSelect = TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX;
664 mrcRegionConfig.valid = true;
665 mrcRegionConfig.nseEnable = true; /* non secure state can access the region for cortex-A35 */
666 mrcRegionConfig.mrcIdx = TRDC_MRC0_INDEX;
667 mrcRegionConfig.domainIdx = 7U;
668 /* Get region number for current MRC instance */
669 TRDC_GetHardwareConfig(TRDC, &hwConfig);
670 for (i = 0; i < hwConfig.mrcNumber; i++)
671 {
672 if (i == mrcRegionConfig.mrcIdx)
673 {
674 n = TRDC_GetMrcRegionNumber(TRDC, mrcRegionConfig.mrcIdx);
675
676 /*__IO uint32_t MRC_DOM0_RGD_W[8][2]; n do not more than 8 (coverity check)*/
677 if (n > 8)
678 {
679 return;
680 }
681
682 for (m = 0U; m < n; m++)
683 {
684 mrcRegionConfig.regionIdx = m;
685 mrcRegionConfig.startAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * m;
686 mrcRegionConfig.endAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * (m + 1U);
687
688 TRDC_MrcSetRegionDescriptorConfig(TRDC, &mrcRegionConfig);
689 }
690 }
691 }
692
693 /* non secure state can access tpm0(PBridge1 slot 21) for cortex-A35 */
694 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
695 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
696 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
697 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
698 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM7_MEM1 */
699 mbcBlockConfig.memoryBlockIdx = 21U; /* MBC2_DOM7_MEM1_BLK_CFG_W21 */
700 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
701
702 /* non secure state can access lpi2c0(PBridge1 slot 24, T-MBC2) for cortex-A35 */
703 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
704 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
705 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
706 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
707 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM7_MEM1 */
708 mbcBlockConfig.memoryBlockIdx = 24U; /* MBC2_DOM7_MEM1_BLK_CFG_W24 */
709 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
710
711 /* non secure state can access FSB(Sentinel slot 1, T-MBC2) and S400 MUAP A-side(Sentinel slot 2, T-MBC2) for
712 * cortex-A35 */
713 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
714 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
715 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
716 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
717 mbcBlockConfig.slaveMemoryIdx = 3U; /* MBC2_DOM7_MEM3, slave memoty is sentinel */
718 mbcBlockConfig.memoryBlockIdx = 1U; /* MBC2_DOM7_MEM3_BLK_CFG_W1 */
719 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
720 mbcBlockConfig.memoryBlockIdx = 2U; /* MBC2_DOM7_MEM3_BLK_CFG_W2 */
721 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
722
723 /* non secure state can access RTD_SIM_SEC(PBridge0 slot 43, T-MBC2) for cortex-A35 */
724 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
725 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
726 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
727 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
728 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0, slave memoty is PBridge0 */
729 mbcBlockConfig.memoryBlockIdx = 43U; /* MBC2_DOM7_MEM0_BLK_CFG_W43 */
730 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
731
732 /* non secure state can access SEMA42[0](PBridge0 slot 55, T-MBC2) for cortex-A35 */
733 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
734 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for cortex-A35 */
735 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
736 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
737 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0, slave memoty is PBridge0 */
738 mbcBlockConfig.memoryBlockIdx = 55U; /* MBC2_DOM7_MEM0_BLK_CFG_W55 */
739 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
740
741 /* non secure state can access flexspi0(PBridge0 slot 57 of T-MBC2, also need setup T-MRC0) for eDMA0 */
742 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
743 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
744 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
745 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
746 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM0_MEM0 */
747 mbcBlockConfig.memoryBlockIdx = 57U; /* MBC2_DOM0_MEM0_BLK_CFG_W57 */
748 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
749 mrcRegionConfig.memoryAccessControlSelect = TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX;
750 mrcRegionConfig.valid = true;
751 mrcRegionConfig.nseEnable = true; /* non secure state can access the region for eDMA0 */
752 mrcRegionConfig.mrcIdx = TRDC_MRC0_INDEX;
753 mrcRegionConfig.domainIdx = TRDC_DMA0_DOMAIN_ID;
754 /* Get region number for current MRC instance */
755 TRDC_GetHardwareConfig(TRDC, &hwConfig);
756 for (i = 0; i < hwConfig.mrcNumber; i++)
757 {
758 if (i == mrcRegionConfig.mrcIdx)
759 {
760 n = TRDC_GetMrcRegionNumber(TRDC, mrcRegionConfig.mrcIdx);
761
762 /*__IO uint32_t MRC_DOM0_RGD_W[8][2]; n do not more than 8 (coverity check)*/
763 if (n > 8)
764 {
765 return;
766 }
767
768 for (m = 0U; m < n; m++)
769 {
770 mrcRegionConfig.regionIdx = m;
771 mrcRegionConfig.startAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * m;
772 mrcRegionConfig.endAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * (m + 1U);
773
774 TRDC_MrcSetRegionDescriptorConfig(TRDC, &mrcRegionConfig);
775 }
776 }
777 }
778
779 /* non secure state can access flexspi1(PBridge1 slot 18 of T-MBC2, also need setup T-MRC1) for eDMA0 */
780 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
781 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
782 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
783 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
784 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
785 mbcBlockConfig.memoryBlockIdx = 18U; /* MBC2_DOM0_MEM1_BLK_CFG_W18 */
786 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
787 mrcRegionConfig.memoryAccessControlSelect = TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX;
788 mrcRegionConfig.valid = true;
789 mrcRegionConfig.nseEnable = true; /* non secure state can access the region for eDMA0 */
790 mrcRegionConfig.mrcIdx = TRDC_MRC1_INDEX;
791 mrcRegionConfig.domainIdx = TRDC_DMA0_DOMAIN_ID;
792 /* Get region number for current MRC instance */
793 TRDC_GetHardwareConfig(TRDC, &hwConfig);
794 for (i = 0; i < hwConfig.mrcNumber; i++)
795 {
796 if (i == mrcRegionConfig.mrcIdx)
797 {
798 n = TRDC_GetMrcRegionNumber(TRDC, mrcRegionConfig.mrcIdx);
799
800 /*__IO uint32_t MRC_DOM0_RGD_W[8][2]; n do not more than 8 (coverity check)*/
801 if (n > 8)
802 {
803 return;
804 }
805
806 for (m = 0U; m < n; m++)
807 {
808 mrcRegionConfig.regionIdx = m;
809 mrcRegionConfig.startAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * m;
810 mrcRegionConfig.endAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * (m + 1U);
811
812 TRDC_MrcSetRegionDescriptorConfig(TRDC, &mrcRegionConfig);
813 }
814 }
815 }
816
817 /* non secure state can access flexspi1(PBridge1 slot 18 of T-MBC2, also need setup T-MRC1) for DCNANO */
818 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
819 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for DCNANO */
820 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
821 mbcBlockConfig.domainIdx = TRDC_DCNANO_DOMAIN_ID; /* MBC2_DOM3 */
822 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
823 mbcBlockConfig.memoryBlockIdx = 18U; /* MBC2_DOM0_MEM1_BLK_CFG_W18 */
824 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
825 mrcRegionConfig.memoryAccessControlSelect = TRDC_MRC_ACCESS_CONTROL_POLICY_ALL_INDEX;
826 mrcRegionConfig.valid = true;
827 mrcRegionConfig.nseEnable = true; /* non secure state can access the region for DCNANO */
828 mrcRegionConfig.mrcIdx = 1;
829 mrcRegionConfig.domainIdx = TRDC_DCNANO_DOMAIN_ID;
830 /* Get region number for current MRC instance */
831 TRDC_GetHardwareConfig(TRDC, &hwConfig);
832 for (i = 0; i < hwConfig.mrcNumber; i++)
833 {
834 if (i == TRDC_MRC1_INDEX)
835 {
836 n = TRDC_GetMrcRegionNumber(TRDC, mrcRegionConfig.mrcIdx);
837
838 /*__IO uint32_t MRC_DOM0_RGD_W[8][2]; n do not more than 8 (coverity check)*/
839 if (n > 8)
840 {
841 return;
842 }
843
844 for (m = 0U; m < n; m++)
845 {
846 mrcRegionConfig.regionIdx = m;
847 mrcRegionConfig.startAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * m;
848 mrcRegionConfig.endAddr = mrc_start_addr[i] + (mrc_end_addr[i] - mrc_start_addr[i]) / n * (m + 1U);
849
850 TRDC_MrcSetRegionDescriptorConfig(TRDC, &mrcRegionConfig);
851 }
852 }
853 }
854
855 /* non secure state can access sai0(PBridge1 slot 28, T-MBC2) for eDMA0 */
856 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
857 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
858 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
859 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
860 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
861 mbcBlockConfig.memoryBlockIdx = 28U; /* MBC2_DOM0_MEM1_BLK_CFG_W28 */
862 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
863
864 /* non secure state can access lpi2c0(PBridge1 slot 24, T-MBC2) for eDMA0 */
865 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
866 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
867 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
868 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
869 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
870 mbcBlockConfig.memoryBlockIdx = 24U; /* MBC2_DOM0_MEM1_BLK_CFG_W24 */
871 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
872
873 /* non secure state can access lpspi1(PBridge0 slot 63, T-MBC2) for eDMA0 */
874 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
875 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
876 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
877 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
878 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM0_MEM0 */
879 mbcBlockConfig.memoryBlockIdx = 63U; /* MBC2_DOM0_MEM0_BLK_CFG_W63 */
880 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
881
882 /* non secure state can access flexio0(PBridge0 slot 60, T-MBC2) for eDMA0 */
883 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
884 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
885 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
886 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
887 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM0_MEM0 */
888 mbcBlockConfig.memoryBlockIdx = 60U; /* MBC2_DOM0_MEM0_BLK_CFG_W60 */
889 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
890
891 /* non secure state can access lpuart1(PBridge1 slot 27, T-MBC2) for eDMA0 */
892 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
893 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
894 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
895 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
896 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
897 mbcBlockConfig.memoryBlockIdx = 27U; /* MBC2_DOM0_MEM1_BLK_CFG_W27 */
898 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
899
900 /* non secure state can access flexcan0(PBridge1 slot 40~43, T-MBC2) for eDMA0 */
901 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
902 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
903 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
904 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC2_DOM0 */
905 mbcBlockConfig.slaveMemoryIdx = 1U; /* MBC2_DOM0_MEM1 */
906 mbcBlockConfig.memoryBlockIdx = 40U; /* MBC2_DOM0_MEM1_BLK_CFG_W40 */
907 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
908 mbcBlockConfig.memoryBlockIdx = 41U; /* MBC2_DOM0_MEM1_BLK_CFG_W41 */
909 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
910 mbcBlockConfig.memoryBlockIdx = 42U; /* MBC2_DOM0_MEM1_BLK_CFG_W42 */
911 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
912 mbcBlockConfig.memoryBlockIdx = 43U; /* MBC2_DOM0_MEM1_BLK_CFG_W43 */
913 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
914
915 /* non secure state can access ssram(T-MBC0) for eDMA0 */
916 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
917 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
918 mbcBlockConfig.mbcIdx = 0U; /* MBC0 */
919 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC0_DOM0 */
920 mbcBlockConfig.slaveMemoryIdx = 2U; /* MBC0_DOM0_MEM2 */
921 /* 0x20000000 ~ 0x20007FFF (SSRAM P0), slot number 0 */
922 mbcBlockConfig.memoryBlockIdx = 0U; /* MBC0_DOM0_MEM2_BLK_CFG_W0 */
923 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
924 /* 0x20008000 ~ 0x2000FFFF (SSRAM P1), slot number 1 */
925 mbcBlockConfig.memoryBlockIdx = 1U; /* MBC0_DOM0_MEM2_BLK_CFG_W1 */
926 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
927 /* 0x20010000 ~ 0x20017FFF (SSRAM P2), slot number 2 */
928 mbcBlockConfig.memoryBlockIdx = 2U; /* MBC0_DOM0_MEM2_BLK_CFG_W2 */
929 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
930 /* 0x20018000 ~ 0x2001FFFF (SSRAM P2), slot number 3 */
931 mbcBlockConfig.memoryBlockIdx = 3U; /* MBC0_DOM0_MEM2_BLK_CFG_W3 */
932 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
933 /* 0x20020000 ~ 0x20027FFF (SSRAM P3), slot number 4 */
934 mbcBlockConfig.memoryBlockIdx = 4U; /* MBC0_DOM0_MEM2_BLK_CFG_W4 */
935 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
936 /* 0x20028000 ~ 0x2002FFFF (SSRAM P3), slot number 5 */
937 mbcBlockConfig.memoryBlockIdx = 5U; /* MBC0_DOM0_MEM2_BLK_CFG_W5 */
938 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
939 /* 0x20030000 ~ 0x20037FFF (SSRAM P4), slot number 6 */
940 mbcBlockConfig.memoryBlockIdx = 6U; /* MBC0_DOM0_MEM2_BLK_CFG_W6 */
941 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
942 /* 0x20038000 ~ 0x2003FFFF (SSRAM P4), slot number 7 */
943 mbcBlockConfig.memoryBlockIdx = 7U; /* MBC0_DOM0_MEM2_BLK_CFG_W7 */
944 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
945 /* 0x20040000 ~ 0x20047FFF (SSRAM P5), slot number 8 */
946 mbcBlockConfig.memoryBlockIdx = 8U; /* MBC0_DOM0_MEM2_BLK_CFG_W8 */
947 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
948 /* 0x20048000 ~ 0x2004FFFF (SSRAM P5), slot number 9 */
949 mbcBlockConfig.memoryBlockIdx = 9U; /* MBC0_DOM0_MEM2_BLK_CFG_W9 */
950 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
951 /* 0x20050000 ~ 0x20057FFF (SSRAM P5), slot number 10 */
952 mbcBlockConfig.memoryBlockIdx = 10U; /* MBC0_DOM0_MEM2_BLK_CFG_W10 */
953 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
954 /* 0x20058000 ~ 0x2005FFFF (SSRAM P5), slot number 11 */
955 mbcBlockConfig.memoryBlockIdx = 11U; /* MBC0_DOM0_MEM2_BLK_CFG_W11 */
956 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
957 /* 0x20060000 ~ 0x20067FFF (SSRAM P6), slot number 12 */
958 mbcBlockConfig.memoryBlockIdx = 12U; /* MBC0_DOM0_MEM2_BLK_CFG_W12 */
959 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
960 /* 0x20068000 ~ 0x2006FFFF (SSRAM P6), slot number 13 */
961 mbcBlockConfig.memoryBlockIdx = 13U; /* MBC0_DOM0_MEM2_BLK_CFG_W13 */
962 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
963 /* 0x20070000 ~ 0x20077FFF (SSRAM P6), slot number 14 */
964 mbcBlockConfig.memoryBlockIdx = 14U; /* MBC0_DOM0_MEM2_BLK_CFG_W14 */
965 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
966 /* 0x20078000 ~ 0x2007FFFF (SSRAM P6), slot number 15 */
967 mbcBlockConfig.memoryBlockIdx = 15U; /* MBC0_DOM0_MEM2_BLK_CFG_W15 */
968 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
969
970 /* 0x0ffc0000 ~ 0x0ffc7fff (SSRAM P7), slot number 24 */
971 mbcBlockConfig.memoryBlockIdx = 24U; /* MBC0_DOM0_MEM2_BLK_CFG_W24 */
972 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
973 /* 0x0ffc8000 ~ 0x0ffcffff (SSRAM P7), slot number 25 */
974 mbcBlockConfig.memoryBlockIdx = 25U; /* MBC0_DOM0_MEM2_BLK_CFG_W25 */
975 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
976 /* 0x0ffd0000 ~ 0x0ffd7fff (SSRAM P7), slot number 26 */
977 mbcBlockConfig.memoryBlockIdx = 26U; /* MBC0_DOM0_MEM2_BLK_CFG_W26 */
978 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
979 /* 0x0ffd8000 ~ 0x0ffdffff (SSRAM P7), slot number 27 */
980 mbcBlockConfig.memoryBlockIdx = 27U; /* MBC0_DOM0_MEM2_BLK_CFG_W27 */
981 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
982 /* 0x0ffe0000 ~ 0x0ffe7fff (SSRAM P7), slot number 28 */
983 mbcBlockConfig.memoryBlockIdx = 28U; /* MBC0_DOM0_MEM2_BLK_CFG_W28 */
984 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
985 /* 0x0ffe8000 ~ 0x0ffeffff (SSRAM P7), slot number 29 */
986 mbcBlockConfig.memoryBlockIdx = 29U; /* MBC0_DOM0_MEM2_BLK_CFG_W29 */
987 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
988 /* 0x0fff0000 ~ 0x0fff7fff (SSRAM P7), slot number 30 */
989 mbcBlockConfig.memoryBlockIdx = 30U; /* MBC0_DOM0_MEM2_BLK_CFG_W30 */
990 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
991 /* 0x0fff8000 ~ 0x0fffffff (SSRAM P7), slot number 31 */
992 mbcBlockConfig.memoryBlockIdx = 31U; /* MBC0_DOM0_MEM2_BLK_CFG_W31 */
993 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
994
995 if (BOARD_IsFusionAvailable() == true)
996 {
997 /* non secure state can access MICFIL(T-MBC3) for eDMA0 */
998 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
999 mbcBlockConfig.nseEnable = true; /* non secure state can access the block for eDMA0 */
1000 mbcBlockConfig.mbcIdx = 3U; /* MBC3 */
1001 mbcBlockConfig.domainIdx = TRDC_DMA0_DOMAIN_ID; /* MBC3_DOM0 */
1002 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC3_DOM0_MEM0 */
1003 mbcBlockConfig.memoryBlockIdx = 17U; /* MBC3_DOM0_MEM0_BLK_CFG_W17 */
1004 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1005 }
1006
1007 TRDC_SetMbcGlobalValid(TRDC);
1008 TRDC_SetMrcGlobalValid(TRDC);
1009
1010 #if 0
1011 /* 5. Assign domain ID for m33 */
1012 trdc_processor_domain_assignment_t domainAssignment;
1013
1014 TRDC_GetDefaultProcessorDomainAssignment(&domainAssignment);
1015 domainAssignment.domainId = TRDC_M33_DOMAIN_ID;
1016
1017 TRDC_SetProcessorDomainAssignment(TRDC, &domainAssignment);
1018 #endif
1019
1020 /* 6. Assign domain ID for DMA0(T-MDAC2),Powerquad(T-MDAC0) */
1021 trdc_non_processor_domain_assignment_t nonProcessorDomainAssignment;
1022 TRDC_GetDefaultNonProcessorDomainAssignment(&nonProcessorDomainAssignment);
1023 nonProcessorDomainAssignment.privilegeAttr = kTRDC_ForcePrivilege;
1024 nonProcessorDomainAssignment.secureAttr = kTRDC_ForceNonSecure;
1025 nonProcessorDomainAssignment.domainId = TRDC_DMA0_DOMAIN_ID;
1026 TRDC_SetNonProcessorDomainAssignment(TRDC, TRDC_DMA0_MASTER_ID, &nonProcessorDomainAssignment);
1027 nonProcessorDomainAssignment.domainId = TRDC_POWERQUAD_DOMAIN_ID;
1028 TRDC_SetNonProcessorDomainAssignment(TRDC, TRDC_POWERQUAD_MASTER_ID, &nonProcessorDomainAssignment);
1029
1030 TRDC_SetDacGlobalValid(TRDC);
1031
1032 /* dump TRDC registers */
1033 BOARD_DumpRegs(0x28032020, 0x2803203c);
1034 BOARD_DumpRegs(0x28032fa8, 0x28032fb4);
1035 }
1036 }
1037
1038 /* Setup TRDC configuration before executing rom code of A35(A35 rom will access FSB, S400 MUAP A-Side, SIM0-S with
1039 * secure state, so m33 help a35 to configure TRDC) */
BOARD_SetTrdcAfterApdReset(void)1040 void BOARD_SetTrdcAfterApdReset(void)
1041 {
1042 trdc_mbc_memory_block_config_t mbcBlockConfig;
1043
1044 BOARD_ReleaseTRDC();
1045 if (releasedTrdc == true)
1046 {
1047 /* secure state can access FSB(Sentinel slot 1, T-MBC2) and S400 MUAP A-side(Sentinel slot 2, T-MBC2) for
1048 * cortex-A35
1049 */
1050 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
1051 mbcBlockConfig.nseEnable = false; /* secure state can access the block for cortex-A35 */
1052 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
1053 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
1054 mbcBlockConfig.slaveMemoryIdx = 3U; /* MBC2_DOM7_MEM3, slave memoty is sentinel */
1055 mbcBlockConfig.memoryBlockIdx = 1U; /* MBC2_DOM7_MEM3_BLK_CFG_W1 */
1056 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1057 mbcBlockConfig.memoryBlockIdx = 2U; /* MBC2_DOM7_MEM3_BLK_CFG_W2 */
1058 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1059
1060 /* secure state can access RTD_SIM_SEC(PBridge0 slot 43, T-MBC2) for cortex-A35 */
1061 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
1062 mbcBlockConfig.nseEnable = false; /* secure state can access the block for cortex-A35 */
1063 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
1064 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
1065 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0, slave memoty is PBridge0 */
1066 mbcBlockConfig.memoryBlockIdx = 43U; /* MBC2_DOM7_MEM0_BLK_CFG_W43 */
1067 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1068
1069 /* secure state can access CGC0: PBrigge0 slot 47 and PCC0 slot 48 for cortex-A35 */
1070 mbcBlockConfig.memoryAccessControlSelect = TRDC_MBC_ACCESS_CONTROL_POLICY_ALL_INDEX;
1071 mbcBlockConfig.nseEnable = false; /* secure state can access the block for cortex-A35 */
1072 mbcBlockConfig.mbcIdx = 2U; /* MBC2 */
1073 mbcBlockConfig.domainIdx = 7U; /* MBC2_DOM7 */
1074 mbcBlockConfig.slaveMemoryIdx = 0U; /* MBC2_DOM7_MEM0 */
1075 mbcBlockConfig.memoryBlockIdx = 47U; /* MBC2_DOM7_MEM0_BLK_CFG_W47 */
1076 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1077 mbcBlockConfig.memoryBlockIdx = 48U; /* MBC2_DOM7_MEM0_BLK_CFG_W48 */
1078 TRDC_MbcSetMemoryBlockConfig(TRDC, &mbcBlockConfig);
1079 }
1080 }
1081
1082 /* true: low power boot type; false: not low power boot type(such as: single boot type, dual boot type) */
BOARD_IsLowPowerBootType(void)1083 bool BOARD_IsLowPowerBootType(void)
1084 {
1085 /*
1086 * BOOTCFG[0](BT0_CFG0)
1087 * dgo_gp5[15:0] = cmc0_mr[15:0] | 0x0100, dgo[31:16] = cmc1_mr[15:0] | 0x0001
1088 * 0: No Low Power Boot
1089 * 1: Boot from M33 with A35 on demand
1090 */
1091 return SIM_SEC->DGO_GP5 & CMC_MR_BOOTCFG(1);
1092 }
1093
1094 /* true: RTD hold LPAV, false: APD hold LPAV */
BOARD_IsLPAVOwnedByRTD(void)1095 bool BOARD_IsLPAVOwnedByRTD(void)
1096 {
1097 return !(SIM_SEC->SYSCTRL0 & SIM_SEC_SYSCTRL0_LPAV_MASTER_CTRL(1));
1098 }
1099
1100 /* true: Single Boot type; false: not Single Boot type(such as: Low Power Boot type, Dual Boot type) */
BOARD_IsSingleBootType(void)1101 bool BOARD_IsSingleBootType(void)
1102 {
1103 /*
1104 * BOOTCFG[0](BT0_CFG0)
1105 * dgo_gp5[15:0] = cmc0_mr[15:0] | 0x0100, dgo[31:16] = cmc1_mr[15:0] | 0x0001
1106 * 0: No Single Boot
1107 * 1: Single Boot
1108 */
1109 return !(SIM_SEC->DGO_GP5 & CMC_MR_BOOTCFG(3));
1110 }
1111
BOARD_GetBootTypeName(void)1112 const char *BOARD_GetBootTypeName(void)
1113 {
1114 boot_type_e bootType = SINGLE_BOOT_TYPE;
1115
1116 if (BOARD_IsSingleBootType())
1117 {
1118 bootType = SINGLE_BOOT_TYPE;
1119 }
1120 else if (BOARD_IsLowPowerBootType())
1121 {
1122 bootType = LOW_POWER_BOOT_TYPE;
1123 }
1124 else
1125 {
1126 bootType = DUAL_BOOT_TYPE;
1127 }
1128
1129 return s_bootTypeNames[bootType];
1130 }
1131 /*
1132 * return the handshake result(fail or success):
1133 * true: succeeded to handshake with uboot; false: failed to handshake with uboot
1134 */
BOARD_HandshakeWithUboot(void)1135 bool BOARD_HandshakeWithUboot(void)
1136 {
1137 #ifdef SDK_OS_FREE_RTOS
1138 TickType_t xTicksToWait = pdMS_TO_TICKS(BOARD_HANDSHAKE_WITH_UBOOT_TIMEOUT_MS);
1139 TickType_t currTick = xTaskGetTickCount();
1140 #else
1141 uint64_t timeout_time = BOARD_HANDSHAKE_WITH_UBOOT_TIMEOUT_MS * 1000; /* us */
1142 uint64_t curr_time = 0U;
1143 #endif
1144 bool state = false;
1145
1146 /*
1147 * Wait MU0_MUA FSR F0 flag is set by uboot
1148 *
1149 * handshake procedure as follows:
1150 * a35(set flag F0 of MU0_MUB) --- ready to do MU communication(also indicates MIPI DSI panel ready) ---> m33
1151 * a35 <--------------- ACK ----------------------------------------------------------------------------> m33 (get
1152 * flag F0 of MU0_MUA, and set flag F0 of MU0_MUA) a35(clear flag F0 of MU0_MUB)
1153 * -----------------------------------------------------------------------> m33 a35
1154 * <------------------------------------------------------------------------------------------------> m33 (get flag
1155 * F0 of MU0_MUA and clear flag F0 of MU0_MUA)
1156 *
1157 * (uboot will set MU0_MUB FCR F0 flag in board_init(), board/freescale/imx8ulp_evk/imx8ulp_evk.c,
1158 * after uboot set MU0_MUB FCR F0 flag, the flag will be shown in MU0_MUA FSR)
1159 */
1160 /* enable clock of MU0_MUA before accessing registers of MU0_MUA */
1161 MU_Init(MU0_MUA);
1162 while (true)
1163 {
1164 if (MU_GetFlags(MU0_MUA) & BOARD_MU0_MUB_F0_INIT_SRTM_COMMUNICATION_FLG)
1165 {
1166 /* Set FCR F0 flag of MU0_MUA to notify uboot to clear FCR F0 flag of MU0_MUB */
1167 MU_SetFlags(MU0_MUA, BOARD_MU0_MUB_F0_INIT_SRTM_COMMUNICATION_FLG);
1168 BOARD_SetTrdcGlobalConfig();
1169 break;
1170 }
1171
1172 #ifdef SDK_OS_FREE_RTOS
1173 vTaskDelay(pdMS_TO_TICKS(BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS));
1174 if (currTick + xTicksToWait < xTaskGetTickCount())
1175 #else
1176 SDK_DelayAtLeastUs(BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS * 1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1177 curr_time += BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS * 1000;
1178 if (curr_time > timeout_time) /* when time out */
1179 #endif
1180 {
1181 PRINTF("\r\n %s: %d handshake with uboot timeout\r\n", __func__, __LINE__);
1182 return state;
1183 }
1184 }
1185
1186 /*
1187 * Wait uboot to clear the FCR F0 flag of MU0_MUB
1188 * Clear FCR F0 flag of MU0_MUA after uboot have cleared the FCR
1189 * F0 flag of MU0_MUB
1190 */
1191
1192 #ifdef SDK_OS_FREE_RTOS
1193 currTick = xTaskGetTickCount(); /* update currTick */
1194 #else
1195 curr_time = 0UL;
1196 #endif
1197 while (true)
1198 {
1199 if ((MU_GetFlags(MU0_MUA) & BOARD_MU0_MUB_F0_INIT_SRTM_COMMUNICATION_FLG) == 0)
1200 {
1201 MU_SetFlags(MU0_MUA, 0);
1202 state = true;
1203 break;
1204 }
1205 #ifdef SDK_OS_FREE_RTOS
1206 vTaskDelay(pdMS_TO_TICKS(BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS));
1207 if (currTick + xTicksToWait < xTaskGetTickCount())
1208 #else
1209 SDK_DelayAtLeastUs(BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS * 1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
1210 curr_time += BOARD_WAIT_MU0_MUB_F0_FLG_FROM_UBOOT_MS * 1000;
1211 if (curr_time > timeout_time) /* when time out */
1212 #endif
1213 {
1214 PRINTF("\r\n %s: %d handshake with uboot timeout\r\n", __func__, __LINE__);
1215 MU_SetFlags(MU0_MUA, 0); /* clear flag */
1216 break;
1217 }
1218 }
1219 return state;
1220 }
1221
BOARD_ConfigMPU(void)1222 void BOARD_ConfigMPU(void)
1223 {
1224 uint8_t attr;
1225
1226 /* Disable MPU */
1227 ARM_MPU_Disable();
1228
1229 /* Attr0: device memory. */
1230 ARM_MPU_SetMemAttr(0U, ARM_MPU_ATTR(ARM_MPU_ATTR_DEVICE, ARM_MPU_ATTR_DEVICE));
1231
1232 /* Attr1: non cacheable, normal memory */
1233 ARM_MPU_SetMemAttr(1U, ARM_MPU_ATTR(ARM_MPU_ATTR_NON_CACHEABLE, ARM_MPU_ATTR_NON_CACHEABLE));
1234
1235 /* Attr2: transient, write through, read allocate, normal memory */
1236 attr = ARM_MPU_ATTR_MEMORY_(0U, 0U, 1U, 0U);
1237 ARM_MPU_SetMemAttr(2U, ARM_MPU_ATTR(attr, attr));
1238
1239 /* Attr3: transient, write back, read/write allocate, normal memory */
1240 attr = ARM_MPU_ATTR_MEMORY_(0U, 1U, 1U, 1U);
1241 ARM_MPU_SetMemAttr(3U, ARM_MPU_ATTR(attr, attr));
1242
1243 /* NOTE1: All SSRAM/TCRAMU/TCRAML is non-cacheable regardless of MPU setting. */
1244 /* NOTE2: [0x0, 0x1FFFFFFF] cannot support write back. */
1245 /* Region 0: [0x0, 0x1FFFFFFF](FlexSPI0 is also in the range), non-shareable, read/write, any privileged,
1246 * executable. Attr 2 (write through). */
1247 ARM_MPU_SetRegion(0U, ARM_MPU_RBAR(0U, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x1FFFFFFFU, 2U));
1248
1249 /* NOTE1: All SSRAM/TCRAMU/TCRAML is non-cacheable regardless of MPU setting. */
1250 /* Region 1: [0x20000000, 0x20037FFF](m_m33_suspend_ram, m_a35_suspend_ram, m_data, m_ncache, Non-Secure),
1251 * non-shareable, read/write, any privileged, executable. Attr 3 (write back). */
1252 ARM_MPU_SetRegion(1U, ARM_MPU_RBAR(0x20000000U, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x20037FFFU, 3U));
1253
1254 /* NOTE1: All SSRAM/TCRAMU/TCRAML is non-cacheable regardless of MPU setting. */
1255 /* Region 2: [0x27000000, 0x2FFFFFFF](pheripheral, Non-Secure), non-shareable, read/write, any privileged,
1256 * executable. Attr 0 (device). */
1257 ARM_MPU_SetRegion(2U, ARM_MPU_RBAR(0x27000000U, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x2FFFFFFFU, 0U));
1258
1259 /* NOTE1: All SSRAM/TCRAMU/TCRAML is non-cacheable regardless of MPU setting. */
1260 /* Region 3: [0x30000000, 0x30037FFF](m_m33_suspend_ram, m_a35_suspend_ram, m_data, m_ncache, Secure),
1261 * non-shareable, read/write, any privileged, executable. Attr 3 (write back). */
1262 ARM_MPU_SetRegion(3U, ARM_MPU_RBAR(0x30000000U, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x30037FFFU, 3U));
1263
1264 /* NOTE1: All SSRAM/TCRAMU/TCRAML is non-cacheable regardless of MPU setting. */
1265 /* Region 4: [0x37000000, 0x3FFFFFFF](pheripheral, Secure), non-shareable, read/write, any privileged,
1266 * executable. Attr 0 (device). */
1267 ARM_MPU_SetRegion(4U, ARM_MPU_RBAR(0x37000000U, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x3FFFFFFFU, 0U));
1268
1269 /* Region 5 (FlexSPI1,2): [0x40000000, 0x7FFFFFFF], non-shareable, read/write, any privileged, executable. Attr 3
1270 * (write back). */
1271 ARM_MPU_SetRegion(5U, ARM_MPU_RBAR(0x40000000, ARM_MPU_SH_NON, 0U, 1U, 0U), ARM_MPU_RLAR(0x7FFFFFFF, 3U));
1272
1273 /* NOTE: DDR is used as shared memory for A/M core communication, set it to non-cacheable. */
1274 /* Region 6 (DDR): [0x80000000, 0xDFFFFFFF], outer shareable, read/write, any privileged, executable. Attr 1
1275 * (non-cacheable). */
1276 ARM_MPU_SetRegion(6U, ARM_MPU_RBAR(0x80000000, ARM_MPU_SH_OUTER, 0U, 1U, 0U), ARM_MPU_RLAR(0xDFFFFFFF, 1U));
1277
1278 /* Enable MPU */
1279 ARM_MPU_Enable(MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk);
1280
1281 CACHE64_EnableCache(CACHE64_CTRL0); /* enable code bus cache(I-Cache) */
1282 CACHE64_EnableCache(CACHE64_CTRL1); /* enable system bus cache(D-Cache) */
1283 /* flush pipeline */
1284 __DSB();
1285 __ISB();
1286 }
1287
flexspi_hyper_ram_write_mcr(FLEXSPI_Type * base,uint8_t regAddr,uint32_t * mrVal)1288 static status_t flexspi_hyper_ram_write_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal)
1289 {
1290 flexspi_transfer_t flashXfer;
1291 status_t status;
1292
1293 /* Write data */
1294 flashXfer.deviceAddress = regAddr;
1295 flashXfer.port = kFLEXSPI_PortA1;
1296 flashXfer.cmdType = kFLEXSPI_Write;
1297 flashXfer.SeqNumber = 1;
1298 flashXfer.seqIndex = 3;
1299 flashXfer.data = mrVal;
1300 flashXfer.dataSize = 1;
1301
1302 status = FLEXSPI_TransferBlocking(base, &flashXfer);
1303
1304 return status;
1305 }
1306
flexspi_hyper_ram_get_mcr(FLEXSPI_Type * base,uint8_t regAddr,uint32_t * mrVal)1307 static status_t flexspi_hyper_ram_get_mcr(FLEXSPI_Type *base, uint8_t regAddr, uint32_t *mrVal)
1308 {
1309 flexspi_transfer_t flashXfer;
1310 status_t status;
1311
1312 /* Read data */
1313 flashXfer.deviceAddress = regAddr;
1314 flashXfer.port = kFLEXSPI_PortA1;
1315 flashXfer.cmdType = kFLEXSPI_Read;
1316 flashXfer.SeqNumber = 1;
1317 flashXfer.seqIndex = 2;
1318 flashXfer.data = mrVal;
1319 flashXfer.dataSize = 2;
1320
1321 status = FLEXSPI_TransferBlocking(base, &flashXfer);
1322
1323 return status;
1324 }
1325
flexspi_hyper_ram_reset(FLEXSPI_Type * base)1326 static status_t flexspi_hyper_ram_reset(FLEXSPI_Type *base)
1327 {
1328 flexspi_transfer_t flashXfer;
1329 status_t status;
1330
1331 /* Write data */
1332 flashXfer.deviceAddress = 0x0U;
1333 flashXfer.port = kFLEXSPI_PortA1;
1334 flashXfer.cmdType = kFLEXSPI_Command;
1335 flashXfer.SeqNumber = 1;
1336 flashXfer.seqIndex = 4;
1337
1338 status = FLEXSPI_TransferBlocking(base, &flashXfer);
1339
1340 if (status == kStatus_Success)
1341 {
1342 /* for loop of 50000 is about 1ms (@200 MHz CPU) */
1343 for (uint32_t i = 2000000U; i > 0; i--)
1344 {
1345 __NOP();
1346 }
1347 }
1348 return status;
1349 }
1350
1351 /* Initialize psram. */
BOARD_InitPsRam(void)1352 status_t BOARD_InitPsRam(void)
1353 {
1354 flexspi_device_config_t deviceconfig = {
1355 .flexspiRootClk = 392000000, /* 392MHZ SPI serial clock, DDR serial clock 196M */
1356 .isSck2Enabled = false,
1357 .flashSize = 0x2000, /* 64Mb/KByte */
1358 .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
1359 .CSInterval = 5,
1360 .CSHoldTime = 3,
1361 .CSSetupTime = 3,
1362 .dataValidTime = 1,
1363 .columnspace = 0,
1364 .enableWordAddress = false,
1365 .AWRSeqIndex = 1,
1366 .AWRSeqNumber = 1,
1367 .ARDSeqIndex = 0,
1368 .ARDSeqNumber = 1,
1369 .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
1370 .AHBWriteWaitInterval = 0,
1371 .enableWriteMask = true,
1372 };
1373
1374 uint32_t customLUT[64] = {
1375 /* Read Data */
1376 [0] =
1377 FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
1378 [1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_READ_DDR,
1379 kFLEXSPI_8PAD, 0x04),
1380
1381 /* Write Data */
1382 [4] =
1383 FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
1384 [5] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_WRITE_DDR,
1385 kFLEXSPI_8PAD, 0x04),
1386
1387 /* Read Register */
1388 [8] =
1389 FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0x40, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
1390 [9] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07, kFLEXSPI_Command_READ_DDR,
1391 kFLEXSPI_8PAD, 0x04),
1392
1393 /* Write Register */
1394 [12] =
1395 FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xC0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x20),
1396 [13] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x08, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD,
1397 0x00),
1398
1399 /* reset */
1400 [16] =
1401 FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_8PAD, 0xFF, kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_8PAD, 0x03),
1402
1403 };
1404
1405 uint32_t mr0mr1[1];
1406 uint32_t mr4mr8[1];
1407 uint32_t mr0Val[1];
1408 uint32_t mr4Val[1];
1409 uint32_t mr8Val[1];
1410 flexspi_config_t config;
1411 status_t status = kStatus_Success;
1412
1413 UPOWER_PowerOnMemPart(0U, (uint32_t)kUPOWER_MP1_FLEXSPI1);
1414
1415 /* 392MHz * 1U / 1U = 392MHz */
1416 CLOCK_SetIpSrcDiv(kCLOCK_Flexspi1, kCLOCK_Pcc1PlatIpSrcPll0Pfd3, 0U, 0U);
1417 RESET_PeripheralReset(kRESET_Flexspi1);
1418
1419 /* Get FLEXSPI default settings and configure the flexspi. */
1420 FLEXSPI_GetDefaultConfig(&config);
1421
1422 /* Init FLEXSPI. */
1423 config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
1424 /*Set AHB buffer size for reading data through AHB bus. */
1425 config.ahbConfig.enableAHBPrefetch = true;
1426 config.ahbConfig.enableAHBBufferable = true;
1427 config.ahbConfig.enableAHBCachable = true;
1428 config.ahbConfig.enableReadAddressOpt = true;
1429 for (uint8_t i = 1; i < FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1; i++)
1430 {
1431 config.ahbConfig.buffer[i].bufferSize = 0;
1432 }
1433 /* FlexSPI1 has total 2KB RX buffer.
1434 * Set GPU/Display master to use AHB Rx Buffer0.
1435 */
1436 config.ahbConfig.buffer[0].masterIndex = 2; /* DMA0 */
1437 config.ahbConfig.buffer[0].bufferSize = 1024; /* Allocate 1KB bytes for DMA0 */
1438 config.ahbConfig.buffer[0].enablePrefetch = true;
1439 config.ahbConfig.buffer[0].priority = 7; /* Set DMA0 to highest priority. */
1440 /* All other masters use last buffer with 1KB bytes. */
1441 config.ahbConfig.buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 1].bufferSize = 1024;
1442 config.enableCombination = true;
1443 FLEXSPI_Init(BOARD_FLEXSPI_PSRAM, &config);
1444
1445 /* Configure flash settings according to serial flash feature. */
1446 FLEXSPI_SetFlashConfig(BOARD_FLEXSPI_PSRAM, &deviceconfig, kFLEXSPI_PortA1);
1447
1448 /* Update LUT table. */
1449 FLEXSPI_UpdateLUT(BOARD_FLEXSPI_PSRAM, 0, customLUT, ARRAY_SIZE(customLUT));
1450
1451 /* Do software reset. */
1452 FLEXSPI_SoftwareReset(BOARD_FLEXSPI_PSRAM);
1453
1454 /* Reset hyper ram. */
1455 status = flexspi_hyper_ram_reset(BOARD_FLEXSPI_PSRAM);
1456 if (status != kStatus_Success)
1457 {
1458 return status;
1459 }
1460
1461 status = flexspi_hyper_ram_get_mcr(BOARD_FLEXSPI_PSRAM, 0x0, mr0mr1);
1462 if (status != kStatus_Success)
1463 {
1464 return status;
1465 }
1466
1467 status = flexspi_hyper_ram_get_mcr(BOARD_FLEXSPI_PSRAM, 0x4, mr4mr8);
1468 if (status != kStatus_Success)
1469 {
1470 return status;
1471 }
1472
1473 /* Enable RBX, burst length set to 1K. - MR8 */
1474 mr8Val[0] = (mr4mr8[0] & 0xFF00U) >> 8U;
1475 mr8Val[0] = mr8Val[0] | 0x0F;
1476 status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x8, mr8Val);
1477 if (status != kStatus_Success)
1478 {
1479 return status;
1480 }
1481
1482 /* Set LC code to 0x04(LC=7, maximum frequency 200M) - MR0. */
1483 mr0Val[0] = mr0mr1[0] & 0x00FFU;
1484 mr0Val[0] = (mr0Val[0] & ~0x3CU) | (4U << 2U);
1485 status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x0, mr0Val);
1486 if (status != kStatus_Success)
1487 {
1488 return status;
1489 }
1490
1491 /* Set WLC code to 0x01(WLC=7, maximum frequency 200M) - MR4. */
1492 mr4Val[0] = mr4mr8[0] & 0x00FFU;
1493 mr4Val[0] = (mr4Val[0] & ~0xE0U) | (1U << 5U);
1494 status = flexspi_hyper_ram_write_mcr(BOARD_FLEXSPI_PSRAM, 0x4, mr4Val);
1495 if (status != kStatus_Success)
1496 {
1497 return status;
1498 }
1499
1500 return status;
1501 }
1502
BOARD_DeinitXip(FLEXSPI_Type * base)1503 void BOARD_DeinitXip(FLEXSPI_Type *base)
1504 {
1505 /* Wait until FLEXSPI is not busy */
1506 while (!((base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK)))
1507 {
1508 }
1509 /* Disable module during the reset procedure */
1510 base->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
1511 }
1512
BOARD_InitXip(FLEXSPI_Type * base)1513 void BOARD_InitXip(FLEXSPI_Type *base)
1514 {
1515 uint32_t status;
1516 uint32_t lastStatus;
1517 uint32_t retry;
1518
1519 /* Enable FLEXSPI module */
1520 base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
1521
1522 base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
1523 while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)
1524 {
1525 }
1526
1527 /* Need to wait DLL locked if DLL enabled */
1528 if (0U != (base->DLLCR[0] & FLEXSPI_DLLCR_DLLEN_MASK))
1529 {
1530 lastStatus = base->STS2;
1531 retry = BOARD_FLEXSPI_DLL_LOCK_RETRY;
1532 /* Wait slave delay line locked and slave reference delay line locked. */
1533 do
1534 {
1535 status = base->STS2;
1536 if ((status & (FLEXSPI_STS2_AREFLOCK_MASK | FLEXSPI_STS2_ASLVLOCK_MASK)) ==
1537 (FLEXSPI_STS2_AREFLOCK_MASK | FLEXSPI_STS2_ASLVLOCK_MASK))
1538 {
1539 /* Locked */
1540 retry = 100;
1541 break;
1542 }
1543 else if (status == lastStatus)
1544 {
1545 /* Same delay cell number in calibration */
1546 retry--;
1547 }
1548 else
1549 {
1550 retry = BOARD_FLEXSPI_DLL_LOCK_RETRY;
1551 lastStatus = status;
1552 }
1553 } while (retry > 0);
1554 /* According to ERR011377, need to delay at least 100 NOPs to ensure the DLL is locked. */
1555 for (; retry > 0U; retry--)
1556 {
1557 __NOP();
1558 }
1559 }
1560 }
1561
1562 /* BOARD_SetFlexspiClock run in RAM used to configure FlexSPI clock source and divider when XIP. */
BOARD_SetFlexspiClock(FLEXSPI_Type * base,uint32_t src,uint8_t divValue,uint8_t fracValue)1563 void BOARD_SetFlexspiClock(FLEXSPI_Type *base, uint32_t src, uint8_t divValue, uint8_t fracValue)
1564 {
1565 uint32_t pccReg;
1566
1567 if (base == FLEXSPI0)
1568 {
1569 pccReg = PCC_REG(kCLOCK_Flexspi0);
1570 if ((PCC_PCS_VAL(pccReg) != src) || PCC_PCD_VAL(pccReg) != divValue || PCC_FRAC_VAL(pccReg) != fracValue)
1571 {
1572 if (BOARD_IS_XIP_FLEXSPI0())
1573 {
1574 BOARD_DeinitXip(base);
1575 }
1576 pccReg &= ~(PCC_CLKCFG_PCD_MASK | PCC_CLKCFG_FRAC_MASK | PCC_CLKCFG_PCS_MASK);
1577 pccReg |= PCC_CLKCFG_PCD(divValue) | PCC_CLKCFG_FRAC(fracValue) | PCC_CLKCFG_PCS(src);
1578 /*
1579 * If clock is already enabled, first disable it, then set the clock
1580 * source and re-enable it.
1581 */
1582 PCC_REG(kCLOCK_Flexspi0) = pccReg & ~PCC_CLKCFG_CGC_MASK;
1583 PCC_REG(kCLOCK_Flexspi0) = pccReg;
1584 if (BOARD_IS_XIP_FLEXSPI0())
1585 {
1586 BOARD_InitXip(base);
1587 }
1588 }
1589 }
1590 else if (base == FLEXSPI1)
1591 {
1592 pccReg = PCC_REG(kCLOCK_Flexspi1);
1593 if ((PCC_PCS_VAL(pccReg) != src) || PCC_PCD_VAL(pccReg) != divValue || PCC_FRAC_VAL(pccReg) != fracValue)
1594 {
1595 /* FLEXSPI1 not for CM33 XIP. */
1596 pccReg &= ~(PCC_CLKCFG_PCD_MASK | PCC_CLKCFG_FRAC_MASK | PCC_CLKCFG_PCS_MASK);
1597 pccReg |= PCC_CLKCFG_PCD(divValue) | PCC_CLKCFG_FRAC(fracValue) | PCC_CLKCFG_PCS(src);
1598 /*
1599 * If clock is already enabled, first disable it, then set the clock
1600 * source and re-enable it.
1601 */
1602 PCC_REG(kCLOCK_Flexspi1) = pccReg & ~PCC_CLKCFG_CGC_MASK;
1603 PCC_REG(kCLOCK_Flexspi1) = pccReg;
1604 }
1605 }
1606 else
1607 {
1608 assert(false);
1609 }
1610 }
1611
1612 /* This function is used to change FlexSPI clock to a stable source before clock sources(Such as PLL and Main clock)
1613 * updating in case XIP(execute code on FLEXSPI memory.) */
BOARD_FlexspiClockSafeConfig(void)1614 void BOARD_FlexspiClockSafeConfig(void)
1615 {
1616 int freq_divider = 1;
1617
1618 /*
1619 * Move FLEXSPI clock source from main clock(old clock source for flexspi0) to FRO(192 MHz) / divider = xx MHz(new
1620 * clock source[FRO] for flexspi0) to avoid instruction/data fetch issue in XIP when updating PLL and main clock.
1621 * 6 - clock source of flexspi0 is FRO
1622 */
1623 BOARD_CalculateDivider(CLK_FRO_192MHZ, BOARD_NOR_FLASH_READ_MAXIMUM_FREQ, &freq_divider);
1624 BOARD_SetFlexspiClock(FLEXSPI0, 6U, freq_divider - 1, 0U); /* flexspi0's clock is FRO(192 MHz) / div */
1625 }
1626
1627 #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
BOARD_LPI2C_Init(LPI2C_Type * base,uint32_t clkSrc_Hz)1628 void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz)
1629 {
1630 lpi2c_master_config_t lpi2cConfig = {0};
1631
1632 /*
1633 * lpi2cConfig.debugEnable = false;
1634 * lpi2cConfig.ignoreAck = false;
1635 * lpi2cConfig.pinConfig = kLPI2C_2PinOpenDrain;
1636 * lpi2cConfig.baudRate_Hz = 100000U;
1637 * lpi2cConfig.busIdleTimeout_ns = 0;
1638 * lpi2cConfig.pinLowTimeout_ns = 0;
1639 * lpi2cConfig.sdaGlitchFilterWidth_ns = 0;
1640 * lpi2cConfig.sclGlitchFilterWidth_ns = 0;
1641 */
1642 LPI2C_MasterGetDefaultConfig(&lpi2cConfig);
1643 LPI2C_MasterInit(base, &lpi2cConfig, clkSrc_Hz);
1644 }
1645
BOARD_LPI2C_Send(LPI2C_Type * base,uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * txBuff,uint16_t txBuffSize,uint32_t flags)1646 status_t BOARD_LPI2C_Send(LPI2C_Type *base,
1647 uint8_t deviceAddress,
1648 uint32_t subAddress,
1649 uint8_t subAddressSize,
1650 uint8_t *txBuff,
1651 uint16_t txBuffSize,
1652 uint32_t flags)
1653 {
1654 lpi2c_master_transfer_t xfer;
1655
1656 xfer.flags = flags;
1657 xfer.slaveAddress = deviceAddress;
1658 xfer.direction = kLPI2C_Write;
1659 xfer.subaddress = subAddress;
1660 xfer.subaddressSize = subAddressSize;
1661 xfer.data = txBuff;
1662 xfer.dataSize = txBuffSize;
1663
1664 return LPI2C_MasterTransferBlocking(base, &xfer);
1665 }
1666
BOARD_LPI2C_Receive(LPI2C_Type * base,uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint16_t rxBuffSize,uint32_t flags)1667 status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
1668 uint8_t deviceAddress,
1669 uint32_t subAddress,
1670 uint8_t subAddressSize,
1671 uint8_t *rxBuff,
1672 uint16_t rxBuffSize,
1673 uint32_t flags)
1674 {
1675 lpi2c_master_transfer_t xfer;
1676
1677 xfer.flags = flags;
1678 xfer.slaveAddress = deviceAddress;
1679 xfer.direction = kLPI2C_Read;
1680 xfer.subaddress = subAddress;
1681 xfer.subaddressSize = subAddressSize;
1682 xfer.data = rxBuff;
1683 xfer.dataSize = rxBuffSize;
1684
1685 return LPI2C_MasterTransferBlocking(base, &xfer);
1686 }
1687
BOARD_Accel_I2C_Init(void)1688 void BOARD_Accel_I2C_Init(void)
1689 {
1690 BOARD_LPI2C_Init(BOARD_ACCEL_I2C_BASEADDR, BOARD_ACCEL_I2C_CLOCK_FREQ);
1691 }
1692
BOARD_Accel_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint32_t txBuff,uint32_t flags)1693 status_t BOARD_Accel_I2C_Send(
1694 uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint32_t txBuff, uint32_t flags)
1695 {
1696 uint8_t data = (uint8_t)txBuff;
1697
1698 return BOARD_LPI2C_Send(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, &data, 1, flags);
1699 }
1700
BOARD_Accel_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint8_t * rxBuff,uint8_t rxBuffSize,uint32_t flags)1701 status_t BOARD_Accel_I2C_Receive(uint8_t deviceAddress,
1702 uint32_t subAddress,
1703 uint8_t subaddressSize,
1704 uint8_t *rxBuff,
1705 uint8_t rxBuffSize,
1706 uint32_t flags)
1707 {
1708 return BOARD_LPI2C_Receive(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, rxBuff, rxBuffSize,
1709 flags);
1710 }
1711
BOARD_Codec_I2C_Init(void)1712 void BOARD_Codec_I2C_Init(void)
1713 {
1714 BOARD_LPI2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ);
1715 }
1716
BOARD_Codec_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,const uint8_t * txBuff,uint8_t txBuffSize,uint32_t flags)1717 status_t BOARD_Codec_I2C_Send(uint8_t deviceAddress,
1718 uint32_t subAddress,
1719 uint8_t subAddressSize,
1720 const uint8_t *txBuff,
1721 uint8_t txBuffSize,
1722 uint32_t flags)
1723 {
1724 return BOARD_LPI2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
1725 txBuffSize, flags);
1726 }
1727
BOARD_Codec_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint8_t rxBuffSize,uint32_t flags)1728 status_t BOARD_Codec_I2C_Receive(uint8_t deviceAddress,
1729 uint32_t subAddress,
1730 uint8_t subAddressSize,
1731 uint8_t *rxBuff,
1732 uint8_t rxBuffSize,
1733 uint32_t flags)
1734 {
1735 return BOARD_LPI2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize,
1736 flags);
1737 }
1738
BOARD_Display_I2C_Init(void)1739 void BOARD_Display_I2C_Init(void)
1740 {
1741 BOARD_LPI2C_Init(BOARD_DISPLAY_I2C_BASEADDR, BOARD_DISPLAY_I2C_CLOCK_FREQ);
1742 }
1743
BOARD_Display_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,const uint8_t * txBuff,uint8_t txBuffSize)1744 status_t BOARD_Display_I2C_Send(
1745 uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
1746 {
1747 return BOARD_LPI2C_Send(BOARD_DISPLAY_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
1748 txBuffSize, 0);
1749 }
1750
BOARD_Display_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint8_t rxBuffSize)1751 status_t BOARD_Display_I2C_Receive(
1752 uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
1753 {
1754 return BOARD_LPI2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize,
1755 0);
1756 }
1757
1758 #if defined(BOARD_USE_PCA6416A) && BOARD_USE_PCA6416A
1759 pca6416a_handle_t g_pca6416aHandle;
1760
BOARD_PCA6416A_I2C_Init(void)1761 void BOARD_PCA6416A_I2C_Init(void)
1762 {
1763 BOARD_LPI2C_Init(BOARD_PCA6416A_I2C, BOARD_PCA6416A_I2C_CLOCK_FREQ);
1764 }
1765
BOARD_PCA6416A_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,const uint8_t * txBuff,uint8_t txBuffSize,uint32_t flags)1766 status_t BOARD_PCA6416A_I2C_Send(uint8_t deviceAddress,
1767 uint32_t subAddress,
1768 uint8_t subAddressSize,
1769 const uint8_t *txBuff,
1770 uint8_t txBuffSize,
1771 uint32_t flags)
1772 {
1773 return BOARD_LPI2C_Send(BOARD_PCA6416A_I2C, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
1774 txBuffSize, flags);
1775 }
1776
BOARD_PCA6416A_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint8_t rxBuffSize,uint32_t flags)1777 status_t BOARD_PCA6416A_I2C_Receive(uint8_t deviceAddress,
1778 uint32_t subAddress,
1779 uint8_t subAddressSize,
1780 uint8_t *rxBuff,
1781 uint8_t rxBuffSize,
1782 uint32_t flags)
1783 {
1784 return BOARD_LPI2C_Receive(BOARD_PCA6416A_I2C, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize,
1785 flags);
1786 }
1787
BOARD_InitPCA6416A(pca6416a_handle_t * handle)1788 void BOARD_InitPCA6416A(pca6416a_handle_t *handle)
1789 {
1790 BOARD_PCA6416A_I2C_Init();
1791
1792 static const pca6416a_config_t config = {
1793 .i2cAddr = BOARD_PCA6416A_I2C_ADDR,
1794 .I2C_SendFunc = BOARD_PCA6416A_I2C_Send,
1795 .I2C_ReceiveFunc = BOARD_PCA6416A_I2C_Receive,
1796 };
1797
1798 PCA6416A_Init(handle, &config);
1799 }
1800
1801 /* Set I2C0 PCA6416 IO9(PTH9_MIPI_SWITH) to high to select MIPI DSI panel path for uboot(running on a35) */
BOARD_InitMipiDsiPins(void)1802 void BOARD_InitMipiDsiPins(void)
1803 {
1804 BOARD_InitPCA6416A(&g_pca6416aHandle);
1805 PCA6416A_SetPins(&g_pca6416aHandle, (1U << BOARD_PCA6416A_MIPI_SWITCH));
1806 PCA6416A_SetDirection(&g_pca6416aHandle, (1U << BOARD_PCA6416A_MIPI_SWITCH), kPCA6416A_Output);
1807 }
1808 #endif /* BOARD_USE_PCA6416A. */
1809
1810 #if defined(BOARD_USE_TPM) && BOARD_USE_TPM
1811 /* Set TPM0_CH2 to full duty cycle to enable backlight at highest brightness for uboot(running on a35) */
BOARD_EnableMipiDsiBacklight(void)1812 void BOARD_EnableMipiDsiBacklight(void)
1813 {
1814 tpm_config_t tpmInfo;
1815 tpm_chnl_pwm_signal_param_t pwmChannelConfig = {
1816 .chnlNumber = (tpm_chnl_t)TPM0_CH2,
1817 .level = kTPM_HighTrue,
1818 .dutyCyclePercent = FULL_DUTY_CYCLE,
1819 };
1820
1821 TPM_GetDefaultConfig(&tpmInfo);
1822 TPM_Init(TPM0, (void *)&tpmInfo);
1823 TPM_SetupPwm(TPM0, (void *)&pwmChannelConfig, 1, kTPM_EdgeAlignedPwm, CLOCK_GetTpmClkFreq(0U), TPM0_CH2_PWM_FREQ);
1824 TPM_StartTimer(TPM0, kTPM_SystemClock);
1825 }
1826 #endif /* BOARD_USE_TPM. */
1827 #endif /* SDK_I2C_BASED_COMPONENT_USED */
1828
1829 /* Init LPAV domain clock, prepare for DDR retention exit */
BOARD_LpavInit()1830 void BOARD_LpavInit()
1831 {
1832 int i;
1833
1834 /* PLL4 */
1835 for (i = 0; i < 9; i++)
1836 {
1837 W32(pll4[i][0], pll4[i][1]);
1838 }
1839
1840 /* wait for PLL4 lock */
1841 while (!(R32(pll4[8][0]) & BIT(24)))
1842 {
1843 }
1844
1845 /* restore the PLL4 PFDs */
1846 W32(pll4[9][0], pll4[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
1847 W32(pll4[9][0], pll4[9][1]);
1848
1849 /* wait for the PFD is stable */
1850 while (!(R32(pll4[9][0]) & PFD_VALID_MASK))
1851 {
1852 }
1853
1854 /* CGC2 restore */
1855 for (i = 0; i < ARRAY_SIZE(cgc2); i++)
1856 {
1857 W32(cgc2[i][0], cgc2[i][1]);
1858 }
1859
1860 /* PCC5 restore */
1861 for (i = 0; i < ARRAY_SIZE(pcc5_0); i++)
1862 {
1863 if (pcc5_0[i][1] & PCC_CLKCFG_PR_MASK)
1864 {
1865 W32(pcc5_0[i][0], pcc5_0[i][1]);
1866 }
1867 }
1868
1869 for (i = 0; i < ARRAY_SIZE(pcc5_1); i++)
1870 {
1871 if (pcc5_1[i][1] & PCC_CLKCFG_PR_MASK)
1872 {
1873 W32(pcc5_1[i][0], pcc5_1[i][1]);
1874 }
1875 }
1876
1877 /* LPAV_SIM */
1878 for (i = 0; i < ARRAY_SIZE(lpav_sim); i++)
1879 {
1880 W32(lpav_sim[i][0], lpav_sim[i][1]);
1881 }
1882
1883 /* Config the LPAV PLL4 and DDR clock for the desired LPDDR operating frequency. */
1884 PCC5->PCC_LPDDR4 |= PCC5_PCC_LPDDR4_CGC_MASK;
1885
1886 /* Write PCC5.PCC_LPDDR4[SWRST] to 1b'1 to release LPDDR from reset. */
1887 PCC5->PCC_LPDDR4 |= PCC5_PCC_LPDDR4_SWRST_MASK;
1888 }
1889
1890 /* Restore DDR controller registers */
ddrInit(uint32_t dram_class,struct dram_cfg * dram_timing_cfg)1891 static void ddrInit(uint32_t dram_class, struct dram_cfg *dram_timing_cfg)
1892 {
1893 int i;
1894
1895 /* restore the ddr ctl config */
1896 for (i = 0; i < CTL_NUM; i++)
1897 {
1898 W32(LPDDR_BASE + i * 4, dram_timing_cfg->ctl_cfg[i]);
1899 }
1900
1901 /* load the PI registers */
1902 for (i = 0; i < PI_NUM; i++)
1903 {
1904 W32(LPDDR_BASE + 0x2000 + i * 4, dram_timing_cfg->pi_cfg[i]);
1905 }
1906
1907 /* restore all PHY registers for all the fsp. */
1908 LPDDR->DENALI_PHY_1537 = LPDDR_DENALI_PHY_1537_PHY_FREQ_SEL_MULTICAST_EN_MASK;
1909
1910 /* restore all the phy configs */
1911 for (i = 0; i < PHY_NUM; i++)
1912 {
1913 if (i >= 121 && i <= 255)
1914 continue;
1915 if (i >= 377 && i <= 511)
1916 continue;
1917 if (i >= 633 && i <= 767)
1918 continue;
1919 if (i >= 889 && i <= 1023)
1920 continue;
1921 if (i >= 1065 && i <= 1279)
1922 continue;
1923 if (i >= 1321 && i <= 1535)
1924 continue;
1925 W32(LPDDR_BASE + 0x4000 + i * 4, dram_timing_cfg->phy_full[i]);
1926 }
1927
1928 if (dram_class == LPDDR4_TYPE)
1929 {
1930 /* restore only the diff. */
1931 LPDDR->DENALI_PHY_1537 = 0;
1932 for (i = 0; i < PHY_DIFF_NUM; i++)
1933 W32(LPDDR_BASE + 0x4000 + freq_specific_reg_array[i] * 4, dram_timing_cfg->phy_diff[i]);
1934 }
1935
1936 /* Re-enable MULTICAST mode */
1937 LPDDR->DENALI_PHY_1537 = LPDDR_DENALI_PHY_1537_PHY_FREQ_SEL_MULTICAST_EN(1);
1938 }
1939
BOARD_DdrSave(void)1940 void BOARD_DdrSave(void)
1941 {
1942 uint32_t i;
1943 struct dram_timing_info *Info;
1944 Info = (struct dram_timing_info *)(SAVED_DRAM_DATA_BASE_ADDR_FROM_TFA);
1945
1946 /*
1947 * Save DDR Controller & PHY config.
1948 * Set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=1. Read and store all the PHY registers
1949 * for F2 into phy_f1_cfg, then read/store the diff between F1 & F2 into phy_f2_cfg.
1950 */
1951
1952 /* save the ctl registers */
1953 for (i = 0; i < CTL_NUM; i++)
1954 {
1955 dram_timing_cfg->ctl_cfg[i] = R32(LPDDR_BASE + i * 4);
1956 }
1957 dram_timing_cfg->ctl_cfg[0] = dram_timing_cfg->ctl_cfg[0] & 0xFFFFFFFE;
1958
1959 /* save th ePIl registers */
1960 for (i = 0; i < PI_NUM; i++)
1961 {
1962 dram_timing_cfg->pi_cfg[i] = R32(LPDDR_BASE + 0x2000 + i * 4);
1963 }
1964
1965 /* Read and store all PHY registers. full array is a full copy for all the setpoint */
1966 if (dram_class == LPDDR4_TYPE)
1967 {
1968 W32(LPDDR_BASE + 0x5804U, 0x10000);
1969 for (i = 0; i < PHY_NUM; i++)
1970 {
1971 /* Make sure MULTICASE is enabled */
1972 if (i == 1537)
1973 {
1974 dram_timing_cfg->phy_full[i] = 0x100;
1975 }
1976 else
1977 {
1978 dram_timing_cfg->phy_full[i] = R32(LPDDR_BASE + 0x4000 + i * 4);
1979 }
1980 }
1981 /* set PHY_FREQ_SEL_MULTICAST_EN=0 & PHY_FREQ_SEL_INDEX=0. Read and store only the diff. */
1982 W32(LPDDR_BASE + 0x5804U, 0x0);
1983 /* save only the frequency based diff config to save memory */
1984 for (i = 0; i < PHY_DIFF_NUM; i++)
1985 {
1986 dram_timing_cfg->phy_diff[i] = R32(LPDDR_BASE + 0x4000 + freq_specific_reg_array[i] * 4);
1987 }
1988 }
1989 else
1990 {
1991 /* LPDDR3, only f1 need to save */
1992 for (i = 0; i < Info->phy_f1_cfg_num; i++)
1993 {
1994 Info->phy_f1_cfg[i].val = R32(Info->phy_f1_cfg[i].reg);
1995 }
1996 }
1997 }
1998
1999 /* Store LPAV domain clock before DDR enter retention */
BOARD_LpavSave(void)2000 void BOARD_LpavSave(void)
2001 {
2002 uint32_t i;
2003 uint32_t val;
2004
2005 /* CGC2 save */
2006 for (i = 0; i < ARRAY_SIZE(cgc2); i++)
2007 cgc2[i][1] = R32(cgc2[i][0]);
2008
2009 /* PLL4 */
2010 for (i = 0; i < ARRAY_SIZE(pll4); i++)
2011 pll4[i][1] = R32(pll4[i][0]);
2012
2013 /*
2014 * PCC5 save
2015 * Note: Check PR bit when save/store PCC5
2016 * When some module is fused, the PCC with PR=0 can't be written.
2017 */
2018
2019 for (i = 0; i < ARRAY_SIZE(pcc5_0); i++)
2020 {
2021 val = R32(pcc5_0[i][0]);
2022 pcc5_0[i][1] = 0U;
2023 if (val & PCC_CLKCFG_PR_MASK)
2024 {
2025 pcc5_0[i][1] = val;
2026 }
2027 }
2028
2029 for (i = 0; i < ARRAY_SIZE(pcc5_1); i++)
2030 {
2031 val = R32(pcc5_1[i][0]);
2032 pcc5_1[i][1] = 0U;
2033 if (val & PCC_CLKCFG_PR_MASK)
2034 {
2035 pcc5_1[i][1] = val;
2036 }
2037 }
2038
2039 /* LPAV SIM save */
2040 for (i = 0; i < ARRAY_SIZE(lpav_sim); i++)
2041 lpav_sim[i][1] = R32(lpav_sim[i][0]);
2042 }
2043
2044 /* Disable low power auto self-refresh for DRAM */
BOARD_DramLpAutoDisable(void)2045 void BOARD_DramLpAutoDisable(void)
2046 {
2047 dram_timing_cfg = (struct dram_cfg *)(SAVED_DRAM_DATA_BASE_ADDR_FROM_TFA + SAVED_DRAM_TIMING_INFO_SIZE_FROM_TFA);
2048 dram_class = (LPDDR->DENALI_CTL[0] >> 8) & 0xF;
2049 uint32_t lp_auto_en;
2050
2051 /* LP AUTO ENTRY EN, Bits[27, 24], Set different bit to enable matching */
2052 lp_auto_en = (R32(LPDDR_BASE + DENALI_CTL_146) & (LP_AUTO_ENTRY_EN << 24));
2053 /* Save initial config */
2054 dram_ctl_143 = R32(LPDDR_BASE + DENALI_CTL_143);
2055
2056 /* Set LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2 to Maximum */
2057 SETBIT32(LPDDR_BASE + DENALI_CTL_143, LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2_NUM << 24);
2058
2059 if (lp_auto_en && !dram_auto_lp_true)
2060 {
2061 /* Save DDRC auto low-power mode parameter */
2062 dram_timing_cfg->auto_lp_cfg[0] = R32(LPDDR_BASE + DENALI_CTL_144);
2063 dram_timing_cfg->auto_lp_cfg[1] = R32(LPDDR_BASE + DENALI_CTL_147);
2064 dram_timing_cfg->auto_lp_cfg[2] = R32(LPDDR_BASE + DENALI_CTL_146);
2065
2066 /*
2067 * Disable DDRC auto low-power mode interface, controls self-refresh long with memory and controller clock
2068 * gating. or self-refresh power-down long with mem-ory and controller clock gating.
2069 */
2070 CLRBIT32(LPDDR_BASE + DENALI_CTL_146, LP_AUTO_ENTRY_EN << 24);
2071
2072 /* Read any location to get DRAM out of Self-refresh */
2073 R32(0x80000000);
2074 /* Roll check [LP_STATE_CS0] and [LP_STATE_CS1] whether DRAM is out of self-refresh */
2075 while ((R32(LPDDR_BASE + DENALI_CTL_146) & 0x004F4F00) != 0x00404000)
2076 {
2077 ;
2078 }
2079 /* Disable DDRC auto low-power exit */
2080 CLRBIT32(LPDDR_BASE + DENALI_CTL_147, LP_AUTO_EXIT_EN);
2081
2082 /* update dram low power mode flag */
2083 dram_auto_lp_true = true;
2084 }
2085 }
2086
2087 /* Enable low power auto self-refresh for DRAM */
BOARD_DramLpAutoEnabble(void)2088 void BOARD_DramLpAutoEnabble(void)
2089 {
2090 /* restore ctl config */
2091 W32(LPDDR_BASE + DENALI_CTL_143, dram_ctl_143);
2092
2093 if (dram_auto_lp_true)
2094 {
2095 /* Now, DRAM is active state, switch back to auto low-power self refresh mode */
2096 /* Roll check [LP_STATE_CS0] and [LP_STATE_CS1] whether DRAM is out of self-refresh */
2097 while ((R32(LPDDR_BASE + DENALI_CTL_146) & 0x004F4F00) != 0x00404000)
2098 {
2099 ;
2100 }
2101 /* Reconfigure DENALI_CTL_144 [LPI_WAKEUP_EN[5:0]] bit LPI_WAKEUP_EN[3] = 1b'1 */
2102 W32(LPDDR_BASE + DENALI_CTL_144, dram_timing_cfg->auto_lp_cfg[0]);
2103 W32(LPDDR_BASE + DENALI_CTL_147, dram_timing_cfg->auto_lp_cfg[1]);
2104 /* Re-enable DDRC auto low-power mode interface */
2105 W32(LPDDR_BASE + DENALI_CTL_146, dram_timing_cfg->auto_lp_cfg[2]);
2106
2107 /* update dram low power mode flag */
2108 dram_auto_lp_true = false;
2109 }
2110 }
2111
2112 /* Program DDR controller to let DRAM enter self-refresh */
BOARD_DramEnterRetention(void)2113 void BOARD_DramEnterRetention(void)
2114 {
2115 uint32_t val;
2116
2117 /* Disable DRAM auto self-refresh if if it is enabled */
2118 BOARD_DramLpAutoDisable();
2119
2120 /* Save lpav context */
2121 BOARD_LpavSave();
2122
2123 /* Save DDR controller registers */
2124 BOARD_DdrSave();
2125
2126 SETBIT32(LPDDR_BASE + DENALI_CTL_144, BIT(3) << LPI_WAKEUP_EN_SHIFT);
2127
2128 /*
2129 * a. Config SIM_LPAV LPDDR_CTRL[LPDDR_AUTO_LP_MODE_DISABLE] to 1b'0(enable the logic to
2130 * to automatic handles low power entry/exit. This is the recommended option over handling
2131 * through software.
2132 * b. Config the SIM_LPAV LPDDR_CTRL[SOC_LP_CMD] to 6b'101001(encoding for self_refresh with
2133 * both DDR controller and DRAM clock gate. THis is mandatory since LPPDR logic will be power
2134 * gated).
2135 */
2136 SIM_LPAV->LPDDR_CTRL &= ~SIM_LPAV_LPDDR_CTRL_LPDDR_AUTO_LP_MODE_DISABLE_MASK;
2137 val = SIM_LPAV->LPDDR_CTRL;
2138 val &= -SIM_LPAV_LPDDR_CTRL_SOC_LP_CMD(0x3f);
2139 val |= SIM_LPAV_LPDDR_CTRL_SOC_LP_CMD(0x29);
2140 SIM_LPAV->LPDDR_CTRL = val;
2141
2142 SIM_LPAV->LPDDR_CTRL2 = SIM_LPAV_LPDDR_CTRL2_LPDDR_EN_CLKGATE_MASK;
2143
2144 /* Program Idle count to enter LP state */
2145 W32(LPDDR_BASE + DENALI_CTL_148, R32(LPDDR_BASE + DENALI_CTL_148) | 0x0F0F000F);
2146
2147 /* Enable Mem clk gating */
2148 W32(LPDDR_BASE + DENALI_CTL_147, R32(LPDDR_BASE + DENALI_CTL_147) | 0x700);
2149
2150 /* Enable Auto entry */
2151 W32(LPDDR_BASE + DENALI_CTL_146, R32(LPDDR_BASE + DENALI_CTL_146) | 0x0F000000);
2152
2153 /* Wait for controller to enter SRPD with Mem and CTl clk gating */
2154 while ((R32(LPDDR_BASE + DENALI_CTL_146) & 0x7F00) != 0x4F00)
2155 {
2156 }
2157 }
2158
2159 /* Program DDR controller to let DRAM exit from self-refresh */
BOARD_DramExitRetention(uint32_t dram_class,struct dram_cfg * dram_timing_cfg)2160 void BOARD_DramExitRetention(uint32_t dram_class, struct dram_cfg *dram_timing_cfg)
2161 {
2162 uint32_t val;
2163 int status;
2164
2165 /* Reload the LPDDR CTL/PI/PHY register */
2166 ddrInit(dram_class, dram_timing_cfg);
2167
2168 if (dram_class == LPDDR4_TYPE)
2169 {
2170 /* a. FIXME Set PHY_SET_DFI_INPUT_N parameters to 4'h1. LPDDR4 only */
2171 W32(LPDDR_BASE + DENALI_PHY_1559, 0x01010101);
2172
2173 /* b. CTL PWRUP_SREFRESH_EXIT=1'b0 for disabling self refresh exit from controller. */
2174 /* c. PI_PWRUP_SELF_REF_EXIT=1, PI_MC_PWRUP_SELF_REF_EXIT=0 for enabling self refresh exit from PI */
2175 /* c. PI_INT_LVL_EN=0 to skip Initialization trainings. */
2176 /*
2177 * d. PI_WRLVL_EN_F0/1/2= PI_CALVL_EN_F0/1/2= PI_RDLVL_EN_F0/1/2= PI_RDLVL_GATE_EN_F0/1/2=
2178 * PI_WDQLVL_EN_F0/1/2=0x2. Enable non initialization trainings.
2179 */
2180 /* e. PI_PWRUP_SREFRESH_EXIT_CS=0xF */
2181 /* f. PI_DLL_RESET=0x1 */
2182 SETBIT32(LPDDR_BASE + DENALI_PI_137, 0x1); /* PI_DLL_RESET=1 */
2183 SETBIT32(LPDDR_BASE + DENALI_PI_132, 0x01000000); /* PI_PWRUP_SELF_REF_EXIT = 1 */
2184 CLRBIT32(LPDDR_BASE + DENALI_PI_132, BIT(16)); /* PI_MC_PWRUP_SELF_REF_EXIT = 0 */
2185 LPDDR->DENALI_PI_4 &= ~LPDDR_DENALI_PI_4_PI_INIT_LVL_EN_MASK; /* PI_INT_LVL_EN = 0 */
2186 LPDDR->DENALI_PI_174 |= (LPDDR_DENALI_PI_174_PI_WRLVL_EN_F0(3) |
2187 LPDDR_DENALI_PI_174_PI_WRLVL_EN_F1(3)); /* PI_WRLVL_EN_F0 = 3, PI_WRLVL_EN_F1 = 3 */
2188 LPDDR->DENALI_PI_175 |= LPDDR_DENALI_PI_175_PI_WRLVL_EN_F2(3); /* PI_WRLVL_EN_F2 = 3 */
2189 LPDDR->DENALI_PI_191 |= (LPDDR_DENALI_PI_191_PI_CALVL_EN_F0(3) |
2190 LPDDR_DENALI_PI_191_PI_CALVL_EN_F1(3)); /* PI_CALVL_EN_F0 = 3, PI_CALVL_EN_F1 = 3 */
2191 LPDDR->DENALI_PI_192 |= LPDDR_DENALI_PI_192_PI_CALVL_EN_F2_MASK; /* PI_CALVL_EN_F2 = 3 */
2192 LPDDR->DENALI_PI_212 |= LPDDR_DENALI_PI_212_PI_WDQLVL_EN_F0(3); /* PI_WDQLVL_EN_F0 = 3 */
2193 LPDDR->DENALI_PI_214 |= LPDDR_DENALI_PI_214_PI_WDQLVL_EN_F1(3); /* PI_WDQLVL_EN_F1 = 3 */
2194 LPDDR->DENALI_PI_217 |= LPDDR_DENALI_PI_217_PI_WDQLVL_EN_F2(3); /* PI_WDQLVL_EN_F2 = 3 */
2195 LPDDR->DENALI_PI_181 |=
2196 (LPDDR_DENALI_PI_181_PI_RDLVL_EN_F0(3) |
2197 LPDDR_DENALI_PI_181_PI_RDLVL_GATE_EN_F0(3)); /* PI_EDLVL_EN_F0 = 3, PI_EDLVL_GATE_EN_F0 = 3 */
2198 LPDDR->DENALI_PI_182 |=
2199 (LPDDR_DENALI_PI_182_PI_RDLVL_EN_F1(3) | LPDDR_DENALI_PI_182_PI_RDLVL_GATE_EN_F1(3) |
2200 LPDDR_DENALI_PI_182_PI_RDLVL_EN_F2(3) |
2201 LPDDR_DENALI_PI_182_PI_RDLVL_GATE_EN_F2(
2202 3)); /* PI_RDLVL_EN_F1 = 3, PI_RDLVL_GATE_EN_F1 = 3, PI_RDLVL_EN_F2 = 3, PI_RDLVL_GATE_EN_F2 = 3 */
2203 SETBIT32(LPDDR_BASE + DENALI_PI_134, 0x000F0000); /* PI_PWRUP_SREFRESH_EXIT_CS = 0xF */
2204 }
2205 else
2206 {
2207 SETBIT32(LPDDR_BASE + DENALI_PI_137, 0x1); /* PI_DLL_RESET=1 */
2208 SETBIT32(LPDDR_BASE + DENALI_PI_132, 0x01000000); /* PI_PWRUP_SELF_REF_EXIT=1 */
2209 CLRBIT32(LPDDR_BASE + DENALI_PI_132, BIT(16)); /* PI_MC_PWRUP_SELF_REF_EXIT=0 */
2210 LPDDR->DENALI_PI_4 &= ~LPDDR_DENALI_PI_4_PI_INIT_LVL_EN_MASK; /* PI_INT_LVL_EN = 0 */
2211 LPDDR->DENALI_PI_174 |= LPDDR_DENALI_PI_174_PI_WRLVL_EN_F0(3); /* PI_WRLVL_EN_F0=3 */
2212 LPDDR->DENALI_PI_191 |= LPDDR_DENALI_PI_191_PI_CALVL_EN_F0(3); /* PI_CALVL_EN_F0=3 */
2213 LPDDR->DENALI_PI_181 |=
2214 (LPDDR_DENALI_PI_181_PI_RDLVL_EN_F0(3) |
2215 LPDDR_DENALI_PI_181_PI_RDLVL_GATE_EN_F0(3)); /* PI_RDLVL_EN_F0=3,PI_RDLVL_GATE_EN_F0=3 */
2216 SETBIT32(LPDDR_BASE + DENALI_PI_134, 0x000F0000); /* PI_PWRUP_SREFRESH_EXIT_CS=0xF */
2217 }
2218
2219 W32(LPDDR_BASE + DENALI_CTL_144, 0x00002D00);
2220
2221 /* Force in-order AXI read data */
2222 W32(LPDDR_BASE + DENALI_CTL_144, 0x1);
2223
2224 /*
2225 * Disable special R/W group switches so that R/W group placement is always
2226 * at END of R/W group.
2227 */
2228 LPDDR->DENALI_CTL[249] = 0x0;
2229
2230 /* Reduce time for IO pad calibration */
2231 W32(LPDDR_BASE + DENALI_PHY_1590, 0x01000000);
2232
2233 LPDDR->DENALI_CTL[25] = LPDDR_DENALI_CTL_FREQ_CHANGE_TYPE_F1(1) | LPDDR_DENALI_CTL_FREQ_CHANGE_TYPE_F2(2);
2234
2235 /* PD disable */
2236 W32(LPDDR_BASE + DENALI_CTL_153, 0x04040000);
2237
2238 status = UPOWER_SetDDRRetention(RTD_DOMAIN, false);
2239 if (status != 0)
2240 {
2241 assert(false);
2242 }
2243
2244 /* Disable automatic LP entry and PCPCS modes LP_AUTO_ENTRY_EN to 1b'0, PCPCS_PD_EN to 1b'0 */
2245 if (dram_class == LPDDR4_TYPE)
2246 {
2247 /* Write PI START parameter to 1'b1 */
2248 LPDDR->DENALI_PI_0 = LPDDR_DENALI_PI_0_PI_START_MASK | LPDDR_DENALI_PI_0_PI_DRAM_CLASS(0xb);
2249
2250 /* Write CTL START parameter to 1'b1 */
2251 LPDDR->DENALI_CTL[0] = LPDDR_DENALI_CTL_START_MASK | LPDDR_DENALI_CTL_DRAM_CLASS(0xb);
2252 }
2253 else
2254 {
2255 /* Write PI START parameter to 1'b1 */
2256 LPDDR->DENALI_PI_0 = LPDDR_DENALI_PI_0_PI_START_MASK | LPDDR_DENALI_PI_0_PI_DRAM_CLASS(0x7);
2257
2258 /* Write CTL START parameter to 1'b1 */
2259 LPDDR->DENALI_CTL[0] = LPDDR_DENALI_CTL_START_MASK | LPDDR_DENALI_CTL_DRAM_CLASS(0x7);
2260 }
2261
2262 /* DENALI_CTL_266: Wait for INT_STATUS_INIT=0x2 */
2263 do
2264 {
2265 val = (R32(LPDDR_BASE + DENALI_CTL_266) >> 8) & 0xFF;
2266 } while (val != 0x2);
2267
2268 /* Run SW trainings by setting PI_CALVL_REQ,PI_WRLVL_REQ,PI_RDLVL_GATE_REQ,PI_RDLVL_REQ,PI_WDQLVL_REQ(NA for LPDDR3)
2269 * in same order. */
2270 if (dram_class == LPDDR4_TYPE)
2271 {
2272 SETBIT32(LPDDR_BASE + DENALI_PI_52, 0x10000); /* CALVL */
2273 SETBIT32(LPDDR_BASE + DENALI_PI_26, 0x100); /* WRLVL */
2274 SETBIT32(LPDDR_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
2275 SETBIT32(LPDDR_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
2276 SETBIT32(LPDDR_BASE + DENALI_PI_65, 0x10000); /* WDQLVL */
2277
2278 /* Wait for trainings to get complete by polling PI_INT_STATUS */
2279 while ((R32(LPDDR_BASE + DENALI_PI_77) & 0x07E00000) != 0x07E00000)
2280 {
2281 }
2282 }
2283 else
2284 {
2285 SETBIT32(LPDDR_BASE + DENALI_PI_52, 0x10000); /* CALVL */
2286 SETBIT32(LPDDR_BASE + DENALI_PI_26, 0x100); /* WRLVL */
2287 SETBIT32(LPDDR_BASE + DENALI_PI_33, 0x10000); /* RDGATE */
2288 SETBIT32(LPDDR_BASE + DENALI_PI_33, 0x100); /* RDQLVL */
2289 while ((R32(LPDDR_BASE + DENALI_PI_77) & 0x05E00000) != 0x05E00000)
2290 {
2291 }
2292 }
2293 BOARD_DramLpAutoEnabble();
2294 }
2295
2296 /* put ddr into self-refresh immediately */
BOARD_DDREnterSelfRefresh()2297 void BOARD_DDREnterSelfRefresh()
2298 {
2299 uint32_t val;
2300 val = R32(LPDDR_BASE + DENALI_CTL_137);
2301 val &= ~LPAV_LPDDR_CTRL_LP_CMD(0x7f);
2302 val |= LPAV_LPDDR_CTRL_LP_CMD(0x51);
2303
2304 W32(LPDDR_BASE + DENALI_CTL_137, val);
2305
2306 /* wait low power state transition */
2307 while ((R32(LPDDR_BASE + DENALI_CTL_146) & 0x400) == 0)
2308 {
2309 ;
2310 }
2311 }
2312
2313 /* let ddr exit self-refresh immediately */
BOARD_DDRExitSelfRefresh()2314 void BOARD_DDRExitSelfRefresh()
2315 {
2316 uint32_t val;
2317 val = R32(LPDDR_BASE + DENALI_CTL_137);
2318 val &= ~LPAV_LPDDR_CTRL_LP_CMD(0x7f);
2319 val |= LPAV_LPDDR_CTRL_LP_CMD(0x2);
2320
2321 W32(LPDDR_BASE + DENALI_CTL_137, val);
2322 }
2323