From patchwork Sat May 11 00:44:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796858 Received: from mail-oo1-f43.google.com (mail-oo1-f43.google.com [209.85.161.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 04CAD9461 for ; Sat, 11 May 2024 00:49:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388599; cv=none; b=O/MLfnYezzQ9cp69v0mPk+okBOz/leTZ1wCTlqeICUcXR/JPe+CQBW/IeYAea6goeyWcKUZtURVb44GAcoBqSQK7cMCcp97bCW0mGnmUlDyC5sRQNeu7bSXs41dzMur7LvdVdJZWzZmlg9f38AXvbJnZk6axLSmYBnCkVr+xyjw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388599; c=relaxed/simple; bh=QslN9hiRjif2714MLfUNTy1aeizyH8JMJMB6mPnzuPI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pDMdBc1ndq+RFSZVDgw3DhTX6DLXUqH0ADd/OSYBb928R243LhQm8Euy5kZwXneQj9FnLHf2b9aZgCM2qCmMZmc6DgR1WgwB2EoawwT9aPwYUNHtCMkSe1tLVW/pYgZuXyXqdsVWpk5o+tTY8ybwlOKw17VAT2frwpnSliWtEDQ= 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=I+AF6YZv; arc=none smtp.client-ip=209.85.161.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="I+AF6YZv" Received: by mail-oo1-f43.google.com with SMTP id 006d021491bc7-5b27999f889so1014459eaf.0 for ; Fri, 10 May 2024 17:49:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388597; x=1715993397; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wm1JDIpGQ3/Aqds3KMjjWWOJUYPSXntTpGvlaeWf3LY=; b=I+AF6YZvb0ZGtqfxIrQkw4wQE744NHHGfeUB2+wEHvD43mTYqJ2ZarJQdW3ERqrwVb 3216460M4XoEsbjvfOhcjNtYa8MFESqGPiOEp3agpE3GpURId0+YTxVSvgIsNrAveWRR Kur18iuO86itQz2qZ6VL75LlRHdL3Bw+3dN9qmYJbkW7wLBgxYc/ky5l8GlZegY17jLl Czsb9EOBKyWCTJwsUxYGYRWgVsmVsvTNyKmY+40iD3jY3xHkohN1/9uooJy3Y+boag2g Y8qUg5Z4Mc1gQODqpnXEPy0eq246RoJX6kKrCtQOc62uR2+2uQkE6q1BS2N5t4XBN4WE 55iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388597; x=1715993397; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wm1JDIpGQ3/Aqds3KMjjWWOJUYPSXntTpGvlaeWf3LY=; b=AserocZtsg2Yf56LfQvCjysc189le5P/vgNgJQSA6sYzOqSO5gZTNRDVkOGT50juBS W0LB7TuG2fHnm/PUPiqkp26SGiXlwDQe1QxGiD6neW2smBlqp1Dlfo+5dyxRSY2F/njI 6wB5p2xsU2bSkD0YEelFyKKjLRDSIrgXdaUu2TagHm2FAu/z8zpw8Lr9WfVrfTMWPmij LYk1JuRd4C1h5JPAhnlPnsuoqJq5ciJmyP4nV2vpgnWxgm6/w3yjvB67sYcQPZcDB4AH CihbA7AHS5yHxWUePo1mTcdcARGZDC+AUPbA5nJmG1elZskm+7qiFDKbVUqkSlr3muFi bbpA== X-Forwarded-Encrypted: i=1; AJvYcCWMPWXosVLOJ4TBXCv7pL5m1mYe6pQfq/0FACdIL5ajWy/BQm5BpL2DDvUjiRjN6xffyjymkO3zewwPVEnmXALl2rlaMkBdU+DA X-Gm-Message-State: AOJu0YwfEMEWOMm/qVytZT/CR8qBC70VXT6zbRmIob7mSVxvF+U5uKO3 b3lSsOKjoRriSiq8C08tydjqD2233VBeNQecWohGctqbNefUNiScGAyfb/DCUU0= X-Google-Smtp-Source: AGHT+IHIlPJpLdkHvfVzDbw2X1xtwQanIP+eKehd+NyrLExBkWOAZfON5byOulKnrHpJ4Pdp/WT0fg== X-Received: by 2002:a4a:907:0:b0:5af:4b39:b7e0 with SMTP id 006d021491bc7-5b2815cd612mr4164258eaf.0.1715388597084; Fri, 10 May 2024 17:49:57 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.49.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:49:56 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 1/8] spi: dt-bindings: spi-peripheral-props: add spi-offloads property Date: Fri, 10 May 2024 19:44:24 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-1-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 This adds a new property to the spi-peripheral-props binding for use with peripherals connected to controllers that support offloading. Here, offloading means that the controller has the ability to perform complex SPI transactions without CPU intervention in some shape or form. This property will be used to assign controller offload resources to each peripheral that needs them. What these resources are will be defined by each specific controller binding. Signed-off-by: David Lechner --- v2 changes: In v1, instead of generic SPI bindings, there were only controller- specific bindings, so this is a new patch. In the previous version I also had an offloads object node that described what the offload capabilities were but it was suggested that this was not necessary/overcomplicated. So I've gone to the other extreme and made it perhaps over-simplified now by requiring all information about how each offload is used to be encoded in a single u32. We could of course consider using #spi-offload-cells instead for allowing encoding multiple parameters for each offload instance if that would be preferable. I also considered adding spi-offload-names that could be used as sort of a compatible string (more of an interface name really) in case some peripherals may want to support more than 1 specialized type of offload. --- .../devicetree/bindings/spi/spi-peripheral-props.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml index 15938f81fdce..32991a2d2264 100644 --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -113,6 +113,16 @@ properties: minItems: 2 maxItems: 4 + spi-offloads: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Array of controller offload instances that are reserved for use by the + peripheral device. The semantic meaning of the values of the array + elements is defined by the controller. For example, it could be a simple + 0-based index of the offload instance, or it could be a bitfield where + a few bits represent the assigned hardware trigger, a few bits represent + the assigned RX stream, etc. + st,spi-midi-ns: description: | Only for STM32H7, (Master Inter-Data Idleness) minimum time From patchwork Sat May 11 00:44:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796857 Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 18FD023AD for ; Sat, 11 May 2024 00:49:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388601; cv=none; b=GRl1oS5Wmv44NC0nwOsCMYPakKAWi0SSVlBNG38NsbVRAHhfh5Cck2LMU4KPbo47oLPt2UDFAtk2zigqnTvWwWQSi+JRW+UX9Ako+MDF2BsMyC0GdYbZR86N77nETUzoAi6DRxN7lvXYKOLBcb3glfkY8dWyxzm/MkTZgJ1vfHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388601; c=relaxed/simple; bh=trOA5E6cr+7SXCIy7MjCsAjJshllVgbE52T91gYWCS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UE0bwsPDqXdsb7wu8TaSz1sbY8x4T1Q1GsuwDtoHCb71hykjo5TRt9wMcN2/7DWdC46DiKnizxHF159/vYRW4rh751Pv78f4ifJGvYUYoRp6lxAoDrhG5nCnNtGKtGUCi+CZWbcEeMBnl42VbWyHnMOhVQKo7WeBmEWGpGko1oI= 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=kRhxpUBi; arc=none smtp.client-ip=209.85.161.49 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="kRhxpUBi" Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-5b2735f217aso1271309eaf.2 for ; Fri, 10 May 2024 17:49:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388598; x=1715993398; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iBA7sAKR0McttWE/pFL/rZ2xrhn9Dfe5dI0ynO4z2uI=; b=kRhxpUBiZ2bjt+Pk7yncaX4o5hIlhYYcwTsSx4AwKv1zEJT/VbOkwT/Wld6jeFghYF 9IGAwXvb8ySiglq+nWSV+xYwTKsZdwdtfxvUzGG/CPvscF5hLo2r/yKs4z9WvPvaVgmR tTpg62W84DaCWrfK8ehvcxYVY3B+U0J4Tle8UNnCj7nQLEYdYhwFrph1TYghveG4wqfQ gbm8taHVEJXZl1Gk+Y8QznTsyuIakYZUPEjiM3196nVqj1x7ErlCYkL5gdaz6erV1C4x DxVyDXkHlfUO9Xi45w1vkovpYU+0Q+CAgWb0akDWBGRkH7mk45v5W4rKM2pWGv/9SMB6 mZEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388598; x=1715993398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=iBA7sAKR0McttWE/pFL/rZ2xrhn9Dfe5dI0ynO4z2uI=; b=Z9/ixN07JojaW/AqdiUHajJwuuOgdUNOSMHv3BpHyQV9YfQW3Qnfd6PjxElb/u41GA DF8rOGcFSuAcBB1OJS03a+5pTE16kEAonH6yQ+IpX5wHisV3S1UIfN1IGjFsTUm4wMaf U1xOlRKD4g82mLavd5EgWKC1O/3anJla8zqHcJKLzUrzjvd0uv1ynkVIOEIsvUqZYxmu bxM8r2UQJiZqtpNdMBvMxTPb/jk5GSMSWPw0/s3tX2CXCiLl8kiwFtVSsaCGa2XB3LUd YytrjSbZCgT94jtY3cQ+MdnvCdYSLH0hPLul7ROrKQX9JKIWLBleDGp0N0TJkIEqS70l HJeg== X-Forwarded-Encrypted: i=1; AJvYcCWDvkGxnb/ScMg6ARkPpqZrgP8k8Hsd8DO3QKuGVc1xYldZqQcNmB7imGOR5VEQCbr3PAve9s9VQFw07tEV5jSoo9rqw5zS0Onn X-Gm-Message-State: AOJu0Yzdu1/11Hg44XVGcG15n48jBoqnaL1XkGTHPMZ2Rw6axUpdMPoW THkRxhrVPc5Hx+DmVahaHVQKRAST9Q2cOhSAqpE1cblEF/8uZCfIGHhnsifl3aw= X-Google-Smtp-Source: AGHT+IFRvVNIdqHmAFp3VONJKZ1EO7R2R6wKqwQ4CFLc4SE6uiCuGQ83poyhcFd37Cu9yDkUnFcxig== X-Received: by 2002:a4a:5487:0:b0:5aa:596c:52d0 with SMTP id 006d021491bc7-5b2819a49dbmr4629752eaf.6.1715388598032; Fri, 10 May 2024 17:49:58 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.49.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:49:57 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 2/8] spi: add basic support for SPI offloading Date: Fri, 10 May 2024 19:44:25 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-2-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 SPI offloading is a feature that allows the SPI controller to perform complex transfers without CPU intervention. This is useful, e.g. for high-speed data acquisition. This patch adds the basic infrastructure to support SPI offloading. It introduces new callbacks that are to be implemented by controllers with offload capabilities. On SPI device probe, the standard spi-offloads devicetree property is parsed and passed to the controller driver to reserve the resources requested by the peripheral via the map_channel() callback. The peripheral driver can then use spi_offload_prepare() to load a SPI message into the offload hardware. If the controller supports it, this message can then be passed to the SPI message queue as if it was a normal message. Future patches will will also implement a way to use a hardware trigger to start the message transfers rather than going through the message queue. Signed-off-by: David Lechner --- 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. In the previous review, Mark suggested that these functions should not be separate from the spi_[un]optimize() functions. I understand the reasoning behind that. However, it seems like there are two different kinds of things going on here. Currently, spi_optimize() only performs operations on the message data structures and doesn't poke any hardware. This makes it free to be use by any peripheral without worrying about tying up any hardware resources while the message is "optimized". On the other hand, spi_offload_prepare() is poking hardware, so we need to be more careful about how it is used. And in these cases, we need a way to specify exactly which hardware resources it should use, which it is currently doing with the extra ID parameter. --- drivers/spi/spi.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/spi.h | 57 +++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 289feccca376..54b814cea54c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2477,6 +2477,28 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi, of_spi_parse_dt_cs_delay(nc, &spi->cs_hold, "spi-cs-hold-delay-ns"); of_spi_parse_dt_cs_delay(nc, &spi->cs_inactive, "spi-cs-inactive-delay-ns"); + /* Offloads */ + rc = of_property_count_u32_elems(nc, "spi-offloads"); + if (rc > 0) { + int num_ch = rc; + + if (!ctlr->offload_ops) { + dev_err(&ctlr->dev, "SPI controller doesn't support offloading\n"); + return -EINVAL; + } + + for (idx = 0; idx < num_ch; idx++) { + of_property_read_u32_index(nc, "spi-offloads", idx, &value); + + rc = ctlr->offload_ops->map_channel(spi, idx, value); + if (rc) { + dev_err(&ctlr->dev, "Failed to map offload channel %d: %d\n", + value, rc); + return rc; + } + } + } + return 0; } @@ -3231,6 +3253,11 @@ static int spi_controller_check_ops(struct spi_controller *ctlr) } } + if (ctlr->offload_ops && !(ctlr->offload_ops->map_channel && + ctlr->offload_ops->prepare && + ctlr->offload_ops->unprepare)) + return -EINVAL; + return 0; } @@ -4708,6 +4735,79 @@ int spi_write_then_read(struct spi_device *spi, } EXPORT_SYMBOL_GPL(spi_write_then_read); +/** + * spi_offload_prepare - prepare offload hardware for a transfer + * @spi: The spi device to use for the transfers. + * @id: Unique identifier for SPI device with more than one offload. + * @msg: The SPI message to use for the offload operation. + * + * Requests an offload instance with the specified ID and programs it with the + * provided message. + * + * The message must not be pre-optimized (do not call spi_optimize_message() on + * the message). + * + * Calls must be balanced with spi_offload_unprepare(). + * + * Return: 0 on success, else a negative error code. + */ +int spi_offload_prepare(struct spi_device *spi, unsigned int id, + struct spi_message *msg) +{ + struct spi_controller *ctlr = spi->controller; + int ret; + + if (!ctlr->offload_ops) + return -EOPNOTSUPP; + + msg->offload = true; + + ret = spi_optimize_message(spi, msg); + if (ret) + return ret; + + mutex_lock(&ctlr->io_mutex); + ret = ctlr->offload_ops->prepare(spi, id, msg); + mutex_unlock(&ctlr->io_mutex); + + if (ret) { + spi_unoptimize_message(msg); + msg->offload = false; + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(spi_offload_prepare); + +/** + * spi_offload_unprepare - releases any resources used by spi_offload_prepare() + * @spi: The same SPI device passed to spi_offload_prepare() + * @id: The same ID device passed to spi_offload_prepare() + * @msg: The same SPI message passed to spi_offload_prepare() + * + * Callers must ensure that the offload is no longer in use before calling this + * function, e.g. no in-progress transfers. + */ +void spi_offload_unprepare(struct spi_device *spi, unsigned int id, + struct spi_message *msg) +{ + struct spi_controller *ctlr = spi->controller; + + if (!ctlr->offload_ops) + return; + + mutex_lock(&ctlr->io_mutex); + ctlr->offload_ops->unprepare(spi, id); + mutex_unlock(&ctlr->io_mutex); + + msg->offload = false; + msg->offload_state = NULL; + + spi_unoptimize_message(msg); +} +EXPORT_SYMBOL_GPL(spi_offload_unprepare); + /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_OF_DYNAMIC) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index e8e1e798924f..a8fc16c6bf37 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -31,6 +31,7 @@ struct spi_transfer; struct spi_controller_mem_ops; struct spi_controller_mem_caps; struct spi_message; +struct spi_controller_offload_ops; /* * INTERFACES between SPI master-side drivers and SPI slave protocol handlers, @@ -500,6 +501,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * This field is optional and should only be implemented if the * controller has native support for memory like operations. * @mem_caps: controller capabilities for the handling of memory operations. + * @offload_ops: operations for controllers with offload support. * @unprepare_message: undo any work done by prepare_message(). * @slave_abort: abort the ongoing transfer request on an SPI slave controller * @target_abort: abort the ongoing transfer request on an SPI target controller @@ -745,6 +747,9 @@ struct spi_controller { const struct spi_controller_mem_ops *mem_ops; const struct spi_controller_mem_caps *mem_caps; + /* Operations for controllers with offload support. */ + const struct spi_controller_offload_ops *offload_ops; + /* GPIO chip select */ struct gpio_desc **cs_gpiods; bool use_gpio_descriptors; @@ -1114,6 +1119,7 @@ struct spi_transfer { * @pre_optimized: peripheral driver pre-optimized the message * @optimized: the message is in the optimized state * @prepared: spi_prepare_message was called for the this message + * @offload: message is to be used with offload hardware * @status: zero for success, else negative errno * @complete: called to report transaction completions * @context: the argument to complete() when it's called @@ -1123,6 +1129,7 @@ struct spi_transfer { * @queue: for use by whichever driver currently owns the message * @state: for use by whichever driver currently owns the message * @opt_state: for use by whichever driver currently owns the message + * @offload_state: for use by whichever driver currently owns the message * @resources: for resource management when the SPI message is processed * * A @spi_message is used to execute an atomic sequence of data transfers, @@ -1151,6 +1158,8 @@ struct spi_message { /* spi_prepare_message() was called for this message */ bool prepared; + /* spi_offload_prepare() was called on this message */ + bool offload; /* * REVISIT: we might want a flag affecting the behavior of the @@ -1183,6 +1192,11 @@ struct spi_message { * __spi_optimize_message() and __spi_unoptimize_message(). */ void *opt_state; + /* + * Optional state for use by controller driver between calls to + * offload_ops->prepare() and offload_ops->unprepare(). + */ + void *offload_state; /* List of spi_res resources when the SPI message is processed */ struct list_head resources; @@ -1546,6 +1560,49 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd) /*---------------------------------------------------------------------------*/ +/* + * Offloading support. + * + * Some SPI controllers support offloading of SPI transfers. Essentially, + * this allows the SPI controller to record SPI transfers and then play them + * back later in one go via a single trigger. + */ + +/** + * struct spi_controller_offload_ops - callbacks for offload support + * + * Drivers for hardware with offload support need to implement all of these + * callbacks. + */ +struct spi_controller_offload_ops { + /** + * @map_channel: Callback to reserve an offload instance for the given + * SPI device. If a SPI device requires more than one instance, then + * @id is used to differentiate between them. Channels must be unmapped + * in the struct spi_controller::cleanup() callback. + */ + int (*map_channel)(struct spi_device *spi, unsigned int id, + unsigned int channel); + /** + * @prepare: Callback to prepare the offload for the given SPI message. + * @msg and any of its members (including any xfer->tx_buf) is not + * guaranteed to be valid beyond the lifetime of this call. + */ + int (*prepare)(struct spi_device *spi, unsigned int id, + struct spi_message *msg); + /** + * @unprepare: Callback to release any resources used by prepare(). + */ + void (*unprepare)(struct spi_device *spi, unsigned int id); +}; + +extern int spi_offload_prepare(struct spi_device *spi, unsigned int id, + struct spi_message *msg); +extern void spi_offload_unprepare(struct spi_device *spi, unsigned int id, + struct spi_message *msg); + +/*---------------------------------------------------------------------------*/ + /* * INTERFACE between board init code and SPI infrastructure. * From patchwork Sat May 11 00:44:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796371 Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.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 01CCF79D3 for ; Sat, 11 May 2024 00:49:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388601; cv=none; b=XD+UfKQ41p6aPAwiQSDPJg30aFm8bC6iHOFN5F6kgCN0B/P6d7dN08bf+Phy4lArVVpa5IjUZGHGfC24oRQ9r0jkc+WDAqSvMLqcd1bcrkpk2LmiWxruKBVLYiaHAkDoFDXvyDCPFWo3V7ArAbSJSvqB9EKQZc/or1ojx8aT458= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388601; c=relaxed/simple; bh=BHMojD3X9bY4SHi0jcrxW7Ha4u/3zvtngRqxXFgXZyc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TTpAyRy8FxpNb4BQ+IQxzm41uSrsItZU8ftSfRwa9xlgDwwt+ZLGNvFpITOXbahtXee0noOEy46qHxIeR6VV9WBG0LKjV+XqWa1zxYnpnzcfRk1xHPMavplQqYheRVaklJKI8nybh/nArJVinNJuYEjHeqJQHYJnIhgCwCNN/YE= 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=km0bM8UU; arc=none smtp.client-ip=209.85.161.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="km0bM8UU" Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-5b27bbcb5f0so1147088eaf.3 for ; Fri, 10 May 2024 17:49:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388599; x=1715993399; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ArLD9QvQN8sa7KIiLAad1A60GsgZ86+t2OLdgGnWFFI=; b=km0bM8UUJOi6Az92hpAatdEWngS05loIKia78sDktc0fZL0f2zFWzJn3rNx3oYoo6/ 5+uFKVMhgoNHJ4gV9tVd6/riWPPn/n70/WuSs79lB41t7iwErFSCKq4pX/CBqOXl/yv5 GUuypa/S1N1RmSBFUllJA2mmOdJBINBtfGBD2RTEdFR6g1cAlAwVbjyVytoKQ29zM9yH mQqlAm0CaiK7ABdBWkcDG/ptbZLndKYBVgmQCi/hhZBhQaMN0sSuAi5KOwtTD5Pq2uLQ BI/z4+DU4Bd9NLlOqrLftD8Jks4+SHzvKIqBqUuYh4X0xDro0d/IE04kM7fxyjvxOXs9 WsYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388599; x=1715993399; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ArLD9QvQN8sa7KIiLAad1A60GsgZ86+t2OLdgGnWFFI=; b=eu59Avyj/2GK/ipCQQqCj+VhNVI1PFz7juAPj7LypxG6muSSdgo89XKeTe28VENEis UJ8iTq/HS/KALrT4E2O/q7WppOYWr0TGX3eiRRhqSBgMR6HdFou8oFWerSFvfVy0z1AP dvRvfQrJZ6njeQ99TqbIQiSz9/AnJYtT4O9cdSZlWXDSnm8OuBdiu3PcX3rw4wpdu4LW kS++Xgw+g+h/rJff78rMiBIareS+7QQMBa/ZAKDWxP0/G2kpJTjx/ek+7kh+TSVXUgj7 AH1hwYkgrnqwv6UDlbjrZEs+Q8/A+Yyt5rEgCzqnEAWpgSFk7OR+B6abdg3iDYkeKPC8 f2Iw== X-Forwarded-Encrypted: i=1; AJvYcCW2702to8a+kYI5O1ztGmNwJN1yQ/h/j3jb3WefsanlF+KH8vqa9SRVanwz3sV5uVQwPjtxTG8mbBlcYfDOK96T0EFBEtA++0Ir X-Gm-Message-State: AOJu0YzwSQNm5NdLy92BAAuDTYmMKgE8HTR4ImHjt/VPKl5DlEg7YqWJ cL/6bgwZKFJorgkdI2bJxUvOgHhj4T0cm+YF7BfDI1WBNElbrdRfrGzVL1rDOAM= X-Google-Smtp-Source: AGHT+IF67/09uCWR5zHPVGAVldQwFwFzVymB/igxM1Xhk/7xfxTF3T4a8rb7utqBzvpAVGATVOiRkw== X-Received: by 2002:a4a:8c08:0:b0:5a4:9977:446b with SMTP id 006d021491bc7-5b2819ad3d5mr3654225eaf.6.1715388599120; Fri, 10 May 2024 17:49:59 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.49.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:49:58 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 3/8] spi: add support for hardware triggered offload Date: Fri, 10 May 2024 19:44:26 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-3-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 This extends the SPI framework to support hardware triggered offloading. This allows an arbitrary hardware trigger to be used to start a SPI transfer that was previously set up with spi_offload_prepare(). Since the hardware trigger can happen at any time, this means the SPI bus must be reserved for exclusive use as long as the hardware trigger is enabled. Since a hardware trigger could be enabled indefinitely, we can't use the existing spi_bus_lock() and spi_bus_unlock() functions, otherwise this could cause deadlocks. So we introduce a new flag so that any attempt to lock or use the bus will fail with -EBUSY as long as the hardware trigger is enabled. Signed-off-by: David Lechner --- v2 changes: This is split out from "spi: add core support for controllers with offload capabilities". Mark suggested that the standard SPI APIs should be aware that the hardware trigger is enabled. So I've added some locking for this. Nuno suggested that this might be overly strict though, and that we should let each individual controller driver decide what to do. For our use case though, I think we generally are going to have a single peripheral on the SPI bus, so this seems like a reasonable starting place anyway. TODO: Currently, spi_bus_lock() always returns 0, so none of the callers check the return value. All callers will need to be updated first before this can be merged. --- drivers/spi/spi.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/spi/spi.h | 17 +++++++++ 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 54b814cea54c..9ad7b04c26a6 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -4427,7 +4427,7 @@ int spi_async(struct spi_device *spi, struct spi_message *message) spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); - if (ctlr->bus_lock_flag) + if (ctlr->bus_lock_flag || ctlr->offload_hw_trigger_enabled) ret = -EBUSY; else ret = __spi_async(spi, message); @@ -4572,6 +4572,12 @@ int spi_sync(struct spi_device *spi, struct spi_message *message) int ret; mutex_lock(&spi->controller->bus_lock_mutex); + + if (spi->controller->offload_hw_trigger_enabled) { + mutex_unlock(&spi->controller->bus_lock_mutex); + return -EBUSY; + } + ret = __spi_sync(spi, message); mutex_unlock(&spi->controller->bus_lock_mutex); @@ -4614,7 +4620,7 @@ EXPORT_SYMBOL_GPL(spi_sync_locked); * exclusive access is over. Data transfer must be done by spi_sync_locked * and spi_async_locked calls when the SPI bus lock is held. * - * Return: always zero. + * Return: 0 on success, -EBUSY if the bus is reserved by offload hardware. */ int spi_bus_lock(struct spi_controller *ctlr) { @@ -4622,6 +4628,11 @@ int spi_bus_lock(struct spi_controller *ctlr) mutex_lock(&ctlr->bus_lock_mutex); + if (ctlr->offload_hw_trigger_enabled) { + mutex_unlock(&ctlr->bus_lock_mutex); + return -EBUSY; + } + spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); ctlr->bus_lock_flag = 1; spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); @@ -4808,6 +4819,83 @@ void spi_offload_unprepare(struct spi_device *spi, unsigned int id, } EXPORT_SYMBOL_GPL(spi_offload_unprepare); +/** + * spi_offload_hw_trigger_enable - enables hardware trigger for offload + * @spi: The spi device to use for the transfers. + * @id: Unique identifier for SPI device with more than one offload. + * + * There must be a prepared offload instance with the specified ID (i.e. + * spi_offload_prepare() was called with the same ID). This will also reserve + * the bus for exclusive use by the offload instance until the hardware trigger + * is disabled. Any other attempts to send a transfer or lock the bus will fail + * with -EBUSY during this time. + * + * Calls must be balanced with spi_offload_hw_trigger_disable(). + * + * Context: can sleep + * Return: 0 on success, else a negative error code. + */ +int spi_offload_hw_trigger_enable(struct spi_device *spi, unsigned int id) +{ + struct spi_controller *ctlr = spi->controller; + unsigned long flags; + int ret; + + if (!ctlr->offload_ops || !ctlr->offload_ops->hw_trigger_enable) + return -EOPNOTSUPP; + + mutex_lock(&ctlr->bus_lock_mutex); + + if (ctlr->offload_hw_trigger_enabled) { + mutex_unlock(&ctlr->bus_lock_mutex); + return -EBUSY; + } + + spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); + ctlr->offload_hw_trigger_enabled = true; + spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); + + /* TODO: how to wait for empty message queue? */ + + mutex_lock(&ctlr->io_mutex); + ret = ctlr->offload_ops->hw_trigger_enable(spi, id); + mutex_unlock(&ctlr->io_mutex); + + if (ret) { + ctlr->offload_hw_trigger_enabled = false; + mutex_unlock(&ctlr->bus_lock_mutex); + return ret; + } + + mutex_unlock(&ctlr->bus_lock_mutex); + + return 0; +} + +/** + * spi_offload_hw_trigger_disable - disables hardware trigger for offload + * @spi: The same SPI device passed to spi_offload_hw_trigger_enable() + * @id: The same ID device passed to spi_offload_hw_trigger_enable() + * + * Disables the hardware trigger for the offload instance with the specified ID + * and releases the bus for use by other clients. + * + * Context: can sleep + */ +void spi_offload_hw_trigger_disable(struct spi_device *spi, unsigned int id) +{ + struct spi_controller *ctlr = spi->controller; + + if (!ctlr->offload_ops || !ctlr->offload_ops->hw_trigger_disable) + return; + + mutex_lock(&ctlr->io_mutex); + ctlr->offload_ops->hw_trigger_disable(spi, id); + mutex_unlock(&ctlr->io_mutex); + + ctlr->offload_hw_trigger_enabled = false; +} + /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_OF_DYNAMIC) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a8fc16c6bf37..ec8d875d31ff 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -632,6 +632,9 @@ struct spi_controller { /* Flag indicating that the SPI bus is locked for exclusive use */ bool bus_lock_flag; + /* Flag indicating the bus is reserved for use by hardware trigger */ + bool offload_hw_trigger_enabled; + /* * Setup mode and clock, etc (SPI driver may call many times). * @@ -1594,12 +1597,26 @@ struct spi_controller_offload_ops { * @unprepare: Callback to release any resources used by prepare(). */ void (*unprepare)(struct spi_device *spi, unsigned int id); + + /** + * @hw_trigger_enable: Callback to enable the hardware trigger for the + * given offload instance. + */ + + int (*hw_trigger_enable)(struct spi_device *spi, unsigned int id); + /** + * @hw_trigger_disable: Callback to disable the hardware trigger for the + * given offload instance. + */ + void (*hw_trigger_disable)(struct spi_device *spi, unsigned int id); }; extern int spi_offload_prepare(struct spi_device *spi, unsigned int id, struct spi_message *msg); extern void spi_offload_unprepare(struct spi_device *spi, unsigned int id, struct spi_message *msg); +extern int spi_offload_hw_trigger_enable(struct spi_device *spi, unsigned int id); +extern void spi_offload_hw_trigger_disable(struct spi_device *spi, unsigned int id); /*---------------------------------------------------------------------------*/ From patchwork Sat May 11 00:44:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796370 Received: from mail-oo1-f50.google.com (mail-oo1-f50.google.com [209.85.161.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 F25B8107A9 for ; Sat, 11 May 2024 00:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388604; cv=none; b=iMteobUHBdZ737vxK9+7q+LBZev0uE/Lf+hKV6JTXtEHkbIR1FJfeB7t/8CzugvNbX2cbZzgg6ozyFdEJ/aaipvXM0wnlLL92/JEvg0C2aaIQ0QF8OsHcNSBqF6XTTPbxPZHjHD/S8xGqWCf0BSq45gpD6Nx2TcCVM7hyHDQpfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388604; c=relaxed/simple; bh=h8IEiY34+3Sx3CIFgaB3bbWMmMeu0qPkNGGmC8siC3M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NOtI50kvBcTC8yHvjsS4ScIf/5S6BnSpUEgQR4LgBV1P3y6KTus20I2RGib4kmcjusWKMFB6itobYUO8/f1SJTrSPy/5v+uNtgEZAcrsCbDOdz2kEzlW1CU32EFRAB5E2+Yl3zmeysUl71rVJC/C0IHzdEqLxUNwtHH+RKWydTM= 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=I348MkFP; arc=none smtp.client-ip=209.85.161.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="I348MkFP" Received: by mail-oo1-f50.google.com with SMTP id 006d021491bc7-5b2735f217aso1271323eaf.2 for ; Fri, 10 May 2024 17:50:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388600; x=1715993400; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=E9avosEdgbBSX3dha6GG6j80VLMTNNyJjLCB0lyPzg0=; b=I348MkFPYgz4UGsp8pm08TTEs8rDAJdCzNDAolDrrHfWIlgJVdh/HqE5Th2DR/XD56 yOz9sTIbVefJpSwAh+cNmAWCtPcKrinC7lMUFFTk97BJBs8GMaeLNv1vpshthz+g0GjL pbDNc0KC3COxrqUq4qyevIya45msb8rjpDVxCZBtGLAxyAaJyVtWBcm2jiNfkvX3c2oF yV+w6cEOUoLNPnbynSeKOz6XOtHE30Sg0QV7WrwTnZZH9CeZyq0V2ut9VFYzpLlDE2y7 XYFpjlT6x2FZ6nL5nOPzDArQX4zzeWir3LwS9cH2zRw5BhFIBLdJyaeWRpoqguIOyg5j Ys4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388600; x=1715993400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=E9avosEdgbBSX3dha6GG6j80VLMTNNyJjLCB0lyPzg0=; b=oanKY3PIQ8afe63JVnvaYsi3fGLttNE4IU375/Mzq5mH/zEKdOJo6fl95OlIPHGU5H RsJJwYIpdIn96ChgPhGj75oo6Z7Bt4T2un7c/Qu7JFC8vwRgaaGBIX8rop5m/IjJfCO0 XWjydhDsZ9VWnvrnmLRTp4xkeEX3KM8FAYQPjou/iHAIEF9++yv6pbGDpjG5427i+wS4 z8nm8h1SiKAUbQ6AO6BvY5Q4xgK1Rm/T5+18j/ZUkHbIUmXnA3Ox+u5D/pbOnPnpViYU yLmoPP0C066jylw7q4W0EaD/zo91zDgowqQlPWhry6FF/WCBMJq+4pZ03/8lZ9Crufqx a4uQ== X-Forwarded-Encrypted: i=1; AJvYcCVmFkaC1EVeCzml8VbmOHDyACduMRuULafGxasEbFgFlVHuimcYqBM+P+hF5SPWs0y/I8ZN6hr6f+t6bkfkIQVEDCMON/TCeGOc X-Gm-Message-State: AOJu0Yzwmu9r+JlGs9U/LafI2vayCEcCwFqRtgJUxi6SR6wSObSNsDSZ 8JyhTzVzAlp0NNnfwiugfOiXKE+apjAxDXurOno9LkTITEJG5K1nsWyFf+mDrWs= X-Google-Smtp-Source: AGHT+IHUqtShftifs93lP5ZXYqlRl7bulmdlCopbK5h5izie+OAx3wEuV9iUi7VdLK8osidQhFAkdw== X-Received: by 2002:a4a:904:0:b0:5b2:bc0:f38b with SMTP id 006d021491bc7-5b281956dc0mr4721017eaf.5.1715388600118; Fri, 10 May 2024 17:50:00 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.49.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:49:59 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 4/8] spi: add offload xfer flags Date: Fri, 10 May 2024 19:44:27 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-4-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 Most configuration of SPI offloads is handles opaquely using the ID handle that is passed to the various offload functions. However, there are some offload features that need to be controller on a per transfer basis. This patch adds a flags field to the spi_transfer structure 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 controller struct for controllers to indicate which flags are supported. This allows for generic checking of offload capabilities during __spi_validate() so that each controller doesn't have to provide their own validation. Signed-off-by: David Lechner --- 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.c | 10 ++++++++++ include/linux/spi/spi.h | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 9ad7b04c26a6..4d34ccf91fd4 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -4189,6 +4189,16 @@ 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 & ctlr->offload_xfer_flags) + != xfer->offload_flags) + return -EINVAL; + } } message->status = -EINPROGRESS; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index ec8d875d31ff..42c39c17ba5a 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -501,6 +501,8 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * This field is optional and should only be implemented if the * controller has native support for memory like operations. * @mem_caps: controller capabilities for the handling of memory operations. + * @offload_xfer_flags: flags supported by this controller for offloading + * transfers. See struct spi_transfer for the list of flags. * @offload_ops: operations for controllers with offload support. * @unprepare_message: undo any work done by prepare_message(). * @slave_abort: abort the ongoing transfer request on an SPI slave controller @@ -751,6 +753,7 @@ struct spi_controller { const struct spi_controller_mem_caps *mem_caps; /* Operations for controllers with offload support. */ + unsigned int offload_xfer_flags; const struct spi_controller_offload_ops *offload_ops; /* GPIO chip select */ @@ -991,6 +994,7 @@ struct spi_res { * @transfer_list: transfers are sequenced through @spi_message.transfers * @tx_sg: Scatterlist for transmit, currently not for client use * @rx_sg: Scatterlist for receive, currently not for client use + * @offload_flags: flags for xfers that use special hardware offload features * @ptp_sts_word_pre: The word (subject to bits_per_word semantics) offset * within @tx_buf for which the SPI device is requesting that the time * snapshot for this transfer begins. Upon completing the SPI transfer, @@ -1107,6 +1111,12 @@ struct spi_transfer { u32 effective_speed_hz; + unsigned int offload_flags; +/* 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) + unsigned int ptp_sts_word_pre; unsigned int ptp_sts_word_post; From patchwork Sat May 11 00:44:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796856 Received: from mail-ot1-f47.google.com (mail-ot1-f47.google.com [209.85.210.47]) (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 04A4E23AD for ; Sat, 11 May 2024 00:50:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388603; cv=none; b=to97xE8EEG7rk7e1lFJ4H2oaGBpAzUNiR2grDaVptukI14c7DsJJAAGoUtSbGdi4cLGU9nqH/iXjlNRaZXW/pdAEMa2pdcUEmyPn0jKHpSqpoe3ws1/hWBOFgzG1DFGWtCE8rnrhRigcPj1JTzjTJWO2VbLB3LIpZ2ZimdaWpnk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388603; c=relaxed/simple; bh=7uQzDb4mHzMFAAji6LQjuiHftGdIMfQwB9bGqhKl+nI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J3mFZnJj7vAD46NbG34I9KhOgTG5QSnMA5mA9YpmMzdJIs+cjh8/IhRiszeV67Q6pQBrT8Cvv46zXQDN5XjimQJLdolXyT4ae4wcMlIUfczoDjyT+ims06tiQ9QaFFrccWKfxLvkxQckmks6dYep9BIVfvcL5BD2LPz32YeFNCY= 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=bNd6Zxbz; arc=none smtp.client-ip=209.85.210.47 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="bNd6Zxbz" Received: by mail-ot1-f47.google.com with SMTP id 46e09a7af769-6f0f07746a4so595309a34.2 for ; Fri, 10 May 2024 17:50:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388601; x=1715993401; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=S0IqckUIZjVVxXVOxgac6w2cx3AmMbKz+eZNoT7XiC4=; b=bNd6ZxbzPbrbmMb4qJJayI2a4grnnbOaKAH2gCGjL1pXoNQBwuoAavz9txl4fEj7SI ZPlGrry1vS1sZgPdOYOU42F9Yzg5axlUcgFxpSojzHnM2z2EDEMWev2scImSJT5C5fWn Mz6XoupaAQFkxZBUl7pHqoctVwCdUip23ui5WXkv1BYNFS2gqa99pvqIKCoEBqIfyI8e n915D+W51EGCSZ7n/9dR/Rh/b8WNa+JCRheQcJN62yRwLO77IyxBOxYJ0bKcwVXazKfI 6J6FxQLvdWpvqKWO3wyiwUT7O+iYpY3GchxLgPCzEXLS7bWKa7LM9s/WzxqthKLf9C+j mJog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388601; x=1715993401; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S0IqckUIZjVVxXVOxgac6w2cx3AmMbKz+eZNoT7XiC4=; b=MrZpaSbPGmxtKH/L6Qd7qs1T5bxEqqtdP4+Zvd3oftLGEY/muvcqb+GB+7KbLvvKVI P65qVCNnizzuo5qtSYWpJGhFEnDoebHl4e/v8PN8qT+SYjoixLXA/l9REDK3he8lF+7O dxbN/a3z7AytjfRmqjOtIwyFa3j80XfdnmqdEw6oxcJ+6M1OMVqRdjiZ6K7U9aksM2FS 9bEv41Y7553NtLYhPqnZMoC5P8AUPaTN2e11Y/8FfmMRXwAbqVmrCyCalmHA0h1Zz1LB oxl2wtVzMqJJ1Sydh0NE8iOd/0+HwC39buqo/UkXF1EHOagi8Xjl0w68gp1crSB1Mez2 O1qQ== X-Forwarded-Encrypted: i=1; AJvYcCVFgVz2WWL9fPXmROjo1cOr8vdZkZns47HMGrPMeg4idKFBtXHzxI6KmHhUoqfsOdyXJ5/L/z+fDT+NyJOk6jA2spuhWHf+ru9j X-Gm-Message-State: AOJu0Yy74pntB7+/JUiq360DcN7/d9gwITOApqoFH5u6TUmxKWbLHVg4 z9lfJZ/oUm4/rncQr6CEpTGtX+BCryH2VTNgWoMyqQ0oQcX0d4n8YQU9lxyNMgQ= X-Google-Smtp-Source: AGHT+IGUPIA9haCNiqxSQz+aWDhBBucJuDctWs45cFqSghUH6sJTwdF42Ovi6gpJML0oFTLvmhlgmA== X-Received: by 2002:a05:6830:205a:b0:6f0:6da5:34f9 with SMTP id 46e09a7af769-6f0e92c8b92mr4444723a34.23.1715388601088; Fri, 10 May 2024 17:50:01 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.50.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:50:00 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 5/8] spi: dt-bindings: axi-spi-engine: document spi-offloads Date: Fri, 10 May 2024 19:44:28 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-5-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 The AXI SPI Engine has support for hardware offloading capabilities. There can be up to 32 offload instances per SPI controller, so the bindings limit the value accordingly. Signed-off-by: David Lechner --- v2 changes: This is basically a new patch. It partially replaces "dt-bindings: iio: offload: add binding for PWM/DMA triggered buffer". The controller no longer has an offloads object node and the spi-offloads property is now a standard SPI peripheral property. --- .../devicetree/bindings/spi/adi,axi-spi-engine.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml index d48faa42d025..c0668aab8b2a 100644 --- a/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml +++ b/Documentation/devicetree/bindings/spi/adi,axi-spi-engine.yaml @@ -41,6 +41,20 @@ properties: - const: s_axi_aclk - const: spi_clk +patternProperties: + "^.*@[0-9a-f]+$": + type: object + $ref: spi-peripheral-props.yaml + additionalProperties: true + properties: + spi-offloads: + description: + An array of 1 or more offload instance numbers assigned to this + peripheral. + items: + minimum: 0 + maximum: 31 + required: - compatible - reg From patchwork Sat May 11 00:44:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796369 Received: from mail-oi1-f180.google.com (mail-oi1-f180.google.com [209.85.167.180]) (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 0F84C17991 for ; Sat, 11 May 2024 00:50:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388606; cv=none; b=QlgxnRBupySE2V1XLAdFwaO0pB12oIhpf/VL8a+XI2XRn6Hr1LZBhM/eCjIr74/85nxRm5PmrEQUynOi4Z/Up+uxZRAaSMHsJrcqTZ52Sugy3nrXdn844HTGK10+ZCS8ESWJnSS0f8nGchvqc/Sp2pKyBUDBfQpX2ygNJuNmhtk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388606; c=relaxed/simple; bh=jbDclhJ4Ltz6ZIxwFk59d4Jg2Ugn8KcUJw9iSCDHoOw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Wx8Mannxu1N3PT/J7aOuHzg8d2MCJ1PQjYZO/wFYyu27ovLaaY72HA5rRVn7+XFMzxXcXpE0/MWoQkRTLgd4GJ33snodKTFrtSZBosx82XBskyE7Sc5oMJFPYUaWlZK/BSmzlpddVslAPmwquttrlSrxbmcn6cHfvbkdtuEzCe8= 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=G/vOyQCS; arc=none smtp.client-ip=209.85.167.180 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="G/vOyQCS" Received: by mail-oi1-f180.google.com with SMTP id 5614622812f47-3c998aed0e0so525634b6e.0 for ; Fri, 10 May 2024 17:50:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388602; x=1715993402; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=M4udCyI6Qf35BCwIyLv7+9qZLaDg57Ov9S/WGjBd7b4=; b=G/vOyQCSJmalYI8BtwMcqgeCoKL/bFvAowtdzpJz1PJru6f3eTCJKlGsTmLYlC/qbF A49c9RGczMPY+6xvWzpOL+DQmIc2x68NB0DSWitlWKYQJdVHyXb87b0E6NGaitCH7KCh qoaBrCA23sF6Jc4UFYGcwn7vkJj38yTYg9i9nbtapkIa1dWiSWJRNEfdAa9c5DIgL3NL REXf5y2PIj6RU9Xa3sE9ksC43BVkCQXZKW7HpjngZoRlwD0KczsSzK3qvwMZEVIlYYqC bUIfPV6t9w/PpJcPXY8HO/nUJUHkAu+SwxwpKVEvvaEMhNLlnZDQoJ7KALVwA+MT2KWH GYXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388602; x=1715993402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=M4udCyI6Qf35BCwIyLv7+9qZLaDg57Ov9S/WGjBd7b4=; b=HQ12F7YWlA1CA23Hz4V8qjMe2OuPkb4ILRYhrHQz0ReoVu+FyQzIwon1NWCTdb4j+l /4+LDrcpYBHhyyolNnauNk0piMZLwcvoF4aWAF/U33GjSzj1uD3pmcvGvKjZot3HUABZ pJ/x9/Fa484MmG8QjrFwsrgYahuBjKXERKDpbJHYF6JJDKPnn8iBAMaauZuYAI4LhL7o mUbJDeK1b8f3lVSOntaAFtOhdvyH7EjMeCWUUONAVEeB1q89mQl14EYGLzs0HOZ9DH9B aCfJw7bEN22Hw+e7WWZxuz51HZYeFakAeU/uNdVLC8in17RmMjt1K5iufAV0JXWjfClu b73g== X-Forwarded-Encrypted: i=1; AJvYcCXJWYUM6SMp7aeQXqQfPk3Tvf8yMZm5MXBvoeGxSlSkxzKIGEZNhD8AlRZBG4vnE9nf80X5i2aL1b3jW5gS2tNR/5oDw/GktAJA X-Gm-Message-State: AOJu0Yzhp3DiMVoF12S0f0ZLlS09QerzfrqpHXxL4w3y4XRlHGgywa/p /gBp9KO6J8jPv1cguYozxbEjwsjuHX45yKZsMbOFKG8xqkGG9Wp3EWI0c5BCJEw= X-Google-Smtp-Source: AGHT+IGjahhfc8kV980Ug9+SQb7W2MTT4ztWS460Tcv/qBM3UEkIaIx+68c/zVIPIHDpTlI0koIHpg== X-Received: by 2002:a05:6808:180a:b0:3c7:4613:9913 with SMTP id 5614622812f47-3c98d906880mr3409340b6e.10.1715388602094; Fri, 10 May 2024 17:50:02 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.50.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:50:01 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 6/8] spi: axi-spi-engine: add offload support Date: Fri, 10 May 2024 19:44:29 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-6-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 This implements 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. Signed-off-by: David Lechner --- v2 changes: This patch has been reworked to accommodate the changes described in all of the other patches. --- drivers/spi/spi-axi-spi-engine.c | 267 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index e358ac5b4509..95327df572a0 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -2,6 +2,7 @@ /* * SPI-Engine SPI controller driver * Copyright 2015 Analog Devices Inc. + * Copyright 2024 BayLibre, SAS * Author: Lars-Peter Clausen */ @@ -16,6 +17,7 @@ #include #include +#define SPI_ENGINE_REG_OFFLOAD_MEM_ADDR_WIDTH 0x10 #define SPI_ENGINE_REG_RESET 0x40 #define SPI_ENGINE_REG_INT_ENABLE 0x80 @@ -23,6 +25,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 @@ -33,10 +36,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) @@ -74,6 +91,10 @@ #define SPI_ENGINE_CMD_SYNC(id) \ SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SYNC, (id)) +/* 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); @@ -101,6 +122,12 @@ struct spi_engine_message_state { uint8_t *rx_buf; }; +struct spi_engine_offload { + struct spi_device *spi; + unsigned int id; + bool prepared; +}; + struct spi_engine { struct clk *clk; struct clk *ref_clk; @@ -111,6 +138,10 @@ struct spi_engine { struct spi_engine_message_state msg_state; struct completion msg_complete; unsigned int int_enable; + + unsigned int offload_ctrl_mem_size; + unsigned int offload_sdo_mem_size; + struct spi_engine_offload offload_priv[SPI_ENGINE_MAX_NUM_OFFLOADS]; }; static void spi_engine_program_add_cmd(struct spi_engine_program *p, @@ -154,7 +185,7 @@ static void spi_engine_gen_xfer(struct spi_engine_program *p, bool dry, if (xfer->tx_buf) 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, @@ -202,16 +233,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, @@ -503,8 +542,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid) 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); @@ -539,6 +581,11 @@ 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"); + return -EOPNOTSUPP; + } + /* reinitialize message state for this transfer */ memset(st, 0, sizeof(*st)); st->cmd_buf = p->instructions; @@ -579,6 +626,204 @@ static int spi_engine_transfer_one_message(struct spi_controller *host, return msg->status; } +static struct spi_engine_offload *spi_engine_get_offload(struct spi_device *spi, + unsigned int id, + unsigned int *offload_num) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + int i; + + for (i = 0; i < SPI_ENGINE_MAX_NUM_OFFLOADS; i++) { + priv = &spi_engine->offload_priv[i]; + + if (priv->spi == spi && priv->id == id) { + *offload_num = i; + return priv; + } + } + + return ERR_PTR(-ENODEV); +} + +static int spi_engine_offload_map_channel(struct spi_device *spi, + unsigned int id, + unsigned int channel) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + + if (channel >= SPI_ENGINE_MAX_NUM_OFFLOADS) + return -EINVAL; + + priv = &spi_engine->offload_priv[channel]; + + if (priv->spi) + return -EBUSY; + + priv->spi = spi; + priv->id = id; + + return 0; +} + +static int spi_engine_offload_prepare(struct spi_device *spi, unsigned int id, + struct spi_message *msg) +{ + struct spi_controller *host = 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; + struct spi_transfer *xfer; + void __iomem *cmd_addr; + void __iomem *sdo_addr; + size_t tx_word_count = 0; + unsigned int offload_num, i; + + priv = spi_engine_get_offload(spi, id, &offload_num); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + if (priv->prepared) + return -EBUSY; + + 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) { + 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_sdo_mem_size) + return -EINVAL; + + cmd_addr = spi_engine->base + SPI_ENGINE_REG_OFFLOAD_CMD_FIFO(priv->id); + sdo_addr = spi_engine->base + SPI_ENGINE_REG_OFFLOAD_SDO_FIFO(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); + + msg->offload_state = (void *)(intptr_t)offload_num; + priv->prepared = true; + + return 0; +} + +static void spi_engine_offload_unprepare(struct spi_device *spi, unsigned int id) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + unsigned int offload_num; + + priv = spi_engine_get_offload(spi, id, &offload_num); + if (IS_ERR(priv)) { + dev_warn(&spi->dev, "failed match offload in unprepare\n"); + return; + } + + writel_relaxed(1, spi_engine->base + SPI_ENGINE_REG_OFFLOAD_RESET(offload_num)); + writel_relaxed(0, spi_engine->base + SPI_ENGINE_REG_OFFLOAD_RESET(offload_num)); + + priv->prepared = false; +} + +static int spi_engine_offload_enable(struct spi_device *spi, unsigned int id) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + unsigned int offload_num, reg; + + priv = spi_engine_get_offload(spi, id, &offload_num); + if (IS_ERR(priv)) + return PTR_ERR(priv); + + reg = readl_relaxed(spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(offload_num)); + reg |= SPI_ENGINE_OFFLOAD_CTRL_ENABLE; + writel_relaxed(reg, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(offload_num)); + + return 0; +} + +static void spi_engine_offload_disable(struct spi_device *spi, unsigned int id) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + struct spi_engine_offload *priv; + unsigned int offload_num, reg; + + priv = spi_engine_get_offload(spi, id, &offload_num); + if (IS_ERR(priv)) { + dev_warn(&spi->dev, "failed match offload in disable\n"); + return; + } + + reg = readl_relaxed(spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(offload_num)); + reg &= ~SPI_ENGINE_OFFLOAD_CTRL_ENABLE; + writel_relaxed(reg, spi_engine->base + + SPI_ENGINE_REG_OFFLOAD_CTRL(offload_num)); +} + +static const struct spi_controller_offload_ops spi_engine_offload_ops = { + .map_channel = spi_engine_offload_map_channel, + .prepare = spi_engine_offload_prepare, + .unprepare = spi_engine_offload_unprepare, + .hw_trigger_enable = spi_engine_offload_enable, + .hw_trigger_disable = spi_engine_offload_disable, +}; + +static void spi_engine_cleanup(struct spi_device *spi) +{ + struct spi_controller *host = spi->controller; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + int i; + + /* remove spi device to offload mapping */ + for (i = 0; i < SPI_ENGINE_MAX_NUM_OFFLOADS; i++) { + struct spi_engine_offload *priv = &spi_engine->offload_priv[i]; + + if (priv->spi == spi) + priv->spi = NULL; + } +} + static void spi_engine_release_hw(void *p) { struct spi_engine *spi_engine = p; @@ -630,6 +875,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); @@ -652,6 +910,9 @@ static int spi_engine_probe(struct platform_device *pdev) host->optimize_message = spi_engine_optimize_message; host->unoptimize_message = spi_engine_unoptimize_message; host->num_chipselect = 8; + host->offload_xfer_flags = SPI_OFFLOAD_XFER_RX_STREAM; + host->offload_ops = &spi_engine_offload_ops; + host->cleanup = spi_engine_cleanup; if (host->max_speed_hz == 0) return dev_err_probe(&pdev->dev, -EINVAL, "spi_clk rate is 0"); From patchwork Sat May 11 00:44:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796855 Received: from mail-oo1-f49.google.com (mail-oo1-f49.google.com [209.85.161.49]) (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 E2DCB18AED for ; Sat, 11 May 2024 00:50:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388606; cv=none; b=jdxgormffz8sfI1/T+kNr5hlgL/Tj6gbcMf/+Qe/0EWVh1qbvETgOUdk3lrCGxGjco4bt8JYPx1qEP4o+tH4XHXMMPJ/CaoK7W8R4ToCa1fZk2T4gTFC1Tg/Gy/tVP9AxURuN1zsh6zfYkP2l/gGO7tRmO027f7hbC2ibiDNnnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388606; c=relaxed/simple; bh=dPMCl0g+OO+JoGM1rnoH86D9s8fsanSB5CULbbdJ0oA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CYrL6NnVyqX7o7iG+sdlpQHVK7K5/isGjhJMw0ySX4rUjfBmT7n8auUUGeGCV/TW1xTCXDslDtaYtsUsxkKiW8Pn16dgIgcKBkZaBUm32KvGV+OAveF/VqhwQ2Ic1KPw2WPLcMRZm1qCE3ie2+BcbIKhNLk7IcqW8/G5TIPpo0c= 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=H86emGCm; arc=none smtp.client-ip=209.85.161.49 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="H86emGCm" Received: by mail-oo1-f49.google.com with SMTP id 006d021491bc7-5b27e8ad4b6so932214eaf.0 for ; Fri, 10 May 2024 17:50:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388603; x=1715993403; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9o3IyLXYhcDBezTLcNXXyCLcD/u+BjxsxpQAYgTMy0o=; b=H86emGCm+gWk+vQN9C9xcomRFJ0ZxxVPtf9ODNfMRiC6nv4h9T6ZQeQicY5+sgPAHd ekOKAluiLPefEyoOQJ8hqMaouvn7X31rwNngQs7DdMfCVp+icV702OS+4WVzI9QUDI1M RR83U6okmaxT6WCfVTq/Qtg2eO7MJRbehgGud4tJlNIz4mPivpiLB4EMlS7T54qzB4Mm aSgpYdJTtN0gyrDVjXZo+F6dvzhJ3PYBcvoNi8+WnpxNoe4WDscA9hs9YvrdpF8J/Zrf Qgtxk4pt6EMXQwpQ7CZX2vRPv5QQZtzlOBGKH7Ojti4BpfCyt9SjW29z8IbinepoL/FT oPlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388603; x=1715993403; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9o3IyLXYhcDBezTLcNXXyCLcD/u+BjxsxpQAYgTMy0o=; b=KURf4t0mFyFJUe/O16JRAZRwY6pDE/XnAQM51dj3C5NQKvN8TrEH0MKNObmDFzYy2A FUq/NAQ8zZDQl0Vd6Gr771dQ8RaaeR+N56nEcFAppylsKqvIhmna1sGY+unTRtGoyWjE aBtQXYTD9IqGzk7BzYXzzSOv630/aPC+KGXj0RB2lR3NspM0+96aHuw+IU5zp7m7G9rF V3emtZUUWNPhY7e3VrPcVztQZYshl9sf5Sj6Z7fFlY3PtnDV7YjS8v5/Tv67A7SK7LK+ TWn02yRMmaAnIu/3AJzCfdCC9NWMuw/EKtHsOfeQ/08DOObciWN+QgQkS4Q4aRjosuhg RM4A== X-Forwarded-Encrypted: i=1; AJvYcCUB+g5QwIOXnoHnGJIAQaTtp8wt2s+piUy9+f/9DA6xS5y2mmEaQHM43s5oHHfgzOTsXlFjLOtksOpB//mgP7RumGnkqYvwHARk X-Gm-Message-State: AOJu0YxLkLLGX1r4LVA+QVEN5pL4UoOUZWqWhuUja7ruJUc8bRT+suIA KQcsAIJyG66zDgrL2P2PQupj0cbwnUxzr15LNdXHMKBA+bhjCuNDzf5/fF1aYKc= X-Google-Smtp-Source: AGHT+IH/UxnNyIem5xjkj+EmfpQmh+3GYvOohKxeg+FekmzNUiGiPzf/c+XGTZipmBuXlKWHUJY7Nw== X-Received: by 2002:a4a:4881:0:b0:5b2:ef4:873d with SMTP id 006d021491bc7-5b28196c378mr4259504eaf.4.1715388603082; Fri, 10 May 2024 17:50:03 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.50.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:50:02 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 7/8] dt-bindings: iio: adc: adi, ad7944: add SPI offload properties Date: Fri, 10 May 2024 19:44:30 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-7-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 To enable capturing data at high rates, the AD7944 is frequently used with the AXI SPI Engine IP core. This patch adds the properties needed to describe the SPI offload configuration in the device tree. The clock trigger and DMA buffer for rx data are external to the SPI controller and specific to the application so the are included in the peripheral bindings. Signed-off-by: David Lechner --- v2 changes: This is a new patch that partially replaces "dt-bindings: iio: offload: add binding for PWM/DMA triggered buffer". In the previous review, it was suggested that having a separate binding and object node for the offload was overcomplicated. So instead this opts to use the proposed standard spi-offloads property as a flag to allow the SPI periperhal node require additional properties that are resources that are physically connected to the SPI offload. On a whim, I also changed pwms to clocks in the binding. The thinking being that we only care about the frequency (it determines the sample rate) so a clock made more sense and might allow more flexibility in the future. But since the actual hardware we have is a PWM, we would have to use "pwm-clock" in the devicetree to make the PWM act as a clock. But it turns out that the pwm-clock driver does not support setting the frequency, so we would have to do more work to actually be able to use this binding in practice. --- .../devicetree/bindings/iio/adc/adi,ad7944.yaml | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7944.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7944.yaml index d17d184842d3..5ea12aac9d25 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7944.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7944.yaml @@ -129,6 +129,25 @@ properties: line goes high while the SDI and CNV lines are high (chain mode), maxItems: 1 + # optional SPI offload support for use with AXI SPI Engine + + spi-offloads: + maxItems: 1 + + dmas: + maxItems: 1 + description: RX DMA Channel for receiving a samples from the SPI offload. + + dma-names: + const: rx + + clocks: + maxItems: 1 + description: Clock to trigger the SPI offload for reading a sample. + + clock-names: + const: trigger + required: - compatible - reg @@ -190,6 +209,23 @@ allOf: properties: turbo-gpios: false + # certain properties are for SPI offload use only + - if: + required: + - spi-offloads + then: + required: + - dmas + - dma-names + - clocks + - clock-names + else: + properties: + dmas: false + dma-names: false + clocks: false + clock-names: false + unevaluatedProperties: false examples: @@ -211,3 +247,25 @@ examples: turbo-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; }; }; + - | + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + adc@0 { + compatible = "adi,ad7944"; + reg = <0>; + spi-cpha; + spi-max-frequency = <111111111>; + adi,spi-mode = "single"; + avdd-supply = <&supply_2_5V>; + dvdd-supply = <&supply_2_5V>; + vio-supply = <&supply_1_8V>; + bvdd-supply = <&supply_5V>; + spi-offloads = <0>; + dmas = <&dma 0>; + dma-names = "rx"; + clocks = <&trigger_clk>; + clock-names = "trigger"; + }; + }; From patchwork Sat May 11 00:44:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 796854 Received: from mail-oo1-f46.google.com (mail-oo1-f46.google.com [209.85.161.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 0D3E91BC41 for ; Sat, 11 May 2024 00:50:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388607; cv=none; b=I8838Y0xbOmeYeGy8W0myO9LyGKPVKdbhIbUyCJwjFW2Rj3KSxdR7kYKqUcRc0WLOUA2LAH4pJnsVORMsSSiqKVTCdT4jMsBJMr3bMPhtfL6tdhHqJKGEizM7hxVu+9qQC4bb7xeZ+9LbYBsy7Rs0ojjbXlmgHIp5IiX7jpcze8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715388607; c=relaxed/simple; bh=qfovg8GPkCrYv+M58MvC1AwOylMJYvN79Ny2UrHzdtM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lbuCdC/oO3+8EWsBT4k22YVsquuuaUMKKIQxMhVsHE17c/oesyiDmreJOHcIgEKdQEICh12DIx1+L4TjNxg80WeE8ETmiBbbeXUSsL7RUd0Wlvfdc3VGkGomHZbcsgHCe/xpp5IuDDnvLaTwTOzqEzVDIeit/k//Fi4CvMoW1c8= 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=JXcOWyD8; arc=none smtp.client-ip=209.85.161.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="JXcOWyD8" Received: by mail-oo1-f46.google.com with SMTP id 006d021491bc7-5aa1bf6cb40so1774234eaf.1 for ; Fri, 10 May 2024 17:50:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1715388604; x=1715993404; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Sef0yxj3M0McfXOWyYuZh5QNVIS4E8ybwIxSMPcOtQk=; b=JXcOWyD8VBvKnYW77q19opIK1vz4yClDsHyCvB/utsUPEdO5Mr3R39PJR0/oEAbYcl kRviy2Kc2QENOgs/R/0n8vfpVSKhaazqNdkght3zIY+CDWkj99Mj1NNanFdfDdHAPqVC FX4K8EJPdTWfYltaAHNSPWg4LysuT7tfgPNhhlv+6MhHXSn199YjNx0wkqmTD1nUOqdv o7xXLsZJXsMqrWd4Fia5EPtoMEtxhptNowK7IofVxdaAIuMzZLEOzAw6aLkzs2pz8Sq5 KApBEZVm6pufbasNL/la4BRiH6YW9OQsKeYQYvpLtt8GGMqaGm8VXFZUd6pg22pMJViR fQ6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715388604; x=1715993404; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Sef0yxj3M0McfXOWyYuZh5QNVIS4E8ybwIxSMPcOtQk=; b=coF3+ycDz/GATUuL9wpbRnUZhlQCY2TjPwO4fFeij9IlZMtQHIUmQ8bKiAtgGyQ6HS 1qgFrCgcbgvNOuSq4ROSZLkMy9IHFv/VcdV+xV4PEmASAf1E1/crlVitMIrFpiNTm+EW BrBi52Jnx96vN/GEaYd3w/7sYjCAVmSP365wcPHHtfkmXRT0y04kuatxMefcTdPngk57 iTpsNoa1kDM5seWlsrZ8ip69dPt0ZzOtXfLZUsur2gIXaRUk2IblguusT+YId+pU35UB d+ihM1ou/RSwOgYtCmII1BJyqXOnwUubiziS/feve7D+Nmy+2jfCF46psZB4QzICCryc tFRg== X-Forwarded-Encrypted: i=1; AJvYcCX3RrMi/dO8n+iktGYpEvop4xQniLMjN0sPtv9REJ8Avx2/0sGAL3U5Fbyas26BL5lkc/D5CWs43URPVMeTtIDTEJLn+UmTWVZb X-Gm-Message-State: AOJu0YwsBdj8B7EU+DxdsvjqMzSNzMDgf87ePqK3mLElKxLd5TL1JyH6 puRG6/TtH/IV7bnYGQ30/C6al0qLDo+vMYvZAoYEQX4t0AFI8Whq+TTs8zaxgio= X-Google-Smtp-Source: AGHT+IFISSd56LKo6PC65Rb6v16dDvY0nToNpJBuoPHdhJJv2V9+3eeHEwn6BehsohvwaWKdMXJowQ== X-Received: by 2002:a4a:8c21:0:b0:5b1:b8a4:bce4 with SMTP id 006d021491bc7-5b281a1b6a7mr4188517eaf.8.1715388604085; Fri, 10 May 2024 17:50:04 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b29015a3dbsm321132eaf.46.2024.05.10.17.50.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 May 2024 17:50:03 -0700 (PDT) From: David Lechner To: Mark Brown , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , =?utf-8?q?Nuno_S=C3=A1?= Cc: David Lechner , 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 Subject: [PATCH RFC v2 8/8] iio: adc: ad7944: add support for SPI offload Date: Fri, 10 May 2024 19:44:31 -0500 Message-ID: <20240510-dlech-mainline-spi-engine-offload-2-v2-8-8707a870c435@baylibre.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> References: <20240510-dlech-mainline-spi-engine-offload-2-v2-0-8707a870c435@baylibre.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Mailer: b4 0.12.4 This adds support for SPI offload to the ad7944 driver. This allows reading data at the max sample rate of 2.5 MSPS. Signed-off-by: David Lechner --- 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. RFC: This isn't very polished yet, just FYI. A few things to sort out: Rather than making the buffer either triggered buffer or hardware buffer, I'm considering allowing both, e.g. buffer0 will always be the triggered buffer and buffer1 will will be the hardware buffer if connected to a SPI controller with offload support, otherwise buffer1 is absent. But since multiple buffers haven't been used much so far, more investigation is needed to see how that would work in practice. If we do that though, then we would always have the sampling_frequency attribute though even though it only applies to one buffer. --- drivers/iio/adc/ad7944.c | 147 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 111 insertions(+), 36 deletions(-) diff --git a/drivers/iio/adc/ad7944.c b/drivers/iio/adc/ad7944.c index 4602ab5ed2a6..6724d6c92778 100644 --- a/drivers/iio/adc/ad7944.c +++ b/drivers/iio/adc/ad7944.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -65,6 +67,8 @@ struct ad7944_adc { bool always_turbo; /* Reference voltage (millivolts). */ unsigned int ref_mv; + /* Clock that triggers SPI offload. */ + struct clk *trigger_clk; /* * DMA (thus cache coherency maintenance) requires the @@ -123,6 +127,7 @@ static const struct ad7944_chip_info _name##_chip_info = { \ .scan_type.endianness = IIO_CPU, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ }, \ IIO_CHAN_SOFT_TIMESTAMP(1), \ }, \ @@ -134,18 +139,12 @@ AD7944_DEFINE_CHIP_INFO(ad7985, ad7944, 16, 0); /* fully differential */ AD7944_DEFINE_CHIP_INFO(ad7986, ad7986, 18, 1); -static void ad7944_unoptimize_msg(void *msg) -{ - spi_unoptimize_message(msg); -} - -static int ad7944_3wire_cs_mode_init_msg(struct device *dev, struct ad7944_adc *adc, - const struct iio_chan_spec *chan) +static void ad7944_3wire_cs_mode_init_msg(struct device *dev, struct ad7944_adc *adc, + const struct iio_chan_spec *chan) { unsigned int t_conv_ns = adc->always_turbo ? adc->timing_spec->turbo_conv_ns : adc->timing_spec->conv_ns; struct spi_transfer *xfers = adc->xfers; - int ret; /* * NB: can get better performance from some SPI controllers if we use @@ -174,21 +173,14 @@ static int ad7944_3wire_cs_mode_init_msg(struct device *dev, struct ad7944_adc * xfers[2].bits_per_word = chan->scan_type.realbits; spi_message_init_with_transfers(&adc->msg, xfers, 3); - - ret = spi_optimize_message(adc->spi, &adc->msg); - if (ret) - return ret; - - return devm_add_action_or_reset(dev, ad7944_unoptimize_msg, &adc->msg); } -static int ad7944_4wire_mode_init_msg(struct device *dev, struct ad7944_adc *adc, - const struct iio_chan_spec *chan) +static void ad7944_4wire_mode_init_msg(struct device *dev, struct ad7944_adc *adc, + const struct iio_chan_spec *chan) { unsigned int t_conv_ns = adc->always_turbo ? adc->timing_spec->turbo_conv_ns : adc->timing_spec->conv_ns; struct spi_transfer *xfers = adc->xfers; - int ret; /* * NB: can get better performance from some SPI controllers if we use @@ -208,12 +200,6 @@ static int ad7944_4wire_mode_init_msg(struct device *dev, struct ad7944_adc *adc xfers[1].bits_per_word = chan->scan_type.realbits; spi_message_init_with_transfers(&adc->msg, xfers, 2); - - ret = spi_optimize_message(adc->spi, &adc->msg); - if (ret) - return ret; - - return devm_add_action_or_reset(dev, ad7944_unoptimize_msg, &adc->msg); } static int ad7944_chain_mode_init_msg(struct device *dev, struct ad7944_adc *adc, @@ -345,6 +331,30 @@ static int ad7944_read_raw(struct iio_dev *indio_dev, return -EINVAL; } + case IIO_CHAN_INFO_SAMP_FREQ: + if (!adc->trigger_clk) + return -EOPNOTSUPP; + + *val = clk_get_rate(adc->trigger_clk); + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +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 (!adc->trigger_clk) + return -EOPNOTSUPP; + + return clk_set_rate(adc->trigger_clk, val); default: return -EINVAL; } @@ -352,6 +362,28 @@ static int ad7944_read_raw(struct iio_dev *indio_dev, static const struct iio_info ad7944_iio_info = { .read_raw = &ad7944_read_raw, + .write_raw = &ad7944_write_raw, +}; + +static int ad7944_offload_ex_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + + return spi_offload_hw_trigger_enable(adc->spi, 0); +} + +static int ad7944_offload_ex_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad7944_adc *adc = iio_priv(indio_dev); + + spi_offload_hw_trigger_disable(adc->spi, 0); + + return 0; +} + +static const struct iio_buffer_setup_ops ad7944_offload_ex_buffer_setup_ops = { + .postenable = &ad7944_offload_ex_buffer_postenable, + .predisable = &ad7944_offload_ex_buffer_predisable, }; static irqreturn_t ad7944_trigger_handler(int irq, void *p) @@ -471,6 +503,18 @@ static void ad7944_ref_disable(void *ref) regulator_disable(ref); } +static void ad7944_offload_unprepare(void *p) +{ + struct ad7944_adc *adc = p; + + spi_offload_unprepare(adc->spi, 0, &adc->msg); +} + +static void ad7944_unoptimize_msg(void *msg) +{ + spi_unoptimize_message(msg); +} + static int ad7944_probe(struct spi_device *spi) { const struct ad7944_chip_info *chip_info; @@ -603,16 +647,10 @@ static int ad7944_probe(struct spi_device *spi) switch (adc->spi_mode) { case AD7944_SPI_MODE_DEFAULT: - ret = ad7944_4wire_mode_init_msg(dev, adc, &chip_info->channels[0]); - if (ret) - return ret; - + ad7944_4wire_mode_init_msg(dev, adc, &chip_info->channels[0]); break; case AD7944_SPI_MODE_SINGLE: - ret = ad7944_3wire_cs_mode_init_msg(dev, adc, &chip_info->channels[0]); - if (ret) - return ret; - + ad7944_3wire_cs_mode_init_msg(dev, adc, &chip_info->channels[0]); break; case AD7944_SPI_MODE_CHAIN: ret = device_property_read_u32(dev, "#daisy-chained-devices", @@ -649,11 +687,48 @@ static int ad7944_probe(struct spi_device *spi) 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; + if (device_property_present(dev, "spi-offloads")) { + /* TODO: make this a parameter to ad7944_3wire_cs_mode_init_msg() */ + /* FIXME: wrong index for 4-wire mode */ + adc->xfers[2].rx_buf = NULL; + adc->xfers[2].offload_flags = SPI_OFFLOAD_XFER_RX_STREAM; + + ret = spi_offload_prepare(adc->spi, 0, &adc->msg); + if (ret) + return dev_err_probe(dev, ret, "failed to prepare offload\n"); + + ret = devm_add_action_or_reset(dev, ad7944_offload_unprepare, adc); + if (ret) + return ret; + + adc->trigger_clk = devm_clk_get_enabled(dev, "trigger"); + if (IS_ERR(adc->trigger_clk)) + return dev_err_probe(dev, PTR_ERR(adc->trigger_clk), + "failed to get trigger clk\n"); + + ret = devm_iio_dmaengine_buffer_setup(dev, indio_dev, "rx"); + if (ret) + return ret; + + indio_dev->setup_ops = &ad7944_offload_ex_buffer_setup_ops; + /* offload can't have soft timestamp */ + indio_dev->num_channels--; + } else { + ret = spi_optimize_message(adc->spi, &adc->msg); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, ad7944_unoptimize_msg, &adc->msg); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + ad7944_trigger_handler, + NULL); + if (ret) + return ret; + } return devm_iio_device_register(dev, indio_dev); }