ADRV9009-ZU11EG SOM clocking network changes for Tx/OBS and Rx core clocks

Hello,

I would like to change the core clock rates for the ADRV9009-ZU11EG SOM reference design. I want to make the changes in the device tree, but I am running into some difficulties understanding the system clocking tree and required dependencies for my planned changes.

The changes I would like to make are to drive both the Tx/OBS and Rx device clocks (core_clk_a/b) at an integer rate, in this case 200MHz. I found this guide that walks through some of the clocking considerations, but not for the HMC7044/ADRV9009-ZU11EG SOM specifically. Additionally, I refer to the System Clocking Tree Diagram for my planning.

In my device tree (snippet posted below), the HMC7044 SOM entry has channels 6 and 7 that are labeled "CORE_CLK_TX_OBS_AB" and "CORE_CLK_RX_AB" (and associated attributes). The HMC7044 SOM attribute "adi,pll2-output-frequency" is important as well, since that frequency value is what is divided by the "adi,divider" value.

Here's an example of what I am having trouble understanding:

Let's say I change the "adi,pll2-output-frequency" value from 2.94912GHz to 3.0GHz. The "adi,divider" values for the Tx/OBS and Rx core clocks need to be 15 (0xf) so that the clocks are now divided down to 200MHz.

Changing the core clocks will change the data rate in the FPGA, so I also need to update the JESD clocks and ADRV9009 device and sysref clocks accordingly. Based on the JESD LMN'S parameters, I can use the equation Lane Rate = (M x S x N' x 10/8 x FC)/L to solve for the lane rate and use Device Clk = Lane Rate/40 to figure out the needed device clock value.

This is where I start to get lost. I want to use an external reference clock at 100MHz and bypass the 122.88MHz VCXO . Looking at the Clocking Tree image, the HMC7044 chip generating the core clocks is local to the SOM and takes inputs from the Carrier HMC7044 chip. The only viable reference clock input I see is from the "Ref_p" SMA connector to the Carrier HMC7044 chip. Then I would output 100MHz clock to the SOM via the "OSCIN" connection. Going to the device tree, I don't see any entries that pop out at as a bypass enable for either the SOM or Carrier HMC7044. For example, in the guide for changing the RF transceiver profile, the AD9528 example entry has an "adi,pll1-bypass-enable/disable" setting to use a ref clock.

This leads me to my first series of questions: (1) How can I use an external reference clock and bypass the VCXO for both the carrier and SOM HMC7044s? (2) Is this possible, preferably with device tree changes? (3) Or should I seriously consider changing the VCXO onboard and make the device tree changes?

My second series of questions relate to the system clocking tree in general: (4) What other clocking dependencies do I need to think about? I can see a number of clocks in the HDL design that I haven't recognized in the device tree. (5) Is there a more centralized source of information regarding the clocking tree and clocking dependencies?

My last question pertains to the ADRV9009 device tree entries specifically: I can use the ADRV9009 Profile Generator to create FIR coefficients for my desired setup. If I convert these to array format and use them in the device tree, will this cause any problems?

 

Does this approach seem viable (external reference clock)? Is there a better way to go about the device tree changes? I appreciate any and all insight into a solution.

Thank you for the assistance,

-Samual

