Adding new spi module on IMX8 quad max with Yocto

cancel
Showing results for 
Search instead for 
Did you mean: 

Adding new spi module on IMX8 quad max with Yocto

6,541 Views
s233199
Contributor II

I am using Yocto on a  imx8 quad max evaluation board, and I want to add a custom spi module. I have done all the steps described in yocto manual, but when I plug in the board the probe function is not called so when I try to use my driver calling a write I have kernel exception messages (when spi_sync is called) such as "Unable to handle kernel NULL pointer dereference at virtual address". I previously tried this module on a Udoo-neo board (with imx6) and it worked fine.

Do I need to modify my device tree files in order to enable my module to use spi? If yes, how can I modify them?

I read a lot of stuff about dts files but still do not understand how they work.

I am new to Yocto and to kernel drivers.

Thank you in advance for your help!

8 Replies

3,469 Views
bernhardfink
NXP Employee
NXP Employee

Hi Erica,

the flexspi port connects to an OctaSPI flash (serial flash with 8 SPI lines), so this is most likley not the SPI port you are looking for. The flash type on the 8QM board is a MICRON MT35XU512, that's why you find the name in this section.

On our 8QM board we don't have anything connected to standard SPI, that's why you don't find any setup for it.

>>  I read a lot of stuff about dts files but still do not understand how they work.

You're not alone  :smileycool:

OK, this is the SPI setup on the i.MX 8QM:

  1. There are four LPSPI ports on the 8QM ( LPSPI[3:0] ), in the Reference Manual you find the LPSPI ports in chapter 9.1.
  2. The standard SPI port has 4 pins: SCK / PCS / SIN / SOUT
  3. The SPI peripherals 0/1/2/3 are located at 0x5A000000 / 0x5A010000 / 0x5A020000 / 0x5A030000

This is what you need to do:

  1. Add SPI port(s) to the file fsl-imx8qm.dts
    • The file can be found in the folder /tmp/work-shared/imx8qmmek/kernel-source/arch/arm64/boot/dts/freescale
    • In the current beta-release there is already an entry for the lpspi0
    • The address of the LPSPI port can be found in the Reference Manual --> System Memory Map --> Audio DMA Memory Maps
    • There is also an LPSPI peripheral in the i.MX7ULP, so for now you can keep this entry in "compatible". Maybe later on, when the i.MX8 became more popular in the Linux world, there might be other strings.
    • The defines for the clocks can be found in the file imx8qm-clock.h

      lpspi0: lpspi@5a000000 {
              compatible = "fsl,imx7ulp-spi";
              reg = <0x0 0x5a000000 0x0 0x10000>;
              interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
              interrupt-parent = <&gic>;
              clocks = <&clk IMX8QM_SPI0_CLK>,
                   <&clk IMX8QM_SPI0_IPG_CLK>;
              clock-names = "per", "ipg";
              assigned-clocks = <&clk IMX8QM_SPI0_CLK>;
              assigned-clock-rates = <20000000>;
              power-domains = <&pd_dma_lpspi0>;
              status = "disabled";
          };

      lpspi1: lpspi@5a010000 {
              compatible = "fsl,imx7ulp-spi";
              reg = <0x0 0x5a010000 0x0 0x10000>;
              interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
              interrupt-parent = <&gic>;
              clocks = <&clk IMX8QM_SPI1_CLK>,
                   <&clk IMX8QM_SPI1_IPG_CLK>;
              clock-names = "per", "ipg";
              assigned-clocks = <&clk IMX8QM_SPI1_CLK>;
              assigned-clock-rates = <20000000>;
              power-domains = <&pd_dma_lpspi1>;
              status = "disabled";
          };

  2. You need to define the pins for the SPI ports you want to use.
    1. There is an example for the lpspi0 in the file fsl-imx8qm-lpddr4-arm2-lpspi.dts in the folder /tmp/work-shared/imx8qmmek/kernel-source/arch/arm64/boot/dts/freescale

      &iomuxc {
          imx8qm-arm2 {
              pinctrl_lpspi0: lpspi0grp {
                  fsl,pins = <
                      SC_P_SPI0_SCK_DMA_SPI0_SCK        0x0600004c
                      SC_P_SPI0_SDO_DMA_SPI0_SDO        0x0600004c
                      SC_P_SPI0_SDI_DMA_SPI0_SDI        0x0600004c
                  >;
              };

              pinctrl_lpspi0_cs: lpspi0cs {
                  fsl,pins = <
                      SC_P_SPI0_CS0_LSIO_GPIO3_IO05        0x21
                  >;
              };
          };
      };

      &lpspi0 {
          #address-cells = <1>;
          #size-cells = <0>;
          fsl,spi-num-chipselects = <1>;
          pinctrl-names = "default";
          pinctrl-0 = <&pinctrl_lpspi0 &pinctrl_lpspi0_cs>;
          cs-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
          status = "okay";
          flash: at45db041e@0 {
              #address-cells = <1>;
              #size-cells = <1>;
              compatible = "atmel,at45", "atmel,dataflash";
              spi-max-frequency = <500000>;
              reg = <0>;
              };
      };
  3. Configure the Kernel config for SPI support
    • Please check if the Kernel config file contains the following defines:
      CONFIG_SPI=y
      CONFIG_SPI_IMX=y
      CONFIG_SPI_FSL_LPSPI=y
    • If you want this as a default Kernel config setting, please edit the file defconfig in the folder /tmp/work-shared/imx8qmmek/kernel-source/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
  4. Test the SPI port
    • After creating an image you can test the SPI port on device level and on hardware level
    • To load the SPI driver on command line:  $ modprobe spidev
    • The standard SPI driver in the Linux Kernel (spi-imx.c) would allow you to use the port and finally you should see something on the port when you try to send data.

