diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-09 17:57:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-09 17:57:08 -0500 |
commit | 2901752c14b8e1b7dd898d2e5245c93e531aa624 (patch) | |
tree | 98780bc17593a3d79e7b3fe2ecf23f2e8882a39a /drivers/pci/controller/dwc | |
parent | 96a6de1a541c86e9e67b9c310c14db4099bd1cbc (diff) | |
parent | dd92b6677e3d0d78e261a7f00f28e753bab41d24 (diff) |
Merge tag 'pci-v5.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
- Use match_string() instead of reimplementing it (Andy Shevchenko)
- Enable SERR# forwarding for all bridges (Bharat Kumar Gogada)
- Use Latency Tolerance Reporting if already enabled by platform (Bjorn
Helgaas)
- Save/restore LTR info for suspend/resume (Bjorn Helgaas)
- Fix DPC use of uninitialized data (Dongdong Liu)
- Probe bridge window attributes only once at enumeration-time to fix
device accesses during rescan (Bjorn Helgaas)
- Return BAR size (not "size -1 ") from pci_size() to simplify code (Du
Changbin)
- Use config header type (not class code) identify bridges more
reliably (Honghui Zhang)
- Work around Intel Denverton incorrect Trace Hub BAR size reporting
(Alexander Shishkin)
- Reorder pciehp cached state/hardware state updates to avoid missed
interrupts (Mika Westerberg)
- Turn ibmphp semaphores into completions or mutexes (Arnd Bergmann)
- Mark expected switch fall-through (Mathieu Malaterre)
- Use of_node_name_eq() for node name comparisons (Rob Herring)
- Add ACS and pciehp quirks for HXT SD4800 (Shunyong Yang)
- Consolidate Rohm Vendor ID definitions (Andy Shevchenko)
- Use u32 (not __u32) for things not exposed to userspace (Logan
Gunthorpe)
- Fix locking semantics of bus and slot reset interfaces (Alex
Williamson)
- Update PCIEPORTBUS Kconfig help text (Hou Zhiqiang)
- Allow portdrv to claim subtractive decode Ports so PCIe services will
work for them (Honghui Zhang)
- Report PCIe links that become degraded at run-time (Alexandru
Gagniuc)
- Blacklist Gigabyte X299 Root Port power management to fix Thunderbolt
hotplug (Mika Westerberg)
- Revert runtime PM suspend/resume callbacks that broke PME on network
cable plug (Mika Westerberg)
- Disable Data Link State Changed interrupts to prevent wakeup
immediately after suspend (Mika Westerberg)
- Extend altera to support Stratix 10 (Ley Foon Tan)
- Allow building altera driver on ARM64 (Ley Foon Tan)
- Replace Douglas with Tom Joseph as Cadence PCI host/endpoint
maintainer (Lorenzo Pieralisi)
- Add DT support for R-Car RZ/G2E (R8A774C0) (Fabrizio Castro)
- Add dra72x/dra74x/dra76x SoC compatible strings (Kishon Vijay Abraham I)
- Enable x2 mode support for dra72x/dra74x/dra76x SoC (Kishon Vijay
Abraham I)
- Configure dra7xx PHY to PCIe mode (Kishon Vijay Abraham I)
- Simplify dwc (remove unnecessary header includes, name variables
consistently, reduce inverted logic, etc) (Gustavo Pimentel)
- Add i.MX8MQ support (Andrey Smirnov)
- Add message to help debug dwc MSI-X mask bit errors (Gustavo
Pimentel)
- Work around imx7d PCIe PLL erratum (Trent Piepho)
- Don't assert qcom reset GPIO during probe (Bjorn Andersson)
- Skip dwc MSI init if MSIs have been disabled (Lucas Stach)
- Use memcpy_fromio()/memcpy_toio() instead of plain memcpy() in PCI
endpoint framework (Wen Yang)
- Add interface to discover supported endpoint features to replace a
bitfield that wasn't flexible enough (Kishon Vijay Abraham I)
- Implement the new supported-feature interface for designware-plat,
dra7xx, rockchip, cadence (Kishon Vijay Abraham I)
- Fix issues with 64-bit BAR in endpoints (Kishon Vijay Abraham I)
- Add layerscape endpoint mode support (Xiaowei Bao)
- Remove duplicate struct hv_vp_set in favor of struct hv_vpset (Maya
Nakamura)
- Rework hv_irq_unmask() to use cpumask_to_vpset() instead of
open-coded reimplementation (Maya Nakamura)
- Align Hyper-V struct retarget_msi_interrupt arguments (Maya Nakamura)
- Fix mediatek MMIO size computation to enable full size of available
MMIO space (Honghui Zhang)
- Fix mediatek DMA window size computation to allow endpoint DMA access
to full DRAM address range (Honghui Zhang)
- Fix mvebu prefetchable BAR regression caused by common bridge
emulation that assumed all bridges had prefetchable windows (Thomas
Petazzoni)
- Make advk_pci_bridge_emul_ops static (Wei Yongjun)
- Configure MPS settings for VMD root ports (Jon Derrick)
* tag 'pci-v5.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (92 commits)
PCI: Update PCIEPORTBUS Kconfig help text
PCI: Fix "try" semantics of bus and slot reset
PCI/LINK: Report degraded links via link bandwidth notification
dt-bindings: PCI: altera: Add altr,pcie-root-port-2.0
PCI: altera: Enable driver on ARM64
PCI: altera: Add Stratix 10 PCIe support
PCI/PME: Fix possible use-after-free on remove
PCI: aardvark: Make symbol 'advk_pci_bridge_emul_ops' static
PCI: dwc: skip MSI init if MSIs have been explicitly disabled
PCI: hv: Refactor hv_irq_unmask() to use cpumask_to_vpset()
PCI: hv: Replace hv_vp_set with hv_vpset
PCI: hv: Add __aligned(8) to struct retarget_msi_interrupt
PCI: mediatek: Enlarge PCIe2AHB window size to support 4GB DRAM
PCI: mediatek: Fix memory mapped IO range size computation
PCI: dwc: Remove superfluous shifting in definitions
PCI: dwc: Make use of GENMASK/FIELD_PREP
PCI: dwc: Make use of BIT() in constant definitions
PCI: dwc: Share code for dw_pcie_rd/wr_other_conf()
PCI: dwc: Make use of IS_ALIGNED()
PCI: imx6: Add code to request/control "pcie_aux" clock for i.MX8MQ
...
Diffstat (limited to 'drivers/pci/controller/dwc')
-rw-r--r-- | drivers/pci/controller/dwc/Kconfig | 4 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/Makefile | 2 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pci-dra7xx.c | 94 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pci-imx6.c | 224 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pci-layerscape-ep.c | 156 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-ep.c | 16 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 115 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-plat.c | 19 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.c | 6 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 60 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-qcom.c | 2 |
11 files changed, 569 insertions, 129 deletions
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 548c58223868..6ea74b1c0d94 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig | |||
@@ -89,8 +89,8 @@ config PCI_EXYNOS | |||
89 | select PCIE_DW_HOST | 89 | select PCIE_DW_HOST |
90 | 90 | ||
91 | config PCI_IMX6 | 91 | config PCI_IMX6 |
92 | bool "Freescale i.MX6/7 PCIe controller" | 92 | bool "Freescale i.MX6/7/8 PCIe controller" |
93 | depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST) | 93 | depends on SOC_IMX6Q || SOC_IMX7D || (ARM64 && ARCH_MXC) || COMPILE_TEST |
94 | depends on PCI_MSI_IRQ_DOMAIN | 94 | depends on PCI_MSI_IRQ_DOMAIN |
95 | select PCIE_DW_HOST | 95 | select PCIE_DW_HOST |
96 | 96 | ||
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 7bcdcdf5024e..b5f3b83cc2b3 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile | |||
@@ -8,7 +8,7 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o | |||
8 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o | 8 | obj-$(CONFIG_PCI_IMX6) += pci-imx6.o |
9 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o | 9 | obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o |
10 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o | 10 | obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o |
11 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o | 11 | obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o |
12 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o | 12 | obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o |
13 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o | 13 | obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o |
14 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | 14 | obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o |
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index a32d6dde7a57..ae84a69ae63a 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c | |||
@@ -81,6 +81,10 @@ | |||
81 | #define MSI_REQ_GRANT BIT(0) | 81 | #define MSI_REQ_GRANT BIT(0) |
82 | #define MSI_VECTOR_SHIFT 7 | 82 | #define MSI_VECTOR_SHIFT 7 |
83 | 83 | ||
84 | #define PCIE_1LANE_2LANE_SELECTION BIT(13) | ||
85 | #define PCIE_B1C0_MODE_SEL BIT(2) | ||
86 | #define PCIE_B0_B1_TSYNCEN BIT(0) | ||
87 | |||
84 | struct dra7xx_pcie { | 88 | struct dra7xx_pcie { |
85 | struct dw_pcie *pci; | 89 | struct dw_pcie *pci; |
86 | void __iomem *base; /* DT ti_conf */ | 90 | void __iomem *base; /* DT ti_conf */ |
@@ -93,6 +97,7 @@ struct dra7xx_pcie { | |||
93 | 97 | ||
94 | struct dra7xx_pcie_of_data { | 98 | struct dra7xx_pcie_of_data { |
95 | enum dw_pcie_device_mode mode; | 99 | enum dw_pcie_device_mode mode; |
100 | u32 b1co_mode_sel_mask; | ||
96 | }; | 101 | }; |
97 | 102 | ||
98 | #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) | 103 | #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) |
@@ -389,9 +394,22 @@ static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
389 | return 0; | 394 | return 0; |
390 | } | 395 | } |
391 | 396 | ||
397 | static const struct pci_epc_features dra7xx_pcie_epc_features = { | ||
398 | .linkup_notifier = true, | ||
399 | .msi_capable = true, | ||
400 | .msix_capable = false, | ||
401 | }; | ||
402 | |||
403 | static const struct pci_epc_features* | ||
404 | dra7xx_pcie_get_features(struct dw_pcie_ep *ep) | ||
405 | { | ||
406 | return &dra7xx_pcie_epc_features; | ||
407 | } | ||
408 | |||
392 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 409 | static struct dw_pcie_ep_ops pcie_ep_ops = { |
393 | .ep_init = dra7xx_pcie_ep_init, | 410 | .ep_init = dra7xx_pcie_ep_init, |
394 | .raise_irq = dra7xx_pcie_raise_irq, | 411 | .raise_irq = dra7xx_pcie_raise_irq, |
412 | .get_features = dra7xx_pcie_get_features, | ||
395 | }; | 413 | }; |
396 | 414 | ||
397 | static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx, | 415 | static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx, |
@@ -499,6 +517,10 @@ static int dra7xx_pcie_enable_phy(struct dra7xx_pcie *dra7xx) | |||
499 | int i; | 517 | int i; |
500 | 518 | ||
501 | for (i = 0; i < phy_count; i++) { | 519 | for (i = 0; i < phy_count; i++) { |
520 | ret = phy_set_mode(dra7xx->phy[i], PHY_MODE_PCIE); | ||
521 | if (ret < 0) | ||
522 | goto err_phy; | ||
523 | |||
502 | ret = phy_init(dra7xx->phy[i]); | 524 | ret = phy_init(dra7xx->phy[i]); |
503 | if (ret < 0) | 525 | if (ret < 0) |
504 | goto err_phy; | 526 | goto err_phy; |
@@ -529,6 +551,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = { | |||
529 | .mode = DW_PCIE_EP_TYPE, | 551 | .mode = DW_PCIE_EP_TYPE, |
530 | }; | 552 | }; |
531 | 553 | ||
554 | static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = { | ||
555 | .b1co_mode_sel_mask = BIT(2), | ||
556 | .mode = DW_PCIE_RC_TYPE, | ||
557 | }; | ||
558 | |||
559 | static const struct dra7xx_pcie_of_data dra726_pcie_rc_of_data = { | ||
560 | .b1co_mode_sel_mask = GENMASK(3, 2), | ||
561 | .mode = DW_PCIE_RC_TYPE, | ||
562 | }; | ||
563 | |||
564 | static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = { | ||
565 | .b1co_mode_sel_mask = BIT(2), | ||
566 | .mode = DW_PCIE_EP_TYPE, | ||
567 | }; | ||
568 | |||
569 | static const struct dra7xx_pcie_of_data dra726_pcie_ep_of_data = { | ||
570 | .b1co_mode_sel_mask = GENMASK(3, 2), | ||
571 | .mode = DW_PCIE_EP_TYPE, | ||
572 | }; | ||
573 | |||
532 | static const struct of_device_id of_dra7xx_pcie_match[] = { | 574 | static const struct of_device_id of_dra7xx_pcie_match[] = { |
533 | { | 575 | { |
534 | .compatible = "ti,dra7-pcie", | 576 | .compatible = "ti,dra7-pcie", |
@@ -538,6 +580,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = { | |||
538 | .compatible = "ti,dra7-pcie-ep", | 580 | .compatible = "ti,dra7-pcie-ep", |
539 | .data = &dra7xx_pcie_ep_of_data, | 581 | .data = &dra7xx_pcie_ep_of_data, |
540 | }, | 582 | }, |
583 | { | ||
584 | .compatible = "ti,dra746-pcie-rc", | ||
585 | .data = &dra746_pcie_rc_of_data, | ||
586 | }, | ||
587 | { | ||
588 | .compatible = "ti,dra726-pcie-rc", | ||
589 | .data = &dra726_pcie_rc_of_data, | ||
590 | }, | ||
591 | { | ||
592 | .compatible = "ti,dra746-pcie-ep", | ||
593 | .data = &dra746_pcie_ep_of_data, | ||
594 | }, | ||
595 | { | ||
596 | .compatible = "ti,dra726-pcie-ep", | ||
597 | .data = &dra726_pcie_ep_of_data, | ||
598 | }, | ||
541 | {}, | 599 | {}, |
542 | }; | 600 | }; |
543 | 601 | ||
@@ -583,6 +641,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev) | |||
583 | return ret; | 641 | return ret; |
584 | } | 642 | } |
585 | 643 | ||
644 | static int dra7xx_pcie_configure_two_lane(struct device *dev, | ||
645 | u32 b1co_mode_sel_mask) | ||
646 | { | ||
647 | struct device_node *np = dev->of_node; | ||
648 | struct regmap *pcie_syscon; | ||
649 | unsigned int pcie_reg; | ||
650 | u32 mask; | ||
651 | u32 val; | ||
652 | |||
653 | pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel"); | ||
654 | if (IS_ERR(pcie_syscon)) { | ||
655 | dev_err(dev, "unable to get ti,syscon-lane-sel\n"); | ||
656 | return -EINVAL; | ||
657 | } | ||
658 | |||
659 | if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1, | ||
660 | &pcie_reg)) { | ||
661 | dev_err(dev, "couldn't get lane selection reg offset\n"); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | |||
665 | mask = b1co_mode_sel_mask | PCIE_B0_B1_TSYNCEN; | ||
666 | val = PCIE_B1C0_MODE_SEL | PCIE_B0_B1_TSYNCEN; | ||
667 | regmap_update_bits(pcie_syscon, pcie_reg, mask, val); | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
586 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) | 672 | static int __init dra7xx_pcie_probe(struct platform_device *pdev) |
587 | { | 673 | { |
588 | u32 reg; | 674 | u32 reg; |
@@ -603,6 +689,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
603 | const struct of_device_id *match; | 689 | const struct of_device_id *match; |
604 | const struct dra7xx_pcie_of_data *data; | 690 | const struct dra7xx_pcie_of_data *data; |
605 | enum dw_pcie_device_mode mode; | 691 | enum dw_pcie_device_mode mode; |
692 | u32 b1co_mode_sel_mask; | ||
606 | 693 | ||
607 | match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); | 694 | match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); |
608 | if (!match) | 695 | if (!match) |
@@ -610,6 +697,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
610 | 697 | ||
611 | data = (struct dra7xx_pcie_of_data *)match->data; | 698 | data = (struct dra7xx_pcie_of_data *)match->data; |
612 | mode = (enum dw_pcie_device_mode)data->mode; | 699 | mode = (enum dw_pcie_device_mode)data->mode; |
700 | b1co_mode_sel_mask = data->b1co_mode_sel_mask; | ||
613 | 701 | ||
614 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); | 702 | dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); |
615 | if (!dra7xx) | 703 | if (!dra7xx) |
@@ -665,6 +753,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) | |||
665 | dra7xx->pci = pci; | 753 | dra7xx->pci = pci; |
666 | dra7xx->phy_count = phy_count; | 754 | dra7xx->phy_count = phy_count; |
667 | 755 | ||
756 | if (phy_count == 2) { | ||
757 | ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask); | ||
758 | if (ret < 0) | ||
759 | dra7xx->phy_count = 1; /* Fallback to x1 lane mode */ | ||
760 | } | ||
761 | |||
668 | ret = dra7xx_pcie_enable_phy(dra7xx); | 762 | ret = dra7xx_pcie_enable_phy(dra7xx); |
669 | if (ret) { | 763 | if (ret) { |
670 | dev_err(dev, "failed to enable phy\n"); | 764 | dev_err(dev, "failed to enable phy\n"); |
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 80f843030e36..3d627f94a166 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Author: Sean Cross <xobs@kosagi.com> | 8 | * Author: Sean Cross <xobs@kosagi.com> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bitfield.h> | ||
11 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
13 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
@@ -18,6 +19,7 @@ | |||
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
20 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/of_address.h> | ||
21 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
@@ -32,6 +34,12 @@ | |||
32 | 34 | ||
33 | #include "pcie-designware.h" | 35 | #include "pcie-designware.h" |
34 | 36 | ||
37 | #define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9) | ||
38 | #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10) | ||
39 | #define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11) | ||
40 | #define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8) | ||
41 | #define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000 | ||
42 | |||
35 | #define to_imx6_pcie(x) dev_get_drvdata((x)->dev) | 43 | #define to_imx6_pcie(x) dev_get_drvdata((x)->dev) |
36 | 44 | ||
37 | enum imx6_pcie_variants { | 45 | enum imx6_pcie_variants { |
@@ -39,6 +47,15 @@ enum imx6_pcie_variants { | |||
39 | IMX6SX, | 47 | IMX6SX, |
40 | IMX6QP, | 48 | IMX6QP, |
41 | IMX7D, | 49 | IMX7D, |
50 | IMX8MQ, | ||
51 | }; | ||
52 | |||
53 | #define IMX6_PCIE_FLAG_IMX6_PHY BIT(0) | ||
54 | #define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1) | ||
55 | |||
56 | struct imx6_pcie_drvdata { | ||
57 | enum imx6_pcie_variants variant; | ||
58 | u32 flags; | ||
42 | }; | 59 | }; |
43 | 60 | ||
44 | struct imx6_pcie { | 61 | struct imx6_pcie { |
@@ -49,11 +66,12 @@ struct imx6_pcie { | |||
49 | struct clk *pcie_phy; | 66 | struct clk *pcie_phy; |
50 | struct clk *pcie_inbound_axi; | 67 | struct clk *pcie_inbound_axi; |
51 | struct clk *pcie; | 68 | struct clk *pcie; |
69 | struct clk *pcie_aux; | ||
52 | struct regmap *iomuxc_gpr; | 70 | struct regmap *iomuxc_gpr; |
71 | u32 controller_id; | ||
53 | struct reset_control *pciephy_reset; | 72 | struct reset_control *pciephy_reset; |
54 | struct reset_control *apps_reset; | 73 | struct reset_control *apps_reset; |
55 | struct reset_control *turnoff_reset; | 74 | struct reset_control *turnoff_reset; |
56 | enum imx6_pcie_variants variant; | ||
57 | u32 tx_deemph_gen1; | 75 | u32 tx_deemph_gen1; |
58 | u32 tx_deemph_gen2_3p5db; | 76 | u32 tx_deemph_gen2_3p5db; |
59 | u32 tx_deemph_gen2_6db; | 77 | u32 tx_deemph_gen2_6db; |
@@ -61,11 +79,13 @@ struct imx6_pcie { | |||
61 | u32 tx_swing_low; | 79 | u32 tx_swing_low; |
62 | int link_gen; | 80 | int link_gen; |
63 | struct regulator *vpcie; | 81 | struct regulator *vpcie; |
82 | void __iomem *phy_base; | ||
64 | 83 | ||
65 | /* power domain for pcie */ | 84 | /* power domain for pcie */ |
66 | struct device *pd_pcie; | 85 | struct device *pd_pcie; |
67 | /* power domain for pcie phy */ | 86 | /* power domain for pcie phy */ |
68 | struct device *pd_pcie_phy; | 87 | struct device *pd_pcie_phy; |
88 | const struct imx6_pcie_drvdata *drvdata; | ||
69 | }; | 89 | }; |
70 | 90 | ||
71 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ | 91 | /* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */ |
@@ -101,7 +121,6 @@ struct imx6_pcie { | |||
101 | #define PCIE_PHY_STAT_ACK_LOC 16 | 121 | #define PCIE_PHY_STAT_ACK_LOC 16 |
102 | 122 | ||
103 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 123 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
104 | #define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) | ||
105 | 124 | ||
106 | /* PHY registers (not memory-mapped) */ | 125 | /* PHY registers (not memory-mapped) */ |
107 | #define PCIE_PHY_ATEOVRD 0x10 | 126 | #define PCIE_PHY_ATEOVRD 0x10 |
@@ -117,6 +136,23 @@ struct imx6_pcie { | |||
117 | #define PCIE_PHY_RX_ASIC_OUT 0x100D | 136 | #define PCIE_PHY_RX_ASIC_OUT 0x100D |
118 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) | 137 | #define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) |
119 | 138 | ||
139 | /* iMX7 PCIe PHY registers */ | ||
140 | #define PCIE_PHY_CMN_REG4 0x14 | ||
141 | /* These are probably the bits that *aren't* DCC_FB_EN */ | ||
142 | #define PCIE_PHY_CMN_REG4_DCC_FB_EN 0x29 | ||
143 | |||
144 | #define PCIE_PHY_CMN_REG15 0x54 | ||
145 | #define PCIE_PHY_CMN_REG15_DLY_4 BIT(2) | ||
146 | #define PCIE_PHY_CMN_REG15_PLL_PD BIT(5) | ||
147 | #define PCIE_PHY_CMN_REG15_OVRD_PLL_PD BIT(7) | ||
148 | |||
149 | #define PCIE_PHY_CMN_REG24 0x90 | ||
150 | #define PCIE_PHY_CMN_REG24_RX_EQ BIT(6) | ||
151 | #define PCIE_PHY_CMN_REG24_RX_EQ_SEL BIT(3) | ||
152 | |||
153 | #define PCIE_PHY_CMN_REG26 0x98 | ||
154 | #define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC | ||
155 | |||
120 | #define PHY_RX_OVRD_IN_LO 0x1005 | 156 | #define PHY_RX_OVRD_IN_LO 0x1005 |
121 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) | 157 | #define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) |
122 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) | 158 | #define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) |
@@ -251,6 +287,9 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) | |||
251 | { | 287 | { |
252 | u32 tmp; | 288 | u32 tmp; |
253 | 289 | ||
290 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | ||
291 | return; | ||
292 | |||
254 | pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp); | 293 | pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp); |
255 | tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | | 294 | tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | |
256 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); | 295 | PHY_RX_OVRD_IN_LO_RX_PLL_EN); |
@@ -264,6 +303,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) | |||
264 | pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp); | 303 | pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp); |
265 | } | 304 | } |
266 | 305 | ||
306 | #ifdef CONFIG_ARM | ||
267 | /* Added for PCI abort handling */ | 307 | /* Added for PCI abort handling */ |
268 | static int imx6q_pcie_abort_handler(unsigned long addr, | 308 | static int imx6q_pcie_abort_handler(unsigned long addr, |
269 | unsigned int fsr, struct pt_regs *regs) | 309 | unsigned int fsr, struct pt_regs *regs) |
@@ -297,6 +337,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr, | |||
297 | 337 | ||
298 | return 1; | 338 | return 1; |
299 | } | 339 | } |
340 | #endif | ||
300 | 341 | ||
301 | static int imx6_pcie_attach_pd(struct device *dev) | 342 | static int imx6_pcie_attach_pd(struct device *dev) |
302 | { | 343 | { |
@@ -342,8 +383,9 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) | |||
342 | { | 383 | { |
343 | struct device *dev = imx6_pcie->pci->dev; | 384 | struct device *dev = imx6_pcie->pci->dev; |
344 | 385 | ||
345 | switch (imx6_pcie->variant) { | 386 | switch (imx6_pcie->drvdata->variant) { |
346 | case IMX7D: | 387 | case IMX7D: |
388 | case IMX8MQ: | ||
347 | reset_control_assert(imx6_pcie->pciephy_reset); | 389 | reset_control_assert(imx6_pcie->pciephy_reset); |
348 | reset_control_assert(imx6_pcie->apps_reset); | 390 | reset_control_assert(imx6_pcie->apps_reset); |
349 | break; | 391 | break; |
@@ -378,13 +420,20 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) | |||
378 | } | 420 | } |
379 | } | 421 | } |
380 | 422 | ||
423 | static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) | ||
424 | { | ||
425 | WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ); | ||
426 | return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14; | ||
427 | } | ||
428 | |||
381 | static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | 429 | static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) |
382 | { | 430 | { |
383 | struct dw_pcie *pci = imx6_pcie->pci; | 431 | struct dw_pcie *pci = imx6_pcie->pci; |
384 | struct device *dev = pci->dev; | 432 | struct device *dev = pci->dev; |
433 | unsigned int offset; | ||
385 | int ret = 0; | 434 | int ret = 0; |
386 | 435 | ||
387 | switch (imx6_pcie->variant) { | 436 | switch (imx6_pcie->drvdata->variant) { |
388 | case IMX6SX: | 437 | case IMX6SX: |
389 | ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); | 438 | ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); |
390 | if (ret) { | 439 | if (ret) { |
@@ -412,6 +461,25 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie) | |||
412 | break; | 461 | break; |
413 | case IMX7D: | 462 | case IMX7D: |
414 | break; | 463 | break; |
464 | case IMX8MQ: | ||
465 | ret = clk_prepare_enable(imx6_pcie->pcie_aux); | ||
466 | if (ret) { | ||
467 | dev_err(dev, "unable to enable pcie_aux clock\n"); | ||
468 | break; | ||
469 | } | ||
470 | |||
471 | offset = imx6_pcie_grp_offset(imx6_pcie); | ||
472 | /* | ||
473 | * Set the over ride low and enabled | ||
474 | * make sure that REF_CLK is turned on. | ||
475 | */ | ||
476 | regmap_update_bits(imx6_pcie->iomuxc_gpr, offset, | ||
477 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE, | ||
478 | 0); | ||
479 | regmap_update_bits(imx6_pcie->iomuxc_gpr, offset, | ||
480 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN, | ||
481 | IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN); | ||
482 | break; | ||
415 | } | 483 | } |
416 | 484 | ||
417 | return ret; | 485 | return ret; |
@@ -487,9 +555,32 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) | |||
487 | !imx6_pcie->gpio_active_high); | 555 | !imx6_pcie->gpio_active_high); |
488 | } | 556 | } |
489 | 557 | ||
490 | switch (imx6_pcie->variant) { | 558 | switch (imx6_pcie->drvdata->variant) { |
559 | case IMX8MQ: | ||
560 | reset_control_deassert(imx6_pcie->pciephy_reset); | ||
561 | break; | ||
491 | case IMX7D: | 562 | case IMX7D: |
492 | reset_control_deassert(imx6_pcie->pciephy_reset); | 563 | reset_control_deassert(imx6_pcie->pciephy_reset); |
564 | |||
565 | /* Workaround for ERR010728, failure of PCI-e PLL VCO to | ||
566 | * oscillate, especially when cold. This turns off "Duty-cycle | ||
567 | * Corrector" and other mysterious undocumented things. | ||
568 | */ | ||
569 | if (likely(imx6_pcie->phy_base)) { | ||
570 | /* De-assert DCC_FB_EN */ | ||
571 | writel(PCIE_PHY_CMN_REG4_DCC_FB_EN, | ||
572 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG4); | ||
573 | /* Assert RX_EQS and RX_EQS_SEL */ | ||
574 | writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL | ||
575 | | PCIE_PHY_CMN_REG24_RX_EQ, | ||
576 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG24); | ||
577 | /* Assert ATT_MODE */ | ||
578 | writel(PCIE_PHY_CMN_REG26_ATT_MODE, | ||
579 | imx6_pcie->phy_base + PCIE_PHY_CMN_REG26); | ||
580 | } else { | ||
581 | dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n"); | ||
582 | } | ||
583 | |||
493 | imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie); | 584 | imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie); |
494 | break; | 585 | break; |
495 | case IMX6SX: | 586 | case IMX6SX: |
@@ -523,9 +614,37 @@ err_pcie_phy: | |||
523 | } | 614 | } |
524 | } | 615 | } |
525 | 616 | ||
617 | static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie) | ||
618 | { | ||
619 | unsigned int mask, val; | ||
620 | |||
621 | if (imx6_pcie->drvdata->variant == IMX8MQ && | ||
622 | imx6_pcie->controller_id == 1) { | ||
623 | mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE; | ||
624 | val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, | ||
625 | PCI_EXP_TYPE_ROOT_PORT); | ||
626 | } else { | ||
627 | mask = IMX6Q_GPR12_DEVICE_TYPE; | ||
628 | val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE, | ||
629 | PCI_EXP_TYPE_ROOT_PORT); | ||
630 | } | ||
631 | |||
632 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val); | ||
633 | } | ||
634 | |||
526 | static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) | 635 | static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) |
527 | { | 636 | { |
528 | switch (imx6_pcie->variant) { | 637 | switch (imx6_pcie->drvdata->variant) { |
638 | case IMX8MQ: | ||
639 | /* | ||
640 | * TODO: Currently this code assumes external | ||
641 | * oscillator is being used | ||
642 | */ | ||
643 | regmap_update_bits(imx6_pcie->iomuxc_gpr, | ||
644 | imx6_pcie_grp_offset(imx6_pcie), | ||
645 | IMX8MQ_GPR_PCIE_REF_USE_PAD, | ||
646 | IMX8MQ_GPR_PCIE_REF_USE_PAD); | ||
647 | break; | ||
529 | case IMX7D: | 648 | case IMX7D: |
530 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 649 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
531 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0); | 650 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0); |
@@ -561,8 +680,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) | |||
561 | break; | 680 | break; |
562 | } | 681 | } |
563 | 682 | ||
564 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 683 | imx6_pcie_configure_type(imx6_pcie); |
565 | IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); | ||
566 | } | 684 | } |
567 | 685 | ||
568 | static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | 686 | static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) |
@@ -571,6 +689,9 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) | |||
571 | int mult, div; | 689 | int mult, div; |
572 | u32 val; | 690 | u32 val; |
573 | 691 | ||
692 | if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) | ||
693 | return 0; | ||
694 | |||
574 | switch (phy_rate) { | 695 | switch (phy_rate) { |
575 | case 125000000: | 696 | case 125000000: |
576 | /* | 697 | /* |
@@ -647,7 +768,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) | |||
647 | { | 768 | { |
648 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 769 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
649 | 770 | ||
650 | switch (imx6_pcie->variant) { | 771 | switch (imx6_pcie->drvdata->variant) { |
651 | case IMX6Q: | 772 | case IMX6Q: |
652 | case IMX6SX: | 773 | case IMX6SX: |
653 | case IMX6QP: | 774 | case IMX6QP: |
@@ -656,6 +777,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev) | |||
656 | IMX6Q_GPR12_PCIE_CTL_2); | 777 | IMX6Q_GPR12_PCIE_CTL_2); |
657 | break; | 778 | break; |
658 | case IMX7D: | 779 | case IMX7D: |
780 | case IMX8MQ: | ||
659 | reset_control_deassert(imx6_pcie->apps_reset); | 781 | reset_control_deassert(imx6_pcie->apps_reset); |
660 | break; | 782 | break; |
661 | } | 783 | } |
@@ -700,7 +822,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) | |||
700 | tmp |= PORT_LOGIC_SPEED_CHANGE; | 822 | tmp |= PORT_LOGIC_SPEED_CHANGE; |
701 | dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); | 823 | dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp); |
702 | 824 | ||
703 | if (imx6_pcie->variant != IMX7D) { | 825 | if (imx6_pcie->drvdata->flags & |
826 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE) { | ||
704 | /* | 827 | /* |
705 | * On i.MX7, DIRECT_SPEED_CHANGE behaves differently | 828 | * On i.MX7, DIRECT_SPEED_CHANGE behaves differently |
706 | * from i.MX6 family when no link speed transition | 829 | * from i.MX6 family when no link speed transition |
@@ -797,7 +920,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev) | |||
797 | { | 920 | { |
798 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); | 921 | struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); |
799 | 922 | ||
800 | switch (imx6_pcie->variant) { | 923 | switch (imx6_pcie->drvdata->variant) { |
801 | case IMX6SX: | 924 | case IMX6SX: |
802 | case IMX6QP: | 925 | case IMX6QP: |
803 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 926 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
@@ -823,7 +946,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie) | |||
823 | } | 946 | } |
824 | 947 | ||
825 | /* Others poke directly at IOMUXC registers */ | 948 | /* Others poke directly at IOMUXC registers */ |
826 | switch (imx6_pcie->variant) { | 949 | switch (imx6_pcie->drvdata->variant) { |
827 | case IMX6SX: | 950 | case IMX6SX: |
828 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, | 951 | regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, |
829 | IMX6SX_GPR12_PCIE_PM_TURN_OFF, | 952 | IMX6SX_GPR12_PCIE_PM_TURN_OFF, |
@@ -853,7 +976,7 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
853 | clk_disable_unprepare(imx6_pcie->pcie_phy); | 976 | clk_disable_unprepare(imx6_pcie->pcie_phy); |
854 | clk_disable_unprepare(imx6_pcie->pcie_bus); | 977 | clk_disable_unprepare(imx6_pcie->pcie_bus); |
855 | 978 | ||
856 | switch (imx6_pcie->variant) { | 979 | switch (imx6_pcie->drvdata->variant) { |
857 | case IMX6SX: | 980 | case IMX6SX: |
858 | clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); | 981 | clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); |
859 | break; | 982 | break; |
@@ -862,6 +985,9 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
862 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, | 985 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, |
863 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); | 986 | IMX7D_GPR12_PCIE_PHY_REFCLK_SEL); |
864 | break; | 987 | break; |
988 | case IMX8MQ: | ||
989 | clk_disable_unprepare(imx6_pcie->pcie_aux); | ||
990 | break; | ||
865 | default: | 991 | default: |
866 | break; | 992 | break; |
867 | } | 993 | } |
@@ -869,8 +995,8 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie) | |||
869 | 995 | ||
870 | static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) | 996 | static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie) |
871 | { | 997 | { |
872 | return (imx6_pcie->variant == IMX7D || | 998 | return (imx6_pcie->drvdata->variant == IMX7D || |
873 | imx6_pcie->variant == IMX6SX); | 999 | imx6_pcie->drvdata->variant == IMX6SX); |
874 | } | 1000 | } |
875 | 1001 | ||
876 | static int imx6_pcie_suspend_noirq(struct device *dev) | 1002 | static int imx6_pcie_suspend_noirq(struct device *dev) |
@@ -919,6 +1045,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
919 | struct device *dev = &pdev->dev; | 1045 | struct device *dev = &pdev->dev; |
920 | struct dw_pcie *pci; | 1046 | struct dw_pcie *pci; |
921 | struct imx6_pcie *imx6_pcie; | 1047 | struct imx6_pcie *imx6_pcie; |
1048 | struct device_node *np; | ||
922 | struct resource *dbi_base; | 1049 | struct resource *dbi_base; |
923 | struct device_node *node = dev->of_node; | 1050 | struct device_node *node = dev->of_node; |
924 | int ret; | 1051 | int ret; |
@@ -936,8 +1063,24 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
936 | pci->ops = &dw_pcie_ops; | 1063 | pci->ops = &dw_pcie_ops; |
937 | 1064 | ||
938 | imx6_pcie->pci = pci; | 1065 | imx6_pcie->pci = pci; |
939 | imx6_pcie->variant = | 1066 | imx6_pcie->drvdata = of_device_get_match_data(dev); |
940 | (enum imx6_pcie_variants)of_device_get_match_data(dev); | 1067 | |
1068 | /* Find the PHY if one is defined, only imx7d uses it */ | ||
1069 | np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0); | ||
1070 | if (np) { | ||
1071 | struct resource res; | ||
1072 | |||
1073 | ret = of_address_to_resource(np, 0, &res); | ||
1074 | if (ret) { | ||
1075 | dev_err(dev, "Unable to map PCIe PHY\n"); | ||
1076 | return ret; | ||
1077 | } | ||
1078 | imx6_pcie->phy_base = devm_ioremap_resource(dev, &res); | ||
1079 | if (IS_ERR(imx6_pcie->phy_base)) { | ||
1080 | dev_err(dev, "Unable to map PCIe PHY\n"); | ||
1081 | return PTR_ERR(imx6_pcie->phy_base); | ||
1082 | } | ||
1083 | } | ||
941 | 1084 | ||
942 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1085 | dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
943 | pci->dbi_base = devm_ioremap_resource(dev, dbi_base); | 1086 | pci->dbi_base = devm_ioremap_resource(dev, dbi_base); |
@@ -981,7 +1124,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
981 | return PTR_ERR(imx6_pcie->pcie); | 1124 | return PTR_ERR(imx6_pcie->pcie); |
982 | } | 1125 | } |
983 | 1126 | ||
984 | switch (imx6_pcie->variant) { | 1127 | switch (imx6_pcie->drvdata->variant) { |
985 | case IMX6SX: | 1128 | case IMX6SX: |
986 | imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, | 1129 | imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, |
987 | "pcie_inbound_axi"); | 1130 | "pcie_inbound_axi"); |
@@ -990,7 +1133,17 @@ static int imx6_pcie_probe(struct platform_device *pdev) | |||
990 | return PTR_ERR(imx6_pcie->pcie_inbound_axi); | 1133 | return PTR_ERR(imx6_pcie->pcie_inbound_axi); |
991 | } | 1134 | } |
992 | break; | 1135 | break; |
1136 | case IMX8MQ: | ||
1137 | imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); | ||
1138 | if (IS_ERR(imx6_pcie->pcie_aux)) { | ||
1139 | dev_err(dev, "pcie_aux clock source missing or invalid\n"); | ||
1140 | return PTR_ERR(imx6_pcie->pcie_aux); | ||
1141 | } | ||
1142 | /* fall through */ | ||
993 | case IMX7D: | 1143 | case IMX7D: |
1144 | if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) | ||
1145 | imx6_pcie->controller_id = 1; | ||
1146 | |||
994 | imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, | 1147 | imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, |
995 | "pciephy"); | 1148 | "pciephy"); |
996 | if (IS_ERR(imx6_pcie->pciephy_reset)) { | 1149 | if (IS_ERR(imx6_pcie->pciephy_reset)) { |
@@ -1087,11 +1240,36 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) | |||
1087 | imx6_pcie_assert_core_reset(imx6_pcie); | 1240 | imx6_pcie_assert_core_reset(imx6_pcie); |
1088 | } | 1241 | } |
1089 | 1242 | ||
1243 | static const struct imx6_pcie_drvdata drvdata[] = { | ||
1244 | [IMX6Q] = { | ||
1245 | .variant = IMX6Q, | ||
1246 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
1247 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
1248 | }, | ||
1249 | [IMX6SX] = { | ||
1250 | .variant = IMX6SX, | ||
1251 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
1252 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
1253 | }, | ||
1254 | [IMX6QP] = { | ||
1255 | .variant = IMX6QP, | ||
1256 | .flags = IMX6_PCIE_FLAG_IMX6_PHY | | ||
1257 | IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE, | ||
1258 | }, | ||
1259 | [IMX7D] = { | ||
1260 | .variant = IMX7D, | ||
1261 | }, | ||
1262 | [IMX8MQ] = { | ||
1263 | .variant = IMX8MQ, | ||
1264 | }, | ||
1265 | }; | ||
1266 | |||
1090 | static const struct of_device_id imx6_pcie_of_match[] = { | 1267 | static const struct of_device_id imx6_pcie_of_match[] = { |
1091 | { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, }, | 1268 | { .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], }, |
1092 | { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, }, | 1269 | { .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], }, |
1093 | { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, | 1270 | { .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], }, |
1094 | { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, }, | 1271 | { .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], }, |
1272 | { .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], } , | ||
1095 | {}, | 1273 | {}, |
1096 | }; | 1274 | }; |
1097 | 1275 | ||
@@ -1108,6 +1286,7 @@ static struct platform_driver imx6_pcie_driver = { | |||
1108 | 1286 | ||
1109 | static int __init imx6_pcie_init(void) | 1287 | static int __init imx6_pcie_init(void) |
1110 | { | 1288 | { |
1289 | #ifdef CONFIG_ARM | ||
1111 | /* | 1290 | /* |
1112 | * Since probe() can be deferred we need to make sure that | 1291 | * Since probe() can be deferred we need to make sure that |
1113 | * hook_fault_code is not called after __init memory is freed | 1292 | * hook_fault_code is not called after __init memory is freed |
@@ -1117,6 +1296,7 @@ static int __init imx6_pcie_init(void) | |||
1117 | */ | 1296 | */ |
1118 | hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0, | 1297 | hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0, |
1119 | "external abort on non-linefetch"); | 1298 | "external abort on non-linefetch"); |
1299 | #endif | ||
1120 | 1300 | ||
1121 | return platform_driver_register(&imx6_pcie_driver); | 1301 | return platform_driver_register(&imx6_pcie_driver); |
1122 | } | 1302 | } |
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c new file mode 100644 index 000000000000..a42c9c3ae1cc --- /dev/null +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c | |||
@@ -0,0 +1,156 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * PCIe controller EP driver for Freescale Layerscape SoCs | ||
4 | * | ||
5 | * Copyright (C) 2018 NXP Semiconductor. | ||
6 | * | ||
7 | * Author: Xiaowei Bao <xiaowei.bao@nxp.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/of_pci.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <linux/of_address.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/resource.h> | ||
18 | |||
19 | #include "pcie-designware.h" | ||
20 | |||
21 | #define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/ | ||
22 | |||
23 | struct ls_pcie_ep { | ||
24 | struct dw_pcie *pci; | ||
25 | }; | ||
26 | |||
27 | #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev) | ||
28 | |||
29 | static int ls_pcie_establish_link(struct dw_pcie *pci) | ||
30 | { | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static const struct dw_pcie_ops ls_pcie_ep_ops = { | ||
35 | .start_link = ls_pcie_establish_link, | ||
36 | }; | ||
37 | |||
38 | static const struct of_device_id ls_pcie_ep_of_match[] = { | ||
39 | { .compatible = "fsl,ls-pcie-ep",}, | ||
40 | { }, | ||
41 | }; | ||
42 | |||
43 | static const struct pci_epc_features ls_pcie_epc_features = { | ||
44 | .linkup_notifier = false, | ||
45 | .msi_capable = true, | ||
46 | .msix_capable = false, | ||
47 | }; | ||
48 | |||
49 | static const struct pci_epc_features* | ||
50 | ls_pcie_ep_get_features(struct dw_pcie_ep *ep) | ||
51 | { | ||
52 | return &ls_pcie_epc_features; | ||
53 | } | ||
54 | |||
55 | static void ls_pcie_ep_init(struct dw_pcie_ep *ep) | ||
56 | { | ||
57 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
58 | enum pci_barno bar; | ||
59 | |||
60 | for (bar = BAR_0; bar <= BAR_5; bar++) | ||
61 | dw_pcie_ep_reset_bar(pci, bar); | ||
62 | } | ||
63 | |||
64 | static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | ||
65 | enum pci_epc_irq_type type, u16 interrupt_num) | ||
66 | { | ||
67 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
68 | |||
69 | switch (type) { | ||
70 | case PCI_EPC_IRQ_LEGACY: | ||
71 | return dw_pcie_ep_raise_legacy_irq(ep, func_no); | ||
72 | case PCI_EPC_IRQ_MSI: | ||
73 | return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); | ||
74 | case PCI_EPC_IRQ_MSIX: | ||
75 | return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); | ||
76 | default: | ||
77 | dev_err(pci->dev, "UNKNOWN IRQ type\n"); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static struct dw_pcie_ep_ops pcie_ep_ops = { | ||
83 | .ep_init = ls_pcie_ep_init, | ||
84 | .raise_irq = ls_pcie_ep_raise_irq, | ||
85 | .get_features = ls_pcie_ep_get_features, | ||
86 | }; | ||
87 | |||
88 | static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie, | ||
89 | struct platform_device *pdev) | ||
90 | { | ||
91 | struct dw_pcie *pci = pcie->pci; | ||
92 | struct device *dev = pci->dev; | ||
93 | struct dw_pcie_ep *ep; | ||
94 | struct resource *res; | ||
95 | int ret; | ||
96 | |||
97 | ep = &pci->ep; | ||
98 | ep->ops = &pcie_ep_ops; | ||
99 | |||
100 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); | ||
101 | if (!res) | ||
102 | return -EINVAL; | ||
103 | |||
104 | ep->phys_base = res->start; | ||
105 | ep->addr_size = resource_size(res); | ||
106 | |||
107 | ret = dw_pcie_ep_init(ep); | ||
108 | if (ret) { | ||
109 | dev_err(dev, "failed to initialize endpoint\n"); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int __init ls_pcie_ep_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct device *dev = &pdev->dev; | ||
119 | struct dw_pcie *pci; | ||
120 | struct ls_pcie_ep *pcie; | ||
121 | struct resource *dbi_base; | ||
122 | int ret; | ||
123 | |||
124 | pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); | ||
125 | if (!pcie) | ||
126 | return -ENOMEM; | ||
127 | |||
128 | pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); | ||
129 | if (!pci) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); | ||
133 | pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base); | ||
134 | if (IS_ERR(pci->dbi_base)) | ||
135 | return PTR_ERR(pci->dbi_base); | ||
136 | |||
137 | pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET; | ||
138 | pci->dev = dev; | ||
139 | pci->ops = &ls_pcie_ep_ops; | ||
140 | pcie->pci = pci; | ||
141 | |||
142 | platform_set_drvdata(pdev, pcie); | ||
143 | |||
144 | ret = ls_add_pcie_ep(pcie, pdev); | ||
145 | |||
146 | return ret; | ||
147 | } | ||
148 | |||
149 | static struct platform_driver ls_pcie_ep_driver = { | ||
150 | .driver = { | ||
151 | .name = "layerscape-pcie-ep", | ||
152 | .of_match_table = ls_pcie_ep_of_match, | ||
153 | .suppress_bind_attrs = true, | ||
154 | }, | ||
155 | }; | ||
156 | builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe); | ||
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index a543c45c7224..24f5a775ad34 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c | |||
@@ -355,6 +355,17 @@ static int dw_pcie_ep_start(struct pci_epc *epc) | |||
355 | return pci->ops->start_link(pci); | 355 | return pci->ops->start_link(pci); |
356 | } | 356 | } |
357 | 357 | ||
358 | static const struct pci_epc_features* | ||
359 | dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
360 | { | ||
361 | struct dw_pcie_ep *ep = epc_get_drvdata(epc); | ||
362 | |||
363 | if (!ep->ops->get_features) | ||
364 | return NULL; | ||
365 | |||
366 | return ep->ops->get_features(ep); | ||
367 | } | ||
368 | |||
358 | static const struct pci_epc_ops epc_ops = { | 369 | static const struct pci_epc_ops epc_ops = { |
359 | .write_header = dw_pcie_ep_write_header, | 370 | .write_header = dw_pcie_ep_write_header, |
360 | .set_bar = dw_pcie_ep_set_bar, | 371 | .set_bar = dw_pcie_ep_set_bar, |
@@ -368,6 +379,7 @@ static const struct pci_epc_ops epc_ops = { | |||
368 | .raise_irq = dw_pcie_ep_raise_irq, | 379 | .raise_irq = dw_pcie_ep_raise_irq, |
369 | .start = dw_pcie_ep_start, | 380 | .start = dw_pcie_ep_start, |
370 | .stop = dw_pcie_ep_stop, | 381 | .stop = dw_pcie_ep_stop, |
382 | .get_features = dw_pcie_ep_get_features, | ||
371 | }; | 383 | }; |
372 | 384 | ||
373 | int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) | 385 | int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) |
@@ -465,8 +477,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
465 | 477 | ||
466 | iounmap(msix_tbl); | 478 | iounmap(msix_tbl); |
467 | 479 | ||
468 | if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) | 480 | if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) { |
481 | dev_dbg(pci->dev, "MSI-X entry ctrl set\n"); | ||
469 | return -EPERM; | 482 | return -EPERM; |
483 | } | ||
470 | 484 | ||
471 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, | 485 | ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, |
472 | epc->mem->page_size); | 486 | epc->mem->page_size); |
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 721d60a5d9e4..25087d3c9a82 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c | |||
@@ -120,9 +120,9 @@ static void dw_chained_msi_isr(struct irq_desc *desc) | |||
120 | chained_irq_exit(chip, desc); | 120 | chained_irq_exit(chip, desc); |
121 | } | 121 | } |
122 | 122 | ||
123 | static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg) | 123 | static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) |
124 | { | 124 | { |
125 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 125 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 126 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
127 | u64 msi_target; | 127 | u64 msi_target; |
128 | 128 | ||
@@ -135,61 +135,61 @@ static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg) | |||
135 | msg->address_hi = upper_32_bits(msi_target); | 135 | msg->address_hi = upper_32_bits(msi_target); |
136 | 136 | ||
137 | if (pp->ops->get_msi_data) | 137 | if (pp->ops->get_msi_data) |
138 | msg->data = pp->ops->get_msi_data(pp, data->hwirq); | 138 | msg->data = pp->ops->get_msi_data(pp, d->hwirq); |
139 | else | 139 | else |
140 | msg->data = data->hwirq; | 140 | msg->data = d->hwirq; |
141 | 141 | ||
142 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", | 142 | dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", |
143 | (int)data->hwirq, msg->address_hi, msg->address_lo); | 143 | (int)d->hwirq, msg->address_hi, msg->address_lo); |
144 | } | 144 | } |
145 | 145 | ||
146 | static int dw_pci_msi_set_affinity(struct irq_data *irq_data, | 146 | static int dw_pci_msi_set_affinity(struct irq_data *d, |
147 | const struct cpumask *mask, bool force) | 147 | const struct cpumask *mask, bool force) |
148 | { | 148 | { |
149 | return -EINVAL; | 149 | return -EINVAL; |
150 | } | 150 | } |
151 | 151 | ||
152 | static void dw_pci_bottom_mask(struct irq_data *data) | 152 | static void dw_pci_bottom_mask(struct irq_data *d) |
153 | { | 153 | { |
154 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 154 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
155 | unsigned int res, bit, ctrl; | 155 | unsigned int res, bit, ctrl; |
156 | unsigned long flags; | 156 | unsigned long flags; |
157 | 157 | ||
158 | raw_spin_lock_irqsave(&pp->lock, flags); | 158 | raw_spin_lock_irqsave(&pp->lock, flags); |
159 | 159 | ||
160 | if (pp->ops->msi_clear_irq) { | 160 | if (pp->ops->msi_clear_irq) { |
161 | pp->ops->msi_clear_irq(pp, data->hwirq); | 161 | pp->ops->msi_clear_irq(pp, d->hwirq); |
162 | } else { | 162 | } else { |
163 | ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; | 163 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
164 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | 164 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
165 | bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; | 165 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
166 | 166 | ||
167 | pp->irq_status[ctrl] &= ~(1 << bit); | 167 | pp->irq_mask[ctrl] |= BIT(bit); |
168 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 168 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
169 | ~pp->irq_status[ctrl]); | 169 | pp->irq_mask[ctrl]); |
170 | } | 170 | } |
171 | 171 | ||
172 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 172 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
173 | } | 173 | } |
174 | 174 | ||
175 | static void dw_pci_bottom_unmask(struct irq_data *data) | 175 | static void dw_pci_bottom_unmask(struct irq_data *d) |
176 | { | 176 | { |
177 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 177 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
178 | unsigned int res, bit, ctrl; | 178 | unsigned int res, bit, ctrl; |
179 | unsigned long flags; | 179 | unsigned long flags; |
180 | 180 | ||
181 | raw_spin_lock_irqsave(&pp->lock, flags); | 181 | raw_spin_lock_irqsave(&pp->lock, flags); |
182 | 182 | ||
183 | if (pp->ops->msi_set_irq) { | 183 | if (pp->ops->msi_set_irq) { |
184 | pp->ops->msi_set_irq(pp, data->hwirq); | 184 | pp->ops->msi_set_irq(pp, d->hwirq); |
185 | } else { | 185 | } else { |
186 | ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; | 186 | ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; |
187 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; | 187 | res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; |
188 | bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; | 188 | bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; |
189 | 189 | ||
190 | pp->irq_status[ctrl] |= 1 << bit; | 190 | pp->irq_mask[ctrl] &= ~BIT(bit); |
191 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, | 191 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4, |
192 | ~pp->irq_status[ctrl]); | 192 | pp->irq_mask[ctrl]); |
193 | } | 193 | } |
194 | 194 | ||
195 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 195 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
@@ -207,7 +207,7 @@ static void dw_pci_bottom_ack(struct irq_data *d) | |||
207 | 207 | ||
208 | raw_spin_lock_irqsave(&pp->lock, flags); | 208 | raw_spin_lock_irqsave(&pp->lock, flags); |
209 | 209 | ||
210 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, 1 << bit); | 210 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, BIT(bit)); |
211 | 211 | ||
212 | if (pp->ops->msi_irq_ack) | 212 | if (pp->ops->msi_irq_ack) |
213 | pp->ops->msi_irq_ack(d->hwirq, pp); | 213 | pp->ops->msi_irq_ack(d->hwirq, pp); |
@@ -255,13 +255,13 @@ static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, | |||
255 | static void dw_pcie_irq_domain_free(struct irq_domain *domain, | 255 | static void dw_pcie_irq_domain_free(struct irq_domain *domain, |
256 | unsigned int virq, unsigned int nr_irqs) | 256 | unsigned int virq, unsigned int nr_irqs) |
257 | { | 257 | { |
258 | struct irq_data *data = irq_domain_get_irq_data(domain, virq); | 258 | struct irq_data *d = irq_domain_get_irq_data(domain, virq); |
259 | struct pcie_port *pp = irq_data_get_irq_chip_data(data); | 259 | struct pcie_port *pp = irq_data_get_irq_chip_data(d); |
260 | unsigned long flags; | 260 | unsigned long flags; |
261 | 261 | ||
262 | raw_spin_lock_irqsave(&pp->lock, flags); | 262 | raw_spin_lock_irqsave(&pp->lock, flags); |
263 | 263 | ||
264 | bitmap_release_region(pp->msi_irq_in_use, data->hwirq, | 264 | bitmap_release_region(pp->msi_irq_in_use, d->hwirq, |
265 | order_base_2(nr_irqs)); | 265 | order_base_2(nr_irqs)); |
266 | 266 | ||
267 | raw_spin_unlock_irqrestore(&pp->lock, flags); | 267 | raw_spin_unlock_irqrestore(&pp->lock, flags); |
@@ -439,7 +439,7 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
439 | if (ret) | 439 | if (ret) |
440 | pci->num_viewport = 2; | 440 | pci->num_viewport = 2; |
441 | 441 | ||
442 | if (IS_ENABLED(CONFIG_PCI_MSI)) { | 442 | if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_enabled()) { |
443 | /* | 443 | /* |
444 | * If a specific SoC driver needs to change the | 444 | * If a specific SoC driver needs to change the |
445 | * default number of vectors, it needs to implement | 445 | * default number of vectors, it needs to implement |
@@ -512,8 +512,9 @@ error: | |||
512 | return ret; | 512 | return ret; |
513 | } | 513 | } |
514 | 514 | ||
515 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 515 | static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
516 | u32 devfn, int where, int size, u32 *val) | 516 | u32 devfn, int where, int size, u32 *val, |
517 | bool write) | ||
517 | { | 518 | { |
518 | int ret, type; | 519 | int ret, type; |
519 | u32 busdev, cfg_size; | 520 | u32 busdev, cfg_size; |
@@ -521,9 +522,6 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
521 | void __iomem *va_cfg_base; | 522 | void __iomem *va_cfg_base; |
522 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 523 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
523 | 524 | ||
524 | if (pp->ops->rd_other_conf) | ||
525 | return pp->ops->rd_other_conf(pp, bus, devfn, where, size, val); | ||
526 | |||
527 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | 525 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | |
528 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | 526 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); |
529 | 527 | ||
@@ -542,7 +540,11 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
542 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 540 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
543 | type, cpu_addr, | 541 | type, cpu_addr, |
544 | busdev, cfg_size); | 542 | busdev, cfg_size); |
545 | ret = dw_pcie_read(va_cfg_base + where, size, val); | 543 | if (write) |
544 | ret = dw_pcie_write(va_cfg_base + where, size, *val); | ||
545 | else | ||
546 | ret = dw_pcie_read(va_cfg_base + where, size, val); | ||
547 | |||
546 | if (pci->num_viewport <= 2) | 548 | if (pci->num_viewport <= 2) |
547 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | 549 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, |
548 | PCIE_ATU_TYPE_IO, pp->io_base, | 550 | PCIE_ATU_TYPE_IO, pp->io_base, |
@@ -551,43 +553,26 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | |||
551 | return ret; | 553 | return ret; |
552 | } | 554 | } |
553 | 555 | ||
556 | static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, | ||
557 | u32 devfn, int where, int size, u32 *val) | ||
558 | { | ||
559 | if (pp->ops->rd_other_conf) | ||
560 | return pp->ops->rd_other_conf(pp, bus, devfn, where, | ||
561 | size, val); | ||
562 | |||
563 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, val, | ||
564 | false); | ||
565 | } | ||
566 | |||
554 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, | 567 | static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, |
555 | u32 devfn, int where, int size, u32 val) | 568 | u32 devfn, int where, int size, u32 val) |
556 | { | 569 | { |
557 | int ret, type; | ||
558 | u32 busdev, cfg_size; | ||
559 | u64 cpu_addr; | ||
560 | void __iomem *va_cfg_base; | ||
561 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
562 | |||
563 | if (pp->ops->wr_other_conf) | 570 | if (pp->ops->wr_other_conf) |
564 | return pp->ops->wr_other_conf(pp, bus, devfn, where, size, val); | 571 | return pp->ops->wr_other_conf(pp, bus, devfn, where, |
565 | 572 | size, val); | |
566 | busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) | | ||
567 | PCIE_ATU_FUNC(PCI_FUNC(devfn)); | ||
568 | 573 | ||
569 | if (bus->parent->number == pp->root_bus_nr) { | 574 | return dw_pcie_access_other_conf(pp, bus, devfn, where, size, &val, |
570 | type = PCIE_ATU_TYPE_CFG0; | 575 | true); |
571 | cpu_addr = pp->cfg0_base; | ||
572 | cfg_size = pp->cfg0_size; | ||
573 | va_cfg_base = pp->va_cfg0_base; | ||
574 | } else { | ||
575 | type = PCIE_ATU_TYPE_CFG1; | ||
576 | cpu_addr = pp->cfg1_base; | ||
577 | cfg_size = pp->cfg1_size; | ||
578 | va_cfg_base = pp->va_cfg1_base; | ||
579 | } | ||
580 | |||
581 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
582 | type, cpu_addr, | ||
583 | busdev, cfg_size); | ||
584 | ret = dw_pcie_write(va_cfg_base + where, size, val); | ||
585 | if (pci->num_viewport <= 2) | ||
586 | dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, | ||
587 | PCIE_ATU_TYPE_IO, pp->io_base, | ||
588 | pp->io_bus_addr, pp->io_size); | ||
589 | |||
590 | return ret; | ||
591 | } | 576 | } |
592 | 577 | ||
593 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, | 578 | static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, |
@@ -665,13 +650,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
665 | 650 | ||
666 | /* Initialize IRQ Status array */ | 651 | /* Initialize IRQ Status array */ |
667 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { | 652 | for (ctrl = 0; ctrl < num_ctrls; ctrl++) { |
653 | pp->irq_mask[ctrl] = ~0; | ||
668 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + | 654 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + |
669 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 655 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
670 | 4, ~0); | 656 | 4, pp->irq_mask[ctrl]); |
671 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + | 657 | dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + |
672 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), | 658 | (ctrl * MSI_REG_CTRL_BLOCK_SIZE), |
673 | 4, ~0); | 659 | 4, ~0); |
674 | pp->irq_status[ctrl] = 0; | ||
675 | } | 660 | } |
676 | 661 | ||
677 | /* Setup RC BARs */ | 662 | /* Setup RC BARs */ |
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index c12bf794d69c..932dbd0b34b6 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c | |||
@@ -13,11 +13,9 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
16 | #include <linux/of_gpio.h> | ||
17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
18 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
19 | #include <linux/resource.h> | 18 | #include <linux/resource.h> |
20 | #include <linux/signal.h> | ||
21 | #include <linux/types.h> | 19 | #include <linux/types.h> |
22 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
23 | 21 | ||
@@ -70,14 +68,10 @@ static const struct dw_pcie_ops dw_pcie_ops = { | |||
70 | static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) | 68 | static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) |
71 | { | 69 | { |
72 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | 70 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); |
73 | struct pci_epc *epc = ep->epc; | ||
74 | enum pci_barno bar; | 71 | enum pci_barno bar; |
75 | 72 | ||
76 | for (bar = BAR_0; bar <= BAR_5; bar++) | 73 | for (bar = BAR_0; bar <= BAR_5; bar++) |
77 | dw_pcie_ep_reset_bar(pci, bar); | 74 | dw_pcie_ep_reset_bar(pci, bar); |
78 | |||
79 | epc->features |= EPC_FEATURE_NO_LINKUP_NOTIFIER; | ||
80 | epc->features |= EPC_FEATURE_MSIX_AVAILABLE; | ||
81 | } | 75 | } |
82 | 76 | ||
83 | static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | 77 | static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, |
@@ -100,9 +94,22 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | |||
100 | return 0; | 94 | return 0; |
101 | } | 95 | } |
102 | 96 | ||
97 | static const struct pci_epc_features dw_plat_pcie_epc_features = { | ||
98 | .linkup_notifier = false, | ||
99 | .msi_capable = true, | ||
100 | .msix_capable = true, | ||
101 | }; | ||
102 | |||
103 | static const struct pci_epc_features* | ||
104 | dw_plat_pcie_get_features(struct dw_pcie_ep *ep) | ||
105 | { | ||
106 | return &dw_plat_pcie_epc_features; | ||
107 | } | ||
108 | |||
103 | static struct dw_pcie_ep_ops pcie_ep_ops = { | 109 | static struct dw_pcie_ep_ops pcie_ep_ops = { |
104 | .ep_init = dw_plat_pcie_ep_init, | 110 | .ep_init = dw_plat_pcie_ep_init, |
105 | .raise_irq = dw_plat_pcie_ep_raise_irq, | 111 | .raise_irq = dw_plat_pcie_ep_raise_irq, |
112 | .get_features = dw_plat_pcie_get_features, | ||
106 | }; | 113 | }; |
107 | 114 | ||
108 | static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie, | 115 | static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie, |
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 93ef8c31fb39..31f6331ca46f 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) | 23 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) |
24 | { | 24 | { |
25 | if ((uintptr_t)addr & (size - 1)) { | 25 | if (!IS_ALIGNED((uintptr_t)addr, size)) { |
26 | *val = 0; | 26 | *val = 0; |
27 | return PCIBIOS_BAD_REGISTER_NUMBER; | 27 | return PCIBIOS_BAD_REGISTER_NUMBER; |
28 | } | 28 | } |
@@ -43,7 +43,7 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val) | |||
43 | 43 | ||
44 | int dw_pcie_write(void __iomem *addr, int size, u32 val) | 44 | int dw_pcie_write(void __iomem *addr, int size, u32 val) |
45 | { | 45 | { |
46 | if ((uintptr_t)addr & (size - 1)) | 46 | if (!IS_ALIGNED((uintptr_t)addr, size)) |
47 | return PCIBIOS_BAD_REGISTER_NUMBER; | 47 | return PCIBIOS_BAD_REGISTER_NUMBER; |
48 | 48 | ||
49 | if (size == 4) | 49 | if (size == 4) |
@@ -306,7 +306,7 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index, | |||
306 | } | 306 | } |
307 | 307 | ||
308 | dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); | 308 | dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); |
309 | dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~PCIE_ATU_ENABLE); | 309 | dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, (u32)~PCIE_ATU_ENABLE); |
310 | } | 310 | } |
311 | 311 | ||
312 | int dw_pcie_wait_for_link(struct dw_pcie *pci) | 312 | int dw_pcie_wait_for_link(struct dw_pcie *pci) |
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 9943d8c68335..377f4c0b52da 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #ifndef _PCIE_DESIGNWARE_H | 11 | #ifndef _PCIE_DESIGNWARE_H |
12 | #define _PCIE_DESIGNWARE_H | 12 | #define _PCIE_DESIGNWARE_H |
13 | 13 | ||
14 | #include <linux/bitfield.h> | ||
14 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
15 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
16 | #include <linux/msi.h> | 17 | #include <linux/msi.h> |
@@ -30,23 +31,25 @@ | |||
30 | 31 | ||
31 | /* Synopsys-specific PCIe configuration registers */ | 32 | /* Synopsys-specific PCIe configuration registers */ |
32 | #define PCIE_PORT_LINK_CONTROL 0x710 | 33 | #define PCIE_PORT_LINK_CONTROL 0x710 |
33 | #define PORT_LINK_MODE_MASK (0x3f << 16) | 34 | #define PORT_LINK_MODE_MASK GENMASK(21, 16) |
34 | #define PORT_LINK_MODE_1_LANES (0x1 << 16) | 35 | #define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n) |
35 | #define PORT_LINK_MODE_2_LANES (0x3 << 16) | 36 | #define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1) |
36 | #define PORT_LINK_MODE_4_LANES (0x7 << 16) | 37 | #define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3) |
37 | #define PORT_LINK_MODE_8_LANES (0xf << 16) | 38 | #define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) |
39 | #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) | ||
38 | 40 | ||
39 | #define PCIE_PORT_DEBUG0 0x728 | 41 | #define PCIE_PORT_DEBUG0 0x728 |
40 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f | 42 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f |
41 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 | 43 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 |
42 | 44 | ||
43 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C | 45 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
44 | #define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) | 46 | #define PORT_LOGIC_SPEED_CHANGE BIT(17) |
45 | #define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8) | 47 | #define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8) |
46 | #define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8) | 48 | #define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n) |
47 | #define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8) | 49 | #define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1) |
48 | #define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8) | 50 | #define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2) |
49 | #define PORT_LOGIC_LINK_WIDTH_8_LANES (0x8 << 8) | 51 | #define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4) |
52 | #define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8) | ||
50 | 53 | ||
51 | #define PCIE_MSI_ADDR_LO 0x820 | 54 | #define PCIE_MSI_ADDR_LO 0x820 |
52 | #define PCIE_MSI_ADDR_HI 0x824 | 55 | #define PCIE_MSI_ADDR_HI 0x824 |
@@ -55,30 +58,30 @@ | |||
55 | #define PCIE_MSI_INTR0_STATUS 0x830 | 58 | #define PCIE_MSI_INTR0_STATUS 0x830 |
56 | 59 | ||
57 | #define PCIE_ATU_VIEWPORT 0x900 | 60 | #define PCIE_ATU_VIEWPORT 0x900 |
58 | #define PCIE_ATU_REGION_INBOUND (0x1 << 31) | 61 | #define PCIE_ATU_REGION_INBOUND BIT(31) |
59 | #define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) | 62 | #define PCIE_ATU_REGION_OUTBOUND 0 |
60 | #define PCIE_ATU_REGION_INDEX2 (0x2 << 0) | 63 | #define PCIE_ATU_REGION_INDEX2 0x2 |
61 | #define PCIE_ATU_REGION_INDEX1 (0x1 << 0) | 64 | #define PCIE_ATU_REGION_INDEX1 0x1 |
62 | #define PCIE_ATU_REGION_INDEX0 (0x0 << 0) | 65 | #define PCIE_ATU_REGION_INDEX0 0x0 |
63 | #define PCIE_ATU_CR1 0x904 | 66 | #define PCIE_ATU_CR1 0x904 |
64 | #define PCIE_ATU_TYPE_MEM (0x0 << 0) | 67 | #define PCIE_ATU_TYPE_MEM 0x0 |
65 | #define PCIE_ATU_TYPE_IO (0x2 << 0) | 68 | #define PCIE_ATU_TYPE_IO 0x2 |
66 | #define PCIE_ATU_TYPE_CFG0 (0x4 << 0) | 69 | #define PCIE_ATU_TYPE_CFG0 0x4 |
67 | #define PCIE_ATU_TYPE_CFG1 (0x5 << 0) | 70 | #define PCIE_ATU_TYPE_CFG1 0x5 |
68 | #define PCIE_ATU_CR2 0x908 | 71 | #define PCIE_ATU_CR2 0x908 |
69 | #define PCIE_ATU_ENABLE (0x1 << 31) | 72 | #define PCIE_ATU_ENABLE BIT(31) |
70 | #define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) | 73 | #define PCIE_ATU_BAR_MODE_ENABLE BIT(30) |
71 | #define PCIE_ATU_LOWER_BASE 0x90C | 74 | #define PCIE_ATU_LOWER_BASE 0x90C |
72 | #define PCIE_ATU_UPPER_BASE 0x910 | 75 | #define PCIE_ATU_UPPER_BASE 0x910 |
73 | #define PCIE_ATU_LIMIT 0x914 | 76 | #define PCIE_ATU_LIMIT 0x914 |
74 | #define PCIE_ATU_LOWER_TARGET 0x918 | 77 | #define PCIE_ATU_LOWER_TARGET 0x918 |
75 | #define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) | 78 | #define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x) |
76 | #define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) | 79 | #define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x) |
77 | #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) | 80 | #define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x) |
78 | #define PCIE_ATU_UPPER_TARGET 0x91C | 81 | #define PCIE_ATU_UPPER_TARGET 0x91C |
79 | 82 | ||
80 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC | 83 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC |
81 | #define PCIE_DBI_RO_WR_EN (0x1 << 0) | 84 | #define PCIE_DBI_RO_WR_EN BIT(0) |
82 | 85 | ||
83 | /* | 86 | /* |
84 | * iATU Unroll-specific register definitions | 87 | * iATU Unroll-specific register definitions |
@@ -105,7 +108,7 @@ | |||
105 | ((region) << 9) | 108 | ((region) << 9) |
106 | 109 | ||
107 | #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ | 110 | #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ |
108 | (((region) << 9) | (0x1 << 8)) | 111 | (((region) << 9) | BIT(8)) |
109 | 112 | ||
110 | #define MAX_MSI_IRQS 256 | 113 | #define MAX_MSI_IRQS 256 |
111 | #define MAX_MSI_IRQS_PER_CTRL 32 | 114 | #define MAX_MSI_IRQS_PER_CTRL 32 |
@@ -177,7 +180,7 @@ struct pcie_port { | |||
177 | struct irq_domain *msi_domain; | 180 | struct irq_domain *msi_domain; |
178 | dma_addr_t msi_data; | 181 | dma_addr_t msi_data; |
179 | u32 num_vectors; | 182 | u32 num_vectors; |
180 | u32 irq_status[MAX_MSI_CTRLS]; | 183 | u32 irq_mask[MAX_MSI_CTRLS]; |
181 | raw_spinlock_t lock; | 184 | raw_spinlock_t lock; |
182 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); | 185 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); |
183 | }; | 186 | }; |
@@ -192,6 +195,7 @@ struct dw_pcie_ep_ops { | |||
192 | void (*ep_init)(struct dw_pcie_ep *ep); | 195 | void (*ep_init)(struct dw_pcie_ep *ep); |
193 | int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, | 196 | int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, |
194 | enum pci_epc_irq_type type, u16 interrupt_num); | 197 | enum pci_epc_irq_type type, u16 interrupt_num); |
198 | const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); | ||
195 | }; | 199 | }; |
196 | 200 | ||
197 | struct dw_pcie_ep { | 201 | struct dw_pcie_ep { |
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index d185ea5fe996..a7f703556790 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c | |||
@@ -1228,7 +1228,7 @@ static int qcom_pcie_probe(struct platform_device *pdev) | |||
1228 | 1228 | ||
1229 | pcie->ops = of_device_get_match_data(dev); | 1229 | pcie->ops = of_device_get_match_data(dev); |
1230 | 1230 | ||
1231 | pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW); | 1231 | pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH); |
1232 | if (IS_ERR(pcie->reset)) { | 1232 | if (IS_ERR(pcie->reset)) { |
1233 | ret = PTR_ERR(pcie->reset); | 1233 | ret = PTR_ERR(pcie->reset); |
1234 | goto err_pm_runtime_put; | 1234 | goto err_pm_runtime_put; |