hmc7044@0 {
				#address-cells = <0x1>;
				#size-cells = <0x0>;
				#clock-cells = <0x1>;
				compatible = "adi,hmc7044";
				reg = <0x2>;
				spi-max-frequency = <0x989680>;
				adi,pll1-clkin-frequencies = <0x7530000 0x7530000 0x0 0x0>;
				adi,pll1-ref-prio-ctrl = <0xe5>;
				adi,clkin0-buffer-mode = <0x9>;
				adi,clkin1-buffer-mode = <0x9>;
				adi,sync-pin-mode = <0x1>;
				adi,pll1-loop-bandwidth-hz = <0xc8>;
				adi,vcxo-frequency = <0x7530000>;
				adi,pll2-output-frequency = <0xafc80000>;
				adi,sysref-timer-divider = <0xf00>;
				adi,pulse-generator-mode = <0x7>;
				adi,oscin-buffer-mode = <0x15>;
				adi,gpi-controls = <0x0 0x0 0x0 0x11>;
				adi,gpo-controls = <0x1f 0x2b 0x0 0x0>;
				adi,high-performance-mode-clock-dist-enable;
				adi,high-performance-mode-pll-vco-enable;
				clock-output-names = "hmc7044_out0_DEV_REFCLK_A", "hmc7044_out1_DEV_SYSREF_A", "hmc7044_out2_DEV_REFCLK_B", "hmc7044_out3_DEV_SYSREF_B", "hmc7044_out4_JESD_REFCLK_TX_OBS_AB", "hmc7044_out5_JESD_REFCLK_RX_AB", "hmc7044_out6_CORE_CLK_TX_OBS_AB", "hmc7044_out7_CORE_CLK_RX_AB", "hmc7044_out8_FPGA_SYSREF_TX_OBS_AB", "hmc7044_out9_FPGA_SYSREF_RX_AB", "hmc7044_out10", "hmc7044_out11", "hmc7044_out12", "hmc7044_out13";
				clocks = <0x2d 0x2>;
				clock-names = "clkin1";
				linux,phandle = <0x2c>;
				phandle = <0x2c>;

				channel@0 {
					reg = <0x0>;
					adi,extended-name = "DEV_REFCLK_A";
					adi,divider = <0xc>;
					adi,driver-mode = <0x2>;
					adi,coarse-digital-delay = <0xf>;
				};

				channel@1 {
					reg = <0x1>;
					adi,extended-name = "DEV_SYSREF_A";
					adi,divider = <0xf00>;
					adi,driver-mode = <0x2>;
					adi,startup-mode-dynamic-enable;
					adi,high-performance-mode-disable;
					adi,driver-impedance-mode = <0x1>;
				};

				channel@2 {
					reg = <0x2>;
					adi,extended-name = "DEV_REFCLK_B";
					adi,divider = <0xc>;
					adi,driver-mode = <0x2>;
					adi,coarse-digital-delay = <0xf>;
				};

				channel@3 {
					reg = <0x3>;
					adi,extended-name = "DEV_SYSREF_B";
					adi,divider = <0xf00>;
					adi,driver-mode = <0x2>;
					adi,startup-mode-dynamic-enable;
					adi,high-performance-mode-disable;
					adi,driver-impedance-mode = <0x1>;
				};

				channel@4 {
					reg = <0x4>;
					adi,extended-name = "JESD_REFCLK_TX_OBS_AB";
					adi,divider = <0xc>;
					adi,driver-mode = <0x1>;
				};

				channel@5 {
					reg = <0x5>;
					adi,extended-name = "JESD_REFCLK_RX_AB";
					adi,divider = <0xc>;
					adi,driver-mode = <0x1>;
				};

				channel@6 {
					reg = <0x6>;
					adi,extended-name = "CORE_CLK_TX_OBS_AB";
					adi,divider = <0x18>;
					adi,driver-mode = <0x2>;
				};

				channel@7 {
					reg = <0x7>;
					adi,extended-name = "CORE_CLK_RX_AB";
					adi,divider = <0xc>;
					adi,driver-mode = <0x2>;
				};

				channel@8 {
					reg = <0x8>;
					adi,extended-name = "FPGA_SYSREF_TX_OBS_AB";
					adi,divider = <0xf00>;
					adi,driver-mode = <0x2>;
					adi,startup-mode-dynamic-enable;
					adi,high-performance-mode-disable;
				};

				channel@9 {
					reg = <0x9>;
					adi,extended-name = "FPGA_SYSREF_RX_AB";
					adi,divider = <0xf00>;
					adi,driver-mode = <0x2>;
					adi,startup-mode-dynamic-enable;
					adi,high-performance-mode-disable;
				};
			};

			hmc7044-car@3 {
				#address-cells = <0x1>;
				#size-cells = <0x0>;
				#clock-cells = <0x1>;
				compatible = "adi,hmc7044";
				reg = <0x3>;
				spi-max-frequency = <0x989680>;
				adi,pll1-clkin-frequencies = <0x0 0x7530000 0x0 0x124f800>;
				adi,pll1-loop-bandwidth-hz = <0xc8>;
				adi,vcxo-frequency = <0x7530000>;
				adi,pll2-output-frequency = <0xafc80000>;
				adi,sysref-timer-divider = <0xf00>;
				adi,pulse-generator-mode = <0x1>;
				adi,oscin-buffer-mode = <0x15>;
				adi,clkin1-buffer-mode = <0x9>;
				adi,clkin3-buffer-mode = <0x11>;
				adi,sync-pin-mode = <0x1>;
				adi,gpi-controls = <0x0 0x0 0x0 0x11>;
				adi,gpo-controls = <0x1f 0x2b 0x0 0x0>;
				clock-output-names = "hmc7044_c_out0_REFCLK_OUT0", "hmc7044_c_out1", "hmc7044_c_out2_REFCLK_OUT2", "hmc7044_c_out3", "hmc7044_c_out4", "hmc7044_c_out5_SYNC_OUT1", "hmc7044_c_out6_SYNC_OUT2", "hmc7044_c_out7", "hmc7044_c_out8_REFCLK_OUT3", "hmc7044_c_out9_REFCLK_OUT4", "hmc7044_c_out10_REFCLK_QSFP", "hmc7044_c_out11_REFCLK_SFP", "hmc7044_c_out12", "hmc7044_c_out13";
				linux,phandle = <0x2d>;
				phandle = <0x2d>;

				channel@2 {
					reg = <0x2>;
					adi,extended-name = "REFCLK_OUT2";
					adi,divider = <0x18>;
					adi,driver-mode = <0x1>;
				};

				channel@5 {
					reg = <0x5>;
					adi,extended-name = "SYNC_OUT1";
					adi,divider = <0xf00>;
					adi,driver-mode = <0x3>;
					adi,startup-mode-dynamic-enable;
					adi,high-performance-mode-disable;
					adi,driver-impedance-mode = <0x3>;
				};
			};
		};



