cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
njozwiak
Adventurer
Adventurer
2,062 Views
Registered: ‎10-19-2017

Howto configure Linux device tree for Ethernet with TI DP83867 PHY in SGMII mode

Jump to solution

Hi all,

I have a custom board that I'm trying to get the Ethernet working on. We're running with the 2019.1 tools. We have the Ethernet working in u-boot, but I cannot seem to figure out the magical Linux device tree configuration to get it running in Linux.

I have attached text file with the contents of the board's startup. You will see I halt startup at u-boot and do a ping test out and that is successful... I then continue booting the board and when I get to Linux, there is no eth0 interface.

1. Ethernet in U-Boot

Getting things working from u-boot took a little effort. The ZCU102 and ZCU106 reference designs used RGMII, but due to pin constraints, we implemented SGMII.

After walking through the GEM status and control registers and reading AR#72620 and AR#66592... my functional u-boot device tree ended up being:

/ {
    model = "Board Rev1";
    compatible = "xlnx,zynqmp-zcu106", "xlnx,zynqmp";
    aliases {
        ethernet0 = &gem3;
    ...
};
...

&gem3 {
    status = "okay";
    phy-handle = <&phy0>;
    phy-mode = "sgmii";
    pinctrl-names = "default";
    local-mac-address = [00 0b 35 00 22 01];
    is-internal-pcspma = "true";
    phy0: phy@0 {
        reg = <0x0>;
        compatible = "ti,dp83867";
        ti,fifo-depth = <0x01>;
        ti,dp83867-rxctrl-strap-quirk;
    };
};

With that device tree, everything seems to be working properly, auto-negotiation has completed, we have link, and you can see from the startup log attached I am successfully able to ping to a remote device.

2. Ethernet in Linux

I figured things would be relatively simple for the Linux device tree since it was working in u-boot... There isn't a lot out there for SGMII nodes, but after some reading it looked simple:
- https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841740/Macb+Driver
- https://forums.xilinx.com/t5/Processor-System-Design-and-AXI/Zynq-MP-Ethernet-SGMII-GT-Transceivers/m-p/816087#M22890

But I've had no such luck. My full device tree is attached (devicetree.txt). But the pieces that comprise it are:

// zynqmp.dtsi

gem3: ethernet@ff0e0000 {
    compatible = "cdns,zynqmp-gem", "cdns,gem";
    status = "disabled";
    interrupt-parent = <&gic>;
    interrupts = <0 63 4>, <0 63 4>;
    reg = <0x0 0xff0e0000 0x0 0x1000>;
    clock-names = "pclk", "hclk", "tx_clk";
    #address-cells = <1>;
    #size-cells = <0>;
    #stream-id-cells = <1>;
    iommus = <&smmu 0x877>;
    power-domains = <&zynqmp_firmware 32>;
};

// pcw.dtsi

&gem3 {
    phy-mode = "sgmii";
    status = "okay";
    xlnx,ptp-enet-clock = <0x0>;
};

// board.dtsi (board mods included in our device tree compilation)

&gem3 {
    status = "okay";
    phy-handle = <&phy0>;

    phy0: phy@0 {
        reg = <0x0>;
        xlnx,phy-type = <0x4>;
    };
};

And you will see all of that gets built into the final gem node:

// devicetree.txt (dts file converted to txt for uploading here. this file is a reverse compilation of the dtb file that is loaded during boot.. its everything)

ethernet@ff0e0000 {
    compatible = "cdns,zynqmp-gem", "cdns,gem";
    status = "okay";
    interrupt-parent = <0x4>;
    interrupts = <0x0 0x3f 0x4 0x0 0x3f 0x4>;
    reg = <0x0 0xff0e0000 0x0 0x1000>;
    clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    #stream-id-cells = <0x1>;
    iommus = <0xd 0x877>;
    power-domains = <0xc 0x20>;
    clocks = <0x3 0x1f 0x3 0x6b 0x3 0x30 0x3 0x34 0x3 0x2c>;
    phy-mode = "sgmii";
    xlnx,ptp-enet-clock = <0x0>;
    phy-handle = <0xe>;

    phy@0 {
        reg = <0x0>;
        xlnx,phy-type = <0x4>;
        phandle = <0xe>;
    };
};

 

Any thoughts to troubleshoot what is going wrong? I did try to copy the node verbatim from my u-boot tree, but that didn't appear to have any effect positive or negative.

Why is eth0 not being created for the interface? What is missing from my device tree?

Thanks

0 Kudos
1 Solution

Accepted Solutions
njozwiak
Adventurer
Adventurer
1,929 Views
Registered: ‎10-19-2017

I was able to get this working. I ended up needing to trace through the Linux driver execution. The fundamental problem was the MDIO_DEVICE_FLAG_PHY flag was not being set during initialization because of several things in the device tree.

Here was my final gem node for my Linux device tree:

gem3: ethernet@ff0e0000 {
    compatible = "cdns,zynqmp-gem", "cdns,gem";
    status = "okay";
    interrupt-parent = <&gic>;
    interrupts = <0 63 4>, <0 63 4>;
    reg = <0x0 0xff0e0000 0x0 0x1000>;
    clock-names = "pclk", "hclk", "tx_clk";
    #address-cells = <1>;
    #size-cells = <0>;
    #stream-id-cells = <1>;
    iommus = <&smmu 0x877>;
    power-domains = <&zynqmp_firmware 32>;
    xlnx,ptp-enet-clock = <0x0>;
    phy-handle = <&phy0>;
    phy-mode = "sgmii";

    phy0: phy@0{
        reg = <0>;
        ti,rx-internal-delay = <0x8>;
        ti,tx-internal-delay = <0xa>;
        ti,fifo-depth = <0x1>;
        ti,rxctrl-strap-worka;
    };
};

Note: there is no entry for "is-internal-pcspma". The Linux drivers do not process that property. But that must exist in the u-boot device tree to do initial configuration.

View solution in original post

4 Replies
njozwiak
Adventurer
Adventurer
1,989 Views
Registered: ‎10-19-2017

I just realized I posted this in Hardware Development > Ethernet (or maybe an admin moved it here?). I intended to post it in the Embedded Linux forum. Is this an appropriate forum for this topic or should I delete the thread and recreate in Embedded Linux?

0 Kudos
nanz
Moderator
Moderator
1,976 Views
Registered: ‎08-25-2009

Hi @njozwiak ,

You are correct to put it here as this board is discussing all Ethernet related issues including driver.

About your setup, are you using PS-GTR SGMII? If so, you may need to add "is-internal-pcspma" in your DTS node.


-------------------------------------------------------------------------------------------

Don’t forget to reply, kudo, and accept as solution.

If starting with Versal take a look at our Versal Design Process Hub and our Versal Blogs and our Versal Ethernet Sticky Note.

-------------------------------------------------------------------------------------------
0 Kudos
njozwiak
Adventurer
Adventurer
1,957 Views
Registered: ‎10-19-2017

Hi @nanz 

Thanks for the response. Yes, we are using PS-GTR SGMII. I did try to add is-internal-pcspma and is-internal-pcspma = "true" to my Linux device tree, but neither resolved the problem. My Ethernet device tree node is now:

ethernet@ff0e0000 {
	compatible = "cdns,zynqmp-gem", "cdns,gem";
	status = "okay";
	interrupt-parent = <0x4>;
	interrupts = <0x0 0x3f 0x4 0x0 0x3f 0x4>;
	reg = <0x0 0xff0e0000 0x0 0x1000>;
	clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
	#address-cells = <0x1>;
	#size-cells = <0x0>;
	#stream-id-cells = <0x1>;
	iommus = <0xd 0x877>;
	power-domains = <0xc 0x20>;
	clocks = <0x3 0x1f 0x3 0x6b 0x3 0x30 0x3 0x34 0x3 0x2c>;
	phy-mode = "sgmii";
	xlnx,ptp-enet-clock = <0x0>;
	phy-handle = <0xe>;
	is-internal-pcspma;

	phy@0 {
		reg = <0x0>;
		xlnx,phy-type = <0x4>;
		phandle = <0xe>;
	};
};

Interestingly, I was searching through the Linux source code and didn't find any drivers that attempt to even read is-internal-pcspma from the device tree.. That exists in the u-boot source, but not in Linux?

u-boot-2019.01$ grep -Irn "is-internal-pcspma" *
arch/arm/dts/esa-excalibur-rev1.dts:119:        is-internal-pcspma = "true";
drivers/net/zynq_gem.c:795:     priv->int_pcs = dev_read_bool(dev, "is-internal-pcspma");

 

0 Kudos
njozwiak
Adventurer
Adventurer
1,930 Views
Registered: ‎10-19-2017

I was able to get this working. I ended up needing to trace through the Linux driver execution. The fundamental problem was the MDIO_DEVICE_FLAG_PHY flag was not being set during initialization because of several things in the device tree.

Here was my final gem node for my Linux device tree:

gem3: ethernet@ff0e0000 {
    compatible = "cdns,zynqmp-gem", "cdns,gem";
    status = "okay";
    interrupt-parent = <&gic>;
    interrupts = <0 63 4>, <0 63 4>;
    reg = <0x0 0xff0e0000 0x0 0x1000>;
    clock-names = "pclk", "hclk", "tx_clk";
    #address-cells = <1>;
    #size-cells = <0>;
    #stream-id-cells = <1>;
    iommus = <&smmu 0x877>;
    power-domains = <&zynqmp_firmware 32>;
    xlnx,ptp-enet-clock = <0x0>;
    phy-handle = <&phy0>;
    phy-mode = "sgmii";

    phy0: phy@0{
        reg = <0>;
        ti,rx-internal-delay = <0x8>;
        ti,tx-internal-delay = <0xa>;
        ti,fifo-depth = <0x1>;
        ti,rxctrl-strap-worka;
    };
};

Note: there is no entry for "is-internal-pcspma". The Linux drivers do not process that property. But that must exist in the u-boot device tree to do initial configuration.

View solution in original post