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