drivers: counter: Adding Mutli Channel PIT Support
Updating the nxp,pit driver to support mutliple channels. Updating the dts and board overlays to account for the changes. Signed-off-by: Emilio Benavente <emilio.benavente@nxp.com>
This commit is contained in:
parent
9cb330e1ed
commit
8bb95d33be
15 changed files with 423 additions and 86 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
config COUNTER_NXP_PIT
|
config COUNTER_NXP_PIT
|
||||||
bool "NXP PIT driver"
|
bool "NXP PIT driver"
|
||||||
default y
|
default y if DT_HAS_NXP_PIT_CHANNEL_ENABLED && \
|
||||||
depends on DT_HAS_NXP_PIT_ENABLED
|
DT_HAS_NXP_PIT_ENABLED
|
||||||
help
|
help
|
||||||
Enable support for the NXP Periodic Interrupt Timer (PIT).
|
Enable support for the NXP Periodic Interrupt Timer (PIT).
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020,2023 NXP
|
* Copyright 2020,2023-2024 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -15,26 +15,46 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_COUNTER_LOG_LEVEL);
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_COUNTER_LOG_LEVEL);
|
||||||
|
|
||||||
|
/* Device holds a pointer to pointer to data */
|
||||||
|
#define PIT_CHANNEL_DATA(dev) \
|
||||||
|
(*(struct nxp_pit_channel_data *const *const)dev->data)
|
||||||
|
|
||||||
|
/* Device config->data is an array of data pointers ordered by channel number,
|
||||||
|
* dev->data is a pointer to one of these pointers in that array,
|
||||||
|
* so the value of the dev->data - dev->config->data is the channel index
|
||||||
|
*/
|
||||||
|
#define PIT_CHANNEL_ID(dev) \
|
||||||
|
(((struct nxp_pit_channel_data *const *)dev->data) - \
|
||||||
|
((const struct nxp_pit_config *)dev->config)->data)
|
||||||
|
|
||||||
|
|
||||||
|
struct nxp_pit_channel_data {
|
||||||
|
uint32_t top;
|
||||||
|
counter_top_callback_t top_callback;
|
||||||
|
void *top_user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct nxp_pit_config {
|
struct nxp_pit_config {
|
||||||
struct counter_config_info info;
|
struct counter_config_info info;
|
||||||
PIT_Type *base;
|
PIT_Type *base;
|
||||||
bool enableRunInDebug;
|
bool enableRunInDebug;
|
||||||
pit_chnl_t pit_channel;
|
int num_channels;
|
||||||
uint32_t pit_period;
|
#if DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts)
|
||||||
void (*irq_config_func)(const struct device *dev);
|
void (*irq_config_func)(const struct device *dev);
|
||||||
|
#else
|
||||||
|
void (**irq_config_func)(const struct device *dev);
|
||||||
|
#endif
|
||||||
const struct device *clock_dev;
|
const struct device *clock_dev;
|
||||||
clock_control_subsys_t clock_subsys;
|
clock_control_subsys_t clock_subsys;
|
||||||
};
|
struct nxp_pit_channel_data *const *data;
|
||||||
|
const struct device *const *channels;
|
||||||
struct nxp_pit_data {
|
|
||||||
counter_top_callback_t top_callback;
|
|
||||||
void *top_user_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t nxp_pit_get_top_value(const struct device *dev)
|
static uint32_t nxp_pit_get_top_value(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
pit_chnl_t channel = config->pit_channel;
|
pit_chnl_t channel = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to RM, the LDVAL trigger = clock ticks -1
|
* According to RM, the LDVAL trigger = clock ticks -1
|
||||||
|
@ -49,21 +69,23 @@ static uint32_t nxp_pit_get_top_value(const struct device *dev)
|
||||||
static int nxp_pit_start(const struct device *dev)
|
static int nxp_pit_start(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
|
int channel_id = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
LOG_DBG("period is %d", nxp_pit_get_top_value(dev));
|
LOG_DBG("period is %d", nxp_pit_get_top_value(dev));
|
||||||
PIT_EnableInterrupts(config->base, config->pit_channel,
|
PIT_EnableInterrupts(config->base, channel_id,
|
||||||
kPIT_TimerInterruptEnable);
|
kPIT_TimerInterruptEnable);
|
||||||
PIT_StartTimer(config->base, config->pit_channel);
|
PIT_StartTimer(config->base, channel_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nxp_pit_stop(const struct device *dev)
|
static int nxp_pit_stop(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
|
int channel_id = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
PIT_DisableInterrupts(config->base, config->pit_channel,
|
PIT_DisableInterrupts(config->base, channel_id,
|
||||||
kPIT_TimerInterruptEnable);
|
kPIT_TimerInterruptEnable);
|
||||||
PIT_StopTimer(config->base, config->pit_channel);
|
PIT_StopTimer(config->base, channel_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -71,8 +93,9 @@ static int nxp_pit_stop(const struct device *dev)
|
||||||
static int nxp_pit_get_value(const struct device *dev, uint32_t *ticks)
|
static int nxp_pit_get_value(const struct device *dev, uint32_t *ticks)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
|
int channel_id = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
*ticks = PIT_GetCurrentTimerCount(config->base, config->pit_channel);
|
*ticks = PIT_GetCurrentTimerCount(config->base, channel_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +104,8 @@ static int nxp_pit_set_top_value(const struct device *dev,
|
||||||
const struct counter_top_cfg *cfg)
|
const struct counter_top_cfg *cfg)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
struct nxp_pit_data *data = dev->data;
|
struct nxp_pit_channel_data *data = PIT_CHANNEL_DATA(dev);
|
||||||
pit_chnl_t channel = config->pit_channel;
|
pit_chnl_t channel = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
if (cfg->ticks == 0) {
|
if (cfg->ticks == 0) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -111,8 +134,9 @@ static uint32_t nxp_pit_get_pending_int(const struct device *dev)
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
uint32_t mask = PIT_TFLG_TIF_MASK;
|
uint32_t mask = PIT_TFLG_TIF_MASK;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
int channel_id = PIT_CHANNEL_ID(dev);
|
||||||
|
|
||||||
flags = PIT_GetStatusFlags(config->base, config->pit_channel);
|
flags = PIT_GetStatusFlags(config->base, channel_id);
|
||||||
|
|
||||||
return ((flags & mask) == mask);
|
return ((flags & mask) == mask);
|
||||||
}
|
}
|
||||||
|
@ -130,19 +154,43 @@ static uint32_t nxp_pit_get_frequency(const struct device *dev)
|
||||||
return clock_rate;
|
return clock_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts)
|
||||||
static void nxp_pit_isr(const struct device *dev)
|
static void nxp_pit_isr(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct nxp_pit_config *config = dev->config;
|
const struct nxp_pit_config *config = dev->config;
|
||||||
struct nxp_pit_data *data = dev->data;
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
LOG_DBG("pit counter isr");
|
LOG_DBG("pit counter isr");
|
||||||
flags = PIT_GetStatusFlags(config->base, config->pit_channel);
|
|
||||||
PIT_ClearStatusFlags(config->base, config->pit_channel, flags);
|
for (int channel_index = 0;
|
||||||
if (data->top_callback) {
|
channel_index < config->num_channels;
|
||||||
|
channel_index++) {
|
||||||
|
flags = PIT_GetStatusFlags(config->base, channel_index);
|
||||||
|
if (flags) {
|
||||||
|
struct nxp_pit_channel_data *data =
|
||||||
|
PIT_CHANNEL_DATA(config->channels[channel_index]);
|
||||||
|
PIT_ClearStatusFlags(config->base, channel_index, flags);
|
||||||
|
data->top_callback(dev, data->top_user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void nxp_pit_isr(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct nxp_pit_config *config = dev->config;
|
||||||
|
struct nxp_pit_channel_data *data = PIT_CHANNEL_DATA(dev);
|
||||||
|
pit_chnl_t channel = PIT_CHANNEL_ID(dev);
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
LOG_DBG("pit counter isr");
|
||||||
|
|
||||||
|
flags = PIT_GetStatusFlags(config->base, channel);
|
||||||
|
if (flags) {
|
||||||
|
PIT_ClearStatusFlags(config->base, channel, flags);
|
||||||
data->top_callback(dev, data->top_user_data);
|
data->top_callback(dev, data->top_user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts) */
|
||||||
|
|
||||||
static int nxp_pit_init(const struct device *dev)
|
static int nxp_pit_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -160,12 +208,27 @@ static int nxp_pit_init(const struct device *dev)
|
||||||
|
|
||||||
PIT_Init(config->base, &pit_config);
|
PIT_Init(config->base, &pit_config);
|
||||||
|
|
||||||
config->irq_config_func(dev);
|
|
||||||
|
|
||||||
clock_rate = nxp_pit_get_frequency(dev);
|
clock_rate = nxp_pit_get_frequency(dev);
|
||||||
PIT_SetTimerPeriod(config->base, config->pit_channel,
|
|
||||||
USEC_TO_COUNT(config->pit_period, clock_rate));
|
|
||||||
|
|
||||||
|
#if DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts)
|
||||||
|
config->irq_config_func(dev);
|
||||||
|
for (int channel_index = 0;
|
||||||
|
channel_index < config->num_channels;
|
||||||
|
channel_index++) {
|
||||||
|
PIT_SetTimerPeriod(config->base, channel_index,
|
||||||
|
USEC_TO_COUNT(config->info.max_top_value, clock_rate));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (int channel_index = 0;
|
||||||
|
channel_index < config->num_channels;
|
||||||
|
channel_index++) {
|
||||||
|
if (config->irq_config_func[channel_index]) {
|
||||||
|
config->irq_config_func[channel_index](dev);
|
||||||
|
PIT_SetTimerPeriod(config->base, channel_index,
|
||||||
|
USEC_TO_COUNT(config->info.max_top_value, clock_rate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts) */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,41 +242,131 @@ static const struct counter_driver_api nxp_pit_driver_api = {
|
||||||
.get_freq = nxp_pit_get_frequency,
|
.get_freq = nxp_pit_get_frequency,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COUNTER_NXP_PIT_IRQ_CONFIG(idx, n) \
|
|
||||||
do { \
|
|
||||||
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, idx, irq), \
|
|
||||||
DT_INST_IRQ_BY_IDX(n, idx, priority), \
|
|
||||||
nxp_pit_isr, DEVICE_DT_INST_GET(n), \
|
|
||||||
COND_CODE_1(DT_INST_IRQ_HAS_NAME(n, flags), \
|
|
||||||
(DT_INST_IRQ_BY_IDX(n, idx, flags)), (0))); \
|
|
||||||
irq_enable(DT_INST_IRQ_BY_IDX(n, idx, irq)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define COUNTER_NXP_PIT_DEVICE(n) \
|
/* Creates a device for a channel (needed for counter API) */
|
||||||
static void nxp_pit_irq_config_##n(const struct device *dev); \
|
#define NXP_PIT_CHANNEL_DEV_INIT(node, pit_inst) \
|
||||||
static struct nxp_pit_data nxp_pit_data_##n; \
|
DEVICE_DT_DEFINE(node, NULL, NULL, \
|
||||||
static const struct nxp_pit_config nxp_pit_config_##n = { \
|
(void *) \
|
||||||
.info = { \
|
&nxp_pit_##pit_inst##_channel_datas[DT_REG_ADDR(node)], \
|
||||||
.max_top_value = DT_INST_PROP(n, max_load_value), \
|
&nxp_pit_##pit_inst##_config, \
|
||||||
.channels = 0, \
|
POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, \
|
||||||
}, \
|
&nxp_pit_driver_api);
|
||||||
.base = (PIT_Type *)DT_INST_REG_ADDR(n), \
|
|
||||||
.pit_channel = DT_INST_PROP(n, pit_channel), \
|
|
||||||
.pit_period = DT_INST_PROP(n, pit_period), \
|
|
||||||
.irq_config_func = nxp_pit_irq_config_##n, \
|
|
||||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
|
|
||||||
.clock_subsys = (clock_control_subsys_t) \
|
|
||||||
DT_INST_CLOCKS_CELL(n, name), \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
DEVICE_DT_INST_DEFINE(n, &nxp_pit_init, NULL, \
|
|
||||||
&nxp_pit_data_##n, &nxp_pit_config_##n, POST_KERNEL, \
|
|
||||||
CONFIG_COUNTER_INIT_PRIORITY, &nxp_pit_driver_api); \
|
|
||||||
\
|
|
||||||
static void nxp_pit_irq_config_##n(const struct device *dev) \
|
|
||||||
{ \
|
|
||||||
LISTIFY(DT_NUM_IRQS(DT_DRV_INST(n)), \
|
|
||||||
COUNTER_NXP_PIT_IRQ_CONFIG, (;), n); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DT_INST_FOREACH_STATUS_OKAY(COUNTER_NXP_PIT_DEVICE)
|
/* Creates a decleration for each pit channel */
|
||||||
|
#define NXP_PIT_CHANNEL_DECLARATIONS(node) static struct nxp_pit_channel_data \
|
||||||
|
nxp_pit_channel_data_##node;
|
||||||
|
|
||||||
|
/* Initializes an element of the channel data pointer array */
|
||||||
|
#define NXP_PIT_INSERT_CHANNEL_INTO_ARRAY(node) \
|
||||||
|
[DT_REG_ADDR(node)] = \
|
||||||
|
&nxp_pit_channel_data_##node,
|
||||||
|
|
||||||
|
#define NXP_PIT_INSERT_CHANNEL_DEVICE_INTO_ARRAY(node) \
|
||||||
|
[DT_REG_ADDR(node)] = DEVICE_DT_GET(node),
|
||||||
|
|
||||||
|
|
||||||
|
#if DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts)
|
||||||
|
#define NXP_PIT_IRQ_CONFIG_DECLARATIONS(n) \
|
||||||
|
static void nxp_pit_irq_config_func_##n(const struct device *dev) \
|
||||||
|
{ \
|
||||||
|
IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, 0, irq), \
|
||||||
|
DT_INST_IRQ_BY_IDX(n, 0, priority), \
|
||||||
|
nxp_pit_isr, \
|
||||||
|
DEVICE_DT_INST_GET(n), 0); \
|
||||||
|
irq_enable(DT_INST_IRQN(n)); \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NXP_PIT_SETUP_IRQ_CONFIG(n) NXP_PIT_IRQ_CONFIG_DECLARATIONS(n);
|
||||||
|
#define NXP_PIT_SETUP_IRQ_ARRAY(ignored)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define NXP_PIT_IRQ_CONFIG_DECLARATIONS(n) \
|
||||||
|
static void nxp_pit_irq_config_func_##n(const struct device *dev) \
|
||||||
|
{ \
|
||||||
|
IRQ_CONNECT(DT_IRQN(n), \
|
||||||
|
DT_IRQ(n, priority), \
|
||||||
|
nxp_pit_isr, \
|
||||||
|
DEVICE_DT_GET(n), 0); \
|
||||||
|
irq_enable(DT_IRQN(n)); \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NXP_PIT_SETUP_IRQ_CONFIG(n) \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, NXP_PIT_IRQ_CONFIG_DECLARATIONS);
|
||||||
|
|
||||||
|
#define NXP_PIT_INSERT_IRQ_CONFIG_INTO_ARRAY(n) \
|
||||||
|
[DT_REG_ADDR(n)] = &nxp_pit_irq_config_func_##n,
|
||||||
|
|
||||||
|
#define NXP_PIT_SETUP_IRQ_ARRAY(n) \
|
||||||
|
/* Create Array of IRQs -> 1 irq func per channel */ \
|
||||||
|
void (*nxp_pit_irq_config_array[DT_INST_FOREACH_CHILD_SEP_VARGS(n, \
|
||||||
|
DT_NODE_HAS_COMPAT, (+), nxp_pit_channel)]) \
|
||||||
|
(const struct device *dev) = { \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \
|
||||||
|
NXP_PIT_INSERT_IRQ_CONFIG_INTO_ARRAY) \
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define COUNTER_NXP_PIT_DEVICE_INIT(n) \
|
||||||
|
\
|
||||||
|
/* Setup the IRQ either for parent irq or per channel irq */ \
|
||||||
|
NXP_PIT_SETUP_IRQ_CONFIG(n) \
|
||||||
|
\
|
||||||
|
/* Create channel declarations */ \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \
|
||||||
|
NXP_PIT_CHANNEL_DECLARATIONS) \
|
||||||
|
\
|
||||||
|
/* Array of channel devices */ \
|
||||||
|
static struct nxp_pit_channel_data *const \
|
||||||
|
nxp_pit_##n##_channel_datas \
|
||||||
|
[DT_INST_FOREACH_CHILD_SEP_VARGS( \
|
||||||
|
n, DT_NODE_HAS_COMPAT, (+), nxp_pit_channel)] = { \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \
|
||||||
|
NXP_PIT_INSERT_CHANNEL_INTO_ARRAY) \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
/* forward declaration */ \
|
||||||
|
static const struct nxp_pit_config nxp_pit_##n##_config; \
|
||||||
|
\
|
||||||
|
/* Create all the channel/counter devices */ \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, \
|
||||||
|
NXP_PIT_CHANNEL_DEV_INIT, n) \
|
||||||
|
\
|
||||||
|
/* This channel device array is needed by the module device ISR */ \
|
||||||
|
const struct device *const nxp_pit_##n##_channels \
|
||||||
|
[DT_INST_FOREACH_CHILD_SEP_VARGS( \
|
||||||
|
n, DT_NODE_HAS_COMPAT, (+), nxp_pit_channel)] = { \
|
||||||
|
DT_INST_FOREACH_CHILD_STATUS_OKAY(n, \
|
||||||
|
NXP_PIT_INSERT_CHANNEL_DEVICE_INTO_ARRAY) \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
NXP_PIT_SETUP_IRQ_ARRAY(n) \
|
||||||
|
\
|
||||||
|
/* This config struct is shared by all the channels and parent device */ \
|
||||||
|
static const struct nxp_pit_config nxp_pit_##n##_config = { \
|
||||||
|
.info = { \
|
||||||
|
.max_top_value = \
|
||||||
|
DT_INST_PROP(n, max_load_value), \
|
||||||
|
.channels = 0, \
|
||||||
|
}, \
|
||||||
|
.base = (PIT_Type *)DT_INST_REG_ADDR(n), \
|
||||||
|
.irq_config_func = COND_CODE_1(DT_NODE_HAS_PROP( \
|
||||||
|
DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_pit), interrupts), \
|
||||||
|
(nxp_pit_irq_config_func_##n), \
|
||||||
|
(&nxp_pit_irq_config_array[0])), \
|
||||||
|
.num_channels = DT_INST_FOREACH_CHILD_SEP_VARGS( \
|
||||||
|
n, DT_NODE_HAS_COMPAT, (+), nxp_pit_channel), \
|
||||||
|
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
|
||||||
|
.clock_subsys = (clock_control_subsys_t) \
|
||||||
|
DT_INST_CLOCKS_CELL(n, name), \
|
||||||
|
.data = nxp_pit_##n##_channel_datas, \
|
||||||
|
.channels = nxp_pit_##n##_channels, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
/* Init parent device in order to handle ISR and init. */ \
|
||||||
|
DEVICE_DT_INST_DEFINE(n, &nxp_pit_init, NULL, \
|
||||||
|
NULL, &nxp_pit_##n##_config, POST_KERNEL, \
|
||||||
|
CONFIG_COUNTER_INIT_PRIORITY, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(COUNTER_NXP_PIT_DEVICE_INIT)
|
||||||
|
|
|
@ -530,11 +530,38 @@
|
||||||
compatible = "nxp,pit";
|
compatible = "nxp,pit";
|
||||||
reg = <0x40037000 0x1000>;
|
reg = <0x40037000 0x1000>;
|
||||||
clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 23>;
|
clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 23>;
|
||||||
interrupts = <48 0>, <49 0>, <50 0>, <51 0>;
|
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
pit-channel = <0>;
|
|
||||||
pit-period = <1000000>;
|
|
||||||
max-load-value = <0xffffffff>;
|
max-load-value = <0xffffffff>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
pit0_channel0: pit0_channel@0 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <0>;
|
||||||
|
interrupts = <48 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel1: pit0_channel@1 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <1>;
|
||||||
|
interrupts = <49 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel2: pit0_channel@2 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <2>;
|
||||||
|
interrupts = <50 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel3: pit0_channel@3 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <3>;
|
||||||
|
interrupts = <51 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -390,11 +390,38 @@
|
||||||
compatible = "nxp,pit";
|
compatible = "nxp,pit";
|
||||||
reg = <0x40037000 0x1000>;
|
reg = <0x40037000 0x1000>;
|
||||||
clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 23>;
|
clocks = <&sim KINETIS_SIM_BUS_CLK 0x103c 23>;
|
||||||
interrupts = <48 0>, <49 0>, <50 0>, <51 0>;
|
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
pit-channel = <0>;
|
|
||||||
pit-period = <1000000>;
|
|
||||||
max-load-value = <0xffffffff>;
|
max-load-value = <0xffffffff>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
pit0_channel0: pit0_channel@0 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <0>;
|
||||||
|
interrupts = <48 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel1: pit0_channel@1 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <1>;
|
||||||
|
interrupts = <49 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel2: pit0_channel@2 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <2>;
|
||||||
|
interrupts = <50 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel3: pit0_channel@3 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <3>;
|
||||||
|
interrupts = <51 0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
edma0: dma-controller@40008000 {
|
edma0: dma-controller@40008000 {
|
||||||
|
|
|
@ -95,6 +95,44 @@
|
||||||
clocks = <&clock NXP_S32_P0_REG_INTF_CLK>;
|
clocks = <&clock NXP_S32_P0_REG_INTF_CLK>;
|
||||||
max-load-value = <0x00ffffff>;
|
max-load-value = <0x00ffffff>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
pit0_channel0: pit0_channel@0 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel1: pit0_channel@1 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <1>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel2: pit0_channel@2 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <2>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel3: pit0_channel@3 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <3>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel4: pit0_channel@4 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <4>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel5: pit0_channel@5 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <5>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,6 +95,44 @@
|
||||||
clocks = <&clock NXP_S32_P1_REG_INTF_CLK>;
|
clocks = <&clock NXP_S32_P1_REG_INTF_CLK>;
|
||||||
max-load-value = <0x00ffffff>;
|
max-load-value = <0x00ffffff>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
pit0_channel0: pit0_channel@0 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <0>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel1: pit0_channel@1 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <1>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel2: pit0_channel@2 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <2>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel3: pit0_channel@3 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <3>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel4: pit0_channel@4 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <4>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pit0_channel5: pit0_channel@5 {
|
||||||
|
compatible = "nxp,pit-channel";
|
||||||
|
reg = <5>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
13
dts/bindings/counter/nxp,pit-channel.yaml
Normal file
13
dts/bindings/counter/nxp,pit-channel.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Copyright 2024 NXP
|
||||||
|
# SPDX-License-Identifier Apache-2.0
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Child node for the Periodic Interrupt Timer node, intended for an individual timer channel
|
||||||
|
|
||||||
|
compatible: "nxp,pit-channel"
|
||||||
|
|
||||||
|
include: base.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
reg:
|
||||||
|
required: true
|
|
@ -14,16 +14,6 @@ properties:
|
||||||
clocks:
|
clocks:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
pit-channel:
|
|
||||||
type: int
|
|
||||||
required: true
|
|
||||||
description: pit channel to active
|
|
||||||
|
|
||||||
pit-period:
|
|
||||||
type: int
|
|
||||||
required: true
|
|
||||||
description: pit default period in us
|
|
||||||
|
|
||||||
max-load-value:
|
max-load-value:
|
||||||
type: int
|
type: int
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -15,4 +15,8 @@
|
||||||
dma-buf-addr-alignment = <4>;
|
dma-buf-addr-alignment = <4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
test_dma: &edma0 { };
|
test_dma: &edma0 { };
|
||||||
|
|
|
@ -15,4 +15,8 @@
|
||||||
dma-buf-addr-alignment = <4>;
|
dma-buf-addr-alignment = <4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
test_dma: &edma0 { };
|
test_dma: &edma0 { };
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 NXP
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pit0_channel1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
/* channel 2 disabled to test disabled channel not breaking things */
|
||||||
|
|
||||||
|
&pit0_channel3 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 NXP
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&pit0_channel1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
/* channel 2 disabled to test disabled channel not breaking things */
|
||||||
|
|
||||||
|
&pit0_channel3 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2022-2023 NXP
|
* Copyright 2022-2024 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&pit0 {
|
&pit0 {
|
||||||
pit-channel = <0>;
|
status = "okay";
|
||||||
pit-period = <1000000>;
|
};
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2022-2023 NXP
|
* Copyright 2022-2024 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
&pit0 {
|
&pit0 {
|
||||||
pit-channel = <0>;
|
status = "okay";
|
||||||
pit-period = <1000000>;
|
};
|
||||||
|
|
||||||
|
&pit0_channel0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Nordic Semiconductor ASA
|
* Copyright (c) 2018, Nordic Semiconductor ASA
|
||||||
|
* Copyright 2024 NXP
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +86,7 @@ static const struct device *const devices[] = {
|
||||||
DEVS_FOR_DT_COMPAT(silabs_gecko_stimer)
|
DEVS_FOR_DT_COMPAT(silabs_gecko_stimer)
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_COUNTER_NXP_PIT
|
#ifdef CONFIG_COUNTER_NXP_PIT
|
||||||
DEVS_FOR_DT_COMPAT(nxp_pit)
|
DEVS_FOR_DT_COMPAT(nxp_pit_channel)
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_COUNTER_XLNX_AXI_TIMER
|
#ifdef CONFIG_COUNTER_XLNX_AXI_TIMER
|
||||||
DEVS_FOR_DT_COMPAT(xlnx_xps_timer_1_00_a)
|
DEVS_FOR_DT_COMPAT(xlnx_xps_timer_1_00_a)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue