Skip to content

Commit 65ca88a

Browse files
committed
drivers: ethernet: imx_netc: add netc block driver
Add NETC block driver, it could do some block memory region MMIO mapping and also so dome block initialization, moved some netc related configuration form board_init() to block driver so that it could be reused between different platforms, although some configuration is different for different platform, but put all NETC related code in the same driver to make it easier to be maintained. Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
1 parent 3308b74 commit 65ca88a

File tree

4 files changed

+223
-16
lines changed

4 files changed

+223
-16
lines changed

boards/nxp/imx95_evk/board.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 NXP
2+
* Copyright 2024-2025 NXP
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -10,21 +10,6 @@
1010

1111
static int board_init(void)
1212
{
13-
#if defined(CONFIG_ETH_NXP_IMX_NETC) && (DT_CHILD_NUM_STATUS_OKAY(DT_NODELABEL(netc)) != 0)
14-
/* Port 0 to 2 protocol configure: RGMII, RGMII, XGMII */
15-
BLK_CTRL_NETCMIX->CFG_LINK_MII_PROT = 0x00000522;
16-
BLK_CTRL_NETCMIX->CFG_LINK_PCS_PROT_2 = 0x00000040;
17-
18-
/* Unlock the IERB. It will warm reset whole NETC. */
19-
NETC_PRIV->NETCRR &= ~NETC_PRIV_NETCRR_LOCK_MASK;
20-
while ((NETC_PRIV->NETCRR & NETC_PRIV_NETCRR_LOCK_MASK) != 0U) {
21-
}
22-
23-
/* Lock the IERB. */
24-
NETC_PRIV->NETCRR |= NETC_PRIV_NETCRR_LOCK_MASK;
25-
while ((NETC_PRIV->NETCSR & NETC_PRIV_NETCSR_STATE_MASK) != 0U) {
26-
}
27-
#endif
2813
return 0;
2914
}
3015

drivers/ethernet/nxp_imx_netc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
if(CONFIG_ETH_NXP_IMX_NETC)
55
zephyr_library_sources(eth_nxp_imx_netc.c)
66
zephyr_library_sources(eth_nxp_imx_netc_psi.c)
7+
zephyr_library_sources_ifdef(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC eth_nxp_imx_netc_blk.c)
78
endif()
89

