Skip to content

Commit 5da1db8

Browse files
JasonHe-nxpJonyZhang7
authored andcommitted
drivers: usb: mcux_ehci: enable support to imx93
Enable i.MX93 support with dynamic clock and MMIO configuration. Signed-off-by: Jason He <jason.he_1@nxp.com> Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com> Signed-off-by: Jony Zhang <jony.zhang@nxp.com>
1 parent f93d28f commit 5da1db8

File tree

2 files changed

+91
-10
lines changed

2 files changed

+91
-10
lines changed

drivers/usb/udc/udc_mcux_ehci.c

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
/*
2-
* Copyright 2024 NXP
2+
* Copyright 2024-2025 NXP
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
#define DT_DRV_COMPAT nxp_ehci
77

8-
#include <soc.h>
98
#include <string.h>
109
#include <stdio.h>
10+
#include <stdint.h>
11+
#include <soc.h>
1112

1213
#include <zephyr/device.h>
1314
#include <zephyr/kernel.h>
1415
#include <zephyr/sys/byteorder.h>
1516
#include <zephyr/drivers/usb/udc.h>
1617
#include <zephyr/drivers/pinctrl.h>
18+
#include <zephyr/drivers/clock_control.h>
1719

1820
#include "udc_common.h"
1921
#include "usb.h"
@@ -34,19 +36,30 @@ LOG_MODULE_REGISTER(udc_mcux, CONFIG_UDC_DRIVER_LOG_LEVEL);
3436

3537
#define PRV_DATA_HANDLE(_handle) CONTAINER_OF(_handle, struct udc_mcux_data, mcux_device)
3638

39+
/* Required by DEVICE_MMIO_NAMED_* macros */
40+
#define DEV_CFG(_dev) ((const struct udc_mcux_config *)(_dev)->config)
41+
#define DEV_DATA(_dev) ((struct udc_mcux_data *)(udc_get_private(_dev)))
42+
3743
struct udc_mcux_config {
3844
const usb_device_controller_interface_struct_t *mcux_if;
3945
void (*irq_enable_func)(const struct device *dev);
4046
void (*irq_disable_func)(const struct device *dev);
4147
size_t num_of_eps;
4248
struct udc_ep_config *ep_cfg_in;
4349
struct udc_ep_config *ep_cfg_out;
44-
uintptr_t base;
50+
DEVICE_MMIO_NAMED_ROM(reg_base);
4551
const struct pinctrl_dev_config *pincfg;
4652
usb_phy_config_struct_t *phy_config;
53+
const struct device *clock_dev;
54+
clock_control_subsys_t clock_subsys;
55+
clock_control_subsys_rate_t clock_rate;
56+
const struct device *phy_clock_dev;
57+
clock_control_subsys_t phy_clock_subsys;
58+
clock_control_subsys_rate_t phy_clock_rate;
4759
};
4860

4961
struct udc_mcux_data {
62+
DEVICE_MMIO_NAMED_RAM(reg_base);
5063
const struct device *dev;
5164
usb_device_struct_t mcux_device;
5265
struct k_work work;
@@ -690,11 +703,14 @@ static int udc_mcux_init(const struct device *dev)
690703
const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
691704
struct udc_mcux_data *priv = udc_get_private(dev);
692705
usb_status_t status;
706+
uintptr_t base;
693707

694708
if (priv->controller_id == 0xFFu) {
695709
return -ENOMEM;
696710
}
697711

712+
base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base);
713+
698714
#ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED
699715
if (config->phy_config != NULL) {
700716
USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config);
@@ -711,7 +727,7 @@ static int udc_mcux_init(const struct device *dev)
711727
/* enable USB interrupt */
712728
config->irq_enable_func(dev);
713729

714-
LOG_DBG("Initialized USB controller %x", (uint32_t)config->base);
730+
LOG_DBG("Initialized USB controller %x", (uint32_t)base);
715731

716732
return 0;
717733
}
@@ -735,9 +751,14 @@ static int udc_mcux_shutdown(const struct device *dev)
735751
return 0;
736752
}
737753

