From ba83e13d10f16656f09379debece0c98b54f3a6f Mon Sep 17 00:00:00 2001 From: Dylan Laduranty Date: Tue, 16 May 2023 15:53:20 +0200 Subject: [PATCH 1/4] cpu/samd5x: fix SAM0_DPLL_FREQ_MAX_HZ value Signed-off-by: Dylan Laduranty --- cpu/samd5x/include/periph_cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/samd5x/include/periph_cpu.h b/cpu/samd5x/include/periph_cpu.h index e6ff957d00c9..acae8fddcac5 100644 --- a/cpu/samd5x/include/periph_cpu.h +++ b/cpu/samd5x/include/periph_cpu.h @@ -47,7 +47,7 @@ extern "C" { /** * @brief DPLL frequency must not exceed 200 MHz */ -#define SAM0_DPLL_FREQ_MAX_HZ MHZ(20) +#define SAM0_DPLL_FREQ_MAX_HZ MHZ(200) /** * @name Power mode configuration From af2fa994704e4f6b61d1aad662b0ae774828c51b Mon Sep 17 00:00:00 2001 From: Dylan Laduranty Date: Tue, 16 May 2023 15:54:18 +0200 Subject: [PATCH 2/4] cpu/samd5x: remove duplicate USE_VREG_BUCK Signed-off-by: Dylan Laduranty --- cpu/samd5x/cpu.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cpu/samd5x/cpu.c b/cpu/samd5x/cpu.c index e4769c94009f..d03201680d0c 100644 --- a/cpu/samd5x/cpu.c +++ b/cpu/samd5x/cpu.c @@ -34,14 +34,6 @@ #define USE_VREG_BUCK (0) #endif -/* - * An external inductor needs to be present on the board, - * so the feature can only be enabled by the board configuration. - */ -#ifndef USE_VREG_BUCK -#define USE_VREG_BUCK (0) -#endif - #if CLOCK_CORECLOCK == 0 #error Please select CLOCK_CORECLOCK #endif From f790d9fe3650318e08ff2b575d0a2814fc3ea16b Mon Sep 17 00:00:00 2001 From: Dylan Laduranty Date: Tue, 16 May 2023 16:03:15 +0200 Subject: [PATCH 3/4] cpu/samd5x: replace fdpll0_init by two generic functions These functions can be used to set both FDPLL0 and FDPLL1 by using an extra argument 'idx' (index) and allow to set the ONDEMAND bit using the 'flags' argument Signed-off-by: Dylan Laduranty --- cpu/samd5x/cpu.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/cpu/samd5x/cpu.c b/cpu/samd5x/cpu.c index d03201680d0c..7cb972e6acd2 100644 --- a/cpu/samd5x/cpu.c +++ b/cpu/samd5x/cpu.c @@ -183,37 +183,43 @@ static void dfll_init(void) while (!OSCCTRL->STATUS.bit.DFLLRDY) {} } -static void fdpll0_init(uint32_t f_cpu) +static void fdpll_init_nolock(uint8_t idx, uint32_t f_cpu, uint8_t flags) { + /* Trigger assertion if not using FDPLL0 or FDPLL1 */ + assert(idx == 0 || idx == 1); + if (!USE_DPLL) { - OSCCTRL->Dpll[0].DPLLCTRLA.reg = 0; + OSCCTRL->Dpll[idx].DPLLCTRLA.reg = 0; return; } - /* We source the DPLL from 32kHz GCLK1 */ - const uint32_t LDR = ((f_cpu << 5) / 32768); + /* Source the DPLL from 32kHz GCLK1 ( equivalent to ((f_cpu << 5) / 32768) ) */ + const uint32_t LDR = (f_cpu >> 10); /* disable the DPLL before changing the configuration */ - OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 0; - while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.reg) {} + OSCCTRL->Dpll[idx].DPLLCTRLA.bit.ENABLE = 0; + while (OSCCTRL->Dpll[idx].DPLLSYNCBUSY.reg) {} /* set DPLL clock source */ - GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; - while (!(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg & GCLK_PCHCTRL_CHEN)) {} + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg = GCLK_PCHCTRL_GEN(1) | GCLK_PCHCTRL_CHEN; + while (!(GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0 + idx].reg & GCLK_PCHCTRL_CHEN)) {} - OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) - | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); + OSCCTRL->Dpll[idx].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR & 0x1F) + | OSCCTRL_DPLLRATIO_LDR((LDR >> 5) - 1); /* Without LBYPASS, startup takes very long, see errata section 2.13. */ - OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK - | OSCCTRL_DPLLCTRLB_WUF - | OSCCTRL_DPLLCTRLB_LBYPASS; + OSCCTRL->Dpll[idx].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK + | OSCCTRL_DPLLCTRLB_WUF + | OSCCTRL_DPLLCTRLB_LBYPASS; - OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + OSCCTRL->Dpll[idx].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | flags; + + while (OSCCTRL->Dpll[idx].DPLLSYNCBUSY.reg) {} +} - while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.reg) {} - while (!(OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY && - OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK)) {} +static void fdpll_lock(uint8_t idx) { + while (!(OSCCTRL->Dpll[idx].DPLLSTATUS.bit.CLKRDY && + OSCCTRL->Dpll[idx].DPLLSTATUS.bit.LOCK)) {} } static void gclk_connect(uint8_t id, uint8_t src, uint32_t flags) { @@ -346,12 +352,13 @@ void cpu_init(void) xosc_init(0); xosc_init(1); - fdpll0_init(CLOCK_CORECLOCK * DPLL_DIV); /* select the source of the main clock */ if (USE_DPLL) { + fdpll_init_nolock(0, CLOCK_CORECLOCK * DPLL_DIV, OSCCTRL_DPLLCTRLA_ONDEMAND); gclk_connect(SAM0_GCLK_MAIN, GCLK_SOURCE_DPLL0, GCLK_GENCTRL_DIV(DPLL_DIV)); + fdpll_lock(0); } else if (USE_DFLL) { gclk_connect(SAM0_GCLK_MAIN, GCLK_SOURCE_DFLL, GCLK_GENCTRL_DIV(SAM0_DFLL_FREQ_HZ / CLOCK_CORECLOCK)); From 6607ed10f626a03d1a0f9f3dff4724b3c2f895c7 Mon Sep 17 00:00:00 2001 From: Dylan Laduranty Date: Tue, 16 May 2023 16:04:17 +0200 Subject: [PATCH 4/4] cpu/samd5x: add support for FDPLL1 running at 200MHz Signed-off-by: Dylan Laduranty --- cpu/samd5x/cpu.c | 8 +++++++- cpu/samd5x/include/periph_cpu.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cpu/samd5x/cpu.c b/cpu/samd5x/cpu.c index 7cb972e6acd2..0daf4665a398 100644 --- a/cpu/samd5x/cpu.c +++ b/cpu/samd5x/cpu.c @@ -254,7 +254,11 @@ void sam0_gclk_enable(uint8_t id) } else if (USE_XOSC) { gclk_connect(SAM0_GCLK_PERIPH, GCLK_SOURCE_ACTIVE_XOSC, 0); } - + break; + case SAM0_GCLK_200MHZ: + fdpll_init_nolock(1, MHZ(200), OSCCTRL_DPLLCTRLA_ONDEMAND); + gclk_connect(SAM0_GCLK_200MHZ, GCLK_SOURCE_DPLL1, 0); + fdpll_lock(1); break; } } @@ -277,6 +281,8 @@ uint32_t sam0_gclk_freq(uint8_t id) assert(0); return 0; } + case SAM0_GCLK_200MHZ: + return MHZ(200); default: return 0; } diff --git a/cpu/samd5x/include/periph_cpu.h b/cpu/samd5x/include/periph_cpu.h index acae8fddcac5..09d0493de9c3 100644 --- a/cpu/samd5x/include/periph_cpu.h +++ b/cpu/samd5x/include/periph_cpu.h @@ -65,6 +65,7 @@ enum { SAM0_GCLK_32KHZ, /**< 32 kHz clock */ SAM0_GCLK_TIMER, /**< 4-8 MHz clock for xTimer */ SAM0_GCLK_PERIPH, /**< 12-48 MHz (DFLL) clock */ + SAM0_GCLK_200MHZ, /**< 200MHz FDPLL clock */ }; /** @} */