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,59 @@ 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+ #else
120+ ARG_UNUSED (dev );
121+ #endif
122+
123+ return 0 ;
124+ }
125+
126+ static inline void release_clock (const struct device * dev )
127+ {
128+ #ifdef USE_CLOCK_REQUESTS
129+ struct spi_nrfx_data * dev_data = dev -> data ;
130+ const struct spi_nrfx_config * dev_config = dev -> config ;
131+
132+ if (!dev_data -> clock_requested ) {
133+ return ;
134+ }
135+
136+ dev_data -> clock_requested = false;
137+
138+ nrf_clock_control_release (dev_config -> clk_dev , & dev_config -> clk_spec );
139+ #else
140+ ARG_UNUSED (dev );
141+ #endif
142+ }
143+
81144static inline void finalize_spi_transaction (const struct device * dev , bool deactivate_cs )
82145{
83146 struct spi_nrfx_data * dev_data = dev -> data ;
@@ -92,6 +155,10 @@ static inline void finalize_spi_transaction(const struct device *dev, bool deact
92155 nrfy_spim_disable (reg );
93156 }
94157
158+ if (!IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
159+ release_clock (dev );
160+ }
161+
95162 pm_device_runtime_put_async (dev , K_NO_WAIT );
96163}
97164
@@ -467,6 +534,11 @@ static int transceive(const struct device *dev,
467534 spi_context_lock (& dev_data -> ctx , asynchronous , cb , userdata , spi_cfg );
468535
469536 error = configure (dev , spi_cfg );
537+
538+ if (error == 0 && !IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
539+ error = request_clock (dev );
540+ }
541+
470542 if (error == 0 ) {
471543 dev_data -> busy = true;
472544
@@ -518,6 +590,8 @@ static int transceive(const struct device *dev,
518590 } else if (error ) {
519591 finalize_spi_transaction (dev , true);
520592 }
593+ } else {
594+ pm_device_runtime_put (dev );
521595 }
522596
523597 spi_context_release (& dev_data -> ctx , error );
@@ -575,7 +649,7 @@ static DEVICE_API(spi, spi_nrfx_driver_api) = {
575649 .release = spi_nrfx_release ,
576650};
577651
578- static void spim_resume (const struct device * dev )
652+ static int spim_resume (const struct device * dev )
579653{
580654 const struct spi_nrfx_config * dev_config = dev -> config ;
581655
@@ -587,6 +661,8 @@ static void spim_resume(const struct device *dev)
587661#ifdef CONFIG_SOC_NRF54H20_GPD
588662 nrf_gpd_retain_pins_set (dev_config -> pcfg , false);
589663#endif
664+
665+ return IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME ) ? request_clock (dev ) : 0 ;
590666}
591667
592668static void spim_suspend (const struct device * dev )
@@ -599,6 +675,10 @@ static void spim_suspend(const struct device *dev)
599675 dev_data -> initialized = false;
600676 }
601677
678+ if (IS_ENABLED (CONFIG_PM_DEVICE_RUNTIME )) {
679+ release_clock (dev );
680+ }
681+
602682#ifdef CONFIG_SOC_NRF54H20_GPD
603683 nrf_gpd_retain_pins_set (dev_config -> pcfg , true);
604684#endif
@@ -609,7 +689,7 @@ static void spim_suspend(const struct device *dev)
609689static int spim_nrfx_pm_action (const struct device * dev , enum pm_device_action action )
610690{
611691 if (action == PM_DEVICE_ACTION_RESUME ) {
612- spim_resume (dev );
692+ return spim_resume (dev );
613693 } else if (IS_ENABLED (CONFIG_PM_DEVICE ) && (action == PM_DEVICE_ACTION_SUSPEND )) {
614694 spim_suspend (dev );
615695 } else {
@@ -685,6 +765,21 @@ static int spi_nrfx_init(const struct device *dev)
685765 (0))), \
686766 (0))
687767
768+ /* Fast instances depend on the global HSFLL clock controller (as they need
769+ * to request the highest frequency from it to operate correctly), so they
770+ * must be initialized after that controller driver, hence the default SPI
771+ * initialization priority may be too early for them.
772+ */
773+ #if defined(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY ) && \
774+ CONFIG_SPI_INIT_PRIORITY < CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY
775+ #define SPIM_INIT_PRIORITY (idx ) \
776+ COND_CODE_1(SPIM_REQUESTS_CLOCK(idx), \
777+ (UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
778+ (CONFIG_SPI_INIT_PRIORITY))
779+ #else
780+ #define SPIM_INIT_PRIORITY (idx ) CONFIG_SPI_INIT_PRIORITY
781+ #endif
782+
688783#define SPI_NRFX_SPIM_DEFINE (idx ) \
689784 NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPIM(idx)); \
690785 static void irq_connect##idx(void) \
@@ -735,6 +830,13 @@ static int spi_nrfx_init(const struct device *dev)
735830 .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
736831 IF_ENABLED(CONFIG_DCACHE, \
737832 (.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
833+ IF_ENABLED(USE_CLOCK_REQUESTS, \
834+ (.clk_dev = SPIM_REQUESTS_CLOCK(idx) \
835+ ? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
836+ : NULL, \
837+ .clk_spec = { \
838+ .frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \
839+ },)) \
738840 }; \
739841 BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
740842 !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
@@ -745,7 +847,7 @@ static int spi_nrfx_init(const struct device *dev)
745847 PM_DEVICE_DT_GET(SPIM(idx)), \
746848 &spi_##idx##_data, \
747849 &spi_##idx##z_config, \
748- POST_KERNEL, CONFIG_SPI_INIT_PRIORITY , \
850+ POST_KERNEL, SPIM_INIT_PRIORITY(idx) , \
749851 &spi_nrfx_driver_api)
750852
751853#define SPIM_MEMORY_SECTION (idx ) \
0 commit comments