cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Teacher
Teacher
266 Views
Registered: ‎01-28-2008

One I2C controller, two board configurations

Jump to solution

Hi folks,

  I'm attempting to accommodate one Petalinux image to work on two ZynqMP-based boards with different I2C trees hanging off of a PS I2C EMIO pin pair. The plan is to handle this with a device tree configuration and select either I2C tree based on runtime selection, i.e. board0 vs. board1.

  The first board has a I2C mux device (NXP PCA9548) and the second board has a I2C GPIO extender (NXP PCA9535) on the same PL pins driven by the PS I2C controller.

  I'm aware of the pinctrl subsystem and how to use it to mux a set of pins for different functions, though in this case, we're using the same set of I2C pins instead. Can it be used to mux functionalities as well? How would the DT look in that case, if possible?

  For instance on board0, the I2C device tree would look like:

&i2c0 {
  status = "okay";
  clock-frequency = <400000>;

  /* PL I2C mux TCA9548 - U3 */
  i2c-mux@70 {
    compatible = "nxp,pca9548";
    #address-cells = <1>;
    #size-cells = <0>;
    reg = <0x70>;
  };
  <...>
};

   While on board1, would look like:

&i2c0 {
  status = "okay";
  clock-frequency = <400000>;

  /* SFP GPIO I2C */
  tca9535_u22: sfp_gpio@20 {
    compatible = "nxp,pca9535";
    reg = <0x20>;
    gpio-controller;
    #gpio-cells = <2>;
    gpio-line-names = "SFP0_TX_FAULT", "SFP1_TX_FAULT", "SFP2_TX_FAULT", "SFP3_TX_FAULT",
          "SFP0_RX_LOS", "SFP1_RX_LOS", "SFP2_RX_LOS", "SFP3_RX_LOS",
          "SFP0_RX_DISABLE", "SFP1_RX_DISABLE", "SFP2_RX_DISABLE", "SFP3_RX_DISABLE",
          "PGOOD-5P5V", "PGOOD-3P3V", "PGOOD-1P8V", "";
    };
  <...>
};

 

Any pointers will be appreciated.

Thanks,

-Pat

 

Give kudos if helpful. Accept as solution if it solves your problem.
https://tuxengineering.com/blog

0 Kudos
Reply
1 Solution

Accepted Solutions
Moderator
Moderator
219 Views
Registered: ‎09-12-2007

One way would be to use devicetree overlays. 

Also, in 2020.1, the uboot loads the DTB at address 0x100000 for zynq Ultrascale:

https://github.com/Xilinx/u-boot-xlnx/blob/master/board/xilinx/common/board.c#L323

So, you could load both blobs in your BIF and patch the uboot to load the correct blob based on your device

Reference:

https://github.com/Xilinx/u-boot-xlnx/blob/master/board/xilinx/zynqmp/zynqmp.c

View solution in original post

3 Replies
Moderator
Moderator
220 Views
Registered: ‎09-12-2007

One way would be to use devicetree overlays. 

Also, in 2020.1, the uboot loads the DTB at address 0x100000 for zynq Ultrascale:

https://github.com/Xilinx/u-boot-xlnx/blob/master/board/xilinx/common/board.c#L323

So, you could load both blobs in your BIF and patch the uboot to load the correct blob based on your device

Reference:

https://github.com/Xilinx/u-boot-xlnx/blob/master/board/xilinx/zynqmp/zynqmp.c

View solution in original post

Teacher
Teacher
167 Views
Registered: ‎01-28-2008

Hi folks,

  Thanks @stephenm for your suggested pointer. I'll go with DT overlays, to be loaded dynamically. The plan is to have two dtbo files and load them onto configfs at runtime, once Linux probes in which slot the board is seated, either slot 0 or 1.

  So far, I was able to load an overlay without issue using a proof of concept device, but expanding the DT to use the I2C mux, it get errors while loading.

  The working dtsi looks like this, using the si570 programmable clock:

/dts-v1/;
/plugin/;

/ {
	compatible = "xlnx,zynqmp";

  fragment@0 {
    target = <&i2c0>;
    __overlay__ {
      #address-cells = <0x01>;
      #size-cells = <0x00>;

      si570: clock-generator@55 {
        #clock-cells = <0>;
         compatible = "silabs,si570";
         temperature-stability = <50>;
         reg = <0x55>;
         factory-fout = <148500000>;
         clock-frequency = <156250000>;
         clock-output-names = "si570_user";
       };
     };
   };
 };

  The dtsi is compiled with the dtc as follows:

