spi/sf: Cleansup and driver model conversions
Subsystems (4)
v2 cover spi/sf: Cleansup and driver model conversions
No minor updates on code.
Changes for v2:
- One change suggested from Simon to use dev_get_parent
thanks!
Jagan.
Jagan Teki (17):
spi: Zap andes_spi driver
spi: Zap ftssp010_spi driver
spi: Zap oc_tiny_spi driver
spi: xilinx_spi: Move header code to driver
spi: xilinx_spi: Driver clean-up
spi: davinci_spi: Move header code to driver
spi: davinci_spi: Driver cleanup
spi/sf: Minor cleanups
dm: spi: zynq_spi: Convert to driver model
zynq: Kconfig: Enable dm spi and spi_flash
dts: zynq: Add zynq spi controller nodes
spi: zynq_spi: Add fdt support in driver
dts: zynq: Enable spi1 for zc770_xm010 board
dm: spi: xilinx_spi: Convert to driver model
spi: xilinx_spi: Add asm/io.h include file
spi: Kconfig: Add Zynq QSPI controller entry
spi: Kconfig: Add Zynq SPI controller entry
arch/arm/Kconfig | 2 + arch/arm/dts/zynq-7000.dtsi | 26 ++ arch/arm/dts/zynq-zc770-xm010.dts | 4 + doc/device-tree-bindings/spi/spi-zynq.txt | 29 ++ drivers/mtd/spi/sf_internal.h | 18 +- drivers/spi/Kconfig | 17 + drivers/spi/Makefile | 3 - drivers/spi/andes_spi.c | 284 ----------------- drivers/spi/andes_spi.h | 115 ------- drivers/spi/davinci_spi.c | 369 ++++++++++++++-------- drivers/spi/davinci_spi.h | 121 -------- drivers/spi/ftssp010_spi.c | 498 ------------------------------ drivers/spi/oc_tiny_spi.c | 245 --------------- drivers/spi/xilinx_spi.c | 330 +++++++++++++------- drivers/spi/xilinx_spi.h | 138 --------- drivers/spi/zynq_spi.c | 312 +++++++++++-------- include/spi.h | 2 +- include/spi_flash.h | 10 +- 18 files changed, 734 insertions(+), 1789 deletions(-) create mode 100644 doc/device-tree-bindings/spi/spi-zynq.txt delete mode 100644 drivers/spi/andes_spi.c delete mode 100644 drivers/spi/andes_spi.h delete mode 100644 drivers/spi/davinci_spi.h delete mode 100644 drivers/spi/ftssp010_spi.c delete mode 100644 drivers/spi/oc_tiny_spi.c delete mode 100644 drivers/spi/xilinx_spi.h
Signature · 1 line
1.9.1
PATCH v2 1/17 spi: Zap andes_spi driver
Zap andes_spi driver since the boards used this driver is no longer been active.
--- drivers/spi/Makefile | 1 - drivers/spi/andes_spi.c | 284 ------------------------------------------------ drivers/spi/andes_spi.h | 115 -------------------- 3 files changed, 400 deletions(-) delete mode 100644 drivers/spi/andes_spi.c delete mode 100644 drivers/spi/andes_spi.h
drivers/spi/Makefile +0 -1
@@ -17,7 +17,6 @@ endif obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o obj-$(CONFIG_ALTERA_SPI) += altera_spi.o -obj-$(CONFIG_ANDES_SPI) += andes_spi.o obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
drivers/spi/andes_spi.c deleted +0 -284
284 lines not on this page · raw message
drivers/spi/andes_spi.h deleted +0 -115
115 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 2/17 spi: Zap ftssp010_spi driver
In reply to Jagan TekiZap ftssp010_spi driver since the boards used this driver is no longer been active.
--- drivers/spi/Makefile | 1 - drivers/spi/ftssp010_spi.c | 498 --------------------------------------------- 2 files changed, 499 deletions(-) delete mode 100644 drivers/spi/ftssp010_spi.c
drivers/spi/Makefile +0 -1
@@ -28,7 +28,6 @@ obj-$(CONFIG_CF_QSPI) += cf_qspi.o obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o -obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o
drivers/spi/ftssp010_spi.c deleted +0 -498
498 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 3/17 spi: Zap oc_tiny_spi driver
In reply to Jagan TekiZap oc_tiny_spi driver since the boards used this driver is no longer been active.
--- drivers/spi/Makefile | 1 - drivers/spi/oc_tiny_spi.c | 245 ---------------------------------------------- 2 files changed, 246 deletions(-) delete mode 100644 drivers/spi/oc_tiny_spi.c
drivers/spi/Makefile +0 -1
@@ -35,7 +35,6 @@ obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.o obj-$(CONFIG_MXS_SPI) += mxs_spi.o -obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o obj-$(CONFIG_SH_SPI) += sh_spi.o
drivers/spi/oc_tiny_spi.c deleted +0 -245
245 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 4/17 spi: xilinx_spi: Move header code to driver
In reply to Jagan TekiMove the header code into driver for more readable and easy to access it.
--- drivers/spi/xilinx_spi.c | 113 +++++++++++++++++++++++++++++++++++++- drivers/spi/xilinx_spi.h | 138 ----------------------------------------------- 2 files changed, 112 insertions(+), 139 deletions(-) delete mode 100644 drivers/spi/xilinx_spi.h
drivers/spi/xilinx_spi.c +112 -1
@@ -21,7 +21,118 @@#include <malloc.h> #include <spi.h> -#include "xilinx_spi.h" +/* +* Xilinx SPI Register Definition +* +* [1]: [0]/ip_documentation/xps_spi.pdf +* page 8, Register Descriptions +* [2]: [0]/ip_documentation/axi_spi_ds742.pdf +* page 7, Register Overview Table +*/ +struct xilinx_spi_reg { +u32 __space0__[7 ]; +u32 dgier;/* Device Global Interrupt Enable Register (DGIER) */ +u32 ipisr;/* IP Interrupt Status Register (IPISR) */ +u32 __space1__; +u32 ipier;/* IP Interrupt Enable Register (IPIER) */ +u32 __space2__[5 ]; +u32 srr;/* Softare Reset Register (SRR) */ +u32 __space3__[7 ]; +u32 spicr;/* SPI Control Register (SPICR) */ +u32 spisr;/* SPI Status Register (SPISR) */ +u32 spidtr;/* SPI Data Transmit Register (SPIDTR) */ +u32 spidrr;/* SPI Data Receive Register (SPIDRR) */ +u32 spissr;/* SPI Slave Select Register (SPISSR) */ +u32 spitfor;/* SPI Transmit FIFO Occupancy Register (SPITFOR) */ +u32 spirfor;/* SPI Receive FIFO Occupancy Register (SPIRFOR) */ +}; + +/* Device Global Interrupt Enable Register (dgier), [1] p15, [2] p15 */ +#define DGIER_GIE (1 << 31) + +/* IP Interrupt Status Register (ipisr), [1] p15, [2] p15 */ +#define IPISR_DRR_NOT_EMPTY (1 << 8) +#define IPISR_SLAVE_SELECT (1 << 7) +#define IPISR_TXF_HALF_EMPTY (1 << 6) +#define IPISR_DRR_OVERRUN (1 << 5) +#define IPISR_DRR_FULL (1 << 4) +#define IPISR_DTR_UNDERRUN (1 << 3) +#define IPISR_DTR_EMPTY (1 << 2) +#define IPISR_SLAVE_MODF (1 << 1) +#define IPISR_MODF (1 << 0) + +/* IP Interrupt Enable Register (ipier), [1] p17, [2] p18 */ +#define IPIER_DRR_NOT_EMPTY (1 << 8) +#define IPIER_SLAVE_SELECT (1 << 7) +#define IPIER_TXF_HALF_EMPTY (1 << 6) +#define IPIER_DRR_OVERRUN (1 << 5) +#define IPIER_DRR_FULL (1 << 4) +#define IPIER_DTR_UNDERRUN (1 << 3) +#define IPIER_DTR_EMPTY (1 << 2) +#define IPIER_SLAVE_MODF (1 << 1) +#define IPIER_MODF (1 << 0) + +/* Softare Reset Register (srr), [1] p9, [2] p8 */ +#define SRR_RESET_CODE 0x0000000A + +/* SPI Control Register (spicr), [1] p9, [2] p8 */ +#define SPICR_LSB_FIRST (1 << 9) +#define SPICR_MASTER_INHIBIT (1 << 8) +#define SPICR_MANUAL_SS (1 << 7) +#define SPICR_RXFIFO_RESEST (1 << 6) +#define SPICR_TXFIFO_RESEST (1 << 5) +#define SPICR_CPHA (1 << 4) +#define SPICR_CPOL (1 << 3) +#define SPICR_MASTER_MODE (1 << 2) +#define SPICR_SPE (1 << 1) +#define SPICR_LOOP (1 << 0) + +/* SPI Status Register (spisr), [1] p11, [2] p10 */ +#define SPISR_SLAVE_MODE_SELECT (1 << 5) +#define SPISR_MODF (1 << 4) +#define SPISR_TX_FULL (1 << 3) +#define SPISR_TX_EMPTY (1 << 2) +#define SPISR_RX_FULL (1 << 1) +#define SPISR_RX_EMPTY (1 << 0) + +/* SPI Data Transmit Register (spidtr), [1] p12, [2] p12 */ +#define SPIDTR_8BIT_MASK (0xff << 0) +#define SPIDTR_16BIT_MASK (0xffff << 0) +#define SPIDTR_32BIT_MASK (0xffffffff << 0) + +/* SPI Data Receive Register (spidrr), [1] p12, [2] p12 */ +#define SPIDRR_8BIT_MASK (0xff << 0) +#define SPIDRR_16BIT_MASK (0xffff << 0) +#define SPIDRR_32BIT_MASK (0xffffffff << 0) + +/* SPI Slave Select Register (spissr), [1] p13, [2] p13 */ +#define SPISSR_MASK (cs) (1 << (cs)) +#define SPISSR_ACT (cs) ~SPISSR_MASK(cs) +#define SPISSR_OFF ~0UL + +/* SPI Transmit FIFO Occupancy Register (spitfor), [1] p13, [2] p14 */ +#define SPITFOR_OCYVAL_POS 0 +#define SPITFOR_OCYVAL_MASK (0xf << SPITFOR_OCYVAL_POS) + +/* SPI Receive FIFO Occupancy Register (spirfor), [1] p14, [2] p14 */ +#define SPIRFOR_OCYVAL_POS 0 +#define SPIRFOR_OCYVAL_MASK (0xf << SPIRFOR_OCYVAL_POS) + +/* SPI Software Reset Register (ssr) */ +#define SPISSR_RESET_VALUE 0x0a + +struct xilinx_spi_slave { +struct spi_slave slave; +struct xilinx_spi_reg *regs; +unsigned int freq; +unsigned int mode; +}; + +static inline struct xilinx_spi_slave *to_xilinx_spi_slave ( +struct spi_slave *slave) +{ + return container_of(slave, struct xilinx_spi_slave, slave); +}#ifndef CONFIG_SYS_XILINX_SPI_LIST #define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE }
drivers/spi/xilinx_spi.h deleted +0 -138
138 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 5/17 spi: xilinx_spi: Driver clean-up
In reply to Jagan Teki- Zap unneeded macros
- Re-arrange the code
- Removed __attribute__((weak))
- Replace __func__ macro with func names to save macro transition.
- Re-arranged comment lines.
- Arrange driver code in more readable format[1]
[1] http://patchwork.ozlabs.org/patch/265683/
--- drivers/spi/xilinx_spi.c | 164 ++++++++++++++++------------------------------- 1 file changed, 57 insertions(+), 107 deletions(-)
drivers/spi/xilinx_spi.c +57 -107
@@ -1,79 +1,31 @@/* * Xilinx SPI driver * -* supports 8 bit SPI transfers only, with or w/o FIFO +* Supports 8 bit SPI transfers only, with or w/o FIFO * -* based on bfin_spi.c, by way of altera_spi.c -* Copyright (c) 2005-2008 Analog Devices Inc. -* Copyright (c) 2010 Thomas Chou <[email protected]> -* Copyright (c) 2010 Graeme Smecher <[email protected]> +* Based on bfin_spi.c, by way of altera_spi.c * Copyright (c) 2012 Stephan Linz <[email protected]> +* Copyright (c) 2010 Graeme Smecher <[email protected]> +* Copyright (c) 2010 Thomas Chou <[email protected]> +* Copyright (c) 2005-2008 Analog Devices Inc. * * SPDX-License-Identifier: GPL-2.0+ -* -* [0]: http://www.xilinx.com/support/documentation -* -* [S]: [0]/ip_documentation/xps_spi.pdf -* [0]/ip_documentation/axi_spi_ds742.pdf */ +#include <config.h> #include <common.h> #include <malloc.h> #include <spi.h> /* -* Xilinx SPI Register Definition +* [0]: http://www.xilinx.com/support/documentation * +* Xilinx SPI Register Definitions * [1]: [0]/ip_documentation/xps_spi.pdf * page 8, Register Descriptions * [2]: [0]/ip_documentation/axi_spi_ds742.pdf * page 7, Register Overview Table */ -struct xilinx_spi_reg { -u32 __space0__[7 ]; -u32 dgier;/* Device Global Interrupt Enable Register (DGIER) */ -u32 ipisr;/* IP Interrupt Status Register (IPISR) */ -u32 __space1__; -u32 ipier;/* IP Interrupt Enable Register (IPIER) */ -u32 __space2__[5 ]; -u32 srr;/* Softare Reset Register (SRR) */ -u32 __space3__[7 ]; -u32 spicr;/* SPI Control Register (SPICR) */ -u32 spisr;/* SPI Status Register (SPISR) */ -u32 spidtr;/* SPI Data Transmit Register (SPIDTR) */ -u32 spidrr;/* SPI Data Receive Register (SPIDRR) */ -u32 spissr;/* SPI Slave Select Register (SPISSR) */ -u32 spitfor;/* SPI Transmit FIFO Occupancy Register (SPITFOR) */ -u32 spirfor;/* SPI Receive FIFO Occupancy Register (SPIRFOR) */ -}; - -/* Device Global Interrupt Enable Register (dgier), [1] p15, [2] p15 */ -#define DGIER_GIE (1 << 31) - -/* IP Interrupt Status Register (ipisr), [1] p15, [2] p15 */ -#define IPISR_DRR_NOT_EMPTY (1 << 8) -#define IPISR_SLAVE_SELECT (1 << 7) -#define IPISR_TXF_HALF_EMPTY (1 << 6) -#define IPISR_DRR_OVERRUN (1 << 5) -#define IPISR_DRR_FULL (1 << 4) -#define IPISR_DTR_UNDERRUN (1 << 3) -#define IPISR_DTR_EMPTY (1 << 2) -#define IPISR_SLAVE_MODF (1 << 1) -#define IPISR_MODF (1 << 0) - -/* IP Interrupt Enable Register (ipier), [1] p17, [2] p18 */ -#define IPIER_DRR_NOT_EMPTY (1 << 8) -#define IPIER_SLAVE_SELECT (1 << 7) -#define IPIER_TXF_HALF_EMPTY (1 << 6) -#define IPIER_DRR_OVERRUN (1 << 5) -#define IPIER_DRR_FULL (1 << 4) -#define IPIER_DTR_UNDERRUN (1 << 3) -#define IPIER_DTR_EMPTY (1 << 2) -#define IPIER_SLAVE_MODF (1 << 1) -#define IPIER_MODF (1 << 0) - -/* Softare Reset Register (srr), [1] p9, [2] p8 */ -#define SRR_RESET_CODE 0x0000000A/* SPI Control Register (spicr), [1] p9, [2] p8 */ #define SPICR_LSB_FIRST (1 << 9)
@@ -110,17 +62,42 @@ struct xilinx_spi_reg {#define SPISSR_ACT (cs) ~SPISSR_MASK(cs)#define SPISSR_OFF ~0UL -/* SPI Transmit FIFO Occupancy Register (spitfor), [1] p13, [2] p14 */ -#define SPITFOR_OCYVAL_POS 0 -#define SPITFOR_OCYVAL_MASK (0xf << SPITFOR_OCYVAL_POS) - -/* SPI Receive FIFO Occupancy Register (spirfor), [1] p14, [2] p14 */ -#define SPIRFOR_OCYVAL_POS 0 -#define SPIRFOR_OCYVAL_MASK (0xf << SPIRFOR_OCYVAL_POS) -/* SPI Software Reset Register (ssr) */ #define SPISSR_RESET_VALUE 0x0a +#define XILSPI_MAX_XFER_BITS 8 +#define XILSPI_SPICR_DFLT_ON (SPICR_MANUAL_SS | SPICR_MASTER_MODE | \ + SPICR_SPE) +#define XILSPI_SPICR_DFLT_OFF (SPICR_MASTER_INHIBIT | SPICR_MANUAL_SS) + +#ifndef CONFIG_XILINX_SPI_IDLE_VAL +#define CONFIG_XILINX_SPI_IDLE_VAL 0xff +#endif + +#ifndef CONFIG_SYS_XILINX_SPI_LIST +#define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE } +#endif + +/* xilinx spi register set */ +struct xilinx_spi_reg { +u32 __space0__[7 ]; +u32 dgier;/* Device Global Interrupt Enable Register (DGIER) */ +u32 ipisr;/* IP Interrupt Status Register (IPISR) */ +u32 __space1__; +u32 ipier;/* IP Interrupt Enable Register (IPIER) */ +u32 __space2__[5 ]; +u32 srr;/* Softare Reset Register (SRR) */ +u32 __space3__[7 ]; +u32 spicr;/* SPI Control Register (SPICR) */ +u32 spisr;/* SPI Status Register (SPISR) */ +u32 spidtr;/* SPI Data Transmit Register (SPIDTR) */ +u32 spidrr;/* SPI Data Receive Register (SPIDRR) */ +u32 spissr;/* SPI Slave Select Register (SPISSR) */ +u32 spitfor;/* SPI Transmit FIFO Occupancy Register (SPITFOR) */ +u32 spirfor;/* SPI Receive FIFO Occupancy Register (SPIRFOR) */ +}; + +/* xilinx spi slave */ struct xilinx_spi_slave {struct spi_slave slave;struct xilinx_spi_reg *regs;
@@ -129,37 +106,17 @@ struct xilinx_spi_slave { };static inline struct xilinx_spi_slave *to_xilinx_spi_slave ( -struct spi_slave *slave) +struct spi_slave *slave) { return container_of(slave, struct xilinx_spi_slave, slave); } -#ifndef CONFIG_SYS_XILINX_SPI_LIST -#define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE } -#endif - -#ifndef CONFIG_XILINX_SPI_IDLE_VAL -#define CONFIG_XILINX_SPI_IDLE_VAL 0xff -#endif - -#define XILSPI_SPICR_DFLT_ON (SPICR_MANUAL_SS | \ - SPICR_MASTER_MODE | \ - SPICR_SPE) - -#define XILSPI_SPICR_DFLT_OFF (SPICR_MASTER_INHIBIT | \ - SPICR_MANUAL_SS) - -#define XILSPI_MAX_XFER_BITS 8 -static unsigned long xilinx_spi_base_list[] =CONFIG_SYS_XILINX_SPI_LIST ; - -__attribute__((weak))int spi_cs_is_valid (unsigned int bus,unsigned int cs) {return bus <ARRAY_SIZE (xilinx_spi_base_list) && cs <32 ; } -__attribute__((weak))void spi_cs_activate (struct spi_slave *slave) {struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave);
@@ -167,7 +124,6 @@ void spi_cs_activate(struct spi_slave *slave)writel (SPISSR_ACT (slave->cs), &xilspi->regs->spissr); } -__attribute__((weak))void spi_cs_deactivate (struct spi_slave *slave) {struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave);
@@ -180,33 +136,26 @@ void spi_init(void)/* do nothing */ } -void spi_set_speed (struct spi_slave *slave,uint hz) -{ -/* xilinx spi core does not support programmable speed */ -} -struct spi_slave *spi_setup_slave (unsigned int bus,unsigned int cs,unsigned int max_hz,unsigned int mode) {struct xilinx_spi_slave *xilspi;if (!spi_cs_is_valid (bus, cs)) { -printf ("XILSPI error: %s: unsupported bus %d / cs %d\n" , - __func__, bus, cs); +printf ("XILSPI error: unsupported bus %d / cs %d\n" , bus, cs);return NULL ; } xilspi = spi_alloc_slave(struct xilinx_spi_slave, bus, cs);if (!xilspi) { -printf ("XILSPI error: %s: malloc of SPI structure failed\n" , - __func__); +printf ("XILSPI error: malloc of SPI structure failed\n" );return NULL ; } xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus]; xilspi->freq = max_hz; xilspi->mode = mode; -debug ("%s: bus:%i cs:%i base:%p mode:%x max_hz:%d\n" , __func__, - bus, cs, xilspi->regs, xilspi->mode, xilspi->freq); +debug ("spi_setup_slave: bus:%i cs:%i base:%p mode:%x max_hz:%d\n" , + bus, cs, xilspi->regs, xilspi->mode, xilspi->freq);writel (SPISSR_RESET_VALUE , &xilspi->regs->srr);
@@ -225,7 +174,7 @@ int spi_claim_bus(struct spi_slave *slave)struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave);u32 spicr; -debug ("%s: bus:%i cs:%i\n" , __func__, slave->bus, slave->cs); +debug ("spi_claim_bus: bus:%i cs:%i\n" , slave->bus, slave->cs);writel (SPISSR_OFF , &xilspi->regs->spissr); spicr =XILSPI_SPICR_DFLT_ON ;
@@ -246,7 +195,7 @@ void spi_release_bus(struct spi_slave *slave) {struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); -debug ("%s: bus:%i cs:%i\n" , __func__, slave->bus, slave->cs); +debug ("spi_release_bus: bus:%i cs:%i\n" , slave->bus, slave->cs);writel (SPISSR_OFF , &xilspi->regs->spissr);writel (XILSPI_SPICR_DFLT_OFF , &xilspi->regs->spicr); }
@@ -262,14 +211,15 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,unsigned rxecount =17 ;/* max. 16 elements in FIFO, leftover 1 */ unsigned global_timeout; -debug ("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n" , __func__, - slave->bus, slave->cs, bitlen, bytes, flags); +debug ("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n" , + slave->bus, slave->cs, bitlen, bytes, flags); +if (bitlen ==0 ) goto done;if (bitlen %XILSPI_MAX_XFER_BITS ) { -printf ("XILSPI warning: %s: Not a multiple of %d bits\n" , - __func__,XILSPI_MAX_XFER_BITS ); +printf ("XILSPI warning: Not a multiple of %d bits\n" , +XILSPI_MAX_XFER_BITS ); flags |=SPI_XFER_END ; goto done; }
@@ -281,7 +231,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }if (!rxecount) { -printf ("XILSPI error: %s: Rx buffer not empty\n" , __func__); +printf ("XILSPI error: Rx buffer not empty\n" );return -1 ; }
@@ -296,7 +246,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,unsigned timeout = global_timeout;/* get Tx element from data out buffer and count up */ unsigned char d = txp ? *txp++ :CONFIG_XILINX_SPI_IDLE_VAL ; -debug ("%s: tx:%x " , __func__, d); +debug ("spi_xfer: tx:%x " , d);/* write out and wait for processing (receive data) */ writel (d &SPIDTR_8BIT_MASK , &xilspi->regs->spidtr);
@@ -307,7 +257,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }if (!timeout) { -printf ("XILSPI error: %s: Xfer timeout\n" , __func__); +printf ("XILSPI error: Xfer timeout\n" );return -1 ; }
@@ -315,7 +265,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, d =readl (&xilspi->regs->spidrr) &SPIDRR_8BIT_MASK ;if (rxp) *rxp++ = d; -debug ("rx:%x\n" , d); +debug ("spi_xfer: rx:%x\n" , d); } done:
Signature · 1 line
1.9.1
PATCH v2 6/17 spi: davinci_spi: Move header code to driver
In reply to Jagan TekiMove the header code into driver for more readable and easy to access it.
--- drivers/spi/davinci_spi.c | 110 ++++++++++++++++++++++++++++++++++++++++- drivers/spi/davinci_spi.h | 121 ---------------------------------------------- 2 files changed, 109 insertions(+), 122 deletions(-) delete mode 100644 drivers/spi/davinci_spi.h
drivers/spi/davinci_spi.c +109 -1
@@ -13,7 +13,115 @@#include <malloc.h> #include <asm/io.h> #include <asm/arch/hardware.h> -#include "davinci_spi.h" + +struct davinci_spi_regs { +dv_reg gcr0;/* 0x00 */ +dv_reg gcr1;/* 0x04 */ +dv_reg int0;/* 0x08 */ +dv_reg lvl;/* 0x0c */ +dv_reg flg;/* 0x10 */ +dv_reg pc0;/* 0x14 */ +dv_reg pc1;/* 0x18 */ +dv_reg pc2;/* 0x1c */ +dv_reg pc3;/* 0x20 */ +dv_reg pc4;/* 0x24 */ +dv_reg pc5;/* 0x28 */ +dv_reg rsvd[3 ]; +dv_reg dat0;/* 0x38 */ +dv_reg dat1;/* 0x3c */ +dv_reg buf;/* 0x40 */ +dv_reg emu;/* 0x44 */ +dv_reg delay;/* 0x48 */ +dv_reg def;/* 0x4c */ +dv_reg fmt0;/* 0x50 */ +dv_reg fmt1;/* 0x54 */ +dv_reg fmt2;/* 0x58 */ +dv_reg fmt3;/* 0x5c */ +dv_reg intvec0;/* 0x60 */ +dv_reg intvec1;/* 0x64 */ +}; + +#define BIT (x) (1 << (x)) + +/* SPIGCR0 */ +#define SPIGCR0_SPIENA_MASK 0x1 +#define SPIGCR0_SPIRST_MASK 0x0 + +/* SPIGCR0 */ +#define SPIGCR1_CLKMOD_MASK BIT(1) +#define SPIGCR1_MASTER_MASK BIT(0) +#define SPIGCR1_SPIENA_MASK BIT(24) + +/* SPIPC0 */ +#define SPIPC0_DIFUN_MASK BIT(11)/* SIMO */ +#define SPIPC0_DOFUN_MASK BIT(10)/* SOMI */ +#define SPIPC0_CLKFUN_MASK BIT(9)/* CLK */ +#define SPIPC0_EN0FUN_MASK BIT(0) + +/* SPIFMT0 */ +#define SPIFMT_SHIFTDIR_SHIFT 20 +#define SPIFMT_POLARITY_SHIFT 17 +#define SPIFMT_PHASE_SHIFT 16 +#define SPIFMT_PRESCALE_SHIFT 8 + +/* SPIDAT1 */ +#define SPIDAT1_CSHOLD_SHIFT 28 +#define SPIDAT1_CSNR_SHIFT 16 + +/* SPIDELAY */ +#define SPI_C2TDELAY_SHIFT 24 +#define SPI_T2CDELAY_SHIFT 16 + +/* SPIBUF */ +#define SPIBUF_RXEMPTY_MASK BIT(31) +#define SPIBUF_TXFULL_MASK BIT(29) + +/* SPIDEF */ +#define SPIDEF_CSDEF0_MASK BIT(0) + +#define SPI0_BUS 0 +#define SPI0_BASE CONFIG_SYS_SPI_BASE +/* +* Define default SPI0_NUM_CS as 1 for existing platforms that uses this +* driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS +* if more than one CS is supported and by defining CONFIG_SYS_SPI0. +*/ +#ifndef CONFIG_SYS_SPI0 +#define SPI0_NUM_CS 1 +#else +#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS +#endif + +/* +* define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and +* CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus +*/ +#ifdef CONFIG_SYS_SPI1 +#define SPI1_BUS 1 +#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS +#define SPI1_BASE CONFIG_SYS_SPI1_BASE +#endif + +/* +* define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and +* CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus +*/ +#ifdef CONFIG_SYS_SPI2 +#define SPI2_BUS 2 +#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS +#define SPI2_BASE CONFIG_SYS_SPI2_BASE +#endif + +struct davinci_spi_slave { +struct spi_slave slave; +struct davinci_spi_regs *regs; +unsigned int freq; +}; + +static inline struct davinci_spi_slave *to_davinci_spi (struct spi_slave *slave) +{ + return container_of(slave, struct davinci_spi_slave, slave); +}void spi_init () {
drivers/spi/davinci_spi.h deleted +0 -121
121 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 7/17 spi: davinci_spi: Driver cleanup
In reply to Jagan TekiArrange driver code in more readable format[1] for easy accessing and readable.
[1] http://patchwork.ozlabs.org/patch/265683/
--- drivers/spi/davinci_spi.c | 343 +++++++++++++++++++++++----------------------- 1 file changed, 173 insertions(+), 170 deletions(-)
drivers/spi/davinci_spi.c +173 -170
@@ -8,39 +8,13 @@* * SPDX-License-Identifier: GPL-2.0+ */ +#include <common.h> #include <spi.h> #include <malloc.h> #include <asm/io.h> #include <asm/arch/hardware.h> -struct davinci_spi_regs { -dv_reg gcr0;/* 0x00 */ -dv_reg gcr1;/* 0x04 */ -dv_reg int0;/* 0x08 */ -dv_reg lvl;/* 0x0c */ -dv_reg flg;/* 0x10 */ -dv_reg pc0;/* 0x14 */ -dv_reg pc1;/* 0x18 */ -dv_reg pc2;/* 0x1c */ -dv_reg pc3;/* 0x20 */ -dv_reg pc4;/* 0x24 */ -dv_reg pc5;/* 0x28 */ -dv_reg rsvd[3 ]; -dv_reg dat0;/* 0x38 */ -dv_reg dat1;/* 0x3c */ -dv_reg buf;/* 0x40 */ -dv_reg emu;/* 0x44 */ -dv_reg delay;/* 0x48 */ -dv_reg def;/* 0x4c */ -dv_reg fmt0;/* 0x50 */ -dv_reg fmt1;/* 0x54 */ -dv_reg fmt2;/* 0x58 */ -dv_reg fmt3;/* 0x5c */ -dv_reg intvec0;/* 0x60 */ -dv_reg intvec1;/* 0x64 */ -}; -#define BIT (x) (1 << (x))/* SPIGCR0 */
@@ -112,6 +86,35 @@ struct davinci_spi_regs {#define SPI2_BASE CONFIG_SYS_SPI2_BASE#endif +/* davinci spi register set */ +struct davinci_spi_regs { +dv_reg gcr0;/* 0x00 */ +dv_reg gcr1;/* 0x04 */ +dv_reg int0;/* 0x08 */ +dv_reg lvl;/* 0x0c */ +dv_reg flg;/* 0x10 */ +dv_reg pc0;/* 0x14 */ +dv_reg pc1;/* 0x18 */ +dv_reg pc2;/* 0x1c */ +dv_reg pc3;/* 0x20 */ +dv_reg pc4;/* 0x24 */ +dv_reg pc5;/* 0x28 */ +dv_reg rsvd[3 ]; +dv_reg dat0;/* 0x38 */ +dv_reg dat1;/* 0x3c */ +dv_reg buf;/* 0x40 */ +dv_reg emu;/* 0x44 */ +dv_reg delay;/* 0x48 */ +dv_reg def;/* 0x4c */ +dv_reg fmt0;/* 0x50 */ +dv_reg fmt1;/* 0x54 */ +dv_reg fmt2;/* 0x58 */ +dv_reg fmt3;/* 0x5c */ +dv_reg intvec0;/* 0x60 */ +dv_reg intvec1;/* 0x64 */ +}; + +/* davinci spi slave */ struct davinci_spi_slave {struct spi_slave slave;struct davinci_spi_regs *regs;
@@ -123,111 +126,6 @@ static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) return container_of(slave, struct davinci_spi_slave, slave); } -void spi_init () -{ -/* do nothing */ -} - -struct spi_slave *spi_setup_slave (unsigned int bus,unsigned int cs, -unsigned int max_hz,unsigned int mode) -{ -struct davinci_spi_slave *ds; - -if (!spi_cs_is_valid (bus, cs)) -return NULL ; - - ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs); -if (!ds) -return NULL ; - -switch (bus) { -case SPI0_BUS : - ds->regs = (struct davinci_spi_regs *)SPI0_BASE ; -break ; -#ifdef CONFIG_SYS_SPI1 -case SPI1_BUS : - ds->regs = (struct davinci_spi_regs *)SPI1_BASE ; -break ; -#endif -#ifdef CONFIG_SYS_SPI2 -case SPI2_BUS : - ds->regs = (struct davinci_spi_regs *)SPI2_BASE ; -break ; -#endif -default :/* Invalid bus number */ -return NULL ; - } - - ds->freq = max_hz; - -return &ds->slave; -} - -void spi_free_slave (struct spi_slave *slave) -{ -struct davinci_spi_slave *ds =to_davinci_spi (slave); - -free (ds); -} - -int spi_claim_bus (struct spi_slave *slave) -{ -struct davinci_spi_slave *ds =to_davinci_spi (slave); -unsigned int scalar; - -/* Enable the SPI hardware */ -writel (SPIGCR0_SPIRST_MASK , &ds->regs->gcr0); -udelay (1000 ); -writel (SPIGCR0_SPIENA_MASK , &ds->regs->gcr0); - -/* Set master mode, powered up and not activated */ -writel (SPIGCR1_MASTER_MASK |SPIGCR1_CLKMOD_MASK , &ds->regs->gcr1); - -/* CS, CLK, SIMO and SOMI are functional pins */ -writel (((1 << slave->cs) |SPIPC0_CLKFUN_MASK | -SPIPC0_DOFUN_MASK |SPIPC0_DIFUN_MASK ), &ds->regs->pc0); - -/* setup format */ - scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) -1 ) &0xFF ; - -/* -* Use following format: -* character length = 8, -* clock signal delayed by half clk cycle, -* clock low in idle state - Mode 0, -* MSB shifted out first -*/ -writel (8 | (scalar <<SPIFMT_PRESCALE_SHIFT ) | - (1 <<SPIFMT_PHASE_SHIFT ), &ds->regs->fmt0); - -/* -* Including a minor delay. No science here. Should be good even with -* no delay -*/ -writel ((50 <<SPI_C2TDELAY_SHIFT ) | - (50 <<SPI_T2CDELAY_SHIFT ), &ds->regs->delay); - -/* default chip select register */ -writel (SPIDEF_CSDEF0_MASK , &ds->regs->def); - -/* no interrupts */ -writel (0 , &ds->regs->int0); -writel (0 , &ds->regs->lvl); - -/* enable SPI */ -writel ((readl (&ds->regs->gcr1) |SPIGCR1_SPIENA_MASK ), &ds->regs->gcr1); - -return 0 ; -} - -void spi_release_bus (struct spi_slave *slave) -{ -struct davinci_spi_slave *ds =to_davinci_spi (slave); - -/* Disable the SPI hardware */ -writel (SPIGCR0_SPIRST_MASK , &ds->regs->gcr0); -} -/* * This functions needs to act like a macro to avoid pipeline reloads in the * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
@@ -343,6 +241,149 @@ static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len, }#endif +int spi_cs_is_valid (unsigned int bus,unsigned int cs) +{ +int ret =0 ; + +switch (bus) { +case SPI0_BUS : +if (cs <SPI0_NUM_CS ) + ret =1 ; +break ; +#ifdef CONFIG_SYS_SPI1 +case SPI1_BUS : +if (cs <SPI1_NUM_CS ) + ret =1 ; +break ; +#endif +#ifdef CONFIG_SYS_SPI2 +case SPI2_BUS : +if (cs <SPI2_NUM_CS ) + ret =1 ; +break ; +#endif +default : +/* Invalid bus number. Do nothing */ +break ; + } +return ret; +} + +void spi_cs_activate (struct spi_slave *slave) +{ +/* do nothing */ +} + +void spi_cs_deactivate (struct spi_slave *slave) +{ +/* do nothing */ +} + +void spi_init (void ) +{ +/* do nothing */ +} + +struct spi_slave *spi_setup_slave (unsigned int bus,unsigned int cs, +unsigned int max_hz,unsigned int mode) +{ +struct davinci_spi_slave *ds; + +if (!spi_cs_is_valid (bus, cs)) +return NULL ; + + ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs); +if (!ds) +return NULL ; + +switch (bus) { +case SPI0_BUS : + ds->regs = (struct davinci_spi_regs *)SPI0_BASE ; +break ; +#ifdef CONFIG_SYS_SPI1 +case SPI1_BUS : + ds->regs = (struct davinci_spi_regs *)SPI1_BASE ; +break ; +#endif +#ifdef CONFIG_SYS_SPI2 +case SPI2_BUS : + ds->regs = (struct davinci_spi_regs *)SPI2_BASE ; +break ; +#endif +default :/* Invalid bus number */ +return NULL ; + } + + ds->freq = max_hz; + +return &ds->slave; +} + +void spi_free_slave (struct spi_slave *slave) +{ +struct davinci_spi_slave *ds =to_davinci_spi (slave); + +free (ds); +} + +int spi_claim_bus (struct spi_slave *slave) +{ +struct davinci_spi_slave *ds =to_davinci_spi (slave); +unsigned int scalar; + +/* Enable the SPI hardware */ +writel (SPIGCR0_SPIRST_MASK , &ds->regs->gcr0); +udelay (1000 ); +writel (SPIGCR0_SPIENA_MASK , &ds->regs->gcr0); + +/* Set master mode, powered up and not activated */ +writel (SPIGCR1_MASTER_MASK |SPIGCR1_CLKMOD_MASK , &ds->regs->gcr1); + +/* CS, CLK, SIMO and SOMI are functional pins */ +writel (((1 << slave->cs) |SPIPC0_CLKFUN_MASK | +SPIPC0_DOFUN_MASK |SPIPC0_DIFUN_MASK ), &ds->regs->pc0); + +/* setup format */ + scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) -1 ) &0xFF ; + +/* +* Use following format: +* character length = 8, +* clock signal delayed by half clk cycle, +* clock low in idle state - Mode 0, +* MSB shifted out first +*/ +writel (8 | (scalar <<SPIFMT_PRESCALE_SHIFT ) | + (1 <<SPIFMT_PHASE_SHIFT ), &ds->regs->fmt0); + +/* +* Including a minor delay. No science here. Should be good even with +* no delay +*/ +writel ((50 <<SPI_C2TDELAY_SHIFT ) | + (50 <<SPI_T2CDELAY_SHIFT ), &ds->regs->delay); + +/* default chip select register */ +writel (SPIDEF_CSDEF0_MASK , &ds->regs->def); + +/* no interrupts */ +writel (0 , &ds->regs->int0); +writel (0 , &ds->regs->lvl); + +/* enable SPI */ +writel ((readl (&ds->regs->gcr1) |SPIGCR1_SPIENA_MASK ), &ds->regs->gcr1); + +return 0 ; +} + +void spi_release_bus (struct spi_slave *slave) +{ +struct davinci_spi_slave *ds =to_davinci_spi (slave); + +/* Disable the SPI hardware */ +writel (SPIGCR0_SPIRST_MASK , &ds->regs->gcr0); +} +int spi_xfer (struct spi_slave *slave,unsigned int bitlen,const void *dout,void *din,unsigned long flags) {
@@ -386,41 +427,3 @@ out: }return 0 ; } - -int spi_cs_is_valid (unsigned int bus,unsigned int cs) -{ -int ret =0 ; - -switch (bus) { -case SPI0_BUS : -if (cs <SPI0_NUM_CS ) - ret =1 ; -break ; -#ifdef CONFIG_SYS_SPI1 -case SPI1_BUS : -if (cs <SPI1_NUM_CS ) - ret =1 ; -break ; -#endif -#ifdef CONFIG_SYS_SPI2 -case SPI2_BUS : -if (cs <SPI2_NUM_CS ) - ret =1 ; -break ; -#endif -default : -/* Invalid bus number. Do nothing */ -break ; - } -return ret; -} - -void spi_cs_activate (struct spi_slave *slave) -{ -/* do nothing */ -} - -void spi_cs_deactivate (struct spi_slave *slave) -{ -/* do nothing */ -}
Signature · 1 line
1.9.1
PATCH v2 8/17 spi/sf: Minor cleanups
In reply to Jagan Teki- Adjust tab spaces
- Add comments
--- drivers/mtd/spi/sf_internal.h | 18 +++++++++--------- include/spi.h | 2 +- include/spi_flash.h | 10 ++++++---- 3 files changed, 16 insertions(+), 14 deletions(-)
drivers/mtd/spi/sf_internal.h +9 -9
@@ -31,9 +31,9 @@ enum spi_read_cmds { };/* Normal - Extended - Full command set */ -#define RD_NORM (ARRAY_SLOW | ARRAY_FAST) -#define RD_EXTN (RD_NORM | DUAL_OUTPUT_FAST | DUAL_IO_FAST) -#define RD_FULL (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST) +#define RD_NORM (ARRAY_SLOW | ARRAY_FAST) +#define RD_EXTN (RD_NORM | DUAL_OUTPUT_FAST | DUAL_IO_FAST) +#define RD_FULL (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST)/* sf param flags */ enum {
@@ -67,12 +67,12 @@ enum {#define CMD_WRITE_STATUS 0x01#define CMD_PAGE_PROGRAM 0x02#define CMD_WRITE_DISABLE 0x04 -#define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS 0x05#define CMD_QUAD_PAGE_PROGRAM 0x32#define CMD_READ_STATUS1 0x35#define CMD_WRITE_ENABLE 0x06 -#define CMD_READ_CONFIG 0x35 -#define CMD_FLAG_STATUS 0x70 +#define CMD_READ_CONFIG 0x35 +#define CMD_FLAG_STATUS 0x70/* Read commands */ #define CMD_READ_ARRAY_SLOW 0x03
@@ -99,13 +99,13 @@ enum {/* Flash timeout values */ #define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ) -#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) +#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ)#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ)/* SST specific */ #ifdef CONFIG_SPI_FLASH_SST # define CMD_SST_BP 0x02/* Byte Program */ -# define CMD_SST_AAI_WP 0xAD/* Auto Address Incr Word Program */ +# define CMD_SST_AAI_WP 0xAD/* Auto Address Incr Word Program */ int sst_write_wp (struct spi_flash *flash,u32 offset,size_t len,const void *buf);
@@ -121,7 +121,7 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len,* @ext_jedec: Device ext_jedec ID * @sector_size: Isn't necessarily a sector size from vendor, * the size listed here is what works with CMD_ERASE_64K -* @nr_sectors: No.of sectors on this device +* @nr_sectors: No.of sectors on this device * @e_rd_cmd: Enum list for read commands * @flags: Important param, for flash specific behaviour */
include/spi.h +1 -1
@@ -54,7 +54,7 @@/* Header byte that marks the start of the message */ #define SPI_PREAMBLE_END_BYTE 0xec -#define SPI_DEFAULT_WORDLEN 8 +#define SPI_DEFAULT_WORDLEN 8#ifdef CONFIG_DM_SPI /* TODO(sjg at chromium.org): Remove this and use max_hz from struct spi_slave */
include/spi_flash.h +6 -4
@@ -37,13 +37,15 @@ struct spi_slave;* struct spi_flash - SPI flash structure * * @spi: SPI slave +* @dev: SPI flash device +* @flags: Indication of spi flash flags * @name: Name of SPI flash -* @dual_flash: Indicates dual flash memories - dual stacked, parallel +* @dual_flash: Indicates dual flash memories - dual stacked, parallel * @shift: Flash shift useful in dual parallel * @size: Total flash size * @page_size: Write (page) size * @sector_size: Sector size -* @erase_size: Erase size +* @erase_size: Erase size * @bank_read_cmd: Bank read cmd * @bank_write_cmd: Bank write cmd * @bank_curr: Current flash bank
@@ -51,8 +53,8 @@ struct spi_slave;* @erase_cmd: Erase cmd 4K, 32K, 64K * @read_cmd: Read cmd - Array Fast, Extn read and quad read. * @write_cmd: Write cmd - page and quad program. -* @dummy_byte: Dummy cycles for read operation. -* @memory_map: Address of read-only SPI flash access +* @dummy_byte: Dummy cycles for read operation. +* @memory_map: Address of read-only SPI flash access * @read: Flash read ops: Read len bytes at offset into buf * Supported cmds: Fast Array Read * @write: Flash write ops: Write len bytes from buf into offset
Signature · 1 line
1.9.1
PATCH v2 9/17 dm: spi: zynq_spi: Convert to driver model
In reply to Jagan TekiThis converts the zynq spi driver to use the driver model.
Minimal functional changes like using meaningful name on structure members wrt mainlined dm spi drivers.
- input_hz -> frequency
- req_hz -> freq
- base -> regs
--- drivers/spi/zynq_spi.c | 305 +++++++++++++++++++++++++++++-------------------- 1 file changed, 181 insertions(+), 124 deletions(-)
drivers/spi/zynq_spi.c +181 -124
@@ -1,5 +1,6 @@/* * (C) Copyright 2013 Inc. +* (C) Copyright 2015 Jagan Teki <[email protected]> * * Xilinx Zynq PS SPI controller driver (master mode only) *
@@ -8,6 +9,8 @@#include <config.h> #include <common.h> +#include <dm.h> +#include <errno.h> #include <malloc.h> #include <spi.h> #include <asm/io.h>
@@ -44,180 +47,142 @@ struct zynq_spi_regs {u32 rxdr;/* 0x20 */ }; -/* zynq spi slave */ -struct zynq_spi_slave { -struct spi_slave slave; -struct zynq_spi_regs *base; -u8 mode; -u8 fifo_depth; + +/* zynq spi platform data */ +struct zynq_spi_platdata { +struct zynq_spi_regs *regs; +u32 frequency;/* input frequency */ u32 speed_hz; -u32 input_hz; -u32 req_hz; }; -static inline struct zynq_spi_slave *to_zynq_spi_slave (struct spi_slave *slave) -{ - return container_of(slave, struct zynq_spi_slave, slave); -} +/* zynq spi priv */ +struct zynq_spi_priv { +struct zynq_spi_regs *regs; +u8 cs; +u8 mode; +u8 fifo_depth; +u32 freq;/* required frequency */ +}; -static inline struct zynq_spi_regs *get_zynq_spi_base (int dev) +static inline struct zynq_spi_regs *get_zynq_spi_regs (struct udevice *bus) { -if (dev) +if (bus->seq)return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR1 ;else return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR0 ; } -static void zynq_spi_init_hw (struct zynq_spi_slave *zslave) +static int zynq_spi_ofdata_to_platdata (struct udevice *bus) +{ +struct zynq_spi_platdata *plat = bus->platdata; + + plat->regs =get_zynq_spi_regs (bus); + plat->frequency =166666700 ; + plat->speed_hz = plat->frequency /2 ; + +return 0 ; +} + +static void zynq_spi_init_hw (struct zynq_spi_priv *priv) { +struct zynq_spi_regs *regs = priv->regs;u32 confr;/* Disable SPI */ -writel (~ZYNQ_SPI_ENR_SPI_EN_MASK , &zslave->base->enr); +writel (~ZYNQ_SPI_ENR_SPI_EN_MASK , ®s->enr);/* Disable Interrupts */ -writel (ZYNQ_SPI_IXR_ALL_MASK , &zslave->base->idr); +writel (ZYNQ_SPI_IXR_ALL_MASK , ®s->idr);/* Clear RX FIFO */ -while (readl (&zslave->base->isr) & +while (readl (®s->isr) &ZYNQ_SPI_IXR_RXNEMPTY_MASK ) -readl (&zslave->base->rxdr); +readl (®s->rxdr);/* Clear Interrupts */ -writel (ZYNQ_SPI_IXR_ALL_MASK , &zslave->base->isr); +writel (ZYNQ_SPI_IXR_ALL_MASK , ®s->isr);/* Manual slave select and Auto start */ confr =ZYNQ_SPI_CR_MCS_MASK |ZYNQ_SPI_CR_CS_MASK |ZYNQ_SPI_CR_MSTREN_MASK ; confr &= ~ZYNQ_SPI_CR_MSA_MASK ; -writel (confr, &zslave->base->cr); +writel (confr, ®s->cr);/* Enable SPI */ -writel (ZYNQ_SPI_ENR_SPI_EN_MASK , &zslave->base->enr); +writel (ZYNQ_SPI_ENR_SPI_EN_MASK , ®s->enr); } -int spi_cs_is_valid (unsigned int bus,unsigned int cs) +static int zynq_spi_probe (struct udevice *bus) { -/* 2 bus with 3 chipselect */ -return bus <2 && cs <3 ; +struct zynq_spi_platdata *plat =dev_get_platdata (bus); +struct zynq_spi_priv *priv =dev_get_priv (bus); + + priv->regs = plat->regs; + priv->cs =spi_chip_select (bus); + priv->fifo_depth =ZYNQ_SPI_FIFO_DEPTH ; + +/* init the zynq spi hw */ +zynq_spi_init_hw (priv); + +return 0 ; } -void spi_cs_activate (struct spi_slave *slave) +static void spi_cs_activate (struct udevice *dev) { -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); +struct udevice *bus = dev->parent; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs;u32 cr; -debug ("spi_cs_activate: 0x%08x\n" , (u32 )slave); - -clrbits_le32 (&zslave->base->cr,ZYNQ_SPI_CR_CS_MASK ); - cr =readl (&zslave->base->cr); +clrbits_le32 (®s->cr,ZYNQ_SPI_CR_CS_MASK ); + cr =readl (®s->cr);/* * CS cal logic: CS[13:10] * xxx0 - cs0 * xx01 - cs1 * x011 - cs2 */ - cr |= (~(0x1 << slave->cs) <<10 ) &ZYNQ_SPI_CR_CS_MASK ; -writel (cr, &zslave->base->cr); + cr |= (~(0x1 << priv->cs) <<10 ) &ZYNQ_SPI_CR_CS_MASK ; +writel (cr, ®s->cr); } -void spi_cs_deactivate (struct spi_slave *slave) +static void spi_cs_deactivate (struct udevice *dev) { -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); - -debug ("spi_cs_deactivate: 0x%08x\n" , (u32 )slave); - -setbits_le32 (&zslave->base->cr,ZYNQ_SPI_CR_CS_MASK ); -} +struct udevice *bus = dev->parent; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs; -void spi_init () -{ -/* nothing to do */ +setbits_le32 (®s->cr,ZYNQ_SPI_CR_CS_MASK ); } -struct spi_slave *spi_setup_slave (unsigned int bus,unsigned int cs, -unsigned int max_hz,unsigned int mode) +static int zynq_spi_claim_bus (struct udevice *dev) { -struct zynq_spi_slave *zslave; - -if (!spi_cs_is_valid (bus, cs)) -return NULL ; - - zslave = spi_alloc_slave(struct zynq_spi_slave, bus, cs); -if (!zslave) { -printf ("SPI_error: Fail to allocate zynq_spi_slave\n" ); -return NULL ; - } - - zslave->base =get_zynq_spi_base (bus); - zslave->mode = mode; - zslave->fifo_depth =ZYNQ_SPI_FIFO_DEPTH ; - zslave->input_hz =166666700 ; - zslave->speed_hz = zslave->input_hz /2 ; - zslave->req_hz = max_hz; - -/* init the zynq spi hw */ -zynq_spi_init_hw (zslave); - -return &zslave->slave; -} +struct udevice *bus = dev->parent; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs; -void spi_free_slave (struct spi_slave *slave) -{ -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); +writel (ZYNQ_SPI_ENR_SPI_EN_MASK , ®s->enr); -debug ("spi_free_slave: 0x%08x\n" , (u32 )slave); -free (zslave); +return 0 ; } -int spi_claim_bus (struct spi_slave *slave) +static int zynq_spi_release_bus (struct udevice *dev) { -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); -u32 confr =0 ; -u8 baud_rate_val =0 ; +struct udevice *bus = dev->parent; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs; -writel (~ZYNQ_SPI_ENR_SPI_EN_MASK , &zslave->base->enr); - -/* Set the SPI Clock phase and polarities */ - confr =readl (&zslave->base->cr); - confr &= ~(ZYNQ_SPI_CR_CPHA_MASK |ZYNQ_SPI_CR_CPOL_MASK ); -if (zslave->mode &SPI_CPHA ) - confr |=ZYNQ_SPI_CR_CPHA_MASK ; -if (zslave->mode &SPI_CPOL ) - confr |=ZYNQ_SPI_CR_CPOL_MASK ; - -/* Set the clock frequency */ -if (zslave->req_hz ==0 ) { -/* Set baudrate x8, if the req_hz is 0 */ - baud_rate_val =0x2 ; - }else if (zslave->speed_hz != zslave->req_hz) { -while ((baud_rate_val <8 ) && - ((zslave->input_hz / - (2 << baud_rate_val)) > zslave->req_hz)) - baud_rate_val++; - zslave->speed_hz = zslave->req_hz / (2 << baud_rate_val); - } - confr &= ~ZYNQ_SPI_CR_BRD_MASK ; - confr |= (baud_rate_val <<3 ); -writel (confr, &zslave->base->cr); - -writel (ZYNQ_SPI_ENR_SPI_EN_MASK , &zslave->base->enr); +writel (~ZYNQ_SPI_ENR_SPI_EN_MASK , ®s->enr);return 0 ; } -void spi_release_bus (struct spi_slave *slave) -{ -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); - -debug ("spi_release_bus: 0x%08x\n" , (u32 )slave); -writel (~ZYNQ_SPI_ENR_SPI_EN_MASK , &zslave->base->enr); -} - -int spi_xfer (struct spi_slave *slave,unsigned int bitlen,const void *dout, -void *din,unsigned long flags) +static int zynq_spi_xfer (struct udevice *dev,unsigned int bitlen, +const void *dout,void *din,unsigned long flags) { -struct zynq_spi_slave *zslave =to_zynq_spi_slave (slave); +struct udevice *bus = dev->parent; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs;u32 len = bitlen /8 ;u32 tx_len = len, rx_len = len, tx_tvl;const u8 *tx_buf = dout;
@@ -225,7 +190,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,u32 ts, status;debug ("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n" , - slave->bus, slave->cs, bitlen, len, flags); + bus->seq, priv->cs, bitlen, len, flags);if (bitlen %8 ) {debug ("spi_xfer: Non byte aligned SPI transfer\n" );
@@ -233,45 +198,137 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }if (flags &SPI_XFER_BEGIN ) -spi_cs_activate (slave); +spi_cs_activate (dev);while (rx_len >0 ) {/* Write the data into TX FIFO - tx threshold is fifo_depth */ tx_tvl =0 ; -while ((tx_tvl < zslave->fifo_depth) && tx_len) { +while ((tx_tvl < priv->fifo_depth) && tx_len) {if (tx_buf) buf = *tx_buf++;else buf =0 ; -writel (buf, &zslave->base->txdr); +writel (buf, ®s->txdr); tx_len--; tx_tvl++; }/* Check TX FIFO completion */ ts =get_timer (0 ); - status =readl (&zslave->base->isr); + status =readl (®s->isr);while (!(status &ZYNQ_SPI_IXR_TXOW_MASK )) {if (get_timer (ts) >CONFIG_SYS_ZYNQ_SPI_WAIT ) {printf ("spi_xfer: Timeout! TX FIFO not full\n" );return -1 ; } - status =readl (&zslave->base->isr); + status =readl (®s->isr); }/* Read the data from RX FIFO */ - status =readl (&zslave->base->isr); + status =readl (®s->isr);while (status &ZYNQ_SPI_IXR_RXNEMPTY_MASK ) { - buf =readl (&zslave->base->rxdr); + buf =readl (®s->rxdr);if (rx_buf) *rx_buf++ = buf; - status =readl (&zslave->base->isr); + status =readl (®s->isr); rx_len--; } }if (flags &SPI_XFER_END ) -spi_cs_deactivate (slave); +spi_cs_deactivate (dev); + +return 0 ; +} + +static int zynq_spi_set_speed (struct udevice *bus,uint speed) +{ +struct zynq_spi_platdata *plat = bus->platdata; +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs; +uint32_t confr; +u8 baud_rate_val =0 ; + +if (speed > plat->frequency) + speed = plat->frequency; + +/* Set the clock frequency */ + confr =readl (®s->cr); +if (speed ==0 ) { +/* Set baudrate x8, if the freq is 0 */ + baud_rate_val =0x2 ; + }else if (plat->speed_hz != speed) { +while ((baud_rate_val <8 ) && + ((plat->frequency / + (2 << baud_rate_val)) > speed)) + baud_rate_val++; + plat->speed_hz = speed / (2 << baud_rate_val); + } + confr &= ~ZYNQ_SPI_CR_BRD_MASK ; + confr |= (baud_rate_val <<3 ); + +writel (confr, ®s->cr); + priv->freq = speed; + +debug ("zynq_spi_set_speed: regs=%p, mode=%d\n" , priv->regs, priv->freq);return 0 ; } + +static int zynq_spi_set_mode (struct udevice *bus,uint mode) +{ +struct zynq_spi_priv *priv =dev_get_priv (bus); +struct zynq_spi_regs *regs = priv->regs; +uint32_t confr; + +/* Set the SPI Clock phase and polarities */ + confr =readl (®s->cr); + confr &= ~(ZYNQ_SPI_CR_CPHA_MASK |ZYNQ_SPI_CR_CPOL_MASK ); + +if (priv->mode &SPI_CPHA ) + confr |=ZYNQ_SPI_CR_CPHA_MASK ; +if (priv->mode &SPI_CPOL ) + confr |=ZYNQ_SPI_CR_CPOL_MASK ; + +writel (confr, ®s->cr); + priv->mode = mode; + +debug ("zynq_spi_set_mode: regs=%p, mode=%d\n" , priv->regs, priv->mode); + +return 0 ; +} + +static int zynq_cs_info (struct udevice *bus,uint cs, +struct spi_cs_info *info) +{ +/* 2 bus with 3 chipselect */ +if (cs >2 ) +return -ENODEV ; +else +return 0 ; +} + +static const struct dm_spi_ops zynq_spi_ops = { + .claim_bus = zynq_spi_claim_bus, + .release_bus = zynq_spi_release_bus, + .xfer = zynq_spi_xfer, + .set_speed = zynq_spi_set_speed, + .set_mode = zynq_spi_set_mode, + .cs_info = zynq_cs_info, +}; + +static const struct udevice_id zynq_spi_ids[] = { + { .compatible ="xlnx,zynq-spi" }, + { } +}; + +U_BOOT_DRIVER (zynq_spi) = { + .name ="zynq_spi" , + .id =UCLASS_SPI , + .of_match = zynq_spi_ids, + .ops = &zynq_spi_ops, + .ofdata_to_platdata = zynq_spi_ofdata_to_platdata, + .platdata_auto_alloc_size =sizeof (struct zynq_spi_platdata ), + .priv_auto_alloc_size =sizeof (struct zynq_spi_priv ), + .probe = zynq_spi_probe, +};
Signature · 1 line
1.9.1
PATCH v2 10/17 zynq: Kconfig: Enable dm spi and spi_flash
In reply to Jagan TekiEnabled CONFIG_DM_SPI and CONFIG_DM_SPI_FLASH for zynq soc.
--- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/Kconfig +2 -0
@@ -664,6 +664,8 @@ config ARCH_ZYNQ select CPU_V7 select SUPPORT_SPL select DM + select DM_SPI + select DM_SPI_FLASH config TARGET_XILINX_ZYNQMP bool "Support Xilinx ZynqMP Platform"
Signature · 1 line
1.9.1
PATCH v2 11/17 dts: zynq: Add zynq spi controller nodes
In reply to Jagan TekiThis patch adds zynq spi controller nodes in zynq-7000.dtsi.
--- arch/arm/dts/zynq-7000.dtsi | 24 ++++++++++++++++++++++++ doc/device-tree-bindings/spi/spi-zynq.txt | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 doc/device-tree-bindings/spi/spi-zynq.txt
arch/arm/dts/zynq-7000.dtsi +24 -0
@@ -109,6 +109,30 @@ interrupts = <0 50 4>; }; + spi0: spi at e0006000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0006000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 26 4>; + clocks = <&clkc 25>, <&clkc 34>; + clock-names = "ref_clk", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi at e0007000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0007000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 49 4>; + clocks = <&clkc 26>, <&clkc 35>; + clock-names = "ref_clk", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + }; + gem0: ethernet at e000b000 { compatible = "cdns,gem"; reg = <0xe000b000 0x4000>;
doc/device-tree-bindings/spi/spi-zynq.txt new file +27 -0
@@ -0,0 +1,27 @@ +Zynq SPI controller Device Tree Bindings +---------------------------------------- + +Required properties: +- compatible : Should be "xlnx,spi-zynq". +- reg : Physical base address and size of SPI registers map. +- status : Status will be disabled in dtsi and enabled in required dts. +- interrupt-parent : Must be core interrupt controller. +- interrupts : Property with a value describing the interrupt + number. +- clocks : Clock phandles (see clock bindings for details). +- clock-names : List of input clock names - "ref_clk", "pclk" + (See clock bindings for details). + +Example: + + spi at e0006000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0006000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 26 4>; + clocks = <&clkc 25>, <&clkc 34>; + clock-names = "ref_clk", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + } ;
Signature · 1 line
1.9.1
PATCH v2 12/17 spi: zynq_spi: Add fdt support in driver
In reply to Jagan TekiNow zynq spi driver platform data is controlled by devicetree, enable the status by saying "okay" on respective board dts to use the devicetree generated platdata.
Ex:
&spi1 {
status = "okay";
};--- arch/arm/dts/zynq-7000.dtsi | 2 ++ doc/device-tree-bindings/spi/spi-zynq.txt | 2 ++ drivers/spi/zynq_spi.c | 23 +++++++++++++---------- 3 files changed, 17 insertions(+), 10 deletions(-)
arch/arm/dts/zynq-7000.dtsi +2 -0
@@ -117,6 +117,7 @@ interrupts = <0 26 4>; clocks = <&clkc 25>, <&clkc 34>; clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; #address-cells = <1>; #size-cells = <0>; };
@@ -129,6 +130,7 @@ interrupts = <0 49 4>; clocks = <&clkc 26>, <&clkc 35>; clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; #address-cells = <1>; #size-cells = <0>; };
doc/device-tree-bindings/spi/spi-zynq.txt +2 -0
@@ -11,6 +11,7 @@ Required properties: - clocks : Clock phandles (see clock bindings for details). - clock-names : List of input clock names - "ref_clk", "pclk" (See clock bindings for details). +- spi-max-frequency : Maximum SPI clocking speed of device in Hz Example:
@@ -22,6 +23,7 @@ Example: interrupts = <0 26 4>; clocks = <&clkc 25>, <&clkc 34>; clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; #address-cells = <1>; #size-cells = <0>; } ;
drivers/spi/zynq_spi.c +13 -10
@@ -13,9 +13,12 @@#include <errno.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/io.h> #include <asm/arch/hardware.h> +DECLARE_GLOBAL_DATA_PTR ; +/* zynq spi register bit masks ZYNQ_SPI_<REG>_<BIT>_MASK */ #define ZYNQ_SPI_CR_MSA_MASK (1 << 15)/* Manual start enb */ #define ZYNQ_SPI_CR_MCS_MASK (1 << 14)/* Manual chip select */
@@ -64,22 +67,22 @@ struct zynq_spi_priv {u32 freq;/* required frequency */ }; -static inline struct zynq_spi_regs *get_zynq_spi_regs (struct udevice *bus) -{ -if (bus->seq) -return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR1 ; -else -return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR0 ; -} -static int zynq_spi_ofdata_to_platdata (struct udevice *bus) {struct zynq_spi_platdata *plat = bus->platdata; +const void *blob = gd->fdt_blob; +int node = bus->of_offset; + + plat->regs = (struct zynq_spi_regs *)fdtdec_get_addr (blob, node,"reg" ); - plat->regs =get_zynq_spi_regs (bus); - plat->frequency =166666700 ; +/* FIXME: Use 250MHz as a suitable default */ + plat->frequency =fdtdec_get_int (blob, node,"spi-max-frequency" , +250000000 ); plat->speed_hz = plat->frequency /2 ; +debug ("zynq_spi_ofdata_to_platdata: regs=%p max-frequency=%d\n" , + plat->regs, plat->frequency); +return 0 ; }
Signature · 1 line
1.9.1
PATCH v2 13/17 dts: zynq: Enable spi1 for zc770_xm010 board
In reply to Jagan TekiThis patch enables spi1 for zynq zc770_xm010 board dts.
--- arch/arm/dts/zynq-zc770-xm010.dts | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/dts/zynq-zc770-xm010.dts +4 -0
@@ -21,3 +21,7 @@ reg = <0 0x40000000>; }; }; + +&spi1 { + status = "okay"; +};
Signature · 1 line
1.9.1
PATCH v2 13/17 dts: zynq: Enable spi1 for zc770_xm010 board
Hi Michal,
Quoted 15 lines · Jagan Teki
This patch enables spi1 for zynq
zc770_xm010board dts.Signed-off-by Jagan Teki <[email protected]>Acked-by Simon Glass <[email protected]>Cc Michal Simek <[email protected]>Cc Siva Durga Prasad Paladugu <[email protected]>--- arch/arm/dts/zynq-zc770-xm010.dts | 4 ++++ 1 file changed, 4 insertions(+)arch/arm/dts/zynq-zc770-xm010.dts +0
-0
arch/arm/dts/zynq-zc770-xm010.dts line 27
Quoted 7 lines
arch/arm/dts/zynq-zc770-xm010.dts +4
-0@@ -21,3 +21,7 @@ reg = <0 0x40000000>; }; }; + +&spi1 { + status = "okay"; +};
Did you find this, its not working with this type enabling in board dts instead it works only with
aliases {
serial0 = &uart1;
spi1 = "/spi at e0007000";
};thanks!
Signature · 1 line
Jagan | openedev.
PATCH v2 13/17 dts: zynq: Enable spi1 for zc770_xm010 board
Quoted 28 lines · Jagan Teki
Hi Michal,
Quoted 15 lines · Jagan Teki
This patch enables spi1 for zynq
zc770_xm010board dts.Signed-off-by Jagan Teki <[email protected]>Acked-by Simon Glass <[email protected]>Cc Michal Simek <[email protected]>Cc Siva Durga Prasad Paladugu <[email protected]>--- arch/arm/dts/zynq-zc770-xm010.dts | 4 ++++ 1 file changed, 4 insertions(+)arch/arm/dts/zynq-zc770-xm010.dts +0
-0arch/arm/dts/zynq-zc770-xm010.dts line 27
Quoted 7 lines
arch/arm/dts/zynq-zc770-xm010.dts +4
-0@@ -21,3 +21,7 @@ reg = <0 0x40000000>; }; }; + +&spi1 { + status = "okay"; +};Did you find this, its not working with this type enabling in board dts instead it works only with
Quoted 4 lines
aliases {
serial0 = &uart1;
spi1 = "/spi at e0007000";
};Sorry I haven't had any time to test this but if you want to use aliases please use &spi1 which does better job.
Thanks,
Michal
PATCH v2 14/17 dm: spi: xilinx_spi: Convert to driver model
In reply to Jagan TekiThis converts the xilinx spi driver to use the driver model.
--- drivers/spi/xilinx_spi.c | 212 +++++++++++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 88 deletions(-)
drivers/spi/xilinx_spi.c +124 -88
@@ -4,6 +4,7 @@* Supports 8 bit SPI transfers only, with or w/o FIFO * * Based on bfin_spi.c, by way of altera_spi.c +* Copyright (c) 2015 Jagan Teki <[email protected]> * Copyright (c) 2012 Stephan Linz <[email protected]> * Copyright (c) 2010 Graeme Smecher <[email protected]> * Copyright (c) 2010 Thomas Chou <[email protected]>
@@ -14,6 +15,8 @@#include <config.h> #include <common.h> +#include <dm.h> +#include <errno.h> #include <malloc.h> #include <spi.h>
@@ -79,7 +82,7 @@#endif /* xilinx spi register set */ -struct xilinx_spi_reg { +struct xilinx_spi_regs {u32 __space0__[7 ];u32 dgier;/* Device Global Interrupt Enable Register (DGIER) */ u32 ipisr;/* IP Interrupt Status Register (IPISR) */
@@ -97,113 +100,76 @@ struct xilinx_spi_reg {u32 spirfor;/* SPI Receive FIFO Occupancy Register (SPIRFOR) */ }; -/* xilinx spi slave */ -struct xilinx_spi_slave { -struct spi_slave slave; -struct xilinx_spi_reg *regs; +/* xilinx spi priv */ +struct xilinx_spi_priv { +struct xilinx_spi_regs *regs;unsigned int freq;unsigned int mode; +unsigned int cs; }; -static inline struct xilinx_spi_slave *to_xilinx_spi_slave ( -struct spi_slave *slave) -{ - return container_of(slave, struct xilinx_spi_slave, slave); -} -static unsigned long xilinx_spi_base_list[] =CONFIG_SYS_XILINX_SPI_LIST ; -int spi_cs_is_valid (unsigned int bus,unsigned int cs) +static int xilinx_spi_probe (struct udevice *bus) { -return bus <ARRAY_SIZE (xilinx_spi_base_list) && cs <32 ; -} +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; -void spi_cs_activate (struct spi_slave *slave) -{ -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); + priv->regs = (struct xilinx_spi_regs *)xilinx_spi_base_list[bus->seq]; + priv->cs =spi_chip_select (bus); -writel (SPISSR_ACT (slave->cs), &xilspi->regs->spissr); -} +writel (SPISSR_RESET_VALUE , ®s->srr); -void spi_cs_deactivate (struct spi_slave *slave) -{ -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); - -writel (SPISSR_OFF , &xilspi->regs->spissr); -} - -void spi_init (void ) -{ -/* do nothing */ +return 0 ; } -struct spi_slave *spi_setup_slave (unsigned int bus,unsigned int cs, -unsigned int max_hz,unsigned int mode) +static void spi_cs_activate (struct udevice *dev) { -struct xilinx_spi_slave *xilspi; - -if (!spi_cs_is_valid (bus, cs)) { -printf ("XILSPI error: unsupported bus %d / cs %d\n" , bus, cs); -return NULL ; - } - - xilspi = spi_alloc_slave(struct xilinx_spi_slave, bus, cs); -if (!xilspi) { -printf ("XILSPI error: malloc of SPI structure failed\n" ); -return NULL ; - } - xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus]; - xilspi->freq = max_hz; - xilspi->mode = mode; -debug ("spi_setup_slave: bus:%i cs:%i base:%p mode:%x max_hz:%d\n" , - bus, cs, xilspi->regs, xilspi->mode, xilspi->freq); - -writel (SPISSR_RESET_VALUE , &xilspi->regs->srr); +struct udevice *bus =dev_get_parent (dev); +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; -return &xilspi->slave; +writel (SPISSR_ACT (priv->cs), ®s->spissr); } -void spi_free_slave (struct spi_slave *slave) +static void spi_cs_deactivate (struct udevice *dev) { -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); +struct udevice *bus =dev_get_parent (dev); +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; -free (xilspi); +writel (SPISSR_OFF , ®s->spissr); } -int spi_claim_bus (struct spi_slave *slave) +static int xilinx_spi_claim_bus (struct udevice *dev) { -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); -u32 spicr; +struct udevice *bus =dev_get_parent (dev); +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; -debug ("spi_claim_bus: bus:%i cs:%i\n" , slave->bus, slave->cs); -writel (SPISSR_OFF , &xilspi->regs->spissr); +writel (SPISSR_OFF , ®s->spissr); +writel (XILSPI_SPICR_DFLT_ON , ®s->spicr); - spicr =XILSPI_SPICR_DFLT_ON ; -if (xilspi->mode &SPI_LSB_FIRST ) - spicr |=SPICR_LSB_FIRST ; -if (xilspi->mode &SPI_CPHA ) - spicr |=SPICR_CPHA ; -if (xilspi->mode &SPI_CPOL ) - spicr |=SPICR_CPOL ; -if (xilspi->mode &SPI_LOOP ) - spicr |=SPICR_LOOP ; - -writel (spicr, &xilspi->regs->spicr);return 0 ; } -void spi_release_bus (struct spi_slave *slave) +static int xilinx_spi_release_bus (struct udevice *dev) { -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); +struct udevice *bus =dev_get_parent (dev); +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; + +writel (SPISSR_OFF , ®s->spissr); +writel (XILSPI_SPICR_DFLT_OFF , ®s->spicr); -debug ("spi_release_bus: bus:%i cs:%i\n" , slave->bus, slave->cs); -writel (SPISSR_OFF , &xilspi->regs->spissr); -writel (XILSPI_SPICR_DFLT_OFF , &xilspi->regs->spicr); +return 0 ; } -int spi_xfer (struct spi_slave *slave,unsigned int bitlen,const void *dout, -void *din,unsigned long flags) +static int xilinx_spi_xfer (struct udevice *dev,unsigned int bitlen, +const void *dout,void *din,unsigned long flags) { -struct xilinx_spi_slave *xilspi =to_xilinx_spi_slave (slave); +struct udevice *bus =dev_get_parent (dev); +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs;/* assume spi core configured to do 8 bit transfers */ unsigned int bytes = bitlen /XILSPI_MAX_XFER_BITS ;const unsigned char *txp = dout;
@@ -212,7 +178,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,unsigned global_timeout;debug ("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n" , - slave->bus, slave->cs, bitlen, bytes, flags); + bus->seq, priv->cs, bitlen, bytes, flags);if (bitlen ==0 ) goto done;
@@ -225,8 +191,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }/* empty read buffer */ -while (rxecount && !(readl (&xilspi->regs->spisr) &SPISR_RX_EMPTY )) { -readl (&xilspi->regs->spidrr); +while (rxecount && !(readl (®s->spisr) &SPISR_RX_EMPTY )) { +readl (®s->spidrr); rxecount--; }
@@ -236,11 +202,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }if (flags &SPI_XFER_BEGIN ) -spi_cs_activate (slave); +spi_cs_activate (dev);/* at least 1usec or greater, leftover 1 */ - global_timeout = xilspi->freq >XILSPI_MAX_XFER_BITS *1000000 ?2 : - (XILSPI_MAX_XFER_BITS *1000000 / xilspi->freq) +1 ; + global_timeout = priv->freq >XILSPI_MAX_XFER_BITS *1000000 ?2 : + (XILSPI_MAX_XFER_BITS *1000000 / priv->freq) +1 ;while (bytes--) {unsigned timeout = global_timeout;
@@ -249,8 +215,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,debug ("spi_xfer: tx:%x " , d);/* write out and wait for processing (receive data) */ -writel (d &SPIDTR_8BIT_MASK , &xilspi->regs->spidtr); -while (timeout &&readl (&xilspi->regs->spisr) +writel (d &SPIDTR_8BIT_MASK , ®s->spidtr); +while (timeout &&readl (®s->spisr) &SPISR_RX_EMPTY ) { timeout--;udelay (1 );
@@ -262,7 +228,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }/* read Rx element and push into data in buffer */ - d =readl (&xilspi->regs->spidrr) &SPIDRR_8BIT_MASK ; + d =readl (®s->spidrr) &SPIDRR_8BIT_MASK ;if (rxp) *rxp++ = d;debug ("spi_xfer: rx:%x\n" , d);
@@ -270,7 +236,77 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, done:if (flags &SPI_XFER_END ) -spi_cs_deactivate (slave); +spi_cs_deactivate (dev); + +return 0 ; +} + +static int xilinx_spi_set_speed (struct udevice *bus,uint speed) +{ +struct xilinx_spi_priv *priv =dev_get_priv (bus); + + priv->freq = speed; + +debug ("xilinx_spi_set_speed: regs=%p, mode=%d\n" , priv->regs, + priv->freq); + +return 0 ; +} + +static int xilinx_spi_set_mode (struct udevice *bus,uint mode) +{ +struct xilinx_spi_priv *priv =dev_get_priv (bus); +struct xilinx_spi_regs *regs = priv->regs; +uint32_t spicr; + + spicr =readl (®s->spicr); +if (priv->mode &SPI_LSB_FIRST ) + spicr |=SPICR_LSB_FIRST ; +if (priv->mode &SPI_CPHA ) + spicr |=SPICR_CPHA ; +if (priv->mode &SPI_CPOL ) + spicr |=SPICR_CPOL ; +if (priv->mode &SPI_LOOP ) + spicr |=SPICR_LOOP ; + +writel (spicr, ®s->spicr); + priv->mode = mode; + +debug ("xilinx_spi_set_mode: regs=%p, mode=%d\n" , priv->regs, + priv->mode);return 0 ; } + +static int xilinx_cs_info (struct udevice *bus,uint cs, +struct spi_cs_info *info) +{ +/* 2 bus with 3 chipselect */ +if (cs >31 ) +return -ENODEV ; +else +return 0 ; +} + +static const struct dm_spi_ops xilinx_spi_ops = { + .claim_bus = xilinx_spi_claim_bus, + .release_bus = xilinx_spi_release_bus, + .xfer = xilinx_spi_xfer, + .set_speed = xilinx_spi_set_speed, + .set_mode = xilinx_spi_set_mode, + .cs_info = xilinx_cs_info, +}; + +static const struct udevice_id xilinx_spi_ids[] = { + { .compatible ="xlnx,xilinx-spi" }, + { } +}; + +U_BOOT_DRIVER (xilinx_spi) = { + .name ="xilinx_spi" , + .id =UCLASS_SPI , + .of_match = xilinx_spi_ids, + .ops = &xilinx_spi_ops, + .priv_auto_alloc_size =sizeof (struct xilinx_spi_priv ), + .probe = xilinx_spi_probe, +};
Signature · 1 line
1.9.1
PATCH v2 15/17 spi: xilinx_spi: Add asm/io.h include file
In reply to Jagan TekiThis patch includes asm/io.h for readl and writel calls.
build errors:drivers/spi/xilinx_spi.c: In function 'xilinx_spi_probe':drivers/spi/xilinx_spi.c:119:2: warning: implicit declaration of function 'writel' [-Wimplicit-function-declaration] drivers/spi/xilinx_spi.c: In function 'xilinx_spi_xfer':drivers/spi/xilinx_spi.c:193:2: warning: implicit declaration of function 'readl' [-Wimplicit-function-declaration]
--- drivers/spi/xilinx_spi.c | 1 + 1 file changed, 1 insertion(+)
drivers/spi/xilinx_spi.c +1 -0
@@ -19,6 +19,7 @@#include <errno.h> #include <malloc.h> #include <spi.h> +#include <asm/io.h> /* * [0]: http://www.xilinx.com/support/documentation
Signature · 1 line
1.9.1
PATCH v2 16/17 spi: Kconfig: Add Zynq QSPI controller entry
In reply to Jagan TekiAdd Zynq QSPI controller Kconfig entry.
--- drivers/spi/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/spi/Kconfig +9 -0
@@ -51,3 +51,12 @@ config CADENCE_QSPI Enable the Cadence Quad-SPI (QSPI) driver. This driver can be used to access the SPI NOR flash on platforms embedding this Cadence IP core. + +config ZYNQ_QSPI + bool "Zynq QSPI driver" + depends on DM_SPI && (ARCH_ZYNQ || TARGET_XILINX_ZYNQMP) + help + Enable the Zynq Quad-SPI (QSPI) driver. This driver can be + used to access the SPI NOR flash on platforms embedding this + Zynq QSPI IP core. This IP is used to connect the flash in + 4-bit qspi, 8-bit dual stacked and shared 4-bit dual parallel.
Signature · 1 line
1.9.1
PATCH v2 17/17 spi: Kconfig: Add Zynq SPI controller entry
In reply to Jagan TekiAdd Zynq SPI controller Kconfig entry.
--- drivers/spi/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/spi/Kconfig +8 -0
@@ -52,6 +52,14 @@ config CADENCE_QSPI used to access the SPI NOR flash on platforms embedding this Cadence IP core. +config ZYNQ_SPI + bool "Zynq SPI driver" + depends on DM_SPI && (ARCH_ZYNQ || TARGET_XILINX_ZYNQMP) + help + Enable the Zynq SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Zynq + SPI IP core. + config ZYNQ_QSPI bool "Zynq QSPI driver" depends on DM_SPI && (ARCH_ZYNQ || TARGET_XILINX_ZYNQMP)
Signature · 1 line
1.9.1
v2 cover spi/sf: Cleansup and driver model conversions
In reply to Jagan TekiHi Siva,
Quoted 18 lines · Jagan Teki
No minor updates on code.
Changes for v2:
- One change suggested from Simon to usedev_get_parentthanks!
Jagan.Jagan Teki (17):
spi: Zapandes_spidriver
spi: Zapftssp010_spidriver
spi: Zapoc_tiny_spidriver
spi:xilinx_spi: Move header code to driver
spi:xilinx_spi: Driver clean-up
spi:davinci_spi: Move header code to driver
spi:davinci_spi: Driver cleanup
spi/sf: Minor cleanups
dm: spi:zynq_spi: Convert to driver model
Quoted 8 lines
zynq:
Kconfig: Enable dm spi andspi_flash
dts: zynq: Add zynq spi controller nodes
spi:zynq_spi: Add fdt support in driver
dts: zynq: Enable spi1 forzc770_xm010board
dm: spi:xilinx_spi: Convert to driver model
spi:xilinx_spi: Addasm/io.hinclude file
spi:Kconfig: Add Zynq QSPI controller entry
spi:Kconfig: Add Zynq SPI controller entry
Can you please verify this stuff on zc770 xm010 board.
Quoted 19 lines
arch/arm/Kconfig | 2 + arch/arm/dts/zynq-7000.dtsi | 26 ++ arch/arm/dts/zynq-zc770-xm010.dts | 4 + doc/device-tree-bindings/spi/spi-zynq.txt | 29 ++ drivers/mtd/spi/sf_internal.h | 18 +- drivers/spi/Kconfig | 17 + drivers/spi/Makefile | 3 - drivers/spi/andes_spi.c | 284 ----------------- drivers/spi/andes_spi.h | 115 ------- drivers/spi/davinci_spi.c | 369 ++++++++++++++-------- drivers/spi/davinci_spi.h | 121 -------- drivers/spi/ftssp010_spi.c | 498 ------------------------------ drivers/spi/oc_tiny_spi.c | 245 --------------- drivers/spi/xilinx_spi.c | 330 +++++++++++++------- drivers/spi/xilinx_spi.h | 138 --------- drivers/spi/zynq_spi.c | 312 +++++++++++-------- include/spi.h | 2 +- include/spi_flash.h | 10 +-
Quoted 8 lines
18 files changed, 734 insertions(+), 1789 deletions(-) create mode 100644 doc/device-tree-bindings/spi/spi-zynq.txt delete mode 100644 drivers/spi/andes_spi.c delete mode 100644 drivers/spi/andes_spi.h delete mode 100644 drivers/spi/davinci_spi.h delete mode 100644 drivers/spi/ftssp010_spi.c delete mode 100644 drivers/spi/oc_tiny_spi.c delete mode 100644 drivers/spi/xilinx_spi.h
thanks!
Signature · 2 lines
Jagan Teki, Openedev.