1313#include <zephyr/drivers/can.h>
1414#include <zephyr/drivers/can/can_mcan.h>
1515#include <zephyr/drivers/clock_control.h>
16+ #include <zephyr/drivers/clock_control/nrf_clock_control.h>
1617#include <zephyr/drivers/pinctrl.h>
1718#include <zephyr/irq.h>
1819
@@ -27,7 +28,8 @@ struct can_nrf_config {
2728 uint32_t mcan ;
2829 uint32_t mrba ;
2930 uint32_t mram ;
30- const struct device * clock ;
31+ const struct device * auxpll ;
32+ const struct device * hsfll ;
3133 const struct pinctrl_dev_config * pcfg ;
3234 void (* irq_configure )(void );
3335 uint16_t irq ;
@@ -54,7 +56,7 @@ static int can_nrf_get_core_clock(const struct device *dev, uint32_t *rate)
5456 const struct can_mcan_config * mcan_config = dev -> config ;
5557 const struct can_nrf_config * config = mcan_config -> custom ;
5658
57- return clock_control_get_rate (config -> clock , NULL , rate );
59+ return clock_control_get_rate (config -> auxpll , NULL , rate );
5860}
5961
6062static DEVICE_API (can , can_nrf_api ) = {
@@ -131,17 +133,41 @@ static const struct can_mcan_ops can_mcan_nrf_ops = {
131133 .clear_mram = can_nrf_clear_mram ,
132134};
133135
136+ static int configure_hsfll (const struct device * dev , bool on )
137+ {
138+ const struct can_mcan_config * mcan_config = dev -> config ;
139+ const struct can_nrf_config * config = mcan_config -> custom ;
140+ struct nrf_clock_spec spec = { 0 };
141+
142+ /* If CAN is on, HSFLL frequency >= AUXPLL frequency */
143+ if (on ) {
144+ int ret ;
145+
146+ ret = clock_control_get_rate (dev , NULL , & spec .frequency );
147+ if (ret < 0 ) {
148+ return ret ;
149+ }
150+ }
151+
152+ return nrf_clock_control_request_sync (config -> hsfll , & spec , K_FOREVER );
153+ }
154+
134155static int can_nrf_init (const struct device * dev )
135156{
136157 const struct can_mcan_config * mcan_config = dev -> config ;
137158 const struct can_nrf_config * config = mcan_config -> custom ;
138159 int ret ;
139160
140- if (!device_is_ready (config -> clock )) {
161+ if (!device_is_ready (config -> auxpll ) || ! device_is_ready ( config -> hsfll )) {
141162 return - ENODEV ;
142163 }
143164
144- ret = clock_control_on (config -> clock , NULL );
165+ ret = configure_hsfll (dev , true);
166+ if (ret < 0 ) {
167+ return ret ;
168+ }
169+
170+ ret = clock_control_on (config -> auxpll , NULL );
145171 if (ret < 0 ) {
146172 return ret ;
147173 }
@@ -186,8 +212,9 @@ static int can_nrf_init(const struct device *dev)
186212 .mcan = CAN_MCAN_DT_INST_MCAN_ADDR(n), \
187213 .mrba = CAN_MCAN_DT_INST_MRBA(n), \
188214 .mram = CAN_MCAN_DT_INST_MRAM_ADDR(n), \
189- .clock = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n )), \
215+ .auxpll = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, auxpll )), \
190216 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
217+ .hsfll = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, hsfll)), \
191218 .irq = DT_INST_IRQN(n), \
192219 .irq_configure = can_nrf_irq_configure##n, \
193220 }; \
0 commit comments