Dopo aver progettato e costruito una scheda portante personalizzata incentrata sul Variscite i.MX System on Module / Computer in Module, una delle prime attività che il tuo team software dovrà affrontare sarà creare un nuovo file con l’albero dei dispositivi per il kernel Linux. L’albero dei dispositivi definisce la descrizione della configurazione hardware per il kernel, che comprende la funzione e le impostazioni di ciascun pin. La maggior parte dei pin SoC i.MX sono multiplexati e offrono fino a 8 funzioni pin alternative. Inoltre, la maggior parte dei pin ha impostazioni configurabili come pull-up interni, pull-down, ecc. Questa guida spiega come configurare una funzione pin e le relative impostazioni per i dispositivi nell’albero Linux per il sistema Variscite i.MX in Module.

Configurazione del pinmux per un dispositivo

Quando si aggiunge un nodo dispositivo che richiede il controllo fisico su un pin, come I2C, PWM, UART, ecc., è necessario specificare la funzione e le impostazioni per ciascun pin. A tale scopo si devono seguire questi due passaggi principali:

  1. aggiungere un nodo per il gruppo di pin al nodo iomuxc che definisce la funzione e le impostazioni dei pin,
  2. fare riferimento a quel nodo per il gruppo di pin nel nodo del nuovo dispositivo che si deve aggiungere

Per mostrare come funziona questo processo, esaminiamo la configurazione pinmux per UART3 sul SoM VAR-SOM-MX8X:

Passaggio 1: aggiungere un nodo per il gruppo di pin al nodo iomuxc

Per VAR-SOM-MX8X, il nodo per il gruppo di pin UART3 è definito in imx8qxp-var-som.dtsi:

&iomuxc {


pinctrl_lpuart3: lpuart3grp {

fsl,pins = <

IMX8QXP_SCU_GPIO0_00_ADMA_UART3_RX          0x06000020
IMX8QXP_SCU_GPIO0_01_ADMA_UART3_TX          0x06000020

>;

};

};

iomuxc è un nodo dispositivo per il driver pinctrl imx8qxp. È definito in imx8qxp.dtsi. La documentazione per questo nodo è disponibile nell’albero delle sorgenti del kernel Linux, all’indirizzo:
documentation/deviceTree/bindings/ARM/FreeScale/FSL, scu.txt
documentation/deviceTree/bindings/pinCtrl/FSL, imx-pinctrl.txt

pinctrl_lpuart3 è un’etichetta utilizzata per fornire un nome al gruppo di pin UART3. Useremo questa etichetta nella fase successiva.

“fsl,pins” è un elenco di pin utilizzati su UART3 con la relativa configurazione. Ogni voce è composta da una macro per la funzione pin (pinmux) e da un numero intero relativo all’impostazione del pad (pull-up interni, pull-down, ecc.).

Funzione Pin:

Ogni pin ha fino a 8 funzioni multiplexate. Per semplificare la selezione della funzione pin, NXP fornisce macro per ogni SOC con la seguente convenzione di denominazione:

<SOC>_<PIN NAME>_<PIN FUNCTION>

In questo esempio, “fsl,pins” ha due voci di pin: il pin SCU_GPIO0_00 è configurato per la funzione ADMA_UART3_RX e il pin SCU_GPIO0_01 è configurato per la funzione ADMA_UART3_TX.

Avvertenza:  per evitare conflitti tra pinmux, bisogna impostare ogni pin su una sola funzione, assegnando ognuna di esse a un singolo pin.

Ogni SoC i.MX ha un file di configurazione dei pin con le definizioni delle macro delle funzioni pin e la documentazione nella directory dei collegamenti dell’albero dei dispositivi. Per ulteriori informazioni sui valori delle macro della funzione pin, basta consultare la documentazione del SoC specifico.

Per i.MX8X e i.MX8QM, i file di intestazione dei pin si trovano in “include/dt-bindings/pinctrl/”, mentre, come detto in precedenza, la documentazione si trova in “Documentation/DeviceTree/Bindings/ARM/FreeScale/”

Header file Documentation
pads-imx8qxp.h fsl,scu.txt
pads-imx8qm.h fsl,scu.txt

Per la famiglia i.MX8M, i file pinfunc si trovano in “arch/arm64/boot/dts/freescale/” e la documentazione è disponibile in “documentation/deviceTree/bindings/pinCtrl/”

Header file Documentation
imx8mp-pinfunc.h fsl,imx8mp-pinctrl.txt
imx8mq-pinfunc.h fsl,imx8mq-pinctrl.txt
imx8mm-pinfunc.h fsl,imx8mm-pinctrl.txt
imx8mn-pinfunc.h fsl,imx8mn-pinctrl.txt

 

Per le famiglie i.MX6/i.MX6UL/i.MX7, i file pinfunc si trovano in “arch/arm/boot/dts/” e la documentazione è disponibile in “Documentation/deviceTree/bindings/pinCtrl/”

Header file Documentation
imx6dl-pinfunc.h fsl,imx6dl-pinctrl.txt
imx6q-pinfunc.h fsl,imx6q-pinctrl.txt
imx6ul-pinfunc.h fsl,imx6ul-pinctrl.txt
imx6ull-pinfunc.h fsl,imx6ul-pinctrl.txt
imx7d-pinfunc.h fsl,imx7d-pinctrl.txt

