Skip to content

Commit 99faf47

Browse files
mstasiaknordicjukkar
authored andcommitted
[nrf fromlist] drivers: pwm: nrfx: add global hsfll request for fast PWM
Added clock control api for global hsfll used in fast PWM120 driver. Upstream PR #: 82133 Signed-off-by: Michał Stasiak <[email protected]>
1 parent a8bb747 commit 99faf47

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

drivers/pwm/pwm_nrfx.c

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
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

5481
struct 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

Comments
 (0)