• 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_pllctl_drv.h>
18 #include <hpm_enet_drv.h>
19 #include <hpm_gpio_drv.h>
20 #include <hpm_pmp_drv.h>
21 /**
22  * @brief FLASH configuration option definitions:
23  * option[0]:
24  *    [31:16] 0xfcf9 - FLASH configuration option tag
25  *    [15:4]  0 - Reserved
26  *    [3:0]   option words (exclude option[0])
27  * option[1]:
28  *    [31:28] Flash probe type
29  *      0 - SFDP SDR / 1 - SFDP DDR
30  *      2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
31  *      4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
32  *      6 - OctaBus DDR (SPI -> OPI DDR)
33  *      8 - Xccela DDR (SPI -> OPI DDR)
34  *      10 - EcoXiP DDR (SPI -> OPI DDR)
35  *    [27:24] Command Pads after Power-on Reset
36  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
37  *    [23:20] Command Pads after Configuring FLASH
38  *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
39  *    [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
40  *      0 - Not needed
41  *      1 - QE bit is at bit 6 in Status Register 1
42  *      2 - QE bit is at bit1 in Status Register 2
43  *      3 - QE bit is at bit7 in Status Register 2
44  *      4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
45  *    [15:8] Dummy cycles
46  *      0 - Auto-probed / detected / default value
47  *      Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
48  *    [7:4] Misc.
49  *      0 - Not used
50  *      1 - SPI mode
51  *      2 - Internal loopback
52  *      3 - External DQS
53  *    [3:0] Frequency option
54  *      1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
55  *
56  * option[2] (Effective only if the bit[3:0] in option[0] > 1)
57  *    [31:20]  Reserved
58  *    [19:16] IO voltage
59  *      0 - 3V / 1 - 1.8V
60  *    [15:12] Pin group
61  *      0 - 1st group / 1 - 2nd group
62  *    [11:8] Connection selection
63  *      0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
64  *    [7:0] Drive Strength
65  *      0 - Default value
66  * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
67  *              JESD216)
68  *    [31:16] reserved
69  *    [15:12] Sector Erase Command Option, not required here
70  *    [11:8]  Sector Size Option, not required here
71  *    [7:0] Flash Size Option
72  *      0 - 4MB / 1 - 8MB / 2 - 16MB
73  */
74 #if defined(FLASH_XIP) && FLASH_XIP
75 __attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90001, 0x00000007, 0x0, 0x0};
76 #endif
77 
board_delay_us(uint32_t us)78 void board_delay_us(uint32_t us)
79 {
80     clock_cpu_delay_us(us);
81 }
82 
board_delay_ms(uint32_t ms)83 void board_delay_ms(uint32_t ms)
84 {
85     clock_cpu_delay_ms(ms);
86 }
87 
board_init_clock(void)88 void board_init_clock(void)
89 {
90     uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
91     if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
92         /* Configure the External OSC ramp-up time: ~9ms */
93         pllctl_xtal_set_rampup_time(HPM_PLLCTL, 32UL * 1000UL * 9U);
94 
95         /* Select clock setting preset1 */
96         sysctl_clock_set_preset(HPM_SYSCTL, sysctl_preset_1);
97     }
98 
99     /* Add most Clocks to group 0 */
100     clock_add_to_group(clock_cpu0, 0);
101     clock_add_to_group(clock_mchtmr0, 0);
102     clock_add_to_group(clock_axi0, 0);
103     clock_add_to_group(clock_axi1, 0);
104     clock_add_to_group(clock_axi2, 0);
105     clock_add_to_group(clock_ahb, 0);
106     clock_add_to_group(clock_dram, 0);
107     clock_add_to_group(clock_xpi0, 0);
108     clock_add_to_group(clock_xpi1, 0);
109     clock_add_to_group(clock_gptmr0, 0);
110     clock_add_to_group(clock_gptmr1, 0);
111     clock_add_to_group(clock_gptmr2, 0);
112     clock_add_to_group(clock_gptmr3, 0);
113     clock_add_to_group(clock_gptmr4, 0);
114     clock_add_to_group(clock_gptmr5, 0);
115     clock_add_to_group(clock_gptmr6, 0);
116     clock_add_to_group(clock_gptmr7, 0);
117     clock_add_to_group(clock_uart0, 0);
118     clock_add_to_group(clock_uart1, 0);
119     clock_add_to_group(clock_uart2, 0);
120     clock_add_to_group(clock_uart3, 0);
121     clock_add_to_group(clock_uart13, 0);
122     clock_add_to_group(clock_i2c0, 0);
123     clock_add_to_group(clock_i2c1, 0);
124     clock_add_to_group(clock_i2c2, 0);
125     clock_add_to_group(clock_i2c3, 0);
126     clock_add_to_group(clock_spi0, 0);
127     clock_add_to_group(clock_spi1, 0);
128     clock_add_to_group(clock_spi2, 0);
129     clock_add_to_group(clock_spi3, 0);
130     clock_add_to_group(clock_can0, 0);
131     clock_add_to_group(clock_can1, 0);
132     clock_add_to_group(clock_can2, 0);
133     clock_add_to_group(clock_can3, 0);
134     clock_add_to_group(clock_display, 0);
135     clock_add_to_group(clock_sdxc0, 0);
136     clock_add_to_group(clock_sdxc1, 0);
137     clock_add_to_group(clock_camera0, 0);
138     clock_add_to_group(clock_camera1, 0);
139     clock_add_to_group(clock_ptpc, 0);
140     clock_add_to_group(clock_ref0, 0);
141     clock_add_to_group(clock_ref1, 0);
142     clock_add_to_group(clock_watchdog0, 0);
143     clock_add_to_group(clock_watchdog1, 0);
144     clock_add_to_group(clock_watchdog2, 0);
145     clock_add_to_group(clock_watchdog3, 0);
146     clock_add_to_group(clock_pwdg, 0);
147     clock_add_to_group(clock_eth0, 0);
148     clock_add_to_group(clock_eth1, 0);
149     clock_add_to_group(clock_sdp, 0);
150     clock_add_to_group(clock_xdma, 0);
151     clock_add_to_group(clock_ram0, 0);
152     clock_add_to_group(clock_ram1, 0);
153     clock_add_to_group(clock_usb0, 0);
154     clock_add_to_group(clock_usb1, 0);
155     clock_add_to_group(clock_jpeg, 0);
156     clock_add_to_group(clock_pdma, 0);
157     clock_add_to_group(clock_kman, 0);
158     clock_add_to_group(clock_gpio, 0);
159     clock_add_to_group(clock_mbx0, 0);
160     clock_add_to_group(clock_hdma, 0);
161     clock_add_to_group(clock_rng, 0);
162     clock_add_to_group(clock_mot0, 0);
163     clock_add_to_group(clock_mot1, 0);
164     clock_add_to_group(clock_mot2, 0);
165     clock_add_to_group(clock_mot3, 0);
166     clock_add_to_group(clock_acmp, 0);
167     clock_add_to_group(clock_dao, 0);
168     clock_add_to_group(clock_msyn, 0);
169     clock_add_to_group(clock_lmm0, 0);
170     clock_add_to_group(clock_lmm1, 0);
171 
172     clock_add_to_group(clock_adc0, 0);
173     clock_add_to_group(clock_adc1, 0);
174     clock_add_to_group(clock_adc2, 0);
175     clock_add_to_group(clock_adc3, 0);
176 
177     clock_add_to_group(clock_i2s0, 0);
178     clock_add_to_group(clock_i2s1, 0);
179     clock_add_to_group(clock_i2s2, 0);
180     clock_add_to_group(clock_i2s3, 0);
181 
182     /* Add the CPU1 clock to Group1 */
183     clock_add_to_group(clock_mchtmr1, 1);
184     clock_add_to_group(clock_mbx1, 1);
185 
186     /* Connect Group0 to CPU0 */
187     clock_connect_group_to_cpu(0, 0);
188 
189     if (status_success != pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ)) {
190         printf("Failed to set pll0_clk0 to %ldHz\n", BOARD_CPU_FREQ);
191         while(1);
192     }
193 
194     clock_set_source_divider(clock_cpu0, clk_src_pll0_clk0, 1);
195     clock_set_source_divider(clock_cpu1, clk_src_pll0_clk0, 1);
196     /* Connect Group1 to CPU1 */
197     clock_connect_group_to_cpu(1, 1);
198 
199     clock_update_core_clock();
200 }
201 
board_init_pmp(void)202 void board_init_pmp(void)
203 {
204     extern uint32_t __noncacheable_start__[];
205     extern uint32_t __noncacheable_end__[];
206 
207     uint32_t start_addr = (uint32_t) __noncacheable_start__;
208     uint32_t end_addr = (uint32_t) __noncacheable_end__;
209     uint32_t length = end_addr - start_addr;
210 
211     if (length == 0) {
212         return;
213     }
214 
215     /* Ensure the address and the length are power of 2 aligned */
216     assert((length & (length - 1U)) == 0U);
217     assert((start_addr & (length - 1U)) == 0U);
218 
219     pmp_entry_t pmp_entry[1];
220     pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
221     pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
222     pmp_entry[0].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
223     pmp_entry[0].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
224 
225     pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry));
226 }
227 
board_init_ahb(void)228 void board_init_ahb(void)
229 {
230     clock_set_source_divider(clock_ahb, clk_src_pll1_clk1, 2);/*200m hz*/
231 }
232 
board_init(void)233 void board_init(void)
234 {
235     board_init_clock();
236     sysctl_set_cpu_lp_mode(HPM_SYSCTL, HPM_CORE0, cpu_lp_mode_ungate_cpu_clock);
237     board_init_pmp();
238     board_init_ahb();
239 }
240 
board_print_clock_freq(void)241 void board_print_clock_freq(void)
242 {
243     printf("==============================\r\n");
244     printf(" %s clock summary\r\n", "HPM6750EVK2");
245     printf("==============================\r\n");
246     printf("cpu0:\t\t %dHz\r\n", clock_get_frequency(clock_cpu0));
247     printf("cpu1:\t\t %dHz\r\n", clock_get_frequency(clock_cpu1));
248     printf("axi0:\t\t %dHz\r\n", clock_get_frequency(clock_axi0));
249     printf("axi1:\t\t %dHz\r\n", clock_get_frequency(clock_axi1));
250     printf("axi2:\t\t %dHz\r\n", clock_get_frequency(clock_axi2));
251     printf("ahb:\t\t %dHz\r\n", clock_get_frequency(clock_ahb));
252     printf("mchtmr0:\t %dHz\r\n", clock_get_frequency(clock_mchtmr0));
253     printf("mchtmr1:\t %dHz\r\n", clock_get_frequency(clock_mchtmr1));
254     printf("xpi0:\t\t %dHz\r\n", clock_get_frequency(clock_xpi0));
255     printf("xpi1:\t\t %dHz\r\n", clock_get_frequency(clock_xpi1));
256     printf("dram:\t\t %dHz\r\n", clock_get_frequency(clock_dram));
257     printf("display:\t %dHz\r\n", clock_get_frequency(clock_display));
258     printf("cam0:\t\t %dHz\r\n", clock_get_frequency(clock_camera0));
259     printf("cam1:\t\t %dHz\r\n", clock_get_frequency(clock_camera1));
260     printf("jpeg:\t\t %dHz\r\n", clock_get_frequency(clock_jpeg));
261     printf("pdma:\t\t %dHz\r\n", clock_get_frequency(clock_pdma));
262     printf("==============================\r\n");
263 }
264 
board_print_banner(void)265 void board_print_banner(void)
266 {
267     const uint8_t banner[] = {"\n\
268 ----------------------------------------------------------------------\r\n\
269 $$\\   $$\\ $$$$$$$\\  $$\\      $$\\ $$\\\r\n\
270 $$ |  $$ |$$  __$$\\ $$$\\    $$$ |\\__|\r\n\
271 $$ |  $$ |$$ |  $$ |$$$$\\  $$$$ |$$\\  $$$$$$$\\  $$$$$$\\   $$$$$$\\\r\n\
272 $$$$$$$$ |$$$$$$$  |$$\\$$\\$$ $$ |$$ |$$  _____|$$  __$$\\ $$  __$$\\\r\n\
273 $$  __$$ |$$  ____/ $$ \\$$$  $$ |$$ |$$ /      $$ |  \\__|$$ /  $$ |\r\n\
274 $$ |  $$ |$$ |      $$ |\\$  /$$ |$$ |$$ |      $$ |      $$ |  $$ |\r\n\
275 $$ |  $$ |$$ |      $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ |      \\$$$$$$  |\r\n\
276 \\__|  \\__|\\__|      \\__|     \\__|\\__| \\_______|\\__|       \\______/\r\n\
277 ----------------------------------------------------------------------\r\n"};
278     printf("%s", banner);
279 }
280 
init_enet_pins(ENET_Type * ptr)281 static void init_enet_pins(ENET_Type *ptr)
282 {
283     if (ptr == HPM_ENET0) {
284         HPM_IOC->PAD[IOC_PAD_PF00].FUNC_CTL = IOC_PF00_FUNC_CTL_GPIO_F_00;
285 
286         HPM_IOC->PAD[IOC_PAD_PE22].FUNC_CTL = IOC_PE22_FUNC_CTL_ETH0_MDC;
287         HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PE23_FUNC_CTL_ETH0_MDIO;
288 
289         HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_ETH0_RXD_0;
290         HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_ETH0_RXD_1;
291         HPM_IOC->PAD[IOC_PAD_PE02].FUNC_CTL = IOC_PE02_FUNC_CTL_ETH0_RXD_2;
292         HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_ETH0_RXD_3;
293         HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_ETH0_RXCK;
294         HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_ETH0_RXDV;
295 
296         HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_ETH0_TXD_0;
297         HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_ETH0_TXD_1;
298         HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_ETH0_TXD_2;
299         HPM_IOC->PAD[IOC_PAD_PE05].FUNC_CTL = IOC_PE05_FUNC_CTL_ETH0_TXD_3;
300         HPM_IOC->PAD[IOC_PAD_PE01].FUNC_CTL = IOC_PE01_FUNC_CTL_ETH0_TXCK;
301         HPM_IOC->PAD[IOC_PAD_PE00].FUNC_CTL = IOC_PE00_FUNC_CTL_ETH0_TXEN;
302     } else if (ptr == HPM_ENET1) {
303         HPM_IOC->PAD[IOC_PAD_PE26].FUNC_CTL = IOC_PE26_FUNC_CTL_GPIO_E_26;
304 
305         HPM_IOC->PAD[IOC_PAD_PD11].FUNC_CTL = IOC_PD11_FUNC_CTL_ETH1_MDC;
306         HPM_IOC->PAD[IOC_PAD_PD14].FUNC_CTL = IOC_PD14_FUNC_CTL_ETH1_MDIO;
307 
308         HPM_IOC->PAD[IOC_PAD_PE20].FUNC_CTL = IOC_PE20_FUNC_CTL_ETH1_RXD_0;
309         HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_ETH1_RXD_1;
310         HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_ETH1_RXDV;
311 
312         HPM_IOC->PAD[IOC_PAD_PE19].FUNC_CTL = IOC_PE19_FUNC_CTL_ETH1_TXD_0;
313         HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_ETH1_TXD_1;
314         HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_ETH1_TXEN;
315 
316         HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PAD_FUNC_CTL_LOOP_BACK_MASK | IOC_PE16_FUNC_CTL_ETH1_REFCLK;
317     }
318 }
319 
board_init_enet_pins(ENET_Type * ptr)320 hpm_stat_t board_init_enet_pins(ENET_Type *ptr)
321 {
322     init_enet_pins(ptr);
323 
324     if (ptr == HPM_ENET0) {
325         gpio_set_pin_output_with_initial(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 0);
326     } else if (ptr == HPM_ENET1) {
327         gpio_set_pin_output_with_initial(BOARD_ENET_RMII_RST_GPIO, BOARD_ENET_RMII_RST_GPIO_INDEX, BOARD_ENET_RMII_RST_GPIO_PIN, 0);
328     } else {
329         return status_invalid_argument;
330     }
331 
332     return status_success;
333 }
334 
board_reset_enet_phy(ENET_Type * ptr)335 hpm_stat_t board_reset_enet_phy(ENET_Type *ptr)
336 {
337     if (ptr == HPM_ENET0) {
338         gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 0);
339         board_delay_ms(1);
340         gpio_write_pin(BOARD_ENET_RGMII_RST_GPIO, BOARD_ENET_RGMII_RST_GPIO_INDEX, BOARD_ENET_RGMII_RST_GPIO_PIN, 1);
341     } else if (ptr == HPM_ENET1) {
342         gpio_write_pin(BOARD_ENET_RMII_RST_GPIO, BOARD_ENET_RMII_RST_GPIO_INDEX, BOARD_ENET_RMII_RST_GPIO_PIN, 0);
343         board_delay_ms(1);
344         gpio_write_pin(BOARD_ENET_RMII_RST_GPIO, BOARD_ENET_RMII_RST_GPIO_INDEX, BOARD_ENET_RMII_RST_GPIO_PIN, 1);
345     } else {
346         return status_invalid_argument;
347     }
348 
349     return status_success;
350 }
351 
352 
board_init_enet_ptp_clock(ENET_Type * ptr)353 hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr)
354 {
355     /* set clock source */
356     if (ptr == HPM_ENET0) {
357         /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for the enet0 ptp function */
358         clock_set_source_divider(clock_ptp0, clk_src_pll1_clk1, 4); /* 100MHz */
359     } else if (ptr == HPM_ENET1) {
360         /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for the enet1 ptp function */
361         clock_set_source_divider(clock_ptp1, clk_src_pll1_clk1, 4); /* 100MHz */
362     } else {
363         return status_invalid_argument;
364     }
365 
366     return status_success;
367 }
368 
board_init_enet_rmii_reference_clock(ENET_Type * ptr,bool internal)369 hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal)
370 {
371     if (internal == false) {
372         return status_success;
373     }
374     /* Configure Enet clock to output reference clock */
375     if (ptr == HPM_ENET0) {
376         /* make sure pll2_clk1 output clock at 250MHz then set 50MHz for enet0 */
377         clock_set_source_divider(clock_eth0, clk_src_pll2_clk1, 5);
378     } else if (ptr == HPM_ENET1) {
379         /* make sure pll2_clk1 output clock at 250MHz then set 50MHz for enet1 */
380         clock_set_source_divider(clock_eth1, clk_src_pll2_clk1, 5); /* set 50MHz for enet1 */
381     } else {
382         return status_invalid_argument;
383     }
384 
385     enet_rmii_enable_clock(ptr, internal);
386 
387     return status_success;
388 }
389 
board_init_enet_rgmii_clock_delay(ENET_Type * ptr)390 hpm_stat_t board_init_enet_rgmii_clock_delay(ENET_Type *ptr)
391 {
392     return enet_rgmii_set_clock_delay(ptr, BOARD_ENET_RGMII_TX_DLY, BOARD_ENET_RGMII_RX_DLY);
393 }
394