[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsmes7ty2i2irzozpbwno562zi25lebxrcejd7biltjtsnb36z@6vhtqwrr4cpk>
Date: Sat, 30 Aug 2025 18:48:03 +0530
From: Manivannan Sadhasivam <mani@...nel.org>
To: hans.zhang@...tech.com
Cc: bhelgaas@...gle.com, lpieralisi@...nel.org, kw@...ux.com,
robh@...nel.org, kwilczynski@...nel.org, krzk+dt@...nel.org, conor+dt@...nel.org,
mpillai@...ence.com, fugang.duan@...tech.com, guoyin.chen@...tech.com,
peter.chen@...tech.com, cix-kernel-upstream@...tech.com, linux-pci@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v8 08/15] PCI: cadence: Add support for High Perf
Architecture (HPA) controller
On Tue, Aug 19, 2025 at 07:52:32PM GMT, hans.zhang@...tech.com wrote:
> From: Manikandan K Pillai <mpillai@...ence.com>
>
> Add support for Cadence PCIe RP and EP configuration for High
> Performance Architecture (HPA) controllers.
>
Add more info about the controller.
> Signed-off-by: Manikandan K Pillai <mpillai@...ence.com>
> Co-developed-by: Hans Zhang <hans.zhang@...tech.com>
> Signed-off-by: Hans Zhang <hans.zhang@...tech.com>
> ---
> drivers/pci/controller/cadence/Makefile | 10 +-
> .../controller/cadence/pcie-cadence-ep-hpa.c | 528 ++++++++++++++++
> .../cadence/pcie-cadence-host-hpa.c | 585 ++++++++++++++++++
> .../pci/controller/cadence/pcie-cadence-hpa.c | 204 ++++++
That's a combined 1200+ loc in a single patch, which is very difficult to
review. You should've split it into atleast two.
> drivers/pci/controller/cadence/pcie-cadence.c | 11 +
> drivers/pci/controller/cadence/pcie-cadence.h | 74 ++-
> 6 files changed, 1403 insertions(+), 9 deletions(-)
> create mode 100644 drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
> create mode 100644 drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
> create mode 100644 drivers/pci/controller/cadence/pcie-cadence-hpa.c
>
> diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
> index b104562fb86a..de4ddae7aca4 100644
> --- a/drivers/pci/controller/cadence/Makefile
> +++ b/drivers/pci/controller/cadence/Makefile
> @@ -1,6 +1,10 @@
> # SPDX-License-Identifier: GPL-2.0
> -obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence-common.o pcie-cadence.o
> -obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-common.o pcie-cadence-host.o
> -obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-common.o pcie-cadence-ep.o
> +pcie-cadence-mod-y := pcie-cadence-hpa.o pcie-cadence-common.o pcie-cadence.o
> +pcie-cadence-host-mod-y := pcie-cadence-host-common.o pcie-cadence-host.o pcie-cadence-host-hpa.o
> +pcie-cadence-ep-mod-y := pcie-cadence-ep-common.o pcie-cadence-ep.o pcie-cadence-ep-hpa.o
> +
> +obj-$(CONFIG_PCIE_CADENCE) = pcie-cadence-mod.o
> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host-mod.o
> +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep-mod.o
> obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
> obj-$(CONFIG_PCI_J721E) += pci-j721e.o
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
> new file mode 100644
> index 000000000000..a5366ecec34f
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep-hpa.c
> @@ -0,0 +1,528 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe endpoint controller driver.
> +// Author: Manikandan K Pillai <mpillai@...ence.com>
> +
> +#include <linux/bitfield.h>
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/pci-epc.h>
> +#include <linux/platform_device.h>
> +#include <linux/sizes.h>
> +
> +#include "pcie-cadence.h"
> +#include "pcie-cadence-ep-common.h"
> +
> +static int cdns_pcie_hpa_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
> + phys_addr_t addr, u64 pci_addr, size_t size)
> +{
> + struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> + struct cdns_pcie *pcie = &ep->pcie;
> + u32 r;
> +
> + r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG);
> + if (r >= ep->max_regions - 1) {
> + dev_err(&epc->dev, "no free outbound region\n");
> + return -EINVAL;
-ENOSPC
> + }
> +
> + fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> + cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
> +
> + set_bit(r, &ep->ob_region_map);
> + ep->ob_addr[r] = addr;
> +
> + return 0;
> +}
> +
> +static void cdns_pcie_hpa_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
> + phys_addr_t addr)
> +{
> + struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> + struct cdns_pcie *pcie = &ep->pcie;
> + u32 r;
> +
> + for (r = 0; r < ep->max_regions - 1; r++)
> + if (ep->ob_addr[r] == addr)
> + break;
> +
> + if (r == ep->max_regions - 1)
> + return;
> +
> + cdns_pcie_hpa_reset_outbound_region(pcie, r);
> +
> + ep->ob_addr[r] = 0;
> + clear_bit(r, &ep->ob_region_map);
> +}
> +
> +static void cdns_pcie_hpa_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
> + bool assert)
> +{
> + struct cdns_pcie *pcie = &ep->pcie;
> + unsigned long flags;
> + u32 offset;
> + u16 status;
> + u8 msg_code;
> +
> + intx &= 3;
> +
> + /* Set the outbound region if needed */
> + if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
> + ep->irq_pci_fn != fn)) {
> + /* First region was reserved for IRQ writes */
> + cdns_pcie_hpa_set_outbound_region_for_normal_msg(pcie, 0, fn, 0, ep->irq_phys_addr);
> + ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
> + ep->irq_pci_fn = fn;
> + }
> +
> + if (assert) {
> + ep->irq_pending |= BIT(intx);
> + msg_code = PCIE_MSG_CODE_ASSERT_INTA + intx;
> + } else {
> + ep->irq_pending &= ~BIT(intx);
> + msg_code = PCIE_MSG_CODE_DEASSERT_INTA + intx;
> + }
> +
> + spin_lock_irqsave(&ep->lock, flags);
> + status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
> + if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
> + status ^= PCI_STATUS_INTERRUPT;
> + cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
> + }
> + spin_unlock_irqrestore(&ep->lock, flags);
> +
> + offset = CDNS_PCIE_NORMAL_MSG_ROUTING(PCIE_MSG_TYPE_R_RC) |
> + CDNS_PCIE_NORMAL_MSG_CODE(msg_code);
> + writel(0, ep->irq_cpu_addr + offset);
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_intx_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> + u8 intx)
> +{
> + u16 cmd;
> +
> + cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
> + if (cmd & PCI_COMMAND_INTX_DISABLE)
> + return -EINVAL;
> +
> + cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, true);
> +
> + /* The mdelay() value was taken from dra7xx_pcie_raise_intx_irq() */
> + mdelay(1);
AFAIK, this 1ms delay is not fixed per the PCIe spec. It depends on how the host
interrupt controller detects the level triggered interrupt. So I don't think
this 1ms delay will work with all host systems.
> + cdns_pcie_hpa_ep_assert_intx(ep, fn, intx, false);
> + return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> + u8 interrupt_num)
> +{
> + struct cdns_pcie *pcie = &ep->pcie;
> + u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
> + u16 flags, mme, data, data_mask;
> + u8 msi_count;
> + u64 pci_addr, pci_addr_mask = 0xff;
> +
> + fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +
> + /* Check whether the MSI feature has been enabled by the PCI host */
> + flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
> + if (!(flags & PCI_MSI_FLAGS_ENABLE))
> + return -EINVAL;
-EOPNOTSUPP
> +
> + /* Get the number of enabled MSIs */
> + mme = FIELD_GET(PCI_MSI_FLAGS_QSIZE, flags);
> + msi_count = 1 << mme;
> + if (!interrupt_num || interrupt_num > msi_count)
> + return -EINVAL;
> +
> + /* Compute the data value to be written */
> + data_mask = msi_count - 1;
> + data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
> + data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
> +
> + /* Get the PCI address where to write the data into */
> + pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
> + pci_addr <<= 32;
> + pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
> + pci_addr &= GENMASK_ULL(63, 2);
> +
> + /* Set the outbound region if needed */
> + if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
> + ep->irq_pci_fn != fn)) {
> + /* First region was reserved for IRQ writes */
> + cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
> + false,
> + ep->irq_phys_addr,
> + pci_addr & ~pci_addr_mask,
> + pci_addr_mask + 1);
> + ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
> + ep->irq_pci_fn = fn;
> + }
> + writel(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
> +
> + return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
> + u16 interrupt_num)
> +{
> + u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
> + u32 tbl_offset, msg_data, reg;
> + struct cdns_pcie *pcie = &ep->pcie;
> + struct pci_epf_msix_tbl *msix_tbl;
> + struct cdns_pcie_epf *epf;
> + u64 pci_addr_mask = 0xff;
> + u64 msg_addr;
> + u16 flags;
> + u8 bir;
> +
> + epf = &ep->epf[fn];
> + if (vfn > 0)
> + epf = &epf->epf[vfn - 1];
> +
> + fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +
> + /* Check whether the MSI-X feature has been enabled by the PCI host */
> + flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
> + if (!(flags & PCI_MSIX_FLAGS_ENABLE))
> + return -EINVAL;
-EOPNOTSUPP
> +
> + reg = cap + PCI_MSIX_TABLE;
> + tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg);
> + bir = FIELD_GET(PCI_MSIX_TABLE_BIR, tbl_offset);
> + tbl_offset &= PCI_MSIX_TABLE_OFFSET;
> +
> + msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
> + msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
> + msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
> +
> + /* Set the outbound region if needed */
> + if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
> + ep->irq_pci_fn != fn) {
> + /* First region was reserved for IRQ writes */
> + cdns_pcie_hpa_set_outbound_region(pcie, 0, fn, 0,
> + false,
> + ep->irq_phys_addr,
> + msg_addr & ~pci_addr_mask,
> + pci_addr_mask + 1);
> + ep->irq_pci_addr = (msg_addr & ~pci_addr_mask);
> + ep->irq_pci_fn = fn;
> + }
> + writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask));
> +
> + return 0;
> +}
> +
> +static int cdns_pcie_hpa_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
> + unsigned int type, u16 interrupt_num)
> +{
> + struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> + struct cdns_pcie *pcie = &ep->pcie;
> + struct device *dev = pcie->dev;
> +
> + switch (type) {
> + case PCI_IRQ_INTX:
> + if (vfn > 0) {
> + dev_err(dev, "Cannot raise INTX interrupts for VF\n");
> + return -EINVAL;
-EOPNOTSUPP
> + }
> + return cdns_pcie_hpa_ep_raise_intx_irq(ep, fn, vfn, 0);
> +
No need of newline
> + case PCI_IRQ_MSI:
> + return cdns_pcie_hpa_ep_raise_msi_irq(ep, fn, vfn, interrupt_num);
> +
> + case PCI_IRQ_MSIX:
> + return cdns_pcie_hpa_ep_raise_msix_irq(ep, fn, vfn, interrupt_num);
> +
> + default:
> + break;
> + }
> +
> + return -EINVAL;
> +}
> +
[...]
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
> new file mode 100644
> index 000000000000..b2e570f2c047
> --- /dev/null
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host-hpa.c
> @@ -0,0 +1,585 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (c) 2017 Cadence
> +// Cadence PCIe host controller driver.
> +// Author: Manikandan K Pillai <mpillai@...ence.com>
> +
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/list_sort.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
> +#include <linux/platform_device.h>
> +
> +#include "pcie-cadence.h"
> +#include "pcie-cadence-host-common.h"
> +
> +static u8 bar_aperture_mask[] = {
> + [RP_BAR0] = 0x1F,
> + [RP_BAR1] = 0xF,
Use lowercase for hex.
> +};
> +
[...]
> +static void cdns_pcie_hpa_create_region_for_ecam(struct cdns_pcie_rc *rc)
> +{
> + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc);
> + struct resource *cfg_res = rc->cfg_res;
> + struct cdns_pcie *pcie = &rc->pcie;
> + u32 value, root_port_req_id_reg, pcie_bus_number_reg;
> + u32 ecam_addr_0, region_size_0, request_id_0;
> + int busnr = 0, secbus = 0, subbus = 0;
> + struct resource_entry *entry;
> + resource_size_t size;
> + u32 axi_address_low;
> + int nbits;
> + u64 sz;
> +
> + entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
> + if (entry) {
> + busnr = entry->res->start;
> + secbus = (busnr < 0xff) ? (busnr + 1) : 0xff;
> + subbus = entry->res->end;
> + }
> + size = resource_size(cfg_res);
> + sz = 1ULL << fls64(size - 1);
> + nbits = ilog2(sz);
> + if (nbits < 8)
> + nbits = 8;
> +
> + root_port_req_id_reg = ((busnr & 0xff) << 8);
> + pcie_bus_number_reg = ((subbus & 0xff) << 16) | ((secbus & 0xff) << 8) |
> + (busnr & 0xff);
> + ecam_addr_0 = cfg_res->start;
> + region_size_0 = nbits - 1;
> + request_id_0 = ((busnr & 0xff) << 8);
> +
> +#define CDNS_PCIE_HPA_TAG_MANAGEMENT (0x0)
Do not use inline definitions. Define them at the start of the file.
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_TAG_MANAGEMENT, 0x200000);
> +
> + /* Taking slave err as OKAY */
> +#define CDNS_PCIE_HPA_SLAVE_RESP (0x100)
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE, CDNS_PCIE_HPA_SLAVE_RESP,
> + 0x0);
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_SLAVE_RESP + 0x4, 0x0);
> +
> + /* Program the register "i_root_port_req_id_reg" with RP's BDF */
> +#define I_ROOT_PORT_REQ_ID_REG (0x141c)
> + cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, I_ROOT_PORT_REQ_ID_REG,
> + root_port_req_id_reg);
> +
> + /**
> + * Program the register "i_pcie_bus_numbers" with Primary(RP's bus number),
> + * secondary and subordinate bus numbers
> + */
> +#define I_PCIE_BUS_NUMBERS (CDNS_PCIE_HPA_RP_BASE + 0x18)
> + cdns_pcie_hpa_writel(pcie, REG_BANK_RP, I_PCIE_BUS_NUMBERS,
> + pcie_bus_number_reg);
> +
> + /* Program the register "lm_hal_sbsa_ctrl[0]" to enable the sbsa */
> +#define LM_HAL_SBSA_CTRL (0x1170)
> + value = cdns_pcie_hpa_readl(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL);
> + value |= BIT(0);
> + cdns_pcie_hpa_writel(pcie, REG_BANK_IP_REG, LM_HAL_SBSA_CTRL, value);
> +
> + /* Program region[0] for ECAM */
> + axi_address_low = (ecam_addr_0 & 0xfff00000) | region_size_0;
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR0(0),
> + axi_address_low);
> +
> + /* rc0-high-axi-address */
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_CPU_ADDR1(0), 0x0);
> + /* Type-1 CFG */
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_DESC0(0), 0x05000000);
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_DESC1(0),
> + (request_id_0 << 16));
> +
> + /* All AXI bits pass through PCIe */
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR0(0), 0x1b);
> + /* PCIe address-high */
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_PCI_ADDR1(0), 0);
> + cdns_pcie_hpa_writel(pcie, REG_BANK_AXI_SLAVE,
> + CDNS_PCIE_HPA_AT_OB_REGION_CTRL0(0), 0x06000000);
> +}
[...]
> +int cdns_pcie_hpa_host_link_setup(struct cdns_pcie_rc *rc)
> +{
> + struct cdns_pcie *pcie = &rc->pcie;
> + struct device *dev = rc->pcie.dev;
> + int ret;
> +
> + if (rc->quirk_detect_quiet_flag)
> + cdns_pcie_hpa_detect_quiet_min_delay_set(&rc->pcie);
> +
> + cdns_pcie_hpa_host_enable_ptm_response(pcie);
> +
> + ret = cdns_pcie_start_link(pcie);
> + if (ret) {
> + dev_err(dev, "Failed to start link\n");
> + return ret;
> + }
> +
> + ret = cdns_pcie_hpa_host_start_link(rc);
> + if (ret)
> + dev_dbg(dev, "PCIe link never came up\n");
You are not supposed to fail the probe if link doesn't come up.
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(cdns_pcie_hpa_host_link_setup);
> +
[...]
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 1174cf597bb0..f2eb3f09b21a 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -7,6 +7,7 @@
> #define _PCIE_CADENCE_H
>
> #include <linux/kernel.h>
> +#include <linux/module.h>
> #include <linux/pci.h>
> #include <linux/pci-epf.h>
> #include <linux/phy/phy.h>
> @@ -42,9 +43,9 @@ enum cdns_pcie_reg_bank {
> };
>
> struct cdns_pcie_ops {
> - int (*start_link)(struct cdns_pcie *pcie);
> - void (*stop_link)(struct cdns_pcie *pcie);
> - bool (*link_up)(struct cdns_pcie *pcie);
> + int (*start_link)(struct cdns_pcie *pcie);
> + void (*stop_link)(struct cdns_pcie *pcie);
> + bool (*link_up)(struct cdns_pcie *pcie);
> u64 (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
> };
>
> @@ -76,6 +77,7 @@ struct cdns_plat_pcie_of_data {
> * struct cdns_pcie - private data for Cadence PCIe controller drivers
> * @reg_base: IO mapped register base
> * @mem_res: start/end offsets in the physical system memory to map PCI accesses
> + * @msg_res: Region for send message to map PCI accesses
> * @dev: PCIe controller
> * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
> * @phy_count: number of supported PHY devices
> @@ -88,6 +90,7 @@ struct cdns_plat_pcie_of_data {
> struct cdns_pcie {
> void __iomem *reg_base;
> struct resource *mem_res;
> + struct resource *msg_res;
> struct device *dev;
> bool is_rc;
> int phy_count;
> @@ -110,6 +113,7 @@ struct cdns_pcie {
> * available
> * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
> * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
> + * @ecam_support_flag: Whether the ECAM flag is supported
> */
> struct cdns_pcie_rc {
> struct cdns_pcie pcie;
> @@ -120,6 +124,8 @@ struct cdns_pcie_rc {
> bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
> unsigned int quirk_retrain_flag:1;
> unsigned int quirk_detect_quiet_flag:1;
> + unsigned int ecam_support_flag:1;
ecam_supported
> + unsigned int no_inbound_flag:1;
no_inbound_map
- Mani
--
மணிவண்ணன் சதாசிவம்
Powered by blists - more mailing lists