1 /*
2  * Copyright (c) 2022-2024 HPMicro
3  * SPDX-License-Identifier: BSD-3-Clause
4  *
5  */
6 
7 #include "board.h"
8 #include "hpm_uart_drv.h"
9 #include "hpm_gptmr_drv.h"
10 #include "hpm_i2c_drv.h"
11 #include "hpm_gpio_drv.h"
12 #include "hpm_femc_drv.h"
13 #include "pinmux.h"
14 #include "hpm_pmp_drv.h"
15 #include "assert.h"
16 #include "hpm_clock_drv.h"
17 #include "hpm_sysctl_drv.h"
18 #include "hpm_sdxc_drv.h"
19 #include "hpm_pwm_drv.h"
20 #include "hpm_trgm_drv.h"
21 #include "hpm_pllctlv2_drv.h"
22 #include "hpm_enet_drv.h"
23 #include "hpm_pcfg_drv.h"
24 
25 #include "hpm_debug_console.h"
26 
27 static board_timer_cb timer_cb;
28 ATTR_PLACE_AT_NONCACHEABLE_BSS static bool init_delay_flag;
29 
30 /**
31  * @brief FLASH configuration option definitions:
32  * option[0]:
33  *    [31:16] 0xfcf9 - FLASH configuration option tag
34  *    [15:4]  0 - Reserved
35  *    [3:0]   option words (exclude option[0])
36  * option[1]:
37  *    [31:28] Flash probe type
38  *      0 - SFDP SDR / 1 - SFDP DDR
39  *      2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
40  *      4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
41  *      6 - OctaBus DDR (SPI -> OPI DDR)
42  *      8 - Xccela DDR (SPI -> OPI DDR)
43  *      10 - EcoXiP DDR (SPI -> OPI DDR)
44  *    [27:24] Command Pads after Power-on Reset
45  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
46  *    [23:20] Command Pads after Configuring FLASH
47  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
48  *    [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
49  *      0 - Not needed
50  *      1 - QE bit is at bit 6 in Status Register 1
51  *      2 - QE bit is at bit1 in Status Register 2
52  *      3 - QE bit is at bit7 in Status Register 2
53  *      4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
54  *    [15:8] Dummy cycles
55  *      0 - Auto-probed / detected / default value
56  *      Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
57  *    [7:4] Misc.
58  *      0 - Not used
59  *      1 - SPI mode
60  *      2 - Internal loopback
61  *      3 - External DQS
62  *    [3:0] Frequency option
63  *      1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
64  *
65  * option[2] (Effective only if the bit[3:0] in option[0] > 1)
66  *    [31:20]  Reserved
67  *    [19:16] IO voltage
68  *      0 - 3V / 1 - 1.8V
69  *    [15:12] Pin group
70  *      0 - 1st group / 1 - 2nd group
71  *    [11:8] Connection selection
72  *      0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
73  *    [7:0] Drive Strength
74  *      0 - Default value
75  * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
76  *              JESD216)
77  *    [31:16] reserved
78  *    [15:12] Sector Erase Command Option, not required here
79  *    [11:8]  Sector Size Option, not required here
80  *    [7:0] Flash Size Option
81  *      0 - 4MB / 1 - 8MB / 2 - 16MB
82  */
83 #if defined(FLASH_XIP) && FLASH_XIP
84 __attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90001, 0x00000007, 0x0, 0x0};
85 #endif
86 
87 #if defined(FLASH_UF2) && FLASH_UF2
88 ATTR_PLACE_AT(".uf2_signature") const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;
89 #endif
90 
board_init_console(void)91 void board_init_console(void)
92 {
93 #if !defined(CONFIG_NDEBUG_CONSOLE) || !CONFIG_NDEBUG_CONSOLE
94 #if CONSOLE_TYPE_UART == BOARD_CONSOLE_TYPE
95     console_config_t cfg;
96 
97     /* uart needs to configure pin function before enabling clock, otherwise the level change of
98     uart rx pin when configuring pin function will cause a wrong data to be received.
99     And a uart rx dma request will be generated by default uart fifo dma trigger level. */
100     init_uart_pins((UART_Type *) BOARD_CONSOLE_UART_BASE);
101 
102     /* Configure the UART clock to 24MHz */
103     clock_set_source_divider(BOARD_CONSOLE_UART_CLK_NAME, clk_src_osc24m, 1U);
104     clock_add_to_group(BOARD_CONSOLE_UART_CLK_NAME, 0);
105 
106     cfg.type = BOARD_CONSOLE_TYPE;
107     cfg.base = (uint32_t) BOARD_CONSOLE_UART_BASE;
108     cfg.src_freq_in_hz = clock_get_frequency(BOARD_CONSOLE_UART_CLK_NAME);
109     cfg.baudrate = BOARD_CONSOLE_UART_BAUDRATE;
110 
111     if (status_success != console_init(&cfg)) {
112         /* failed to  initialize debug console */
113         while (1) {
114         }
115     }
116 #else
117     while (1) {
118     }
119 #endif
120 #endif
121 }
122 
board_print_clock_freq(void)123 void board_print_clock_freq(void)
124 {
125     printf("==============================\n");
126     printf(" %s clock summary\n", BOARD_NAME);
127     printf("==============================\n");
128     printf("cpu0:\t\t %luHz\n", clock_get_frequency(clock_cpu0));
129     printf("axi:\t\t %luHz\n", clock_get_frequency(clock_axi));
130     printf("ahb:\t\t %luHz\n", clock_get_frequency(clock_ahb));
131     printf("mchtmr0:\t %luHz\n", clock_get_frequency(clock_mchtmr0));
132     printf("xpi0:\t\t %luHz\n", clock_get_frequency(clock_xpi0));
133     printf("xpi1:\t\t %luHz\n", clock_get_frequency(clock_xpi1));
134     printf("femc:\t\t %luHz\n", clock_get_frequency(clock_femc));
135     printf("==============================\n");
136 }
137 
board_init_uart(UART_Type * ptr)138 void board_init_uart(UART_Type *ptr)
139 {
140     /* configure uart's pin before opening uart's clock */
141     init_uart_pins(ptr);
142     board_init_uart_clock(ptr);
143 }
144 
board_print_banner(void)145 void board_print_banner(void)
146 {
147     const uint8_t banner[] = {"\n\
148 ----------------------------------------------------------------------\n\
149 $$\\   $$\\ $$$$$$$\\  $$\\      $$\\ $$\\\n\
150 $$ |  $$ |$$  __$$\\ $$$\\    $$$ |\\__|\n\
151 $$ |  $$ |$$ |  $$ |$$$$\\  $$$$ |$$\\  $$$$$$$\\  $$$$$$\\   $$$$$$\\\n\
152 $$$$$$$$ |$$$$$$$  |$$\\$$\\$$ $$ |$$ |$$  _____|$$  __$$\\ $$  __$$\\\n\
153 $$  __$$ |$$  ____/ $$ \\$$$  $$ |$$ |$$ /      $$ |  \\__|$$ /  $$ |\n\
154 $$ |  $$ |$$ |      $$ |\\$  /$$ |$$ |$$ |      $$ |      $$ |  $$ |\n\
155 $$ |  $$ |$$ |      $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ |      \\$$$$$$  |\n\
156 \\__|  \\__|\\__|      \\__|     \\__|\\__| \\_______|\\__|       \\______/\n\
157 ----------------------------------------------------------------------\n"};
158 #ifdef SDK_VERSION_STRING
159     printf("hpm_sdk: %s\n", SDK_VERSION_STRING);
160 #endif
161     printf("%s", banner);
162 }
163 
board_ungate_mchtmr_at_lp_mode(void)164 void board_ungate_mchtmr_at_lp_mode(void)
165 {
166     /* Keep cpu clock on wfi, so that mchtmr irq can still work after wfi */
167     sysctl_set_cpu_lp_mode(HPM_SYSCTL, BOARD_RUNNING_CORE, cpu_lp_mode_ungate_cpu_clock);
168 }
169 
board_init(void)170 void board_init(void)
171 {
172     pcfg_dcdc_set_voltage(HPM_PCFG, 1100);
173     board_init_clock();
174     board_init_console();
175     board_init_pmp();
176 #if BOARD_SHOW_CLOCK
177     board_print_clock_freq();
178 #endif
179 #if BOARD_SHOW_BANNER
180     board_print_banner();
181 #endif
182 }
183 
board_init_sdram_pins(void)184 void board_init_sdram_pins(void)
185 {
186     init_sdram_pins();
187 }
188 
board_init_femc_clock(void)189 uint32_t board_init_femc_clock(void)
190 {
191     clock_add_to_group(clock_femc, 0);
192     /* Configure the SDRAM to 166MHz */
193     clock_set_source_divider(clock_femc, clk_src_pll0_clk1, 2U);
194 
195     return clock_get_frequency(clock_femc);
196 }
197 
board_delay_us(uint32_t us)198 void board_delay_us(uint32_t us)
199 {
200     clock_cpu_delay_us(us);
201 }
202 
board_delay_ms(uint32_t ms)203 void board_delay_ms(uint32_t ms)
204 {
205     clock_cpu_delay_ms(ms);
206 }
207 
board_timer_isr(void)208 void board_timer_isr(void)
209 {
210     if (gptmr_check_status(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_STAT_MASK(BOARD_CALLBACK_TIMER_CH))) {
211         gptmr_clear_status(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_STAT_MASK(BOARD_CALLBACK_TIMER_CH));
212         timer_cb();
213     }
214 }
215 SDK_DECLARE_EXT_ISR_M(BOARD_CALLBACK_TIMER_IRQ, board_timer_isr);
216 
board_timer_create(uint32_t ms,board_timer_cb cb)217 void board_timer_create(uint32_t ms, board_timer_cb cb)
218 {
219     uint32_t gptmr_freq;
220     gptmr_channel_config_t config;
221 
222     timer_cb = cb;
223     gptmr_channel_get_default_config(BOARD_CALLBACK_TIMER, &config);
224 
225     clock_add_to_group(BOARD_CALLBACK_TIMER_CLK_NAME, 0);
226     gptmr_freq = clock_get_frequency(BOARD_CALLBACK_TIMER_CLK_NAME);
227 
228     config.reload = gptmr_freq / 1000 * ms;
229     gptmr_channel_config(BOARD_CALLBACK_TIMER, BOARD_CALLBACK_TIMER_CH, &config, false);
230     gptmr_enable_irq(BOARD_CALLBACK_TIMER, GPTMR_CH_RLD_IRQ_MASK(BOARD_CALLBACK_TIMER_CH));
231     intc_m_enable_irq_with_priority(BOARD_CALLBACK_TIMER_IRQ, 1);
232 
233     gptmr_start_counter(BOARD_CALLBACK_TIMER, BOARD_CALLBACK_TIMER_CH);
234 }
235 
board_i2c_bus_clear(I2C_Type * ptr)236 void board_i2c_bus_clear(I2C_Type *ptr)
237 {
238     init_i2c_pins_as_gpio(ptr);
239     if (ptr == BOARD_APP_I2C_BASE) {
240         gpio_set_pin_input(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SDA_GPIO_INDEX, BOARD_I2C_SDA_GPIO_PIN);
241         gpio_set_pin_input(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SCL_GPIO_INDEX, BOARD_I2C_SCL_GPIO_PIN);
242         if (!gpio_read_pin(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SCL_GPIO_INDEX, BOARD_I2C_SCL_GPIO_PIN)) {
243             printf("CLK is low, please power cycle the board\n");
244             while (1) {
245             }
246         }
247         if (!gpio_read_pin(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SDA_GPIO_INDEX, BOARD_I2C_SDA_GPIO_PIN)) {
248             printf("SDA is low, try to issue I2C bus clear\n");
249         } else {
250             printf("I2C bus is ready\n");
251             return;
252         }
253 
254         gpio_set_pin_output(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SCL_GPIO_INDEX, BOARD_I2C_SCL_GPIO_PIN);
255         while (1) {
256             for (uint32_t i = 0; i < 9; i++) {
257                 gpio_write_pin(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SCL_GPIO_INDEX, BOARD_I2C_SCL_GPIO_PIN, 1);
258                 board_delay_ms(10);
259                 gpio_write_pin(BOARD_I2C_GPIO_CTRL, BOARD_I2C_SCL_GPIO_INDEX, BOARD_I2C_SCL_GPIO_PIN, 0);
260                 board_delay_ms(10);
261             }
262             board_delay_ms(100);
263         }
264         printf("I2C bus is cleared\n");
265     }
266 }
267 
board_init_i2c(I2C_Type * ptr)268 void board_init_i2c(I2C_Type *ptr)
269 {
270     i2c_config_t config;
271     hpm_stat_t stat;
272     uint32_t freq;
273     if (ptr == NULL) {
274         return;
275     }
276 
277     board_i2c_bus_clear(ptr);
278     init_i2c_pins(ptr);
279     clock_add_to_group(clock_i2c0, 0);
280     clock_add_to_group(clock_i2c1, 0);
281     clock_add_to_group(clock_i2c2, 0);
282     clock_add_to_group(clock_i2c3, 0);
283     /* Configure the I2C clock to 24MHz */
284     clock_set_source_divider(BOARD_APP_I2C_CLK_NAME, clk_src_osc24m, 1U);
285 
286     config.i2c_mode = i2c_mode_normal;
287     config.is_10bit_addressing = false;
288     freq = clock_get_frequency(BOARD_APP_I2C_CLK_NAME);
289     stat = i2c_init_master(ptr, freq, &config);
290     if (stat != status_success) {
291         printf("failed to initialize i2c 0x%x\n", (uint32_t) ptr);
292         while (1) {
293         }
294     }
295 }
296 
board_init_spi_clock(SPI_Type * ptr)297 uint32_t board_init_spi_clock(SPI_Type *ptr)
298 {
299     if (ptr == HPM_SPI3) {
300         /* SPI3 clock configure */
301         clock_add_to_group(clock_spi3, 0);
302         clock_set_source_divider(clock_spi3, clk_src_pll0_clk0, 5U); /* 80MHz */
303 
304         return clock_get_frequency(clock_spi3);
305     }
306     return 0;
307 }
308 
board_init_gpio_pins(void)309 void board_init_gpio_pins(void)
310 {
311     init_gpio_pins();
312 }
313 
board_init_spi_pins(SPI_Type * ptr)314 void board_init_spi_pins(SPI_Type *ptr)
315 {
316     init_spi_pins(ptr);
317 }
318 
board_init_spi_pins_with_gpio_as_cs(SPI_Type * ptr)319 void board_init_spi_pins_with_gpio_as_cs(SPI_Type *ptr)
320 {
321     init_spi_pins_with_gpio_as_cs(ptr);
322     gpio_set_pin_output_with_initial(BOARD_SPI_CS_GPIO_CTRL, GPIO_GET_PORT_INDEX(BOARD_SPI_CS_PIN),
323                                     GPIO_GET_PIN_INDEX(BOARD_SPI_CS_PIN), !BOARD_SPI_CS_ACTIVE_LEVEL);
324 }
325 
board_write_spi_cs(uint32_t pin,uint8_t state)326 void board_write_spi_cs(uint32_t pin, uint8_t state)
327 {
328     gpio_write_pin(BOARD_SPI_CS_GPIO_CTRL, GPIO_GET_PORT_INDEX(pin), GPIO_GET_PIN_INDEX(pin), state);
329 }
330 
board_get_led_gpio_off_level(void)331 uint8_t board_get_led_gpio_off_level(void)
332 {
333     return BOARD_LED_OFF_LEVEL;
334 }
335 
board_init_led_pins(void)336 void board_init_led_pins(void)
337 {
338     init_led_pins();
339     gpio_set_pin_output_with_initial(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, board_get_led_gpio_off_level());
340 }
341 
board_led_toggle(void)342 void board_led_toggle(void)
343 {
344     gpio_toggle_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);
345 }
346 
board_led_write(uint8_t state)347 void board_led_write(uint8_t state)
348 {
349     gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, state);
350 }
351 
board_init_usb_pins(void)352 void board_init_usb_pins(void)
353 {
354     /* set pull-up for USBx ID pin */
355     init_usb_pins();
356 
357     /* configure USBx ID pin as input function */
358     gpio_set_pin_input(BOARD_USB0_ID_PORT, BOARD_USB0_ID_GPIO_INDEX, BOARD_USB0_ID_GPIO_PIN);
359 }
360 
board_get_usb_id_status(void)361 uint8_t board_get_usb_id_status(void)
362 {
363     return gpio_read_pin(BOARD_USB0_ID_PORT, BOARD_USB0_ID_GPIO_INDEX, BOARD_USB0_ID_GPIO_PIN);
364 }
365 
board_usb_vbus_ctrl(uint8_t usb_index,uint8_t level)366 void board_usb_vbus_ctrl(uint8_t usb_index, uint8_t level)
367 {
368     (void) usb_index;
369     (void) level;
370 }
371 
board_init_pmp(void)372 void board_init_pmp(void)
373 {
374     extern uint32_t __noncacheable_start__[];
375     extern uint32_t __noncacheable_end__[];
376 
377     uint32_t start_addr = (uint32_t) __noncacheable_start__;
378     uint32_t end_addr = (uint32_t) __noncacheable_end__;
379     uint32_t length = end_addr - start_addr;
380 
381     if (length == 0) {
382         return;
383     }
384 
385     /* Ensure the address and the length are power of 2 aligned */
386     assert((length & (length - 1U)) == 0U);
387     assert((start_addr & (length - 1U)) == 0U);
388 
389     pmp_entry_t pmp_entry[3] = {0};
390     pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(0x0000000, 0x80000000);
391     pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
392 
393 
394     pmp_entry[1].pmp_addr = PMP_NAPOT_ADDR(0x80000000, 0x80000000);
395     pmp_entry[1].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
396 
397     pmp_entry[2].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
398     pmp_entry[2].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
399     pmp_entry[2].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
400     pmp_entry[2].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
401     pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry));
402 }
403 
board_init_clock(void)404 void board_init_clock(void)
405 {
406     uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
407     if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
408         /* Configure the External OSC ramp-up time: ~9ms */
409         pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32UL * 1000UL * 9U);
410 
411         /* Select clock setting preset1 */
412         sysctl_clock_set_preset(HPM_SYSCTL, 2);
413     }
414 
415 
416     /* Add most Clocks to group 0 */
417     /* not open uart clock in this API, uart should configure pin function before opening clock */
418     clock_add_to_group(clock_cpu0, 0);
419     clock_add_to_group(clock_ahbp, 0);
420     clock_add_to_group(clock_axic, 0);
421     clock_add_to_group(clock_axis, 0);
422 
423     clock_add_to_group(clock_mchtmr0, 0);
424     clock_add_to_group(clock_femc, 0);
425     clock_add_to_group(clock_xpi0, 0);
426     clock_add_to_group(clock_xpi1, 0);
427     clock_add_to_group(clock_gptmr0, 0);
428     clock_add_to_group(clock_gptmr1, 0);
429     clock_add_to_group(clock_gptmr2, 0);
430     clock_add_to_group(clock_gptmr3, 0);
431     clock_add_to_group(clock_i2c0, 0);
432     clock_add_to_group(clock_i2c1, 0);
433     clock_add_to_group(clock_i2c2, 0);
434     clock_add_to_group(clock_i2c3, 0);
435     clock_add_to_group(clock_spi0, 0);
436     clock_add_to_group(clock_spi1, 0);
437     clock_add_to_group(clock_spi2, 0);
438     clock_add_to_group(clock_spi3, 0);
439     clock_add_to_group(clock_can0, 0);
440     clock_add_to_group(clock_can1, 0);
441     clock_add_to_group(clock_sdxc0, 0);
442     clock_add_to_group(clock_ptpc, 0);
443     clock_add_to_group(clock_ref0, 0);
444     clock_add_to_group(clock_ref1, 0);
445     clock_add_to_group(clock_watchdog0, 0);
446     clock_add_to_group(clock_eth0, 0);
447     clock_add_to_group(clock_sdp, 0);
448     clock_add_to_group(clock_xdma, 0);
449     clock_add_to_group(clock_ram0, 0);
450     clock_add_to_group(clock_usb0, 0);
451     clock_add_to_group(clock_kman, 0);
452     clock_add_to_group(clock_gpio, 0);
453     clock_add_to_group(clock_mbx0, 0);
454     clock_add_to_group(clock_hdma, 0);
455     clock_add_to_group(clock_rng, 0);
456     clock_add_to_group(clock_mot0, 0);
457     clock_add_to_group(clock_mot1, 0);
458     clock_add_to_group(clock_acmp, 0);
459     clock_add_to_group(clock_dao, 0);
460     clock_add_to_group(clock_synt, 0);
461     clock_add_to_group(clock_lmm0, 0);
462     clock_add_to_group(clock_pdm, 0);
463 
464     clock_add_to_group(clock_adc0, 0);
465     clock_add_to_group(clock_adc1, 0);
466     clock_add_to_group(clock_adc2, 0);
467 
468     clock_add_to_group(clock_dac0, 0);
469 
470     clock_add_to_group(clock_i2s0, 0);
471     clock_add_to_group(clock_i2s1, 0);
472 
473     clock_add_to_group(clock_ffa0, 0);
474     clock_add_to_group(clock_tsns, 0);
475 
476     /* Connect Group0 to CPU0 */
477     clock_connect_group_to_cpu(0, 0);
478 
479     /* Configure CPU to 480MHz, AXI/AHB to 160MHz */
480     sysctl_config_cpu0_domain_clock(HPM_SYSCTL, clock_source_pll1_clk0, 1, 3, 3);
481     /* Configure PLL1_CLK0 Post Divider to 1.2 */
482     pllctlv2_set_postdiv(HPM_PLLCTLV2, 1, 0, 1);
483     /* Configure PLL1 clock frequencey to 576MHz, the PLL1_CLK0 frequency = 576MHz / 1.2 = 480MHz */
484     pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 1, 576000000);
485     clock_update_core_clock();
486 
487     /* Configure mchtmr to 24MHz */
488     clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
489 }
490 
board_init_dao_clock(void)491 uint32_t board_init_dao_clock(void)
492 {
493     return clock_get_frequency(clock_dao);
494 }
495 
board_init_pdm_clock(void)496 uint32_t board_init_pdm_clock(void)
497 {
498     return clock_get_frequency(clock_pdm);
499 }
500 
board_set_audio_pll_clock(uint32_t freq)501 hpm_stat_t board_set_audio_pll_clock(uint32_t freq)
502 {
503     return pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 2, freq);    /* pll2clk */
504 }
505 
board_init_i2s_clock(I2S_Type * ptr)506 uint32_t board_init_i2s_clock(I2S_Type *ptr)
507 {
508     (void) ptr;
509     return 0;
510 }
511 
board_init_adc16_pins(void)512 void board_init_adc16_pins(void)
513 {
514     init_adc_pins();
515 }
516 
board_init_adc16_clock(ADC16_Type * ptr,bool clk_src_ahb)517 uint32_t board_init_adc16_clock(ADC16_Type *ptr, bool clk_src_ahb)
518 {
519     uint32_t freq = 0;
520 
521     if (ptr == HPM_ADC0) {
522         if (clk_src_ahb) {
523             /* Configure the ADC clock from AHB (@160MHz by default)*/
524             clock_set_adc_source(clock_adc0, clk_adc_src_ahb0);
525         } else {
526             /* Configure the ADC clock from pll0_clk1 divided by 2 (@166MHz by default) */
527             clock_set_adc_source(clock_adc0, clk_adc_src_ana0);
528             clock_set_source_divider(clock_ana0, clk_src_pll0_clk1, 2U);
529         }
530 
531         freq = clock_get_frequency(clock_adc0);
532     } else if (ptr == HPM_ADC1) {
533         if (clk_src_ahb) {
534             /* Configure the ADC clock from AHB (@160MHz by default)*/
535             clock_set_adc_source(clock_adc1, clk_adc_src_ahb0);
536         } else {
537             /* Configure the ADC clock from pll1_clk1 divided by 2 (@166MHz by default) */
538             clock_set_adc_source(clock_adc1, clk_adc_src_ana1);
539             clock_set_source_divider(clock_ana1, clk_src_pll0_clk1, 2U);
540         }
541 
542         freq = clock_get_frequency(clock_adc1);
543     } else if (ptr == HPM_ADC2) {
544         if (clk_src_ahb) {
545             /* Configure the ADC clock from AHB (@160MHz by default)*/
546             clock_set_adc_source(clock_adc2, clk_adc_src_ahb0);
547         } else {
548             /* Configure the ADC clock from pll1_clk1 divided by 2 (@166MHz by default) */
549             clock_set_adc_source(clock_adc2, clk_adc_src_ana2);
550             clock_set_source_divider(clock_ana2, clk_src_pll0_clk1, 2U);
551         }
552 
553         freq = clock_get_frequency(clock_adc2);
554     }
555 
556     return freq;
557 }
558 
board_init_dac_clock(DAC_Type * ptr,bool clk_src_ahb)559 uint32_t board_init_dac_clock(DAC_Type *ptr, bool clk_src_ahb)
560 {
561     uint32_t freq = 0;
562 
563     if (ptr == HPM_DAC) {
564         if (clk_src_ahb == true) {
565             /* Configure the DAC clock to 160MHz */
566             clock_set_dac_source(clock_dac0, clk_dac_src_ahb0);
567         } else {
568             /* Configure the DAC clock to 166MHz */
569             clock_set_dac_source(clock_dac0, clk_dac_src_ana3);
570             clock_set_source_divider(clock_ana3, clk_src_pll0_clk1, 2);
571         }
572 
573         freq = clock_get_frequency(clock_dac0);
574     }
575 
576     return freq;
577 }
578 
board_init_can(CAN_Type * ptr)579 void board_init_can(CAN_Type *ptr)
580 {
581     init_can_pins(ptr);
582 }
583 
board_init_can_clock(CAN_Type * ptr)584 uint32_t board_init_can_clock(CAN_Type *ptr)
585 {
586     uint32_t freq = 0;
587     if (ptr == HPM_CAN0) {
588         /* Set the CAN0 peripheral clock to 80MHz */
589         clock_set_source_divider(clock_can0, clk_src_pll0_clk0, 5);
590         freq = clock_get_frequency(clock_can0);
591     } else if (ptr == HPM_CAN1) {
592         /* Set the CAN1 peripheral clock to 80MHz */
593         clock_set_source_divider(clock_can1, clk_src_pll0_clk0, 5);
594         freq = clock_get_frequency(clock_can1);
595     } else {
596         /* Invalid CAN instance */
597     }
598     return freq;
599 }
600 
board_init_gptmr_clock(GPTMR_Type * ptr)601 uint32_t board_init_gptmr_clock(GPTMR_Type *ptr)
602 {
603     uint32_t freq = 0;
604 
605     if (ptr == HPM_GPTMR0) {
606         clock_add_to_group(clock_gptmr0, 0);
607         clock_set_source_divider(clock_gptmr0, clk_src_pll1_clk1, 4);
608         freq = clock_get_frequency(clock_gptmr0);
609     }
610     else if (ptr == HPM_GPTMR1) {
611         clock_add_to_group(clock_gptmr1, 0);
612         clock_set_source_divider(clock_gptmr1, clk_src_pll1_clk1, 4);
613         freq = clock_get_frequency(clock_gptmr1);
614     }
615     else if (ptr == HPM_GPTMR2) {
616         clock_add_to_group(clock_gptmr2, 0);
617         clock_set_source_divider(clock_gptmr2, clk_src_pll1_clk1, 4);
618         freq = clock_get_frequency(clock_gptmr2);
619     }
620     else if (ptr == HPM_GPTMR3) {
621         clock_add_to_group(clock_gptmr3, 0);
622         clock_set_source_divider(clock_gptmr3, clk_src_pll1_clk1, 4);
623         freq = clock_get_frequency(clock_gptmr3);
624     }
625     else {
626         /* Invalid instance */
627     }
628     return freq;
629 }
630 
board_sd_power_switch(SDXC_Type * ptr,bool on_off)631 void board_sd_power_switch(SDXC_Type *ptr, bool on_off)
632 {
633     /* This feature is not supported */
634 }
635 
636 /*
637  * this function will be called during startup to initialize external memory for data use
638  */
_init_ext_ram(void)639 void _init_ext_ram(void)
640 {
641     uint32_t femc_clk_in_hz;
642     board_init_sdram_pins();
643     femc_clk_in_hz = board_init_femc_clock();
644 
645     femc_config_t config = {0};
646     femc_sdram_config_t sdram_config = {0};
647 
648     femc_default_config(HPM_FEMC, &config);
649     femc_init(HPM_FEMC, &config);
650 
651     femc_get_typical_sdram_config(HPM_FEMC, &sdram_config);
652 
653     sdram_config.bank_num = FEMC_SDRAM_BANK_NUM_4;
654     sdram_config.prescaler = 0x3;
655     sdram_config.burst_len_in_byte = 8;
656     sdram_config.auto_refresh_count_in_one_burst = 1;
657     sdram_config.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
658     sdram_config.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
659 
660     sdram_config.refresh_to_refresh_in_ns = 60;     /* Trc */
661     sdram_config.refresh_recover_in_ns = 60;        /* Trc */
662     sdram_config.act_to_precharge_in_ns = 42;       /* Tras */
663     sdram_config.act_to_rw_in_ns = 18;              /* Trcd */
664     sdram_config.precharge_to_act_in_ns = 18;       /* Trp */
665     sdram_config.act_to_act_in_ns = 12;             /* Trrd */
666     sdram_config.write_recover_in_ns = 12;          /* Twr/Tdpl */
667     sdram_config.self_refresh_recover_in_ns = 72;   /* Txsr */
668 
669     sdram_config.cs = BOARD_SDRAM_CS;
670     sdram_config.base_address = BOARD_SDRAM_ADDRESS;
671     sdram_config.size_in_byte = BOARD_SDRAM_SIZE;
672     sdram_config.port_size = BOARD_SDRAM_PORT_SIZE;
673     sdram_config.refresh_count = BOARD_SDRAM_REFRESH_COUNT;
674     sdram_config.refresh_in_ms = BOARD_SDRAM_REFRESH_IN_MS;
675     sdram_config.delay_cell_disable = true;
676     sdram_config.delay_cell_value = 0;
677 
678     femc_config_sdram(HPM_FEMC, femc_clk_in_hz, &sdram_config);
679 }
680 
681 
board_sd_configure_clock(SDXC_Type * ptr,uint32_t freq,bool need_inverse)682 uint32_t board_sd_configure_clock(SDXC_Type *ptr, uint32_t freq, bool need_inverse)
683 {
684     uint32_t actual_freq = 0;
685     do {
686         if (ptr != HPM_SDXC0) {
687             break;
688         }
689         clock_name_t sdxc_clk = clock_sdxc0;
690         sdxc_enable_inverse_clock(ptr, false);
691         sdxc_enable_sd_clock(ptr, false);
692         /* Configure the SDXC Frequency to 200MHz */
693         clock_set_source_divider(sdxc_clk, clk_src_pll0_clk0, 2);
694         sdxc_enable_freq_selection(ptr);
695 
696         /* Configure the clock below 400KHz for the identification state */
697         if (freq <= 400000UL) {
698             sdxc_set_clock_divider(ptr, 600);
699         }
700             /* configure the clock to 24MHz for the SDR12/Default speed */
701         else if (freq <= 26000000UL) {
702             sdxc_set_clock_divider(ptr, 8);
703         }
704             /* Configure the clock to 50MHz for the SDR25/High speed/50MHz DDR/50MHz SDR */
705         else if (freq <= 52000000UL) {
706             sdxc_set_clock_divider(ptr, 4);
707         }
708             /* Configure the clock to 100MHz for the SDR50 */
709         else if (freq <= 100000000UL) {
710             sdxc_set_clock_divider(ptr, 2);
711         }
712             /* Configure the clock to 166MHz for SDR104/HS200/HS400  */
713         else if (freq <= 208000000UL) {
714             sdxc_set_clock_divider(ptr, 1);
715         }
716             /* For other unsupported clock ranges, configure the clock to 24MHz */
717         else {
718             sdxc_set_clock_divider(ptr, 8);
719         }
720         if (need_inverse) {
721             sdxc_enable_inverse_clock(ptr, true);
722         }
723         sdxc_enable_sd_clock(ptr, true);
724         actual_freq = clock_get_frequency(sdxc_clk) / sdxc_get_clock_divider(ptr);
725     } while (false);
726 
727     return actual_freq;
728 }
729 
board_sd_switch_pins_to_1v8(SDXC_Type * ptr)730 void board_sd_switch_pins_to_1v8(SDXC_Type *ptr)
731 {
732     (void) ptr;
733     /* This feature is not supported */
734 }
735 
board_sd_detect_card(SDXC_Type * ptr)736 bool board_sd_detect_card(SDXC_Type *ptr)
737 {
738     return sdxc_is_card_inserted(ptr);
739 }
740 
board_init_enet_ptp_clock(ENET_Type * ptr)741 hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr)
742 {
743     /* set clock source */
744     if (ptr == HPM_ENET0) {
745         /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for ent0 ptp clock */
746         clock_set_source_divider(clock_ptp0, clk_src_pll0_clk0, 4); /* 100MHz */
747     } else {
748         return status_invalid_argument;
749     }
750 
751     return status_success;
752 }
753 
board_init_enet_rmii_reference_clock(ENET_Type * ptr,bool internal)754 hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal)
755 {
756     /* Configure Enet clock to output reference clock */
757     if (ptr == HPM_ENET0) {
758         if (internal) {
759             /* set pll output frequency at 1GHz */
760             if (pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1000000000UL) == status_success) {
761                 /* set pll2_clk1 output frequence at 250MHz from PLL2 divided by 4 (1 + 15 / 5) */
762                 pllctlv2_set_postdiv(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1, 15);
763                 /* set eth clock frequency at 50MHz for enet0 */
764                 clock_set_source_divider(clock_eth0, clk_src_pll2_clk1, 5);
765             } else {
766                 return status_fail;
767             }
768         }
769     } else {
770         return status_invalid_argument;
771     }
772 
773     enet_rmii_enable_clock(ptr, internal);
774 
775     return status_success;
776 }
777 
board_init_enet_pins(ENET_Type * ptr)778 hpm_stat_t board_init_enet_pins(ENET_Type *ptr)
779 {
780     init_enet_pins(ptr);
781 
782     return status_success;
783 }
784 
board_reset_enet_phy(ENET_Type * ptr)785 hpm_stat_t board_reset_enet_phy(ENET_Type *ptr)
786 {
787     (void) ptr;
788     return status_success;
789 }
790 
board_init_dac_pins(DAC_Type * ptr)791 void board_init_dac_pins(DAC_Type *ptr)
792 {
793    init_dac_pins(ptr);
794 }
795 
board_init_uart_clock(UART_Type * ptr)796 uint32_t board_init_uart_clock(UART_Type *ptr)
797 {
798     uint32_t freq = 0U;
799     if (ptr == HPM_UART0) {
800         clock_set_source_divider(clock_uart0, clk_src_osc24m, 1);
801         clock_add_to_group(clock_uart0, 0);
802         freq = clock_get_frequency(clock_uart0);
803     } else if (ptr == HPM_UART1) {
804         clock_set_source_divider(clock_uart1, clk_src_osc24m, 1);
805         clock_add_to_group(clock_uart1, 0);
806         freq = clock_get_frequency(clock_uart1);
807     } else if (ptr == HPM_UART2) {
808         clock_set_source_divider(clock_uart2, clk_src_osc24m, 1);
809         clock_add_to_group(clock_uart2, 0);
810         freq = clock_get_frequency(clock_uart2);
811     } else {
812         /* Not supported */
813     }
814     return freq;
815 }
816 
board_init_pwm_clock(PWM_Type * ptr)817 uint32_t board_init_pwm_clock(PWM_Type *ptr)
818 {
819     uint32_t freq = 0;
820     (void) ptr;
821     return freq;
822 }
823 
board_get_enet_dma_pbl(ENET_Type * ptr)824 uint8_t board_get_enet_dma_pbl(ENET_Type *ptr)
825 {
826     (void) ptr;
827     return enet_pbl_16;
828 }
829 
board_enable_enet_irq(ENET_Type * ptr)830 hpm_stat_t board_enable_enet_irq(ENET_Type *ptr)
831 {
832     if (ptr == HPM_ENET0) {
833         intc_m_enable_irq(IRQn_ENET0);
834     } else {
835         return status_invalid_argument;
836     }
837 
838     return status_success;
839 }
840 
board_disable_enet_irq(ENET_Type * ptr)841 hpm_stat_t board_disable_enet_irq(ENET_Type *ptr)
842 {
843     if (ptr == HPM_ENET0) {
844         intc_m_disable_irq(IRQn_ENET0);
845     }  else {
846         return status_invalid_argument;
847     }
848 
849     return status_success;
850 }
851 
board_init_enet_pps_pins(ENET_Type * ptr)852 void board_init_enet_pps_pins(ENET_Type *ptr)
853 {
854     (void) ptr;
855     init_enet_pps_pins();
856 }
857