Pin collision between I2C2 and PWMs on Colibri iMX7

I am trying to enable all I2C buses and all PWM channels on Colibri iMX7D, but it seems that I2C2 collides with PWM2 and PWM3.

I have following DTS configuration created in similar manner to files for evaluation board.

imx7d-colibri-janom-imp-rev0.dts

/dts-v1/;
#include "imx7d-colibri.dtsi"
#include "imx7-colibri-janom-imp-rev0.dtsi"

/ {
	model = "Toradex Colibri iMX7D on Janom IMP rev.0";
	compatible = "egmedical,colibri_imx7d-janom_imp", "toradex,colibri_imx7d", "fsl,imx7d";
};

imx7-colibri-janom-imp-rev0.dtsi

/ {
	chosen {
		bootargs = "console=ttymxc0,115200";
	};
};

&iomuxc {
	imx7d-colibri {
		pinctrl_i2c2: i2c2grp {
			fsl,pins = <
				MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA	0x4000007f
				MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL	0x4000007f
			>;
		};
	};
};

&i2c2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c2>;
	clock-frequency = <100000>;
	status = "okay";
};

&pwm2 {
	status = "okay";
};

&pwm3 {
	status = "okay";
};

&uart1 {
	pinctrl-0 = <&pinctrl_uart1>;
	/delete-property/ fsl,uart-has-rtscts;
	status = "okay";
};

DTS compiles without any issues and Colibri is able to boot with it. But there are error messages in dmesg indicating that there is collision of pins used by PWM, but the stated pins are different from what is I2C2 using (see part of log below, complete dmesg output is attached).

dmesg | grep pin

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
[    0.023233] pinctrl core: initialized pinctrl subsystem
[    0.107347] imx7d-pinctrl 30270000.lpsr-gpr: initialized IMX pinctrl driver
[    0.107543] imx7d-pinctrl 302c0000.iomuxc-lpsr: initialized IMX pinctrl driver
[    0.108800] imx7d-pinctrl 30330000.iomuxc: initialized IMX pinctrl driver
[    0.155978] imx7d-pinctrl 30330000.iomuxc: pin MX7D_PAD_GPIO1_IO09 already requested by 30a30000.i2c; cannot claim for 30670000.pwm
[    0.156028] imx7d-pinctrl 30330000.iomuxc: pin-6 (30670000.pwm) status -22
[    0.156057] imx7d-pinctrl 30330000.iomuxc: could not request pin 6 (MX7D_PAD_GPIO1_IO09) from group pwm2grp  on device 30330000.iomuxc
[    0.156395] imx7d-pinctrl 30330000.iomuxc: pin MX7D_PAD_GPIO1_IO10 already requested by 30a30000.i2c; cannot claim for 30680000.pwm
[    0.156441] imx7d-pinctrl 30330000.iomuxc: pin-7 (30680000.pwm) status -22
[    0.156470] imx7d-pinctrl 30330000.iomuxc: could not request pin 7 (MX7D_PAD_GPIO1_IO10) from group pwm3grp  on device 30330000.iomuxc
[    1.492437] imx-sgtl5000 sound: sgtl5000 <-> 308a0000.sai mapping ok

I do not understand why is it complaining because I2C2 should use GPIO1_IO06 and GPIO1_IO07 (as stated in DTS above) instead of GPIO1_IO09 and GPIO1_IO10 as stated in log.

Any idea what is causing this error? I believe that this configuration should be possible.

It seems that I have figured it out. I have put pinctrl with MX7D_PAD_LPSR_… macros into &iomuxc block, which is wrong, because everything with “LPSR” in the name belongs into &iomuxc_lpsr.

Correct DTS definition (relevant part only, rest is same as posted in original post):

&iomuxc_lpsr {
	imx7d-colibri {
		pinctrl_i2c2: i2c2grp {
			fsl,pins = <
				MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA	0x4000007f
				MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL	0x4000007f
			>;
		};
	};
};

Everything else can remain unchanged.

