Back to home page

LXR

 
 

    


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

0001 /*
0002  * Atmel AT91RM9200 PMC functions
0003  *
0004  * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
0005  *
0006  *  The license and distribution terms for this file may be
0007  *  found in the file LICENSE in this distribution or at
0008  *  http://www.rtems.org/license/LICENSE.
0009  */
0010 
0011 #include <rtems.h>
0012 #include <bsp.h>
0013 #include <at91rm9200.h>
0014 #include <at91rm9200_pmc.h>
0015 
0016 int at91rm9200_get_mainclk(void)
0017 {
0018     return BSP_MAIN_FREQ;
0019 }
0020 
0021 int at91rm9200_get_slck(void)
0022 {
0023     return BSP_SLCK_FREQ;
0024 }
0025 
0026 int at91rm9200_get_mck(void)
0027 {
0028     uint32_t mck_reg;
0029     uint32_t mck_freq = 0;  /* to avoid warnings */
0030     uint32_t pll_reg;
0031     int prescaler = 0;  /* to avoid warnings */
0032 
0033     mck_reg = PMC_REG(PMC_MCKR);
0034 
0035     switch(mck_reg & PMC_MCKR_PRES_MASK) {
0036     case PMC_MCKR_PRES_1:
0037         prescaler = 1;
0038         break;
0039     case PMC_MCKR_PRES_2:
0040         prescaler = 2;
0041         break;
0042     case PMC_MCKR_PRES_4:
0043         prescaler = 4;
0044         break;
0045     case PMC_MCKR_PRES_8:
0046         prescaler = 8;
0047         break;
0048     case PMC_MCKR_PRES_16:
0049         prescaler = 16;
0050         break;
0051     case PMC_MCKR_PRES_32:
0052         prescaler = 32;
0053         break;
0054     case PMC_MCKR_PRES_64:
0055         prescaler = 64;
0056         break;
0057     }
0058 
0059     /* Let's find out what MCK's source is */
0060     switch (mck_reg & PMC_MCKR_CSS_MASK) {
0061     case PMC_MCKR_CSS_SLOW:
0062         /* I'm assuming the slow clock is 32.768 MHz */
0063         mck_freq = at91rm9200_get_slck() / prescaler;
0064         break;
0065 
0066     case PMC_MCKR_CSS_MAIN:
0067         mck_freq = at91rm9200_get_mainclk() / prescaler;
0068         break;
0069 
0070     case PMC_MCKR_CSS_PLLA:
0071         pll_reg = PMC_REG(PMC_PLLAR);
0072         mck_freq = at91rm9200_get_mainclk() / prescaler;
0073         mck_freq = mck_freq / (pll_reg & PMC_PLLAR_DIV_MASK);
0074         mck_freq = mck_freq * (((pll_reg & PMC_PLLAR_MUL_MASK) >> 16) + 1);
0075         break;
0076 
0077     case PMC_MCKR_CSS_PLLB:
0078         pll_reg = PMC_REG(PMC_PLLBR);
0079         mck_freq = at91rm9200_get_mainclk() / prescaler;
0080         mck_freq = mck_freq / (pll_reg & PMC_PLLBR_DIV_MASK);
0081         mck_freq = mck_freq * (((pll_reg & PMC_PLLBR_MUL_MASK) >> 16) + 1);
0082         break;
0083     }
0084 
0085     if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_2) {
0086         mck_freq = mck_freq / 2;
0087     } else if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_3) {
0088         mck_freq = mck_freq / 3;
0089     } else if ((mck_reg & PMC_MCKR_MDIV_MASK) == PMC_MCKR_MDIV_4) {
0090         mck_freq = mck_freq / 4;
0091     }
0092 
0093 
0094     return mck_freq;
0095 }
0096