Hi Andrew Murray,

On 01/10/19 3:37 PM, Andrew Murray wrote:
> Hi Tom,
> 
> Thanks for the patch.
> 
> I'd suggest that you rename the subject of this series to "PCI: cadence: ..."
> to be consistent with the existing commit history, e.g. git log 
> --oneline drivers/pci/controller/pcie-cadence* - you'll also see that you
> don't need a full stop at the end, and you ought to also change the tense
> of the subject, e.g. Refactor driver to ...
> 
> See comments inline...
> 
> On Mon, Sep 30, 2019 at 05:42:48PM +0100, Tom Joseph wrote:
>> All the platform related APIs/Structures in the driver has been extracted
>>  out to a separate file (pcie-cadence-plat.c). This will enable the
>>  driver to be used as a core library, which could be used by other
>>  platform drivers.Testing was done using simulation environment.
> 
> Also change the tense for this description.
> 
> This patch appears to take the dwc approach of spliting itself into consise
> parts, such that you can have a generic Cadence driver, yet also leave room
> and share functionality with/for Cadence derivatives - this seems like a
> sensible approach. Though, as you'll see in my comments below, because there
> are no other platform drivers yet - we end up with unused code and confusing
> Kconfig options.
> 
> Is there an immediate plan to add another Cadence based controller? - if so
> I'd suggest that you include this patch in that patchset for this new
> controller. Otherwise I'm happy with these changes once the Kconfig and unused
> code are fixed.

Yes, I'll send J721E support based on this series. I've sent the RFC series
here [1]. I'll work on that while Tom could fix review comments on this series.

[1] ->  https://lkml.org/lkml/2019/6/4/619

Thanks
Kishon

