Skip to content

Commit 14912d2

Browse files
ar-conclusivecarlescufi
authored andcommitted
nxp: imx: Implement iuart clock gating
Add clock control support for UART controllers found in i.MX SoC family. This change moves clock gating out of respective `soc.c` files and into clock controller's `clock_control_on`/`_off` methods, allowing for dynamic clock state control, and setup via Device Tree bindings. This is especially important on SoCs, where Zephyr is sharing the bus with cores running other OSes, such as might be the case for i.MX 8MM. Unfortunately, Zephyr doesn't possess an ability to represent clock hierarchy (e.g. via DT's `assigned-clocks` property), so clock source and frequency still need to be hardcoded in aforementioned `soc.c` files. Signed-off-by: Artur Rojek <[email protected]>
1 parent 1bc6045 commit 14912d2

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

drivers/clock_control/clock_control_mcux_ccm.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ static const clock_root_control_t uart_clk_root[] = {
3030
kCLOCK_RootUart3,
3131
kCLOCK_RootUart4,
3232
};
33+
34+
static const clock_ip_name_t uart_clocks[] = {
35+
kCLOCK_Uart1,
36+
kCLOCK_Uart2,
37+
kCLOCK_Uart3,
38+
kCLOCK_Uart4,
39+
};
3340
#endif
3441
#if defined(CONFIG_UART_MCUX_LPUART) && defined(CONFIG_SOC_MIMX93_A55)
3542
static const clock_root_t lpuart_clk_root[] = {
@@ -47,13 +54,43 @@ static const clock_root_t lpuart_clk_root[] = {
4754
static int mcux_ccm_on(const struct device *dev,
4855
clock_control_subsys_t sub_system)
4956
{
50-
return 0;
57+
uint32_t clock_name = (uintptr_t)sub_system;
58+
uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK;
59+
60+
switch (clock_name) {
61+
#ifdef CONFIG_UART_MCUX_IUART
62+
case IMX_CCM_UART1_CLK:
63+
case IMX_CCM_UART2_CLK:
64+
case IMX_CCM_UART3_CLK:
65+
case IMX_CCM_UART4_CLK:
66+
CLOCK_EnableClock(uart_clocks[instance]);
67+
return 0;
68+
#endif
69+
default:
70+
(void)instance;
71+
return 0;
72+
}
5173
}
5274

5375
static int mcux_ccm_off(const struct device *dev,
5476
clock_control_subsys_t sub_system)
5577
{
56-
return 0;
78+
uint32_t clock_name = (uintptr_t)sub_system;
79+
uint32_t instance = clock_name & IMX_CCM_INSTANCE_MASK;
80+
81+
switch (clock_name) {
82+
#ifdef CONFIG_UART_MCUX_IUART
83+
case IMX_CCM_UART1_CLK:
84+
case IMX_CCM_UART2_CLK:
85+
case IMX_CCM_UART3_CLK:
86+
case IMX_CCM_UART4_CLK:
87+
CLOCK_DisableClock(uart_clocks[instance]);
88+
return 0;
89+
#endif
90+
default:
91+
(void)instance;
92+
return 0;
93+
}
5794
}
5895

5996
static int mcux_ccm_get_subsys_rate(const struct device *dev,

drivers/serial/uart_mcux_iuart.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,12 @@ static int mcux_iuart_init(const struct device *dev)
241241
uart_config.enableRx = true;
242242
uart_config.baudRate_Bps = config->baud_rate;
243243

244+
clock_control_on(config->clock_dev, config->clock_subsys);
244245
UART_Init(config->base, &uart_config, clock_freq);
245246

246247
err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
247248
if (err) {
249+
clock_control_off(config->clock_dev, config->clock_subsys);
248250
return err;
249251
}
250252

0 commit comments

Comments
 (0)