summaryrefslogblamecommitdiffstats
path: root/bsps/arm/altera-cyclone-v/contrib/hwlib/src/hwmgr/alt_clock_manager.c
blob: 95404c1c13bd227de252c72bf99cbf126678dc1b (plain) (tree)
1
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
                                                                               

































                                                                                  





                                  



































                                                                                            






                                                      






















                                                                                        








                                                                






















                                                                                    








































                                                                                           


                                                                 


















                                                    




























                                                                               











                                                                                                                                       

















                                                                                          
                                                            






                                  















                                                                                         
                                              











                                                                                    
                                                                             
 








                                                                                                     
 

      




                                                                   
 



                        






























































                                                                                          
                                                                                   
 






                                                                    
     
                             



                                                                
                             
     








                                                                                          








                                                                                             









                                                                                          
                                           


                                
                                                                                                



                                           
                                                                                               



                                           
                                                                                               

                                           
                  









                                                                                          
                                         









                                                                                             
                                        







                                                                                          
                                        

      
                  










































                                                                                          

                                           
                           


                                      









                                                                                        
                                                                 



                                                                                                                     
                                 


                                                                                                                     
                                 

                         

                                                                             













                                                                                                         
                                                










































                                                                                                                  
                                                






















                                                                                                       
                                                

         



                             
 
                  








                                                                                          

                                           
                              


                                      








                                                                                        
                                                                 



                                                                                                                     
                                 


                                                                                                                     
                                 

                         

                                                                             




                                                                                             
                                                





                                                                                              
                                                

      




                                    
         
     




                                                                                          
                                                             



                                                                                                              
                             


                                                                                                              
                             

                     

                                                                         



















                                                                                          
                               









                                                                                         
                               
     
                  













                                                                                          
                                           


                                
                                                                                




                                                                                        
                                                                                




                                                                                       
                                                                                


                                                                                       
                  






                                                                                          
                                               
 
                                         







































                                                                                         
     


               



                                                                                    

                                                    
                                           


                




                                                       
              
 






























                                                                                                
 







































                                                                                              
 












                                                                                              
 


                               
     
 

                  

 



                                                                                     

                                                   
                                           


                





                                                  
 






























                                                                                                
 











































                                                                                                        
 












                                                                                              
 



                               
 
                  

 


                                                                              

                                                 
                                           
 







                                                                        
 


























                                                                                 
 








































                                                                                                   
 
































                                                                                                 
 
















                                                                                              
 
















                                                                                                 
 


                               

     
 

                  
 



                                                                                     

                                           

                                    


                












                                                    
 





























                                                                         
 












                                                                                             
                                                                             








                                                                                           
 




                                                                                             
                                                                             








                                                                                           
 




















                                                                         
 










                                                                                    
 



                                                                                        
 



                                                                                        
 







                                                                                        
 



                                                                                        
 












                                                                                          
                                                                                   


                                                                                            
 













                                                                                         
                                                                                   


                                                                                            
 
















                                                                                            
 

























                                                                              
 












                                  
 



                              
 


               







                                                                                     
 

                                           


                                







                                                                          


                                           

                                                          
                                                   
 



                                                                                       




                                                                                       




                                                                                                
         



                                      
     
                                      
     
                                                          
                                                   
 



                                                                                       




                                                                                       




                                                                                               
         



                                      
     

                                   
                             


                                                                                                   



                                                                                                   
         



                                      
     




                                                                                                   



                                                                                                   
         



                                      
     
                                  
     
                                                          
                                                    
 



                                                                                                      




                                                                                                 




                                                                                                   
         



                                      
     
                                                               


                                                         
 



                                                                                                    




                                                                                               




                                                                                                 
         



                                      
     
                                 
     
                                                          
                                                   
 



                                                                                                    




                                                                                               




                                                                                                 
         



                                      
     
 

                  
 





                                                                                     

                                                                        
                                           





                                                                                                               




                                     
         
     




                                                                                                               




                                     
         
     




                                                                                                             




                                     
         
     




                                                                                                           




                                     
         
     



                               
 

                  

 



                                                                                 

                                                  
                     




















                                                                                              












                                                                               
 





                                                               
 


                                                                                                            
 

                                                                                                              
 

                                                                                                                 
 

                                                                                                                       
 











                                                                                                                                 
     

                                                                                         
         
                                                           
             
                                                       
             
                                                                
             
                                                       
             
                                                                         
             

                                                          
 


                                                                  
 


                                                                                                                   
 

                                                                                                                   
 

                                                                                                                       
 

                                                                                                                                 
 



























                                                                                                                         
             
























                                                                                                                            

         
 



               




                                                                                      
 



                                     
 
                                                                                               
     






























                                                                                             
         
                                                                                       
         
                                                         
         
                                                                                       
         
                                                            
         





























































































                                                                                                                             

         
 



               







































                                                                                       



















































                                                                                          
 
                       










                                                       
 











                                                                 

                                          
     
























                                                                  
         

                                                              
                                                            
         
                                                              
         
                                                                     
         




                                                             
         







                                                         
 

















                                                                    
         














                                                                                                    
 









                                                                 
             

                                                           
             





                                                                
             

                                        
                 
                                                 

                 





                                                                 
             

                                            
                 
                                                     

                 


                                                                
             

                                            
                 
                                                     





                 
      

































































































































                                                                                          






                                                                                      






                                            
                     
     
































                                                                  
         
                                                                     











                                                                     




                                          


                                                                   
                             
                                    
             














                                                                     
         
                                                            
         
                                                                     
         
                                                                    
         

                                                                   
 




                                    
             


                                                                  
 

                                    
             






                                                                  


               


                                                              

                                                  
                     















                                                            




                                                                                       

                                                                              


                                                         
     
                               
     
 
                                           
 






















                                                                                            
 



                                                                               
 

                                           
 
                    
     

                                     
 







                                                                                                       
 





                                                                                                         
 





                                                                                                           
 



                                                                                                                
 



                                                                                                                          
 




                                                                                                                      
 
             
 




                                                                                                        
 



                                                                                                        
 


                                                                                                            
 


                                                                                                                      
 


                                                                                                            
 



                                                                                                              
 
             
 




                                                                                                          
 



                                                                                                              
 



                                                                                                        
 



                                                                                                              
 
             
 











                                                                                                      
 












                                                                                                      
 










                                                                                                      
 










                                                                                                      
 










                                                                                                     
 





























































































                                                                                                         
 











                                                                              

                                        
     
 
                 
     

                             
 



                                           
 
































                                                                    
 






























                                                                          
 




































                                                                     

         
 


                  
 


















                                                                  
 





                                                                        








                                                                               
                
     




                                                                                                                   
 




                                                                                         
 


                                                                                                                  
                                    

                
             
                                      
             

              
 







                                                                                                                     
             

                                                                                                                  
 
                                           
 




                                                                                            
 
                                                                                                                         
                 
                                     
                 
                                                                                                                         
                 
                                     
                 



                                                                                                 
 
                                                                       
 





                                                                                                  

                                    
                
             



                                      
 



                                                                                                                       
 







                                                                                                                  
 

                                    
                
             



                                      
 











                                                                                                                     
                 

                                                                                                           

                 
                                








                                                                                                      


                                                                    
                                                                                               


                                    





                                  
 






                                                                                     
 



                                                                                                     
             
 

                                                                                                   
             

                                                                                        
             
 

                                       
             
                                                             
                                                                


                                                                                             
 






                                                                                 
 








                                                                                                       
 

                                       
                                                                                                        

                                                                                                         
                 

                                                                                                 

                                                                     
             






                                  
 









                                                                                     
             


                                                                                                                             
 







                                                                            
 
                                                                                                     
 
                          
             
                                                                 
             






                                  
 
             
 







                                                                                           
 
                          
             

                                                                                                        
 












                                                                                              
             






                                  
 








                                                                                           
             






















                                                                                                        
 










                                                                                             

                              

                                                                                                           
                 
             
 







                                                                       
 












                                                                                                
 


























                                                                                                                           
             
 







                                                                            
 
                                                                                                      
 


                                                                                                          
             


                                                                                                           
             





























































                                                                                                                
 







                                                                                           
             
                                                                                                           
             
 



















                                                                                         
 








                                                                                      
             


                                                                                                         
             
 
















                                                                                                        
 







                                                                                      
             


                                                                                                           
             
 






                                                                        
             
                                                                                                        
             






                                  
 







                                                                                      
             

                                                                                                        

                                 






                                                                       

                          
                                                                                                        

                                





                                  
 







                                                                                      
             


                                                                                                           
             
 






                                                                        
             
                                                                                                        
             








                                  
 



                                                                                 
 



                                                             
             


                                                                                                         
             



                                                                                                          
             
                                                                                                         
             






                                  
 




                                                                                 
 
























                                                                                                          
             












































































































































































































































































































                                                                                                             
                 










                                                                                                      

                              

                                                                                                      


                                    
                
             







                                                                      
                 










                                                                                                      

                              

                                                                                                      


                                    





                                      
 
             
 



                            
 
               
 
 


                                                                          

                                                                 



                                        
 



                           
 
                
     






                                                      
 




                                                      
 




                                                     
 




                                                    
 
             
 













                                                                    
 






























                                                                                             
 






























                                                                                             
 
             
 














                                                                
 








                                                                  
 













                                                                  
 













                                                                  
 









                                                                  
 













                                                                  
 


















                                                                  
 







                                                                                                   



                                                                        

                                                                                                   
                 



                                                                              


                                            

                                                                                
                 


              
 







                                                                                                   



                                                                        

                                                                          
                 


                                                                                                  



                                                                              

                                                                                
                 


              
 









                                                                  
 













                                                                  
 


















                                                                  
 













                                                                  
 








                                                                  
 








                                                                  
 









                                                                  
 
             
 














                                                                      
 








                                                                        
 








                                                                        
 













                                                                        
 













                                                                        
 













                                                                        
 






























































































































































                                                                                          
 









                                                                   
 









                                                                   
 


                                                                 

                                 


















                                                                   
             
                                         
             







                                  

         
 


               



                                                                              

                                                                             


                                                                 




                             
     

 



                                                                            

                                                                            


                                                                 




                             
     

 
     
 



                                                                                 
                                                                  
                                                                                      
 


                                                                             
 
                                          
     

                                                                                                  
 

                                                                                                    
 


                                                                                                        
 




                                                                                                                            
 

                                                                                                
 

                                                                                                          
 

                                                                                                        
 

                                                                                                            
 

                                                                                                      
 



                                                                                                     
 


                                                                       
 





                                                                                                
 

                                                                                                  
 


                                                                                                          
 




                                                                                                                        
 

                                                                                              
 







                                                                                                        
 

                                                                                                  
 



                                                                      
 





                                                                                                
 

                                                                                                 
 


                                                                                                            
 


                                                                                                                
 

                                                                                              
 









                                                                                                  
 










                                                                                            
 


                                                           
 






                                                                                   
 
                                           
 







                                                             

         

                   
 







                                                                                                         
 

                                                                                                    
 






                                                                                                                            
 

                                                                                                
 

                                                                                                          
 

                                                                                                        
 

                                                                                                            
 





















































                                                                                                                        
 




                                                         
 

                  
 



                                                                                  
 
                       
 
                   
     





                              
 






                                             
 















                                              
 

















































































































































                                                                                              
 






























                                                                                   
 

































                                   
 



                                                                                
 









                                                   
 
 






                                                                                                
 
                                           
 

                                 
 


























                                                                                                 
 
























                                                                                                 
 





















                                                                                                 

     

               
































































                                                                                                   
/******************************************************************************
 *
 * Copyright 2013 Altera Corporation. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 ******************************************************************************/

#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>

#include <bsp/socal/hps.h>
#include <bsp/socal/socal.h>
#include <bsp/socal/alt_sysmgr.h>
#include <bsp/hwlib.h>
#include <bsp/alt_clock_manager.h>
#include <bsp/alt_mpu_registers.h>

#define UINT12_MAX              (4096)

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Useful Structures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


        /* General structure used to hold parameters of various clock entities, */
typedef struct ALT_CLK_PARAMS_s
{
    alt_freq_t      freqcur;                   // current frequency of the clock
    alt_freq_t      freqmin;                   // minimum allowed frequency for this clock
    alt_freq_t      freqmax;                   // maximum allowed frequency for this clock
    uint32_t        guardband : 7;             // guardband percentage (0-100) if this clock
                                               //    is a PLL, ignored otherwise
    uint32_t        active    : 1;             // current state of activity of this clock
} ALT_CLK_PARAMS_t;


typedef struct ALT_EXT_CLK_PARAMBLOK_s
{
    ALT_CLK_PARAMS_t        clkosc1;        // ALT_CLK_OSC1
    ALT_CLK_PARAMS_t        clkosc2;        // ALT_CLK_OSC2
    ALT_CLK_PARAMS_t        periph;         // ALT_CLK_F2H_PERIPH_REF
    ALT_CLK_PARAMS_t        sdram;          // ALT_CLK_F2H_SDRAM_REF
} ALT_EXT_CLK_PARAMBLOK_t;


        /* Initializes the External Clock Frequency Limits block                        */
        /* The first field is the current external clock frequency, and can be set by   */
        /* alt_clk_ext_clk_freq_set(), the second and third fields are the minimum and  */
        /* maximum frequencies, the fourth field is ignored, and the fifth field        */
        /* contains the current activity state of the clock, 1=active, 0=inactive.      */
        /* Values taken from Section 2.3 and Section 2.7.1 of the HHP HPS-Clocking      */
        /* NPP specification.                                                           */
static ALT_EXT_CLK_PARAMBLOK_t alt_ext_clk_paramblok =
{
    { 25000000, 10000000, 50000000, 0, 1 },
    { 25000000, 10000000, 50000000, 0, 1 },
    {        0, 10000000, 50000000, 0, 1 },
    {        0, 10000000, 50000000, 0, 1 }
};


        /* PLL frequency limits */
typedef struct ALT_PLL_CLK_PARAMBLOK_s
{
    ALT_CLK_PARAMS_t       MainPLL_600;         // Main PLL values for 600 MHz SoC
    ALT_CLK_PARAMS_t       PeriphPLL_600;       // Peripheral PLL values for 600 MHz SoC
    ALT_CLK_PARAMS_t       SDRAMPLL_600;        // SDRAM PLL values for 600 MHz SoC
    ALT_CLK_PARAMS_t       MainPLL_800;         // Main PLL values for 800 MHz SoC
    ALT_CLK_PARAMS_t       PeriphPLL_800;       // Peripheral PLL values for 800 MHz SoC
    ALT_CLK_PARAMS_t       SDRAMPLL_800;        // SDRAM PLL values for 800 MHz SoC
} ALT_PLL_CLK_PARAMBLOK_t;


    /* Initializes the PLL frequency limits block                               */
    /* The first field is the current frequency, the second and third fields    */
    /* are the design limits of the PLLs as listed in Section 3.2.1.2 of the    */
    /* HHP HPS-Clocking NPP document. The fourth field of each line is the      */
    /* guardband percentage, and the fifth field of each line is the current    */
    /* state of the PLL, 1=active, 0=inactive.                                  */
#define     ALT_ORIGINAL_GUARDBAND_VAL      20
#define     ALT_GUARDBAND_LIMIT             20