> 
>>
>> Signed-off-by: Tom Joseph <[email protected]>
>> ---
>>  drivers/pci/controller/Kconfig             |  35 +++++++
>>  drivers/pci/controller/Makefile            |   1 +
>>  drivers/pci/controller/pcie-cadence-ep.c   |  78 ++-------------
>>  drivers/pci/controller/pcie-cadence-host.c |  77 +++------------
>>  drivers/pci/controller/pcie-cadence-plat.c | 154 
>> +++++++++++++++++++++++++++++
>>  drivers/pci/controller/pcie-cadence.h      |  69 +++++++++++++
>>  6 files changed, 278 insertions(+), 136 deletions(-)
>>  create mode 100644 drivers/pci/controller/pcie-cadence-plat.c
>>
>> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
>> index fe9f9f1..c175b21 100644
>> --- a/drivers/pci/controller/Kconfig
>> +++ b/drivers/pci/controller/Kconfig
>> @@ -48,6 +48,41 @@ config PCIE_CADENCE_EP
>>        endpoint mode. This PCIe controller may be embedded into many
>>        different vendors SoCs.
>>  
>> +config PCIE_CADENCE_PLAT
>> +    bool "Cadence PCIe endpoint controller"
>> +    depends on OF
>> +    depends on PCI_ENDPOINT
>> +    select PCIE_CADENCE
>> +    help
>> +      Say Y here if you want to support the Cadence PCIe  controller in
>> +      endpoint mode. This PCIe controller may be embedded into many
>> +      different vendors SoCs.
>> +
>> +config PCIE_CADENCE_PLAT_HOST
>> +    bool "Cadence PCIe platform host controller"
>> +    depends on OF
>> +    depends on PCI
>> +    select IRQ_DOMAIN
>> +    select PCIE_CADENCE
>> +    select PCIE_CADENCE_HOST
>> +    select PCIE_CADENCE_PLAT
>> +    help
>> +      Say Y here if you want to support the Cadence PCIe platform 
>> controller in
>> +      host mode. This PCIe controller may be embedded into many different
>> +      vendors SoCs.
>> +
>> +config PCIE_CADENCE_PLAT_EP
>> +    bool "Cadence PCIe platform endpoint controller"
>> +    depends on OF
>> +    depends on PCI_ENDPOINT
>> +    select PCIE_CADENCE
>> +    select PCIE_CADENCE_EP
>> +    select PCIE_CADENCE_PLAT
>> +    help
>> +      Say Y here if you want to support the Cadence PCIe  platform 
>> controller in
>> +      endpoint mode. This PCIe controller may be embedded into many
>> +      different vendors SoCs.
>> +
> 
> I find this too confusing, if I navigate to Cadence PCIe controllers support
> in menuconfig I see these options:
> 
> Cadence PCIe host controller
> Cadence PCIe endpoint controller
> Cadence PCIe endpoint controller (NEW)
> Cadence PCIe platform host controller (NEW)
> Cadence PCIe platform endpoint controller (NEW)
> 
> I don't think users need to care about the platform/library support, surely
> all they care about is enabling the EP or host bridge controllers for their
> hardware (and then rely on Kconfig to select what is needed).
> 
>>  endmenu
>>  
>>  config PCIE_XILINX_NWL
>> diff --git a/drivers/pci/controller/Makefile 
>> b/drivers/pci/controller/Makefile
>> index d56a507..676a41e 100644
>> --- a/drivers/pci/controller/Makefile
>> +++ b/drivers/pci/controller/Makefile
>> @@ -2,6 +2,7 @@
>>  obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
>>  obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
>>  obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
>> +obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
>>  obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o
>>  obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
>>  obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
>> diff --git a/drivers/pci/controller/pcie-cadence-ep.c 
>> b/drivers/pci/controller/pcie-cadence-ep.c
>> index def7820..617a71f 100644
>> --- a/drivers/pci/controller/pcie-cadence-ep.c
>> +++ b/drivers/pci/controller/pcie-cadence-ep.c
>> @@ -17,35 +17,6 @@
>>  #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE              0x1
>>  #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY    0x3
>>  
>> -/**
>> - * struct cdns_pcie_ep - private data for this PCIe endpoint controller 
>> driver
>> - * @pcie: Cadence PCIe controller
>> - * @max_regions: maximum number of regions supported by hardware
>> - * @ob_region_map: bitmask of mapped outbound regions
>> - * @ob_addr: base addresses in the AXI bus where the outbound regions start
>> - * @irq_phys_addr: base address on the AXI bus where the MSI/legacy IRQ
>> - *             dedicated outbound regions is mapped.
>> - * @irq_cpu_addr: base address in the CPU space where a write access 
>> triggers
>> - *            the sending of a memory write (MSI) / normal message (legacy
>> - *            IRQ) TLP through the PCIe bus.
>> - * @irq_pci_addr: used to save the current mapping of the MSI/legacy IRQ
>> - *            dedicated outbound region.
>> - * @irq_pci_fn: the latest PCI function that has updated the mapping of
>> - *          the MSI/legacy IRQ dedicated outbound region.
>> - * @irq_pending: bitmask of asserted legacy IRQs.
>> - */
>> -struct cdns_pcie_ep {
>> -    struct cdns_pcie                pcie;
>> -    u32                             max_regions;
>> -    unsigned long                   ob_region_map;
>> -    phys_addr_t                     *ob_addr;
>> -    phys_addr_t                     irq_phys_addr;
>> -    void __iomem                    *irq_cpu_addr;
>> -    u64                             irq_pci_addr;
>> -    u8                              irq_pci_fn;
>> -    u8                              irq_pending;
>> -};
>> -
>>  static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
>>                                   struct pci_epf_header *hdr)
>>  {
>> @@ -396,6 +367,9 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
>>              cfg |= BIT(epf->func_no);
>>      cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg);
>>  
>> +    if (pcie->ops->cdns_start_link)
>> +            return  pcie->ops->cdns_start_link(pcie, true);
>> +
>>      return 0;
>>  }
>>  
>> @@ -424,30 +398,18 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
>>      .get_features   = cdns_pcie_ep_get_features,
>>  };
>>  
>> -static const struct of_device_id cdns_pcie_ep_of_match[] = {
>> -    { .compatible = "cdns,cdns-pcie-ep" },
>> -
>> -    { },
>> -};
>>  
>> -static int cdns_pcie_ep_probe(struct platform_device *pdev)
>> +int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>>  {
>> -    struct device *dev = &pdev->dev;
>> +    struct device *dev = ep->dev;
>> +    struct platform_device *pdev = to_platform_device(dev);
>>      struct device_node *np = dev->of_node;
>> -    struct cdns_pcie_ep *ep;
>> -    struct cdns_pcie *pcie;
>> +    struct cdns_pcie *pcie = &ep->pcie;
>>      struct pci_epc *epc;
>>      struct resource *res;
>>      int ret;
>>      int phy_count;
>>  
>> -    ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
>> -    if (!ep)
>> -            return -ENOMEM;
>> -
>> -    pcie = &ep->pcie;
>> -    pcie->is_rc = false;
>> -
>>      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
>>      pcie->reg_base = devm_ioremap_resource(dev, res);
>>      if (IS_ERR(pcie->reg_base)) {
>> @@ -537,29 +499,3 @@ static int cdns_pcie_ep_probe(struct platform_device 
>> *pdev)
>>  
>>      return ret;
>>  }
>> -
>> -static void cdns_pcie_ep_shutdown(struct platform_device *pdev)
>> -{
>> -    struct device *dev = &pdev->dev;
>> -    struct cdns_pcie *pcie = dev_get_drvdata(dev);
>> -    int ret;
>> -
>> -    ret = pm_runtime_put_sync(dev);
>> -    if (ret < 0)
>> -            dev_dbg(dev, "pm_runtime_put_sync failed\n");
>> -
>> -    pm_runtime_disable(dev);
>> -
>> -    cdns_pcie_disable_phy(pcie);
>> -}
>> -
>> -static struct platform_driver cdns_pcie_ep_driver = {
>> -    .driver = {
>> -            .name = "cdns-pcie-ep",
>> -            .of_match_table = cdns_pcie_ep_of_match,
>> -            .pm     = &cdns_pcie_pm_ops,
>> -    },
>> -    .probe = cdns_pcie_ep_probe,
>> -    .shutdown = cdns_pcie_ep_shutdown,
>> -};
>> -builtin_platform_driver(cdns_pcie_ep_driver);
>> diff --git a/drivers/pci/controller/pcie-cadence-host.c 
>> b/drivers/pci/controller/pcie-cadence-host.c
>> index 97e2510..55c2085 100644
>> --- a/drivers/pci/controller/pcie-cadence-host.c
>> +++ b/drivers/pci/controller/pcie-cadence-host.c
>> @@ -11,33 +11,6 @@
>>  
>>  #include "pcie-cadence.h"
>>  
>> -/**
>> - * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
>> - * @pcie: Cadence PCIe controller
>> - * @dev: pointer to PCIe device
>> - * @cfg_res: start/end offsets in the physical system memory to map PCI
>> - *           configuration space accesses
>> - * @bus_range: first/last buses behind the PCIe host controller
>> - * @cfg_base: IO mapped window to access the PCI configuration space of a
>> - *            single function at a time
>> - * @max_regions: maximum number of regions supported by the hardware
>> - * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address
>> - *                translation (nbits sets into the "no BAR match" register)
>> - * @vendor_id: PCI vendor ID
>> - * @device_id: PCI device ID
>> - */
>> -struct cdns_pcie_rc {
>> -    struct cdns_pcie        pcie;
>> -    struct device           *dev;
>> -    struct resource         *cfg_res;
>> -    struct resource         *bus_range;
>> -    void __iomem            *cfg_base;
>> -    u32                     max_regions;
>> -    u32                     no_bar_nbits;
>> -    u16                     vendor_id;
>> -    u16                     device_id;
>> -};
>> -
>>  static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int 
>> devfn,
>>                                    int where)
>>  {
>> @@ -92,11 +65,6 @@ static struct pci_ops cdns_pcie_host_ops = {
>>      .write          = pci_generic_config_write,
>>  };
>>  
>> -static const struct of_device_id cdns_pcie_host_of_match[] = {
>> -    { .compatible = "cdns,cdns-pcie-host" },
>> -
>> -    { },
>> -};
>>  
>>  static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
>>  {
>> @@ -233,27 +201,23 @@ static int cdns_pcie_host_init(struct device *dev,
>>      return err;
>>  }
>>  
>> -static int cdns_pcie_host_probe(struct platform_device *pdev)
>> +int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>>  {
>> -    struct device *dev = &pdev->dev;
>> +    struct device *dev = rc->dev;
>> +    struct platform_device *pdev = to_platform_device(dev);
>>      struct device_node *np = dev->of_node;
>>      struct pci_host_bridge *bridge;
>>      struct list_head resources;
>> -    struct cdns_pcie_rc *rc;
>>      struct cdns_pcie *pcie;
>>      struct resource *res;
>>      int ret;
>>      int phy_count;
>>  
>> -    bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
>> +    bridge = pci_host_bridge_from_priv(rc);
>>      if (!bridge)
>>              return -ENOMEM;
>>  
>> -    rc = pci_host_bridge_priv(bridge);
>> -    rc->dev = dev;
>> -
>>      pcie = &rc->pcie;
>> -    pcie->is_rc = true;
>>  
>>      rc->max_regions = 32;
>>      of_property_read_u32(np, "cdns,max-outbound-regions", &rc->max_regions);
>> @@ -303,6 +267,14 @@ static int cdns_pcie_host_probe(struct platform_device 
>> *pdev)
>>              goto err_get_sync;
>>      }
>>  
>> +    if (pcie->ops->cdns_start_link) {
>> +            ret =  pcie->ops->cdns_start_link(pcie, true);
>> +            if (ret) {
>> +                    dev_err(dev, "Failed to start link\n");
>> +                    return ret;
>> +            }
>> +    }
>> +
>>      ret = cdns_pcie_host_init(dev, &resources, rc);
>>      if (ret)
>>              goto err_init;
>> @@ -335,28 +307,3 @@ static int cdns_pcie_host_probe(struct platform_device 
>> *pdev)
>>  
>>      return ret;
>>  }
>> -
>> -static void cdns_pcie_shutdown(struct platform_device *pdev)
>> -{
>> -    struct device *dev = &pdev->dev;
>> -    struct cdns_pcie *pcie = dev_get_drvdata(dev);
>> -    int ret;
>> -
>> -    ret = pm_runtime_put_sync(dev);
>> -    if (ret < 0)
>> -            dev_dbg(dev, "pm_runtime_put_sync failed\n");
>> -
>> -    pm_runtime_disable(dev);
>> -    cdns_pcie_disable_phy(pcie);
>> -}
>> -
>> -static struct platform_driver cdns_pcie_host_driver = {
>> -    .driver = {
>> -            .name = "cdns-pcie-host",
>> -            .of_match_table = cdns_pcie_host_of_match,
>> -            .pm     = &cdns_pcie_pm_ops,
>> -    },
>> -    .probe = cdns_pcie_host_probe,
>> -    .shutdown = cdns_pcie_shutdown,
>> -};
>> -builtin_platform_driver(cdns_pcie_host_driver);
>> diff --git a/drivers/pci/controller/pcie-cadence-plat.c 
>> b/drivers/pci/controller/pcie-cadence-plat.c
>> new file mode 100644
>> index 0000000..274615d
>> --- /dev/null
>> +++ b/drivers/pci/controller/pcie-cadence-plat.c
>> @@ -0,0 +1,154 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (c) 2019 Cadence
>> +// Cadence PCIe platform  driver.
>> +// Author: Tom Joseph <[email protected]>
>> +
> 
> The style of this comment block is consistent with the other cadence files in
> the tree, however the cadence files aren't consistent with the other PCI
> controller drivers (or probably much of the kernel). I don't have any 
> objections
> with this, but ideally we'd eventually move to this:
> 
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Cadence PCIe platform driver.
> + *
> + * Copyright (c) 2019 Cadence
> + *
> + * Author: Tom Joseph <[email protected]>
> + */
> 
>> +#include <linux/kernel.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_pci.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/of_device.h>
>> +#include "pcie-cadence.h"
>> +
>> +/**
>> + * struct cdns_plat_pcie - private data for this PCIe platform driver
>> + * @pcie: Cadence PCIe controller
>> + * @regmap: pointer to PCIe device
> 
> regmap? A leftover from pcie-designware-plat.c?
> 
>> + * @is_rc: Set to 1 indicates the PCIe controller mode is Root Complex,
>> + *         if 0 it is in Endpoint mode.
>> + */
>> +struct cdns_plat_pcie {
>> +    struct cdns_pcie        *pcie;
>> +    bool is_rc;
>> +};
>> +
>> +struct cdns_plat_pcie_of_data {
>> +    bool is_rc;
>> +};
>> +
>> +static const struct of_device_id cdns_plat_pcie_of_match[];
>> +
>> +int cdns_plat_pcie_link_control(struct cdns_pcie *pcie, bool start)
>> +{
>> +    pr_debug(" %s called\n", __func__);
>> +    return 0;
>> +}
>> +
>> +bool cdns_plat_pcie_link_status(struct cdns_pcie *pcie)
>> +{
>> +    pr_debug(" %s called\n", __func__);
>> +    return 0;
>> +}
> 
> Given that these above two functions are only called through the
> cdns_pcie_common_ops abstraction, they should be declared static.
> 
> I also don't understand why they are here in *this* patch -
> cdns_plat_pcie_link_status isn't called anywhere, and even though
> cdns_plat_pcie_link_control is called it doesn't do anything (start
> is always true which makes me wonder if you'll ever get a caller
> that sets it to false).
> 
> I'd suggest removing these two functions (and related logic) until
> there is a user. This also makes reviewing the patch easier. 
> 
>> +
>> +static const struct cdns_pcie_common_ops cdns_pcie_common_ops = {
>> +    .cdns_start_link = cdns_plat_pcie_link_control,
>> +    .cdns_is_link_up = cdns_plat_pcie_link_status,
>> +};
>> +
>> +static int cdns_plat_pcie_probe(struct platform_device *pdev)
>> +{
>> +    struct device *dev = &pdev->dev;
>> +    struct cdns_plat_pcie *cdns_plat_pcie;
>> +    const struct of_device_id *match;
>> +    const struct cdns_plat_pcie_of_data *data;
>> +    struct pci_host_bridge *bridge;
>> +    struct cdns_pcie_rc *rc;
>> +    struct cdns_pcie_ep *ep;
>> +    int ret;
>> +    bool is_rc;
>> +
>> +    match = of_match_device(cdns_plat_pcie_of_match, dev);
>> +    if (!match)
>> +            return -EINVAL;
> 
> Add a new line here.
> 
>> +    data = (struct cdns_plat_pcie_of_data *)match->data;
>> +    is_rc = data->is_rc;
>> +
>> +    pr_debug(" Started %s with is_rc: %d\n", __func__, is_rc);
>> +    cdns_plat_pcie = devm_kzalloc(dev, sizeof(*cdns_plat_pcie), GFP_KERNEL);
>> +    if (!cdns_plat_pcie)
>> +            return -ENOMEM;
>> +
>> +    platform_set_drvdata(pdev, cdns_plat_pcie);
>> +    if (is_rc) {
>> +            if (!IS_ENABLED(CONFIG_PCIE_CADENCE_PLAT_HOST))
>> +                    return -ENODEV;
>> +
>> +            bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
>> +            if (!bridge)
>> +                    return -ENOMEM;
>> +
>> +            rc = pci_host_bridge_priv(bridge);
>> +            rc->dev = dev;
>> +            rc->pcie.ops = &cdns_pcie_common_ops;
>> +            cdns_plat_pcie->pcie = &rc->pcie;
>> +            cdns_plat_pcie->is_rc = is_rc;
>> +
>> +            ret = cdns_pcie_host_setup(rc);
>> +            if (ret < 0)
>> +                    return ret;
>> +    } else {
>> +            if (!IS_ENABLED(CONFIG_PCIE_CADENCE_PLAT_EP))
>> +                    return -ENODEV;
>> +
>> +            ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
>> +            if (!ep)
>> +                    return -ENOMEM;
>> +            ep->dev = dev;
>> +            ep->pcie.ops = &cdns_pcie_common_ops;
>> +            cdns_plat_pcie->pcie = &ep->pcie;
>> +            cdns_plat_pcie->is_rc = is_rc;
>> +
>> +            ret = cdns_pcie_ep_setup(ep);
>> +            if (ret < 0)
>> +                    return ret;
>> +    }
>> +    return 0;
>> +}
>> +
>> +
>> +static void cdns_plat_pcie_shutdown(struct platform_device *pdev)
>> +{
>> +    struct device *dev = &pdev->dev;
>> +    struct cdns_pcie *pcie = dev_get_drvdata(dev);
>> +    int ret;
>> +
>> +    ret = pm_runtime_put_sync(dev);
>> +    if (ret < 0)
>> +            dev_dbg(dev, "pm_runtime_put_sync failed\n");
>> +
>> +    pm_runtime_disable(dev);
>> +
>> +    cdns_pcie_disable_phy(pcie);
>> +}
>> +
>> +static const struct cdns_plat_pcie_of_data cdns_plat_pcie_host_of_data = {
>> +    .is_rc = true,
>> +};
>> +
>> +static const struct cdns_plat_pcie_of_data cdns_plat_pcie_ep_of_data = {
>> +    .is_rc = false,
>> +};
>> +
>> +static const struct of_device_id cdns_plat_pcie_of_match[] = {
>> +    {
>> +            .compatible = "cdns,cdns-pcie-host",
>> +            .data = &cdns_plat_pcie_host_of_data,
>> +    },
>> +    {
>> +            .compatible = "cdns,cdns-pcie-ep",
>> +            .data = &cdns_plat_pcie_ep_of_data,
>> +    },
>> +    {},
>> +};
>> +
>> +static struct platform_driver cdns_plat_pcie_driver = {
>> +    .driver = {
>> +            .name = "cdns-pcie",
>> +            .of_match_table = cdns_plat_pcie_of_match,
>> +            .pm     = &cdns_pcie_pm_ops,
>> +    },
>> +    .probe = cdns_plat_pcie_probe,
>> +    .shutdown = cdns_plat_pcie_shutdown,
>> +};
>> +builtin_platform_driver(cdns_plat_pcie_driver);
>> diff --git a/drivers/pci/controller/pcie-cadence.h 
>> b/drivers/pci/controller/pcie-cadence.h
>> index ae6bf2a..3df902a 100644
>> --- a/drivers/pci/controller/pcie-cadence.h
>> +++ b/drivers/pci/controller/pcie-cadence.h
>> @@ -190,6 +190,8 @@ enum cdns_pcie_rp_bar {
>>      (((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
>>  #define CDNS_PCIE_MSG_NO_DATA                       BIT(16)
>>  
>> +struct cdns_pcie;
>> +
>>  enum cdns_pcie_msg_code {
>>      MSG_CODE_ASSERT_INTA    = 0x20,
>>      MSG_CODE_ASSERT_INTB    = 0x21,
>> @@ -221,6 +223,11 @@ enum cdns_pcie_msg_routing {
>>      MSG_ROUTING_GATHER,
>>  };
>>  
>> +
>> +struct cdns_pcie_common_ops {
>> +    int     (*cdns_start_link)(struct cdns_pcie *pcie, bool start);
>> +    bool    (*cdns_is_link_up)(struct cdns_pcie *pcie);
>> +};
>>  /**
>>   * struct cdns_pcie - private data for Cadence PCIe controller drivers
>>   * @reg_base: IO mapped register base
>> @@ -236,8 +243,67 @@ struct cdns_pcie {
>>      int                     phy_count;
>>      struct phy              **phy;
>>      struct device_link      **link;
>> +    const struct cdns_pcie_common_ops *ops;
>> +};
>> +
>> +/**
>> + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
>> + * @pcie: Cadence PCIe controller
>> + * @dev: pointer to PCIe device
>> + * @cfg_res: start/end offsets in the physical system memory to map PCI
>> + *           configuration space accesses
>> + * @bus_range: first/last buses behind the PCIe host controller
>> + * @cfg_base: IO mapped window to access the PCI configuration space of a
>> + *            single function at a time
>> + * @max_regions: maximum number of regions supported by the hardware
>> + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address
>> + *                translation (nbits sets into the "no BAR match" register)
>> + * @vendor_id: PCI vendor ID
>> + * @device_id: PCI device ID
>> + */
>> +struct cdns_pcie_rc {
>> +    struct cdns_pcie        pcie;
>> +    struct device           *dev;
>> +    struct resource         *cfg_res;
>> +    struct resource         *bus_range;
>> +    void __iomem            *cfg_base;
>> +    u32                     max_regions;
>> +    u32                     no_bar_nbits;
>> +    u16                     vendor_id;
>> +    u16                     device_id;
>>  };
>>  
>> +/**
>> + * struct cdns_pcie_ep - private data for this PCIe endpoint controller 
>> driver
>> + * @pcie: Cadence PCIe controller
>> + * @max_regions: maximum number of regions supported by hardware
>> + * @ob_region_map: bitmask of mapped outbound regions
>> + * @ob_addr: base addresses in the AXI bus where the outbound regions start
>> + * @irq_phys_addr: base address on the AXI bus where the MSI/legacy IRQ
>> + *             dedicated outbound regions is mapped.
>> + * @irq_cpu_addr: base address in the CPU space where a write access 
>> triggers
>> + *            the sending of a memory write (MSI) / normal message (legacy
>> + *            IRQ) TLP through the PCIe bus.
>> + * @irq_pci_addr: used to save the current mapping of the MSI/legacy IRQ
>> + *            dedicated outbound region.
>> + * @irq_pci_fn: the latest PCI function that has updated the mapping of
>> + *          the MSI/legacy IRQ dedicated outbound region.
>> + * @irq_pending: bitmask of asserted legacy IRQs.
>> + */
>> +struct cdns_pcie_ep {
>> +    struct cdns_pcie        pcie;
>> +    struct device           *dev;
>> +    u32                     max_regions;
>> +    unsigned long           ob_region_map;
>> +    phys_addr_t             *ob_addr;
>> +    phys_addr_t             irq_phys_addr;
>> +    void __iomem            *irq_cpu_addr;
>> +    u64                     irq_pci_addr;
>> +    u8                      irq_pci_fn;
>> +    u8                      irq_pending;
>> +};
>> +
>> +
>>  /* Register access */
>>  static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 
>> value)
>>  {
>> @@ -306,6 +372,9 @@ static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie 
>> *pcie, u8 fn, u32 reg)
>>      return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
>>  }
>>  
>> +int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
>> +int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep);
>> +
> 
> What happens if a user only selects the host bridge, will you get a build
> error relating to cdns_plat_pcie_probe not being able to find an
> implementation of cdns_pcie_ep_setup?
> 
> Thanks,
> 
> Andrew Murray
> 
>>  void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
>>                                 u32 r, bool is_io,
>>                                 u64 cpu_addr, u64 pci_addr, size_t size);
>> -- 
>> 2.2.2
>>

Reply via email to