I need to admit that at the time of writing I didn't test it on the 8QM board, so if you can't make it working please come back to me and I will give it a try on my side.

Regards,

Bernhard.

3,469 Views
darsh_dev
Contributor V

Well explanation bernhardfink I would like enable the SPI support for u-boot. I can't get any SPI Bus driver or compatible driver "fsl,imx7ulp-spi" from uboot. Can you please share the details.

0 Kudos

3,469 Views
mikemalgin
Contributor II

Bernhard, is there such an excellent explanation for those who work with Android 9? We weren't able to enable spidev easily on Android 9. And "make manuconfig" doesn't seem to work as well.   

0 Kudos

3,469 Views
s233199
Contributor II

Hello, thank you for your answer. I have tried this but my custom driver does not probe. In my init function spi_register_driver returns 0 but my probe function does not print anything. Do I need to insert { .compatible = "fsl,imx7ulp-spi" } in the struct of_device_id of my custom driver? Or I need to write something else in .compatile?

0 Kudos

3,469 Views
s233199
Contributor II

Adding .compatible = "fsl,imx7ulp-spi" still does not probe. I also added status = "okay" in the lpspi0 entry in the first file.

0 Kudos

3,469 Views
igorpadykov
NXP TechSupport
NXP TechSupport

Hi Erica

example for i.MX8QM can be found in

linux/arch/arm64/boot/dts/freescale/fsl-imx8qm-mek.dts

fsl-imx8qm-mek.dts\freescale\dts\boot\arm64\arch - linux-imx - i.MX Linux kernel 

However this processor is not publicly released and not supported yet.

For i.MX8MQ example on below link and procedure is similar to i.MX6 processors.

linux/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts

fsl-imx8mq-evk.dts\freescale\dts\boot\arm64\arch - linux-imx - i.MX Linux kernel 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,469 Views
s233199
Contributor II

Thank you for your answer!

Opening the first link, on the section "&flexspi0" there is this:

flash0: mt35xu512aba@0 {           reg = <0>;           #address-cells = <1>;           #size-cells = <1>;           compatible = "micron,mt35xu512aba";           spi-max-frequency = <29000000>;           spi-nor,ddr-quad-read-dummy = <8>;      };

can you please explain what flash0, mt35xu512aba@0 and compatible mean?
Is this part the key to add my driver or I am wrong?
0 Kudos

3,469 Views
igorpadykov
NXP TechSupport
NXP TechSupport

for dts definitions one can look at AN5125 Introduction to Device Tree

https://www.nxp.com/docs/en/application-note/AN5125.pdf 

Best regards
igor

0 Kudos