I am still not quite sure where did MX7D_PAD_GPIO1_IO09 and MX7D_PAD_GPIO1_IO10 came from (I am not able to find these in included DTS files), but they are probably used for I2C2 by default. If anyone could confirm or deny that, please post a comment.

EDIT: I have figured out exact cause of this behavior. If you would like to know more, read this comment down below.

According to the error message it has been requested by 30a30000.i2c which is I2C2. The soc level device trees (imx7s/imx7d.dtsi) as well as the module level device trees (imx7-colibri.dtsi/imx7d-colibri.dtsi) do not enable or assign any pinmux to i2c2…

But our evaluation board device tree (imx7-colibri-eval-v3.dtsi) contains a pinmux for those pins to use them as GPIO, maybe this mux made it in an early version of you device tree?

@stefan.tx: Thanks for possible explanation, but I believe that this is not the case. I have tried it again right now and it behaves in same way as described in the question.

I have even tried to remove DTS files related to evaluation board (imx7-colibri-eval-v3.dtsi, imx7d-colibri-eval-v3.dts and imx7s-colibri-eval-v3.dts) and recompiled DTBs again. As expected, the file for our carrier board builds just fine, while DTBs for evaluation board results in error, as there are no DTS files to compile.

You can get resulting DTB file here and try it for yourself. I know that it is probably not possible to tell which files have been included for compilation, but maybe it can explain something?

There is a pinmux assigned to I2C2, that is what fdtdump reveils (use fdtdump ~/Downloads/imx7d-colibri-janom-imp-rev0.dtb | grep -A 10 i2c).

        i2c@30a30000 {          
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
            compatible = "fsl,imx7d-i2c", "fsl,imx21-i2c";
            reg = <0x30a30000 0x00010000>;
            interrupts = <0x00000000 0x00000024 0x00000004>;
            clocks = <0x00000001 0x000000d6>;
            status = "okay";                                
            pinctrl-names = "default";       
            pinctrl-0 = <0x00000039>;
            clock-frequency = <0x000186a0>;
        };                            

The SoC level device trees as well as module level device trees do not assign a pinctrl to the i2c2 node by default. It has to be part of your device tree (or a device tree you are including other than the default SoC/module device trees). Unless the there have been modifications in them…

@stefan.tx: I am not sure what are you trying to prove here. Of course there is pinctrl assigned to i2c2 node, I have defined it as i2c2grp and you can find it in dump as well.

But I have messed up placing this pinctrl inside correct node, because I have put it into iomuxc while I should have put it into iomuxc_lpsr as the pinctrl uses macros clearly related to LPSR. And that is something you can not really tell from fdtdump output you have posted. Or can you?


I believe I have found out exactly what happened there. If you look up macro definitions used for pinctrl of I2C2 and PWM2/PWM3, you will find out following values:

  • in imx7d-pinfunc.h:
    #define MX7D_PAD_GPIO1_IO09__PWM2_OUT 0x0018 0x0270 0x0000 0x7 0x0
    #define MX7D_PAD_GPIO1_IO10__PWM3_OUT 0x001C 0x0274 0x0000 0x7 0x0
  • in imx7d-pinfunc-lpsr.h:
    #define MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL 0x0018 0x0048 0x05DC 0x4 0x2
    #define MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA 0x001C 0x004C 0x05E0 0x4 0x2

As you can see, the first value of each macro is same for respective pairs of used pinctrl macros, so putting them into wrong node ( iomuxc vs iomuxc_lpsr) will cause different interpretation of these values, which explains errors from imx7d-pinctrl in dmesg.

Stefan, thank you for the fdtdump tool hint. It helped me to understand this problem. I have to remember it next time I will encounter strange DT related stuff.

Yeah I kind of forgot about the fact that you had it in the wrong iomuxc. But yes, now its clear, the numeric value of the defines were valid and translate into different pins for the two controllers, so that is where those GPIO1_IO09/10 were coming from.

