From: Richard Cheng <icheng@nvidia.com>
To: Davidlohr Bueso <dave@stgolabs.net>
Cc: dave.jiang@intel.com, jic23@kernel.org,
alison.schofield@intel.com, benjamin.cheatham@amd.com,
alucerop@amd.com, dongjoo.seo1@samsung.com,
linux-cxl@vger.kernel.org
Subject: Re: [PATCH v7 1/8] cxl: Add BI register probing and port initialization
Date: Fri, 7 Aug 2026 13:38:22 +0800 [thread overview]
Message-ID: <anVt9LtGbP8PzklF@MWDK4CY14F> (raw)
In-Reply-To: <20260728144136.709882-2-dave@stgolabs.net>
On Tue, Jul 28, 2026 at 07:41:29AM +0800, Davidlohr Bueso wrote:
> Add register probing for BI Route Table and BI Decoder capability
> structures in cxl_probe_component_regs(), and helpers to map them.
>
> cxl_dport_map_bi() maps the BI Decoder of a downstream port (root
> port or switch DSP) at dport-creation time via cxl_port_add_dport();
> cxl_port_map_bi() maps a port's own BI capability during port probe
> when the upstream link is in 256B Flit operation -- BI Decoder for
> an endpoint, BI RT for a switch USP.
>
> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
> ---
> drivers/cxl/core/core.h | 1 +
> drivers/cxl/core/pci.c | 38 ++++++++++++++++++++++++++++++++++
> drivers/cxl/core/port.c | 4 +++-
> drivers/cxl/core/regs.c | 14 +++++++++++++
> drivers/cxl/cxl.h | 7 +++++++
> drivers/cxl/port.c | 45 +++++++++++++++++++++++++++++++++++++++++
> include/cxl/cxl.h | 6 ++++++
> 7 files changed, 114 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
> index 07555ae63859..e36b55fd63bd 100644
> --- a/drivers/cxl/core/core.h
> +++ b/drivers/cxl/core/core.h
> @@ -209,6 +209,7 @@ static inline void devm_cxl_dport_ras_setup(struct cxl_dport *dport) { }
> #endif /* CONFIG_CXL_RAS */
>
> int cxl_gpf_port_setup(struct cxl_dport *dport);
> +void devm_cxl_dport_bi_setup(struct cxl_dport *dport);
>
> struct cxl_hdm;
> int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm,
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index e4338fd7e01b..f82559d8a8c5 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -926,3 +926,41 @@ int cxl_port_get_possible_dports(struct cxl_port *port)
>
> return ctx.count;
> }
> +
> +static void cxl_dport_map_bi(struct cxl_dport *dport)
> +{
> + struct cxl_register_map *map = &dport->reg_map;
> + struct device *dev = dport->dport_dev;
> +
> + if (!map->component_map.bi_decoder.valid) {
> + dev_dbg(dev, "BI Decoder registers not found\n");
> + return;
> + }
> +
> + if (cxl_map_component_regs(map, &dport->regs.component,
> + BIT(CXL_CM_CAP_CAP_ID_BI_DECODER)))
> + dev_dbg(dev, "Failed to map BI Decoder capability\n");
> +}
> +
> +/**
> + * devm_cxl_dport_bi_setup - Map BI Decoder registers on a CXL dport
> + * @dport: the cxl_dport that needs to be initialized
> + *
> + * Must be called while the dport's devres group is open so iomap
> + * allocations are released on dport removal.
> + */
> +void devm_cxl_dport_bi_setup(struct cxl_dport *dport)
> +{
> + if (!dev_is_pci(dport->dport_dev))
> + return;
> +
> + switch (pci_pcie_type(to_pci_dev(dport->dport_dev))) {
> + case PCI_EXP_TYPE_ROOT_PORT:
> + case PCI_EXP_TYPE_DOWNSTREAM:
> + dport->reg_map.host = dport_to_host(dport);
> + cxl_dport_map_bi(dport);
> + break;
> + default:
> + break;
> + }
> +}
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 1215ee4f4035..b2f8fb9547d3 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -1242,8 +1242,10 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
>
> cxl_debugfs_create_dport_dir(dport);
>
> - if (!dport->rch)
> + if (!dport->rch) {
> devm_cxl_dport_ras_setup(dport);
> + devm_cxl_dport_bi_setup(dport);
> + }
>
> /* keep the group, and mark the end of devm actions */
> cxl_dport_close_dr_group(dport, no_free_ptr(dport_dr_group));
> diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c
> index 93710cf4f0a6..a6caa793e7a4 100644
> --- a/drivers/cxl/core/regs.c
> +++ b/drivers/cxl/core/regs.c
> @@ -92,6 +92,18 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base,
> length = CXL_RAS_CAPABILITY_LENGTH;
> rmap = &map->ras;
> break;
> + case CXL_CM_CAP_CAP_ID_BI_RT:
> + dev_dbg(dev, "found BI RT capability (0x%x)\n",
> + offset);
> + length = CXL_BI_RT_CAPABILITY_LENGTH;
> + rmap = &map->bi_rt;
> + break;
> + case CXL_CM_CAP_CAP_ID_BI_DECODER:
> + dev_dbg(dev, "found BI Decoder capability (0x%x)\n",
> + offset);
> + length = CXL_BI_DECODER_CAPABILITY_LENGTH;
> + rmap = &map->bi_decoder;
> + break;
> default:
> dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
> offset);
> @@ -211,6 +223,8 @@ int cxl_map_component_regs(const struct cxl_register_map *map,
> } mapinfo[] = {
> { &map->component_map.hdm_decoder, ®s->hdm_decoder },
> { &map->component_map.ras, ®s->ras },
> + { &map->component_map.bi_rt, ®s->bi_rt },
> + { &map->component_map.bi_decoder, ®s->bi_decoder },
> };
> int i;
>
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index c0e5308e4d1b..f9fcb6387fc8 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -39,9 +39,16 @@ extern const struct nvdimm_security_ops *cxl_security_ops;
> #define CXL_CM_CAP_HDR_ARRAY_SIZE_MASK GENMASK(31, 24)
> #define CXL_CM_CAP_PTR_MASK GENMASK(31, 20)
>
> +/* CXL 4.0 8.2.4 Table 8-74 */
> #define CXL_CM_CAP_CAP_ID_RAS 0x2
> #define CXL_CM_CAP_CAP_ID_HDM 0x5
> #define CXL_CM_CAP_CAP_HDM_VERSION 1
> +#define CXL_CM_CAP_CAP_ID_BI_RT 0xB
> +#define CXL_CM_CAP_CAP_ID_BI_DECODER 0xC
> +
> +/* CXL 4.0 8.2.4.26 / 8.2.4.27 BI Capability Structures */
> +#define CXL_BI_RT_CAPABILITY_LENGTH 0xC
> +#define CXL_BI_DECODER_CAPABILITY_LENGTH 0xC
>
> /* HDM decoders CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure */
> #define CXL_HDM_DECODER_CAP_OFFSET 0x0
> diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c
> index 99cf77b6b699..a527dd13fb68 100644
> --- a/drivers/cxl/port.c
> +++ b/drivers/cxl/port.c
> @@ -58,6 +58,47 @@ static int discover_region(struct device *dev, void *unused)
> return 0;
> }
>
> +static void cxl_port_map_bi(struct cxl_port *port)
> +{
> + struct cxl_register_map *map = &port->reg_map;
> + struct cxl_dport *parent_dport = port->parent_dport;
> + struct device *udev;
> + int cap_id;
> +
> + /* no upstream BI registers above host bridges or the cxl_root */
> + if (!parent_dport || is_cxl_root(parent_dport->port))
> + return;
> +
> + udev = is_cxl_endpoint(port) ?
> + port->uport_dev->parent : port->uport_dev;
> + if (!dev_is_pci(udev))
> + return;
> +
> + /* BI requires 256B Flit on the upstream link */
> + if (!cxl_pci_flit_256(to_pci_dev(udev)))
> + return;
> +
> + /* map this port's own BI capability */
> + if (is_cxl_endpoint(port)) {
> + if (!map->component_map.bi_decoder.valid) {
> + dev_dbg(&port->dev, "BI Decoder registers not found\n");
> + return;
> + }
> + cap_id = CXL_CM_CAP_CAP_ID_BI_DECODER;
> + } else {
> + if (!map->component_map.bi_rt.valid) {
> + dev_dbg(&port->dev, "BI RT registers not found\n");
> + return;
> + }
> + cap_id = CXL_CM_CAP_CAP_ID_BI_RT;
> + }
> +
> + map->host = &port->dev;
> + if (cxl_map_component_regs(map, &port->regs, BIT(cap_id)))
> + dev_dbg(&port->dev, "Failed to map BI capability 0x%x\n",
> + cap_id);
Do we need to distinguish an optional absent BI RT from an advertised BI RT
that failed to map?
In both cases port->regs.bi_rt is NULL, then cxl_is_bi_capable() accepts a NULL BI
pointer for a USP, and __cxl_bi_ctrl_dport() consequently skips __cxl_bi_commit_rt().
So a mapping failure of a present BI RT can be treated like the switch do not need a
route table.
I think we should treat mapping failure of BI RT differently.
Best regards,
Richard Cheng.
> +}
> +
> static int cxl_switch_port_probe(struct cxl_port *port)
> {
> /* Reset nr_dports for rebind of driver */
> @@ -128,6 +169,8 @@ static int cxl_endpoint_port_probe(struct cxl_port *port)
> read_cdat_data(port);
> cxl_endpoint_parse_cdat(port);
>
> + cxl_port_map_bi(port);
> +
> get_device(&cxlmd->dev);
> rc = devm_add_action_or_reset(&port->dev, schedule_detach, cxlmd);
> if (rc)
> @@ -252,6 +295,8 @@ static struct cxl_dport *cxl_port_add_dport(struct cxl_port *port,
> * on failure, or the device does not implement RAS registers.
> */
> devm_cxl_port_ras_setup(port);
> +
> + cxl_port_map_bi(port);
> }
>
> dport = devm_cxl_add_dport_by_dev(port, dport_dev);
> diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h
> index 016c74fb747c..2816954680b3 100644
> --- a/include/cxl/cxl.h
> +++ b/include/cxl/cxl.h
> @@ -34,10 +34,14 @@ struct cxl_regs {
> * Common set of CXL Component register block base pointers
> * @hdm_decoder: CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure
> * @ras: CXL 2.0 8.2.5.9 CXL RAS Capability Structure
> + * @bi_rt: CXL 4.0 8.2.4.26 CXL BI Route Table Capability Structure
> + * @bi_decoder: CXL 4.0 8.2.4.27 CXL BI Decoder Capability Structure
> */
> struct_group_tagged(cxl_component_regs, component,
> void __iomem *hdm_decoder;
> void __iomem *ras;
> + void __iomem *bi_rt;
> + void __iomem *bi_decoder;
> );
> /*
> * Common set of CXL Device register block base pointers
> @@ -80,6 +84,8 @@ struct cxl_reg_map {
> struct cxl_component_reg_map {
> struct cxl_reg_map hdm_decoder;
> struct cxl_reg_map ras;
> + struct cxl_reg_map bi_rt;
> + struct cxl_reg_map bi_decoder;
> };
>
> struct cxl_device_reg_map {
> --
> 2.39.5
>
next prev parent reply other threads:[~2026-08-07 5:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-28 14:41 [PATCH v7 0/8] cxl: Support Back-Invalidate Davidlohr Bueso
2026-07-28 14:41 ` [PATCH v7 1/8] cxl: Add BI register probing and port initialization Davidlohr Bueso
2026-08-04 21:13 ` Dave Jiang
2026-08-05 0:42 ` Alison Schofield
2026-08-05 10:41 ` Li Ming
2026-08-07 5:38 ` Richard Cheng [this message]
2026-07-28 14:41 ` [PATCH v7 2/8] cxl/pci: Add BI topology enable/disable Davidlohr Bueso
2026-07-28 15:16 ` sashiko-bot
2026-08-03 18:55 ` Davidlohr Bueso
2026-08-05 12:49 ` Li Ming
2026-08-05 13:33 ` Li Ming
2026-08-07 6:54 ` Richard Cheng
2026-07-28 14:41 ` [PATCH v7 3/8] cxl/hdm: Add BI coherency support for endpoint decoders Davidlohr Bueso
2026-07-28 15:26 ` sashiko-bot
2026-07-28 18:44 ` Davidlohr Bueso
2026-07-28 14:41 ` [PATCH v7 4/8] cxl: Add HDM-DB region creation Davidlohr Bueso
2026-08-04 22:28 ` Dave Jiang
2026-08-05 0:11 ` Alison Schofield
2026-08-05 19:10 ` Davidlohr Bueso
2026-08-07 11:50 ` Richard Cheng
2026-07-28 14:41 ` [PATCH v7 5/8] cxl/hdm: Rename decoder coherency flags Davidlohr Bueso
2026-08-05 1:13 ` Alison Schofield
2026-07-28 14:41 ` [PATCH v7 6/8] cxl/region: Log the coherency model at region creation Davidlohr Bueso
2026-08-04 22:51 ` Dave Jiang
2026-07-28 14:41 ` [PATCH v7 7/8] cxl/pci: Split BI capability probe from setup Davidlohr Bueso
2026-08-04 23:07 ` Dave Jiang
2026-07-28 14:41 ` [PATCH v7 8/8] cxl: Allow auto-committed BI hdm decoders Davidlohr Bueso
2026-07-28 15:46 ` sashiko-bot
2026-08-03 19:04 ` Davidlohr Bueso
2026-08-04 23:22 ` Dave Jiang
2026-08-05 0:51 ` Alison Schofield
2026-08-05 20:53 ` Davidlohr Bueso
2026-08-07 12:03 ` Richard Cheng
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=anVt9LtGbP8PzklF@MWDK4CY14F \
--to=icheng@nvidia.com \
--cc=alison.schofield@intel.com \
--cc=alucerop@amd.com \
--cc=benjamin.cheatham@amd.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=dongjoo.seo1@samsung.com \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
/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