From: Manikandan K Pillai <mpillai@cadence.com>
Add helper functions, register read, register write functions and update
platform data structures for supporting High Performance Architecture (HPA)
PCIe controllers from Cadence.
Signed-off-by: Manikandan K Pillai <mpillai@cadence.com>
Co-developed-by: Hans Zhang <hans.zhang@cixtech.com>
Signed-off-by: Hans Zhang <hans.zhang@cixtech.com>
---
.../controller/cadence/pcie-cadence-plat.c | 4 -
drivers/pci/controller/cadence/pcie-cadence.h | 111 ++++++++++++++++--
2 files changed, 103 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index ebd5c3afdfcd..b067a3296dd3 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -22,10 +22,6 @@ struct cdns_plat_pcie {
struct cdns_pcie *pcie;
};
-struct cdns_plat_pcie_of_data {
- bool is_rc;
-};
-
static const struct of_device_id cdns_plat_pcie_of_match[];
static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index ddfc44f8d3ef..1174cf597bb0 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -26,6 +26,20 @@ struct cdns_pcie_rp_ib_bar {
};
struct cdns_pcie;
+struct cdns_pcie_rc;
+
+enum cdns_pcie_reg_bank {
+ REG_BANK_RP,
+ REG_BANK_IP_REG,
+ REG_BANK_IP_CFG_CTRL_REG,
+ REG_BANK_AXI_MASTER_COMMON,
+ REG_BANK_AXI_MASTER,
+ REG_BANK_AXI_SLAVE,
+ REG_BANK_AXI_HLS,
+ REG_BANK_AXI_RAS,
+ REG_BANK_AXI_DTI,
+ REG_BANKS_MAX,
+};
struct cdns_pcie_ops {
int (*start_link)(struct cdns_pcie *pcie);
@@ -34,6 +48,30 @@ struct cdns_pcie_ops {
u64 (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
};
+/**
+ * struct cdns_plat_pcie_of_data - Register bank offset for a platform
+ * @is_rc: controller is a RC
+ * @ip_reg_bank_offset: ip register bank start offset
+ * @ip_cfg_ctrl_reg_offset: ip config control register start offset
+ * @axi_mstr_common_offset: AXI master common register start offset
+ * @axi_slave_offset: AXI slave start offset
+ * @axi_master_offset: AXI master start offset
+ * @axi_hls_offset: AXI HLS offset start
+ * @axi_ras_offset: AXI RAS offset
+ * @axi_dti_offset: AXI DTI offset
+ */
+struct cdns_plat_pcie_of_data {
+ u32 is_rc:1;
+ u32 ip_reg_bank_offset;
+ u32 ip_cfg_ctrl_reg_offset;
+ u32 axi_mstr_common_offset;
+ u32 axi_slave_offset;
+ u32 axi_master_offset;
+ u32 axi_hls_offset;
+ u32 axi_ras_offset;
+ u32 axi_dti_offset;
+};
+
/**
* struct cdns_pcie - private data for Cadence PCIe controller drivers
* @reg_base: IO mapped register base
@@ -45,16 +83,18 @@ struct cdns_pcie_ops {
* @link: list of pointers to corresponding device link representations
* @ops: Platform-specific ops to control various inputs from Cadence PCIe
* wrapper
+ * @cdns_pcie_reg_offsets: Register bank offsets for different SoC
*/
struct cdns_pcie {
- void __iomem *reg_base;
- struct resource *mem_res;
- struct device *dev;
- bool is_rc;
- int phy_count;
- struct phy **phy;
- struct device_link **link;
- const struct cdns_pcie_ops *ops;
+ void __iomem *reg_base;
+ struct resource *mem_res;
+ struct device *dev;
+ bool is_rc;
+ int phy_count;
+ struct phy **phy;
+ struct device_link **link;
+ const struct cdns_pcie_ops *ops;
+ const struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets;
};
/**
@@ -132,6 +172,40 @@ struct cdns_pcie_ep {
unsigned int quirk_disable_flr:1;
};
+static inline u32 cdns_reg_bank_to_off(struct cdns_pcie *pcie, enum cdns_pcie_reg_bank bank)
+{
+ u32 offset = 0x0;
+
+ switch (bank) {
+ case REG_BANK_IP_REG:
+ offset = pcie->cdns_pcie_reg_offsets->ip_reg_bank_offset;
+ break;
+ case REG_BANK_IP_CFG_CTRL_REG:
+ offset = pcie->cdns_pcie_reg_offsets->ip_cfg_ctrl_reg_offset;
+ break;
+ case REG_BANK_AXI_MASTER_COMMON:
+ offset = pcie->cdns_pcie_reg_offsets->axi_mstr_common_offset;
+ break;
+ case REG_BANK_AXI_MASTER:
+ offset = pcie->cdns_pcie_reg_offsets->axi_master_offset;
+ break;
+ case REG_BANK_AXI_SLAVE:
+ offset = pcie->cdns_pcie_reg_offsets->axi_slave_offset;
+ break;
+ case REG_BANK_AXI_HLS:
+ offset = pcie->cdns_pcie_reg_offsets->axi_hls_offset;
+ break;
+ case REG_BANK_AXI_RAS:
+ offset = pcie->cdns_pcie_reg_offsets->axi_ras_offset;
+ break;
+ case REG_BANK_AXI_DTI:
+ offset = pcie->cdns_pcie_reg_offsets->axi_dti_offset;
+ break;
+ default:
+ break;
+ };
+ return offset;
+}
/* Register access */
static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
@@ -144,6 +218,27 @@ static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
return readl(pcie->reg_base + reg);
}
+static inline void cdns_pcie_hpa_writel(struct cdns_pcie *pcie,
+ enum cdns_pcie_reg_bank bank,
+ u32 reg,
+ u32 value)
+{
+ u32 offset = cdns_reg_bank_to_off(pcie, bank);
+
+ reg += offset;
+ writel(value, pcie->reg_base + reg);
+}
+
+static inline u32 cdns_pcie_hpa_readl(struct cdns_pcie *pcie,
+ enum cdns_pcie_reg_bank bank,
+ u32 reg)
+{
+ u32 offset = cdns_reg_bank_to_off(pcie, bank);
+
+ reg += offset;
+ return readl(pcie->reg_base + reg);
+}
+
static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size)
{
void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
--
2.49.0
On Mon, Sep 01, 2025 at 05:20:42PM GMT, hans.zhang@cixtech.com wrote: > From: Manikandan K Pillai <mpillai@cadence.com> > > Add helper functions, register read, register write functions and update > platform data structures for supporting High Performance Architecture (HPA) > PCIe controllers from Cadence. > > Signed-off-by: Manikandan K Pillai <mpillai@cadence.com> > Co-developed-by: Hans Zhang <hans.zhang@cixtech.com> > Signed-off-by: Hans Zhang <hans.zhang@cixtech.com> Again, no need to split this into a separate patch. - Mani > --- > .../controller/cadence/pcie-cadence-plat.c | 4 - > drivers/pci/controller/cadence/pcie-cadence.h | 111 ++++++++++++++++-- > 2 files changed, 103 insertions(+), 12 deletions(-) > > diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c > index ebd5c3afdfcd..b067a3296dd3 100644 > --- a/drivers/pci/controller/cadence/pcie-cadence-plat.c > +++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c > @@ -22,10 +22,6 @@ struct cdns_plat_pcie { > struct cdns_pcie *pcie; > }; > > -struct cdns_plat_pcie_of_data { > - bool is_rc; > -}; > - > static const struct of_device_id cdns_plat_pcie_of_match[]; > > static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr) > diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h > index ddfc44f8d3ef..1174cf597bb0 100644 > --- a/drivers/pci/controller/cadence/pcie-cadence.h > +++ b/drivers/pci/controller/cadence/pcie-cadence.h > @@ -26,6 +26,20 @@ struct cdns_pcie_rp_ib_bar { > }; > > struct cdns_pcie; > +struct cdns_pcie_rc; > + > +enum cdns_pcie_reg_bank { > + REG_BANK_RP, > + REG_BANK_IP_REG, > + REG_BANK_IP_CFG_CTRL_REG, > + REG_BANK_AXI_MASTER_COMMON, > + REG_BANK_AXI_MASTER, > + REG_BANK_AXI_SLAVE, > + REG_BANK_AXI_HLS, > + REG_BANK_AXI_RAS, > + REG_BANK_AXI_DTI, > + REG_BANKS_MAX, > +}; > > struct cdns_pcie_ops { > int (*start_link)(struct cdns_pcie *pcie); > @@ -34,6 +48,30 @@ struct cdns_pcie_ops { > u64 (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr); > }; > > +/** > + * struct cdns_plat_pcie_of_data - Register bank offset for a platform > + * @is_rc: controller is a RC > + * @ip_reg_bank_offset: ip register bank start offset > + * @ip_cfg_ctrl_reg_offset: ip config control register start offset > + * @axi_mstr_common_offset: AXI master common register start offset > + * @axi_slave_offset: AXI slave start offset > + * @axi_master_offset: AXI master start offset > + * @axi_hls_offset: AXI HLS offset start > + * @axi_ras_offset: AXI RAS offset > + * @axi_dti_offset: AXI DTI offset > + */ > +struct cdns_plat_pcie_of_data { > + u32 is_rc:1; > + u32 ip_reg_bank_offset; > + u32 ip_cfg_ctrl_reg_offset; > + u32 axi_mstr_common_offset; > + u32 axi_slave_offset; > + u32 axi_master_offset; > + u32 axi_hls_offset; > + u32 axi_ras_offset; > + u32 axi_dti_offset; > +}; > + > /** > * struct cdns_pcie - private data for Cadence PCIe controller drivers > * @reg_base: IO mapped register base > @@ -45,16 +83,18 @@ struct cdns_pcie_ops { > * @link: list of pointers to corresponding device link representations > * @ops: Platform-specific ops to control various inputs from Cadence PCIe > * wrapper > + * @cdns_pcie_reg_offsets: Register bank offsets for different SoC > */ > struct cdns_pcie { > - void __iomem *reg_base; > - struct resource *mem_res; > - struct device *dev; > - bool is_rc; > - int phy_count; > - struct phy **phy; > - struct device_link **link; > - const struct cdns_pcie_ops *ops; > + void __iomem *reg_base; > + struct resource *mem_res; > + struct device *dev; > + bool is_rc; > + int phy_count; > + struct phy **phy; > + struct device_link **link; > + const struct cdns_pcie_ops *ops; > + const struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets; > }; > > /** > @@ -132,6 +172,40 @@ struct cdns_pcie_ep { > unsigned int quirk_disable_flr:1; > }; > > +static inline u32 cdns_reg_bank_to_off(struct cdns_pcie *pcie, enum cdns_pcie_reg_bank bank) > +{ > + u32 offset = 0x0; > + > + switch (bank) { > + case REG_BANK_IP_REG: > + offset = pcie->cdns_pcie_reg_offsets->ip_reg_bank_offset; > + break; > + case REG_BANK_IP_CFG_CTRL_REG: > + offset = pcie->cdns_pcie_reg_offsets->ip_cfg_ctrl_reg_offset; > + break; > + case REG_BANK_AXI_MASTER_COMMON: > + offset = pcie->cdns_pcie_reg_offsets->axi_mstr_common_offset; > + break; > + case REG_BANK_AXI_MASTER: > + offset = pcie->cdns_pcie_reg_offsets->axi_master_offset; > + break; > + case REG_BANK_AXI_SLAVE: > + offset = pcie->cdns_pcie_reg_offsets->axi_slave_offset; > + break; > + case REG_BANK_AXI_HLS: > + offset = pcie->cdns_pcie_reg_offsets->axi_hls_offset; > + break; > + case REG_BANK_AXI_RAS: > + offset = pcie->cdns_pcie_reg_offsets->axi_ras_offset; > + break; > + case REG_BANK_AXI_DTI: > + offset = pcie->cdns_pcie_reg_offsets->axi_dti_offset; > + break; > + default: > + break; > + }; > + return offset; > +} > > /* Register access */ > static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value) > @@ -144,6 +218,27 @@ static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg) > return readl(pcie->reg_base + reg); > } > > +static inline void cdns_pcie_hpa_writel(struct cdns_pcie *pcie, > + enum cdns_pcie_reg_bank bank, > + u32 reg, > + u32 value) > +{ > + u32 offset = cdns_reg_bank_to_off(pcie, bank); > + > + reg += offset; > + writel(value, pcie->reg_base + reg); > +} > + > +static inline u32 cdns_pcie_hpa_readl(struct cdns_pcie *pcie, > + enum cdns_pcie_reg_bank bank, > + u32 reg) > +{ > + u32 offset = cdns_reg_bank_to_off(pcie, bank); > + > + reg += offset; > + return readl(pcie->reg_base + reg); > +} > + > static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size) > { > void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4); > -- > 2.49.0 > -- மணிவண்ணன் சதாசிவம்
© 2016 - 2025 Red Hat, Inc.