Impostazione del pad:

Oltre alla macro della funzione pin, ogni voce “fsl,pins” richiede un valore per le impostazioni del pad. In questo caso, 0x06000020 è il valore di impostazione del pad che configura il pull-up del pin, la forza dell’unità, ecc. Le opzioni di configurazione per ciascun pin sono descritte nel manuale di riferimento i.MX8QXP.

Di seguito è riportato il registro di controllo pad/mux per il pin UART3_RX, tratto dal manuale di riferimento i.MX8QXP Rev. 0, 05/2020, pagina 957:

datesheet_diagram

Figura 1: Registro di controllo PAD/MUX per SCU_GPIO0_00

 

 

VAR-SOM-MX8X : NXP iMX 8X System on Module (SoM)

VAR-SOM-MX8X : NXP iMX 8X SoM

 

 

Field Function
31
update_mux_mode
update lock for mux control
write 1 to allow programming to mux control [29:19]
30
update_pad_ctl
update lock for pad control
write 1 to allow programming to pad control [14-1:0]
29-27
mux_mode
mux_mode
000b – SCU_GPIO0_IO00
001b – SCU_UART0_RX
010b – M40_UART0_RX
011b – ADMA_UART3_RX
100b – LSIO_GPIO2_IO03
26-25
sw_config
output and input configuration
00b – DEFAULT
01b – OPEN_DRAIN
10b – OPEN_DRAIN_INPUT
11b – INOUT
24-23
lp_config
lower power configuration
00b – PASS
01b – EARLY_ISO
10b – LATE_ISO
11b – LATCH
22
ENABLE_WAKEUP_CHANGE
Enable WAKEUP change
Allows modification of the WAKEUP_CTRL field without having to read or modify the other bits
21-19
WAKEUP_CTRL
wakeup control
000b – OFF
001b – RESAMPLE (The wakeup field is not modified (it retains its old value) but because a write is done, the flag is cleared)
100b – LOW
101b – FALL
110b – RISE
111b – HIGH
18-17 Reserved
6-5
PULL
Pull Down Pull Up
00b – Bus-Keeper
01b – pull up
10b – pull down
11b – No Pull
4-3 Reserved
2-0
DSE
Drive
000b – Drive select 1mA
001b – Drive select 2mA
010b – Drive select 4mA
011b – Drive select 6mA
100b – Drive select 8mA
101b – Drive select 10mA
110b – Drive select 12mA
111b – High Speed

 

Considerando che questo registro ha valore pari a 0x06000020 (bit 5, 25, 26 abilitati) in questo esempio, l’elenco corrispondente contiene tutte le configurazioni e i relativi valori:

update_mux_mode: valore 0

update_pad_ctl: valore 0

mux_mode: valore 0 (configurato dalla macro della funzione pin)

sw_config: valore 0b11

lp_config: valore 0

enable_wakeup_change: valore 0

wakeup_ctrl: valore 0

pull: valore 0b01: resistenza di pull-up interna selezionata.

DSE: valore 0b000: potenza di trasmissione selezionata di 1 mA.

Per ulteriori informazioni su tutte le configurazioni possibili, consulta il manuale di riferimento i.MX8QXP.

 

Passaggio 2: fare riferimento al nodo per il gruppo di pin corrispondente nel nodo del dispositivo

Dopo aver aggiunto il nodo per il gruppo di pin (lpuart3grp) a iomuxc, il passaggio successivo consiste nel fornire un riferimento al nodo del dispositivo che utilizzerà questi pin. In questo esempio, abbiamo usato lpuart3, definito in imx8-ss-dma.dtsi e configurato da Variscite in imx8qxp-var-som-symphony.dtsi:

/* Console */
&lpuart3 {

pinctrl-names = “default”;
pinctrl-0 = <&pinctrl_lpuart3>;

};

Durante l’inizializzazione di lpuart3, il core del dispositivo Linux richiamerà pinctrl_bind_pins prima di chiamare la funzione sonda nel driver lpuart3. Il driver pinctrl scriverà, quindi, nei registri specifici di i.MX per configurare lo stato dei pin predefinito per ogni voce in pinctrl_lpuart3.

Stati dei pin

Alcuni dispositivi supportano più stati dei pin.
Ad esempio, per un dispositivo MMC:

 &usdhc1 {

pinctrl-names = “default”, “state_100mhz”, “state_200mhz”;
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;

};

In questo esempio, usdhc1 ha tre stati pinctrl: default, 100 mhz e 200 mhz. Il core del dispositivo Linux inizializzerà lo stato predefinito prima di richiamare la funzione probe del driver della piattaforma. Tuttavia, il driver ha anche la possibilità di modificare le impostazioni dei pin in base alla modalità MMC.

Per ulteriori informazioni su questo argomento, vedere il seguente file di documentazione nell’albero delle sorgenti del kernel: “Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt”

 

Riepilogo

In sintesi, i nodi del dispositivo che richiedono la configurazione dei pin necessitano di un riferimento a un nodo per il gruppo di pin definito in iomuxc. Il nodo per il gruppo di pin definisce la funzione e le impostazioni dei pin per ogni pin pertinente. Per saperne di più sui dettagli di ciascun SoC, consultare la documentazione disponibile nell’albero delle sorgenti del kernel all’indirizzo “Documentation/deviceTree/bindings/pinCTRL/”.