static ALT_PLL_CLK_PARAMBLOK_t alt_pll_clk_paramblok =
{
    { 0, 320000000, 1200000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
    { 0, 320000000,  900000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
    { 0, 320000000,  800000000, ALT_ORIGINAL_GUARDBAND_VAL, 0 },
    { 0, 320000000, 1600000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 },
    { 0, 320000000, 1250000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 },
    { 0, 320000000, 1066000000, ALT_ORIGINAL_GUARDBAND_VAL, 1 }
};


        /* PLL counter frequency limits */
typedef struct ALT_PLL_CNTR_FREQMAX_s
{
    alt_freq_t       MainPLL_C0;         // Main PLL Counter 0 parameter block
    alt_freq_t       MainPLL_C1;         // Main PLL Counter 1 parameter block
    alt_freq_t       MainPLL_C2;         // Main PLL Counter 2 parameter block
    alt_freq_t       MainPLL_C3;         // Main PLL Counter 3 parameter block
    alt_freq_t       MainPLL_C4;         // Main PLL Counter 4 parameter block
    alt_freq_t       MainPLL_C5;         // Main PLL Counter 5 parameter block
    alt_freq_t       PeriphPLL_C0;       // Peripheral PLL Counter 0 parameter block
    alt_freq_t       PeriphPLL_C1;       // Peripheral PLL Counter 1 parameter block
    alt_freq_t       PeriphPLL_C2;       // Peripheral PLL Counter 2 parameter block
    alt_freq_t       PeriphPLL_C3;       // Peripheral PLL Counter 3 parameter block
    alt_freq_t       PeriphPLL_C4;       // Peripheral PLL Counter 4 parameter block
    alt_freq_t       PeriphPLL_C5;       // Peripheral PLL Counter 5 parameter block
    alt_freq_t       SDRAMPLL_C0;        // SDRAM PLL Counter 0 parameter block
    alt_freq_t       SDRAMPLL_C1;        // SDRAM PLL Counter 1 parameter block
    alt_freq_t       SDRAMPLL_C2;        // SDRAM PLL Counter 2 parameter block
    alt_freq_t       SDRAMPLL_C5;        // SDRAM PLL Counter 5 parameter block
} ALT_PLL_CNTR_FREQMAX_t;

//
// The following pll max frequency array statically defined must be recalculated each time 
// when powering up, by calling alt_clk_clkmgr_init()
//
// for 14.1 uboot preloader, the following values are calculated dynamically.
//
// Arrial 5
// alt_pll_cntr_maxfreq.MainPLL_C0   = 1050000000
// alt_pll_cntr_maxfreq.MainPLL_C1   =  350000000
// alt_pll_cntr_maxfreq.MainPLL_C2   =  262500000
// alt_pll_cntr_maxfreq.MainPLL_C3   =  350000000
// alt_pll_cntr_maxfreq.MainPLL_C4   =    2050781
// alt_pll_cntr_maxfreq.MainPLL_C5   =  116666666
// alt_pll_cntr_maxfreq.PeriphPLL_C0 =    1953125
// alt_pll_cntr_maxfreq.PeriphPLL_C1 =  250000000
// alt_pll_cntr_maxfreq.PeriphPLL_C2 =    1953125
// alt_pll_cntr_maxfreq.PeriphPLL_C3 =  200000000
// alt_pll_cntr_maxfreq.PeriphPLL_C4 =  200000000
// alt_pll_cntr_maxfreq.PeriphPLL_C5 =    1953125
// alt_pll_cntr_maxfreq.SDRAMPLL_C0  =  533333333
// alt_pll_cntr_maxfreq.SDRAMPLL_C1  = 1066666666
// alt_pll_cntr_maxfreq.SDRAMPLL_C2  =  533333333
// alt_pll_cntr_maxfreq.SDRAMPLL_C5  =  177777777

// Cyclone V 
// alt_pll_cntr_maxfreq.MainPLL_C0   =  925000000
// alt_pll_cntr_maxfreq.MainPLL_C1   =  370000000
// alt_pll_cntr_maxfreq.MainPLL_C2   =  462500000
// alt_pll_cntr_maxfreq.MainPLL_C3   =  370000000
// alt_pll_cntr_maxfreq.MainPLL_C4   =    3613281
// alt_pll_cntr_maxfreq.MainPLL_C5   =  123333333
// alt_pll_cntr_maxfreq.PeriphPLL_C0 =    1953125
// alt_pll_cntr_maxfreq.PeriphPLL_C1 =  250000000
// alt_pll_cntr_maxfreq.PeriphPLL_C2 =    1953125
// alt_pll_cntr_maxfreq.PeriphPLL_C3 =  200000000
// alt_pll_cntr_maxfreq.PeriphPLL_C4 =  200000000
// alt_pll_cntr_maxfreq.PeriphPLL_C5 =    1953125
// alt_pll_cntr_maxfreq.SDRAMPLL_C0  =  400000000
// alt_pll_cntr_maxfreq.SDRAMPLL_C1  =  800000000
// alt_pll_cntr_maxfreq.SDRAMPLL_C2  =  400000000
// alt_pll_cntr_maxfreq.SDRAMPLL_C5  =  133333333


/* Initializes the PLL Counter output maximum frequency block  */
static ALT_PLL_CNTR_FREQMAX_t alt_pll_cntr_maxfreq =
{
    800000000,    /* Main PLL Outputs */
    400000000,
    400000000,
    432000000,
    250000000,
    125000000,
    250000000,    /* Peripheral PLL Outputs */
    250000000,
    432000000,
    250000000,
    200000000,
    100000000,    /* SDRAM PLL Outputs */
    533000000,
    1066000000,
    533000000,
    200000000
};



        /* Maximum multiply, divide, and counter divisor values for each PLL */
#define     ALT_CLK_PLL_MULT_MAX        4095
#define     ALT_CLK_PLL_DIV_MAX         63
#define     ALT_CLK_PLL_CNTR_MAX        511


        /* Definitions for the reset request and reset acknowledge bits    */
        /* for each of the output counters for each of the PLLS            */
#define     ALT_CLK_PLL_RST_BIT_C0      0x00000001
#define     ALT_CLK_PLL_RST_BIT_C1      0x00000002
#define     ALT_CLK_PLL_RST_BIT_C2      0x00000004
#define     ALT_CLK_PLL_RST_BIT_C3      0x00000008
#define     ALT_CLK_PLL_RST_BIT_C4      0x00000010
#define     ALT_CLK_PLL_RST_BIT_C5      0x00000020


        /* These are the bits that deal with PLL lock and this macro */
        /* defines a mask to test for bits outside of these */
#define ALT_CLK_MGR_PLL_LOCK_BITS  (ALT_CLKMGR_INTREN_MAINPLLACHIEVED_CLR_MSK \
                                  & ALT_CLKMGR_INTREN_PERPLLACHIEVED_CLR_MSK \
                                  & ALT_CLKMGR_INTREN_SDRPLLACHIEVED_CLR_MSK \
                                  & ALT_CLKMGR_INTREN_MAINPLLLOST_CLR_MSK \
                                  & ALT_CLKMGR_INTREN_PERPLLLOST_CLR_MSK \
                                  & ALT_CLKMGR_INTREN_SDRPLLLOST_CLR_MSK)


// Undocumented register which determines clock dividers for main PLL C0, C1, and C2. These should be considered RO.
#define ALT_CLKMGR_ALTERA_OFST           0xe0
#define ALT_CLKMGR_ALTERA_MPUCLK_OFST    0x0
#define ALT_CLKMGR_ALTERA_MAINCLK_OFST   0x4
#define ALT_CLKMGR_ALTERA_DBGATCLK_OFST  0x8
#define ALT_CLKMGR_ALTERA_ADDR           ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ADDR) + ALT_CLKMGR_ALTERA_OFST))
#define ALT_CLKMGR_ALTERA_MPUCLK_ADDR    ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_MPUCLK_OFST))
#define ALT_CLKMGR_ALTERA_MAINCLK_ADDR   ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_MAINCLK_OFST))
#define ALT_CLKMGR_ALTERA_DBGATCLK_ADDR  ALT_CAST(void *, (ALT_CAST(char *, ALT_CLKMGR_ALTERA_ADDR) + ALT_CLKMGR_ALTERA_DBGATCLK_OFST))
#define ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(value)   (((value) & 0x000001ff) >> 0)
#define ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(value)  (((value) & 0x000001ff) >> 0)
#define ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(value) (((value) & 0x000001ff) >> 0)

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utility functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/****************************************************************************************/
/* alt_clk_mgr_wait() introduces a delay, not very exact, but very light in             */
/* implementation. Depending upon the optinization level, it will wait at least the     */
/* number of clock cycles specified in the cnt parameter, sometimes many more. The      */
/* reg parameter is set to a register or a memory location that was recently used (so   */
/* as to avoid accidently evicting a register and a recently-used cache line in favor   */
/* of one whose values are not actually needed.). The cnt parameter sets the number of  */
/* repeated volatile memory reads and so sets a minimum time delay measured in          */
/* mpu_clk cycles. If mpu_clk = osc1 clock (as in bypass mode), then this gives a       */
/* minimum osc1 clock cycle delay.                                                      */
/****************************************************************************************/

inline static void alt_clk_mgr_wait(void* reg, uint32_t cnt)
{
    for (; cnt ; cnt--)
    {
        (void) alt_read_word(reg);
    }
}

    /* Wait time constants */
    /* These values came from Section 4.9.4 of the HHP HPS-Clocking NPP document */
#define ALT_SW_MANAGED_CLK_WAIT_CTRDIV          30      /* 30 or more MPU clock cycles */
#define ALT_SW_MANAGED_CLK_WAIT_HWCTRDIV        40
#define ALT_SW_MANAGED_CLK_WAIT_BYPASS          30
#define ALT_SW_MANAGED_CLK_WAIT_SAFEREQ         30
#define ALT_SW_MANAGED_CLK_WAIT_SAFEEXIT        30
#define ALT_SW_MANAGED_CLK_WAIT_NANDCLK         8       /* 8 or more MPU clock cycles */


#define ALT_BYPASS_TIMEOUT_CNT      50
        // arbitrary number until i find more info
#define ALT_TIMEOUT_PHASE_SYNC      300
        // how many loops to wait for the SDRAM clock to come around
        // to zero and allow for writing a new divisor ratio to it

ALT_STATUS_CODE alt_clk_plls_settle_wait(void)
{
    int32_t     i = ALT_BYPASS_TIMEOUT_CNT;
    bool        nofini;

    do
    {
        nofini = alt_read_word(ALT_CLKMGR_STAT_ADDR) & ALT_CLKMGR_STAT_BUSY_SET_MSK;
    } while (nofini && i--);
            // wait until clocks finish transitioning and become stable again
    return (i > 0) ? ALT_E_SUCCESS : ALT_E_ERROR;
}

static ALT_STATUS_CODE alt_clk_pll_lock_wait(ALT_CLK_t pll, uint32_t timeout)
{
    uint32_t locked_mask = 0;

    if      (pll == ALT_CLK_MAIN_PLL)       { locked_mask = ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK; }
    else if (pll == ALT_CLK_PERIPHERAL_PLL) { locked_mask = ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK; }
    else if (pll == ALT_CLK_SDRAM_PLL)      { locked_mask = ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK; }
    else
    {
        return ALT_E_BAD_ARG;
    }

    do
    {
        uint32_t int_status = alt_read_word(ALT_CLKMGR_INTER_ADDR);
        if (int_status & locked_mask)
        {
            return ALT_E_SUCCESS;
        }

    } while (timeout--);

    return ALT_E_TMO;
}

        /* Useful utility macro for checking if two values  */
        /* are within a certain percentage of each other    */
#define  alt_within_delta(ref, neu, prcnt)  (((((neu) * 100)/(ref)) < (100 + (prcnt))) \
                                            && ((((neu) * 100)/(ref)) > (100 - (prcnt))))


        /* Flags to include or omit code sections */
// There are four cases where there is a small possibility of producing clock
// glitches. Code has been added from an abundance of caution to prevent
// these glitches. If further testing shows that this extra code is not necessary
// under any conditions, it may be easily eliminated by clearing these flags.

#define ALT_PREVENT_GLITCH_BYP              true
// for PLL entering or leaving bypass
#define ALT_PREVENT_GLITCH_EXSAFE           true
// for PLL exiting safe mode
#define ALT_PREVENT_GLITCH_CNTRRST          true
// resets counter phase
#define ALT_PREVENT_GLITCH_CHGC1            true
// for changing Main PLL C1 counter



/****************************************************************************************/
/* Bare-bones utility function used to make the somewhat complex writes to the PLL      */
/* counter registers (the clock dividers) easier. No parameter-checking or              */
/* error-checking, this is a static to this file and invisible to Doxygen.              */
/****************************************************************************************/

static void alt_clk_pllcounter_write(void* vcoaddr, void* stataddr, void* cntraddr,
        uint32_t val, uint32_t msk, uint32_t shift)
{
#if ALT_PREVENT_GLITCH_CNTRRST
    // this is here from an abundance of caution and it may not be necessary
    // to put the counter in reset for this write
    volatile uint32_t   temp;

    alt_setbits_word(vcoaddr, msk << shift);                // put the counter in reset
    do
    {
        temp = alt_read_word(stataddr);
    } while (!(temp & msk));

    alt_write_word(cntraddr, val);
    alt_clrbits_word(vcoaddr, msk << shift);                // release counter reset

#else       // should we find out that resetting the counters as above is unnecessary
    alt_write_word(cntraddr, val);
#endif
}


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Main Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


/****************************************************************************************/
/* alt_clk_lock_status_clear() clears assertions of one or more of the PLL lock status  */
/* conditions.                                                                          */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_lock_status_clear(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
{
    if (lock_stat_mask & (  ALT_CLKMGR_INTER_MAINPLLACHIEVED_CLR_MSK
                          & ALT_CLKMGR_INTER_PERPLLACHIEVED_CLR_MSK
                          & ALT_CLKMGR_INTER_SDRPLLACHIEVED_CLR_MSK
                          & ALT_CLKMGR_INTER_MAINPLLLOST_CLR_MSK
                          & ALT_CLKMGR_INTER_PERPLLLOST_CLR_MSK
                          & ALT_CLKMGR_INTER_SDRPLLLOST_CLR_MSK)
        )
    {
        return ALT_E_BAD_ARG;
    }
    else
    {
        alt_setbits_word(ALT_CLKMGR_INTER_ADDR, lock_stat_mask);
        return ALT_E_SUCCESS;
    }
}


/****************************************************************************************/
/* alt_clk_lock_status_get() returns the value of the PLL lock status conditions.       */
/****************************************************************************************/

uint32_t alt_clk_lock_status_get(void)
{
    return alt_read_word(ALT_CLKMGR_INTER_ADDR) & (  ALT_CLKMGR_INTER_MAINPLLACHIEVED_SET_MSK
                                                   | ALT_CLKMGR_INTER_PERPLLACHIEVED_SET_MSK
                                                   | ALT_CLKMGR_INTER_SDRPLLACHIEVED_SET_MSK
                                                   | ALT_CLKMGR_INTER_MAINPLLLOST_SET_MSK
                                                   | ALT_CLKMGR_INTER_PERPLLLOST_SET_MSK
                                                   | ALT_CLKMGR_INTER_SDRPLLLOST_SET_MSK
                                                   | ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK
                                                   | ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK
                                                   | ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK );
}


/****************************************************************************************/
/* alt_clk_pll_is_locked() returns ALT_E_TRUE if the designated PLL is currently        */
/* locked and ALT_E_FALSE if not.                                                       */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_pll_is_locked(ALT_CLK_t pll)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;

    if (pll == ALT_CLK_MAIN_PLL)
    {
        status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_MAINPLLLOCKED_SET_MSK)
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_PERPLLLOCKED_SET_MSK)
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        status = (alt_read_word(ALT_CLKMGR_INTER_ADDR) & ALT_CLKMGR_INTER_SDRPLLLOCKED_SET_MSK)
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    return status;
}


/****************************************************************************************/
/* alt_clk_safe_mode_clear() clears the safe mode status of the Clock Manager following */
/* a reset.                                                                             */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_safe_mode_clear(void)
{
    ALT_STATUS_CODE status = ALT_E_ERROR;
#if ALT_PREVENT_GLITCH_EXSAFE
    uint32_t        temp;

    temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
    alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp &
            (ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK));
                    // gate off l4MP and L4SP clocks (no matter their source)

    alt_setbits_word(ALT_CLKMGR_CTL_ADDR, ALT_CLKMGR_CTL_SAFEMOD_SET_MSK);
                    // clear safe mode bit
    status = alt_clk_plls_settle_wait();
    alt_replbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR,
            ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK | ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK,
            temp);
                    // gate l4MP and L4SP clocks back on if they were on previously

#else
    alt_setbits_word(ALT_CLKMGR_CTL_ADDR, ALT_CLKMGR_CTL_SAFEMOD_SET_MSK);
                    // clear safe mode bit
    status = alt_clk_plls_settle_wait();

#endif
    return status;
}


/****************************************************************************************/
/* alt_clk_is_in_safe_mode() returns whether the specified safe mode clock domain is in */
/* safe mode or not.                                                                    */
/****************************************************************************************/

bool alt_clk_is_in_safe_mode(ALT_CLK_SAFE_DOMAIN_t clk_domain)
{
    bool        ret = false;
    uint32_t    temp;

    if (clk_domain == ALT_CLK_DOMAIN_NORMAL)
    {
        ret = alt_read_word(ALT_CLKMGR_CTL_ADDR) & ALT_CLKMGR_CTL_SAFEMOD_SET_MSK;
                // is the main clock domain in safe mode?
    }
    else if (clk_domain == ALT_CLK_DOMAIN_DEBUG)
    {
        temp = alt_read_word(ALT_CLKMGR_DBCTL_ADDR);
        if (temp & ALT_CLKMGR_DBCTL_STAYOSC1_SET_MSK)
        {
            ret = true;                // is the debug clock domain in safe mode?
        }
        else if (temp & ALT_CLKMGR_DBCTL_ENSFMDWR_SET_MSK)
        {
            ret = alt_read_word(ALT_CLKMGR_CTL_ADDR) & ALT_CLKMGR_CTL_SAFEMOD_SET_MSK;
                    // is the debug clock domain following the main clock domain
                    // AND is the main clock domain in safe mode?
        }
    }
    return ret;
}

/****************************************************************************************/
/* alt_clk_pll_bypass_disable() disables bypass mode for the specified PLL, removing    */
/* it from bypass mode and allowing it to provide the output of the PLL to drive the    */
/* six main clocks.                                                                     */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_pll_bypass_disable(ALT_CLK_t pll)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;
    uint32_t        temp;
#if  ALT_PREVENT_GLITCH_BYP
    uint32_t        temp1;
    bool            restore_0 = false;
    bool            restore_1 = false;
#endif

    // this function should only be called after the selected PLL is locked
    if (alt_clk_pll_is_locked(pll) == ALT_E_TRUE)
    {
        if (pll == ALT_CLK_MAIN_PLL)
        {
#if  ALT_PREVENT_GLITCH_BYP
            // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
            // bypass state, then gate clock back on. FogBugz #63778
            temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
            temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
            {
                restore_0 = true;
            }
            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
            {
                restore_1 = true;
            }
            temp = temp1;
            if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
            if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
            if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
#endif

            // assert outresetall of main PLL
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
            alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp | ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_SET_MSK);

            // deassert outresetall of main PLL
            alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp & ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_CLR_MSK);

            alt_clk_plls_settle_wait();

            // remove bypass
            alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
            status = alt_clk_plls_settle_wait();

#if  ALT_PREVENT_GLITCH_BYP
            if (restore_0 || restore_1)
            {
                alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                            // wait a bit more before reenabling the L4MP and L4SP clocks
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1);
            }
#endif
        }

        else if (pll == ALT_CLK_PERIPHERAL_PLL)
        {
#if  ALT_PREVENT_GLITCH_BYP
            // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
            // bypass state, then gate clock back on. FogBugz #63778
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
            temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK))
            {
                    restore_0 = true;
            }
            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK))
            {
                    restore_1 = true;
            }
            temp = temp1;
            if (restore_0)  { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
            if (restore_1)  { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
            if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }
#endif

            // assert outresetall of Peripheral PLL
            temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
            alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp | ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_SET_MSK);
            alt_clk_plls_settle_wait();

            // deassert outresetall of main PLL
            alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp & ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_CLR_MSK);

            // remove bypass - don't think that there's any need to touch the bypass clock source
            alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_PERPLL_SET_MSK);
            status = alt_clk_plls_settle_wait();

#if  ALT_PREVENT_GLITCH_BYP
            if (restore_0 || restore_1)
            {
                alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                            // wait a bit more before reenabling the L4MP and L4SP clocks
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1);
            }
#endif
        }

        else if (pll == ALT_CLK_SDRAM_PLL)
        {
            // assert outresetall of SDRAM PLL
            temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
            alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp | ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK);

            // deassert outresetall of main PLL
            alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp & ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_CLR_MSK);
            alt_clk_plls_settle_wait();

            // remove bypass - don't think that there's any need to touch the bypass clock source
            alt_clrbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_SDRPLLSRC_SET_MSK);
            status = alt_clk_plls_settle_wait();
        }
    }
    else
    {
        status = ALT_E_ERROR;
    }

    return status;
}


/****************************************************************************************/
/* alt_clk_pll_bypass_enable() enable bypass mode for the specified PLL.                */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_pll_bypass_enable(ALT_CLK_t pll, bool use_input_mux)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;
    uint32_t        temp;
#ifdef  ALT_PREVENT_GLITCH_BYP
    uint32_t        temp1;
    bool            restore_0 = false;
    bool            restore_1 = false;
#endif

    if (pll == ALT_CLK_MAIN_PLL)
    {
        if (!use_input_mux)
        {
#ifdef  ALT_PREVENT_GLITCH_BYP
            // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
            // bypass state, then gate clock back on. FogBugz #63778
            temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
            temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
            {
                restore_0 = true;
            }
            if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
            {
                restore_1 = true;
            }
            temp = temp1;
            if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
            if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
            if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }

            alt_setbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
                        // no input mux select on main PLL

            status = alt_clk_plls_settle_wait();
                        // wait before reenabling the L4MP and L4SP clocks
            if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }

#else
            alt_setbits_word(ALT_CLKMGR_BYPASS_ADDR, ALT_CLKMGR_BYPASS_MAINPLL_SET_MSK);
                        // no input mux select on main PLL
            status = alt_clk_plls_settle_wait();

#endif
            status = ALT_E_SUCCESS;
        }
        else
        {
            status =  ALT_E_BAD_ARG;
        }
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
#ifdef  ALT_PREVENT_GLITCH_BYP
        // if L4MP or L4SP source is set to Peripheral PLL C1, gate it off before changing
        // bypass state, then gate clock back on. FogBugz #63778
        temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
        temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

        if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK))
        {
            restore_0 = true;
        }
        if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK))
        {
            restore_1 = true;
        }
        temp = temp1;
        if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
        if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
        if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }

        temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
                (ALT_CLKMGR_BYPASS_PERPLL_CLR_MSK & ALT_CLKMGR_BYPASS_PERPLLSRC_CLR_MSK);
        temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_PERPLL_SET_MSK |
                ALT_CLKMGR_BYPASS_PERPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_PERPLL_SET_MSK;
                    // set bypass bit and optionally the source select bit

        alt_write_word(ALT_CLKMGR_BYPASS_ADDR, temp);
        alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                    // wait a bit before reenabling the L4MP and L4SP clocks
        if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }

#else
        temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
                (ALT_CLKMGR_BYPASS_PERPLL_CLR_MSK & ALT_CLKMGR_BYPASS_PERPLLSRC_CLR_MSK);
        temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_PERPLL_SET_MSK |
                ALT_CLKMGR_BYPASS_PERPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_PERPLL_SET_MSK;
                    // set bypass bit and optionally the source select bit
