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