diff --git a/drivers/adc/adc_sam0.c b/drivers/adc/adc_sam0.c index 7cf31bc2ef5..b36f961de47 100644 --- a/drivers/adc/adc_sam0.c +++ b/drivers/adc/adc_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,8 @@ #include LOG_MODULE_REGISTER(adc_sam0, CONFIG_ADC_LOG_LEVEL); +/* clang-format off */ + #define ADC_CONTEXT_USES_KERNEL_TIMER #include "adc_context.h" @@ -46,18 +49,12 @@ struct adc_sam0_data { struct adc_sam0_cfg { Adc *regs; const struct pinctrl_dev_config *pcfg; - -#ifdef MCLK + volatile uint32_t *mclk; uint32_t mclk_mask; - uint32_t gclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t gclk; -#endif - uint32_t freq; uint16_t prescaler; - void (*config_func)(const struct device *dev); }; @@ -449,14 +446,15 @@ static int adc_sam0_init(const struct device *dev) Adc *const adc = cfg->regs; int retval; -#ifdef MCLK - GCLK->PCHCTRL[cfg->gclk_id].reg = cfg->gclk_mask | GCLK_PCHCTRL_CHEN; + *cfg->mclk |= cfg->mclk_mask; - MCLK_ADC |= cfg->mclk_mask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); #else - PM->APBCMASK.bit.ADC_ = 1; - - GCLK->CLKCTRL.reg = cfg->gclk | GCLK_CLKCTRL_CLKEN; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -515,81 +513,82 @@ static DEVICE_API(adc, adc_sam0_api) = { #ifdef MCLK -#define ADC_SAM0_CLOCK_CONTROL(n) \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_mask = UTIL_CAT(GCLK_PCHCTRL_GEN_GCLK, \ - DT_INST_PROP(n, gclk)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch), \ - .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ - UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), - -#define ADC_SAM0_CONFIGURE(n) \ -do { \ - const struct adc_sam0_cfg *const cfg = dev->config; \ - Adc * const adc = cfg->regs; \ - adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \ - | ADC_SAM0_BIASR2R(n) \ - | ADC_SAM0_BIASREFBUF(n); \ +#define ADC_SAM0_CONFIGURE(n) \ +do { \ + const struct adc_sam0_cfg *const cfg = dev->config; \ + Adc * const adc = cfg->regs; \ + adc->CALIB.reg = ADC_SAM0_BIASCOMP(n) \ + | ADC_SAM0_BIASR2R(n) \ + | ADC_SAM0_BIASREFBUF(n); \ } while (false) #else -#define ADC_SAM0_CLOCK_CONTROL(n) \ - .gclk = UTIL_CAT(GCLK_CLKCTRL_GEN_GCLK, DT_INST_PROP(n, gclk)) |\ - GCLK_CLKCTRL_ID_ADC, \ - .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ - UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), - -#define ADC_SAM0_CONFIGURE(n) \ -do { \ - const struct adc_sam0_cfg *const cfg = dev->config; \ - Adc * const adc = cfg->regs; \ - /* Linearity is split across two words */ \ +#define ADC_SAM0_CONFIGURE(n) \ +do { \ + const struct adc_sam0_cfg *const cfg = dev->config; \ + Adc * const adc = cfg->regs; \ + /* Linearity is split across two words */ \ uint32_t lin = ((*(uint32_t *)ADC_FUSES_LINEARITY_0_ADDR) & \ - ADC_FUSES_LINEARITY_0_Msk) >> \ - ADC_FUSES_LINEARITY_0_Pos; \ - lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \ - ADC_FUSES_LINEARITY_1_Msk) >> \ - ADC_FUSES_LINEARITY_1_Pos) << 4; \ + ADC_FUSES_LINEARITY_0_Msk) >> \ + ADC_FUSES_LINEARITY_0_Pos; \ + lin |= (((*(uint32_t *)ADC_FUSES_LINEARITY_1_ADDR) & \ + ADC_FUSES_LINEARITY_1_Msk) >> \ + ADC_FUSES_LINEARITY_1_Pos) << 4; \ uint32_t bias = ((*(uint32_t *)ADC_FUSES_BIASCAL_ADDR) & \ - ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \ - adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \ - ADC_CALIB_LINEARITY_CAL(lin); \ + ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; \ + adc->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | \ + ADC_CALIB_LINEARITY_CAL(lin); \ } while (false) #endif -#define ADC_SAM0_DEVICE(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static void adc_sam0_config_##n(const struct device *dev); \ - static const struct adc_sam0_cfg adc_sam_cfg_##n = { \ - .regs = (Adc *)DT_INST_REG_ADDR(n), \ - ADC_SAM0_CLOCK_CONTROL(n) \ - .freq = UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \ - DT_INST_PROP(n, gclk)), \ - _FREQ_HZ) / \ - DT_INST_PROP(n, prescaler), \ - .config_func = &adc_sam0_config_##n, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - }; \ - static struct adc_sam0_data adc_sam_data_##n = { \ - ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \ - ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \ - ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \ - }; \ - DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \ - &adc_sam_data_##n, \ - &adc_sam_cfg_##n, POST_KERNEL, \ - CONFIG_ADC_INIT_PRIORITY, \ - &adc_sam0_api); \ - static void adc_sam0_config_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \ - DT_INST_IRQ_BY_NAME(n, resrdy, priority), \ - adc_sam0_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \ - ADC_SAM0_CONFIGURE(n); \ +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define ADC_SAM0_GCLK_FREQ(n) \ + UTIL_CAT(UTIL_CAT(SOC_ATMEL_SAM0_GCLK, \ + ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen)), \ + _FREQ_HZ) + +#define ADC_SAM0_FREQ(n) \ + .prescaler = UTIL_CAT(ADC_CTRLx_PRESCALER_DIV, \ + UTIL_CAT(DT_INST_PROP(n, prescaler), _Val)), \ + .freq = ADC_SAM0_GCLK_FREQ(n) / DT_INST_PROP(n, prescaler) + +#define ADC_SAM0_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void adc_sam0_config_##n(const struct device *dev); \ + static const struct adc_sam0_cfg adc_sam_cfg_##n = { \ + .regs = (Adc *)DT_INST_REG_ADDR(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + ADC_SAM0_FREQ(n), \ + .config_func = &adc_sam0_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + static struct adc_sam0_data adc_sam_data_##n = { \ + ADC_CONTEXT_INIT_TIMER(adc_sam_data_##n, ctx), \ + ADC_CONTEXT_INIT_LOCK(adc_sam_data_##n, ctx), \ + ADC_CONTEXT_INIT_SYNC(adc_sam_data_##n, ctx), \ + }; \ + DEVICE_DT_INST_DEFINE(n, adc_sam0_init, NULL, \ + &adc_sam_data_##n, \ + &adc_sam_cfg_##n, POST_KERNEL, \ + CONFIG_ADC_INIT_PRIORITY, \ + &adc_sam0_api); \ + static void adc_sam0_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, resrdy, irq), \ + DT_INST_IRQ_BY_NAME(n, resrdy, priority), \ + adc_sam0_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(n, resrdy, irq)); \ + ADC_SAM0_CONFIGURE(n); \ } DT_INST_FOREACH_STATUS_OKAY(ADC_SAM0_DEVICE) + +/* clang-format on */ diff --git a/drivers/can/can_sam0.c b/drivers/can/can_sam0.c index 74532748e2e..4680fc63a71 100644 --- a/drivers/can/can_sam0.c +++ b/drivers/can/can_sam0.c @@ -3,6 +3,7 @@ * Copyright (c) 2021 Alexander Wachter * Copyright (c) 2022 Kamil Serwus * Copyright (c) 2023 Sebastian Schlupp + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL); +/* clang-format off */ + #define DT_DRV_COMPAT atmel_sam0_can struct can_sam0_config { @@ -26,7 +29,8 @@ struct can_sam0_config { const struct pinctrl_dev_config *pcfg; volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; + uint32_t gclk_gen; + uint16_t gclk_id; int divider; }; @@ -109,6 +113,11 @@ static int can_sam0_get_core_clock(const struct device *dev, uint32_t *rate) static void can_sam0_clock_enable(const struct can_sam0_config *cfg) { + *cfg->mclk |= cfg->mclk_mask; + + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); + /* Enable the GLCK7 with DIV*/ #if defined(CONFIG_SOC_SERIES_SAME51) || defined(CONFIG_SOC_SERIES_SAME54) /*DFFL has to be used as clock source for the ATSAME51/54 family of SoCs*/ @@ -121,13 +130,6 @@ static void can_sam0_clock_enable(const struct can_sam0_config *cfg) | GCLK_GENCTRL_DIV(cfg->divider) | GCLK_GENCTRL_GENEN; #endif - - /* Route channel */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK7 - | GCLK_PCHCTRL_CHEN; - - /* Enable CAN clock in MCLK */ - *cfg->mclk |= cfg->mclk_mask; } static int can_sam0_init(const struct device *dev) @@ -204,6 +206,9 @@ static void config_can_##inst##_irq(void) \ irq_enable(DT_INST_IRQ_BY_NAME(inst, int0, irq)); \ } +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #define CAN_SAM0_CFG_INST(inst) \ CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \ CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \ @@ -211,9 +216,10 @@ static void config_can_##inst##_irq(void) \ static const struct can_sam0_config can_sam0_cfg_##inst = { \ .base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \ .mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ .divider = DT_INST_PROP(inst, divider), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .config_irq = config_can_##inst##_irq, \ @@ -243,3 +249,5 @@ static void config_can_##inst##_irq(void) \ CAN_SAM0_DEVICE_INST(inst) DT_INST_FOREACH_STATUS_OKAY(CAN_SAM0_INST) + +/* clang-format on */ diff --git a/drivers/counter/counter_sam0_tc32.c b/drivers/counter/counter_sam0_tc32.c index 2965fb5c5da..4656000003b 100644 --- a/drivers/counter/counter_sam0_tc32.c +++ b/drivers/counter/counter_sam0_tc32.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +16,8 @@ #include LOG_MODULE_REGISTER(counter_sam0_tc32, CONFIG_COUNTER_LOG_LEVEL); +/* clang-format off */ + struct counter_sam0_tc32_ch_data { counter_alarm_callback_t callback; void *user_data; @@ -31,16 +34,11 @@ struct counter_sam0_tc32_config { struct counter_config_info info; TcCount32 *regs; const struct pinctrl_dev_config *pcfg; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif uint16_t prescaler; - void (*irq_config_func)(const struct device *dev); }; @@ -336,20 +334,15 @@ static int counter_sam0_tc32_initialize(const struct device *dev) TcCount32 *tc = cfg->regs; int retval; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable TC clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* @@ -403,60 +396,57 @@ static DEVICE_API(counter, counter_sam0_tc32_driver_api) = { }; -#ifdef MCLK -#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch), -#else -#define COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id), -#endif +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME -#define SAM0_TC32_PRESCALER(n) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \ +#define SAM0_TC32_PRESCALER(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prescaler), \ (DT_INST_PROP(n, prescaler)), (1)) -#define COUNTER_SAM0_TC32_DEVICE(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static void counter_sam0_tc32_config_##n(const struct device *dev); \ - static const struct counter_sam0_tc32_config \ - \ - counter_sam0_tc32_dev_config_##n = { \ - .info = { \ - .max_top_value = UINT32_MAX, \ - .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ - SAM0_TC32_PRESCALER(n), \ - .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ - .channels = 1 \ - }, \ - .regs = (TcCount32 *)DT_INST_REG_ADDR(n), \ - COUNTER_SAM0_TC32_CLOCK_CONTROL(n) \ - .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ - SAM0_TC32_PRESCALER(n)), \ - .irq_config_func = &counter_sam0_tc32_config_##n, \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - }; \ - \ - static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n;\ - \ - DEVICE_DT_INST_DEFINE(n, \ - &counter_sam0_tc32_initialize, \ - NULL, \ - &counter_sam0_tc32_dev_data_##n, \ - &counter_sam0_tc32_dev_config_##n, \ - PRE_KERNEL_1, \ - CONFIG_COUNTER_INIT_PRIORITY, \ - &counter_sam0_tc32_driver_api); \ - \ - static void counter_sam0_tc32_config_##n(const struct device *dev) \ - { \ - IRQ_CONNECT(DT_INST_IRQN(n), \ - DT_INST_IRQ(n, priority), \ - counter_sam0_tc32_isr, \ - DEVICE_DT_INST_GET(n), 0); \ - irq_enable(DT_INST_IRQN(n)); \ +#define COUNTER_SAM0_TC32_DEVICE(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static void counter_sam0_tc32_config_##n(const struct device *dev); \ + static const struct counter_sam0_tc32_config \ + \ + counter_sam0_tc32_dev_config_##n = { \ + .info = { \ + .max_top_value = UINT32_MAX, \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + SAM0_TC32_PRESCALER(n), \ + .flags = COUNTER_CONFIG_INFO_COUNT_UP, \ + .channels = 1 \ + }, \ + .regs = (TcCount32 *)DT_INST_REG_ADDR(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ + SAM0_TC32_PRESCALER(n)), \ + .irq_config_func = &counter_sam0_tc32_config_##n, \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct counter_sam0_tc32_data counter_sam0_tc32_dev_data_##n; \ + \ + DEVICE_DT_INST_DEFINE(n, \ + &counter_sam0_tc32_initialize, \ + NULL, \ + &counter_sam0_tc32_dev_data_##n, \ + &counter_sam0_tc32_dev_config_##n, \ + PRE_KERNEL_1, \ + CONFIG_COUNTER_INIT_PRIORITY, \ + &counter_sam0_tc32_driver_api); \ + \ + static void counter_sam0_tc32_config_##n(const struct device *dev) \ + { \ + IRQ_CONNECT(DT_INST_IRQN(n), \ + DT_INST_IRQ(n, priority), \ + counter_sam0_tc32_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ } DT_INST_FOREACH_STATUS_OKAY(COUNTER_SAM0_TC32_DEVICE) + +/* clang-format on */ diff --git a/drivers/dac/dac_sam0.c b/drivers/dac/dac_sam0.c index 02013ac9dcb..dc307cfe98e 100644 --- a/drivers/dac/dac_sam0.c +++ b/drivers/dac/dac_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,8 @@ #include LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL); +/* clang-format off */ + /* * Maps between the DTS reference property names and register values. Note that * the ASF uses the 09/2015 names which differ from the 03/2020 datasheet. @@ -27,8 +30,10 @@ LOG_MODULE_REGISTER(dac_sam0, CONFIG_DAC_LOG_LEVEL); struct dac_sam0_cfg { Dac *regs; const struct pinctrl_dev_config *pcfg; - uint8_t pm_apbc_bit; - uint8_t gclk_clkctrl_id; + volatile uint32_t *mclk; + uint32_t mclk_mask; + uint32_t gclk_gen; + uint16_t gclk_id; uint8_t refsel; }; @@ -77,18 +82,22 @@ static int dac_sam0_init(const struct device *dev) Dac *regs = cfg->regs; int retval; - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; + *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); +#endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); if (retval < 0) { return retval; } - /* Enable the clock in PM */ - PM->APBCMASK.reg |= 1 << cfg->pm_apbc_bit; - /* Reset then configure the DAC */ regs->CTRLA.bit.SWRST = 1; while (regs->STATUS.bit.SYNCBUSY) { @@ -110,24 +119,30 @@ static DEVICE_API(dac, api_sam0_driver_api) = { .write_value = dac_sam0_write_value }; -#define SAM0_DAC_REFSEL(n) \ - COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \ +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define SAM0_DAC_REFSEL(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, reference), \ (DT_INST_ENUM_IDX(n, reference)), (0)) -#define SAM0_DAC_INIT(n) \ - PINCTRL_DT_INST_DEFINE(n); \ - static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \ - .regs = (Dac *)DT_INST_REG_ADDR(n), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .pm_apbc_bit = DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit), \ - .gclk_clkctrl_id = \ - DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id), \ - .refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \ - &dac_sam0_cfg_##n, POST_KERNEL, \ - CONFIG_DAC_INIT_PRIORITY, \ +#define SAM0_DAC_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + static const struct dac_sam0_cfg dac_sam0_cfg_##n = { \ + .regs = (Dac *)DT_INST_REG_ADDR(n), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ + .refsel = UTIL_CAT(SAM0_DAC_REFSEL_, SAM0_DAC_REFSEL(n)), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, &dac_sam0_init, NULL, NULL, \ + &dac_sam0_cfg_##n, POST_KERNEL, \ + CONFIG_DAC_INIT_PRIORITY, \ &api_sam0_driver_api) DT_INST_FOREACH_STATUS_OKAY(SAM0_DAC_INIT); + +/* clang-format on */ diff --git a/drivers/i2c/i2c_sam0.c b/drivers/i2c/i2c_sam0.c index 0f668448407..f28c65a359e 100644 --- a/drivers/i2c/i2c_sam0.c +++ b/drivers/i2c/i2c_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Derek Hageman + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +19,8 @@ #include LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL); +/* clang-format off */ + #include "i2c-priv.h" #ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER @@ -34,14 +37,10 @@ struct i2c_sam0_dev_config { SercomI2cm *regs; const struct pinctrl_dev_config *pcfg; uint32_t bitrate; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; void (*irq_config_func)(const struct device *dev); #ifdef CONFIG_I2C_SAM0_DMA_DRIVEN @@ -711,20 +710,17 @@ static int i2c_sam0_initialize(const struct device *dev) SercomI2cm *i2c = cfg->regs; int retval; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - /* Enable SERCOM clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif + /* Disable all I2C interrupts */ i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK; @@ -801,7 +797,7 @@ static DEVICE_API(i2c, i2c_sam0_driver_api) = { #if DT_INST_IRQ_HAS_IDX(0, 3) #define I2C_SAM0_IRQ_HANDLER(n) \ -static void i2c_sam0_irq_config_##n(const struct device *dev) \ +static void i2c_sam0_irq_config_##n(const struct device *dev) \ { \ SAM0_I2C_IRQ_CONNECT(n, 0); \ SAM0_I2C_IRQ_CONNECT(n, 1); \ @@ -810,21 +806,25 @@ static void i2c_sam0_irq_config_##n(const struct device *dev) \ } #else #define I2C_SAM0_IRQ_HANDLER(n) \ -static void i2c_sam0_irq_config_##n(const struct device *dev) \ +static void i2c_sam0_irq_config_##n(const struct device *dev) \ { \ SAM0_I2C_IRQ_CONNECT(n, 0); \ } #endif +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #ifdef MCLK #define I2C_SAM0_CONFIG(n) \ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ .regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .bitrate = DT_INST_PROP(n, clock_frequency), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .irq_config_func = &i2c_sam0_irq_config_##n, \ I2C_SAM0_DMA_CHANNELS(n) \ } @@ -834,8 +834,10 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ .regs = (SercomI2cm *)DT_INST_REG_ADDR(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .bitrate = DT_INST_PROP(n, clock_frequency), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .irq_config_func = &i2c_sam0_irq_config_##n, \ I2C_SAM0_DMA_CHANNELS(n) \ } @@ -856,3 +858,5 @@ static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = { \ I2C_SAM0_IRQ_HANDLER(n) DT_INST_FOREACH_STATUS_OKAY(I2C_SAM0_DEVICE) + +/* clang-format on */ diff --git a/drivers/pwm/pwm_sam0_tc.c b/drivers/pwm/pwm_sam0_tc.c index 655c0cb0491..8f8b72cf2ff 100644 --- a/drivers/pwm/pwm_sam0_tc.c +++ b/drivers/pwm/pwm_sam0_tc.c @@ -28,6 +28,8 @@ #include #include +/* clang-format off */ + /* Static configuration */ struct pwm_sam0_config { Tc *regs; @@ -36,15 +38,10 @@ struct pwm_sam0_config { uint8_t counter_size; uint16_t prescaler; uint32_t freq; - -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif }; #define COUNTER_8BITS 8U @@ -133,19 +130,19 @@ static int pwm_sam0_set_cycles(const struct device *dev, uint32_t channel, uint3 static int pwm_sam0_init(const struct device *dev) { const struct pwm_sam0_config *const cfg = dev->config; - int retval; - Tc *regs = cfg->regs; uint8_t counter_size = cfg->counter_size; + Tc *regs = cfg->regs; + int retval; - /* Enable the clocks */ -#ifdef MCLK - GCLK->PCHCTRL[cfg->gclk_id].reg = - GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); #else - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - PM->APBCMASK.reg |= cfg->pm_apbcmask; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -185,30 +182,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = { .get_cycles_per_sec = pwm_sam0_get_cycles_per_sec, }; -#ifdef MCLK -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch) -#else -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id) -#endif - -#define PWM_SAM0_INIT(inst) \ - PINCTRL_DT_INST_DEFINE(inst); \ - static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ - .regs = (Tc *)DT_INST_REG_ADDR(inst), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ - .channels = DT_INST_PROP(inst, channels), \ - .counter_size = DT_INST_PROP(inst, counter_size), \ - .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, DT_INST_PROP(inst, prescaler)), \ - .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / DT_INST_PROP(inst, prescaler), \ - PWM_SAM0_INIT_CLOCKS(inst), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, NULL, &pwm_sam0_config_##inst, \ - POST_KERNEL, CONFIG_PWM_TC_INIT_PRIORITY, &pwm_sam0_driver_api); +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define PWM_SAM0_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst) \ + static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ + .regs = (Tc *)DT_INST_REG_ADDR(inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .channels = DT_INST_PROP(inst, channels), \ + .counter_size = DT_INST_PROP(inst, counter_size), \ + .prescaler = UTIL_CAT(TC_CTRLA_PRESCALER_DIV, \ + DT_INST_PROP(inst, prescaler)), \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + DT_INST_PROP(inst, prescaler), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ + NULL, &pwm_sam0_config_##inst, \ + POST_KERNEL, CONFIG_PWM_TC_INIT_PRIORITY, \ + &pwm_sam0_driver_api); DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT) + +/* clang-format on */ diff --git a/drivers/pwm/pwm_sam0_tcc.c b/drivers/pwm/pwm_sam0_tcc.c index 20b40c917da..1d5578c5a77 100644 --- a/drivers/pwm/pwm_sam0_tcc.c +++ b/drivers/pwm/pwm_sam0_tcc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ #include #include +/* clang-format off */ + /* Static configuration */ struct pwm_sam0_config { Tcc *regs; @@ -25,15 +28,10 @@ struct pwm_sam0_config { uint8_t counter_size; uint16_t prescaler; uint32_t freq; - -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; + uint32_t gclk_gen; uint16_t gclk_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif }; /* Wait for the peripheral to finish all commands */ @@ -106,15 +104,15 @@ static int pwm_sam0_init(const struct device *dev) Tcc *regs = cfg->regs; int retval; - /* Enable the clocks */ -#ifdef MCLK - GCLK->PCHCTRL[cfg->gclk_id].reg = - GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; *cfg->mclk |= cfg->mclk_mask; + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); #else - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - PM->APBCMASK.reg |= cfg->pm_apbcmask; + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif retval = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); @@ -140,34 +138,31 @@ static DEVICE_API(pwm, pwm_sam0_driver_api) = { .get_cycles_per_sec = pwm_sam0_get_cycles_per_sec, }; -#ifdef MCLK -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \ - .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch) -#else -#define PWM_SAM0_INIT_CLOCKS(inst) \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, clkctrl_id) -#endif - -#define PWM_SAM0_INIT(inst) \ - PINCTRL_DT_INST_DEFINE(inst); \ - static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ - .regs = (Tcc *)DT_INST_REG_ADDR(inst), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ - .channels = DT_INST_PROP(inst, channels), \ - .counter_size = DT_INST_PROP(inst, counter_size), \ - .prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \ - DT_INST_PROP(inst, prescaler)), \ - .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ - DT_INST_PROP(inst, prescaler), \ - PWM_SAM0_INIT_CLOCKS(inst), \ - }; \ - \ - DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ - NULL, &pwm_sam0_config_##inst, \ - POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ - &pwm_sam0_driver_api); +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + +#define PWM_SAM0_INIT(inst) \ + PINCTRL_DT_INST_DEFINE(inst); \ + static const struct pwm_sam0_config pwm_sam0_config_##inst = { \ + .regs = (Tcc *)DT_INST_REG_ADDR(inst), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ + .channels = DT_INST_PROP(inst, channels), \ + .counter_size = DT_INST_PROP(inst, counter_size), \ + .prescaler = UTIL_CAT(TCC_CTRLA_PRESCALER_DIV, \ + DT_INST_PROP(inst, prescaler)), \ + .freq = SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / \ + DT_INST_PROP(inst, prescaler), \ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(inst, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(inst), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(inst, bit), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &pwm_sam0_init, NULL, \ + NULL, &pwm_sam0_config_##inst, \ + POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \ + &pwm_sam0_driver_api); DT_INST_FOREACH_STATUS_OKAY(PWM_SAM0_INIT) + +/* clang-format on */ diff --git a/drivers/serial/uart_sam0.c b/drivers/serial/uart_sam0.c index 10e222f12c6..407e2ebe7b6 100644 --- a/drivers/serial/uart_sam0.c +++ b/drivers/serial/uart_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +18,8 @@ #include #include +/* clang-format off */ + #ifndef SERCOM_USART_CTRLA_MODE_USART_INT_CLK #define SERCOM_USART_CTRLA_MODE_USART_INT_CLK SERCOM_USART_CTRLA_MODE(0x1) #endif @@ -35,14 +38,11 @@ struct uart_sam0_dev_cfg { uint32_t baudrate; uint32_t pads; bool collision_detect; -#ifdef MCLK volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; + #if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_SAM0_ASYNC void (*irq_config_func)(const struct device *dev); #endif @@ -510,20 +510,15 @@ static int uart_sam0_init(const struct device *dev) SercomUsart * const usart = cfg->regs; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable SERCOM clock in MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* Disable all USART interrupts */ @@ -1272,34 +1267,23 @@ static void uart_sam0_irq_config_##n(const struct device *dev) \ #define UART_SAM0_SERCOM_COLLISION_DETECT(n) \ (DT_INST_PROP(n, collision_detection)) -#ifdef MCLK -#define UART_SAM0_CONFIG_DEFN(n) \ -static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \ - .regs = (SercomUsart *)DT_INST_REG_ADDR(n), \ - .baudrate = DT_INST_PROP(n, current_speed), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ - .pads = UART_SAM0_SERCOM_PADS(n), \ - .collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \ - .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - UART_SAM0_IRQ_HANDLER_FUNC(n) \ - UART_SAM0_DMA_CHANNELS(n) \ -} -#else +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #define UART_SAM0_CONFIG_DEFN(n) \ static const struct uart_sam0_dev_cfg uart_sam0_config_##n = { \ .regs = (SercomUsart *)DT_INST_REG_ADDR(n), \ .baudrate = DT_INST_PROP(n, current_speed), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = UART_SAM0_SERCOM_PADS(n), \ .collision_detect = UART_SAM0_SERCOM_COLLISION_DETECT(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ UART_SAM0_IRQ_HANDLER_FUNC(n) \ UART_SAM0_DMA_CHANNELS(n) \ } -#endif #define UART_SAM0_DEVICE_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ @@ -1314,3 +1298,5 @@ DEVICE_DT_INST_DEFINE(n, uart_sam0_init, NULL, \ UART_SAM0_IRQ_HANDLER(n) DT_INST_FOREACH_STATUS_OKAY(UART_SAM0_DEVICE_INIT) + +/* clang-format on */ diff --git a/drivers/spi/spi_sam0.c b/drivers/spi/spi_sam0.c index ddf820e5579..6dd2d64fad5 100644 --- a/drivers/spi/spi_sam0.c +++ b/drivers/spi/spi_sam0.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +10,8 @@ #include LOG_MODULE_REGISTER(spi_sam0); +/* clang-format off */ + #include "spi_context.h" #include #include @@ -27,14 +30,12 @@ struct spi_sam0_config { SercomSpi *regs; uint32_t pads; const struct pinctrl_dev_config *pcfg; -#ifdef MCLK + volatile uint32_t *mclk; uint32_t mclk_mask; - uint16_t gclk_core_id; -#else - uint32_t pm_apbcmask; - uint16_t gclk_clkctrl_id; -#endif + uint32_t gclk_gen; + uint16_t gclk_id; + #ifdef CONFIG_SPI_ASYNC const struct device *dma_dev; uint8_t tx_dma_request; @@ -645,20 +646,15 @@ static int spi_sam0_init(const struct device *dev) struct spi_sam0_data *data = dev->data; SercomSpi *regs = cfg->regs; -#ifdef MCLK - /* Enable the GCLK */ - GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 | - GCLK_PCHCTRL_CHEN; - - /* Enable the MCLK */ *cfg->mclk |= cfg->mclk_mask; -#else - /* Enable the GCLK */ - GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 | - GCLK_CLKCTRL_CLKEN; - /* Enable SERCOM clock in PM */ - PM->APBCMASK.reg |= cfg->pm_apbcmask; +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = GCLK_PCHCTRL_CHEN + | GCLK_PCHCTRL_GEN(cfg->gclk_gen); +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(cfg->gclk_gen) + | GCLK_CLKCTRL_ID(cfg->gclk_id); #endif /* Disable all SPI interrupts */ @@ -717,13 +713,17 @@ static DEVICE_API(spi, spi_sam0_driver_api) = { SERCOM_SPI_CTRLA_DIPO(DT_INST_PROP(n, dipo)) | \ SERCOM_SPI_CTRLA_DOPO(DT_INST_PROP(n, dopo)) +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + #ifdef MCLK #define SPI_SAM0_DEFINE_CONFIG(n) \ static const struct spi_sam0_config spi_sam0_config_##n = { \ .regs = (SercomSpi *)DT_INST_REG_ADDR(n), \ - .mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n), \ - .mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)), \ - .gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = SPI_SAM0_SERCOM_PADS(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ SPI_SAM0_DMA_CHANNELS(n) \ @@ -732,8 +732,10 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ #define SPI_SAM0_DEFINE_CONFIG(n) \ static const struct spi_sam0_config spi_sam0_config_##n = { \ .regs = (SercomSpi *)DT_INST_REG_ADDR(n), \ - .pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)), \ - .gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\ + .gclk_gen = ASSIGNED_CLOCKS_CELL_BY_NAME(n, gclk, gen), \ + .gclk_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, id), \ + .mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n), \ + .mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, bit), \ .pads = SPI_SAM0_SERCOM_PADS(n), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ SPI_SAM0_DMA_CHANNELS(n) \ @@ -755,3 +757,5 @@ static const struct spi_sam0_config spi_sam0_config_##n = { \ &spi_sam0_driver_api); DT_INST_FOREACH_STATUS_OKAY(SPI_SAM0_DEVICE_INIT) + +/* clang-format on */ diff --git a/drivers/timer/sam0_rtc_timer.c b/drivers/timer/sam0_rtc_timer.c index 8e87b1848bb..1ad978aa2bc 100644 --- a/drivers/timer/sam0_rtc_timer.c +++ b/drivers/timer/sam0_rtc_timer.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 omSquare s.r.o. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +26,8 @@ #include #include +/* clang-format off */ + /* RTC registers. */ #define RTC0 ((RtcMode0 *) DT_INST_REG_ADDR(0)) @@ -66,10 +69,6 @@ BUILD_ASSERT(CYCLES_PER_TICK > 1, #endif /* CONFIG_TICKLESS_KERNEL */ -/* Helper macro to get the correct GCLK GEN based on configuration. */ -#define GCLK_GEN(n) GCLK_EVAL(n) -#define GCLK_EVAL(n) GCLK_CLKCTRL_GEN_GCLK##n - /* Tick/cycle count of the last announce call. */ static volatile uint32_t rtc_last; @@ -245,29 +244,35 @@ uint32_t sys_clock_cycle_get_32(void) return rtc_count(); } +#define ASSIGNED_CLOCKS_CELL_BY_NAME \ + ATMEL_SAM0_DT_INST_ASSIGNED_CLOCKS_CELL_BY_NAME + static int sys_clock_driver_init(void) { - int retval; + volatile uint32_t *mclk = ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(0); + uint32_t mclk_mask = ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(0, bit); + *cfg->mclk |= cfg->mclk_mask; #ifdef MCLK - MCLK->APBAMASK.reg |= MCLK_APBAMASK_RTC; OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_ULP32K; #else - /* Set up bus clock and GCLK generator. */ - PM->APBAMASK.reg |= PM_APBAMASK_RTC; - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(RTC_GCLK_ID) | GCLK_CLKCTRL_CLKEN - | GCLK_GEN(DT_INST_PROP(0, clock_generator)); + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN + | GCLK_CLKCTRL_GEN(ASSIGNED_CLOCKS_CELL_BY_NAME(0, gclk, gen)) + | GCLK_CLKCTRL_ID(DT_INST_CLOCKS_CELL_BY_NAME(0, gclk, id)); /* Synchronize GCLK. */ while (GCLK->STATUS.bit.SYNCBUSY) { } #endif - retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); - if (retval < 0) { +#ifndef CONFIG_TICKLESS_KERNEL + int retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT); + + if (retval < 0 && retval != -ENOENT) { return retval; } +#endif /* Reset module to hardware defaults. */ rtc_reset(); @@ -330,3 +335,5 @@ static int sys_clock_driver_init(void) SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); + +/* clang-format on */ diff --git a/dts/arm/atmel/samc21.dtsi b/dts/arm/atmel/samc21.dtsi index f54b5672e75..0e91f58e341 100644 --- a/dts/arm/atmel/samc21.dtsi +++ b/dts/arm/atmel/samc21.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,11 +23,12 @@ interrupt-names = "resrdy"; clocks = <&gclk 34>, <&mclk 0x1c 18>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; #io-channel-cells = <1>; - gclk = <0>; prescaler = <4>; }; @@ -36,6 +38,8 @@ interrupts = <13 0>; clocks = <&gclk 23>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -45,6 +49,8 @@ interrupts = <14 0>; clocks = <&gclk 25>, <&mclk 0x1c 6>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -55,6 +61,8 @@ interrupt-names = "int0"; clocks = <&gclk 26>, <&mclk 0x10 8>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; @@ -68,6 +76,8 @@ interrupt-names = "int0"; clocks = <&gclk 27>, <&mclk 0x10 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>; diff --git a/dts/arm/atmel/samc2x.dtsi b/dts/arm/atmel/samc2x.dtsi index a1a78112487..ba70408eb46 100644 --- a/dts/arm/atmel/samc2x.dtsi +++ b/dts/arm/atmel/samc2x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Kamil Serwus + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,7 +65,6 @@ compatible = "atmel,sam0-nvmctrl"; reg = <0x41004000 0x22>; interrupts = <6 0>; - #address-cells = <1>; #size-cells = <1>; @@ -78,17 +78,25 @@ }; mclk: mclk@40000800 { - compatible = "atmel,samc2x-mclk"; + compatible = "atmel,sam0-mclk"; reg = <0x40000800 0x400>; #clock-cells = <2>; }; + osc32kctrl: osc32kctrl@40001400 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001400 0x400>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; + }; + gclk: gclk@40001c00 { - compatible = "atmel,samc2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001c00 0x400>; #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; eic: eic@40002800 { @@ -124,11 +132,12 @@ interrupt-names = "resrdy"; clocks = <&gclk 33>, <&mclk 0x1c 17>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; #io-channel-cells = <1>; - gclk = <0>; prescaler = <4>; }; @@ -138,6 +147,8 @@ interrupts = <9 0>; clocks = <&gclk 19>, <&mclk 0x1c 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -147,6 +158,8 @@ interrupts = <10 0>; clocks = <&gclk 20>, <&mclk 0x1c 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -156,6 +169,8 @@ interrupts = <11 0>; clocks = <&gclk 21>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -165,6 +180,8 @@ interrupts = <12 0>; clocks = <&gclk 22>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -174,6 +191,8 @@ interrupts = <17 0>; clocks = <&gclk 28>, <&mclk 0x1c 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -186,6 +205,8 @@ interrupts = <18 0>; clocks = <&gclk 28>, <&mclk 0x1c 10>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -198,6 +219,8 @@ interrupts = <19 0>; clocks = <&gclk 29>, <&mclk 0x1c 11>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; @@ -244,11 +267,13 @@ rtc: rtc@40002400 { compatible = "atmel,sam0-rtc"; - reg = <0x40002400 0x1C>; - interrupts = <3 0>; + reg = <0x40002400 0x24>; + interrupts = <2 0>; + clocks = <&osc32kctrl>, <&mclk 0x14 9>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; - - clock-generator = <0>; }; }; }; diff --git a/dts/arm/atmel/samd20.dtsi b/dts/arm/atmel/samd20.dtsi index 8e367d9fd9a..26c16e36e2d 100644 --- a/dts/arm/atmel/samd20.dtsi +++ b/dts/arm/atmel/samd20.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 Sean Nyekjaer + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +21,8 @@ interrupts = <13 0>; clocks = <&gclk 0x13>, <&pm 0x20 8>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -29,6 +32,8 @@ interrupts = <15 0>; clocks = <&gclk 0x14>, <&pm 0x20 10>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -38,6 +43,8 @@ interrupts = <19 0>; clocks = <&gclk 0x16>, <&pm 0x20 14>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; }; @@ -47,48 +54,71 @@ interrupts = <23 0>; clocks = <&gclk 26>, <&pm 0x20 18>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; +}; + +&rtc { + clocks = <&gclk 2>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 4>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <7 0>; clocks = <&gclk 0xd>, <&pm 0x20 2>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <8 0>; clocks = <&gclk 0xe>, <&pm 0x20 3>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <9 0>; clocks = <&gclk 0xf>, <&pm 0x20 4>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <10 0>; clocks = <&gclk 0x10>, <&pm 0x20 5>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <11 0>; clocks = <&gclk 0x11>, <&pm 0x20 6>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <12 0>; clocks = <&gclk 0x12>, <&pm 0x20 7>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <17 0>; clocks = <&gclk 0x15>, <&pm 0x20 12>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { @@ -96,4 +126,11 @@ interrupt-names = "resrdy"; clocks = <&gclk 0x17>, <&pm 0x20 16>; clock-names = "GCLK", "PM"; + /* + * 2.1 MHz is ADC max clock + * 8 MHz GCLK / 4 = 2 MHz + * Generator 3: DFLL48M / 8MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/samd21.dtsi b/dts/arm/atmel/samd21.dtsi index c4692ffa9e5..790bfe007a6 100644 --- a/dts/arm/atmel/samd21.dtsi +++ b/dts/arm/atmel/samd21.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +41,8 @@ interrupts = <21 0>; clocks = <&gclk 0x1d>, <&pm 0x20 14>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -49,6 +52,8 @@ interrupts = <15 0>; clocks = <&gclk 26>, <&pm 0x20 8>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -61,6 +66,8 @@ interrupts = <16 0>; clocks = <&gclk 26>, <&pm 0x20 9>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; @@ -73,6 +80,8 @@ interrupts = <17 0>; clocks = <&gclk 27>, <&pm 0x20 10>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; @@ -85,53 +94,83 @@ interrupts = <25 0>; clocks = <&gclk 33>, <&pm 0x20 18>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; +}; + +&rtc { + clocks = <&gclk 4>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 4>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <9 0>; clocks = <&gclk 0x14>, <&pm 0x20 2>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <10 0>; clocks = <&gclk 0x15>, <&pm 0x20 3>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <11 0>; clocks = <&gclk 0x16>, <&pm 0x20 4>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <12 0>; clocks = <&gclk 0x17>, <&pm 0x20 5>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <13 0>; clocks = <&gclk 0x18>, <&pm 0x20 6>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <14 0>; clocks = <&gclk 0x19>, <&pm 0x20 7>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <19 0>; clocks = <&gclk 0x1c>, <&pm 0x20 12>; clock-names = "GCLK", "PM"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { - clocks = <&gclk 0x1e>, <&pm 0x20 16>; - clock-names = "GCLK", "PM"; interrupts = <23 0>; interrupt-names = "resrdy"; + clocks = <&gclk 0x1e>, <&pm 0x20 16>; + clock-names = "GCLK", "PM"; + /* + * 2.1 MHz is ADC max clock + * 8 MHz GCLK / 4 = 2 MHz + * Generator 3: DFLL48M / 8MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/samd2x.dtsi b/dts/arm/atmel/samd2x.dtsi index d40e558f732..af2d30f47b9 100644 --- a/dts/arm/atmel/samd2x.dtsi +++ b/dts/arm/atmel/samd2x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Google LLC. + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -77,7 +78,7 @@ }; pm: pm@40000400 { - compatible = "atmel,samd2x-pm"; + compatible = "atmel,sam0-mclk"; reg = <0x40000400 0x400>; interrupts = <0 0>; @@ -85,10 +86,11 @@ }; gclk: gclk@40000c00 { - compatible = "atmel,samd2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40000c00 0x400>; #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; eic: eic@40001800 { @@ -188,8 +190,6 @@ reg = <0x40001400 0x1C>; interrupts = <3 0>; status = "disabled"; - - clock-generator = <0>; }; adc: adc@42004000 { @@ -199,11 +199,6 @@ #io-channel-cells = <1>; - /* - * 2.1 MHz max, so clock it with the - * 8 MHz GCLK / 4 = 2 MHz - */ - gclk = <3>; prescaler = <4>; }; diff --git a/dts/arm/atmel/samd5x.dtsi b/dts/arm/atmel/samd5x.dtsi index 12593682eae..6282b510093 100644 --- a/dts/arm/atmel/samd5x.dtsi +++ b/dts/arm/atmel/samd5x.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 ML!PA Consulting GmbH + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -88,17 +89,25 @@ }; mclk: mclk@40000800 { - compatible = "atmel,samd5x-mclk"; + compatible = "atmel,sam0-mclk"; reg = <0x40000800 0x400>; #clock-cells = <2>; }; + osc32kctrl: osc32kctrl@40001400 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001400 0x400>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; + }; + gclk: gclk@40001c00 { - compatible = "atmel,samd5x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001c00 0x400>; #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; nvmctrl: nvmctrl@41004000 { @@ -168,6 +177,8 @@ interrupts = <46 0>, <47 0>, <48 0>, <49 0>; clocks = <&gclk 7>, <&mclk 0x14 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -177,6 +188,8 @@ interrupts = <50 0>, <51 0>, <52 0>, <53 0>; clocks = <&gclk 8>, <&mclk 0x14 13>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -186,6 +199,8 @@ interrupts = <54 0>, <55 0>, <56 0>, <57 0>; clocks = <&gclk 23>, <&mclk 0x18 9>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -195,6 +210,8 @@ interrupts = <58 0>, <59 0>, <60 0>, <61 0>; clocks = <&gclk 24>, <&mclk 0x18 10>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -204,6 +221,8 @@ interrupts = <62 0>, <63 0>, <64 0>, <65 0>; clocks = <&gclk 34>, <&mclk 0x20 0>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -213,6 +232,8 @@ interrupts = <66 0>, <67 0>, <68 0>, <69 0>; clocks = <&gclk 35>, <&mclk 0x20 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -222,6 +243,8 @@ interrupts = <70 0>, <71 0>, <72 0>, <73 0>; clocks = <&gclk 36>, <&mclk 0x20 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -231,6 +254,8 @@ interrupts = <74 0>, <75 0>, <76 0>, <77 0>; clocks = <&gclk 37>, <&mclk 0x20 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -299,11 +324,13 @@ rtc: rtc@40002400 { compatible = "atmel,sam0-rtc"; - reg = <0x40002400 0x1C>; + reg = <0x40002400 0x40>; interrupts = <11 0>; + clocks = <&osc32kctrl>, <&mclk 0x14 9>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; - - clock-generator = <0>; }; adc0: adc@43001c00 { @@ -313,17 +340,20 @@ interrupt-names = "overrun", "resrdy"; clocks = <&gclk 40>, <&mclk 0x20 7>; clock-names = "GCLK", "MCLK"; - status = "disabled"; - - #io-channel-cells = <1>; - /* - * 16 MHz max, source clock must not exceed 100 MHz. + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. * - table 54-8, section 54.6, page 2020 * - table 54-24, section 54.10.4, page 2031 - * -> 48 MHz GCLK(2) / 4 = 12 MHz + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 */ - gclk = <2>; + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + + status = "disabled"; + + #io-channel-cells = <1>; + prescaler = <4>; calib-offset = <0>; }; @@ -335,17 +365,19 @@ interrupt-names = "overrun", "resrdy"; clocks = <&gclk 41>, <&mclk 0x20 8>; clock-names = "GCLK", "MCLK"; - status = "disabled"; - - #io-channel-cells = <1>; - /* - * 16 MHz max, source clock must not exceed 100 MHz. + * 16 MHz is ADC max clock, source clock must not exceed 100 MHz. * - table 54-8, section 54.6, page 2020 * - table 54-24, section 54.10.4, page 2031 - * -> 48 MHz GCLK(2) / 4 = 12 MHz + * 48 MHz GCLK / 4 = 12 MHz + * Generator 2: DFLL48M / 4 */ - gclk = <2>; + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + status = "disabled"; + + #io-channel-cells = <1>; + prescaler = <4>; calib-offset = <14>; }; @@ -356,6 +388,8 @@ interrupts = <107 0>; clocks = <&gclk 9>, <&mclk 0x14 14>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -365,6 +399,8 @@ interrupts = <109 0>; clocks = <&gclk 26>, <&mclk 0x18 13>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -374,6 +410,8 @@ interrupts = <111 0>; clocks = <&gclk 30>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -383,6 +421,8 @@ interrupts = <113 0>; clocks = <&gclk 39>, <&mclk 0x20 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; }; @@ -393,6 +433,8 @@ <90 0>, <91 0>; clocks = <&gclk 25>, <&mclk 0x18 11>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <6>; @@ -405,6 +447,8 @@ interrupts = <92 0>, <93 0>, <94 0>, <95 0>, <96 0>; clocks = <&gclk 25>, <&mclk 0x18 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -417,6 +461,8 @@ interrupts = <97 0>, <98 0>, <99 0>, <100 0>; clocks = <&gclk 29>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <3>; @@ -429,6 +475,8 @@ interrupts = <101 0>, <102 0>, <103 0>; clocks = <&gclk 29>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; @@ -441,6 +489,8 @@ interrupts = <104 0>, <105 0>, <106 0>; clocks = <&gclk 38>, <&mclk 0x20 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; diff --git a/dts/arm/atmel/same5x.dtsi b/dts/arm/atmel/same5x.dtsi index 9df4876736a..f7b0418c4c1 100644 --- a/dts/arm/atmel/same5x.dtsi +++ b/dts/arm/atmel/same5x.dtsi @@ -1,6 +1,7 @@ /* * Copyright (c) 2020 Stephanos Ioannidis * Copyright (c) 2023 Sebastian Schlupp + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,6 +37,8 @@ interrupt-names = "int0", "int1"; clocks = <&gclk 27>, <&mclk 0x10 17>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; @@ -49,6 +52,8 @@ interrupt-names = "int0", "int1"; clocks = <&gclk 28>, <&mclk 0x10 18>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; diff --git a/dts/arm/atmel/saml21.dtsi b/dts/arm/atmel/saml21.dtsi index 6e015b5772c..de2f456e200 100644 --- a/dts/arm/atmel/saml21.dtsi +++ b/dts/arm/atmel/saml21.dtsi @@ -21,6 +21,8 @@ interrupts = <14 0>; clocks = <&gclk 25>, <&mclk 0x1c 5>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -33,6 +35,8 @@ interrupts = <15 0>; clocks = <&gclk 25>, <&mclk 0x1c 6>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <4>; @@ -45,6 +49,8 @@ interrupts = <16 0>; clocks = <&gclk 26>, <&mclk 0x1c 7>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; status = "disabled"; channels = <2>; @@ -57,48 +63,64 @@ interrupts = <24 0>; clocks = <&gclk 32>, <&mclk 0x1c 12>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom0 { interrupts = <8 0>; clocks = <&gclk 18>, <&mclk 0x1c 0>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom1 { interrupts = <9 0>; clocks = <&gclk 19>, <&mclk 0x1c 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom2 { interrupts = <10 0>; clocks = <&gclk 20>, <&mclk 0x1c 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom3 { interrupts = <11 0>; clocks = <&gclk 21>, <&mclk 0x1c 3>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom4 { interrupts = <12 0>; clocks = <&gclk 22>, <&mclk 0x1c 4>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &sercom5 { interrupts = <13 0>; clocks = <&gclk 24>, <&mclk 0x20 1>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &tc4 { interrupts = <21 0>; clocks = <&gclk 29>, <&mclk 0x20 2>; clock-names = "GCLK", "MCLK"; + atmel,assigned-clocks = <&gclk 0>; + atmel,assigned-clock-names = "GCLK"; }; &adc { @@ -106,4 +128,11 @@ interrupt-names = "resrdy"; clocks = <&gclk 30>, <&mclk 0x20 3>; clock-names = "GCLK", "MCLK"; + /* + * 16 MHz is ADC max clock + * 48 MHz DFLL / 2 / 2 = 12 MHz + * Generator 3: 48MHz + */ + atmel,assigned-clocks = <&gclk 3>; + atmel,assigned-clock-names = "GCLK"; }; diff --git a/dts/arm/atmel/saml2x.dtsi b/dts/arm/atmel/saml2x.dtsi index d9191c03a13..efbdd64d869 100644 --- a/dts/arm/atmel/saml2x.dtsi +++ b/dts/arm/atmel/saml2x.dtsi @@ -32,8 +32,8 @@ }; chosen { - zephyr,flash-controller = &nvmctrl; zephyr,entropy = &trng; + zephyr,flash-controller = &nvmctrl; }; cpus { @@ -80,26 +80,27 @@ }; }; - pm: pm@40000400 { - compatible = "atmel,saml2x-pm"; + mclk: mclk@40000400 { + compatible = "atmel,sam0-mclk"; reg = <0x40000400 0x400>; - interrupts = <0 0>; #clock-cells = <2>; }; - mclk: mclk@40000400 { - compatible = "atmel,saml2x-mclk"; - reg = <0x40000400 0x400>; + osc32kctrl: osc32kctrl@40001000 { + compatible = "atmel,sam0-osc32kctrl"; + reg = <0x40001000 0x400>; - #clock-cells = <2>; + #clock-cells = <0>; + #atmel,assigned-clock-cells = <1>; }; gclk: gclk@40001800 { - compatible = "atmel,saml2x-gclk"; + compatible = "atmel,sam0-gclk"; reg = <0x40001800 0x400>; #clock-cells = <1>; + #atmel,assigned-clock-cells = <1>; }; dmac: dmac@44000400 { @@ -195,11 +196,13 @@ rtc: rtc@40002000 { compatible = "atmel,sam0-rtc"; - reg = <0x40002000 0x1c>; + reg = <0x40002000 0x44>; interrupts = <2 0>; + clocks = <&osc32kctrl>, <&mclk 0x14 8>; + clock-names = "OSC32KCTRL", "MCLK"; + atmel,assigned-clocks = <&osc32kctrl 0>; + atmel,assigned-clock-names = "OSC32KCTRL"; status = "disabled"; - - clock-generator = <0>; }; adc: adc@43000c00 { @@ -209,11 +212,6 @@ #io-channel-cells = <1>; - /* - * 16 MHz max, so clock it with the - * 48 MHz DFLL / 2 / 2 = 12 MHz - */ - gclk = <3>; prescaler = <2>; }; diff --git a/dts/arm/atmel/samr34.dtsi b/dts/arm/atmel/samr34.dtsi index 351e02bb1e1..c14a08b28cf 100644 --- a/dts/arm/atmel/samr34.dtsi +++ b/dts/arm/atmel/samr34.dtsi @@ -28,6 +28,7 @@ #atmel,pin-cells = <2>; #gpio-cells = <2>; + gpio-controller; }; }; diff --git a/dts/bindings/adc/atmel,sam0-adc.yaml b/dts/bindings/adc/atmel,sam0-adc.yaml index e403b2316b6..71c7941bcba 100644 --- a/dts/bindings/adc/atmel,sam0-adc.yaml +++ b/dts/bindings/adc/atmel,sam0-adc.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 family ADC @@ -8,6 +9,7 @@ compatible: "atmel,sam0-adc" include: - name: adc-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,10 +24,11 @@ properties: clock-names: required: true - gclk: - type: int + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: required: true - description: generic clock generator source prescaler: type: int diff --git a/dts/bindings/arm/atmel,sam0-sercom.yaml b/dts/bindings/arm/atmel,sam0-sercom.yaml index 30fb3b59176..f3aa21cc281 100644 --- a/dts/bindings/arm/atmel,sam0-sercom.yaml +++ b/dts/bindings/arm/atmel,sam0-sercom.yaml @@ -1,8 +1,13 @@ +# Copyright (c) 2024, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Atmel SAM0 multi-protocol (UART, SPI, I2C) SERCOM unit compatible: "atmel,sam0-sercom" -include: base.yaml +include: + - name: base.yaml + - name: atmel,assigned-clocks.yaml properties: reg: diff --git a/dts/bindings/arm/atmel,samd2x-pm.yaml b/dts/bindings/arm/atmel,samd2x-pm.yaml deleted file mode 100644 index 7fa232b815d..00000000000 --- a/dts/bindings/arm/atmel,samd2x-pm.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD2x Power Manager (PM) - -compatible: "atmel,samd2x-pm" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/can/atmel,sam0-can.yaml b/dts/bindings/can/atmel,sam0-can.yaml index 7002386c922..25e8eede707 100644 --- a/dts/bindings/can/atmel,sam0-can.yaml +++ b/dts/bindings/can/atmel,sam0-can.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Specialization of Bosch m_can CAN FD controller for Atmel SAM0 compatible: "atmel,sam0-can" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-can" include: - name: bosch,m_can-base.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +26,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + divider: type: int required: true diff --git a/dts/bindings/clock/atmel,sam0-gclk.yaml b/dts/bindings/clock/atmel,sam0-gclk.yaml new file mode 100644 index 00000000000..9d1059e50c6 --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-gclk.yaml @@ -0,0 +1,66 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAMD0 Generic Clock Controller (GCLK) + +compatible: "atmel,sam0-gclk" + +include: + - base.yaml + - clock-controller.yaml + - atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 1 + description: | + - The ID cell is the peripheral identification. + + These information are used on GCLK->CLKCTRL register to select the + clock for an specific peripheral. + + Example 1: Connect the XOSC32K to RTC on SAMD2x + Assuming that generator 2 have the following configuration: + GLKC->GENCTRL: + SRC: 5 (XOSC32K) + ID: 2 (Generator 2) + + Then to enable the clock to the peripheral + Generator: 2 + Identificator: 4 (GCLK_RTC) + + &rtc { + /* The peripheral is fixed and it is defined at soc devictree + * clocks property + */ + clocks = <&gclk 4>, <&pm 0x18 5>; + clock-names = "GCLK", "PM"; + + /* The generator is user selectable and because of that it is + * defined at board + */ + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + + Example 2: Connect the XOSC32K to RTC on SAMD5x + In the SAMD5x the RTC is direct connected on the OSC32KCTRL and no + generator is used. See atmel,sam0-osc32kctrl.yaml for reference. + + "#atmel,assigned-clock-cells": + required: true + type: int + const: 1 + description: | + - The GEN cell is an integer number that represents the index of + the generic clock generator. It is usually a number between 0~8 + but could be more depending of the SoC. + +clock-cells: + - id + +atmel,assigned-clock-cells: + - gen diff --git a/dts/bindings/clock/atmel,sam0-mclk.yaml b/dts/bindings/clock/atmel,sam0-mclk.yaml new file mode 100644 index 00000000000..b71d81baa3e --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-mclk.yaml @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM0 Main Clock Controller (MCLK) + +compatible: "atmel,sam0-mclk" + +include: + - base.yaml + - clock-controller.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 2 + description: | + - The OFFSET cell is an address of a bus mask. The buses can be + AHB and APB[A-D]. Each bus mask can enable a paripheral clock + selecting the BIT position in the mask. + - The BIT cell is the peripheral bit mask. + + These information are used on PM and MCLK register to select the + clock for an specific peripheral. The generator 2 is used on this + example and can be defined by the user at board. + + Example: Enable SERCOM0 on SAMD21 + &sercom0 { + clocks = <&gclk 0x14>, <&pm 0x20 2>; + clock-names = "GCLK", "PM"; + + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + + Example: Enable SERCOM0 on SAME54 + &sercom0 { + clocks = <&gclk 7>, <&mclk 0x14 12>; + clock-names = "GCLK", "MCLK"; + + atmel,assigned-clocks = <&gclk 2>; + atmel,assigned-clock-names = "GCLK"; + }; + +clock-cells: + - offset + - bit diff --git a/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml b/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml new file mode 100644 index 00000000000..e2f25565d91 --- /dev/null +++ b/dts/bindings/clock/atmel,sam0-osc32kctrl.yaml @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +description: Atmel SAM0 32kHz Oscillator Controller (OSC32KCTRL) + +compatible: "atmel,sam0-osc32kctrl" + +include: + - base.yaml + - clock-controller.yaml + - atmel,assigned-clocks.yaml + +properties: + reg: + required: true + + "#clock-cells": + const: 0 + + "#atmel,assigned-clock-cells": + required: true + type: int + const: 1 + description: | + It selects the OSC32CTRL clock to be routed to RTC peripheral + + Example: Connect the XOSC32K to RTC on SAMD5x + + &rtc { + clocks = <&mclk 0x14 9 &osc32kctrl>; + clock-names = "MCLK", "OSC32KCTRL"; + + atmel,assigned-clocks = <&osc32kctrl 4>; + atmel,assigned-clock-names = "OSC32KCTRL"; + }; + +atmel,assigned-clock-cells: + - src diff --git a/dts/bindings/clock/atmel,samc2x-gclk.yaml b/dts/bindings/clock/atmel,samc2x-gclk.yaml deleted file mode 100644 index d1e97272df7..00000000000 --- a/dts/bindings/clock/atmel,samc2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2022 Kamil Serwus -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMC2x Generic Clock Controller (GCLK) - -compatible: "atmel,samc2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,samc2x-mclk.yaml b/dts/bindings/clock/atmel,samc2x-mclk.yaml deleted file mode 100644 index 227fa5246c0..00000000000 --- a/dts/bindings/clock/atmel,samc2x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2022, Kamil Serwus -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMC2x Generic Clock Controller (MCLK) - -compatible: "atmel,samc2x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/clock/atmel,samd2x-gclk.yaml b/dts/bindings/clock/atmel,samd2x-gclk.yaml deleted file mode 100644 index f5188aef05f..00000000000 --- a/dts/bindings/clock/atmel,samd2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD2x Generic Clock Controller (GCLK) - -compatible: "atmel,samd2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - clkctrl_id diff --git a/dts/bindings/clock/atmel,samd5x-gclk.yaml b/dts/bindings/clock/atmel,samd5x-gclk.yaml deleted file mode 100644 index 68fd94b44eb..00000000000 --- a/dts/bindings/clock/atmel,samd5x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD5x Generic Clock Controller (GCLK) - -compatible: "atmel,samd5x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,samd5x-mclk.yaml b/dts/bindings/clock/atmel,samd5x-mclk.yaml deleted file mode 100644 index 603196570da..00000000000 --- a/dts/bindings/clock/atmel,samd5x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2020, Linaro Limited -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAMD5x Generic Clock Controller (MCLK) - -compatible: "atmel,samd5x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/clock/atmel,saml2x-gclk.yaml b/dts/bindings/clock/atmel,saml2x-gclk.yaml deleted file mode 100644 index 3c9020d5052..00000000000 --- a/dts/bindings/clock/atmel,saml2x-gclk.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) 2021 Argentum Systems Ltd. -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAML2x Generic Clock Controller (GCLK) - -compatible: "atmel,saml2x-gclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 1 - -clock-cells: - - periph_ch diff --git a/dts/bindings/clock/atmel,saml2x-mclk.yaml b/dts/bindings/clock/atmel,saml2x-mclk.yaml deleted file mode 100644 index ed89ba36f12..00000000000 --- a/dts/bindings/clock/atmel,saml2x-mclk.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2021 Argentum Systems Ltd. -# SPDX-License-Identifier: Apache-2.0 - -description: Atmel SAML2x Generic Clock Controller (MCLK) - -compatible: "atmel,saml2x-mclk" - -include: [clock-controller.yaml, base.yaml] - -properties: - reg: - required: true - - "#clock-cells": - const: 2 - -clock-cells: - - offset - - bit diff --git a/dts/bindings/counter/atmel,sam0-tc32.yaml b/dts/bindings/counter/atmel,sam0-tc32.yaml index c523e6e4104..3a9b49f2f3f 100644 --- a/dts/bindings/counter/atmel,sam0-tc32.yaml +++ b/dts/bindings/counter/atmel,sam0-tc32.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 basic timer counter (TC) operating in 32-bit wide mode @@ -8,6 +9,7 @@ compatible: "atmel,sam0-tc32" include: - name: base.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +24,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + prescaler: type: int description: Timer prescaler diff --git a/dts/bindings/dac/atmel,sam0-dac.yaml b/dts/bindings/dac/atmel,sam0-dac.yaml index 05ffd62d337..8a0f92f0fe5 100644 --- a/dts/bindings/dac/atmel,sam0-dac.yaml +++ b/dts/bindings/dac/atmel,sam0-dac.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 family DAC @@ -8,6 +9,7 @@ compatible: "atmel,sam0-dac" include: - name: dac-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +21,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + reference: type: string description: Reference voltage source diff --git a/dts/bindings/i2c/atmel,sam0-i2c.yaml b/dts/bindings/i2c/atmel,sam0-i2c.yaml index 9f8d34e95f9..db0610b785f 100644 --- a/dts/bindings/i2c/atmel,sam0-i2c.yaml +++ b/dts/bindings/i2c/atmel,sam0-i2c.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2019 Derek Hageman +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 series SERCOM I2C node @@ -8,6 +9,7 @@ compatible: "atmel,sam0-i2c" include: - name: i2c-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -22,6 +24,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + dmas: description: | Optional TX & RX dma specifiers. Each specifier will have a phandle diff --git a/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml b/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml index f13dfa448c9..bb486bdbff0 100644 --- a/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml +++ b/dts/bindings/pwm/atmel,sam0-tc-pwm.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 TC in PWM mode @@ -9,6 +10,7 @@ include: - name: base.yaml - name: pwm-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -23,6 +25,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + channels: type: int required: true diff --git a/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml b/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml index 358528f47ef..75f4c2abd00 100644 --- a/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml +++ b/dts/bindings/pwm/atmel,sam0-tcc-pwm.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2020 Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 TCC in PWM mode @@ -9,6 +10,7 @@ include: - name: base.yaml - name: pwm-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -23,6 +25,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + channels: type: int required: true diff --git a/dts/bindings/rtc/atmel,sam0-rtc.yaml b/dts/bindings/rtc/atmel,sam0-rtc.yaml index f2210e8bfb4..b14f3044050 100644 --- a/dts/bindings/rtc/atmel,sam0-rtc.yaml +++ b/dts/bindings/rtc/atmel,sam0-rtc.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2018 omSquare s.r.o. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 RTC @@ -8,12 +9,20 @@ compatible: "atmel,sam0-rtc" include: - name: rtc.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: required: true - clock-generator: - type: int - description: clock generator index + clocks: + required: true + + clock-names: + required: true + + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: required: true diff --git a/dts/bindings/serial/atmel,sam0-uart.yaml b/dts/bindings/serial/atmel,sam0-uart.yaml index f817137d7b6..19dd2c35461 100644 --- a/dts/bindings/serial/atmel,sam0-uart.yaml +++ b/dts/bindings/serial/atmel,sam0-uart.yaml @@ -1,3 +1,6 @@ +# Copyright (c) 2024 Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + description: Atmel SAM0 SERCOM UART driver compatible: "atmel,sam0-uart" @@ -5,6 +8,7 @@ compatible: "atmel,sam0-uart" include: - name: uart-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +23,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + rxpo: type: int required: true diff --git a/dts/bindings/spi/atmel,sam0-spi.yaml b/dts/bindings/spi/atmel,sam0-spi.yaml index 8b1c79b8220..ea5a5750111 100644 --- a/dts/bindings/spi/atmel,sam0-spi.yaml +++ b/dts/bindings/spi/atmel,sam0-spi.yaml @@ -1,4 +1,5 @@ # Copyright (c) 2018, Google LLC. +# Copyright (c) 2024 Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: Atmel SAM0 SERCOM SPI controller @@ -8,6 +9,7 @@ compatible: "atmel,sam0-spi" include: - name: spi-controller.yaml - name: pinctrl-device.yaml + - name: atmel,assigned-clocks.yaml properties: reg: @@ -19,6 +21,12 @@ properties: clock-names: required: true + atmel,assigned-clocks: + required: true + + atmel,assigned-clock-names: + required: true + dipo: type: int required: true diff --git a/soc/atmel/sam0/common/atmel_sam0_dt.h b/soc/atmel/sam0/common/atmel_sam0_dt.h index 23e2d438bcb..2c86808a9a1 100644 --- a/soc/atmel/sam0/common/atmel_sam0_dt.h +++ b/soc/atmel/sam0/common/atmel_sam0_dt.h @@ -14,12 +14,28 @@ /* clang-format off */ -/* Helper macro to get MCLK register address for corresponding - * that has corresponding clock enable bit. +#define ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, cell) \ + (volatile uint32_t *) \ + (DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, cell)) + \ + DT_INST_CLOCKS_CELL_BY_NAME(n, cell, offset)) + +#define ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, name, cell) \ + BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, name, cell)) + +/* Helper macro to get register address that control peripheral clock + * enable bit. + */ +#define ATMEL_SAM0_DT_INST_MCLK_PM_REG_ADDR_OFFSET(n) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_REG_ADDR_OFFSET(n, pm))) + +/* Helper macro to get peripheral clock bit mask. */ -#define MCLK_MASK_DT_INT_REG_ADDR(n) \ - (DT_REG_ADDR(DT_INST_PHANDLE_BY_NAME(n, clocks, mclk)) + \ - DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, offset)) +#define ATMEL_SAM0_DT_INST_MCLK_PM_PERIPH_MASK(n, cell) \ + COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(mclk)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, mclk, cell)), \ + (ATMEL_SAM0_DT_INST_CELL_PERIPH_MASK(n, pm, cell))) /* Helper macros for use with ATMEL SAM0 DMAC controller * return 0xff as default value if there is no 'dmas' property diff --git a/tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay b/tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay index ab5e6da356b..d54d2351c57 100644 --- a/tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay +++ b/tests/drivers/spi/spi_loopback/boards/same54_xpro.overlay @@ -1,18 +1,26 @@ /* * Copyright (c) 2020 Stephanos Ioannidis + * Copyright (c) 2024 Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ +&dmac { + status = "okay"; +}; + &sercom4 { /* Internally connect MOSI to MISO for loop-back operation */ dipo = <3>; dopo = <2>; + /* Assign a CS pin */ cs-gpios = <&portb 28 GPIO_ACTIVE_LOW>; + /* Configure DMA */ dmas = <&dmac 0 12>, <&dmac 1 13>; dma-names = "rx", "tx"; + slow@0 { compatible = "test-spi-loopback-slow"; reg = <0>;