#endif
        status = ALT_E_SUCCESS;
    }

    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_BYPASS_ADDR) &
                (ALT_CLKMGR_BYPASS_SDRPLL_CLR_MSK & ALT_CLKMGR_BYPASS_SDRPLLSRC_CLR_MSK);
        temp |= (use_input_mux) ? ALT_CLKMGR_BYPASS_SDRPLL_SET_MSK |
                ALT_CLKMGR_BYPASS_SDRPLLSRC_SET_MSK : ALT_CLKMGR_BYPASS_SDRPLL_SET_MSK;
                    // set bypass bit and optionally the source select bit
        alt_write_word(ALT_CLKMGR_BYPASS_ADDR, temp);
        status = ALT_E_SUCCESS;
    }
    return status;
}


/****************************************************************************************/
/* alt_clk_pll_is_bypassed() returns whether the specified PLL is in bypass or not.     */
/* Bypass is a special state where the PLL VCO and the C0-C5 counters are bypassed      */
/* and not in the circuit. Either the Osc1 clock input or the input chosen by the       */
/* input mux may be selected to be operational in the bypass state. All changes to      */
/* the PLL VCO must be made in bypass mode to avoid the potential of producing clock    */
/* glitches which may affect downstream clock dividers and peripherals.                 */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_pll_is_bypassed(ALT_CLK_t pll)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;

    if (pll == ALT_CLK_MAIN_PLL)
    {
        status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
                || ALT_CLKMGR_BYPASS_MAINPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
                || ALT_CLKMGR_BYPASS_PERPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        status = (ALT_CLKMGR_CTL_SAFEMOD_GET(alt_read_word(ALT_CLKMGR_CTL_ADDR))
                || ALT_CLKMGR_BYPASS_SDRPLL_GET(alt_read_word(ALT_CLKMGR_BYPASS_ADDR)))
                ? ALT_E_TRUE : ALT_E_FALSE;
    }
    return status;
}


/****************************************************************************************/
/* alt_clk_pll_source_get() returns the current input of the specified PLL.             */
/****************************************************************************************/

ALT_CLK_t alt_clk_pll_source_get(ALT_CLK_t pll)
{
    ALT_CLK_t      ret = ALT_CLK_UNKNOWN;
    uint32_t       temp;


    if (pll == ALT_CLK_MAIN_PLL)
    {
        ret = ALT_CLK_IN_PIN_OSC1;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        // three possible clock sources for the peripheral PLL
        temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
        {
            ret = ALT_CLK_IN_PIN_OSC1;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
        {
            ret = ALT_CLK_IN_PIN_OSC2;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
        {
            ret = ALT_CLK_F2H_PERIPH_REF;
        }
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        // three possible clock sources for the SDRAM PLL
        temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
        if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
        {
            ret = ALT_CLK_IN_PIN_OSC1;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
        {
            ret = ALT_CLK_IN_PIN_OSC2;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
        {
            ret = ALT_CLK_F2H_SDRAM_REF;
        }
    }
    return ret;
}

//
// alt_clk_clock_disable() disables the specified clock. Once the clock is disabled,
// its clock signal does not propagate to its clocked elements.
//
ALT_STATUS_CODE alt_clk_clock_disable(ALT_CLK_t clk)
{
    ALT_STATUS_CODE status = ALT_E_SUCCESS;

    switch (clk)
    {
        // For PLLs, put them in bypass mode.
    case ALT_CLK_MAIN_PLL:
    case ALT_CLK_PERIPHERAL_PLL:
    case ALT_CLK_SDRAM_PLL:
        status = alt_clk_pll_bypass_enable(clk, false);
        break;

        // Clocks that originate at the Main PLL.
    case ALT_CLK_L4_MAIN:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_SET_MSK);
        break;
    case ALT_CLK_L3_MP:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK);
        break;
    case ALT_CLK_L4_MP:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
        break;
    case ALT_CLK_L4_SP:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);
        break;
    case ALT_CLK_DBG_AT:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK);
        break;
    case ALT_CLK_DBG:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK);
        break;
    case ALT_CLK_DBG_TRACE:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK);
        break;
    case ALT_CLK_DBG_TIMER:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_SET_MSK);
        break;
    case ALT_CLK_CFG:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER0:
        alt_clrbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK);
        break;

        // Clocks that originate at the Peripheral PLL.
    case ALT_CLK_EMAC0:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK);
        break;
    case ALT_CLK_EMAC1:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK);
        break;
    case ALT_CLK_USB_MP:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK);
        break;
    case ALT_CLK_SPI_M:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK);
        break;
    case ALT_CLK_CAN0:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK);
        break;
    case ALT_CLK_CAN1:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK);
        break;
    case ALT_CLK_GPIO_DB:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER1:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK);
        break;
    case ALT_CLK_SDMMC:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
        break;
    case ALT_CLK_NAND_X:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
        alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
        // gate nand_clk off before nand_x_clk.
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
        break;
    case ALT_CLK_NAND:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
        break;
    case ALT_CLK_QSPI:
        alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
        break;

        // Clocks that originate at the SDRAM PLL.
    case ALT_CLK_DDR_DQS:
        alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK);
        break;
    case ALT_CLK_DDR_2X_DQS:
        alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK);
        break;
    case ALT_CLK_DDR_DQ:
        alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER2:
        alt_clrbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK);
        break;

    default:
        status = ALT_E_BAD_ARG;
        break;
    }

    return status;
}


//
// alt_clk_clock_enable() enables the specified clock. Once the clock is enabled, its
// clock signal propagates to its elements.
//
ALT_STATUS_CODE alt_clk_clock_enable(ALT_CLK_t clk)
{
    ALT_STATUS_CODE status = ALT_E_SUCCESS;

    switch (clk)
    {
        // For PLLs, take them out of bypass mode.
    case ALT_CLK_MAIN_PLL:
    case ALT_CLK_PERIPHERAL_PLL:
    case ALT_CLK_SDRAM_PLL:
        status = alt_clk_pll_bypass_disable(clk);
        break;

        // Clocks that originate at the Main PLL.
    case ALT_CLK_L4_MAIN:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_SET_MSK);
        break;
    case ALT_CLK_L3_MP:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK);
        break;
    case ALT_CLK_L4_MP:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
        break;
    case ALT_CLK_L4_SP:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);
        break;
    case ALT_CLK_DBG_AT:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK);
        break;
    case ALT_CLK_DBG:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK);
        break;
    case ALT_CLK_DBG_TRACE:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK);
        break;
    case ALT_CLK_DBG_TIMER:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_SET_MSK);
        break;
    case ALT_CLK_CFG:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER0:
        alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK);
        break;

        // Clocks that originate at the Peripheral PLL.
    case ALT_CLK_EMAC0:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK);
        break;
    case ALT_CLK_EMAC1:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK);
        break;
    case ALT_CLK_USB_MP:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK);
        break;
    case ALT_CLK_SPI_M:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK);
        break;
    case ALT_CLK_CAN0:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK);
        break;
    case ALT_CLK_CAN1:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK);
        break;
    case ALT_CLK_GPIO_DB:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER1:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK);
        break;
    case ALT_CLK_SDMMC:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
        break;
    case ALT_CLK_NAND_X:
        // implementation detail - should ALK_CLK_NAND be gated off here before enabling ALT_CLK_NAND_X?
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
        // implementation detail - should this wait be enforced here?
        alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
        break;
    case ALT_CLK_NAND:
        // enabling ALT_CLK_NAND always implies enabling ALT_CLK_NAND_X first
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
        alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
        // gate nand_x_clk on at least 8 MCU clocks before nand_clk
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);
        break;
    case ALT_CLK_QSPI:
        alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
        break;

        // Clocks that originate at the SDRAM PLL.
    case ALT_CLK_DDR_DQS:
        alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK);
        break;
    case ALT_CLK_DDR_2X_DQS:
        alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK);
        break;
    case ALT_CLK_DDR_DQ:
        alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK);
        break;
    case ALT_CLK_H2F_USER2:
        alt_setbits_word(ALT_CLKMGR_SDRPLL_EN_ADDR, ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK);
        break;

    default:
        status = ALT_E_BAD_ARG;
        break;
    }

    return status;
}

//
// alt_clk_is_enabled() returns whether the specified clock is enabled or not.
//
ALT_STATUS_CODE alt_clk_is_enabled(ALT_CLK_t clk)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;

    switch (clk)
    {
        // For PLLs, this function checks if the PLL is bypassed or not.
    case ALT_CLK_MAIN_PLL:
    case ALT_CLK_PERIPHERAL_PLL:
    case ALT_CLK_SDRAM_PLL:
        status = (alt_clk_pll_is_bypassed(clk) != ALT_E_TRUE);
        break;

        // These clocks are not gated, so must return a ALT_E_BAD_ARG type error.
    case ALT_CLK_MAIN_PLL_C0:
    case ALT_CLK_MAIN_PLL_C1:
    case ALT_CLK_MAIN_PLL_C2:
    case ALT_CLK_MAIN_PLL_C3:
    case ALT_CLK_MAIN_PLL_C4:
    case ALT_CLK_MAIN_PLL_C5:
    case ALT_CLK_MPU:
    case ALT_CLK_MPU_L2_RAM:
    case ALT_CLK_MPU_PERIPH:
    case ALT_CLK_L3_MAIN:
    case ALT_CLK_L3_SP:
    case ALT_CLK_DBG_BASE:
    case ALT_CLK_MAIN_QSPI:
    case ALT_CLK_MAIN_NAND_SDMMC:
    case ALT_CLK_PERIPHERAL_PLL_C0:
    case ALT_CLK_PERIPHERAL_PLL_C1:
    case ALT_CLK_PERIPHERAL_PLL_C2:
    case ALT_CLK_PERIPHERAL_PLL_C3:
    case ALT_CLK_PERIPHERAL_PLL_C4:
    case ALT_CLK_PERIPHERAL_PLL_C5:
    case ALT_CLK_SDRAM_PLL_C0:
    case ALT_CLK_SDRAM_PLL_C1:
    case ALT_CLK_SDRAM_PLL_C2:
    case ALT_CLK_SDRAM_PLL_C5:
        status = ALT_E_BAD_ARG;
        break;

        // Clocks that originate at the Main PLL.
    case ALT_CLK_L4_MAIN:
        status = (ALT_CLKMGR_MAINPLL_EN_L4MAINCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_L3_MP:
        status = (ALT_CLKMGR_MAINPLL_EN_L3MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_L4_MP:
        status = (ALT_CLKMGR_MAINPLL_EN_L4MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_L4_SP:
        status = (ALT_CLKMGR_MAINPLL_EN_L4SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DBG_AT:
        status = (ALT_CLKMGR_MAINPLL_EN_DBGATCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DBG:
        status = (ALT_CLKMGR_MAINPLL_EN_DBGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DBG_TRACE:
        status = (ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DBG_TIMER:
        status = (ALT_CLKMGR_MAINPLL_EN_DBGTMRCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_CFG:
        status = (ALT_CLKMGR_MAINPLL_EN_CFGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_H2F_USER0:
        status = (ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;

        // Clocks that originate at the Peripheral PLL.
    case ALT_CLK_EMAC0:
        status = (ALT_CLKMGR_PERPLL_EN_EMAC0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_EMAC1:
        status = (ALT_CLKMGR_PERPLL_EN_EMAC1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_USB_MP:
        status = (ALT_CLKMGR_PERPLL_EN_USBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_SPI_M:
        status = (ALT_CLKMGR_PERPLL_EN_SPIMCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_CAN0:
        status = (ALT_CLKMGR_PERPLL_EN_CAN0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_CAN1:
        status = (ALT_CLKMGR_PERPLL_EN_CAN1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_GPIO_DB:
        status = (ALT_CLKMGR_PERPLL_EN_GPIOCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_H2F_USER1:
        status = (ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;

        // Clocks that may originate at the Main PLL, the Peripheral PLL, or the FPGA.
    case ALT_CLK_SDMMC:
        status = (ALT_CLKMGR_PERPLL_EN_SDMMCCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_NAND_X:
        status = (ALT_CLKMGR_PERPLL_EN_NANDXCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_NAND:
        status = (ALT_CLKMGR_PERPLL_EN_NANDCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_QSPI:
        status = (ALT_CLKMGR_PERPLL_EN_QSPICLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;

        // Clocks that originate at the SDRAM PLL.
    case ALT_CLK_DDR_DQS:
        status = (ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DDR_2X_DQS:
        status = (ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_DDR_DQ:
        status = (ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;
    case ALT_CLK_H2F_USER2:
        status = (ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_GET(alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR)))
            ? ALT_E_TRUE : ALT_E_FALSE;
        break;

    default:
        status = ALT_E_BAD_ARG;
        break;

    }

    return status;
}

//
// alt_clk_source_get() gets the input reference clock source selection value for the
// specified clock or PLL.
//
ALT_CLK_t alt_clk_source_get(ALT_CLK_t clk)
{
    ALT_CLK_t ret = ALT_CLK_UNKNOWN;
    uint32_t  temp;

    switch (clk)
    {
        // Potential external clock sources.
        // these clock entities are their own source
    case ALT_CLK_IN_PIN_OSC1:
    case ALT_CLK_IN_PIN_OSC2:
    case ALT_CLK_F2H_PERIPH_REF:
    case ALT_CLK_F2H_SDRAM_REF:
    case ALT_CLK_IN_PIN_JTAG:
    case ALT_CLK_IN_PIN_ULPI0:
    case ALT_CLK_IN_PIN_ULPI1:
    case ALT_CLK_IN_PIN_EMAC0_RX:
    case ALT_CLK_IN_PIN_EMAC1_RX:
        ret = clk;
        break;

        // Phase-Locked Loops.
    case ALT_CLK_MAIN_PLL:
    case ALT_CLK_OSC1:
        ret = ALT_CLK_IN_PIN_OSC1;
        break;
    case ALT_CLK_PERIPHERAL_PLL:
        ret = alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL);
        break;
    case ALT_CLK_SDRAM_PLL:
        ret = alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL);
        break;

        // Main Clock Group.
    case ALT_CLK_MAIN_PLL_C0:
    case ALT_CLK_MAIN_PLL_C1:
    case ALT_CLK_MAIN_PLL_C2:
    case ALT_CLK_MAIN_PLL_C3:
    case ALT_CLK_MAIN_PLL_C4:
    case ALT_CLK_MAIN_PLL_C5:
        // check bypass, return either osc1 or PLL ID
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL;
        break;

    case ALT_CLK_MPU_PERIPH:
    case ALT_CLK_MPU_L2_RAM:
    case ALT_CLK_MPU:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C0;
        break;

    case ALT_CLK_L4_MAIN:
    case ALT_CLK_L3_MAIN:
    case ALT_CLK_L3_MP:
    case ALT_CLK_L3_SP:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
        break;

    case ALT_CLK_L4_MP:
        // read the state of the L4_mp source bit
        if ((ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR)))
            == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_MAINPLL)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
                ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
        }
        else
        {
            // if the clock comes from periph_base_clk
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
                alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL_C4;
        }
        break;

    case ALT_CLK_L4_SP:
        // read the state of the source bit
        if ((ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR)))
            == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_MAINPLL)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
                ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C1;
        }
        else
        {
            // if the clock comes from periph_base_clk
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
                alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL_C4;
        }
        break;

    case ALT_CLK_DBG_BASE:
    case ALT_CLK_DBG_AT:
    case ALT_CLK_DBG_TRACE:
    case ALT_CLK_DBG_TIMER:
    case ALT_CLK_DBG:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C2;
        break;
    case ALT_CLK_MAIN_QSPI:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C3;
        break;
    case ALT_CLK_MAIN_NAND_SDMMC:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C4;
        break;
    case ALT_CLK_CFG:
    case ALT_CLK_H2F_USER0:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
            ALT_CLK_OSC1 : ALT_CLK_MAIN_PLL_C5;
        break;

        // Peripherals Clock Group
    case ALT_CLK_PERIPHERAL_PLL_C0:
    case ALT_CLK_PERIPHERAL_PLL_C1:
    case ALT_CLK_PERIPHERAL_PLL_C2:
    case ALT_CLK_PERIPHERAL_PLL_C3:
    case ALT_CLK_PERIPHERAL_PLL_C4:
    case ALT_CLK_PERIPHERAL_PLL_C5:
        // if the clock comes from periph_base_clk
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) : ALT_CLK_PERIPHERAL_PLL;
        break;

    case ALT_CLK_EMAC0:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C0;
        break;

    case ALT_CLK_EMAC1:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C1;
        break;

    case ALT_CLK_USB_MP:
    case ALT_CLK_SPI_M:
    case ALT_CLK_CAN0:
    case ALT_CLK_CAN1:
    case ALT_CLK_GPIO_DB:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C4;
        break;

    case ALT_CLK_H2F_USER1:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C5;
        break;

    case ALT_CLK_SDMMC:
        temp = ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK)
        {
            ret = ALT_CLK_F2H_PERIPH_REF;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
                ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C4;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
                alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C3;
        }
        break;

    case ALT_CLK_NAND_X:
    case ALT_CLK_NAND:
        temp = ALT_CLKMGR_PERPLL_SRC_NAND_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK)
        {
            ret = ALT_CLK_F2H_PERIPH_REF;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
                ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C4;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
                alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C3;
        }
        break;

    case ALT_CLK_QSPI:
        temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK)
        {
            ret = ALT_CLK_F2H_PERIPH_REF;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE) ?
                ALT_CLK_IN_PIN_OSC1 : ALT_CLK_MAIN_PLL_C3;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
        {
            ret = (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE) ?
                alt_clk_pll_source_get(ALT_CLK_PERIPHERAL_PLL) :  ALT_CLK_PERIPHERAL_PLL_C2;
        }
        break;

        // SDRAM Clock Group
    case ALT_CLK_SDRAM_PLL_C0:
    case ALT_CLK_SDRAM_PLL_C1:
    case ALT_CLK_SDRAM_PLL_C2:
    case ALT_CLK_SDRAM_PLL_C3:
    case ALT_CLK_SDRAM_PLL_C4:
    case ALT_CLK_SDRAM_PLL_C5:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL;
        break;
    case ALT_CLK_DDR_DQS:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C0;
        break;
    case ALT_CLK_DDR_2X_DQS:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C1;
        break;
    case ALT_CLK_DDR_DQ:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C2;
        break;
    case ALT_CLK_H2F_USER2:
        ret = (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE) ?
            alt_clk_pll_source_get(ALT_CLK_SDRAM_PLL) :  ALT_CLK_SDRAM_PLL_C5;
        break;

        // Clock Output Pins
    case ALT_CLK_OUT_PIN_EMAC0_TX:
    case ALT_CLK_OUT_PIN_EMAC1_TX:
    case ALT_CLK_OUT_PIN_SDMMC:
    case ALT_CLK_OUT_PIN_I2C0_SCL:
    case ALT_CLK_OUT_PIN_I2C1_SCL:
    case ALT_CLK_OUT_PIN_I2C2_SCL:
    case ALT_CLK_OUT_PIN_I2C3_SCL:
    case ALT_CLK_OUT_PIN_SPIM0:
    case ALT_CLK_OUT_PIN_SPIM1:
    case ALT_CLK_OUT_PIN_QSPI:
        ret = ALT_CLK_UNKNOWN;
        break;

    default:
        ret = ALT_CLK_UNKNOWN;
        break;
    }

    return ret;
}

//
// alt_clk_source_set() sets the specified clock's input reference clock source
// selection to the specified input. It does not handle gating the specified clock
// off and back on, those are covered in other functions in this API, but it does
// verify that the clock is off before changing the divider or PLL. Note that the PLL
// must have regained phase-lock before being the bypass is disabled.
//
ALT_STATUS_CODE alt_clk_source_set(ALT_CLK_t clk, ALT_CLK_t ref_clk)
{
    ALT_STATUS_CODE status = ALT_E_SUCCESS;
    uint32_t        temp;

    if (ALT_CLK_MAIN_PLL == clk)
    {
        if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
        {
            // ret = ALT_E_SUCCESS;
        }
        else
        {
            status = ALT_E_BAD_ARG;
        }
    }
    else if (ALT_CLK_PERIPHERAL_PLL == clk)
    {
        // the PLL must be bypassed before getting here
        temp  = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
        temp &= ALT_CLKMGR_PERPLL_VCO_PSRC_CLR_MSK;

        if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1);
            alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_IN_PIN_OSC2)
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2);
            alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF);
            alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if (ALT_CLK_SDRAM_PLL == clk)
    {
        temp  = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
        temp &= ALT_CLKMGR_SDRPLL_VCO_SSRC_CLR_MSK;

        if ((ref_clk == ALT_CLK_IN_PIN_OSC1) || (ref_clk == ALT_CLK_OSC1))
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1);
            alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_IN_PIN_OSC2)
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2);
            alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_F2H_SDRAM_REF)
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF);
            alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if ( ALT_CLK_L4_MP == clk)
    {
        // clock is gated off
        if (ref_clk == ALT_CLK_MAIN_PLL_C1)
        {
            alt_clrbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK);
        }
        else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C4)
        {
            alt_setbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if ( ALT_CLK_L4_SP == clk)
    {
        if (ref_clk == ALT_CLK_MAIN_PLL_C1)
        {
            alt_clrbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK);
        }
        else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C4)
        {
            alt_setbits_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if (ALT_CLK_SDMMC == clk)
    {
        temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
        temp &= ALT_CLKMGR_PERPLL_SRC_SDMMC_CLR_MSK;

        if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if ((ref_clk == ALT_CLK_MAIN_PLL_C4) || (ref_clk == ALT_CLK_MAIN_NAND_SDMMC))
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C3)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_SDMMC_SET(ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if ((ALT_CLK_NAND_X == clk) || ( ALT_CLK_NAND == clk))
    {
        temp = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
        temp &= ALT_CLKMGR_PERPLL_SRC_NAND_CLR_MSK;

        if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if ((ref_clk == ALT_CLK_MAIN_PLL_C4) || (ref_clk == ALT_CLK_MAIN_NAND_SDMMC))
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C3)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_NAND_SET(ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }
    else if (ALT_CLK_QSPI == clk)
    {
        temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
        temp &= ALT_CLKMGR_PERPLL_SRC_QSPI_CLR_MSK;

        if (ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if ((ref_clk == ALT_CLK_MAIN_PLL_C3) || (ref_clk == ALT_CLK_MAIN_QSPI))
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else if (ref_clk == ALT_CLK_PERIPHERAL_PLL_C2)
        {
            temp |= ALT_CLKMGR_PERPLL_SRC_QSPI_SET(ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK);
            alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, temp);
        }
        else
        {
            status = ALT_E_INV_OPTION;
        }
    }

    return status;
}

//
// alt_clk_ext_clk_freq_set() specifies the frequency of the external clock source as
// a measure of Hz. This value is stored in a static array and used for calculations.
// The supplied frequency should be within the Fmin and Fmax values allowed for the
// external clock source.
//
ALT_STATUS_CODE alt_clk_ext_clk_freq_set(ALT_CLK_t clk, alt_freq_t freq)
{
    ALT_STATUS_CODE status = ALT_E_BAD_ARG;

    if ((clk == ALT_CLK_IN_PIN_OSC1) || (clk == ALT_CLK_OSC1))      // two names for one input
    {
        if ((freq >= alt_ext_clk_paramblok.clkosc1.freqmin) && (freq <= alt_ext_clk_paramblok.clkosc1.freqmax))
        {
            alt_ext_clk_paramblok.clkosc1.freqcur = freq;
            status = ALT_E_SUCCESS;
        }
        else
        {
            status = ALT_E_ARG_RANGE;
        }
    }
    else if (clk == ALT_CLK_IN_PIN_OSC2)                            // the other clock input pin
    {
        if ((freq >= alt_ext_clk_paramblok.clkosc2.freqmin) && (freq <= alt_ext_clk_paramblok.clkosc2.freqmax))
        {
            alt_ext_clk_paramblok.clkosc2.freqcur = freq;
            status = ALT_E_SUCCESS;
        }
        else
        {
            status = ALT_E_ARG_RANGE;
        }
    }
    else if (clk == ALT_CLK_F2H_PERIPH_REF)                         // clock from the FPGA
    {
        if ((freq >= alt_ext_clk_paramblok.periph.freqmin) && (freq <= alt_ext_clk_paramblok.periph.freqmax))
        {
            alt_ext_clk_paramblok.periph.freqcur = freq;
            status = ALT_E_SUCCESS;
        }
        else
        {
            status = ALT_E_ARG_RANGE;
        }
    }
    else if (clk == ALT_CLK_F2H_SDRAM_REF)                          // clock from the FPGA SDRAM
    {
        if ((freq >= alt_ext_clk_paramblok.sdram.freqmin) && (freq <= alt_ext_clk_paramblok.sdram.freqmax))
        {
            alt_ext_clk_paramblok.sdram.freqcur = freq;
            status = ALT_E_SUCCESS;
        }
        else
        {
            status = ALT_E_ARG_RANGE;
        }
    }
    else
    {
        status = ALT_E_BAD_ARG;
    }

    return status;
}


//
// alt_clk_ext_clk_freq_get returns the frequency of the external clock source as
// a measure of Hz. This value is stored in a static array.
//
alt_freq_t alt_clk_ext_clk_freq_get(ALT_CLK_t clk)
{
    uint32_t ret = 0;

    if ((clk == ALT_CLK_IN_PIN_OSC1) || (clk == ALT_CLK_OSC1))      // two names for one input
    {
        ret = alt_ext_clk_paramblok.clkosc1.freqcur;
    }
    else if (clk == ALT_CLK_IN_PIN_OSC2)
    {
        ret = alt_ext_clk_paramblok.clkosc2.freqcur;
    }
    else if (clk == ALT_CLK_F2H_PERIPH_REF)                         // clock from the FPGA
    {
        ret = alt_ext_clk_paramblok.periph.freqcur;
    }
    else if (clk == ALT_CLK_F2H_SDRAM_REF)                         // clock from the FPGA
    {
        ret = alt_ext_clk_paramblok.sdram.freqcur;
    }
    return ret;
}


//
// alt_clk_pll_cfg_get() returns the current PLL configuration.
//
ALT_STATUS_CODE alt_clk_pll_cfg_get(ALT_CLK_t pll, ALT_CLK_PLL_CFG_t * pll_cfg)
{
    ALT_STATUS_CODE        ret = ALT_E_ERROR;                  // return value
    uint32_t               temp;                               // temp variable
 
    if (pll_cfg == NULL)
    {
		ret = ALT_E_BAD_ARG;
		return ret;
    }

    if (pll == ALT_CLK_MAIN_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
        pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
        pll_cfg->mult = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
        pll_cfg->div = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);

        // Get the C0-C5 divider values:
        pll_cfg->cntrs[0] = ALT_CLKMGR_MAINPLL_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR));
        // C0 - mpu_clk

        pll_cfg->cntrs[1] = ALT_CLKMGR_MAINPLL_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR));
        // C1 - main_clk

        pll_cfg->cntrs[2] = ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR));
        // C2 - dbg_base_clk

        pll_cfg->cntrs[3] = ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR));
        // C3 - main_qspi_clk

        pll_cfg->cntrs[4] = ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR));
        // C4 - main_nand_sdmmc_clk

        pll_cfg->cntrs[5] = ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR));
        // C5 - cfg_s2f_user0_clk aka cfg_h2f_user0_clk

        // The Main PLL C0-C5 outputs have no phase shift capabilities :
        pll_cfg->pshift[0] = pll_cfg->pshift[1] = pll_cfg->pshift[2] =
            pll_cfg->pshift[3] = pll_cfg->pshift[4] = pll_cfg->pshift[5] = 0;
        ret = ALT_E_SUCCESS;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
        if (temp <= 2)
        {
            if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
            {
                pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
            }
            else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
            {
                pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC2;
            }
            else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
            {
                pll_cfg->ref_clk = ALT_CLK_F2H_PERIPH_REF;
            }

            temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
            pll_cfg->mult = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
            pll_cfg->div = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);

            // Get the C0-C5 divider values:
            pll_cfg->cntrs[0] = ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR));
            // C0 - emac0_clk

            pll_cfg->cntrs[1] = ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR));
            // C1 - emac1_clk

            pll_cfg->cntrs[2] = ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR));
            // C2 - periph_qspi_clk

            pll_cfg->cntrs[3] = ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR));
            // C3 - periph_nand_sdmmc_clk

            pll_cfg->cntrs[4] = ALT_CLKMGR_PERPLL_PERBASECLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR));
            // C4 - periph_base_clk

            pll_cfg->cntrs[5] = ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR));
            // C5 - s2f_user1_clk

            // The Peripheral PLL C0-C5 outputs have no phase shift capabilities :
            pll_cfg->pshift[0] = pll_cfg->pshift[1] = pll_cfg->pshift[2] =
                pll_cfg->pshift[3] = pll_cfg->pshift[4] = pll_cfg->pshift[5] = 0;
            ret = ALT_E_SUCCESS;
        }
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
        if (temp <= 2)
        {
            if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
            {
                pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC1;
            }
            else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
            {
                pll_cfg->ref_clk = ALT_CLK_IN_PIN_OSC2;
            }
            else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
            {
                pll_cfg->ref_clk = ALT_CLK_F2H_SDRAM_REF;
            }

            pll_cfg->mult = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
            pll_cfg->div = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));

            // Get the C0-C5 divider values:
            pll_cfg->cntrs[0]  = ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR));
            pll_cfg->pshift[0] = ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR));
            // C0  - ddr_dqs_clk

            pll_cfg->cntrs[1]  = ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR));
            pll_cfg->pshift[1] = ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR));
            // C1  - ddr_2x_dqs_clk

            pll_cfg->cntrs[2]  = ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR));
            pll_cfg->pshift[2] = ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR));
            // C2  - ddr_dq_clk

            pll_cfg->cntrs[3]  = pll_cfg->cntrs[4] = pll_cfg->pshift[3] = pll_cfg->pshift[4] = 0;
            // C3  & C4 outputs don't exist on the SDRAM PLL

            pll_cfg->cntrs[5]  = ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR));
            pll_cfg->pshift[5] = ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR));
            // C5  - s2f_user2_clk or h2f_user2_clk

            ret = ALT_E_SUCCESS;
        }
    }

    return ret;
}


