diff --git a/boards/nxp/imx95_evk/board.c b/boards/nxp/imx95_evk/board.c index 477bcc38f6ae9..2b43501bfec0e 100644 --- a/boards/nxp/imx95_evk/board.c +++ b/boards/nxp/imx95_evk/board.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * SPDX-License-Identifier: Apache-2.0 */ @@ -10,21 +10,6 @@ static int board_init(void) { -#if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0) - /* Port 0 to 2 protocol configure: RGMII, RGMII, XGMII */ - BLK_CTRL_NETCMIX->CFG_LINK_MII_PROT = 0x00000522; - BLK_CTRL_NETCMIX->CFG_LINK_PCS_PROT_2 = 0x00000040; - - /* Unlock the IERB. It will warm reset whole NETC. */ - NETC_PRIV->NETCRR &= ~NETC_PRIV_NETCRR_LOCK_MASK; - while ((NETC_PRIV->NETCRR & NETC_PRIV_NETCRR_LOCK_MASK) != 0U) { - } - - /* Lock the IERB. */ - NETC_PRIV->NETCRR |= NETC_PRIV_NETCRR_LOCK_MASK; - while ((NETC_PRIV->NETCSR & NETC_PRIV_NETCSR_STATE_MASK) != 0U) { - } -#endif return 0; } diff --git a/boards/nxp/imx95_evk/doc/index.rst b/boards/nxp/imx95_evk/doc/index.rst index 4b52b0563c8ec..4a186e4300719 100644 --- a/boards/nxp/imx95_evk/doc/index.rst +++ b/boards/nxp/imx95_evk/doc/index.rst @@ -106,8 +106,7 @@ Ethernet -------- NETC driver supports to manage the Physical Station Interface (PSI). -The first ENET1 port could be enabled for M7 by west build option -``-DEXTRA_DTC_OVERLAY_FILE=enetc_psi0.overlay``. +The first ENET1 port could be enabled on M7 DDR platform. Programming and Debugging (A55) diff --git a/boards/nxp/imx95_evk/dts/enetc_psi0.overlay b/boards/nxp/imx95_evk/dts/enetc_psi0.overlay deleted file mode 100644 index a14003810f063..0000000000000 --- a/boards/nxp/imx95_evk/dts/enetc_psi0.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2025 NXP - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&emdio { - status = "okay"; - - phy0: phy@1 { - status = "okay"; - }; -}; - -&enetc_psi0 { - status = "okay"; -}; - -&enetc_ptp_clock { - status = "okay"; -}; diff --git a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts index 8b661db7a8aff..6c5167634d257 100644 --- a/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts +++ b/boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,12 +26,12 @@ &emdio { pinctrl-0 = <&emdio_default>; pinctrl-names = "default"; - status = "disabled"; + status = "okay"; phy0: phy@1 { compatible = "realtek,rtl8211f"; reg = <0x1>; - status = "disabled"; + status = "okay"; }; }; @@ -41,7 +41,11 @@ pinctrl-names = "default"; phy-handle = <&phy0>; phy-connection-type = "rgmii"; - status = "disabled"; + status = "okay"; +}; + +&enetc_ptp_clock { + status = "okay"; }; &flexspi { diff --git a/drivers/ethernet/nxp_imx_netc/CMakeLists.txt b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt index 91fbf4d4f1eef..28631f49ba316 100644 --- a/drivers/ethernet/nxp_imx_netc/CMakeLists.txt +++ b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt @@ -4,6 +4,7 @@ if(CONFIG_ETH_NXP_IMX_NETC) zephyr_library_sources(eth_nxp_imx_netc.c) zephyr_library_sources(eth_nxp_imx_netc_psi.c) + zephyr_library_sources_ifdef(CONFIG_DT_HAS_NXP_IMX_NETC_BLK_CTRL_ENABLED eth_nxp_imx_netc_blk.c) endif() zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) diff --git a/drivers/ethernet/nxp_imx_netc/Kconfig b/drivers/ethernet/nxp_imx_netc/Kconfig index 5c6af4f5c0cb6..21636cb438aca 100644 --- a/drivers/ethernet/nxp_imx_netc/Kconfig +++ b/drivers/ethernet/nxp_imx_netc/Kconfig @@ -12,11 +12,25 @@ menuconfig ETH_NXP_IMX_NETC if ETH_NXP_IMX_NETC +DT_GIC_ITS_COMPAT := arm,gic-v3-its +DT_NETC_PATH := $(dt_nodelabel_path,netc) +DT_NETC_INT_PARENT_PATH := $(dt_node_ph_prop_path,$(DT_NETC_PATH),msi-parent) +DT_NETC_INT_IS_GIC := $(dt_node_has_compat,$(DT_NETC_INT_PARENT_PATH),$(DT_GIC_ITS_COMPAT)) + +config ETH_NXP_IMX_NETC_MSI_GIC + bool + default y if ($(DT_NETC_INT_IS_GIC) && DT_HAS_ARM_GIC_V3_ITS_ENABLED) + depends on GIC_V3_ITS + help + Use GIC ITS controller as MSI module for NXP NETC + +if !ETH_NXP_IMX_NETC_MSI_GIC config ETH_NXP_IMX_MSGINTR int "Message Interrupt module select" default 1 help Message Interrupt module select. +endif config ETH_NXP_IMX_RX_THREAD_PRIO int "RX thread priority" diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 32762582dce7d..ec82fafb653b8 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(nxp_imx_eth); #include #include #include +#ifdef CONFIG_GIC_V3_ITS +#include +#endif #include "../eth.h" #include "eth_nxp_imx_netc_priv.h" @@ -173,6 +176,28 @@ static void netc_eth_rx_thread(void *arg1, void *unused1, void *unused2) } } +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + +static void netc_tx_isr_handler(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct netc_eth_data *data = dev->data; + + EP_CleanTxIntrFlags(&data->handle, 1, 0); + data->tx_done = true; +} + +static void netc_rx_isr_handler(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct netc_eth_data *data = dev->data; + + EP_CleanRxIntrFlags(&data->handle, 1); + k_sem_give(&data->rx_sem); +} + +#else /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */ + static void msgintr_isr(void) { uint32_t irqs = NETC_MSGINTR->MSI[NETC_MSGINTR_CHANNEL].MSIR; @@ -203,6 +228,8 @@ static void msgintr_isr(void) SDK_ISR_EXIT_BARRIER; } +#endif + int netc_eth_init_common(const struct device *dev) { const struct netc_eth_config *config = dev->config; @@ -222,6 +249,51 @@ int netc_eth_init_common(const struct device *dev) #endif /* MSIX entry configuration */ +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + int ret; + + if (config->msi_dev == NULL) { + LOG_ERR("MSI device is not configured"); + return -ENODEV; + } + ret = its_setup_deviceid(config->msi_dev, config->msi_device_id, NETC_MSIX_ENTRY_NUM); + if (ret != 0) { + LOG_ERR("Failed to setup device ID for MSI: %d", ret); + return ret; + } + data->tx_intid = its_alloc_intid(config->msi_dev); + data->rx_intid = its_alloc_intid(config->msi_dev); + + msg_addr = its_get_msi_addr(config->msi_dev); + msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; + msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr; + msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgData = NETC_TX_MSIX_ENTRY_IDX; + ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_TX_MSIX_ENTRY_IDX, + data->tx_intid); + if (ret != 0) { + LOG_ERR("Failed to map TX MSI interrupt: %d", ret); + return ret; + } + + msix_entry[NETC_RX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; + msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgAddr = msg_addr; + msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgData = NETC_RX_MSIX_ENTRY_IDX; + ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_RX_MSIX_ENTRY_IDX, + data->rx_intid); + if (ret != 0) { + LOG_ERR("Failed to map RX MSI interrupt: %d", ret); + return ret; + } + + if (!irq_is_enabled(data->tx_intid)) { + irq_connect_dynamic(data->tx_intid, 0, netc_tx_isr_handler, dev, 0); + irq_enable(data->tx_intid); + } + if (!irq_is_enabled(data->rx_intid)) { + irq_connect_dynamic(data->rx_intid, 0, netc_rx_isr_handler, dev, 0); + irq_enable(data->rx_intid); + } +#else msg_addr = MSGINTR_GetIntrSelectAddr(NETC_MSGINTR, NETC_MSGINTR_CHANNEL); msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr; @@ -235,6 +307,7 @@ int netc_eth_init_common(const struct device *dev) IRQ_CONNECT(NETC_MSGINTR_IRQ, 0, msgintr_isr, 0, 0); irq_enable(NETC_MSGINTR_IRQ); } +#endif /* Endpoint configuration. */ EP_GetDefaultConfig(&ep_config); diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c new file mode 100644 index 0000000000000..5e6aaa9e87978 --- /dev/null +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_blk.c @@ -0,0 +1,210 @@ +/* NXP NETC Block Controller Driver + * + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT nxp_imx_netc_blk_ctrl + +#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL +#include +LOG_MODULE_REGISTER(nxp_imx_netc_blk); + +#include +#include + +/* NETC integrated endpoint register block register */ +#define IERB_EMDIOFAUXR 0x344 +#define IERB_T0FAUXR 0x444 +#define IERB_ETBCR(a) (0x300c + 0x100 * (a)) +#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a)) +#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a)) + +/* NETC privileged register block register */ +#define PRB_NETCRR 0x100 +#define NETCRR_SR BIT(0) +#define NETCRR_LOCK BIT(1) + +#define PRB_NETCSR 0x104 +#define NETCSR_ERROR BIT(0) +#define NETCSR_STATE BIT(1) + +/* NETCMIX CFG Link register */ +#define CFG_LINK_MII_PROT 0x10 +enum { + MII, + RMII, + RGMII, + reserved, + SGMII, + XGMII, +}; +#define CFG_LINK_MII_PROT_0_SHIFT 0 +#define CFG_LINK_MII_PROT_1_SHIFT 4 +#define CFG_LINK_MII_PROT_2_SHIFT 8 +#define MII_PROT_N(prot, n) ((prot) << CFG_LINK_MII_PROT_##n##_SHIFT) + +/* NETCMIX PCS protocol register */ +#define CFG_LINK_PCS_PROT_0 0x14 +#define CFG_LINK_PCS_PROT_1 0x18 +#define CFG_LINK_PCS_PROT_2 0x1c +/* PCS Protocols */ +#define CFG_LINK_PCS_PROT_1G_SGMII BIT(0) +#define CFG_LINK_PCS_PROT_2500M_SGMII BIT(1) +#define CFG_LINK_PCS_PROT_XFI BIT(3) +#define CFG_LINK_PCS_PROT_10G_SXGMII BIT(6) + +struct eth_nxp_imx_netc_blk_config { + DEVICE_MMIO_NAMED_ROM(ierb); + DEVICE_MMIO_NAMED_ROM(prb); + DEVICE_MMIO_NAMED_ROM(netcmix); +}; + +struct eth_nxp_imx_netc_blk_data { + DEVICE_MMIO_NAMED_RAM(ierb); + DEVICE_MMIO_NAMED_RAM(prb); + DEVICE_MMIO_NAMED_RAM(netcmix); +}; + +#define DEV_CFG(_dev) ((const struct eth_nxp_imx_netc_blk_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct eth_nxp_imx_netc_blk_data *)(_dev)->data) + +#define read_and_poll_timeout(reg, val, cond) \ + ({ \ + unsigned int count = 1000000; /* 1s! */ \ + while (1) { \ + (val) = sys_read32(reg); \ + if (cond) { \ + break; \ + } \ + count--; \ + if (!count) { \ + break; \ + } \ + k_usleep(1); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ + }) + +static bool ierb_is_locked(const struct device *dev) +{ + uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb); + + return sys_read32(base + PRB_NETCRR) & NETCRR_LOCK; +} + +static int ierb_lock(const struct device *dev) +{ + uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb); + uint32_t val; + + sys_write32(NETCRR_LOCK, base + PRB_NETCRR); + + return read_and_poll_timeout(base + PRB_NETCSR, val, !(val & NETCSR_STATE)); +} + +static int ierb_unlock(const struct device *dev) +{ + uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb); + uint32_t val; + + sys_write32(1, base + PRB_NETCRR); + + return read_and_poll_timeout(base + PRB_NETCRR, val, !(val & NETCRR_LOCK)); +} + +#ifdef CONFIG_SOC_MIMX9596 +/* Set LDID */ +static int ierb_init(const struct device *dev) +{ + uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, ierb); + + /* EMDIO : No MSI-X interrupt */ + sys_write32(0, base + IERB_EMDIOFAUXR); + /* ENETC0 PF */ + sys_write32(0, base + IERB_EFAUXR(0)); + /* ENETC0 VF0 */ + sys_write32(1, base + IERB_VFAUXR(0)); + /* ENETC0 VF1 */ + sys_write32(2, base + IERB_VFAUXR(1)); + /* ENETC1 PF */ + sys_write32(3, base + IERB_EFAUXR(1)); + /* ENETC1 VF0 : Disabled on 19x19 board dts */ + sys_write32(5, base + IERB_VFAUXR(2)); + /* ENETC1 VF1 : Disabled on 19x19 board dts */ + sys_write32(6, base + IERB_VFAUXR(3)); + /* ENETC2 PF */ + sys_write32(4, base + IERB_EFAUXR(2)); + /* ENETC2 VF0 : Disabled on 15x15 board dts */ + sys_write32(5, base + IERB_VFAUXR(4)); + /* ENETC2 VF1 : Disabled on 15x15 board dts */ + sys_write32(6, base + IERB_VFAUXR(5)); + /* NETC TIMER */ + sys_write32(7, base + IERB_T0FAUXR); + + return 0; +} + +static int netcmix_init(const struct device *dev) +{ + uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, netcmix); + uint32_t reg_val; + + /* ToDo: configure PSC protocol and MII protocol according to PHY mode */ + reg_val = MII_PROT_N(RGMII, 0) | MII_PROT_N(RGMII, 1) | MII_PROT_N(XGMII, 2); + sys_write32(reg_val, base + CFG_LINK_MII_PROT); + sys_write32(CFG_LINK_PCS_PROT_10G_SXGMII, base + CFG_LINK_PCS_PROT_2); + + return 0; +} +#endif + +static int eth_nxp_imx_netc_blk_init(const struct device *dev) +{ + int ret; + + DEVICE_MMIO_NAMED_MAP(dev, ierb, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + DEVICE_MMIO_NAMED_MAP(dev, prb, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + DEVICE_MMIO_NAMED_MAP(dev, netcmix, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + + if (ierb_is_locked(dev)) { + ret = ierb_unlock(dev); + if (ret) { + LOG_ERR("Unlock IERB failed."); + return ret; + } + } + + if (ierb_init(dev) != 0) { + LOG_ERR("Failed to initialize IERB"); + return -EIO; + } + + ret = ierb_lock(dev); + if (ret) { + LOG_ERR("Lock IERB failed."); + return ret; + } + + ret = netcmix_init(dev); + if (ret) { + LOG_ERR("NETCMIX init failed."); + return ret; + } + + return 0; +} + +#define ETH_NXP_IMX_NETC_BLK_INIT(inst) \ + static struct eth_nxp_imx_netc_blk_data eth_nxp_imx_netc_blk_data_##inst; \ + static const struct eth_nxp_imx_netc_blk_config eth_nxp_imx_netc_blk_config_##inst = { \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(ierb, DT_DRV_INST(inst)), \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(prb, DT_DRV_INST(inst)), \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(netcmix, DT_DRV_INST(inst)), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, eth_nxp_imx_netc_blk_init, NULL, \ + ð_nxp_imx_netc_blk_data_##inst, \ + ð_nxp_imx_netc_blk_config_##inst, POST_KERNEL, \ + CONFIG_MDIO_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(ETH_NXP_IMX_NETC_BLK_INIT) diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h index 157f7e61bae47..3dce788f1a24c 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h @@ -9,7 +9,9 @@ #include "nxp_imx_netc.h" #include "fsl_netc_endpoint.h" +#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC #include "fsl_msgintr.h" +#endif /* Buffer and descriptor alignment */ #define NETC_BUFF_ALIGN 64 @@ -33,6 +35,7 @@ #define NETC_MSGINTR_IRQ DT_IRQN_BY_IDX(DT_NODELABEL(netc), 0) #endif +#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC #if (CONFIG_ETH_NXP_IMX_MSGINTR == 1) #define NETC_MSGINTR MSGINTR1 #ifndef NETC_MSGINTR_IRQ @@ -46,6 +49,7 @@ #else #error "Current CONFIG_ETH_NXP_IMX_MSGINTR not support" #endif +#endif /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */ /* Timeout for various operations */ #define NETC_TIMEOUT K_MSEC(20) @@ -82,6 +86,8 @@ } struct netc_eth_config { + DEVICE_MMIO_NAMED_ROM(port); + DEVICE_MMIO_NAMED_ROM(pfconfig); uint16_t si_idx; const struct device *phy_dev; netc_hw_mii_mode_t phy_mode; @@ -90,8 +96,13 @@ struct netc_eth_config { void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config, netc_tx_bdr_config_t *tx_bdr_config); const struct pinctrl_dev_config *pincfg; +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + const struct device *msi_dev; + uint8_t msi_device_id; /* MSI device ID */ +#else uint8_t tx_intr_msg_data; uint8_t rx_intr_msg_data; +#endif #ifdef CONFIG_PTP_CLOCK_NXP_NETC const struct device *ptp_clock; #endif @@ -100,6 +111,8 @@ struct netc_eth_config { typedef uint8_t rx_buffer_t[NETC_RX_RING_BUF_SIZE_ALIGN]; struct netc_eth_data { + DEVICE_MMIO_NAMED_RAM(port); + DEVICE_MMIO_NAMED_RAM(pfconfig); ep_handle_t handle; struct net_if *iface; uint8_t mac_addr[6]; @@ -113,6 +126,10 @@ struct netc_eth_data { K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_NXP_IMX_RX_THREAD_STACK_SIZE); uint8_t *rx_frame; +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + unsigned int tx_intid; + unsigned int rx_intid; +#endif }; int netc_eth_init_common(const struct device *dev); diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c index 3dc10ae872469..1f2eda5094971 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c @@ -22,6 +22,9 @@ LOG_MODULE_REGISTER(nxp_imx_eth_psi); #include "../eth.h" #include "eth_nxp_imx_netc_priv.h" +#define DEV_CFG(_dev) ((const struct netc_eth_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct netc_eth_data *)(_dev)->data) + static void netc_eth_phylink_callback(const struct device *pdev, struct phy_link_state *state, void *user_data) { @@ -104,6 +107,9 @@ static int netc_eth_init(const struct device *dev) const struct netc_eth_config *cfg = dev->config; int err; + DEVICE_MMIO_NAMED_MAP(dev, port, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + DEVICE_MMIO_NAMED_MAP(dev, pfconfig, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + if (cfg->pseudo_mac) { goto init_common; } @@ -192,6 +198,8 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac .rx_frame = eth##n##_rx_frame, \ }; \ static const struct netc_eth_config netc_eth##n##_config = { \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(port, DT_DRV_INST(n)), \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(pfconfig, DT_DRV_INST(n)), \ .generate_mac = netc_eth##n##_generate_mac, \ .bdr_init = netc_eth##n##_bdr_init, \ .phy_dev = (COND_CODE_1(DT_INST_NODE_HAS_PROP(n, phy_handle), \ @@ -200,8 +208,14 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac .pseudo_mac = DT_ENUM_HAS_VALUE(DT_DRV_INST(n), phy_connection_type, internal), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \ - .tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ - .rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n, \ + IF_ENABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \ + (.msi_device_id = DT_INST_PROP_OR(n, msi_device_id, 0), \ + .msi_dev = (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_PARENT(n), msi_parent), \ + (DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(n), msi_parent))), NULL)), \ + )) \ + IF_DISABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \ + (.tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ + .rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n,)) \ IF_ENABLED(CONFIG_PTP_CLOCK_NXP_NETC, \ (.ptp_clock = DEVICE_DT_GET(DT_INST_PHANDLE(n, ptp_clock)),)) \ }; \ diff --git a/drivers/mdio/mdio_nxp_imx_netc.c b/drivers/mdio/mdio_nxp_imx_netc.c index 4882f16b08d98..c9afc4a4c4055 100644 --- a/drivers/mdio/mdio_nxp_imx_netc.c +++ b/drivers/mdio/mdio_nxp_imx_netc.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,13 +15,20 @@ #include "fsl_netc_mdio.h" LOG_MODULE_REGISTER(nxp_imx_netc_emdio, CONFIG_MDIO_LOG_LEVEL); +#define DEV_CFG(_dev) ((const struct nxp_imx_netc_mdio_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct nxp_imx_netc_mdio_data *)(_dev)->data) + struct nxp_imx_netc_mdio_config { + DEVICE_MMIO_NAMED_ROM(basic); + DEVICE_MMIO_NAMED_ROM(pfconfig); const struct pinctrl_dev_config *pincfg; const struct device *clock_dev; clock_control_subsys_t clock_subsys; }; struct nxp_imx_netc_mdio_data { + DEVICE_MMIO_NAMED_RAM(basic); + DEVICE_MMIO_NAMED_RAM(pfconfig); struct k_mutex rw_mutex; netc_mdio_handle_t handle; }; @@ -60,6 +67,9 @@ static int nxp_imx_netc_mdio_initialize(const struct device *dev) status_t result; int err; + DEVICE_MMIO_NAMED_MAP(dev, basic, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + DEVICE_MMIO_NAMED_MAP(dev, pfconfig, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); if (err) { return err; @@ -89,6 +99,8 @@ static DEVICE_API(mdio, nxp_imx_netc_mdio_api) = { PINCTRL_DT_INST_DEFINE(n); \ static struct nxp_imx_netc_mdio_data nxp_imx_netc_mdio##n##_data; \ static const struct nxp_imx_netc_mdio_config nxp_imx_netc_mdio##n##_cfg = { \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(basic, DT_DRV_INST(n)), \ + DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(pfconfig, DT_DRV_INST(n)), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ diff --git a/dts/arm/nxp/nxp_imx943_m33.dtsi b/dts/arm/nxp/nxp_imx943_m33.dtsi index 787fbcfd29744..41637e6a96638 100644 --- a/dts/arm/nxp/nxp_imx943_m33.dtsi +++ b/dts/arm/nxp/nxp_imx943_m33.dtsi @@ -263,25 +263,18 @@ status = "disabled"; }; - netc: ethernet@4ca00000 { - reg = <0x4ca00000 0x500000>; + netc: ethernet { + compatible = "nxp,imx-netc"; interrupts = <294 0>; #address-cells = <1>; #size-cells = <1>; ranges; - emdio: mdio@4cde0000 { - compatible = "nxp,imx-netc-emdio"; - reg = <0x4cde0000 0x10000>; - clocks = <&scmi_clk IMX943_CLK_ENET>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - enetc_psi0: ethernet@4cc80000 { compatible = "nxp,imx-netc-psi"; - reg = <0x4cc80000 0x10000>; + reg = <0x4cc80000 0x10000>, + <0x4cb00000 0x1000>; + reg-names = "port", "pfconfig"; mac-index = <0>; si-index = <0>; status = "disabled"; @@ -289,7 +282,9 @@ enetc_psi1: ethernet@4ccc0000 { compatible = "nxp,imx-netc-psi"; - reg = <0x4ccc0000 0x10000>; + reg = <0x4ccc0000 0x10000>, + <0x4cb40000 0x1000>; + reg-names = "port", "pfconfig"; mac-index = <1>; si-index = <1>; status = "disabled"; @@ -297,7 +292,9 @@ enetc_psi2: ethernet@4cd00000 { compatible = "nxp,imx-netc-psi"; - reg = <0x4cd00000 0x10000>; + reg = <0x4cd00000 0x10000>, + <0x4cb80000 0x1000>; + reg-names = "port", "pfconfig"; mac-index = <2>; si-index = <2>; status = "disabled"; @@ -323,6 +320,17 @@ clocks = <&scmi_clk IMX943_CLK_ENET>; status = "disabled"; }; + + emdio: mdio@4cde0000 { + compatible = "nxp,imx-netc-emdio"; + reg = <0x4cde0000 0x10000>, + <0x4cbc0000 0x40000>; + reg-names = "basic", "pfconfig"; + clocks = <&scmi_clk IMX943_CLK_ENET>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; }; }; diff --git a/dts/arm/nxp/nxp_imx95_m7.dtsi b/dts/arm/nxp/nxp_imx95_m7.dtsi index 1751f15014eb3..b80830aa264c5 100644 --- a/dts/arm/nxp/nxp_imx95_m7.dtsi +++ b/dts/arm/nxp/nxp_imx95_m7.dtsi @@ -526,52 +526,71 @@ }; }; - netc: ethernet@4ca00000 { - reg = <0x4ca00000 0x1000000>; - interrupt-parent = <&irqsteer_master0>; - interrupts = <13 0 0>; + netc_blk_ctrl: netc-blk-ctrl@4cde0000 { + compatible = "nxp,imx-netc-blk-ctrl"; + reg = <0x4cde0000 0x10000>, + <0x4cdf0000 0x10000>, + <0x4c810000 0x18>; + reg-names = "ierb", "prb", "netcmix"; #address-cells = <1>; #size-cells = <1>; ranges; - emdio: mdio@4cce0000 { - compatible = "nxp,imx-netc-emdio"; - reg = <0x4cce0000 0x1c44>; - clocks = <&scmi_clk IMX95_CLK_ENET>; + netc: ethernet { + compatible = "nxp,imx-netc"; + interrupt-parent = <&irqsteer_master0>; + interrupts = <13 0 0>; #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; + #size-cells = <1>; + ranges; + + enetc_psi0: ethernet@4cc00000 { + compatible = "nxp,imx-netc-psi"; + reg = <0x4cc00000 0x10000>, + <0x4ca00000 0x1000>; + reg-names = "port", "pfconfig"; + mac-index = <0>; + si-index = <0>; + status = "disabled"; + }; - enetc_psi0: ethernet@4cc00000 { - compatible = "nxp,imx-netc-psi"; - reg = <0x4cc00000 0x10000>; - mac-index = <0>; - si-index = <0>; - status = "disabled"; - }; + enetc_psi1: ethernet@4cc40000 { + compatible = "nxp,imx-netc-psi"; + reg = <0x4cc40000 0x10000>, + <0x4ca40000 0x1000>; + reg-names = "port", "pfconfig"; + mac-index = <1>; + si-index = <1>; + status = "disabled"; + }; - enetc_psi1: ethernet@4cc40000 { - compatible = "nxp,imx-netc-psi"; - reg = <0x4cc40000 0x10000>; - mac-index = <1>; - si-index = <1>; - status = "disabled"; - }; + enetc_psi2: ethernet@4cc80000 { + compatible = "nxp,imx-netc-psi"; + reg = <0x4cc80000 0x10000>, + <0x4ca80000 0x1000>; + reg-names = "port", "pfconfig"; + mac-index = <2>; + si-index = <2>; + status = "disabled"; + }; - enetc_psi2: ethernet@4cc80000 { - compatible = "nxp,imx-netc-psi"; - reg = <0x4cc80000 0x10000>; - mac-index = <2>; - si-index = <2>; - status = "disabled"; - }; + emdio: mdio@4cb00000 { + compatible = "nxp,imx-netc-emdio"; + reg = <0x4cce0000 0x2000>, + <0x4cb00000 0x100000>; + reg-names = "basic", "pfconfig"; + clocks = <&scmi_clk IMX95_CLK_ENET>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; - enetc_ptp_clock: ptp_clock@4ccc0000 { - compatible = "nxp,netc-ptp-clock"; - reg = <0x4ccc0000 0x10000>; - clocks = <&scmi_clk IMX95_CLK_ENET>; - status = "disabled"; + enetc_ptp_clock: ptp_clock@4ccc0000 { + compatible = "nxp,netc-ptp-clock"; + reg = <0x4ccc0000 0x10000>; + clocks = <&scmi_clk IMX95_CLK_ENET>; + status = "disabled"; + }; }; }; }; diff --git a/dts/arm/nxp/nxp_rt118x.dtsi b/dts/arm/nxp/nxp_rt118x.dtsi index dc25cfb24ecb4..686987b1c0399 100644 --- a/dts/arm/nxp/nxp_rt118x.dtsi +++ b/dts/arm/nxp/nxp_rt118x.dtsi @@ -618,15 +618,17 @@ }; }; - netc: ethernet@60000000 { - reg = <0x60000000 0x1000000>; + netc: ethernet { + compatible = "nxp,imx-netc"; #address-cells = <1>; #size-cells = <1>; ranges; enetc_psi0: ethernet@60b00000 { compatible = "nxp,imx-netc-psi"; - reg = <0x60b00000 0x10000>; + reg = <0x60b00000 0x10000>, + <0x60003000 0x1000>; + reg-names = "port", "pfconfig"; mac-index = <0>; si-index = <0>; status = "disabled"; @@ -634,7 +636,9 @@ enetc_psi1: ethernet@60b40000 { compatible = "nxp,imx-netc-psi"; - reg = <0x60b40000 0x10000>; + reg = <0x60b40000 0x10000>, + <0x60004000 0x1000>; + reg-names = "port", "pfconfig"; mac-index = <1>; si-index = <1>; phy-connection-type = "internal"; @@ -643,7 +647,9 @@ emdio: mdio@60ba0000 { compatible = "nxp,imx-netc-emdio"; - reg = <0x60ba0000 0x1c44>; + reg = <0x60ba0000 0x1c44>, + <0x60001000 0x1000>; + reg-names = "basic", "pfconfig"; clocks = <&ccm IMX_CCM_NETC_CLK 0x0 0>; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/bindings/ethernet/nxp,imx-netc-blk-ctrl.yaml b/dts/bindings/ethernet/nxp,imx-netc-blk-ctrl.yaml new file mode 100644 index 0000000000000..7ad70ebaf5e3a --- /dev/null +++ b/dts/bindings/ethernet/nxp,imx-netc-blk-ctrl.yaml @@ -0,0 +1,12 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP i.MX NETC Block Controller + +compatible: "nxp,imx-netc-blk-ctrl" + +include: [base.yaml] + +properties: + reg: + required: true diff --git a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml index 7aba10df1e35d..128a385af07a9 100644 --- a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml +++ b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml @@ -20,3 +20,7 @@ properties: required: true type: int description: The SI index of this PSI. + + msi-device-id: + type: int + description: The device ID passed to MSI controller. diff --git a/dts/bindings/ethernet/nxp,imx-netc.yaml b/dts/bindings/ethernet/nxp,imx-netc.yaml new file mode 100644 index 0000000000000..badfc134a7e3c --- /dev/null +++ b/dts/bindings/ethernet/nxp,imx-netc.yaml @@ -0,0 +1,13 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP i.MX NETC Controller + +compatible: "nxp,imx-netc" + +include: [base.yaml] + +properties: + msi-parent: + type: phandle + description: MSI controller diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index b794013ca972c..d7fa09bed8551 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -142,7 +142,9 @@ set_variable_ifdef(CONFIG_MIPI_DBI_NXP_DCNANO_LCDIF CONFIG_MCUX_COMPONENT_driver set_variable_ifdef(CONFIG_MIPI_DBI_NXP_FLEXIO_LCDIF CONFIG_MCUX_COMPONENT_driver.flexio_mculcd) set_variable_ifdef(CONFIG_VIDEO_MCUX_MIPI_CSI2RX CONFIG_MCUX_COMPONENT_driver.mipi_csi2rx) set_variable_ifdef(CONFIG_ETH_NXP_IMX_NETC CONFIG_MCUX_COMPONENT_driver.netc) -set_variable_ifdef(CONFIG_ETH_NXP_IMX_NETC CONFIG_MCUX_COMPONENT_driver.netc_switch) +if(NOT CONFIG_SOC_MIMX9596) + set_variable_ifdef(CONFIG_ETH_NXP_IMX_NETC CONFIG_MCUX_COMPONENT_driver.netc_switch) +endif() set_variable_ifdef(CONFIG_SOC_SERIES_IMXRT10XX CONFIG_MCUX_COMPONENT_driver.ocotp) set_variable_ifdef(CONFIG_SOC_SERIES_IMXRT11XX CONFIG_MCUX_COMPONENT_driver.ocotp)