axi_adxcvr driver returns error when trying to configure clock

Hi,

I've gotten my SPI interface to work finally by fixing some verilog but I still get errors when booting Linux. It seems the axi_adxcvr core is trying to enable a clock and it fails with error -5 this and causes the ad9467 driver to throw a -5 error before trying to communicate SPI. When I bypass this error check in the ad9467_probe function the operating system and driver are successfully able to communicate to both of my AD9250 ADCs. Obviously when the driver goes to tell the axi_adxcvr to enable the JESD204B link it fails with a -5 error.  

I've turned on additional debugging in the drivers and I'm noticing the axi_adxcvr driver is trying to set the rate to 2MHz from a fixed 100MHz source.

axi_adxcvr 44a60000.axi_adxcvr: adxcvr_clk_recalc_rate: Parent Rate 100000000 Hz
axi_adxcvr 44a60000.axi_adxcvr: adxcvr_clk_set_rate: Rate 2000000 Hz Parent Rate 100000000 Hz
axi_adxcvr 44a60000.axi_adxcvr: adxcvr_clk_recalc_rate: Parent Rate 100000000 Hz
axi_adxcvr 44a60000.axi_adxcvr: AXI-ADXCVR-RX (16.01.a) using GTX2 at 0x44A60000 mapped to 0xf09a0000. Number of Lanes: 4.

After a bit of time, the ad9467 driver starts and performs the probe function and throws the error -5 when it tries to call the function clk_prepare_enable(clk) which is calling the adxcvr_clk_enable function in the axi_adxcvr driver.

The axi_adxcvr driver does throw an error before returning control to the ad9467 driver:

axi_adxcvr 44a60000.axi_adxcvr: adxcvr_clk_enable: RX
axi_adxcvr 44a60000.axi_adxcvr: RX Error: 0

I now know the 0 is the link status from the status register in the axi_adxcvr core. It should be 1 but that is not the case.

Let me also provide my current device tree just in case the error is there:

/ {

	clocks {
		clk_bus_0: clock@0 {
			compatible = "fixed-clock";
			clock-frequency = <100000000>;
			clock-output-names = "s_axi_aclk_100M";
			#clock-cells = <0>;
		};
	};

};


&axi_ad9250_0_dma {
	compatible = "adi,axi-dmac-1.00.a";
	reg = <0x7c420000 0x10000>;
	#dma-cells = <1>;
	interrupts = <0 57 0>;
	clocks = <&clk_bus_0>;

	adi,channels {
		#address-cells = <1>;
		#size-cells = <0>;
	
		dma-channel@0 {
			reg = <0>;
			adi,source-bus-width = <64>;
			adi,source-bus-type = <2>;
			adi,destination-bus-width = <64>;
			adi,destination-bus-type = <0>;
		};
	};

};


&axi_ad9250_1_dma {
	compatible = "adi,axi-dmac-1.00.a";
	reg = <0x7c430000 0x10000>;
	#dma-cells = <1>;
	interrupts = <0 57 0>;
	clocks = <&clk_bus_0>;

	adi,channels {
		#address-cells = <1>;
		#size-cells = <0>;
	
		dma-channel@0 {
			reg = <0>;
			adi,source-bus-width = <64>;
			adi,source-bus-type = <2>;
			adi,destination-bus-width = <64>;
			adi,destination-bus-type = <0>;
		};
	};

};


&spi0 {
	compatible = "xlnx,zynq-spi-r1p6";
	reg = <0xe0006000 0x1000>;
	status = "okay";
	num-cs = <3>;
	#address-cells = <1>;
	#size-cells = <0>;
	
	adc0_ad9250: ad9250-0@0 {
		compatible = "adi,ad9250";
		reg = <0>;
		spi-max-frequency = <10000000>;
		clocks = <&axi_jesd204_rx_0>, <&clk_bus_0>;
		clock-names = "jesd_adc_clk", "adc_clk";
	};
	
	adc1_ad9250: ad9250-1@1 {
		compatible = "adi,ad9250";
		reg = <1>;
		spi-max-frequency = <10000000>;
		clocks = <&axi_jesd204_rx_0>, <&clk_bus_0>;
		clock-names = "jesd_adc_clk", "adc_clk";
	};
};


&axi_ad9250_0 {
	compatible = "xlnx,axi-ad9250-1.00.a";
	reg = <0x44a1000 0x10000>;
	status = "okay";
	dmas = <&axi_ad9250_0_dma>;
	dma-names = "rx";
	spibus-connected = <adc0_ad9250>;
};

&axi_ad9250_1 {
	compatible = "xlnx,axi-ad9250-1.00.a";
	reg = <0x44a2000 0x10000>;
	status = "okay";
	dmas = <&axi_ad9250_1_dma>;
	dma-names = "rx";
	spibus-connected = <adc1_ad9250>;
};

&axi_jesd204_rx_0 {
	compatible = "adi,axi-jesd204-rx-1.0";
	reg = <0x44aa0000 0x1000>;

	interrupts = <0 55 0>;

	clocks = <&clk_bus_0>, <&axi_adxcvr_0 1>, <&axi_adxcvr_0 0>;
	clock_names = "s_axi_aclk", "device_clk", "lane_clk";

	#clock-cells = <0>;
	clock-output-names = "jesd_adc_lane_clk";

	adi,octets-per-frame = <2>;
	adi,frames-per-multiframe = <32>;
};


&axi_adxcvr {
	compatible = "adi,axi-adxcvr-1.0";
	reg = <0x44a60000 0x1000>;

	clocks = <&clk_bus_0>;
	clock-names = "conv";

	#clock-cells = <1>;
	clock-output-names = "adc_gt_clk", "rx_out_clk";

	adi,sys-clk-select = <0>;
	adi,out-clk-select = <2>;
	adi,use-cpll-enable;
};


&gpio0 {
    sysref-enable {
        gpio-hog;
        gpios = <86 6>;
        output-high;
        line-name = "sysref-enable";
    };
};

Unfortunately I don't know what could be causing this issue except that the axi_adxcvr doesn't like fixed clocks. The 100 MHz clock I am using feeds into the gbt clock inputs of my GTX2 quads. It is also the clock that goes into a clocking wizard of my Zynq fabric and the clock also goes into the clock input of both of my AD9250 ADCs. The clock source is appropriately distributed using an ADCLK944 fanout buffer. The GTX2 gbtclk signals get this clock after it goes through a AD9515 clock divider which is currently set to not divide or delay the clock and just give the full 100 MHz frequency.

Any suggestions? I'm getting to the point to ask my lead to just make a new board with a AD9517 like the fmcjesdadc1 reference is configured.

  • 0
    •  Analog Employees 
    on Feb 22, 2019 10:01 AM over 2 years ago

    What kernel (branch) are you using?

    The XCVR typically consumes two clocks. The GT reference and an optional lanerate div40 link clock.

    We typical provide this clock via a clock chip or an MMCN. If out_clk_sel = 2, this can be avoided and the recovery clocked from the deserializer is used instead.

    I would add more debug prints into the XCVR driver to see what exactly is going on with your fixed clock.

    -Michael 

  • I am using release 2018_R2 from the Analog Devices github repo and building that kernel with Petalinux 2018.2.

    I have not seen any print messages about the div40 link clock, in fact it seems the adxcvr_work_func() function does not get called at all. Nothing else from the adxcvr or xilinx_transceiver driver seems to jump out at me as an issue.

    Is it safe to assume the rate of 2,000,000 Hz in the debug print out incorrect and is supposed to be 2,000,000 kbps which is a 2Gbps lane rate? I also printed the terms that are calculated for N1, N2, M and D are 5, 2, 1, and 1 respectively. Using those terms and the transceiver math from UG476 I get a CPLL frequency of 1GHz and rate of 2Gbps.

  • 0
    •  Analog Employees 
    on Feb 28, 2019 9:19 AM over 2 years ago in reply to asm2750

    The linux common clock framework on 32-bit systems only handles rates up to 2^32.

    So we decided that lane rates are always scaled in kHz rather than Hz.

    -Michael

  • Found my issue looks like a clock buffer chip was not being configured correctly. I get a message now that says:

    ad9467 spi1.0: AD9250 PLL LOCKED, JESD204B Link Ready
    ad9467 spi1.1: AD9250 PLL LOCKED, JESD204B Link Ready

    Now to figure out how to get both devices to show up as an iio device. Currently all I see is the iio entry for XADC. I'll make that a different forum post if I get stuck.

    Thanks for the help.