//
// alt_clk_pll_cfg_set() sets the PLL configuration using the configuration parameters
// specified in pll_cfg.
//
ALT_STATUS_CODE alt_clk_pll_cfg_set(ALT_CLK_t pll, const ALT_CLK_PLL_CFG_t * pll_cfg)
{
    if (pll_cfg == NULL)
    {
		return ALT_E_BAD_ARG;
    }

    if (alt_clk_pll_is_bypassed(pll) != ALT_E_TRUE)         // safe to write the PLL registers?
    {
        return ALT_E_ERROR;
    }

    ALT_STATUS_CODE ret = ALT_E_ERROR;
    uint32_t        temp;

    if (pll == ALT_CLK_MAIN_PLL)
    {
        temp  = (ALT_CLKMGR_MAINPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_MAINPLL_VCO_DENOM_CLR_MSK)
            & alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
        temp |= ALT_CLKMGR_MAINPLL_VCO_NUMER_SET(pll_cfg->mult) |
            ALT_CLKMGR_MAINPLL_VCO_DENOM_SET(pll_cfg->div);

        alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, temp);
        alt_write_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR,           pll_cfg->cntrs[0]);
        alt_write_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR,          pll_cfg->cntrs[1]);
        alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR,         pll_cfg->cntrs[2]);
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,      pll_cfg->cntrs[3]);
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, pll_cfg->cntrs[4]);
        alt_write_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,   pll_cfg->cntrs[5]);
        ret = ALT_E_SUCCESS;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        temp =  ALT_CLKMGR_PERPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_PERPLL_VCO_DENOM_CLR_MSK
            & ALT_CLKMGR_PERPLL_VCO_PSRC_CLR_MSK;
        temp &= alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
        temp |= ALT_CLKMGR_PERPLL_VCO_NUMER_SET(pll_cfg->mult)
            | ALT_CLKMGR_PERPLL_VCO_DENOM_SET(pll_cfg->div);

        if ((pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC1) || (pll_cfg->ref_clk == ALT_CLK_OSC1))
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1);
        }
        else if (pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC2)
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2);
        }
        else if (pll_cfg->ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_PERPLL_VCO_PSRC_SET(ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF);
        }
        else
        {
            return ret;
        }

        alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, temp);
        alt_write_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,        pll_cfg->cntrs[0]);
        alt_write_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,        pll_cfg->cntrs[1]);
        alt_write_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,      pll_cfg->cntrs[2]);
        alt_write_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, pll_cfg->cntrs[3]);
        alt_write_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,      pll_cfg->cntrs[4]);
        alt_write_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,     pll_cfg->cntrs[5]);
        ret = ALT_E_SUCCESS;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        // write the SDRAM PLL VCO Counter -----------------------------
        temp =  ALT_CLKMGR_SDRPLL_VCO_NUMER_CLR_MSK & ALT_CLKMGR_SDRPLL_VCO_DENOM_CLR_MSK
            & ALT_CLKMGR_SDRPLL_VCO_SSRC_CLR_MSK;           // make a mask
        temp &= alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
        temp |= ALT_CLKMGR_SDRPLL_VCO_NUMER_SET(pll_cfg->mult)
            | ALT_CLKMGR_SDRPLL_VCO_DENOM_SET(pll_cfg->div)
            | ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK;
        // setting this bit aligns the output phase of the counters and prevents
        // glitches and too-short clock periods when restarting.
        // this bit is cleared at the end of this routine

        if ((pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC1) || (pll_cfg->ref_clk == ALT_CLK_OSC1))
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1);
        }
        else if (pll_cfg->ref_clk == ALT_CLK_IN_PIN_OSC2)
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2);
        }
        else if (pll_cfg->ref_clk == ALT_CLK_F2H_PERIPH_REF)
        {
            temp |= ALT_CLKMGR_SDRPLL_VCO_SSRC_SET(ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF);
        }
        else
        {
            return ret;
        }

        alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, temp);

        // write the SDRAM PLL C0 Divide Counter -----------------------------
        temp =  ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET(pll_cfg->cntrs[0])
            | ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_SET(pll_cfg->pshift[0]);

        alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
                                 ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR, temp,
                                 ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDRDQSCLK_PHASE_SET_MSK,
                                 ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_LSB);

        // write the SDRAM PLL C1 Divide Counter -----------------------------
        if (ret == ALT_E_SUCCESS)
        {
            temp =  ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET(pll_cfg->cntrs[1])
                | ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_SET(pll_cfg->pshift[1]);
            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR, temp,
                                     ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_PHASE_SET_MSK,
                                     ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_LSB);
        }

        // write the SDRAM PLL C2 Divide Counter -----------------------------
        if (ret == ALT_E_SUCCESS)
        {
            temp =  ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET(pll_cfg->cntrs[2])
                | ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_SET(pll_cfg->pshift[2]);
            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR, temp,
                                     ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_DDRDQCLK_PHASE_SET_MSK,
                                     ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_LSB);
        }

        // write the SDRAM PLL C5 Divide Counter -----------------------------
        if (ret == ALT_E_SUCCESS)
        {
            temp =  ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET(pll_cfg->cntrs[2])
                | ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_SET(pll_cfg->pshift[2]);
            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR, temp,
                                     ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET_MSK | ALT_CLKMGR_SDRPLL_S2FUSER2CLK_PHASE_SET_MSK,
                                     ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_LSB);
        }

        if (ret == ALT_E_SUCCESS)
        {
            alt_clrbits_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_SET_MSK);
            // allow the phase multiplexer and output counter to leave reset
        }
    }

    return ret;
}


//
// alt_clk_pll_vco_cfg_get() returns the current PLL VCO frequency configuration.
//
ALT_STATUS_CODE alt_clk_pll_vco_cfg_get(ALT_CLK_t pll, uint32_t * mult, uint32_t * div)
{
    ALT_STATUS_CODE status = ALT_E_SUCCESS;
    uint32_t        temp;

    if ( (mult == NULL) || (div == NULL) )
    {
		return ALT_E_BAD_ARG;
    }

    if (pll == ALT_CLK_MAIN_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
        *mult = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp) + 1;
        *div  = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp) + 1;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
        *mult = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp) + 1;
        *div  = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp) + 1;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
        *mult = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp) + 1;
        *div  = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp) + 1;
    }
    else
    {
        status = ALT_E_ERROR;
    }

    return status;
}


/****************************************************************************************/
/* This enum enumerates a set of possible change methods that are available for use by  */
/* alt_clk_pll_vco_cfg_set() to change VCO parameter settings.                          */
/****************************************************************************************/

typedef enum ALT_CLK_PLL_VCO_CHG_METHOD_e
{
    ALT_VCO_CHG_NONE_VALID      = 0,            /*  No valid method to  change PLL
                                                 *  VCO was found                       */
    ALT_VCO_CHG_NOCHANGE        = 0x00000001,   /*  Proposed new VCO values are the
                                                 *  same as the old values              */
    ALT_VCO_CHG_NUM             = 0x00000002,   /*  Can change the VCO multiplier
                                                 *  alone                               */
    ALT_VCO_CHG_NUM_BYP         = 0x00000004,   /*  A VCO multiplier-only change will
                                                 *  require putting the PLL in bypass   */
    ALT_VCO_CHG_DENOM           = 0x00000008,   /*  Can change the VCO divider
                                                 *  alone                               */
    ALT_VCO_CHG_DENOM_BYP       = 0x00000010,   /*  A VCO divider-only change will
                                                 *  require putting the PLL in bypass   */
    ALT_VCO_CHG_NUM_DENOM       = 0x00000020,   /*  Can change the clock multiplier
                                                 *  first. then the clock divider       */
    ALT_VCO_CHG_NUM_DENOM_BYP   = 0x00000040,   /*  Changing the clock multiplier first.
                                                 *  then the clock divider will
                                                 *  require putting the PLL in bypass   */
    ALT_VCO_CHG_DENOM_NUM       = 0x00000080,   /*  Can change the clock divider first.
                                                 *  then the clock multiplier           */
    ALT_VCO_CHG_DENOM_NUM_BYP   = 0x00000100    /*  Changing the clock divider first.
                                                 *  then the clock multiplier will
                                                 *  require putting the PLL in bypass   */
} ALT_CLK_PLL_VCO_CHG_METHOD_t;



/****************************************************************************************/
/* alt_clk_pll_vco_chg_methods_get() determines which possible methods to change the    */
/* VCO are allowed within the limits set by the maximum PLL multiplier and divider      */
/* values and by the upper and lower frequency limits of the PLL, and also determines   */
/* whether each of these changes can be made without the PLL losing lock, which         */
/* requires the PLL to be bypassed before making changes, and removed from bypass state */
/* afterwards.                                                                          */
/****************************************************************************************/


#define ALT_CLK_PLL_VCO_CHG_METHOD_TEST_MODE        false
    // used for testing writes to the PLL VCOs



