From patchwork Wed Dec 11 20:54:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849669 Received: from mail-oo1-f41.google.com (mail-oo1-f41.google.com [209.85.161.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA2E92288D2 for ; Wed, 11 Dec 2024 20:54:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950500; cv=none; b=q41Y+U5YcBhw3MWRaTuT/BK/PALP7ZmyZBi0adZ8Y4iE4xlTaY+Lgm1cxNOtHhke6AMEcO1CNtU9suzeV08+i4LMsVGrLb2pWKxtsLP6UVr5Bu17G5kuhc0tGy+CegIIaubgvPfR9HE5qLYHznLeLAGuiwBcTjMnJEwxlkeMvFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950500; c=relaxed/simple; bh=RGggUajwKcxwMBqnwmDZ76Eu+OfENqU99nf0uDpoQRo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oHFqwNkTc5sYB1gJzu9/u7F5xzAU99hAsw5yggo85BuBCV7mY7TYZ0VgRVzlpWr7kRBF0SZGsh6okMEDXLfnn7vlghnsn3/6Gng1XbgGrdS09EsORuCb9qzEj39Q7Hxpu+a5fvhwa4x9izz2i6iNWVOdtBY6iicp/Ya3u7w185k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=t4W4CT+W; arc=none smtp.client-ip=209.85.161.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="t4W4CT+W" Received: by mail-oo1-f41.google.com with SMTP id 006d021491bc7-5f2e370bb3aso200124eaf.0 for ; Wed, 11 Dec 2024 12:54:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950497; x=1734555297; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=4ffc3LxMkAvRH+svHl43EnhBnXUPIwZq2nOCjPB5PSI=; b=t4W4CT+WaFUICIFPy9VoOBAfzBVgHz8ww/CDhMDHqjy1ZVxq8ukEjYeweTgPl5ioyg lgexYO2GBpzXrzhNPZ34NGBDEuTOMFzk5eQu+bpHdurTIlBYlYTO8zM+OH7TJZbRmS4N 5cHBa/YvQoDYJkV8BUOrmrTLHJoLNxtlXpiUQ+Sq4sDnwWYcIF2GGK/2QHhuB0oy7baS vvd624yUoRzu3prnU75f1saGZoC7NvtSh5I0iXbPZ9gQFNxpQ0kdcg0hXNPPI/JFHX10 F7cC6Edets41PNObY2p4y3CMMzk9SwfDowf6+Vq7nHwPmAfRdd/Bg3pJGMe9lNedrTRd 5DOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950497; x=1734555297; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4ffc3LxMkAvRH+svHl43EnhBnXUPIwZq2nOCjPB5PSI=; b=bYdm7m/eHCZ6Wa5hmqAWnVJ5rWKWq01EzzCQulIFE14j/Y+plr9LJqNyOGDVRUw8n7 DLZUC449ACDTb5t6DnhCMVsd7TusRnBbGwCq4zSdKP16Yi/YHpv1/G/m38MYgG8xKlI0 EC+qPFr2IC7Cgj2Xjk2oZjIbIR8KFaF39bEW5zYZlfmm75tABsWQ/PLu5zqxGqgtKHfq PeULakqKxTuGy8L0YUq9V2mVIVWoht+59hIOtQsGNycHsoKoAP+vJTOSMGq1hdp0KSLA o52fFt19+4BWsOt50K4SEkErorZn6abM1wvoG0GIA8cfZN+rrPkkROK3NNovV7CuDGeh YTxQ== X-Forwarded-Encrypted: i=1; AJvYcCVzVQYrDRcGWJrlldRV+T3xGOWyU+Vvy+HyG7jFeSosllIYpbCVAJMo1cvzPdDqS1FOVanQYTxKGSQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwjOhTeh1xpM14XZcUETy/nGyhyxJcpOh6Y4GoRwmTFjUjEx1fd uUghieXoJ1z577jftOJJWGnlAbbQT5oCraObCunWD3kad8Sp6WccpFsAxLyTI0k= X-Gm-Gg: ASbGncuGCkbbtVtaGQBHD4D2hZcsI+hsc7mIqZUHLn/vbK1/n1zDknwNom/R7GNprn/ OB8e12rFpyn0vGT8SdZ4D0ihre9+rPLQEeHFl3P6VxKIDO7zYKdEGIq7hjbQnNJOy+Qf7Vt/rFF SVp1AEaWKUwVfuk2b1Nm7K9iwgFNyHhDqzjZXgPSujG1jxj7ROVKdYGKNxrW25PvQjxq7obIgHD VSyk0z2QEGkjG4153uBy4OWTET91OzLyTFIUzA9DDkznfCopBeWm/+A6raF51lzGL9teF0Iv3dB fQLwoCxing== X-Google-Smtp-Source: AGHT+IG7inO0xnuwDZeUqSYTrfiBKUGM+ravvukMEKOFTzNGsJgAfy6fOUDwdyEAKDaxSFKj91kwLA== X-Received: by 2002:a05:6820:1989:b0:5f1:e3d1:b994 with SMTP id 006d021491bc7-5f2ef873a5emr610173eaf.0.1733950496838; Wed, 11 Dec 2024 12:54:56 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:54:55 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:38 -0600 Subject: [PATCH v6 01/17] spi: add basic support for SPI offloading Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-1-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, Jonathan Cameron , David Lechner X-Mailer: b4 0.14.2 Add the basic infrastructure to support SPI offload providers and consumers. SPI offloading is a feature that allows the SPI controller to perform transfers without any CPU intervention. This is useful, e.g. for high-speed data acquisition. SPI controllers with offload support need to implement the get_offload and put_offload callbacks and can use the devm_spi_offload_alloc() to allocate offload instances. SPI peripheral drivers will call devm_spi_offload_get() to get a reference to the matching offload instance. This offload instance can then be attached to a SPI message to request offloading that message. It is expected that SPI controllers with offload support will check for the offload instance in the SPI message in the ctlr->optimize_message() callback and handle it accordingly. CONFIG_SPI_OFFLOAD is intended to be a select-only option. Both consumer and provider drivers should `select SPI_OFFLOAD` in their Kconfig to ensure that the SPI core is built with offload support. Reviewed-by: Jonathan Cameron Signed-off-by: David Lechner --- v6 changes: * Drop use of PTR_ERR_OR_ZERO(). * Split header into types.h/provider.h/consumer.h. * Remove unused spi_controller_offload_ops forward declaration. v5 changes: * Don't include linux/property.h (moved to later patch). * Only allocate single offload instance instead of array. * Allocate *priv separately to avoid alignment issues. * Add put_offload() callback instead of assuming devm semantics. * Drop struct spi_offload::spi. It was only being used as a flag. * Don't get/put struct spi_offload::provider_dev. * Add MAINTAINERS entry for me as reviewer for anything related to SPI offload. v4 changes: * SPI offload functions moved to a separate file instead of spi.c (spi.c is already too long). * struct spi_offload and devm_spi_offload_get() are back, similar to but improved over v1. This avoids having to pass the function ID string to every function call and re-lookup the offload instance. * offload message prepare/unprepare functions are removed. Instead the existing optimize/unoptimize functions should be used. Setting spi_message::offload pointer is used as a flag to differentiate between an offloaded message and a regular message. v3 changes: * Minor changes to doc comments. * Changed to use phandle array for spi-offloads. * Changed id to string to make use of spi-offload-names. v2 changes: * This is a rework of "spi: add core support for controllers with offload capabilities" from v1. * The spi_offload_get() function that Nuno didn't like is gone. Instead, there is now a mapping callback that uses the new generic devicetree binding to request resources automatically when a SPI device is probed. * The spi_offload_enable/disable() functions for dealing with hardware triggers are deferred to a separate patch. * This leaves adding spi_offload_prepare/unprepare() which have been reworked to be a bit more robust. --- MAINTAINERS | 6 ++ drivers/spi/Kconfig | 3 + drivers/spi/Makefile | 1 + drivers/spi/spi-offload.c | 114 +++++++++++++++++++++++++++++++++++ include/linux/spi/offload/consumer.h | 22 +++++++ include/linux/spi/offload/provider.h | 19 ++++++ include/linux/spi/offload/types.h | 43 +++++++++++++ include/linux/spi/spi.h | 17 ++++++ 8 files changed, 225 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index bf2dcd4e0261785add520b5eac747ceac523e112..9284a257607a740ab7f6fd960c2bcdc34ead7586 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22129,6 +22129,12 @@ F: Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml F: drivers/mtd/spi-nor/ F: include/linux/mtd/spi-nor.h +SPI OFFLOAD +R: David Lechner +F: drivers/spi/spi-offload.c +F: include/linux/spi/spi-offload.h +K: spi_offload + SPI SUBSYSTEM M: Mark Brown L: linux-spi@vger.kernel.org diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ea8a310329274bb2701e265cd152a56fb4e0f3a7..02064a4e292815ec0213e2e446b4f90ed8855a52 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -55,6 +55,9 @@ config SPI_MEM This extension is meant to simplify interaction with SPI memories by providing a high-level interface to send memory-like commands. +config SPI_OFFLOAD + bool + comment "SPI Master Controller Drivers" config SPI_AIROHA_SNFI diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 9db7554c1864bf9b37dcf59c16eb76f5af03a7e8..bb5fc20df21332232533c2e70c0cc230f6bcf27f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -10,6 +10,7 @@ ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG obj-$(CONFIG_SPI_MASTER) += spi.o obj-$(CONFIG_SPI_MEM) += spi-mem.o obj-$(CONFIG_SPI_MUX) += spi-mux.o +obj-$(CONFIG_SPI_OFFLOAD) += spi-offload.o obj-$(CONFIG_SPI_SPIDEV) += spidev.o obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o diff --git a/drivers/spi/spi-offload.c b/drivers/spi/spi-offload.c new file mode 100644 index 0000000000000000000000000000000000000000..3a40ef30debf09c6fd7b2c14526f3e5976e2b21f --- /dev/null +++ b/drivers/spi/spi-offload.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Analog Devices Inc. + * Copyright (C) 2024 BayLibre, SAS + */ + +/* + * SPI Offloading support. + * + * Some SPI controllers support offloading of SPI transfers. Essentially, this + * is the ability for a SPI controller to perform SPI transfers with minimal + * or even no CPU intervention, e.g. via a specialized SPI controller with a + * hardware trigger or via a conventional SPI controller using a non-Linux MCU + * processor core to offload the work. + */ + +#define DEFAULT_SYMBOL_NAMESPACE "SPI_OFFLOAD" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct spi_controller_and_offload { + struct spi_controller *controller; + struct spi_offload *offload; +}; + +/** + * devm_spi_offload_alloc() - Allocate offload instance + * @dev: Device for devm purposes and assigned to &struct spi_offload.provider_dev + * @priv_size: Size of private data to allocate + * + * Offload providers should use this to allocate offload instances. + * + * Return: Pointer to new offload instance or error on failure. + */ +struct spi_offload *devm_spi_offload_alloc(struct device *dev, + size_t priv_size) +{ + struct spi_offload *offload; + void *priv; + + offload = devm_kzalloc(dev, sizeof(*offload), GFP_KERNEL); + if (!offload) + return ERR_PTR(-ENOMEM); + + priv = devm_kzalloc(dev, priv_size, GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + offload->provider_dev = dev; + offload->priv = priv; + + return offload; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_alloc); + +static void spi_offload_put(void *data) +{ + struct spi_controller_and_offload *resource = data; + + resource->controller->put_offload(resource->offload); + kfree(resource); +} + +/** + * devm_spi_offload_get() - Get an offload instance + * @dev: Device for devm purposes + * @spi: SPI device to use for the transfers + * @config: Offload configuration + * + * Peripheral drivers call this function to get an offload instance that meets + * the requirements specified in @config. If no suitable offload instance is + * available, -ENODEV is returned. + * + * Return: Offload instance or error on failure. + */ +struct spi_offload *devm_spi_offload_get(struct device *dev, + struct spi_device *spi, + const struct spi_offload_config *config) +{ + struct spi_controller_and_offload *resource; + int ret; + + if (!spi || !config) + return ERR_PTR(-EINVAL); + + if (!spi->controller->get_offload) + return ERR_PTR(-ENODEV); + + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (!resource) + return ERR_PTR(-ENOMEM); + + resource->controller = spi->controller; + resource->offload = spi->controller->get_offload(spi, config); + if (IS_ERR(resource->offload)) { + kfree(resource); + return resource->offload; + } + + ret = devm_add_action_or_reset(dev, spi_offload_put, resource); + if (ret) + return ERR_PTR(ret); + + return resource->offload; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_get); diff --git a/include/linux/spi/offload/consumer.h b/include/linux/spi/offload/consumer.h new file mode 100644 index 0000000000000000000000000000000000000000..05543dbedf3086fb4befcd149cff3c8c70a88825 --- /dev/null +++ b/include/linux/spi/offload/consumer.h @@ -0,0 +1,22 @@ +/* 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 +#include +#include + +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); + +#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 0000000000000000000000000000000000000000..278c4edfcdb7b1f43870ca99d2ba252bf2820576 --- /dev/null +++ b/include/linux/spi/offload/provider.h @@ -0,0 +1,19 @@ +/* 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 +#include + +MODULE_IMPORT_NS("SPI_OFFLOAD"); + +struct device; + +struct spi_offload *devm_spi_offload_alloc(struct device *dev, size_t priv_size); + +#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 0000000000000000000000000000000000000000..a74f8d84541b10062353e81a638f05628b696394 --- /dev/null +++ b/include/linux/spi/offload/types.h @@ -0,0 +1,43 @@ +/* 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 + +struct device; + +/* 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; +}; + +#endif /* __LINUX_SPI_OFFLOAD_TYPES_H */ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 8497f4747e24d4ecd85b74f49609ac1c82c73535..98bdc8c16c20521c0a94e5f72f5e71c4f6d7d11e 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -31,6 +31,8 @@ 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, @@ -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 @@ -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; @@ -1108,6 +1118,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 +1179,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; }; From patchwork Wed Dec 11 20:54:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849668 Received: from mail-ot1-f41.google.com (mail-ot1-f41.google.com [209.85.210.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 962572288FE for ; Wed, 11 Dec 2024 20:55:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950502; cv=none; b=sj6nQHCMhYHPSnu4VaI9JqYahT5q0Su1iqowHN7O7BZJLlLj9+sVUvh56VG2WeTB7EJRNR7UH5zUDYiXmS0/RLpgV6nsKzv+m8w+ZC1owxKjQQVqVBw8u24wTV0daW/at6yMeB7SvwZnQ3qTE4YKK/WFORy2Xpkudzdix7Fs9AE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950502; c=relaxed/simple; bh=XZtUpr/DURpr/L2sxiom5IoH3+HQHJD/Z1pBX1+yTWM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gisli5Livzqv6g/OCA0fWfqz+BvBizOIni4adBiJ7wc3FVm2oMDMzy0oyL4FXWaK/YdkarJ9U1MpCVjjWgWm7fwhMjwQQ//Wzqb6EDEMvBOXPKWERB/GReTKUDWnYoFujDjP8wvN9v9H/kQsi/I36eWuP894+eBcNfTbn/dcBtM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=pDSf7vzv; arc=none smtp.client-ip=209.85.210.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="pDSf7vzv" Received: by mail-ot1-f41.google.com with SMTP id 46e09a7af769-71e1d6c7738so516940a34.2 for ; Wed, 11 Dec 2024 12:55:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950500; x=1734555300; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=13F43V2/MzfKP/yJr1bHKQJVOtOvlPMBJZi2ZlwKDuQ=; b=pDSf7vzvR7Uk/cANUdnE84v5WYVrmVsrE6SKptWAWrBM5fs+eXobtYNckPxOwQT18M kg2jz7aZJhUlqBpMUoAskMQruxKo7FNFg68g0TNl/XufutkKepdLC2XvvLU9V32D4jUh ARabx4BySMqocNXw/94PnKNO5GL/zPtopGGLf6iSP0PT0+k52fXpwXIgpz/sjs+03Lj6 oiOB9QgWIK17MwidX8cd9EtkH+T0aOg7OP722RHfjM2kws4FMJKL2B1YcGkRmApWauLr CnNeqahVygVOGRXhTWrh5cFbd4UuNgBaUrtreKCNe3585aZtYQ6JdaakgcCsTcxEGSBO EYUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950500; x=1734555300; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=13F43V2/MzfKP/yJr1bHKQJVOtOvlPMBJZi2ZlwKDuQ=; b=QHHJz+ih8x9kiDB/tXsarkXC9lUfTljrPyE8Xj35Wg29xM+CLUkegFHiWaw47Mcaq1 rro6CYW5AV44gWrBQ4SiKLSgCu9T9Ymn3r0JVHQXU4uKYjwkT5R56eO8ofQT6/kPhrh7 OgbsCOc9OuIdCfiXAHoRO/wr4U/zmYBDXr5udWplE4uxqySGb3Ax5K7phACu83mEYYUL BIVp9rb5y1Osn2mcAWOiY9WVbWJi7ZpRrM+MofRq8fqvupWKeZTK0Id0v8CoxKK9CtEY +JK1FYXNv89az5F6SGmtud2fWrdxBdx8zd5wVQg66d/mIgsa/beURvjJhrvCBoKTSHyw Fouw== X-Forwarded-Encrypted: i=1; AJvYcCVbW5DMHYnQ2YjjdQHAqP91Jpwe0EUqSJKrz/aVF3x4ABVUrfGw3f2/B3zv7HklPCFGGPG3/LJeu/o=@vger.kernel.org X-Gm-Message-State: AOJu0YxT9BDSWjKHQ5WYTCSncNZsEg8df9pQKu/Cv/6Ak2VSKfx68V5x i2+DyJjwZRW/pJ6WNTarAtzal7O33DDNATcbU+/Wsdh2dteOmgxBGUJdoAo9pnM= X-Gm-Gg: ASbGnctQqmrlaTAITHDGLNk8LgsgKkU3OIwbpbKXviEaO47ywD1srELaDvpDRfs/IaU fXjaLvx20BI3gP/9vfXVGxcavJdMrljR74ihBEzFWiMOYocYntPS54I3kE6yr0JWEW1O93o9rMw ME+Gn99qBXUcXD4wiglbjVCX7KhhBG/qaivECtbKM95WNlNzjktgr7yWkuw28irVQp9Ytiz/64y iWH/GmL9FhAtkQbW4i867MbKedDqgRc2h1qJmRXlV6MrmnpKKWyjGi71hZqiVj5oq66mYILqPGC cYPKjYweWw== X-Google-Smtp-Source: AGHT+IFj7c/njNJ9PwxP0C3GEgabzaeOT+72JrS8RcScb/tiWJFWNji25E8s/KzbYVZsbfcjXdh7VQ== X-Received: by 2002:a05:6830:6e87:b0:71e:1ca5:fc90 with SMTP id 46e09a7af769-71e29c5d7dcmr541603a34.26.1733950499810; Wed, 11 Dec 2024 12:54:59 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.54.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:54:59 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:40 -0600 Subject: [PATCH v6 03/17] dt-bindings: trigger-source: add generic PWM trigger source Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-3-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.2 Add a new binding for using a PWM signal as a trigger source. The idea here is similar to e.g. "pwm-clock" to allow a trigger source consumer to use a PWM provider as a trigger source. Signed-off-by: David Lechner --- v6 changes: * Moved file from bindings/spi/ to bindings/trigger-source/ * Updated description to not mention SPI * Dropped $ref: /schemas/spi/trigger-source.yaml# * Swapped order in name to be consistent with "pwm-clock" v5 changes: * Add MAINTAINERS entry v4 changes: new patch in v4 --- .../bindings/trigger-source/pwm-trigger.yaml | 37 ++++++++++++++++++++++ MAINTAINERS | 5 +++ 2 files changed, 42 insertions(+) diff --git a/Documentation/devicetree/bindings/trigger-source/pwm-trigger.yaml b/Documentation/devicetree/bindings/trigger-source/pwm-trigger.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1eac20031dc3cf921aafb8aa37f4e4eca1075835 --- /dev/null +++ b/Documentation/devicetree/bindings/trigger-source/pwm-trigger.yaml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/trigger-source/pwm-trigger.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Generic trigger source using PWM + +description: Remaps a PWM channel as a trigger source. + +maintainers: + - David Lechner + +properties: + compatible: + const: pwm-trigger + + '#trigger-source-cells': + const: 0 + + pwms: + maxItems: 1 + +required: + - compatible + - '#trigger-source-cells' + - pwms + +additionalProperties: false + +examples: + - | + trigger { + compatible = "pwm-trigger"; + #trigger-source-cells = <0>; + pwms = <&pwm 0 1000000 0>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 9284a257607a740ab7f6fd960c2bcdc34ead7586..b2aa6f37743e48353c60e5973ea8126590c7f6d5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -23879,6 +23879,11 @@ W: https://github.com/srcres258/linux-doc T: git git://github.com/srcres258/linux-doc.git doc-zh-tw F: Documentation/translations/zh_TW/ +TRIGGER SOURCE - PWM +M: David Lechner +S: Maintained +F: Documentation/devicetree/bindings/trigger-source/pwm-trigger.yaml + TRUSTED SECURITY MODULE (TSM) ATTESTATION REPORTS M: Dan Williams L: linux-coco@lists.linux.dev From patchwork Wed Dec 11 20:54:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849667 Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C1D6122966C for ; Wed, 11 Dec 2024 20:55:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950507; cv=none; b=VJqDpoIK04HPZBCBfhDXGPObIxrWax72T+kZjyD4LMfn+88ktRJvJwlcEv9M4xEykhrmwIC0qjwC6vYt/sy0AfZYoLziKSgOV6fVJQJa477yRVKUz71Mz9GS6CWNEJ6uK5fbin1D30GGIkKrQ84h9FAJeIbQwFLS9ZLN41cW4wA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950507; c=relaxed/simple; bh=zdncvfZ0Q50oYp1R7RHAvey85jbOGhAbt2b/jbzQSKQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ml2a2W1l0/T0ea9N0Ggz+xZl9VEmXBnzJFAmMcw/yuTxLJ+ZO5yqVSgdCBePb3sasUWf7i309AjBderLy4Jj8b20T+JFNNQprI3Y7+Bm5e5rdWDfhCCEpg+mzqaX9/T6rh3Zj99Aq9GfCU1yMPa24fBds80MWhhQa8D6Ws/MxEM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=csJI4HNP; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="csJI4HNP" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-71e163493efso818174a34.3 for ; Wed, 11 Dec 2024 12:55:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950504; x=1734555304; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=vouqSSWMwE0i1CMHfrBToPiWRjTEnBfzG9E3I/smeiU=; b=csJI4HNPhzHiuPZlBZaE7+ln7Ng0r5BDh7vNMonX4/vA3NaYgOW5qdh29vyhEkOsIB nS1O4pwa1MlmQMDjk8aRytFOWwYbmGZ3brRImuTgPUg8vSl4gpBB8LnYLsWdyBcQQydL D9nVysl5Lby8JreBZgN1FXu+VeS4gxsJG7MlVOFd/ZXXWB4SJWtajhQ08U7JpmgAYrMI PZ5sysElFndGZhPmps6q2xlLfyPdBmJr7E+nFR87jHkWGcxDo37rxY1PtLCC6S3Mva00 hAsxoof7X61tCJ2u8M08OVYqbQ1qxI7zxU0gRfhqvhrLFNKI6MWk/F05ymsmrQaIYIyR MS9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950504; x=1734555304; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vouqSSWMwE0i1CMHfrBToPiWRjTEnBfzG9E3I/smeiU=; b=p4w3S13j4KnHXkQyMYJQfO6KXpB7SAUqWLNRtQK8PYease/r2MHFHDwd+x0IwB7YLY QE1HiS7lxZMANS86uGgiW7Jb+WwNx5ugLQwnanOkNHiE6QrH/3WNTj12JEHzsGJ/83eU 2+e3R190BiRyo5Dq2/FCB1nxG06eKsphK69Dv1os7HA39/ejYPBtnXb7w8p4nR1KNXUO Edr0FAV3Dm3f3J1VhgYinG8PrTkooTXkb+Rpz1wjFbXW2wrUOs5l3bHswz6YDpLiAFsb wjFNevVGvOogPhXfr0WftT9gF0mUfBHjK8bHgqJvDgZKbhDZAUlNgrdLyBtEvuZi5wen C1Qw== X-Forwarded-Encrypted: i=1; AJvYcCWjnsKU5pCxX5OKTtKQe6FBRKAJUvtOJAFC5vQdI99r814qq9GxDDWAMDsmYG1Ue3Fcx0FFzWW30tE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4zxXBUDZdc0n37DYF2AHaz3SLRFSrsZv1Kz3qby3rFM57/PXL GEiIIZ4RFnCBJXD0IiFgAbX2eAis96bseexI2x3keBm4nqXVB8kpUppBo7o2zTs= X-Gm-Gg: ASbGncte7tl1TJsXsl32Y4h4MtXL4NNwO+pxiOUPCeco7EHCOqFADQRU5BQA6503zLb qByXx9iELrb2kLpfUfrVITMIbj6MgugV+jEHrH/0x0ZsyHdH5Mh9YBQVi4txTvBvTTErqAkvqYD Le1xdAeap2yPhWLwpdH4CAe33zCxjdLuvLNsRnYdUBZVrhJHFmrYvHR25hx1sc/YIh8YOuoAc9u HWoTs+0p7bpVHJYMVCMaDhs/hJMebCJe/bbENTWeYzMapijHAZcS9gv+TFHcpKjDtcbdHH5C9w5 BlxcrL546w== X-Google-Smtp-Source: AGHT+IGjdtY9SJoSuhMzq6sD9FjC+U2bj5zrP1DIdEBADIpRixwTBYhxCGTjehUjJtVHBExWPH0lGQ== X-Received: by 2002:a05:6830:6d09:b0:717:f666:9559 with SMTP id 46e09a7af769-71e29c5a609mr595769a34.9.1733950503638; Wed, 11 Dec 2024 12:55:03 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:03 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:42 -0600 Subject: [PATCH v6 05/17] spi: add offload TX/RX streaming APIs Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-5-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.2 Most configuration of SPI offloads is handled opaquely using the offload pointer that is passed to the various offload functions. However, there are some offload features that need to be controlled on a per transfer basis. This patch adds a flag field to struct spi_transfer to allow specifying such features. The first feature to be added is the ability to stream data to/from a hardware sink/source rather than using a tx or rx buffer. Additional flags can be added in the future as needed. A flags field is also added to the offload struct for providers to indicate which flags are supported. This allows for generic checking of offload capabilities during __spi_validate() so that each offload provider doesn't have to implement their own validation. As a first users of this streaming capability, getter functions are added to get a DMA channel that is directly connected to the offload. Peripheral drivers will use this to get a DMA channel and configure it to suit their needs. Signed-off-by: David Lechner --- v6 changes: * Update for header file split. * Fix wrong kernel-doc comments. v5 change: * Remove incorrect comment about caller needing to release DMA channels. v4 changes: * DMA API's now automatically release DMA channels instead of leaving it up to the caller. v3 changes: * Added spi_offload_{tx,rx}_stream_get_dma_chan() functions. v2 changes: * This is also split out from "spi: add core support for controllers with offload capabilities". * In the previous version, we were using (void *)-1 as a sentinel value that could be assigned, e.g. to rx_buf. But this was naive since there is core code that would try to dereference this pointer. So instead, we've added a new flags field to the spi_transfer structure for this sort of thing. This also has the advantage of being able to be used in the future for other arbitrary features. --- drivers/spi/spi-offload.c | 70 ++++++++++++++++++++++++++++++++++++ drivers/spi/spi.c | 10 ++++++ include/linux/spi/offload/consumer.h | 5 +++ include/linux/spi/offload/types.h | 19 ++++++++++ include/linux/spi/spi.h | 3 ++ 5 files changed, 107 insertions(+) diff --git a/drivers/spi/spi-offload.c b/drivers/spi/spi-offload.c index 43582e50e279c4b1b958765fec556aaa91180e55..df5e963d5ee29d37833559595536a460c530bc81 100644 --- a/drivers/spi/spi-offload.c +++ b/drivers/spi/spi-offload.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -332,6 +333,75 @@ void spi_offload_trigger_disable(struct spi_offload *offload, } EXPORT_SYMBOL_GPL(spi_offload_trigger_disable); +static void spi_offload_release_dma_chan(void *chan) +{ + dma_release_channel(chan); +} + +/** + * devm_spi_offload_tx_stream_request_dma_chan - Get the DMA channel info for the TX stream + * @dev: Device for devm purposes. + * @offload: Offload instance + * + * This is the DMA channel that will provide data to transfers that use the + * %SPI_OFFLOAD_XFER_TX_STREAM offload flag. + * + * Return: Pointer to DMA channel info, or negative error code + */ +struct dma_chan +*devm_spi_offload_tx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload) +{ + struct dma_chan *chan; + int ret; + + if (!offload->ops || !offload->ops->tx_stream_request_dma_chan) + return ERR_PTR(-EOPNOTSUPP); + + chan = offload->ops->tx_stream_request_dma_chan(offload); + if (IS_ERR(chan)) + return chan; + + ret = devm_add_action_or_reset(dev, spi_offload_release_dma_chan, chan); + if (ret) + return ERR_PTR(ret); + + return chan; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_tx_stream_request_dma_chan); + +/** + * devm_spi_offload_rx_stream_request_dma_chan - Get the DMA channel info for the RX stream + * @dev: Device for devm purposes. + * @offload: Offload instance + * + * This is the DMA channel that will receive data from transfers that use the + * %SPI_OFFLOAD_XFER_RX_STREAM offload flag. + * + * Return: Pointer to DMA channel info, or negative error code + */ +struct dma_chan +*devm_spi_offload_rx_stream_request_dma_chan(struct device *dev, + struct spi_offload *offload) +{ + struct dma_chan *chan; + int ret; + + if (!offload->ops || !offload->ops->rx_stream_request_dma_chan) + return ERR_PTR(-EOPNOTSUPP); + + chan = offload->ops->rx_stream_request_dma_chan(offload); + if (IS_ERR(chan)) + return chan; + + ret = devm_add_action_or_reset(dev, spi_offload_release_dma_chan, chan); + if (ret) + return ERR_PTR(ret); + + return chan; +} +EXPORT_SYMBOL_GPL(devm_spi_offload_rx_stream_request_dma_chan); + /* Triggers providers */ static void spi_offload_trigger_unregister(void *data) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ff1add2ecb91f18cf82e6f1e9595584c11adf9d8..4a871db9ee636aba64c866ebdd8bb1dbf82e0f42 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -4163,6 +4164,15 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (_spi_xfer_word_delay_update(xfer, spi)) return -EINVAL; + + /* make sure controller supports required offload features */ + if (xfer->offload_flags) { + if (!message->offload) + return -EINVAL; + + if (xfer->offload_flags & ~message->offload->xfer_flags) + return -EINVAL; + } } message->status = -EINPROGRESS; diff --git a/include/linux/spi/offload/consumer.h b/include/linux/spi/offload/consumer.h index 5a0ec5303d600728959594bcdbd0cb2baeba7c77..cd7d5daa21e69b61c16eba6c10c855345a4f3297 100644 --- a/include/linux/spi/offload/consumer.h +++ b/include/linux/spi/offload/consumer.h @@ -31,4 +31,9 @@ int spi_offload_trigger_enable(struct spi_offload *offload, 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/types.h b/include/linux/spi/offload/types.h index 7476f2073b02ee0f9edd3ae75e587b075746fa92..86d0e8cb9495bb43e177378b2041067de8ea8786 100644 --- a/include/linux/spi/offload/types.h +++ b/include/linux/spi/offload/types.h @@ -11,6 +11,11 @@ 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. */ @@ -40,6 +45,8 @@ struct spi_offload { 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 { @@ -75,6 +82,18 @@ struct spi_offload_ops { * 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 98bdc8c16c20521c0a94e5f72f5e71c4f6d7d11e..4c087009cf974595f23036b1b7a030a45913420c 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1093,6 +1093,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; From patchwork Wed Dec 11 20:54:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849666 Received: from mail-ot1-f46.google.com (mail-ot1-f46.google.com [209.85.210.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A604A231A5A for ; Wed, 11 Dec 2024 20:55:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950513; cv=none; b=iiHlnDYPyAYI20WDW7rwYvRybbfcVJGE5bniTidwbx/7osUZd0tj8iog8gc/BbvdF8nqKnGSjj98ZPduJOvD9JTbm33+DDZVu9BVjRDcvFUDXV+mUO8eOswcZvkLVlHvF+rmbPGH/cDIa5LA76nD7JZFKndJiDVe4cgfADSuWeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950513; c=relaxed/simple; bh=bG112EwT4RFP3FXqYfRosO4GL5m752X4biwP3n9IITc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ONl4nvp/PIgXWX6p1Hw7Nu757GR5Ibby2CS0VUe2cgSCbk6ajpcl9oQVZY/A+TZAUZzHXSe5Dne4JcX272IBnVcvIp5roNDLipKS8Xo9PcPy69ztu5gfbFkGysZfxrQfzMypLG6wMDmWIwZOFDoMkd7bVVqSc2sWz/aBe2eq8UQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=VYgA+t7d; arc=none smtp.client-ip=209.85.210.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="VYgA+t7d" Received: by mail-ot1-f46.google.com with SMTP id 46e09a7af769-71e17de2816so663332a34.0 for ; Wed, 11 Dec 2024 12:55:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950509; x=1734555309; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=X+MK6Laxk5lSyVO7UoxwG8imqZsEDijB7oEXcuKXi5w=; b=VYgA+t7dALAVrsQc2yVgG+tG9YUgO6ukV4Ja2z6aborB7GSO/UBYpRhMldhn0YvJs9 cVPFThUlA4Onn83Z1tFjK9SKYG+rlW1ekUMn44v4MY2Ha3Hav4nRgOwrhHui6ITtFWXF iwfyEeDvpEfpnf63NDQVhj7iYV7ds8iVFlHr8to4LhOSjgmNt/K9apU9HAxUhzKlMa/v 0VfJm5gE3grfjakbIFrJHFKbkuH+dzueoE7OGTxCKOTPh+XV4AU3N9Ng53ZACoEB22t2 AtyUsalDrnkuG62rigLtMrk3AIuH2zD28UjXNlZBbIivsBWSPs5sDcRzKtP4Z9Ac9Vx7 D46A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950509; x=1734555309; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X+MK6Laxk5lSyVO7UoxwG8imqZsEDijB7oEXcuKXi5w=; b=Xbi3+ZfFQIDvwxX3mMVQNva6OqYJk0XZQsTQqXJVgikN9YKZCM81M52It6c1sV8Buh VPTG90G1gUjtGaY+z5/7y+52/d+XKxObeQzDj860t7ABwelbqWYd7WnQfxA8N9Mqrz8h jkWh3XsF13H4ez6zro6sgS497L6V55KmF7y1GoVqSWfruobqWXJZf8XLG49cH/d6iISu Z4N1Ts3iMyJw99WTf+NVvhRB4QM6RyBTVjl72qDnr7lc3DXiP72L5ZN8yJjvhUbHbaYG qk6B0eLQ3JLwPnKytXLcvRa1/HreKLR6gC8wRXCJS+mCmTXpTigtzqP2h6e0ZgPvhTSO 9C0w== X-Forwarded-Encrypted: i=1; AJvYcCUg/zzEL3toTnv7QfrlYoPwI4S0gp3kOh9LzOXJSGoPK1IMXgKQxSTFXQmCg2xOATu41J53OM5sJGA=@vger.kernel.org X-Gm-Message-State: AOJu0YxAcTBF1i1XbOgnpAKjJwLKFBPnmTJRNwNwyS/qILFWnWEU+DIp oFzD8f6wYVYnUn5eN6mAoqRc1FGQKsD/k76ec3H87RRNoc1fIYjbIKUc5sGABUY= X-Gm-Gg: ASbGncufMr6+CJqQJW9Hz9bSvYR4ZYHDge3o7zzw2u0LxMH1oRTNlwZkaGzjeaZdTZH Q6didFLxOrQF339JQc3pNRvUl/kZQ5IP51VxWPclpZynSozkqHtXpPOh816GyK+y8GBFHWUetQ/ 6zAa0HsbGN4eHeBKxhmjUYdbk/t2DJPJYj3CXk59BIfzdbBTUuz9AKq4oQkfjuogWn3j1ZWqrd4 GHY56PkAWoGQpOUNh1s0Fb+7LhQqBBV754xtx3Z6q9w0o/6U0HUmLOPYFAOTvA4Vk9uETTFprV6 D3jUSlETYQ== X-Google-Smtp-Source: AGHT+IE/5g1g4OFL1A9KLQFv1DxOEjPfgmgVz3Vv4DYo6anKprWGf2qL4DXSqgQgg74Tq8cTnwWrmg== X-Received: by 2002:a05:6830:388f:b0:71d:e900:2322 with SMTP id 46e09a7af769-71e29c25742mr422116a34.8.1733950508755; Wed, 11 Dec 2024 12:55:08 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:08 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:44 -0600 Subject: [PATCH v6 07/17] spi: axi-spi-engine: implement offload support Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-7-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, Jonathan Cameron , David Lechner X-Mailer: b4 0.14.2 Implement SPI offload support for the AXI SPI Engine. Currently, the hardware only supports triggering offload transfers with a hardware trigger so attempting to use an offload message in the regular SPI message queue will fail. Also, only allows streaming rx data to an external sink, so attempts to use a rx_buf in the offload message will fail. Reviewed-by: Jonathan Cameron Signed-off-by: David Lechner --- v6 changes: * Update for split spi/offload headers. v5 changes: * Set offload capability flags based on DT properties. * Add support for TX DMA since the hardware supports that now. * Update for changes in other patches in the series. v4 changes: * Adapted to changes in other patches in the series. * Moved trigger enable/disable to same function as offload enable/disable. v3 changes: * Added clk and dma_chan getter callbacks. * Fixed some bugs. v2 changes: This patch has been reworked to accommodate the changes described in all of the other patches. --- drivers/spi/Kconfig | 1 + drivers/spi/spi-axi-spi-engine.c | 314 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 308 insertions(+), 7 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2cfc14be869790f5226130428bb7cb40aadfb031..f496ab127ef011d092f66063e05772725ab89771 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -179,6 +179,7 @@ config SPI_AU1550 config SPI_AXI_SPI_ENGINE tristate "Analog Devices AXI SPI Engine controller" depends on HAS_IOMEM + select SPI_OFFLOAD help This enables support for the Analog Devices AXI SPI Engine SPI controller. It is part of the SPI Engine framework that is used in some Analog Devices diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 7c252126b33ea83fe6a6e80c6cb87499243069f5..dd6077d3ff7b8d29b0ca2e803a5930c4cedf2e93 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -2,11 +2,14 @@ /* * SPI-Engine SPI controller driver * Copyright 2015 Analog Devices Inc. + * Copyright 2024 BayLibre, SAS * Author: Lars-Peter Clausen */ +#include #include #include +#include #include #include #include @@ -14,9 +17,11 @@ #include #include #include +#include #include #include +#define SPI_ENGINE_REG_OFFLOAD_MEM_ADDR_WIDTH 0x10 #define SPI_ENGINE_REG_RESET 0x40 #define SPI_ENGINE_REG_INT_ENABLE 0x80 @@ -24,6 +29,7 @@ #define SPI_ENGINE_REG_INT_SOURCE 0x88 #define SPI_ENGINE_REG_SYNC_ID 0xc0 +#define SPI_ENGINE_REG_OFFLOAD_SYNC_ID 0xc4 #define SPI_ENGINE_REG_CMD_FIFO_ROOM 0xd0 #define SPI_ENGINE_REG_SDO_FIFO_ROOM 0xd4 @@ -34,10 +40,24 @@ #define SPI_ENGINE_REG_SDI_DATA_FIFO 0xe8 #define SPI_ENGINE_REG_SDI_DATA_FIFO_PEEK 0xec +#define SPI_ENGINE_MAX_NUM_OFFLOADS 32 + +#define SPI_ENGINE_REG_OFFLOAD_CTRL(x) (0x100 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) +#define SPI_ENGINE_REG_OFFLOAD_STATUS(x) (0x104 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) +#define SPI_ENGINE_REG_OFFLOAD_RESET(x) (0x108 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) +#define SPI_ENGINE_REG_OFFLOAD_CMD_FIFO(x) (0x110 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) +#define SPI_ENGINE_REG_OFFLOAD_SDO_FIFO(x) (0x114 + SPI_ENGINE_MAX_NUM_OFFLOADS * (x)) + +#define SPI_ENGINE_SPI_OFFLOAD_MEM_WIDTH_SDO GENMASK(15, 8) +#define SPI_ENGINE_SPI_OFFLOAD_MEM_WIDTH_CMD GENMASK(7, 0) + #define SPI_ENGINE_INT_CMD_ALMOST_EMPTY BIT(0) #define SPI_ENGINE_INT_SDO_ALMOST_EMPTY BIT(1) #define SPI_ENGINE_INT_SDI_ALMOST_FULL BIT(2) #define SPI_ENGINE_INT_SYNC BIT(3) +#define SPI_ENGINE_INT_OFFLOAD_SYNC BIT(4) + +#define SPI_ENGINE_OFFLOAD_CTRL_ENABLE BIT(0) #define SPI_ENGINE_CONFIG_CPHA BIT(0) #define SPI_ENGINE_CONFIG_CPOL BIT(1) @@ -79,6 +99,10 @@ #define SPI_ENGINE_CMD_CS_INV(flags) \ SPI_ENGINE_CMD(SPI_ENGINE_INST_CS_INV, 0, (flags)) +/* default sizes - can be changed when SPI Engine firmware is compiled */ +#define SPI_ENGINE_OFFLOAD_CMD_FIFO_SIZE 16 +#define SPI_ENGINE_OFFLOAD_SDO_FIFO_SIZE 16 + struct spi_engine_program { unsigned int length; uint16_t instructions[] __counted_by(length); @@ -106,6 +130,17 @@ struct spi_engine_message_state { uint8_t *rx_buf; }; +enum { + SPI_ENGINE_OFFLOAD_FLAG_ASSIGNED, + SPI_ENGINE_OFFLOAD_FLAG_PREPARED, +}; + +struct spi_engine_offload { + struct spi_engine *spi_engine; + unsigned long flags; + unsigned int offload_num; +}; + struct spi_engine { struct clk *clk; struct clk *ref_clk; @@ -118,6 +153,11 @@ struct spi_engine { unsigned int int_enable; /* shadows hardware CS inversion flag state */ u8 cs_inv; + + unsigned int offload_ctrl_mem_size; + unsigned int offload_sdo_mem_size; + struct spi_offload *offload; + u32 offload_caps; }; static void spi_engine_program_add_cmd(struct spi_engine_program *p, @@ -163,9 +203,9 @@ static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry, unsigned int n = min(len, 256U); unsigned int flags = 0; - if (xfer->tx_buf) + if (xfer->tx_buf || (xfer->offload_flags & SPI_OFFLOAD_XFER_TX_STREAM)) flags |= SPI_ENGINE_TRANSFER_WRITE; - if (xfer->rx_buf) + if (xfer->rx_buf || (xfer->offload_flags & SPI_OFFLOAD_XFER_RX_STREAM)) flags |= SPI_ENGINE_TRANSFER_READ; spi_engine_program_add_cmd(p, dry, @@ -217,16 +257,24 @@ static void spi_engine_gen_cs(struct spi_engine_program *p, bool dry, * * NB: This is separate from spi_engine_compile_message() because the latter * is called twice and would otherwise result in double-evaluation. + * + * Returns 0 on success, -EINVAL on failure. */ -static void spi_engine_precompile_message(struct spi_message *msg) +static int spi_engine_precompile_message(struct spi_message *msg) { unsigned int clk_div, max_hz = msg->spi->controller->max_speed_hz; struct spi_transfer *xfer; list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* If we have an offload transfer, we can't rx to buffer */ + if (msg->offload && xfer->rx_buf) + return -EINVAL; + clk_div = DIV_ROUND_UP(max_hz, xfer->speed_hz); xfer->effective_speed_hz = max_hz / min(clk_div, 256U); } + + return 0; } static void spi_engine_compile_message(struct spi_message *msg, bool dry, @@ -521,11 +569,105 @@ static irqreturn_t spi_engine_irq(int irq, void *devid) return IRQ_HANDLED; } +static int spi_engine_offload_prepare(struct spi_message *msg) +{ + struct spi_controller *host = msg->spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_program *p = msg->opt_state; + struct spi_engine_offload *priv = msg->offload->priv; + struct spi_transfer *xfer; + void __iomem *cmd_addr; + void __iomem *sdo_addr; + size_t tx_word_count = 0; + unsigned int i; + + if (p->length > spi_engine->offload_ctrl_mem_size) + return -EINVAL; + + /* count total number of tx words in message */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + /* no support for reading to rx_buf */ + if (xfer->rx_buf) + return -EINVAL; + + if (!xfer->tx_buf) + continue; + + if (xfer->bits_per_word <= 8) + tx_word_count += xfer->len; + else if (xfer->bits_per_word <= 16) + tx_word_count += xfer->len / 2; + else + tx_word_count += xfer->len / 4; + } + + if (tx_word_count && !(spi_engine->offload_caps & SPI_OFFLOAD_CAP_TX_STATIC_DATA)) + return -EINVAL; + + if (tx_word_count > spi_engine->offload_sdo_mem_size) + return -EINVAL; + + /* + * This protects against calling spi_optimize_message() with an offload + * that has already been prepared with a different message. + */ + if (test_and_set_bit_lock(SPI_ENGINE_OFFLOAD_FLAG_PREPARED, &priv->flags)) + return -EBUSY; + + cmd_addr = spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CMD_FIFO(priv->offload_num); + sdo_addr = spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_SDO_FIFO(priv->offload_num); + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (!xfer->tx_buf) + continue; + + if (xfer->bits_per_word <= 8) { + const u8 *buf = xfer->tx_buf; + + for (i = 0; i < xfer->len; i++) + writel_relaxed(buf[i], sdo_addr); + } else if (xfer->bits_per_word <= 16) { + const u16 *buf = xfer->tx_buf; + + for (i = 0; i < xfer->len / 2; i++) + writel_relaxed(buf[i], sdo_addr); + } else { + const u32 *buf = xfer->tx_buf; + + for (i = 0; i < xfer->len / 4; i++) + writel_relaxed(buf[i], sdo_addr); + } + } + + for (i = 0; i < p->length; i++) + writel_relaxed(p->instructions[i], cmd_addr); + + return 0; +} + +static void spi_engine_offload_unprepare(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + struct spi_engine *spi_engine = priv->spi_engine; + + writel_relaxed(1, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_RESET(priv->offload_num)); + writel_relaxed(0, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_RESET(priv->offload_num)); + + clear_bit_unlock(SPI_ENGINE_OFFLOAD_FLAG_PREPARED, &priv->flags); +} + static int spi_engine_optimize_message(struct spi_message *msg) { struct spi_engine_program p_dry, *p; + int ret; - spi_engine_precompile_message(msg); + ret = spi_engine_precompile_message(msg); + if (ret) + return ret; p_dry.length = 0; spi_engine_compile_message(msg, true, &p_dry); @@ -537,20 +679,61 @@ static int spi_engine_optimize_message(struct spi_message *msg) spi_engine_compile_message(msg, false, p); spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC( - AXI_SPI_ENGINE_CUR_MSG_SYNC_ID)); + msg->offload ? 0 : AXI_SPI_ENGINE_CUR_MSG_SYNC_ID)); msg->opt_state = p; + if (msg->offload) { + ret = spi_engine_offload_prepare(msg); + if (ret) { + msg->opt_state = NULL; + kfree(p); + return ret; + } + } + return 0; } static int spi_engine_unoptimize_message(struct spi_message *msg) { + if (msg->offload) + spi_engine_offload_unprepare(msg->offload); + kfree(msg->opt_state); return 0; } +static struct spi_offload +*spi_engine_get_offload(struct spi_device *spi, + const struct spi_offload_config *config) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + + if (!spi_engine->offload) + return ERR_PTR(-ENODEV); + + if (config->capability_flags & ~spi_engine->offload_caps) + return ERR_PTR(-EINVAL); + + priv = spi_engine->offload->priv; + + if (test_and_set_bit_lock(SPI_ENGINE_OFFLOAD_FLAG_ASSIGNED, &priv->flags)) + return ERR_PTR(-EBUSY); + + return spi_engine->offload; +} + +static void spi_engine_put_offload(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + + clear_bit_unlock(SPI_ENGINE_OFFLOAD_FLAG_ASSIGNED, &priv->flags); +} + static int spi_engine_setup(struct spi_device *device) { struct spi_controller *host = device->controller; @@ -583,6 +766,12 @@ static int spi_engine_transfer_one_message(struct spi_controller *host, unsigned int int_enable = 0; unsigned long flags; + if (msg->offload) { + dev_err(&host->dev, "Single transfer offload not supported\n"); + msg->status = -EOPNOTSUPP; + goto out; + } + /* reinitialize message state for this transfer */ memset(st, 0, sizeof(*st)); st->cmd_buf = p->instructions; @@ -632,11 +821,68 @@ static int spi_engine_transfer_one_message(struct spi_controller *host, trace_spi_transfer_stop(msg, xfer); } +out: spi_finalize_current_message(host); return msg->status; } +static int spi_engine_trigger_enable(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + struct spi_engine *spi_engine = priv->spi_engine; + unsigned int reg; + + reg = readl_relaxed(spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(priv->offload_num)); + reg |= SPI_ENGINE_OFFLOAD_CTRL_ENABLE; + writel_relaxed(reg, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(priv->offload_num)); + return 0; +} + +static void spi_engine_trigger_disable(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + struct spi_engine *spi_engine = priv->spi_engine; + unsigned int reg; + + reg = readl_relaxed(spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(priv->offload_num)); + reg &= ~SPI_ENGINE_OFFLOAD_CTRL_ENABLE; + writel_relaxed(reg, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(priv->offload_num)); +} + +static struct dma_chan +*spi_engine_tx_stream_request_dma_chan(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + char name[16]; + + snprintf(name, sizeof(name), "offload%u-tx", priv->offload_num); + + return dma_request_chan(offload->provider_dev, name); +} + +static struct dma_chan +*spi_engine_rx_stream_request_dma_chan(struct spi_offload *offload) +{ + struct spi_engine_offload *priv = offload->priv; + char name[16]; + + snprintf(name, sizeof(name), "offload%u-rx", priv->offload_num); + + return dma_request_chan(offload->provider_dev, name); +} + +static const struct spi_offload_ops spi_engine_offload_ops = { + .trigger_enable = spi_engine_trigger_enable, + .trigger_disable = spi_engine_trigger_disable, + .tx_stream_request_dma_chan = spi_engine_tx_stream_request_dma_chan, + .rx_stream_request_dma_chan = spi_engine_rx_stream_request_dma_chan, +}; + static void spi_engine_release_hw(void *p) { struct spi_engine *spi_engine = p; @@ -651,8 +897,7 @@ static int spi_engine_probe(struct platform_device *pdev) struct spi_engine *spi_engine; struct spi_controller *host; unsigned int version; - int irq; - int ret; + int irq, ret; irq = platform_get_irq(pdev, 0); if (irq < 0) @@ -667,6 +912,46 @@ static int spi_engine_probe(struct platform_device *pdev) spin_lock_init(&spi_engine->lock); init_completion(&spi_engine->msg_complete); + /* + * REVISIT: for now, all SPI Engines only have one offload. In the + * future, this should be read from a memory mapped register to + * determine the number of offloads enabled at HDL compile time. For + * now, we can tell if an offload is present if there is a trigger + * source wired up to it. + */ + if (device_property_present(&pdev->dev, "trigger-sources")) { + struct spi_engine_offload *priv; + + spi_engine->offload = + devm_spi_offload_alloc(&pdev->dev, + sizeof(struct spi_engine_offload)); + if (IS_ERR(spi_engine->offload)) + return PTR_ERR(spi_engine->offload); + + priv = spi_engine->offload->priv; + priv->spi_engine = spi_engine; + priv->offload_num = 0; + + spi_engine->offload->ops = &spi_engine_offload_ops; + spi_engine->offload_caps = SPI_OFFLOAD_CAP_TRIGGER; + + if (device_property_match_string(&pdev->dev, "dma-names", "offload0-rx") >= 0) { + spi_engine->offload_caps |= SPI_OFFLOAD_CAP_RX_STREAM_DMA; + spi_engine->offload->xfer_flags |= SPI_OFFLOAD_XFER_RX_STREAM; + } + + if (device_property_match_string(&pdev->dev, "dma-names", "offload0-tx") >= 0) { + spi_engine->offload_caps |= SPI_OFFLOAD_CAP_TX_STREAM_DMA; + spi_engine->offload->xfer_flags |= SPI_OFFLOAD_XFER_TX_STREAM; + } else { + /* + * HDL compile option to enable TX DMA stream also disables + * the SDO memory, so can't do both at the same time. + */ + spi_engine->offload_caps |= SPI_OFFLOAD_CAP_TX_STATIC_DATA; + } + } + spi_engine->clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); if (IS_ERR(spi_engine->clk)) return PTR_ERR(spi_engine->clk); @@ -688,6 +973,19 @@ static int spi_engine_probe(struct platform_device *pdev) return -ENODEV; } + if (ADI_AXI_PCORE_VER_MINOR(version) >= 1) { + unsigned int sizes = readl(spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_MEM_ADDR_WIDTH); + + spi_engine->offload_ctrl_mem_size = 1 << + FIELD_GET(SPI_ENGINE_SPI_OFFLOAD_MEM_WIDTH_CMD, sizes); + spi_engine->offload_sdo_mem_size = 1 << + FIELD_GET(SPI_ENGINE_SPI_OFFLOAD_MEM_WIDTH_SDO, sizes); + } else { + spi_engine->offload_ctrl_mem_size = SPI_ENGINE_OFFLOAD_CMD_FIFO_SIZE; + spi_engine->offload_sdo_mem_size = SPI_ENGINE_OFFLOAD_SDO_FIFO_SIZE; + } + writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); @@ -709,6 +1007,8 @@ static int spi_engine_probe(struct platform_device *pdev) host->transfer_one_message = spi_engine_transfer_one_message; host->optimize_message = spi_engine_optimize_message; host->unoptimize_message = spi_engine_unoptimize_message; + host->get_offload = spi_engine_get_offload; + host->put_offload = spi_engine_put_offload; host->num_chipselect = 8; /* Some features depend of the IP core version. */ From patchwork Wed Dec 11 20:54:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849665 Received: from mail-ot1-f42.google.com (mail-ot1-f42.google.com [209.85.210.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A83D7235C48 for ; Wed, 11 Dec 2024 20:55:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950515; cv=none; b=SyzjftsAZhCYMaGJMeTfX4LSS7m8ob/p86lS1rR5PSgkSr/ZVRXVgJ93h3YEB1QJ0t6rd1i9csXw1SOCFhU6hGgttiyq00Y8AlWs1XK4w0LuDLYVohrLS4M1rnNd81ylihkPf27oJj/mbxRlNnM+29qvm6Wf/vN0Jk6pxdbBYrs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950515; c=relaxed/simple; bh=0Ok/5ZnOlSAk0SyWH0Ar/2/amiOP/dC0SnejVgYuWPQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jZGhk7LjP/Chx3EQXoaWg7MB8szOCWY2ea4wcAHIBDRpg1ZO7q02OixEyQ9fMYl3A7+o20GhvrMDrLiPc8/oeh/jfGl6WsT0a0XU6E9nwGc6WgDGrqVB9HSbGx/Cy7ISqN8jdnKfzu/rV/QGpBNMPqBcNehOqDeds13p5pGyH/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=ZROVsmWo; arc=none smtp.client-ip=209.85.210.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="ZROVsmWo" Received: by mail-ot1-f42.google.com with SMTP id 46e09a7af769-71e10e6a1ceso512077a34.0 for ; Wed, 11 Dec 2024 12:55:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950512; x=1734555312; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7xX2yx2vSa/aaxQ+2sqQV4bQgGy0uEeuXD04S3quCr0=; b=ZROVsmWo5qPGPrdI74wJ4S03IABj9S3L0HcLtBh8841WN6hldEimlHZ07KTuEJoKW4 7i7calvW6GBPDvUXF9REPUzvJq8aCpeknkogdBAjcg5MZ+eoRnRICTzMm+8Ez3HOWEez wXQHQpNS/GysR5NEPhTgxedWjWhURlBvYXnThLGwHjbIQczuKijAo6mUGRe/sV5BPnAH ZrnE6fXsoTxuwQ4JoYDOSX6CQOHPOdTDOec7hoVLVBYfpPYnDGBUlNHMZ7Z+D5Ikg0FK J16rT8+PGgGy9aQKPvmsK/LKlNjFOh0T5kp71xdxBgkr8RLipFkDDgefXH4cY8wLrt6X Ws5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950512; x=1734555312; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7xX2yx2vSa/aaxQ+2sqQV4bQgGy0uEeuXD04S3quCr0=; b=mvWU1tabGVb/s/8jyuDXMHnuutNDignRKnCg24s2JvkueZKkdyRlTDQcdn+qqdbpiF 0y4bLU8rH3wgtJuyCzqDUqvbMdkyKqiedwxWrvxXKxuZ6HR9oBbw4zG8tot8LZo5Cr4G jk3WcwI803jXiyWVjHZ0K+0YA7n1SzsNfaOFIpXwuMteQiTESGPJ0jXYTYJATzi/DTS0 3zVtntkFb1tQuaR4s5/lkqGQwEOJoimWC2+3C0/7bmzkba/NsmdjPnfkTCd/l8ave5TH oiKXxZ9xtvPR+5a4C6cqb8cuXmYRSVs9HyUtqbcnfhwgsn7sXNH6wWvH3hPlsfxWjMEc 48zQ== X-Forwarded-Encrypted: i=1; AJvYcCVAILQBAQQjiMnCOtc4A7bXS1/JVDsmnDSAbxv1HKOJS++dEvGGUHKNo/MF/kXKWl62n7c56bcnEtw=@vger.kernel.org X-Gm-Message-State: AOJu0Yz8qRvkCXQfNXAzfWjjwvNtPyke84RuLsGxjkXan8Lcl4ciSjxN 4A4ovc3EbOAFNTzu8W6bVT3Xei7yl6f6/YWMFKpFOezUMTC36pR/WOyENipQqBI= X-Gm-Gg: ASbGncuGBXKoJ9HtImki4tNd60eKIN7Hf5I//WzQAFNybWGw9kvqblqHXEUK3lcRKq3 NUGTReX2RTJWU54IujijRJdQwmtC/iSXmXb4LC9vB9xGtU72eJFhTrvHbp4fFR7JqNZNGiFwDOH yLVm5QcN0oMgylyV9vlqmefQN1cQepOa9CONc+wuiwzRXb7PayP6o01eknOPvMr98n6vjmZ4cL4 SKPfUM6PyBRZ6vC1w2+2YaMXFbkrPolTRaa5Qv/0RF4abtFOI/Fq95z/iFUl80czoMoM/2PIx0k XvgUU8TrGQ== X-Google-Smtp-Source: AGHT+IFNtplY01hYwghmbGt8YZ7/urTHWFQ5LfK7SnSy2+GwyAQ+mInY95pngCiueu62gcUzQpnmsw== X-Received: by 2002:a05:6830:3695:b0:71e:155:9bf with SMTP id 46e09a7af769-71e29c95d48mr725956a34.25.1733950511793; Wed, 11 Dec 2024 12:55:11 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:11 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:46 -0600 Subject: [PATCH v6 09/17] iio: buffer-dmaengine: add devm_iio_dmaengine_buffer_setup_with_handle() Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-9-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.2 Add a new devm_iio_dmaengine_buffer_setup_with_handle() function to handle cases where the DMA channel is managed by the caller rather than being requested and released by the iio_dmaengine module. Signed-off-by: David Lechner --- v6 changes: * Rename from devm_iio_dmaengine_buffer_setup_ext2() * This patch now just adds the new function - prep work was split out to a separate patch v5 changes: none v4 changes: * This replaces "iio: buffer-dmaengine: generalize requesting DMA channel" --- drivers/iio/buffer/industrialio-buffer-dmaengine.c | 38 ++++++++++++++++++++++ include/linux/iio/buffer-dmaengine.h | 5 +++ 2 files changed, 43 insertions(+) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 02847d3962fcbb43ec76167db6482ab951f20942..e9d9a7d39fe191c2b6e8c196a08cdd26cd3a8d4b 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -380,6 +380,44 @@ int devm_iio_dmaengine_buffer_setup_ext(struct device *dev, } EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_ext, "IIO_DMAENGINE_BUFFER"); +static void devm_iio_dmaengine_buffer_free(void *buffer) +{ + iio_dmaengine_buffer_free(buffer); +} + +/** + * devm_iio_dmaengine_buffer_setup_with_handle() - Setup a DMA buffer for an + * IIO device + * @dev: Device for devm ownership + * @indio_dev: IIO device to which to attach this buffer. + * @chan: DMA channel + * @dir: Direction of buffer (in or out) + * + * This allocates a new IIO buffer with devm_iio_dmaengine_buffer_alloc() + * and attaches it to an IIO device with iio_device_attach_buffer(). + * It also appends the INDIO_BUFFER_HARDWARE mode to the supported modes of the + * IIO device. + * + * This is the same as devm_iio_dmaengine_buffer_setup_ext() except that the + * caller manages requesting and releasing the DMA channel handle. + */ +int devm_iio_dmaengine_buffer_setup_with_handle(struct device *dev, + struct iio_dev *indio_dev, + struct dma_chan *chan, + enum iio_buffer_direction dir) +{ + struct iio_buffer *buffer; + + buffer = __iio_dmaengine_buffer_setup_ext(indio_dev, chan, dir); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + + return devm_add_action_or_reset(dev, devm_iio_dmaengine_buffer_free, + buffer); +} +EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup_with_handle, + "IIO_DMAENGINE_BUFFER"); + MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_DESCRIPTION("DMA buffer for the IIO framework"); MODULE_LICENSE("GPL"); diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h index 72a2e3fd8a5bf5e8f27ee226ddd92979d233754b..37f27545f69f761c3327c307cc6311b02a751096 100644 --- a/include/linux/iio/buffer-dmaengine.h +++ b/include/linux/iio/buffer-dmaengine.h @@ -11,6 +11,7 @@ struct iio_dev; struct device; +struct dma_chan; void iio_dmaengine_buffer_teardown(struct iio_buffer *buffer); struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev, @@ -26,6 +27,10 @@ int devm_iio_dmaengine_buffer_setup_ext(struct device *dev, struct iio_dev *indio_dev, const char *channel, enum iio_buffer_direction dir); +int devm_iio_dmaengine_buffer_setup_with_handle(struct device *dev, + struct iio_dev *indio_dev, + struct dma_chan *chan, + enum iio_buffer_direction dir); #define devm_iio_dmaengine_buffer_setup(dev, indio_dev, channel) \ devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \ From patchwork Wed Dec 11 20:54:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849664 Received: from mail-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E05442288D0 for ; Wed, 11 Dec 2024 20:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950519; cv=none; b=TEVeMgetALIkcmq7BBs06O7DqLzXFoYLqKKmKE6apm09pWfbq5WZOP8hYKImDL0x9ffl5CyNPhEJud206n9KOcJub4o2u7m9et3HZY6yrEOekwURlylef7r+KPWcZeoweV1kiueGsfsxlZx6UwIpUuqSukeixghBY7Za5TOgOwA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950519; c=relaxed/simple; bh=VZ/YwavR6N31puyPe6nsp32O5zBdZ+orvym1UmTOrl0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nml3MtiIVTLfK69DfCg9vaZR01EEFqf1B+8YwjShpMuGSYETGYrRfEl7MHOp3BWX/96nTLXmtljdYO6kbc7KnJeQjoPiznTAqohsr9MUVaDap8h4gu9A9Y9jVB5vCpPCJUB2Bq4/8a8pP/T9th4xjaRaiQVXQCzZ3DM6PHcbfeQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=NZgauuA9; arc=none smtp.client-ip=209.85.210.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="NZgauuA9" Received: by mail-ot1-f50.google.com with SMTP id 46e09a7af769-71e16519031so539726a34.1 for ; Wed, 11 Dec 2024 12:55:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950516; x=1734555316; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=q6hO0WOY+hz9HGePeUohTIasiE4zWiY+iKplztZrAkg=; b=NZgauuA9AoXBeT/M8ShASIbUtOhho1EM5o2FHqjqKS3Srw4Teym9FIiVMxr2mpDMTk lZcjL3NV6MvarX62sWyJr64ZFTuS26MHzZZ6TXxOcytOGEyfj+jf4D/OCJcYQHS8yxy0 6G+lRwBJN7GbyBCVtL4yeB350manERFWHaCTAVTkOFXQqgmp4fQ36nfCFt/NbGZ26uQT FFD+9fNLuKJV3ewVdpoIO/11Bzr1bmdpAdkXzww7GPeKZ8tZXkNAiqsbPLM6DV2M7PB6 YlwyB9xmnuvK9Gz0+tShxjBrmgUhM4UUcv8vYOeqvG1FsmHxVlXWA3IOKaIZU4B4t7w0 Emfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950516; x=1734555316; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q6hO0WOY+hz9HGePeUohTIasiE4zWiY+iKplztZrAkg=; b=TWgap00Z1LvqXM2s4AnYrDOUmv6E7JkH+bgorEbI6N7GjtagaRkpp8wyKUc42uB5ry MFvYHGP0TVGFnjK6SlS5RgSHSIRXlyN8LaAvarB/rlkVZygZphPEWxNFIykuEEE/xKTg KS9teRjZuQm5zFaA4BcDTJ5Q/C1tOw3EWzlbRYjbuZoXnWT1+Axh3LgkvYRX3S5XqxkX WeDO0SGrKrmehN5qp+cQhm6w3Hua7dJAWsqjXYmNIaeg0q81FXyeyugE+/vreylYhhvF JarWlnzRpm01yZvv8skytCYKGhI1+7ILxIqtxs7vWAtd0GrEK6p1u3SPi6e3wF8bWzEY Hn8w== X-Forwarded-Encrypted: i=1; AJvYcCVky7i+PUnwlDtRyxNDgzZnFYXIugbn6Y7MMpf5XbHbSCbysouU5ccu9ND1a1JveQPNTAbCvo/UY1M=@vger.kernel.org X-Gm-Message-State: AOJu0YxFEu6ucTNwkoZ2uTbRs59pMtkevNBSNzXc7R+HoSsJ6AUYoOnO L0oOYY416U3YEPYcVyU9smmW4782fPYqJ8QzLzH7YdSOL/hE3MgeFrjY6xE1Pjw= X-Gm-Gg: ASbGncuuPs97iA90YTeu6tY4rd7ku/yUiALsKKieFtLi0IWLr1ZwXcJoeoIAxs1rBen /NPwPn5+yBjO0H9yxkH9PE4oWSZZ27681g1CigtnxNjZgoWgv1+znk/dx4isbjR3wSnNMG0pu6n qTEsRF1AsXBSJm5lMCZuYZCFJpx1vA8cs0au66nU09M/tlVDqMbzzQ0xBvT89QqzZ0sg+gM8MA2 8w8dIUoL4JuFZWNuuZUquUQOySrknko7b7chDYIS4Crje+oG6tOHXQldPpTbGXUcXgS6pcjJ0Ea sebO2+/X3w== X-Google-Smtp-Source: AGHT+IHb1oORKLdRGyRTnUrtVj3EkyeE9CvWai9FRmcovMJCbgLiwZu4IVnlqFZDgdV6Bj5B1wELpg== X-Received: by 2002:a05:6830:7009:b0:71e:30e:e022 with SMTP id 46e09a7af769-71e2a7d7df1mr372599a34.10.1733950515995; Wed, 11 Dec 2024 12:55:15 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:15 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:48 -0600 Subject: [PATCH v6 11/17] iio: adc: ad7944: add support for SPI offload Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-11-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, Jonathan Cameron , David Lechner X-Mailer: b4 0.14.2 Add support for SPI offload to the ad7944 driver. This allows reading data at the max sample rate of 2.5 MSPS. Reviewed-by: Jonathan Cameron Signed-off-by: David Lechner --- v6 changes: * More detailed comments on offload channels info struct. (I didn't put them inside the macro because the multiline comments don't play well with the line continuation "\".) v5 changes: * Remove dev_info() message. * Implement sampling_frequency_available attribute. * Limit max sample rate to chip-specific value. v4 changes: * Adapted to changes in other patches. * Add new separate channel spec for when using SPI offload. * Fixed some nitpicks. v3 changes: * Finished TODOs. * Adapted to changes in other patches. v2 changes: In the previous version, there was a new separate driver for the PWM trigger and DMA hardware buffer. This was deemed too complex so they are moved into the ad7944 driver. It has also been reworked to accommodate for the changes described in the other patches. --- drivers/iio/adc/Kconfig | 1 + drivers/iio/adc/ad7944.c | 291 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 276 insertions(+), 16 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a3e8ac569ce4c6b6b30b48acb265d530aa98e89c..995b9cacbaa964d26424346120c139858f93cdcd 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -360,6 +360,7 @@ config AD7923 config AD7944 tristate "Analog Devices AD7944 and similar ADCs driver" depends on SPI + select SPI_OFFLOAD select IIO_BUFFER select IIO_TRIGGERED_BUFFER help diff --git a/drivers/iio/adc/ad7944.c b/drivers/iio/adc/ad7944.c index 6d1202bd55a013b092ff803f2065fd128dfa9bdd..07984eb450e82fc06d67fa0a157e3ae4e7555678 100644 --- a/drivers/iio/adc/ad7944.c +++ b/drivers/iio/adc/ad7944.c @@ -16,11 +16,14 @@ #include #include #include +#include #include #include +#include #include #include +#include #include #include @@ -54,6 +57,12 @@ struct ad7944_adc { enum ad7944_spi_mode spi_mode; struct spi_transfer xfers[3]; struct spi_message msg; + struct spi_transfer offload_xfers[2]; + struct spi_message offload_msg; + struct spi_offload *offload; + struct spi_offload_trigger *offload_trigger; + unsigned long offload_trigger_hz; + int sample_freq_range[3]; void *chain_mode_buf; /* Chip-specific timing specifications. */ const struct ad7944_timing_spec *timing_spec; @@ -81,6 +90,8 @@ struct ad7944_adc { /* quite time before CNV rising edge */ #define AD7944_T_QUIET_NS 20 +/* minimum CNV high time to trigger conversion */ +#define AD7944_T_CNVH_NS 10 static const struct ad7944_timing_spec ad7944_timing_spec = { .conv_ns = 420, @@ -95,7 +106,9 @@ static const struct ad7944_timing_spec ad7986_timing_spec = { struct ad7944_chip_info { const char *name; const struct ad7944_timing_spec *timing_spec; + u32 max_sample_rate_hz; const struct iio_chan_spec channels[2]; + const struct iio_chan_spec offload_channels[1]; }; /* get number of bytes for SPI xfer */ @@ -105,13 +118,15 @@ struct ad7944_chip_info { * AD7944_DEFINE_CHIP_INFO - Define a chip info structure for a specific chip * @_name: The name of the chip * @_ts: The timing specification for the chip + * @_max: The maximum sample rate in Hz * @_bits: The number of bits in the conversion result * @_diff: Whether the chip is true differential or not */ -#define AD7944_DEFINE_CHIP_INFO(_name, _ts, _bits, _diff) \ +#define AD7944_DEFINE_CHIP_INFO(_name, _ts, _max, _bits, _diff) \ static const struct ad7944_chip_info _name##_chip_info = { \ .name = #_name, \ .timing_spec = &_ts##_timing_spec, \ + .max_sample_rate_hz = _max, \ .channels = { \ { \ .type = IIO_VOLTAGE, \ @@ -129,13 +144,43 @@ static const struct ad7944_chip_info _name##_chip_info = { \ }, \ IIO_CHAN_SOFT_TIMESTAMP(1), \ }, \ + .offload_channels = { \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .differential = _diff, \ + .channel = 0, \ + .channel2 = _diff ? 1 : 0, \ + .scan_index = 0, \ + .scan_type.sign = _diff ? 's' : 'u', \ + .scan_type.realbits = _bits, \ + .scan_type.storagebits = 32, \ + .scan_type.endianness = IIO_CPU, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ + | BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_separate_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + }, \ + }, \ } +/* + * Notes on the offload channels: + * - There is no soft timestamp since everything is done in hardware. + * - There is a sampling frequency attribute added. This controls the SPI + * offload trigger. + * - The storagebits value depends on the SPI offload provider. Currently there + * is only one supported provider, namely the ADI PULSAR ADC HDL project, + * which always uses 32-bit words for data values, even for <= 16-bit ADCs. + * So the value is just hardcoded to 32 for now. + */ + /* pseudo-differential with ground sense */ -AD7944_DEFINE_CHIP_INFO(ad7944, ad7944, 14, 0); -AD7944_DEFINE_CHIP_INFO(ad7985, ad7944, 16, 0); +AD7944_DEFINE_CHIP_INFO(ad7944, ad7944, 2.5 * MEGA, 14, 0); +AD7944_DEFINE_CHIP_INFO(ad7985, ad7944, 2.5 * MEGA, 16, 0); /* fully differential */ -AD7944_DEFINE_CHIP_INFO(ad7986, ad7986, 18, 1); +AD7944_DEFINE_CHIP_INFO(ad7986, ad7986, 2 * MEGA, 18, 1); static int ad7944_3wire_cs_mode_init_msg(struct device *dev, struct ad7944_adc *adc, const struct iio_chan_spec *chan) @@ -239,6 +284,48 @@ static int ad7944_chain_mode_init_msg(struct device *dev, struct ad7944_adc *adc return devm_spi_optimize_message(dev, adc->spi, &adc->msg); } +/* + * Unlike ad7944_3wire_cs_mode_init_msg(), this creates a message that reads + * during the conversion phase instead of the acquisition phase when reading + * a sample from the ADC. This is needed to be able to read at the maximum + * sample rate. It requires the SPI controller to have offload support and a + * high enough SCLK rate to read the sample during the conversion phase. + */ +static int ad7944_3wire_cs_mode_init_offload_msg(struct device *dev, + struct ad7944_adc *adc, + const struct iio_chan_spec *chan) +{ + struct spi_transfer *xfers = adc->offload_xfers; + int ret; + + /* + * CS is tied to CNV and we need a low to high transition to start the + * conversion, so place CNV low for t_QUIET to prepare for this. + */ + xfers[0].delay.value = AD7944_T_QUIET_NS; + xfers[0].delay.unit = SPI_DELAY_UNIT_NSECS; + /* CNV has to be high for a minimum time to trigger conversion. */ + xfers[0].cs_change = 1; + xfers[0].cs_change_delay.value = AD7944_T_CNVH_NS; + xfers[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS; + + /* Then we can read the previous sample during the conversion phase */ + xfers[1].offload_flags = SPI_OFFLOAD_XFER_RX_STREAM; + xfers[1].len = AD7944_SPI_BYTES(chan->scan_type); + xfers[1].bits_per_word = chan->scan_type.realbits; + + spi_message_init_with_transfers(&adc->offload_msg, xfers, + ARRAY_SIZE(adc->offload_xfers)); + + adc->offload_msg.offload = adc->offload; + + ret = devm_spi_optimize_message(dev, adc->spi, &adc->offload_msg); + if (ret) + return dev_err_probe(dev, ret, "failed to prepare offload msg\n"); + + return 0; +} + /** * ad7944_convert_and_acquire - Perform a single conversion and acquisition * @adc: The ADC device structure @@ -294,6 +381,23 @@ static int ad7944_single_conversion(struct ad7944_adc *adc, return IIO_VAL_INT; } +static int ad7944_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = adc->sample_freq_range; + *type = IIO_VAL_INT; + return IIO_AVAIL_RANGE; + default: + return -EINVAL; + } +} + static int ad7944_read_raw(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, int *val, int *val2, long info) @@ -326,13 +430,104 @@ static int ad7944_read_raw(struct iio_dev *indio_dev, return -EINVAL; } + case IIO_CHAN_INFO_SAMP_FREQ: + *val = adc->offload_trigger_hz; + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static int ad7944_set_sample_freq(struct ad7944_adc *adc, int val) +{ + struct spi_offload_trigger_config config = { + .type = SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic = { + .frequency_hz = val, + }, + }; + int ret; + + ret = spi_offload_trigger_validate(adc->offload_trigger, &config); + if (ret) + return ret; + + adc->offload_trigger_hz = config.periodic.frequency_hz; + + return 0; +} + +static int ad7944_write_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int val, int val2, long info) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (val < 1 || val > adc->sample_freq_range[2]) + return -EINVAL; + + return ad7944_set_sample_freq(adc, val); default: return -EINVAL; } } +static int ad7944_write_raw_get_fmt(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT; + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + static const struct iio_info ad7944_iio_info = { + .read_avail = &ad7944_read_avail, .read_raw = &ad7944_read_raw, + .write_raw = &ad7944_write_raw, + .write_raw_get_fmt = &ad7944_write_raw_get_fmt, +}; + +static int ad7944_offload_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + struct spi_offload_trigger_config config = { + .type = SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic = { + .frequency_hz = adc->offload_trigger_hz, + }, + }; + int ret; + + gpiod_set_value_cansleep(adc->turbo, 1); + + ret = spi_offload_trigger_enable(adc->offload, adc->offload_trigger, + &config); + if (ret) + gpiod_set_value_cansleep(adc->turbo, 0); + + return ret; +} + +static int ad7944_offload_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + + spi_offload_trigger_disable(adc->offload, adc->offload_trigger); + gpiod_set_value_cansleep(adc->turbo, 0); + + return 0; +} + +static const struct iio_buffer_setup_ops ad7944_offload_buffer_setup_ops = { + .postenable = &ad7944_offload_buffer_postenable, + .predisable = &ad7944_offload_buffer_predisable, }; static irqreturn_t ad7944_trigger_handler(int irq, void *p) @@ -446,6 +641,11 @@ static const char * const ad7944_power_supplies[] = { "avdd", "dvdd", "bvdd", "vio" }; +static const struct spi_offload_config ad7944_offload_config = { + .capability_flags = SPI_OFFLOAD_CAP_TRIGGER | + SPI_OFFLOAD_CAP_RX_STREAM_DMA, +}; + static int ad7944_probe(struct spi_device *spi) { const struct ad7944_chip_info *chip_info; @@ -471,6 +671,10 @@ static int ad7944_probe(struct spi_device *spi) adc->timing_spec = chip_info->timing_spec; + adc->sample_freq_range[0] = 1; /* min */ + adc->sample_freq_range[1] = 1; /* step */ + adc->sample_freq_range[2] = chip_info->max_sample_rate_hz; /* max */ + ret = device_property_match_property_string(dev, "adi,spi-mode", ad7944_spi_modes, ARRAY_SIZE(ad7944_spi_modes)); @@ -590,20 +794,74 @@ static int ad7944_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &ad7944_iio_info; - if (adc->spi_mode == AD7944_SPI_MODE_CHAIN) { - indio_dev->available_scan_masks = chain_scan_masks; - indio_dev->channels = chain_chan; - indio_dev->num_channels = n_chain_dev + 1; + adc->offload = devm_spi_offload_get(dev, spi, &ad7944_offload_config); + ret = PTR_ERR_OR_ZERO(adc->offload); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to get offload\n"); + + /* Fall back to low speed usage when no SPI offload available. */ + if (ret == -ENODEV) { + if (adc->spi_mode == AD7944_SPI_MODE_CHAIN) { + indio_dev->available_scan_masks = chain_scan_masks; + indio_dev->channels = chain_chan; + indio_dev->num_channels = n_chain_dev + 1; + } else { + indio_dev->channels = chip_info->channels; + indio_dev->num_channels = ARRAY_SIZE(chip_info->channels); + } + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + ad7944_trigger_handler, + NULL); + if (ret) + return ret; } else { - indio_dev->channels = chip_info->channels; - indio_dev->num_channels = ARRAY_SIZE(chip_info->channels); - } + struct dma_chan *rx_dma; - ret = devm_iio_triggered_buffer_setup(dev, indio_dev, - iio_pollfunc_store_time, - ad7944_trigger_handler, NULL); - if (ret) - return ret; + if (adc->spi_mode != AD7944_SPI_MODE_SINGLE) + return dev_err_probe(dev, -EINVAL, + "offload only supported in single mode\n"); + + indio_dev->setup_ops = &ad7944_offload_buffer_setup_ops; + indio_dev->channels = chip_info->offload_channels; + indio_dev->num_channels = ARRAY_SIZE(chip_info->offload_channels); + + adc->offload_trigger = devm_spi_offload_trigger_get(dev, + adc->offload, SPI_OFFLOAD_TRIGGER_PERIODIC); + if (IS_ERR(adc->offload_trigger)) + return dev_err_probe(dev, PTR_ERR(adc->offload_trigger), + "failed to get offload trigger\n"); + + ret = ad7944_set_sample_freq(adc, 2 * MEGA); + if (ret) + return dev_err_probe(dev, ret, + "failed to init sample rate\n"); + + rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, + adc->offload); + if (IS_ERR(rx_dma)) + return dev_err_probe(dev, PTR_ERR(rx_dma), + "failed to get offload RX DMA\n"); + + /* + * REVISIT: ideally, we would confirm that the offload RX DMA + * buffer layout is the same as what is hard-coded in + * offload_channels. Right now, the only supported offload + * is the pulsar_adc project which always uses 32-bit word + * size for data values, regardless of the SPI bits per word. + */ + + ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, + indio_dev, rx_dma, IIO_BUFFER_DIRECTION_IN); + if (ret) + return ret; + + ret = ad7944_3wire_cs_mode_init_offload_msg(dev, adc, + &chip_info->offload_channels[0]); + if (ret) + return ret; + } return devm_iio_device_register(dev, indio_dev); } @@ -638,3 +896,4 @@ module_spi_driver(ad7944_driver); MODULE_AUTHOR("David Lechner "); MODULE_DESCRIPTION("Analog Devices AD7944 PulSAR ADC family driver"); MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); From patchwork Wed Dec 11 20:54:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849663 Received: from mail-ot1-f48.google.com (mail-ot1-f48.google.com [209.85.210.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A2D10238E10 for ; Wed, 11 Dec 2024 20:55:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950523; cv=none; b=hxVniyhuBmeXSw3f4FOA/a5UuuAqtXJNsTU9AlPK+6XI9fu1rp0HgXc7agRWCj2e3Z5Pu4ex1v0E2Sqm+IM6OHSnMtz0zZcgxRtI1FA528POgsolC7GqpQl2Tt0LiqE73kNcabWYAcQ+si1zru0Um6ngMVy2WRHShpjFZo01SbM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950523; c=relaxed/simple; bh=PTJfYKdBGpwH9pcTz0bvWoTFNmHgjQKdz5cWv2rkdwE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WXU3X3oACLpTw0Uwp34YiC/fQ9LE2jWVd8c94YsBlKVJxuU6n1l0SKOClZ5ViPId90NRhPUkRGx27MCRwRgbAkpvIkFQ40MZmTj/7yxnOGB8sC56UavKV/EaYeCQj4EtoISmauQ8rq161zxv9E6n5I+Mum6mhxbn4zug9Rb3Pu8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=hE7GtBCl; arc=none smtp.client-ip=209.85.210.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="hE7GtBCl" Received: by mail-ot1-f48.google.com with SMTP id 46e09a7af769-71e0351311eso726242a34.1 for ; Wed, 11 Dec 2024 12:55:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950521; x=1734555321; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=/dUWQVk2bfRYwGLIDUzweNbNW5RzAk7U0S7NeccQg/Q=; b=hE7GtBClNq/kw+XuIX8ycI0KuWSRElaI+voBscq3k0dlbc4UBGv12gkFh6I/6vgi90 VWeQs9iHMBgHG2aszAoriBSmSSBvW0DXUYuxNWeW19OBOvxem0yisIx2eBphiV3UTd2X vmuP7fu3Y9ukohy5xxAadfdJjaSAi1NsGr/kL5xhaljVEVE+jkz0qqxAqL05EX4YR6WH c6e6htLbdY6RchSLILGgQl3q3t6vPnfzufuIZhTizFh0jCzUrZQM2Iau6Pzkc1CScjDL wHC/qXysW2X2SIcVPKhrl7N/FWWdxF0tXOD+OnO5d3lHFWgt9gSrjIOvsRtD0vlXQsCX /0Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950521; x=1734555321; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/dUWQVk2bfRYwGLIDUzweNbNW5RzAk7U0S7NeccQg/Q=; b=Oa0zWiMn5Ws/fvuci0woFJBE1HM/WB8wmRfT+oPJiCdMsaCCHFkHuRAahyyE87CGt4 ug6xvqKI4h8+V5cW7sdggc2Z9eTjBQDtLQKJ6tzwmENS8yagWsuIX4reg0cyoZpj8PLI qpAH2K82n0Ikd7SwGxpQhwU+GgAlCgxeS280byPhXTj531J7bJH4D4nKepOGkbSKx/NA Ubgf/87cuwhFSchvbhBN31KCveyN/450IcKb6qVY5yPv+jkt1Q7HzN80PmHsPAomQ5MU JB0xkbbjgrz9cSo50s7NrAQDEEbT3CEmgaOwYwVj9W0aM2vmsRxFjnpQ97+ORoerbKyc Jlog== X-Forwarded-Encrypted: i=1; AJvYcCWC7+vZzSr/5uNCUxE9JrjUDadg9kRCooQRpyPjh7MUm74O68nYHvivO/oUToG9PkAlwQFI61U0nnQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxrtIZLR4pojgyEi7/sgicjkBllfID/fL0Cjk+8LqBRqN4e20Oq 8q5TDVHqRZRwqBZ32h4RY/DlnKK1adSDHvvyQZYtlLRmaUG1nGpGUWHjSQuoQAE= X-Gm-Gg: ASbGncvn/Bl+pxM9Qi6hQAwgm+b9Pc6R4Ieq0HmRI+gS1+aCemN+WUP3eG9Zn2MSrTs hP6is4BNTVuEoIjR1L7Livg5o+S0SmTIW1mwn190JOFBnWXbqbi8HrcOTEdzgLEqSmOtrPXx+AI 4dTKNkwbpiFgZ2hooHpRLm3jXA3O/97Qg8njE/7kKqhopSarLc536135lcuIJCLXsXGU06O01lQ 47O1rsaeucSYIeCBcs7tyMmNkrkw0OJef5ij6jp5X86S00FW2slPPKf2n193FBSRTMXndYo2yKS 3gzeEB8bWQ== X-Google-Smtp-Source: AGHT+IFkwqE9NeuzPSJABYVR8sPjY32nx1fs0VxalgjIVAvgimK8wt5SxqxergECQMEez9To3l0WaA== X-Received: by 2002:a05:6830:648e:b0:71d:f239:c0b7 with SMTP id 46e09a7af769-71e29bd5721mr568395a34.12.1733950520886; Wed, 11 Dec 2024 12:55:20 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:19 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:50 -0600 Subject: [PATCH v6 13/17] dt-bindings: iio: adc: adi,ad4695: add SPI offload properties Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-13-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.2 Add a pwms property to the adi,ad4695 binding to specify an optional PWM output connected to the CNV pin on the ADC. Also add #trigger-source-cells property to allow the BUSY output to be used as a SPI offload trigger source to indicate when a sample is ready to be read. Macros are added to adi,ad4695.h for the cell values to help with readability since they are arbitrary values. Signed-off-by: David Lechner --- v6 changes: * Drop $ref to trigger-source.yaml * Add maxItems to pwms property v5 changes: * Added macros for cell values v4 changes: new patch in v4 --- Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml | 13 +++++++++++++ include/dt-bindings/iio/adc/adi,ad4695.h | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml index 7d2229dee4441e20a7bafc9165fe309ac2e9eada..cbde7a0505d2b5df22c54ca4556878bf22e9b4b1 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4695.yaml @@ -84,6 +84,10 @@ properties: description: The Reset Input (RESET). Should be configured GPIO_ACTIVE_LOW. maxItems: 1 + pwms: + description: PWM signal connected to the CNV pin. + maxItems: 1 + interrupts: minItems: 1 items: @@ -106,6 +110,15 @@ properties: The first cell is the GPn number: 0 to 3. The second cell takes standard GPIO flags. + '#trigger-source-cells': + description: | + First cell indicates the output signal: 0 = BUSY, 1 = ALERT. + Second cell indicates which GPn pin is used: 0, 2 or 3. + + For convenience, macros for these values are available in + dt-bindings/iio/adc/adi,ad4695.h. + const: 2 + "#address-cells": const: 1 diff --git a/include/dt-bindings/iio/adc/adi,ad4695.h b/include/dt-bindings/iio/adc/adi,ad4695.h index 9fbef542bf670015c5b34bfbe1336e7e295bf8ab..fea4525d2710cbf58cd4236d3276bad4cb318df9 100644 --- a/include/dt-bindings/iio/adc/adi,ad4695.h +++ b/include/dt-bindings/iio/adc/adi,ad4695.h @@ -6,4 +6,11 @@ #define AD4695_COMMON_MODE_REFGND 0xFF #define AD4695_COMMON_MODE_COM 0xFE +#define AD4695_TRIGGER_EVENT_BUSY 0 +#define AD4695_TRIGGER_EVENT_ALERT 1 + +#define AD4695_TRIGGER_PIN_GP0 0 +#define AD4695_TRIGGER_PIN_GP2 2 +#define AD4695_TRIGGER_PIN_GP3 3 + #endif /* _DT_BINDINGS_ADI_AD4695_H */ From patchwork Wed Dec 11 20:54:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849662 Received: from mail-ot1-f43.google.com (mail-ot1-f43.google.com [209.85.210.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33FEE23A18B for ; Wed, 11 Dec 2024 20:55:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950531; cv=none; b=oHZuGj2jK+Fk5LUmDVOJCO38f4LpAF592ILEkZa3dXhqpMxZcV6BJeV9RNMmWyydK+EI5oZpWe3HMd6n2HScryn1YfPKqTPQMx/CuNA4wMJNouFs2KW3bLyknzTBUEgmxIigA7pCJWvKvk0rZAiOAv/S0NtWW/xg2GtBhEXrVsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950531; c=relaxed/simple; bh=WAwTb5myka3LdUPJqpDewXuqJ4E4xxoro/9r7/Szvgs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CeoZi/HVTiIRkvT0BawjzPifFhnNsf0YHBfAt0HEjK6iUD6ntWEF1LW3zmEUdvgVAJeg9XgHTzR2zt+7y6FNkjIeDq/PtpsLQRFXyRliQrJPmuxUq2kJG/KVnDt7cpnu6CFmP4HygTrzDIuosUGtWHMGpy8TxUIgh/7Q9wIn6Ao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=XxhoNC2e; arc=none smtp.client-ip=209.85.210.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="XxhoNC2e" Received: by mail-ot1-f43.google.com with SMTP id 46e09a7af769-71e2bb84fe3so18941a34.1 for ; Wed, 11 Dec 2024 12:55:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950528; x=1734555328; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=iQTW6D1fIdftX2zgH4Jllg1mjOtWmH2bIJ8hHBb6gVk=; b=XxhoNC2exsi0+emKrjMP4sDx5XqmlS2PQiVe9r64Ix8BLDmF0w1/lAnkooiUZhOgvv vBnSWcVlxXb8qiJdMNqVyMsOzLPQeW87vwVvMsKhImQVzWPwo4QTs7bpNlb/3oojEzD7 QPj33WHPMuoFdt5IIowefhxRezP/im3LsghAN/IpVkWi98CgZeLLFWtxwCAfzQmf8vgK yeE9spo3atQeCUw8hZcgEMJXkBa1515blRSoiZr4tD2RxxaXPKgywLN1leYZd0pvfjov Psrd/spH0pwZVdKcJjzk0HM8qcJnpT+iCEJ8Z1F1sSjOskfZNfnAWc43SjkciiZa6m49 U/fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950528; x=1734555328; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iQTW6D1fIdftX2zgH4Jllg1mjOtWmH2bIJ8hHBb6gVk=; b=cZoN7HJyt+F+mOsZTpHsi3/PiFvd/0faA+xaXhzPGZzNyMLiehRbmXqmCE/iANjxoG 4gyT+Vfn+CwE5RTSeQqGMkZJQbUf3goZ4hNn8tXHMuJSx+G3Nyktu4uy5Jdphc0cU54d i4HyNPTzxDblXkCaSgoZe0UwQPh5dspeaggrhMBM+Up6HK2bbACBdXXW/gjSYGdRUgI5 736FJLMQwZ1mMDP7ZiYD0lehFwzMnqAgQTA8fXgZ57//VNHpznHS4JxkuEwofMLTe9fj tCBWKRwZVICQxAdNIrt2HzrukPAwPFWXp9cMZUcqHcIcov9pNnj46VoXfxXrP2uhCnvb zVNg== X-Forwarded-Encrypted: i=1; AJvYcCVW4oN0KabkmWSSzjMfvr70WWQMMSY819cnXyuGGMyIOa7jfG/2s41HyQSRGBpQlQVnuAMEzZxm0u0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxg8JInPVrqKDZvhullqQrKeHQcJQ7Poc4ufQxK+3FQ44gBATMT gCWEqwmbqDJvp+S9oSV/Nw2AHqUrP+NK5M310NKZ1Rx3pQ57RDuvhqRm5AUUXhk= X-Gm-Gg: ASbGncuHNAmbHjUipi9rn0J+fQsVio55IcrNwOq8nK/JMJ/9wDC7wVygKRSg/SWVheY rKBlTsg4Re8h7W+En0jQld19j8Ah7ouF+pIckeInAWnsnNLFjC3kHqU8agZdOCb+wYY/ReqxP2o MRAtiSc/W2Lc3LM09WOM7Wd7wWtjNzlWoPmpm0iBR9DEFh1IUmXBbo4zQwLuPXsQYpasAmFV7Lk FjnTb2hl0V89jJ7hZ1lomTjKzdplHLhXa+wrXP2eeMvae6cD5sAWRUTzdVht2F6HVfZseve39zK ii5EtdpgtA== X-Google-Smtp-Source: AGHT+IFuudyGftKCliMPrvNIjDvrTqh80IEhkFgUdBPmfjIx2sVP9rniThVNaNVnvLDBQ2fzFuey2A== X-Received: by 2002:a05:6830:6a8b:b0:71e:1b44:35c5 with SMTP id 46e09a7af769-71e29c5f375mr670404a34.18.1733950528037; Wed, 11 Dec 2024 12:55:28 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:27 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:53 -0600 Subject: [PATCH v6 16/17] iio: dac: ad5791: sort include directives Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-16-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, David Lechner X-Mailer: b4 0.14.2 Sort includes alphabetically before we add more in a later patch. Signed-off-by: David Lechner --- v6 changes: new patch in v6 --- drivers/iio/dac/ad5791.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 57374f78f6b885e1d4f2fb452ac0563b85fc222e..24462cb020e19e8e2c6faa13109ac047cf423c37 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -6,21 +6,21 @@ * Copyright 2011 Analog Devices Inc. */ -#include -#include -#include +#include #include +#include +#include +#include #include -#include +#include +#include #include +#include #include -#include -#include -#include +#include #include #include -#include #define AD5791_DAC_MASK GENMASK(19, 0) From patchwork Wed Dec 11 20:54:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 849661 Received: from mail-ot1-f52.google.com (mail-ot1-f52.google.com [209.85.210.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7940B23E6C7 for ; Wed, 11 Dec 2024 20:55:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950534; cv=none; b=BaZ0HVR9uZBluBcKbtveFvjkgJIti/DBjkljGvsxtLe3gJfN3/KMar2ilruaIW3MbeSD4bUQt+3gfKqwAbRm9tHU7rhJR4IsgZjjTboXnad2e1tThH1UMHoU2PG3tYXcpAdutsIyKCW+WazbId0ODP7tD9Us1aJeZmS9CfA9CA4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733950534; c=relaxed/simple; bh=OzAu1y/H3v98Oh+obJXz2LVpGi8e3bYBOTQLvfGilLE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uunKFzww1k3BRxC/xoo4aDP8w7K3xaUBnxRLe+YgQA+d1fyq7+CJtF2S71Dnax7fyL71ASC6fnjaOM/NWs0IQJXk3PnPbKlEyjEMxeRk4E9oz+VX0Wo1gOHmp6sE35epTBYmOt+uxcdKeVa/V8kU5+PL8vHsFv7R3BJsoTOD3PQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=bMSwM9xH; arc=none smtp.client-ip=209.85.210.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="bMSwM9xH" Received: by mail-ot1-f52.google.com with SMTP id 46e09a7af769-71decc7de4eso1082229a34.2 for ; Wed, 11 Dec 2024 12:55:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1733950530; x=1734555330; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=UIG6sINpyGyOIxw92FCk6jPcVNBP3Duj2CqVoFPTTHM=; b=bMSwM9xHzsq1QkBxECtKTZYr3usMseHCs9OeG4rs3pLB5gUTPv6CuFBuijIvI48Twd bhbblW5ui+wmAHA5TWSOz1iBQ//Yk4fOO9VBrKWJdS6lpCZ8tCxGc70CvU1MAjSuGDJv nywyZbydRprQbq560XJW+/6YHA22Swn8+FzVsLOE4JhE7kWlNafbOCTDvcCdMCluw+nF AjsLdJugpDHohNlv07Xs4XIrz2lLoOqxO+iPPIqchcKSpHifi4ZwhjUeZIRE4Ibs2OkK v/f41Bxdn17PoeFsZqNEe9uFbsorCT9GZ4oswLaLsecHqPNwr4eAYLYOCwAY7C10DFoL f/4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1733950530; x=1734555330; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UIG6sINpyGyOIxw92FCk6jPcVNBP3Duj2CqVoFPTTHM=; b=NDW0DdoViRzUgxpNiUo33UddA0e9sx/RI2e2jRjRcZA5GFYGsLw98qy9mlY/v2AAUd LPvPzLqWA/fH4RhY0zdOS3kDcA0Yf0AhkKMCLDXrtnjeOeHNKIRTwr2SHBXZOuGcuxlD efpnD+pEsXWATQ4xmiPFI5yCuhOGIf+PTSNNn2AaL071fHBj8RZ9cpHJavhXXI52Jl1v w9EToZljhx7cf+o+sX7LwarY8BXDFC7Bm0oCQFabPE95lSYoHjn9JV9aLgrFaJh3QWWr bYN+VKx7e4vl1JTVoQ5EI/WFVPVSXjp5PDDQxb19GaaMILXnmGl80uglryVJZJh++93+ NnUw== X-Forwarded-Encrypted: i=1; AJvYcCWyUY1/KgBGw967B0gFcRW7yb8fMEDglLWxuy4r+QH9t0aLniTAOWcOawzJKlHltr1UHlSpmVGlkUY=@vger.kernel.org X-Gm-Message-State: AOJu0YylK/3gVOqhqqOlPYp4YpsJM7uN6UMJNaqtG0JcVoklh6G6dc9o sUaq8Iocs/D+Hovw2obvU/9Y92ox+C7emEnWazDAvUgIu+eRXAd3dgXdwq78dVw= X-Gm-Gg: ASbGncsJwYIX6vvEa4df+4QLIRDbB2y82Trx9NN3R7utxOlu9jA0J5Pt9Uwl8mqbkdc nmjaBPlIzjshsSlZVOpwU2ONykHZSqY6NI1U6UcPUtRvT4tZPJtDvXU1/mTTlmO5uPg1Kqwxee3 +HXgzgXOpAX4kN6ulopjDudeINENKU7apUOI9MzCuFR6Z2RQzIirHYuJjfhmzuWjscnqRKkR8DP hmCTKCkFdn9TLR0/aYYVxoYDcgYzcStB4KAwistX2vggxXw0avgn49Rki44rxJkyoR0g4eDmtJM 8WbhpuT/qA== X-Google-Smtp-Source: AGHT+IEFT/scxcmkfgIOkKvLV+l02WCW6R4Q/Nhv22dR9dP0pLo0cFMOt9o0Fzd4itbazmNHYYYouQ== X-Received: by 2002:a05:6830:438d:b0:718:6da0:72b with SMTP id 46e09a7af769-71e29baca4emr609402a34.7.1733950530105; Wed, 11 Dec 2024 12:55:30 -0800 (PST) Received: from [127.0.1.1] (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-71def651fb2sm1888288a34.27.2024.12.11.12.55.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Dec 2024 12:55:29 -0800 (PST) From: David Lechner Date: Wed, 11 Dec 2024 14:54:54 -0600 Subject: [PATCH v6 17/17] iio: dac: ad5791: Add offload support Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241211-dlech-mainline-spi-engine-offload-2-v6-17-88ee574d5d03@baylibre.com> References: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> In-Reply-To: <20241211-dlech-mainline-spi-engine-offload-2-v6-0-88ee574d5d03@baylibre.com> To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Michael Hennerich , Lars-Peter Clausen , David Jander , Martin Sperl , linux-spi@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, linux-pwm@vger.kernel.org, Axel Haslam , David Lechner X-Mailer: b4 0.14.2 From: Axel Haslam Add SPI offload support to stream TX buffers using DMA. This allows loading samples to the DAC with a rate of 1 MSPS. Signed-off-by: Axel Haslam Signed-off-by: David Lechner --- v6 changes: new patch in v6 --- drivers/iio/dac/Kconfig | 3 + drivers/iio/dac/ad5791.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 4cde34e8c8e3356aa41bcd2cba38d67d5c6f8049..f6c5cb632acbdc2432f60b163452bb0c5f89fa72 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -296,6 +296,9 @@ config AD5770R config AD5791 tristate "Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC SPI driver" depends on SPI + select SPI_OFFLOAD + select IIO_BUFFER + select IIO_BUFFER_DMAENGINE help Say yes here to build support for Analog Devices AD5760, AD5780, AD5781, AD5790, AD5791 High Resolution Voltage Output Digital to diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index 24462cb020e19e8e2c6faa13109ac047cf423c37..a2953a9a4e5d5bc17c9c4a8281be4b41b1af5de8 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -15,9 +15,12 @@ #include #include #include +#include #include #include +#include +#include #include #include #include @@ -64,11 +67,13 @@ * struct ad5791_chip_info - chip specific information * @name: name of the dac chip * @channel: channel specification + * @channel_offload: channel specification for offload * @get_lin_comp: function pointer to the device specific function */ struct ad5791_chip_info { const char *name; const struct iio_chan_spec channel; + const struct iio_chan_spec channel_offload; int (*get_lin_comp)(unsigned int span); }; @@ -81,6 +86,11 @@ struct ad5791_chip_info { * @gpio_clear: clear gpio * @gpio_ldac: load dac gpio * @chip_info: chip model specific constants + * @offload_msg: spi message used for offload + * @offload_xfer: spi transfer used for offload + * @offload: offload device + * @offload_trigger: offload trigger + * @offload_trigger_hz: offload sample rate * @vref_mv: actual reference voltage used * @vref_neg_mv: voltage of the negative supply * @ctrl: control register cache @@ -96,6 +106,11 @@ struct ad5791_state { struct gpio_desc *gpio_clear; struct gpio_desc *gpio_ldac; const struct ad5791_chip_info *chip_info; + struct spi_message offload_msg; + struct spi_transfer offload_xfer; + struct spi_offload *offload; + struct spi_offload_trigger *offload_trigger; + unsigned int offload_trigger_hz; unsigned short vref_mv; unsigned int vref_neg_mv; unsigned ctrl; @@ -232,6 +247,25 @@ static int ad5780_get_lin_comp(unsigned int span) return AD5780_LINCOMP_10_20; } +static int ad5791_set_sample_freq(struct ad5791_state *st, int val) +{ + struct spi_offload_trigger_config config = { + .type = SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic = { + .frequency_hz = val, + }, + }; + int ret; + + ret = spi_offload_trigger_validate(st->offload_trigger, &config); + if (ret) + return ret; + + st->offload_trigger_hz = config.periodic.frequency_hz; + + return 0; +} + static int ad5791_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, @@ -259,6 +293,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, do_div(val64, st->vref_mv); *val = -val64; return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + *val = st->offload_trigger_hz; + return IIO_VAL_INT; default: return -EINVAL; } @@ -299,6 +336,24 @@ static const struct ad5791_chip_info _name##_chip_info = { \ }, \ .ext_info = ad5791_ext_info, \ }, \ + .channel_offload = { \ + .type = IIO_VOLTAGE, \ + .output = 1, \ + .indexed = 1, \ + .address = AD5791_ADDR_DAC0, \ + .channel = 0, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 32, \ + .shift = (_shift), \ + }, \ + .ext_info = ad5791_ext_info, \ + }, \ } AD5791_DEFINE_CHIP_INFO(ad5760, 16, 4, ad5780_get_lin_comp); @@ -322,16 +377,95 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, return ad5791_spi_write(st, chan->address, val); + case IIO_CHAN_INFO_SAMP_FREQ: + if (val < 0 || val2 < 0) + return -EINVAL; + return ad5791_set_sample_freq(st, val); default: return -EINVAL; } } +static int ad5791_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ad5791_state *st = iio_priv(indio_dev); + struct spi_offload_trigger_config config = { + .type = SPI_OFFLOAD_TRIGGER_PERIODIC, + .periodic = { + .frequency_hz = st->offload_trigger_hz, + }, + }; + + if (st->pwr_down) + return -EINVAL; + + return spi_offload_trigger_enable(st->offload, st->offload_trigger, + &config); +} + +static int ad5791_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad5791_state *st = iio_priv(indio_dev); + + spi_offload_trigger_disable(st->offload, st->offload_trigger); + + return 0; +} + +static const struct iio_buffer_setup_ops ad5791_buffer_setup_ops = { + .preenable = &ad5791_buffer_preenable, + .postdisable = &ad5791_buffer_postdisable, +}; + +static int ad5791_offload_setup(struct iio_dev *indio_dev) +{ + struct ad5791_state *st = iio_priv(indio_dev); + struct spi_device *spi = st->spi; + struct dma_chan *tx_dma; + int ret; + + st->offload_trigger = devm_spi_offload_trigger_get(&spi->dev, + st->offload, SPI_OFFLOAD_TRIGGER_PERIODIC); + if (IS_ERR(st->offload_trigger)) + return dev_err_probe(&spi->dev, PTR_ERR(st->offload_trigger), + "failed to get offload trigger\n"); + + ret = ad5791_set_sample_freq(st, 1 * MEGA); + if (ret) + return dev_err_probe(&spi->dev, ret, + "failed to init sample rate\n"); + + tx_dma = devm_spi_offload_tx_stream_request_dma_chan(&spi->dev, + st->offload); + if (IS_ERR(tx_dma)) + return dev_err_probe(&spi->dev, PTR_ERR(tx_dma), + "failed to get offload TX DMA\n"); + + ret = devm_iio_dmaengine_buffer_setup_with_handle(&spi->dev, + indio_dev, tx_dma, IIO_BUFFER_DIRECTION_OUT); + if (ret) + return ret; + + st->offload_xfer.len = 4; + st->offload_xfer.bits_per_word = 24; + st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_TX_STREAM; + + spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1); + st->offload_msg.offload = st->offload; + + return devm_spi_optimize_message(&spi->dev, st->spi, &st->offload_msg); +} + static const struct iio_info ad5791_info = { .read_raw = &ad5791_read_raw, .write_raw = &ad5791_write_raw, }; +static const struct spi_offload_config ad5791_offload_config = { + .capability_flags = SPI_OFFLOAD_CAP_TRIGGER | + SPI_OFFLOAD_CAP_TX_STREAM_DMA, +}; + static int ad5791_probe(struct spi_device *spi) { const struct ad5791_platform_data *pdata = dev_get_platdata(&spi->dev); @@ -416,6 +550,21 @@ static int ad5791_probe(struct spi_device *spi) indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; indio_dev->name = st->chip_info->name; + + st->offload = devm_spi_offload_get(&spi->dev, spi, &ad5791_offload_config); + ret = PTR_ERR_OR_ZERO(st->offload); + if (ret && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, "failed to get offload\n"); + + if (ret != -ENODEV) { + indio_dev->channels = &st->chip_info->channel_offload; + indio_dev->setup_ops = &ad5791_buffer_setup_ops; + ret = ad5791_offload_setup(indio_dev); + if (ret) + return dev_err_probe(&spi->dev, ret, + "fail to setup offload\n"); + } + return devm_iio_device_register(&spi->dev, indio_dev); } @@ -452,3 +601,4 @@ module_spi_driver(ad5791_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");