Skip to content

Commit e6085fe

Browse files
drivers: serial: uart_mcux_flexcomm: add support for clock management
Add support for clock management to the serial flexcomm driver, dependent on CONFIG_CLOCK_MGMT. When clock management is not enabled, the flexcomm driver will fall back to the clock control API. Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
1 parent afc7f91 commit e6085fe

File tree

1 file changed

+76
-23
lines changed

1 file changed

+76
-23
lines changed

drivers/serial/uart_mcux_flexcomm.c

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <soc.h>
2222
#include <fsl_device_registers.h>
2323
#include <zephyr/drivers/pinctrl.h>
24+
#include <zephyr/drivers/clock_management.h>
2425
#ifdef CONFIG_UART_ASYNC_API
2526
#include <zephyr/drivers/dma.h>
2627
#include <fsl_inputmux.h>
@@ -37,14 +38,19 @@ struct mcux_flexcomm_uart_dma_config {
3738

3839
struct mcux_flexcomm_config {
3940
USART_Type *base;
40-
const struct device *clock_dev;
41-
clock_control_subsys_t clock_subsys;
4241
uint32_t baud_rate;
4342
uint8_t parity;
4443
#ifdef CONFIG_UART_MCUX_FLEXCOMM_ISR_SUPPORT
4544
void (*irq_config_func)(const struct device *dev);
4645
#endif
4746
const struct pinctrl_dev_config *pincfg;
47+
#ifdef CONFIG_CLOCK_MANAGEMENT
48+
const struct clock_output *clock_output;
49+
clock_management_state_t clock_state;
50+
#else
51+
const struct device *clock_dev;
52+
clock_control_subsys_t clock_subsys;
53+
#endif
4854
#ifdef CONFIG_UART_ASYNC_API
4955
struct mcux_flexcomm_uart_dma_config tx_dma;
5056
struct mcux_flexcomm_uart_dma_config rx_dma;
@@ -395,8 +401,12 @@ static int mcux_flexcomm_uart_configure(const struct device *dev, const struct u
395401
USART_Deinit(config->base);
396402

397403
/* Get UART clock frequency */
404+
#ifdef CONFIG_CLOCK_MANAGEMENT
405+
clock_freq = clock_management_get_rate(config->clock_output);
406+
#else
398407
clock_control_get_rate(config->clock_dev,
399408
config->clock_subsys, &clock_freq);
409+
#endif
400410

401411
/* Handle 9 bit mode */
402412
USART_Enable9bitMode(config->base, nine_bit_mode);
@@ -1051,15 +1061,53 @@ static void mcux_flexcomm_isr(const struct device *dev)
10511061
}
10521062
#endif /* CONFIG_UART_MCUX_FLEXCOMM_ISR_SUPPORT */
10531063

1064+
static void mcux_flexcomm_uart_setup(const struct device *dev, uint32_t clock_rate)
1065+
{
1066+
const struct mcux_flexcomm_config *config = dev->config;
1067+
usart_config_t usart_config;
1068+
usart_parity_mode_t parity_mode;
1069+
1070+
if (config->parity == UART_CFG_PARITY_ODD) {
1071+
parity_mode = kUSART_ParityOdd;
1072+
} else if (config->parity == UART_CFG_PARITY_EVEN) {
1073+
parity_mode = kUSART_ParityEven;
1074+
} else {
1075+
parity_mode = kUSART_ParityDisabled;
1076+
}
1077+
1078+
USART_GetDefaultConfig(&usart_config);
1079+
usart_config.enableTx = true;
1080+
usart_config.enableRx = true;
1081+
usart_config.parityMode = parity_mode;
1082+
usart_config.baudRate_Bps = config->baud_rate;
1083+
1084+
USART_Init(config->base, &usart_config, clock_rate);
1085+
}
1086+
1087+
#ifdef CONFIG_CLOCK_MANAGEMENT_RUNTIME
1088+
int uart_mcux_flexcomm_clock_cb(const struct clock_management_event *ev, const void *data)
1089+
{
1090+
const struct device *uart_dev = data;
1091+
const struct mcux_flexcomm_config *config = uart_dev->config;
1092+
1093+
if (ev->type == CLOCK_MANAGEMENT_PRE_RATE_CHANGE) {
1094+
/* Deinit USART */
1095+
USART_Deinit(config->base);
1096+
} else if (ev->type == CLOCK_MANAGEMENT_POST_RATE_CHANGE) {
1097+
/* Reconfigure USART */
1098+
mcux_flexcomm_uart_setup(uart_dev, ev->new_rate);
1099+
}
1100+
return 0;
1101+
}
1102+
#endif
1103+
10541104
static int mcux_flexcomm_init_common(const struct device *dev)
10551105
{
10561106
const struct mcux_flexcomm_config *config = dev->config;
10571107
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
10581108
struct mcux_flexcomm_data *data = dev->data;
10591109
struct uart_config *cfg = &data->uart_config;
10601110
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
1061-
usart_config_t usart_config;
1062-
usart_parity_mode_t parity_mode;
10631111
uint32_t clock_freq;
10641112
int err;
10651113

@@ -1068,6 +1116,14 @@ static int mcux_flexcomm_init_common(const struct device *dev)
10681116
return err;
10691117
}
10701118

1119+
#ifdef CONFIG_CLOCK_MANAGEMENT
1120+
clock_freq = clock_management_apply_state(config->clock_output,
1121+
config->clock_state);
1122+
#ifdef CONFIG_CLOCK_MANAGEMENT_RUNTIME
1123+
clock_management_set_callback(config->clock_output,
1124+
uart_mcux_flexcomm_clock_cb, dev);
1125+
#endif
1126+
#else
10711127
if (!device_is_ready(config->clock_dev)) {
10721128
return -ENODEV;
10731129
}
@@ -1077,20 +1133,8 @@ static int mcux_flexcomm_init_common(const struct device *dev)
10771133
&clock_freq)) {
10781134
return -EINVAL;
10791135
}
1080-
1081-
if (config->parity == UART_CFG_PARITY_ODD) {
1082-
parity_mode = kUSART_ParityOdd;
1083-
} else if (config->parity == UART_CFG_PARITY_EVEN) {
1084-
parity_mode = kUSART_ParityEven;
1085-
} else {
1086-
parity_mode = kUSART_ParityDisabled;
1087-
}
1088-
1089-
USART_GetDefaultConfig(&usart_config);
1090-
usart_config.enableTx = true;
1091-
usart_config.enableRx = true;
1092-
usart_config.parityMode = parity_mode;
1093-
usart_config.baudRate_Bps = config->baud_rate;
1136+
#endif
1137+
mcux_flexcomm_uart_setup(dev, clock_freq);
10941138

