Lines Matching +full:clock +full:- +full:div

2  * arch/arm/mach-lpc32xx/clock.c
20 * LPC32xx clock management driver overview
26 * clocks are already running. Stopping a system clock during normal
30 * The LPC32xx high level clock tree looks as follows. Clocks marked with
33 * with a caret are always on if it is the selected clock for the SYSCLK
34 * source. The clock that isn't used for SYSCLK can be enabled and
52 * generate various clock rates up to 266MHz and beyond. The internal bus
57 * dividers as part of the IP itself. Because of this, the system clock
70 * complexities of clock management during clock frequency changes,
71 * there are some limitations to the clock driver explained below:
72 * - The PLL397 and main oscillator can be enabled and disabled by the
74 * on that clock. This allows the other oscillator that isn't driving
75 * the HCLK PLL to be used as another system clock that can be routed
77 * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with
79 * - HCLK and PCLK rates cannot be changed as part of this driver.
80 * - Most peripherals have their own dividers are part of the peripheral
97 #include "clock.h"
112 * If a clock has a rate of 0, then it inherits it's parent in local_return_parent_rate()
113 * clock rate in local_return_parent_rate()
115 while (clk->rate == 0) in local_return_parent_rate()
116 clk = clk->parent; in local_return_parent_rate()
118 return clk->rate; in local_return_parent_rate()
121 /* 32KHz clock has a fixed rate and is not stoppable */
150 return -ENODEV; in local_pll397_enable()
179 return -ENODEV; in local_oscmain_enable()
230 if (PllSetup->analog_on != 0) in local_clk_pll_setup()
232 if (PllSetup->cco_bypass_b15 != 0) in local_clk_pll_setup()
234 if (PllSetup->direct_output_b14 != 0) in local_clk_pll_setup()
236 if (PllSetup->fdbk_div_ctrl_b13 != 0) in local_clk_pll_setup()
239 tv = ffs(PllSetup->pll_p) - 1; in local_clk_pll_setup()
240 if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3)) in local_clk_pll_setup()
244 tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1); in local_clk_pll_setup()
245 tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1); in local_clk_pll_setup()
257 clkin = clk_armpll.parent->rate; in local_update_armpll_rate()
276 if (abs(pllin_freq - target_freq) <= freqtol) { in local_clk_find_pll_cfg()
277 pllsetup->analog_on = 0; in local_clk_find_pll_cfg()
278 pllsetup->cco_bypass_b15 = 1; in local_clk_find_pll_cfg()
279 pllsetup->direct_output_b14 = 1; in local_clk_find_pll_cfg()
280 pllsetup->fdbk_div_ctrl_b13 = 1; in local_clk_find_pll_cfg()
281 pllsetup->pll_p = pll_postdivs[0]; in local_clk_find_pll_cfg()
282 pllsetup->pll_n = 1; in local_clk_find_pll_cfg()
283 pllsetup->pll_m = 1; in local_clk_find_pll_cfg()
286 pllsetup->analog_on = 0; in local_clk_find_pll_cfg()
287 pllsetup->cco_bypass_b15 = 1; in local_clk_find_pll_cfg()
288 pllsetup->direct_output_b14 = 0; in local_clk_find_pll_cfg()
289 pllsetup->fdbk_div_ctrl_b13 = 1; in local_clk_find_pll_cfg()
290 pllsetup->pll_n = 1; in local_clk_find_pll_cfg()
291 pllsetup->pll_m = 1; in local_clk_find_pll_cfg()
293 pllsetup->pll_p = pll_postdivs[p]; in local_clk_find_pll_cfg()
295 if (abs(target_freq - fclkout) <= freqtol) in local_clk_find_pll_cfg()
301 pllsetup->analog_on = 1; in local_clk_find_pll_cfg()
302 pllsetup->cco_bypass_b15 = 0; in local_clk_find_pll_cfg()
303 pllsetup->direct_output_b14 = 1; in local_clk_find_pll_cfg()
304 pllsetup->fdbk_div_ctrl_b13 = 0; in local_clk_find_pll_cfg()
305 pllsetup->pll_p = pll_postdivs[0]; in local_clk_find_pll_cfg()
309 pllsetup->pll_n = n; in local_clk_find_pll_cfg()
310 pllsetup->pll_m = m; in local_clk_find_pll_cfg()
313 if (abs(target_freq - fclkout) <= in local_clk_find_pll_cfg()
320 pllsetup->analog_on = 1; in local_clk_find_pll_cfg()
321 pllsetup->cco_bypass_b15 = 0; in local_clk_find_pll_cfg()
322 pllsetup->direct_output_b14 = 0; in local_clk_find_pll_cfg()
323 pllsetup->fdbk_div_ctrl_b13 = 1; in local_clk_find_pll_cfg()
328 pllsetup->pll_p = pll_postdivs[p]; in local_clk_find_pll_cfg()
329 pllsetup->pll_n = n; in local_clk_find_pll_cfg()
330 pllsetup->pll_m = m; in local_clk_find_pll_cfg()
333 if (abs(target_freq - fclkout) <= freqtol) in local_clk_find_pll_cfg()
339 /* Try non-integer mode */ in local_clk_find_pll_cfg()
340 pllsetup->analog_on = 1; in local_clk_find_pll_cfg()
341 pllsetup->cco_bypass_b15 = 0; in local_clk_find_pll_cfg()
342 pllsetup->direct_output_b14 = 0; in local_clk_find_pll_cfg()
343 pllsetup->fdbk_div_ctrl_b13 = 0; in local_clk_find_pll_cfg()
348 pllsetup->pll_p = pll_postdivs[p]; in local_clk_find_pll_cfg()
349 pllsetup->pll_n = n; in local_clk_find_pll_cfg()
350 pllsetup->pll_m = m; in local_clk_find_pll_cfg()
353 if (abs(target_freq - fclkout) <= freqtol) in local_clk_find_pll_cfg()
378 return clk_check_pll_setup(clk_usbpll.parent->rate, in local_clk_usbpll_setup()
385 int ret = -ENODEV; in local_usbpll_enable()
399 while ((timeout > jiffies) & (ret == -ENODEV)) { in local_usbpll_enable()
421 * Unlike other clocks, this clock has a KHz input rate, so bump in local_usbpll_round_rate()
426 clkin = clk->parent->rate; in local_usbpll_round_rate()
444 * Unlike other clocks, this clock has a KHz input rate, so bump in local_usbpll_set_rate()
449 clkin = clk->get_rate(clk); in local_usbpll_set_rate()
456 return -EINVAL; in local_usbpll_set_rate()
467 clk->rate = clk_check_pll_setup(clkin, &pllsetup); in local_usbpll_set_rate()
506 tmp = __raw_readl(clk->enable_reg); in local_onoff_enable()
509 tmp &= ~clk->enable_mask; in local_onoff_enable()
511 tmp |= clk->enable_mask; in local_onoff_enable()
513 __raw_writel(tmp, clk->enable_reg); in local_onoff_enable()
518 /* Peripheral clock sources */
701 /* Make sure 32KHz clock is the selected clock */ in tsc_onoff_enable()
707 __raw_writel(0, clk->enable_reg); in tsc_onoff_enable()
709 __raw_writel(clk->enable_mask, clk->enable_reg); in tsc_onoff_enable()
729 /* If rate is 0, disable clock */ in mmc_onoff_enable()
740 u32 div, rate, oldclk; in mmc_get_rate() local
742 /* The MMC clock must be on when accessing an MMC register */ in mmc_get_rate()
746 div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); in mmc_get_rate()
749 /* Get the parent clock rate */ in mmc_get_rate()
750 rate = clk->parent->get_rate(clk->parent); in mmc_get_rate()
752 /* Get the MMC controller clock divider value */ in mmc_get_rate()
753 div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); in mmc_get_rate()
755 if (!div) in mmc_get_rate()
756 div = 1; in mmc_get_rate()
758 return rate / div; in mmc_get_rate()
763 unsigned long div, prate; in mmc_round_rate() local
765 /* Get the parent clock rate */ in mmc_round_rate()
766 prate = clk->parent->get_rate(clk->parent); in mmc_round_rate()
771 div = prate / rate; in mmc_round_rate()
772 if (div > 0xf) in mmc_round_rate()
773 div = 0xf; in mmc_round_rate()
775 return prate / div; in mmc_round_rate()
781 unsigned long prate, div, crate = mmc_round_rate(clk, rate); in mmc_set_rate() local
783 prate = clk->parent->get_rate(clk->parent); in mmc_set_rate()
785 div = prate / crate; in mmc_set_rate()
787 /* The MMC clock must be on when accessing an MMC register */ in mmc_set_rate()
793 tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div); in mmc_set_rate()
813 u32 tmp, div, rate, oldclk; in clcd_get_rate() local
815 /* The LCD clock must be on when accessing an LCD register */ in clcd_get_rate()
822 rate = clk->parent->get_rate(clk->parent); in clcd_get_rate()
828 div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22); in clcd_get_rate()
829 tmp = rate / (2 + div); in clcd_get_rate()
836 u32 tmp, prate, div, oldclk; in clcd_set_rate() local
838 /* The LCD clock must be on when accessing an LCD register */ in clcd_set_rate()
844 prate = clk->parent->get_rate(clk->parent); in clcd_set_rate()
848 div = prate / rate; in clcd_set_rate()
849 if (div >= 2) { in clcd_set_rate()
850 div -= 2; in clcd_set_rate()
855 tmp |= (div & 0x1F); in clcd_set_rate()
856 tmp |= (((div >> 5) & 0x1F) << 27); in clcd_set_rate()
867 u32 prate, div; in clcd_round_rate() local
869 prate = clk->parent->get_rate(clk->parent); in clcd_round_rate()
874 div = prate / rate; in clcd_round_rate()
875 if (div > 0x3ff) in clcd_round_rate()
876 div = 0x3ff; in clcd_round_rate()
878 rate = prate / div; in clcd_round_rate()
906 WARN_ON(clk->usecount == 0); in local_clk_disable()
908 /* Don't attempt to disable clock if it has no users */ in local_clk_disable()
909 if (clk->usecount > 0) { in local_clk_disable()
910 clk->usecount--; in local_clk_disable()
912 /* Only disable clock when it has no more users */ in local_clk_disable()
913 if ((clk->usecount == 0) && (clk->enable)) in local_clk_disable()
914 clk->enable(clk, 0); in local_clk_disable()
917 if (clk->parent) in local_clk_disable()
918 local_clk_disable(clk->parent); in local_clk_disable()
927 if (clk->parent) in local_clk_enable()
928 ret = local_clk_enable(clk->parent); in local_clk_enable()
931 /* Only enable clock if it's currently disabled */ in local_clk_enable()
932 if ((clk->usecount == 0) && (clk->enable)) in local_clk_enable()
933 ret = clk->enable(clk, 1); in local_clk_enable()
936 clk->usecount++; in local_clk_enable()
937 else if (clk->parent) in local_clk_enable()
938 local_clk_disable(clk->parent); in local_clk_enable()
945 * clk_enable - inform the system when the clock source should be running.
960 * clk_disable - inform the system when the clock source is no longer required
971 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source
978 rate = clk->get_rate(clk); in clk_get_rate()
986 * clk_set_rate - set the clock rate for a clock source
990 int ret = -EINVAL; in clk_set_rate()
995 * instead of high level clock control in clk_set_rate()
997 if (clk->set_rate) { in clk_set_rate()
999 ret = clk->set_rate(clk, rate); in clk_set_rate()
1008 * clk_round_rate - adjust a rate to the exact rate a clock can provide
1014 if (clk->round_rate) in clk_round_rate()
1015 rate = clk->round_rate(clk, rate); in clk_round_rate()
1017 rate = clk->get_rate(clk); in clk_round_rate()
1026 * clk_set_parent - set the parent clock source for this clock
1030 /* Clock re-parenting is not supported */ in clk_set_parent()
1031 return -EINVAL; in clk_set_parent()
1036 * clk_get_parent - get the parent clock source for this clock
1040 return clk->parent; in clk_get_parent()
1066 _REGISTER_CLOCK("pnx4008-watchdog", NULL, clk_wdt)
1071 _REGISTER_CLOCK("pnx-i2c.0", NULL, clk_i2c0)
1072 _REGISTER_CLOCK("pnx-i2c.1", NULL, clk_i2c1)
1073 _REGISTER_CLOCK("pnx-i2c.2", NULL, clk_i2c2)
1077 _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
1080 _REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
1082 _REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
1096 * Setup muxed SYSCLK for HCLK PLL base -this selects the in clk_init()
1097 * parent clock used for the ARM PLL and is used to derive in clk_init()
1098 * the many system clock rates in the device. in clk_init()
1105 clk_sys.rate = clk_sys.parent->rate; in clk_init()
1111 clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div(); in clk_init()
1112 clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div(); in clk_init()
1115 * Enable system clocks - this step is somewhat formal, as the in clk_init()
1116 * clocks are already running, but it does get the clock data in clk_init()
1120 * handle clock gating. in clk_init()