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 <david.jewsbury@nordicsemi.no>
This commit is contained in:
parent
b4a9b8e3de
commit
49b0f1abb8
@ -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)
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
@ -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 <stdint.h>
|
||||
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/dt-bindings/clock/nrf-auxpll.h>
|
||||
#include "clock_control_nrf2_common.h"
|
||||
|
||||
#include <hal/nrf_auxpll.h>
|
||||
|
||||
/* 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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user