/
SPI Zynq driver
SPI Zynq driver
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
- Slave 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
Important AR links
SPI Linux driver Slave mode support failure - AR-Link
SPI slave devices are not created - AR-Link
Kernel Configuration Options
The following config options need to be enabled for operating in Master Mode:CONFIG_SPI_CADENCE
It depends on:
CONFIG_SPI_MASTER
CONFIG_ARM
The following config options need to be enabled for operating in Slave Mode:
CONFIG_SPI_CADENCE
CONFIG_SPI_CADENCE
CONFIG_SPI_SLAVE=y
CONFIG_SPI_SLAVE_TIME=y
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
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.
#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
#/**/
#*SPI flash testing with flashcp
#*/
#To know MTD partion(partitions) is(are) present and size of partition(partitions)in flash
cat /proc/mtd
#Creating a file to be written to the flash
dd if=/dev/urandom of=./sample.bin bs=1024 count=900
#Write the file to the partition - this erases the partition, writes the file and verifies
flashcp -v ./smaple.bin /dev/mtd0
#/*
#*SPI flash testing with jffs2
#*/
#Erase a the whole partition with jffs2 markers
flash_eraseall -j /dev/mtd0
#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
#Write the file to the flash
cp ./sample.bin /spi_flash0/
#Check the presence of the file(s) in spi_flash0
ls /spi_flash0
#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.
CONFIG_SPI_SLAVE_TIME=y
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
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 treespi: 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
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
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
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
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
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
Erasing 4 Kibyte @ ff000 - 97% complete. Cleanmarker written at ff0000. Erasing 4 Kibyte @ 100000 - 100% complete
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
900+0 records in 900+0 records out 921600 bytes (900.0KB) copied, 0.706526 seconds, 1.2MB/s
cp ./sample.bin /spi_flash0/
#Check the presence of the file(s) in spi_flash0
ls /spi_flash0
sample.bin
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
jffs2 log: #flash_eraseall -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 #diff ./sample.bin /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
2024.2
2024.1
- Summary
- Reverse the order of interleaved operations
- Commits
- Summary
2023.2
2023.1
- Summary
- Replace all spi->chip_select and spi->cs_gpiod references with function call
- Commits
- Summary
2022.2
- Summary
- Fix SPI NO Slave Select macro definition
- Commits
- Summary
2022.1
- Summary
- None
- Commits
- None
- Summary
2021.2
2021.1
- Summary
- None
- Commits
- None
- Summary
Related Links
, multiple selections available,
Related content
Spips standalone driver
Spips standalone driver
Read with this
Zynq QSPI Driver
Zynq QSPI Driver
More like this
Linux Drivers
Linux Drivers
Read with this
Linux ZynqMP GQSPI Driver
Linux ZynqMP GQSPI Driver
More like this
Linux GPIO Driver
Linux GPIO Driver
Read with this
Linux SPI Driver
Linux SPI Driver
More like this
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy