diff options
Diffstat (limited to 'cpu/at32ap/at32ap700x/clk.c')
| -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 2b1cd36bf..2c2e19c29 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; +} |