910
zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c)
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/* NXP NETC Block Controller Driver
2+
*
3+
* Copyright 2025 NXP
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
#define DT_DRV_COMPAT nxp_imx_netc_blk_ctrl
8+
9+
#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL
10+
#include <zephyr/logging/log.h>
11+
LOG_MODULE_REGISTER(nxp_imx_netc_blk);
12+
13+
#include <zephyr/kernel.h>
14+
#include <zephyr/device.h>
15+
16+
/* NETC integrated endpoint register block register */
17+
#define IERB_EMDIOFAUXR 0x344
18+
#define IERB_T0FAUXR 0x444
19+
#define IERB_ETBCR(a) (0x300c + 0x100 * (a))
20+
#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a))
21+
#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a))
22+
23+
/* NETC privileged register block register */
24+
#define PRB_NETCRR 0x100
25+
#define NETCRR_SR BIT(0)
26+
#define NETCRR_LOCK BIT(1)
27+
28+
#define PRB_NETCSR 0x104
29+
#define NETCSR_ERROR BIT(0)
30+
#define NETCSR_STATE BIT(1)
31+
32+
/* NETCMIX CFG Link register */
33+
#define CFG_LINK_MII_PROT 0x10
34+
enum {
35+
MII,
36+
RMII,
37+
RGMII,
38+
reserved,
39+
SGMII,
40+
XGMII,
41+
};
42+
#define CFG_LINK_MII_PROT_0_SHIFT 0
43+
#define CFG_LINK_MII_PROT_1_SHIFT 4
44+
#define CFG_LINK_MII_PROT_2_SHIFT 8
45+
#define MII_PROT_N(prot, n) ((prot) << CFG_LINK_MII_PROT_##n##_SHIFT)
46+
47+
/* NETCMIX PCS protocol register */
48+
#define CFG_LINK_PCS_PROT_0 0x14
49+
#define CFG_LINK_PCS_PROT_1 0x18
50+
#define CFG_LINK_PCS_PROT_2 0x1c
51+
/* PCS Protocols */
52+
#define CFG_LINK_PCS_PROT_1G_SGMII BIT(0)
53+
#define CFG_LINK_PCS_PROT_2500M_SGMII BIT(1)
54+
#define CFG_LINK_PCS_PROT_XFI BIT(3)
55+
#define CFG_LINK_PCS_PROT_10G_SXGMII BIT(6)
56+
57+
struct eth_nxp_imx_netc_blk_config {
58+
DEVICE_MMIO_NAMED_ROM(ierb);
59+
DEVICE_MMIO_NAMED_ROM(prb);
60+
DEVICE_MMIO_NAMED_ROM(netcmix);
61+
};
62+
63+
struct eth_nxp_imx_netc_blk_data {
64+
DEVICE_MMIO_NAMED_RAM(ierb);
65+
DEVICE_MMIO_NAMED_RAM(prb);
66+
DEVICE_MMIO_NAMED_RAM(netcmix);
67+
};
68+
69+
#define DEV_CFG(_dev) ((const struct eth_nxp_imx_netc_blk_config *)(_dev)->config)
70+
#define DEV_DATA(_dev) ((struct eth_nxp_imx_netc_blk_data *)(_dev)->data)
71+
72+
#define read_and_poll_timeout(reg, val, cond) \
73+
({ \
74+
unsigned int count = 1000000; /* 1s! */ \
75+
while (1) { \
76+
(val) = sys_read32(reg); \
77+
if (cond) { \
78+
break; \
79+
} \
80+
count--; \
81+
if (!count) { \
82+
break; \
83+
} \
84+
k_usleep(1); \
85+
} \
86+
(cond) ? 0 : -ETIMEDOUT; \
87+
})
88+
89+
static bool ierb_is_locked(const struct device *dev)
90+
{
91+
uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb);
92+
93+
return sys_read32(base + PRB_NETCRR) & NETCRR_LOCK;
94+
}
95+
96+
static int ierb_lock(const struct device *dev)
97+
{
98+
uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb);
99+
uint32_t val;
100+
101+
sys_write32(NETCRR_LOCK, base + PRB_NETCRR);
102+
103+
return read_and_poll_timeout(base + PRB_NETCSR, val, !(val & NETCSR_STATE));
104+
}
105+
106+
static int ierb_unlock(const struct device *dev)
107+
{
108+
uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, prb);
109+
uint32_t val;
110+
111+
sys_write32(1, base + PRB_NETCRR);
112+
113+
return read_and_poll_timeout(base + PRB_NETCRR, val, !(val & NETCRR_LOCK));
114+
}
115+
116+
#ifdef CONFIG_SOC_MIMX9596
117+
/* Set LDID */
118+
static int ierb_init(const struct device *dev)
119+
{
120+
uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, ierb);
121+
122+
/* EMDIO : No MSI-X interrupt */
123+
sys_write32(0, base + IERB_EMDIOFAUXR);
124+
/* ENETC0 PF */
125+
sys_write32(0, base + IERB_EFAUXR(0));
126+
/* ENETC0 VF0 */
127+
sys_write32(1, base + IERB_VFAUXR(0));
128+
/* ENETC0 VF1 */
129+
sys_write32(2, base + IERB_VFAUXR(1));
130+
/* ENETC1 PF */
131+
sys_write32(3, base + IERB_EFAUXR(1));
132+
/* ENETC1 VF0 : Disabled on 19x19 board dts */
133+
sys_write32(5, base + IERB_VFAUXR(2));
134+
/* ENETC1 VF1 : Disabled on 19x19 board dts */
135+
sys_write32(6, base + IERB_VFAUXR(3));
136+
/* ENETC2 PF */
137+
sys_write32(4, base + IERB_EFAUXR(2));
138+
/* ENETC2 VF0 : Disabled on 15x15 board dts */
139+
sys_write32(5, base + IERB_VFAUXR(4));
140+
/* ENETC2 VF1 : Disabled on 15x15 board dts */
141+
sys_write32(6, base + IERB_VFAUXR(5));
142+
/* NETC TIMER */
143+
sys_write32(7, base + IERB_T0FAUXR);
144+
145+
return 0;
146+
}
147+
148+
static int netcmix_init(const struct device *dev)
149+
{
150+
uintptr_t base = DEVICE_MMIO_NAMED_GET(dev, netcmix);
151+
uint32_t reg_val;
152+
153+
reg_val = MII_PROT_N(RGMII, 0) | MII_PROT_N(RGMII, 1) | MII_PROT_N(XGMII, 2);
154+
sys_write32(reg_val, base + CFG_LINK_MII_PROT);
155+
sys_write32(CFG_LINK_PCS_PROT_10G_SXGMII, base + CFG_LINK_PCS_PROT_2);
156+
157+
return 0;
158+
}
159+
#endif
160+
161+
static int eth_nxp_imx_netc_blk_init(const struct device *dev)
162+
{
163+
int ret;
164+
165+
DEVICE_MMIO_NAMED_MAP(dev, ierb, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
166+
DEVICE_MMIO_NAMED_MAP(dev, prb, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
167+
DEVICE_MMIO_NAMED_MAP(dev, netcmix, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
168+
169+
if (ierb_is_locked(dev)) {
170+
ret = ierb_unlock(dev);
171+
if (ret) {
172+
LOG_ERR("Unlock IERB failed.");
173+
return ret;
174+
}
175+
}
176+
177+
if (ierb_init(dev) != 0) {
178+
LOG_ERR("Failed to initialize IERB");
179+
return -EIO;
180+
}
181+
182+
ret = ierb_lock(dev);
183+
if (ret) {
184+
LOG_ERR("Lock IERB failed.");
185+
return ret;
186+
}
187+
188+
ret = netcmix_init(dev);
189+
if (ret) {
190+
LOG_ERR("NETCMIX init failed.");
191+
return ret;
192+
}
193+
194+
return 0;
195+
}
196+
197+
#define ETH_NXP_IMX_NETC_BLK_INIT(inst) \
198+
static struct eth_nxp_imx_netc_blk_data eth_nxp_imx_netc_blk_data_##inst; \
199+
static const struct eth_nxp_imx_netc_blk_config eth_nxp_imx_netc_blk_config_##inst = { \
200+
DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(ierb, DT_DRV_INST(inst)), \
201+
DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(prb, DT_DRV_INST(inst)), \
202+
DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(netcmix, DT_DRV_INST(inst)), \
203+
}; \
204+
DEVICE_DT_INST_DEFINE(inst, eth_nxp_imx_netc_blk_init, NULL, \
205+
&eth_nxp_imx_netc_blk_data_##inst, \
206+
&eth_nxp_imx_netc_blk_config_##inst, POST_KERNEL, \
207+
CONFIG_MDIO_INIT_PRIORITY, NULL);
208+
209+
DT_INST_FOREACH_STATUS_OKAY(ETH_NXP_IMX_NETC_BLK_INIT)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2025 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: NXP i.MX NETC Block Controller
5+
6+
compatible: "nxp,imx-netc-blk-ctrl"
7+
8+
include: [base.yaml]
9+
10+
properties:
11+
reg:
12+
required: true

0 commit comments

Comments
 (0)