From ebbb4b67b96bb27e7292f5bf153b5e6847663a82 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Thu, 28 Apr 2022 22:14:10 +0200 Subject: [PATCH] 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 919a73328d9..8952f4d1ae7 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 6309d4bd92c..56aef49565d 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 df4e85e271e..273de941f53 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 e441a2d8703..837c8615837 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