{"id":2221935,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2221935/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260410-sdxi-base-v1-20-1d184cb5c60a@amd.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/1.1/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260410-sdxi-base-v1-20-1d184cb5c60a@amd.com>","date":"2026-04-10T13:07:30","name":"[20/23] dmaengine: sdxi: Encode nop, copy, and interrupt descriptors","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"e5fcf161221aec75d9d0733f2e973a9e7536134f","submitter":{"id":91626,"url":"http://patchwork.ozlabs.org/api/1.1/people/91626/?format=json","name":"Nathan Lynch via B4 Relay","email":"devnull+nathan.lynch.amd.com@kernel.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260410-sdxi-base-v1-20-1d184cb5c60a@amd.com/mbox/","series":[{"id":499458,"url":"http://patchwork.ozlabs.org/api/1.1/series/499458/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=499458","date":"2026-04-10T13:07:10","name":"dmaengine: Smart Data Accelerator Interface (SDXI) basic support","version":1,"mbox":"http://patchwork.ozlabs.org/series/499458/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2221935/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2221935/checks/","tags":{},"headers":{"Return-Path":"\n <linux-pci+bounces-52331-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=ftZsZkT8;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.105.105.114; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-52331-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"ftZsZkT8\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fscYt4HJ3z1yGb\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 23:08:34 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id D5A61301A50C\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Apr 2026 13:08:04 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 3F0813C141F;\n\tFri, 10 Apr 2026 13:07:51 +0000 (UTC)","from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id E8BD53BE62A;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPS id CFAFBC2BCB5;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)","from aws-us-west-2-korg-lkml-1.web.codeaurora.org\n (localhost.localdomain [127.0.0.1])\n\tby smtp.lore.kernel.org (Postfix) with ESMTP id C92F5F44860;\n\tFri, 10 Apr 2026 13:07:50 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775826471; cv=none;\n b=RTrTHuIwm2Q0Hrklo8uy+/Upb/33NcLqk5TRbgHVscB5vJXyrjDM+xX5X69H2sOp3s97HeMZZyM0tgj2pwse1rPID9bN3en0YIaUexmCKhYLf+feO4S2RlRoQ7NgCqobpXDS1B5mVoSAfBqc3CHRD9xAUbxXf5BwnzwDMUrRRIY=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775826471; c=relaxed/simple;\n\tbh=2dyKKbeGNA+sdmxto4YfxYBZgT6QxwbVecXrxAUTfI0=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References:\n\t In-Reply-To:To:Cc;\n b=R554KAKa9/dy9NUYhxIO6xTtZ/j6IDXosNNItteD+wGIgPviJ+ttoCAkptIl9OJa/vuV1+TnuGe9C/22GqdG2U8LU45WuKn+a6G7z4b33IViOIiWV6pj7YaAVcxcEz6vqmhNZFgOLaRizArvPZo9G2a2ZM5U1PJDS/nIKV/ay1I=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=ftZsZkT8; arc=none smtp.client-ip=10.30.226.201","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1775826470;\n\tbh=2dyKKbeGNA+sdmxto4YfxYBZgT6QxwbVecXrxAUTfI0=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From;\n\tb=ftZsZkT8DHs239qMqkBiODRVZQwjRl9fgPUewmZtntZyQiHwdKqZHowKFddtYyNMS\n\t 8AKFxVrUSYyWFCiIwWKrLaqK4a4YezoY1GGUNk2diuanS/5JSLXcZEofnNGNqc5oBM\n\t ZMZAi8XIzV/ZaKNZ0rQUQ3KtbjccvwTp8L3QSHXpB+Qbz8sQ8T23Abm5ygy5hrWs3z\n\t yqc5oMBlLSNFBoaoqjOPcg3SIuJ5N524Z2ceoNBsjidd3Hrlk6QschXyFnUcIVAOCK\n\t F5bnu7DTd1YuWTWQlfh1Yi8FsSlM+gX3StF6Fj5Q5anK3m3fhgzNPhy0uimkZvMevR\n\t roIIrLDqCG6eA==","From":"Nathan Lynch via B4 Relay <devnull+nathan.lynch.amd.com@kernel.org>","Date":"Fri, 10 Apr 2026 08:07:30 -0500","Subject":"[PATCH 20/23] dmaengine: sdxi: Encode nop, copy, and interrupt\n descriptors","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-Id":"<20260410-sdxi-base-v1-20-1d184cb5c60a@amd.com>","References":"<20260410-sdxi-base-v1-0-1d184cb5c60a@amd.com>","In-Reply-To":"<20260410-sdxi-base-v1-0-1d184cb5c60a@amd.com>","To":"Vinod Koul <vkoul@kernel.org>","Cc":"Wei Huang <wei.huang2@amd.com>,\n Mario Limonciello <mario.limonciello@amd.com>,\n Bjorn Helgaas <bhelgaas@google.com>,\n Jonathan Cameron <jonathan.cameron@huawei.com>,\n Stephen Bates <Stephen.Bates@amd.com>, PradeepVineshReddy.Kodamati@amd.com,\n John.Kariuki@amd.com, linux-pci@vger.kernel.org,\n linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,\n Nathan Lynch <nathan.lynch@amd.com>","X-Mailer":"b4 0.15.2","X-Developer-Signature":"v=1; a=ed25519-sha256; t=1775826467; l=7375;\n i=nathan.lynch@amd.com; s=20260410; h=from:subject:message-id;\n bh=v16ENkACRv4VCqxQPotIvR4Vnct9VpRc0P+k81qylyw=;\n b=+zXZ1AgjxXQBpKYfy4UE6tmfRHEptiPyVL4ZwGwBNB2bvFgWwhoK3HFHk9727msmrFd3t3kFQ\n 57TcM4fEF/9CzMzVFjRO8m3SxKlLED00JmUIm6Lvy9oKnhtUC8yPm+0","X-Developer-Key":"i=nathan.lynch@amd.com; a=ed25519;\n pk=PK4ozhq+/z9/2Jl5rgDmvHa9raVomv79qM8p1RAFpEw=","X-Endpoint-Received":"by B4 Relay for nathan.lynch@amd.com/20260410 with\n auth_id=728","X-Original-From":"Nathan Lynch <nathan.lynch@amd.com>","Reply-To":"nathan.lynch@amd.com"},"content":"From: Nathan Lynch <nathan.lynch@amd.com>\n\nIntroduce low-level support for serializing three operation types to\nthe descriptor ring of a client context: nop, copy, and interrupt.\nAs with the administrative descriptor support introduced earlier, each\noperation has its own distinct type that overlays the generic struct\nsdxi_desc, along with a dedicated encoder function that accepts an\noperation-specific parameter struct.\n\nCopy descriptors are used to implement memcpy offload for the DMA\nengine provider, and interrupt descriptors are used to signal the\ncompletion of preceding descriptors in the ring. Nops can be used in\nerror paths where a ring reservation has been obtained and the caller\nneeds to submit valid descriptors before returning.\n\nConditionally expose sdxi_encode_size32() for unit testing.\n\nCo-developed-by: Wei Huang <wei.huang2@amd.com>\nSigned-off-by: Wei Huang <wei.huang2@amd.com>\nSigned-off-by: Nathan Lynch <nathan.lynch@amd.com>\n---\n drivers/dma/sdxi/descriptor.c | 107 ++++++++++++++++++++++++++++++++++++++++++\n drivers/dma/sdxi/descriptor.h |  25 ++++++++++\n drivers/dma/sdxi/hw.h         |  33 +++++++++++++\n 3 files changed, 165 insertions(+)","diff":"diff --git a/drivers/dma/sdxi/descriptor.c b/drivers/dma/sdxi/descriptor.c\nindex be2a9244ce19..41019e747528 100644\n--- a/drivers/dma/sdxi/descriptor.c\n+++ b/drivers/dma/sdxi/descriptor.c\n@@ -7,12 +7,119 @@\n \n #include <kunit/visibility.h>\n #include <linux/bitfield.h>\n+#include <linux/bug.h>\n+#include <linux/range.h>\n+#include <linux/sizes.h>\n #include <linux/types.h>\n #include <asm/byteorder.h>\n \n #include \"hw.h\"\n #include \"descriptor.h\"\n \n+VISIBLE_IF_KUNIT int __must_check sdxi_encode_size32(u64 size, __le32 *dest)\n+{\n+\t/*\n+\t * sizes are encoded as value - 1:\n+\t * value    encoding\n+\t *     1           0\n+\t *     2           1\n+\t *   ...\n+\t *    4G  0xffffffff\n+\t */\n+\tif (WARN_ON_ONCE(size > SZ_4G) ||\n+\t    WARN_ON_ONCE(size == 0))\n+\t\treturn -EINVAL;\n+\tsize = clamp_val(size, 1, SZ_4G);\n+\t*dest = cpu_to_le32((u32)(size - 1));\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_encode_size32);\n+\n+void sdxi_serialize_nop(struct sdxi_desc *desc)\n+{\n+\tu32 opcode = (FIELD_PREP(SDXI_DSC_SUBTYPE, SDXI_DSC_OP_SUBTYPE_NOP) |\n+\t\t      FIELD_PREP(SDXI_DSC_TYPE, SDXI_DSC_OP_TYPE_DMAB));\n+\tu64 csb_ptr = FIELD_PREP(SDXI_DSC_NP, 1);\n+\n+\t*desc = (typeof(*desc)) {\n+\t\t.nop = (typeof(desc->nop)) {\n+\t\t\t.opcode = cpu_to_le32(opcode),\n+\t\t\t.csb_ptr = cpu_to_le64(csb_ptr),\n+\t\t},\n+\t};\n+\n+}\n+\n+int sdxi_encode_copy(struct sdxi_desc *desc, const struct sdxi_copy *params)\n+{\n+\tu64 csb_ptr;\n+\tu32 opcode;\n+\t__le32 size;\n+\tint err;\n+\n+\terr = sdxi_encode_size32(params->len, &size);\n+\tif (err)\n+\t\treturn err;\n+\t/*\n+\t * Reject overlapping src and dst. \"Software ... shall not\n+\t * overlap the source buffer, destination buffer, Atomic\n+\t * Return Data, or completion status block.\" - SDXI 1.0 5.6\n+\t * Memory Consistency Model\n+\t */\n+\tif (range_overlaps(&(const struct range) {\n+\t\t\t\t   .start = params->src,\n+\t\t\t\t   .end   = params->src + params->len - 1,\n+\t\t\t   },\n+\t\t\t   &(const struct range) {\n+\t\t\t\t   .start = params->dst,\n+\t\t\t\t   .end   = params->dst + params->len - 1,\n+\t\t\t   }))\n+\t\treturn -EINVAL;\n+\n+\topcode = (FIELD_PREP(SDXI_DSC_SUBTYPE, SDXI_DSC_OP_SUBTYPE_COPY) |\n+\t\t  FIELD_PREP(SDXI_DSC_TYPE, SDXI_DSC_OP_TYPE_DMAB));\n+\n+\tcsb_ptr = FIELD_PREP(SDXI_DSC_NP, 1);\n+\n+\t*desc = (typeof(*desc)) {\n+\t\t.copy = (typeof(desc->copy)) {\n+\t\t\t.opcode = cpu_to_le32(opcode),\n+\t\t\t.size = size,\n+\t\t\t.akey0 = cpu_to_le16(params->src_akey),\n+\t\t\t.akey1 = cpu_to_le16(params->dst_akey),\n+\t\t\t.addr0 = cpu_to_le64(params->src),\n+\t\t\t.addr1 = cpu_to_le64(params->dst),\n+\t\t\t.csb_ptr = cpu_to_le64(csb_ptr),\n+\t\t},\n+\t};\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_encode_copy);\n+\n+int sdxi_encode_intr(struct sdxi_desc *desc,\n+\t\t     const struct sdxi_intr *params)\n+{\n+\tu64 csb_ptr;\n+\tu32 opcode;\n+\n+\topcode = (FIELD_PREP(SDXI_DSC_SUBTYPE, SDXI_DSC_OP_SUBTYPE_INTR) |\n+\t\t  FIELD_PREP(SDXI_DSC_TYPE, SDXI_DSC_OP_TYPE_INTR));\n+\n+\tcsb_ptr = FIELD_PREP(SDXI_DSC_NP, 1);\n+\n+\t*desc = (typeof(*desc)) {\n+\t\t.intr = (typeof(desc->intr)) {\n+\t\t\t.opcode = cpu_to_le32(opcode),\n+\t\t\t.akey = cpu_to_le16(params->akey),\n+\t\t\t.csb_ptr = cpu_to_le64(csb_ptr),\n+\t\t},\n+\t};\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_IF_KUNIT(sdxi_encode_intr);\n+\n int sdxi_encode_cxt_start(struct sdxi_desc *desc,\n \t\t\t  const struct sdxi_cxt_start *params)\n {\ndiff --git a/drivers/dma/sdxi/descriptor.h b/drivers/dma/sdxi/descriptor.h\nindex 5b8fd7cbaa03..14f92c8dea1d 100644\n--- a/drivers/dma/sdxi/descriptor.h\n+++ b/drivers/dma/sdxi/descriptor.h\n@@ -9,6 +9,7 @@\n  */\n \n #include <linux/bitfield.h>\n+#include <linux/kconfig.h>\n #include <linux/minmax.h>\n #include <linux/ratelimit.h>\n #include <linux/types.h>\n@@ -16,6 +17,10 @@\n \n #include \"hw.h\"\n \n+#if IS_ENABLED(CONFIG_KUNIT)\n+int __must_check sdxi_encode_size32(u64 size, __le32 *dest);\n+#endif\n+\n static inline void sdxi_desc_vl_expect(const struct sdxi_desc *desc, bool expected)\n {\n \tu8 vl = FIELD_GET(SDXI_DSC_VL, le32_to_cpu(desc->opcode));\n@@ -80,6 +85,26 @@ static inline struct sdxi_cxt_range sdxi_cxt_range_single(u16 nr)\n \treturn sdxi_cxt_range(nr, nr);\n }\n \n+void sdxi_serialize_nop(struct sdxi_desc *desc);\n+\n+struct sdxi_copy {\n+\tdma_addr_t src;\n+\tdma_addr_t dst;\n+\tu64 len;\n+\tu16 src_akey;\n+\tu16 dst_akey;\n+};\n+\n+int sdxi_encode_copy(struct sdxi_desc *desc,\n+\t\t     const struct sdxi_copy *params);\n+\n+struct sdxi_intr {\n+\tu16 akey;\n+};\n+\n+int sdxi_encode_intr(struct sdxi_desc *desc,\n+\t\t     const struct sdxi_intr *params);\n+\n struct sdxi_cxt_start {\n \tstruct sdxi_cxt_range range;\n };\ndiff --git a/drivers/dma/sdxi/hw.h b/drivers/dma/sdxi/hw.h\nindex 4dcd0a3ff0fd..11d88cfc8819 100644\n--- a/drivers/dma/sdxi/hw.h\n+++ b/drivers/dma/sdxi/hw.h\n@@ -164,6 +164,30 @@ struct sdxi_desc {\n \tstatic_assert(offsetof(struct tag_, csb_ptr) ==\t\t\t\\\n \t\t      offsetof(struct sdxi_dsc_generic, csb_ptr))\n \n+\t\t/* SDXI 1.0 Table 6-6: DSC_DMAB_NOP Descriptor Format */\n+\t\tdefine_sdxi_dsc(sdxi_dsc_dmab_nop, nop,\n+\t\t\t__u8 rsvd_0[52];\n+\t\t);\n+\n+\t\t/* SDXI 1.0 Table 6-8: DSC_DMAB_COPY Descriptor Format */\n+\t\tdefine_sdxi_dsc(sdxi_dsc_dmab_copy, copy,\n+\t\t\t__le32 size;\n+\t\t\t__u8 attr;\n+\t\t\t__u8 rsvd_0[3];\n+\t\t\t__le16 akey0;\n+\t\t\t__le16 akey1;\n+\t\t\t__le64 addr0;\n+\t\t\t__le64 addr1;\n+\t\t\t__u8 rsvd_1[24];\n+\t\t);\n+\n+\t\t/* SDXI 1.0 Table 6-12: DSC_INTR Descriptor Format */\n+\t\tdefine_sdxi_dsc(sdxi_dsc_intr, intr,\n+\t\t\t__u8 rsvd_0[8];\n+\t\t\t__le16 akey;\n+\t\t\t__u8 rsvd_1[42];\n+\t\t);\n+\n \t\t/* SDXI 1.0 Table 6-14: DSC_CXT_START Descriptor Format */\n \t\tdefine_sdxi_dsc(sdxi_dsc_cxt_start, cxt_start,\n \t\t\t__u8 rsvd_0;\n@@ -207,11 +231,20 @@ static_assert(sizeof(struct sdxi_desc) == 64);\n \n /* SDXI 1.0 Table 6-1: SDXI Operation Groups */\n enum sdxi_dsc_type {\n+\tSDXI_DSC_OP_TYPE_DMAB    = 0x001,\n \tSDXI_DSC_OP_TYPE_ADMIN   = 0x002,\n+\tSDXI_DSC_OP_TYPE_INTR    = 0x004,\n };\n \n /* SDXI 1.0 Table 6-2: SDXI Operation Groups, Types, and Subtypes */\n enum sdxi_dsc_subtype {\n+\t/* DMA Base */\n+\tSDXI_DSC_OP_SUBTYPE_NOP     = 0x01,\n+\tSDXI_DSC_OP_SUBTYPE_COPY    = 0x03,\n+\n+\t/* Interrupt */\n+\tSDXI_DSC_OP_SUBTYPE_INTR = 0x00,\n+\n \t/* Administrative */\n \tSDXI_DSC_OP_SUBTYPE_CXT_START_NM = 0x03,\n \tSDXI_DSC_OP_SUBTYPE_CXT_STOP     = 0x04,\n","prefixes":["20/23"]}