1313#include  <zephyr/linker/devicetree_regions.h> 
1414#include  <zephyr/cache.h> 
1515#include  <zephyr/mem_mgmt/mem_attr.h> 
16+ #ifdef  CONFIG_CLOCK_CONTROL 
17+ #include  <zephyr/drivers/clock_control/nrf_clock_control.h> 
18+ #endif 
1619#ifdef  CONFIG_SOC_NRF54H20_GPD 
1720#include  <nrf/gpd.h> 
1821#endif 
@@ -35,6 +38,26 @@ LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);
3538#define  ANOMALY_109_EGU_IRQ_CONNECT (idx )
3639#endif 
3740
41+ #define  PWM (dev_idx ) DT_NODELABEL(pwm##dev_idx)
42+ #define  PWM_PROP (dev_idx , prop ) DT_PROP(PWM(dev_idx), prop)
43+ #define  PWM_HAS_PROP (idx , prop ) DT_NODE_HAS_PROP(PWM(idx), prop)
44+ 
45+ #define  PWM_NRFX_IS_FAST (unused , prefix , idx , _ )					\
46+ 	COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(PWM(idx)),					\
47+ 		(COND_CODE_1(PWM_HAS_PROP(idx, power_domains),				\
48+ 		    (IS_EQ(DT_PHA(PWM(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)),	\
49+ 		    (0))), (0))
50+ 
51+ #if  NRFX_FOREACH_PRESENT (PWM , PWM_NRFX_IS_FAST , (|| ), (0 ))
52+ #if  CONFIG_CLOCK_CONTROL 
53+ #define  PWM_NRFX_USE_CLOCK_CONTROL  1
54+ #endif 
55+ #define  PWM_NRFX_INIT_PRIORITY  99
56+ #else 
57+ #define  PWM_NRFX_INIT_PRIORITY  CONFIG_PWM_INIT_PRIORITY
58+ #endif 
59+ 
60+ 
3861#define  PWM_NRFX_CH_POLARITY_MASK  BIT(15)
3962#define  PWM_NRFX_CH_COMPARE_MASK   BIT_MASK(15)
4063#define  PWM_NRFX_CH_VALUE (compare_value , inverted ) \
@@ -49,6 +72,10 @@ struct pwm_nrfx_config {
4972#ifdef  CONFIG_DCACHE 
5073	uint32_t  mem_attr ;
5174#endif 
75+ #ifdef  PWM_NRFX_USE_CLOCK_CONTROL 
76+ 	const  struct  device  * clk_dev ;
77+ 	struct  nrf_clock_spec  clk_spec ;
78+ #endif 
5279};
5380
5481struct  pwm_nrfx_data  {
@@ -57,6 +84,9 @@ struct pwm_nrfx_data {
5784	uint8_t   pwm_needed ;
5885	uint8_t   prescaler ;
5986	bool      stop_requested ;
87+ #ifdef  PWM_NRFX_USE_CLOCK_CONTROL 
88+ 	bool      clock_requested ;
89+ #endif 
6090};
6191/* Ensure the pwm_needed bit mask can accommodate all available channels. */ 
6292#if  (NRF_PWM_CHANNEL_COUNT  >  8 )
@@ -229,6 +259,18 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
229259		 * ensure it is stopped before starting the next playback. 
230260		 */ 
231261		nrfx_pwm_stop (& config -> pwm , false);
262+ #if  PWM_NRFX_USE_CLOCK_CONTROL 
263+ 		if  (data -> clock_requested ) {
264+ 			int  ret  =  nrf_clock_control_release (config -> clk_dev , & config -> clk_spec );
265+ 
266+ 			if  (ret  <  0 ) {
267+ 				LOG_ERR ("Global HSFLL release failed: %d" , ret );
268+ 				return  ret ;
269+ 			}
270+ 
271+ 			data -> clock_requested  =  false;
272+ 		}
273+ #endif 
232274		data -> stop_requested  =  true;
233275	} else  {
234276		if  (data -> stop_requested ) {
@@ -248,6 +290,18 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
248290		 * until another playback is requested (new values will be 
249291		 * loaded then) or the PWM peripheral is stopped. 
250292		 */ 
293+ #if  PWM_NRFX_USE_CLOCK_CONTROL 
294+ 
295+ 		int  ret  =  nrf_clock_control_request_sync (config -> clk_dev , & config -> clk_spec ,
296+ 							 K_FOREVER );
297+ 
298+ 		if  (ret  <  0 ) {
299+ 			LOG_ERR ("Global HSFLL request failed: %d" , ret );
300+ 			return  ret ;
301+ 		}
302+ 
303+ 		data -> clock_requested  =  true;
304+ #endif 
251305		nrfx_pwm_simple_playback (& config -> pwm , & config -> seq , 1 ,
252306					 NRFX_PWM_FLAG_NO_EVT_FINISHED );
253307	}
@@ -306,6 +360,14 @@ static void pwm_suspend(const struct device *dev)
306360	const  struct  pwm_nrfx_config  * config  =  dev -> config ;
307361
308362	nrfx_pwm_stop (& config -> pwm , false);
363+ #if  PWM_NRFX_USE_CLOCK_CONTROL 
364+ 
365+ 		int  ret  =  nrf_clock_control_release (config -> clk_dev , & config -> clk_spec );
366+ 
367+ 		if  (ret  <  0 ) {
368+ 			LOG_ERR ("Global HSFLL release failed: %d" , ret );
369+ 		}
370+ #endif 
309371	while  (!nrfx_pwm_stopped_check (& config -> pwm )) {
310372	}
311373
@@ -351,9 +413,6 @@ static int pwm_nrfx_init(const struct device *dev)
351413	return  pm_device_driver_init (dev , pwm_nrfx_pm_action );
352414}
353415
354- #define  PWM (dev_idx ) DT_NODELABEL(pwm##dev_idx)
355- #define  PWM_PROP (dev_idx , prop ) DT_PROP(PWM(dev_idx), prop)
356- #define  PWM_HAS_PROP (idx , prop ) DT_NODE_HAS_PROP(PWM(idx), prop)
357416#define  PWM_MEM_REGION (idx )     DT_PHANDLE(PWM(idx), memory_regions)
358417
359418#define  PWM_MEMORY_SECTION (idx )						      \
@@ -393,6 +452,15 @@ static int pwm_nrfx_init(const struct device *dev)
393452			(16ul * 1000ul * 1000ul)),			      \
394453		IF_ENABLED(CONFIG_DCACHE,				      \
395454			(.mem_attr = PWM_GET_MEM_ATTR(idx),))		      \
455+ 		IF_ENABLED(PWM_NRFX_USE_CLOCK_CONTROL,		      \
456+ 			(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))),  \
457+ 			 .clk_spec = {					      \
458+ 				.frequency =				      \
459+ 					NRF_PERIPH_GET_FREQUENCY(PWM(idx)),   \
460+ 				.accuracy = 0,				      \
461+ 				.precision =				      \
462+ 					NRF_CLOCK_CONTROL_PRECISION_DEFAULT,  \
463+ 			 },))						      \
396464	};								      \
397465	static int pwm_nrfx_init##idx(const struct device *dev)		      \
398466	{								      \
@@ -405,7 +473,7 @@ static int pwm_nrfx_init(const struct device *dev)
405473			 pwm_nrfx_init##idx, PM_DEVICE_DT_GET(PWM(idx)),      \
406474			 &pwm_nrfx_##idx##_data,			      \
407475			 &pwm_nrfx_##idx##_config,			      \
408- 			 POST_KERNEL, CONFIG_PWM_INIT_PRIORITY ,		      \
476+ 			 POST_KERNEL, PWM_NRFX_INIT_PRIORITY ,		      \
409477			 &pwm_nrfx_drv_api_funcs)
410478
411479#define  COND_PWM_NRFX_DEVICE (unused , prefix , i , _ ) \
0 commit comments