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+
3744struct 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
4962struct 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 ) \
857920static 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 = { \
0 commit comments