738-
static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv,
739-
const struct udc_mcux_config *config)
754+
static inline void udc_mcux_get_hal_driver_id(const struct device *dev)
740755
{
756+
struct udc_data *data = dev->data;
757+
struct udc_mcux_data *priv = data->priv;
758+
uintptr_t base;
759+
760+
base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base);
761+
741762
/*
742763
* MCUX USB controller drivers use an ID to tell the HAL drivers
743764
* which controller is being used. This part of the code converts
@@ -752,7 +773,7 @@ static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv,
752773
/* get the right controller id */
753774
priv->controller_id = 0xFFu; /* invalid value */
754775
for (uint8_t i = 0; i < ARRAY_SIZE(usb_base_addrs); i++) {
755-
if (usb_base_addrs[i] == config->base) {
776+
if (usb_base_addrs[i] == base) {
756777
priv->controller_id = kUSB_ControllerEhci0 + i;
757778
break;
758779
}
@@ -766,11 +787,28 @@ static int udc_mcux_driver_preinit(const struct device *dev)
766787
struct udc_mcux_data *priv = data->priv;
767788
int err;
768789

769-
udc_mcux_get_hal_driver_id(priv, config);
790+
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
791+
792+
udc_mcux_get_hal_driver_id(dev);
770793
if (priv->controller_id == 0xFFu) {
771794
return -ENOMEM;
772795
}
773796

797+
if (config->clock_dev && config->clock_rate) {
798+
clock_control_set_rate(
799+
config->clock_dev,
800+
config->clock_subsys,
801+
config->clock_rate
802+
);
803+
}
804+
if (config->phy_clock_dev && config->phy_clock_rate) {
805+
clock_control_set_rate(
806+
config->phy_clock_dev,
807+
config->phy_clock_subsys,
808+
config->phy_clock_rate
809+
);
810+
}
811+
774812
k_mutex_init(&data->mutex);
775813
k_fifo_init(&priv->fifo);
776814
k_work_init(&priv->work, udc_mcux_work_handler);
@@ -853,6 +891,42 @@ static const usb_device_controller_interface_struct_t udc_mcux_if = {
853891
USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
854892
};
855893

894+
#define UDC_MCUX_CLK0_DEFINE(n) \
895+
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 0)), \
896+
.clock_subsys = (clock_control_subsys_t) \
897+
DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name), \
898+
.clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 0),
899+
900+
#define UDC_MCUX_CLK0_DEFINE_NULL \
901+
.clock_dev = NULL, \
902+
.clock_subsys = NULL, \
903+
.clock_rate = NULL,
904+
905+
#define UDC_MCUX_CLK0_DEFINE_OR(n) \
906+
COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(n, 0), \
907+
(COND_CODE_1(DT_INST_PROP_HAS_IDX(n, clock_rates, 0), \
908+
(UDC_MCUX_CLK0_DEFINE(n)), \
909+
(UDC_MCUX_CLK0_DEFINE_NULL))), \
910+
(UDC_MCUX_CLK0_DEFINE_NULL))
911+
912+
#define UDC_MCUX_CLK1_DEFINE(n) \
913+
.phy_clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 1)), \
914+
.phy_clock_subsys = (clock_control_subsys_t) \
915+
DT_INST_CLOCKS_CELL_BY_IDX(n, 1, name), \
916+
.phy_clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 1),
917+
918+
#define UDC_MCUX_CLK1_DEFINE_NULL \
919+
.phy_clock_dev = NULL, \
920+
.phy_clock_subsys = NULL, \
921+
.phy_clock_rate = NULL,
922+
923+
#define UDC_MCUX_CLK1_DEFINE_OR(n) \
924+
COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(n, 1), \
925+
(COND_CODE_1(DT_INST_PROP_HAS_IDX(n, clock_rates, 1), \
926+
(UDC_MCUX_CLK1_DEFINE(n)), \
927+
(UDC_MCUX_CLK1_DEFINE_NULL))), \
928+
(UDC_MCUX_CLK1_DEFINE_NULL))
929+
856930
#define UDC_MCUX_PHY_DEFINE(n) \
857931
static usb_phy_config_struct_t phy_config_##n = { \
858932
.D_CAL = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_d_cal, 0), \
@@ -898,7 +972,7 @@ static usb_phy_config_struct_t phy_config_##n = { \
898972
PINCTRL_DT_INST_DEFINE(n); \
899973
\
900974
static struct udc_mcux_config priv_config_##n = { \
901-
.base = DT_INST_REG_ADDR(n), \
975+
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \
902976
.irq_enable_func = udc_irq_enable_func##n, \
903977
.irq_disable_func = udc_irq_disable_func##n, \
904978
.num_of_eps = DT_INST_PROP(n, num_bidir_endpoints), \
@@ -907,6 +981,8 @@ static usb_phy_config_struct_t phy_config_##n = { \
907981
.mcux_if = &udc_mcux_if, \
908982
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
909983
.phy_config = UDC_MCUX_PHY_CFG_PTR_OR_NULL(n), \
984+
UDC_MCUX_CLK0_DEFINE_OR(n) \
985+
UDC_MCUX_CLK1_DEFINE_OR(n) \
910986
}; \
911987
\
912988
static struct udc_mcux_data priv_data_##n = { \

dts/bindings/usb/nxp,ehci.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2023 NXP
1+
# Copyright 2023,2025 NXP
22
# SPDX-License-Identifier: Apache-2.0
33

44
description: NXP EHCI USB device mode
@@ -10,3 +10,8 @@ include: "nxp,mcux-usbd.yaml"
1010
properties:
1111
phy-handle:
1212
type: phandle
13+
14+
clock-rates:
15+
type: array
16+
description: |
17+
Optional rate given to each clock provider in the "clocks" property.

0 commit comments

Comments
 (0)