atsamd: Do not generate 200M/100M interal clocks
Now that the internal DWT timer is used for software timers, there is no need to clock the peripherals at a higher clock speed. Clock all peripherals at 48Mhz and simplify the clock generation code. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
a00657d2ae
commit
b33ad59e25
|
@ -9,18 +9,14 @@
|
||||||
|
|
||||||
// The "generic clock generators" that are configured
|
// The "generic clock generators" that are configured
|
||||||
#define CLKGEN_MAIN 0
|
#define CLKGEN_MAIN 0
|
||||||
#define CLKGEN_200M 1
|
|
||||||
#define CLKGEN_32K 2
|
#define CLKGEN_32K 2
|
||||||
#define CLKGEN_48M 3
|
#define CLKGEN_48M 3
|
||||||
#define CLKGEN_2M 4
|
#define CLKGEN_2M 4
|
||||||
#define CLKGEN_100M 5
|
|
||||||
|
|
||||||
#define FREQ_MAIN 120000000
|
#define FREQ_MAIN 120000000
|
||||||
#define FREQ_200M 200000000
|
|
||||||
#define FREQ_32K 32768
|
#define FREQ_32K 32768
|
||||||
#define FREQ_48M 48000000
|
#define FREQ_48M 48000000
|
||||||
#define FREQ_2M 2000000
|
#define FREQ_2M 2000000
|
||||||
#define FREQ_100M 100000000
|
|
||||||
|
|
||||||
// Configure a clock generator using a given source as input
|
// Configure a clock generator using a given source as input
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -45,12 +41,7 @@ route_pclock(uint32_t pclk_id, uint32_t clkgen_id)
|
||||||
void
|
void
|
||||||
enable_pclock(uint32_t pclk_id, uint32_t pm_id)
|
enable_pclock(uint32_t pclk_id, uint32_t pm_id)
|
||||||
{
|
{
|
||||||
uint32_t clkgen_id = CLKGEN_100M;
|
route_pclock(pclk_id, CLKGEN_48M);
|
||||||
if (pclk_id == TC0_GCLK_ID || pclk_id == TC1_GCLK_ID)
|
|
||||||
clkgen_id = CLKGEN_200M;
|
|
||||||
else if (pclk_id == USB_GCLK_ID)
|
|
||||||
clkgen_id = CLKGEN_48M;
|
|
||||||
route_pclock(pclk_id, clkgen_id);
|
|
||||||
uint32_t pm_port = pm_id / 32, pm_bit = 1 << (pm_id % 32);
|
uint32_t pm_port = pm_id / 32, pm_bit = 1 << (pm_id % 32);
|
||||||
(&MCLK->APBAMASK.reg)[pm_port] |= pm_bit;
|
(&MCLK->APBAMASK.reg)[pm_port] |= pm_bit;
|
||||||
}
|
}
|
||||||
|
@ -59,11 +50,7 @@ enable_pclock(uint32_t pclk_id, uint32_t pm_id)
|
||||||
uint32_t
|
uint32_t
|
||||||
get_pclock_frequency(uint32_t pclk_id)
|
get_pclock_frequency(uint32_t pclk_id)
|
||||||
{
|
{
|
||||||
if (pclk_id == TC0_GCLK_ID || pclk_id == TC1_GCLK_ID)
|
|
||||||
return FREQ_200M;
|
|
||||||
else if (pclk_id == USB_GCLK_ID)
|
|
||||||
return FREQ_48M;
|
return FREQ_48M;
|
||||||
return FREQ_100M;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the clocks using an external 32K crystal
|
// Initialize the clocks using an external 32K crystal
|
||||||
|
@ -94,24 +81,6 @@ clock_init_32k(void)
|
||||||
// Switch main clock to 120Mhz PLL0
|
// Switch main clock to 120Mhz PLL0
|
||||||
gen_clock(CLKGEN_MAIN, GCLK_GENCTRL_SRC_DPLL0);
|
gen_clock(CLKGEN_MAIN, GCLK_GENCTRL_SRC_DPLL0);
|
||||||
|
|
||||||
// Generate 200Mhz clock on PLL1 (with CLKGEN_32K as reference)
|
|
||||||
route_pclock(OSCCTRL_GCLK_ID_FDPLL1, CLKGEN_32K);
|
|
||||||
mul = DIV_ROUND_CLOSEST(FREQ_200M, FREQ_32K);
|
|
||||||
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDR(mul - 1);
|
|
||||||
while (OSCCTRL->Dpll[1].DPLLSYNCBUSY.reg & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO)
|
|
||||||
;
|
|
||||||
OSCCTRL->Dpll[1].DPLLCTRLB.reg = (OSCCTRL_DPLLCTRLB_REFCLK_GCLK
|
|
||||||
| OSCCTRL_DPLLCTRLB_LBYPASS);
|
|
||||||
OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
|
|
||||||
mask = OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK;
|
|
||||||
while ((OSCCTRL->Dpll[1].DPLLSTATUS.reg & mask) != mask)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Produce 100Mhz and 200Mhz clocks from PLL1
|
|
||||||
gen_clock(CLKGEN_200M, GCLK_GENCTRL_SRC_DPLL1);
|
|
||||||
uint32_t div = DIV_ROUND_CLOSEST(FREQ_200M, FREQ_100M);
|
|
||||||
gen_clock(CLKGEN_100M, GCLK_GENCTRL_SRC_DPLL1 | GCLK_GENCTRL_DIV(div));
|
|
||||||
|
|
||||||
// Configure DFLL48M clock (with CLKGEN_32K as reference)
|
// Configure DFLL48M clock (with CLKGEN_32K as reference)
|
||||||
OSCCTRL->DFLLCTRLA.reg = 0;
|
OSCCTRL->DFLLCTRLA.reg = 0;
|
||||||
route_pclock(OSCCTRL_GCLK_ID_DFLL48, CLKGEN_32K);
|
route_pclock(OSCCTRL_GCLK_ID_DFLL48, CLKGEN_32K);
|
||||||
|
@ -157,24 +126,6 @@ clock_init_internal(void)
|
||||||
|
|
||||||
// Switch main clock to 120Mhz PLL0
|
// Switch main clock to 120Mhz PLL0
|
||||||
gen_clock(CLKGEN_MAIN, GCLK_GENCTRL_SRC_DPLL0);
|
gen_clock(CLKGEN_MAIN, GCLK_GENCTRL_SRC_DPLL0);
|
||||||
|
|
||||||
// Generate 200Mhz clock on PLL1 (with CLKGEN_2M as reference)
|
|
||||||
route_pclock(OSCCTRL_GCLK_ID_FDPLL1, CLKGEN_2M);
|
|
||||||
mul = DIV_ROUND_CLOSEST(FREQ_200M, FREQ_2M);
|
|
||||||
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDR(mul - 1);
|
|
||||||
while (OSCCTRL->Dpll[1].DPLLSYNCBUSY.reg & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO)
|
|
||||||
;
|
|
||||||
OSCCTRL->Dpll[1].DPLLCTRLB.reg = (OSCCTRL_DPLLCTRLB_REFCLK_GCLK
|
|
||||||
| OSCCTRL_DPLLCTRLB_LBYPASS);
|
|
||||||
OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE;
|
|
||||||
mask = OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK;
|
|
||||||
while ((OSCCTRL->Dpll[1].DPLLSTATUS.reg & mask) != mask)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Produce 100Mhz and 200Mhz clocks from PLL1
|
|
||||||
gen_clock(CLKGEN_200M, GCLK_GENCTRL_SRC_DPLL1);
|
|
||||||
div = DIV_ROUND_CLOSEST(FREQ_200M, FREQ_100M);
|
|
||||||
gen_clock(CLKGEN_100M, GCLK_GENCTRL_SRC_DPLL1 | GCLK_GENCTRL_DIV(div));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue