• 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_enet_drv.h>
19 #include <hpm_gpio_drv.h>
20 #include <hpm_pmp_drv.h>
21 #include <hpm_pcfg_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_clock(void)89 void board_init_clock(void)
90 {
91     uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
92     if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
93         /* Configure the External OSC ramp-up time: ~9ms */
94         pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32UL * 1000UL * 9U);
95 
96         /* Select clock setting preset1 */
97         sysctl_clock_set_preset(HPM_SYSCTL, 2);
98     }
99 
100     /* Add most Clocks to group 0 */
101     /* not open uart clock in this API, uart should configure pin function before opening clock */
102     clock_add_to_group(clock_cpu0, 0);
103     clock_add_to_group(clock_ahbp, 0);
104     clock_add_to_group(clock_axic, 0);
105     clock_add_to_group(clock_axis, 0);
106 
107     clock_add_to_group(clock_mchtmr0, 0);
108     clock_add_to_group(clock_femc, 0);
109     clock_add_to_group(clock_xpi0, 0);
110     clock_add_to_group(clock_xpi1, 0);
111     clock_add_to_group(clock_gptmr0, 0);
112     clock_add_to_group(clock_gptmr1, 0);
113     clock_add_to_group(clock_gptmr2, 0);
114     clock_add_to_group(clock_gptmr3, 0);
115     clock_add_to_group(clock_uart0, 0);
116     clock_add_to_group(clock_i2c0, 0);
117     clock_add_to_group(clock_i2c1, 0);
118     clock_add_to_group(clock_i2c2, 0);
119     clock_add_to_group(clock_i2c3, 0);
120     clock_add_to_group(clock_spi0, 0);
121     clock_add_to_group(clock_spi1, 0);
122     clock_add_to_group(clock_spi2, 0);
123     clock_add_to_group(clock_spi3, 0);
124     clock_add_to_group(clock_can0, 0);
125     clock_add_to_group(clock_can1, 0);
126     clock_add_to_group(clock_sdxc0, 0);
127     clock_add_to_group(clock_ptpc, 0);
128     clock_add_to_group(clock_ref0, 0);
129     clock_add_to_group(clock_ref1, 0);
130     clock_add_to_group(clock_watchdog0, 0);
131     clock_add_to_group(clock_eth0, 0);
132     clock_add_to_group(clock_sdp, 0);
133     clock_add_to_group(clock_xdma, 0);
134     clock_add_to_group(clock_ram0, 0);
135     clock_add_to_group(clock_usb0, 0);
136     clock_add_to_group(clock_kman, 0);
137     clock_add_to_group(clock_gpio, 0);
138     clock_add_to_group(clock_mbx0, 0);
139     clock_add_to_group(clock_hdma, 0);
140     clock_add_to_group(clock_rng, 0);
141     clock_add_to_group(clock_mot0, 0);
142     clock_add_to_group(clock_mot1, 0);
143     clock_add_to_group(clock_acmp, 0);
144     clock_add_to_group(clock_dao, 0);
145     clock_add_to_group(clock_msyn, 0);
146     clock_add_to_group(clock_lmm0, 0);
147     clock_add_to_group(clock_pdm, 0);
148 
149     clock_add_to_group(clock_adc0, 0);
150     clock_add_to_group(clock_adc1, 0);
151     clock_add_to_group(clock_adc2, 0);
152 
153     clock_add_to_group(clock_dac0, 0);
154 
155     clock_add_to_group(clock_i2s0, 0);
156     clock_add_to_group(clock_i2s1, 0);
157 
158     clock_add_to_group(clock_ffa0, 0);
159     clock_add_to_group(clock_tsns, 0);
160 
161     /* Connect Group0 to CPU0 */
162     clock_connect_group_to_cpu(0, 0);
163 
164     /* Configure CPU to 480MHz, AXI/AHB to 160MHz */
165     sysctl_config_cpu0_domain_clock(HPM_SYSCTL, clock_source_pll1_clk0, 1, 3, 3);
166     /* Configure PLL1_CLK0 Post Divider to 1.2 */
167     pllctlv2_set_postdiv(HPM_PLLCTLV2, 1, 0, 1);
168     /* Configure PLL1 clock frequencey to 576MHz, the PLL1_CLK0 frequency = 576MHz / 1.2 = 480MHz */
169     pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 1, 576000000);
170     clock_update_core_clock();
171 
172     /* Configure mchtmr to 24MHz */
173     clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
174 }
175 
board_init_pmp(void)176 void board_init_pmp(void)
177 {
178     extern uint32_t __noncacheable_start__[];
179     extern uint32_t __noncacheable_end__[];
180 
181     uint32_t start_addr = (uint32_t) __noncacheable_start__;
182     uint32_t end_addr = (uint32_t) __noncacheable_end__;
183     uint32_t length = end_addr - start_addr;
184 
185     if (length == 0) {
186         return;
187     }
188 
189     /* Ensure the address and the length are power of 2 aligned */
190     assert((length & (length - 1U)) == 0U);
191     assert((start_addr & (length - 1U)) == 0U);
192 
193     pmp_entry_t pmp_entry[3] = {0};
194     pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(0x0000000, 0x80000000);
195     pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
196 
197 
198     pmp_entry[1].pmp_addr = PMP_NAPOT_ADDR(0x80000000, 0x80000000);
199     pmp_entry[1].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
200 
201     pmp_entry[2].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
202     pmp_entry[2].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
203     pmp_entry[2].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
204     pmp_entry[2].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
205     pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry));
206 }
207 
board_init(void)208 void board_init(void)
209 {
210     pcfg_dcdc_set_voltage(HPM_PCFG, 1100);
211     board_init_clock();
212     board_init_pmp();
213 }
214 
board_print_clock_freq(void)215 void board_print_clock_freq(void)
216 {
217     printf("==============================\n");
218     printf(" %s clock summary\n", "HPM6300EVK");
219     printf("==============================\n");
220     printf("cpu0:\t\t %luHz\n", clock_get_frequency(clock_cpu0));
221     printf("axi:\t\t %luHz\n", clock_get_frequency(clock_axi));
222     printf("ahb:\t\t %luHz\n", clock_get_frequency(clock_ahb));
223     printf("mchtmr0:\t %luHz\n", clock_get_frequency(clock_mchtmr0));
224     printf("xpi0:\t\t %luHz\n", clock_get_frequency(clock_xpi0));
225     printf("xpi1:\t\t %luHz\n", clock_get_frequency(clock_xpi1));
226     printf("femc:\t\t %luHz\n", clock_get_frequency(clock_femc));
227     printf("==============================\n");
228 }
229 
board_print_banner(void)230 void board_print_banner(void)
231 {
232     const uint8_t banner[] = {"\n\
233 ----------------------------------------------------------------------\r\n\
234 $$\\   $$\\ $$$$$$$\\  $$\\      $$\\ $$\\\r\n\
235 $$ |  $$ |$$  __$$\\ $$$\\    $$$ |\\__|\r\n\
236 $$ |  $$ |$$ |  $$ |$$$$\\  $$$$ |$$\\  $$$$$$$\\  $$$$$$\\   $$$$$$\\\r\n\
237 $$$$$$$$ |$$$$$$$  |$$\\$$\\$$ $$ |$$ |$$  _____|$$  __$$\\ $$  __$$\\\r\n\
238 $$  __$$ |$$  ____/ $$ \\$$$  $$ |$$ |$$ /      $$ |  \\__|$$ /  $$ |\r\n\
239 $$ |  $$ |$$ |      $$ |\\$  /$$ |$$ |$$ |      $$ |      $$ |  $$ |\r\n\
240 $$ |  $$ |$$ |      $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ |      \\$$$$$$  |\r\n\
241 \\__|  \\__|\\__|      \\__|     \\__|\\__| \\_______|\\__|       \\______/\r\n\
242 ----------------------------------------------------------------------\r\n"};
243     printf("%s", banner);
244 }
245 
init_enet_pins(ENET_Type * ptr)246 static void init_enet_pins(ENET_Type *ptr)
247 {
248     if (ptr == HPM_ENET0) {
249         HPM_IOC->PAD[IOC_PAD_PA16].FUNC_CTL = IOC_PA16_FUNC_CTL_ETH0_MDC;
250         HPM_IOC->PAD[IOC_PAD_PA15].FUNC_CTL = IOC_PA15_FUNC_CTL_ETH0_MDIO;
251 
252         HPM_IOC->PAD[IOC_PAD_PA18].FUNC_CTL = IOC_PA18_FUNC_CTL_ETH0_RXD_0;
253         HPM_IOC->PAD[IOC_PAD_PA17].FUNC_CTL = IOC_PA17_FUNC_CTL_ETH0_RXD_1;
254         HPM_IOC->PAD[IOC_PAD_PA19].FUNC_CTL = IOC_PA19_FUNC_CTL_ETH0_RXDV;
255 
256         HPM_IOC->PAD[IOC_PAD_PA20].FUNC_CTL = IOC_PA20_FUNC_CTL_ETH0_TXD_0;
257         HPM_IOC->PAD[IOC_PAD_PA21].FUNC_CTL = IOC_PA21_FUNC_CTL_ETH0_TXD_1;
258         HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_ETH0_TXEN;
259 
260         HPM_IOC->PAD[IOC_PAD_PA22].FUNC_CTL = IOC_PAD_FUNC_CTL_LOOP_BACK_MASK | IOC_PA22_FUNC_CTL_ETH0_REFCLK;
261     }
262 }
263 
board_init_enet_pins(ENET_Type * ptr)264 hpm_stat_t board_init_enet_pins(ENET_Type *ptr)
265 {
266     init_enet_pins(ptr);
267 
268     return status_success;
269 }
270 
board_init_enet_ptp_clock(ENET_Type * ptr)271 hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr)
272 {
273     /* set clock source */
274     if (ptr == HPM_ENET0) {
275         /* make sure pll0_clk0 output clock at 400MHz to get a clock at 100MHz for ent0 ptp clock */
276         clock_set_source_divider(clock_ptp0, clk_src_pll0_clk0, 4); /* 100MHz */
277     } else {
278         return status_invalid_argument;
279     }
280 
281     return status_success;
282 }
283 
board_init_enet_rmii_reference_clock(ENET_Type * ptr,bool internal)284 hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal)
285 {
286     /* Configure Enet clock to output reference clock */
287     if (ptr == HPM_ENET0) {
288         if (internal) {
289             /* set pll output frequency at 1GHz */
290             if (pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1000000000UL) == status_success) {
291                 /* set pll2_clk1 output frequence at 250MHz from PLL2 divided by 4 (1 + 15 / 5) */
292                 pllctlv2_set_postdiv(HPM_PLLCTLV2, PLLCTLV2_PLL_PLL2, 1, 15);
293                 /* set eth clock frequency at 50MHz for enet0 */
294                 clock_set_source_divider(clock_eth0, clk_src_pll2_clk1, 5);
295             } else {
296                 return status_fail;
297             }
298         }
299     } else {
300         return status_invalid_argument;
301     }
302 
303     enet_rmii_enable_clock(ptr, internal);
304 
305     return status_success;
306 }
307 
init_gpio_pins(void)308 void init_gpio_pins(void)
309 {
310     HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_SOC_PZ_02;
311     HPM_BIOC->PAD[IOC_PAD_PZ02].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
312     HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = IOC_PZ03_FUNC_CTL_SOC_PZ_03;
313     HPM_BIOC->PAD[IOC_PAD_PZ03].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
314 
315     HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = 0;
316     HPM_IOC->PAD[IOC_PAD_PZ02].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
317 
318     HPM_IOC->PAD[IOC_PAD_PZ03].FUNC_CTL = 0;
319     HPM_IOC->PAD[IOC_PAD_PZ03].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
320 }
321 
init_gpio_out_task_pins(void)322 void init_gpio_out_task_pins(void)
323 {
324     HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = 0;
325     HPM_IOC->PAD[IOC_PAD_PA07].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
326 
327     HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = 0;
328     HPM_IOC->PAD[IOC_PAD_PA08].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
329 
330     HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = 0;
331     HPM_IOC->PAD[IOC_PAD_PA09].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
332 }
333 
init_i2c_pins(I2C_Type * ptr)334 void init_i2c_pins(I2C_Type *ptr)
335 {
336     if (ptr == HPM_I2C0) {
337         HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_I2C0_SCL
338                                             | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
339         HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_I2C0_SDA
340                                             | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
341         HPM_IOC->PAD[IOC_PAD_PC13].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
342         HPM_IOC->PAD[IOC_PAD_PC14].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
343     } else {
344         while (1) {
345         }
346     }
347 }
348 
init_spi_pins(SPI_Type * ptr)349 void init_spi_pins(SPI_Type *ptr)
350 {
351     if (ptr == HPM_SPI3) {
352         HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_SPI3_CSN;
353         HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_SPI3_MOSI;
354         HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_SPI3_MISO;
355         HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_SPI3_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1);
356     }
357 }
358