Skip to content

Commit de0cc63

Browse files
JasonHe-nxpJonyZhang7
authored andcommitted
drivers: usb: mcux_ehci: enable support to imx93
Enable support on i.MX93. Signed-off-by: Jason He <jason.he_1@nxp.com> Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
1 parent 233e9be commit de0cc63

File tree

2 files changed

+80
-10
lines changed

2 files changed

+80
-10
lines changed

drivers/usb/udc/udc_mcux_ehci.c

Lines changed: 74 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,31 @@ 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) \
41+
((const struct udc_mcux_config *)(_dev)->config)
42+
#define DEV_DATA(_dev) ((struct udc_mcux_data *)(udc_get_private(_dev)))
43+
3744
struct udc_mcux_config {
3845
const usb_device_controller_interface_struct_t *mcux_if;
3946
void (*irq_enable_func)(const struct device *dev);
4047
void (*irq_disable_func)(const struct device *dev);
4148
size_t num_of_eps;
4249
struct udc_ep_config *ep_cfg_in;
4350
struct udc_ep_config *ep_cfg_out;
44-
uintptr_t base;
51+
DEVICE_MMIO_NAMED_ROM(reg_base);
4552
const struct pinctrl_dev_config *pincfg;
4653
usb_phy_config_struct_t *phy_config;
54+
const struct device *usb_clock_dev;
55+
clock_control_subsys_t usb_clock_subsys;
56+
clock_control_subsys_rate_t usb_clock_rate;
57+
const struct device *usbphy_clock_dev;
58+
clock_control_subsys_t usbphy_clock_subsys;
59+
clock_control_subsys_rate_t usbphy_clock_rate;
4760
};
4861

4962
struct udc_mcux_data {
63+
DEVICE_MMIO_NAMED_RAM(reg_base);
5064
const struct device *dev;
5165
usb_device_struct_t mcux_device;
5266
struct k_work work;
@@ -690,11 +704,14 @@ static int udc_mcux_init(const struct device *dev)
690704
const usb_device_controller_interface_struct_t *mcux_if = config->mcux_if;
691705
struct udc_mcux_data *priv = udc_get_private(dev);
692706
usb_status_t status;
707+
uintptr_t base;
693708

694709
if (priv->controller_id == 0xFFu) {
695710
return -ENOMEM;
696711
}
697712

713+
base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base);
714+
698715
#ifdef CONFIG_DT_HAS_NXP_USBPHY_ENABLED
699716
if (config->phy_config != NULL) {
700717
USB_EhciPhyInit(priv->controller_id, 0u, config->phy_config);
@@ -711,7 +728,7 @@ static int udc_mcux_init(const struct device *dev)
711728
/* enable USB interrupt */
712729
config->irq_enable_func(dev);
713730

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

716733
return 0;
717734
}
@@ -735,9 +752,14 @@ static int udc_mcux_shutdown(const struct device *dev)
735752
return 0;
736753
}
737754

