cxl: Move pci generic code from cxl_pci to core/cxl_pci
Inside cxl/core/pci.c there are helpers for CXL PCIe initialization meanwhile cxl/pci_drv.c implements the functionality for a Type3 device initialization. In preparation for type2 support, move helper functions from cxl/pci.c to cxl/core/pci.c in order to be exported and used by type2 drivers. [ dj: Clarified subject. ] Signed-off-by: Alejandro Lucero <alucerop@amd.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Gregory Price <gourry@gourry.net> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Signed-off-by: Gregory Price <gourry@gourry.net> Link: https://patch.msgid.link/20260306164741.3796372-4-alejandro.lucero-palau@amd.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>master
parent
005869886d
commit
58f28930c7
|
|
@ -224,4 +224,6 @@ int cxl_set_feature(struct cxl_mailbox *cxl_mbox, const uuid_t *feat_uuid,
|
|||
u16 *return_code);
|
||||
#endif
|
||||
|
||||
resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
|
||||
struct cxl_dport *dport);
|
||||
#endif /* __CXL_CORE_H__ */
|
||||
|
|
|
|||
|
|
@ -696,6 +696,68 @@ bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
|
|||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, "CXL");
|
||||
|
||||
static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
|
||||
struct cxl_register_map *map,
|
||||
struct cxl_dport *dport)
|
||||
{
|
||||
resource_size_t component_reg_phys;
|
||||
|
||||
*map = (struct cxl_register_map) {
|
||||
.host = &pdev->dev,
|
||||
.resource = CXL_RESOURCE_NONE,
|
||||
};
|
||||
|
||||
struct cxl_port *port __free(put_cxl_port) =
|
||||
cxl_pci_find_port(pdev, &dport);
|
||||
if (!port)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
|
||||
if (component_reg_phys == CXL_RESOURCE_NONE)
|
||||
return -ENXIO;
|
||||
|
||||
map->resource = component_reg_phys;
|
||||
map->reg_type = CXL_REGLOC_RBI_COMPONENT;
|
||||
map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
|
||||
struct cxl_register_map *map)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = cxl_find_regblock(pdev, type, map);
|
||||
|
||||
/*
|
||||
* If the Register Locator DVSEC does not exist, check if it
|
||||
* is an RCH and try to extract the Component Registers from
|
||||
* an RCRB.
|
||||
*/
|
||||
if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev)) {
|
||||
struct cxl_dport *dport;
|
||||
struct cxl_port *port __free(put_cxl_port) =
|
||||
cxl_pci_find_port(pdev, &dport);
|
||||
if (!port)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
rc = cxl_rcrb_get_comp_regs(pdev, map, dport);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cxl_dport_map_rcd_linkcap(pdev, dport);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
} else if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return cxl_setup_regs(map);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cxl_pci_setup_regs, "CXL");
|
||||
|
||||
int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c)
|
||||
{
|
||||
int speed, bw;
|
||||
|
|
|
|||
|
|
@ -641,4 +641,3 @@ resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
|
|||
return CXL_RESOURCE_NONE;
|
||||
return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, "CXL");
|
||||
|
|
|
|||
|
|
@ -222,8 +222,6 @@ int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
|
|||
struct cxl_register_map *map);
|
||||
int cxl_setup_regs(struct cxl_register_map *map);
|
||||
struct cxl_dport;
|
||||
resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
|
||||
struct cxl_dport *dport);
|
||||
int cxl_dport_map_rcd_linkcap(struct pci_dev *pdev, struct cxl_dport *dport);
|
||||
|
||||
#define CXL_RESOURCE_NONE ((resource_size_t) -1)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,17 @@ static inline bool cxl_pci_flit_256(struct pci_dev *pdev)
|
|||
return lnksta2 & PCI_EXP_LNKSTA2_FLIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that the caller has already validated that @pdev has CXL
|
||||
* capabilities, any RCiEP with CXL capabilities is treated as a
|
||||
* Restricted CXL Device (RCD) and finds upstream port and endpoint
|
||||
* registers in a Root Complex Register Block (RCRB).
|
||||
*/
|
||||
static inline bool is_cxl_restricted(struct pci_dev *pdev)
|
||||
{
|
||||
return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
|
||||
}
|
||||
|
||||
struct cxl_dev_state;
|
||||
void read_cdat_data(struct cxl_port *port);
|
||||
|
||||
|
|
@ -101,4 +112,6 @@ static inline void devm_cxl_port_ras_setup(struct cxl_port *port)
|
|||
}
|
||||
#endif
|
||||
|
||||
int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
|
||||
struct cxl_register_map *map);
|
||||
#endif /* __CXL_PCI_H__ */
|
||||
|
|
|
|||
|
|
@ -465,76 +465,6 @@ static int cxl_pci_setup_mailbox(struct cxl_memdev_state *mds, bool irq_avail)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that any RCIEP that emits the CXL memory expander class code
|
||||
* is an RCD
|
||||
*/
|
||||
static bool is_cxl_restricted(struct pci_dev *pdev)
|
||||
{
|
||||
return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END;
|
||||
}
|
||||
|
||||
static int cxl_rcrb_get_comp_regs(struct pci_dev *pdev,
|
||||
struct cxl_register_map *map,
|
||||
struct cxl_dport *dport)
|
||||
{
|
||||
resource_size_t component_reg_phys;
|
||||
|
||||
*map = (struct cxl_register_map) {
|
||||
.host = &pdev->dev,
|
||||
.resource = CXL_RESOURCE_NONE,
|
||||
};
|
||||
|
||||
struct cxl_port *port __free(put_cxl_port) =
|
||||
cxl_pci_find_port(pdev, &dport);
|
||||
if (!port)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
component_reg_phys = cxl_rcd_component_reg_phys(&pdev->dev, dport);
|
||||
if (component_reg_phys == CXL_RESOURCE_NONE)
|
||||
return -ENXIO;
|
||||
|
||||
map->resource = component_reg_phys;
|
||||
map->reg_type = CXL_REGLOC_RBI_COMPONENT;
|
||||
map->max_size = CXL_COMPONENT_REG_BLOCK_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type,
|
||||
struct cxl_register_map *map)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = cxl_find_regblock(pdev, type, map);
|
||||
|
||||
/*
|
||||
* If the Register Locator DVSEC does not exist, check if it
|
||||
* is an RCH and try to extract the Component Registers from
|
||||
* an RCRB.
|
||||
*/
|
||||
if (rc && type == CXL_REGLOC_RBI_COMPONENT && is_cxl_restricted(pdev)) {
|
||||
struct cxl_dport *dport;
|
||||
struct cxl_port *port __free(put_cxl_port) =
|
||||
cxl_pci_find_port(pdev, &dport);
|
||||
if (!port)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
rc = cxl_rcrb_get_comp_regs(pdev, map, dport);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cxl_dport_map_rcd_linkcap(pdev, dport);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
} else if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return cxl_setup_regs(map);
|
||||
}
|
||||
|
||||
static void free_event_buf(void *buf)
|
||||
{
|
||||
kvfree(buf);
|
||||
|
|
|
|||
Loading…
Reference in New Issue