From 13173acd9217a67f75cee3b1ccab478405bb4dd9 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 May 2022 09:42:32 +0200 Subject: [PATCH 1/4] soc: arm: atmel: same70: enable the UPLL clock Enable the UTMI PLL (UPLL) clock and add a static definition of its clock frequency. Signed-off-by: Henrik Brix Andersen Co-authored-by: Gerson Fernando Budke --- soc/arm/atmel_sam/same70/soc.c | 8 ++++++++ soc/arm/atmel_sam/same70/soc.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/soc/arm/atmel_sam/same70/soc.c b/soc/arm/atmel_sam/same70/soc.c index 2cefd1162bf4d..9ad8c498f73de 100644 --- a/soc/arm/atmel_sam/same70/soc.c +++ b/soc/arm/atmel_sam/same70/soc.c @@ -177,6 +177,14 @@ static ALWAYS_INLINE void clock_init(void) ; } + /* Setup UPLL */ + PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(0x3Fu) | CKGR_UCKR_UPLLEN; + + /* Wait for PLL lock */ + while (!(PMC->PMC_SR & PMC_SR_LOCKU)) { + ; + } + /* * Final setup of the Master Clock */ diff --git a/soc/arm/atmel_sam/same70/soc.h b/soc/arm/atmel_sam/same70/soc.h index 1f9ba4d28920e..37f10e2792a0a 100644 --- a/soc/arm/atmel_sam/same70/soc.h +++ b/soc/arm/atmel_sam/same70/soc.h @@ -73,6 +73,9 @@ #define SOC_ATMEL_SAM_MCK_FREQ_HZ \ (SOC_ATMEL_SAM_HCLK_FREQ_HZ / CONFIG_SOC_ATMEL_SAME70_MDIV) +/** UTMI PLL clock (UPLLCK) Frequency */ +#define SOC_ATMEL_SAM_UPLLCK_FREQ_HZ MHZ(480) + #endif /* _ASMLANGUAGE */ #endif /* _ATMEL_SAME70_SOC_H_ */ From 31ec2b6ccc35db9b510bc8e9457b4faabab565fd Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Sat, 7 May 2022 19:57:38 +0200 Subject: [PATCH 2/4] soc: arm: atmel: samv71: enable the UPLL clock Enable the UTMI PLL (UPLL) clock and add a static definition of its clock frequency. Signed-off-by: Henrik Brix Andersen Co-authored-by: Gerson Fernando Budke --- soc/arm/atmel_sam/samv71/soc.c | 8 ++++++++ soc/arm/atmel_sam/samv71/soc.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/soc/arm/atmel_sam/samv71/soc.c b/soc/arm/atmel_sam/samv71/soc.c index 2cbad87640694..232299c1b8f50 100644 --- a/soc/arm/atmel_sam/samv71/soc.c +++ b/soc/arm/atmel_sam/samv71/soc.c @@ -178,6 +178,14 @@ static ALWAYS_INLINE void clock_init(void) ; } + /* Setup UPLL */ + PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(0x3Fu) | CKGR_UCKR_UPLLEN; + + /* Wait for PLL lock */ + while (!(PMC->PMC_SR & PMC_SR_LOCKU)) { + ; + } + /* * Final setup of the Master Clock */ diff --git a/soc/arm/atmel_sam/samv71/soc.h b/soc/arm/atmel_sam/samv71/soc.h index 0e5a3548d608e..264f92c5172e6 100644 --- a/soc/arm/atmel_sam/samv71/soc.h +++ b/soc/arm/atmel_sam/samv71/soc.h @@ -74,6 +74,9 @@ #define SOC_ATMEL_SAM_MCK_FREQ_HZ \ (SOC_ATMEL_SAM_HCLK_FREQ_HZ / CONFIG_SOC_ATMEL_SAMV71_MDIV) +/** UTMI PLL clock (UPLLCK) Frequency */ +#define SOC_ATMEL_SAM_UPLLCK_FREQ_HZ MHZ(480) + #endif /* _ASMLANGUAGE */ #include "pwm_fixup.h" From c496212666d8c3f097e8e1d36ea480646d8f702f Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 28 Apr 2022 22:14:10 +0200 Subject: [PATCH 3/4] drivers: can: sam: use UPLL clock instead of PLLA clock Use the UPLLCK clock for the CAN controller as recommended by the Atmel SAM E70 data sheet. Move the configuration of the clock prescaler from Kconfig to devicetree and limit it to the values recommended by the SAM E70 datasheet. Fixes: #45012 Signed-off-by: Henrik Brix Andersen --- drivers/can/Kconfig.sam | 12 ------------ drivers/can/can_sam.c | 14 +++++++++----- dts/arm/atmel/same70.dtsi | 2 ++ dts/bindings/can/atmel,sam-can.yaml | 9 +++++++++ 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/can/Kconfig.sam b/drivers/can/Kconfig.sam index 919a73328d9c4..8952f4d1ae758 100644 --- a/drivers/can/Kconfig.sam +++ b/drivers/can/Kconfig.sam @@ -8,15 +8,3 @@ config CAN_SAM bool "Atmel SAM CAN driver" default $(dt_compat_enabled,$(DT_COMPAT_ATMEL_SAM_CAN)) select CAN_MCAN - -if CAN_SAM - -config CAN_SAM_CKDIV - int "Clock divider" - range 0 255 - default 0 - depends on CAN_SAM - help - Clock divider for the MCAN core clock. - -endif #CAN_SAM diff --git a/drivers/can/can_sam.c b/drivers/can/can_sam.c index 6309d4bd92cb4..56aef49565d98 100644 --- a/drivers/can/can_sam.c +++ b/drivers/can/can_sam.c @@ -21,6 +21,7 @@ struct can_sam_config { void (*config_irq)(void); const struct pinctrl_dev_config *pcfg; uint8_t pmc_id; + int divider; }; struct can_sam_data { @@ -29,18 +30,20 @@ struct can_sam_data { static int can_sam_get_core_clock(const struct device *dev, uint32_t *rate) { - ARG_UNUSED(dev); + const struct can_mcan_config *mcan_cfg = dev->config; + const struct can_sam_config *sam_cfg = mcan_cfg->custom; - *rate = SOC_ATMEL_SAM_MCK_FREQ_HZ / (CONFIG_CAN_SAM_CKDIV + 1); + *rate = SOC_ATMEL_SAM_UPLLCK_FREQ_HZ / (sam_cfg->divider); return 0; } -static void can_sam_clock_enable(const struct can_sam_config *cfg) +static void can_sam_clock_enable(const struct can_sam_config *sam_cfg) { - REG_PMC_PCK5 = PMC_PCK_CSS_PLLA_CLK | PMC_PCK_PRES(CONFIG_CAN_SAM_CKDIV); + REG_PMC_PCK5 = PMC_PCK_CSS_UPLL_CLK | PMC_PCK_PRES(sam_cfg->divider - 1); PMC->PMC_SCER |= PMC_SCER_PCK5; - soc_pmc_peripheral_enable(cfg->pmc_id); + + soc_pmc_peripheral_enable(sam_cfg->pmc_id); } static int can_sam_init(const struct device *dev) @@ -129,6 +132,7 @@ static void config_can_##inst##_irq(void) #define CAN_SAM_CFG_INST(inst) \ static const struct can_sam_config can_sam_cfg_##inst = { \ .pmc_id = DT_INST_PROP(inst, peripheral_id), \ + .divider = DT_INST_PROP(inst, divider), \ .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \ .config_irq = config_can_##inst##_irq, \ }; \ diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index df4e85e271ea6..273de941f53ed 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -445,6 +445,7 @@ interrupts = <35 0>, <36 0>; interrupt-names = "LINE_0", "LINE_1"; peripheral-id = <35>; + divider = <6>; sjw = <1>; sample-point = <875>; sjw-data = <1>; @@ -462,6 +463,7 @@ interrupts = <37 0>, <38 0>; interrupt-names = "LINE_0", "LINE_1"; peripheral-id = <37>; + divider = <6>; sjw = <1>; sample-point = <875>; sjw-data = <1>; diff --git a/dts/bindings/can/atmel,sam-can.yaml b/dts/bindings/can/atmel,sam-can.yaml index e441a2d870351..837c8615837ac 100644 --- a/dts/bindings/can/atmel,sam-can.yaml +++ b/dts/bindings/can/atmel,sam-can.yaml @@ -17,3 +17,12 @@ properties: type: int required: true description: peripheral ID + + divider: + type: int + required: true + enum: + - 6 + - 12 + - 24 + description: Clock divider for the CAN core clock From a20bfae5dd9b37f95af77ae95690cbea44c0a54d Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 5 May 2022 09:48:55 +0200 Subject: [PATCH 4/4] dts: arm: atmel: same70: remove unnecessary #address-cells/#size-cells Remove unnecessary #address-cells/#size-cells from the CAN devicetree nodes. Signed-off-by: Henrik Brix Andersen --- dts/arm/atmel/same70.dtsi | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi index 273de941f53ed..94036b7e862ea 100644 --- a/dts/arm/atmel/same70.dtsi +++ b/dts/arm/atmel/same70.dtsi @@ -438,8 +438,6 @@ can0: can@40030000 { compatible = "atmel,sam-can"; - #address-cells = <1>; - #size-cells = <0>; reg = <0x40030000 0x100>; reg-names = "m_can"; interrupts = <35 0>, <36 0>; @@ -456,8 +454,6 @@ can1: can@40034000 { compatible = "atmel,sam-can"; - #address-cells = <1>; - #size-cells = <0>; reg = <0x40034000 0x100>; reg-names = "m_can"; interrupts = <37 0>, <38 0>;