• Hi,


    I'm trying to get SPI_A (ecspi3) with multiple chip selects to work,

    but only the predefined chip select (gpio5 25) seems to work.


    Below my device tree:


    I checked that no other node is using or muxing my pins

  • Hello,


    which release do you work with? Your device tree seems to be correct.

    We'll have to reproduce this on our side and come back to you as soon as possible.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • If you are telling the driver with num-cs = <5> that you use 5 devices, then you also have to define 5 sub-nodes for these devices. If you do not need all devices right now, you can use compatible = "linux,spidev" for the others. We have more than one CS on our efusa9, so see


    arch/arm/boot/dts/efusa9qdl.dts


    in node &ecspi1 for an example with three CS signals.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Tried the following device tree without success...

    Perhaps I'm missing a kernel module?


  • Perhaps I'm missing a kernel module?

    That is also possible. For our boards, we use a rather minimized set of drivers. If you are adding own hardware, you typically also have to activate the driver for it. So in Linux menuconfig, go to "Device Drivers" -> "Industrial I/O support" -> "Digital to analog converters" and activate "Linear Technology LTC2632-12/10/8 DAC spi driver". You can either do this by "Y", then the driver is included in the kernel image, or you can set it to "M", then the driver is built as a kernel module. Then the kernel must be rebuilt and reinstalled. In the latter case, you also have to rebuild your Buildroot/Yocto rootfs to have the new kernel module included.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Just one more test. If you move the <&gpio3 1 GPIO_ACTIVE_LOW> to the first position in the CS-Sequence, so that it becomes CS0, does it work then? Of course you have to move the sub-node accordingly to position 0 then. This would show if there is a general problem with the other GPIOs or if only entry 0 will work.


    I know we had some modifications in the SPI driver in the past to make this work with more than 1 CS signal, maybe there were some changes when updating to the newer kernel so that there is again something wrong. We have to check this, but the above test would help us in locating the problem.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • To keep you updated, we are working on it, but strangely enough, it is working here, as far as we can see up to now. Unfortunately it is difficult to test some pins on our baseboard, so it takes a little bit longer to check all your chip selects.

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Hello again,


    I finally tested all your pins you defined as chip selects. I measured the respective chip select signal with an oscilloscope and could see the pull-down.

    Furthermore I sent some arbitrary data to the different spi devices (spidev2.0 to spidev2.4), which were chosen via chip select.


    I used the picocoremx8mp.dts device tree. I only added your changes and had to comment the MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 pin in the hoggrp out.

    Do your spi devices get properly initialized? You can check this by executing dmesg | grep spi or by checking the /dev/ path for the respective spi devices. Did you actually send any data or did you "only" measure the CS signal with an oscilloscope?

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • One more thing that is worth a try. In all i.MX8M device trees, NXP is using the value 0x40000 for the SPI chip select pad setting. We simply copied that without thinking too much about it. However when looking at it now, this value is rather strange. It does not match what we know about these pad settings. Typically, this value is the bit combination that should be written to the appropriate PAD settings register in the iomuxc register file. In addition, there are two special bits. If bit 31 is set, then the value should not be modified. This is for signals that are already set earlier, by the bootloader for example, and should not be changed in Linux. And if bit 30 is set, then the SION flag should be set. This bit activates the input branch of the pad, so that the value can be read back. This is necessary for signals that need to read the real pad value for loop-back purposes. This SION bit is actually in a different register, but to avoid having an additional value just for this bit, NXP uses this trick. If bit 30 is set, then the driver will set the SION bit in the other register.


    On i.MX8M CPUs, only a few bits in the PAD settings register are actually valid. No bit higher than bit 8 is ever used, so the value can always be represented by at most three hex digits. So the value 0x40000 does not make sense. It does not refer to a valid bit in the PAD settings register, but it is also not one of the two bits 30 and 31, that are handled specially by the driver.


    So it might actually be a mistake by NXP. Maybe they copied a value with SION enabled from somewhere else (0x40000xxx), removed the last three digits of the original number (these are the valid bits of the register), but forgot to append three new digits for the new bits. If this assumption is correct, then the PAD settings bits would actually be set to all zero and the unimplemented bit that was set by the 4 has no effect. This would result in a rather weak driver strength of the signal.


    So in our point of view, it makes more sense to define an own value here that actually represents the PAD settings register bits. So try to use 0x40000156 instead of 0x40000 in all the pad settings in the pinctrl_ecspi3_cs: ecspi3cs subnode. This will use maximum driver strength, a fast Slew Rate and a weak Pull-up. Maybe this modification does the trick for you.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

    Edited once, last by fs-support_HK ().

  • With 0x40000156 on all cs, the gpio1 15 seems to work.


    i had already commented the line in the hog group so this should not be an issue.


    here is the output of the dmesg command:

    i noticed that the bus gets initialized twice... dont know if thats an issue.


    next i entered the follwing command and noticed that the gpio3 (gpiochip2) pins hat the wrong direction mode:




    Futhermore i modified the spi-imc.c driver file and printed the return value of the gpio_direction_ouput call and also the cs pin numer

    see "spi_imx_setup: cs 78"

    and "spi_imx_setup: dir ret: 0" for example in the dmesg log at the top.

  • We have located the problem. It is a driver thing, rather complicated. Now we are looking for the easiest way to fix it. The patch should be available soon.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.

  • Ok, here is the explanation what happens.


    When starting up, the spi-imx.c driver calls a function to register the SPI controller. This function parses the device tree and collects all GPIO chip select numbers in an array. Then when the function returns, the driver calls gpio_request() for each entry in the array so that all these GPIOs can be used as chip selects afterwards.


    However the above function does much more than just collecting GPIO numbers. It also parses all sub-nodes in the SPI device tree node and creates a device for each of them. This actually leads to a call of function spi_imx_setup() for each device which is used to set the GPIO direction of the appropriate chip select to output. But as you can see, this happens *before* the original function returns to the probe function, where the GPIOs are requested. So the sequence, that a GPIO must be requested first before it can be used, is violated.


    On GPIO1, where other drivers already requested some GPIOs, this nonetheless works because the clock to this GPIO block is already active from the other GPIOs. But on GPIO3, where no other GPIOs are requested by other drivers, this fails because the clock is still off when the output direction should be set. The clock is only activated later by the gpio_request() call.


    This made it quite difficult to locate the problem. Of course I immediately thought of the clocks, but after the probe function, when the system is running, the clock to GPIO3 was active, too. So at first I did not understand at all why only the accesses to GPIO3 fail. It needed quite a lot of debug output and many many tries to understand that the clock is still off at the point of time when the GPIO direction is set.


    The attached patch will move the gpio_request() from the probe function to function spi_imx_setup(). This fixes the call sequence.


    Go to the Linux kernel source directory and call


    Code
    1. patch -p1 < 0001-spi-imx.c-Fix-GPIO-request-and-direction-sequence.patch


    Please note the less-than character '<' to redirect the input.


    Then recompile and reinstall the kernel. Now everything should work as expected. Sorry for the inconvenience.


    Your F&S Support Team

  • Ok, I see you are using git in your Linux kernel directory. This has the effect that the kernel version now has a "-dirty" attached. This means that the kernel does not find its modules (on the board) because they use a different path in /lib/modules/<version>. So one dirty trick would be to create a symbolic link there that redirects the new version to the old path ...


    Code
    1. cd /lib/modules
    2. ln -s <old-version> <new-version>


    If you can not log in, you probably have to reinstall the previous kernel, create the link and then go back again to the new kernel.


    Or you also have to rebuild the rootfs with all the modules, so that the module names match again the kernel version. A clean build should be done anyway after you are done with your development, when you have committed all your changes to git and when you build your own final version to be released to your customers. Then all "-dirty" settings should be gone.


    Your F&S Support Team

    F&S Elektronik Systeme GmbH
    As this is an international forum, please try to post in English.
    Da dies ein internationales Forum ist, bitten wir darum, Beiträge möglichst in Englisch zu verfassen.