Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:42

0001 /**
0002  * @file
0003  *
0004  * @ingroup RTEMSBSPsARMCycVContrib
0005  */
0006 
0007 /******************************************************************************
0008  *
0009  * Copyright 2013 Altera Corporation. All Rights Reserved.
0010  *
0011  * Redistribution and use in source and binary forms, with or without
0012  * modification, are permitted provided that the following conditions are met:
0013  *
0014  * 1. Redistributions of source code must retain the above copyright notice,
0015  * this list of conditions and the following disclaimer.
0016  *
0017  * 2. Redistributions in binary form must reproduce the above copyright notice,
0018  * this list of conditions and the following disclaimer in the documentation
0019  * and/or other materials provided with the distribution.
0020  *
0021  * 3. The name of the author may not be used to endorse or promote products
0022  * derived from this software without specific prior written permission.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
0025  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
0027  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
0029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
0032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
0033  * OF SUCH DAMAGE.
0034  *
0035  ******************************************************************************/
0036 
0037 #include <stdint.h>
0038 #include <stdlib.h>
0039 #include <stdbool.h>
0040 #include <stdio.h>
0041 
0042 #include <bsp/socal/hps.h>
0043 #include <bsp/socal/socal.h>
0044 #include <bsp/socal/alt_sysmgr.h>
0045 #include <bsp/hwlib.h>
0046 #include <bsp/alt_clock_manager.h>
0047 #include <bsp/alt_mpu_registers.h>
0048 
0049 #define UINT12_MAX              (4096)
0050 
0051 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0052 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Useful Structures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0053 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0054 
0055 
0056         /* General structure used to hold parameters of various clock entities, */
0057 typedef struct ALT_CLK_PARAMS_s
0058 {
0059     alt_freq_t      freqcur;                   // current frequency of the clock
0060     alt_freq_t      freqmin;                   // minimum allowed frequency for this clock
0061     alt_freq_t      freqmax;                   // maximum allowed frequency for this clock
0062     uint32_t        guardband : 7;             // guardband percentage (0-100) if this clock
0063                                                //    is a PLL, ignored otherwise
0064     uint32_t        active    : 1;             // current state of activity of this clock
0065 } ALT_CLK_PARAMS_t;
0066 
0067 
0068 typedef struct ALT_EXT_CLK_PARAMBLOK_s
0069 {
0070     ALT_CLK_PARAMS_t        clkosc1;        // ALT_CLK_OSC1
0071     ALT_CLK_PARAMS_t        clkosc2;        // ALT_CLK_OSC2
0072     ALT_CLK_PARAMS_t        periph;         // ALT_CLK_F2H_PERIPH_REF
0073     ALT_CLK_PARAMS_t        sdram;          // ALT_CLK_F2H_SDRAM_REF
0074 } ALT_EXT_CLK_PARAMBLOK_t;
0075 
0076 
0077         /* Initializes the External Clock Frequency Limits block                        */
0078         /* The first field is the current external clock frequency, and can be set by   */
0079         /* alt_clk_ext_clk_freq_set(), the second and third fields are the minimum and  */
0080         /* maximum frequencies, the fourth field is ignored, and the fifth field        */
0081         /* contains the current activity state of the clock, 1=active, 0=inactive.      */
0082         /* Values taken from Section 2.3 and Section 2.7.1 of the HHP HPS-Clocking      */
0083         /* NPP specification.                                                           */
0084 static ALT_EXT_CLK_PARAMBLOK_t alt_ext_clk_paramblok =
0085 {
0086     { 25000000, 10000000, 50000000, 0, 1 },
0087     { 25000000, 10000000, 50000000, 0, 1 },
0088     {        0, 10000000, 50000000, 0, 1 },
0089     {        0, 10000000, 50000000, 0, 1 }
0090 };
0091 
0092 
0093         /* PLL frequency limits */
0094 typedef struct ALT_PLL_CLK_PARAMBLOK_s
0095 {
0096     ALT_CLK_PARAMS_t       MainPLL_600;         // Main PLL values for 600 MHz SoC
0097     ALT_CLK_PARAMS_t       PeriphPLL_600;       // Peripheral PLL values for 600 MHz SoC
0098     ALT_CLK_PARAMS_t       SDRAMPLL_600;        // SDRAM PLL values for 600 MHz SoC
0099     ALT_CLK_PARAMS_t       MainPLL_800;         // Main PLL values for 800 MHz SoC
0100     ALT_CLK_PARAMS_t       PeriphPLL_800;       // Peripheral PLL values for 800 MHz SoC
0101     ALT_CLK_PARAMS_t       SDRAMPLL_800;        // SDRAM PLL values for 800 MHz SoC
0102 } ALT_PLL_CLK_PARAMBLOK_t;
0103 
0104 
0105     /* Initializes the PLL frequency limits block                               */
0106     /* The first field is the current frequency, the second and third fields    */
0107     /* are the design limits of the PLLs as listed in Section 3.2.1.2 of the    */
0108     /* HHP HPS-Clocking NPP document. The fourth field of each line is the      */
0109     /* guardband percentage, and the fifth field of each line is the current    */
0110     /* state of the PLL, 1=active, 0=inactive.                                  */
0111 #define     ALT_ORIGINAL_GUARDBAND_VAL      20
0112 #define     ALT_GUARDBAND_LIMIT             20
0113 
0114 static ALT_PLL_CLK_PARAMBLOK_t alt_pll_clk_paramblok =
0115 {
0116     { 0, 320000000, 1200000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
0117     { 0, 320000000,  900000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
0118     { 0, 320000000,  800000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
0119     { 0, 320000000, 1600000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 },
0120     { 0, 320000000, 1250000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 },
0121     { 0, 320000000, 1066000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 }
0122 };
0123 
0124 
0125         /* PLL counter frequency limits */
0126 typedef struct ALT_PLL_CNTR_FREQMAX_s
0127 {
0128     alt_freq_t       MainPLL_C0;         // Main PLL Counter 0 parameter block
0129     alt_freq_t       MainPLL_C1;         // Main PLL Counter 1 parameter block
0130     alt_freq_t       MainPLL_C2;         // Main PLL Counter 2 parameter block
0131     alt_freq_t       MainPLL_C3;         // Main PLL Counter 3 parameter block
0132     alt_freq_t       MainPLL_C4;         // Main PLL Counter 4 parameter block
0133     alt_freq_t       MainPLL_C5;         // Main PLL Counter 5 parameter block
0134     alt_freq_t       PeriphPLL_C0;       // Peripheral PLL Counter 0 parameter block
0135     alt_freq_t       PeriphPLL_C1;       // Peripheral PLL Counter 1 parameter block
0136     alt_freq_t       PeriphPLL_C2;       // Peripheral PLL Counter 2 parameter block
0137     alt_freq_t       PeriphPLL_C3;       // Peripheral PLL Counter 3 parameter block
0138     alt_freq_t       PeriphPLL_C4;       // Peripheral PLL Counter 4 parameter block
0139     alt_freq_t       PeriphPLL_C5;       // Peripheral PLL Counter 5 parameter block
0140     alt_freq_t       SDRAMPLL_C0;        // SDRAM PLL Counter 0 parameter block
0141     alt_freq_t       SDRAMPLL_C1;        // SDRAM PLL Counter 1 parameter block
0142     alt_freq_t       SDRAMPLL_C2;        // SDRAM PLL Counter 2 parameter block
0143     alt_freq_t       SDRAMPLL_C5;        // SDRAM PLL Counter 5 parameter block
0144 } ALT_PLL_CNTR_FREQMAX_t;
0145 
0146 //
0147 // The following pll max frequency array statically defined must be recalculated each time 
0148 // when powering up, by calling alt_clk_clkmgr_init()
0149 //
0150 // for 14.1 uboot preloader, the following values are calculated dynamically.
0151 //
0152 // Arrial 5
0153 // alt_pll_cntr_maxfreq.MainPLL_C0   = 1050000000
0154 // alt_pll_cntr_maxfreq.MainPLL_C1   =  350000000
0155 // alt_pll_cntr_maxfreq.MainPLL_C2   =  262500000
0156 // alt_pll_cntr_maxfreq.MainPLL_C3   =  350000000
0157 // alt_pll_cntr_maxfreq.MainPLL_C4   =    2050781
0158 // alt_pll_cntr_maxfreq.MainPLL_C5   =  116666666
0159 // alt_pll_cntr_maxfreq.PeriphPLL_C0 =    1953125
0160 // alt_pll_cntr_maxfreq.PeriphPLL_C1 =  250000000
0161 // alt_pll_cntr_maxfreq.PeriphPLL_C2 =    1953125
0162 // alt_pll_cntr_maxfreq.PeriphPLL_C3 =  200000000
0163 // alt_pll_cntr_maxfreq.PeriphPLL_C4 =  200000000
0164 // alt_pll_cntr_maxfreq.PeriphPLL_C5 =    1953125
0165 // alt_pll_cntr_maxfreq.SDRAMPLL_C0  =  533333333
0166 // alt_pll_cntr_maxfreq.SDRAMPLL_C1  = 1066666666
0167 // alt_pll_cntr_maxfreq.SDRAMPLL_C2  =  533333333
0168 // alt_pll_cntr_maxfreq.SDRAMPLL_C5  =  177777777
0169 
0170 // Cyclone V 
0171 // alt_pll_cntr_maxfreq.MainPLL_C0   =  925000000
0172 // alt_pll_cntr_maxfreq.MainPLL_C1   =  370000000
0173 // alt_pll_cntr_maxfreq.MainPLL_C2   =  462500000
0174 // alt_pll_cntr_maxfreq.MainPLL_C3   =  370000000
0175 // alt_pll_cntr_maxfreq.MainPLL_C4   =    3613281
0176 // alt_pll_cntr_maxfreq.MainPLL_C5   =  123333333
0177 // alt_pll_cntr_maxfreq.PeriphPLL_C0 =    1953125
0178 // alt_pll_cntr_maxfreq.PeriphPLL_C1 =  250000000
0179 // alt_pll_cntr_maxfreq.PeriphPLL_C2 =    1953125
0180 // alt_pll_cntr_maxfreq.PeriphPLL_C3 =  200000000
0181 // alt_pll_cntr_maxfreq.PeriphPLL_C4 =  200000000
0182 // alt_pll_cntr_maxfreq.PeriphPLL_C5 =    1953125
0183 // alt_pll_cntr_maxfreq.SDRAMPLL_C0  =  400000000
0184 // alt_pll_cntr_maxfreq.SDRAMPLL_C1  =  800000000
0185 // alt_pll_cntr_maxfreq.SDRAMPLL_C2  =  400000000
0186 // alt_pll_cntr_maxfreq.SDRAMPLL_C5  =  133333333
0187 
0188 
0189 /* Initializes the PLL Counter output maximum frequency block  */
0190 static ALT_PLL_CNTR_FREQMAX_t alt_pll_cntr_maxfreq =
0191 {
0192     800000000,    /* Main PLL Outputs */
0193     400000000,
0194     400000000,
0195     432000000,
0196     250000000,
0197     125000000,
0198     250000000,    /* Peripheral PLL Outputs */
0199     250000000,
0200     432000000,
0201     250000000,
0202     200000000,
0203     100000000,    /* SDRAM PLL Outputs */
0204     533000000,
0205     1066000000,
0206     533000000,
0207     200000000
0208 };
0209 
0210 
0211 
0212         /* Maximum multiply, divide, and counter divisor values for each PLL */
0213 #define     ALT_CLK_PLL_MULT_MAX        4095
0214 #define     ALT_CLK_PLL_DIV_MAX         63
0215 #define     ALT_CLK_PLL_CNTR_MAX        511
0216 
0217 
0218         /* Definitions for the reset request and reset acknowledge bits    */
0219         /* for each of the output counters for each of the PLLS            */
0220 #define     ALT_CLK_PLL_RST_BIT_C0      0x00000001
0221 #define     ALT_CLK_PLL_RST_BIT_C1      0x00000002
0222 #define     ALT_CLK_PLL_RST_BIT_C2      0x00000004
0223 #define     ALT_CLK_PLL_RST_BIT_C3      0x00000008
0224 #define     ALT_CLK_PLL_RST_BIT_C4      0x00000010
0225 #define     ALT_CLK_PLL_RST_BIT_C5      0x00000020
0226 
0227 
0228         /* These are the bits that deal with PLL lock and this macro */
0229         /* defines a mask to test for bits outside of these */
0230 #define ALT_CLK_MGR_PLL_LOCK_BITS  (ALT_CLKMGR_INTREN_MAINPLLACHIEVED_CLR_MSK \
0231                                   & ALT_CLKMGR_INTREN_PERPLLACHIEVED_CLR_MSK \
0232                                   & ALT_CLKMGR_INTREN_SDRPLLACHIEVED_CLR_MSK \
0233                                   & ALT_CLKMGR_INTREN_MAINPLLLOST_CLR_MSK \
0234                                   & ALT_CLKMGR_INTREN_PERPLLLOST_CLR_MSK \
0235                                   & ALT_CLKMGR_INTREN_SDRPLLLOST_CLR_MSK)
0236 
0237 
0238 // Undocumented register which determines clock dividers for main PLL C0, C1, and C2. These should be considered RO.
0239 #define ALT_CLKMGR_ALTERA_OFST           0xe0
0240 #define ALT_CLKMGR_ALTERA_MPUCLK_OFST    0x0
0241 #define ALT_CLKMGR_ALTERA_MAINCLK_OFST   0x4
0242 #define ALT_CLKMGR_ALTERA_DBGATCLK_OFST  0x8
0243 #define ALT_CLKMGR_ALTERA_ADDR           ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ADDR) + ALT_CLKMGR_ALTERA_OFST))
0244 #define ALT_CLKMGR_ALTERA_MPUCLK_ADDR    ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_MPUCLK_OFST))
0245 #define ALT_CLKMGR_ALTERA_MAINCLK_ADDR   ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_MAINCLK_OFST))
0246 #define ALT_CLKMGR_ALTERA_DBGATCLK_ADDR  ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_DBGATCLK_OFST))
0247 #define ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(value)   (((value) & 0x000001ff) >> 0)
0248 #define ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(value)  (((value) & 0x000001ff) >> 0)
0249 #define ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(value) (((value) & 0x000001ff) >> 0)
0250 
0251 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0252 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utility functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0253 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0254 
0255 
0256 /****************************************************************************************/
0257 /* alt_clk_mgr_wait() introduces a delay, not very exact, but very light in             */
0258 /* implementation. Depending upon the optinization level, it will wait at least the     */
0259 /* number of clock cycles specified in the cnt parameter, sometimes many more. The      */
0260 /* reg parameter is set to a register or a memory location that was recently used (so   */
0261 /* as to avoid accidently evicting a register and a recently-used cache line in favor   */
0262 /* of one whose values are not actually needed.). The cnt parameter sets the number of  */
0263 /* repeated volatile memory reads and so sets a minimum time delay measured in          */
0264 /* mpu_clk cycles. If mpu_clk = osc1 clock (as in bypass mode), then this gives a       */
0265 /* minimum osc1 clock cycle delay.                                                      */
0266 /****************************************************************************************/
0267 
0268 inline static void alt_clk_mgr_wait(void* reg, uint32_t cnt)
0269 {
0270     for (; cnt ; cnt--)
0271     {
0272         (void) alt_read_word(reg);
0273     }
0274 }
0275 
0276     /* Wait time constants */
0277     /* These values came from Section 4.9.4 of the HHP HPS-Clocking NPP document */
0278 #define ALT_SW_MANAGED_CLK_WAIT_CTRDIV          30      /* 30 or more MPU clock cycles */
0279 #define ALT_SW_MANAGED_CLK_WAIT_HWCTRDIV        40
0280 #define ALT_SW_MANAGED_CLK_WAIT_BYPASS          30
0281 #define ALT_SW_MANAGED_CLK_WAIT_SAFEREQ         30
0282 #define ALT_SW_MANAGED_CLK_WAIT_SAFEEXIT        30
0283 #define ALT_SW_MANAGED_CLK_WAIT_NANDCLK         8       /* 8 or more MPU clock cycles */
0284 
0285 
0286 #define ALT_BYPASS_TIMEOUT_CNT      50
0287         // arbitrary number until i find more info
0288 #define ALT_TIMEOUT_PHASE_SYNC      300
0289         // how many loops to wait for the SDRAM clock to come around
0290         // to zero and allow for writing a new divisor ratio to it
0291 
0292 ALT_STATUS_CODE alt_clk_plls_settle_wait(void)
0293 {
0294     int32_t     i = ALT_BYPASS_TIMEOUT_CNT;
0295     bool        nofini;
0296 
0297     do
0298     {
0299         nofini = alt_read_word(ALT_CLKMGR_STAT_ADDR) & ALT_CLKMGR_STAT_BUSY_SET_MSK;
0300     } while (nofini && i--);
0301             // wait until clocks finish transitioning and become stable again
0302     return (i > 0) ? ALT_E_SUCCESS : ALT_E_ERROR;
0303 }
0304 
0305 static ALT_STATUS_CODE alt_clk_pll_lock_wait(ALT_CLK_t pll, uint32_t timeout)
0306 {
0307     uint32_t locked_mask = 0;
0308 
0309     if      (pll == ALT_CLK_MAIN_PLL)       { locked_mask = ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK; }
0310     else if (pll == ALT_CLK_PERIPHERAL_PLL) { locked_mask = ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK; }
0311     else if (pll == ALT_CLK_SDRAM_PLL)      { locked_mask = ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK; }
0312     else
0313     {
0314         return ALT_E_BAD_ARG;
0315     }
0316 
0317     do
0318     {
0319         uint32_t int_status = alt_read_word(ALT_CLKMGR_INTER_ADDR);
0320         if (int_status & locked_mask)
0321         {
0322             return ALT_E_SUCCESS;
0323         }
0324 
0325     } while (timeout--);
0326 
0327     return ALT_E_TMO;
0328 }
0329 
0330         /* Useful utility macro for checking if two values  */
0331         /* are within a certain percentage of each other    */
0332 #define  alt_within_delta(ref, neu, prcnt)  (((((neu) * 100)/(ref)) < (100 + (prcnt))) \
0333                                             && ((((neu) * 100)/(ref)) > (100 - (prcnt))))
0334 
0335 
0336         /* Flags to include or omit code sections */
0337 // There are four cases where there is a small possibility of producing clock
0338 // glitches. Code has been added from an abundance of caution to prevent
0339 // these glitches. If further testing shows that this extra code is not necessary
0340 // under any conditions, it may be easily eliminated by clearing these flags.
0341 
0342 #define ALT_PREVENT_GLITCH_BYP              true
0343 // for PLL entering or leaving bypass
0344 #define ALT_PREVENT_GLITCH_EXSAFE           true
0345 // for PLL exiting safe mode
0346 #define ALT_PREVENT_GLITCH_CNTRRST          true
0347 // resets counter phase
0348 #define ALT_PREVENT_GLITCH_CHGC1            true
0349 // for changing Main PLL C1 counter
0350 
0351 
0352 
0353 /****************************************************************************************/
0354 /* Bare-bones utility function used to make the somewhat complex writes to the PLL      */
0355 /* counter registers (the clock dividers) easier. No parameter-checking or              */
0356 /* error-checking, this is a static to this file and invisible to Doxygen.              */
0357 /****************************************************************************************/
0358 
0359 static void alt_clk_pllcounter_write(void* vcoaddr, void* stataddr, void* cntraddr,
0360         uint32_t val, uint32_t msk, uint32_t shift)
0361 {
0362 #if ALT_PREVENT_GLITCH_CNTRRST
0363     // this is here from an abundance of caution and it may not be necessary
0364     // to put the counter in reset for this write
0365     volatile uint32_t   temp;
0366 
0367     alt_setbits_word(vcoaddr, msk << shift);                // put the counter in reset
0368     do
0369     {
0370         temp = alt_read_word(stataddr);
0371     } while (!(temp & msk));
0372 
0373     alt_write_word(cntraddr, val);
0374     alt_clrbits_word(vcoaddr, msk << shift);                // release counter reset
0375 
0376 #else       // should we find out that resetting the counters as above is unnecessary
0377     alt_write_word(cntraddr, val);
0378 #endif
0379 }
0380 
0381 
0382 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0383 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Main Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0384 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
0385 
0386 
0387 /****************************************************************************************/
0388 /* alt_clk_lock_status_clear() clears assertions of one or more of the PLL lock status  */
0389 /* conditions.                                                                          */
0390 /****************************************************************************************/
0391 
0392 ALT_STATUS_CODE alt_clk_lock_status_clear(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
0393 {
0394     if (lock_stat_mask & (  ALT_CLKMGR_INTER_MAINPLLACHIEVED_CLR_MSK
0395                           & ALT_CLKMGR_INTER_PERPLLACHIEVED_CLR_MSK
0396                           & ALT_CLKMGR_INTER_SDRPLLACHIEVED_CLR_MSK
0397                           & ALT_CLKMGR_INTER_MAINPLLLOST_CLR_MSK
0398                           & ALT_CLKMGR_INTER_PERPLLLOST_CLR_MSK
0399                           & ALT_CLKMGR_INTER_SDRPLLLOST_CLR_MSK)
0400         )
0401     {
0402         return ALT_E_BAD_ARG;
0403     }
0404     else
0405     {
0406         alt_setbits_word(ALT_CLKMGR_INTER_ADDR, lock_stat_mask);
0407         return ALT_E_SUCCESS;
0408     }
0409 }
0410 
0411 
0412 /****************************************************************************************/
0413 /* alt_clk_lock_status_get() returns the value of the PLL lock status conditions.       */
0414 /****************************************************************************************/
0415 
0416 uint32_t alt_clk_lock_status_get(void)
0417 {
0418     return alt_read_word(ALT_CLKMGR_INTER_ADDR) & (  ALT_CLKMGR_INTER_MAINPLLACHIEVED_SET_MSK
0419                                                    | ALT_CLKMGR_INTER_PERPLLACHIEVED_SET_MSK
0420                                                    | ALT_CLKMGR_INTER_SDRPLLACHIEVED_SET_MSK
0421                                                    | ALT_CLKMGR_INTER_MAINPLLLOST_SET_MSK
0422                                                    | ALT_CLKMGR_INTER_PERPLLLOST_SET_MSK
0423                                                    | ALT_CLKMGR_INTER_SDRPLLLOST_SET_MSK
0424                                                    | ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK
0425                                                    | ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK
0426                                                    | ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK );
0427 }
0428 
0429 
0430 /****************************************************************************************/
0431 /* alt_clk_pll_is_locked() returns ALT_E_TRUE if the designated PLL is currently        */
0432 /* locked and ALT_E_FALSE if not.                                                       */
0433 /****************************************************************************************/
0434 
0435 ALT_STATUS_CODE alt_clk_pll_is_locked(ALT_CLK_t pll)
0436 {
0437     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
0438 
0439     if (pll == ALT_CLK_MAIN_PLL)
0440     {
0441         status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK)
0442                 ? ALT_E_TRUE : ALT_E_FALSE;
0443     }
0444     else if (pll == ALT_CLK_PERIPHERAL_PLL)
0445     {
0446         status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK)
0447                 ? ALT_E_TRUE : ALT_E_FALSE;
0448     }
0449     else if (pll == ALT_CLK_SDRAM_PLL)
0450     {
0451         status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK)
0452                 ? ALT_E_TRUE : ALT_E_FALSE;
0453     }
0454     return status;
0455 }
0456 
0457 
0458 /****************************************************************************************/
0459 /* alt_clk_safe_mode_clear() clears the safe mode status of the Clock Manager following */
0460 /* a reset.                                                                             */
0461 /****************************************************************************************/
0462 
0463 ALT_STATUS_CODE alt_clk_safe_mode_clear(void)
0464 {
0465     ALT_STATUS_CODE status = ALT_E_ERROR;
0466 #if ALT_PREVENT_GLITCH_EXSAFE
0467     uint32_t        temp;
0468 
0469     temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
0470     alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp &
0471             (ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK));
0472                     // gate off l4MP and L4SP clocks (no matter their source)
0473 
0474     alt_setbits_word(ALT_CLKMGR_CTL_ADDR, ALT_CLKMGR_CTL_SAFEMOD_SET_MSK);
0475                     // clear safe mode bit
0476     status = alt_clk_plls_settle_wait();
0477     alt_replbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR,
0478             ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK | ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK,
0479             temp);
0480                     // gate l4MP and L4SP clocks back on if they were on previously
0481 
0482 #else
0483     alt_setbits_word(ALT_CLKMGR_CTL_ADDR, ALT_CLKMGR_CTL_SAFEMOD_SET_MSK);
0484                     // clear safe mode bit
0485     status = alt_clk_plls_settle_wait();
0486 
0487 #endif
0488     return status;
0489 }
0490 
0491 
0492 /****************************************************************************************/
0493 /* alt_clk_is_in_safe_mode() returns whether the specified safe mode clock domain is in */
0494 /* safe mode or not.                                                                    */
0495 /****************************************************************************************/
0496 
0497 bool alt_clk_is_in_safe_mode(ALT_CLK_SAFE_DOMAIN_t clk_domain)
0498 {
0499     bool        ret = false;
0500     uint32_t    temp;
0501 
0502     if (clk_domain == ALT_CLK_DOMAIN_NORMAL)
0503     {
0504         ret = alt_read_word(ALT_CLKMGR_CTL_ADDR) & ALT_CLKMGR_CTL_SAFEMOD_SET_MSK;
0505                 // is the main clock domain in safe mode?
0506     }
0507     else if (clk_domain == ALT_CLK_DOMAIN_DEBUG)
0508     {
0509         temp = alt_read_word(ALT_CLKMGR_DBCTL_ADDR);
0510         if (temp & ALT_CLKMGR_DBCTL_STAYOSC1_SET_MSK)
0511         {
0512             ret = true;                // is the debug clock domain in safe mode?
0513         }
0514         else if (temp & ALT_CLKMGR_DBCTL_ENSFMDWR_SET_MSK)
0515         {
0516             ret = alt_read_word(ALT_CLKMGR_CTL_ADDR) & ALT_CLKMGR_CTL_SAFEMOD_SET_MSK;
0517                     // is the debug clock domain following the main clock domain
0518                     // AND is the main clock domain in safe mode?
0519         }
0520     }
0521     return ret;
0522 }
0523 
0524 /****************************************************************************************/
0525 /* alt_clk_pll_bypass_disable() disables bypass mode for the specified PLL, removing    */
0526 /* it from bypass mode and allowing it to provide the output of the PLL to drive the    */
0527 /* six main clocks.                                                                     */
0528 /****************************************************************************************/
0529 
0530 ALT_STATUS_CODE alt_clk_pll_bypass_disable(ALT_CLK_t pll)
0531 {
0532     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
0533     uint32_t        temp;
0534 #if  ALT_PREVENT_GLITCH_BYP
0535     uint32_t        temp1;
0536     bool            restore_0 = false;
0537     bool            restore_1 = false;
0538 #endif
0539 
0540     // this function should only be called after the selected PLL is locked
0541     if (alt_clk_pll_is_locked(pll) == ALT_E_TRUE)
0542     {
0543         if (pll == ALT_CLK_MAIN_PLL)
0544         {
0545 #if  ALT_PREVENT_GLITCH_BYP
0546             // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
0547             // bypass state, then gate clock back on. FogBugz #63778
0548             temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
0549             temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
0550 
0551             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
0552             {
0553                 restore_0 = true;
0554             }
0555             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
0556             {
0557                 restore_1 = true;
0558             }
0559             temp = temp1;
0560             if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
0561             if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
0562             if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
0563 #endif
0564 
0565             // assert outresetall of main PLL
0566             temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
0567             alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp | ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_SET_MSK);
0568 
0569             // deassert outresetall of main PLL
0570             alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp & ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_CLR_MSK);
0571 
0572             alt_clk_plls_settle_wait();
0573 
0574             // remove bypass
0575             alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
0576             status = alt_clk_plls_settle_wait();
0577 
0578 #if  ALT_PREVENT_GLITCH_BYP
0579             if (restore_0 || restore_1)
0580             {
0581                 alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
0582                             // wait a bit more before reenabling the L4MP and L4SP clocks
0583                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1);
0584             }
0585 #endif
0586         }
0587 
0588         else if (pll == ALT_CLK_PERIPHERAL_PLL)
0589         {
0590 #if  ALT_PREVENT_GLITCH_BYP
0591             // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
0592             // bypass state, then gate clock back on. FogBugz #63778
0593             temp = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
0594             temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
0595 
0596             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK))
0597             {
0598                     restore_0 = true;
0599             }
0600             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK))
0601             {
0602                     restore_1 = true;
0603             }
0604             temp = temp1;
0605             if (restore_0)  { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
0606             if (restore_1)  { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
0607             if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
0608 #endif
0609 
0610             // assert outresetall of Peripheral PLL
0611             temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
0612             alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp | ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_SET_MSK);
0613             alt_clk_plls_settle_wait();
0614 
0615             // deassert outresetall of main PLL
0616             alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp & ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_CLR_MSK);
0617 
0618             // remove bypass - don't think that there's any need to touch the bypass clock source
0619             alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_PERPLL_SET_MSK);
0620             status = alt_clk_plls_settle_wait();
0621 
0622 #if  ALT_PREVENT_GLITCH_BYP
0623             if (restore_0 || restore_1)
0624             {
0625                 alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
0626                             // wait a bit more before reenabling the L4MP and L4SP clocks
0627                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1);
0628             }
0629 #endif
0630         }
0631 
0632         else if (pll == ALT_CLK_SDRAM_PLL)
0633         {
0634             // assert outresetall of SDRAM PLL
0635             temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
0636             alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp | ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK);
0637 
0638             // deassert outresetall of main PLL
0639             alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp & ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_CLR_MSK);
0640             alt_clk_plls_settle_wait();
0641 
0642             // remove bypass - don't think that there's any need to touch the bypass clock source
0643             alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_SDRPLLSRC_SET_MSK);
0644             status = alt_clk_plls_settle_wait();
0645         }
0646     }
0647     else
0648     {
0649         status = ALT_E_ERROR;
0650     }
0651 
0652     return status;
0653 }
0654 
0655 
0656 /****************************************************************************************/
0657 /* alt_clk_pll_bypass_enable() enable bypass mode for the specified PLL.                */
0658 /****************************************************************************************/
0659 
0660 ALT_STATUS_CODE alt_clk_pll_bypass_enable(ALT_CLK_t pll, bool use_input_mux)
0661 {
0662     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
0663     uint32_t        temp;
0664 #ifdef  ALT_PREVENT_GLITCH_BYP
0665     uint32_t        temp1;
0666     bool            restore_0 = false;
0667     bool            restore_1 = false;
0668 #endif
0669 
0670     if (pll == ALT_CLK_MAIN_PLL)
0671     {
0672         if (!use_input_mux)
0673         {
0674 #ifdef  ALT_PREVENT_GLITCH_BYP
0675             // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
0676             // bypass state, then gate clock back on. FogBugz #63778
0677             temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
0678             temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
0679 
0680             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
0681             {
0682                 restore_0 = true;
0683             }
0684             if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
0685             {
0686                 restore_1 = true;
0687             }
0688             temp = temp1;
0689             if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
0690             if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
0691             if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
0692 
0693             alt_setbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
0694                         // no input mux select on main PLL
0695 
0696             status = alt_clk_plls_settle_wait();
0697                         // wait before reenabling the L4MP and L4SP clocks
0698             if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }
0699 
0700 #else
0701             alt_setbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
0702                         // no input mux select on main PLL
0703             status = alt_clk_plls_settle_wait();
0704 
0705 #endif
0706             status = ALT_E_SUCCESS;
0707         }
0708         else
0709         {
0710             status =  ALT_E_BAD_ARG;
0711         }
0712     }
0713     else if (pll == ALT_CLK_PERIPHERAL_PLL)
0714     {
0715 #ifdef  ALT_PREVENT_GLITCH_BYP
0716         // if L4MP or L4SP source is set to Peripheral PLL C1, gate it off before changing
0717         // bypass state, then gate clock back on. FogBugz #63778
0718         temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
0719         temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
0720 
0721         if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK))
0722         {
0723             restore_0 = true;
0724         }
0725         if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK))
0726         {
0727             restore_1 = true;
0728         }
0729         temp = temp1;
0730         if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
0731         if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
0732         if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
0733 
0734         temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
0735                 (ALT_CLKMGR_BYPASS_PERPLL_CLR_MSK & ALT_CLKMGR_BYPASS_PERPLLSRC_CLR_MSK);
0736         temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_PERPLL_SET_MSK |
0737                 ALT_CLKMGR_BYPASS_PERPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_PERPLL_SET_MSK;
0738                     // set bypass bit and optionally the source select bit
0739 
0740         alt_write_word(ALT_CLKMGR_BYPASS_ADDR, temp);
0741         alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
0742                     // wait a bit before reenabling the L4MP and L4SP clocks
0743         if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }
0744 
0745 #else
0746         temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
0747                 (ALT_CLKMGR_BYPASS_PERPLL_CLR_MSK & ALT_CLKMGR_BYPASS_PERPLLSRC_CLR_MSK);
0748         temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_PERPLL_SET_MSK |
0749                 ALT_CLKMGR_BYPASS_PERPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_PERPLL_SET_MSK;
0750                     // set bypass bit and optionally the source select bit
0751 #endif
0752         status = ALT_E_SUCCESS;
0753     }
0754 
0755     else if (pll == ALT_CLK_SDRAM_PLL)
0756     {
0757         temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
0758                 (ALT_CLKMGR_BYPASS_SDRPLL_CLR_MSK & ALT_CLKMGR_BYPASS_SDRPLLSRC_CLR_MSK);
0759         temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_SDRPLL_SET_MSK |
0760                 ALT_CLKMGR_BYPASS_SDRPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_SDRPLL_SET_MSK;
0761                     // set bypass bit and optionally the source select bit
0762         alt_write_word(ALT_CLKMGR_BYPASS_ADDR, temp);
0763         status = ALT_E_SUCCESS;
0764     }
0765     return status;
0766 }
0767 
0768 
0769 /****************************************************************************************/
0770 /* alt_clk_pll_is_bypassed() returns whether the specified PLL is in bypass or not.     */
0771 /* Bypass is a special state where the PLL VCO and the C0-C5 counters are bypassed      */
0772 /* and not in the circuit. Either the Osc1 clock input or the input chosen by the       */
0773 /* input mux may be selected to be operational in the bypass state. All changes to      */
0774 /* the PLL VCO must be made in bypass mode to avoid the potential of producing clock    */
0775 /* glitches which may affect downstream clock dividers and peripherals.                 */
0776 /****************************************************************************************/
0777 
0778 ALT_STATUS_CODE alt_clk_pll_is_bypassed(ALT_CLK_t pll)
0779 {
0780     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
0781 
0782     if (pll == ALT_CLK_MAIN_PLL)
0783     {
0784         status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
0785                 || ALT_CLKMGR_BYPASS_MAINPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
0786                 ? ALT_E_TRUE : ALT_E_FALSE;
0787     }
0788     else if (pll == ALT_CLK_PERIPHERAL_PLL)
0789     {
0790         status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
0791                 || ALT_CLKMGR_BYPASS_PERPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
0792                 ? ALT_E_TRUE : ALT_E_FALSE;
0793     }
0794     else if (pll == ALT_CLK_SDRAM_PLL)
0795     {
0796         status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
0797                 || ALT_CLKMGR_BYPASS_SDRPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
0798                 ? ALT_E_TRUE : ALT_E_FALSE;
0799     }
0800     return status;
0801 }
0802 
0803 
0804 /****************************************************************************************/
0805 /* alt_clk_pll_source_get() returns the current input of the specified PLL.             */
0806 /****************************************************************************************/
0807 
0808 ALT_CLK_t alt_clk_pll_source_get(ALT_CLK_t pll)
0809 {
0810     ALT_CLK_t      ret = ALT_CLK_UNKNOWN;
0811     uint32_t       temp;
0812 
0813 
0814     if (pll == ALT_CLK_MAIN_PLL)
0815     {
0816         ret = ALT_CLK_IN_PIN_OSC1;
0817     }
0818     else if (pll == ALT_CLK_PERIPHERAL_PLL)
0819     {
0820         // three possible clock sources for the peripheral PLL
0821         temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
0822         if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
0823         {
0824             ret = ALT_CLK_IN_PIN_OSC1;
0825         }
0826         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
0827         {
0828             ret = ALT_CLK_IN_PIN_OSC2;
0829         }
0830         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
0831         {
0832             ret = ALT_CLK_F2H_PERIPH_REF;
0833         }
0834     }
0835     else if (pll == ALT_CLK_SDRAM_PLL)
0836     {
0837         // three possible clock sources for the SDRAM PLL
0838         temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
0839         if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
0840         {
0841             ret = ALT_CLK_IN_PIN_OSC1;
0842         }
0843         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
0844         {
0845             ret = ALT_CLK_IN_PIN_OSC2;
0846         }
0847         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
0848         {
0849             ret = ALT_CLK_F2H_SDRAM_REF;
0850         }
0851     }
0852     return ret;
0853 }
0854 
0855 //
0856 // alt_clk_clock_disable() disables the specified clock. Once the clock is disabled,
0857 // its clock signal does not propagate to its clocked elements.
0858 //
0859 ALT_STATUS_CODE alt_clk_clock_disable(ALT_CLK_t clk)
0860 {
0861     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0862 
0863     switch (clk)
0864     {
0865         // For PLLs, put them in bypass mode.
0866     case ALT_CLK_MAIN_PLL:
0867     case ALT_CLK_PERIPHERAL_PLL:
0868     case ALT_CLK_SDRAM_PLL:
0869         status = alt_clk_pll_bypass_enable(clk, false);
0870         break;
0871 
0872         // Clocks that originate at the Main PLL.
0873     case ALT_CLK_L4_MAIN:
0874         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_SET_MSK);
0875         break;
0876     case ALT_CLK_L3_MP:
0877         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK);
0878         break;
0879     case ALT_CLK_L4_MP:
0880         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
0881         break;
0882     case ALT_CLK_L4_SP:
0883         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);
0884         break;
0885     case ALT_CLK_DBG_AT:
0886         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK);
0887         break;
0888     case ALT_CLK_DBG:
0889         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK);
0890         break;
0891     case ALT_CLK_DBG_TRACE:
0892         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK);
0893         break;
0894     case ALT_CLK_DBG_TIMER:
0895         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_SET_MSK);
0896         break;
0897     case ALT_CLK_CFG:
0898         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK);
0899         break;
0900     case ALT_CLK_H2F_USER0:
0901         alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK);
0902         break;
0903 
0904         // Clocks that originate at the Peripheral PLL.
0905     case ALT_CLK_EMAC0:
0906         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK);
0907         break;
0908     case ALT_CLK_EMAC1:
0909         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK);
0910         break;
0911     case ALT_CLK_USB_MP:
0912         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK);
0913         break;
0914     case ALT_CLK_SPI_M:
0915         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK);
0916         break;
0917     case ALT_CLK_CAN0:
0918         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK);
0919         break;
0920     case ALT_CLK_CAN1:
0921         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK);
0922         break;
0923     case ALT_CLK_GPIO_DB:
0924         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK);
0925         break;
0926     case ALT_CLK_H2F_USER1:
0927         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK);
0928         break;
0929     case ALT_CLK_SDMMC:
0930         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
0931         break;
0932     case ALT_CLK_NAND_X:
0933         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
0934         alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
0935         // gate nand_clk off before nand_x_clk.
0936         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
0937         break;
0938     case ALT_CLK_NAND:
0939         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
0940         break;
0941     case ALT_CLK_QSPI:
0942         alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
0943         break;
0944 
0945         // Clocks that originate at the SDRAM PLL.
0946     case ALT_CLK_DDR_DQS:
0947         alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK);
0948         break;
0949     case ALT_CLK_DDR_2X_DQS:
0950         alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK);
0951         break;
0952     case ALT_CLK_DDR_DQ:
0953         alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK);
0954         break;
0955     case ALT_CLK_H2F_USER2:
0956         alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK);
0957         break;
0958 
0959     default:
0960         status = ALT_E_BAD_ARG;
0961         break;
0962     }
0963 
0964     return status;
0965 }
0966 
0967 
0968 //
0969 // alt_clk_clock_enable() enables the specified clock. Once the clock is enabled, its
0970 // clock signal propagates to its elements.
0971 //
0972 ALT_STATUS_CODE alt_clk_clock_enable(ALT_CLK_t clk)
0973 {
0974     ALT_STATUS_CODE status = ALT_E_SUCCESS;
0975 
0976     switch (clk)
0977     {
0978         // For PLLs, take them out of bypass mode.
0979     case ALT_CLK_MAIN_PLL:
0980     case ALT_CLK_PERIPHERAL_PLL:
0981     case ALT_CLK_SDRAM_PLL:
0982         status = alt_clk_pll_bypass_disable(clk);
0983         break;
0984 
0985         // Clocks that originate at the Main PLL.
0986     case ALT_CLK_L4_MAIN:
0987         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_SET_MSK);
0988         break;
0989     case ALT_CLK_L3_MP:
0990         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK);
0991         break;
0992     case ALT_CLK_L4_MP:
0993         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
0994         break;
0995     case ALT_CLK_L4_SP:
0996         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);
0997         break;
0998     case ALT_CLK_DBG_AT:
0999         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK);
1000         break;
1001     case ALT_CLK_DBG:
1002         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK);
1003         break;
1004     case ALT_CLK_DBG_TRACE:
1005         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK);
1006         break;
1007     case ALT_CLK_DBG_TIMER:
1008         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_SET_MSK);
1009         break;
1010     case ALT_CLK_CFG:
1011         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK);
1012         break;
1013     case ALT_CLK_H2F_USER0:
1014         alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK);
1015         break;
1016 
1017         // Clocks that originate at the Peripheral PLL.
1018     case ALT_CLK_EMAC0:
1019         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK);
1020         break;
1021     case ALT_CLK_EMAC1:
1022         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK);
1023         break;
1024     case ALT_CLK_USB_MP:
1025         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK);
1026         break;
1027     case ALT_CLK_SPI_M:
1028         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK);
1029         break;
1030     case ALT_CLK_CAN0:
1031         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK);
1032         break;
1033     case ALT_CLK_CAN1:
1034         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK);
1035         break;
1036     case ALT_CLK_GPIO_DB:
1037         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK);
1038         break;
1039     case ALT_CLK_H2F_USER1:
1040         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK);
1041         break;
1042     case ALT_CLK_SDMMC:
1043         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
1044         break;
1045     case ALT_CLK_NAND_X:
1046         // implementation detail - should ALK_CLK_NAND be gated off here before enabling ALT_CLK_NAND_X?
1047         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
1048         // implementation detail - should this wait be enforced here?
1049         alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
1050         break;
1051     case ALT_CLK_NAND:
1052         // enabling ALT_CLK_NAND always implies enabling ALT_CLK_NAND_X first
1053         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
1054         alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
1055         // gate nand_x_clk on at least 8 MCU clocks before nand_clk
1056         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
1057         break;
1058     case ALT_CLK_QSPI:
1059         alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
1060         break;
1061 
1062         // Clocks that originate at the SDRAM PLL.
1063     case ALT_CLK_DDR_DQS:
1064         alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK);
1065         break;
1066     case ALT_CLK_DDR_2X_DQS:
1067         alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK);
1068         break;
1069     case ALT_CLK_DDR_DQ:
1070         alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK);
1071         break;
1072     case ALT_CLK_H2F_USER2:
1073         alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK);
1074         break;
1075 
1076     default:
1077         status = ALT_E_BAD_ARG;
1078         break;
1079     }
1080 
1081     return status;
1082 }
1083 
1084 //
1085 // alt_clk_is_enabled() returns whether the specified clock is enabled or not.
1086 //
1087 ALT_STATUS_CODE alt_clk_is_enabled(ALT_CLK_t clk)
1088 {
1089     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
1090 
1091     switch (clk)
1092     {
1093         // For PLLs, this function checks if the PLL is bypassed or not.
1094     case ALT_CLK_MAIN_PLL:
1095     case ALT_CLK_PERIPHERAL_PLL:
1096     case ALT_CLK_SDRAM_PLL:
1097         status = (alt_clk_pll_is_bypassed(clk) != ALT_E_TRUE);
1098         break;
1099 
1100         // These clocks are not gated, so must return a ALT_E_BAD_ARG type error.
1101     case ALT_CLK_MAIN_PLL_C0:
1102     case ALT_CLK_MAIN_PLL_C1:
1103     case ALT_CLK_MAIN_PLL_C2:
1104     case ALT_CLK_MAIN_PLL_C3:
1105     case ALT_CLK_MAIN_PLL_C4:
1106     case ALT_CLK_MAIN_PLL_C5:
1107     case ALT_CLK_MPU:
1108     case ALT_CLK_MPU_L2_RAM:
1109     case ALT_CLK_MPU_PERIPH:
1110     case ALT_CLK_L3_MAIN:
1111     case ALT_CLK_L3_SP:
1112     case ALT_CLK_DBG_BASE:
1113     case ALT_CLK_MAIN_QSPI:
1114     case ALT_CLK_MAIN_NAND_SDMMC:
1115     case ALT_CLK_PERIPHERAL_PLL_C0:
1116     case ALT_CLK_PERIPHERAL_PLL_C1:
1117     case ALT_CLK_PERIPHERAL_PLL_C2:
1118     case ALT_CLK_PERIPHERAL_PLL_C3:
1119     case ALT_CLK_PERIPHERAL_PLL_C4:
1120     case ALT_CLK_PERIPHERAL_PLL_C5:
1121     case ALT_CLK_SDRAM_PLL_C0:
1122     case ALT_CLK_SDRAM_PLL_C1:
1123     case ALT_CLK_SDRAM_PLL_C2:
1124     case ALT_CLK_SDRAM_PLL_C5:
1125         status = ALT_E_BAD_ARG;
1126         break;
1127 
1128         // Clocks that originate at the Main PLL.
1129     case ALT_CLK_L4_MAIN:
1130         status = (ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1131             ? ALT_E_TRUE : ALT_E_FALSE;
1132         break;
1133     case ALT_CLK_L3_MP:
1134         status = (ALT_CLKMGR_MAINPLL_EN_L3MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1135             ? ALT_E_TRUE : ALT_E_FALSE;
1136         break;
1137     case ALT_CLK_L4_MP:
1138         status = (ALT_CLKMGR_MAINPLL_EN_L4MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1139             ? ALT_E_TRUE : ALT_E_FALSE;
1140         break;
1141     case ALT_CLK_L4_SP:
1142         status = (ALT_CLKMGR_MAINPLL_EN_L4SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1143             ? ALT_E_TRUE : ALT_E_FALSE;
1144         break;
1145     case ALT_CLK_DBG_AT:
1146         status = (ALT_CLKMGR_MAINPLL_EN_DBGATCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1147             ? ALT_E_TRUE : ALT_E_FALSE;
1148         break;
1149     case ALT_CLK_DBG:
1150         status = (ALT_CLKMGR_MAINPLL_EN_DBGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1151             ? ALT_E_TRUE : ALT_E_FALSE;
1152         break;
1153     case ALT_CLK_DBG_TRACE:
1154         status = (ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1155             ? ALT_E_TRUE : ALT_E_FALSE;
1156         break;
1157     case ALT_CLK_DBG_TIMER:
1158         status = (ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1159             ? ALT_E_TRUE : ALT_E_FALSE;
1160         break;
1161     case ALT_CLK_CFG:
1162         status = (ALT_CLKMGR_MAINPLL_EN_CFGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1163             ? ALT_E_TRUE : ALT_E_FALSE;
1164         break;
1165     case ALT_CLK_H2F_USER0:
1166         status = (ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
1167             ? ALT_E_TRUE : ALT_E_FALSE;
1168         break;
1169 
1170         // Clocks that originate at the Peripheral PLL.
1171     case ALT_CLK_EMAC0:
1172         status = (ALT_CLKMGR_PERPLL_EN_EMAC0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1173             ? ALT_E_TRUE : ALT_E_FALSE;
1174         break;
1175     case ALT_CLK_EMAC1:
1176         status = (ALT_CLKMGR_PERPLL_EN_EMAC1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1177             ? ALT_E_TRUE : ALT_E_FALSE;
1178         break;
1179     case ALT_CLK_USB_MP:
1180         status = (ALT_CLKMGR_PERPLL_EN_USBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1181             ? ALT_E_TRUE : ALT_E_FALSE;
1182         break;
1183     case ALT_CLK_SPI_M:
1184         status = (ALT_CLKMGR_PERPLL_EN_SPIMCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1185             ? ALT_E_TRUE : ALT_E_FALSE;
1186         break;
1187     case ALT_CLK_CAN0:
1188         status = (ALT_CLKMGR_PERPLL_EN_CAN0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1189             ? ALT_E_TRUE : ALT_E_FALSE;
1190         break;
1191     case ALT_CLK_CAN1:
1192         status = (ALT_CLKMGR_PERPLL_EN_CAN1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1193             ? ALT_E_TRUE : ALT_E_FALSE;
1194         break;
1195     case ALT_CLK_GPIO_DB:
1196         status = (ALT_CLKMGR_PERPLL_EN_GPIOCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1197             ? ALT_E_TRUE : ALT_E_FALSE;
1198         break;
1199     case ALT_CLK_H2F_USER1:
1200         status = (ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1201             ? ALT_E_TRUE : ALT_E_FALSE;
1202         break;
1203 
1204         // Clocks that may originate at the Main PLL, the Peripheral PLL, or the FPGA.
1205     case ALT_CLK_SDMMC:
1206         status = (ALT_CLKMGR_PERPLL_EN_SDMMCCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1207             ? ALT_E_TRUE : ALT_E_FALSE;
1208         break;
1209     case ALT_CLK_NAND_X:
1210         status = (ALT_CLKMGR_PERPLL_EN_NANDXCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1211             ? ALT_E_TRUE : ALT_E_FALSE;
1212         break;
1213     case ALT_CLK_NAND:
1214         status = (ALT_CLKMGR_PERPLL_EN_NANDCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1215             ? ALT_E_TRUE : ALT_E_FALSE;
1216         break;
1217     case ALT_CLK_QSPI:
1218         status = (ALT_CLKMGR_PERPLL_EN_QSPICLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
1219             ? ALT_E_TRUE : ALT_E_FALSE;
1220         break;
1221 
1222         // Clocks that originate at the SDRAM PLL.
1223     case ALT_CLK_DDR_DQS:
1224         status = (ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
1225             ? ALT_E_TRUE : ALT_E_FALSE;
1226         break;
1227     case ALT_CLK_DDR_2X_DQS:
1228         status = (ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
1229             ? ALT_E_TRUE : ALT_E_FALSE;
1230         break;
1231     case ALT_CLK_DDR_DQ:
1232         status = (ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
1233             ? ALT_E_TRUE : ALT_E_FALSE;
1234         break;
1235     case ALT_CLK_H2F_USER2:
1236         status = (ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
1237             ? ALT_E_TRUE : ALT_E_FALSE;
1238         break;
1239 
1240     default:
1241         status = ALT_E_BAD_ARG;
1242         break;
1243 
1244     }
1245 
1246     return status;
1247 }
1248 
1249 //
1250 // alt_clk_source_get() gets the input reference clock source selection value for the
1251 // specified clock or PLL.
1252 //
1253 ALT_CLK_t alt_clk_source_get(ALT_CLK_t clk)
1254 {
1255     ALT_CLK_t ret = ALT_CLK_UNKNOWN;
1256     uint32_t  temp;
1257 
1258     switch (clk)
1259     {
1260         // Potential external clock sources.
1261         // these clock entities are their own source
1262     case ALT_CLK_IN_PIN_OSC1:
1263     case ALT_CLK_IN_PIN_OSC2:
1264     case ALT_CLK_F2H_PERIPH_REF:
1265     case ALT_CLK_F2H_SDRAM_REF:
1266     case ALT_CLK_IN_PIN_JTAG:
1267     case ALT_CLK_IN_PIN_ULPI0:
1268     case ALT_CLK_IN_PIN_ULPI1:
1269     case ALT_CLK_IN_PIN_EMAC0_RX:
1270     case ALT_CLK_IN_PIN_EMAC1_RX:
1271         ret = clk;
1272         break;
1273 
1274         // Phase-Locked Loops.
1275     case ALT_CLK_MAIN_PLL:
1276     case ALT_CLK_OSC1:
1277         ret = ALT_CLK_IN_PIN_OSC1;
1278         break;
1279     case ALT_CLK_PERIPHERAL_PLL:
1280         ret = alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL);
1281         break;
1282     case ALT_CLK_SDRAM_PLL:
1283         ret = alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL);
1284         break;
1285 
1286         // Main Clock Group.
1287     case ALT_CLK_MAIN_PLL_C0:
1288     case ALT_CLK_MAIN_PLL_C1:
1289     case ALT_CLK_MAIN_PLL_C2:
1290     case ALT_CLK_MAIN_PLL_C3:
1291     case ALT_CLK_MAIN_PLL_C4:
1292     case ALT_CLK_MAIN_PLL_C5:
1293         // check bypass, return either osc1 or PLL ID
1294         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1295             ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL;
1296         break;
1297 
1298     case ALT_CLK_MPU_PERIPH:
1299     case ALT_CLK_MPU_L2_RAM:
1300     case ALT_CLK_MPU:
1301         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1302             ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C0;
1303         break;
1304 
1305     case ALT_CLK_L4_MAIN:
1306     case ALT_CLK_L3_MAIN:
1307     case ALT_CLK_L3_MP:
1308     case ALT_CLK_L3_SP:
1309         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1310             ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
1311         break;
1312 
1313     case ALT_CLK_L4_MP:
1314         // read the state of the L4_mp source bit
1315         if ((ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR)))
1316             == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_MAINPLL)
1317         {
1318             ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1319                 ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
1320         }
1321         else
1322         {
1323             // if the clock comes from periph_base_clk
1324             ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1325                 alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL_C4;
1326         }
1327         break;
1328 
1329     case ALT_CLK_L4_SP:
1330         // read the state of the source bit
1331         if ((ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR)))
1332             == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_MAINPLL)
1333         {
1334             ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1335                 ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
1336         }
1337         else
1338         {
1339             // if the clock comes from periph_base_clk
1340             ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1341                 alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL_C4;
1342         }
1343         break;
1344 
1345     case ALT_CLK_DBG_BASE:
1346     case ALT_CLK_DBG_AT:
1347     case ALT_CLK_DBG_TRACE:
1348     case ALT_CLK_DBG_TIMER:
1349     case ALT_CLK_DBG:
1350         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1351             ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C2;
1352         break;
1353     case ALT_CLK_MAIN_QSPI:
1354         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1355             ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C3;
1356         break;
1357     case ALT_CLK_MAIN_NAND_SDMMC:
1358         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1359             ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C4;
1360         break;
1361     case ALT_CLK_CFG:
1362     case ALT_CLK_H2F_USER0:
1363         ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1364             ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C5;
1365         break;
1366 
1367         // Peripherals Clock Group
1368     case ALT_CLK_PERIPHERAL_PLL_C0:
1369     case ALT_CLK_PERIPHERAL_PLL_C1:
1370     case ALT_CLK_PERIPHERAL_PLL_C2:
1371     case ALT_CLK_PERIPHERAL_PLL_C3:
1372     case ALT_CLK_PERIPHERAL_PLL_C4:
1373     case ALT_CLK_PERIPHERAL_PLL_C5:
1374         // if the clock comes from periph_base_clk
1375         ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1376             alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL;
1377         break;
1378 
1379     case ALT_CLK_EMAC0:
1380         ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1381             alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C0;
1382         break;
1383 
1384     case ALT_CLK_EMAC1:
1385         ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1386             alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C1;
1387         break;
1388 
1389     case ALT_CLK_USB_MP:
1390     case ALT_CLK_SPI_M:
1391     case ALT_CLK_CAN0:
1392     case ALT_CLK_CAN1:
1393     case ALT_CLK_GPIO_DB:
1394         ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1395             alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C4;
1396         break;
1397 
1398     case ALT_CLK_H2F_USER1:
1399         ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1400             alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C5;
1401         break;
1402 
1403     case ALT_CLK_SDMMC:
1404         temp = ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
1405         if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK)
1406         {
1407             ret = ALT_CLK_F2H_PERIPH_REF;
1408         }
1409         else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
1410         {
1411             ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1412                 ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C4;
1413         }
1414         else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK)
1415         {
1416             ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1417                 alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C3;
1418         }
1419         break;
1420 
1421     case ALT_CLK_NAND_X:
1422     case ALT_CLK_NAND:
1423         temp = ALT_CLKMGR_PERPLL_SRC_NAND_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
1424         if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK)
1425         {
1426             ret = ALT_CLK_F2H_PERIPH_REF;
1427         }
1428         else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
1429         {
1430             ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1431                 ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C4;
1432         }
1433         else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK)
1434         {
1435             ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1436                 alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C3;
1437         }
1438         break;
1439 
1440     case ALT_CLK_QSPI:
1441         temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
1442         if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK)
1443         {
1444             ret = ALT_CLK_F2H_PERIPH_REF;
1445         }
1446         else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
1447         {
1448             ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
1449                 ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C3;
1450         }
1451         else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
1452         {
1453             ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
1454                 alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C2;
1455         }
1456         break;
1457 
1458         // SDRAM Clock Group
1459     case ALT_CLK_SDRAM_PLL_C0:
1460     case ALT_CLK_SDRAM_PLL_C1:
1461     case ALT_CLK_SDRAM_PLL_C2:
1462     case ALT_CLK_SDRAM_PLL_C3:
1463     case ALT_CLK_SDRAM_PLL_C4:
1464     case ALT_CLK_SDRAM_PLL_C5:
1465         ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
1466             alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL;
1467         break;
1468     case ALT_CLK_DDR_DQS:
1469         ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
1470             alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C0;
1471         break;
1472     case ALT_CLK_DDR_2X_DQS:
1473         ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
1474             alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C1;
1475         break;
1476     case ALT_CLK_DDR_DQ:
1477         ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
1478             alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C2;
1479         break;
1480     case ALT_CLK_H2F_USER2:
1481         ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
1482             alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C5;
1483         break;
1484 
1485         // Clock Output Pins
1486     case ALT_CLK_OUT_PIN_EMAC0_TX:
1487     case ALT_CLK_OUT_PIN_EMAC1_TX:
1488     case ALT_CLK_OUT_PIN_SDMMC:
1489     case ALT_CLK_OUT_PIN_I2C0_SCL:
1490     case ALT_CLK_OUT_PIN_I2C1_SCL:
1491     case ALT_CLK_OUT_PIN_I2C2_SCL:
1492     case ALT_CLK_OUT_PIN_I2C3_SCL:
1493     case ALT_CLK_OUT_PIN_SPIM0:
1494     case ALT_CLK_OUT_PIN_SPIM1:
1495     case ALT_CLK_OUT_PIN_QSPI:
1496         ret = ALT_CLK_UNKNOWN;
1497         break;
1498 
1499     default:
1500         ret = ALT_CLK_UNKNOWN;
1501         break;
1502     }
1503 
1504     return ret;
1505 }
1506 
1507 //
1508 // alt_clk_source_set() sets the specified clock's input reference clock source
1509 // selection to the specified input. It does not handle gating the specified clock
1510 // off and back on, those are covered in other functions in this API, but it does
1511 // verify that the clock is off before changing the divider or PLL. Note that the PLL
1512 // must have regained phase-lock before being the bypass is disabled.
1513 //
1514 ALT_STATUS_CODE alt_clk_source_set(ALT_CLK_t clk, ALT_CLK_t ref_clk)
1515 {
1516     ALT_STATUS_CODE status = ALT_E_SUCCESS;
1517     uint32_t        temp;
1518 
1519     if (ALT_CLK_MAIN_PLL == clk)
1520     {
1521         if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
1522         {
1523             // ret = ALT_E_SUCCESS;
1524         }
1525         else
1526         {
1527             status = ALT_E_BAD_ARG;
1528         }
1529     }
1530     else if (ALT_CLK_PERIPHERAL_PLL == clk)
1531     {
1532         // the PLL must be bypassed before getting here
1533         temp  = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
1534         temp &= ALT_CLKMGR_PERPLL_VCO_PSRC_CLR_MSK;
1535 
1536         if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
1537         {
1538             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1);
1539             alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
1540         }
1541         else if (ref_clk == ALT_CLK_IN_PIN_OSC2)
1542         {
1543             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2);
1544             alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
1545         }
1546         else if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
1547         {
1548             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF);
1549             alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
1550         }
1551         else
1552         {
1553             status = ALT_E_INV_OPTION;
1554         }
1555     }
1556     else if (ALT_CLK_SDRAM_PLL == clk)
1557     {
1558         temp  = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
1559         temp &= ALT_CLKMGR_SDRPLL_VCO_SSRC_CLR_MSK;
1560 
1561         if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
1562         {
1563             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1);
1564             alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
1565         }
1566         else if (ref_clk == ALT_CLK_IN_PIN_OSC2)
1567         {
1568             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2);
1569             alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
1570         }
1571         else if (ref_clk == ALT_CLK_F2H_SDRAM_REF)
1572         {
1573             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF);
1574             alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
1575         }
1576         else
1577         {
1578             status = ALT_E_INV_OPTION;
1579         }
1580     }
1581     else if ( ALT_CLK_L4_MP == clk)
1582     {
1583         // clock is gated off
1584         if (ref_clk == ALT_CLK_MAIN_PLL_C1)
1585         {
1586             alt_clrbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK);
1587         }
1588         else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C4)
1589         {
1590             alt_setbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK);
1591         }
1592         else
1593         {
1594             status = ALT_E_INV_OPTION;
1595         }
1596     }
1597     else if ( ALT_CLK_L4_SP == clk)
1598     {
1599         if (ref_clk == ALT_CLK_MAIN_PLL_C1)
1600         {
1601             alt_clrbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK);
1602         }
1603         else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C4)
1604         {
1605             alt_setbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK);
1606         }
1607         else
1608         {
1609             status = ALT_E_INV_OPTION;
1610         }
1611     }
1612     else if (ALT_CLK_SDMMC == clk)
1613     {
1614         temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
1615         temp &= ALT_CLKMGR_PERPLL_SRC_SDMMC_CLR_MSK;
1616 
1617         if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
1618         {
1619             temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK);
1620             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1621         }
1622         else if ((ref_clk == ALT_CLK_MAIN_PLL_C4) || (ref_clk == ALT_CLK_MAIN_NAND_SDMMC))
1623         {
1624             temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK);
1625             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1626         }
1627         else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C3)
1628         {
1629             temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK);
1630             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1631         }
1632         else
1633         {
1634             status = ALT_E_INV_OPTION;
1635         }
1636     }
1637     else if ((ALT_CLK_NAND_X == clk) || ( ALT_CLK_NAND == clk))
1638     {
1639         temp = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
1640         temp &= ALT_CLKMGR_PERPLL_SRC_NAND_CLR_MSK;
1641 
1642         if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
1643         {
1644             temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK);
1645             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1646         }
1647         else if ((ref_clk == ALT_CLK_MAIN_PLL_C4) || (ref_clk == ALT_CLK_MAIN_NAND_SDMMC))
1648         {
1649             temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK);
1650             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1651         }
1652         else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C3)
1653         {
1654             temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK);
1655             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1656         }
1657         else
1658         {
1659             status = ALT_E_INV_OPTION;
1660         }
1661     }
1662     else if (ALT_CLK_QSPI == clk)
1663     {
1664         temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
1665         temp &= ALT_CLKMGR_PERPLL_SRC_QSPI_CLR_MSK;
1666 
1667         if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
1668         {
1669             temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK);
1670             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1671         }
1672         else if ((ref_clk == ALT_CLK_MAIN_PLL_C3) || (ref_clk == ALT_CLK_MAIN_QSPI))
1673         {
1674             temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK);
1675             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1676         }
1677         else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C2)
1678         {
1679             temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK);
1680             alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
1681         }
1682         else
1683         {
1684             status = ALT_E_INV_OPTION;
1685         }
1686     }
1687 
1688     return status;
1689 }
1690 
1691 //
1692 // alt_clk_ext_clk_freq_set() specifies the frequency of the external clock source as
1693 // a measure of Hz. This value is stored in a static array and used for calculations.
1694 // The supplied frequency should be within the Fmin and Fmax values allowed for the
1695 // external clock source.
1696 //
1697 ALT_STATUS_CODE alt_clk_ext_clk_freq_set(ALT_CLK_t clk, alt_freq_t freq)
1698 {
1699     ALT_STATUS_CODE status = ALT_E_BAD_ARG;
1700 
1701     if ((clk == ALT_CLK_IN_PIN_OSC1) || (clk == ALT_CLK_OSC1))      // two names for one input
1702     {
1703         if ((freq >= alt_ext_clk_paramblok.clkosc1.freqmin) && (freq <= alt_ext_clk_paramblok.clkosc1.freqmax))
1704         {
1705             alt_ext_clk_paramblok.clkosc1.freqcur = freq;
1706             status = ALT_E_SUCCESS;
1707         }
1708         else
1709         {
1710             status = ALT_E_ARG_RANGE;
1711         }
1712     }
1713     else if (clk == ALT_CLK_IN_PIN_OSC2)                            // the other clock input pin
1714     {
1715         if ((freq >= alt_ext_clk_paramblok.clkosc2.freqmin) && (freq <= alt_ext_clk_paramblok.clkosc2.freqmax))
1716         {
1717             alt_ext_clk_paramblok.clkosc2.freqcur = freq;
1718             status = ALT_E_SUCCESS;
1719         }
1720         else
1721         {
1722             status = ALT_E_ARG_RANGE;
1723         }
1724     }
1725     else if (clk == ALT_CLK_F2H_PERIPH_REF)                         // clock from the FPGA
1726     {
1727         if ((freq >= alt_ext_clk_paramblok.periph.freqmin) && (freq <= alt_ext_clk_paramblok.periph.freqmax))
1728         {
1729             alt_ext_clk_paramblok.periph.freqcur = freq;
1730             status = ALT_E_SUCCESS;
1731         }
1732         else
1733         {
1734             status = ALT_E_ARG_RANGE;
1735         }
1736     }
1737     else if (clk == ALT_CLK_F2H_SDRAM_REF)                          // clock from the FPGA SDRAM
1738     {
1739         if ((freq >= alt_ext_clk_paramblok.sdram.freqmin) && (freq <= alt_ext_clk_paramblok.sdram.freqmax))
1740         {
1741             alt_ext_clk_paramblok.sdram.freqcur = freq;
1742             status = ALT_E_SUCCESS;
1743         }
1744         else
1745         {
1746             status = ALT_E_ARG_RANGE;
1747         }
1748     }
1749     else
1750     {
1751         status = ALT_E_BAD_ARG;
1752     }
1753 
1754     return status;
1755 }
1756 
1757 
1758 //
1759 // alt_clk_ext_clk_freq_get returns the frequency of the external clock source as
1760 // a measure of Hz. This value is stored in a static array.
1761 //
1762 alt_freq_t alt_clk_ext_clk_freq_get(ALT_CLK_t clk)
1763 {
1764     uint32_t ret = 0;
1765 
1766     if ((clk == ALT_CLK_IN_PIN_OSC1) || (clk == ALT_CLK_OSC1))      // two names for one input
1767     {
1768         ret = alt_ext_clk_paramblok.clkosc1.freqcur;
1769     }
1770     else if (clk == ALT_CLK_IN_PIN_OSC2)
1771     {
1772         ret = alt_ext_clk_paramblok.clkosc2.freqcur;
1773     }
1774     else if (clk == ALT_CLK_F2H_PERIPH_REF)                         // clock from the FPGA
1775     {
1776         ret = alt_ext_clk_paramblok.periph.freqcur;
1777     }
1778     else if (clk == ALT_CLK_F2H_SDRAM_REF)                         // clock from the FPGA
1779     {
1780         ret = alt_ext_clk_paramblok.sdram.freqcur;
1781     }
1782     return ret;
1783 }
1784 
1785 
1786 //
1787 // alt_clk_pll_cfg_get() returns the current PLL configuration.
1788 //
1789 ALT_STATUS_CODE alt_clk_pll_cfg_get(ALT_CLK_t pll, ALT_CLK_PLL_CFG_t * pll_cfg)
1790 {
1791     ALT_STATUS_CODE        ret = ALT_E_ERROR;                  // return value
1792     uint32_t               temp;                               // temp variable
1793  
1794     if (pll_cfg == NULL)
1795     {
1796         ret = ALT_E_BAD_ARG;
1797         return ret;
1798     }
1799 
1800     if (pll == ALT_CLK_MAIN_PLL)
1801     {
1802         temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
1803         pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
1804         pll_cfg->mult = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
1805         pll_cfg->div = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);
1806 
1807         // Get the C0-C5 divider values:
1808         pll_cfg->cntrs[0] = ALT_CLKMGR_MAINPLL_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR));
1809         // C0 - mpu_clk
1810 
1811         pll_cfg->cntrs[1] = ALT_CLKMGR_MAINPLL_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR));
1812         // C1 - main_clk
1813 
1814         pll_cfg->cntrs[2] = ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR));
1815         // C2 - dbg_base_clk
1816 
1817         pll_cfg->cntrs[3] = ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR));
1818         // C3 - main_qspi_clk
1819 
1820         pll_cfg->cntrs[4] = ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR));
1821         // C4 - main_nand_sdmmc_clk
1822 
1823         pll_cfg->cntrs[5] = ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR));
1824         // C5 - cfg_s2f_user0_clk aka cfg_h2f_user0_clk
1825 
1826         // The Main PLL C0-C5 outputs have no phase shift capabilities :
1827         pll_cfg->pshift[0] = pll_cfg->pshift[1] = pll_cfg->pshift[2] =
1828             pll_cfg->pshift[3] = pll_cfg->pshift[4] = pll_cfg->pshift[5] = 0;
1829         ret = ALT_E_SUCCESS;
1830     }
1831     else if (pll == ALT_CLK_PERIPHERAL_PLL)
1832     {
1833         temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
1834         if (temp <= 2)
1835         {
1836             if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
1837             {
1838                 pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
1839             }
1840             else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
1841             {
1842                 pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC2;
1843             }
1844             else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
1845             {
1846                 pll_cfg->ref_clk = ALT_CLK_F2H_PERIPH_REF;
1847             }
1848 
1849             temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
1850             pll_cfg->mult = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
1851             pll_cfg->div = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);
1852 
1853             // Get the C0-C5 divider values:
1854             pll_cfg->cntrs[0] = ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR));
1855             // C0 - emac0_clk
1856 
1857             pll_cfg->cntrs[1] = ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR));
1858             // C1 - emac1_clk
1859 
1860             pll_cfg->cntrs[2] = ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR));
1861             // C2 - periph_qspi_clk
1862 
1863             pll_cfg->cntrs[3] = ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR));
1864             // C3 - periph_nand_sdmmc_clk
1865 
1866             pll_cfg->cntrs[4] = ALT_CLKMGR_PERPLL_PERBASECLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR));
1867             // C4 - periph_base_clk
1868 
1869             pll_cfg->cntrs[5] = ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR));
1870             // C5 - s2f_user1_clk
1871 
1872             // The Peripheral PLL C0-C5 outputs have no phase shift capabilities :
1873             pll_cfg->pshift[0] = pll_cfg->pshift[1] = pll_cfg->pshift[2] =
1874                 pll_cfg->pshift[3] = pll_cfg->pshift[4] = pll_cfg->pshift[5] = 0;
1875             ret = ALT_E_SUCCESS;
1876         }
1877     }
1878     else if (pll == ALT_CLK_SDRAM_PLL)
1879     {
1880         temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
1881         if (temp <= 2)
1882         {
1883             if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
1884             {
1885                 pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
1886             }
1887             else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
1888             {
1889                 pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC2;
1890             }
1891             else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
1892             {
1893                 pll_cfg->ref_clk = ALT_CLK_F2H_SDRAM_REF;
1894             }
1895 
1896             pll_cfg->mult = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
1897             pll_cfg->div = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
1898 
1899             // Get the C0-C5 divider values:
1900             pll_cfg->cntrs[0]  = ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR));
1901             pll_cfg->pshift[0] = ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR));
1902             // C0  - ddr_dqs_clk
1903 
1904             pll_cfg->cntrs[1]  = ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR));
1905             pll_cfg->pshift[1] = ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR));
1906             // C1  - ddr_2x_dqs_clk
1907 
1908             pll_cfg->cntrs[2]  = ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR));
1909             pll_cfg->pshift[2] = ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR));
1910             // C2  - ddr_dq_clk
1911 
1912             pll_cfg->cntrs[3]  = pll_cfg->cntrs[4] = pll_cfg->pshift[3] = pll_cfg->pshift[4] = 0;
1913             // C3  & C4 outputs don't exist on the SDRAM PLL
1914 
1915             pll_cfg->cntrs[5]  = ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR));
1916             pll_cfg->pshift[5] = ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR));
1917             // C5  - s2f_user2_clk or h2f_user2_clk
1918 
1919             ret = ALT_E_SUCCESS;
1920         }
1921     }
1922 
1923     return ret;
1924 }
1925 
1926 
1927 //
1928 // alt_clk_pll_cfg_set() sets the PLL configuration using the configuration parameters
1929 // specified in pll_cfg.
1930 //
1931 ALT_STATUS_CODE alt_clk_pll_cfg_set(ALT_CLK_t pll, const ALT_CLK_PLL_CFG_t * pll_cfg)
1932 {
1933     if (pll_cfg == NULL)
1934     {
1935         return ALT_E_BAD_ARG;
1936     }
1937 
1938     if (alt_clk_pll_is_bypassed(pll) != ALT_E_TRUE)         // safe to write the PLL registers?
1939     {
1940         return ALT_E_ERROR;
1941     }
1942 
1943     ALT_STATUS_CODE ret = ALT_E_ERROR;
1944     uint32_t        temp;
1945 
1946     if (pll == ALT_CLK_MAIN_PLL)
1947     {
1948         temp  = (ALT_CLKMGR_MAINPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_MAINPLL_VCO_DENOM_CLR_MSK)
1949             & alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
1950         temp |= ALT_CLKMGR_MAINPLL_VCO_NUMER_SET(pll_cfg->mult) |
1951             ALT_CLKMGR_MAINPLL_VCO_DENOM_SET(pll_cfg->div);
1952 
1953         alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp);
1954         alt_write_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR,           pll_cfg->cntrs[0]);
1955         alt_write_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR,          pll_cfg->cntrs[1]);
1956         alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR,         pll_cfg->cntrs[2]);
1957         alt_write_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,      pll_cfg->cntrs[3]);
1958         alt_write_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, pll_cfg->cntrs[4]);
1959         alt_write_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,   pll_cfg->cntrs[5]);
1960         ret = ALT_E_SUCCESS;
1961     }
1962     else if (pll == ALT_CLK_PERIPHERAL_PLL)
1963     {
1964         temp =  ALT_CLKMGR_PERPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_PERPLL_VCO_DENOM_CLR_MSK
1965             & ALT_CLKMGR_PERPLL_VCO_PSRC_CLR_MSK;
1966         temp &= alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
1967         temp |= ALT_CLKMGR_PERPLL_VCO_NUMER_SET(pll_cfg->mult)
1968             | ALT_CLKMGR_PERPLL_VCO_DENOM_SET(pll_cfg->div);
1969 
1970         if ((pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC1) || (pll_cfg->ref_clk == ALT_CLK_OSC1))
1971         {
1972             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1);
1973         }
1974         else if (pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC2)
1975         {
1976             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2);
1977         }
1978         else if (pll_cfg->ref_clk == ALT_CLK_F2H_PERIPH_REF)
1979         {
1980             temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF);
1981         }
1982         else
1983         {
1984             return ret;
1985         }
1986 
1987         alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
1988         alt_write_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,        pll_cfg->cntrs[0]);
1989         alt_write_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,        pll_cfg->cntrs[1]);
1990         alt_write_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,      pll_cfg->cntrs[2]);
1991         alt_write_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, pll_cfg->cntrs[3]);
1992         alt_write_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,      pll_cfg->cntrs[4]);
1993         alt_write_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,     pll_cfg->cntrs[5]);
1994         ret = ALT_E_SUCCESS;
1995     }
1996     else if (pll == ALT_CLK_SDRAM_PLL)
1997     {
1998         // write the SDRAM PLL VCO Counter -----------------------------
1999         temp =  ALT_CLKMGR_SDRPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_SDRPLL_VCO_DENOM_CLR_MSK
2000             & ALT_CLKMGR_SDRPLL_VCO_SSRC_CLR_MSK;           // make a mask
2001         temp &= alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
2002         temp |= ALT_CLKMGR_SDRPLL_VCO_NUMER_SET(pll_cfg->mult)
2003             | ALT_CLKMGR_SDRPLL_VCO_DENOM_SET(pll_cfg->div)
2004             | ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK;
2005         // setting this bit aligns the output phase of the counters and prevents
2006         // glitches and too-short clock periods when restarting.
2007         // this bit is cleared at the end of this routine
2008 
2009         if ((pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC1) || (pll_cfg->ref_clk == ALT_CLK_OSC1))
2010         {
2011             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1);
2012         }
2013         else if (pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC2)
2014         {
2015             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2);
2016         }
2017         else if (pll_cfg->ref_clk == ALT_CLK_F2H_PERIPH_REF)
2018         {
2019             temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF);
2020         }
2021         else
2022         {
2023             return ret;
2024         }
2025 
2026         alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
2027 
2028         // write the SDRAM PLL C0 Divide Counter -----------------------------
2029         temp =  ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET(pll_cfg->cntrs[0])
2030             | ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_SET(pll_cfg->pshift[0]);
2031 
2032         alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
2033                                  ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR, temp,
2034                                  ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_SET_MSK,
2035                                  ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_LSB);
2036 
2037         // write the SDRAM PLL C1 Divide Counter -----------------------------
2038         if (ret == ALT_E_SUCCESS)
2039         {
2040             temp =  ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET(pll_cfg->cntrs[1])
2041                 | ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_SET(pll_cfg->pshift[1]);
2042             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
2043                                      ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR, temp,
2044                                      ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_SET_MSK,
2045                                      ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_LSB);
2046         }
2047 
2048         // write the SDRAM PLL C2 Divide Counter -----------------------------
2049         if (ret == ALT_E_SUCCESS)
2050         {
2051             temp =  ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET(pll_cfg->cntrs[2])
2052                 | ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_SET(pll_cfg->pshift[2]);
2053             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
2054                                      ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR, temp,
2055                                      ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_SET_MSK,
2056                                      ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_LSB);
2057         }
2058 
2059         // write the SDRAM PLL C5 Divide Counter -----------------------------
2060         if (ret == ALT_E_SUCCESS)
2061         {
2062             temp =  ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET(pll_cfg->cntrs[2])
2063                 | ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_SET(pll_cfg->pshift[2]);
2064             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
2065                                      ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR, temp,
2066                                      ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_SET_MSK,
2067                                      ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_LSB);
2068         }
2069 
2070         if (ret == ALT_E_SUCCESS)
2071         {
2072             alt_clrbits_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK);
2073             // allow the phase multiplexer and output counter to leave reset
2074         }
2075     }
2076 
2077     return ret;
2078 }
2079 
2080 
2081 //
2082 // alt_clk_pll_vco_cfg_get() returns the current PLL VCO frequency configuration.
2083 //
2084 ALT_STATUS_CODE alt_clk_pll_vco_cfg_get(ALT_CLK_t pll, uint32_t * mult, uint32_t * div)
2085 {
2086     ALT_STATUS_CODE status = ALT_E_SUCCESS;
2087     uint32_t        temp;
2088 
2089     if ( (mult == NULL) || (div == NULL) )
2090     {
2091         return ALT_E_BAD_ARG;
2092     }
2093 
2094     if (pll == ALT_CLK_MAIN_PLL)
2095     {
2096         temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
2097         *mult = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp) + 1;
2098         *div  = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp) + 1;
2099     }
2100     else if (pll == ALT_CLK_PERIPHERAL_PLL)
2101     {
2102         temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
2103         *mult = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp) + 1;
2104         *div  = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp) + 1;
2105     }
2106     else if (pll == ALT_CLK_SDRAM_PLL)
2107     {
2108         temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
2109         *mult = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp) + 1;
2110         *div  = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp) + 1;
2111     }
2112     else
2113     {
2114         status = ALT_E_ERROR;
2115     }
2116 
2117     return status;
2118 }
2119 
2120 
2121 /****************************************************************************************/
2122 /* This enum enumerates a set of possible change methods that are available for use by  */
2123 /* alt_clk_pll_vco_cfg_set() to change VCO parameter settings.                          */
2124 /****************************************************************************************/
2125 
2126 typedef enum ALT_CLK_PLL_VCO_CHG_METHOD_e
2127 {
2128     ALT_VCO_CHG_NONE_VALID      = 0,            /*  No valid method to  change PLL
2129                                                  *  VCO was found                       */
2130     ALT_VCO_CHG_NOCHANGE        = 0x00000001,   /*  Proposed new VCO values are the
2131                                                  *  same as the old values              */
2132     ALT_VCO_CHG_NUM             = 0x00000002,   /*  Can change the VCO multiplier
2133                                                  *  alone                               */
2134     ALT_VCO_CHG_NUM_BYP         = 0x00000004,   /*  A VCO multiplier-only change will
2135                                                  *  require putting the PLL in bypass   */
2136     ALT_VCO_CHG_DENOM           = 0x00000008,   /*  Can change the VCO divider
2137                                                  *  alone                               */
2138     ALT_VCO_CHG_DENOM_BYP       = 0x00000010,   /*  A VCO divider-only change will
2139                                                  *  require putting the PLL in bypass   */
2140     ALT_VCO_CHG_NUM_DENOM       = 0x00000020,   /*  Can change the clock multiplier
2141                                                  *  first. then the clock divider       */
2142     ALT_VCO_CHG_NUM_DENOM_BYP   = 0x00000040,   /*  Changing the clock multiplier first.
2143                                                  *  then the clock divider will
2144                                                  *  require putting the PLL in bypass   */
2145     ALT_VCO_CHG_DENOM_NUM       = 0x00000080,   /*  Can change the clock divider first.
2146                                                  *  then the clock multiplier           */
2147     ALT_VCO_CHG_DENOM_NUM_BYP   = 0x00000100    /*  Changing the clock divider first.
2148                                                  *  then the clock multiplier will
2149                                                  *  require putting the PLL in bypass   */
2150 } ALT_CLK_PLL_VCO_CHG_METHOD_t;
2151 
2152 
2153 
2154 /****************************************************************************************/
2155 /* alt_clk_pll_vco_chg_methods_get() determines which possible methods to change the    */
2156 /* VCO are allowed within the limits set by the maximum PLL multiplier and divider      */
2157 /* values and by the upper and lower frequency limits of the PLL, and also determines   */
2158 /* whether each of these changes can be made without the PLL losing lock, which         */
2159 /* requires the PLL to be bypassed before making changes, and removed from bypass state */
2160 /* afterwards.                                                                          */
2161 /****************************************************************************************/
2162 
2163 
2164 #define ALT_CLK_PLL_VCO_CHG_METHOD_TEST_MODE        false
2165     // used for testing writes to the PLL VCOs
2166 
2167 
2168 
2169 static ALT_CLK_PLL_VCO_CHG_METHOD_t alt_clk_pll_vco_chg_methods_get(ALT_CLK_t pll,
2170         uint32_t mult, uint32_t div )
2171 {
2172 #if ALT_CLK_PLL_VCO_CHG_METHOD_TEST_MODE
2173 
2174     // used for testing
2175     return ALT_VCO_CHG_NOCHANGE;
2176 
2177 #else
2178 
2179     // check PLL max value limits
2180     if (   (mult == 0) || (mult > ALT_CLK_PLL_MULT_MAX)
2181         || (div  == 0) || (div  > ALT_CLK_PLL_DIV_MAX)
2182        )
2183     {
2184         return ALT_VCO_CHG_NONE_VALID;
2185     }
2186 
2187     ALT_CLK_PLL_VCO_CHG_METHOD_t    ret = ALT_VCO_CHG_NONE_VALID;
2188     uint32_t                        temp;
2189     uint32_t                        numer;
2190     uint32_t                        denom;
2191     uint32_t                        freqmax;
2192     uint32_t                        freqmin;
2193     uint32_t                        inputfreq;
2194     uint32_t                        guardband;
2195     bool                            numerchg = false;
2196     bool                            denomchg = false;
2197     bool                            within_gb;
2198 
2199     // gather data values according to PLL
2200     if (pll == ALT_CLK_MAIN_PLL)
2201     {
2202         temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
2203 
2204         numer = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
2205         denom = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);
2206 
2207         freqmax   = alt_pll_clk_paramblok.MainPLL_800.freqmax;
2208         freqmin   = alt_pll_clk_paramblok.MainPLL_800.freqmin;
2209         guardband = alt_pll_clk_paramblok.MainPLL_800.guardband;
2210 
2211         inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
2212     }
2213 
2214     else if (pll == ALT_CLK_PERIPHERAL_PLL)
2215     {
2216         temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
2217 
2218         numer = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
2219         denom = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);
2220 
2221         freqmax   = alt_pll_clk_paramblok.PeriphPLL_800.freqmax;
2222         freqmin   = alt_pll_clk_paramblok.PeriphPLL_800.freqmin;
2223         guardband = alt_pll_clk_paramblok.PeriphPLL_800.guardband;
2224 
2225         temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(temp);
2226         if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
2227         {
2228             inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
2229         }
2230         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
2231         {
2232             inputfreq = alt_ext_clk_paramblok.clkosc2.freqcur;
2233         }
2234         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
2235         {
2236             inputfreq = alt_ext_clk_paramblok.periph.freqcur;
2237         }
2238         else
2239         {
2240             return ret;
2241         }
2242     }
2243 
2244     else if (pll == ALT_CLK_SDRAM_PLL)
2245     {
2246         temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
2247 
2248         numer = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp);
2249         denom = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp);
2250 
2251         freqmax   = alt_pll_clk_paramblok.SDRAMPLL_800.freqmax;
2252         freqmin   = alt_pll_clk_paramblok.SDRAMPLL_800.freqmin;
2253         guardband = alt_pll_clk_paramblok.SDRAMPLL_800.guardband;
2254 
2255         temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(temp);
2256         if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
2257         {
2258             inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
2259         }
2260         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
2261         {
2262             inputfreq = alt_ext_clk_paramblok.clkosc2.freqcur;
2263         }
2264         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
2265         {
2266             inputfreq = alt_ext_clk_paramblok.sdram.freqcur;
2267         }
2268         else
2269         {
2270             return ret;
2271         }
2272     }
2273     else
2274     {
2275         return ret;
2276     }
2277 
2278     temp = mult * (inputfreq / div);
2279     if ((temp <= freqmax) && (temp >= freqmin))     // are the final values within frequency limits?
2280     {
2281         numer++;
2282         denom++;
2283         numerchg = (mult != numer);
2284         denomchg = (div != denom);
2285 
2286         if (!numerchg && !denomchg)
2287         {
2288             ret = ALT_VCO_CHG_NOCHANGE;
2289         }
2290         else if (numerchg && !denomchg)
2291         {
2292             within_gb = alt_within_delta(numer, mult, guardband);
2293             // check if change is within the guardband limits
2294             temp = mult * (inputfreq / denom);
2295             if ((temp <= freqmax) && (temp >= freqmin))
2296             {
2297                 ret = ALT_VCO_CHG_NUM;
2298                 if (!within_gb) ret |= ALT_VCO_CHG_NUM_BYP;
2299             }
2300         }
2301         else if (!numerchg && denomchg)
2302         {
2303             within_gb = alt_within_delta(denom, div, guardband);
2304             temp = numer * (inputfreq / div);
2305             if ((temp <= freqmax) && (temp >= freqmin))
2306             {
2307                 ret = ALT_VCO_CHG_DENOM;
2308                 if (!within_gb)
2309                 {
2310                     ret |= ALT_VCO_CHG_DENOM_BYP;
2311                 }
2312             }
2313         }
2314         else    //numerchg && denomchg
2315         {
2316             within_gb = alt_within_delta(numer, mult, guardband);
2317             temp = mult * (inputfreq / denom);
2318             if ((temp <= freqmax) && (temp >= freqmin))
2319             {
2320                 ret = ALT_VCO_CHG_NUM_DENOM;
2321                 if (!within_gb)
2322                 {
2323                     ret |= ALT_VCO_CHG_NUM_DENOM_BYP;
2324                 }
2325             }
2326             within_gb = alt_within_delta(denom, div, guardband);
2327             temp = numer * (inputfreq / div);
2328             if ((temp <= freqmax) && (temp >= freqmin))
2329             {
2330                 ret = ALT_VCO_CHG_DENOM_NUM;
2331                 if (!within_gb)
2332                 {
2333                     ret |= ALT_VCO_CHG_DENOM_NUM_BYP;
2334                 }
2335             }
2336         }
2337     }
2338 
2339     return ret;
2340 #endif
2341 }
2342 
2343 
2344 /****************************************************************************************/
2345 /* alt_clk_pll_vco_cfg_set() sets the PLL VCO frequency configuration using the         */
2346 /* supplied multiplier and divider arguments. alt_clk_pll_vco_chg_methods_get()         */
2347 /* determines which methods are allowed by the limits set by the maximum multiplier     */
2348 /* and divider values and by the upper and lower frequency limits of the PLL, and also  */
2349 /* determines whether these changes can be made without requiring the PLL to be         */
2350 /* bypassed. alt_clk_pll_vco_cfg_set() then carries out the actions required to effect  */
2351 /* the method chosen to change the VCO settings.                                        */
2352 /****************************************************************************************/
2353 
2354 ALT_STATUS_CODE alt_clk_pll_vco_cfg_set(ALT_CLK_t pll, uint32_t mult, uint32_t div)
2355 {
2356     ALT_STATUS_CODE                 ret = ALT_E_ERROR;
2357     ALT_CLK_PLL_VCO_CHG_METHOD_t    method;
2358     bool                            byp = false;
2359     void                            *vaddr;
2360     uint32_t                        numermask, denommask;
2361     uint32_t                        numershift, denomshift;
2362 
2363 
2364     method = alt_clk_pll_vco_chg_methods_get(pll, mult, div);
2365 
2366     if (method == ALT_VCO_CHG_NONE_VALID)
2367     {
2368         ret = ALT_E_BAD_CLK;
2369     }
2370     else if (method == ALT_VCO_CHG_NOCHANGE)
2371     {
2372         ret = ALT_E_INV_OPTION;
2373     }
2374     else
2375     {
2376         if (pll == ALT_CLK_MAIN_PLL)
2377         {
2378             vaddr = ALT_CLKMGR_MAINPLL_VCO_ADDR;
2379             numermask = ALT_CLKMGR_MAINPLL_VCO_NUMER_SET_MSK;
2380             denommask = ALT_CLKMGR_MAINPLL_VCO_DENOM_SET_MSK;
2381             numershift = ALT_CLKMGR_MAINPLL_VCO_NUMER_LSB;
2382             denomshift = ALT_CLKMGR_MAINPLL_VCO_DENOM_LSB;
2383         }
2384         else if (pll == ALT_CLK_PERIPHERAL_PLL)
2385         {
2386             vaddr = ALT_CLKMGR_PERPLL_VCO_ADDR;
2387             numermask = ALT_CLKMGR_PERPLL_VCO_NUMER_SET_MSK;
2388             denommask = ALT_CLKMGR_PERPLL_VCO_DENOM_SET_MSK;
2389             numershift = ALT_CLKMGR_PERPLL_VCO_NUMER_LSB;
2390             denomshift = ALT_CLKMGR_PERPLL_VCO_DENOM_LSB;
2391         }
2392         else if (pll == ALT_CLK_SDRAM_PLL)
2393         {
2394             vaddr = ALT_CLKMGR_SDRPLL_VCO_ADDR;
2395             numermask = ALT_CLKMGR_SDRPLL_VCO_NUMER_SET_MSK;
2396             denommask = ALT_CLKMGR_SDRPLL_VCO_DENOM_SET_MSK;
2397             numershift = ALT_CLKMGR_SDRPLL_VCO_NUMER_LSB;
2398             denomshift = ALT_CLKMGR_SDRPLL_VCO_DENOM_LSB;
2399         }
2400         else { return ALT_E_BAD_ARG; }
2401 
2402         mult--;
2403         div--;
2404 
2405         if (method & ALT_VCO_CHG_NUM)
2406         {
2407             if (method & ALT_VCO_CHG_NUM_BYP)
2408             {
2409                 alt_clk_pll_bypass_enable(pll, 0);
2410                 byp = true;
2411                 alt_clk_mgr_wait(vaddr, ALT_SW_MANAGED_CLK_WAIT_BYPASS);
2412             }
2413             alt_replbits_word(vaddr, numermask, mult << numershift);
2414         }
2415 
2416         else if (method & ALT_VCO_CHG_DENOM)
2417         {
2418             if (method & ALT_VCO_CHG_DENOM_BYP)
2419             {
2420                 alt_clk_pll_bypass_enable(pll, 0);
2421                 byp = true;
2422             }
2423             alt_replbits_word(vaddr, denommask, div << denomshift);
2424         }
2425 
2426         else if (method & ALT_VCO_CHG_NUM_DENOM)
2427         {
2428             if (method & ALT_VCO_CHG_NUM_DENOM_BYP)
2429             {
2430                 alt_clk_pll_bypass_enable(pll, 0);
2431                 byp = true;
2432             }
2433             alt_replbits_word(vaddr, numermask, mult << numershift);
2434             if (!byp)       // if PLL is not bypassed
2435             {
2436                 ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
2437                       // verify PLL is still locked or wait for it to lock again
2438             }
2439             alt_replbits_word(vaddr, denommask, div << denomshift);
2440         }
2441 
2442         else if (method & ALT_VCO_CHG_DENOM_NUM)
2443         {
2444             if (method & ALT_VCO_CHG_DENOM_NUM_BYP)
2445             {
2446                 alt_clk_pll_bypass_enable(pll, 0);
2447                 byp = true;
2448             }
2449             alt_replbits_word(vaddr, numermask, mult << numershift);
2450             if (!byp)       // if PLL is not bypassed
2451             {
2452                 ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
2453                       // verify PLL is still locked or wait for it to lock again
2454             }
2455             alt_replbits_word(vaddr, denommask, div << denomshift);
2456         }
2457 
2458         ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
2459               // verify PLL is still locked or wait for it to lock again
2460         if (byp)
2461         {
2462             alt_clk_pll_bypass_disable(pll);
2463             alt_clk_mgr_wait(vaddr, ALT_SW_MANAGED_CLK_WAIT_BYPASS);
2464                 // wait for PLL to come out of bypass mode completely
2465         }
2466     }
2467     return ret;
2468 }
2469 
2470 
2471 //
2472 // alt_clk_pll_vco_freq_get() gets the VCO frequency of the specified PLL.
2473 // Note that since there is at present no known way for software to obtain the speed
2474 // bin of the SoC or MPU that it is running on, the function below only deals with the
2475 // 800 MHz part. This may need to be revised in the future.
2476 //
2477 ALT_STATUS_CODE alt_clk_pll_vco_freq_get(ALT_CLK_t pll, alt_freq_t * freq)
2478 {
2479     uint64_t            temp1 = 0;
2480     uint32_t            temp;
2481     uint32_t            numer;
2482     uint32_t            denom;
2483     ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;
2484 
2485     if (freq == NULL)
2486     {
2487         return ret;
2488     }
2489 
2490     if (pll == ALT_CLK_MAIN_PLL)
2491     {
2492         temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
2493         numer = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
2494         denom = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);
2495         temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
2496         temp1 *= (numer + 1);
2497         temp1 /= (denom + 1);
2498 
2499         if (temp1 <= UINT32_MAX)
2500         {
2501             temp = (alt_freq_t) temp1;
2502             alt_pll_clk_paramblok.MainPLL_800.freqcur = temp;
2503             // store this value in the parameter block table
2504          *freq = temp;
2505             // should NOT check value against PLL frequency limits
2506             ret = ALT_E_SUCCESS;
2507         }
2508         else
2509         {
2510             ret = ALT_E_ERROR;
2511         }
2512     }
2513     else if (pll == ALT_CLK_PERIPHERAL_PLL)
2514     {
2515         temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
2516         numer = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
2517         denom = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);
2518         temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(temp);
2519         if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
2520         {
2521             temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
2522         }
2523         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
2524         {
2525             temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc2.freqcur;
2526         }
2527         else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
2528         {
2529             temp1 = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
2530         }
2531 
2532         if (temp1 != 0)
2533         {
2534             temp1 *= (numer + 1);
2535             temp1 /= (denom + 1);
2536             if (temp1 <= UINT32_MAX)
2537             {
2538                 temp = (alt_freq_t) temp1;
2539                 alt_pll_clk_paramblok.PeriphPLL_800.freqcur = temp;
2540                 // store this value in the parameter block table
2541 
2542                 *freq = temp;
2543                 ret = ALT_E_SUCCESS;
2544             }
2545             else
2546             {
2547                 ret = ALT_E_ERROR;
2548             }
2549         }       // this returns ALT_BAD_ARG if the source isn't known
2550     }
2551     else if (pll == ALT_CLK_SDRAM_PLL)
2552     {
2553         temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
2554         numer = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp);
2555         denom = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp);
2556         temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(temp);
2557         if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
2558         {
2559             temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
2560         }
2561         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
2562         {
2563             temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc2.freqcur;
2564         }
2565         else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
2566         {
2567             temp1 = (uint64_t) alt_ext_clk_paramblok.sdram.freqcur;
2568         }
2569 
2570         if (temp1 != 0)
2571         {
2572             temp1 *= (numer + 1);
2573             temp1 /= (denom + 1);
2574             if (temp1 <= UINT32_MAX)
2575             {
2576                 temp = (alt_freq_t) temp1;
2577                 alt_pll_clk_paramblok.SDRAMPLL_800.freqcur = temp;
2578                 // store this value in the parameter block table
2579 
2580                 *freq = temp;
2581                 ret = ALT_E_SUCCESS;
2582             }
2583             else
2584             {
2585                 ret = ALT_E_ERROR;
2586             }
2587         }
2588     }       // which returns ALT_BAD_ARG if the source isn't known
2589 
2590     return ret;
2591 }
2592 
2593 //
2594 // Returns the current guard band range in effect for the PLL.
2595 //
2596 uint32_t alt_clk_pll_guard_band_get(ALT_CLK_t pll)
2597 {
2598     uint32_t ret = 0;
2599 
2600     if (pll == ALT_CLK_MAIN_PLL)
2601     {
2602         ret = alt_pll_clk_paramblok.MainPLL_800.guardband;
2603     }
2604     else if (pll == ALT_CLK_PERIPHERAL_PLL)
2605     {
2606         ret = alt_pll_clk_paramblok.PeriphPLL_800.guardband;
2607     }
2608     else if (pll == ALT_CLK_SDRAM_PLL)
2609     {
2610         ret = alt_pll_clk_paramblok.SDRAMPLL_800.guardband;
2611     }
2612     return ret;
2613 }
2614 
2615 //
2616 // clk_mgr_pll_guard_band_set() changes the guard band from its current value to permit
2617 // a more lenient or stringent policy to be in effect for the implementation of the
2618 // functions configuring PLL VCO frequency.
2619 //
2620 ALT_STATUS_CODE alt_clk_pll_guard_band_set(ALT_CLK_t pll, uint32_t guard_band)
2621 {
2622     if (   (guard_band > UINT12_MAX) || (guard_band <= 0)
2623         || (guard_band > ALT_GUARDBAND_LIMIT)
2624        )
2625     {
2626         return ALT_E_ARG_RANGE;
2627     }
2628 
2629     ALT_STATUS_CODE status = ALT_E_SUCCESS;
2630 
2631     if (pll == ALT_CLK_MAIN_PLL)
2632     {
2633         alt_pll_clk_paramblok.MainPLL_800.guardband = guard_band;
2634         //alt_pll_clk_paramblok.MainPLL_600.guardband = guard_band;
2635         // ??? Don't know how to check the MPU speed bin yet, so only 800 MHz struct is used
2636     }
2637     else if (pll == ALT_CLK_PERIPHERAL_PLL)
2638     {
2639         alt_pll_clk_paramblok.PeriphPLL_800.guardband = guard_band;
2640         //alt_pll_clk_paramblok.PeriphPLL_600.guardband = guard_band;
2641     }
2642     else if (pll == ALT_CLK_SDRAM_PLL)
2643     {
2644         alt_pll_clk_paramblok.SDRAMPLL_800.guardband = guard_band;
2645         //alt_pll_clk_paramblok.SDRAMPLL_600.guardband = guard_band;
2646     }
2647     else
2648     {
2649         status = ALT_E_ERROR;
2650     }
2651 
2652     return status;
2653 }
2654 
2655 //
2656 // alt_clk_divider_get() gets configured divider value for the specified clock.
2657 //
2658 ALT_STATUS_CODE alt_clk_divider_get(ALT_CLK_t clk, uint32_t * div)
2659 {
2660     ALT_STATUS_CODE status = ALT_E_SUCCESS;
2661     uint32_t        temp;
2662 
2663     if (div == NULL)
2664     {
2665         return ALT_E_BAD_ARG;
2666     }
2667 
2668     switch (clk)
2669     {
2670         // Main PLL outputs
2671     case ALT_CLK_MAIN_PLL_C0:
2672     case ALT_CLK_MPU:
2673         *div = (ALT_CLKMGR_MAINPLL_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR)) + 1) *
2674                (ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR)) + 1);
2675         break;
2676 
2677     case ALT_CLK_MAIN_PLL_C1:
2678     case ALT_CLK_L4_MAIN:
2679     case ALT_CLK_L3_MAIN:
2680         *div = (ALT_CLKMGR_MAINPLL_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR)) + 1) *
2681                (ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR)) + 1);
2682         break;
2683 
2684     case ALT_CLK_MAIN_PLL_C2:
2685     case ALT_CLK_DBG_BASE:
2686     case ALT_CLK_DBG_TIMER:
2687         *div = (ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR)) + 1) *
2688                (ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_DBGATCLK_ADDR)) + 1);
2689         break;
2690 
2691     case ALT_CLK_MAIN_PLL_C3:
2692     case ALT_CLK_MAIN_QSPI:
2693         *div = (ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR))) + 1;
2694         break;
2695 
2696     case ALT_CLK_MAIN_PLL_C4:
2697     case ALT_CLK_MAIN_NAND_SDMMC:
2698         *div = (ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR))) + 1;
2699         break;
2700 
2701     case ALT_CLK_MAIN_PLL_C5:
2702     case ALT_CLK_CFG:
2703     case ALT_CLK_H2F_USER0:
2704         *div = (ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR))) + 1;
2705         break;
2706 
2707         /////
2708 
2709         // Peripheral PLL outputs
2710     case ALT_CLK_PERIPHERAL_PLL_C0:
2711     case ALT_CLK_EMAC0:
2712         *div = (ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR))) + 1;
2713         break;
2714 
2715     case ALT_CLK_PERIPHERAL_PLL_C1:
2716     case ALT_CLK_EMAC1:
2717         *div = (ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR))) + 1;
2718         break;
2719 
2720     case ALT_CLK_PERIPHERAL_PLL_C2:
2721         *div = (ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR))) + 1;
2722         break;
2723 
2724     case ALT_CLK_PERIPHERAL_PLL_C3:
2725         *div = (ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR))) + 1;
2726         break;
2727 
2728     case ALT_CLK_PERIPHERAL_PLL_C4:
2729         *div = (ALT_CLKMGR_PERPLL_PERBASECLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR))) + 1;
2730         break;
2731 
2732     case ALT_CLK_PERIPHERAL_PLL_C5:
2733     case ALT_CLK_H2F_USER1:
2734         *div = (ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR))) + 1;
2735         break;
2736 
2737         /////
2738 
2739         // SDRAM PLL outputs
2740     case ALT_CLK_SDRAM_PLL_C0:
2741     case ALT_CLK_DDR_DQS:
2742         *div = (ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR))) + 1;
2743         break;
2744 
2745     case ALT_CLK_SDRAM_PLL_C1:
2746     case ALT_CLK_DDR_2X_DQS:
2747         *div = (ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR))) + 1;
2748         break;
2749 
2750     case ALT_CLK_SDRAM_PLL_C2:
2751     case ALT_CLK_DDR_DQ:
2752         *div = (ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR))) + 1;
2753         break;
2754 
2755     case ALT_CLK_SDRAM_PLL_C5:
2756     case ALT_CLK_H2F_USER2:
2757         *div = (ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR))) + 1;
2758         break;
2759 
2760         /////
2761 
2762         // Other clock dividers
2763     case ALT_CLK_L3_MP:
2764         temp = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
2765         if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV2)
2766         {
2767             *div = temp + 1;
2768         }
2769         else
2770         {
2771             status = ALT_E_ERROR;
2772         }
2773         break;
2774 
2775     case ALT_CLK_L3_SP:
2776         temp = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
2777         if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV2)
2778         {
2779             *div = temp + 1;
2780         }
2781         else
2782         {
2783             status = ALT_E_ERROR;
2784         }
2785         // note that this value does not include the additional effect
2786         // of the L3_MP divider that is upchain from this one
2787         break;
2788 
2789     case ALT_CLK_L4_MP:
2790         temp = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
2791         if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV16)
2792         {
2793             *div = 1 << temp;
2794         }
2795         else
2796         {
2797             status = ALT_E_ERROR;
2798         }
2799         break;
2800 
2801     case ALT_CLK_L4_SP:
2802         temp = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
2803         if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV16)
2804         {
2805             *div = 1 << temp;
2806         }
2807         else
2808         {
2809             status = ALT_E_ERROR;
2810         }
2811         break;
2812 
2813     case ALT_CLK_DBG_AT:
2814         temp = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR));
2815         if (temp <= ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV4)
2816         {
2817             *div = 1 << temp;
2818         }
2819         else
2820         {
2821             status = ALT_E_ERROR;
2822         }
2823         break;
2824 
2825     case ALT_CLK_DBG:
2826         temp = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR));
2827         if (temp <= ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV4)
2828         {
2829             *div =  1 << temp;
2830         }
2831         else
2832         {
2833             status = ALT_E_ERROR;
2834         }
2835         // note that this value does not include the value of the upstream dbg_at_clk divder
2836         break;
2837 
2838     case ALT_CLK_DBG_TRACE:
2839         temp = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR));
2840         if (temp <= ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV16)
2841         {
2842             *div =  1 << temp;
2843         }
2844         else
2845         {
2846             status = ALT_E_ERROR;
2847         }
2848         break;
2849 
2850     case ALT_CLK_USB_MP:
2851         temp = ALT_CLKMGR_PERPLL_DIV_USBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
2852         if (temp <= ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV16)
2853         {
2854             *div = 1 << temp;
2855         }
2856         else
2857         {
2858             status = ALT_E_ERROR;
2859         }
2860         break;
2861 
2862     case ALT_CLK_SPI_M:
2863         temp = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
2864         if (temp <= ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV16)
2865         {
2866             *div = 1 << temp;
2867         }
2868         else
2869         {
2870             status = ALT_E_ERROR;
2871         }
2872         break;
2873 
2874     case ALT_CLK_CAN0:
2875         temp = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
2876         if (temp <= ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV16)
2877         {
2878             *div = 1 << temp;
2879         }
2880         else
2881         {
2882             status = ALT_E_ERROR;
2883         }
2884         break;
2885 
2886     case ALT_CLK_CAN1:
2887         temp = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
2888         if (temp <= ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV16)
2889         {
2890             *div = 1 << temp;
2891         }
2892         else
2893         {
2894             status = ALT_E_ERROR;
2895         }
2896         break;
2897 
2898     case ALT_CLK_GPIO_DB:
2899         temp = ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR));
2900         *div = temp + 1;
2901         break;
2902 
2903     case ALT_CLK_MPU_PERIPH:
2904         *div = 4;                           // set by hardware
2905         break;
2906 
2907     case ALT_CLK_MPU_L2_RAM:
2908         *div = 2;                           // set by hardware
2909         break;
2910 
2911     case ALT_CLK_NAND:
2912         *div = 4;                           // set by hardware
2913         break;
2914 
2915     default:
2916         status = ALT_E_BAD_ARG;
2917         break;
2918     }
2919 
2920     return status;
2921 }
2922 
2923 /////
2924 
2925 #define ALT_CLK_WITHIN_FREQ_LIMITS_TEST_MODE        false
2926     // used for testing writes to the the full range of counters without
2927     // regard to the usual output frequency upper and lower limits
2928 
2929 
2930 static ALT_STATUS_CODE alt_clk_within_freq_limits(ALT_CLK_t clk, uint32_t div)
2931 {
2932 #if ALT_CLK_WITHIN_FREQ_LIMITS_TEST_MODE
2933     return ALT_E_TRUE;
2934 #else
2935 
2936     if (div == 0)
2937     {
2938         return ALT_E_BAD_ARG;
2939     }
2940 
2941     ALT_STATUS_CODE status = ALT_E_SUCCESS;
2942     uint32_t        numer = 0;
2943     uint32_t        hilimit;
2944     uint32_t        lolimit;
2945 
2946     switch (clk)
2947     {
2948         // Counters of the Main PLL
2949     case ALT_CLK_MAIN_PLL_C0:
2950         hilimit = alt_pll_cntr_maxfreq.MainPLL_C0;
2951         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
2952         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2953         break;
2954     case  ALT_CLK_MAIN_PLL_C1:
2955         hilimit = alt_pll_cntr_maxfreq.MainPLL_C1;
2956         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
2957         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2958         break;
2959     case ALT_CLK_MAIN_PLL_C2:
2960         hilimit = alt_pll_cntr_maxfreq.MainPLL_C2;
2961         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
2962         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2963         break;
2964     case ALT_CLK_MAIN_PLL_C3:
2965         hilimit = alt_pll_cntr_maxfreq.MainPLL_C3;
2966         lolimit = 0;
2967         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2968         break;
2969     case ALT_CLK_MAIN_PLL_C4:
2970         hilimit = alt_pll_cntr_maxfreq.MainPLL_C4;
2971         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
2972         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2973         break;
2974     case ALT_CLK_MAIN_PLL_C5:
2975         hilimit = alt_pll_cntr_maxfreq.MainPLL_C5;
2976         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
2977         status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
2978         break;
2979 
2980     // Counters of the Peripheral PLL
2981     case ALT_CLK_PERIPHERAL_PLL_C0:
2982         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C0;
2983         lolimit = 0;
2984         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
2985         break;
2986     case ALT_CLK_PERIPHERAL_PLL_C1:
2987         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C1;
2988         lolimit = 0;
2989         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
2990         break;
2991     case ALT_CLK_PERIPHERAL_PLL_C2:
2992         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C2;
2993         lolimit = 0;
2994         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
2995         break;
2996     case ALT_CLK_PERIPHERAL_PLL_C3:
2997         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C3;
2998         lolimit = 0;
2999         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
3000         break;
3001     case ALT_CLK_PERIPHERAL_PLL_C4:
3002         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C4;
3003         lolimit = 0;
3004         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
3005         break;
3006     case ALT_CLK_PERIPHERAL_PLL_C5:
3007         hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C5;
3008         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
3009         status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
3010         break;
3011 
3012     // Counters of the SDRAM PLL
3013     case ALT_CLK_SDRAM_PLL_C0:
3014         hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C0;
3015         lolimit = 0;
3016         status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
3017         break;
3018     case ALT_CLK_SDRAM_PLL_C1:
3019         hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C1;
3020         lolimit = 0;
3021         status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
3022         break;
3023     case ALT_CLK_SDRAM_PLL_C2:
3024         hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C2;
3025         lolimit = 0;
3026         status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
3027         break;
3028     case ALT_CLK_SDRAM_PLL_C5:
3029         hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C5;
3030         lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
3031         status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
3032         break;
3033 
3034     default:
3035         status = ALT_E_BAD_ARG;
3036         break;
3037     }
3038 
3039     if (status == ALT_E_SUCCESS)
3040     {
3041         numer = numer / div;
3042         if ((numer <= hilimit) && (numer >= lolimit))
3043         {
3044             status = ALT_E_TRUE;
3045         }
3046         else
3047         {
3048             status = ALT_E_FALSE;
3049         }
3050     }
3051 
3052     return status;
3053 #endif
3054 }
3055 
3056 static bool alt_clkmgr_is_val_modulo_n(uint32_t div, uint32_t mod)
3057 {
3058     if (mod == 1)
3059     {
3060         return true;
3061     }
3062     else if (mod == 2)
3063     {
3064         return (div & 0x1) == 0;
3065     }
3066     else if (mod == 4)
3067     {
3068         return (div & 0x3) == 0;
3069     }
3070     else
3071     {
3072         return (div % mod) == 0;
3073     }
3074 }
3075 
3076 //
3077 // alt_clk_divider_set() sets the divider value for the specified clock.
3078 //
3079 // See pages 38, 44, 45, and 46 of the HPS-Clocking NPP for a map of the
3080 // HPS clocking architecture and hierarchy of connections.
3081 //
3082 ALT_STATUS_CODE alt_clk_divider_set(ALT_CLK_t clk, uint32_t div)
3083 {
3084     ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;
3085     volatile uint32_t   temp, temp1;
3086     uint32_t            wrval = UINT32_MAX;              // value to be written
3087     bool                restore_0 = false;
3088     bool                restore_1 = false;
3089     bool                restore_2 = false;
3090 
3091     switch (clk)
3092     {
3093         // Main PLL outputs
3094     case ALT_CLK_MAIN_PLL_C0:
3095     case ALT_CLK_MPU:
3096         {
3097             uint32_t prediv = (ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR)) + 1);
3098 
3099             if (   (div <= ((ALT_CLKMGR_MAINPLL_MPUCLK_CNT_SET_MSK + 1) * prediv))
3100                 && alt_clkmgr_is_val_modulo_n(div, prediv)
3101                 && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C0, div) == ALT_E_TRUE) )
3102             {
3103                 wrval = (div / prediv) - 1;
3104 
3105                 // HW managed clock, change by writing to the external counter,  no need to gate clock
3106                 // or match phase or wait for transistion time. No other field in the register to mask off either.
3107                 alt_write_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR, wrval);
3108                 ret = ALT_E_SUCCESS;
3109             }
3110             else
3111             {
3112                 ret = ALT_E_ARG_RANGE;
3113             }
3114         }
3115         break;
3116 
3117     case ALT_CLK_MAIN_PLL_C1:
3118     case ALT_CLK_L3_MAIN:
3119         {
3120             uint32_t prediv = (ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR)) + 1);
3121 
3122             if (   (div <= ((ALT_CLKMGR_MAINPLL_MAINCLK_CNT_SET_MSK + 1) * prediv))
3123                 && alt_clkmgr_is_val_modulo_n(div, prediv)
3124                 && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C1, div) == ALT_E_TRUE) )
3125             {
3126                 // HW managed clock, change by writing to the external counter, no need to gate clock
3127                 // or match phase or wait for transistion time. No other field in the register to mask off either.
3128 
3129                 wrval = (div / prediv) - 1;
3130 
3131 #if ALT_PREVENT_GLITCH_CHGC1
3132                 // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
3133                 // bypass state, then gate clock back on. FogBugz #63778
3134                 temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
3135                 temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3136 
3137                 if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
3138                 {
3139                     restore_0 = true;
3140                 }
3141                 if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
3142                 {
3143                     restore_1 = true;
3144                 }
3145                 temp = temp1;
3146                 if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
3147                 if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
3148                 if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
3149 
3150                 alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR, wrval);
3151 
3152                 alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3153                 // wait a bit before reenabling the L4MP and L4SP clocks
3154                 if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }
3155 #else
3156                 alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR, wrval);
3157 #endif
3158                 ret = ALT_E_SUCCESS;
3159             }
3160             else
3161             {
3162                 ret = ALT_E_ARG_RANGE;
3163             }
3164         }
3165         break;
3166 
3167     case ALT_CLK_MAIN_PLL_C2:
3168     case ALT_CLK_DBG_BASE:
3169         {
3170             uint32_t prediv = (ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_DBGATCLK_ADDR)) + 1);
3171 
3172             if (   (div <= ((ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_SET_MSK + 1) * prediv))
3173                    && alt_clkmgr_is_val_modulo_n(div, prediv)
3174                 && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C2, div) == ALT_E_TRUE) )
3175             {
3176                 wrval = (div / prediv) - 1;
3177                 // HW managed clock, change by writing to the external counter,  no need to gate clock
3178                 // or match phase or wait for transistion time. No other field in the register to mask off either.
3179                 alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR, wrval);
3180 
3181                 ret = ALT_E_SUCCESS;
3182             }
3183             else
3184             {
3185                 ret = ALT_E_ARG_RANGE;
3186             }
3187         }
3188         break;
3189 
3190     case ALT_CLK_MAIN_PLL_C3:
3191         // The rest of the PLL outputs do not have external counters, but
3192         // their internal counters are programmable rather than fixed
3193         if (   (div <= (ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_SET_MSK + 1))
3194             && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C3, div) == ALT_E_TRUE) )
3195         {
3196             // if the main_qspi_clk input is selected for the qspi_clk
3197             if (ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR)) ==
3198                 ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
3199             {
3200                 restore_0 = (temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)) & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
3201                 if (restore_0)             // AND if the QSPI clock is currently enabled
3202                 {
3203                     alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_CLR_MSK);
3204                     // gate off the QSPI clock
3205                 }
3206 
3207                 wrval = div - 1;
3208                 // the rest are software-managed clocks and require a reset sequence to write to
3209                 alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
3210                                          ALT_CLKMGR_MAINPLL_STAT_ADDR,
3211                                          ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,
3212                                          wrval,
3213                                          ALT_CLK_PLL_RST_BIT_C3,
3214                                          ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);
3215 
3216                 alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3217                 if (restore_0)
3218                 {
3219                     alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3220                     // if the QSPI clock was gated on (enabled) before, return it to that state
3221                 }
3222                 ret = ALT_E_SUCCESS;
3223             }
3224         }
3225         else
3226         {
3227             ret = ALT_E_ARG_RANGE;
3228         }
3229         break;
3230 
3231     case ALT_CLK_MAIN_PLL_C4:
3232     case ALT_CLK_MAIN_NAND_SDMMC:
3233         if (   (div <= (ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_SET_MSK + 1))
3234             && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C4, div) == ALT_E_TRUE) )
3235         {
3236             temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
3237             temp1 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3238 
3239             // do we need to gate off the SDMMC clock ?
3240             if (ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(temp) == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
3241             {
3242                 if (temp1 & ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK) { restore_0 = true; }
3243             }
3244 
3245             // do we need to gate off the NAND clock and/or the NANDX clock?
3246             if (ALT_CLKMGR_PERPLL_SRC_NAND_GET(temp) == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
3247             {
3248                 if (temp1 & ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK) { restore_1 = true; }
3249                 if (temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK)  { restore_2 = true; }
3250             }
3251 
3252             temp = temp1;
3253             if (restore_1 && restore_2)
3254             {
3255                 temp &= ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK;
3256                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3257                 alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
3258                 // gate nand_clk off at least 8 MPU clock cycles before before nand_x_clk
3259             }
3260 
3261             if (restore_0 || restore_1)
3262             {
3263                 if (restore_0) { temp &= ALT_CLKMGR_PERPLL_EN_SDMMCCLK_CLR_MSK; }
3264                 if (restore_1) { temp &= ALT_CLKMGR_PERPLL_EN_NANDXCLK_CLR_MSK; }
3265                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3266                 // gate off sdmmc_clk and/or nand_x_clk
3267             }
3268 
3269             // now write the new divisor ratio
3270             wrval = div - 1;
3271             alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
3272                                      ALT_CLKMGR_MAINPLL_STAT_ADDR,
3273                                      ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR,
3274                                      wrval,
3275                                      ALT_CLK_PLL_RST_BIT_C4,
3276                                      ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);
3277             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3278 
3279             if (restore_0 || restore_1)
3280             {
3281                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK);
3282                 // if the NANDX and/or SDMMC clock was gated on (enabled) before, return it to that state
3283                 if (restore_1 && restore_2)
3284                 {
3285                     // wait at least 8 clock cycles to turn the nand_clk on
3286                     alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
3287                     alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
3288                 }
3289             }
3290             ret = ALT_E_SUCCESS;
3291         }
3292         else
3293         {
3294             ret = ALT_E_ARG_RANGE;
3295         }
3296         break;
3297 
3298     case ALT_CLK_MAIN_PLL_C5:
3299     case ALT_CLK_CFG:
3300     case ALT_CLK_H2F_USER0:
3301         if (   (div <= (ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_SET_MSK + 1))
3302             && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C5, div) == ALT_E_TRUE) )
3303         {
3304             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3305             restore_0 = ((temp & ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK) ||
3306                          (temp & ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK));
3307             if (restore_0)
3308             {
3309                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & (ALT_CLKMGR_MAINPLL_EN_CFGCLK_CLR_MSK &
3310                                                                    ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_CLR_MSK)); // clear both
3311             }
3312 
3313             // now write the new divisor ratio
3314             wrval = div - 1;
3315             alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
3316                                      ALT_CLKMGR_MAINPLL_STAT_ADDR,
3317                                      ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,
3318                                      wrval,
3319                                      ALT_CLK_PLL_RST_BIT_C5,
3320                                      ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);
3321 
3322             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3323 
3324             if (restore_0)
3325             {
3326                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3327             }
3328             ret = ALT_E_SUCCESS;
3329         }
3330         else
3331         {
3332             ret = ALT_E_ARG_RANGE;
3333         }
3334         break;
3335 
3336         /////
3337 
3338         // Peripheral PLL outputs
3339     case ALT_CLK_PERIPHERAL_PLL_C0:
3340     case ALT_CLK_EMAC0:
3341         if (   (div <= (ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_SET_MSK + 1))
3342             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C0, div) == ALT_E_TRUE) )
3343         {
3344             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3345             restore_0 = temp & ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK;
3346 
3347             if (restore_0)
3348             {
3349                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_EMAC0CLK_CLR_MSK);
3350             }
3351 
3352             // now write the new divisor ratio
3353             wrval = div - 1;
3354             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3355                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3356                                      ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,
3357                                      wrval,
3358                                      ALT_CLK_PLL_RST_BIT_C0,
3359                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3360 
3361             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3362             if (restore_0)
3363             {
3364                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3365             }
3366             ret = ALT_E_SUCCESS;
3367         }
3368         else
3369         {
3370             ret = ALT_E_ARG_RANGE;
3371         }
3372         break;
3373 
3374     case ALT_CLK_PERIPHERAL_PLL_C1:
3375     case ALT_CLK_EMAC1:
3376         if (   (div <= (ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_SET_MSK + 1))
3377             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C1, div) == ALT_E_TRUE) )
3378         {
3379             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3380             restore_0 = temp & ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK;
3381 
3382             if (restore_0)
3383             {
3384                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_EMAC1CLK_CLR_MSK);
3385             }
3386             // now write the new divisor ratio
3387             wrval = div - 1;
3388             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3389                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3390                                      ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,
3391                                      wrval,
3392                                      ALT_CLK_PLL_RST_BIT_C1,
3393                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3394 
3395             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3396             if (restore_0)
3397             {
3398                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3399             }
3400             ret = ALT_E_SUCCESS;
3401         }
3402         else
3403         {
3404             ret = ALT_E_ARG_RANGE;
3405         }
3406         break;
3407 
3408     case ALT_CLK_PERIPHERAL_PLL_C2:
3409         if (   (div <= (ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_SET_MSK + 1))
3410             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C2, div) == ALT_E_TRUE) )
3411         {
3412             temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
3413             if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
3414             {
3415                 // if qspi source is set to Peripheral PLL C2
3416                 temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3417                 // and if qspi_clk is enabled
3418                 restore_0 = temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
3419                 if (restore_0)
3420                 {
3421                     alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_CLR_MSK);
3422                     // gate it off
3423                 }
3424             }
3425 
3426             // now write the new divisor ratio
3427             wrval = div - 1;
3428             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3429                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3430                                      ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,
3431                                      wrval,
3432                                      ALT_CLK_PLL_RST_BIT_C2,
3433                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3434 
3435             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3436             if (restore_0)
3437             {
3438                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3439                 // if the clock was gated on (enabled) before, return it to that state
3440             }
3441             ret = ALT_E_SUCCESS;
3442         }
3443         else
3444         {
3445             ret = ALT_E_ARG_RANGE;
3446         }
3447         break;
3448 
3449     case ALT_CLK_PERIPHERAL_PLL_C3:
3450         if (   (div <= (ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_SET_MSK + 1))
3451             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C3, div) == ALT_E_TRUE) )
3452         {
3453             // first, are the clock MUX input selections currently set to use the clock we want to change?
3454             temp = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
3455             restore_0 = (ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(temp) == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK);
3456             restore_1 = restore_2 = (ALT_CLKMGR_PERPLL_SRC_NAND_GET(temp) == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK);
3457 
3458             // now AND those with the current state of the three gate enables
3459             // to get the clocks which must be gated off and then back on
3460             temp1 = temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3461             restore_0 = restore_0 && (temp & ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
3462             restore_1 = restore_1 && (temp & ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
3463             restore_2 = restore_2 && (temp & ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
3464 
3465             // gate off the clocks that depend on the clock divider that we want to change
3466             if (restore_2) { temp &= ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK; }
3467             if (restore_0) { temp &= ALT_CLKMGR_PERPLL_EN_SDMMCCLK_CLR_MSK; }
3468             alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3469 
3470             // the NAND clock must be gated off before the NANDX clock,
3471             if (restore_1)
3472             {
3473                 alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
3474                 temp &= ALT_CLKMGR_PERPLL_EN_NANDXCLK_CLR_MSK;
3475                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3476             }
3477 
3478             // now write the new divisor ratio
3479             wrval = div - 1;
3480             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3481                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3482                                      ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR,
3483                                      wrval,
3484                                      ALT_CLK_PLL_RST_BIT_C3,
3485                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3486 
3487             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
3488 
3489             // NAND clock and NAND_X clock cannot be written together, must be a set sequence with a delay
3490             alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK);
3491             if (restore_2)
3492             {
3493                 // the NANDX clock must be gated on before the NAND clock.
3494                 alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK );
3495                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
3496             }
3497             ret = ALT_E_SUCCESS;
3498         }
3499         else
3500         {
3501             ret = ALT_E_ARG_RANGE;
3502         }
3503         break;
3504 
3505     case ALT_CLK_PERIPHERAL_PLL_C4:
3506         if (   (div <= (ALT_CLKMGR_PERPLL_PERBASECLK_CNT_SET_MSK + 1))
3507             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C4, div) == ALT_E_TRUE) )
3508         {
3509             // look at the L4 set of clock gates first
3510             temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
3511             restore_0 = (ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(temp1) == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_PERIPHPLL);
3512             restore_1 = (ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(temp1) == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_PERIPHPLL);
3513             temp1 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3514             restore_0 = restore_0 && (temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
3515             restore_1 = restore_1 && (temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);
3516 
3517             // if the l4_sp and l4_mp clocks are not set to use the periph_base_clk
3518             // from the Peripheral PLL C4 clock divider output, or if they are
3519             // not currently gated on, don't change their gates
3520             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3521             if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
3522             if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
3523             alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3524 
3525             // now look at the C4 direct set of clock gates
3526             // first, create a mask of the C4 direct set of clock gate enables
3527             temp = (  ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK
3528                     | ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK
3529                     | ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK
3530                     | ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK
3531                     | ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK );
3532 
3533             // gate off all the C4 Direct set of clocks
3534             alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ~temp);
3535 
3536             // change the clock divider ratio - the reason we're here
3537             wrval = div - 1;
3538             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3539                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3540                                      ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,
3541                                      wrval,
3542                                      ALT_CLK_PLL_RST_BIT_C4,
3543                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3544 
3545             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
3546 
3547             // gate the affected clocks that were on before back on - both sets of gates
3548             temp = (restore_0) ? ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK : 0;
3549             if (restore_1) { temp |= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK; }
3550             alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3551             alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
3552             ret = ALT_E_SUCCESS;
3553         }
3554         else
3555         {
3556             ret = ALT_E_ARG_RANGE;
3557         }
3558         break;
3559 
3560     case ALT_CLK_PERIPHERAL_PLL_C5:
3561     case ALT_CLK_H2F_USER1:
3562         if (   (div <= (ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_SET_MSK + 1))
3563             && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C5, div) == ALT_E_TRUE) )
3564         {
3565             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3566             restore_0 = temp & ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK;
3567             if (restore_0)
3568             {
3569                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_CLR_MSK);
3570             }
3571 
3572             // now write the new divisor ratio
3573             wrval = div - 1;
3574             alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
3575                                      ALT_CLKMGR_PERPLL_STAT_ADDR,
3576                                      ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,
3577                                      wrval,
3578                                      ALT_CLK_PLL_RST_BIT_C5,
3579                                      ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
3580 
3581             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
3582             if (restore_0) { alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp); }
3583             ret = ALT_E_SUCCESS;
3584         }
3585         else
3586         {
3587             ret = ALT_E_ARG_RANGE;
3588         }
3589         break;
3590 
3591         /////
3592 
3593         // SDRAM PLL outputs
3594     case ALT_CLK_SDRAM_PLL_C0:
3595     case ALT_CLK_DDR_DQS:
3596         if (   (div <= (ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET_MSK + 1))
3597             && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C0, div) == ALT_E_TRUE) )
3598         {
3599             wrval = div - 1;
3600             temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
3601             if (temp & ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK)
3602             {
3603                 // if clock is currently on, gate it off
3604                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_CLR_MSK);
3605                 restore_0 = true;
3606             }
3607 
3608             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
3609                                      ALT_CLKMGR_SDRPLL_STAT_ADDR,
3610                                      ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR,
3611                                      wrval,
3612                                      ALT_CLK_PLL_RST_BIT_C0,
3613                                      ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_LSB);
3614             if (restore_0)
3615             {
3616                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
3617             }
3618             ret = ALT_E_SUCCESS;
3619         }
3620         else
3621         {
3622             ret = ALT_E_ARG_RANGE;
3623         }
3624         break;
3625 
3626     case ALT_CLK_SDRAM_PLL_C1:
3627     case ALT_CLK_DDR_2X_DQS:
3628         if (   (div <= (ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET_MSK + 1))
3629             && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C1, div) == ALT_E_TRUE) )
3630         {
3631             wrval = div - 1;
3632             temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
3633             if (temp & ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK)
3634             {
3635                 // if clock is currently on, gate it off
3636                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_CLR_MSK);
3637                 restore_0 = true;
3638             }
3639 
3640             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
3641                                      ALT_CLKMGR_SDRPLL_STAT_ADDR,
3642                                      ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR,
3643                                      wrval,
3644                                      ALT_CLK_PLL_RST_BIT_C1,
3645                                      ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
3646             if (restore_0)
3647             {
3648                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
3649             }
3650             ret = ALT_E_SUCCESS;
3651         }
3652         else
3653         {
3654             ret = ALT_E_ARG_RANGE;
3655         }
3656         break;
3657 
3658     case ALT_CLK_SDRAM_PLL_C2:
3659     case ALT_CLK_DDR_DQ:
3660         if (   (div <= (ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET_MSK + 1))
3661             && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C2, div) == ALT_E_TRUE) )
3662         {
3663             wrval = div - 1;
3664             temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
3665             if (temp & ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK)
3666             {
3667                 // if clock is currently on, gate it off
3668                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_CLR_MSK);
3669                 restore_0 = true;
3670             }
3671 
3672             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
3673                                      ALT_CLKMGR_SDRPLL_STAT_ADDR,
3674                                      ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR,
3675                                      wrval,
3676                                      ALT_CLK_PLL_RST_BIT_C2,
3677                                      ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
3678             if (restore_0)
3679             {
3680                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
3681             }
3682             ret = ALT_E_SUCCESS;
3683         }
3684         else
3685         {
3686             ret = ALT_E_ARG_RANGE;
3687         }
3688         break;
3689 
3690     case ALT_CLK_SDRAM_PLL_C5:
3691     case ALT_CLK_H2F_USER2:
3692         if (   (div <= (ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET_MSK + 1))
3693             && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C5, div) == ALT_E_TRUE) )
3694         {
3695             wrval = div - 1;
3696             temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
3697             if (temp & ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK)
3698             {
3699                 // if clock is currently on, gate it off
3700                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_CLR_MSK);
3701                 restore_0 = true;
3702             }
3703 
3704             alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
3705                                      ALT_CLKMGR_SDRPLL_STAT_ADDR,
3706                                      ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR,
3707                                      wrval,
3708                                      ALT_CLK_PLL_RST_BIT_C5,
3709                                      ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
3710             if (restore_0)
3711             {
3712                 alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
3713             }
3714             ret = ALT_E_SUCCESS;
3715         }
3716         else
3717         {
3718             ret = ALT_E_ARG_RANGE;
3719         }
3720         break;
3721 
3722         /////
3723 
3724         // Other clock dividers
3725     case ALT_CLK_L3_MP:
3726         if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV1; }
3727         else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV2; }
3728 
3729         if (wrval != UINT32_MAX)
3730         {
3731             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3732             if (temp & ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK)
3733             {
3734                 // if clock is currently on, gate it off
3735                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L3MPCLK_CLR_MSK);
3736                 restore_0 = true;
3737             }
3738             alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_SET_MSK,
3739                               wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_LSB);
3740             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
3741             if (restore_0)
3742             {
3743                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);         // which has the enable bit set
3744             }
3745             ret = ALT_E_SUCCESS;
3746         }
3747         else
3748         {
3749             ret = ALT_E_ARG_RANGE;
3750         }
3751         break;
3752 
3753     case ALT_CLK_L3_SP:
3754         // note that the L3MP divider is upstream from the L3SP divider
3755         // and any changes to the former will affect the output of both
3756         if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV1; }
3757         else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV2; }
3758 
3759         if (wrval != UINT32_MAX)
3760         {
3761             alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_SET_MSK,
3762                               wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_LSB);
3763             // no clock gate to close and reopen
3764             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
3765             ret = ALT_E_SUCCESS;
3766         }
3767         else
3768         {
3769             ret = ALT_E_ARG_RANGE;
3770         }
3771         break;
3772 
3773     case ALT_CLK_L4_MP:
3774         if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV1; }
3775         else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV2; }
3776         else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV4; }
3777         else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV8; }
3778         else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV16; }
3779 
3780         if (wrval != UINT32_MAX)
3781         {
3782             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3783             if (temp & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK)
3784             {
3785                 // if clock is currently on, gate it off
3786                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK);
3787                 restore_0 = true;
3788             }
3789             alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_SET_MSK,
3790                               wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_LSB);
3791             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3792             if (restore_0)
3793             {
3794                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);         // which has the enable bit set
3795             }
3796             ret = ALT_E_SUCCESS;
3797         }
3798         else
3799         {
3800             ret = ALT_E_ARG_RANGE;
3801         }
3802         break;
3803 
3804     case ALT_CLK_L4_SP:
3805         if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV1; }
3806         else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV2; }
3807         else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV4; }
3808         else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV8; }
3809         else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV16; }
3810 
3811         if (wrval != UINT32_MAX)
3812         {
3813             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3814             if (temp & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK)
3815             {
3816                 // if clock is currently on, gate it off
3817                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK);
3818                 restore_0 = true;
3819             }
3820             alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_SET_MSK,
3821                               wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_LSB);
3822             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3823             if (restore_0)
3824             {
3825                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3826             }
3827             ret = ALT_E_SUCCESS;
3828         }
3829         else
3830         {
3831             ret = ALT_E_ARG_RANGE;
3832         }
3833         break;
3834 
3835     case ALT_CLK_DBG_AT:
3836         if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV1; }
3837         else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV2; }
3838         else if (div == 4) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV4; }
3839 
3840         if (wrval != UINT32_MAX)
3841         {
3842             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3843             if (temp & ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK)
3844             {
3845                 // if clock is currently on, gate it off
3846                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGATCLK_CLR_MSK);
3847                 restore_0 = true;
3848             }
3849             alt_replbits_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_SET_MSK,
3850                               wrval << ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_LSB);
3851             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3852             if (restore_0)
3853             {
3854                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3855             }
3856             ret = ALT_E_SUCCESS;
3857         }
3858         else
3859         {
3860             ret = ALT_E_ARG_RANGE;
3861         }
3862         break;
3863 
3864     case ALT_CLK_DBG:
3865         if      (div == 2) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV2; }
3866         else if (div == 4) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV4; }
3867 
3868         if (wrval != UINT32_MAX)
3869         {
3870             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3871             if (temp & ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK)
3872             {
3873                 // if clock is currently on, gate it off
3874                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGCLK_CLR_MSK);
3875                 restore_0 = true;
3876             }
3877             alt_replbits_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_SET_MSK,
3878                               wrval << (ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_LSB - 1));
3879             // account for the fact that the divisor ratios are 2x the value
3880             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3881             if (restore_0)
3882             {
3883                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3884             }
3885             ret = ALT_E_SUCCESS;
3886         }
3887         else
3888         {
3889             ret = ALT_E_ARG_RANGE;
3890         }
3891         break;
3892 
3893     case ALT_CLK_DBG_TRACE:
3894         if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV1; }
3895         else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV2; }
3896         else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV4; }
3897         else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV8; }
3898         else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV16; }
3899 
3900         if (wrval != UINT32_MAX)
3901         {
3902             temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
3903             if (temp & ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK)
3904             {
3905                 // if clock is currently on, gate it off
3906                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_CLR_MSK);
3907                 restore_0 = true;
3908             }
3909             alt_replbits_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_SET_MSK,
3910                               wrval << ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_LSB);
3911             alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3912             if (restore_0)
3913             {
3914                 alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
3915             }
3916             ret = ALT_E_SUCCESS;
3917         }
3918         else
3919         {
3920             ret = ALT_E_ARG_RANGE;
3921         }
3922         break;
3923 
3924     case ALT_CLK_USB_MP:
3925         if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV1; }
3926         else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV2; }
3927         else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV4; }
3928         else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV8; }
3929         else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV16; }
3930 
3931         if (wrval != UINT32_MAX)
3932         {
3933             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3934             if (temp & ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK)
3935             {
3936                 // if clock is currently on, gate it off
3937                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_USBCLK_CLR_MSK);
3938                 restore_0 = true;
3939             }
3940             alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_USBCLK_SET_MSK,
3941                               wrval << ALT_CLKMGR_PERPLL_DIV_USBCLK_LSB);
3942             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3943             if (restore_0)
3944             {
3945                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3946             }
3947             ret = ALT_E_SUCCESS;
3948         }
3949         else
3950         {
3951             ret = ALT_E_ARG_RANGE;
3952         }
3953         break;
3954 
3955     case ALT_CLK_SPI_M:
3956         if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV1; }
3957         else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV2; }
3958         else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV4; }
3959         else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV8; }
3960         else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV16; }
3961 
3962         if (wrval != UINT32_MAX)
3963         {
3964             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3965             if (temp & ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK)
3966             {
3967                 // if clock is currently on, gate it off
3968                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_SPIMCLK_CLR_MSK);
3969                 restore_0 = true;
3970             }
3971             alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_SPIMCLK_SET_MSK,
3972                               wrval << ALT_CLKMGR_PERPLL_DIV_SPIMCLK_LSB);
3973             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
3974             if (restore_0)
3975             {
3976                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
3977             }
3978             ret = ALT_E_SUCCESS;
3979         }
3980         else
3981         {
3982             ret = ALT_E_ARG_RANGE;
3983         }
3984         break;
3985 
3986     case ALT_CLK_CAN0:
3987         if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV1; }
3988         else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV2; }
3989         else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV4; }
3990         else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV8; }
3991         else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV16; }
3992 
3993         if (wrval != UINT32_MAX)
3994         {
3995             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
3996             if (temp & ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK)
3997             {
3998                 // if clock is currently on, gate it off
3999                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_CAN0CLK_CLR_MSK);
4000                 restore_0 = true;
4001             }
4002             alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_CAN0CLK_SET_MSK,
4003                               wrval << ALT_CLKMGR_PERPLL_DIV_CAN0CLK_LSB);
4004             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
4005             if (restore_0)
4006             {
4007                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
4008             }
4009             ret = ALT_E_SUCCESS;
4010         }
4011         else
4012         {
4013             ret = ALT_E_ARG_RANGE;
4014         }
4015         break;
4016 
4017     case ALT_CLK_CAN1:
4018         if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV1; }
4019         else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV2; }
4020         else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV4; }
4021         else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV8; }
4022         else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV16; }
4023 
4024         if (wrval != UINT32_MAX)
4025         {
4026             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
4027             if (temp & ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK)
4028             {
4029                 // if clock is currently on, gate it off
4030                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_CAN1CLK_CLR_MSK);
4031                 restore_0 = true;
4032             }
4033             alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_CAN1CLK_SET_MSK,
4034                               wrval << ALT_CLKMGR_PERPLL_DIV_CAN1CLK_LSB);
4035             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
4036             if (restore_0)
4037             {
4038                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
4039             }
4040             ret = ALT_E_SUCCESS;
4041         }
4042         else
4043         {
4044             ret = ALT_E_ARG_RANGE;
4045         }
4046         break;
4047 
4048     case ALT_CLK_GPIO_DB:           // GPIO debounce clock
4049         if (div <= ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET_MSK)
4050         {
4051             temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
4052             if (temp & ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK)
4053             {
4054                 // if clock is currently on, gate it off
4055                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_GPIOCLK_CLR_MSK);
4056                 restore_0 = true;
4057             }
4058             wrval = div - 1;
4059             alt_replbits_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET_MSK,
4060                               wrval << ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_LSB);
4061             alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
4062             if (restore_0)
4063             {
4064                 alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
4065             }
4066             ret = ALT_E_SUCCESS;
4067         }
4068         else
4069         {
4070             ret = ALT_E_ARG_RANGE;
4071         }
4072         break;
4073 
4074     case ALT_CLK_MAIN_QSPI:
4075         temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
4076         // get the QSPI clock source
4077         restore_0 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR) & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
4078         // and the current enable state
4079         wrval = div - 1;
4080 
4081         if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
4082         {           // if the main_qspi_clk (Main PLL C3 Ouput) input is selected
4083             if (div <= ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_SET_MSK)
4084             {
4085                 if (restore_0)
4086                 {
4087                     alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
4088                 }                // gate off the QSPI clock
4089 
4090                 alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
4091                                          ALT_CLKMGR_MAINPLL_STAT_ADDR,
4092                                          ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,
4093                                          wrval,
4094                                          ALT_CLK_PLL_RST_BIT_C3,
4095                                          ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);
4096 
4097                 alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
4098                 if (restore_0)
4099                 {
4100                     alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
4101                     // if the QSPI clock was gated on (enabled) before, return it to that state
4102                 }
4103                 ret = ALT_E_SUCCESS;
4104             }
4105             else
4106             {
4107                 ret = ALT_E_ARG_RANGE;
4108             }
4109         }
4110         else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
4111         {
4112             if (div <= ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_SET_MSK)
4113             {
4114                 if (restore_0)
4115                 {
4116                     alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
4117                 }                // gate off the QSPI clock
4118 
4119                 alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
4120                                          ALT_CLKMGR_PERPLL_STAT_ADDR,
4121                                          ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,
4122                                          wrval,
4123                                          ALT_CLK_PLL_RST_BIT_C2,
4124                                          ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);
4125 
4126                 alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
4127                 if (restore_0)
4128                 {
4129                     alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
4130                     // if the QSPI clock was gated on (enabled) before, return it to that state
4131                 }
4132                 ret = ALT_E_SUCCESS;
4133             }
4134             else
4135             {
4136                 ret = ALT_E_ARG_RANGE;
4137             }
4138         }
4139         break;
4140 
4141         /////
4142 
4143     default:
4144         ret = ALT_E_BAD_ARG;
4145         break;
4146     }
4147 
4148     return ret;
4149 }
4150 
4151 //
4152 // alt_clk_freq_get() returns the output frequency of the specified clock.
4153 //
4154 ALT_STATUS_CODE alt_clk_freq_get(ALT_CLK_t clk, alt_freq_t* freq)
4155 {
4156     ALT_STATUS_CODE ret = ALT_E_BAD_ARG;
4157     uint32_t        temp = 0;
4158     uint64_t        numer = 0;
4159     uint64_t        denom = 1;
4160 
4161     if (freq == NULL)
4162     {
4163         return ret;
4164     }
4165 
4166     switch (clk)
4167     {
4168         // External Inputs
4169     case ALT_CLK_IN_PIN_OSC1:
4170     case ALT_CLK_OSC1:
4171         numer = alt_ext_clk_paramblok.clkosc1.freqcur;
4172         // denom = 1 by default
4173         ret = ALT_E_SUCCESS;
4174         break;
4175 
4176     case ALT_CLK_IN_PIN_OSC2:
4177         numer = alt_ext_clk_paramblok.clkosc2.freqcur;
4178         // denom = 1 by default
4179         ret = ALT_E_SUCCESS;
4180         break;
4181 
4182     case ALT_CLK_F2H_PERIPH_REF:
4183         numer = alt_ext_clk_paramblok.periph.freqcur;
4184         // denom = 1 by default
4185         ret = ALT_E_SUCCESS;
4186         break;
4187 
4188     case ALT_CLK_F2H_SDRAM_REF:
4189         numer = alt_ext_clk_paramblok.sdram.freqcur;
4190         // denom = 1 by default
4191         ret = ALT_E_SUCCESS;
4192         break;
4193 
4194         /////
4195 
4196         // PLLs
4197     case ALT_CLK_MAIN_PLL:
4198         if (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE)
4199         {
4200             temp = alt_ext_clk_paramblok.clkosc1.freqcur;
4201             ret = ALT_E_SUCCESS;
4202         }
4203         else
4204         {
4205             ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4206         }
4207         numer = (uint64_t) temp;
4208         // denom = 1 by default
4209         break;
4210 
4211     case ALT_CLK_PERIPHERAL_PLL:
4212         if (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE)
4213         {
4214             temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
4215             if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
4216             {
4217                 temp = alt_ext_clk_paramblok.clkosc1.freqcur;
4218                 ret = ALT_E_SUCCESS;
4219             }
4220             else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
4221             {
4222                 temp = alt_ext_clk_paramblok.clkosc2.freqcur;
4223                 ret = ALT_E_SUCCESS;
4224             }
4225             else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
4226             {
4227                 temp = alt_ext_clk_paramblok.periph.freqcur;
4228                 ret = ALT_E_SUCCESS;
4229             }
4230             else
4231             {
4232                 ret = ALT_E_ERROR;
4233             }
4234         }
4235         else
4236         {
4237             ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4238         }
4239         numer = (uint64_t) temp;
4240         // denom = 1 by default
4241         break;
4242 
4243     case ALT_CLK_SDRAM_PLL:
4244         if (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE)
4245         {
4246             temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
4247             if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
4248             {
4249                 temp = alt_ext_clk_paramblok.clkosc1.freqcur;
4250                 ret = ALT_E_SUCCESS;
4251             }
4252             else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
4253             {
4254                 temp = alt_ext_clk_paramblok.clkosc2.freqcur;
4255                 ret = ALT_E_SUCCESS;
4256             }
4257             else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
4258             {
4259                 temp = alt_ext_clk_paramblok.sdram.freqcur;
4260                 ret = ALT_E_SUCCESS;
4261             }
4262             else
4263             {
4264                 ret = ALT_E_ERROR;
4265             }
4266         }
4267         else
4268         {
4269             ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
4270         }
4271         numer = (uint64_t) temp;
4272         // denom = 1 by default
4273         break;
4274 
4275         /////
4276 
4277         // Main Clock Group
4278     case ALT_CLK_MAIN_PLL_C0:
4279     case ALT_CLK_MAIN_PLL_C1:
4280     case ALT_CLK_MAIN_PLL_C2:
4281     case ALT_CLK_MAIN_PLL_C3:
4282     case ALT_CLK_MAIN_PLL_C4:
4283     case ALT_CLK_MAIN_PLL_C5:
4284         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4285         if (ret == ALT_E_SUCCESS)
4286         {
4287             numer = (uint64_t) temp;
4288             ret = alt_clk_divider_get(clk, &temp);
4289             denom = (uint64_t) temp;
4290         }
4291         break;
4292 
4293     case ALT_CLK_MPU:
4294         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4295         if (ret == ALT_E_SUCCESS)
4296         {
4297             numer = (uint64_t) temp;
4298             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
4299             denom = (uint64_t) temp;
4300         }
4301         break;
4302 
4303     case ALT_CLK_MPU_PERIPH:
4304         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4305         if (ret == ALT_E_SUCCESS)
4306         {
4307             numer = (uint64_t) temp;
4308             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
4309         }
4310         if (ret == ALT_E_SUCCESS)
4311         {
4312             denom = (uint64_t) temp;
4313             ret = alt_clk_divider_get(ALT_CLK_MPU_PERIPH, &temp);
4314             denom = denom * (uint64_t) temp;
4315         }
4316         break;
4317 
4318     case ALT_CLK_MPU_L2_RAM:
4319         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4320         if (ret == ALT_E_SUCCESS)
4321         {
4322             numer = (uint64_t) temp;
4323             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
4324         }
4325         if (ret == ALT_E_SUCCESS)
4326         {
4327             denom = (uint64_t) temp;
4328             ret = alt_clk_divider_get(ALT_CLK_MPU_L2_RAM, &temp);
4329             denom = denom * (uint64_t) temp;
4330         }
4331         break;
4332 
4333     case ALT_CLK_L4_MAIN:
4334     case ALT_CLK_L3_MAIN:
4335         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4336         if (ret == ALT_E_SUCCESS)
4337         {
4338             numer = (uint64_t) temp;
4339             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
4340             denom = (uint64_t) temp;
4341         }
4342         break;
4343 
4344     case ALT_CLK_L3_MP:
4345         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4346         if (ret == ALT_E_SUCCESS)
4347         {
4348             numer = (uint64_t) temp;
4349             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
4350         }
4351         if (ret == ALT_E_SUCCESS)
4352         {
4353             denom = (uint64_t) temp;
4354             ret = alt_clk_divider_get(ALT_CLK_L3_MP, &temp);
4355             denom = denom * (uint64_t) temp;
4356         }
4357         break;
4358 
4359     case ALT_CLK_L3_SP:
4360         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4361         if (ret == ALT_E_SUCCESS)
4362         {
4363             numer = (uint64_t) temp;
4364             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
4365         }
4366         if (ret == ALT_E_SUCCESS)
4367         {
4368             denom = (uint64_t) temp;
4369             ret = alt_clk_divider_get(ALT_CLK_L3_MP, &temp);
4370         }
4371         if (ret == ALT_E_SUCCESS)
4372         {
4373             denom = denom * (uint64_t) temp;
4374             ret = alt_clk_divider_get(ALT_CLK_L3_SP, &temp);
4375             denom = denom * (uint64_t) temp;
4376         }
4377         break;
4378 
4379     case ALT_CLK_L4_MP:
4380         ret = alt_clk_divider_get(ALT_CLK_L4_MP, &temp);
4381         if (ret == ALT_E_SUCCESS)
4382         {
4383             denom = (uint64_t) temp;
4384             temp = ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR));
4385             if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_MAINPLL)
4386             {
4387                 ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4388                 if (ret == ALT_E_SUCCESS)
4389                 {
4390                     numer = (uint64_t) temp;
4391                     ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
4392                     denom = denom * (uint64_t) temp;        // no real harm if temp is garbage data
4393                 }
4394             }
4395             else if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_PERIPHPLL)
4396             {
4397                 ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4398                 if (ret == ALT_E_SUCCESS)
4399                 {
4400                     numer = (uint64_t) temp;
4401                     ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4402                     denom = denom * (uint64_t) temp;
4403                 }
4404             }
4405         }
4406         break;
4407 
4408     case ALT_CLK_L4_SP:
4409         ret = alt_clk_divider_get(ALT_CLK_L4_SP, &temp);
4410         if (ret == ALT_E_SUCCESS)
4411         {
4412             denom = (uint64_t) temp;
4413             temp = ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR));
4414             if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_MAINPLL)
4415             {
4416                 ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4417                 if (ret == ALT_E_SUCCESS)
4418                 {
4419                     numer = (uint64_t) temp;
4420                     ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
4421                     denom = denom * (uint64_t) temp;
4422                 }
4423             }
4424             else if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_PERIPHPLL)         // periph_base_clk
4425             {
4426                 ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4427                 if (ret == ALT_E_SUCCESS)
4428                 {
4429                     numer = (uint64_t) temp;
4430                     ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4431                     denom = denom * (uint64_t) temp;
4432                 }
4433             }
4434         }
4435         break;
4436 
4437     case ALT_CLK_DBG_BASE:
4438     case ALT_CLK_DBG_TIMER:
4439         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4440         if (ret == ALT_E_SUCCESS)
4441         {
4442             numer = (uint64_t) temp;
4443             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
4444             denom = (uint64_t) temp;
4445         }
4446         break;
4447 
4448     case ALT_CLK_DBG_AT:
4449         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4450         if (ret == ALT_E_SUCCESS)
4451         {
4452             numer = (uint64_t) temp;
4453             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
4454         }
4455         if (ret == ALT_E_SUCCESS)
4456         {
4457             denom = (uint64_t) temp;
4458             ret = alt_clk_divider_get(ALT_CLK_DBG_AT, &temp);
4459             denom = denom * (uint64_t) temp;
4460         }
4461         break;
4462 
4463     case ALT_CLK_DBG:
4464         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4465         if (ret == ALT_E_SUCCESS)
4466         {
4467             numer = (uint64_t) temp;
4468             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
4469         }
4470         if (ret == ALT_E_SUCCESS)
4471         {
4472             denom = (uint64_t) temp;
4473             ret = alt_clk_divider_get(ALT_CLK_DBG_AT, &temp);
4474         }
4475         if (ret == ALT_E_SUCCESS)
4476         {
4477             denom = denom * (uint64_t) temp;
4478             ret = alt_clk_divider_get(ALT_CLK_DBG, &temp);
4479             denom = denom * (uint64_t) temp;
4480         }
4481         break;
4482 
4483     case ALT_CLK_DBG_TRACE:
4484         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4485         if (ret == ALT_E_SUCCESS)
4486         {
4487             numer = (uint64_t) temp;
4488             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
4489         }
4490         if (ret == ALT_E_SUCCESS)
4491         {
4492             denom = (uint64_t) temp;
4493             ret = alt_clk_divider_get(ALT_CLK_DBG_TRACE, &temp);
4494             denom = denom * (uint64_t) temp;
4495         }
4496         break;
4497 
4498     case ALT_CLK_MAIN_QSPI:
4499         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4500         if (ret == ALT_E_SUCCESS)
4501         {
4502             numer = (uint64_t) temp;
4503             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C3, &temp);
4504             denom = (uint64_t) temp;
4505         }
4506         break;
4507 
4508     case ALT_CLK_MAIN_NAND_SDMMC:
4509         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4510         if (ret == ALT_E_SUCCESS)
4511         {
4512             numer = (uint64_t) temp;
4513             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
4514             denom = (uint64_t) temp;
4515         }
4516         break;
4517 
4518     case ALT_CLK_CFG:
4519     case ALT_CLK_H2F_USER0:
4520         ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4521         if (ret == ALT_E_SUCCESS)
4522         {
4523             numer = (uint64_t) temp;
4524             ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C5, &temp);
4525             denom = (uint64_t) temp;
4526         }
4527         break;
4528 
4529         /////
4530 
4531         // Peripheral Clock Group
4532     case ALT_CLK_PERIPHERAL_PLL_C0:
4533     case ALT_CLK_PERIPHERAL_PLL_C1:
4534     case ALT_CLK_PERIPHERAL_PLL_C2:
4535     case ALT_CLK_PERIPHERAL_PLL_C3:
4536     case ALT_CLK_PERIPHERAL_PLL_C4:
4537     case ALT_CLK_PERIPHERAL_PLL_C5:
4538         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4539         if (ret == ALT_E_SUCCESS)
4540         {
4541             numer = (uint64_t) temp;
4542             ret = alt_clk_divider_get(clk, &temp);
4543             denom = (uint64_t) temp;
4544         }
4545         break;
4546 
4547     case ALT_CLK_EMAC0:
4548         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4549         if (ret == ALT_E_SUCCESS)
4550         {
4551             numer = (uint64_t) temp;
4552             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C0, &temp);
4553             denom = (uint64_t) temp;
4554         }
4555         break;
4556 
4557     case ALT_CLK_EMAC1:
4558         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4559         if (ret == ALT_E_SUCCESS)
4560         {
4561             numer = (uint64_t) temp;
4562             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C1, &temp);
4563             denom = (uint64_t) temp;
4564         }
4565         break;
4566 
4567     case ALT_CLK_USB_MP:
4568         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4569         if (ret == ALT_E_SUCCESS)
4570         {
4571             numer = (uint64_t) temp;
4572             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4573             if (ret == ALT_E_SUCCESS)
4574             {
4575                 denom = (uint64_t) temp;
4576                 ret = alt_clk_divider_get(ALT_CLK_USB_MP, &temp);
4577                 denom = denom * (uint64_t) temp;
4578             }
4579         }
4580         break;
4581 
4582     case ALT_CLK_SPI_M:
4583         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4584         if (ret == ALT_E_SUCCESS)
4585         {
4586             numer = (uint64_t) temp;
4587             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4588         }
4589         if (ret == ALT_E_SUCCESS)
4590         {
4591             denom = (uint64_t) temp;
4592             ret = alt_clk_divider_get(ALT_CLK_SPI_M, &temp);
4593             denom = denom * (uint64_t) temp;
4594         }
4595         break;
4596 
4597     case ALT_CLK_CAN0:
4598         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4599         if (ret == ALT_E_SUCCESS)
4600         {
4601             numer = (uint64_t) temp;
4602             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4603         }
4604         if (ret == ALT_E_SUCCESS)
4605         {
4606             denom = (uint64_t) temp;
4607             ret = alt_clk_divider_get(ALT_CLK_CAN0, &temp);
4608             denom = denom * (uint64_t) temp;
4609         }
4610         break;
4611 
4612     case ALT_CLK_CAN1:
4613         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4614         if (ret == ALT_E_SUCCESS)
4615         {
4616             numer = (uint64_t) temp;
4617             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4618         }
4619         if (ret == ALT_E_SUCCESS)
4620         {
4621             denom = (uint64_t) temp;
4622             ret = alt_clk_divider_get(ALT_CLK_CAN1, &temp);
4623             denom = denom * (uint64_t) temp;
4624         }
4625         break;
4626 
4627     case ALT_CLK_GPIO_DB:
4628         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4629         if (ret == ALT_E_SUCCESS)
4630         {
4631             numer = (uint64_t) temp;
4632             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
4633         }
4634         if (ret == ALT_E_SUCCESS)
4635         {
4636             denom = (uint64_t) temp;
4637             ret = alt_clk_divider_get(ALT_CLK_GPIO_DB, &temp);
4638             denom = denom * (uint64_t) temp;
4639         }
4640         break;
4641 
4642     case ALT_CLK_H2F_USER1:
4643         ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4644         if (ret == ALT_E_SUCCESS)
4645         {
4646             numer = (uint64_t) temp;
4647             ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C5, &temp);
4648             denom = (uint64_t) temp;
4649         }
4650         break;
4651 
4652         /* Clocks That Can Switch Between Different Clock Groups */
4653     case ALT_CLK_SDMMC:
4654         temp = ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
4655         if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK)
4656         {
4657             numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
4658             // denom = 1 by default
4659             ret = ALT_E_SUCCESS;
4660         }
4661         else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
4662         {
4663             ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4664             if (ret == ALT_E_SUCCESS)
4665             {
4666                 numer = (uint64_t) temp;
4667                 ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
4668                 denom = (uint64_t) temp;
4669             }
4670         }
4671         else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK)
4672         {
4673             ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4674             if (ret == ALT_E_SUCCESS)
4675             {
4676                 numer = (uint64_t) temp;
4677                 ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C3, &temp);
4678                 denom = (uint64_t) temp;
4679             }
4680         }
4681         else
4682         {
4683             ret = ALT_E_ERROR;
4684         }
4685         break;
4686 
4687     case ALT_CLK_NAND:
4688         denom = 4;
4689         // the absence of a break statement here is not a mistake
4690     case ALT_CLK_NAND_X:
4691         temp = ALT_CLKMGR_PERPLL_SRC_NAND_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
4692         if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK)
4693         {
4694             numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
4695             // denom = 1 or 4 by default;
4696             ret = ALT_E_SUCCESS;
4697         }
4698         else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
4699         {
4700             ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4701             if (ret == ALT_E_SUCCESS)
4702             {
4703                 numer = (uint64_t) temp;
4704                 ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
4705                 denom = denom * (uint64_t) temp;
4706             }
4707         }
4708         else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK)
4709         {
4710             ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4711             if (ret == ALT_E_SUCCESS)
4712             {
4713                 numer = (uint64_t) temp;
4714                 ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C3, &temp);
4715                 denom = denom * (uint64_t) temp;
4716             }
4717         }
4718         else
4719         {
4720             ret = ALT_E_ERROR;
4721         }
4722         break;
4723 
4724     case ALT_CLK_QSPI:
4725         temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
4726         if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK)
4727         {
4728             numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
4729             // denom = 1 by default;
4730             ret = ALT_E_SUCCESS;
4731         }
4732         else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
4733         {
4734             ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
4735             if (ret == ALT_E_SUCCESS)
4736             {
4737                 numer = (uint64_t) temp;
4738                 ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C3, &temp);
4739                 denom = (uint64_t) temp;
4740             }
4741         }
4742         else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
4743         {
4744             ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
4745             if (ret == ALT_E_SUCCESS)
4746             {
4747                 numer = (uint64_t) temp;
4748                 ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C2, &temp);
4749                 denom = (uint64_t) temp;
4750             }
4751         }
4752         else
4753         {
4754             ret = ALT_E_ERROR;
4755         }
4756         break;
4757 
4758         /////
4759 
4760         // SDRAM Clock Group
4761     case ALT_CLK_SDRAM_PLL_C0:
4762     case ALT_CLK_DDR_DQS:
4763         ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
4764         if (ret == ALT_E_SUCCESS)
4765         {
4766             numer = (uint64_t) temp;
4767             ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C0, &temp);
4768             denom = (uint64_t) temp;
4769         }
4770         break;
4771 
4772     case ALT_CLK_SDRAM_PLL_C1:
4773     case ALT_CLK_DDR_2X_DQS:
4774         ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
4775         if (ret == ALT_E_SUCCESS)
4776         {
4777             numer = (uint64_t) temp;
4778             ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C1, &temp);
4779             denom = (uint64_t) temp;
4780         }
4781         break;
4782 
4783     case ALT_CLK_SDRAM_PLL_C2:
4784     case ALT_CLK_DDR_DQ:
4785         ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
4786         if (ret == ALT_E_SUCCESS)
4787         {
4788             numer = (uint64_t) temp;
4789             ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C2, &temp);
4790             denom = (uint64_t) temp;
4791         }
4792         break;
4793 
4794     case ALT_CLK_SDRAM_PLL_C5:
4795     case ALT_CLK_H2F_USER2:
4796         ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
4797         if (ret == ALT_E_SUCCESS)
4798         {
4799             numer = (uint64_t) temp;
4800             ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C5, &temp);
4801             denom = (uint64_t) temp;
4802         }
4803         break;
4804 
4805     default:
4806         ret = ALT_E_BAD_ARG;
4807         break;
4808 
4809     }   // end of switch-case construct
4810 
4811     if (ret == ALT_E_SUCCESS)
4812     {
4813         // will not get here if none of above cases match
4814         if (denom > 0)
4815         {
4816             numer /= denom;
4817             if (numer <= UINT32_MAX)
4818             {
4819                 *freq = (uint32_t) numer;
4820             }
4821             else
4822             {
4823                 ret = ALT_E_ERROR;
4824             }
4825         }
4826         else
4827         {
4828             ret = ALT_E_ERROR;
4829         }
4830     }
4831 
4832     return ret;
4833 }
4834 
4835 //
4836 // alt_clk_irq_disable() disables one or more of the lock status conditions as
4837 // contributors to the clkmgr_IRQ interrupt signal state.
4838 //
4839 ALT_STATUS_CODE alt_clk_irq_disable(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
4840 {
4841     if (!(lock_stat_mask & ALT_CLK_MGR_PLL_LOCK_BITS))
4842     {
4843         alt_clrbits_word(ALT_CLKMGR_INTREN_ADDR, lock_stat_mask);
4844         return ALT_E_SUCCESS;
4845     }
4846     else
4847     {
4848         return ALT_E_BAD_ARG;
4849     }
4850 }
4851 
4852 //
4853 // alt_clk_irq_enable() enables one or more of the lock status conditions as
4854 // contributors to the clkmgr_IRQ interrupt signal state.
4855 //
4856 ALT_STATUS_CODE alt_clk_irq_enable(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
4857 {
4858     if (!(lock_stat_mask & ALT_CLK_MGR_PLL_LOCK_BITS))
4859     {
4860         alt_setbits_word(ALT_CLKMGR_INTREN_ADDR, lock_stat_mask);
4861         return ALT_E_SUCCESS;
4862     }
4863     else
4864     {
4865         return ALT_E_BAD_ARG;
4866     }
4867 }
4868 
4869 /////
4870 
4871 //
4872 // alt_clk_group_cfg_raw_get() gets the raw configuration state of the designated
4873 // clock group.
4874 //
4875 ALT_STATUS_CODE alt_clk_group_cfg_raw_get(ALT_CLK_GRP_t clk_group,
4876                                           ALT_CLK_GROUP_RAW_CFG_t * clk_group_raw_cfg)
4877 {
4878     clk_group_raw_cfg->verid     = alt_read_word(ALT_SYSMGR_SILICONID1_ADDR);
4879     clk_group_raw_cfg->siliid2   = alt_read_word(ALT_SYSMGR_SILICONID2_ADDR);
4880     clk_group_raw_cfg->clkgrpsel = clk_group;
4881 
4882     if (clk_group == ALT_MAIN_PLL_CLK_GRP)
4883     {
4884         // Main PLL VCO register
4885         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
4886 
4887         // Main PLL Misc register
4888         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.misc = alt_read_word(ALT_CLKMGR_MAINPLL_MISC_ADDR);
4889 
4890         // Main PLL C0-C5 Counter registers
4891         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mpuclk = alt_read_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR);
4892         // doing these as 32-bit reads and writes avoids unnecessary masking operations
4893 
4894         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainclk          = alt_read_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR);
4895         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgatclk         = alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR);
4896         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainqspiclk      = alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR);
4897         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainnandsdmmcclk = alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR);
4898         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.cfgs2fuser0clk   = alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR);
4899 
4900         // Main PLL Enable register
4901         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.en = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
4902 
4903         // Main PLL Maindiv register
4904         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.maindiv = alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR);
4905 
4906         // Main PLL Debugdiv register
4907         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgdiv = alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR);
4908 
4909         // Main PLL Tracediv register
4910         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.tracediv = alt_read_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR);
4911 
4912         // Main PLL L4 Source register
4913         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.l4src = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
4914 
4915         // Main PLL Status register
4916         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_MAINPLL_STAT_ADDR);
4917         // clkgrp.mainpllgrp.stat.outresetack is defined in the ALT_CLKMGR_MAINPLL_STAT_s declaration
4918         // as a const but alt_indwrite_word() overrides that restriction.
4919 
4920         // padding ...
4921         clk_group_raw_cfg->clkgrp.mainpllgrp.raw._pad_0x38_0x40[0] = 0;
4922         clk_group_raw_cfg->clkgrp.mainpllgrp.raw._pad_0x38_0x40[1] = 0;
4923 
4924         return ALT_E_SUCCESS;
4925     }
4926     else if (clk_group == ALT_PERIPH_PLL_CLK_GRP)
4927     {
4928         // Peripheral PLL VCO register
4929         clk_group_raw_cfg->clkgrp.perpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
4930 
4931         // Peripheral PLL Misc register
4932         clk_group_raw_cfg->clkgrp.perpllgrp.raw.misc = alt_read_word(ALT_CLKMGR_PERPLL_MISC_ADDR);
4933 
4934         // Peripheral PLL C0-C5 Counters
4935         clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac0clk = alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR);
4936         // doing these as 32-bit reads and writes avoids unnecessary masking operations
4937 
4938         clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac1clk        = alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR);
4939         clk_group_raw_cfg->clkgrp.perpllgrp.raw.perqspiclk      = alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR);
4940         clk_group_raw_cfg->clkgrp.perpllgrp.raw.pernandsdmmcclk = alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR);
4941         clk_group_raw_cfg->clkgrp.perpllgrp.raw.perbaseclk      = alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR);
4942         clk_group_raw_cfg->clkgrp.perpllgrp.raw.s2fuser1clk     = alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR);
4943 
4944         // Peripheral PLL Enable register
4945         clk_group_raw_cfg->clkgrp.perpllgrp.raw.en = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
4946 
4947         // Peripheral PLL Divider register
4948         clk_group_raw_cfg->clkgrp.perpllgrp.raw.div = alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR);
4949 
4950         // Peripheral PLL GPIO Divider register
4951         clk_group_raw_cfg->clkgrp.perpllgrp.raw.gpiodiv = alt_read_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR);
4952 
4953         // Peripheral PLL Source register
4954         clk_group_raw_cfg->clkgrp.perpllgrp.raw.src = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
4955 
4956         // Peripheral PLL Status register
4957         clk_group_raw_cfg->clkgrp.perpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_PERPLL_STAT_ADDR);
4958 
4959         // padding ...
4960         clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[0] = 0;
4961         clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[1] = 0;
4962         clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[2] = 0;
4963 
4964         return ALT_E_SUCCESS;
4965     }
4966     else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)
4967     {
4968         // SDRAM PLL VCO register
4969         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
4970 
4971         // SDRAM PLL Control register
4972         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ctrl = alt_read_word(ALT_CLKMGR_SDRPLL_CTL_ADDR);
4973 
4974         // SDRAM PLL C0-C2 & C5 Counters
4975         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqsclk = alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR);
4976         // doing these as 32-bit reads and writes avoids unnecessary masking operations
4977 
4978         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddr2xdqsclk = alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR);
4979         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqclk    = alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR);
4980         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.s2fuser2clk = alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR);
4981 
4982         // SDRAM PLL Enable register
4983         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.en = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
4984 
4985         // SDRAM PLL Status register
4986         clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_SDRPLL_STAT_ADDR);
4987 
4988         return ALT_E_SUCCESS;
4989     }
4990     else
4991     {
4992         return ALT_E_BAD_ARG;
4993     }
4994 }
4995 
4996 //
4997 // alt_clk_group_cfg_raw_set() sets the clock group configuration.
4998 //
4999 ALT_STATUS_CODE alt_clk_group_cfg_raw_set(const ALT_CLK_GROUP_RAW_CFG_t * clk_group_raw_cfg)
5000 {
5001     // test for matching silicon ID, but not for matching silicon revision number
5002     if (ALT_SYSMGR_SILICONID1_ID_GET(alt_read_word(ALT_SYSMGR_SILICONID1_ADDR)) !=
5003         ALT_SYSMGR_SILICONID1_ID_GET(clk_group_raw_cfg->verid))
5004     {
5005         return ALT_E_BAD_VERSION;
5006     }
5007 
5008     // get the PLL ID
5009     ALT_CLK_GRP_t clk_group = clk_group_raw_cfg->clkgrpsel;
5010     ALT_CLK_t     pll;
5011 
5012     if      (clk_group == ALT_MAIN_PLL_CLK_GRP)   { pll = ALT_CLK_MAIN_PLL; }
5013     else if (clk_group == ALT_PERIPH_PLL_CLK_GRP) { pll = ALT_CLK_PERIPHERAL_PLL; }
5014     else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)  { pll = ALT_CLK_SDRAM_PLL; }
5015     else
5016     {
5017         return ALT_E_ERROR;
5018     }
5019 
5020     ALT_STATUS_CODE status = ALT_E_SUCCESS;
5021 
5022     // if the PLL isn't in bypass mode, put it in bypass mode
5023     bool byp = false;
5024     if (alt_clk_pll_is_bypassed(pll) == ALT_E_FALSE)
5025     {
5026         status = alt_clk_pll_bypass_enable(pll, false);
5027         if (status != ALT_E_SUCCESS)
5028         {
5029             return status;
5030         }
5031 
5032         byp = true;
5033     }
5034 
5035     // now write the values in the ALT_CLK_GROUP_RAW_CFG_t structure to the registers
5036     if (clk_group == ALT_MAIN_PLL_CLK_GRP)
5037     {
5038         // Main PLL VCO register
5039         alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.vco &
5040                        ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_CLR_MSK & ALT_CLKMGR_MAINPLL_VCO_OUTRST_CLR_MSK);
5041         // the outreset and outresetall bits were probably clear when the
5042         // state was saved, but make sure they're clear now
5043 
5044         // Main PLL Misc register
5045         alt_write_word(ALT_CLKMGR_MAINPLL_MISC_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.misc);
5046 
5047         // Main PLL C0-C5 Counter registers
5048         alt_write_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR,           clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mpuclk);
5049         alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR,          clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainclk);
5050         alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR,         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgatclk);
5051         alt_write_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,      clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainqspiclk);
5052         alt_write_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainnandsdmmcclk);
5053         alt_write_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,   clk_group_raw_cfg->clkgrp.mainpllgrp.raw.cfgs2fuser0clk);
5054 
5055         // Main PLL Counter Enable register
5056         alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.en);
5057 
5058         // Main PLL Maindiv register
5059         alt_write_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.maindiv);
5060 
5061         // Main PLL Debugdiv register
5062         alt_write_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgdiv);
5063 
5064         // Main PLL Tracediv register
5065         alt_write_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.tracediv);
5066 
5067         // Main PLL L4 Source register
5068         alt_write_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.l4src);
5069     }
5070     else if (clk_group == ALT_PERIPH_PLL_CLK_GRP)
5071     {
5072         // Peripheral PLL VCO register
5073         alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.vco &
5074                        ALT_CLKMGR_PERPLL_VCO_OUTRST_CLR_MSK & ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_CLR_MSK);
5075         // the outreset and outresetall bits were probably clear when the
5076         // state was saved, but make sure they're clear now
5077 
5078         // Peripheral PLL Misc register
5079         alt_write_word(ALT_CLKMGR_PERPLL_MISC_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.misc);
5080 
5081         // Peripheral PLL C0-C5 Counters
5082         alt_write_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac0clk);
5083         alt_write_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac1clk);
5084         alt_write_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,      clk_group_raw_cfg->clkgrp.perpllgrp.raw.perqspiclk);
5085         alt_write_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.pernandsdmmcclk);
5086         alt_write_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,      clk_group_raw_cfg->clkgrp.perpllgrp.raw.perbaseclk);
5087         alt_write_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,     clk_group_raw_cfg->clkgrp.perpllgrp.raw.s2fuser1clk);
5088 
5089         // Peripheral PLL Counter Enable register
5090         alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.en);
5091 
5092         // Peripheral PLL Divider register
5093         alt_write_word(ALT_CLKMGR_PERPLL_DIV_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.div);
5094 
5095         // Peripheral PLL GPIO Divider register
5096         alt_write_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.gpiodiv);
5097 
5098         // Peripheral PLL Source register
5099         alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.src);
5100     }
5101     else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)
5102     {
5103         // SDRAM PLL VCO register
5104         alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.vco &
5105                        ALT_CLKMGR_SDRPLL_VCO_OUTRST_CLR_MSK & ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_CLR_MSK);
5106         // the outreset and outresetall bits were probably clear when the
5107         // state was saved, but make sure they're clear now
5108 
5109         // SDRAM PLL Control register
5110         alt_write_word(ALT_CLKMGR_SDRPLL_CTL_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ctrl);
5111 
5112         // SDRAM PLL C0-C2 & C5 Counters
5113         alt_write_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR,   clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqsclk);
5114         alt_write_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddr2xdqsclk);
5115         alt_write_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR,    clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqclk);
5116         alt_write_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.s2fuser2clk);
5117 
5118         // SDRAM PLL Counter Enable register
5119         alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.en);
5120     }
5121 
5122     // if PLL was not bypassed before, restore that state
5123     if (byp)
5124     {
5125         status = alt_clk_pll_bypass_disable(pll);
5126     }
5127 
5128     return status;
5129 }
5130 
5131 //
5132 // alt_clk_id_to_string() converts a clock ID to a text string.
5133 //
5134 ALT_STATUS_CODE alt_clk_id_to_string(ALT_CLK_t clk_id, char * output, size_t size)
5135 {
5136     char * name = NULL;
5137 
5138     switch (clk_id)
5139     {
5140     case ALT_CLK_IN_PIN_OSC1:
5141         name =  "IN_PIN_OSC1";
5142         break;
5143     case ALT_CLK_IN_PIN_OSC2:
5144         name =  "IN_PIN_OSC2";
5145         break;
5146 
5147         // FPGA Clock Sources External to HPS
5148     case ALT_CLK_F2H_PERIPH_REF:
5149         name =  "F2H_PERIPH_REF";
5150         break;
5151     case ALT_CLK_F2H_SDRAM_REF:
5152         name =  "F2H_SDRAM_REF";
5153         break;
5154 
5155         // Other Clock Sources External to HPS
5156     case ALT_CLK_IN_PIN_JTAG:
5157         name =  "IN_PIN_JTAG";
5158         break;
5159     case ALT_CLK_IN_PIN_ULPI0:
5160         name =  "IN_PIN_ULPI0";
5161         break;
5162     case ALT_CLK_IN_PIN_ULPI1:
5163         name =  "IN_PIN_ULPI1";
5164         break;
5165     case ALT_CLK_IN_PIN_EMAC0_RX:
5166         name =  "IN_PIN_EMAC0_RX";
5167         break;
5168     case ALT_CLK_IN_PIN_EMAC1_RX:
5169         name =  "IN_PIN_EMAC1_RX";
5170         break;
5171 
5172         // PLLs
5173     case ALT_CLK_MAIN_PLL:
5174         name =  "MAIN_PLL";
5175         break;
5176     case ALT_CLK_PERIPHERAL_PLL:
5177         name =  "PERIPHERAL_PLL";
5178         break;
5179     case ALT_CLK_SDRAM_PLL:
5180         name =  "SDRAM_PLL";
5181         break;
5182 
5183         // OSC1 Clock Group - The OSC1 clock group contains those clocks which are derived
5184         // directly from the osc_clk_1_HPS pin
5185     case ALT_CLK_OSC1:
5186         name =  "OSC1";
5187         break;
5188 
5189         // Main Clock Group - The following clocks are derived from the Main PLL.
5190     case ALT_CLK_MAIN_PLL_C0:
5191         name =  "MAIN_PLL_C0";
5192         break;
5193     case ALT_CLK_MAIN_PLL_C1:
5194         name =  "MAIN_PLL_C1";
5195         break;
5196     case ALT_CLK_MAIN_PLL_C2:
5197         name =  "MAIN_PLL_C2";
5198         break;
5199     case ALT_CLK_MAIN_PLL_C3:
5200         name =  "MAIN_PLL_C3";
5201         break;
5202     case ALT_CLK_MAIN_PLL_C4:
5203         name =  "MAIN_PLL_C4";
5204         break;
5205     case ALT_CLK_MAIN_PLL_C5:
5206         name =  "MAIN_PLL_C5";
5207         break;
5208     case ALT_CLK_MPU:
5209         name =  "MPU";
5210         break;
5211     case ALT_CLK_MPU_L2_RAM:
5212         name =  "MPU_L2_RAM";
5213         break;
5214     case ALT_CLK_MPU_PERIPH:
5215         name =  "MPU_PERIPH";
5216         break;
5217     case ALT_CLK_L3_MAIN:
5218         name =  "L3_MAIN";
5219         break;
5220     case ALT_CLK_L3_MP:
5221         name =  "L3_MP";
5222         break;
5223     case ALT_CLK_L3_SP:
5224         name =  "L3_SP";
5225         break;
5226     case ALT_CLK_L4_MAIN:
5227         name =  "L4_MAIN";
5228         break;
5229     case ALT_CLK_L4_MP:
5230         name =  "L4_MP";
5231         break;
5232     case ALT_CLK_L4_SP:
5233         name =  "L4_SP";
5234         break;
5235     case ALT_CLK_DBG_BASE:
5236         name =  "DBG_BASE";
5237         break;
5238     case ALT_CLK_DBG_AT:
5239         name =  "DBG_AT";
5240         break;
5241     case ALT_CLK_DBG_TRACE:
5242         name =  "DBG_TRACE";
5243         break;
5244     case ALT_CLK_DBG_TIMER:
5245         name =  "DBG_TIMER";
5246         break;
5247     case ALT_CLK_DBG:
5248         name =  "DBG";
5249         break;
5250     case ALT_CLK_MAIN_QSPI:
5251         name =  "MAIN_QSPI";
5252         break;
5253     case ALT_CLK_MAIN_NAND_SDMMC:
5254         name =  "MAIN_NAND_SDMMC";
5255         break;
5256     case ALT_CLK_CFG:
5257         name =  "CFG";
5258         break;
5259     case ALT_CLK_H2F_USER0:
5260         name =  "H2F_USER0";
5261         break;
5262 
5263         // Peripherals Clock Group - The following clocks are derived from the Peripheral PLL.
5264     case ALT_CLK_PERIPHERAL_PLL_C0:
5265         name =  "PERIPHERAL_PLL_C0";
5266         break;
5267     case ALT_CLK_PERIPHERAL_PLL_C1:
5268         name =  "PERIPHERAL_PLL_C1";
5269         break;
5270     case ALT_CLK_PERIPHERAL_PLL_C2:
5271         name =  "PERIPHERAL_PLL_C2";
5272         break;
5273     case ALT_CLK_PERIPHERAL_PLL_C3:
5274         name =  "PERIPHERAL_PLL_C3";
5275         break;
5276     case ALT_CLK_PERIPHERAL_PLL_C4:
5277         name =  "PERIPHERAL_PLL_C4";
5278         break;
5279     case ALT_CLK_PERIPHERAL_PLL_C5:
5280         name =  "PERIPHERAL_PLL_C5";
5281         break;
5282     case ALT_CLK_USB_MP:
5283         name =  "USB_MP";
5284         break;
5285     case ALT_CLK_SPI_M:
5286         name =  "SPI_M";
5287         break;
5288     case ALT_CLK_QSPI:
5289         name =  "QSPI";
5290         break;
5291     case ALT_CLK_NAND_X:
5292         name =  "NAND_X";
5293         break;
5294     case ALT_CLK_NAND:
5295         name =  "NAND";
5296         break;
5297     case ALT_CLK_SDMMC:
5298         name =  "SDMMC";
5299         break;
5300     case ALT_CLK_EMAC0:
5301         name =  "EMAC0";
5302         break;
5303     case ALT_CLK_EMAC1:
5304         name =  "EMAC1";
5305         break;
5306     case ALT_CLK_CAN0:
5307         name =  "CAN0";
5308         break;
5309     case ALT_CLK_CAN1:
5310         name =  "CAN1";
5311         break;
5312     case ALT_CLK_GPIO_DB:
5313         name =  "GPIO_DB";
5314         break;
5315     case ALT_CLK_H2F_USER1:
5316         name =  "H2F_USER1";
5317         break;
5318 
5319         // SDRAM Clock Group - The following clocks are derived from the SDRAM PLL.
5320     case ALT_CLK_SDRAM_PLL_C0:
5321         name =  "SDRAM_PLL_C0";
5322         break;
5323     case ALT_CLK_SDRAM_PLL_C1:
5324         name =  "SDRAM_PLL_C1";
5325         break;
5326     case ALT_CLK_SDRAM_PLL_C2:
5327         name =  "SDRAM_PLL_C2";
5328         break;
5329     case ALT_CLK_SDRAM_PLL_C3:
5330         name =  "SDRAM_PLL_C3";
5331         break;
5332     case ALT_CLK_SDRAM_PLL_C4:
5333         name =  "SDRAM_PLL_C4";
5334         break;
5335     case ALT_CLK_SDRAM_PLL_C5:
5336         name =  "SDRAM_PLL_C5";
5337         break;
5338     case ALT_CLK_DDR_DQS:
5339         name =  "DDR_DQS";
5340         break;
5341     case ALT_CLK_DDR_2X_DQS:
5342         name =  "DDR_2X_DQS";
5343         break;
5344     case ALT_CLK_DDR_DQ:
5345         name =  "DDR_DQ";
5346         break;
5347     case ALT_CLK_H2F_USER2:
5348         name =  "H2F_USER2";
5349         break;
5350 
5351         // Clock Output Pins
5352     case ALT_CLK_OUT_PIN_EMAC0_TX:
5353         name =  "OUT_PIN_EMAC0_TX";
5354         break;
5355     case ALT_CLK_OUT_PIN_EMAC1_TX:
5356         name =  "OUT_PIN_EMAC1_TX";
5357         break;
5358     case ALT_CLK_OUT_PIN_SDMMC:
5359         name =  "OUT_PIN_SDMMC";
5360         break;
5361     case ALT_CLK_OUT_PIN_I2C0_SCL:
5362         name =  "OUT_PIN_I2C0_SCL";
5363         break;
5364     case ALT_CLK_OUT_PIN_I2C1_SCL:
5365         name =  "OUT_PIN_I2C1_SCL";
5366         break;
5367     case ALT_CLK_OUT_PIN_I2C2_SCL:
5368         name =  "OUT_PIN_I2C2_SCL";
5369         break;
5370     case ALT_CLK_OUT_PIN_I2C3_SCL:
5371         name =  "OUT_PIN_I2C3_SCL";
5372         break;
5373     case ALT_CLK_OUT_PIN_SPIM0:
5374         name =  "OUT_PIN_SPIM0";
5375         break;
5376     case ALT_CLK_OUT_PIN_SPIM1:
5377         name =  "OUT_PIN_SPIM1";
5378         break;
5379     case ALT_CLK_OUT_PIN_QSPI:
5380         name =  "OUT_PIN_QSPI";
5381         break;
5382     case ALT_CLK_UNKNOWN:
5383         name =  "UNKNOWN";
5384         break;
5385 
5386         // do *not* put a 'default' statement here. Then the compiler will throw
5387         // an error if another clock id enum is added if the corresponding
5388         // string is not added to this function.
5389     }
5390 
5391     if (name != NULL)
5392     {
5393         snprintf(output, size, "ALT_CLK_%s", name);
5394         return ALT_E_SUCCESS;
5395     }
5396     else
5397     {
5398         return ALT_E_BAD_ARG;
5399     }
5400 }
5401 
5402 
5403 //
5404 // alt_clk_pll_cntr_maxfreq_recalc() recalculate the maxmum frequency of the specified clock.
5405 //
5406 ALT_STATUS_CODE alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_t clk, ALT_PLL_CNTR_FREQMAX_t * maxfreq)
5407 {
5408     ALT_STATUS_CODE ret = ALT_E_BAD_ARG;
5409     alt_freq_t freq;
5410 
5411     ret = alt_clk_freq_get(clk, &freq);
5412 
5413     if (ret == ALT_E_SUCCESS)
5414     {
5415 
5416         switch (clk)
5417         {
5418             // Main Clock Group
5419         case ALT_CLK_MAIN_PLL_C0:
5420             maxfreq->MainPLL_C0 = freq;
5421             printf("alt_pll_cntr_maxfreq.MainPLL_C0   = %10d\n", (unsigned int)freq);
5422             break;
5423         case ALT_CLK_MAIN_PLL_C1:
5424             maxfreq->MainPLL_C1 = freq;
5425             printf("alt_pll_cntr_maxfreq.MainPLL_C1   = %10d\n", (unsigned int)freq);
5426             break;
5427         case ALT_CLK_MAIN_PLL_C2:
5428             maxfreq->MainPLL_C2 = freq;
5429             printf("alt_pll_cntr_maxfreq.MainPLL_C2   = %10d\n", (unsigned int)freq);
5430             break;
5431         case ALT_CLK_MAIN_PLL_C3:
5432             maxfreq->MainPLL_C3 = freq;
5433             printf("alt_pll_cntr_maxfreq.MainPLL_C3   = %10d\n", (unsigned int)freq);
5434             break;
5435         case ALT_CLK_MAIN_PLL_C4:
5436             maxfreq->MainPLL_C4 = freq;
5437             printf("alt_pll_cntr_maxfreq.MainPLL_C4   = %10d\n", (unsigned int)freq);
5438             break;
5439         case ALT_CLK_MAIN_PLL_C5:
5440             maxfreq->MainPLL_C5 = freq;
5441             printf("alt_pll_cntr_maxfreq.MainPLL_C5   = %10d\n", (unsigned int)freq);
5442             break;
5443 
5444             // Peripheral Clock Group
5445         case ALT_CLK_PERIPHERAL_PLL_C0:
5446             maxfreq->PeriphPLL_C0 = freq;
5447             printf("alt_pll_cntr_maxfreq.PeriphPLL_C0 = %10d\n", (unsigned int)freq);
5448             break;
5449         case ALT_CLK_PERIPHERAL_PLL_C1:
5450             maxfreq->PeriphPLL_C1 = freq;
5451             printf("alt_pll_cntr_maxfreq.PeriphPLL_C1 = %10d\n", (unsigned int)freq);
5452             break;
5453         case ALT_CLK_PERIPHERAL_PLL_C2:
5454             maxfreq->PeriphPLL_C2 = freq;
5455             printf("alt_pll_cntr_maxfreq.PeriphPLL_C2 = %10d\n", (unsigned int)freq);
5456             break;
5457         case ALT_CLK_PERIPHERAL_PLL_C3:
5458             maxfreq->PeriphPLL_C3 = freq;
5459             printf("alt_pll_cntr_maxfreq.PeriphPLL_C3 = %10d\n", (unsigned int)freq);
5460             break;
5461         case ALT_CLK_PERIPHERAL_PLL_C4:
5462             maxfreq->PeriphPLL_C4 = freq;
5463             printf("alt_pll_cntr_maxfreq.PeriphPLL_C4 = %10d\n", (unsigned int)freq);
5464             break;
5465         case ALT_CLK_PERIPHERAL_PLL_C5:
5466             maxfreq->PeriphPLL_C5 = freq;
5467             printf("alt_pll_cntr_maxfreq.PeriphPLL_C5 = %10d\n", (unsigned int)freq);
5468             break;
5469 
5470             // SDRAM Clock Group
5471         case ALT_CLK_SDRAM_PLL_C0:
5472             maxfreq->SDRAMPLL_C0 = freq;
5473             printf("alt_pll_cntr_maxfreq.SDRAMPLL_C0  = %10d\n", (unsigned int)freq);
5474             break;
5475         case ALT_CLK_SDRAM_PLL_C1:
5476             maxfreq->SDRAMPLL_C1 = freq;
5477             printf("alt_pll_cntr_maxfreq.SDRAMPLL_C1  = %10d\n", (unsigned int)freq);
5478             break;
5479         case ALT_CLK_SDRAM_PLL_C2:
5480             maxfreq->SDRAMPLL_C2 = freq;
5481             printf("alt_pll_cntr_maxfreq.SDRAMPLL_C2  = %10d\n", (unsigned int)freq);
5482             break;
5483         case ALT_CLK_SDRAM_PLL_C5:
5484             maxfreq->SDRAMPLL_C5 = freq;
5485             printf("alt_pll_cntr_maxfreq.SDRAMPLL_C5  = %10d\n", (unsigned int)freq);
5486             break;
5487         default:
5488             ret = ALT_E_BAD_ARG;
5489             printf("bad max frequency parameter\n");
5490             break;
5491         }   // end of switch-case construct
5492     }
5493 
5494     return ret;
5495 }
5496 
5497 //
5498 //  u-boot preloader actually initialize clock manager circuitry
5499 //
5500 //  alt_clk_clkmgr_init() attempt to fix the pll counter max frequencies, since
5501 //  thses frequencies are not known in advance until u-boot programmed clock manager.
5502 //
5503 ALT_STATUS_CODE alt_clk_clkmgr_init(void)
5504 {
5505     ALT_STATUS_CODE ret = ALT_E_SUCCESS;
5506     ALT_STATUS_CODE status ;
5507 
5508     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C0,&alt_pll_cntr_maxfreq );
5509     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5510 
5511     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C1,&alt_pll_cntr_maxfreq );
5512     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5513 
5514     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C2,&alt_pll_cntr_maxfreq );
5515     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5516 
5517     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C3,&alt_pll_cntr_maxfreq );
5518     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5519 
5520     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C4,&alt_pll_cntr_maxfreq );
5521     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5522 
5523     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C5,&alt_pll_cntr_maxfreq );
5524     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5525 
5526     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C0,&alt_pll_cntr_maxfreq );
5527     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5528 
5529     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C1,&alt_pll_cntr_maxfreq );
5530     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5531 
5532     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C2,&alt_pll_cntr_maxfreq );
5533     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5534 
5535     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C3,&alt_pll_cntr_maxfreq );
5536     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5537 
5538     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C4,&alt_pll_cntr_maxfreq );
5539     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5540 
5541     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C5,&alt_pll_cntr_maxfreq );
5542     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5543 
5544 
5545     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C0,&alt_pll_cntr_maxfreq );
5546     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5547 
5548     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C1,&alt_pll_cntr_maxfreq );
5549     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5550 
5551     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C2,&alt_pll_cntr_maxfreq );
5552     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5553 
5554     status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C5,&alt_pll_cntr_maxfreq );
5555     if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;
5556 
5557 
5558     return ret;
5559 }
5560