Yeah fdtdump can be pretty helpful at times. Also checking /proc/device-tree after doing some dt changes can help, just to make sure you run the correct device tree and make the right assumptions…

Hi

Note that this is not really a follow-up of the original question.

In your kernel version MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA and MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL are not defined.

Compare with arch/arm/boot/dts/imx7d-pinfunc-lpsr.h. I guess that changing to MX7D_PAD_GPIO1_IO07__I2C2_SDA and MX7D_PAD_GPIO1_IO06__I2C2_SCL makes the build succeed.

Max

Hi
You obviously changed more than just the macro names.
Could you attach the device tree sources and the full output of dmesg and not just snippets?
Max

H Max

Thanks for your reply. I have just figured that out. Now I am using the correct PIN NAME as follows.

&iomuxc-lpsr  {
    compatible = "fsl,imx7d-iomuxc-lpsr";
    reg = <0x302c0000 0x10000>;
    fsl,input-sel = <&iomuxc>;
    pinctrl_i2c2: i2c2grp {
        fsl,pins = <
            MX7D_PAD_GPIO1_IO06__I2C2_SCL      0x4000007f
            MX7D_PAD_GPIO1_IO07__I2C2_SDA      0x4000007f
        >;
    };
  };

But after booting, I see the dmesg log the following erros are happening.

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260096
[    0.031487] pinctrl core: initialized pinctrl subsystem
[    0.079557] imx7d-pinctrl 302c0000.iomuxc-lpsr: no fsl,pins property in node /soc/aips-bus@30000000/iomuxc-lpsr@302c0000/imx7d-colibri
[    0.079725] imx7d-pinctrl 302c0000.iomuxc-lpsr: initialized IMX pinctrl driver
[    0.080713] imx7d-pinctrl 30330000.iomuxc: initialized IMX pinctrl driver
[    0.110622] imx7d-pinctrl 302c0000.iomuxc-lpsr: unable to find group for node i2c2_custom
[    2.324066] asoc-simple-card sound: sgtl5000 <-> 308a0000.sai mapping ok

I am completely lost. If I use the standard &iomuxc, then I get exact same error as op. i.e I lose pwm2 and pwm3 also i2c2 does not work correctly. If I use the standard io mux register &iomuxc, then I have the following error.

