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.

AM6442: Single port network topology DT setup

Part Number: AM6442
Other Parts Discussed in Thread: DP83869, SYSCONFIG

Hi,

I have a couple of questions regarding setting up ethernet on PRU_ICSSG.

I would like to setup the network topology in single port mode using a single dp83869 PHY in fiber mode:

Single Port Mode

In this mode only one of the PRU-ICSS Ethernet ports are used. This is the simplest mode and works as you would expect it to.

The documentation also states:

Limitations

Both MIIx ports have to be enabled in DT even if one of them is not used (no Ethernet PHY wired) for proper PRU_ICSSG Ethernet driver work. Use fixed-link for unused port as workaround

QUESTIONS:

1) How do I setup the device tree to accomplish this? The limitation states that the workaround for using a single MII port is to used fixed link. Does that mean I would use something like the following modification to the DT?

From 1ec7fbf339bbd7d8d99d5769a116cd985b6fcd5f Mon Sep 17 00:00:00 2001
From: jweyer <jweyer@aecontrols.com>
Date: Wed, 14 Jan 2026 16:17:29 -0800
Subject: [PATCH] single port patch

---
 .../boot/dts/ti/k3-am642-phyboard-electra-rdk.dts      | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
index 97ca16f00cd2..e9fb7cbee5b8 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
@@ -281,10 +281,14 @@ icssg1_emac0: port@0 {
 				local-mac-address = [00 00 00 00 00 00];
 			};
 			icssg1_emac1: port@1 {
-				reg = <1>;
-				/* Filled in by bootloader */
+				phy-mode = "rgmii-rxid";
+				syscon-rgmii-delay = <&scm_conf 0x4124>;
 				local-mac-address = [00 00 00 00 00 00];
-				status = "disabled";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
 			};
 		};
 	};
-- 
2.25.1

2) How do I set the PHY type to dp83869? Do I just need to modify the the icssg0_mdio node to let it know what PHY hardware it will be interfacing with? It seems like I would need to do more than this; however, I can't find any examples that do.

From befa78bc09093e58266136b7f111edce0af608e3 Mon Sep 17 00:00:00 2001
From: jweyer <jweyer@aecontrols.com>
Date: Wed, 14 Jan 2026 16:48:24 -0800
Subject: [PATCH] phy type

---
 arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
index e9fb7cbee5b8..866aabc6ee3c 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
@@ -832,6 +832,7 @@ icssg1_phy1: ethernet-phy@f {
 		reg = <0xf>;
 		tx-internal-delay-ps = <250>;
 		rx-internal-delay-ps = <2000>;
+		ti,fifo-depth = <DP83869_PHYCR_FIFO_DEPTH_4_B_NIB>;
 	};
 };
 
-- 
2.25.1

3) It is my understanding that the ti-prueth driver configures the pinmux for MII and that remoteproc uploads the ethernet firmware. I am assuming that sysconfig is used to build the ethernet firmware that is loaded onto the PRUs. If this is the case how does the pinmuxing defined in sysconfig not conflict/overwrite the pinmux setup by ti-prueth?


4) How do I change the DT to configure for fiber mode?

Thanks for your help,

