Commit 964db794 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/ctrl/dwc'

- Stop link on host_init errors and de-initialization (Serge Semin)

- Add support for unrolled iATU register space in dw_pcie_disable_atu()
  (Serge Semin)

- Disable outbound windows only for controllers that use iATU (Serge Semin)

- Set INCREASE_REGION_SIZE flag based on limit address, not on the size,
  since even a small size may cross a 4GB boundary (Serge Semin)

- Deallocate EPC memory on dw_pcie_ep_init() errors to avoid a leak (Serge
  Semin)

- Always enable CDM check if "snps,enable-cdm-check" exists instead of
  exiting early if the optional "num-lanes" was absent (Serge Semin)

- Simplify detection of whether we're using unrolled iATU registers (Serge
  Semin)

- Make dw_pcie_link_up() more generic by using dw_pcie_readl_dbi() instead
  of readl() (Serge Semin)

- Add dw_pcie_start_link() and dw_pcie_stop_link() wrappers to factor out
  checks for ops being implemented (Serge Semin)

- Move io_cfg_atu_shared to struct pcie_port and rename to cfg0_io_shared,
  since it's not used by dwc common code or dwc endpoint code (Serge Semin)

- Rename struct pcie_port to dw_pcie_rp to indicate that it's
  DesignWare-specific (Serge Semin)

- Drop unused struct dw_plat_pcie regmap pointer (Serge Semin)

- Fix some coding style issues (Serge Semin)

- Log link speed and width if it comes up (Serge Semin)

- Save DWC IP core version in native format as read from
  PORT_LOGIC.PCIE_VERSION_OFF register (Serge Semin)

- Read DWC IP core version from PORT_LOGIC.PCIE_VERSION_OFF (Serge Semin)

- Add macros to compare Synopsys IP core versions (Serge Semin)

- Drop manual DWC IP core version setup from intel-gw and tegra194 (Serge
  Semin)

- Add dw_pcie_ops.host_deinit() callback (Serge Semin)

- Drop enum dw_pcie_as_type in favor of PCIE_ATU_TYPE_MEM/IO (Serge Semin)

- Drop enum dw_pcie_region_type in favor of PCIE_ATU_REGION_DIR_IB/OB
  (Serge Semin)

- Simplify in/outbound iATU setup methods and reduce duplicated code (Serge
  Semin)

- Detect iATU region size from hardware (Serge Semin)

- Validate iATU outbound mappings against hardware constraints (Serge
  Semin)

- Check for errors in iATU setup (Serge Semin)

- Allocate a 32-bit DMA-able page to be MSI target instead of using a
  driver data structure that may not be addressable with 32-bit address
  (Will McVicker)

- Use the bitmap API to allocate bitmaps instead of open-coding it
  (Christophe JAILLET)

- Correct dw_pcie_free_msi() checking for when to remove IRQ handler and
  data (Dmitry Baryshkov)

- Split MSI init to new dw_pcie_msi_host_init() function (Dmitry Baryshkov)

- Convert struct pcie_port.msi_irq to an array so we can support more than
  32 MSI interrupts (Dmitry Baryshkov)

- Handle MSIs routed to multiple GIC interrupts for Qualcomm platforms with
  groups of 32 MSI vectors (Dmitry Baryshkov)

- Add additional MSI interrupts to qcom DT (Dmitry Baryshkov)

