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 | |
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')
20 files changed, 896 insertions, 210 deletions
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 6671946dbf66..6012f3059acd 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig | |||
@@ -175,7 +175,7 @@ config PCIE_IPROC_MSI | |||
175 | 175 | ||
176 | config PCIE_ALTERA | 176 | config PCIE_ALTERA |
177 | bool "Altera PCIe controller" | 177 | bool "Altera PCIe controller" |
178 | depends on ARM || NIOS2 || COMPILE_TEST | 178 | depends on ARM || NIOS2 || ARM64 || COMPILE_TEST |
179 | help | 179 | help |
180 | Say Y here if you want to enable PCIe controller support on Altera | 180 | Say Y here if you want to enable PCIe controller support on Altera |
181 | FPGA. | 181 | FPGA. |
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; |
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 750081c1cb48..eb58dfdaba1b 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c | |||
@@ -466,7 +466,7 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, | |||
466 | } | 466 | } |
467 | } | 467 | } |
468 | 468 | ||
469 | struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { | 469 | static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { |
470 | .read_pcie = advk_pci_bridge_emul_pcie_conf_read, | 470 | .read_pcie = advk_pci_bridge_emul_pcie_conf_read, |
471 | .write_pcie = advk_pci_bridge_emul_pcie_conf_write, | 471 | .write_pcie = advk_pci_bridge_emul_pcie_conf_write, |
472 | }; | 472 | }; |
@@ -499,7 +499,7 @@ static void advk_sw_pci_bridge_init(struct advk_pcie *pcie) | |||
499 | bridge->data = pcie; | 499 | bridge->data = pcie; |
500 | bridge->ops = &advk_pci_bridge_emul_ops; | 500 | bridge->ops = &advk_pci_bridge_emul_ops; |
501 | 501 | ||
502 | pci_bridge_emul_init(bridge); | 502 | pci_bridge_emul_init(bridge, 0); |
503 | 503 | ||
504 | } | 504 | } |
505 | 505 | ||
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 9ba4d12c179c..95441a35eceb 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c | |||
@@ -391,14 +391,6 @@ struct hv_interrupt_entry { | |||
391 | u32 data; | 391 | u32 data; |
392 | }; | 392 | }; |
393 | 393 | ||
394 | #define HV_VP_SET_BANK_COUNT_MAX 5 /* current implementation limit */ | ||
395 | |||
396 | struct hv_vp_set { | ||
397 | u64 format; /* 0 (HvGenericSetSparse4k) */ | ||
398 | u64 valid_banks; | ||
399 | u64 masks[HV_VP_SET_BANK_COUNT_MAX]; | ||
400 | }; | ||
401 | |||
402 | /* | 394 | /* |
403 | * flags for hv_device_interrupt_target.flags | 395 | * flags for hv_device_interrupt_target.flags |
404 | */ | 396 | */ |
@@ -410,7 +402,7 @@ struct hv_device_interrupt_target { | |||
410 | u32 flags; | 402 | u32 flags; |
411 | union { | 403 | union { |
412 | u64 vp_mask; | 404 | u64 vp_mask; |
413 | struct hv_vp_set vp_set; | 405 | struct hv_vpset vp_set; |
414 | }; | 406 | }; |
415 | }; | 407 | }; |
416 | 408 | ||
@@ -420,7 +412,7 @@ struct retarget_msi_interrupt { | |||
420 | struct hv_interrupt_entry int_entry; | 412 | struct hv_interrupt_entry int_entry; |
421 | u64 reserved2; | 413 | u64 reserved2; |
422 | struct hv_device_interrupt_target int_target; | 414 | struct hv_device_interrupt_target int_target; |
423 | } __packed; | 415 | } __packed __aligned(8); |
424 | 416 | ||
425 | /* | 417 | /* |
426 | * Driver specific state. | 418 | * Driver specific state. |
@@ -460,12 +452,16 @@ struct hv_pcibus_device { | |||
460 | struct msi_controller msi_chip; | 452 | struct msi_controller msi_chip; |
461 | struct irq_domain *irq_domain; | 453 | struct irq_domain *irq_domain; |
462 | 454 | ||
463 | /* hypercall arg, must not cross page boundary */ | ||
464 | struct retarget_msi_interrupt retarget_msi_interrupt_params; | ||
465 | |||
466 | spinlock_t retarget_msi_interrupt_lock; | 455 | spinlock_t retarget_msi_interrupt_lock; |
467 | 456 | ||
468 | struct workqueue_struct *wq; | 457 | struct workqueue_struct *wq; |
458 | |||
459 | /* hypercall arg, must not cross page boundary */ | ||
460 | struct retarget_msi_interrupt retarget_msi_interrupt_params; | ||
461 | |||
462 | /* | ||
463 | * Don't put anything here: retarget_msi_interrupt_params must be last | ||
464 | */ | ||
469 | }; | 465 | }; |
470 | 466 | ||
471 | /* | 467 | /* |
@@ -910,12 +906,12 @@ static void hv_irq_unmask(struct irq_data *data) | |||
910 | struct retarget_msi_interrupt *params; | 906 | struct retarget_msi_interrupt *params; |
911 | struct hv_pcibus_device *hbus; | 907 | struct hv_pcibus_device *hbus; |
912 | struct cpumask *dest; | 908 | struct cpumask *dest; |
909 | cpumask_var_t tmp; | ||
913 | struct pci_bus *pbus; | 910 | struct pci_bus *pbus; |
914 | struct pci_dev *pdev; | 911 | struct pci_dev *pdev; |
915 | unsigned long flags; | 912 | unsigned long flags; |
916 | u32 var_size = 0; | 913 | u32 var_size = 0; |
917 | int cpu_vmbus; | 914 | int cpu, nr_bank; |
918 | int cpu; | ||
919 | u64 res; | 915 | u64 res; |
920 | 916 | ||
921 | dest = irq_data_get_effective_affinity_mask(data); | 917 | dest = irq_data_get_effective_affinity_mask(data); |
@@ -955,28 +951,27 @@ static void hv_irq_unmask(struct irq_data *data) | |||
955 | */ | 951 | */ |
956 | params->int_target.flags |= | 952 | params->int_target.flags |= |
957 | HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; | 953 | HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; |
958 | params->int_target.vp_set.valid_banks = | ||
959 | (1ull << HV_VP_SET_BANK_COUNT_MAX) - 1; | ||
960 | 954 | ||
961 | /* | 955 | if (!alloc_cpumask_var(&tmp, GFP_ATOMIC)) { |
962 | * var-sized hypercall, var-size starts after vp_mask (thus | 956 | res = 1; |
963 | * vp_set.format does not count, but vp_set.valid_banks does). | 957 | goto exit_unlock; |
964 | */ | 958 | } |
965 | var_size = 1 + HV_VP_SET_BANK_COUNT_MAX; | ||
966 | 959 | ||
967 | for_each_cpu_and(cpu, dest, cpu_online_mask) { | 960 | cpumask_and(tmp, dest, cpu_online_mask); |
968 | cpu_vmbus = hv_cpu_number_to_vp_number(cpu); | 961 | nr_bank = cpumask_to_vpset(¶ms->int_target.vp_set, tmp); |
962 | free_cpumask_var(tmp); | ||
969 | 963 | ||
970 | if (cpu_vmbus >= HV_VP_SET_BANK_COUNT_MAX * 64) { | 964 | if (nr_bank <= 0) { |
971 | dev_err(&hbus->hdev->device, | 965 | res = 1; |
972 | "too high CPU %d", cpu_vmbus); | 966 | goto exit_unlock; |
973 | res = 1; | ||
974 | goto exit_unlock; | ||
975 | } | ||
976 | |||
977 | params->int_target.vp_set.masks[cpu_vmbus / 64] |= | ||
978 | (1ULL << (cpu_vmbus & 63)); | ||
979 | } | 967 | } |
968 | |||
969 | /* | ||
970 | * var-sized hypercall, var-size starts after vp_mask (thus | ||
971 | * vp_set.format does not count, but vp_set.valid_bank_mask | ||
972 | * does). | ||
973 | */ | ||
974 | var_size = 1 + nr_bank; | ||
980 | } else { | 975 | } else { |
981 | for_each_cpu_and(cpu, dest, cpu_online_mask) { | 976 | for_each_cpu_and(cpu, dest, cpu_online_mask) { |
982 | params->int_target.vp_mask |= | 977 | params->int_target.vp_mask |= |
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index fa0fc46edb0c..d3a0419e42f2 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c | |||
@@ -583,7 +583,7 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) | |||
583 | bridge->data = port; | 583 | bridge->data = port; |
584 | bridge->ops = &mvebu_pci_bridge_emul_ops; | 584 | bridge->ops = &mvebu_pci_bridge_emul_ops; |
585 | 585 | ||
586 | pci_bridge_emul_init(bridge); | 586 | pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR); |
587 | } | 587 | } |
588 | 588 | ||
589 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) | 589 | static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys) |
diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c index 7d05e51205b3..27edcebd1726 100644 --- a/drivers/pci/controller/pcie-altera.c +++ b/drivers/pci/controller/pcie-altera.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/irqchip/chained_irq.h> | 11 | #include <linux/irqchip/chained_irq.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
14 | #include <linux/of_device.h> | ||
14 | #include <linux/of_irq.h> | 15 | #include <linux/of_irq.h> |
15 | #include <linux/of_pci.h> | 16 | #include <linux/of_pci.h> |
16 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
@@ -37,7 +38,12 @@ | |||
37 | #define RP_LTSSM_MASK 0x1f | 38 | #define RP_LTSSM_MASK 0x1f |
38 | #define LTSSM_L0 0xf | 39 | #define LTSSM_L0 0xf |
39 | 40 | ||
40 | #define PCIE_CAP_OFFSET 0x80 | 41 | #define S10_RP_TX_CNTRL 0x2004 |
42 | #define S10_RP_RXCPL_REG 0x2008 | ||
43 | #define S10_RP_RXCPL_STATUS 0x200C | ||
44 | #define S10_RP_CFG_ADDR(pcie, reg) \ | ||
45 | (((pcie)->hip_base) + (reg) + (1 << 20)) | ||
46 | |||
41 | /* TLP configuration type 0 and 1 */ | 47 | /* TLP configuration type 0 and 1 */ |
42 | #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ | 48 | #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ |
43 | #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ | 49 | #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ |
@@ -49,18 +55,19 @@ | |||
49 | #define RP_DEVFN 0 | 55 | #define RP_DEVFN 0 |
50 | #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn)) | 56 | #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn)) |
51 | #define TLP_CFGRD_DW0(pcie, bus) \ | 57 | #define TLP_CFGRD_DW0(pcie, bus) \ |
52 | ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \ | 58 | ((((bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgrd0 \ |
53 | : TLP_FMTTYPE_CFGRD1) << 24) | \ | 59 | : pcie->pcie_data->cfgrd1) << 24) | \ |
54 | TLP_PAYLOAD_SIZE) | 60 | TLP_PAYLOAD_SIZE) |
55 | #define TLP_CFGWR_DW0(pcie, bus) \ | 61 | #define TLP_CFGWR_DW0(pcie, bus) \ |
56 | ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \ | 62 | ((((bus == pcie->root_bus_nr) ? pcie->pcie_data->cfgwr0 \ |
57 | : TLP_FMTTYPE_CFGWR1) << 24) | \ | 63 | : pcie->pcie_data->cfgwr1) << 24) | \ |
58 | TLP_PAYLOAD_SIZE) | 64 | TLP_PAYLOAD_SIZE) |
59 | #define TLP_CFG_DW1(pcie, tag, be) \ | 65 | #define TLP_CFG_DW1(pcie, tag, be) \ |
60 | (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be)) | 66 | (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be)) |
61 | #define TLP_CFG_DW2(bus, devfn, offset) \ | 67 | #define TLP_CFG_DW2(bus, devfn, offset) \ |
62 | (((bus) << 24) | ((devfn) << 16) | (offset)) | 68 | (((bus) << 24) | ((devfn) << 16) | (offset)) |
63 | #define TLP_COMP_STATUS(s) (((s) >> 13) & 7) | 69 | #define TLP_COMP_STATUS(s) (((s) >> 13) & 7) |
70 | #define TLP_BYTE_COUNT(s) (((s) >> 0) & 0xfff) | ||
64 | #define TLP_HDR_SIZE 3 | 71 | #define TLP_HDR_SIZE 3 |
65 | #define TLP_LOOP 500 | 72 | #define TLP_LOOP 500 |
66 | 73 | ||
@@ -69,14 +76,47 @@ | |||
69 | 76 | ||
70 | #define DWORD_MASK 3 | 77 | #define DWORD_MASK 3 |
71 | 78 | ||
79 | #define S10_TLP_FMTTYPE_CFGRD0 0x05 | ||
80 | #define S10_TLP_FMTTYPE_CFGRD1 0x04 | ||
81 | #define S10_TLP_FMTTYPE_CFGWR0 0x45 | ||
82 | #define S10_TLP_FMTTYPE_CFGWR1 0x44 | ||
83 | |||
84 | enum altera_pcie_version { | ||
85 | ALTERA_PCIE_V1 = 0, | ||
86 | ALTERA_PCIE_V2, | ||
87 | }; | ||
88 | |||
72 | struct altera_pcie { | 89 | struct altera_pcie { |
73 | struct platform_device *pdev; | 90 | struct platform_device *pdev; |
74 | void __iomem *cra_base; /* DT Cra */ | 91 | void __iomem *cra_base; |
92 | void __iomem *hip_base; | ||
75 | int irq; | 93 | int irq; |
76 | u8 root_bus_nr; | 94 | u8 root_bus_nr; |
77 | struct irq_domain *irq_domain; | 95 | struct irq_domain *irq_domain; |
78 | struct resource bus_range; | 96 | struct resource bus_range; |
79 | struct list_head resources; | 97 | struct list_head resources; |
98 | const struct altera_pcie_data *pcie_data; | ||
99 | }; | ||
100 | |||
101 | struct altera_pcie_ops { | ||
102 | int (*tlp_read_pkt)(struct altera_pcie *pcie, u32 *value); | ||
103 | void (*tlp_write_pkt)(struct altera_pcie *pcie, u32 *headers, | ||
104 | u32 data, bool align); | ||
105 | bool (*get_link_status)(struct altera_pcie *pcie); | ||
106 | int (*rp_read_cfg)(struct altera_pcie *pcie, int where, | ||
107 | int size, u32 *value); | ||
108 | int (*rp_write_cfg)(struct altera_pcie *pcie, u8 busno, | ||
109 | int where, int size, u32 value); | ||
110 | }; | ||
111 | |||
112 | struct altera_pcie_data { | ||
113 | const struct altera_pcie_ops *ops; | ||
114 | enum altera_pcie_version version; | ||
115 | u32 cap_offset; /* PCIe capability structure register offset */ | ||
116 | u32 cfgrd0; | ||
117 | u32 cfgrd1; | ||
118 | u32 cfgwr0; | ||
119 | u32 cfgwr1; | ||
80 | }; | 120 | }; |
81 | 121 | ||
82 | struct tlp_rp_regpair_t { | 122 | struct tlp_rp_regpair_t { |
@@ -101,6 +141,15 @@ static bool altera_pcie_link_up(struct altera_pcie *pcie) | |||
101 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); | 141 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); |
102 | } | 142 | } |
103 | 143 | ||
144 | static bool s10_altera_pcie_link_up(struct altera_pcie *pcie) | ||
145 | { | ||
146 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, | ||
147 | pcie->pcie_data->cap_offset + | ||
148 | PCI_EXP_LNKSTA); | ||
149 | |||
150 | return !!(readw(addr) & PCI_EXP_LNKSTA_DLLLA); | ||
151 | } | ||
152 | |||
104 | /* | 153 | /* |
105 | * Altera PCIe port uses BAR0 of RC's configuration space as the translation | 154 | * Altera PCIe port uses BAR0 of RC's configuration space as the translation |
106 | * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space | 155 | * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space |
@@ -128,12 +177,18 @@ static void tlp_write_tx(struct altera_pcie *pcie, | |||
128 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); | 177 | cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); |
129 | } | 178 | } |
130 | 179 | ||
180 | static void s10_tlp_write_tx(struct altera_pcie *pcie, u32 reg0, u32 ctrl) | ||
181 | { | ||
182 | cra_writel(pcie, reg0, RP_TX_REG0); | ||
183 | cra_writel(pcie, ctrl, S10_RP_TX_CNTRL); | ||
184 | } | ||
185 | |||
131 | static bool altera_pcie_valid_device(struct altera_pcie *pcie, | 186 | static bool altera_pcie_valid_device(struct altera_pcie *pcie, |
132 | struct pci_bus *bus, int dev) | 187 | struct pci_bus *bus, int dev) |
133 | { | 188 | { |
134 | /* If there is no link, then there is no device */ | 189 | /* If there is no link, then there is no device */ |
135 | if (bus->number != pcie->root_bus_nr) { | 190 | if (bus->number != pcie->root_bus_nr) { |
136 | if (!altera_pcie_link_up(pcie)) | 191 | if (!pcie->pcie_data->ops->get_link_status(pcie)) |
137 | return false; | 192 | return false; |
138 | } | 193 | } |
139 | 194 | ||
@@ -183,6 +238,53 @@ static int tlp_read_packet(struct altera_pcie *pcie, u32 *value) | |||
183 | return PCIBIOS_DEVICE_NOT_FOUND; | 238 | return PCIBIOS_DEVICE_NOT_FOUND; |
184 | } | 239 | } |
185 | 240 | ||
241 | static int s10_tlp_read_packet(struct altera_pcie *pcie, u32 *value) | ||
242 | { | ||
243 | u32 ctrl; | ||
244 | u32 comp_status; | ||
245 | u32 dw[4]; | ||
246 | u32 count; | ||
247 | struct device *dev = &pcie->pdev->dev; | ||
248 | |||
249 | for (count = 0; count < TLP_LOOP; count++) { | ||
250 | ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS); | ||
251 | if (ctrl & RP_RXCPL_SOP) { | ||
252 | /* Read first DW */ | ||
253 | dw[0] = cra_readl(pcie, S10_RP_RXCPL_REG); | ||
254 | break; | ||
255 | } | ||
256 | |||
257 | udelay(5); | ||
258 | } | ||
259 | |||
260 | /* SOP detection failed, return error */ | ||
261 | if (count == TLP_LOOP) | ||
262 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
263 | |||
264 | count = 1; | ||
265 | |||
266 | /* Poll for EOP */ | ||
267 | while (count < ARRAY_SIZE(dw)) { | ||
268 | ctrl = cra_readl(pcie, S10_RP_RXCPL_STATUS); | ||
269 | dw[count++] = cra_readl(pcie, S10_RP_RXCPL_REG); | ||
270 | if (ctrl & RP_RXCPL_EOP) { | ||
271 | comp_status = TLP_COMP_STATUS(dw[1]); | ||
272 | if (comp_status) | ||
273 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
274 | |||
275 | if (value && TLP_BYTE_COUNT(dw[1]) == sizeof(u32) && | ||
276 | count == 4) | ||
277 | *value = dw[3]; | ||
278 | |||
279 | return PCIBIOS_SUCCESSFUL; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | dev_warn(dev, "Malformed TLP packet\n"); | ||
284 | |||
285 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
286 | } | ||
287 | |||
186 | static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | 288 | static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, |
187 | u32 data, bool align) | 289 | u32 data, bool align) |
188 | { | 290 | { |
@@ -210,6 +312,15 @@ static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | |||
210 | tlp_write_tx(pcie, &tlp_rp_regdata); | 312 | tlp_write_tx(pcie, &tlp_rp_regdata); |
211 | } | 313 | } |
212 | 314 | ||
315 | static void s10_tlp_write_packet(struct altera_pcie *pcie, u32 *headers, | ||
316 | u32 data, bool dummy) | ||
317 | { | ||
318 | s10_tlp_write_tx(pcie, headers[0], RP_TX_SOP); | ||
319 | s10_tlp_write_tx(pcie, headers[1], 0); | ||
320 | s10_tlp_write_tx(pcie, headers[2], 0); | ||
321 | s10_tlp_write_tx(pcie, data, RP_TX_EOP); | ||
322 | } | ||
323 | |||
213 | static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, | 324 | static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, |
214 | int where, u8 byte_en, u32 *value) | 325 | int where, u8 byte_en, u32 *value) |
215 | { | 326 | { |
@@ -219,9 +330,9 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
219 | headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en); | 330 | headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en); |
220 | headers[2] = TLP_CFG_DW2(bus, devfn, where); | 331 | headers[2] = TLP_CFG_DW2(bus, devfn, where); |
221 | 332 | ||
222 | tlp_write_packet(pcie, headers, 0, false); | 333 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, 0, false); |
223 | 334 | ||
224 | return tlp_read_packet(pcie, value); | 335 | return pcie->pcie_data->ops->tlp_read_pkt(pcie, value); |
225 | } | 336 | } |
226 | 337 | ||
227 | static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | 338 | static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, |
@@ -236,11 +347,13 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
236 | 347 | ||
237 | /* check alignment to Qword */ | 348 | /* check alignment to Qword */ |
238 | if ((where & 0x7) == 0) | 349 | if ((where & 0x7) == 0) |
239 | tlp_write_packet(pcie, headers, value, true); | 350 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, |
351 | value, true); | ||
240 | else | 352 | else |
241 | tlp_write_packet(pcie, headers, value, false); | 353 | pcie->pcie_data->ops->tlp_write_pkt(pcie, headers, |
354 | value, false); | ||
242 | 355 | ||
243 | ret = tlp_read_packet(pcie, NULL); | 356 | ret = pcie->pcie_data->ops->tlp_read_pkt(pcie, NULL); |
244 | if (ret != PCIBIOS_SUCCESSFUL) | 357 | if (ret != PCIBIOS_SUCCESSFUL) |
245 | return ret; | 358 | return ret; |
246 | 359 | ||
@@ -254,6 +367,53 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, | |||
254 | return PCIBIOS_SUCCESSFUL; | 367 | return PCIBIOS_SUCCESSFUL; |
255 | } | 368 | } |
256 | 369 | ||
370 | static int s10_rp_read_cfg(struct altera_pcie *pcie, int where, | ||
371 | int size, u32 *value) | ||
372 | { | ||
373 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, where); | ||
374 | |||
375 | switch (size) { | ||
376 | case 1: | ||
377 | *value = readb(addr); | ||
378 | break; | ||
379 | case 2: | ||
380 | *value = readw(addr); | ||
381 | break; | ||
382 | default: | ||
383 | *value = readl(addr); | ||
384 | break; | ||
385 | } | ||
386 | |||
387 | return PCIBIOS_SUCCESSFUL; | ||
388 | } | ||
389 | |||
390 | static int s10_rp_write_cfg(struct altera_pcie *pcie, u8 busno, | ||
391 | int where, int size, u32 value) | ||
392 | { | ||
393 | void __iomem *addr = S10_RP_CFG_ADDR(pcie, where); | ||
394 | |||
395 | switch (size) { | ||
396 | case 1: | ||
397 | writeb(value, addr); | ||
398 | break; | ||
399 | case 2: | ||
400 | writew(value, addr); | ||
401 | break; | ||
402 | default: | ||
403 | writel(value, addr); | ||
404 | break; | ||
405 | } | ||
406 | |||
407 | /* | ||
408 | * Monitor changes to PCI_PRIMARY_BUS register on root port | ||
409 | * and update local copy of root bus number accordingly. | ||
410 | */ | ||
411 | if (busno == pcie->root_bus_nr && where == PCI_PRIMARY_BUS) | ||
412 | pcie->root_bus_nr = value & 0xff; | ||
413 | |||
414 | return PCIBIOS_SUCCESSFUL; | ||
415 | } | ||
416 | |||
257 | static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, | 417 | static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, |
258 | unsigned int devfn, int where, int size, | 418 | unsigned int devfn, int where, int size, |
259 | u32 *value) | 419 | u32 *value) |
@@ -262,6 +422,10 @@ static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, | |||
262 | u32 data; | 422 | u32 data; |
263 | u8 byte_en; | 423 | u8 byte_en; |
264 | 424 | ||
425 | if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_read_cfg) | ||
426 | return pcie->pcie_data->ops->rp_read_cfg(pcie, where, | ||
427 | size, value); | ||
428 | |||
265 | switch (size) { | 429 | switch (size) { |
266 | case 1: | 430 | case 1: |
267 | byte_en = 1 << (where & 3); | 431 | byte_en = 1 << (where & 3); |
@@ -302,6 +466,10 @@ static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno, | |||
302 | u32 shift = 8 * (where & 3); | 466 | u32 shift = 8 * (where & 3); |
303 | u8 byte_en; | 467 | u8 byte_en; |
304 | 468 | ||
469 | if (busno == pcie->root_bus_nr && pcie->pcie_data->ops->rp_write_cfg) | ||
470 | return pcie->pcie_data->ops->rp_write_cfg(pcie, busno, | ||
471 | where, size, value); | ||
472 | |||
305 | switch (size) { | 473 | switch (size) { |
306 | case 1: | 474 | case 1: |
307 | data32 = (value & 0xff) << shift; | 475 | data32 = (value & 0xff) << shift; |
@@ -365,7 +533,8 @@ static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno, | |||
365 | int ret; | 533 | int ret; |
366 | 534 | ||
367 | ret = _altera_pcie_cfg_read(pcie, busno, devfn, | 535 | ret = _altera_pcie_cfg_read(pcie, busno, devfn, |
368 | PCIE_CAP_OFFSET + offset, sizeof(*value), | 536 | pcie->pcie_data->cap_offset + offset, |
537 | sizeof(*value), | ||
369 | &data); | 538 | &data); |
370 | *value = data; | 539 | *value = data; |
371 | return ret; | 540 | return ret; |
@@ -375,7 +544,8 @@ static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno, | |||
375 | unsigned int devfn, int offset, u16 value) | 544 | unsigned int devfn, int offset, u16 value) |
376 | { | 545 | { |
377 | return _altera_pcie_cfg_write(pcie, busno, devfn, | 546 | return _altera_pcie_cfg_write(pcie, busno, devfn, |
378 | PCIE_CAP_OFFSET + offset, sizeof(value), | 547 | pcie->pcie_data->cap_offset + offset, |
548 | sizeof(value), | ||
379 | value); | 549 | value); |
380 | } | 550 | } |
381 | 551 | ||
@@ -403,7 +573,7 @@ static void altera_wait_link_retrain(struct altera_pcie *pcie) | |||
403 | /* Wait for link is up */ | 573 | /* Wait for link is up */ |
404 | start_jiffies = jiffies; | 574 | start_jiffies = jiffies; |
405 | for (;;) { | 575 | for (;;) { |
406 | if (altera_pcie_link_up(pcie)) | 576 | if (pcie->pcie_data->ops->get_link_status(pcie)) |
407 | break; | 577 | break; |
408 | 578 | ||
409 | if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { | 579 | if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { |
@@ -418,7 +588,7 @@ static void altera_pcie_retrain(struct altera_pcie *pcie) | |||
418 | { | 588 | { |
419 | u16 linkcap, linkstat, linkctl; | 589 | u16 linkcap, linkstat, linkctl; |
420 | 590 | ||
421 | if (!altera_pcie_link_up(pcie)) | 591 | if (!pcie->pcie_data->ops->get_link_status(pcie)) |
422 | return; | 592 | return; |
423 | 593 | ||
424 | /* | 594 | /* |
@@ -540,12 +710,20 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) | |||
540 | struct device *dev = &pcie->pdev->dev; | 710 | struct device *dev = &pcie->pdev->dev; |
541 | struct platform_device *pdev = pcie->pdev; | 711 | struct platform_device *pdev = pcie->pdev; |
542 | struct resource *cra; | 712 | struct resource *cra; |
713 | struct resource *hip; | ||
543 | 714 | ||
544 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); | 715 | cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra"); |
545 | pcie->cra_base = devm_ioremap_resource(dev, cra); | 716 | pcie->cra_base = devm_ioremap_resource(dev, cra); |
546 | if (IS_ERR(pcie->cra_base)) | 717 | if (IS_ERR(pcie->cra_base)) |
547 | return PTR_ERR(pcie->cra_base); | 718 | return PTR_ERR(pcie->cra_base); |
548 | 719 | ||
720 | if (pcie->pcie_data->version == ALTERA_PCIE_V2) { | ||
721 | hip = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Hip"); | ||
722 | pcie->hip_base = devm_ioremap_resource(&pdev->dev, hip); | ||
723 | if (IS_ERR(pcie->hip_base)) | ||
724 | return PTR_ERR(pcie->hip_base); | ||
725 | } | ||
726 | |||
549 | /* setup IRQ */ | 727 | /* setup IRQ */ |
550 | pcie->irq = platform_get_irq(pdev, 0); | 728 | pcie->irq = platform_get_irq(pdev, 0); |
551 | if (pcie->irq < 0) { | 729 | if (pcie->irq < 0) { |
@@ -562,6 +740,48 @@ static void altera_pcie_host_init(struct altera_pcie *pcie) | |||
562 | altera_pcie_retrain(pcie); | 740 | altera_pcie_retrain(pcie); |
563 | } | 741 | } |
564 | 742 | ||
743 | static const struct altera_pcie_ops altera_pcie_ops_1_0 = { | ||
744 | .tlp_read_pkt = tlp_read_packet, | ||
745 | .tlp_write_pkt = tlp_write_packet, | ||
746 | .get_link_status = altera_pcie_link_up, | ||
747 | }; | ||
748 | |||
749 | static const struct altera_pcie_ops altera_pcie_ops_2_0 = { | ||
750 | .tlp_read_pkt = s10_tlp_read_packet, | ||
751 | .tlp_write_pkt = s10_tlp_write_packet, | ||
752 | .get_link_status = s10_altera_pcie_link_up, | ||
753 | .rp_read_cfg = s10_rp_read_cfg, | ||
754 | .rp_write_cfg = s10_rp_write_cfg, | ||
755 | }; | ||
756 | |||
757 | static const struct altera_pcie_data altera_pcie_1_0_data = { | ||
758 | .ops = &altera_pcie_ops_1_0, | ||
759 | .cap_offset = 0x80, | ||
760 | .version = ALTERA_PCIE_V1, | ||
761 | .cfgrd0 = TLP_FMTTYPE_CFGRD0, | ||
762 | .cfgrd1 = TLP_FMTTYPE_CFGRD1, | ||
763 | .cfgwr0 = TLP_FMTTYPE_CFGWR0, | ||
764 | .cfgwr1 = TLP_FMTTYPE_CFGWR1, | ||
765 | }; | ||
766 | |||
767 | static const struct altera_pcie_data altera_pcie_2_0_data = { | ||
768 | .ops = &altera_pcie_ops_2_0, | ||
769 | .version = ALTERA_PCIE_V2, | ||
770 | .cap_offset = 0x70, | ||
771 | .cfgrd0 = S10_TLP_FMTTYPE_CFGRD0, | ||
772 | .cfgrd1 = S10_TLP_FMTTYPE_CFGRD1, | ||
773 | .cfgwr0 = S10_TLP_FMTTYPE_CFGWR0, | ||
774 | .cfgwr1 = S10_TLP_FMTTYPE_CFGWR1, | ||
775 | }; | ||
776 | |||
777 | static const struct of_device_id altera_pcie_of_match[] = { | ||
778 | {.compatible = "altr,pcie-root-port-1.0", | ||
779 | .data = &altera_pcie_1_0_data }, | ||
780 | {.compatible = "altr,pcie-root-port-2.0", | ||
781 | .data = &altera_pcie_2_0_data }, | ||
782 | {}, | ||
783 | }; | ||
784 | |||
565 | static int altera_pcie_probe(struct platform_device *pdev) | 785 | static int altera_pcie_probe(struct platform_device *pdev) |
566 | { | 786 | { |
567 | struct device *dev = &pdev->dev; | 787 | struct device *dev = &pdev->dev; |
@@ -570,6 +790,7 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
570 | struct pci_bus *child; | 790 | struct pci_bus *child; |
571 | struct pci_host_bridge *bridge; | 791 | struct pci_host_bridge *bridge; |
572 | int ret; | 792 | int ret; |
793 | const struct of_device_id *match; | ||
573 | 794 | ||
574 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); | 795 | bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); |
575 | if (!bridge) | 796 | if (!bridge) |
@@ -578,6 +799,12 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
578 | pcie = pci_host_bridge_priv(bridge); | 799 | pcie = pci_host_bridge_priv(bridge); |
579 | pcie->pdev = pdev; | 800 | pcie->pdev = pdev; |
580 | 801 | ||
802 | match = of_match_device(altera_pcie_of_match, &pdev->dev); | ||
803 | if (!match) | ||
804 | return -ENODEV; | ||
805 | |||
806 | pcie->pcie_data = match->data; | ||
807 | |||
581 | ret = altera_pcie_parse_dt(pcie); | 808 | ret = altera_pcie_parse_dt(pcie); |
582 | if (ret) { | 809 | if (ret) { |
583 | dev_err(dev, "Parsing DT failed\n"); | 810 | dev_err(dev, "Parsing DT failed\n"); |
@@ -628,11 +855,6 @@ static int altera_pcie_probe(struct platform_device *pdev) | |||
628 | return ret; | 855 | return ret; |
629 | } | 856 | } |
630 | 857 | ||
631 | static const struct of_device_id altera_pcie_of_match[] = { | ||
632 | { .compatible = "altr,pcie-root-port-1.0", }, | ||
633 | {}, | ||
634 | }; | ||
635 | |||
636 | static struct platform_driver altera_pcie_driver = { | 858 | static struct platform_driver altera_pcie_driver = { |
637 | .probe = altera_pcie_probe, | 859 | .probe = altera_pcie_probe, |
638 | .driver = { | 860 | .driver = { |
diff --git a/drivers/pci/controller/pcie-cadence-ep.c b/drivers/pci/controller/pcie-cadence-ep.c index c3a088910f48..def7820cb824 100644 --- a/drivers/pci/controller/pcie-cadence-ep.c +++ b/drivers/pci/controller/pcie-cadence-ep.c | |||
@@ -396,21 +396,21 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) | |||
396 | cfg |= BIT(epf->func_no); | 396 | cfg |= BIT(epf->func_no); |
397 | cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg); | 397 | cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg); |
398 | 398 | ||
399 | /* | ||
400 | * The PCIe links are automatically established by the controller | ||
401 | * once for all at powerup: the software can neither start nor stop | ||
402 | * those links later at runtime. | ||
403 | * | ||
404 | * Then we only have to notify the EP core that our links are already | ||
405 | * established. However we don't call directly pci_epc_linkup() because | ||
406 | * we've already locked the epc->lock. | ||
407 | */ | ||
408 | list_for_each_entry(epf, &epc->pci_epf, list) | ||
409 | pci_epf_linkup(epf); | ||
410 | |||
411 | return 0; | 399 | return 0; |
412 | } | 400 | } |
413 | 401 | ||
402 | static const struct pci_epc_features cdns_pcie_epc_features = { | ||
403 | .linkup_notifier = false, | ||
404 | .msi_capable = true, | ||
405 | .msix_capable = false, | ||
406 | }; | ||
407 | |||
408 | static const struct pci_epc_features* | ||
409 | cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
410 | { | ||
411 | return &cdns_pcie_epc_features; | ||
412 | } | ||
413 | |||
414 | static const struct pci_epc_ops cdns_pcie_epc_ops = { | 414 | static const struct pci_epc_ops cdns_pcie_epc_ops = { |
415 | .write_header = cdns_pcie_ep_write_header, | 415 | .write_header = cdns_pcie_ep_write_header, |
416 | .set_bar = cdns_pcie_ep_set_bar, | 416 | .set_bar = cdns_pcie_ep_set_bar, |
@@ -421,6 +421,7 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = { | |||
421 | .get_msi = cdns_pcie_ep_get_msi, | 421 | .get_msi = cdns_pcie_ep_get_msi, |
422 | .raise_irq = cdns_pcie_ep_raise_irq, | 422 | .raise_irq = cdns_pcie_ep_raise_irq, |
423 | .start = cdns_pcie_ep_start, | 423 | .start = cdns_pcie_ep_start, |
424 | .get_features = cdns_pcie_ep_get_features, | ||
424 | }; | 425 | }; |
425 | 426 | ||
426 | static const struct of_device_id cdns_pcie_ep_of_match[] = { | 427 | static const struct of_device_id cdns_pcie_ep_of_match[] = { |
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index 55e471c18e8d..0b6c72804e03 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c | |||
@@ -90,6 +90,12 @@ | |||
90 | #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) | 90 | #define AHB2PCIE_SIZE(x) ((x) & GENMASK(4, 0)) |
91 | #define PCIE_AXI_WINDOW0 0x448 | 91 | #define PCIE_AXI_WINDOW0 0x448 |
92 | #define WIN_ENABLE BIT(7) | 92 | #define WIN_ENABLE BIT(7) |
93 | /* | ||
94 | * Define PCIe to AHB window size as 2^33 to support max 8GB address space | ||
95 | * translate, support least 4GB DRAM size access from EP DMA(physical DRAM | ||
96 | * start from 0x40000000). | ||
97 | */ | ||
98 | #define PCIE2AHB_SIZE 0x21 | ||
93 | 99 | ||
94 | /* PCIe V2 configuration transaction header */ | 100 | /* PCIe V2 configuration transaction header */ |
95 | #define PCIE_CFG_HEADER0 0x460 | 101 | #define PCIE_CFG_HEADER0 0x460 |
@@ -654,7 +660,6 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | |||
654 | struct resource *mem = &pcie->mem; | 660 | struct resource *mem = &pcie->mem; |
655 | const struct mtk_pcie_soc *soc = port->pcie->soc; | 661 | const struct mtk_pcie_soc *soc = port->pcie->soc; |
656 | u32 val; | 662 | u32 val; |
657 | size_t size; | ||
658 | int err; | 663 | int err; |
659 | 664 | ||
660 | /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ | 665 | /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ |
@@ -706,15 +711,15 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port) | |||
706 | mtk_pcie_enable_msi(port); | 711 | mtk_pcie_enable_msi(port); |
707 | 712 | ||
708 | /* Set AHB to PCIe translation windows */ | 713 | /* Set AHB to PCIe translation windows */ |
709 | size = mem->end - mem->start; | 714 | val = lower_32_bits(mem->start) | |
710 | val = lower_32_bits(mem->start) | AHB2PCIE_SIZE(fls(size)); | 715 | AHB2PCIE_SIZE(fls(resource_size(mem))); |
711 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); | 716 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_L); |
712 | 717 | ||
713 | val = upper_32_bits(mem->start); | 718 | val = upper_32_bits(mem->start); |
714 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); | 719 | writel(val, port->base + PCIE_AHB_TRANS_BASE0_H); |
715 | 720 | ||
716 | /* Set PCIe to AXI translation memory space.*/ | 721 | /* Set PCIe to AXI translation memory space.*/ |
717 | val = fls(0xffffffff) | WIN_ENABLE; | 722 | val = PCIE2AHB_SIZE | WIN_ENABLE; |
718 | writel(val, port->base + PCIE_AXI_WINDOW0); | 723 | writel(val, port->base + PCIE_AXI_WINDOW0); |
719 | 724 | ||
720 | return 0; | 725 | return 0; |
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index b8163c56a142..a5d799e2dff2 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c | |||
@@ -499,12 +499,21 @@ static int rockchip_pcie_ep_start(struct pci_epc *epc) | |||
499 | 499 | ||
500 | rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); | 500 | rockchip_pcie_write(rockchip, cfg, PCIE_CORE_PHY_FUNC_CFG); |
501 | 501 | ||
502 | list_for_each_entry(epf, &epc->pci_epf, list) | ||
503 | pci_epf_linkup(epf); | ||
504 | |||
505 | return 0; | 502 | return 0; |
506 | } | 503 | } |
507 | 504 | ||
505 | static const struct pci_epc_features rockchip_pcie_epc_features = { | ||
506 | .linkup_notifier = false, | ||
507 | .msi_capable = true, | ||
508 | .msix_capable = false, | ||
509 | }; | ||
510 | |||
511 | static const struct pci_epc_features* | ||
512 | rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no) | ||
513 | { | ||
514 | return &rockchip_pcie_epc_features; | ||
515 | } | ||
516 | |||
508 | static const struct pci_epc_ops rockchip_pcie_epc_ops = { | 517 | static const struct pci_epc_ops rockchip_pcie_epc_ops = { |
509 | .write_header = rockchip_pcie_ep_write_header, | 518 | .write_header = rockchip_pcie_ep_write_header, |
510 | .set_bar = rockchip_pcie_ep_set_bar, | 519 | .set_bar = rockchip_pcie_ep_set_bar, |
@@ -515,6 +524,7 @@ static const struct pci_epc_ops rockchip_pcie_epc_ops = { | |||
515 | .get_msi = rockchip_pcie_ep_get_msi, | 524 | .get_msi = rockchip_pcie_ep_get_msi, |
516 | .raise_irq = rockchip_pcie_ep_raise_irq, | 525 | .raise_irq = rockchip_pcie_ep_raise_irq, |
517 | .start = rockchip_pcie_ep_start, | 526 | .start = rockchip_pcie_ep_start, |
527 | .get_features = rockchip_pcie_ep_get_features, | ||
518 | }; | 528 | }; |
519 | 529 | ||
520 | static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip, | 530 | static int rockchip_pcie_parse_ep_dt(struct rockchip_pcie *rockchip, |
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 3890812cdf87..cf6816b55b5e 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c | |||
@@ -571,6 +571,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) | |||
571 | LIST_HEAD(resources); | 571 | LIST_HEAD(resources); |
572 | resource_size_t offset[2] = {0}; | 572 | resource_size_t offset[2] = {0}; |
573 | resource_size_t membar2_offset = 0x2000, busn_start = 0; | 573 | resource_size_t membar2_offset = 0x2000, busn_start = 0; |
574 | struct pci_bus *child; | ||
574 | 575 | ||
575 | /* | 576 | /* |
576 | * Shadow registers may exist in certain VMD device ids which allow | 577 | * Shadow registers may exist in certain VMD device ids which allow |
@@ -698,7 +699,19 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) | |||
698 | vmd_attach_resources(vmd); | 699 | vmd_attach_resources(vmd); |
699 | vmd_setup_dma_ops(vmd); | 700 | vmd_setup_dma_ops(vmd); |
700 | dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); | 701 | dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); |
701 | pci_rescan_bus(vmd->bus); | 702 | |
703 | pci_scan_child_bus(vmd->bus); | ||
704 | pci_assign_unassigned_bus_resources(vmd->bus); | ||
705 | |||
706 | /* | ||
707 | * VMD root buses are virtual and don't return true on pci_is_pcie() | ||
708 | * and will fail pcie_bus_configure_settings() early. It can instead be | ||
709 | * run on each of the real root ports. | ||
710 | */ | ||
711 | list_for_each_entry(child, &vmd->bus->children, node) | ||
712 | pcie_bus_configure_settings(child); | ||
713 | |||
714 | pci_bus_add_devices(vmd->bus); | ||
702 | 715 | ||
703 | WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, | 716 | WARN(sysfs_create_link(&vmd->dev->dev.kobj, &vmd->bus->dev.kobj, |
704 | "domain"), "Can't create symlink to domain\n"); | 717 | "domain"), "Can't create symlink to domain\n"); |