1 /*
2  * Copyright 2018-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_common.h"
9 #include "fsl_debug_console.h"
10 #include "fsl_rdc.h"
11 #include "fsl_iomuxc.h"
12 #include "pin_mux.h"
13 #include "board.h"
14 #include "fsl_clock.h"
15 
16 /*******************************************************************************
17  * Variables
18  ******************************************************************************/
19 
20 /*******************************************************************************
21  * Code
22  ******************************************************************************/
23 /* Initialize debug console. */
BOARD_InitDebugConsole(void)24 void BOARD_InitDebugConsole(void)
25 {
26     uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
27     CLOCK_EnableClock(kCLOCK_Uart4);
28     DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
29 }
30 /* Initialize MPU, configure non-cacheable memory */
BOARD_InitMemory(void)31 void BOARD_InitMemory(void)
32 {
33 #if defined(__CC_ARM) || defined(__ARMCC_VERSION)
34     extern uint32_t Load$$LR$$LR_cache_region$$Base[];
35     extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
36     uint32_t cacheStart = (uint32_t)Load$$LR$$LR_cache_region$$Base;
37     uint32_t size       = (cacheStart < 0x20000000U) ? (0) : ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit - cacheStart);
38 #else
39     extern uint32_t __CACHE_REGION_START[];
40     extern uint32_t __CACHE_REGION_SIZE[];
41     uint32_t cacheStart = (uint32_t)__CACHE_REGION_START;
42     uint32_t size       = (uint32_t)__CACHE_REGION_SIZE;
43 #endif
44     uint32_t i = 0;
45     /* Make sure outstanding transfers are done. */
46     __DMB();
47     /* Disable the MPU. */
48     MPU->CTRL = 0;
49 
50     /*
51      *  The ARMv7-M default address map define the address space 0x20000000 to 0x3FFFFFFF as SRAM with Normal type, but
52      *  there the address space 0x28000000 ~ 0x3FFFFFFF has been physically mapped to smart subsystems, so there need
53      *  change the default memory attributes.
54      *  Since the base address of MPU region should be multiples of region size, to make it simple, the MPU region 0 set
55      *  the all 512M of SRAM space with device attributes, then disable subregion 0 and 1 (address space 0x20000000 ~
56      *  0x27FFFFFF) to use the
57      *  background memory attributes.
58      */
59 
60     /* Select Region 0 and set its base address to the M4 code bus start address. */
61     MPU->RBAR = (0x20000000U & MPU_RBAR_ADDR_Msk) | MPU_RBAR_VALID_Msk | (0 << MPU_RBAR_REGION_Pos);
62 
63     /* Region 0 setting:
64      * 1) Disable Instruction Access;
65      * 2) AP = 011b, full access;
66      * 3) Non-shared device;
67      * 4) Region Not Shared;
68      * 5) Sub-Region 0,1 Disabled;
69      * 6) MPU Protection Region size = 512M byte;
70      * 7) Enable Region 0.
71      */
72     MPU->RASR = (0x1 << MPU_RASR_XN_Pos) | (0x3 << MPU_RASR_AP_Pos) | (0x2 << MPU_RASR_TEX_Pos) |
73                 (0x3 << MPU_RASR_SRD_Pos) | (28 << MPU_RASR_SIZE_Pos) | MPU_RASR_ENABLE_Msk;
74 
75     /*
76      *  Non-cacheable area is provided in DDR memory, the DDR region 2MB - 128MB totally 126MB is revserved for CM4
77      *  cores. You can put global or static uninitialized variables in NonCacheable section(initialized variables in
78      *  NonCacheable.init section) to make them uncacheable. Since the base address of MPU region should be multiples of
79      * region size,
80      *  to make it simple, the MPU region 1 & 2 set all DDR address space 0x40000000 ~ 0xBFFFFFFF to be non-cacheable).
81      *  Then MPU region 3 set the text and data section to be cacheable if the program running on DDR.
82      *  The cacheable area base address should be multiples of its size in linker file, they can be modified per your
83      * needs.
84      */
85 
86     /* Select Region 1 and set its base address to the DDR start address. */
87     MPU->RBAR = (0x40000000U & MPU_RBAR_ADDR_Msk) | MPU_RBAR_VALID_Msk | (1 << MPU_RBAR_REGION_Pos);
88 
89     /* Region 1 setting:
90      * 1) Enable Instruction Access;
91      * 2) AP = 011b, full access;
92      * 3) Shared Device;
93      * 4) MPU Protection Region size = 1024M byte;
94      * 5) Enable Region 1.
95      */
96     MPU->RASR = (0x3 << MPU_RASR_AP_Pos) | (0x1 << MPU_RASR_B_Pos) | (29 << MPU_RASR_SIZE_Pos) | MPU_RASR_ENABLE_Msk;
97 
98     /* Select Region 2 and set its base address to the DDR start address. */
99     MPU->RBAR = (0x80000000U & MPU_RBAR_ADDR_Msk) | MPU_RBAR_VALID_Msk | (2 << MPU_RBAR_REGION_Pos);
100 
101     /* Region 2 setting:
102      * 1) Enable Instruction Access;
103      * 2) AP = 011b, full access;
104      * 3) Shared Device;
105      * 4) MPU Protection Region size = 1024M byte;
106      * 5) Enable Region 2.
107      */
108     MPU->RASR = (0x3 << MPU_RASR_AP_Pos) | (0x1 << MPU_RASR_B_Pos) | (29 << MPU_RASR_SIZE_Pos) | MPU_RASR_ENABLE_Msk;
109 
110     while ((size >> i) > 0x1U)
111     {
112         i++;
113     }
114 
115     /* If run on DDR, configure text and data section to be cacheable */
116     if (i != 0)
117     {
118         /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */
119         assert((size & (size - 1)) == 0);
120         assert(!(cacheStart % size));
121         assert(size == (uint32_t)(1 << i));
122         assert(i >= 5);
123 
124         /* Select Region 3 and set its base address to the cache able region start address. */
125         MPU->RBAR = (cacheStart & MPU_RBAR_ADDR_Msk) | MPU_RBAR_VALID_Msk | (3 << MPU_RBAR_REGION_Pos);
126 
127         /* Region 3 setting:
128          * 1) Enable Instruction Access;
129          * 2) AP = 011b, full access;
130          * 3) Outer and inner Cacheable, write and read allocate;
131          * 4) Region Not Shared;
132          * 5) All Sub-Region Enabled;
133          * 6) MPU Protection Region size get from linker file;
134          * 7) Enable Region 3.
135          */
136         MPU->RASR = (0x3 << MPU_RASR_AP_Pos) | (0x1 << MPU_RASR_TEX_Pos) | (0x1 << MPU_RASR_C_Pos) |
137                     (0x1 << MPU_RASR_B_Pos) | ((i - 1) << MPU_RASR_SIZE_Pos) | MPU_RASR_ENABLE_Msk;
138     }
139 
140     /* Enable Privileged default memory map and the MPU. */
141     MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;
142     /* Memory barriers to ensure subsequence data & instruction
143      * transfers using updated MPU settings.
144      */
145     __DSB();
146     __ISB();
147 
148     /* Configure the force_incr programmable bit in GPV_5 of PL301_display, which fixes partial write issue.
149      * The AXI2AHB bridge is used for masters that access the TCM through system bus.
150      * Please refer to errata for more information */
151     /* Only configure the GPV5 if the M core access type is secure. */
152     if ((*(uint32_t *)(CSU_SA_ADDR)&CSU_SA_NSN_M_BIT_MASK) == 0U)
153     {
154         *(uint32_t *)(GPV5_BASE_ADDR + FORCE_INCR_OFFSET) =
155             *(uint32_t *)(GPV5_BASE_ADDR + FORCE_INCR_OFFSET) | FORCE_INCR_BIT_MASK;
156     }
157 }
158 
BOARD_RdcInit(void)159 void BOARD_RdcInit(void)
160 {
161     /* Move M4 core to specific RDC domain 1 */
162     rdc_domain_assignment_t assignment = {0};
163     uint8_t domainId                   = 0U;
164 
165     domainId = RDC_GetCurrentMasterDomainId(RDC);
166     /* Only configure the RDC if RDC peripheral write access allowed. */
167     if ((0x1U & RDC_GetPeriphAccessPolicy(RDC, kRDC_Periph_RDC, domainId)) != 0U)
168     {
169         assignment.domainId = BOARD_DOMAIN_ID;
170         RDC_SetMasterDomainAssignment(RDC, kRDC_Master_M4, &assignment);
171     }
172 
173     /*
174      * The M4 core is running at domain 1, now enable the clock gate of the following IP/BUS/PLL in domain 1 in the CCM.
175      * In this way, to ensure the clock of the peripherals used by M core not be affected by A core which is running at
176      * domain 0.
177      */
178     CLOCK_EnableClock(kCLOCK_Iomux);
179 
180     CLOCK_EnableClock(kCLOCK_Ipmux1);
181     CLOCK_EnableClock(kCLOCK_Ipmux2);
182     CLOCK_EnableClock(kCLOCK_Ipmux3);
183     CLOCK_EnableClock(kCLOCK_Ipmux4);
184 
185 #if defined(FLASH_TARGET)
186     CLOCK_EnableClock(kCLOCK_Qspi);
187 #endif
188 
189     CLOCK_ControlGate(kCLOCK_SysPll1Gate, kCLOCK_ClockNeededAll);   /* Enable the CCGR gate for SysPLL1 in Domain 1 */
190     CLOCK_ControlGate(kCLOCK_SysPll2Gate, kCLOCK_ClockNeededAll);   /* Enable the CCGR gate for SysPLL2 in Domain 1 */
191     CLOCK_ControlGate(kCLOCK_SysPll3Gate, kCLOCK_ClockNeededAll);   /* Enable the CCGR gate for SysPLL3 in Domain 1 */
192     CLOCK_ControlGate(kCLOCK_AudioPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL1 in Domain 1 */
193     CLOCK_ControlGate(kCLOCK_AudioPll2Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for AudioPLL2 in Domain 1 */
194     CLOCK_ControlGate(kCLOCK_VideoPll1Gate, kCLOCK_ClockNeededAll); /* Enable the CCGR gate for VideoPLL1 in Domain 1 */
195 }
196