7

I am running Arch Linux ARM on a Raspberry Pi 2 Model B, and I am attempting to communicate with a TFT display. I am writing a kernel module to interface with the display using SPI, and it works, but I cannot get the SPI frequency to go above 500 kHz. I have successfully used higher frequencies in the user space when using the BCM2835 library, so I know it is possible.

Using the following command to parse the device tree,

dtc -I fs /sys/firmware/devicetree/base | grep max-frequency

I can see that spi-max-frequency = <0x7735940>, which is hexadecimal for 150 MHz.

hexdump /sys/class/spi_master/spi0/of_node/spi-max-frequency

gives me 7307 4059, hexadecimal for the same number (just with the byte order reversed). In my kernel module, I do the following.

struct spi_board_info spiBoardInfo = {
    .modalias = "spi",
    .max_speed_hz = 32000000,
    .bus_num = 0,
    .chip_select = 0,
    .mode = 0
};

master = spi_busnum_to_master(spiBoardInfo.bus_num);
spiDevice = spi_new_device(master, &spiBoardInfo);
spiDevice->bits_per_word = 8;
ret = spi_setup(spiDevice);
printk(KERN_INFO "TFT: device max speed %ld\n", spiDevice->max_speed_hz);

which prints out 32000000, as expected (error checking code was removed above for brevity). To write to the slave, I use the following command

spi_write(spiDevice, &data, sizeof(data));

(I have also tried using spi_sync_transfer() and setting the speed there as well, to no avail). This command successfully writes the data, but at a speed of 500 kHz.

Does anyone know why I am being limited to this frequency?

EDIT

After investigating further, I strongly feel it has to do with the device tree. I added the following overlay

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2708";
    fragment@0 {
            target = <&spidev0>;
            __overlay__ {
                    status = "disabled";
            };
    };
    fragment@1 {
            target = <&spi0>;
            __overlay__ {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    status = "okay";
                    tft@0 {
                            compatible = "tft,st7789";
                            spi-max-frequency = <320000000>;
                            reg = <0>;
                    };
            };
    };
    __overrides__ {
            tft = <0>, "=0=1";
    };
};

and now receive

spi-bcm2835 3f204000.spi: chipselect 0 already in use

The name of my kernel module is tft, and the I do the following

static const struct of_device_id dtIDs[] = {
    {.compatible = "tft,st7789"},
    {}
};
MODULE_DEVICE_TABLE(of, dtIDs);

So it seems as if the SPI driver is not recognizing my kernel module as the owner of chipselect 0, and not letting me access SPI as a result. I feel as though, if I got this working, I would get the correct speeds, as the spi-max-frequency will have been directly set for my driver.

  • 150MHz is a configuration limit, but the GPIO drivers (transistors) are limited, in most conditions to 10MHz or less.Officially, when driven as a clock, with 1.2V IO Supply and minimal load, the maximum GPIO switching frequency is 125MHZ – crasic Jun 6 at 1:01
  • @crasic with the BCM2835 library I’m capable of getting at least 32 MHz. – Chris Loonam Jun 6 at 1:03
  • " I have successfully used higher frequencies in the user space when using the BCM2835 library, so I know it is possible." was this done on exactly the same setup hardware wise? – crasic Jun 6 at 1:03
  • Yes, identical. I actually can do them side by side, running the user space program using the library, and then using the kernel module. – Chris Loonam Jun 6 at 1:04
  • 1
    As confirmation of my rule of thumb (10MHz is conservative). Library doc says "Although it is possible to select high speeds for the SPI interface, up to 125MHz (see bcm2835_spi_setClockDivider()) you should not expect to actually achieve those sorts of speeds with the RPi wiring. Our tests on RPi 2 show that the SPI CLK line when unloaded has a resonant frequency of about 40MHz, and when loaded, the MOSI and MISO lines ring at an even lower frequency. Measurements show that SPI waveforms are very poor and unusable at 62 and 125MHz. Dont expect any speed faster than 31MHz to work reliably." – crasic Jun 6 at 1:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.