Friday, April 26, 2024

pinctrl in device tree

An example where we configure imx8mp GPIO1_IO15 (B5) to use as a PWM output.

Can configure it in several ways in the device-tree.


option 1

&pwm4 {

    status = "okay";

};


&iomuxc {

    pinctrl-names = "default";

    pinctrl-0 = <&..>, <&pinctrl_pwm4>; /* pinctrl_pwm4 and others */


    pinctrl_pwm4: pwm4grp {

        fsl,pins = <

            MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT          0x00000006

        >;

    };

};


option 2

&pwm4 {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_pwm4>;

    status = "okay";

};


&iomuxc {

    pinctrl-names = "default";

    pinctrl-0 = <&..>;          /* other pinctrls but no pinctrl_pwm4 */


    pinctrl_pwm4: pwm4grp {

        fsl,pins = <

            MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT          0x00000006

        >;

    };

};


Documentation/devicetree/bindings/pinctrl/fsl,imx8mp-pinctrl.yaml tells us how to interpret the pinmux settings we are seeing in the device-tree


fsl,pins:

description:

  each entry consists of 6 integers and represents the mux and config

  setting for one pin. The first 5 integers <mux_reg conf_reg input_reg

  mux_val input_val> are specified using a PIN_FUNC_ID macro, which can

  be found in <arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h>. The last

  integer CONFIG is the pad setting value like pull-up on this pin. Please

  refer to i.MX8M Plus Reference Manual for detailed CONFIG settings.

$ref: /schemas/types.yaml#/definitions/uint32-matrix

items:

  items:

    - description: |

        "mux_reg" indicates the offset of mux register.

    - description: |

        "conf_reg" indicates the offset of pad configuration register.

    - description: |

        "input_reg" indicates the offset of select input register.

    - description: |

        "mux_val" indicates the mux value to be applied.

    - description: |

        "input_val" indicates the select input value to be applied.

    - description: |

        "pad_setting" indicates the pad configuration value to be applied..


from arch/arm64/boot/dts/freescale/imx8mp-pinfunc.h


                      pad/pin     functionality we want to

                      in imx8mp   assign to the pad

                     |--------|  |---------|

#define MX8MP_IOMUXC_GPIO1_IO15__GPIO1_IO15    0x050 0x2B0 0x000 0x0 0x0

#define MX8MP_IOMUXC_GPIO1_IO15__USB2_OC       0x050 0x2B0 0x000 0x1 0x0

#define MX8MP_IOMUXC_GPIO1_IO15__USDHC3_WP     0x050 0x2B0 0x634 0x4 0x0

#define MX8MP_IOMUXC_GPIO1_IO15__PWM4_OUT      0x050 0x2B0 0x000 0x5 0x0

#define MX8MP_IOMUXC_GPIO1_IO15__CCM_CLKO2     0x050 0x2B0 0x000 0x6 0x0


pin mux from the imx8mp reference manual


instance    port            pad             mode

CCM         CCM_CLKO2       GPIO1_IO15      ALT6

GPIO1       GPIO1_IO15      GPIO1_IO15      ALT0

PWM4        PWM4_OUT        GPIO1_IO15      ALT5

USB2        USB2_OC         GPIO1_IO15      ALT1

USDHC3      USDHC3_WP       GPIO1_IO15      ALT4


from the imx8mp reference manual, we see mux_reg and conf_reg registers of iomuxc are


32-bit MUX Control Register IOMUXC_SW_MUX_CTL_PAD_x to configure ALT mode (MUX MODE)

32-bit PAD Control Register IOMUXC_SW_PAD_CTL_PAD_x to configure pad settings


for our GPIO1_IO15


SW_MUX_CTL_PAD_GPIO1_IO15 SW MUX Control Register

(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO15)

Address: 3033_0000h base + 50h offset = 3033_0050h


31 .... 5   4       3      2   1  0

[reserved][SION][reserved][mux mode]


mux_val: IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO15[2:0] = 101 -  ALT5_PWM4_OUT


SW_PAD_CTL_PAD_GPIO1_IO15 SW PAD Control Register

(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO15)

Address: 3033_0000h base + 2B0h offset = 3033_02B0h


31 .... 9  8    7    6    5    4      3      2..1    0

[reserved][PE][HYS][PUE][ODE][FSEL][reserved][DSE][reserved]


pad_setting = 0x00000006 : sets the drive strength

where

PE  : pull resistors enable/disable

HYS : cmos/schmitt

PUE : pull up/down config

ODE : open drain enable/disable

FSEL: slew rate slow/fast

DSE : drive strength


Other than linux kernel documentation, some good documentation on pin setting can be found in 

AN5078: Influence of Pin Setting on System Function and Performance