From: Nathan Lynch via B4 Relay <devnull+nathan.lynch.amd.com@kernel.org>
To: Vinod Koul <vkoul@kernel.org>, Frank Li <Frank.Li@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
David Rientjes <rientjes@google.com>,
John.Kariuki@amd.com, Jonathan Cameron <jic23@kernel.org>,
Kinsey Ho <kinseyho@google.com>,
Mario Limonciello <mario.limonciello@amd.com>,
PradeepVineshReddy.Kodamati@amd.com,
Shivank Garg <shivankg@amd.com>,
Stephen Bates <Stephen.Bates@amd.com>,
Tycho Andersen <tycho@kernel.org>,
Wei Huang <wei.huang2@amd.com>, Wei Xu <weixugc@google.com>,
dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, Nathan Lynch <nathan.lynch@amd.com>
Subject: [PATCH v3 08/23] dmaengine: sdxi: Install administrative context
Date: Fri, 05 Jun 2026 19:02:11 -0500 [thread overview]
Message-ID: <20260605-sdxi-base-v3-8-4d38ca2bdffe@amd.com> (raw)
In-Reply-To: <20260605-sdxi-base-v3-0-4d38ca2bdffe@amd.com>
From: Nathan Lynch <nathan.lynch@amd.com>
Serialize the context control block, akey table, and L1 entry for the
admin context, making its descriptor ring, write index, and context
status block visible to the SDXI implementation once it is activated.
Co-developed-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Nathan Lynch <nathan.lynch@amd.com>
---
drivers/dma/sdxi/context.c | 162 +++++++++++++++++++++++++++++++++++++++++++++
drivers/dma/sdxi/context.h | 7 ++
drivers/dma/sdxi/hw.h | 15 +++++
drivers/dma/sdxi/sdxi.h | 9 +++
4 files changed, 193 insertions(+)
diff --git a/drivers/dma/sdxi/context.c b/drivers/dma/sdxi/context.c
index 443c231303af..cc99fe9ecf92 100644
--- a/drivers/dma/sdxi/context.c
+++ b/drivers/dma/sdxi/context.c
@@ -7,16 +7,22 @@
#define pr_fmt(fmt) "SDXI: " fmt
+#include <linux/align.h>
+#include <linux/bitfield.h>
#include <linux/bug.h>
#include <linux/cleanup.h>
#include <linux/device/devres.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/errno.h>
+#include <linux/iommu.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/rwonce.h>
#include "context.h"
+#include "hw.h"
#include "sdxi.h"
#define DEFAULT_DESC_RING_ENTRIES 1024
@@ -106,6 +112,152 @@ static struct sdxi_cxt *sdxi_alloc_cxt(struct sdxi_dev *sdxi)
return_ptr(cxt);
}
+struct sdxi_cxt_ctl_cfg {
+ dma_addr_t ds_ring_ptr;
+ dma_addr_t cxt_sts_ptr;
+ dma_addr_t write_index_ptr;
+ u32 ds_ring_sz;
+ u8 qos;
+ u8 csa;
+ bool se;
+};
+
+static int configure_cxt_ctl(struct sdxi_cxt_ctl *ctl, const struct sdxi_cxt_ctl_cfg *cfg)
+{
+ u64 ds_ring_ptr, cxt_sts_ptr, write_index_ptr;
+
+ write_index_ptr = FIELD_PREP(SDXI_CXT_CTL_WRITE_INDEX_PTR,
+ cfg->write_index_ptr >> WRT_INDEX_PTR_SHIFT);
+ cxt_sts_ptr = FIELD_PREP(SDXI_CXT_CTL_CXT_STS_PTR,
+ cfg->cxt_sts_ptr >> CXT_STATUS_PTR_SHIFT);
+
+ *ctl = (typeof(*ctl)) {
+ /*
+ * ds_ring_ptr contains the validity bit and is updated
+ * after a barrier is issued.
+ */
+ .ds_ring_sz = cpu_to_le32(cfg->ds_ring_sz),
+ .cxt_sts_ptr = cpu_to_le64(cxt_sts_ptr),
+ .write_index_ptr = cpu_to_le64(write_index_ptr),
+ };
+
+ ds_ring_ptr = FIELD_PREP(SDXI_CXT_CTL_VL, 1) |
+ FIELD_PREP(SDXI_CXT_CTL_QOS, cfg->qos) |
+ FIELD_PREP(SDXI_CXT_CTL_SE, cfg->se) |
+ FIELD_PREP(SDXI_CXT_CTL_CSA, cfg->csa) |
+ FIELD_PREP(SDXI_CXT_CTL_DS_RING_PTR,
+ cfg->ds_ring_ptr >> DESC_RING_BASE_PTR_SHIFT);
+ /* Ensure other fields are visible before hw sees vl=1. */
+ dma_wmb();
+ WRITE_ONCE(ctl->ds_ring_ptr, cpu_to_le64(ds_ring_ptr));
+
+ return 0;
+}
+
+/*
+ * Logical representation of CXT_L1_ENT subfields.
+ */
+struct sdxi_cxt_L1_cfg {
+ dma_addr_t cxt_ctl_ptr;
+ dma_addr_t akey_ptr;
+ u32 cxt_pasid;
+ u32 opb_000_enb;
+ u16 max_buffer;
+ u8 akey_sz;
+ bool ka;
+ bool pv;
+};
+
+static int configure_L1_entry(struct sdxi_cxt_L1_ent *ent,
+ const struct sdxi_cxt_L1_cfg *cfg)
+{
+ u64 cxt_ctl_ptr, akey_ptr;
+ u32 misc0;
+
+ if (WARN_ON_ONCE(!IS_ALIGNED(cfg->cxt_ctl_ptr, SZ_64)))
+ return -EFAULT;
+ if (WARN_ON_ONCE(!IS_ALIGNED(cfg->akey_ptr, SZ_4K)))
+ return -EFAULT;
+
+ akey_ptr = FIELD_PREP(SDXI_CXT_L1_ENT_AKEY_SZ, cfg->akey_sz) |
+ FIELD_PREP(SDXI_CXT_L1_ENT_AKEY_PTR,
+ cfg->akey_ptr >> L1_CXT_AKEY_PTR_SHIFT);
+
+ misc0 = FIELD_PREP(SDXI_CXT_L1_ENT_PASID, cfg->cxt_pasid) |
+ FIELD_PREP(SDXI_CXT_L1_ENT_MAX_BUFFER, cfg->max_buffer);
+
+ *ent = (typeof(*ent)) {
+ /*
+ * cxt_ctl_ptr contains the validity bit and is
+ * updated after a barrier is issued.
+ */
+ .akey_ptr = cpu_to_le64(akey_ptr),
+ .misc0 = cpu_to_le32(misc0),
+ .opb_000_enb = cpu_to_le32(cfg->opb_000_enb),
+ };
+
+ cxt_ctl_ptr = FIELD_PREP(SDXI_CXT_L1_ENT_VL, 1) |
+ FIELD_PREP(SDXI_CXT_L1_ENT_KA, cfg->ka) |
+ FIELD_PREP(SDXI_CXT_L1_ENT_PV, cfg->pv) |
+ FIELD_PREP(SDXI_CXT_L1_ENT_CXT_CTL_PTR,
+ cfg->cxt_ctl_ptr >> L1_CXT_CTRL_PTR_SHIFT);
+ /* Ensure other fields are visible before hw sees vl=1. */
+ dma_wmb();
+ WRITE_ONCE(ent->cxt_ctl_ptr, cpu_to_le64(cxt_ctl_ptr));
+
+ return 0;
+}
+
+/*
+ * Make the context control structure hierarchy valid from the POV of
+ * the SDXI implementation. This may eventually involve allocation of
+ * a L1 table page, so it needs to be fallible.
+ */
+static int sdxi_publish_cxt(const struct sdxi_cxt *cxt)
+{
+ struct sdxi_cxt_ctl_cfg ctl_cfg;
+ struct sdxi_cxt_L1_cfg L1_cfg;
+ struct sdxi_cxt_L1_ent *ent;
+ u8 l1_idx;
+ int err;
+
+ if (WARN_ONCE(cxt->id > cxt->sdxi->max_cxtid,
+ "can't install cxt with id %u (limit %u)",
+ cxt->id, cxt->sdxi->max_cxtid))
+ return -EINVAL;
+
+ ctl_cfg = (typeof(ctl_cfg)) {
+ .se = 1,
+ .csa = 1,
+ .ds_ring_ptr = cxt->sq->ring_dma,
+ .ds_ring_sz = cxt->sq->ring_size >> 6,
+ .cxt_sts_ptr = cxt->sq->cxt_sts_dma,
+ .write_index_ptr = cxt->sq->write_index_dma,
+ };
+
+ err = configure_cxt_ctl(cxt->cxt_ctl, &ctl_cfg);
+ if (err)
+ return err;
+
+ l1_idx = ID_TO_L1_INDEX(cxt->id);
+
+ ent = &cxt->sdxi->L1_table->entry[l1_idx];
+
+ L1_cfg = (typeof(L1_cfg)) {
+ .ka = 1,
+ .pv = 0,
+ .cxt_ctl_ptr = cxt->cxt_ctl_dma,
+ .akey_sz = akey_table_order(cxt->akey_table),
+ .akey_ptr = cxt->akey_table_dma,
+ .cxt_pasid = IOMMU_NO_PASID,
+ .max_buffer = 11, /* 4GB */
+ .opb_000_enb = cxt->sdxi->op_grp_cap,
+ };
+
+ return configure_L1_entry(ent, &L1_cfg);
+ /* todo: need to send DSC_CXT_UPD to admin */
+}
+
static void free_admin_cxt(void *ptr)
{
struct sdxi_dev *sdxi = ptr;
@@ -115,13 +267,23 @@ static void free_admin_cxt(void *ptr)
int sdxi_admin_cxt_init(struct sdxi_dev *sdxi)
{
+ int err;
+ struct sdxi_sq *sq;
+
struct sdxi_cxt *cxt __free(sdxi_cxt) = sdxi_alloc_cxt(sdxi);
if (!cxt)
return -ENOMEM;
+ sq = cxt->sq;
+ /* SDXI 1.0 4.1.8.4.b: Set CXT_STS.state to CXTV_RUN. */
+ sq->cxt_sts->state = FIELD_PREP(SDXI_CXT_STS_STATE, CXTV_RUN);
cxt->id = SDXI_ADMIN_CXT_ID;
cxt->db = sdxi->dbs + cxt->id * sdxi->db_stride;
+ err = sdxi_publish_cxt(cxt);
+ if (err)
+ return err;
+
sdxi->admin_cxt = no_free_ptr(cxt);
return devm_add_action_or_reset(sdxi->dev, free_admin_cxt, sdxi);
diff --git a/drivers/dma/sdxi/context.h b/drivers/dma/sdxi/context.h
index a29387900df7..65b773446ba3 100644
--- a/drivers/dma/sdxi/context.h
+++ b/drivers/dma/sdxi/context.h
@@ -20,6 +20,13 @@ struct sdxi_akey_table {
struct sdxi_akey_ent entry[SZ_4K / sizeof(struct sdxi_akey_ent)];
};
+/* For encoding the akey table size in CXT_L1_ENT's akey_sz. */
+static inline u8 akey_table_order(const struct sdxi_akey_table *tbl)
+{
+ static_assert(sizeof(*tbl) == SZ_4K);
+ return 0;
+}
+
/* Submission Queue */
struct sdxi_sq {
u32 ring_entries;
diff --git a/drivers/dma/sdxi/hw.h b/drivers/dma/sdxi/hw.h
index 55d63d50a01b..4b65337a5975 100644
--- a/drivers/dma/sdxi/hw.h
+++ b/drivers/dma/sdxi/hw.h
@@ -45,8 +45,16 @@ static_assert(sizeof(struct sdxi_cxt_L2_table) == 4096);
/* SDXI 1.0 Table 3-3: Context Level 1 Table Entry (CXT_L1_ENT) */
struct sdxi_cxt_L1_ent {
__le64 cxt_ctl_ptr;
+#define SDXI_CXT_L1_ENT_VL BIT_ULL(0)
+#define SDXI_CXT_L1_ENT_KA BIT_ULL(1)
+#define SDXI_CXT_L1_ENT_PV BIT_ULL(2)
+#define SDXI_CXT_L1_ENT_CXT_CTL_PTR GENMASK_ULL(63, 6)
__le64 akey_ptr;
+#define SDXI_CXT_L1_ENT_AKEY_SZ GENMASK_ULL(3, 0)
+#define SDXI_CXT_L1_ENT_AKEY_PTR GENMASK_ULL(63, 12)
__le32 misc0;
+#define SDXI_CXT_L1_ENT_PASID GENMASK(19, 0)
+#define SDXI_CXT_L1_ENT_MAX_BUFFER GENMASK(23, 20)
__le32 opb_000_enb;
__u8 rsvd_0[8];
} __packed __aligned(32);
@@ -62,10 +70,17 @@ static_assert(sizeof(struct sdxi_cxt_L1_table) == 4096);
/* SDXI 1.0 Table 3-4: Context Control (CXT_CTL) */
struct sdxi_cxt_ctl {
__le64 ds_ring_ptr;
+#define SDXI_CXT_CTL_VL BIT_ULL(0)
+#define SDXI_CXT_CTL_QOS GENMASK_ULL(3, 2)
+#define SDXI_CXT_CTL_SE BIT_ULL(4)
+#define SDXI_CXT_CTL_CSA BIT_ULL(5)
+#define SDXI_CXT_CTL_DS_RING_PTR GENMASK_ULL(63, 6)
__le32 ds_ring_sz;
__u8 rsvd_0[4];
__le64 cxt_sts_ptr;
+#define SDXI_CXT_CTL_CXT_STS_PTR GENMASK_ULL(63, 4)
__le64 write_index_ptr;
+#define SDXI_CXT_CTL_WRITE_INDEX_PTR GENMASK_ULL(63, 3)
__u8 rsvd_1[32];
} __packed __aligned(64);
static_assert(sizeof(struct sdxi_cxt_ctl) == 64);
diff --git a/drivers/dma/sdxi/sdxi.h b/drivers/dma/sdxi/sdxi.h
index f5e0cd986b9e..903bf18bd3cc 100644
--- a/drivers/dma/sdxi/sdxi.h
+++ b/drivers/dma/sdxi/sdxi.h
@@ -15,6 +15,15 @@
#include "mmio.h"
+#define ID_TO_L1_INDEX(id) ((id) & 0x7F)
+
+#define DESC_RING_BASE_PTR_SHIFT 6
+#define CXT_STATUS_PTR_SHIFT 4
+#define WRT_INDEX_PTR_SHIFT 3
+
+#define L1_CXT_CTRL_PTR_SHIFT 6
+#define L1_CXT_AKEY_PTR_SHIFT 12
+
struct sdxi_dev;
/**
--
2.54.0
next prev parent reply other threads:[~2026-06-06 0:02 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-06 0:02 [PATCH v3 00/23] dmaengine: Smart Data Accelerator Interface (SDXI) basic support Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 01/23] PCI: Add SNIA SDXI accelerator sub-class Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 02/23] MAINTAINERS: Add entry for SDXI driver Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 03/23] dmaengine: sdxi: Add PCI initialization Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 04/23] dmaengine: sdxi: Feature discovery and initial configuration Nathan Lynch via B4 Relay
2026-06-06 0:14 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 05/23] dmaengine: sdxi: Configure context tables Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 06/23] dmaengine: sdxi: Allocate DMA pools Nathan Lynch via B4 Relay
2026-06-06 0:15 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 07/23] dmaengine: sdxi: Allocate administrative context Nathan Lynch via B4 Relay
2026-06-06 0:02 ` Nathan Lynch via B4 Relay [this message]
2026-06-06 0:26 ` [PATCH v3 08/23] dmaengine: sdxi: Install " sashiko-bot
2026-06-06 0:02 ` [PATCH v3 09/23] dmaengine: sdxi: Start functions on probe, stop on remove Nathan Lynch via B4 Relay
2026-06-06 0:14 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 10/23] dmaengine: sdxi: Complete administrative context jump start Nathan Lynch via B4 Relay
2026-06-06 0:12 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 11/23] dmaengine: sdxi: Add client context alloc and release APIs Nathan Lynch via B4 Relay
2026-06-06 0:22 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 12/23] dmaengine: sdxi: Add descriptor ring management Nathan Lynch via B4 Relay
2026-06-06 0:19 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 13/23] dmaengine: sdxi: Add unit tests for descriptor ring reservations Nathan Lynch via B4 Relay
2026-06-06 0:16 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 14/23] dmaengine: sdxi: Attach descriptor ring state to contexts Nathan Lynch via B4 Relay
2026-06-06 0:24 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 15/23] dmaengine: sdxi: Per-context access key (AKey) table entry allocator Nathan Lynch via B4 Relay
2026-06-06 0:20 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 16/23] dmaengine: sdxi: Generic descriptor manipulation helpers Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 17/23] dmaengine: sdxi: Add completion status block API Nathan Lynch via B4 Relay
2026-06-06 0:21 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 18/23] dmaengine: sdxi: Encode context start, stop, and sync descriptors Nathan Lynch via B4 Relay
2026-06-06 0:02 ` [PATCH v3 19/23] dmaengine: sdxi: Provide context start and stop APIs Nathan Lynch via B4 Relay
2026-06-06 0:22 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 20/23] dmaengine: sdxi: Encode nop, copy, and interrupt descriptors Nathan Lynch via B4 Relay
2026-06-06 0:20 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 21/23] dmaengine: sdxi: Add unit tests for descriptor encoding Nathan Lynch via B4 Relay
2026-06-06 0:26 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 22/23] dmaengine: sdxi: MSI/MSI-X vector allocation and mapping Nathan Lynch via B4 Relay
2026-06-06 0:31 ` sashiko-bot
2026-06-06 0:02 ` [PATCH v3 23/23] dmaengine: sdxi: Add DMA engine provider Nathan Lynch via B4 Relay
2026-06-06 0:33 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260605-sdxi-base-v3-8-4d38ca2bdffe@amd.com \
--to=devnull+nathan.lynch.amd.com@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=John.Kariuki@amd.com \
--cc=PradeepVineshReddy.Kodamati@amd.com \
--cc=Stephen.Bates@amd.com \
--cc=bhelgaas@google.com \
--cc=dmaengine@vger.kernel.org \
--cc=jic23@kernel.org \
--cc=kinseyho@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=nathan.lynch@amd.com \
--cc=rientjes@google.com \
--cc=shivankg@amd.com \
--cc=tycho@kernel.org \
--cc=vkoul@kernel.org \
--cc=wei.huang2@amd.com \
--cc=weixugc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox