1 /* 2 * clocks.c - figure out sclk/cclk/vco and such 3 * 4 * Copyright (c) 2005-2008 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later. 7 */ 8 9 #include <common.h> 10 #include <asm/blackfin.h> 11 12 /* Get the voltage input multiplier */ 13 static u_long cached_vco_pll_ctl, cached_vco; get_vco(void)14u_long get_vco(void) 15 { 16 u_long msel; 17 18 u_long pll_ctl = bfin_read_PLL_CTL(); 19 if (pll_ctl == cached_vco_pll_ctl) 20 return cached_vco; 21 else 22 cached_vco_pll_ctl = pll_ctl; 23 24 msel = (pll_ctl >> 9) & 0x3F; 25 if (0 == msel) 26 msel = 64; 27 28 cached_vco = CONFIG_CLKIN_HZ; 29 cached_vco >>= (1 & pll_ctl); /* DF bit */ 30 cached_vco *= msel; 31 return cached_vco; 32 } 33 34 /* Get the Core clock */ 35 static u_long cached_cclk_pll_div, cached_cclk; get_cclk(void)36u_long get_cclk(void) 37 { 38 u_long csel, ssel; 39 40 if (bfin_read_PLL_STAT() & 0x1) 41 return CONFIG_CLKIN_HZ; 42 43 ssel = bfin_read_PLL_DIV(); 44 if (ssel == cached_cclk_pll_div) 45 return cached_cclk; 46 else 47 cached_cclk_pll_div = ssel; 48 49 csel = ((ssel >> 4) & 0x03); 50 ssel &= 0xf; 51 if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ 52 cached_cclk = get_vco() / ssel; 53 else 54 cached_cclk = get_vco() >> csel; 55 return cached_cclk; 56 } 57 58 /* Get the System clock */ 59 static u_long cached_sclk_pll_div, cached_sclk; get_sclk(void)60u_long get_sclk(void) 61 { 62 u_long ssel; 63 64 if (bfin_read_PLL_STAT() & 0x1) 65 return CONFIG_CLKIN_HZ; 66 67 ssel = bfin_read_PLL_DIV(); 68 if (ssel == cached_sclk_pll_div) 69 return cached_sclk; 70 else 71 cached_sclk_pll_div = ssel; 72 73 ssel &= 0xf; 74 75 cached_sclk = get_vco() / ssel; 76 return cached_sclk; 77 } 78