• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "board.h"
17 #include "hpm_pllctlv2_drv.h"
18 #include "hpm_pcfg_drv.h"
19 #include <hpm_enet_drv.h>
20 #include <hpm_gpio_drv.h>
21 #include <hpm_pmp_drv.h>
22 /**
23  * @brief FLASH configuration option definitions:
24  * option[0]:
25  *    [31:16] 0xfcf9 - FLASH configuration option tag
26  *    [15:4]  0 - Reserved
27  *    [3:0]   option words (exclude option[0])
28  * option[1]:
29  *    [31:28] Flash probe type
30  *      0 - SFDP SDR / 1 - SFDP DDR
31  *      2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
32  *      4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
33  *      6 - OctaBus DDR (SPI -> OPI DDR)
34  *      8 - Xccela DDR (SPI -> OPI DDR)
35  *      10 - EcoXiP DDR (SPI -> OPI DDR)
36  *    [27:24] Command Pads after Power-on Reset
37  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
38  *    [23:20] Command Pads after Configuring FLASH
39  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
40  *    [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
41  *      0 - Not needed
42  *      1 - QE bit is at bit 6 in Status Register 1
43  *      2 - QE bit is at bit1 in Status Register 2
44  *      3 - QE bit is at bit7 in Status Register 2
45  *      4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
46  *    [15:8] Dummy cycles
47  *      0 - Auto-probed / detected / default value
48  *      Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
49  *    [7:4] Misc.
50  *      0 - Not used
51  *      1 - SPI mode
52  *      2 - Internal loopback
53  *      3 - External DQS
54  *    [3:0] Frequency option
55  *      1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
56  *
57  * option[2] (Effective only if the bit[3:0] in option[0] > 1)
58  *    [31:20]  Reserved
59  *    [19:16] IO voltage
60  *      0 - 3V / 1 - 1.8V
61  *    [15:12] Pin group
62  *      0 - 1st group / 1 - 2nd group
63  *    [11:8] Connection selection
64  *      0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
65  *    [7:0] Drive Strength
66  *      0 - Default value
67  * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
68  *              JESD216)
69  *    [31:16] reserved
70  *    [15:12] Sector Erase Command Option, not required here
71  *    [11:8]  Sector Size Option, not required here
72  *    [7:0] Flash Size Option
73  *      0 - 4MB / 1 - 8MB / 2 - 16MB
74  */
75 #if defined(FLASH_XIP) && FLASH_XIP
76 __attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90001, 0x00000007, 0x0, 0x0};
77 #endif
78 
board_delay_us(uint32_t us)79 void board_delay_us(uint32_t us)
80 {
81     clock_cpu_delay_us(us);
82 }
83 
board_delay_ms(uint32_t ms)84 void board_delay_ms(uint32_t ms)
85 {
86     clock_cpu_delay_ms(ms);
87 }
88 
board_init_pmp(void)89 void board_init_pmp(void)
90 {
91     extern uint32_t __noncacheable_start__[];
92     extern uint32_t __noncacheable_end__[];
93 
94     uint32_t start_addr = (uint32_t) __noncacheable_start__;
95     uint32_t end_addr = (uint32_t) __noncacheable_end__;
96     uint32_t length = end_addr - start_addr;
97 
98     if (length == 0) {
99         return;
100     }
101 
102     /* Ensure the address and the length are power of 2 aligned */
103     assert((length & (length - 1U)) == 0U);
104     assert((start_addr & (length - 1U)) == 0U);
105 
106     pmp_entry_t pmp_entry[3] = { 0 };
107     pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(0x0000000, 0x80000000);
108     pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
109 
110 
111     pmp_entry[1].pmp_addr = PMP_NAPOT_ADDR(0x80000000, 0x80000000);
112     pmp_entry[1].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
113 
114     pmp_entry[2].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
115     pmp_entry[2].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
116     pmp_entry[2].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
117     pmp_entry[2].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
118     pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry));
119 }
120 
board_init_display_system_clock(void)121 void board_init_display_system_clock(void)
122 {
123     clock_add_to_group(clock_gpu0, 0);
124     clock_add_to_group(clock_gwc0, 0);
125     clock_add_to_group(clock_gwc1, 0);
126     clock_add_to_group(clock_lvb, 0);
127     clock_add_to_group(clock_lcb, 0);
128     clock_add_to_group(clock_lcd0, 0);
129     clock_add_to_group(clock_dsi0, 0);
130     clock_add_to_group(clock_dsi1, 0);
131     clock_add_to_group(clock_cam0, 0);
132     clock_add_to_group(clock_cam1, 0);
133     clock_add_to_group(clock_jpeg, 0);
134     clock_add_to_group(clock_pdma, 0);
135 }
136 
board_init_clock(void)137 void board_init_clock(void)
138 {
139     uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
140     if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
141         /* Configure the External OSC ramp-up time: ~9ms */
142         pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32UL * 1000UL * 9U);
143 
144         /* Select clock setting preset1 */
145         sysctl_clock_set_preset(HPM_SYSCTL, 2);
146     }
147     /* Add most Clocks to group 0 */
148     /* not open uart clock in this API, uart should configure pin function before opening clock */
149     clock_add_to_group(clock_cpu0, 0);
150     clock_add_to_group(clock_ahb, 0);
151     clock_add_to_group(clock_axic, 0);
152     clock_add_to_group(clock_axis, 0);
153     clock_add_to_group(clock_axiv, 0);
154     clock_add_to_group(clock_axid, 0);
155     clock_add_to_group(clock_axig, 0);
156 
157     clock_add_to_group(clock_mchtmr0, 0);
158     clock_add_to_group(clock_xpi0, 0);
159     clock_add_to_group(clock_gptmr0, 0);
160     clock_add_to_group(clock_gptmr1, 0);
161     clock_add_to_group(clock_gptmr2, 0);
162     clock_add_to_group(clock_gptmr3, 0);
163     clock_add_to_group(clock_uart0, 0);
164     clock_add_to_group(clock_i2c0, 0);
165     clock_add_to_group(clock_i2c1, 0);
166     clock_add_to_group(clock_i2c2, 0);
167     clock_add_to_group(clock_i2c3, 0);
168     clock_add_to_group(clock_spi0, 0);
169     clock_add_to_group(clock_spi1, 0);
170     clock_add_to_group(clock_spi2, 0);
171     clock_add_to_group(clock_spi3, 0);
172     clock_add_to_group(clock_can0, 0);
173     clock_add_to_group(clock_can1, 0);
174     clock_add_to_group(clock_can2, 0);
175     clock_add_to_group(clock_can3, 0);
176     clock_add_to_group(clock_can4, 0);
177     clock_add_to_group(clock_can5, 0);
178     clock_add_to_group(clock_can6, 0);
179     clock_add_to_group(clock_can7, 0);
180     clock_add_to_group(clock_ptpc, 0);
181     clock_add_to_group(clock_ref0, 0);
182     clock_add_to_group(clock_ref1, 0);
183     clock_add_to_group(clock_watchdog0, 0);
184     clock_add_to_group(clock_sdp, 0);
185     clock_add_to_group(clock_xdma, 0);
186     clock_add_to_group(clock_xram, 0);
187     clock_add_to_group(clock_usb0, 0);
188     clock_add_to_group(clock_kman, 0);
189     clock_add_to_group(clock_gpio, 0);
190     clock_add_to_group(clock_mbx0, 0);
191     clock_add_to_group(clock_hdma, 0);
192     clock_add_to_group(clock_rng, 0);
193     clock_add_to_group(clock_adc0, 0);
194     clock_add_to_group(clock_adc1, 0);
195     clock_add_to_group(clock_crc0, 0);
196     clock_add_to_group(clock_dao, 0);
197     clock_add_to_group(clock_pdm, 0);
198     clock_add_to_group(clock_smix, 0);
199 
200     clock_add_to_group(clock_i2s0, 0);
201     clock_add_to_group(clock_i2s1, 0);
202     clock_add_to_group(clock_i2s2, 0);
203     clock_add_to_group(clock_i2s3, 0);
204 
205     clock_add_to_group(clock_eth0, 0);
206     clock_add_to_group(clock_ffa, 0);
207 
208     board_init_display_system_clock();
209 
210     /* Connect Group0 to CPU0 */
211     clock_connect_group_to_cpu(0, 0);
212 
213     /* Bump up DCDC voltage to 1150mv */
214     pcfg_dcdc_set_voltage(HPM_PCFG, 1150);
215 
216     /* Configure PLL1_CLK0 Post Divider to 1 */
217     pllctlv2_set_postdiv(HPM_PLLCTLV2, 0, 0, 0);
218     pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 0, BOARD_CPU_FREQ);
219 
220     /* Configure axis to 200MHz */
221     clock_set_source_divider(clock_axis, clk_src_pll1_clk0, 4);
222 
223     /* Configure axig/clock_gpu0 to 400MHz */
224     clock_set_source_divider(clock_axig, clk_src_pll1_clk0, 2);
225 
226     /* Configure mchtmr to 24MHz */
227     clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
228 
229     clock_update_core_clock();
230 }
231 
board_init(void)232 void board_init(void)
233 {
234     board_init_clock();
235     sysctl_set_cpu0_lp_mode(HPM_SYSCTL, cpu_lp_mode_ungate_cpu_clock);
236     board_init_pmp();
237 }
238 
board_print_clock_freq(void)239 void board_print_clock_freq(void)
240 {
241     printf("==============================\n");
242     printf(" %s clock summary\n", BOARD_NAME);
243     printf("==============================\n");
244     printf("cpu0:\t\t %dHz\n", clock_get_frequency(clock_cpu0));
245     printf("gpu0:\t\t %dHz\n", clock_get_frequency(clock_gpu0));
246     printf("axis:\t\t %dHz\n", clock_get_frequency(clock_axis));
247     printf("axic:\t\t %dHz\n", clock_get_frequency(clock_axic));
248     printf("axif:\t\t %dHz\n", clock_get_frequency(clock_axif));
249     printf("axid:\t\t %dHz\n", clock_get_frequency(clock_axid));
250     printf("axiv:\t\t %dHz\n", clock_get_frequency(clock_axiv));
251     printf("axig:\t\t %dHz\n", clock_get_frequency(clock_axig));
252     printf("mchtmr0:\t %dHz\n", clock_get_frequency(clock_mchtmr0));
253     printf("xpi0:\t\t %dHz\n", clock_get_frequency(clock_xpi0));
254     printf("==============================\n");
255 }
256 
board_print_banner(void)257 void board_print_banner(void)
258 {
259     const uint8_t banner[] = {"\n\
260 ----------------------------------------------------------------------\r\n\
261 $$\\   $$\\ $$$$$$$\\  $$\\      $$\\ $$\\\r\n\
262 $$ |  $$ |$$  __$$\\ $$$\\    $$$ |\\__|\r\n\
263 $$ |  $$ |$$ |  $$ |$$$$\\  $$$$ |$$\\  $$$$$$$\\  $$$$$$\\   $$$$$$\\\r\n\
264 $$$$$$$$ |$$$$$$$  |$$\\$$\\$$ $$ |$$ |$$  _____|$$  __$$\\ $$  __$$\\\r\n\
265 $$  __$$ |$$  ____/ $$ \\$$$  $$ |$$ |$$ /      $$ |  \\__|$$ /  $$ |\r\n\
266 $$ |  $$ |$$ |      $$ |\\$  /$$ |$$ |$$ |      $$ |      $$ |  $$ |\r\n\
267 $$ |  $$ |$$ |      $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ |      \\$$$$$$  |\r\n\
268 \\__|  \\__|\\__|      \\__|     \\__|\\__| \\_______|\\__|       \\______/\r\n\
269 ----------------------------------------------------------------------\r\n"};
270     printf("%s", banner);
271 }
272 
init_enet_pins(ENET_Type * ptr)273 void init_enet_pins(ENET_Type *ptr)
274 {
275     if (ptr == HPM_ENET0) {
276         HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_GPIO_D_18;
277 
278         HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_ETH0_MDC;
279         HPM_IOC->PAD[IOC_PAD_PD03].FUNC_CTL = IOC_PD03_FUNC_CTL_ETH0_MDIO;
280 
281         HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_ETH0_RXD_0;
282         HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_ETH0_RXD_1;
283         HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_ETH0_RXD_2;
284         HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_ETH0_RXD_3;
285         HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_ETH0_RXCK;
286         HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_ETH0_RXDV;
287 
288         HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_ETH0_TXD_0;
289         HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_ETH0_TXD_1;
290         HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_ETH0_TXD_2;
291         HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_ETH0_TXD_3;
292         HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_ETH0_TXCK;
293         HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_ETH0_TXEN;
294     }
295 }
296 
board_init_enet_pins(ENET_Type * ptr)297 hpm_stat_t board_init_enet_pins(ENET_Type *ptr)
298 {
299     init_enet_pins(ptr);
300 
301     if (ptr == HPM_ENET0) {
302         gpio_set_pin_output_with_initial(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX,
303                                          BOARD_ENET_RGMII_RST_GPIO_PIN, 0);
304     } else {
305         return status_invalid_argument;
306     }
307 
308     return status_success;
309 }
310 
board_reset_enet_phy(ENET_Type * ptr)311 hpm_stat_t board_reset_enet_phy(ENET_Type *ptr)
312 {
313     if (ptr == HPM_ENET0) {
314         gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 0);
315         board_delay_ms(1);
316         gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 1);
317     } else {
318         return status_invalid_argument;
319     }
320 
321     return status_success;
322 }
323 
board_get_enet_dma_pbl(ENET_Type * ptr)324 uint8_t board_get_enet_dma_pbl(ENET_Type *ptr)
325 {
326     (void) ptr;
327     return enet_pbl_32;
328 }
329 
board_enable_enet_irq(ENET_Type * ptr)330 hpm_stat_t board_enable_enet_irq(ENET_Type *ptr)
331 {
332     if (ptr == HPM_ENET0) {
333         intc_m_enable_irq(IRQn_ENET0);
334     } else {
335         return status_invalid_argument;
336     }
337 
338     return status_success;
339 }
340 
board_disable_enet_irq(ENET_Type * ptr)341 hpm_stat_t board_disable_enet_irq(ENET_Type *ptr)
342 {
343     if (ptr == HPM_ENET0) {
344         intc_m_disable_irq(IRQn_ENET0);
345     } else {
346         return status_invalid_argument;
347     }
348 
349     return status_success;
350 }
351 
board_init_enet_ptp_clock(ENET_Type * ptr)352 hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr)
353 {
354     /* set clock source */
355     if (ptr == HPM_ENET0) {
356         /* make sure pll0_clk0 output clock at 800MHz to get a clock at 100MHz for the enet0 ptp function */
357         clock_set_source_divider(clock_ptp0, clk_src_pll1_clk0, 8); /* 100MHz */
358     } else {
359         return status_invalid_argument;
360     }
361 
362     return status_success;
363 }
364 
board_init_enet_rmii_reference_clock(ENET_Type * ptr,bool internal)365 hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal)
366 {
367     (void) ptr;
368     (void) internal;
369     return status_success;
370 }
371 
board_init_enet_rgmii_clock_delay(ENET_Type * ptr)372 hpm_stat_t board_init_enet_rgmii_clock_delay(ENET_Type *ptr)
373 {
374     if (ptr == HPM_ENET0) {
375         return enet_rgmii_set_clock_delay(ptr, BOARD_ENET_RGMII_TX_DLY, BOARD_ENET_RGMII_RX_DLY);
376     }
377 
378     return status_invalid_argument;
379 }
380 
init_gpio_pins(void)381 void init_gpio_pins(void)
382 {
383     HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = 0;
384     HPM_IOC->PAD[IOC_PAD_PF06].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_MASK;
385 
386     HPM_IOC->PAD[IOC_PAD_PF07].FUNC_CTL = 0;
387     HPM_IOC->PAD[IOC_PAD_PF07].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_MASK;
388 }
389 
init_gpio_out_task_pins(void)390 void init_gpio_out_task_pins(void)
391 {
392     HPM_IOC->PAD[IOC_PAD_PF01].FUNC_CTL = 0;
393     HPM_IOC->PAD[IOC_PAD_PF01].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
394 
395     HPM_IOC->PAD[IOC_PAD_PF02].FUNC_CTL = 0;
396     HPM_IOC->PAD[IOC_PAD_PF02].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
397 
398     HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = 0;
399     HPM_IOC->PAD[IOC_PAD_PF05].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
400 }
401 
init_i2c_pins(I2C_Type * ptr)402 void init_i2c_pins(I2C_Type *ptr)
403 {
404     if (ptr == HPM_I2C1) {
405         HPM_IOC->PAD[IOC_PAD_PE12].FUNC_CTL = IOC_PE12_FUNC_CTL_I2C1_SDA
406                                             | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
407         HPM_IOC->PAD[IOC_PAD_PE13].FUNC_CTL = IOC_PE13_FUNC_CTL_I2C1_SCL
408                                             | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
409         HPM_IOC->PAD[IOC_PAD_PE12].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK;
410         HPM_IOC->PAD[IOC_PAD_PE13].PAD_CTL = IOC_PAD_PAD_CTL_OD_MASK;
411     } else {
412         ;
413     }
414 }
415 
init_spi_pins(SPI_Type * ptr)416 void init_spi_pins(SPI_Type *ptr)
417 {
418     if (ptr == HPM_SPI3) {
419         HPM_IOC->PAD[IOC_PAD_PE05].FUNC_CTL = IOC_PE05_FUNC_CTL_SPI3_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1);
420         HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_SPI3_MISO;
421         HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_SPI3_MOSI;
422         HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_SPI3_CS_0;
423     }
424 }