diff options
author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-08-31 18:05:32 +0200 |
---|---|---|
committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-09-01 14:21:34 +0200 |
commit | 98090cd75cdb40b2ab94c806c338540a5716748b (patch) | |
tree | 1e401a8b0b0b1b46f170d603edc8b58227faf346 /cpu | |
parent | ab0df36fc7db9dda0b786b909f653e279dfeb9cf (diff) | |
download | u-boot-imx-98090cd75cdb40b2ab94c806c338540a5716748b.zip u-boot-imx-98090cd75cdb40b2ab94c806c338540a5716748b.tar.gz u-boot-imx-98090cd75cdb40b2ab94c806c338540a5716748b.tar.bz2 |
avr32: Add gclk helper functions
Add two helper functions for configuring and enabling generic clocks:
- gclk_enable_output: Enables output on a GCLKx pin
- gclk_set_rate: Configures a gclk to run at a specific rate
This should eliminate any reason to go mucking about with PM registers
from board code.
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/at32ap/at32ap700x/clk.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c index b3aa034..a6a6c88 100644 --- a/cpu/at32ap/at32ap700x/clk.c +++ b/cpu/at32ap/at32ap700x/clk.c @@ -25,6 +25,7 @@ #include <asm/arch/clk.h> #include <asm/arch/memory-map.h> +#include <asm/arch/portmux.h> #include "sm.h" @@ -66,3 +67,27 @@ void clk_init(void) sm_writel(PM_MCCTRL, SM_BIT(PLLSEL)); #endif } + +unsigned long __gclk_set_rate(unsigned int id, enum gclk_parent parent, + unsigned long rate, unsigned long parent_rate) +{ + unsigned long divider; + + if (rate == 0 || parent_rate == 0) { + sm_writel(PM_GCCTRL(id), 0); + return 0; + } + + divider = (parent_rate + rate / 2) / rate; + if (divider <= 1) { + sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN)); + rate = parent_rate; + } else { + divider = min(255, divider / 2 - 1); + sm_writel(PM_GCCTRL(id), parent | SM_BIT(CEN) | SM_BIT(DIVEN) + | SM_BF(DIV, divider)); + rate = parent_rate / (2 * (divider + 1)); + } + + return rate; +} |