99#include <zephyr/cache.h>
1010#include <zephyr/pm/device.h>
1111#include <zephyr/pm/device_runtime.h>
12+ #include <zephyr/drivers/clock_control/nrf_clock_control.h>
1213#include <zephyr/drivers/pinctrl.h>
1314#include <zephyr/mem_mgmt/mem_attr.h>
1415#include <soc.h>
@@ -42,6 +43,16 @@ LOG_MODULE_REGISTER(spi_nrfx_spim, CONFIG_SPI_LOG_LEVEL);
4243#define SPI_BUFFER_IN_RAM 1
4344#endif
4445
46+ #if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL ) && \
47+ (defined(CONFIG_HAS_HW_NRF_SPIM120 ) || \
48+ defined(CONFIG_HAS_HW_NRF_SPIM121 ))
49+ #define SPIM_REQUESTS_CLOCK (idx ) UTIL_OR(IS_EQ(idx, 120), \
50+ IS_EQ(idx, 121))
51+ #define USE_CLOCK_REQUESTS 1
52+ #else
53+ #define SPIM_REQUESTS_CLOCK (idx ) 0
54+ #endif
55+
4556struct spi_nrfx_data {
4657 struct spi_context ctx ;
4758 const struct device * dev ;
@@ -57,6 +68,9 @@ struct spi_nrfx_data {
5768 uint8_t ppi_ch ;
5869 uint8_t gpiote_ch ;
5970#endif
71+ #ifdef USE_CLOCK_REQUESTS
72+ bool clock_requested ;
73+ #endif
6074};
6175
6276struct spi_nrfx_config {
@@ -74,10 +88,55 @@ struct spi_nrfx_config {
7488#ifdef CONFIG_DCACHE
7589 uint32_t mem_attr ;
7690#endif
91+ #ifdef USE_CLOCK_REQUESTS
92+ const struct device * clk_dev ;
93+ struct nrf_clock_spec clk_spec ;
94+ #endif
7795};
7896
7997static void event_handler (const nrfx_spim_evt_t * p_event , void * p_context );
8098
99+ static inline int request_clock (const struct device * dev )
100+ {
101+ #ifdef USE_CLOCK_REQUESTS
102+ struct spi_nrfx_data * dev_data = dev -> data ;
103+ const struct spi_nrfx_config * dev_config = dev -> config ;
104+ int error ;
105+
106+ if (!dev_config -> clk_dev ) {
107+ return 0 ;
108+ }
109+
110+ error = nrf_clock_control_request_sync (
111+ dev_config -> clk_dev , & dev_config -> clk_spec ,
112+ K_MSEC (CONFIG_SPI_COMPLETION_TIMEOUT_TOLERANCE ));
113+ if (error < 0 ) {
114+ LOG_ERR ("Failed to request clock: %d" , error );
115+ return error ;
116+ }
117+
118+ dev_data -> clock_requested = true;
119+ #endif
120+
121+ return 0 ;
122+ }
123+
124+ static inline void release_clock (const struct device * dev )
125+ {
126+ #ifdef USE_CLOCK_REQUESTS
127+ struct spi_nrfx_data * dev_data = dev -> data ;
128+ const struct spi_nrfx_config * dev_config = dev -> config ;
129+
130+ if (!dev_data -> clock_requested ) {
131+ return ;
132+ }
133+
134+ dev_data -> clock_requested = false;
135+
136+ nrf_clock_control_release (dev_config -> clk_dev , & dev_config -> clk_spec );
137+ #endif
138+ }
139+
81140static inline void finalize_spi_transaction (const struct device * dev , bool deactivate_cs )
82141{
83142 struct spi_nrfx_data * dev_data = dev -> data ;
@@ -92,6 +151,10 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact
92151 nrfy_spim_disable (reg );
93152 }
94153
154+ if (!IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
155+ release_clock (dev );
156+ }
157+
95158 pm_device_runtime_put_async (dev , K_NO_WAIT );
96159}
97160
@@ -467,6 +530,11 @@ static int transceive(const struct device *dev,
467530 spi_context_lock (& dev_data -> ctx , asynchronous , cb , userdata , spi_cfg );
468531
469532 error = configure (dev , spi_cfg );
533+
534+ if (error == 0 && !IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
535+ error = request_clock (dev );
536+ }
537+
470538 if (error == 0 ) {
471539 dev_data -> busy = true;
472540
@@ -518,6 +586,8 @@ static int transceive(const struct device *dev,
518586 } else if (error ) {
519587 finalize_spi_transaction (dev , true);
520588 }
589+ } else {
590+ pm_device_runtime_put (dev );
521591 }
522592
523593 spi_context_release (& dev_data -> ctx , error );
@@ -575,7 +645,7 @@ static const struct spi_driver_api spi_nrfx_driver_api = {
575645 .release = spi_nrfx_release ,
576646};
577647
578- static void spim_resume (const struct device * dev )
648+ static int spim_resume (const struct device * dev )
579649{
580650 const struct spi_nrfx_config * dev_config = dev -> config ;
581651
@@ -587,6 +657,8 @@ static void spim_resume(const struct device *dev)
587657#ifdef CONFIG_SOC_NRF54H20_GPD
588658 nrf_gpd_retain_pins_set (dev_config -> pcfg , false);
589659#endif
660+
661+ return IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME ) ? request_clock (dev ) : 0 ;
590662}
591663
592664static void spim_suspend (const struct device * dev )
@@ -599,6 +671,10 @@ static void spim_suspend(const struct device *dev)
599671 dev_data -> initialized = false;
600672 }
601673
674+ if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
675+ release_clock (dev );
676+ }
677+
602678#ifdef CONFIG_SOC_NRF54H20_GPD
603679 nrf_gpd_retain_pins_set (dev_config -> pcfg , true);
604680#endif
@@ -609,7 +685,11 @@ static void spim_suspend(const struct device *dev)
609685static int spim_nrfx_pm_action (const struct device * dev , enum pm_device_action action )
610686{
611687 if (action == PM_DEVICE_ACTION_RESUME ) {
612- spim_resume (dev );
688+ int error = spim_resume (dev );
689+
690+ if (error < 0 ) {
691+ return error ;
692+ }
613693 } else if (IS_ENABLED (CONFIG_PM_DEVICE ) && (action == PM_DEVICE_ACTION_SUSPEND )) {
614694 spim_suspend (dev );
615695 } else {
@@ -685,6 +765,14 @@ static int spi_nrfx_init(const struct device *dev)
685765 (0))), \
686766 (0))
687767
768+ #define SPIM_INIT_LEVEL (idx ) \
769+ COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), (POST_KERNEL), (PRE_KERNEL_1))
770+
771+ #define SPIM_INIT_PRIO (idx ) \
772+ COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \
773+ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
774+ (CONFIG_SPI_INIT_PRIORITY))
775+
688776#define SPI_NRFX_SPIM_DEFINE (idx ) \
689777 NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \
690778 static void irq_connect##idx(void) \
@@ -735,6 +823,13 @@ static int spi_nrfx_init(const struct device *dev)
735823 .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
736824 IF_ENABLED(CONFIG_DCACHE, \
737825 (.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
826+ IF_ENABLED(USE_CLOCK_REQUESTS, \
827+ (.clk_dev = SPIM_REQUESTS_CLOCK(idx) \
828+ ? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
829+ : NULL, \
830+ .clk_spec = { \
831+ .frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \
832+ },)) \
738833 }; \
739834 BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
740835 !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
@@ -745,7 +840,7 @@ static int spi_nrfx_init(const struct device *dev)
745840 PM_DEVICE_DT_GET(SPIM(idx)), \
746841 &spi_##idx##_data, \
747842 &spi_##idx##z_config, \
748- POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
843+ SPIM_INIT_LEVEL(idx), SPIM_INIT_PRIO(idx), \
749844 &spi_nrfx_driver_api)
750845
751846#define SPIM_MEMORY_SECTION (idx ) \
0 commit comments