Problem in AD7768-1 Zedboard Linux setup

Hello Everyone and Good day.

I'm currently trying to bring-up the EVAL-AD7768-1 FMC board in my Zedboard, and so I used the reference design from ADI here.  Both hdl and meta-adi repositories are used for this.  There is an existing .dts file for ad77681evb and so I used it, I just created a pl-delete-nodes-* version of it, placed it on meta-adi-xilinx device tree file folder, and updated the device tree bbappend file to include that pl-delete-nodes-* dtsi file.

I also added a line that inserts carriage return in device tree bbappend, since without it, system-top.dts last line is like " };#include "system-user.dtsi" " and it is causing device tree compile to fail.  By making the change, the #include "system-user.dtsi" is placed on a new line and the compilation succeeds.

After building and booting, I always encounter this error during boot:

spi_master spi0: Timeout occured while waiting for transfer to complete. Hardware is probably broken.
ad7768-1 spi0.0: AD7768 setup failed
ad7768-1 spi0.0: Dropping the link to regulator.2
ad7768-1: probe of spi0.0 failed with error -110

It seems the axi spi engine is not loading properly, and it is causing the loading of the ad7768-1 driver to fail since it is a child node of the axi spi engine in the device tree.

As added detail, the ad7768-1 has no sysfs entry, but the axi spi engine has one:

root@ad77681evb_p2019_1:/sys/class/spi_master/spi0# ls -l
lrwxrwxrwx    1 root     root             0 Aug  9 02:11 device -> ../../../44a00000.axi-spi-engine
lrwxrwxrwx    1 root     root             0 Aug  9 02:11 of_node -> ../../../../../../firmware/devicetree/base/fpga-axi@0/axi-spi-engine@0x44a00000
drwxr-xr-x    2 root     root             0 Aug  9 02:11 power
drwxr-xr-x    4 root     root             0 Jan  1  1970 spi0.0
drwxr-xr-x    2 root     root             0 Aug  9 02:11 statistics
lrwxrwxrwx    1 root     root             0 Aug  9 02:11 subsystem -> ../../../../../../class/spi_master
-rw-r--r--    1 root     root          4096 Jan  1  1970 uevent

This is in meta-adi 2020.1 and adi hdl master.

I tried to set this up in 2019_R2 (hdl_2019_r2 and meta-adi-2019-R2), installed Vivado Webpack for this version as well the corresponding petalinux, but this error still happens.  So in my case, both 2020.1 and 2019.1 versions of the ad77681evb reference designs are failing during boot.

