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