static ALT_CLK_PLL_VCO_CHG_METHOD_t alt_clk_pll_vco_chg_methods_get(ALT_CLK_t pll,
        uint32_t mult, uint32_t div )
{
#if ALT_CLK_PLL_VCO_CHG_METHOD_TEST_MODE

    // used for testing
    return ALT_VCO_CHG_NOCHANGE;

#else

    // check PLL max value limits
    if (   (mult == 0) || (mult > ALT_CLK_PLL_MULT_MAX)
        || (div  == 0) || (div  > ALT_CLK_PLL_DIV_MAX)
       )
    {
        return ALT_VCO_CHG_NONE_VALID;
    }

    ALT_CLK_PLL_VCO_CHG_METHOD_t    ret = ALT_VCO_CHG_NONE_VALID;
    uint32_t                        temp;
    uint32_t                        numer;
    uint32_t                        denom;
    uint32_t                        freqmax;
    uint32_t                        freqmin;
    uint32_t                        inputfreq;
    uint32_t                        guardband;
    bool                            numerchg = false;
    bool                            denomchg = false;
    bool                            within_gb;

    // gather data values according to PLL
    if (pll == ALT_CLK_MAIN_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);

        numer = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);

        freqmax   = alt_pll_clk_paramblok.MainPLL_800.freqmax;
        freqmin   = alt_pll_clk_paramblok.MainPLL_800.freqmin;
        guardband = alt_pll_clk_paramblok.MainPLL_800.guardband;

        inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
    }

    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);

        numer = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);

        freqmax   = alt_pll_clk_paramblok.PeriphPLL_800.freqmax;
        freqmin   = alt_pll_clk_paramblok.PeriphPLL_800.freqmin;
        guardband = alt_pll_clk_paramblok.PeriphPLL_800.guardband;

        temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(temp);
        if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
        {
            inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
        {
            inputfreq = alt_ext_clk_paramblok.clkosc2.freqcur;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
        {
            inputfreq = alt_ext_clk_paramblok.periph.freqcur;
        }
        else
        {
            return ret;
        }
    }

    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);

        numer = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp);

        freqmax   = alt_pll_clk_paramblok.SDRAMPLL_800.freqmax;
        freqmin   = alt_pll_clk_paramblok.SDRAMPLL_800.freqmin;
        guardband = alt_pll_clk_paramblok.SDRAMPLL_800.guardband;

        temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(temp);
        if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
        {
            inputfreq = alt_ext_clk_paramblok.clkosc1.freqcur;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
        {
            inputfreq = alt_ext_clk_paramblok.clkosc2.freqcur;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
        {
            inputfreq = alt_ext_clk_paramblok.sdram.freqcur;
        }
        else
        {
            return ret;
        }
    }
    else
    {
        return ret;
    }

    temp = mult * (inputfreq / div);
    if ((temp <= freqmax) && (temp >= freqmin))     // are the final values within frequency limits?
    {
        numer++;
        denom++;
        numerchg = (mult != numer);
        denomchg = (div != denom);

        if (!numerchg && !denomchg)
        {
            ret = ALT_VCO_CHG_NOCHANGE;
        }
        else if (numerchg && !denomchg)
        {
            within_gb = alt_within_delta(numer, mult, guardband);
            // check if change is within the guardband limits
            temp = mult * (inputfreq / denom);
            if ((temp <= freqmax) && (temp >= freqmin))
            {
                ret = ALT_VCO_CHG_NUM;
                if (!within_gb) ret |= ALT_VCO_CHG_NUM_BYP;
            }
        }
        else if (!numerchg && denomchg)
        {
            within_gb = alt_within_delta(denom, div, guardband);
            temp = numer * (inputfreq / div);
            if ((temp <= freqmax) && (temp >= freqmin))
            {
                ret = ALT_VCO_CHG_DENOM;
                if (!within_gb)
                {
                    ret |= ALT_VCO_CHG_DENOM_BYP;
                }
            }
        }
        else    //numerchg && denomchg
        {
            within_gb = alt_within_delta(numer, mult, guardband);
            temp = mult * (inputfreq / denom);
            if ((temp <= freqmax) && (temp >= freqmin))
            {
                ret = ALT_VCO_CHG_NUM_DENOM;
                if (!within_gb)
                {
                    ret |= ALT_VCO_CHG_NUM_DENOM_BYP;
                }
            }
            within_gb = alt_within_delta(denom, div, guardband);
            temp = numer * (inputfreq / div);
            if ((temp <= freqmax) && (temp >= freqmin))
            {
                ret = ALT_VCO_CHG_DENOM_NUM;
                if (!within_gb)
                {
                    ret |= ALT_VCO_CHG_DENOM_NUM_BYP;
                }
            }
        }
    }

    return ret;
#endif
}


/****************************************************************************************/
/* alt_clk_pll_vco_cfg_set() sets the PLL VCO frequency configuration using the         */
/* supplied multiplier and divider arguments. alt_clk_pll_vco_chg_methods_get()         */
/* determines which methods are allowed by the limits set by the maximum multiplier     */
/* and divider values and by the upper and lower frequency limits of the PLL, and also  */
/* determines whether these changes can be made without requiring the PLL to be         */
/* bypassed. alt_clk_pll_vco_cfg_set() then carries out the actions required to effect  */
/* the method chosen to change the VCO settings.                                        */
/****************************************************************************************/

ALT_STATUS_CODE alt_clk_pll_vco_cfg_set(ALT_CLK_t pll, uint32_t mult, uint32_t div)
{
    ALT_STATUS_CODE                 ret = ALT_E_ERROR;
    ALT_CLK_PLL_VCO_CHG_METHOD_t    method;
    bool                            byp = false;
    void                            *vaddr;
    uint32_t                        numermask, denommask;
    uint32_t                        numershift, denomshift;


    method = alt_clk_pll_vco_chg_methods_get(pll, mult, div);

    if (method == ALT_VCO_CHG_NONE_VALID)
    {
        ret = ALT_E_BAD_CLK;
    }
    else if (method == ALT_VCO_CHG_NOCHANGE)
    {
        ret = ALT_E_INV_OPTION;
    }
    else
    {
        if (pll == ALT_CLK_MAIN_PLL)
        {
            vaddr = ALT_CLKMGR_MAINPLL_VCO_ADDR;
            numermask = ALT_CLKMGR_MAINPLL_VCO_NUMER_SET_MSK;
            denommask = ALT_CLKMGR_MAINPLL_VCO_DENOM_SET_MSK;
            numershift = ALT_CLKMGR_MAINPLL_VCO_NUMER_LSB;
            denomshift = ALT_CLKMGR_MAINPLL_VCO_DENOM_LSB;
        }
        else if (pll == ALT_CLK_PERIPHERAL_PLL)
        {
            vaddr = ALT_CLKMGR_PERPLL_VCO_ADDR;
            numermask = ALT_CLKMGR_PERPLL_VCO_NUMER_SET_MSK;
            denommask = ALT_CLKMGR_PERPLL_VCO_DENOM_SET_MSK;
            numershift = ALT_CLKMGR_PERPLL_VCO_NUMER_LSB;
            denomshift = ALT_CLKMGR_PERPLL_VCO_DENOM_LSB;
        }
        else if (pll == ALT_CLK_SDRAM_PLL)
        {
            vaddr = ALT_CLKMGR_SDRPLL_VCO_ADDR;
            numermask = ALT_CLKMGR_SDRPLL_VCO_NUMER_SET_MSK;
            denommask = ALT_CLKMGR_SDRPLL_VCO_DENOM_SET_MSK;
            numershift = ALT_CLKMGR_SDRPLL_VCO_NUMER_LSB;
            denomshift = ALT_CLKMGR_SDRPLL_VCO_DENOM_LSB;
        }
        else { return ALT_E_BAD_ARG; }

        mult--;
        div--;

        if (method & ALT_VCO_CHG_NUM)
        {
            if (method & ALT_VCO_CHG_NUM_BYP)
            {
                alt_clk_pll_bypass_enable(pll, 0);
                byp = true;
                alt_clk_mgr_wait(vaddr, ALT_SW_MANAGED_CLK_WAIT_BYPASS);
            }
            alt_replbits_word(vaddr, numermask, mult << numershift);
        }

        else if (method & ALT_VCO_CHG_DENOM)
        {
            if (method & ALT_VCO_CHG_DENOM_BYP)
            {
                alt_clk_pll_bypass_enable(pll, 0);
                byp = true;
            }
            alt_replbits_word(vaddr, denommask, div << denomshift);
        }

        else if (method & ALT_VCO_CHG_NUM_DENOM)
        {
            if (method & ALT_VCO_CHG_NUM_DENOM_BYP)
            {
                alt_clk_pll_bypass_enable(pll, 0);
                byp = true;
            }
            alt_replbits_word(vaddr, numermask, mult << numershift);
            if (!byp)       // if PLL is not bypassed
            {
                ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
                      // verify PLL is still locked or wait for it to lock again
            }
            alt_replbits_word(vaddr, denommask, div << denomshift);
        }

        else if (method & ALT_VCO_CHG_DENOM_NUM)
        {
            if (method & ALT_VCO_CHG_DENOM_NUM_BYP)
            {
                alt_clk_pll_bypass_enable(pll, 0);
                byp = true;
            }
            alt_replbits_word(vaddr, numermask, mult << numershift);
            if (!byp)       // if PLL is not bypassed
            {
                ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
                      // verify PLL is still locked or wait for it to lock again
            }
            alt_replbits_word(vaddr, denommask, div << denomshift);
        }

        ret = alt_clk_pll_lock_wait(ALT_CLK_MAIN_PLL, 1000);
              // verify PLL is still locked or wait for it to lock again
        if (byp)
        {
            alt_clk_pll_bypass_disable(pll);
            alt_clk_mgr_wait(vaddr, ALT_SW_MANAGED_CLK_WAIT_BYPASS);
                // wait for PLL to come out of bypass mode completely
        }
    }
    return ret;
}


//
// alt_clk_pll_vco_freq_get() gets the VCO frequency of the specified PLL.
// Note that since there is at present no known way for software to obtain the speed
// bin of the SoC or MPU that it is running on, the function below only deals with the
// 800 MHz part. This may need to be revised in the future.
//
ALT_STATUS_CODE alt_clk_pll_vco_freq_get(ALT_CLK_t pll, alt_freq_t * freq)
{
    uint64_t            temp1 = 0;
    uint32_t            temp;
    uint32_t            numer;
    uint32_t            denom;
    ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;

    if (freq == NULL)
    {
		return ret;
    }

    if (pll == ALT_CLK_MAIN_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);
        numer = ALT_CLKMGR_MAINPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_MAINPLL_VCO_DENOM_GET(temp);
        temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
        temp1 *= (numer + 1);
        temp1 /= (denom + 1);

        if (temp1 <= UINT32_MAX)
        {
            temp = (alt_freq_t) temp1;
            alt_pll_clk_paramblok.MainPLL_800.freqcur = temp;
            // store this value in the parameter block table
	     *freq = temp;
            // should NOT check value against PLL frequency limits
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ERROR;
        }
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);
        numer = ALT_CLKMGR_PERPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_PERPLL_VCO_DENOM_GET(temp);
        temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(temp);
        if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc2.freqcur;
        }
        else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
        }

        if (temp1 != 0)
        {
            temp1 *= (numer + 1);
            temp1 /= (denom + 1);
            if (temp1 <= UINT32_MAX)
            {
                temp = (alt_freq_t) temp1;
                alt_pll_clk_paramblok.PeriphPLL_800.freqcur = temp;
                // store this value in the parameter block table

                *freq = temp;
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ERROR;
            }
        }       // this returns ALT_BAD_ARG if the source isn't known
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        temp = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);
        numer = ALT_CLKMGR_SDRPLL_VCO_NUMER_GET(temp);
        denom = ALT_CLKMGR_SDRPLL_VCO_DENOM_GET(temp);
        temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(temp);
        if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc1.freqcur;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.clkosc2.freqcur;
        }
        else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
        {
            temp1 = (uint64_t) alt_ext_clk_paramblok.sdram.freqcur;
        }

        if (temp1 != 0)
        {
            temp1 *= (numer + 1);
            temp1 /= (denom + 1);
            if (temp1 <= UINT32_MAX)
            {
                temp = (alt_freq_t) temp1;
                alt_pll_clk_paramblok.SDRAMPLL_800.freqcur = temp;
                // store this value in the parameter block table

                *freq = temp;
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ERROR;
            }
        }
    }       // which returns ALT_BAD_ARG if the source isn't known

    return ret;
}

//
// Returns the current guard band range in effect for the PLL.
//
uint32_t alt_clk_pll_guard_band_get(ALT_CLK_t pll)
{
    uint32_t ret = 0;

    if (pll == ALT_CLK_MAIN_PLL)
    {
        ret = alt_pll_clk_paramblok.MainPLL_800.guardband;
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        ret = alt_pll_clk_paramblok.PeriphPLL_800.guardband;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        ret = alt_pll_clk_paramblok.SDRAMPLL_800.guardband;
    }
    return ret;
}

//
// clk_mgr_pll_guard_band_set() changes the guard band from its current value to permit
// a more lenient or stringent policy to be in effect for the implementation of the
// functions configuring PLL VCO frequency.
//
ALT_STATUS_CODE alt_clk_pll_guard_band_set(ALT_CLK_t pll, uint32_t guard_band)
{
    if (   (guard_band > UINT12_MAX) || (guard_band <= 0)
        || (guard_band > ALT_GUARDBAND_LIMIT)
       )
    {
        return ALT_E_ARG_RANGE;
    }

    ALT_STATUS_CODE status = ALT_E_SUCCESS;

    if (pll == ALT_CLK_MAIN_PLL)
    {
        alt_pll_clk_paramblok.MainPLL_800.guardband = guard_band;
        //alt_pll_clk_paramblok.MainPLL_600.guardband = guard_band;
        // ??? Don't know how to check the MPU speed bin yet, so only 800 MHz struct is used
    }
    else if (pll == ALT_CLK_PERIPHERAL_PLL)
    {
        alt_pll_clk_paramblok.PeriphPLL_800.guardband = guard_band;
        //alt_pll_clk_paramblok.PeriphPLL_600.guardband = guard_band;
    }
    else if (pll == ALT_CLK_SDRAM_PLL)
    {
        alt_pll_clk_paramblok.SDRAMPLL_800.guardband = guard_band;
        //alt_pll_clk_paramblok.SDRAMPLL_600.guardband = guard_band;
    }
    else
    {
        status = ALT_E_ERROR;
    }

    return status;
}

//
// alt_clk_divider_get() gets configured divider value for the specified clock.
//
ALT_STATUS_CODE alt_clk_divider_get(ALT_CLK_t clk, uint32_t * div)
{
    ALT_STATUS_CODE status = ALT_E_SUCCESS;
    uint32_t        temp;

    if (div == NULL)
    {
		return ALT_E_BAD_ARG;
    }

    switch (clk)
    {
        // Main PLL outputs
    case ALT_CLK_MAIN_PLL_C0:
    case ALT_CLK_MPU:
        *div = (ALT_CLKMGR_MAINPLL_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR)) + 1) *
               (ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR)) + 1);
        break;

    case ALT_CLK_MAIN_PLL_C1:
    case ALT_CLK_L4_MAIN:
    case ALT_CLK_L3_MAIN:
        *div = (ALT_CLKMGR_MAINPLL_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR)) + 1) *
               (ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR)) + 1);
        break;

    case ALT_CLK_MAIN_PLL_C2:
    case ALT_CLK_DBG_BASE:
    case ALT_CLK_DBG_TIMER:
        *div = (ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR)) + 1) *
               (ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_DBGATCLK_ADDR)) + 1);
        break;

    case ALT_CLK_MAIN_PLL_C3:
    case ALT_CLK_MAIN_QSPI:
        *div = (ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR))) + 1;
        break;

    case ALT_CLK_MAIN_PLL_C4:
    case ALT_CLK_MAIN_NAND_SDMMC:
        *div = (ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR))) + 1;
        break;

    case ALT_CLK_MAIN_PLL_C5:
    case ALT_CLK_CFG:
    case ALT_CLK_H2F_USER0:
        *div = (ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR))) + 1;
        break;

        /////

        // Peripheral PLL outputs
    case ALT_CLK_PERIPHERAL_PLL_C0:
    case ALT_CLK_EMAC0:
        *div = (ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR))) + 1;
        break;

    case ALT_CLK_PERIPHERAL_PLL_C1:
    case ALT_CLK_EMAC1:
        *div = (ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR))) + 1;
        break;

    case ALT_CLK_PERIPHERAL_PLL_C2:
        *div = (ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR))) + 1;
        break;

    case ALT_CLK_PERIPHERAL_PLL_C3:
        *div = (ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR))) + 1;
        break;

    case ALT_CLK_PERIPHERAL_PLL_C4:
        *div = (ALT_CLKMGR_PERPLL_PERBASECLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR))) + 1;
        break;

    case ALT_CLK_PERIPHERAL_PLL_C5:
    case ALT_CLK_H2F_USER1:
        *div = (ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_GET(alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR))) + 1;
        break;

        /////

        // SDRAM PLL outputs
    case ALT_CLK_SDRAM_PLL_C0:
    case ALT_CLK_DDR_DQS:
        *div = (ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR))) + 1;
        break;

    case ALT_CLK_SDRAM_PLL_C1:
    case ALT_CLK_DDR_2X_DQS:
        *div = (ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR))) + 1;
        break;

    case ALT_CLK_SDRAM_PLL_C2:
    case ALT_CLK_DDR_DQ:
        *div = (ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR))) + 1;
        break;

    case ALT_CLK_SDRAM_PLL_C5:
    case ALT_CLK_H2F_USER2:
        *div = (ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_GET(alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR))) + 1;
        break;

        /////

        // Other clock dividers
    case ALT_CLK_L3_MP:
        temp = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV2)
        {
            *div = temp + 1;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_L3_SP:
        temp = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV2)
        {
            *div = temp + 1;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        // note that this value does not include the additional effect
        // of the L3_MP divider that is upchain from this one
        break;

    case ALT_CLK_L4_MP:
        temp = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_L4_SP:
        temp = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_DBG_AT:
        temp = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV4)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_DBG:
        temp = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV4)
        {
            *div =  1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        // note that this value does not include the value of the upstream dbg_at_clk divder
        break;

    case ALT_CLK_DBG_TRACE:
        temp = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_GET(alt_read_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR));
        if (temp <= ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV16)
        {
            *div =  1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_USB_MP:
        temp = ALT_CLKMGR_PERPLL_DIV_USBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
        if (temp <= ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_SPI_M:
        temp = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
        if (temp <= ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_CAN0:
        temp = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
        if (temp <= ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_CAN1:
        temp = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR));
        if (temp <= ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV16)
        {
            *div = 1 << temp;
        }
        else
        {
            status = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_GPIO_DB:
        temp = ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_GET(alt_read_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR));
        *div = temp + 1;
        break;

    case ALT_CLK_MPU_PERIPH:
        *div = 4;                           // set by hardware
        break;

    case ALT_CLK_MPU_L2_RAM:
        *div = 2;                           // set by hardware
        break;

    case ALT_CLK_NAND:
        *div = 4;                           // set by hardware
        break;

    default:
        status = ALT_E_BAD_ARG;
        break;
    }

    return status;
}

/////

#define ALT_CLK_WITHIN_FREQ_LIMITS_TEST_MODE        false
    // used for testing writes to the the full range of counters without
    // regard to the usual output frequency upper and lower limits


