diff options
author | 2025-03-25 19:28:14 -0700 | |
---|---|---|
committer | 2025-03-25 19:28:14 -0700 | |
commit | 47618bc875407b54296285e21d92d79889ce503a (patch) | |
tree | 75c2e380e78c0a50848f94a392bc2e4aac047753 /include | |
parent | Merge tag 'regulator-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator (diff) | |
parent | spi: dt-bindings: cdns,qspi-nor: Improve (diff) | |
download | wireguard-linux-47618bc875407b54296285e21d92d79889ce503a.tar.xz wireguard-linux-47618bc875407b54296285e21d92d79889ce503a.zip |
Merge tag 'spi-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"The biggest change for SPI this release is the addition of offload
support from David Lechner, allowing the hardware to trigger SPI
transactions autonomously. The initial use case is for triggering IIO
operations but there are other applications where having the hardware
ready to go at a minimal signal is useful for synchronising with
external inputs (eg, interrupt handling) or reducing latency (eg, CAN
networking).
Otherwise there's the usual fixes, improvements and cleanups, plus
support for a bunch of new devices.
- Support for offloading support from David Lechner
- Support for GOcontrol1 Moduline modules, Mediatek MT7988, NXP
i.MX94, Qualcomm SPI NAMD, Rockchip RK3562, Sophogo SG2044 and ST
STM32 OSPI"
* tag 'spi-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (59 commits)
spi: spi-mem: Introduce a default ->exec_op() debug log
spi: dt-bindings: cdns,qspi-nor: Require some peripheral properties
spi: dt-bindings: cdns,qspi-nor: Deprecate the Cadence compatible alone
spi: dt-bindings: cdns,qspi-nor: Be more descriptive regarding what this controller is
spi: stm32-ospi: Include "gpio/consumer.h"
MAINTAINERS: adjust the file entry in GOCONTROLL MODULINE MODULE SLOT
spi: spi-qpic-snand: avoid memleak in qcom_spi_ecc_init_ctx_pipelined()
spi: spi-mux: Fix coverity issue, unchecked return value
spi: sophgo: fix incorrect type for ret in sg2044_spifmc_write()
spi: sg2044-nor: fix uninitialized variable in probe
spi: sg2044-nor: fix signedness bug in sg2044_spifmc_write()
spi: sg2044-nor: Convert to dev_err_probe()
spi: sg2044-nor: Fully convert to device managed resources
dt-bindings: spi: add compatibles for mt7988
spi: spidev: Add an entry for the gocontroll moduline module slot
MAINTAINERS: add maintainer for the GOcontroll Moduline module slot
dt-bindings: connector: Add the GOcontroll Moduline module slot bindings
dt-bindings: vendor-prefixes: add GOcontroll
spi: Use inclusive language
spi: cadence-qspi: Improve spi memory performance
...
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mtd/nand-qpic-common.h | 7 | ||||
-rw-r--r-- | include/linux/spi/offload/consumer.h | 39 | ||||
-rw-r--r-- | include/linux/spi/offload/provider.h | 47 | ||||
-rw-r--r-- | include/linux/spi/offload/types.h | 100 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 56 |
5 files changed, 232 insertions, 17 deletions
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h index 4d9b736ff8b7..7760154de581 100644 --- a/include/linux/mtd/nand-qpic-common.h +++ b/include/linux/mtd/nand-qpic-common.h @@ -325,6 +325,10 @@ struct nandc_regs { __le32 read_location_last1; __le32 read_location_last2; __le32 read_location_last3; + __le32 spi_cfg; + __le32 num_addr_cycle; + __le32 busy_wait_cnt; + __le32 flash_feature; __le32 erased_cw_detect_cfg_clr; __le32 erased_cw_detect_cfg_set; @@ -339,6 +343,7 @@ struct nandc_regs { * * @core_clk: controller clock * @aon_clk: another controller clock + * @iomacro_clk: io macro clock * * @regs: a contiguous chunk of memory for DMA register * writes. contains the register values to be @@ -348,6 +353,7 @@ struct nandc_regs { * initialized via DT match data * * @controller: base controller structure + * @qspi: qpic spi structure * @host_list: list containing all the chips attached to the * controller * @@ -392,6 +398,7 @@ struct qcom_nand_controller { const struct qcom_nandc_props *props; struct nand_controller *controller; + struct qpic_spi_nand *qspi; struct list_head host_list; union { diff --git a/include/linux/spi/offload/consumer.h b/include/linux/spi/offload/consumer.h new file mode 100644 index 000000000000..cd7d5daa21e6 --- /dev/null +++ b/include/linux/spi/offload/consumer.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_CONSUMER_H +#define __LINUX_SPI_OFFLOAD_CONSUMER_H + +#include <linux/module.h> +#include <linux/spi/offload/types.h> +#include <linux/types.h> + +MODULE_IMPORT_NS("SPI_OFFLOAD"); + +struct device; +struct spi_device; + +struct spi_offload *devm_spi_offload_get(struct device *dev, struct spi_device *spi, + const struct spi_offload_config *config); + +struct spi_offload_trigger +*devm_spi_offload_trigger_get(struct device *dev, + struct spi_offload *offload, + enum spi_offload_trigger_type type); +int spi_offload_trigger_validate(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); +int spi_offload_trigger_enable(struct spi_offload *offload, + struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); +void spi_offload_trigger_disable(struct spi_offload *offload, + struct spi_offload_trigger *trigger); + +struct dma_chan *devm_spi_offload_tx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload); +struct dma_chan *devm_spi_offload_rx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload); + +#endif /* __LINUX_SPI_OFFLOAD_CONSUMER_H */ diff --git a/include/linux/spi/offload/provider.h b/include/linux/spi/offload/provider.h new file mode 100644 index 000000000000..76c7cf651092 --- /dev/null +++ b/include/linux/spi/offload/provider.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_PROVIDER_H +#define __LINUX_SPI_OFFLOAD_PROVIDER_H + +#include <linux/module.h> +#include <linux/spi/offload/types.h> +#include <linux/types.h> + +MODULE_IMPORT_NS("SPI_OFFLOAD"); + +struct device; +struct spi_offload_trigger; + +struct spi_offload *devm_spi_offload_alloc(struct device *dev, size_t priv_size); + +struct spi_offload_trigger_ops { + bool (*match)(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, u64 *args, u32 nargs); + int (*request)(struct spi_offload_trigger *trigger, + enum spi_offload_trigger_type type, u64 *args, u32 nargs); + void (*release)(struct spi_offload_trigger *trigger); + int (*validate)(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); + int (*enable)(struct spi_offload_trigger *trigger, + struct spi_offload_trigger_config *config); + void (*disable)(struct spi_offload_trigger *trigger); +}; + +struct spi_offload_trigger_info { + /** @fwnode: Provider fwnode, used to match to consumer. */ + struct fwnode_handle *fwnode; + /** @ops: Provider-specific callbacks. */ + const struct spi_offload_trigger_ops *ops; + /** Provider-specific state to be used in callbacks. */ + void *priv; +}; + +int devm_spi_offload_trigger_register(struct device *dev, + struct spi_offload_trigger_info *info); +void *spi_offload_trigger_get_priv(struct spi_offload_trigger *trigger); + +#endif /* __LINUX_SPI_OFFLOAD_PROVIDER_H */ diff --git a/include/linux/spi/offload/types.h b/include/linux/spi/offload/types.h new file mode 100644 index 000000000000..6f7892347871 --- /dev/null +++ b/include/linux/spi/offload/types.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +#ifndef __LINUX_SPI_OFFLOAD_TYPES_H +#define __LINUX_SPI_OFFLOAD_TYPES_H + +#include <linux/bits.h> +#include <linux/types.h> + +struct device; + +/* This is write xfer but TX uses external data stream rather than tx_buf. */ +#define SPI_OFFLOAD_XFER_TX_STREAM BIT(0) +/* This is read xfer but RX uses external data stream rather than rx_buf. */ +#define SPI_OFFLOAD_XFER_RX_STREAM BIT(1) + +/* Offload can be triggered by external hardware event. */ +#define SPI_OFFLOAD_CAP_TRIGGER BIT(0) +/* Offload can record and then play back TX data when triggered. */ +#define SPI_OFFLOAD_CAP_TX_STATIC_DATA BIT(1) +/* Offload can get TX data from an external stream source. */ +#define SPI_OFFLOAD_CAP_TX_STREAM_DMA BIT(2) +/* Offload can send RX data to an external stream sink. */ +#define SPI_OFFLOAD_CAP_RX_STREAM_DMA BIT(3) + +/** + * struct spi_offload_config - offload configuration + * + * This is used to request an offload with specific configuration. + */ +struct spi_offload_config { + /** @capability_flags: required capabilities. See %SPI_OFFLOAD_CAP_* */ + u32 capability_flags; +}; + +/** + * struct spi_offload - offload instance + */ +struct spi_offload { + /** @provider_dev: for get/put reference counting */ + struct device *provider_dev; + /** @priv: provider driver private data */ + void *priv; + /** @ops: callbacks for offload support */ + const struct spi_offload_ops *ops; + /** @xfer_flags: %SPI_OFFLOAD_XFER_* flags supported by provider */ + u32 xfer_flags; +}; + +enum spi_offload_trigger_type { + /* Indication from SPI peripheral that data is read to read. */ + SPI_OFFLOAD_TRIGGER_DATA_READY, + /* Trigger comes from a periodic source such as a clock. */ + SPI_OFFLOAD_TRIGGER_PERIODIC, +}; + +struct spi_offload_trigger_periodic { + u64 frequency_hz; +}; + +struct spi_offload_trigger_config { + /** @type: type discriminator for union */ + enum spi_offload_trigger_type type; + union { + struct spi_offload_trigger_periodic periodic; + }; +}; + +/** + * struct spi_offload_ops - callbacks implemented by offload providers + */ +struct spi_offload_ops { + /** + * @trigger_enable: Optional callback to enable the trigger for the + * given offload instance. + */ + int (*trigger_enable)(struct spi_offload *offload); + /** + * @trigger_disable: Optional callback to disable the trigger for the + * given offload instance. + */ + void (*trigger_disable)(struct spi_offload *offload); + /** + * @tx_stream_request_dma_chan: Optional callback for controllers that + * have an offload where the TX data stream is connected directly to a + * DMA channel. + */ + struct dma_chan *(*tx_stream_request_dma_chan)(struct spi_offload *offload); + /** + * @rx_stream_request_dma_chan: Optional callback for controllers that + * have an offload where the RX data stream is connected directly to a + * DMA channel. + */ + struct dma_chan *(*rx_stream_request_dma_chan)(struct spi_offload *offload); +}; + +#endif /* __LINUX_SPI_OFFLOAD_TYPES_H */ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 8497f4747e24..0ba5e49bace4 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -31,9 +31,11 @@ struct spi_transfer; struct spi_controller_mem_ops; struct spi_controller_mem_caps; struct spi_message; +struct spi_offload; +struct spi_offload_config; /* - * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, + * INTERFACES between SPI controller-side drivers and SPI target protocol handlers, * and SPI infrastructure. */ extern const struct bus_type spi_bus_type; @@ -128,7 +130,7 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, struct spi_transfer *xfer); /** - * struct spi_device - Controller side proxy for an SPI slave device + * struct spi_device - Controller side proxy for an SPI target device * @dev: Driver model representation of the device. * @controller: SPI controller used with the device. * @max_speed_hz: Maximum clock rate to be used with this chip @@ -172,7 +174,7 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, * @pcpu_statistics: statistics for the spi_device * @cs_index_mask: Bit mask of the active chipselect(s) in the chipselect array * - * A @spi_device is used to interchange data between an SPI slave + * A @spi_device is used to interchange data between an SPI target device * (usually a discrete chip) and CPU memory. * * In @dev, the platform_data is used to hold information about this @@ -386,15 +388,15 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch spi_unregister_driver) /** - * struct spi_controller - interface to SPI master or slave controller + * struct spi_controller - interface to SPI host or target controller * @dev: device interface to this driver * @list: link with the global spi_controller list * @bus_num: board-specific (and often SOC-specific) identifier for a * given SPI controller. * @num_chipselect: chipselects are used to distinguish individual - * SPI slaves, and are numbered from zero to num_chipselects. - * each slave has a chipselect signal, but it's common that not - * every chipselect is connected to a slave. + * SPI targets, and are numbered from zero to num_chipselects. + * each target has a chipselect signal, but it's common that not + * every chipselect is connected to a target. * @dma_alignment: SPI controller constraint on DMA buffers alignment. * @mode_bits: flags understood by this controller driver * @buswidth_override_bits: flags to override for this controller driver @@ -423,9 +425,9 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * must fail if an unrecognized or unsupported mode is requested. * It's always safe to call this unless transfers are pending on * the device whose settings are being modified. - * @set_cs_timing: optional hook for SPI devices to request SPI master + * @set_cs_timing: optional hook for SPI devices to request SPI * controller for configuring specific CS setup time, hold time and inactive - * delay interms of clock counts + * delay in terms of clock counts * @transfer: adds a message to the controller's transfer queue. * @cleanup: frees controller-specific state * @can_dma: determine whether this controller supports DMA @@ -496,6 +498,10 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @mem_ops: optimized/dedicated operations for interactions with SPI memory. * This field is optional and should only be implemented if the * controller has native support for memory like operations. + * @get_offload: callback for controllers with offload support to get matching + * offload instance. Implementations should return -ENODEV if no match is + * found. + * @put_offload: release the offload instance acquired by @get_offload. * @mem_caps: controller capabilities for the handling of memory operations. * @unprepare_message: undo any work done by prepare_message(). * @target_abort: abort the ongoing transfer request on an SPI target controller @@ -541,7 +547,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * * The driver for an SPI controller manages access to those devices through * a queue of spi_message transactions, copying data between CPU memory and - * an SPI slave device. For each such message it queues, it calls the + * an SPI target device. For each such message it queues, it calls the * message's completion function when the transaction completes. */ struct spi_controller { @@ -591,7 +597,7 @@ struct spi_controller { #define SPI_CONTROLLER_NO_TX BIT(2) /* Can't do buffer write */ #define SPI_CONTROLLER_MUST_RX BIT(3) /* Requires rx */ #define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */ -#define SPI_CONTROLLER_GPIO_SS BIT(5) /* GPIO CS must select slave */ +#define SPI_CONTROLLER_GPIO_SS BIT(5) /* GPIO CS must select target device */ #define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */ /* * The spi-controller has multi chip select capability and can @@ -658,7 +664,7 @@ struct spi_controller { * + To a given spi_device, message queueing is pure FIFO * * + The controller's main job is to process its message queue, - * selecting a chip (for masters), then transferring data + * selecting a chip (for controllers), then transferring data * + If there are multiple spi_device children, the i/o queue * arbitration algorithm is unspecified (round robin, FIFO, * priority, reservations, preemption, etc) @@ -740,6 +746,10 @@ struct spi_controller { const struct spi_controller_mem_ops *mem_ops; const struct spi_controller_mem_caps *mem_caps; + struct spi_offload *(*get_offload)(struct spi_device *spi, + const struct spi_offload_config *config); + void (*put_offload)(struct spi_offload *offload); + /* GPIO chip select */ struct gpio_desc **cs_gpiods; bool use_gpio_descriptors; @@ -822,7 +832,7 @@ void spi_take_timestamp_post(struct spi_controller *ctlr, /* The SPI driver core manages memory for the spi_controller classdev */ extern struct spi_controller *__spi_alloc_controller(struct device *host, - unsigned int size, bool slave); + unsigned int size, bool target); static inline struct spi_controller *spi_alloc_host(struct device *dev, unsigned int size) @@ -841,7 +851,7 @@ static inline struct spi_controller *spi_alloc_target(struct device *dev, struct spi_controller *__devm_spi_alloc_controller(struct device *dev, unsigned int size, - bool slave); + bool target); static inline struct spi_controller *devm_spi_alloc_host(struct device *dev, unsigned int size) @@ -963,6 +973,8 @@ struct spi_res { * @rx_sg_mapped: If true, the @rx_sg is mapped for DMA * @tx_sg: Scatterlist for transmit, currently not for client use * @rx_sg: Scatterlist for receive, currently not for client use + * @offload_flags: Flags that are only applicable to specialized SPI offload + * transfers. See %SPI_OFFLOAD_XFER_* in spi-offload.h. * @ptp_sts_word_pre: The word (subject to bits_per_word semantics) offset * within @tx_buf for which the SPI device is requesting that the time * snapshot for this transfer begins. Upon completing the SPI transfer, @@ -977,12 +989,12 @@ struct spi_res { * purposefully (instead of setting to spi_transfer->len - 1) to denote * that a transfer-level snapshot taken from within the driver may still * be of higher quality. - * @ptp_sts: Pointer to a memory location held by the SPI slave device where a + * @ptp_sts: Pointer to a memory location held by the SPI target device where a * PTP system timestamp structure may lie. If drivers use PIO or their * hardware has some sort of assist for retrieving exact transfer timing, * they can (and should) assert @ptp_sts_supported and populate this * structure using the ptp_read_system_*ts helper functions. - * The timestamp must represent the time at which the SPI slave device has + * The timestamp must represent the time at which the SPI target device has * processed the word, i.e. the "pre" timestamp should be taken before * transmitting the "pre" word, and the "post" timestamp after receiving * transmit confirmation from the controller for the "post" word. @@ -1083,6 +1095,9 @@ struct spi_transfer { u32 effective_speed_hz; + /* Use %SPI_OFFLOAD_XFER_* from spi-offload.h */ + unsigned int offload_flags; + unsigned int ptp_sts_word_pre; unsigned int ptp_sts_word_post; @@ -1108,6 +1123,7 @@ struct spi_transfer { * @state: for use by whichever driver currently owns the message * @opt_state: for use by whichever driver currently owns the message * @resources: for resource management when the SPI message is processed + * @offload: (optional) offload instance used by this message * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer. The sequence is "atomic" @@ -1168,6 +1184,12 @@ struct spi_message { */ void *opt_state; + /* + * Optional offload instance used by this message. This must be set + * by the peripheral driver before calling spi_optimize_message(). + */ + struct spi_offload *offload; + /* List of spi_res resources when the SPI message is processed */ struct list_head resources; }; @@ -1600,7 +1622,7 @@ struct spi_board_info { * bus_num is board specific and matches the bus_num of some * spi_controller that will probably be registered later. * - * chip_select reflects how this chip is wired to that master; + * chip_select reflects how this chip is wired to that controller; * it's less than num_chipselect. */ u16 bus_num; |