1 /*
2 * Copyright (c) 2023 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_gpio_drv.h>
19 #include <hpm_pmp_drv.h>
20 #include <hpm_pllctlv2_drv.h>
21 #include <hpm_pcfg_drv.h>
22 #include <hpm_i2c_drv.h>
23 /**
24 * @brief FLASH configuration option definitions:
25 * option[0]:
26 * [31:16] 0xfcf9 - FLASH configuration option tag
27 * [15:4] 0 - Reserved
28 * [3:0] option words (exclude option[0])
29 * option[1]:
30 * [31:28] Flash probe type
31 * 0 - SFDP SDR / 1 - SFDP DDR
32 * 2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
33 * 4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
34 * 6 - OctaBus DDR (SPI -> OPI DDR)
35 * 8 - Xccela DDR (SPI -> OPI DDR)
36 * 10 - EcoXiP DDR (SPI -> OPI DDR)
37 * [27:24] Command Pads after Power-on Reset
38 * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
39 * [23:20] Command Pads after Configuring FLASH
40 * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
41 * [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
42 * 0 - Not needed
43 * 1 - QE bit is at bit 6 in Status Register 1
44 * 2 - QE bit is at bit1 in Status Register 2
45 * 3 - QE bit is at bit7 in Status Register 2
46 * 4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
47 * [15:8] Dummy cycles
48 * 0 - Auto-probed / detected / default value
49 * Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
50 * [7:4] Misc.
51 * 0 - Not used
52 * 1 - SPI mode
53 * 2 - Internal loopback
54 * 3 - External DQS
55 * [3:0] Frequency option
56 * 1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
57 *
58 * option[2] (Effective only if the bit[3:0] in option[0] > 1)
59 * [31:20] Reserved
60 * [19:16] IO voltage
61 * 0 - 3V / 1 - 1.8V
62 * [15:12] Pin group
63 * 0 - 1st group / 1 - 2nd group
64 * [11:8] Connection selection
65 * 0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
66 * [7:0] Drive Strength
67 * 0 - Default value
68 * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
69 * JESD216)
70 * [31:16] reserved
71 * [15:12] Sector Erase Command Option, not required here
72 * [11:8] Sector Size Option, not required here
73 * [7:0] Flash Size Option
74 * 0 - 4MB / 1 - 8MB / 2 - 16MB
75 */
76 #if defined(FLASH_XIP) && FLASH_XIP
77 __attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90001, 0x00000007, 0x0, 0x0};
78 #endif
79
board_delay_us(uint32_t us)80 void board_delay_us(uint32_t us)
81 {
82 clock_cpu_delay_us(us);
83 }
84
board_delay_ms(uint32_t ms)85 void board_delay_ms(uint32_t ms)
86 {
87 clock_cpu_delay_ms(ms);
88 }
89
board_init_clock(void)90 void board_init_clock(void)
91 {
92 uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
93 if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
94 /* Configure the External OSC ramp-up time: ~9ms */
95 pllctlv2_xtal_set_rampup_time(HPM_PLLCTLV2, 32UL * 1000UL * 9U);
96
97 /* Select clock setting preset1 */
98 sysctl_clock_set_preset(HPM_SYSCTL, 2);
99 }
100
101 /* Add most Clocks to group 0 */
102 clock_add_to_group(clock_cpu0, 0);
103 clock_add_to_group(clock_mchtmr0, 0);
104 clock_add_to_group(clock_axic, 0);
105 clock_add_to_group(clock_axis, 0);
106 clock_add_to_group(clock_ahb, 0);
107 clock_add_to_group(clock_xpi0, 0);
108 clock_add_to_group(clock_gptmr0, 0);
109 clock_add_to_group(clock_gptmr1, 0);
110 clock_add_to_group(clock_gptmr2, 0);
111 clock_add_to_group(clock_gptmr3, 0);
112 clock_add_to_group(clock_uart0, 0);
113 clock_add_to_group(clock_uart1, 0);
114 clock_add_to_group(clock_uart2, 0);
115 clock_add_to_group(clock_i2c0, 0);
116 clock_add_to_group(clock_i2c1, 0);
117 clock_add_to_group(clock_i2c2, 0);
118 clock_add_to_group(clock_i2c3, 0);
119 clock_add_to_group(clock_spi0, 0);
120 clock_add_to_group(clock_spi1, 0);
121 clock_add_to_group(clock_spi2, 0);
122 clock_add_to_group(clock_spi3, 0);
123 clock_add_to_group(clock_can0, 0);
124 clock_add_to_group(clock_can1, 0);
125 clock_add_to_group(clock_can2, 0);
126 clock_add_to_group(clock_can3, 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_watchdog1, 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_gpio, 0);
137 clock_add_to_group(clock_mbx0, 0);
138 clock_add_to_group(clock_hdma, 0);
139 clock_add_to_group(clock_rng, 0);
140 clock_add_to_group(clock_mot0, 0);
141 clock_add_to_group(clock_mot1, 0);
142 clock_add_to_group(clock_mot2, 0);
143 clock_add_to_group(clock_mot3, 0);
144 clock_add_to_group(clock_acmp, 0);
145 clock_add_to_group(clock_msyn, 0);
146 clock_add_to_group(clock_lmm0, 0);
147 clock_add_to_group(clock_lmm1, 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 /* Add the CPU1 clock to Group1 */
154 clock_add_to_group(clock_mchtmr1, 1);
155 clock_add_to_group(clock_mbx1, 1);
156
157 /* Connect Group0 to CPU0 */
158 clock_connect_group_to_cpu(0, 0);
159
160 /* Connect Group1 to CPU1 */
161 clock_connect_group_to_cpu(1, 1);
162
163 /* Bump up DCDC voltage to 1275mv */
164 pcfg_dcdc_set_voltage(HPM_PCFG, 1275);
165
166 /* Connect CAN2/CAN3 to pll0clk0*/
167 clock_set_source_divider(clock_can2, clk_src_pll0_clk0, 1);
168 clock_set_source_divider(clock_can3, clk_src_pll0_clk0, 1);
169
170 /* Configure CPU to 600MHz, AXI/AHB to 200MHz */
171 sysctl_config_cpu0_domain_clock(HPM_SYSCTL, clock_source_pll1_clk0, 1, 3, 3);
172 /* Configure PLL1_CLK0 Post Divider to 1 */
173 pllctlv2_set_postdiv(HPM_PLLCTLV2, 1, 0, 0);
174 pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, 1, 600000000);
175 clock_update_core_clock();
176
177 /* Configure mchtmr to 24MHz */
178 clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
179 clock_set_source_divider(clock_mchtmr1, clk_src_osc24m, 1);
180 }
181
board_init_pmp(void)182 void board_init_pmp(void)
183 {
184 extern uint32_t __noncacheable_start__[];
185 extern uint32_t __noncacheable_end__[];
186
187 uint32_t start_addr = (uint32_t) __noncacheable_start__;
188 uint32_t end_addr = (uint32_t) __noncacheable_end__;
189 uint32_t length = end_addr - start_addr;
190
191 if (length == 0) {
192 return;
193 }
194
195 /* Ensure the address and the length are power of 2 aligned */
196 assert((length & (length - 1U)) == 0U);
197 assert((start_addr & (length - 1U)) == 0U);
198
199 pmp_entry_t pmp_entry[1];
200 pmp_entry[0].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
201 pmp_entry[0].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
202 pmp_entry[0].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
203 pmp_entry[0].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
204
205 pmp_config(&pmp_entry[0], ARRAY_SIZE(pmp_entry));
206 }
207
board_init_ahb(void)208 void board_init_ahb(void)
209 {
210 //clock_set_source_divider(clock_ahb, clk_src_pll1_clk1, 2);/*200m hz*/
211 }
212
board_init(void)213 void board_init(void)
214 {
215 board_init_clock();
216 sysctl_set_cpu_lp_mode(HPM_SYSCTL, HPM_CORE0, cpu_lp_mode_ungate_cpu_clock);
217 board_init_pmp();
218 board_init_ahb();
219 }
220
board_print_clock_freq(void)221 void board_print_clock_freq(void)
222 {
223 printf("==============================\r\n");
224 printf(" %s clock summary\r\n", "HPM6280EVK");
225 printf("==============================\r\n");
226 printf("cpu0:\t\t %luHz\n", clock_get_frequency(clock_cpu0));
227 printf("cpu1:\t\t %luHz\n", clock_get_frequency(clock_cpu1));
228 printf("axi:\t\t %luHz\n", clock_get_frequency(clock_axi));
229 printf("ahb:\t\t %luHz\n", clock_get_frequency(clock_ahb));
230 printf("mchtmr0:\t %luHz\n", clock_get_frequency(clock_mchtmr0));
231 printf("mchtmr1:\t %luHz\n", clock_get_frequency(clock_mchtmr1));
232 printf("xpi0:\t\t %luHz\n", clock_get_frequency(clock_xpi0));
233 printf("==============================\r\n");
234 }
235
board_print_banner(void)236 void board_print_banner(void)
237 {
238 const uint8_t banner[] = {"\n\
239 ----------------------------------------------------------------------\r\n\
240 $$\\ $$\\ $$$$$$$\\ $$\\ $$\\ $$\\\r\n\
241 $$ | $$ |$$ __$$\\ $$$\\ $$$ |\\__|\r\n\
242 $$ | $$ |$$ | $$ |$$$$\\ $$$$ |$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\\r\n\
243 $$$$$$$$ |$$$$$$$ |$$\\$$\\$$ $$ |$$ |$$ _____|$$ __$$\\ $$ __$$\\\r\n\
244 $$ __$$ |$$ ____/ $$ \\$$$ $$ |$$ |$$ / $$ | \\__|$$ / $$ |\r\n\
245 $$ | $$ |$$ | $$ |\\$ /$$ |$$ |$$ | $$ | $$ | $$ |\r\n\
246 $$ | $$ |$$ | $$ | \\_/ $$ |$$ |\\$$$$$$$\\ $$ | \\$$$$$$ |\r\n\
247 \\__| \\__|\\__| \\__| \\__|\\__| \\_______|\\__| \\______/\r\n\
248 ----------------------------------------------------------------------\r\n"};
249 printf("%s", banner);
250 }
251
init_gpio_pins(void)252 void init_gpio_pins(void)
253 {
254 HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = 0;
255 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);
256
257 HPM_IOC->PAD[IOC_PAD_PZ03].FUNC_CTL = 0;
258 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);
259
260 HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_SOC_PZ_02;
261 HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = IOC_PZ03_FUNC_CTL_SOC_PZ_03;
262 }
263
init_gpio_out_task_pins(void)264 void init_gpio_out_task_pins(void)
265 {
266 HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = 0;
267 HPM_IOC->PAD[IOC_PAD_PA27].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
268
269 HPM_IOC->PAD[IOC_PAD_PB01].FUNC_CTL = 0;
270 HPM_IOC->PAD[IOC_PAD_PB01].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
271
272 HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = 0;
273 HPM_IOC->PAD[IOC_PAD_PB19].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
274 }
275
init_i2c_pins(I2C_Type * ptr)276 void init_i2c_pins(I2C_Type *ptr)
277 {
278 if (ptr == HPM_I2C0) {
279 HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_I2C0_SCL
280 | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
281 HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_I2C0_SDA
282 | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
283 HPM_IOC->PAD[IOC_PAD_PB22].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
284 HPM_IOC->PAD[IOC_PAD_PB23].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
285 } else {
286 while (1) {
287 }
288 }
289 }
290
init_spi_pins(SPI_Type * ptr)291 void init_spi_pins(SPI_Type *ptr)
292 {
293 if (ptr == HPM_SPI1) {
294 HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_SPI1_CSN;
295 HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_SPI1_MOSI;
296 HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_SPI1_MISO;
297 HPM_IOC->PAD[IOC_PAD_PB04].FUNC_CTL = IOC_PB04_FUNC_CTL_SPI1_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1);
298 }
299 }
300
301