From 98090cd75cdb40b2ab94c806c338540a5716748b Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Sun, 31 Aug 2008 18:05:32 +0200 Subject: 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 --- cpu/at32ap/at32ap700x/clk.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'cpu/at32ap') diff --git a/cpu/at32ap/at32ap700x/clk.c b/cpu/at32ap/at32ap700x/clk.c index b3aa03495..a6a6c885e 100644 --- a/cpu/at32ap/at32ap700x/clk.c +++ b/cpu/at32ap/at32ap700x/clk.c @@ -25,6 +25,7 @@ #include #include +#include #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; +} -- cgit v1.2.3