Jared Weyer

  • Hi,

    Any update on this?

    Thanks,

    Jared

  • Hello Jared,

    To confirm, are you actually connecting with MII interface, or with the RGMII interface? RGMII does not require that workaround in the Linux devicetree.

    Please also confirm the version of Linux SDK that you are using.

    Regards,

    Nick

  • Hey Nick,

    I am using Yocto to build Linux, we are using Phytec's fork, version 6.12.8.

    We will be using RGMII, so we will not need to implement the workaround? Below is my best guess on how to accomplish single port fiber ethernet with DP83869 PHY:

    	icssg0_eth: icssg0-eth {
    		compatible = "ti,am642-icssg-prueth";
    		pinctrl-names = "default";
    		pinctrl-0 = <&icssg1_rgmii1_pins_default &icssg1_rgmii2_pins_default>;
    
    		sram = <&oc_sram>;
    		ti,prus = <&pru0_0>, <&rtu0_0>, <&tx_pru0_0>, <&pru0_1>, <&rtu0_1>, <&tx_pru0_1>;
    		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
    
    		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
    				      <2>,
    				      <2>,
    				      <2>,	/* MII mode */
    				      <2>,
    				      <2>;
    
    		ti,mii-g-rt = <&icssg0_mii_g_rt>;
    		ti,mii-rt = <&icssg0_mii_rt>;
    		ti,pa-stats = <&icssg0_pa_stats>;
    		iep = <&icssg0_iep0>;
    
    		interrupt-parent = <&icssg0_intc>;
    		interrupts = <24 0 2>, <25 1 3>;
    		interrupt-names = "tx_ts0", "tx_ts1";
    
    		dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc201 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc202 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc203 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc204 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc205 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc206 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc207 15>, /* egress slice 1 */
    		       <&main_pktdma 0x4200 15>, /* ingress slice 0 */
    		       <&main_pktdma 0x4201 15>, /* ingress slice 1 */
    		       <&main_pktdma 0x4202 0>, /* mgmnt rsp slice 0 */
    		       <&main_pktdma 0x4203 0>; /* mgmnt rsp slice 1 */
    		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
    			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
    			    "rx0", "rx1";
    
    		ethernet-ports {
    			#address-cells = <1>;
    			#size-cells = <0>;
    			icssg0_emac0: port@0 {
    				//status = "disabled"; 
    				reg = <0>;
    				phy-handle = <&icssg0_phy0>;
    				phy-mode = "rgmii-id";
    				ti,syscon-rgmii-delay = <&main_conf 0x4110>;
    				/* Filled in by bootloader */
    				local-mac-address = [00 00 00 00 00 00];
    			};
    		};
    	};
    };
    
    &icssg1_mdio {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&icssg1_mdio1_pins_default>;
    
    	icssg1_phy0: ethernet-phy@0 {
    	    compatible = "ethernet-phy-id2000.a0f1"; /* DP83869 */
    		reg = <0>;
    		tx-internal-delay-ps = <250>;
    		rx-internal-delay-ps = <2000>;		
    		ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>; /* TODO: HOW DO I SET TO FIBER MODE? `ti-dp83869.h` does not contain definition for fiber mode */
    	};
    };



    QUESTIONS:

    1) Does the above DT look correct to you?

    2) I am unsure how to set the ti,op-mode to fiber. `ti-dp83869.h` only has a definition for `DP83869_RGMII_COPPER_ETHERNET`. 

    3) The distinction between cpsw and pru-eth is still slightly unclear to me. Do I need to make any adjustments to the `cpsw3g` node in order to get pru-eth working? Is there any good documentation on the distinction?

    4) I came across this relevant thread that is making me somewhat nervous as it seems to have gone unresolved. Do you know if this issue was resolved elsewhere? Is there any way for me to reopen the issue to ask Chris if he was able to resolve the issue?

    Thanks,

    Jared

    Really appreciate your help Nick.

    Thanks again,

    Jared

  • Hello Jared,

    CPSW vs PRU Ethernet 

    CPSW3G is a group of hardware circuits that implement an Ethernet interface (so this is a hardware peripheral, just like all the other peripherals inside a processor that you are used to interacting with). 3G means there are 3 gigabit Ethernet ports in the CPSW instance: 2 Gigabit Ethernet ports going to the processor pins (this is why you can have up to 2 single EMAC CPSW ports, or a single Ethernet switch with the CPSW), and 1 Gigabit Ethernet port going back to the Linux A53 or R5F core that is controlling the interface.

    Note that this limits total throughput going out of both CPSW ports (or coming into both CPSW ports) to 1 Gigabit total, since they get funneled through a single internal port.

    More information: https://software-dl.ti.com/processor-sdk-linux/esd/AM64X/11_01_05_03/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/Network/CPSW-Ethernet.html

    The PRU subsystem has 6 PRU cores per subsystem, as well as a bunch of accelerators. That is why you see firmware getting loaded to the PRU cores whenever you initialize a PRU Ethernet port. While the MII accelerator, IEP peripheral, etc within the PRU subsystem are hardware circuits, the PRU cores themselves are programmable. That is why the PRU cores can be used to implement standard ethernet, or specialized networking protocols that would normally require an external ASIC.

    Each PRU subsystem can implement 2 Gigabit ethernet endpoints, or 1 gigabit Ethernet switch. Since there are 2 PRU_ICSSG subsystems on AM64x, that means 4 PRU Ethernet ports total are possible.

    More information about standard Linux PRU Ethernet: https://software-dl.ti.com/processor-sdk-linux/esd/AM64X/11_01_05_03/exports/docs/linux/Foundational_Components/PRU-ICSS/Linux_Drivers/PRU_ICSSG_Ethernet.html 

    More information about some of the PRU networking protocols: https://www.ti.com/tool/download/INDUSTRIAL-COMMUNICATIONS-SDK-AM64X 

    Note that Ethernet takes a lot of pins. Due to pinmux limitations, you can only pin out up to 5 of the Ethernet ports in a single design.

    So... can I program the PRU cores myself? 

    Why yes you can, thank you for asking future reader!

    If one of the PRU subsystems is being used for Ethernet, but the other PRU subsystem is free, you can also write your own code on that unused PRU subsystem. We are currently in the process of writing the PRU Academy to guide customers who want to create their own PRU code.

    What is the PRU, and what is the PRU good for?

    AM64x PRU Academy (AM243x academy also has a first draft published, still writing AM62x academy & AM26x academy)

    the OpenPRU repo has example projects that can be used as a starting point

    The PRU Software Support Package continues to be the primary source of example code for older devices like AM335x/AM437x/AM57x, but my goal is to eventually migrate most examples for AM243x/AM62x/AM64x to the OpenPRU repo

    Regards,

    Nick

  • Ok, back to your questions 

    The AM64x EVM only has 3 Ethernet ports on it, but we are able to toggle one of those Ethernet ports between CPSW and PRU Ethernet.

    By default, k3-am642-evm.dts configures the EVM to route 2 of the Ethernet ports to CPSW, and 1 Ethernet port to PRU Ethernet. So you can use this file as an example of how to configure single port RGMII PRU Ethernet.

    Devicetree overlay k3-am642-evm-icssg1-dualemac.dtso changes the configuration to be 1 port to CPSW, 2 ports to PRU Ethernet.

    I am reassigning your thread to another team member to comment on connecting to fiber vs "regular" Ethernet cables.

    Regards,

    Nick

  • For future readers, we have split Jared's followup questions about how PRU Ethernet is set up into a separate thread:
    AM6442: How is PRU Ethernet initialized?

    We will use this thread to continue talking about how to get single port fiber PRU Ethernet working.

    Regards,

    Nick

  • Hello,

    Any update on how to setup the device tree for fiber mode?

    Thanks,

    Jared

  • Hi,

    Stil working on getting pru-eth working in fiber mode. This is my current device tree:

    	qbus {
    		compatible = "ti,am642-icssg-prueth";
    		pinctrl-names = "default";
    		pinctrl-0 = <&icssg0_rgmii1_pins_default>;
    
    		interrupt-parent = <&icssg0_intc>;
    		interrupts = <24 0 2>, <25 1 3>;
    		interrupt-names = "tx_ts0", "tx_ts1";
    
    		sram = <&ethernet_sram>;
    		firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
    				"ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
    
    		dmas = <&main_pktdma 0xc100 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc101 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc102 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc103 15>, /* egress slice 0 */
    		       <&main_pktdma 0xc104 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc105 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc106 15>, /* egress slice 1 */
    		       <&main_pktdma 0xc107 15>, /* egress slice 1 */
    		       <&main_pktdma 0x4100 15>, /* ingress slice 0 */
    		       <&main_pktdma 0x4101 15>; /* ingress slice 1 */
    		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
    			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
    			    "rx0", "rx1";
    
    		ti,prus = <&pru0_0>, <&rtu0_0>, <&tx_pru0_0>, <&pru0_1>, <&rtu0_1>, <&tx_pru0_1>;
    		ti,pruss-gp-mux-sel = <2>,	/* MII mode */
    				      <2>,
    				      <2>,
    				      <2>,	/* MII mode */
    				      <2>,
    				      <2>;
    
    		ti,mii-g-rt = <&icssg0_mii_g_rt>;
    		ti,mii-rt = <&icssg0_mii_rt>;
    		ti,iep = <&icssg0_iep0>, <&icssg0_iep1>;
    
    		ethernet-ports {
    			#address-cells = <1>;
    			#size-cells = <0>;
    			icssg0_emac0: port@0 {
    				reg = <0>;
    				phy-handle = <&icssg0_phy0>;
    				phy-mode = "rgmii-id";
    				/* Filled in by bootloader */
    				local-mac-address = [00 00 00 00 00 00];
    				ti,syscon-rgmii-delay = <&main_conf 0x4100>;
    			};
    		};
    	};
    	
    	/* QBUS MDIO */
    &icssg0_mdio {
    	pinctrl-names = "default";
    	pinctrl-0 = <&icssg0_mdio_pins_default &clkout0_pins_default>;
    	status = "okay";
    
    	icssg0_phy0: ethernet-phy@0 {
    		compatible = "ethernet-phy-id2000.a0f1", "ethernet-phy-ieee802.3-c22";
    		reg = <0x0>;
    		ti,op-mode = <DP83869_RGMII_1000_BASE>;
    		tx-internal-delay-ps = <2000>;
    		rx-internal-delay-ps = <2000>;
    		reset-gpios = <&main_gpio1 18 GPIO_ACTIVE_LOW>;
    		reset-assert-us = <1>; /* DP83869HM TRM TBL 6.6: 720 ns */
    		reset-deassert-us = <30>; /* DP83869HM TRM TBL 6.6: 30 us */
    	};
    };
    
    /* QBUS SFP I2C Comms */
    &main_i2c2 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&i2c2_sfp_pins_default>;
    	clock-frequency = <400000>;
    };
    
    /* QBUS IEP */
    &icssg0_iep0 {
    	status = "okay";
    };
    &icssg0_iep1 {
    	status = "okay";
    };
    

    This seems to work. Linux seems to successfully probe and configure the PHY:
    [    8.190366] icssg-prueth qbus: couldn't get ti,pa-stats syscon regmap
    [    8.262492] icssg-prueth qbus: couldn't get ti,pa-stats syscon regmap
    [    8.274897] icssg-prueth qbus: port 1: using random MAC addr: 7a:19:66:3b:eb:45
    [    8.307144] icssg-prueth qbus: TI PRU ethernet driver initialized: single EMAC mode
    [    8.852705] remoteproc remoteproc9: Booting fw image ti-pruss/am65x-sr2-pru0-prueth-fw.elf, size 39636
    [    8.885449] remoteproc remoteproc12: Booting fw image ti-pruss/am65x-sr2-rtu0-prueth-fw.elf, size 30444
    [    8.913116] remoteproc remoteproc3: Booting fw image ti-pruss/am65x-sr2-txpru0-prueth-fw.elf, size 39080
    

    Also, with `ethtool` I can see that the PHY was configured as per the device tree.

    root@aec-am6442:~# ethtool eth1
    Settings for eth1:
            Supported ports: [ TP    MII     FIBRE ]
            Supported link modes:   10baseT/Full
                                    100baseT/Full
                                    1000baseT/Full
                                    1000baseX/Full
            Supported pause frame use: No
            Supports auto-negotiation: Yes
            Supported FEC modes: Not reported
            Advertised link modes:  10baseT/Full
                                    100baseT/Full
                                    1000baseT/Full
                                    1000baseX/Full
            Advertised pause frame use: No
            Advertised auto-negotiation: Yes
            Advertised FEC modes: Not reported
            Speed: Unknown!
            Duplex: Unknown! (255)
            Auto-negotiation: on
            Port: FIBRE
            PHYAD: 0
            Transceiver: external
            Current message level: 0x00000000 (0)
    
            Link detected: no
    

    However, I cannot read the PHY registers with `phytool`:
    root@aec-am6442:~# phytool read eth1/0/2
    0xffff
    root@aec-am6442:~# phytool read eth1/0/3
    0xffff
    


    QUESTIONS:

    1. Why am I unable to read PHY registers? Obviously Linux is able to communicate with the PHY since `ethtool` is working.

    2. Is there any way that I can turn auto-negotiation off from within the device tree? If not, what is the recommend approach to doing this? Currently I am running `ethtool -s eth1 autoneg off speed 1000 duplex full` manually after boot.

    Thanks for your help,

    Jared

  • Hi Jared,

    I apologize as this thread dropped of my dashboard. Are you still having an issue?

    Best Regards,

    Schuyler