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.h
12  * @author Microchip-FPGA Embedded Systems Solutions
13  * @brief PLL defines
14  *
15  */
16 
17 /*=========================================================================*//**
18   @page PolarFire SoC MSS Clock Setup
19   ==============================================================================
20   Introduction
21   ==============================================================================
22   The PolarFire SoC Microprocessor subsystem (MSS) has three PLL's, the MSS, DDR
23   and MSS SGMII's.
24   Two CFM IP blocks are used to mux the PLL input and outputs.
25 
26   ==============================================================================
27   PLL Inputs
28   ==============================================================================
29   Each of the three PLL's can be configured with the following inputs:
30     - VSS ( default on reset )
31     - external ref clock in SGMII IO Block
32     - SCB Clock (80MHz)
33     - North West corner clock mux structure ICB
34 
35   There are two bits associated with setting clk source
36 
37   Note on North West corner clock mux structure ICB
38   The Fabric reference clock inputs source come from the clock mux's in the
39   upper  left corner (regular FPGA corner) that provided clocks that can be
40   routed in from various places that will include from IOs, from the FPGA
41   fabric, etc.
42 
43 
44 
45   ==============================================================================
46   MSS PLL Outputs
47   ==============================================================================
48   Each PLL has four outputs. These are generally gated through a mux
49   MSS PLL Outputs
50 
51     | Output(0-3)   |    Detail     | Mux           | Muxed with  |
52     | ------------- |:-------------:|:-------------:| -----------:|
53     | msspll_fdr_0  | clk_in_mss    | no            | -           |
54     | msspll_fdr_1  | clk_in_crypto | no            | -           |
55     | msspll_fdr_2  | clk_in_emmc   | glitch-less   | SCB clk     |
56     | msspll_fdr_3  | clk_in_can    | glitch-less   | SCB clk     |
57 
58   ==============================================================================
59   SCB bus timing
60   ==============================================================================
61   When the MSS is using the SCB bus, there is a timing relationship.
62   The defaults should be OK here. In necessary, the timing used by the MSS SCB
63   access is adjusted using the MSS system register TIMER.
64   (SCBCFG_REGS->TIMER.TIMER)
65       - Bits 15:8 Sets how long SCB request is held active after SCB bus granted.
66       - Allows SCB bus master-ship to maintained across multiple SCB access
67         cycles
68       - Bits 7:0 Set the timeout for an SCB access in CPU cycles.
69 
70   ==============================================================================
71   eNVM timing
72   ==============================================================================
73   The clk used by the eNVM is adjusted using the following register:
74   SYSREG->ENVM_CR
75      [5:0]
76      Sets the number of AHB cycles used to generate the PNVM clock,.
77      Clock period = (Value+1) * (1000/AHBFREQMHZ)
78      Value must be 1 to 63 (0 defaults to 15)
79      e.g.
80      11 will generate a 40ns period 25MHz clock if the AHB clock is 250MHz
81      15 will generate a 40ns period 25MHz clock if the AHB clock is 400MHz
82 
83   ==============================================================================
84   MSS clocks at reset
85   ==============================================================================
86   When the MSS comes out of reset, the MSS will be running on the SCB supplied
87   80MHz clock.
88 
89 
90 
91   ==============================================================================
92   MSS clock setup - Use case one - using external reference from SGMII I/O Blk
93   ==============================================================================
94   Use case one will be used in the majority of cases.
95   This is where the MSS PLL reference clk will be supplied from an external
96   reference through the external ref clock in SGMII IO Block.
97 
98 
99                                                  scb clk
100                      01=>ext clk ref             +
101                       +----------+   +--------+  |  0=>SCB
102                   crn |          |   |  MSS   |  |  1=>PLL
103                  +--->|          |   |  PLL   |  | +------+
104      +-----+      scb |          |   |        |  +>|      |mss
105      |     |     +----           |   |        |    | mux  +-->
106      | ext + p        |  mux     +-->|ref0   0+--->|      |clk
107      | clk +--------->|          |   |        |    +------+
108      | ref | n    vss |          |   |        |     0=>SCB
109      |     +---+    ->|          |   |        |     1=>PLL
110      |     |   |      |          |   |        |    +------+
111      |     |   |      |          |   |        |scb-|      |crypto
112      +-----+   |      +----------+   |        |    | mux  +-->
113                |                     |       1+--->|      |clk
114                |    01=>ext clk ref  |        |    +------+
115                |      +----------+   |        |
116                |   crn|          |   |        |    +------+
117                |  +-->|          |   |        |    |      |
118                |   scb|          |   |       2+--->| eMMC +
119                |  +-->|          |   |        |    |      |
120                |      |  mux     +-->|ref1    |    +------+
121                +----->|          |   |        |
122                    vss|          |   |        |    +------+
123                   +-->|          |   |        |    |      |
124                       |          |   |       3+--->| CAN  +
125                       |          |   |        |    |      |
126                       +----------+   +--------+    +------+
127 
128   Steps to setup ext clk:
129   1. The external clock reference is setup- In SGMII setup
130   2. The input mux is set to take input from ext ref clk
131   3. MSS PLL clock is setup with required settings
132   4. PLL is checked until locked
133   5. MSS PLL output is switched through to MSS ( switch code run from ram )
134   6. eNVM clcock is changed as required
135   7. return from RAM routine and continue
136 
137   ==============================================================================
138   MSS clock dividers
139   ==============================================================================
140   The three dividers generating the MSS master clocks are controllable via the
141   system register (CLOCK_CONFIG_CR).
142   CPU clock dividers are set in the function  mss_mux_post_mss_pll_config(void)
143 
144     | Divider       | Config bits   | Reset      | MAX feq. *  |
145     | ------------- |:-------------:|:----------:| -----------:|
146     | CPU           | 1:0           | 00         | 625         |
147     | AXI           | 3:2           | 01         | 312.5       |
148     | AHB/APB       | 5:4           | 10         | 156.25      |
149 
150   settings = 00=/1, 01=/2, 01=/4, 01=/8
151   * verify MAX feq. setting with particular silicon variant data sheet
152    - The CPU clock must not exceed 625MHz
153    - The AXI clock  must not exceed 312.5MHz
154    - The AHB clock must not exceed 156.25MHz
155    - The CPU clock must be greater or equal to the AXI clock
156    - The AHB/APB clocks cannot be divided by 1. Divide by 1 will divide the
157      clock by 2.
158    - The clock divider register may be changed from any value to any value in
159      one go.
160    - When the USB block is in-use the AHB clock must be greater than 66 MHz.
161 
162 
163                           +---------------------+          +-------------+
164                           |      +----------+   |          |             |
165                           |   +--> /1/2/4/8 +-->+--------->|   CPU cores |
166     +-----------+         |   |  +----------+   |          |             |
167     |           |         |   |                 |          +-------------+
168     |  MSS CLK  |         |   |                 |
169     |           |         |   |                 |          +-------------+
170     |           +---------+---+  +---------+    |          | dfi_apb_pclk|
171     |           |         |   +->|/4/8/16  +--->+---------->             |
172     |           |         |   |  +---------+    |          |             |
173     |           |         |   |                 |          +-------------+
174     +-----------+         |   |                 |
175                           |   |                 |
176                           |   |                 |          +-------------+
177                           |   |  +---------+    |          | MSS AXI     |
178                           |   +--> 1/2/4/8 +--->+--------->| Buses and   |
179                           |   |  +---------+    |          | peripherals |
180                           |   |                 |          +-------------+
181                           |   |                 |
182                           |   |                 |
183                           |   |                 |          +-------------+
184                           |   |  +-------+      |          | MSS APB/AHB |
185                           |   +->| 2/4/8 +----->+--------->| Buses and
186                           |      +-------+      |          | peripherals |
187                           +---------------------+          +-------------+
188 
189 
190  *//*=========================================================================*/
191 #ifndef MSS_DDR_SGMII_MSS_PLL_H_
192 #define MSS_DDR_SGMII_MSS_PLL_H_
193 
194 #ifdef __cplusplus
195 extern "C" {
196 #endif
197 
198 #define PLL_CTRL_LOCK_BIT ((0x01U) << 25U)
199 /*
200  * bit0 1: This when asserted resets all the non-volatile register  bits
201  *         e.g. RW-P bits, the bit self clears i.e. is similar to a W1P bit
202  * bit1 1: This when asserted resets all the register  bits apart from the
203  *         non-volatile registers,  the bit self clears.  i.e. is similar to a
204  *         W1P bit
205  */
206 #define PLL_INIT_AND_OUT_OF_RESET               0x00000003UL
207 
208 #define PLL_CTRL_REG_POWERDOWN_B_MASK           0x00000001UL
209 
210 typedef enum RTC_CLK_SOURCE_
211 {
212     SCB_80M_CLOCK                   = 0x00,       /*!< 0 SCB clock source */
213     MSS_PLL_CLOCK                   = 0x01,       /*!< 1 MSS PLL clock source */
214 }   RTC_CLK_SOURCE;
215 
216 typedef enum REG_LOAD_METHOD_
217 {
218     SCB_UPDATE                   = 0x00,       /*!< 0 SCB direct load */
219     RPC_REG_UPDATE               = 0x01,       /*!< 1 RPC -> SCB load */
220 }   REG_LOAD_METHOD;
221 
222 
223 
224 /***************************************************************************//**
225   ddr_pll_config() configure DDR PLL
226 
227   Example:
228   @code
229 
230       ddr_pll_config();
231 
232   @endcode
233 
234  */
235 void ddr_pll_config(REG_LOAD_METHOD option);
236 
237 /***************************************************************************//**
238   ddr_pll_lock_scb() Checks if PLL locked
239 
240   @return
241     0U if locked
242 
243   Example:
244   @code
245       if (ddr_pvt_calibration() == 0U)
246       {
247            PLL is locked
248       }
249   @endcode
250 
251  */
252 uint8_t ddr_pll_lock_scb(void);
253 
254 /***************************************************************************//**
255   sgmii_pll_config_scb() configure sgmii PLL
256 
257    @param option 1 => soft reset, load RPC settings
258                  0 => write values using SCB
259 
260   Example:
261   @code
262 
263       sgmii_pll_config_scb(1U);
264 
265   @endcode
266 
267  */
268 void sgmii_pll_config_scb(uint8_t option);
269 
270 /***************************************************************************//**
271   sgmii_pll_lock_scb() Checks if PLL is locked
272 
273    @return
274     0U if locked
275 
276   Example:
277   @code
278       if (ddr_pvt_calibration() == 0U)
279       {
280            PLL is locked
281       }
282   @endcode
283 
284  */
285 uint8_t sgmii_pll_lock_scb(void);
286 
287 /***************************************************************************//**
288   ddr_pll_config_scb_turn_off() Puts PLL in reset
289 
290   Example:
291   @code
292 
293       ddr_pll_config_scb_turn_off();
294 
295   @endcode
296 
297  */
298 void ddr_pll_config_scb_turn_off(void);
299 
300 /***************************************************************************//**
301   set_RTC_divisor() Sets the RTC divisor based on values from Libero
302   It is assumed the RTC clock is set to 1MHz
303   Example:
304   @code
305 
306       set_RTC_divisor();
307 
308   @endcode
309 
310  */
311 void set_RTC_divisor(void);
312 
313 /***************************************************************************//**
314   sgmii_mux_config_via_scb() configures mux for SGMii
315 
316   Example:
317   @code
318 
319       sgmii_mux_config_via_scb();
320 
321   @endcode
322 
323  */
324 void sgmii_mux_config_via_scb(uint8_t option);
325 
326 /***************************************************************************//**
327   pre_configure_sgmii_and_ddr_pll_via_scb()
328 
329   @param option 1 => soft reset, load RPC settings
330                 0 => write values using SCB
331 
332   Example:
333   @code
334 
335       ddr_pvt_calibration(1U);
336 
337   @endcode
338 
339  */
340 void pre_configure_sgmii_and_ddr_pll_via_scb(uint8_t option);
341 
342 /******************************************************************************
343  * Public Functions - API                                                      *
344  ******************************************************************************/
345 void mss_pll_config(void);
346 
347 #ifdef __cplusplus
348 }
349 #endif
350 
351 #endif /* MSS_DDR_SGMII_MSS_PLL_H_ */
352