1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 */
9
10 /*******************************************************************************
11 * @file mss_pll.c
12 * @author Microchip-FPGA Embedded Systems Solutions
13 * @brief MPSS PLL setup
14 *
15 */
16
17 #include "mpfs_hal/mss_hal.h"
18 #include "mss_pll.h"
19 #ifndef SIFIVE_HIFIVE_UNLEASHED
20
21 /**
22 * We do it this way to avoid multiple LDRA warnings
23 * alternate it to
24 * #define MSS_SCB_MSS_PLL (IOSCB_CFM_MSS *) )x7xxxxxxx The actual
25 * address * but above results in error every time we use the function
26 */
27
28 PLL_TypeDef * const MSS_SCB_MSS_PLL = ((PLL_TypeDef *) MSS_SCB_MSS_PLL_BASE);
29 PLL_TypeDef * const MSS_SCB_DDR_PLL = ((PLL_TypeDef *) MSS_SCB_DDR_PLL_BASE);
30 PLL_TypeDef * const MSS_SCB_SGMII_PLL = ((PLL_TypeDef *) MSS_SCB_SGMII_PLL_BASE);
31 IOSCB_CFM_MSS * const MSS_SCB_CFM_MSS_MUX =\
32 ((IOSCB_CFM_MSS *) MSS_SCB_MSS_MUX_BASE);
33 IOSCB_CFM_SGMII * const MSS_SCB_CFM_SGMII_MUX =\
34 ((IOSCB_CFM_SGMII *) MSS_SCB_SGMII_MUX_BASE);
35 IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_SGMII =\
36 (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_SGMII_BASE;
37 IOSCB_IO_CALIB_STRUCT * const IOSCB_IO_CALIB_DDR =\
38 (IOSCB_IO_CALIB_STRUCT *)IOSCB_IO_CALIB_DDR_BASE;
39
40
41 /*******************************************************************************-
42 * Symbols from the linker script used to locate the text, data and bss
43 * sections.
44 ******************************************************************************/
45 #ifndef MPFS_HAL_HW_CONFIG
46 uint32_t __sc_load;
47 uint32_t __sc_start;
48 uint32_t __sc_end;
49 #else
50 extern uint32_t __sc_load;
51 extern uint32_t __sc_start;
52 extern uint32_t __sc_end;
53
54 /*******************************************************************************
55 * Local Defines *
56 ******************************************************************************/
57
58 /*******************************************************************************
59 * Local function declarations
60 */
61 __attribute__((weak)) void copy_switch_code(void);
62
63
64 /*******************************************************************************
65 * Instance definitions *
66 ******************************************************************************/
67
68 void sgmii_mux_config(uint8_t option);
69
70 /*******************************************************************************
71 Local functions *
72 *******************************************************************************/
73
74
75 /***************************************************************************//**
76 * set_RTC_divisor()
77 * Set the RTC divisor based on MSS Configurator setting
78 * Note: This will always be calculated so RTC clock is 1MHz.
79 */
set_RTC_divisor(void)80 void set_RTC_divisor(void)
81 {
82
83 SYSREG->RTC_CLOCK_CR &= ~(0x01U<<16); /* disable RTC clock */
84
85 SYSREG->RTC_CLOCK_CR = (LIBERO_SETTING_MSS_EXT_SGMII_REF_CLK / \
86 LIBERO_SETTING_MSS_RTC_TOGGLE_CLK);
87
88 SYSREG->RTC_CLOCK_CR |= (0x01U<<16); /* enable RTC clock */
89
90 }
91
92
93 /***************************************************************************//**
94 * mss_mux_pre_mss_pll_config()
95 *
96 * Feed through required reference clks to PLL, configure PLL and wait for lock
97 ******************************************************************************/
mss_mux_pre_mss_pll_config(void)98 static void mss_mux_pre_mss_pll_config(void)
99 {
100 /*
101 * PLL RF clk mux selections
102 * [31:15] Reserved
103 * [14:10] pll1_fdr_sel
104 * [9:8] pll1_rfclk1_sel
105 * [7:6] pll1_rfclk0_sel
106 * [5:4] pll0_rfclk1_sel
107 * [3:2] pll0_rfclk0_sel
108 * [1:0] clk_in_mac_tsu_sel
109 *
110 * Each mux uses 2 configuration bits. These are decoded as follows:
111 * 00 vss
112 * 01 refclk_p,refclk_n
113 * 10 scb_clk
114 * 10 serdes_refclk_crn_mss<0>, serdes_refclk_crn_mss<1>
115 *
116 * e.g.
117 * PLL_CKMUX = 0x00000154
118 * pll0_rfclk0_sel = 1 => refclk_p is used for pll0 ref0 and refclk_n is
119 * fed to MSS PLL ref1
120 */
121 /* CFM_MSS 0x3E002000 - 0x08 */
122 MSS_SCB_CFM_MSS_MUX->PLL_CKMUX = LIBERO_SETTING_MSS_PLL_CKMUX;
123 /*
124 * MSS Clock mux selections
125 * [31:5] Reserved
126 * [4] clk_standby_sel
127 * [3:2] mssclk_mux_md
128 * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
129 * MSS PLL clock.
130 * [1:0] mssclk_mux_sel MSS glitchless mux select
131 * 00 - msspll_fdr_0=clk_standby
132 * msspll_fdr_1=clk_standby
133 * 01 - msspll_fdr_0=pllout0
134 * msspll_fdr_1=clk_standby
135 * 10 - msspll_fdr_0=clk_standby
136 * msspll_fdr_1=pllout1
137 * 11 - msspll_fdr_0=pllout0
138 * msspll_fdr_1=pllout1
139 *
140 *
141 */
142 /*
143 * We will not set as already set to 0, we feed through after we have setup
144 * clock
145 * MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
146 */
147
148 /*
149 * Clock_Receiver
150 * [13] en_rdiff
151 * [12] clkbuf_en_pullup
152 * [11:10] en_rxmode_n
153 * [9:8] en_term_n
154 * [7] en_ins_hyst_n
155 * [6] en_udrive_n
156 * [5:4] en_rxmode_p
157 * [3:2] en_term_p
158 * [1] en_ins_hyst_p
159 * [0] en_udrive_p
160 */
161 MSS_SCB_CFM_SGMII_MUX->CLK_XCVR = LIBERO_SETTING_SGMII_CLK_XCVR;
162
163 /*
164 * 29:25 bclk5_sel
165 * 24:20 bclk4_sel
166 * 19:15 bclk3_sel
167 * 14:10 bclk2_sel
168 * 9:5 bclk1_sel
169 * 4:0 bclk0_sel
170 *
171 * From SAC spec:
172 * Table 9 1: Each gbim bank clock mux programming in MSS corner
173 * The DDRPHY bank clocks bclk_horz<5:0> and bclk_vert<5:0> are driven
174 * from mux's gbim<5:0> in the MSS corner. Each mux uses 5 configuration
175 * bits.
176 *
177 * BCLK mux selections
178 * bclk0_sel=0x8 (pll0_out_1k<2> selected)
179 * bclk1_sel=0x10 (pll0_out_1k<3> selected)
180 * bclk2_sel=0x1 (vss selected)
181 * bclk3_sel=0x1 (vss selected)
182 * bclk4_sel=0x1 (vss selected)
183 * bclk5_sel=0x1 (vss selected)
184 *
185 */
186 MSS_SCB_CFM_MSS_MUX->BCLKMUX = LIBERO_SETTING_MSS_BCLKMUX;
187
188 /* MSS_SCB_CFM_MSS_MUX->SPARE0 = BCLKMUX_USER_CONFIG; */
189 MSS_SCB_CFM_MSS_MUX->FMETER_ADDR = LIBERO_SETTING_MSS_FMETER_ADDR;
190
191 MSS_SCB_CFM_MSS_MUX->FMETER_DATAW = LIBERO_SETTING_MSS_FMETER_DATAW;
192
193 MSS_SCB_CFM_MSS_MUX->FMETER_DATAR = LIBERO_SETTING_MSS_FMETER_DATAR;
194
195 /*
196 *
197 */
198 volatile uint32_t i;
199 for(i = 0U; i < 400U; i++)
200 {
201 i++;
202 }
203 }
204
205
206 /***************************************************************************//**
207 * mss_mux_post_mss_pll_config(void)
208 *
209 * Once MSS locked, feed through to MSS
210 * We must run this code from RAM, as we need to modify the clock of the eNVM
211 * The first thing we do is change the eNVM clock, to prevent L1 cache accessing
212 * eNVM as it will do as we approach the return instruction
213 * The mb() makes sure order of processing is not changed by the compiler
214 ******************************************************************************/
215 __attribute__((section(".ram_codetext"))) \
mss_mux_post_mss_pll_config(void)216 static void mss_mux_post_mss_pll_config(void)
217 {
218 /*
219 * Modify the eNVM clock, so it now matches new MSS clock
220 *
221 * [5:0]
222 * Sets the number of AHB cycles used to generate the PNVM clock,.
223 * Clock period = (Value+1) * (1000/AHBFREQMHZ)
224 * Value must be 1 to 63 (0 defaults to 15)
225 * e.g.
226 * 7 will generate a 40ns period 25MHz clock if the AHB clock is 200MHz
227 * 11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
228 * 15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
229 *
230 */
231 SYSREG->ENVM_CR = LIBERO_SETTING_MSS_ENVM_CR;
232
233 mb(); /* make sure we change clock in eNVM first so ready by the time we
234 leave */
235
236 /*
237 * When you're changing the eNVM clock frequency, there is a bit
238 * (ENVM_CR_clock_okay) in the eNVM_CR which can be polled to check that
239 * the frequency change has happened before bumping up the AHB frequency.
240 */
241 volatile uint32_t wait_for_true = 0U;
242 while ((SYSREG->ENVM_CR & ENVM_CR_CLOCK_OKAY_MASK) !=\
243 ENVM_CR_CLOCK_OKAY_MASK)
244 {
245 #ifdef RENODE_DEBUG
246 break;
247 #endif
248 wait_for_true++; /* need something here to stop debugger freezing */
249 }
250
251 /*
252 * Change the MSS clock as required.
253 *
254 * CLOCK_CONFIG_CR
255 * [5:0]
256 * Sets the master synchronous clock divider
257 * bits [1:0] CPU clock divider
258 * bits [3:2] AXI clock divider
259 * bits [5:4] AHB/APB clock divider
260 * 00=/1 01=/2 10=/4 11=/8 (AHB/APB divider may not be set to /1)
261 * Reset = 0x3F
262 *
263 * SYSREG->CLOCK_CONFIG_CR = (0x0U<<0U) | (0x1U<<2U) | (0x2U<<4U);
264 * MSS clk= 80Mhz, implies CPU = 80Mhz, AXI = 40Mhz, AHB/APB = 20Mhz
265 * Until we switch in MSS PLL clock (MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = 0x01)
266 * e.g. If MSS clk 800Mhz
267 * MSS clk= 800Mhz, implies CPU = 800Mhz, AXI = 400Mhz, AHB/APB = 200Mhz
268 */
269 SYSREG->CLOCK_CONFIG_CR = LIBERO_SETTING_MSS_CLOCK_CONFIG_CR;
270
271 /*
272 * Feed clock from MSS PLL to MSS, using glitch-less mux
273 *
274 * MSS Clock mux selections
275 * [31:5] Reserved
276 * [4] clk_standby_sel
277 * [3:2] mssclk_mux_md
278 * step 7: 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the
279 * MSS PLL clock.
280 * [1:0] mssclk_mux_sel MSS glitchless mux select
281 * 00 - msspll_fdr_0=clk_standby
282 * msspll_fdr_1=clk_standby
283 * 01 - msspll_fdr_0=pllout0
284 * msspll_fdr_1=clk_standby
285 * 10 - msspll_fdr_0=clk_standby
286 * msspll_fdr_1=pllout1
287 * 11 - msspll_fdr_0=pllout0
288 * msspll_fdr_1=pllout1
289 *
290 *
291 */
292 MSS_SCB_CFM_MSS_MUX->MSSCLKMUX = LIBERO_SETTING_MSS_MSSCLKMUX;
293
294 /*
295 * Change the RTC clock divisor, so RTC clock is 1MHz
296 */
297 set_RTC_divisor();
298 }
299
300 /***************************************************************************//**
301 * sgmii_mux_config(uint8_t option)
302 * @param option 1 => soft reset, load RPC settings
303 * 0 => write values using SCB
304 ******************************************************************************/
sgmii_mux_config(uint8_t option)305 void sgmii_mux_config(uint8_t option)
306 {
307 switch(option)
308 {
309 default:
310 case SCB_UPDATE: /* write to SCB register */
311
312 /*
313 * SCB address: 0x3E20 0008
314 * MSS Clock mux selections
315 *
316 * [31:0] SGMII_CLKMUX
317 */
318 /* CFM_ETH - 0x3E200000 - - 0x08 */
319 MSS_SCB_CFM_SGMII_MUX->SGMII_CLKMUX =\
320 LIBERO_SETTING_SGMII_SGMII_CLKMUX;
321 /*
322 * SCB address: 0x3E20 0010
323 * Clock_Receiver
324 *
325 * [13] en_rdiff
326 * [12] clkbuf_en_pullup
327 * [11:10] en_rxmode_n
328 * [9:8] en_term_n
329 * [7] en_ins_hyst_n
330 * [6] en_udrive_n
331 * [5:4] en_rxmode_p
332 * [3:2] en_term_p
333 * [1] en_ins_hyst_p
334 * [0] en_udrive_p
335 */
336 MSS_SCB_CFM_SGMII_MUX->CLK_XCVR =\
337 LIBERO_SETTING_SGMII_CLK_XCVR; /* 0x2011 */
338 /*
339 * SCB address: 0x3E20 0004
340 * PLL RF clk mux selections
341 *
342 * [3:2] pll0_rfclk1_sel
343 * 00 => vss
344 * 01 => refclk_p muxed to DDR PLL
345 * and SGMII PLL ( see
346 * 10 => scb_clk
347 * 11 => serdes_refclk_crn_mss<1>
348 * [1:0] pll0_rfclk0_sel
349 * 00 => vss
350 * 01 => refclk_n muxed to DDR PLL
351 * and SGMII PLL
352 * 10 => scb_clk
353 * 11 => serdes_refclk_crn_mss<1>
354 *
355 *
356 */
357 /* 0x05 => ref to SGMII and DDR */
358 MSS_SCB_CFM_SGMII_MUX->RFCKMUX =\
359 LIBERO_SETTING_SGMII_REFCLKMUX;
360 break;
361
362 case RPC_REG_UPDATE:
363 /*
364 * set the NV map reset
365 * This will load the APB registers, set via SGMII TIP.
366 * */
367 MSS_SCB_CFM_SGMII_MUX->SOFT_RESET = 1U;
368 break;
369 }
370 }
371
372 /***************************************************************************//**
373 *
374 * On startup, MSS supplied with 80MHz SCB clock
375
376 9.2 Power on procedure for the MSS PLL clock
377
378 During POR:
379 Keep PLL in power down mode. powerdown_int_b=0
380
381 After POR, Power-On steps:
382 1) mssclk_mux_sel_int<0>=0 & powerdown_int_b=0 & clk_standby_sel=0
383 MSS PLL is powered down and selects clk_standby=scb_clk
384 2) PFC Processor writes powerdown_int_b=1 & divq0_int_en=1
385 MSS PLL powers up, then lock asserts when locked.
386 3) PFC Processor switches mssclk_mux_sel_int<0>=1
387 MSS PLL clock is now sent to MSS.
388 4) When BOOT authentication is complete
389 a. PFC processor writes mssclk_mux_sel_int<0>=0 to select clk_standby.
390 b. PFC Processor writes powerdown_int_b=0 to power down the PLL
391 >>>>>>>> G5 Soc User code >>>>>>>>>>>>>>
392 c. MSS Processor writes new parameters to the MSS PLL
393 5) MSS Processor writes powerdown_int_b=1
394 Start up the PLL with NEW parameters.
395 Wait for LOCK
396 6) MSS Processor enables all 4 PLL outputs.
397 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
398 clock.
399 *
400 ******************************************************************************/
mss_pll_config(void)401 void mss_pll_config(void)
402 {
403 copy_switch_code(); /* copy switch code to RAM */
404
405 MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
406 MSS_SCB_MSS_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
407
408 /*
409 Enable the PLL by removing the reset-
410 PERIPH / periph_reset_b - This asserts the functional reset of the
411 block.
412 It is asserted at power up. When written is stays asserted until written
413 to 0.
414 */
415 /*
416 * 4. c. MSS Processor writes new parameters to the MSS PLL
417 */
418 /*
419 * [0] REG_BYPASS_GO_B
420 * [0] BYPCK_SEL
421 * [0] RESETONLOCK
422 * [0] REG_RFCLK_SEL
423 * [0] REG_DIVQ3_EN
424 * [0] REG_DIVQ2_EN
425 * [0] REG_DIVQ1_EN
426 * [0] REG_DIVQ0_EN
427 * [0] REG_RFDIV_EN
428 * [0] REG_POWERDOWN_B
429 */
430
431 MSS_SCB_MSS_PLL->PLL_CTRL = LIBERO_SETTING_MSS_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
432
433 /*
434 * PLL calibration register
435 * This value is factory set, do not overwrite
436 * MSS_SCB_MSS_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
437 *
438 */
439
440 MSS_SCB_MSS_PLL->PLL_REF_FB = LIBERO_SETTING_MSS_PLL_REF_FB;
441
442 MSS_SCB_MSS_PLL->PLL_DIV_0_1 = LIBERO_SETTING_MSS_PLL_DIV_0_1;
443
444 MSS_SCB_MSS_PLL->PLL_DIV_2_3 = LIBERO_SETTING_MSS_PLL_DIV_2_3;
445
446 MSS_SCB_MSS_PLL->PLL_CTRL2 = LIBERO_SETTING_MSS_PLL_CTRL2;
447
448 MSS_SCB_MSS_PLL->PLL_FRACN = LIBERO_SETTING_MSS_PLL_FRACN;
449 MSS_SCB_MSS_PLL->SSCG_REG_0 = LIBERO_SETTING_MSS_SSCG_REG_0;
450 MSS_SCB_MSS_PLL->SSCG_REG_1 = LIBERO_SETTING_MSS_SSCG_REG_1;
451
452 MSS_SCB_MSS_PLL->SSCG_REG_2 = LIBERO_SETTING_MSS_SSCG_REG_2;
453 MSS_SCB_MSS_PLL->SSCG_REG_3 = LIBERO_SETTING_MSS_SSCG_REG_3;
454
455 /* PLL phase registers */
456 MSS_SCB_MSS_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
457
458 /*
459 * 5) MSS Processor writes powerdown_int_b=1
460 * Start up the PLL with NEW parameters.
461 Wait for LOCK
462 */
463 mss_mux_pre_mss_pll_config(); /* feed required inputs */
464 /* bit 0 == REG_POWERDOWN_B */
465 MSS_SCB_MSS_PLL->PLL_CTRL = (LIBERO_SETTING_MSS_PLL_CTRL) | 0x01U;
466 /*
467 * Start up the PLL with NEW parameters.
468 * Wait for LOCK
469 * todo: make wait clock based
470 */
471 volatile uint32_t timer_out=0x000000FFU;
472 while((MSS_SCB_MSS_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == 0U)
473 {
474 #ifdef RENODE_DEBUG
475 break;
476 #endif
477 if (timer_out != 0U)
478 {
479 timer_out--;
480 }
481 else
482 {
483 //todo: add failure mode
484 }
485 }
486
487 /*
488 * 6) MSS Processor enables all 4 PLL outputs.
489 * 7) MSS Processor writes mssclk_mux_sel_int<0>=1 to select the MSS PLL
490 * clock.
491 */
492 mss_mux_post_mss_pll_config();
493 }
494
495 /**
496 *
497 * @param option choose between SCB or RPC and soft reset update method.
498 */
ddr_pll_config(REG_LOAD_METHOD option)499 void ddr_pll_config(REG_LOAD_METHOD option)
500 {
501
502 switch(option)
503 {
504 default:
505 case SCB_UPDATE: /* write to SCB register */
506 /* PERIPH / periph_reset_b - This asserts the functional reset of
507 * the block. It is asserted at power up. When written is stays
508 * asserted until written to 0.
509 * First set periph_reset_b, than remove reset. As may be called
510 * more than one.
511 * */
512 MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
513
514 MSS_SCB_DDR_PLL->PLL_CTRL = LIBERO_SETTING_DDR_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
515 /* PLL calibration register */
516
517 /*
518 * PLL calibration register
519 * This value is factory set, do not overwrite
520 * MSS_SCB_DDR_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
521 *
522 */
523
524 MSS_SCB_DDR_PLL->PLL_REF_FB = LIBERO_SETTING_DDR_PLL_REF_FB;
525
526
527 MSS_SCB_DDR_PLL->PLL_DIV_0_1 = LIBERO_SETTING_DDR_PLL_DIV_0_1;
528
529 MSS_SCB_DDR_PLL->PLL_DIV_2_3 = LIBERO_SETTING_DDR_PLL_DIV_2_3;
530
531
532 MSS_SCB_DDR_PLL->PLL_CTRL2 = LIBERO_SETTING_DDR_PLL_CTRL2;
533
534 MSS_SCB_DDR_PLL->PLL_FRACN = LIBERO_SETTING_DDR_PLL_FRACN;
535 MSS_SCB_DDR_PLL->SSCG_REG_0 = LIBERO_SETTING_DDR_SSCG_REG_0;
536 MSS_SCB_DDR_PLL->SSCG_REG_1 = LIBERO_SETTING_DDR_SSCG_REG_1;
537
538 MSS_SCB_DDR_PLL->SSCG_REG_2 = LIBERO_SETTING_DDR_SSCG_REG_2;
539 MSS_SCB_DDR_PLL->SSCG_REG_3 = LIBERO_SETTING_DDR_SSCG_REG_3;
540
541 /* PLL phase registers */
542
543 MSS_SCB_DDR_PLL->PLL_PHADJ = LIBERO_SETTING_MSS_PLL_PHADJ;
544
545 MSS_SCB_DDR_PLL->PLL_CTRL = (LIBERO_SETTING_DDR_PLL_CTRL)\
546 | 0x01U; /* bit 0 == REG_POWERDOWN_B */
547
548 break;
549
550 case RPC_REG_UPDATE:
551 /* CFG_DDR_SGMII_PHY->SOFT_RESET_MAIN_PLL; */
552 CFG_DDR_SGMII_PHY->PLL_CTRL_MAIN.PLL_CTRL_MAIN =\
553 LIBERO_SETTING_DDR_PLL_CTRL | 0x01U;
554 CFG_DDR_SGMII_PHY->PLL_REF_FB_MAIN.PLL_REF_FB_MAIN =\
555 LIBERO_SETTING_DDR_PLL_REF_FB;
556 /* Read only in RPC
557 * CFG_DDR_SGMII_PHY->PLL_FRACN_MAIN.PLL_FRACN_MAIN =\
558 * LIBERO_SETTING_DDR_PLL_FRACN; */
559 CFG_DDR_SGMII_PHY->PLL_DIV_0_1_MAIN.PLL_DIV_0_1_MAIN =\
560 LIBERO_SETTING_DDR_PLL_DIV_0_1;
561 CFG_DDR_SGMII_PHY->PLL_DIV_2_3_MAIN.PLL_DIV_2_3_MAIN =\
562 LIBERO_SETTING_DDR_PLL_DIV_2_3;
563 CFG_DDR_SGMII_PHY->PLL_CTRL2_MAIN.PLL_CTRL2_MAIN =\
564 LIBERO_SETTING_DDR_PLL_CTRL2;
565 /* Read only in RPC todo: verify this is correct
566 * CFG_DDR_SGMII_PHY->PLL_CAL_MAIN.PLL_CAL_MAIN =\
567 * LIBERO_SETTING_DDR_PLL_CAL; */
568 CFG_DDR_SGMII_PHY->PLL_PHADJ_MAIN.PLL_PHADJ_MAIN =\
569 LIBERO_SETTING_DDR_PLL_PHADJ;
570 /*__I CFG_DDR_SGMII_PHY_SSCG_REG_0_MAIN_TypeDef SSCG_REG_0_MAIN; */
571 /*__I CFG_DDR_SGMII_PHY_SSCG_REG_1_MAIN_TypeDef SSCG_REG_1_MAIN; */
572 CFG_DDR_SGMII_PHY->SSCG_REG_2_MAIN.SSCG_REG_2_MAIN =\
573 LIBERO_SETTING_DDR_SSCG_REG_2;
574 /*__I CFG_DDR_SGMII_PHY_SSCG_REG_3_MAIN_TypeDef SSCG_REG_3_MAIN; */
575 /*
576 * set the NV map reset
577 * This will load the APB registers, set via SGMII TIP.
578 * */
579 /* bit 0 == REG_POWERDOWN_B */
580 MSS_SCB_DDR_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
581 break;
582 }
583 }
584
585 /**
586 * ddr_pll_lock_scb(void)
587 * checks to see if lock has occurred
588 * @return => lock has occurred, 1=> no lock
589 */
ddr_pll_lock_scb(void)590 uint8_t ddr_pll_lock_scb(void)
591 {
592 uint8_t result = 1U;
593 #ifndef RENODE_DEBUG
594 if((MSS_SCB_DDR_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
595 {
596 result = 0U; /* PLL lock has occurred */
597 }
598 #else
599 result = 0U;
600 #endif
601 return (result);
602 }
603
604 /***************************************************************************//**
605 *
606 ******************************************************************************/
ddr_pll_config_scb_turn_off(void)607 void ddr_pll_config_scb_turn_off(void)
608 {
609 /* PERIPH / periph_reset_b */
610 MSS_SCB_DDR_PLL->PLL_CTRL &= (uint32_t)~0x00000001UL;
611 }
612
613
614 /***************************************************************************//**
615 * sgmii_pll_config_scb(uint8_t option)
616 * @param option 1 => soft reset, load RPC settings
617 * 0 => write values using SCB
618 ******************************************************************************/
sgmii_pll_config_scb(uint8_t option)619 void sgmii_pll_config_scb(uint8_t option)
620 {
621
622 switch(option)
623 {
624 default:
625 case SCB_UPDATE: /* write to SCB register */
626 /* PERIPH / periph_reset_b - This asserts the functional reset of
627 * the block. It is asserted at power up. When written is stays
628 * asserted until written to 0.
629 * First set periph_reset_b, than remove reset. As may be called
630 * more than one.
631 * */
632 MSS_SCB_SGMII_PLL->SOFT_RESET = PLL_INIT_AND_OUT_OF_RESET;
633
634 MSS_SCB_SGMII_PLL->PLL_CTRL = LIBERO_SETTING_SGMII_PLL_CTRL & ~(PLL_CTRL_REG_POWERDOWN_B_MASK);
635 /* PLL calibration register */
636
637 /*
638 * PLL calibration register
639 * This value is factory set, do not overwrite
640 * MSS_SCB_SGMII_PLL->PLL_CAL = LIBERO_SETTING_MSS_PLL_CAL;
641 *
642 */
643
644 MSS_SCB_SGMII_PLL->PLL_REF_FB = LIBERO_SETTING_SGMII_PLL_REF_FB;
645
646
647 MSS_SCB_SGMII_PLL->PLL_DIV_0_1 = LIBERO_SETTING_SGMII_PLL_DIV_0_1;
648
649 MSS_SCB_SGMII_PLL->PLL_DIV_2_3 = LIBERO_SETTING_SGMII_PLL_DIV_2_3;
650
651
652 MSS_SCB_SGMII_PLL->PLL_CTRL2 = LIBERO_SETTING_SGMII_PLL_CTRL2;
653
654 MSS_SCB_SGMII_PLL->PLL_FRACN = LIBERO_SETTING_SGMII_PLL_FRACN;
655 MSS_SCB_SGMII_PLL->SSCG_REG_0 = LIBERO_SETTING_SGMII_SSCG_REG_0;
656 MSS_SCB_SGMII_PLL->SSCG_REG_1 = LIBERO_SETTING_SGMII_SSCG_REG_1;
657
658 MSS_SCB_SGMII_PLL->SSCG_REG_2 = LIBERO_SETTING_SGMII_SSCG_REG_2;
659 MSS_SCB_SGMII_PLL->SSCG_REG_3 = LIBERO_SETTING_SGMII_SSCG_REG_3;
660
661 /* PLL phase registers */
662
663 MSS_SCB_SGMII_PLL->PLL_PHADJ = LIBERO_SETTING_SGMII_PLL_PHADJ;
664
665 MSS_SCB_SGMII_PLL->PLL_CTRL = (LIBERO_SETTING_SGMII_PLL_CTRL)\
666 | 0x01U; /* bit 0 == REG_POWERDOWN_B */
667
668 break;
669
670 case RPC_REG_UPDATE:
671 /*
672 * set the NV map reset
673 * This will load the APB registers, set via SGMII TIP.
674 * */
675 /* bit 0 == REG_POWERDOWN_B */
676 MSS_SCB_SGMII_PLL->SOFT_RESET = 0x01U;
677 break;
678 }
679 }
680
681 /**
682 * sgmii_pll_lock_scb(void)
683 * checks to see if lock has occurred
684 * @return => lock has occurred, 1=> no lock
685 */
sgmii_pll_lock_scb(void)686 uint8_t sgmii_pll_lock_scb(void)
687 {
688 uint8_t result = 1U;
689 #ifndef RENODE_DEBUG
690 if((MSS_SCB_SGMII_PLL->PLL_CTRL & PLL_CTRL_LOCK_BIT) == PLL_CTRL_LOCK_BIT)
691 {
692 result = 0U; /* PLL lock has occurred */
693 }
694 #else
695 result = 0U;
696 #endif
697 return (result);
698 }
699
700
701 /***************************************************************************//**
702 * Copy switch code routine to RAM.
703 * Copy locations have been defined in the linker script
704 ******************************************************************************/
copy_switch_code(void)705 __attribute__((weak)) void copy_switch_code(void)
706 {
707 uint32_t * sc_lma = &__sc_load;
708 uint32_t * end_sc_vma = &__sc_end;
709 uint32_t * sc_vma = &__sc_start;
710
711 if ( sc_vma != sc_lma )
712 {
713 while ( sc_vma < end_sc_vma )
714 {
715 *sc_vma = *sc_lma;
716 sc_vma++ ; sc_lma++;
717 }
718 }
719 }
720
721 #endif /* MPFS_HAL_HW_CONFIG */
722 #endif
723
724
725