* pci/ctrl/dwc:
  dt-bindings: PCI: qcom: Support additional MSI vectors
  PCI: dwc: Handle MSIs routed to multiple GIC interrupts
  PCI: dwc: Convert struct pcie_port.msi_irq to an array
  PCI: dwc: Split MSI IRQ parsing/allocation to a separate function
  PCI: dwc: Correct msi_irq condition in dw_pcie_free_msi()
  PCI: dwc: Use the bitmap API to allocate bitmaps
  PCI: dwc: Fix MSI msi_msg DMA mapping
  PCI: dwc: Check iATU in/outbound range setup status
  PCI: dwc: Validate iATU outbound mappings against hardware constraints
  PCI: dwc: Add iATU regions size detection procedure
  PCI: dwc: Simplify in/outbound iATU setup methods
  PCI: dwc: Drop enum dw_pcie_region_type in favor of PCIE_ATU_REGION_DIR_IB/OB
  PCI: dwc: Drop enum dw_pcie_as_type in favor of PCIE_ATU_TYPE_MEM/IO
  PCI: dwc: Add dw_pcie_ops.host_deinit() callback
  PCI: tegra194: Drop manual DW PCIe controller version setup
  PCI: intel-gw: Drop manual DW PCIe controller version setup
  PCI: dwc: Add macros to compare Synopsys IP core versions
  PCI: dwc: Read DWC IP core version from register
  PCI: dwc: Use native DWC IP core version representation
  PCI: dwc: Detect iATU settings after getting "addr_space" resource
  PCI: dwc: Log link speed and width if it comes up
  PCI: dwc-plat: Drop dw_plat_pcie_of_match[] forward declaration
  PCI: dwc-plat: Drop unused regmap pointer
  PCI: dwc-plat: Simplify dw_plat_pcie_probe() return values
  PCI: dwc: Rename struct pcie_port to dw_pcie_rp
  PCI: dwc: Move io_cfg_atu_shared to struct pcie_port
  PCI: dwc: Add start_link/stop_link inlines
  PCI: dwc: Reuse local pointer to the resource data
  PCI: dwc: Organize local variable usage
  PCI: dwc: Convert dw_pcie_link_up() to use dw_pcie_readl_dbi()
  PCI: dwc: Simplify unrolled iATU detection
  PCI: dwc: Add newlines to log messages
  PCI: dwc: Add braces to multi-line if-else statements
  PCI: dwc: Always enable CDM check if "snps,enable-cdm-check" exists
  PCI: dwc: Deallocate EPC memory on dw_pcie_ep_init() errors
  PCI: dwc: Set INCREASE_REGION_SIZE flag based on limit address
  PCI: dwc: Disable outbound windows only for controllers using iATU
  PCI: dwc: Add unroll iATU space support to dw_pcie_disable_atu()
  PCI: dwc: Stop link on host_init errors and de-initialization
parents 9154b00f 91a773f9
Loading
Loading
Loading
Loading
+48 −3
Original line number Diff line number Diff line
@@ -43,11 +43,12 @@ properties:
    maxItems: 5

  interrupts:
    maxItems: 1
    minItems: 1
    maxItems: 8

  interrupt-names:
    items:
      - const: msi
    minItems: 1
    maxItems: 8

  # Common definitions for clocks, clock-names and reset.
  # Platform constraints are described later.
@@ -623,6 +624,50 @@ allOf:
        - resets
        - reset-names

    # Newer chipsets support either 1 or 8 MSI vectors
    # On older chipsets it's always 1 MSI vector
  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-msm8996
              - qcom,pcie-sc7280
              - qcom,pcie-sc8180x
              - qcom,pcie-sdm845
              - qcom,pcie-sm8150
              - qcom,pcie-sm8250
              - qcom,pcie-sm8450-pcie0
              - qcom,pcie-sm8450-pcie1
    then:
      oneOf:
        - properties:
            interrupts:
              maxItems: 1
            interrupt-names:
              items:
                - const: msi
        - properties:
            interrupts:
              minItems: 8
            interrupt-names:
              items:
                - const: msi0
                - const: msi1
                - const: msi2
                - const: msi3
                - const: msi4
                - const: msi5
                - const: msi6
                - const: msi7
    else:
      properties:
        interrupts:
          maxItems: 1
        interrupt-names:
          items:
            - const: msi

unevaluatedProperties: false

examples:
+7 −7
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
	dra7xx_pcie_enable_msi_interrupts(dra7xx);
}

static int dra7xx_pcie_host_init(struct pcie_port *pp)
static int dra7xx_pcie_host_init(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
@@ -202,7 +202,7 @@ static const struct irq_domain_ops intx_domain_ops = {
	.xlate = pci_irqd_intx_xlate,
};

static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index)
static int dra7xx_pcie_handle_msi(struct dw_pcie_rp *pp, int index)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	unsigned long val;
@@ -224,7 +224,7 @@ static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index)
	return 1;
}

