Skip to content

add NETC support on imx95 A55 #92585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
104a956
drivers: intc_gicv3: enable dma-noncoherent support
JiafeiPan Jun 27, 2025
8f425d2
drivers: gicv3_its: enable dma noncoherent support
JiafeiPan Jun 12, 2025
c690257
drivers: intc_gicv3_its: fix incorrect RDbase when PE number is used
JiafeiPan Jun 27, 2025
5ec58c9
drivers: intc_gicv3_its: fix sleep issue in pre-kernel
JiafeiPan Jun 27, 2025
a4bd88f
boards: imx95_evk: a55: enlarge memory size
JiafeiPan May 30, 2025
85367f2
dts: arm64: imx95_a55: add gic v3 its dts node
JiafeiPan Jun 27, 2025
1eee2af
soc: imx95: a55: include LPI in irq number
JiafeiPan Jun 13, 2025
5b3c732
soc: imx95: a55: enable GIC redistribute noncoherent
JiafeiPan Jun 27, 2025
bffe8d5
boards: imx95_evk: refine GIC and SCMI objects init priority
JiafeiPan Jun 27, 2025
4e606a4
tests: arm64_gicv3_its: add imx95_evk support
JiafeiPan Jun 27, 2025
1d98712
west.yml: depend on hal_nxp PR
JiafeiPan Jul 3, 2025
3308b74
drivers: ethernet: imx_netc: add GIC MSI support
JiafeiPan May 22, 2025
338fc79
drivers: ethernet: imx_netc: add netc block driver
JiafeiPan Jun 29, 2025
db5d41a
drivers: mdio: imx_netc: add mmio mapping support
JiafeiPan Jun 23, 2025
d2f26cb
drivers: ethernet: imx_netc: add MMIO memory mapping
JiafeiPan Jul 2, 2025
e43fc0c
drivers: ethernet: netc_psi: add MMIPO mapping support
JiafeiPan Jul 2, 2025
fb48e36
modules: hal_nxp: disable netc switch on imx95
JiafeiPan Jun 30, 2025
a3a8fce
dts: arm: imx95_m7: update netc device nodes
JiafeiPan Jul 3, 2025
44925f2
dts: arm: rt118x: update netc device nodes
JiafeiPan Jul 9, 2025
855dcf1
dts: arm: imx943_m33: update netc device nodes
JiafeiPan Jul 9, 2025
5aeedda
dts: arm64: imx95_evk: add netc dts nodes
JiafeiPan Jun 29, 2025
646098a
dts: arm64: imx95_a55: add SCMI power device node
JiafeiPan Jun 24, 2025
a74b079
soc: imx95: a55: add netc power and clock init in soc.c
JiafeiPan Jun 24, 2025
f51c63e
board: imx95_evk: m7: refine NETC dts
JiafeiPan Jul 4, 2025
d37b067
boards: imx95_evk: a55: add NETC support
JiafeiPan Jun 29, 2025
784e7a5
boards: imx95_evk: a55: enlarge networking stack size
JiafeiPan Jul 9, 2025
d6c9cda
samples: net: zperf: add imx95 evk a55 suppport
JiafeiPan Jul 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions boards/nxp/imx95_evk/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright 2024-2025 NXP
# SPDX-License-Identifier: Apache-2.0

if SOC_MIMX9596_A55

if ETH_NXP_IMX_NETC

config GIC_V3_ITS
default y

endif # ETH_NXP_IMX_NETC

# GIC ITS depends on kernel heap which init priority is 30, so set
# GIC to be 31, mailbox and SCMI will be initialized by the order
# according to dts dependency although they use the same init priority.
config INTC_INIT_PRIORITY
default 31

config MBOX_INIT_PRIORITY
default 31

config ARM_SCMI_SHMEM_INIT_PRIORITY
default 31

config ARM_SCMI_TRANSPORT_INIT_PRIORITY
default 31

config CLOCK_CONTROL_INIT_PRIORITY
default 31

# Enlarge default networking stack
if NETWORKING

config NET_L2_ETHERNET
default y

config NET_TX_STACK_SIZE
default 8192

config NET_RX_STACK_SIZE
default 8192

if NET_TCP

config NET_TCP_WORKQ_STACK_SIZE
default 8192

endif # NET_TCP

if NET_MGMT_EVENT

config NET_MGMT_EVENT_STACK_SIZE
default 8192

endif # NET_MGMT_EVENT

if NET_SOCKETS_SERVICE

config NET_SOCKETS_SERVICE_STACK_SIZE
default 8192

endif # NET_SOCKETS_SERVICE

endif # NETWORKING

endif # SOC_MIMX9596_A55
17 changes: 1 addition & 16 deletions boards/nxp/imx95_evk/board.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024 NXP
* Copyright 2024-2025 NXP
* SPDX-License-Identifier: Apache-2.0
*/

Expand All @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions boards/nxp/imx95_evk/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ 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 and A55 platforms.

For A55 Core, NETC depends on GIC ITS, so need to make sure to allocate heap memory to
be larger than 851968 byes by setting CONFIG_HEAP_MEM_POOL_SIZE.

