Skip to content

Commit 85b9ccb

Browse files
[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 92c1c55 commit 85b9ccb

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

drivers/pwm/pwm_nrfx.c

Lines changed: 64 additions & 3 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,20 @@ 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+
#define PWM_NRFX_FAST_PRESENT 1
53+
#endif
54+
3855
#define PWM_NRFX_CH_POLARITY_MASK BIT(15)
3956
#define PWM_NRFX_CH_COMPARE_MASK BIT_MASK(15)
4057
#define PWM_NRFX_CH_VALUE(compare_value, inverted) \
@@ -49,6 +66,10 @@ struct pwm_nrfx_config {
4966
#ifdef CONFIG_DCACHE
5067
uint32_t mem_attr;
5168
#endif
69+
#ifdef PWM_NRFX_FAST_PRESENT
70+
const struct device *clk_dev;
71+
struct nrf_clock_spec clk_spec;
72+
#endif
5273
};
5374

5475
struct pwm_nrfx_data {
@@ -57,6 +78,9 @@ struct pwm_nrfx_data {
5778
uint8_t pwm_needed;
5879
uint8_t prescaler;
5980
bool stop_requested;
81+
#ifdef PWM_NRFX_FAST_PRESENT
82+
bool clock_requested;
83+
#endif
6084
};
6185
/* Ensure the pwm_needed bit mask can accommodate all available channels. */
6286
#if (NRF_PWM_CHANNEL_COUNT > 8)
@@ -229,6 +253,18 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
229253
* ensure it is stopped before starting the next playback.
230254
*/
231255
nrfx_pwm_stop(&config->pwm, false);
256+
#if PWM_NRFX_FAST_PRESENT
257+
if (data->clock_requested) {
258+
int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
259+
260+
if (ret < 0) {
261+
LOG_ERR("Global HSFLL release failed: %d", ret);
262+
return ret;
263+
}
264+
265+
data->clock_requested = false;
266+
}
267+
#endif
232268
data->stop_requested = true;
233269
} else {
234270
if (data->stop_requested) {
@@ -248,6 +284,17 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel,
248284
* until another playback is requested (new values will be
249285
* loaded then) or the PWM peripheral is stopped.
250286
*/
287+
#if PWM_NRFX_FAST_PRESENT
288+
289+
int ret = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER);
290+
291+
if (ret < 0) {
292+
LOG_ERR("Global HSFLL request failed: %d", ret);
293+
return ret;
294+
}
295+
296+
data->clock_requested = true;
297+
#endif
251298
nrfx_pwm_simple_playback(&config->pwm, &config->seq, 1,
252299
NRFX_PWM_FLAG_NO_EVT_FINISHED);
253300
}
@@ -306,6 +353,14 @@ static void pwm_suspend(const struct device *dev)
306353
const struct pwm_nrfx_config *config = dev->config;
307354

308355
nrfx_pwm_stop(&config->pwm, false);
356+
#if PWM_NRFX_FAST_PRESENT
357+
358+
int ret = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
359+
360+
if (ret < 0) {
361+
LOG_ERR("Global HSFLL release failed: %d", ret);
362+
}
363+
#endif
309364
while (!nrfx_pwm_stopped_check(&config->pwm)) {
310365
}
311366

@@ -351,9 +406,6 @@ static int pwm_nrfx_init(const struct device *dev)
351406
return pm_device_driver_init(dev, pwm_nrfx_pm_action);
352407
}
353408

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)
357409
#define PWM_MEM_REGION(idx) DT_PHANDLE(PWM(idx), memory_regions)
358410

359411
#define PWM_MEMORY_SECTION(idx) \
@@ -393,6 +445,15 @@ static int pwm_nrfx_init(const struct device *dev)
393445
(16ul * 1000ul * 1000ul)), \
394446
IF_ENABLED(CONFIG_DCACHE, \
395447
(.mem_attr = PWM_GET_MEM_ATTR(idx),)) \
448+
IF_ENABLED(PWM_NRFX_IS_FAST(_, , idx, _), \
449+
(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(PWM(idx))), \
450+
.clk_spec = { \
451+
.frequency = \
452+
NRF_PERIPH_GET_FREQUENCY(PWM(idx)), \
453+
.accuracy = 0, \
454+
.precision = \
455+
NRF_CLOCK_CONTROL_PRECISION_DEFAULT, \
456+
},)) \
396457
}; \
397458
static int pwm_nrfx_init##idx(const struct device *dev) \
398459
{ \

tests/drivers/pwm/pwm_api/testcase.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ tests:
2222
CONFIG_DT_HAS_NXP_FLEXIO_PWM_ENABLED
2323
depends_on: pwm
2424
drivers.pwm.pwm_fast:
25-
extra_args: DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay"
26-
platform_allow:
25+
extra_args:
26+
- DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast.overlay"
27+
- CONFIG_CLOCK_CONTROL=y
28+
- CONFIG_PWM_INIT_PRIORITY=99
2729
- nrf54h20dk/nrf54h20/cpuapp

0 commit comments

Comments
 (0)