1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022/12/25     flyingcys    first version
9  * 2023/01/17     chushicheng  add pin and i2c
10  * 2023/03/15     flyingcys    update bsp file structure
11  */
12 #include <rthw.h>
13 #include <rtthread.h>
14 
15 #include "board.h"
16 #include "drv_uart.h"
17 
system_clock_init(void)18 static void system_clock_init(void)
19 {
20     /* wifipll/audiopll */
21     GLB_Power_On_XTAL_And_PLL_CLK(GLB_XTAL_40M, GLB_PLL_WIFIPLL |
22                                                     GLB_PLL_CPUPLL |
23                                                     GLB_PLL_UHSPLL |
24                                                     GLB_PLL_MIPIPLL);
25 
26     GLB_Set_MCU_System_CLK(GLB_MCU_SYS_CLK_WIFIPLL_320M);
27     GLB_Set_DSP_System_CLK(GLB_DSP_SYS_CLK_CPUPLL_400M);
28     GLB_Config_CPU_PLL(GLB_XTAL_40M, cpuPllCfg_480M);
29 
30     CPU_Set_MTimer_CLK(ENABLE, CPU_Get_MTimer_Source_Clock() / 1000 / 1000 - 1);
31 }
32 
peripheral_clock_init(void)33 static void peripheral_clock_init(void)
34 {
35     PERIPHERAL_CLOCK_ADC_DAC_ENABLE();
36     PERIPHERAL_CLOCK_SEC_ENABLE();
37     PERIPHERAL_CLOCK_DMA0_ENABLE();
38     PERIPHERAL_CLOCK_UART0_ENABLE();
39     PERIPHERAL_CLOCK_UART1_ENABLE();
40     PERIPHERAL_CLOCK_SPI0_1_ENABLE();
41     PERIPHERAL_CLOCK_I2C0_ENABLE();
42     PERIPHERAL_CLOCK_PWM0_ENABLE();
43     PERIPHERAL_CLOCK_TIMER0_1_WDG_ENABLE();
44     PERIPHERAL_CLOCK_IR_ENABLE();
45     PERIPHERAL_CLOCK_I2S_ENABLE();
46     PERIPHERAL_CLOCK_USB_ENABLE();
47     PERIPHERAL_CLOCK_CAN_UART2_ENABLE();
48 
49     GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 4);
50     GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_XCLK, 0);
51     GLB_Set_DSP_UART0_CLK(ENABLE, GLB_DSP_UART_CLK_DSP_XCLK, 0);
52     GLB_Set_SPI_CLK(ENABLE, GLB_SPI_CLK_MCU_MUXPLL_160M, 0);
53     GLB_Set_I2C_CLK(ENABLE, GLB_I2C_CLK_XCLK, 0);
54     GLB_Set_IR_CLK(ENABLE, GLB_IR_CLK_SRC_XCLK, 19);
55     GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 1);
56     GLB_Set_DIG_CLK_Sel(GLB_DIG_CLK_XCLK);
57     GLB_Set_DIG_512K_CLK(ENABLE, ENABLE, 0x4E);
58     GLB_Set_PWM1_IO_Sel(GLB_PWM1_IO_DIFF_END);
59     GLB_Set_CAM_CLK(ENABLE, GLB_CAM_CLK_WIFIPLL_96M, 3);
60 
61     GLB_Set_PKA_CLK_Sel(GLB_PKA_CLK_MCU_MUXPLL_160M);
62 
63 #ifdef BSP_USING_CSI
64     GLB_CSI_Config_MIPIPLL(2, 0x21000);
65     GLB_CSI_Power_Up_MIPIPLL();
66     GLB_Set_DSP_CLK(ENABLE, GLB_DSP_CLK_MUXPLL_160M, 1);
67 #endif
68     GLB_Set_USB_CLK_From_WIFIPLL(1);
69 }
70 
71 #ifdef BSP_USING_PSRAM
72 #define WB_4MB_PSRAM   (1)
73 #define UHS_32MB_PSRAM (2)
74 #define UHS_64MB_PSRAM (3)
75 #define WB_32MB_PSRAM  (4)
76 #define NONE_UHS_PSRAM (-1)
77 
uhs_psram_init(void)78 int uhs_psram_init(void)
79 {
80     PSRAM_UHS_Cfg_Type psramDefaultCfg = {
81         2000,
82         PSRAM_MEM_SIZE_32MB,
83         PSRAM_PAGE_SIZE_2KB,
84         PSRAM_UHS_NORMAL_TEMP,
85     };
86 
87     bflb_efuse_device_info_type chip_info;
88     bflb_ef_ctrl_get_device_info(&chip_info);
89     if (chip_info.psramInfo == UHS_32MB_PSRAM) {
90         psramDefaultCfg.psramMemSize = PSRAM_MEM_SIZE_32MB;
91     } else if (chip_info.psramInfo == UHS_64MB_PSRAM) {
92         psramDefaultCfg.psramMemSize = PSRAM_MEM_SIZE_64MB;
93     } else {
94         return -1;
95     }
96 
97     //init uhs PLL; Must open uhs pll first, and then initialize uhs psram
98     GLB_Config_UHS_PLL(GLB_XTAL_40M, uhsPllCfg_2000M);
99     //init uhs psram ;
100     // Psram_UHS_x16_Init(Clock_Peripheral_Clock_Get(BL_PERIPHERAL_CLOCK_PSRAMA) / 1000000);
101     Psram_UHS_x16_Init_Override(&psramDefaultCfg);
102     Tzc_Sec_PSRAMA_Access_Release();
103 
104     // example: 2000Mbps typical cal values
105     uhs_phy_cal_res->rl = 39;
106     uhs_phy_cal_res->rdqs = 3;
107     uhs_phy_cal_res->rdq = 0;
108     uhs_phy_cal_res->wl = 13;
109     uhs_phy_cal_res->wdqs = 4;
110     uhs_phy_cal_res->wdq = 5;
111     uhs_phy_cal_res->ck = 9;
112     /* TODO: use uhs psram trim update */
113     set_uhs_latency_r(uhs_phy_cal_res->rl);
114     cfg_dqs_rx(uhs_phy_cal_res->rdqs);
115     cfg_dq_rx(uhs_phy_cal_res->rdq);
116     set_uhs_latency_w(uhs_phy_cal_res->wl);
117     cfg_dq_drv(uhs_phy_cal_res->wdq);
118     cfg_ck_cen_drv(uhs_phy_cal_res->wdq + 4, uhs_phy_cal_res->wdq + 1);
119     cfg_dqs_drv(uhs_phy_cal_res->wdqs);
120     // set_odt_en();
121     mr_read_back();
122     return 0;
123 }
124 #endif
125 
126 /* This is the timer interrupt service routine. */
systick_isr(void)127 static void systick_isr(void)
128 {
129     rt_tick_increase();
130 }
131 
rt_hw_board_init(void)132 void rt_hw_board_init(void)
133 {
134     GLB_Halt_CPU(GLB_CORE_ID_D0);
135     GLB_Halt_CPU(GLB_CORE_ID_LP);
136 
137     bflb_flash_init();
138 
139     system_clock_init();
140     peripheral_clock_init();
141     bflb_irq_initialize();
142 
143     bflb_mtimer_config(CPU_Get_MTimer_Clock() / RT_TICK_PER_SECOND, systick_isr);
144 
145 #ifdef BSP_USING_PSRAM
146     if (uhs_psram_init() < 0)
147     {
148         rt_kprintf("uhs_psram_init failed!\n");
149         return;
150     }
151 
152     extern uint32_t __psrambss_start__;
153     extern uint32_t __psrambss_end__;
154     uint32_t *pDest;
155     pDest = &__psrambss_start__;
156 
157     for (; pDest < &__psrambss_end__;) {
158         *pDest++ = 0ul;
159     }
160 #endif
161 
162 #ifdef RT_USING_HEAP
163     /* initialize memory system */
164     rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
165 #endif
166 
167     /* UART driver initialization is open by default */
168 #ifdef RT_USING_SERIAL
169     rt_hw_uart_init();
170 #endif
171 
172     /* Set the shell console output device */
173 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
174     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
175 #endif
176 
177 #ifdef RT_USING_COMPONENTS_INIT
178     rt_components_board_init();
179 #endif
180 
181 #ifdef BSP_USING_TRIPLECORE
182     /* set CPU D0 boot XIP address and flash address */
183     Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_D0, 1);
184     /* D0 boot from 0x58000000 */
185     GLB_Set_CPU_Reset_Address(GLB_CORE_ID_D0, 0x58000000);
186     /* D0 image offset on flash is CONFIG_D0_FLASH_ADDR */
187     bflb_sf_ctrl_set_flash_image_offset(CONFIG_D0_FLASH_ADDR, 1, SF_CTRL_FLASH_BANK0);
188 
189     Tzc_Sec_Set_CPU_Group(GLB_CORE_ID_LP, 0);
190     /* LP boot from 0x580C0000 */
191     GLB_Set_CPU_Reset_Address(GLB_CORE_ID_LP, 0x58000000 + CONFIG_LP_FLASH_ADDR);
192 
193     GLB_Release_CPU(GLB_CORE_ID_D0);
194     GLB_Release_CPU(GLB_CORE_ID_LP);
195 
196     /* release d0 and then do can run */
197     BL_WR_WORD(IPC_SYNC_ADDR1, IPC_SYNC_FLAG);
198     BL_WR_WORD(IPC_SYNC_ADDR2, IPC_SYNC_FLAG);
199     L1C_DCache_Clean_By_Addr(IPC_SYNC_ADDR1, 8);
200 #endif
201 
202 #ifdef RT_USING_HEAP
203     rt_kprintf("RT_HW_HEAP_BEGIN:%x RT_HW_HEAP_END:%x size: %d\r\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END, RT_HW_HEAP_END - RT_HW_HEAP_BEGIN);
204 #endif
205 }
206 
rt_hw_cpu_reset(void)207 void rt_hw_cpu_reset(void)
208 {
209     GLB_SW_POR_Reset();
210 }
211 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
212