static ALT_STATUS_CODE alt_clk_within_freq_limits(ALT_CLK_t clk, uint32_t div)
{
#if ALT_CLK_WITHIN_FREQ_LIMITS_TEST_MODE
    return ALT_E_TRUE;
#else

    if (div == 0)
    {
        return ALT_E_BAD_ARG;
    }

    ALT_STATUS_CODE status = ALT_E_SUCCESS;
    uint32_t        numer = 0;
    uint32_t        hilimit;
    uint32_t        lolimit;

    switch (clk)
    {
        // Counters of the Main PLL
    case ALT_CLK_MAIN_PLL_C0:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C0;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;
    case  ALT_CLK_MAIN_PLL_C1:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C1;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;
    case ALT_CLK_MAIN_PLL_C2:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C2;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;
    case ALT_CLK_MAIN_PLL_C3:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C3;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;
    case ALT_CLK_MAIN_PLL_C4:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C4;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;
    case ALT_CLK_MAIN_PLL_C5:
        hilimit = alt_pll_cntr_maxfreq.MainPLL_C5;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &numer);
        break;

    // Counters of the Peripheral PLL
    case ALT_CLK_PERIPHERAL_PLL_C0:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C0;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;
    case ALT_CLK_PERIPHERAL_PLL_C1:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C1;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;
    case ALT_CLK_PERIPHERAL_PLL_C2:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C2;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;
    case ALT_CLK_PERIPHERAL_PLL_C3:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C3;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;
    case ALT_CLK_PERIPHERAL_PLL_C4:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C4;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;
    case ALT_CLK_PERIPHERAL_PLL_C5:
        hilimit = alt_pll_cntr_maxfreq.PeriphPLL_C5;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &numer);
        break;

    // Counters of the SDRAM PLL
    case ALT_CLK_SDRAM_PLL_C0:
        hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C0;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
        break;
    case ALT_CLK_SDRAM_PLL_C1:
        hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C1;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
        break;
    case ALT_CLK_SDRAM_PLL_C2:
        hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C2;
        lolimit = 0;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
        break;
    case ALT_CLK_SDRAM_PLL_C5:
        hilimit = alt_pll_cntr_maxfreq.SDRAMPLL_C5;
        lolimit = alt_ext_clk_paramblok.clkosc1.freqcur;
        status = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &numer);
        break;

    default:
        status = ALT_E_BAD_ARG;
        break;
    }

    if (status == ALT_E_SUCCESS)
    {
        numer = numer / div;
        if ((numer <= hilimit) && (numer >= lolimit))
        {
            status = ALT_E_TRUE;
        }
        else
        {
            status = ALT_E_FALSE;
        }
    }

    return status;
#endif
}

static bool alt_clkmgr_is_val_modulo_n(uint32_t div, uint32_t mod)
{
    if (mod == 1)
    {
        return true;
    }
    else if (mod == 2)
    {
        return (div & 0x1) == 0;
    }
    else if (mod == 4)
    {
        return (div & 0x3) == 0;
    }
    else
    {
        return (div % mod) == 0;
    }
}

//
// alt_clk_divider_set() sets the divider value for the specified clock.
//
// See pages 38, 44, 45, and 46 of the HPS-Clocking NPP for a map of the
// HPS clocking architecture and hierarchy of connections.
//
ALT_STATUS_CODE alt_clk_divider_set(ALT_CLK_t clk, uint32_t div)
{
    ALT_STATUS_CODE     ret = ALT_E_BAD_ARG;
    volatile uint32_t   temp, temp1;
    uint32_t            wrval = UINT32_MAX;              // value to be written
    bool                restore_0 = false;
    bool                restore_1 = false;
    bool                restore_2 = false;

    switch (clk)
    {
        // Main PLL outputs
    case ALT_CLK_MAIN_PLL_C0:
    case ALT_CLK_MPU:
        {
            uint32_t prediv = (ALT_CLKMGR_ALTERA_MPUCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MPUCLK_ADDR)) + 1);

            if (   (div <= ((ALT_CLKMGR_MAINPLL_MPUCLK_CNT_SET_MSK + 1) * prediv))
                && alt_clkmgr_is_val_modulo_n(div, prediv)
                && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C0, div) == ALT_E_TRUE) )
            {
                wrval = (div / prediv) - 1;

                // HW managed clock, change by writing to the external counter,  no need to gate clock
                // or match phase or wait for transistion time. No other field in the register to mask off either.
                alt_write_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR, wrval);
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ARG_RANGE;
            }
        }
        break;

    case ALT_CLK_MAIN_PLL_C1:
    case ALT_CLK_L3_MAIN:
        {
            uint32_t prediv = (ALT_CLKMGR_ALTERA_MAINCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_MAINCLK_ADDR)) + 1);

            if (   (div <= ((ALT_CLKMGR_MAINPLL_MAINCLK_CNT_SET_MSK + 1) * prediv))
                && alt_clkmgr_is_val_modulo_n(div, prediv)
                && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C1, div) == ALT_E_TRUE) )
            {
                // HW managed clock, change by writing to the external counter, no need to gate clock
                // or match phase or wait for transistion time. No other field in the register to mask off either.

                wrval = (div / prediv) - 1;

#if ALT_PREVENT_GLITCH_CHGC1
                // if L4MP or L4SP source is set to Main PLL C1, gate it off before changing
                // bypass state, then gate clock back on. FogBugz #63778
                temp  = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
                temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

                if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4MP_SET_MSK)))
                {
                    restore_0 = true;
                }
                if ((temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK) && (!(temp & ALT_CLKMGR_MAINPLL_L4SRC_L4SP_SET_MSK)))
                {
                    restore_1 = true;
                }
                temp = temp1;
                if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
                if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
                if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp); }

                alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR, wrval);

                alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                // wait a bit before reenabling the L4MP and L4SP clocks
                if (restore_0 || restore_1) { alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp1); }
#else
                alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR, wrval);
#endif
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ARG_RANGE;
            }
        }
        break;

    case ALT_CLK_MAIN_PLL_C2:
    case ALT_CLK_DBG_BASE:
        {
            uint32_t prediv = (ALT_CLKMGR_ALTERA_DBGATCLK_CNT_GET(alt_read_word(ALT_CLKMGR_ALTERA_DBGATCLK_ADDR)) + 1);

            if (   (div <= ((ALT_CLKMGR_MAINPLL_DBGATCLK_CNT_SET_MSK + 1) * prediv))
                   && alt_clkmgr_is_val_modulo_n(div, prediv)
                && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C2, div) == ALT_E_TRUE) )
            {
                wrval = (div / prediv) - 1;
                // HW managed clock, change by writing to the external counter,  no need to gate clock
                // or match phase or wait for transistion time. No other field in the register to mask off either.
                alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR, wrval);

                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ARG_RANGE;
            }
        }
        break;

    case ALT_CLK_MAIN_PLL_C3:
        // The rest of the PLL outputs do not have external counters, but
        // their internal counters are programmable rather than fixed
        if (   (div <= (ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C3, div) == ALT_E_TRUE) )
        {
            // if the main_qspi_clk input is selected for the qspi_clk
            if (ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR)) ==
                ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
            {
                restore_0 = (temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR)) & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
                if (restore_0)             // AND if the QSPI clock is currently enabled
                {
                    alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_CLR_MSK);
                    // gate off the QSPI clock
                }

                wrval = div - 1;
                // the rest are software-managed clocks and require a reset sequence to write to
                alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
                                         ALT_CLKMGR_MAINPLL_STAT_ADDR,
                                         ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,
                                         wrval,
                                         ALT_CLK_PLL_RST_BIT_C3,
                                         ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);

                alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                if (restore_0)
                {
                    alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
                    // if the QSPI clock was gated on (enabled) before, return it to that state
                }
                ret = ALT_E_SUCCESS;
            }
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_MAIN_PLL_C4:
    case ALT_CLK_MAIN_NAND_SDMMC:
        if (   (div <= (ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C4, div) == ALT_E_TRUE) )
        {
            temp  = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
            temp1 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);

            // do we need to gate off the SDMMC clock ?
            if (ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(temp) == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
            {
                if (temp1 & ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK) { restore_0 = true; }
            }

            // do we need to gate off the NAND clock and/or the NANDX clock?
            if (ALT_CLKMGR_PERPLL_SRC_NAND_GET(temp) == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
            {
                if (temp1 & ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK) { restore_1 = true; }
                if (temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK)  { restore_2 = true; }
            }

            temp = temp1;
            if (restore_1 && restore_2)
            {
                temp &= ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK;
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
                alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
                // gate nand_clk off at least 8 MPU clock cycles before before nand_x_clk
            }

            if (restore_0 || restore_1)
            {
                if (restore_0) { temp &= ALT_CLKMGR_PERPLL_EN_SDMMCCLK_CLR_MSK; }
                if (restore_1) { temp &= ALT_CLKMGR_PERPLL_EN_NANDXCLK_CLR_MSK; }
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
                // gate off sdmmc_clk and/or nand_x_clk
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
                                     ALT_CLKMGR_MAINPLL_STAT_ADDR,
                                     ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C4,
                                     ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);

            if (restore_0 || restore_1)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK);
                // if the NANDX and/or SDMMC clock was gated on (enabled) before, return it to that state
                if (restore_1 && restore_2)
                {
                    // wait at least 8 clock cycles to turn the nand_clk on
                    alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
                    alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
                }
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_MAIN_PLL_C5:
    case ALT_CLK_CFG:
    case ALT_CLK_H2F_USER0:
        if (   (div <= (ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_MAIN_PLL_C5, div) == ALT_E_TRUE) )
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            restore_0 = ((temp & ALT_CLKMGR_MAINPLL_EN_CFGCLK_SET_MSK) ||
                         (temp & ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_SET_MSK));
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & (ALT_CLKMGR_MAINPLL_EN_CFGCLK_CLR_MSK &
                                                                   ALT_CLKMGR_MAINPLL_EN_S2FUSER0CLK_CLR_MSK)); // clear both
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
                                     ALT_CLKMGR_MAINPLL_STAT_ADDR,
                                     ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C5,
                                     ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);

            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

        /////

        // Peripheral PLL outputs
    case ALT_CLK_PERIPHERAL_PLL_C0:
    case ALT_CLK_EMAC0:
        if (   (div <= (ALT_CLKMGR_PERPLL_EMAC0CLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C0, div) == ALT_E_TRUE) )
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            restore_0 = temp & ALT_CLKMGR_PERPLL_EN_EMAC0CLK_SET_MSK;

            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_EMAC0CLK_CLR_MSK);
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C0,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_PERIPHERAL_PLL_C1:
    case ALT_CLK_EMAC1:
        if (   (div <= (ALT_CLKMGR_PERPLL_EMAC1CLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C1, div) == ALT_E_TRUE) )
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            restore_0 = temp & ALT_CLKMGR_PERPLL_EN_EMAC1CLK_SET_MSK;

            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_EMAC1CLK_CLR_MSK);
            }
            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C1,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_PERIPHERAL_PLL_C2:
        if (   (div <= (ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C2, div) == ALT_E_TRUE) )
        {
            temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
            if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
            {
                // if qspi source is set to Peripheral PLL C2
                temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
                // and if qspi_clk is enabled
                restore_0 = temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
                if (restore_0)
                {
                    alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_QSPICLK_CLR_MSK);
                    // gate it off
                }
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C2,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
                // if the clock was gated on (enabled) before, return it to that state
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_PERIPHERAL_PLL_C3:
        if (   (div <= (ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C3, div) == ALT_E_TRUE) )
        {
            // first, are the clock MUX input selections currently set to use the clock we want to change?
            temp = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);
            restore_0 = (ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(temp) == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK);
            restore_1 = restore_2 = (ALT_CLKMGR_PERPLL_SRC_NAND_GET(temp) == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK);

            // now AND those with the current state of the three gate enables
            // to get the clocks which must be gated off and then back on
            temp1 = temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            restore_0 = restore_0 && (temp & ALT_CLKMGR_PERPLL_EN_SDMMCCLK_SET_MSK);
            restore_1 = restore_1 && (temp & ALT_CLKMGR_PERPLL_EN_NANDXCLK_SET_MSK);
            restore_2 = restore_2 && (temp & ALT_CLKMGR_PERPLL_EN_NANDCLK_SET_MSK);

            // gate off the clocks that depend on the clock divider that we want to change
            if (restore_2) { temp &= ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK; }
            if (restore_0) { temp &= ALT_CLKMGR_PERPLL_EN_SDMMCCLK_CLR_MSK; }
            alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);

            // the NAND clock must be gated off before the NANDX clock,
            if (restore_1)
            {
                alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK);
                temp &= ALT_CLKMGR_PERPLL_EN_NANDXCLK_CLR_MSK;
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C3,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );

            // NAND clock and NAND_X clock cannot be written together, must be a set sequence with a delay
            alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ALT_CLKMGR_PERPLL_EN_NANDCLK_CLR_MSK);
            if (restore_2)
            {
                // the NANDX clock must be gated on before the NAND clock.
                alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_NANDCLK );
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_PERIPHERAL_PLL_C4:
        if (   (div <= (ALT_CLKMGR_PERPLL_PERBASECLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C4, div) == ALT_E_TRUE) )
        {
            // look at the L4 set of clock gates first
            temp1 = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);
            restore_0 = (ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(temp1) == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_PERIPHPLL);
            restore_1 = (ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(temp1) == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_PERIPHPLL);
            temp1 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            restore_0 = restore_0 && (temp1 & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK);
            restore_1 = restore_1 && (temp1 & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK);

            // if the l4_sp and l4_mp clocks are not set to use the periph_base_clk
            // from the Peripheral PLL C4 clock divider output, or if they are
            // not currently gated on, don't change their gates
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (restore_0) { temp &= ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK; }
            if (restore_1) { temp &= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK; }
            alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);

            // now look at the C4 direct set of clock gates
            // first, create a mask of the C4 direct set of clock gate enables
            temp = (  ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK
                    | ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK
                    | ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK
                    | ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK
                    | ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK );

            // gate off all the C4 Direct set of clocks
            alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1 & ~temp);

            // change the clock divider ratio - the reason we're here
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C4,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );

            // gate the affected clocks that were on before back on - both sets of gates
            temp = (restore_0) ? ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK : 0;
            if (restore_1) { temp |= ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK; }
            alt_setbits_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp1);
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_PERIPHERAL_PLL_C5:
    case ALT_CLK_H2F_USER1:
        if (   (div <= (ALT_CLKMGR_PERPLL_S2FUSER1CLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_PERIPHERAL_PLL_C5, div) == ALT_E_TRUE) )
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            restore_0 = temp & ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_SET_MSK;
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_S2FUSER1CLK_CLR_MSK);
            }

            // now write the new divisor ratio
            wrval = div - 1;
            alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                     ALT_CLKMGR_PERPLL_STAT_ADDR,
                                     ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C5,
                                     ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
            if (restore_0) { alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp); }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

        /////

        // SDRAM PLL outputs
    case ALT_CLK_SDRAM_PLL_C0:
    case ALT_CLK_DDR_DQS:
        if (   (div <= (ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C0, div) == ALT_E_TRUE) )
        {
            wrval = div - 1;
            temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDRDQSCLK_CLR_MSK);
                restore_0 = true;
            }

            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
                                     ALT_CLKMGR_SDRPLL_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C0,
                                     ALT_CLKMGR_SDRPLL_DDRDQSCLK_CNT_LSB);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C1:
    case ALT_CLK_DDR_2X_DQS:
        if (   (div <= (ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C1, div) == ALT_E_TRUE) )
        {
            wrval = div - 1;
            temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDR2XDQSCLK_CLR_MSK);
                restore_0 = true;
            }

            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
                                     ALT_CLKMGR_SDRPLL_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C1,
                                     ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C2:
    case ALT_CLK_DDR_DQ:
        if (   (div <= (ALT_CLKMGR_SDRPLL_DDRDQCLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C2, div) == ALT_E_TRUE) )
        {
            wrval = div - 1;
            temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_DDRDQCLK_CLR_MSK);
                restore_0 = true;
            }

            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
                                     ALT_CLKMGR_SDRPLL_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C2,
                                     ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C5:
    case ALT_CLK_H2F_USER2:
        if (   (div <= (ALT_CLKMGR_SDRPLL_S2FUSER2CLK_CNT_SET_MSK + 1))
            && (alt_clk_within_freq_limits(ALT_CLK_SDRAM_PLL_C5, div) == ALT_E_TRUE) )
        {
            wrval = div - 1;
            temp = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp & ALT_CLKMGR_SDRPLL_EN_S2FUSER2CLK_CLR_MSK);
                restore_0 = true;
            }

            alt_clk_pllcounter_write(ALT_CLKMGR_SDRPLL_VCO_ADDR,
                                     ALT_CLKMGR_SDRPLL_STAT_ADDR,
                                     ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR,
                                     wrval,
                                     ALT_CLK_PLL_RST_BIT_C5,
                                     ALT_CLKMGR_SDRPLL_VCO_OUTRST_LSB);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

        /////

        // Other clock dividers
    case ALT_CLK_L3_MP:
        if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV1; }
        else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_E_DIV2; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_L3MPCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L3MPCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L3MPCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_EN_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_L3_SP:
        // note that the L3MP divider is upstream from the L3SP divider
        // and any changes to the former will affect the output of both
        if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV1; }
        else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_E_DIV2; }

        if (wrval != UINT32_MAX)
        {
            alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L3SPCLK_LSB);
            // no clock gate to close and reopen
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV );
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_L4_MP:
        if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L4MPCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L4MPCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);         // which has the enable bit set
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_L4_SP:
        if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_L4SPCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_MAINDIV_L4SPCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_DBG_AT:
        if      (div == 1) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV1; }
        else if (div == 2) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV2; }
        else if (div == 4) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_E_DIV4; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_DBGATCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGATCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_DBGDIV_DBGATCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_DBG:
        if      (div == 2) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV2; }
        else if (div == 4) { wrval = ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_E_DIV4; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_DBGCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_SET_MSK,
                              wrval << (ALT_CLKMGR_MAINPLL_DBGDIV_DBGCLK_LSB - 1));
            // account for the fact that the divisor ratios are 2x the value
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_DBG_TRACE:
        if      (div ==  1) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp & ALT_CLKMGR_MAINPLL_EN_DBGTRACECLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_SET_MSK,
                              wrval << ALT_CLKMGR_MAINPLL_TRACEDIV_TRACECLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_USB_MP:
        if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_USBCLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_PERPLL_EN_USBCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_USBCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_USBCLK_SET_MSK,
                              wrval << ALT_CLKMGR_PERPLL_DIV_USBCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_SPI_M:
        if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_SPIMCLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_PERPLL_EN_SPIMCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_SPIMCLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_SPIMCLK_SET_MSK,
                              wrval << ALT_CLKMGR_PERPLL_DIV_SPIMCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_CAN0:
        if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN0CLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_PERPLL_EN_CAN0CLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_CAN0CLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_CAN0CLK_SET_MSK,
                              wrval << ALT_CLKMGR_PERPLL_DIV_CAN0CLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_CAN1:
        if      (div ==  1) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV1; }
        else if (div ==  2) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV2; }
        else if (div ==  4) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV4; }
        else if (div ==  8) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV8; }
        else if (div == 16) { wrval = ALT_CLKMGR_PERPLL_DIV_CAN1CLK_E_DIV16; }

        if (wrval != UINT32_MAX)
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_PERPLL_EN_CAN1CLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_CAN1CLK_CLR_MSK);
                restore_0 = true;
            }
            alt_replbits_word(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_CLKMGR_PERPLL_DIV_CAN1CLK_SET_MSK,
                              wrval << ALT_CLKMGR_PERPLL_DIV_CAN1CLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_DIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_GPIO_DB:           // GPIO debounce clock
        if (div <= ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET_MSK)
        {
            temp = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);
            if (temp & ALT_CLKMGR_PERPLL_EN_GPIOCLK_SET_MSK)
            {
                // if clock is currently on, gate it off
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp & ALT_CLKMGR_PERPLL_EN_GPIOCLK_CLR_MSK);
                restore_0 = true;
            }
            wrval = div - 1;
            alt_replbits_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET_MSK,
                              wrval << ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_LSB);
            alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
            if (restore_0)
            {
                alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, temp);
            }
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = ALT_E_ARG_RANGE;
        }
        break;

    case ALT_CLK_MAIN_QSPI:
        temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        // get the QSPI clock source
        restore_0 = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR) & ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK;
        // and the current enable state
        wrval = div - 1;

        if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
        {           // if the main_qspi_clk (Main PLL C3 Ouput) input is selected
            if (div <= ALT_CLKMGR_MAINPLL_MAINQSPICLK_CNT_SET_MSK)
            {
                if (restore_0)
                {
                    alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
                }                // gate off the QSPI clock

                alt_clk_pllcounter_write(ALT_CLKMGR_MAINPLL_VCO_ADDR,
                                         ALT_CLKMGR_MAINPLL_STAT_ADDR,
                                         ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,
                                         wrval,
                                         ALT_CLK_PLL_RST_BIT_C3,
                                         ALT_CLKMGR_MAINPLL_VCO_OUTRST_LSB);

                alt_clk_mgr_wait(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                if (restore_0)
                {
                    alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
                    // if the QSPI clock was gated on (enabled) before, return it to that state
                }
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ARG_RANGE;
            }
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
        {
            if (div <= ALT_CLKMGR_PERPLL_PERQSPICLK_CNT_SET_MSK)
            {
                if (restore_0)
                {
                    alt_clrbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
                }                // gate off the QSPI clock

                alt_clk_pllcounter_write(ALT_CLKMGR_PERPLL_VCO_ADDR,
                                         ALT_CLKMGR_PERPLL_STAT_ADDR,
                                         ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,
                                         wrval,
                                         ALT_CLK_PLL_RST_BIT_C2,
                                         ALT_CLKMGR_PERPLL_VCO_OUTRST_LSB);

                alt_clk_mgr_wait(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR, ALT_SW_MANAGED_CLK_WAIT_CTRDIV);
                if (restore_0)
                {
                    alt_setbits_word(ALT_CLKMGR_PERPLL_EN_ADDR, ALT_CLKMGR_PERPLL_EN_QSPICLK_SET_MSK);
                    // if the QSPI clock was gated on (enabled) before, return it to that state
                }
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ARG_RANGE;
            }
        }
        break;

        /////

    default:
        ret = ALT_E_BAD_ARG;
        break;
    }

    return ret;
}