10951139
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
10961140
cfg->baudrate = config->baud_rate;
@@ -1101,8 +1145,6 @@ static int mcux_flexcomm_init_common(const struct device *dev)
11011145
cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
11021146
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
11031147

1104-
USART_Init(config->base, &usart_config, clock_freq);
1105-
11061148
#ifdef CONFIG_UART_MCUX_FLEXCOMM_ISR_SUPPORT
11071149
config->irq_config_func(dev);
11081150
#endif
@@ -1266,20 +1308,31 @@ DT_INST_FOREACH_STATUS_OKAY(UART_MCUX_FLEXCOMM_RX_TIMEOUT_FUNC);
12661308
#define UART_MCUX_FLEXCOMM_ASYNC_CFG(n)
12671309
#endif /* CONFIG_UART_ASYNC_API */
12681310

1311+
#ifdef CONFIG_CLOCK_MANAGEMENT
1312+
#define UART_MCUX_FLEXCOMM_CLK_DEFINE(n) CLOCK_MANAGEMENT_DT_INST_DEFINE_OUTPUT(n)
1313+
#define UART_MCUX_FLEXCOMM_CLK_INIT(n) \
1314+
.clock_output = CLOCK_MANAGEMENT_DT_INST_GET_OUTPUT(n), \
1315+
.clock_state = CLOCK_MANAGEMENT_DT_INST_GET_STATE(n, default, default),
1316+
#else
1317+
#define UART_MCUX_FLEXCOMM_CLK_DEFINE(n)
1318+
#define UART_MCUX_FLEXCOMM_CLK_INIT(n) \
1319+
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
1320+
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),
1321+
#endif
1322+
12691323
#define UART_MCUX_FLEXCOMM_INIT_CFG(n) \
12701324
static const struct mcux_flexcomm_config mcux_flexcomm_##n##_config = { \
12711325
.base = (USART_Type *)DT_INST_REG_ADDR(n), \
1272-
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
1273-
.clock_subsys = \
1274-
(clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \
12751326
.baud_rate = DT_INST_PROP(n, current_speed), \
12761327
.parity = DT_INST_ENUM_IDX(n, parity), \
12771328
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
1329+
UART_MCUX_FLEXCOMM_CLK_INIT(n) \
12781330
UART_MCUX_FLEXCOMM_IRQ_CFG_FUNC_INIT(n) \
12791331
UART_MCUX_FLEXCOMM_ASYNC_CFG(n) \
12801332
};
12811333

12821334
#define UART_MCUX_FLEXCOMM_INIT(n) \
1335+
UART_MCUX_FLEXCOMM_CLK_DEFINE(n); \
12831336
\
12841337
PINCTRL_DT_INST_DEFINE(n); \
12851338
\

0 commit comments

Comments
 (0)