static void dra7xx_pcie_handle_msi_irq(struct pcie_port *pp)
static void dra7xx_pcie_handle_msi_irq(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	int ret, i, count, num_ctrls;
@@ -255,8 +255,8 @@ static void dra7xx_pcie_msi_irq_handler(struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct dra7xx_pcie *dra7xx;
	struct dw_pcie_rp *pp;
	struct dw_pcie *pci;
	struct pcie_port *pp;
	unsigned long reg;
	u32 bit;

@@ -344,7 +344,7 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
	return IRQ_HANDLED;
}

static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
static int dra7xx_pcie_init_irq_domain(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct device *dev = pci->dev;
@@ -475,7 +475,7 @@ static int dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
{
	int ret;
	struct dw_pcie *pci = dra7xx->pci;
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_rp *pp = &pci->pp;
	struct device *dev = pci->dev;

	pp->irq = platform_get_irq(pdev, 1);
@@ -483,7 +483,7 @@ static int dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
		return pp->irq;

	/* MSI IRQ is muxed */
	pp->msi_irq = -ENODEV;
	pp->msi_irq[0] = -ENODEV;

	ret = dra7xx_pcie_init_irq_domain(pp);
	if (ret < 0)
+4 −4
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static int exynos_pcie_link_up(struct dw_pcie *pci)
	return (val & PCIE_ELBI_XMLH_LINKUP);
}

static int exynos_pcie_host_init(struct pcie_port *pp)
static int exynos_pcie_host_init(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct exynos_pcie *ep = to_exynos_pcie(pci);
@@ -276,7 +276,7 @@ static int exynos_add_pcie_port(struct exynos_pcie *ep,
				       struct platform_device *pdev)
{
	struct dw_pcie *pci = &ep->pci;
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_rp *pp = &pci->pp;
	struct device *dev = &pdev->dev;
	int ret;

@@ -292,7 +292,7 @@ static int exynos_add_pcie_port(struct exynos_pcie *ep,
	}

	pp->ops = &exynos_pcie_host_ops;
	pp->msi_irq = -ENODEV;
	pp->msi_irq[0] = -ENODEV;

	ret = dw_pcie_host_init(pp);
	if (ret) {
@@ -406,7 +406,7 @@ static int __maybe_unused exynos_pcie_resume_noirq(struct device *dev)
{
	struct exynos_pcie *ep = dev_get_drvdata(dev);
	struct dw_pcie *pci = &ep->pci;
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_rp *pp = &pci->pp;
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(ep->supplies), ep->supplies);
+3 −3
Original line number Diff line number Diff line
@@ -863,7 +863,7 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
	return ret;
}

static int imx6_pcie_host_init(struct pcie_port *pp)
static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
@@ -992,7 +992,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)
{
	int ret;
	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
	struct pcie_port *pp = &imx6_pcie->pci->pp;
	struct dw_pcie_rp *pp = &imx6_pcie->pci->pp;

	if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_SUPPORTS_SUSPEND))
		return 0;
@@ -1291,7 +1291,7 @@ static struct platform_driver imx6_pcie_driver = {
static void imx6_pcie_quirk(struct pci_dev *dev)
{
	struct pci_bus *bus = dev->bus;
	struct pcie_port *pp = bus->sysdata;
	struct dw_pcie_rp *pp = bus->sysdata;

	/* Bus parent is the PCI bridge, its parent is this platform driver */
	if (!bus->dev.parent || !bus->dev.parent->parent)
+16 −16
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ struct ks_pcie_of_data {
	enum dw_pcie_device_mode mode;
	const struct dw_pcie_host_ops *host_ops;
	const struct dw_pcie_ep_ops *ep_ops;
	unsigned int version;
	u32 version;
};

struct keystone_pcie {
@@ -147,7 +147,7 @@ static void ks_pcie_app_writel(struct keystone_pcie *ks_pcie, u32 offset,

static void ks_pcie_msi_irq_ack(struct irq_data *data)
{
	struct pcie_port *pp  = irq_data_get_irq_chip_data(data);
	struct dw_pcie_rp *pp  = irq_data_get_irq_chip_data(data);
	struct keystone_pcie *ks_pcie;
	u32 irq = data->hwirq;
	struct dw_pcie *pci;
@@ -167,7 +167,7 @@ static void ks_pcie_msi_irq_ack(struct irq_data *data)

static void ks_pcie_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
	struct pcie_port *pp = irq_data_get_irq_chip_data(data);
	struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(data);
	struct keystone_pcie *ks_pcie;
	struct dw_pcie *pci;
	u64 msi_target;
@@ -192,7 +192,7 @@ static int ks_pcie_msi_set_affinity(struct irq_data *irq_data,

static void ks_pcie_msi_mask(struct irq_data *data)
{
	struct pcie_port *pp = irq_data_get_irq_chip_data(data);
	struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(data);
	struct keystone_pcie *ks_pcie;
	u32 irq = data->hwirq;
	struct dw_pcie *pci;
@@ -216,7 +216,7 @@ static void ks_pcie_msi_mask(struct irq_data *data)

static void ks_pcie_msi_unmask(struct irq_data *data)
{
	struct pcie_port *pp = irq_data_get_irq_chip_data(data);
	struct dw_pcie_rp *pp = irq_data_get_irq_chip_data(data);
	struct keystone_pcie *ks_pcie;
	u32 irq = data->hwirq;
	struct dw_pcie *pci;
@@ -247,7 +247,7 @@ static struct irq_chip ks_pcie_msi_irq_chip = {
	.irq_unmask = ks_pcie_msi_unmask,
};

static int ks_pcie_msi_host_init(struct pcie_port *pp)
static int ks_pcie_msi_host_init(struct dw_pcie_rp *pp)
{
	pp->msi_irq_chip = &ks_pcie_msi_irq_chip;
	return dw_pcie_allocate_domains(pp);
@@ -390,7 +390,7 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
	u32 val;
	u32 num_viewport = ks_pcie->num_viewport;
	struct dw_pcie *pci = ks_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_rp *pp = &pci->pp;
	u64 start, end;
	struct resource *mem;
	int i;
@@ -428,7 +428,7 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
static void __iomem *ks_pcie_other_map_bus(struct pci_bus *bus,
					   unsigned int devfn, int where)
{
	struct pcie_port *pp = bus->sysdata;
	struct dw_pcie_rp *pp = bus->sysdata;
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
	u32 reg;
@@ -456,7 +456,7 @@ static struct pci_ops ks_child_pcie_ops = {
 */
static int ks_pcie_v3_65_add_bus(struct pci_bus *bus)
{
	struct pcie_port *pp = bus->sysdata;
	struct dw_pcie_rp *pp = bus->sysdata;
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);

@@ -574,7 +574,7 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc)
	struct keystone_pcie *ks_pcie = irq_desc_get_handler_data(desc);
	u32 offset = irq - ks_pcie->msi_host_irq;
	struct dw_pcie *pci = ks_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_rp *pp = &pci->pp;
	struct device *dev = pci->dev;
	struct irq_chip *chip = irq_desc_get_chip(desc);
	u32 vector, reg, pos;
@@ -799,7 +799,7 @@ static int __init ks_pcie_init_id(struct keystone_pcie *ks_pcie)
	return 0;
}

static int __init ks_pcie_host_init(struct pcie_port *pp)
static int __init ks_pcie_host_init(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct keystone_pcie *ks_pcie = to_keystone_pcie(pci);
@@ -1069,19 +1069,19 @@ static int ks_pcie_am654_set_mode(struct device *dev,

static const struct ks_pcie_of_data ks_pcie_rc_of_data = {
	.host_ops = &ks_pcie_host_ops,
	.version = 0x365A,
	.version = DW_PCIE_VER_365A,
};

static const struct ks_pcie_of_data ks_pcie_am654_rc_of_data = {
	.host_ops = &ks_pcie_am654_host_ops,
	.mode = DW_PCIE_RC_TYPE,
	.version = 0x490A,
	.version = DW_PCIE_VER_490A,
};

static const struct ks_pcie_of_data ks_pcie_am654_ep_of_data = {
	.ep_ops = &ks_pcie_am654_ep_ops,
	.mode = DW_PCIE_EP_TYPE,
	.version = 0x490A,
	.version = DW_PCIE_VER_490A,
};

static const struct of_device_id ks_pcie_of_match[] = {
@@ -1114,12 +1114,12 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
	struct device_link **link;
	struct gpio_desc *gpiod;
	struct resource *res;
	unsigned int version;
	void __iomem *base;
	u32 num_viewport;
	struct phy **phy;
	u32 num_lanes;
	char name[10];
	u32 version;
	int ret;
	int irq;
	int i;
@@ -1233,7 +1233,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
		goto err_get_sync;
	}

	if (pci->version >= 0x480A)
	if (dw_pcie_ver_is_ge(pci, 480A))
		ret = ks_pcie_am654_set_mode(dev, mode);
	else
		ret = ks_pcie_set_mode(dev);
Loading