//
// alt_clk_freq_get() returns the output frequency of the specified clock.
//
ALT_STATUS_CODE alt_clk_freq_get(ALT_CLK_t clk, alt_freq_t* freq)
{
    ALT_STATUS_CODE ret = ALT_E_BAD_ARG;
    uint32_t        temp = 0;
    uint64_t        numer = 0;
    uint64_t        denom = 1;

    if (freq == NULL)
	{
		return ret;
	}

    switch (clk)
    {
        // External Inputs
    case ALT_CLK_IN_PIN_OSC1:
    case ALT_CLK_OSC1:
        numer = alt_ext_clk_paramblok.clkosc1.freqcur;
        // denom = 1 by default
        ret = ALT_E_SUCCESS;
        break;

    case ALT_CLK_IN_PIN_OSC2:
        numer = alt_ext_clk_paramblok.clkosc2.freqcur;
        // denom = 1 by default
        ret = ALT_E_SUCCESS;
        break;

    case ALT_CLK_F2H_PERIPH_REF:
        numer = alt_ext_clk_paramblok.periph.freqcur;
        // denom = 1 by default
        ret = ALT_E_SUCCESS;
        break;

    case ALT_CLK_F2H_SDRAM_REF:
        numer = alt_ext_clk_paramblok.sdram.freqcur;
        // denom = 1 by default
        ret = ALT_E_SUCCESS;
        break;

        /////

        // PLLs
    case ALT_CLK_MAIN_PLL:
        if (alt_clk_pll_is_bypassed(ALT_CLK_MAIN_PLL) == ALT_E_TRUE)
        {
            temp = alt_ext_clk_paramblok.clkosc1.freqcur;
            ret = ALT_E_SUCCESS;
        }
        else
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        }
        numer = (uint64_t) temp;
        // denom = 1 by default
        break;

    case ALT_CLK_PERIPHERAL_PLL:
        if (alt_clk_pll_is_bypassed(ALT_CLK_PERIPHERAL_PLL) == ALT_E_TRUE)
        {
            temp = ALT_CLKMGR_PERPLL_VCO_PSRC_GET(alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR));
            if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC1)
            {
                temp = alt_ext_clk_paramblok.clkosc1.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_EOSC2)
            {
                temp = alt_ext_clk_paramblok.clkosc2.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else if (temp == ALT_CLKMGR_PERPLL_VCO_PSRC_E_F2S_PERIPH_REF)
            {
                temp = alt_ext_clk_paramblok.periph.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ERROR;
            }
        }
        else
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        }
        numer = (uint64_t) temp;
        // denom = 1 by default
        break;

    case ALT_CLK_SDRAM_PLL:
        if (alt_clk_pll_is_bypassed(ALT_CLK_SDRAM_PLL) == ALT_E_TRUE)
        {
            temp = ALT_CLKMGR_SDRPLL_VCO_SSRC_GET(alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR));
            if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC1)
            {
                temp = alt_ext_clk_paramblok.clkosc1.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_EOSC2)
            {
                temp = alt_ext_clk_paramblok.clkosc2.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else if (temp == ALT_CLKMGR_SDRPLL_VCO_SSRC_E_F2S_SDRAM_REF)
            {
                temp = alt_ext_clk_paramblok.sdram.freqcur;
                ret = ALT_E_SUCCESS;
            }
            else
            {
                ret = ALT_E_ERROR;
            }
        }
        else
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
        }
        numer = (uint64_t) temp;
        // denom = 1 by default
        break;

        /////

        // Main Clock Group
    case ALT_CLK_MAIN_PLL_C0:
    case ALT_CLK_MAIN_PLL_C1:
    case ALT_CLK_MAIN_PLL_C2:
    case ALT_CLK_MAIN_PLL_C3:
    case ALT_CLK_MAIN_PLL_C4:
    case ALT_CLK_MAIN_PLL_C5:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(clk, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_MPU:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_MPU_PERIPH:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MPU_PERIPH, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_MPU_L2_RAM:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C0, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MPU_L2_RAM, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_L4_MAIN:
    case ALT_CLK_L3_MAIN:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_L3_MP:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_L3_MP, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_L3_SP:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_L3_MP, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = denom * (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_L3_SP, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_L4_MP:
        ret = alt_clk_divider_get(ALT_CLK_L4_MP, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            temp = ALT_CLKMGR_MAINPLL_L4SRC_L4MP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR));
            if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_MAINPLL)
            {
                ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
                if (ret == ALT_E_SUCCESS)
                {
                    numer = (uint64_t) temp;
                    ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
                    denom = denom * (uint64_t) temp;        // no real harm if temp is garbage data
                }
            }
            else if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4MP_E_PERIPHPLL)
            {
                ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
                if (ret == ALT_E_SUCCESS)
                {
                    numer = (uint64_t) temp;
                    ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
                    denom = denom * (uint64_t) temp;
                }
            }
        }
        break;

    case ALT_CLK_L4_SP:
        ret = alt_clk_divider_get(ALT_CLK_L4_SP, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            temp = ALT_CLKMGR_MAINPLL_L4SRC_L4SP_GET(alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR));
            if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_MAINPLL)
            {
                ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
                if (ret == ALT_E_SUCCESS)
                {
                    numer = (uint64_t) temp;
                    ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C1, &temp);
                    denom = denom * (uint64_t) temp;
                }
            }
            else if (temp == ALT_CLKMGR_MAINPLL_L4SRC_L4SP_E_PERIPHPLL)         // periph_base_clk
            {
                ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
                if (ret == ALT_E_SUCCESS)
                {
                    numer = (uint64_t) temp;
                    ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
                    denom = denom * (uint64_t) temp;
                }
            }
        }
        break;

    case ALT_CLK_DBG_BASE:
    case ALT_CLK_DBG_TIMER:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_DBG_AT:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_DBG_AT, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_DBG:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_DBG_AT, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = denom * (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_DBG, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_DBG_TRACE:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C2, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_DBG_TRACE, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_MAIN_QSPI:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C3, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_MAIN_NAND_SDMMC:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_CFG:
    case ALT_CLK_H2F_USER0:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C5, &temp);
            denom = (uint64_t) temp;
        }
        break;

        /////

        // Peripheral Clock Group
    case ALT_CLK_PERIPHERAL_PLL_C0:
    case ALT_CLK_PERIPHERAL_PLL_C1:
    case ALT_CLK_PERIPHERAL_PLL_C2:
    case ALT_CLK_PERIPHERAL_PLL_C3:
    case ALT_CLK_PERIPHERAL_PLL_C4:
    case ALT_CLK_PERIPHERAL_PLL_C5:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(clk, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_EMAC0:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C0, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_EMAC1:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C1, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_USB_MP:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                denom = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_USB_MP, &temp);
                denom = denom * (uint64_t) temp;
            }
        }
        break;

    case ALT_CLK_SPI_M:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_SPI_M, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_CAN0:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_CAN0, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_CAN1:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_CAN1, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_GPIO_DB:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C4, &temp);
        }
        if (ret == ALT_E_SUCCESS)
        {
            denom = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_GPIO_DB, &temp);
            denom = denom * (uint64_t) temp;
        }
        break;

    case ALT_CLK_H2F_USER1:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C5, &temp);
            denom = (uint64_t) temp;
        }
        break;

        /* Clocks That Can Switch Between Different Clock Groups */
    case ALT_CLK_SDMMC:
        temp = ALT_CLKMGR_PERPLL_SRC_SDMMC_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_F2S_PERIPH_REF_CLK)
        {
            numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
            // denom = 1 by default
            ret = ALT_E_SUCCESS;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_MAIN_NAND_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
                denom = (uint64_t) temp;
            }
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_SDMMC_E_PERIPH_NAND_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C3, &temp);
                denom = (uint64_t) temp;
            }
        }
        else
        {
            ret = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_NAND:
        denom = 4;
        // the absence of a break statement here is not a mistake
    case ALT_CLK_NAND_X:
        temp = ALT_CLKMGR_PERPLL_SRC_NAND_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_F2S_PERIPH_REF_CLK)
        {
            numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
            // denom = 1 or 4 by default;
            ret = ALT_E_SUCCESS;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_MAIN_NAND_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C4, &temp);
                denom = denom * (uint64_t) temp;
            }
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_NAND_E_PERIPH_NAND_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C3, &temp);
                denom = denom * (uint64_t) temp;
            }
        }
        else
        {
            ret = ALT_E_ERROR;
        }
        break;

    case ALT_CLK_QSPI:
        temp = ALT_CLKMGR_PERPLL_SRC_QSPI_GET(alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR));
        if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_F2S_PERIPH_REF_CLK)
        {
            numer = (uint64_t) alt_ext_clk_paramblok.periph.freqcur;
            // denom = 1 by default;
            ret = ALT_E_SUCCESS;
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_MAIN_QSPI_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_MAIN_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_MAIN_PLL_C3, &temp);
                denom = (uint64_t) temp;
            }
        }
        else if (temp == ALT_CLKMGR_PERPLL_SRC_QSPI_E_PERIPH_QSPI_CLK)
        {
            ret = alt_clk_pll_vco_freq_get(ALT_CLK_PERIPHERAL_PLL, &temp);
            if (ret == ALT_E_SUCCESS)
            {
                numer = (uint64_t) temp;
                ret = alt_clk_divider_get(ALT_CLK_PERIPHERAL_PLL_C2, &temp);
                denom = (uint64_t) temp;
            }
        }
        else
        {
            ret = ALT_E_ERROR;
        }
        break;

        /////

        // SDRAM Clock Group
    case ALT_CLK_SDRAM_PLL_C0:
    case ALT_CLK_DDR_DQS:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C0, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C1:
    case ALT_CLK_DDR_2X_DQS:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C1, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C2:
    case ALT_CLK_DDR_DQ:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C2, &temp);
            denom = (uint64_t) temp;
        }
        break;

    case ALT_CLK_SDRAM_PLL_C5:
    case ALT_CLK_H2F_USER2:
        ret = alt_clk_pll_vco_freq_get(ALT_CLK_SDRAM_PLL, &temp);
        if (ret == ALT_E_SUCCESS)
        {
            numer = (uint64_t) temp;
            ret = alt_clk_divider_get(ALT_CLK_SDRAM_PLL_C5, &temp);
            denom = (uint64_t) temp;
        }
        break;

    default:
        ret = ALT_E_BAD_ARG;
        break;

    }   // end of switch-case construct

    if (ret == ALT_E_SUCCESS)
    {
        // will not get here if none of above cases match
        if (denom > 0)
        {
            numer /= denom;
            if (numer <= UINT32_MAX)
            {
                *freq = (uint32_t) numer;
            }
            else
            {
                ret = ALT_E_ERROR;
            }
        }
        else
        {
            ret = ALT_E_ERROR;
        }
    }

    return ret;
}

//
// alt_clk_irq_disable() disables one or more of the lock status conditions as
// contributors to the clkmgr_IRQ interrupt signal state.
//
ALT_STATUS_CODE alt_clk_irq_disable(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
{
    if (!(lock_stat_mask & ALT_CLK_MGR_PLL_LOCK_BITS))
    {
        alt_clrbits_word(ALT_CLKMGR_INTREN_ADDR, lock_stat_mask);
        return ALT_E_SUCCESS;
    }
    else
    {
        return ALT_E_BAD_ARG;
    }
}

//
// alt_clk_irq_enable() enables one or more of the lock status conditions as
// contributors to the clkmgr_IRQ interrupt signal state.
//
ALT_STATUS_CODE alt_clk_irq_enable(ALT_CLK_PLL_LOCK_STATUS_t lock_stat_mask)
{
    if (!(lock_stat_mask & ALT_CLK_MGR_PLL_LOCK_BITS))
    {
        alt_setbits_word(ALT_CLKMGR_INTREN_ADDR, lock_stat_mask);
        return ALT_E_SUCCESS;
    }
    else
    {
        return ALT_E_BAD_ARG;
    }
}

/////

//
// alt_clk_group_cfg_raw_get() gets the raw configuration state of the designated
// clock group.
//
ALT_STATUS_CODE alt_clk_group_cfg_raw_get(ALT_CLK_GRP_t clk_group,
                                          ALT_CLK_GROUP_RAW_CFG_t * clk_group_raw_cfg)
{
    clk_group_raw_cfg->verid     = alt_read_word(ALT_SYSMGR_SILICONID1_ADDR);
    clk_group_raw_cfg->siliid2   = alt_read_word(ALT_SYSMGR_SILICONID2_ADDR);
    clk_group_raw_cfg->clkgrpsel = clk_group;

    if (clk_group == ALT_MAIN_PLL_CLK_GRP)
    {
        // Main PLL VCO register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_MAINPLL_VCO_ADDR);

        // Main PLL Misc register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.misc = alt_read_word(ALT_CLKMGR_MAINPLL_MISC_ADDR);

        // Main PLL C0-C5 Counter registers
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mpuclk = alt_read_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR);
        // doing these as 32-bit reads and writes avoids unnecessary masking operations

        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainclk          = alt_read_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR);
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgatclk         = alt_read_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR);
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainqspiclk      = alt_read_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR);
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainnandsdmmcclk = alt_read_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR);
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.cfgs2fuser0clk   = alt_read_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR);

        // Main PLL Enable register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.en = alt_read_word(ALT_CLKMGR_MAINPLL_EN_ADDR);

        // Main PLL Maindiv register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.maindiv = alt_read_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR);

        // Main PLL Debugdiv register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgdiv = alt_read_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR);

        // Main PLL Tracediv register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.tracediv = alt_read_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR);

        // Main PLL L4 Source register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.l4src = alt_read_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR);

        // Main PLL Status register
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_MAINPLL_STAT_ADDR);
        // clkgrp.mainpllgrp.stat.outresetack is defined in the ALT_CLKMGR_MAINPLL_STAT_s declaration
        // as a const but alt_indwrite_word() overrides that restriction.

        // padding ...
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw._pad_0x38_0x40[0] = 0;
        clk_group_raw_cfg->clkgrp.mainpllgrp.raw._pad_0x38_0x40[1] = 0;

        return ALT_E_SUCCESS;
    }
    else if (clk_group == ALT_PERIPH_PLL_CLK_GRP)
    {
        // Peripheral PLL VCO register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_PERPLL_VCO_ADDR);

        // Peripheral PLL Misc register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.misc = alt_read_word(ALT_CLKMGR_PERPLL_MISC_ADDR);

        // Peripheral PLL C0-C5 Counters
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac0clk = alt_read_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR);
        // doing these as 32-bit reads and writes avoids unnecessary masking operations

        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac1clk        = alt_read_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR);
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.perqspiclk      = alt_read_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR);
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.pernandsdmmcclk = alt_read_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR);
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.perbaseclk      = alt_read_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR);
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.s2fuser1clk     = alt_read_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR);

        // Peripheral PLL Enable register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.en = alt_read_word(ALT_CLKMGR_PERPLL_EN_ADDR);

        // Peripheral PLL Divider register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.div = alt_read_word(ALT_CLKMGR_PERPLL_DIV_ADDR);

        // Peripheral PLL GPIO Divider register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.gpiodiv = alt_read_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR);

        // Peripheral PLL Source register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.src = alt_read_word(ALT_CLKMGR_PERPLL_SRC_ADDR);

        // Peripheral PLL Status register
        clk_group_raw_cfg->clkgrp.perpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_PERPLL_STAT_ADDR);

        // padding ...
        clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[0] = 0;
        clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[1] = 0;
        clk_group_raw_cfg->clkgrp.perpllgrp.raw._pad_0x34_0x40[2] = 0;

        return ALT_E_SUCCESS;
    }
    else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)
    {
        // SDRAM PLL VCO register
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.vco = alt_read_word(ALT_CLKMGR_SDRPLL_VCO_ADDR);

        // SDRAM PLL Control register
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ctrl = alt_read_word(ALT_CLKMGR_SDRPLL_CTL_ADDR);

        // SDRAM PLL C0-C2 & C5 Counters
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqsclk = alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR);
        // doing these as 32-bit reads and writes avoids unnecessary masking operations

        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddr2xdqsclk = alt_read_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR);
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqclk    = alt_read_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR);
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.s2fuser2clk = alt_read_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR);

        // SDRAM PLL Enable register
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.en = alt_read_word(ALT_CLKMGR_SDRPLL_EN_ADDR);

        // SDRAM PLL Status register
        clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.stat = alt_read_word(ALT_CLKMGR_SDRPLL_STAT_ADDR);

        return ALT_E_SUCCESS;
    }
    else
    {
        return ALT_E_BAD_ARG;
    }
}

//
// alt_clk_group_cfg_raw_set() sets the clock group configuration.
//
ALT_STATUS_CODE alt_clk_group_cfg_raw_set(const ALT_CLK_GROUP_RAW_CFG_t * clk_group_raw_cfg)
{
    // test for matching silicon ID, but not for matching silicon revision number
    if (ALT_SYSMGR_SILICONID1_ID_GET(alt_read_word(ALT_SYSMGR_SILICONID1_ADDR)) !=
        ALT_SYSMGR_SILICONID1_ID_GET(clk_group_raw_cfg->verid))
    {
        return ALT_E_BAD_VERSION;
    }

    // get the PLL ID
    ALT_CLK_GRP_t clk_group = clk_group_raw_cfg->clkgrpsel;
    ALT_CLK_t     pll;

    if      (clk_group == ALT_MAIN_PLL_CLK_GRP)   { pll = ALT_CLK_MAIN_PLL; }
    else if (clk_group == ALT_PERIPH_PLL_CLK_GRP) { pll = ALT_CLK_PERIPHERAL_PLL; }
    else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)  { pll = ALT_CLK_SDRAM_PLL; }
    else
    {
        return ALT_E_ERROR;
    }

    ALT_STATUS_CODE status = ALT_E_SUCCESS;

    // if the PLL isn't in bypass mode, put it in bypass mode
    bool byp = false;
    if (alt_clk_pll_is_bypassed(pll) == ALT_E_FALSE)
    {
        status = alt_clk_pll_bypass_enable(pll, false);
        if (status != ALT_E_SUCCESS)
        {
            return status;
        }

        byp = true;
    }

    // now write the values in the ALT_CLK_GROUP_RAW_CFG_t structure to the registers
    if (clk_group == ALT_MAIN_PLL_CLK_GRP)
    {
        // Main PLL VCO register
        alt_write_word(ALT_CLKMGR_MAINPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.vco &
                       ALT_CLKMGR_MAINPLL_VCO_OUTRSTALL_CLR_MSK & ALT_CLKMGR_MAINPLL_VCO_OUTRST_CLR_MSK);
        // the outreset and outresetall bits were probably clear when the
        // state was saved, but make sure they're clear now

        // Main PLL Misc register
        alt_write_word(ALT_CLKMGR_MAINPLL_MISC_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.misc);

        // Main PLL C0-C5 Counter registers
        alt_write_word(ALT_CLKMGR_MAINPLL_MPUCLK_ADDR,           clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mpuclk);
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINCLK_ADDR,          clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainclk);
        alt_write_word(ALT_CLKMGR_MAINPLL_DBGATCLK_ADDR,         clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgatclk);
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINQSPICLK_ADDR,      clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainqspiclk);
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINNANDSDMMCCLK_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.mainnandsdmmcclk);
        alt_write_word(ALT_CLKMGR_MAINPLL_CFGS2FUSER0CLK_ADDR,   clk_group_raw_cfg->clkgrp.mainpllgrp.raw.cfgs2fuser0clk);

        // Main PLL Counter Enable register
        alt_write_word(ALT_CLKMGR_MAINPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.en);

        // Main PLL Maindiv register
        alt_write_word(ALT_CLKMGR_MAINPLL_MAINDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.maindiv);

        // Main PLL Debugdiv register
        alt_write_word(ALT_CLKMGR_MAINPLL_DBGDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.dbgdiv);

        // Main PLL Tracediv register
        alt_write_word(ALT_CLKMGR_MAINPLL_TRACEDIV_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.tracediv);

        // Main PLL L4 Source register
        alt_write_word(ALT_CLKMGR_MAINPLL_L4SRC_ADDR, clk_group_raw_cfg->clkgrp.mainpllgrp.raw.l4src);
    }
    else if (clk_group == ALT_PERIPH_PLL_CLK_GRP)
    {
        // Peripheral PLL VCO register
        alt_write_word(ALT_CLKMGR_PERPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.vco &
                       ALT_CLKMGR_PERPLL_VCO_OUTRST_CLR_MSK & ALT_CLKMGR_PERPLL_VCO_OUTRSTALL_CLR_MSK);
        // the outreset and outresetall bits were probably clear when the
        // state was saved, but make sure they're clear now

        // Peripheral PLL Misc register
        alt_write_word(ALT_CLKMGR_PERPLL_MISC_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.misc);

        // Peripheral PLL C0-C5 Counters
        alt_write_word(ALT_CLKMGR_PERPLL_EMAC0CLK_ADDR,        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac0clk);
        alt_write_word(ALT_CLKMGR_PERPLL_EMAC1CLK_ADDR,        clk_group_raw_cfg->clkgrp.perpllgrp.raw.emac1clk);
        alt_write_word(ALT_CLKMGR_PERPLL_PERQSPICLK_ADDR,      clk_group_raw_cfg->clkgrp.perpllgrp.raw.perqspiclk);
        alt_write_word(ALT_CLKMGR_PERPLL_PERNANDSDMMCCLK_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.pernandsdmmcclk);
        alt_write_word(ALT_CLKMGR_PERPLL_PERBASECLK_ADDR,      clk_group_raw_cfg->clkgrp.perpllgrp.raw.perbaseclk);
        alt_write_word(ALT_CLKMGR_PERPLL_S2FUSER1CLK_ADDR,     clk_group_raw_cfg->clkgrp.perpllgrp.raw.s2fuser1clk);

        // Peripheral PLL Counter Enable register
        alt_write_word(ALT_CLKMGR_PERPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.en);

        // Peripheral PLL Divider register
        alt_write_word(ALT_CLKMGR_PERPLL_DIV_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.div);

        // Peripheral PLL GPIO Divider register
        alt_write_word(ALT_CLKMGR_PERPLL_GPIODIV_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.gpiodiv);

        // Peripheral PLL Source register
        alt_write_word(ALT_CLKMGR_PERPLL_SRC_ADDR, clk_group_raw_cfg->clkgrp.perpllgrp.raw.src);
    }
    else if (clk_group == ALT_SDRAM_PLL_CLK_GRP)
    {
        // SDRAM PLL VCO register
        alt_write_word(ALT_CLKMGR_SDRPLL_VCO_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.vco &
                       ALT_CLKMGR_SDRPLL_VCO_OUTRST_CLR_MSK & ALT_CLKMGR_SDRPLL_VCO_OUTRSTALL_CLR_MSK);
        // the outreset and outresetall bits were probably clear when the
        // state was saved, but make sure they're clear now

        // SDRAM PLL Control register
        alt_write_word(ALT_CLKMGR_SDRPLL_CTL_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ctrl);

        // SDRAM PLL C0-C2 & C5 Counters
        alt_write_word(ALT_CLKMGR_SDRPLL_DDRDQSCLK_ADDR,   clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqsclk);
        alt_write_word(ALT_CLKMGR_SDRPLL_DDR2XDQSCLK_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddr2xdqsclk);
        alt_write_word(ALT_CLKMGR_SDRPLL_DDRDQCLK_ADDR,    clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.ddrdqclk);
        alt_write_word(ALT_CLKMGR_SDRPLL_S2FUSER2CLK_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.s2fuser2clk);

        // SDRAM PLL Counter Enable register
        alt_write_word(ALT_CLKMGR_SDRPLL_EN_ADDR, clk_group_raw_cfg->clkgrp.sdrpllgrp.raw.en);
    }

    // if PLL was not bypassed before, restore that state
    if (byp)
    {
        status = alt_clk_pll_bypass_disable(pll);
    }

    return status;
}

//
// alt_clk_id_to_string() converts a clock ID to a text string.
//
ALT_STATUS_CODE alt_clk_id_to_string(ALT_CLK_t clk_id, char * output, size_t size)
{
    char * name = NULL;

    switch (clk_id)
    {
    case ALT_CLK_IN_PIN_OSC1:
        name =  "IN_PIN_OSC1";
        break;
    case ALT_CLK_IN_PIN_OSC2:
        name =  "IN_PIN_OSC2";
        break;

        // FPGA Clock Sources External to HPS
    case ALT_CLK_F2H_PERIPH_REF:
        name =  "F2H_PERIPH_REF";
        break;
    case ALT_CLK_F2H_SDRAM_REF:
        name =  "F2H_SDRAM_REF";
        break;

        // Other Clock Sources External to HPS
    case ALT_CLK_IN_PIN_JTAG:
        name =  "IN_PIN_JTAG";
        break;
    case ALT_CLK_IN_PIN_ULPI0:
        name =  "IN_PIN_ULPI0";
        break;
    case ALT_CLK_IN_PIN_ULPI1:
        name =  "IN_PIN_ULPI1";
        break;
    case ALT_CLK_IN_PIN_EMAC0_RX:
        name =  "IN_PIN_EMAC0_RX";
        break;
    case ALT_CLK_IN_PIN_EMAC1_RX:
        name =  "IN_PIN_EMAC1_RX";
        break;

        // PLLs
    case ALT_CLK_MAIN_PLL:
        name =  "MAIN_PLL";
        break;
    case ALT_CLK_PERIPHERAL_PLL:
        name =  "PERIPHERAL_PLL";
        break;
    case ALT_CLK_SDRAM_PLL:
        name =  "SDRAM_PLL";
        break;

        // OSC1 Clock Group - The OSC1 clock group contains those clocks which are derived
        // directly from the osc_clk_1_HPS pin
    case ALT_CLK_OSC1:
        name =  "OSC1";
        break;

        // Main Clock Group - The following clocks are derived from the Main PLL.
    case ALT_CLK_MAIN_PLL_C0:
        name =  "MAIN_PLL_C0";
        break;
    case ALT_CLK_MAIN_PLL_C1:
        name =  "MAIN_PLL_C1";
        break;
    case ALT_CLK_MAIN_PLL_C2:
        name =  "MAIN_PLL_C2";
        break;
    case ALT_CLK_MAIN_PLL_C3:
        name =  "MAIN_PLL_C3";
        break;
    case ALT_CLK_MAIN_PLL_C4:
        name =  "MAIN_PLL_C4";
        break;
    case ALT_CLK_MAIN_PLL_C5:
        name =  "MAIN_PLL_C5";
        break;
    case ALT_CLK_MPU:
        name =  "MPU";
        break;
    case ALT_CLK_MPU_L2_RAM:
        name =  "MPU_L2_RAM";
        break;
    case ALT_CLK_MPU_PERIPH:
        name =  "MPU_PERIPH";
        break;
    case ALT_CLK_L3_MAIN:
        name =  "L3_MAIN";
        break;
    case ALT_CLK_L3_MP:
        name =  "L3_MP";
        break;
    case ALT_CLK_L3_SP:
        name =  "L3_SP";
        break;
    case ALT_CLK_L4_MAIN:
        name =  "L4_MAIN";
        break;
    case ALT_CLK_L4_MP:
        name =  "L4_MP";
        break;
    case ALT_CLK_L4_SP:
        name =  "L4_SP";
        break;
    case ALT_CLK_DBG_BASE:
        name =  "DBG_BASE";
        break;
    case ALT_CLK_DBG_AT:
        name =  "DBG_AT";
        break;
    case ALT_CLK_DBG_TRACE:
        name =  "DBG_TRACE";
        break;
    case ALT_CLK_DBG_TIMER:
        name =  "DBG_TIMER";
        break;
    case ALT_CLK_DBG:
        name =  "DBG";
        break;
    case ALT_CLK_MAIN_QSPI:
        name =  "MAIN_QSPI";
        break;
    case ALT_CLK_MAIN_NAND_SDMMC:
        name =  "MAIN_NAND_SDMMC";
        break;
    case ALT_CLK_CFG:
        name =  "CFG";
        break;
    case ALT_CLK_H2F_USER0:
        name =  "H2F_USER0";
        break;

        // Peripherals Clock Group - The following clocks are derived from the Peripheral PLL.
    case ALT_CLK_PERIPHERAL_PLL_C0:
        name =  "PERIPHERAL_PLL_C0";
        break;
    case ALT_CLK_PERIPHERAL_PLL_C1:
        name =  "PERIPHERAL_PLL_C1";
        break;
    case ALT_CLK_PERIPHERAL_PLL_C2:
        name =  "PERIPHERAL_PLL_C2";
        break;
    case ALT_CLK_PERIPHERAL_PLL_C3:
        name =  "PERIPHERAL_PLL_C3";
        break;
    case ALT_CLK_PERIPHERAL_PLL_C4:
        name =  "PERIPHERAL_PLL_C4";
        break;
    case ALT_CLK_PERIPHERAL_PLL_C5:
        name =  "PERIPHERAL_PLL_C5";
        break;
    case ALT_CLK_USB_MP:
        name =  "USB_MP";
        break;
    case ALT_CLK_SPI_M:
        name =  "SPI_M";
        break;
    case ALT_CLK_QSPI:
        name =  "QSPI";
        break;
    case ALT_CLK_NAND_X:
        name =  "NAND_X";
        break;
    case ALT_CLK_NAND:
        name =  "NAND";
        break;
    case ALT_CLK_SDMMC:
        name =  "SDMMC";
        break;
    case ALT_CLK_EMAC0:
        name =  "EMAC0";
        break;
    case ALT_CLK_EMAC1:
        name =  "EMAC1";
        break;
    case ALT_CLK_CAN0:
        name =  "CAN0";
        break;
    case ALT_CLK_CAN1:
        name =  "CAN1";
        break;
    case ALT_CLK_GPIO_DB:
        name =  "GPIO_DB";
        break;
    case ALT_CLK_H2F_USER1:
        name =  "H2F_USER1";
        break;

        // SDRAM Clock Group - The following clocks are derived from the SDRAM PLL.
    case ALT_CLK_SDRAM_PLL_C0:
        name =  "SDRAM_PLL_C0";
        break;
    case ALT_CLK_SDRAM_PLL_C1:
        name =  "SDRAM_PLL_C1";
        break;
    case ALT_CLK_SDRAM_PLL_C2:
        name =  "SDRAM_PLL_C2";
        break;
    case ALT_CLK_SDRAM_PLL_C3:
        name =  "SDRAM_PLL_C3";
        break;
    case ALT_CLK_SDRAM_PLL_C4:
        name =  "SDRAM_PLL_C4";
        break;
    case ALT_CLK_SDRAM_PLL_C5:
        name =  "SDRAM_PLL_C5";
        break;
    case ALT_CLK_DDR_DQS:
        name =  "DDR_DQS";
        break;
    case ALT_CLK_DDR_2X_DQS:
        name =  "DDR_2X_DQS";
        break;
    case ALT_CLK_DDR_DQ:
        name =  "DDR_DQ";
        break;
    case ALT_CLK_H2F_USER2:
        name =  "H2F_USER2";
        break;

        // Clock Output Pins
    case ALT_CLK_OUT_PIN_EMAC0_TX:
        name =  "OUT_PIN_EMAC0_TX";
        break;
    case ALT_CLK_OUT_PIN_EMAC1_TX:
        name =  "OUT_PIN_EMAC1_TX";
        break;
    case ALT_CLK_OUT_PIN_SDMMC:
        name =  "OUT_PIN_SDMMC";
        break;
    case ALT_CLK_OUT_PIN_I2C0_SCL:
        name =  "OUT_PIN_I2C0_SCL";
        break;
    case ALT_CLK_OUT_PIN_I2C1_SCL:
        name =  "OUT_PIN_I2C1_SCL";
        break;
    case ALT_CLK_OUT_PIN_I2C2_SCL:
        name =  "OUT_PIN_I2C2_SCL";
        break;
    case ALT_CLK_OUT_PIN_I2C3_SCL:
        name =  "OUT_PIN_I2C3_SCL";
        break;
    case ALT_CLK_OUT_PIN_SPIM0:
        name =  "OUT_PIN_SPIM0";
        break;
    case ALT_CLK_OUT_PIN_SPIM1:
        name =  "OUT_PIN_SPIM1";
        break;
    case ALT_CLK_OUT_PIN_QSPI:
        name =  "OUT_PIN_QSPI";
        break;
    case ALT_CLK_UNKNOWN:
        name =  "UNKNOWN";
        break;

        // do *not* put a 'default' statement here. Then the compiler will throw
        // an error if another clock id enum is added if the corresponding
        // string is not added to this function.
    }

    if (name != NULL)
    {
        snprintf(output, size, "ALT_CLK_%s", name);
        return ALT_E_SUCCESS;
    }
    else
    {
        return ALT_E_BAD_ARG;
    }
}


//
// alt_clk_pll_cntr_maxfreq_recalc() recalculate the maxmum frequency of the specified clock.
//
ALT_STATUS_CODE alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_t clk, ALT_PLL_CNTR_FREQMAX_t * maxfreq)
{
    ALT_STATUS_CODE ret = ALT_E_BAD_ARG;
	alt_freq_t freq;

	ret = alt_clk_freq_get(clk, &freq);

	if (ret == ALT_E_SUCCESS)
    {

        switch (clk)
        {
            // Main Clock Group
        case ALT_CLK_MAIN_PLL_C0:
            maxfreq->MainPLL_C0 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C0   = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_MAIN_PLL_C1:
            maxfreq->MainPLL_C1 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C1   = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_MAIN_PLL_C2:
            maxfreq->MainPLL_C2 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C2   = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_MAIN_PLL_C3:
            maxfreq->MainPLL_C3 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C3   = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_MAIN_PLL_C4:
            maxfreq->MainPLL_C4 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C4   = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_MAIN_PLL_C5:
            maxfreq->MainPLL_C5 = freq;
			printf("alt_pll_cntr_maxfreq.MainPLL_C5   = %10d\n", (unsigned int)freq);
            break;

            // Peripheral Clock Group
        case ALT_CLK_PERIPHERAL_PLL_C0:
            maxfreq->PeriphPLL_C0 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C0 = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_PERIPHERAL_PLL_C1:
            maxfreq->PeriphPLL_C1 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C1 = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_PERIPHERAL_PLL_C2:
            maxfreq->PeriphPLL_C2 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C2 = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_PERIPHERAL_PLL_C3:
            maxfreq->PeriphPLL_C3 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C3 = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_PERIPHERAL_PLL_C4:
            maxfreq->PeriphPLL_C4 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C4 = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_PERIPHERAL_PLL_C5:
            maxfreq->PeriphPLL_C5 = freq;
			printf("alt_pll_cntr_maxfreq.PeriphPLL_C5 = %10d\n", (unsigned int)freq);
            break;

            // SDRAM Clock Group
        case ALT_CLK_SDRAM_PLL_C0:
            maxfreq->SDRAMPLL_C0 = freq;
			printf("alt_pll_cntr_maxfreq.SDRAMPLL_C0  = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_SDRAM_PLL_C1:
            maxfreq->SDRAMPLL_C1 = freq;
			printf("alt_pll_cntr_maxfreq.SDRAMPLL_C1  = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_SDRAM_PLL_C2:
            maxfreq->SDRAMPLL_C2 = freq;
			printf("alt_pll_cntr_maxfreq.SDRAMPLL_C2  = %10d\n", (unsigned int)freq);
            break;
        case ALT_CLK_SDRAM_PLL_C5:
            maxfreq->SDRAMPLL_C5 = freq;
			printf("alt_pll_cntr_maxfreq.SDRAMPLL_C5  = %10d\n", (unsigned int)freq);
            break;
        default:
            ret = ALT_E_BAD_ARG;
			printf("bad max frequency parameter\n");
            break;
    	}   // end of switch-case construct
    }

    return ret;
}

//
//  u-boot preloader actually initialize clock manager circuitry
//
//  alt_clk_clkmgr_init() attempt to fix the pll counter max frequencies, since
//  thses frequencies are not known in advance until u-boot programmed clock manager.
//
ALT_STATUS_CODE alt_clk_clkmgr_init(void)
{
    ALT_STATUS_CODE ret = ALT_E_SUCCESS;
    ALT_STATUS_CODE status ;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C0,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C1,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C2,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C3,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C4,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_MAIN_PLL_C5,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C0,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C1,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C2,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C3,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C4,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_PERIPHERAL_PLL_C5,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;


	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C0,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C1,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C2,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;

	status = alt_clk_pll_cntr_maxfreq_recalc(ALT_CLK_SDRAM_PLL_C5,&alt_pll_cntr_maxfreq );
	if (status != ALT_E_SUCCESS) ret = ALT_E_ERROR;


	return ret;
}