Can anyone advise me on where did I go wrong?  I followed the exact procedures in the README files (with some changes that I think I specified above) but this always happen.  I thought by going to 2019_R2 this will solve things but I was wrong.

  • Hello,

    Can you do a memory read (with memtool or devmem) at 0x44a70000?

    There may be a chance that the clock provider for the spi engine is being hold in reset.

    Sergiu

  • Thanks  for responding to my desperate plea.

    After using devmem 0x44a70000, the result I got is as follows:

    root@ad77681evb_p2019_1:~# devmem 0x44a70000
    0x00050063

    root@ad77681evb_p2019_1:~# devmem 0x44a70040
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a70044
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a7005c
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a70070
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a70074
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a7000c
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a70010
    0x00000000

    root@ad77681evb_p2019_1:~# devmem 0x44a7001c
    0x01040A0E

    What do these values tell us?  

    Also, your suggestion about this 0x44a70000 register address had me thinking.  I'm using the existing zynq-zed-adv7511-ad7768-1-evb.dts in meta-adi-linux kernel but it has no corresponding pl-delete-nodes* dtsi.  I noticed this 0x44a70000 address is from the spi_clkgen entry of the pl.dtsi which, I included in the pl-delete-nodes-zynq-zed-adv7511-ad7768-1-evb.dtsi that I created and included in meta-adi device tree file folders as well as in the .bbappend file.  This is because I followed an ez.analog thread on how to support unsupported boards, and the thread said that all entries' aliases in the resulting pl.dtsi has to be included in the pl-delete-nodes-* dtsi file.

    Here is the link I followed:

    https://ez.analog.com/linux-software-drivers/f/q-a/168039/meta-adi-with-custom-board?ReplySortBy=CreatedDate&ReplySortOrder=Ascending

    I'm worried that I may have unknowingly excluded other necessary components from the pl.dtsi like spi-clkgen and others into the final device tree blob.  Is there a set of rules to follow when creating the pl-delete-nodes?

    There's another thing that I observed hopefully this can be a clue.  There is no spi engine interrupt that occurred here, in contrast to ad4020 where an spi engine interrupt occurred and whose probe succeeded.  Both ad7768-1 and ad4020 uses spi-axi-engine though.  With no spi engine interrupt occurring, the spi message (during AD7768-1 probe) timed out.

  • Hi 

    I want to post my device tree files here in case you want to check them out:

    pl.dtsi

    / {
        amba_pl: amba_pl {
            #address-cells = <1>;
            #size-cells = <1>;
            compatible = "simple-bus";
            ranges ;
            axi_ad77681_dma: axi_dmac@44a30000 {
                clock-names = "s_axi_aclk", "m_dest_axi_aclk", "s_axis_aclk";
                clocks = <&clkc 15>, <&clkc 15>, <&misc_clk_0>;
                compatible = "xlnx,axi-dmac-1.0";
                interrupt-names = "irq";
                interrupt-parent = <&intc>;
                interrupts = <0 31 4>;
                reg = <0x44a30000 0x1000>;
            };
            misc_clk_0: misc_clk_0 {
                #clock-cells = <0>;
                clock-frequency = <80000000>;
                compatible = "fixed-clock";
            };
            axi_hdmi_clkgen: axi_clkgen@79000000 {
                clock-names = "clk", "s_axi_aclk";
                clocks = <&clkc 16>, <&clkc 15>;
                compatible = "xlnx,axi-clkgen-1.0";
                reg = <0x79000000 0x10000>;
            };
            axi_hdmi_core: axi_hdmi_tx@70e00000 {
                clock-names = "hdmi_clk", "vdma_clk", "s_axi_aclk";
                clocks = <&misc_clk_1>, <&clkc 15>, <&clkc 15>;
                compatible = "xlnx,axi-hdmi-tx-1.0";
                reg = <0x70e00000 0x10000>;
            };
            misc_clk_1: misc_clk_1 {
                #clock-cells = <0>;
                clock-frequency = <148484848>;
                compatible = "fixed-clock";
            };
            axi_hdmi_dma: axi_dmac@43000000 {
                clock-names = "s_axi_aclk", "m_src_axi_aclk", "m_axis_aclk";
                clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>;
                compatible = "xlnx,axi-dmac-1.0";
                interrupt-names = "irq";
                interrupt-parent = <&intc>;
                interrupts = <0 29 4>;
                reg = <0x43000000 0x1000>;
            };
            axi_i2s_adi: axi_i2s_adi@77600000 {
                clock-names = "data_clk_i", "dma_req_tx_aclk", "dma_req_rx_aclk", "s_axi_aclk";
                clocks = <&misc_clk_2>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
                compatible = "xlnx,axi-i2s-adi-1.0";
                reg = <0x77600000 0x10000>;
            };
            misc_clk_2: misc_clk_2 {
                #clock-cells = <0>;
                clock-frequency = <12287988>;
                compatible = "fixed-clock";
            };
            axi_iic_fmc: i2c@41620000 {
                #address-cells = <1>;
                #size-cells = <0>;
                clock-names = "s_axi_aclk";
                clocks = <&clkc 15>;
                compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a";
                reg = <0x41620000 0x1000>;
            };
            axi_iic_main: i2c@41600000 {
                #address-cells = <1>;
                #size-cells = <0>;
                clock-names = "s_axi_aclk";
                clocks = <&clkc 15>;
                compatible = "xlnx,axi-iic-2.0", "xlnx,xps-iic-2.00.a";
                interrupt-names = "iic2intc_irpt";
                interrupt-parent = <&intc>;
                interrupts = <0 30 4>;
                reg = <0x41600000 0x1000>;
            };
            axi_spdif_tx_core: axi_spdif_tx@75c00000 {
                clock-names = "spdif_data_clk", "s_axi_aclk", "dma_req_aclk";
                clocks = <&misc_clk_2>, <&clkc 15>, <&clkc 15>;
                compatible = "xlnx,axi-spdif-tx-1.0";
                reg = <0x75c00000 0x10000>;
            };
            axi_sysid_0: axi_sysid@45000000 {
                clock-names = "s_axi_aclk";
                clocks = <&clkc 15>;
                compatible = "xlnx,axi-sysid-1.0";
                reg = <0x45000000 0x10000>;
            };
            spi_adc_axi_regmap: axi_spi_engine@44a00000 {
                clock-names = "s_axi_aclk", "spi_clk";
                clocks = <&clkc 15>, <&misc_clk_0>;
                compatible = "xlnx,axi-spi-engine-1.0";
                reg = <0x44a00000 0x10000>;
            };
            spi_clkgen: axi_clkgen@44a70000 {
                clock-names = "clk", "s_axi_aclk";
                clocks = <&clkc 15>, <&clkc 15>;
                compatible = "xlnx,axi-clkgen-1.0";
                reg = <0x44a70000 0x10000>;
            };
        };
    };
    /include/ "pl-delete-nodes-zynq-zed-adv7511-ad7768-1-evb.dtsi"

    pl-delete-nodes-zynq-zed-adv7511-ad7768-1-evb.dtsi (I created this)

    /*Delete nodes from pl.dtsi which are redefined in ADI dts*/
    /delete-node/ &axi_ad77681_dma;
    /delete-node/ &misc_clk_0;
    /delete-node/ &axi_hdmi_clkgen;
    /delete-node/ &axi_hdmi_core;
    /delete-node/ &misc_clk_1;
    /delete-node/ &axi_hdmi_dma;
    /delete-node/ &axi_i2s_adi;
    /delete-node/ &misc_clk_2;
    /delete-node/ &axi_iic_fmc;
    /delete-node/ &axi_iic_main;
    /delete-node/ &axi_spdif_tx_core;
    /delete-node/ &axi_sysid_0;
    /delete-node/ &spi_adc_axi_regmap;
    /delete-node/ &spi_clkgen;

    zynq-zed-adv7511-ad7768-1-evb.dts (default version from the meta-adi linux kernel; no changes were done to it from my side)

    /dts-v1/;

    #include "zynq-zed.dtsi"
    #include "zynq-zed-adv7511.dtsi"
    #include <dt-bindings/interrupt-controller/irq.h>
    #include <dt-bindings/gpio/gpio.h>

    / {
        vref: regulator-vref {
            compatible = "regulator-fixed";
            regulator-name = "fixed-supply";
            regulator-min-microvolt = <4096000>;
            regulator-max-microvolt = <4096000>;
            regulator-always-on;
        };

        clocks {
            ad7768_1_mclk: clock@0 {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <16384000>;
            };
        };
    };

    &fpga_axi {
        rx_dma: rx-dmac@0x44a30000 {
            compatible = "adi,axi-dmac-1.00.a";
            reg = <0x44a30000 0x10000>;
            #dma-cells = <1>;
            interrupt-parent = <&intc>;
            interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&clkc 16>;

            adi,channels {
                #size-cells = <0>;
                #address-cells = <1>;

                dma-channel@0 {
                    reg = <0>;
                    adi,source-bus-width = <32>;
                    adi,source-bus-type = <1>;
                    adi,destination-bus-width = <64>;
                    adi,destination-bus-type = <0>;
                };
            };
        };

        axi_spi_engine_0: axi-spi-engine@0x44a00000 {
            compatible = "adi,axi-spi-engine-1.00.a";
            reg = <0x44a00000 0x1000>;
            interrupt-parent = <&intc>;
            interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&clkc 15 &clkc 15>;
            clock-names = "s_axi_aclk", "spi_clk";
            num-cs = <1>;

            #address-cells = <0x1>;
            #size-cells = <0x0>;

            ad7768_1: adc@0 {
                compatible = "adi,ad7768-1";
                reg = <0>;
                spi-max-frequency = <20000000>;
                spi-cpol;
                spi-cpha;
                vref-supply = <&vref>;
                adi,sync-in-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>;
                reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
                clocks = <&ad7768_1_mclk>;
                clock-names = "mclk";
                dmas = <&rx_dma 0>;
                dma-names = "rx";
                #io-channel-cells = <1>;
            };
        };
    };

  • Looks like I've solved this.

    I changed the default device tree from this

        axi_spi_engine_0: axi-spi-engine@0x44a00000 {
            compatible = "adi,axi-spi-engine-1.00.a";
            reg = <0x44a00000 0x1000>;
            interrupt-parent = <&intc>;
            interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&clkc 15 &clkc 15>;
            clock-names = "s_axi_aclk", "spi_clk";
            num-cs = <1>;
    
            #address-cells = <0x1>;
            #size-cells = <0x0>;
    

    to this:

        axi_spi_engine_0: axi-spi-engine@0x44a00000 {
            compatible = "adi,axi-spi-engine-1.00.a";
            reg = <0x44a00000 0x1000>;
            interrupt-parent = <&intc>;
            interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>;
            clocks = <&clkc 15 &spi_clk>;
            clock-names = "s_axi_aclk", "spi_clk";
            num-cs = <1>;
    
            #address-cells = <0x1>;
            #size-cells = <0x0>;
    

    Because from the Vivado HDL block diagram, the spi clk input for the axi-spi-engine comes from an axi-clkgen, and not the same as fclk0 which is the input for s_axi_aclk of the spi engine.  Of course, I also have to add the clkgen node under the fpga_axi phandle:

    	spi_clk: axi-clkgen@0x44a70000 {
    		compatible = "adi,axi-clkgen-2.00.a";
    		reg = <0x44a70000 0x10000>;
    		#clock-cells = <0>;
    		clocks = <&clkc 15>, <&clkc 15>;
    		clock-names = "s_axi_aclk", "clkin1";
    		clock-output-names = "spi_clk";
    

    Afterwards, the probe function for AD7768-1 is succeeding now.  Registers in 0x44a70000 seems to indicate clocks are no longer stuck in reset.