Programming and Debugging (A55)
*******************************
Expand Down
21 changes: 0 additions & 21 deletions boards/nxp/imx95_evk/dts/enetc_psi0.overlay

This file was deleted.

27 changes: 26 additions & 1 deletion boards/nxp/imx95_evk/imx95_evk_mimx9596_a55.dts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,35 @@
};

dram: memory@d0000000 {
reg = <0xd0000000 DT_SIZE_M(1)>;
reg = <0xd0000000 DT_SIZE_M(10)>;
};
};

&emdio {
pinctrl-0 = <&emdio_default>;
pinctrl-names = "default";
status = "okay";

phy0: phy@1 {
compatible = "realtek,rtl8211f";
reg = <0x1>;
status = "okay";
};
};

&enetc_psi0 {
local-mac-address = [00 00 00 01 02 00];
pinctrl-0 = <&eth0_default>;
pinctrl-names = "default";
phy-handle = <&phy0>;
phy-connection-type = "rgmii";
status = "okay";
};

&enetc_ptp_clock {
status = "okay";
};

&lpi2c5 {
pinctrl-0 = <&lpi2c5_default>;
pinctrl-names = "default";
Expand Down
2 changes: 0 additions & 2 deletions boards/nxp/imx95_evk/imx95_evk_mimx9596_a55_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,3 @@ CONFIG_CLOCK_CONTROL=y

CONFIG_MBOX=y
CONFIG_ARM_SCMI=y
CONFIG_INTC_INIT_PRIORITY=2
CONFIG_MBOX_INIT_PRIORITY=3
12 changes: 8 additions & 4 deletions boards/nxp/imx95_evk/imx95_evk_mimx9596_m7.dts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024 NXP
* Copyright 2024-2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -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";
};
};

Expand All @@ -41,7 +41,11 @@
pinctrl-names = "default";
phy-handle = <&phy0>;
phy-connection-type = "rgmii";
status = "disabled";
status = "okay";
};

&enetc_ptp_clock {
status = "okay";
};

&flexspi {
Expand Down
1 change: 1 addition & 0 deletions drivers/ethernet/nxp_imx_netc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
14 changes: 14 additions & 0 deletions drivers/ethernet/nxp_imx_netc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
104 changes: 104 additions & 0 deletions drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT nxp_imx_netc

#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL
#include <zephyr/logging/log.h>
Expand All @@ -21,6 +22,9 @@ LOG_MODULE_REGISTER(nxp_imx_eth);
#include <zephyr/net/phy.h>
#include <ethernet/eth_stats.h>
#include <zephyr/net/dsa_core.h>
#ifdef CONFIG_GIC_V3_ITS
#include <zephyr/drivers/interrupt_controller/gicv3_its.h>
#endif
#include "../eth.h"
#include "eth_nxp_imx_netc_priv.h"

Expand All @@ -29,6 +33,17 @@ LOG_MODULE_REGISTER(nxp_imx_eth);
#define NETC_HAS_NO_SWITCH_TAG_SUPPORT 1
#endif

#define DEV_CFG(_dev) ((const struct eth_nxp_imx_netc_ecam_config *)(_dev)->config)
#define DEV_DATA(_dev) ((struct eth_nxp_imx_netc_ecam_data *)(_dev)->data)

struct eth_nxp_imx_netc_ecam_config {
DEVICE_MMIO_NAMED_ROM(base);
};

struct eth_nxp_imx_netc_ecam_data {
DEVICE_MMIO_NAMED_RAM(base);
};

const struct device *netc_dev_list[NETC_DRV_MAX_INST_SUPPORT];

#ifdef CONFIG_PTP_CLOCK_NXP_NETC
Expand Down Expand Up @@ -173,6 +188,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;
Expand Down Expand Up @@ -203,6 +240,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;
Expand All @@ -222,6 +261,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;
Expand All @@ -235,6 +319,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);
Expand Down Expand Up @@ -456,3 +541,22 @@ int netc_eth_set_config(const struct device *dev, enum ethernet_config_type type

return ret;
}

static int eth_nxp_imx_netc_ecam_init(const struct device *dev)
{
DEVICE_MMIO_NAMED_MAP(dev, base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);

return 0;
}

#define ETH_NXP_IMX_NETC_ECAM_INIT(inst) \
static struct eth_nxp_imx_netc_ecam_data eth_nxp_imx_netc_ecam_data_##inst; \
static const struct eth_nxp_imx_netc_ecam_config eth_nxp_imx_netc_ecam_config_##inst = { \
DEVICE_MMIO_NAMED_ROM_INIT(base, DT_DRV_INST(inst)), \
}; \
DEVICE_DT_INST_DEFINE(inst, eth_nxp_imx_netc_ecam_init, NULL, \
&eth_nxp_imx_netc_ecam_data_##inst, \
&eth_nxp_imx_netc_ecam_config_##inst, POST_KERNEL, \
CONFIG_ETH_INIT_PRIORITY, NULL);

DT_INST_FOREACH_STATUS_OKAY(ETH_NXP_IMX_NETC_ECAM_INIT)
Loading
Loading