$ dtc -I dts -O dtb pl-i2c0.dtsi -b 0 -@ -o output/pl-i2c0.dtbo

  Then the resulting .dtbo is copied to the running target and loaded as follows:

# mkdir /configfs
# mount -t configfs configfs /configfs
# mkdir /configfs/device-tree/overlays/pl-i2c0
# cat pl-i2c0.dtbo > /configfs/device-tree/overlays/pl-i2c0/dtbo
root@DAQ16-2020:~# cat pl-i2c0.dtbo> /configfs/device-tree/overlays/pl-i2c/dtbo
[ 1730.800676] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/si570
[ 1730.824888] si570 0-0055: registered, current frequency 156250000 Hz

  So the si570 driver is being loaded and the device is correctly programmed to the requested frequency. So far so good.

  Now, in the actual hardware (arriving in a couple of weeks), the I2C tree has an I2C mux on one site, and an I2C GPIO expander on the second site. When adding the device tree blob for this I2C mux, I get errors.

  Here's the device tree overlay .dtsi:

/dts-v1/;
/plugin/;

/ {
	compatible = "xlnx,zynqmp";

  fragment@0 {
    target = <&i2c0>;
    __overlay__ {
      #address-cells = <0x01>;
      #size-cells = <0x00>;

      /* PL I2C mux TCA9548 - U3 */
      i2c-mux@70 {
        compatible = "nxp,pca9548";
        #address-cells = <1>;
        #size-cells = <0>;
        reg = <0x55>;

        sfp0_i2c: i2c@0 {
          #address-cells = <1>;
          #size-cells = <0>;
          reg = <0x0>;
          /* SFP0 I2C */
        };
     };
    };
   };
 };

  Following the same procedure as before, loading this dtbo throws these error messages:

root@DAQ16-2020:~# cat pl-i2c0.dtbo > /configfs/device-tree/overlays/pl-i2c/dtbo
[  416.749113] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /amba/i2c@ff020000/i2c-mux@70/compatible
[  416.760609] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /amba/i2c@ff020000/i2c-mux@70/reg
[  416.771477] create_overlay: Failed to create overlay (err=-22)

  Removing the sfp0_i2c node makes the error go away though, but the warnings stay. The sfp0_i2c node will be used later from the "sff,sfp" node that talks to the SFP transceivers over I2C.

  Any idea why this node is failing to be added as an overlay?

 

Thanks in advance for any pointers,

-Pat

 

 

 

Give kudos if helpful. Accept as solution if it solves your problem.
https://tuxengineering.com/blog

0 Kudos
Reply
Teacher
Teacher
147 Views
Registered: ‎01-28-2008

Hi there,

  Well, it was operator error. The loaded static DT in the system already had those nodes defined, so it couldn't load the same nodes from the overlay on top. Listing the symbols under /proc/device-tree/__symbols__ made this obvious.

  Now, loading the DT overlays after removing the static nodes, reports:

root@DAQ16-2020:~# cat pl-i2c0.dtbo > /sys/kernel/config/device-tree/overlays/pl-i2c0/dtbo
[   79.472752] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/i2cmux
[   79.482422] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/sfp0_i2c
[   79.493790] i2c i2c-0: Added multiplexed i2c bus 1
[   79.498779] i2c i2c-0: Added multiplexed i2c bus 2
[   79.503694] i2c i2c-0: Added multiplexed i2c bus 3
[   79.508628] i2c i2c-0: Added multiplexed i2c bus 4
[   79.513561] i2c i2c-0: Added multiplexed i2c bus 5
[   79.518476] i2c i2c-0: Added multiplexed i2c bus 6
[   79.523394] i2c i2c-0: Added multiplexed i2c bus 7
[   79.528326] i2c i2c-0: Added multiplexed i2c bus 8
[   79.533116] pca954x 0-0055: registered 8 multiplexed busses for I2C switch pca9548

 

Thanks,

-Pat

 

Give kudos if helpful. Accept as solution if it solves your problem.
https://tuxengineering.com/blog

0 Kudos
Reply