738-
static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv,
739-
const struct udc_mcux_config *config)
755+
static inline void udc_mcux_get_hal_driver_id(const struct device *dev)
740756
{
757+
struct udc_data *data = dev->data;
758+
struct udc_mcux_data *priv = data->priv;
759+
uintptr_t base;
760+
761+
base = (uintptr_t)DEVICE_MMIO_NAMED_GET(dev, reg_base);
762+
741763
/*
742764
* MCUX USB controller drivers use an ID to tell the HAL drivers
743765
* which controller is being used. This part of the code converts
@@ -752,7 +774,7 @@ static inline void udc_mcux_get_hal_driver_id(struct udc_mcux_data *priv,
752774
/* get the right controller id */
753775
priv->controller_id = 0xFFu; /* invalid value */
754776
for (uint8_t i = 0; i < ARRAY_SIZE(usb_base_addrs); i++) {
755-
if (usb_base_addrs[i] == config->base) {
777+
if (usb_base_addrs[i] == base) {
756778
priv->controller_id = kUSB_ControllerEhci0 + i;
757779
break;
758780
}
@@ -766,11 +788,18 @@ static int udc_mcux_driver_preinit(const struct device *dev)
766788
struct udc_mcux_data *priv = data->priv;
767789
int err;
768790

769-
udc_mcux_get_hal_driver_id(priv, config);
791+
DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
792+
793+
udc_mcux_get_hal_driver_id(dev);
770794
if (priv->controller_id == 0xFFu) {
771795
return -ENOMEM;
772796
}
773797

798+
if (config->usb_clock_dev && config->usb_clock_rate)
799+
clock_control_set_rate(config->usb_clock_dev, config->usb_clock_subsys, config->usb_clock_rate);
800+
if (config->usbphy_clock_dev && config->usbphy_clock_rate)
801+
clock_control_set_rate(config->usbphy_clock_dev, config->usbphy_clock_subsys, config->usbphy_clock_rate);
802+
774803
k_mutex_init(&data->mutex);
775804
k_fifo_init(&priv->fifo);
776805
k_work_init(&priv->work, udc_mcux_work_handler);
@@ -853,6 +882,40 @@ static const usb_device_controller_interface_struct_t udc_mcux_if = {
853882
USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
854883
};
855884

885+
#define UDC_MCUX_CLK0_DEFINE(n) \
886+
.usb_clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 0)), \
887+
.usb_clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(n, 0, name), \
888+
.usb_clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 0),
889+
890+
#define UDC_MCUX_CLK0_DEFINE_NULL \
891+
.usb_clock_dev = NULL, \
892+
.usb_clock_subsys = NULL, \
893+
.usb_clock_rate = NULL,
894+
895+
#define UDC_MCUX_CLK0_DEFINE_OR(n) \
896+
COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(n, 0), \
897+
(COND_CODE_1(DT_INST_PROP_HAS_IDX(n, clock_rates, 0), \
898+
(UDC_MCUX_CLK0_DEFINE(n)), \
899+
(UDC_MCUX_CLK0_DEFINE_NULL))), \
900+
(UDC_MCUX_CLK0_DEFINE_NULL))
901+
902+
#define UDC_MCUX_CLK1_DEFINE(n) \
903+
.usbphy_clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_IDX(n, 1)), \
904+
.usbphy_clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_IDX(n, 1, name), \
905+
.usbphy_clock_rate = (void *)(uintptr_t)DT_INST_PROP_BY_IDX(n, clock_rates, 1),
906+
907+
#define UDC_MCUX_CLK1_DEFINE_NULL \
908+
.usbphy_clock_dev = NULL, \
909+
.usbphy_clock_subsys = NULL, \
910+
.usbphy_clock_rate = NULL,
911+
912+
#define UDC_MCUX_CLK1_DEFINE_OR(n) \
913+
COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(n, 1), \
914+
(COND_CODE_1(DT_INST_PROP_HAS_IDX(n, clock_rates, 1), \
915+
(UDC_MCUX_CLK1_DEFINE(n)), \
916+
(UDC_MCUX_CLK1_DEFINE_NULL))), \
917+
(UDC_MCUX_CLK1_DEFINE_NULL))
918+
856919
#define UDC_MCUX_PHY_DEFINE(n) \
857920
static usb_phy_config_struct_t phy_config_##n = { \
858921
.D_CAL = DT_PROP_OR(DT_INST_PHANDLE(n, phy_handle), tx_d_cal, 0), \
@@ -898,7 +961,7 @@ static usb_phy_config_struct_t phy_config_##n = { \
898961
PINCTRL_DT_INST_DEFINE(n); \
899962
\
900963
static struct udc_mcux_config priv_config_##n = { \
901-
.base = DT_INST_REG_ADDR(n), \
964+
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \
902965
.irq_enable_func = udc_irq_enable_func##n, \
903966
.irq_disable_func = udc_irq_disable_func##n, \
904967
.num_of_eps = DT_INST_PROP(n, num_bidir_endpoints), \
@@ -907,6 +970,8 @@ static usb_phy_config_struct_t phy_config_##n = { \
907970
.mcux_if = &udc_mcux_if, \
908971
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
909972
.phy_config = UDC_MCUX_PHY_CFG_PTR_OR_NULL(n), \
973+
UDC_MCUX_CLK0_DEFINE_OR(n) \
974+
UDC_MCUX_CLK1_DEFINE_OR(n) \
910975
}; \
911976
\
912977
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)