From 49b0f1abb8b43dc429fea65230b79271bbb6ee6e Mon Sep 17 00:00:00 2001 From: David Jewsbury Date: Wed, 4 Jun 2025 14:28:35 +0100 Subject: [PATCH] drivers: clock_control: refactor nrf_auxpll driver to nrf2 Refactor of previous clock_control_nrf_auxpll.c to use the nrf2 clock control API Signed-off-by: David Jewsbury --- drivers/clock_control/CMakeLists.txt | 2 +- drivers/clock_control/Kconfig | 2 - drivers/clock_control/Kconfig.nrf | 6 + drivers/clock_control/Kconfig.nrf_auxpll | 9 - .../clock_control/clock_control_nrf_auxpll.c | 157 ++++++++++++++---- 5 files changed, 131 insertions(+), 45 deletions(-) delete mode 100644 drivers/clock_control/Kconfig.nrf_auxpll diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index bec53ab1ba5..18b6025df6c 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -54,6 +54,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_FLL16M clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF54H_HFXO clock_control_nrf54h_hfxo.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HSFLL_LOCAL clock_control_nrf_hsfll_local.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_LFCLK clock_control_nrf_lfclk.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_AUXPLL clock_control_nrf_auxpll.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL60X clock_control_bl60x.c) if(CONFIG_CLOCK_CONTROL_RENESAS_RZA2M_CPG) @@ -120,5 +121,4 @@ endif() zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AST10X0 clock_control_ast10x0.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_MAX32 clock_control_max32.c) -zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_AUXPLL clock_control_nrf_auxpll.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_WCH_RCC clock_control_wch_rcc.c) diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 82fa462ee71..05a2a7fb8fa 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -104,8 +104,6 @@ source "drivers/clock_control/Kconfig.pwm" source "drivers/clock_control/Kconfig.rpi_pico" -source "drivers/clock_control/Kconfig.nrf_auxpll" - source "drivers/clock_control/Kconfig.arm_scmi" source "drivers/clock_control/Kconfig.silabs" diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index 0a32df55a61..76ff68bff4a 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -302,3 +302,9 @@ config CLOCK_CONTROL_NRF_LFCLK_CLOCK_TIMEOUT_MS default 1000 endif # CLOCK_CONTROL_NRF_LFCLK + +config CLOCK_CONTROL_NRF_AUXPLL + bool "nRF Auxiliary PLL driver" + default y + depends on DT_HAS_NORDIC_NRF_AUXPLL_ENABLED + select CLOCK_CONTROL_NRF2_COMMON diff --git a/drivers/clock_control/Kconfig.nrf_auxpll b/drivers/clock_control/Kconfig.nrf_auxpll deleted file mode 100644 index 413452c1ac4..00000000000 --- a/drivers/clock_control/Kconfig.nrf_auxpll +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2024 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -config CLOCK_CONTROL_NRF_AUXPLL - bool "nRF Auxiliary PLL driver" - default y - depends on DT_HAS_NORDIC_NRF_AUXPLL_ENABLED - help - Driver for nRF Auxiliary PLL. diff --git a/drivers/clock_control/clock_control_nrf_auxpll.c b/drivers/clock_control/clock_control_nrf_auxpll.c index 19dee8c4493..d048f4ed1c7 100644 --- a/drivers/clock_control/clock_control_nrf_auxpll.c +++ b/drivers/clock_control/clock_control_nrf_auxpll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Nordic Semiconductor ASA + * Copyright (c) 2025 Nordic Semiconductor ASA * SPDX-License-Identifier: Apache-2.0 */ @@ -9,55 +9,65 @@ #include #include -#include #include -#include -#include +#include #include #include +#include +#include "clock_control_nrf2_common.h" #include -/* maximum lock time in ms, >10x time observed experimentally */ -#define AUXPLL_LOCK_TIME_MAX_MS 20 -/* lock wait step in ms*/ -#define AUXPLL_LOCK_WAIT_STEP_MS 1 + +/* Check dt-bindings match MDK frequency division definitions*/ +BUILD_ASSERT(NRF_AUXPLL_FREQ_DIV_MIN == NRF_AUXPLL_FREQUENCY_DIV_MIN, + "Different AUXPLL_FREQ_DIV_MIN definition in MDK and devicetree binding"); +BUILD_ASSERT(NRF_AUXPLL_FREQ_DIV_AUDIO_44K1 == NRF_AUXPLL_FREQUENCY_AUDIO_44K1, + "Different AUXPLL_FREQ_DIV_AUDIO_44K1 definition in MDK and devicetree binding"); +BUILD_ASSERT(NRF_AUXPLL_FREQ_DIV_USB24M == NRF_AUXPLL_FREQUENCY_USB_24M, + "Different AUXPLL_FREQ_DIV_USB24M definition in MDK and devicetree binding"); +BUILD_ASSERT(NRF_AUXPLL_FREQ_DIV_AUDIO_48K == NRF_AUXPLL_FREQUENCY_AUDIO_48K, + "Different AUXPLL_FREQ_DIV_AUDIO_48K definition in MDK and devicetree binding"); +BUILD_ASSERT(NRF_AUXPLL_FREQ_DIV_MAX == NRF_AUXPLL_FREQUENCY_DIV_MAX, + "Different AUXPLL_FREQ_DIV_MAX definition in MDK and devicetree binding"); + +/* maximum lock time in us, >10x time observed experimentally */ +#define AUXPLL_LOCK_TIME_MAX_US 20000 +/* lock wait step in us*/ +#define AUXPLL_LOCK_WAIT_STEP_US 1000 + +struct dev_data_auxpll { + struct onoff_manager mgr; + onoff_notify_fn notify; + const struct device *dev; +}; struct clock_control_nrf_auxpll_config { NRF_AUXPLL_Type *auxpll; uint32_t ref_clk_hz; uint32_t ficr_ctune; nrf_auxpll_config_t cfg; - uint16_t frequency; + nrf_auxpll_freq_div_ratio_t frequency; nrf_auxpll_ctrl_outsel_t out_div; }; -static int clock_control_nrf_auxpll_on(const struct device *dev, clock_control_subsys_t sys) +static int clock_control_nrf_auxpll_on(struct dev_data_auxpll *dev_data) { - const struct clock_control_nrf_auxpll_config *config = dev->config; + const struct clock_control_nrf_auxpll_config *config = dev_data->dev->config; bool locked; - unsigned int wait = 0U; - - ARG_UNUSED(sys); nrf_auxpll_task_trigger(config->auxpll, NRF_AUXPLL_TASK_START); - do { - locked = nrf_auxpll_mode_locked_check(config->auxpll); - if (!locked) { - k_msleep(AUXPLL_LOCK_WAIT_STEP_MS); - wait += AUXPLL_LOCK_WAIT_STEP_MS; - } - } while (wait < AUXPLL_LOCK_TIME_MAX_MS && !locked); + NRFX_WAIT_FOR(nrf_auxpll_mode_locked_check(config->auxpll), + AUXPLL_LOCK_TIME_MAX_US / AUXPLL_LOCK_WAIT_STEP_US, + AUXPLL_LOCK_WAIT_STEP_US, locked); return locked ? 0 : -ETIMEDOUT; } -static int clock_control_nrf_auxpll_off(const struct device *dev, clock_control_subsys_t sys) +static int clock_control_nrf_auxpll_off(struct dev_data_auxpll *dev_data) { - const struct clock_control_nrf_auxpll_config *config = dev->config; - - ARG_UNUSED(sys); + const struct clock_control_nrf_auxpll_config *config = dev_data->dev->config; nrf_auxpll_task_trigger(config->auxpll, NRF_AUXPLL_TASK_STOP); @@ -67,6 +77,58 @@ static int clock_control_nrf_auxpll_off(const struct device *dev, clock_control_ return 0; } +static void onoff_start_auxpll(struct onoff_manager *mgr, onoff_notify_fn notify) +{ + struct dev_data_auxpll *dev_data = + CONTAINER_OF(mgr, struct dev_data_auxpll, mgr); + + int ret = clock_control_nrf_auxpll_on(dev_data); + + notify(&dev_data->mgr, ret); + +} + +static void onoff_stop_auxpll(struct onoff_manager *mgr, onoff_notify_fn notify) +{ + struct dev_data_auxpll *dev_data = + CONTAINER_OF(mgr, struct dev_data_auxpll, mgr); + + clock_control_nrf_auxpll_off(dev_data); + notify(mgr, 0); +} + +static int api_request_auxpll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct dev_data_auxpll *dev_data = dev->data; + + ARG_UNUSED(spec); + + return onoff_request(&dev_data->mgr, cli); +} + +static int api_release_auxpll(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + struct dev_data_auxpll *dev_data = dev->data; + + ARG_UNUSED(spec); + + return onoff_release(&dev_data->mgr); +} + +static int api_cancel_or_release_auxpll(const struct device *dev, + const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ + struct dev_data_auxpll *dev_data = dev->data; + + ARG_UNUSED(spec); + + return onoff_cancel_or_release(&dev_data->mgr, cli); +} + static int clock_control_nrf_auxpll_get_rate(const struct device *dev, clock_control_subsys_t sys, uint32_t *rate) { @@ -99,16 +161,21 @@ static enum clock_control_status clock_control_nrf_auxpll_get_status(const struc return CLOCK_CONTROL_STATUS_OFF; } -static DEVICE_API(clock_control, clock_control_nrf_auxpll_api) = { - .on = clock_control_nrf_auxpll_on, - .off = clock_control_nrf_auxpll_off, - .get_rate = clock_control_nrf_auxpll_get_rate, - .get_status = clock_control_nrf_auxpll_get_status, +static const struct onoff_transitions transitions = { + .start = onoff_start_auxpll, + .stop = onoff_stop_auxpll }; static int clock_control_nrf_auxpll_init(const struct device *dev) { + struct dev_data_auxpll *dev_data = dev->data; const struct clock_control_nrf_auxpll_config *config = dev->config; + int rc; + + rc = onoff_manager_init(&dev_data->mgr, &transitions); + if (rc < 0) { + return rc; + } nrf_auxpll_ctrl_frequency_set(config->auxpll, config->frequency); @@ -123,7 +190,31 @@ static int clock_control_nrf_auxpll_init(const struct device *dev) return 0; } +static DEVICE_API(nrf_clock_control, drv_api_auxpll) = { + .std_api = { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + .get_rate = clock_control_nrf_auxpll_get_rate, + .get_status = clock_control_nrf_auxpll_get_status, + }, + .request = api_request_auxpll, + .release = api_release_auxpll, + .cancel_or_release = api_cancel_or_release_auxpll, +}; + #define CLOCK_CONTROL_NRF_AUXPLL_DEFINE(n) \ + BUILD_ASSERT( \ + DT_INST_PROP(n, nordic_frequency) == NRF_AUXPLL_FREQUENCY_DIV_MIN || \ + DT_INST_PROP(n, nordic_frequency) == NRF_AUXPLL_FREQUENCY_AUDIO_44K1 || \ + DT_INST_PROP(n, nordic_frequency) == NRF_AUXPLL_FREQUENCY_USB_24M || \ + DT_INST_PROP(n, nordic_frequency) == NRF_AUXPLL_FREQUENCY_AUDIO_48K || \ + DT_INST_PROP(n, nordic_frequency) == NRF_AUXPLL_FREQUENCY_DIV_MAX, \ + "Invalid nordic,frequency value in DeviceTree for AUXPLL instance " #n); \ + BUILD_ASSERT(DT_INST_PROP(n, nordic_out_div) > 0, \ + "nordic,out_div must be greater than 0 for AUXPLL instance " #n); \ + static struct dev_data_auxpll data_auxpll##n = { \ + .dev = DEVICE_DT_INST_GET(n), \ + }; \ static const struct clock_control_nrf_auxpll_config config##n = { \ .auxpll = (NRF_AUXPLL_Type *)DT_INST_REG_ADDR(n), \ .ref_clk_hz = DT_PROP(DT_INST_CLOCKS_CTLR(n), clock_frequency), \ @@ -140,9 +231,9 @@ static int clock_control_nrf_auxpll_init(const struct device *dev) .frequency = DT_INST_PROP(n, nordic_frequency), \ .out_div = DT_INST_PROP(n, nordic_out_div), \ }; \ - \ - DEVICE_DT_INST_DEFINE(n, clock_control_nrf_auxpll_init, NULL, NULL, &config##n, \ + \ + DEVICE_DT_INST_DEFINE(n, clock_control_nrf_auxpll_init, NULL, &data_auxpll##n, &config##n, \ PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \ - &clock_control_nrf_auxpll_api); + &drv_api_auxpll); DT_INST_FOREACH_STATUS_OKAY(CLOCK_CONTROL_NRF_AUXPLL_DEFINE)