This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi Team,
Environment: J721E EVM, self-compiling SBL boot version
Issue: Eth0 network port exists, but after the IP address is configured, communication with the outside world is not possible.
Troubleshooting:
1) TCP/IP is good: Ifconfig eth0 port exists and TX packets count is increasing when ping packets, 127.0.0.1 can be pinged.
2) Network interface PHY is working properly: J721E EVM and PC are connected via 1000M Ethernet cable, log port has printed eth0: "link becomes ready", and "m65-cpsw-nuss 46000000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx”, link up also can be seen at ethtool eth0.
3) The network transmit DMA should have no problem:
A. Interrupt number registered successfully: In am65_cpsw_nuss_ndev_add_tx_napi function, tx_chn->irq=63; in am65_cpsw_nuss_init_rx_chns function, rx_chn->irq=65.
B. am65_cpsw_nuss_TX_compll_packets function can run, and the delivery looks good with the first res sent in each packet while returning 0 and the second res returning -ENODATA.
Issue:
a. ethtool -S eth0 found tx_good_frames=0. By checking the code of the am65-cpsw-ethtool.c, it was found that tx_good_frames read the register values directly.
b. After ifconfig -a, only two network cards are found, eth0 and lo. No other Virtual cards are found.
c. After sending the packet, the following error message is as follows: "am65-cpsw-nuss 46000000.ethernet eth0: txq:0 DRV_XOFF:0 tmo:482336 dql_avail:-6 free_desc:508"
d. The device tree used by the customer is the k3-j721e-mcu-wakeup.dtsi, the eth0 device tree is as follows:
mcu_cpsw: ethernet@46000000 { compatible = "ti,j721e-cpsw-nuss"; #address-cells = <2>; #size-cells = <2>; reg = <0x0 0x46000000 0x0 0x200000>; reg-names = "cpsw_nuss"; ranges = <0x0 0x0 0x0 0x46000000 0x0 0x200000>; dma-coherent; clocks = <&k3_clks 18 22>; clock-names = "fck"; power-domains = <&k3_pds 18 TI_SCI_PD_EXCLUSIVE>; dmas = <&mcu_udmap 0xf000>, <&mcu_udmap 0xf001>, <&mcu_udmap 0xf002>, <&mcu_udmap 0xf003>, <&mcu_udmap 0xf004>, <&mcu_udmap 0xf005>, <&mcu_udmap 0xf006>, <&mcu_udmap 0xf007>, <&mcu_udmap 0x7000>; dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7", "rx"; ethernet-ports { #address-cells = <1>; #size-cells = <0>; cpsw_port1: port@1 { reg = <1>; ti,mac-only; label = "port1"; ti,syscon-efuse = <&mcu_conf 0x200>; phys = <&phy_gmii_sel 1>; }; }; davinci_mdio: mdio@f00 { compatible = "ti,cpsw-mdio","ti,davinci_mdio"; reg = <0x0 0xf00 0x0 0x100>; #address-cells = <1>; #size-cells = <0>; clocks = <&k3_clks 18 22>; clock-names = "fck"; bus_freq = <1000000>; }; cpts@3d000 { compatible = "ti,am65-cpts"; reg = <0x0 0x3d000 0x0 0x400>; clocks = <&k3_clks 18 2>; clock-names = "cpts"; interrupts-extended = <&gic500 GIC_SPI 858 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "cpts"; ti,cpts-ext-ts-inputs = <4>; ti,cpts-periodic-outputs = <2>; }; };
Could you help check this case? Thanks.
Best Regards,
Cherry
Hi Cherry,
Can you please confirm SBL (optimized boot flow) is used for above? If so, Issue is due to unlocking of CTRLMMR registers.
In case of development boot (SBL) or SPL u-boot is unlocking all CTRLMMR blocks so that Interface selection is reflecting in ENET_CTRL register.
In case of optimized boot flow (SBL), where u-boot is not present and SBL loads Linux image no one is unlocking the CTRL MMR blocks so, interface selection to RGMII from ENET_CTRL is not happening as register is locked. (write will not affect the value in register).
This is the reason where you see interface is still RMII even in device tree interface configured as RGMII.
Fix for above:
Unlock the the CTRLMMR registers in SBL or Linux.
Please refer to below changes and add the patch to <PSDK-RTOS>/pdk/packages/ti/boot/sbl/k3/sbl_main.c, where we are unlocking all CTRLMMR from sbl.
The below changes are for J721S2, Please update relevant registers related to TDA4VM.
+#define WKUP_CTRL_MMR0_BASE 0x43000000 +#define MCU_CTRL_MMR0_BASE 0x40f00000 +#define CTRL_MMR0_BASE 0x00100000 +/* + * The CTRL_MMR0 memory space is divided into several equally-spaced + * partitions, so defining the partition size allows us to determine + * register addresses common to those partitions. +*/ +#define CTRL_MMR0_PARTITION_SIZE 0x4000 +/* + * CTRL_MMR0, WKUP_CTRL_MMR0, and MCU_CTRL_MMR0 lock/kick-mechanism + * shared register definitions. The same registers are also used for + * PADCFG_MMR lock/kick-mechanism. +*/ +#define CTRLMMR_LOCK_KICK0 0x1008 +#define CTRLMMR_LOCK_KICK0_UNLOCK_VAL 0x68ef3490 +#define CTRLMMR_LOCK_KICK1 0x100c +#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL 0xd172bc5a +void CTRL_MMR_unlock(volatile uint32_t baseAddr, uint32_t partition) +{ + /* Get the part base address */ + uint32_t partBaseAddr = baseAddr + (partition * CTRL_MMR0_PARTITION_SIZE); + + /* Unlock the requested partition if locked using two-step sequence */ + *(volatile uint32_t *)(partBaseAddr + CTRLMMR_LOCK_KICK0) = CTRLMMR_LOCK_KICK0_UNLOCK_VAL; + *(volatile uint32_t *)(partBaseAddr + CTRLMMR_LOCK_KICK1) = CTRLMMR_LOCK_KICK1_UNLOCK_VAL; +} + +static void SBL_CTRL_MMR_unlock_all(void) +{ + /* Unlock all WKUP_CTRL_MMR0 module registers */ + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 0); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 1); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 2); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 3); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 4); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 6); + CTRL_MMR_unlock(WKUP_CTRL_MMR0_BASE, 7); + + /* Unlock all MCU_CTRL_MMR0 module registers */ + CTRL_MMR_unlock(MCU_CTRL_MMR0_BASE, 0); + CTRL_MMR_unlock(MCU_CTRL_MMR0_BASE, 1); + CTRL_MMR_unlock(MCU_CTRL_MMR0_BASE, 2); + CTRL_MMR_unlock(MCU_CTRL_MMR0_BASE, 3); + CTRL_MMR_unlock(MCU_CTRL_MMR0_BASE, 4); + + /* Unlock all CTRL_MMR0 module registers */ + CTRL_MMR_unlock(CTRL_MMR0_BASE, 0); + CTRL_MMR_unlock(CTRL_MMR0_BASE, 1); + CTRL_MMR_unlock(CTRL_MMR0_BASE, 2); + CTRL_MMR_unlock(CTRL_MMR0_BASE, 3); + CTRL_MMR_unlock(CTRL_MMR0_BASE, 5); + #if defined(SOC_J721S2) + CTRL_MMR_unlock(CTRL_MMR0_BASE, 6); + #endif + CTRL_MMR_unlock(CTRL_MMR0_BASE, 7); +} int main() { ...... /* Any SoC specific Init. */ SBL_SocEarlyInit(); + /* Unlock control MMR registers */ + SBL_CTRL_MMR_unlock_all(); if (SBL_LOG_LEVEL > SBL_LOG_ERR) { /* Configure UART Tx pinmux. */ Board_uartTxPinmuxConfig(); }