[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 260096
[    0.031408] pinctrl core: initialized pinctrl subsystem
[    0.079619] imx7d-pinctrl 302c0000.iomuxc-lpsr: initialized IMX pinctrl driver
[    0.080607] imx7d-pinctrl 30330000.iomuxc: initialized IMX pinctrl driver
[    0.146400] imx7d-pinctrl 30330000.iomuxc: pin MX7D_PAD_GPIO1_IO09 already requested by 30a30000.i2c; cannot claim for 30670000.pwm
[    0.146456] imx7d-pinctrl 30330000.iomuxc: pin-6 (30670000.pwm) status -22
[    0.146488] imx7d-pinctrl 30330000.iomuxc: could not request pin 6 (MX7D_PAD_GPIO1_IO09) from group pwm2-grp  on device 30330000.iomuxc
[    0.146646] imx7d-pinctrl 30330000.iomuxc: pin MX7D_PAD_GPIO1_IO10 already requested by 30a30000.i2c; cannot claim for 30680000.pwm
[    0.146696] imx7d-pinctrl 30330000.iomuxc: pin-7 (30680000.pwm) status -22
[    0.146727] imx7d-pinctrl 30330000.iomuxc: could not request pin 7 (MX7D_PAD_GPIO1_IO10) from group pwm3-grp  on device 30330000.iomuxc
[    2.394224] asoc-simple-card sound: sgtl5000 <-> 308a0000.sai mapping ok

@max.tx

I have tried the exact same code (posted in my last reply ) and tried to do build it after completely cleaning all the build cache and it worked. Thanks a lot for help.

Hi All,

bumping this old thread again.

I am trying to enable i2c2 (which is disabled in colibri-eval-v3 carrierboard) with the exact same code. My am unable to compile the dts file. It gives me syntax error. I believe that the syntax is correct. Here is my dts file :

/dts-v1/;                   
    #include "imx7d-colibri.dtsi"              
    #include "imx7d-colibri-emmc.dtsi"                                         
                                                                                                                                    
    / {                                                                                                                             
            model = "Toradex Colibri iMX7D 1GB on BOR Carrier Board V0.1";                                                    
            compatible = "toradex,colibri_imx7d_emmc-eval", "toradex,colibri_imx7d_emmc", \                                         
            "fsl,imx7d";                                                                                                            
    };
                                                                                                                                    
    &i2c2 {                                              
         pinctrl-names = "default";                                                                                                 
         pinctrl-0 = <&pinctrl_i2c2>;             
         clock-frequency = <100000>;                                                                                                
         status = "okay";
    };                                                                                                                              
    
     &pwm2 {            
         status = "okay";          
    };                                                                                                                              
                                         
     &pwm3 {                                           
         status = "okay";                     
    };                                                                                                                              
                                     
     &uart1 {                                                             
         pinctrl-0 = <&pinctrl_uart1>;
         /delete-property/ fsl,uart-has-rtscts;                           
         status = "okay";                                                                  
    };                                                                                                                              
                                                                          
                                                                             
    &iomuxc_lpsr {                                                        
         imx7d-colibri {                                                  
             pinctrl_i2c2: i2c2grp {                                         
                 fsl,pins = <
                    MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA    0x4000007f
                    MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL    0x4000007f
                 >;      
             };          
         };              
    };                   

And here is the error output while compiling.

NOTE: make -j 20 HOSTCC=gcc  -isystem/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/usr/include -O2 -pipe -L/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/usr/lib -L/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/lib -Wl,-rpath-link,/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/usr/lib -Wl,-rpath-link,/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/lib -Wl,-rpath,/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/usr/lib -Wl,-rpath,/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/recipe-sysroot-native/lib -Wl,-O1 HOSTCPP=gcc  -E imx7d-colibri-emmc-bor-carrier-board.dtb
|   CHK     scripts/mod/devicetable-offsets.h
|   DTC     arch/arm/boot/dts/imx7d-colibri-emmc-bor-carrier-board.dtb
| Error: /home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work-shared/colibri-imx7-emmc/kernel-source/arch/arm/boot/dts/imx7d-colibri-emmc-bor-carrier-board.dts:37.18-19 syntax error
| FATAL ERROR: Unable to parse input tree
| scripts/Makefile.lib:313: recipe for target 'arch/arm/boot/dts/imx7d-colibri-emmc-bor-carrier-board.dtb' failed
| make[3]: *** [arch/arm/boot/dts/imx7d-colibri-emmc-bor-carrier-board.dtb] Error 1
| arch/arm/Makefile:336: recipe for target 'imx7d-colibri-emmc-bor-carrier-board.dtb' failed
| make[2]: *** [imx7d-colibri-emmc-bor-carrier-board.dtb] Error 2
| Makefile:152: recipe for target 'sub-make' failed
| make[1]: *** [sub-make] Error 2
| Makefile:24: recipe for target '__sub-make' failed
| make: *** [__sub-make] Error 2
| ERROR: oe_runmake failed
| WARNING: exit code 1 from a shell command.
| ERROR: Function failed: do_compile (log file is located at /home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/tmp-glibc/work/colibri_imx7_emmc-angstrom-linux-gnueabi/linux-toradex/4.9-2.3.x+gitAUTOINC+d899927728-r0/temp/log.do_compile.12184)
ERROR: Task (/home/frodo/bor/meta_open_embedded_carrier_board/oe-core/build/../layers/meta-bor-carrier-board/recipes-kernel/linux/linux-toradex_4.9-2.3.x.bb:do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 600 tasks of which 592 didn't need to be rerun and 1 failed.     

I can see that the line number 37 throws error. But I am unable to understand where is the syntax error. Any help is much appreciated .

Great that it worked!