Message ID | 20240610082222.22772-2-kobayashi.da-06@fujitsu.com |
---|---|
State | New, archived |
Headers | show |
Series | cxl: Export cxl1.1 device link status to sysfs | expand |
On Mon, 10 Jun 2024 17:22:21 +0900 "Kobayashi,Daisuke" <kobayashi.da-06@fujitsu.com> wrote: > Add rcd_pcie_cap and its initialization at __rcrb_to_component() to cache > the offset of cxl1.1 device link status information. By caching it, avoid > the walking memory map area to find the offset when output the register value. > > Signed-off-by: "Kobayashi,Daisuke" <kobayashi.da-06@fujitsu.com> Hi. This is getting closer, but a few minor comments inline on the implementation. Thanks, Jonathan > --- > drivers/cxl/core/core.h | 4 ++++ > drivers/cxl/core/regs.c | 26 +++++++++++++++++++++++++- > drivers/cxl/cxl.h | 9 +++++++++ > 3 files changed, 38 insertions(+), 1 deletion(-) > > diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h > index 3b64fb1b9ed0..42e3483b4a14 100644 > --- a/drivers/cxl/core/core.h > +++ b/drivers/cxl/core/core.h > @@ -75,6 +75,10 @@ resource_size_t __rcrb_to_component(struct device *dev, > enum cxl_rcrb which); > u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb); > > +#define PCI_RCRB_CAP_LIST_ID_MASK GENMASK(7, 0) > +#define PCI_RCRB_CAP_HDR_ID_MASK GENMASK(7, 0) > +#define PCI_RCRB_CAP_HDR_NEXT_MASK GENMASK(15, 8) > + > extern struct rw_semaphore cxl_dpa_rwsem; > extern struct rw_semaphore cxl_region_rwsem; > > diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c > index 372786f80955..cc1ce5e032e2 100644 > --- a/drivers/cxl/core/regs.c > +++ b/drivers/cxl/core/regs.c > @@ -514,6 +514,8 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri > u32 bar0, bar1; > u16 cmd; > u32 id; > + u16 offset; > + u32 cap_hdr; > > if (which == CXL_RCRB_UPSTREAM) > rcrb += SZ_4K; > @@ -537,6 +539,17 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri > cmd = readw(addr + PCI_COMMAND); > bar0 = readl(addr + PCI_BASE_ADDRESS_0); > bar1 = readl(addr + PCI_BASE_ADDRESS_1); > + offset = FIELD_GET(PCI_RCRB_CAP_LIST_ID_MASK, readw(addr + PCI_CAPABILITY_LIST)); > + cap_hdr = readl(addr + offset); > + while ((FIELD_GET(PCI_RCRB_CAP_HDR_ID_MASK, cap_hdr)) != PCI_CAP_ID_EXP) { > + offset = FIELD_GET(PCI_RCRB_CAP_HDR_NEXT_MASK, cap_hdr); > + if (offset == 0 || offset > SZ_4K) > + break; > + cap_hdr = readl(addr + offset); > + } > + if (offset) If offset > SZ_4K? I'd make it 0 at the check inside the loop. > + ri->rcd_pcie_cap = offset; > + > iounmap(addr); > release_mem_region(rcrb, SZ_4K); > > @@ -572,8 +585,19 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri > resource_size_t cxl_rcd_component_reg_phys(struct device *dev, > struct cxl_dport *dport) > { > + void __iomem *dport_pcie_cap = NULL; > + resource_size_t rcd_pcie_offset, ret; blank line here. I'd also reduce the scope of rcd_pcie_offset. > if (!dport->rch) > return CXL_RESOURCE_NONE; > - return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); > + > + ret = __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); > + if (dport->rcrb.rcd_pcie_cap) { > + rcd_pcie_offset = dport->rcrb.base + dport->rcrb.rcd_pcie_cap; > + dport_pcie_cap = devm_cxl_iomap_block(dev, rcd_pcie_offset, > + sizeof(u8) * 0x42); Something odd here with alignment. I guess tab width 4 rather than 8 in your editor? Also, add a define for the 0x42 I think. Directly assign into dport->regs.rcd_pcie_cap having made change suggested below. > + } > + dport->regs.rcd_pcie_cap = dport_pcie_cap; Why not move this in the brackets? I think you can rely on the regs structuring being initialized to zero for the 'else' path. > + > + return ret; > } >
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 3b64fb1b9ed0..42e3483b4a14 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -75,6 +75,10 @@ resource_size_t __rcrb_to_component(struct device *dev, enum cxl_rcrb which); u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb); +#define PCI_RCRB_CAP_LIST_ID_MASK GENMASK(7, 0) +#define PCI_RCRB_CAP_HDR_ID_MASK GENMASK(7, 0) +#define PCI_RCRB_CAP_HDR_NEXT_MASK GENMASK(15, 8) + extern struct rw_semaphore cxl_dpa_rwsem; extern struct rw_semaphore cxl_region_rwsem; diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index 372786f80955..cc1ce5e032e2 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -514,6 +514,8 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri u32 bar0, bar1; u16 cmd; u32 id; + u16 offset; + u32 cap_hdr; if (which == CXL_RCRB_UPSTREAM) rcrb += SZ_4K; @@ -537,6 +539,17 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri cmd = readw(addr + PCI_COMMAND); bar0 = readl(addr + PCI_BASE_ADDRESS_0); bar1 = readl(addr + PCI_BASE_ADDRESS_1); + offset = FIELD_GET(PCI_RCRB_CAP_LIST_ID_MASK, readw(addr + PCI_CAPABILITY_LIST)); + cap_hdr = readl(addr + offset); + while ((FIELD_GET(PCI_RCRB_CAP_HDR_ID_MASK, cap_hdr)) != PCI_CAP_ID_EXP) { + offset = FIELD_GET(PCI_RCRB_CAP_HDR_NEXT_MASK, cap_hdr); + if (offset == 0 || offset > SZ_4K) + break; + cap_hdr = readl(addr + offset); + } + if (offset) + ri->rcd_pcie_cap = offset; + iounmap(addr); release_mem_region(rcrb, SZ_4K); @@ -572,8 +585,19 @@ resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri resource_size_t cxl_rcd_component_reg_phys(struct device *dev, struct cxl_dport *dport) { + void __iomem *dport_pcie_cap = NULL; + resource_size_t rcd_pcie_offset, ret; if (!dport->rch) return CXL_RESOURCE_NONE; - return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); + + ret = __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM); + if (dport->rcrb.rcd_pcie_cap) { + rcd_pcie_offset = dport->rcrb.base + dport->rcrb.rcd_pcie_cap; + dport_pcie_cap = devm_cxl_iomap_block(dev, rcd_pcie_offset, + sizeof(u8) * 0x42); + } + dport->regs.rcd_pcie_cap = dport_pcie_cap; + + return ret; } EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, CXL); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 003feebab79b..fc9e0dbd5932 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -230,6 +230,14 @@ struct cxl_regs { struct_group_tagged(cxl_rch_regs, rch_regs, void __iomem *dport_aer; ); + + /* + * RCD upstream port specific PCIe cap register + * @pcie_cap: CXL 3.0 8.2.1.2 RCD Upstream Port RCRB + */ + struct_group_tagged(cxl_rcd_regs, rcd_regs, + void __iomem *rcd_pcie_cap; + ); }; struct cxl_reg_map { @@ -646,6 +654,7 @@ cxl_find_dport_by_dev(struct cxl_port *port, const struct device *dport_dev) struct cxl_rcrb_info { resource_size_t base; + u16 rcd_pcie_cap; u16 aer_cap; };
Add rcd_pcie_cap and its initialization at __rcrb_to_component() to cache the offset of cxl1.1 device link status information. By caching it, avoid the walking memory map area to find the offset when output the register value. Signed-off-by: "Kobayashi,Daisuke" <kobayashi.da-06@fujitsu.com> --- drivers/cxl/core/core.h | 4 ++++ drivers/cxl/core/regs.c | 26 +++++++++++++++++++++++++- drivers/cxl/cxl.h | 9 +++++++++ 3 files changed, 38 insertions(+), 1 deletion(-)