Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
Introduction

This page provides information about the Zynq/ZynqMP SPI driver which can be found on Xilinx GIT and mainline as spi-cadence.c.
Zynq/ZynqMP has two SPI hard IP. This is a Cadence IP. Some minor properties in the cadence IP offer multiple options which were customized as desirable.
This driver only supports master mode.
Detailed below are its use two slaves - EEPROM and flash.

HW IP Features

  • Master mode
  • All SPI flash instructions
  • Support for 3 slaves - can be extended using a 3

    Table of Contents
    Introduction

    This page provides information about the Zynq/ZynqMP SPI driver which can be found on Xilinx GIT and mainline as spi-cadence.c.
    Zynq/ZynqMP has two SPI hard IP. This is a Cadence IP. Some minor properties in the cadence IP offer multiple options which were customized as desirable.
    This driver supports master mode and slave modes.
    Detailed below are its use two slaves - EEPROM and flash.

    HW IP Features

    • Master mode
    • All SPI flash instructions
    • Support for 3 slaves - can be extended using a 3 to 8 decoder
    • Driver uses manual chip select and auto start options
    • Programmable clock frequency, polarity and phase
    • Interrupt support

    Missing Features and known Issues/Limitations in Driver

    • None

    Kernel Configuration Options

    The following config options need to be enabled:
    CONFIG_SPI_CADENCE
    It depends on:
    CONFIG_SPI_MASTER
    CONFIG_ARM
    Image Removed


    Device-tree

    Refer to Documentation/devicetree/bindings/spi/spi-cadence.txt for complete description.
    These are some specific points to be noted about the properties:
    - compatible string: This can be either cdns or xlnx compatible string.
    - num-cs: This is SOC specific - Since this driver is for the cadence IP in the mainline, this option is made available in the devicetree.
    - is-decoded-cs: This refers to whether a decoder is used to extend the existing chip selects.
    - spi-max-frequency - This should reflect the maximum frequency supported by the slave/master (or) user intends to use.
    - partitions - The size and number of these are user configurable and the sum should not exceed the total flash size.

    Using SPI with EEPROM

    Adding an SPI EEPROM to the devicetree

    The following example shows adding an SPI EEPROM to a device tree
    Code Block
    themeMidnight
    spi: spi@e0006000 {
         compatible = "xlnx,spi-zynq-r196";
         clock-names = "ref_clk", "pclk";
         clocks = <&&clkc 25>, <&&clkc 34>;
         interrupt-parent = <&&gic>;
         interrupts = <0 26 4>;
         num-cs = <4>;
         is-decoded-cs = <0>;
         reg = <0xe0006000 0x1000>;
         #address-cells = <1>;
         #size-cells = <0>;
         eeprom: at25@0 {
                 compatible = "atmel,at25";
                 at25,byte-len = <8192>;
                 at25,addr-mode = <2>;
                 at25,page-size = <32>;
                 reg = <2>;
                 spi-max-frequency = <1000000>;
         };
    };

    Using SPI with flash

    Adding an SPI flash to the devicetree

    Zynq:

    Note: The interrupt number and the controller register space information are mentioned in Zynq-7000 TRM

    Code Block
    themeMidnight
    spi: spi@e0007000 {
         compatible = "cdns,spi-r1p6";
         clock-names = "ref_clk", "pclk";
         clocks = <&&clkc 26>, <&&clkc 35>;
         interrupt-parent = <&&ps7_scugic_0>;
         interrupts = <0 49 4>;
         num-cs = <4>;
         is-decoded-cs = <0>;
         reg = <0xe0007000 0x1000>;
         #address-cells = <1>;
         #size-cells = <0>;
         flash@0 {
                 compatible = "sst25wf080";
                 reg = <1>;
                 spi-max-frequency = <1000000>;
                 #address-cells = <1>;
                 #size-cells = <1>;
                 partition@test {
                                label = "spi-flash";
                                reg = <0x0 0x100000>;
                 };
         };
    };

    ZynqMP:

    Note: The interrupt number and the controller register space information are mentioned in Zynq Ultrascale TRM

    Code Block
    themeMidnight
    spi0: spi@ff040000 {
        compatible = "cdns,spi-r1p6";
        interrupt-parent = <&&gic>;
        interrupts = <0 19 4>;
        reg = <0x0 0xff040000 0x0 0x1000>;
        clock-names = "ref_clk", "pclk";
        #address-cells = <1>;
        #size-cells = <0>;
        power-domains = <&&pd_spi0>;
        num-cs = <1>;
        pinctrl-names = "default";
        pinctrl-0 = <&&pinctrl_spi0_default>;
     
        spi0_flash0: spi0_flash0@0 {
                compatible = "m25p80";
            #address-cells = <1>;
            #size-cells = <1>;
            spi-max-frequency = <50000000>;
            reg = <0>;
                    spi0_flash0@00000000 {
              label = "spi0_flash0";
              reg = <0x0 0x100000>;
            };
           };
    };


    Test Procedure

    Testing using sysfs

    #/
    #SPI - eeprom testing
    #*/
    #check whether eeprom device is present or not .
    dmesg | grep eeprom
    #read from the EEPROM
    cat sys/bus/spi/devices/spi0.2/eeprom
    #write to the EEPROM
    echo "Hi this is testing the eeprom device through spi interface" > sys/bus/spi/devices/spi0.2/eeprom
    #read from the EEPROM to verify
    cat sys/bus/spi/devices/spi0.2/eeprom
    #/**/

    Testing using flashcp

    #/*
    #*SPI flash testing with flashcp
    #*/
    #To know MTD partion(partitions) is(are) present and size of partition(partitions)in flash
    cat /proc/mtd
    Code Block
    themeMidnight
    dev:    size   erasesize  name
    mtd0: 00100000 00001000 "spi-flash"

    #Creating a file to be written to the flash
    dd if=/dev/urandom of=./sample.bin bs=1024 count=900
    Code Block
    themeMidnight
    900+0 records in
    900+0 records out
    921600 bytes (900.0KB) copied, 0.706526 seconds, 1.2MB/s

    #Write the file to the partition - this erases the partition, writes the file and verifies
    flashcp -v ./smaple.bin /dev/mtd0
    Code Block
    themeMidnight
    Erasing block: 225/225 (100%)
    Writing kb: 896/900 (99%)
    Verifying kb: 896/900 (99%)

    Testing using jffs2

    #
    #/*
    #*SPI flash testing with jffs2
    #*/
    #Erase a the whole partition with jffs2 markers
    flash_eraseall -j /dev/mtd0
    Code Block
    themeMidnight
    Erasing 4 Kibyte @ ff000 - 97% complete. Cleanmarker written at ff0000.
    Erasing 4 Kibyte @ 100000 - 100% complete
    #create a directory
    mkdir spi_flash0
    #Mount the partition to spi_flash0
    mount -t jffs2 /dev/mtdblock0 /spi_flash0
    #Creating a file to be written to the flash
    dd if=/dev/urandom of=./sample.bin bs=1024 count=900
    Code Block
    themeMidnight
    900+0 records in
    900+0 records out
    921600 bytes (900.0KB) copied, 0.706526 seconds, 1.2MB/s
    #Write the file to the flash
    cp ./sample.bin /spi_flash0/
    #Check the presence of the file(s) in spi_flash0
    ls /spi_flash0
    Code Block
    themeMidnight
    sample.bin
    #Unmount
    umount spi_flash0
    #Mount again - MTD 0 to spi_flash0
    mount -t jffs2 /dev/mtdblock0 /spi_flash0
    #Compare the files - there should be no differences
    diff ./sample.bin /spi_flash0/sample.bin
    #Unmount
    umount spi_flash0

    #The data can be verified again after a power on reset if desired.

    Expected Output

    Code Block
    themeMidnight
    jffs2 log:
     
    #flash_eraseall  
    #flash_eraseall -j /dev/mtd0
    Erasing 4 Kibyte @ ff000 - 97% complete. Cleanmarker written at ff0000.
    Erasing 4 Kibyte @ 100000 - 100% complete
    #mkdir-j /dev/mtd0
    Erasing 4 Kibyte @ ff000 - 97% complete. Cleanmarker written at ff0000.
    Erasing 4 Kibyte @ 100000 - 100% complete
    #mkdir spi_flash0
    #mount -t jffs2 /dev/mtdblock0 /spi_flash0
    #dd if=/dev/urandom of=./sample.bin bs=1024 count=900
    900+0 records in
    900+0 records out
    921600 bytes (900.0KB) copied, 0.706526 seconds, 1.2MB/s
    #cp ./sample.bin /spi_flash0/
    #ls /spi_flash0
    sample.bin
    #umount spi_flash0
    #mount -t jffs2 /dev/mtdblock0 /spi_flash0
    #dd if=/dev/urandom of=#diff ./sample.bin bs=1024 count=900
    900+0 records in
    900+0 records out
    921600 bytes (900.0KB) copied, 0.706526 seconds, 1.2MB/s
    #cp ./sample.bin /spi_flash0/
    #ls /spi_flash0
    sample.bin
    #umount spi_flash0
    #mount -t jffs2 /dev/mtdblock0 /spi_flash0
    #diff ./sample.bin /spi_flash0/sample.bin
     
     

    Change Log

  • 2016.3

    • Summary
      • Use to_platform_devive( ) api
    • Commits
  • 2016
    /spi_flash0/sample.bin
     
     

    SPI Slave Support

    See the following page: Linux PS SPI Slave Mode.

    Mainline Status

    In sync with mainline driver.

    Change Log

    • 2016.3

      • Summary
        • Use to_platform_devive( ) api
      • Commits
    • 2016.4

      • Summary
        • None
      • Commits
        • None
    • 2017.1

      • Summary
        • Fix checkpatch warning
        • Remove _MASK and _OFFSET suffix
        • Fix probe error handling
        • Fix kernel doc warning
        • Add runtime pm adaptation
        • Remove the clock enable and disable from suspend and resume
        • Return the error code for cdns_spi_suspend and cdns_spi_resume
        • Fix some checkpatch warnings
        • mark pm functions __maybe_unused
      • Commits
    • 2017.2

      • Summary
        • Add support for context loss
      • Commits
    • 2017.3

      • Summary
        • Update PM APIs sequence of calling

    • 2017.4

      • Summary
        • None
      • Commits
        • None
    • 2017

      2018.1

      • Summary
        • None
      • Commits
        • None
    • 2018.2

      2017.4
      • Summary
        • Fix checkpatch warning
        • Remove _MASK and _OFFSET suffix
        • Fix probe error handling
        • Fix kernel doc warning
        • Add runtime pm adaptation
        • Remove the clock enable and disable from suspend and resume
        • Return the error code for cdns_spi_suspend and cdns_spi_resume
        • Fix some checkpatch warnings
        • mark pm functions __maybe_unused
      • Commits
    • 2017.2

      • Summary
        • Add support for context loss
      • Commits
    • 2017.3

      • Summary
        • Update PM APIs sequence of calling
        • None
      • Commits
        • None
    • 2018.3

      • Summary
        • None
      • Commits
        • None
    • 2019.1

      • Summary
        • Add usleep_range() for cdns_spi_fill_tx_fifo() 
        • Change usleep_range() to udelay(), for atomic context
        • Fix missing clk_disable_unprepare() on error in cnds_runtime_resume()
        • Initialize and power up the hardware before enabling PM runtime.
      • Commits
    • 2019.2

      • Summary
        • None
      • Commits
        • None
    • 2018

      2020.1

      2018.3
      • Summary
        • None
      • Commits
        • None
    • 2018.2

      • Summary
        • None
      • Commits
        • None
        • Fix default polarity of native chipselect
        • Remove dev_err() usage after platform_get_irq()
        • use devm_platform_ioremap_resource() to simplify code
      • Commits
    • 2020.2

      • Summary
        • Fix mixed_enum_type coverity warning
        • Fix uninit_use coverity warning
      • Commits
    • 2021.1

      • Summary
        • None
      • Commits
        • None
      2019
    • 2021.

      1

      2

      • Summary
        • Add usleep_range() for cdns_spi_fill_tx_fifo() 
        • Change usleep_range() to udelay(), for atomic context
        • Fix missing clk_disable_unprepare() on error in cnds_runtime_resume()
        • Initialize and power up the hardware before enabling PM runtime.
      • Commits
      2019.2
        • Fix SPI CS gets toggling sporadically
        • Align function names
        • Fix kernel-doc format for resume/suspend
      • Commits
    • 2022.1

      • Summary
        • None
      • Commits
        • None
      2020
    • 2022.

      1

      2

      • Summary
        • Fix default polarity of native chipselect
        • Remove dev_err() usage after platform_get_irq()
        • use devm_platform_ioremap_resource() to simplify code
      • Commits
      2020
        • SPI NO Slave Select macro definition
      • Commits
    • 2023.1

      • Summary
        • Replace all spi->chip_select and spi->cs_gpiod references with function call
      • Commits
    • 2023.2

      • Summary
        • Fix mixed_enum_type coverity warning
        • Fix uninit_use coverity warning
        Commits
        • fe4403b
        • e331b37Add support for Slave mode
        • Fix transfer timeout issue
        • Update irq sequence for read opeation
      • Commits

    Related Links

    ...