diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-28 21:10:20 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-06-28 21:10:20 +0300 |
commit | 69609a91ac1d82f9c958a762614edfe0ac8498e3 (patch) | |
tree | a1a1988ff3334cf316a30e35205a16878dbbe697 /include | |
parent | c10383b3fb10286dfeac7754ca964ec992f6fe78 (diff) | |
parent | 1bee1ecf232cd90ad112d78ab5124850b4e5ea09 (diff) | |
download | linux-69609a91ac1d82f9c958a762614edfe0ac8498e3.tar.xz |
Merge tag 'spi-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"The biggest single thing in the diffstat here is a massive overhaul of
the PXA2xx driver from Andy Shevchenko (the IP is still in use on
modern Intel systems), though we also have quite a lot of core work as
well:
- Better support for mixing native and GPIO chip selects also from
Andy.
- Support for devices with multiple chip selects from Sebastian
Reichel.
- Helper for polling status registers in spi-mem from Patrice
Chotard.
- Support for Renesas RZ/N1 and Rockchip RV1126"
* tag 'spi-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (86 commits)
spi: core: add dma_map_dev for dma device
spi: convert Xilinx Zynq UltraScale+ MPSoC GQSPI bindings to YAML
spi: Fix self assignment issue with ancillary->mode
spi: spi-sh-msiof: : use proper DMAENGINE API for termination
spi: spi-rspi: : use proper DMAENGINE API for termination
spi: spi-rockchip: add description for rv1126
spi: rockchip: Support SPI_CS_HIGH
spi: rockchip: Support cs-gpio
spi: rockchip: Wait for STB status in slave mode tx_xfer
spi: rockchip: Set rx_fifo interrupt waterline base on transfer item
spi: rockchip: add compatible string for rv1126
spi: spi-sun6i: Fix chipselect/clock bug
spi: dt-bindings: support devices with multiple chipselects
spi: add ancillary device support
spi: xilinx: convert to yaml
spi: convert Cadence SPI bindings to YAML
spi: stm32-qspi: Remove unused qspi field of struct stm32_qspi_flash
spi: add of_device_uevent_modalias support
spi: meson-spicc: fix memory leak in meson_spicc_probe
spi: meson-spicc: fix a wrong goto jump for avoiding memory leak.
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mtd/spinand.h | 22 | ||||
-rw-r--r-- | include/linux/platform_data/spi-ath79.h | 16 | ||||
-rw-r--r-- | include/linux/pxa2xx_ssp.h | 51 | ||||
-rw-r--r-- | include/linux/spi/pxa2xx_spi.h | 21 | ||||
-rw-r--r-- | include/linux/spi/spi-mem.h | 16 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 8 | ||||
-rw-r--r-- | include/trace/events/spi.h | 57 |
7 files changed, 156 insertions, 35 deletions
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 6bb92f26833e..6988956b8492 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -170,6 +170,28 @@ struct spinand_op; struct spinand_device; #define SPINAND_MAX_ID_LEN 4 +/* + * For erase, write and read operation, we got the following timings : + * tBERS (erase) 1ms to 4ms + * tPROG 300us to 400us + * tREAD 25us to 100us + * In order to minimize latency, the min value is divided by 4 for the + * initial delay, and dividing by 20 for the poll delay. + * For reset, 5us/10us/500us if the device is respectively + * reading/programming/erasing when the RESET occurs. Since we always + * issue a RESET when the device is IDLE, 5us is selected for both initial + * and poll delay. + */ +#define SPINAND_READ_INITIAL_DELAY_US 6 +#define SPINAND_READ_POLL_DELAY_US 5 +#define SPINAND_RESET_INITIAL_DELAY_US 5 +#define SPINAND_RESET_POLL_DELAY_US 5 +#define SPINAND_WRITE_INITIAL_DELAY_US 75 +#define SPINAND_WRITE_POLL_DELAY_US 15 +#define SPINAND_ERASE_INITIAL_DELAY_US 250 +#define SPINAND_ERASE_POLL_DELAY_US 50 + +#define SPINAND_WAITRDY_TIMEOUT_MS 400 /** * struct spinand_id - SPI NAND id structure diff --git a/include/linux/platform_data/spi-ath79.h b/include/linux/platform_data/spi-ath79.h deleted file mode 100644 index 81a388ff58cc..000000000000 --- a/include/linux/platform_data/spi-ath79.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller - * - * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> - */ - -#ifndef _ATH79_SPI_PLATFORM_H -#define _ATH79_SPI_PLATFORM_H - -struct ath79_spi_platform_data { - unsigned bus_num; - unsigned num_chipselect; -}; - -#endif /* _ATH79_SPI_PLATFORM_H */ diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index 7f73b26ed22e..a3fec2de512f 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2003 Russell King, All Rights Reserved. + * Copyright (C) 2003 Russell King, All Rights Reserved. * * This driver supports the following PXA CPU/SSP ports:- * @@ -11,8 +11,8 @@ * PXA3xx SSP1, SSP2, SSP3, SSP4 */ -#ifndef __LINUX_SSP_H -#define __LINUX_SSP_H +#ifndef __LINUX_PXA2XX_SSP_H +#define __LINUX_PXA2XX_SSP_H #include <linux/bits.h> #include <linux/compiler_types.h> @@ -38,7 +38,6 @@ struct device_node; #define SSDR (0x10) /* SSP Data Write/Data Read Register */ #define SSTO (0x28) /* SSP Time Out Register */ -#define DDS_RATE (0x28) /* SSP DDS Clock Rate Register (Intel Quark) */ #define SSPSP (0x2C) /* SSP Programmable Serial Protocol */ #define SSTSA (0x30) /* SSP Tx Timeslot Active */ #define SSRSA (0x34) /* SSP Rx Timeslot Active */ @@ -60,7 +59,7 @@ struct device_node; /* PXA27x, PXA3xx */ #define SSCR0_EDSS BIT(20) /* Extended data size select */ #define SSCR0_NCS BIT(21) /* Network clock select */ -#define SSCR0_RIM BIT(22) /* Receive FIFO overrrun interrupt mask */ +#define SSCR0_RIM BIT(22) /* Receive FIFO overrun interrupt mask */ #define SSCR0_TUM BIT(23) /* Transmit FIFO underrun interrupt mask */ #define SSCR0_FRDC GENMASK(26, 24) /* Frame rate divider control (mask) */ #define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */ @@ -105,6 +104,9 @@ struct device_node; #define CE4100_SSCR1_RFT GENMASK(11, 10) /* Receive FIFO Threshold (mask) */ #define CE4100_SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..4] */ +/* Intel Quark X1000 */ +#define DDS_RATE 0x28 /* SSP DDS Clock Rate Register */ + /* QUARK_X1000 SSCR0 bit definition */ #define QUARK_X1000_SSCR0_DSS GENMASK(4, 0) /* Data Size Select (mask) */ #define QUARK_X1000_SSCR0_DataSize(x) ((x) - 1) /* Data Size Select [4..32] */ @@ -124,7 +126,7 @@ struct device_node; #define QUARK_X1000_SSCR1_EFWR BIT(16) /* Enable FIFO Write/Read */ #define QUARK_X1000_SSCR1_STRF BIT(17) /* Select FIFO or EFWR */ -/* extra bits in PXA255, PXA26x and PXA27x SSP ports */ +/* Extra bits in PXA255, PXA26x and PXA27x SSP ports */ #define SSCR0_TISSP (1 << 4) /* TI Sync Serial Protocol */ #define SSCR0_PSP (3 << 4) /* PSP - Programmable Serial Protocol */ @@ -181,6 +183,21 @@ struct device_node; #define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */ #define SSACD_SCDX8 BIT(7) /* SYSCLK division ratio select */ +/* Intel Merrifield SSP */ +#define SFIFOL 0x68 /* FIFO level */ +#define SFIFOTT 0x6c /* FIFO trigger threshold */ + +#define RX_THRESH_MRFLD_DFLT 16 +#define TX_THRESH_MRFLD_DFLT 16 + +#define SFIFOL_TFL_MASK GENMASK(15, 0) /* Transmit FIFO Level mask */ +#define SFIFOL_RFL_MASK GENMASK(31, 16) /* Receive FIFO Level mask */ + +#define SFIFOTT_TFT GENMASK(15, 0) /* Transmit FIFO Threshold (mask) */ +#define SFIFOTT_TxThresh(x) (((x) - 1) << 0) /* TX FIFO trigger threshold / level */ +#define SFIFOTT_RFT GENMASK(31, 16) /* Receive FIFO Threshold (mask) */ +#define SFIFOTT_RxThresh(x) (((x) - 1) << 16) /* RX FIFO trigger threshold / level */ + /* LPSS SSP */ #define SSITF 0x44 /* TX FIFO trigger level */ #define SSITF_TxHiThresh(x) (((x) - 1) << 0) @@ -203,8 +220,10 @@ enum pxa_ssp_type { MMP2_SSP, PXA910_SSP, CE4100_SSP, + MRFLD_SSP, QUARK_X1000_SSP, - LPSS_LPT_SSP, /* Keep LPSS types sorted with lpss_platforms[] */ + /* Keep LPSS types sorted with lpss_platforms[] */ + LPSS_LPT_SSP, LPSS_BYT_SSP, LPSS_BSW_SSP, LPSS_SPT_SSP, @@ -252,6 +271,22 @@ static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg) return __raw_readl(dev->mmio_base + reg); } +static inline void pxa_ssp_enable(struct ssp_device *ssp) +{ + u32 sscr0; + + sscr0 = pxa_ssp_read_reg(ssp, SSCR0) | SSCR0_SSE; + pxa_ssp_write_reg(ssp, SSCR0, sscr0); +} + +static inline void pxa_ssp_disable(struct ssp_device *ssp) +{ + u32 sscr0; + + sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~SSCR0_SSE; + pxa_ssp_write_reg(ssp, SSCR0, sscr0); +} + #if IS_ENABLED(CONFIG_PXA_SSP) struct ssp_device *pxa_ssp_request(int port, const char *label); void pxa_ssp_free(struct ssp_device *); @@ -270,4 +305,4 @@ static inline struct ssp_device *pxa_ssp_request_of(const struct device_node *n, static inline void pxa_ssp_free(struct ssp_device *ssp) {} #endif -#endif +#endif /* __LINUX_PXA2XX_SSP_H */ diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h index 31f00c7f4f59..eaab121ee575 100644 --- a/include/linux/spi/pxa2xx_spi.h +++ b/include/linux/spi/pxa2xx_spi.h @@ -2,8 +2,10 @@ /* * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs */ -#ifndef __linux_pxa2xx_spi_h -#define __linux_pxa2xx_spi_h +#ifndef __LINUX_SPI_PXA2XX_SPI_H +#define __LINUX_SPI_PXA2XX_SPI_H + +#include <linux/types.h> #include <linux/pxa2xx_ssp.h> @@ -12,7 +14,10 @@ struct dma_chan; -/* device.platform_data for SSP controller devices */ +/* + * The platform data for SSP controller devices + * (resides in device.platform_data). + */ struct pxa2xx_spi_controller { u16 num_chipselect; u8 enable_dma; @@ -28,8 +33,11 @@ struct pxa2xx_spi_controller { struct ssp_device ssp; }; -/* spi_board_info.controller_data for SPI slave devices, - * copied to spi_device.platform_data ... mostly for dma tuning +/* + * The controller specific data for SPI slave devices + * (resides in spi_board_info.controller_data), + * copied to spi_device.platform_data ... mostly for + * DMA tuning. */ struct pxa2xx_spi_chip { u8 tx_threshold; @@ -49,4 +57,5 @@ struct pxa2xx_spi_chip { extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_controller *info); #endif -#endif + +#endif /* __LINUX_SPI_PXA2XX_SPI_H */ diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 2b65c9edc34e..85e2ff7b840d 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -250,6 +250,9 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * the currently mapped area), and the caller of * spi_mem_dirmap_write() is responsible for calling it again in * this case. + * @poll_status: poll memory device status until (status & mask) == match or + * when the timeout has expired. It fills the data buffer with + * the last status value. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the @@ -274,6 +277,12 @@ struct spi_controller_mem_ops { u64 offs, size_t len, void *buf); ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, const void *buf); + int (*poll_status)(struct spi_mem *mem, + const struct spi_mem_op *op, + u16 mask, u16 match, + unsigned long initial_delay_us, + unsigned long polling_rate_us, + unsigned long timeout_ms); }; /** @@ -369,6 +378,13 @@ devm_spi_mem_dirmap_create(struct device *dev, struct spi_mem *mem, void devm_spi_mem_dirmap_destroy(struct device *dev, struct spi_mem_dirmap_desc *desc); +int spi_mem_poll_status(struct spi_mem *mem, + const struct spi_mem_op *op, + u16 mask, u16 match, + unsigned long initial_delay_us, + unsigned long polling_delay_us, + u16 timeout_ms); + int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, struct module *owner); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 74239d65c7fd..97b8d12b5f2b 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -299,6 +299,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) driver_unregister(&sdrv->driver); } +extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select); + /* use a define to avoid include chaining to get THIS_MODULE */ #define spi_register_driver(driver) \ __spi_register_driver(THIS_MODULE, driver) @@ -586,6 +588,7 @@ struct spi_controller { bool (*can_dma)(struct spi_controller *ctlr, struct spi_device *spi, struct spi_transfer *xfer); + struct device *dma_map_dev; /* * These hooks are for drivers that want to use the generic @@ -1108,11 +1111,6 @@ static inline void spi_message_free(struct spi_message *m) kfree(m); } -extern int spi_set_cs_timing(struct spi_device *spi, - struct spi_delay *setup, - struct spi_delay *hold, - struct spi_delay *inactive); - extern int spi_setup(struct spi_device *spi); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, diff --git a/include/trace/events/spi.h b/include/trace/events/spi.h index 0dd9171d2ad8..c0d9844befd7 100644 --- a/include/trace/events/spi.h +++ b/include/trace/events/spi.h @@ -42,6 +42,63 @@ DEFINE_EVENT(spi_controller, spi_controller_busy, ); +TRACE_EVENT(spi_setup, + TP_PROTO(struct spi_device *spi, int status), + TP_ARGS(spi, status), + + TP_STRUCT__entry( + __field(int, bus_num) + __field(int, chip_select) + __field(unsigned long, mode) + __field(unsigned int, bits_per_word) + __field(unsigned int, max_speed_hz) + __field(int, status) + ), + + TP_fast_assign( + __entry->bus_num = spi->controller->bus_num; + __entry->chip_select = spi->chip_select; + __entry->mode = spi->mode; + __entry->bits_per_word = spi->bits_per_word; + __entry->max_speed_hz = spi->max_speed_hz; + __entry->status = status; + ), + + TP_printk("spi%d.%d setup mode %lu, %s%s%s%s%u bits/w, %u Hz max --> %d", + __entry->bus_num, __entry->chip_select, + (__entry->mode & SPI_MODE_X_MASK), + (__entry->mode & SPI_CS_HIGH) ? "cs_high, " : "", + (__entry->mode & SPI_LSB_FIRST) ? "lsb, " : "", + (__entry->mode & SPI_3WIRE) ? "3wire, " : "", + (__entry->mode & SPI_LOOP) ? "loopback, " : "", + __entry->bits_per_word, __entry->max_speed_hz, + __entry->status) +); + +TRACE_EVENT(spi_set_cs, + TP_PROTO(struct spi_device *spi, bool enable), + TP_ARGS(spi, enable), + + TP_STRUCT__entry( + __field(int, bus_num) + __field(int, chip_select) + __field(unsigned long, mode) + __field(bool, enable) + ), + + TP_fast_assign( + __entry->bus_num = spi->controller->bus_num; + __entry->chip_select = spi->chip_select; + __entry->mode = spi->mode; + __entry->enable = enable; + ), + + TP_printk("spi%d.%d %s%s", + __entry->bus_num, __entry->chip_select, + __entry->enable ? "activate" : "deactivate", + (__entry->mode & SPI_CS_HIGH) ? ", cs_high" : "") +); + DECLARE_EVENT_CLASS(spi_message, TP_PROTO(struct spi_message *msg), |