Edit: Forgot to add the device tree snippet
[edited by: Samual at 2:30 PM (GMT 0) on 25 Mar 2020]
Parents Reply
  • +1
    •  Analog Employees 
    on Mar 30, 2020 8:27 AM in reply to Samual
    And there's no similar functionality for the SOM with the REF_CLK_P to reconfigure PLL2 to support something like 3GHz or similar based on how I understand your answer. Changing the VCXO would be more straightforward to change PLL2. Or, I could lock PLL1 to an external clock, also provide a clock to lock to the VCXO independently, and then update the device tree to use PLL1 instead.

    You can't use PLL1 only. PLL1 is only used to lock PLL2 against a reference.

    The only thing what might be possible is to use the HMC7044 as a HMC7043. So that you feed a high frequency clock into CLKIN1/FIN and then use the HMC7044 just a output divider of that clock. In order to do that you would need to do the same for the HMC7044 which is on the carrier.

    I should also update, based on the profile, to

                    adi,pll2-output-frequency = <8000000000>; //8GHz

    You can't do that the VCO/PLL2 only has certain tuning range (please see below)

    ...You would set things to 3GHz instead.

    VOLTAGE CONTROLLED OSCILLATOR (VCO) Frequency Tuning Range, On-Board VCOs1

    2150 2880 MHz Low VCO typical coverage

    2650 3550 MHz High VCO typical coverage

    2400 3200 MHz Guaranteed frequency coverage 

    In the profile there is a line <clkPLLHsDiv=2.0>, but I can't find a matching device tree entry. Is that entry handled by the driver, and I won't have to worry about it?

    That's a ADRV9009 property.

    https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/adrv9009-customization

    It translates to adi,dig-clocks-clk-pll-hs-div.

    To make the CORE_CLK changes for the FPGA clocks to make them 200MHz (8GHz/40), I would change from:

    Assuming your lane rate is 8G your link/core clock needs to be 200M, so the drivers could set this clock to 3G/15 = 200. You only need to make sure this won't fail, by setting a proper PLL2 frequency.

    Would drivers handle this? Is there any reason to change the JESD clocks in the device tree to my predicted LANERATE/40 value, or since the drivers configure from the PLL2 defice tree values I shouldn't have to worry about it?

    Yes.

    This code here will set the LANE and SYSREF rate:

    https://github.com/analogdevicesinc/linux/blob/master/drivers/iio/adc/adrv9009.c#L285

    Which will in return call into this driver which sets the SERDES QPLL/CPLL rates and also the div/40 clock.

    https://github.com/analogdevicesinc/linux/blob/master/drivers/iio/jesd204/axi_adxcvr.c#L223

    -Michael

Children