• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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