Skip to content

Commit 93c398b

Browse files
committed
Merge branch 'pci/controller/dwc'
- Extend PCI_FIND_NEXT_CAP() and PCI_FIND_NEXT_EXT_CAP() to return a pointer to the preceding Capability (Qiang Yu) - Add dw_pcie_remove_capability() and dw_pcie_remove_ext_capability() to remove Capabilities that are advertised but not fully implemented (Qiang Yu) - Remove MSI and MSI-X Capabilities for DWC controllers in platforms that can't support them, so we automatically fall back to INTx (Qiang Yu) - Remove MSI-X and DPC Capabilities for Qualcomm platforms that advertise but don't support them (Qiang Yu) - Remove duplicate dw_pcie_ep_hide_ext_capability() function and replace with dw_pcie_remove_ext_capability() (Qiang Yu) - Add ASPM L1.1 and L1.2 Substates context to debugfs ltssm_status for drivers that support this (Shawn Lin) - Skip PME_Turn_Off broadcast and L2/L3 transition during suspend if link is not up to avoid an unnecessary timeout (Manivannan Sadhasivam) - Revert dw-rockchip, qcom, and DWC core changes that used link-up IRQs to trigger enumeration instead of waiting for link to be up because the PCI core doesn't allocate bus number space for hierarchies that might be attached (Niklas Cassel) - Make endpoint iATU entry for MSI permanent instead of programming it dynamically, which is slow and racy with respect to other concurrent traffic, e.g., eDMA (Koichiro Den) - Use iMSI-RX MSI target address when possible to fix endpoints using 32-bit MSI (Shawn Lin) - Make dw_pcie_ltssm_status_string() available and use it for logging errors in dw_pcie_wait_for_link() (Manivannan Sadhasivam) - Return -ENODEV when dw_pcie_wait_for_link() finds no devices, -EIO for device present but inactive, -ETIMEDOUT for other failures, so callers can handle these cases differently (Manivannan Sadhasivam) - Allow DWC host controller driver probe to continue if device is not found or found but inactive; only fail when there's an error with the link (Manivannan Sadhasivam) - For controllers like NXP i.MX6QP and i.MX7D, where LTSSM registers are not accessible after PME_Turn_Off, simply wait 10ms instead of polling for L2/L3 Ready (Richard Zhu) - Use multiple iATU entries to map large bridge windows and DMA ranges when necessary instead of failing (Samuel Holland) - Rename struct dw_pcie_rp.has_msi_ctrl to .use_imsi_rx for clarity (Qiang Yu) - Add EPC dynamic_inbound_mapping feature bit for Endpoint Controllers that can update BAR inbound address translation without requiring EPF driver to clear/reset the BAR first, and advertise it for DWC-based Endpoints (Koichiro Den) - Add EPC subrange_mapping feature bit for Endpoint Controllers that can map multiple independent inbound regions in a single BAR, implement subrange mapping, advertise it for DWC-based Endpoints, and add Endpoint selftests for it (Koichiro Den) - Allow overriding default BAR sizes for pci-epf-test (Niklas Cassel) - Make resizable BARs work for Endpoint multi-PF configurations; previously it only worked for PF 0 (Aksh Garg) - Fix Endpoint non-PF 0 support for BAR configuration, ATU mappings, and Address Match Mode (Aksh Garg) - Fix issues with outbound iATU index assignment that caused iATU index to be out of bounds (Niklas Cassel) - Clean up iATU index tracking to be consistent (Niklas Cassel) - Set up iATU when ECAM is enabled; previously IO and MEM outbound windows weren't programmed, and ECAM-related iATU entries weren't restored after suspend/resume, so config accesses failed (Krishna Chaitanya Chundru) * pci/controller/dwc: PCI: dwc: Fix missing iATU setup when ECAM is enabled PCI: dwc: Clean up iATU index usage in dw_pcie_iatu_setup() PCI: dwc: Fix msg_atu_index assignment PCI: dwc: ep: Add comment explaining controller level PTM access in multi PF setup PCI: dwc: ep: Add per-PF BAR and inbound ATU mapping support PCI: dwc: ep: Fix resizable BAR support for multi-PF configurations PCI: endpoint: pci-epf-test: Allow overriding default BAR sizes selftests: pci_endpoint: Add BAR subrange mapping test case misc: pci_endpoint_test: Add BAR subrange mapping test case PCI: endpoint: pci-epf-test: Add BAR subrange mapping test support Documentation: PCI: endpoint: Clarify pci_epc_set_bar() usage PCI: dwc: ep: Support BAR subrange inbound mapping via Address Match Mode iATU PCI: dwc: Advertise dynamic inbound mapping support PCI: endpoint: Add BAR subrange mapping support PCI: endpoint: Add dynamic_inbound_mapping EPC feature PCI: dwc: Rename dw_pcie_rp::has_msi_ctrl to dw_pcie_rp::use_imsi_rx for clarity PCI: dwc: Fix grammar and formatting for comment in dw_pcie_remove_ext_capability() PCI: dwc: Use multiple iATU windows for mapping large bridge windows and DMA ranges PCI: dwc: Remove duplicate dw_pcie_ep_hide_ext_capability() function PCI: dwc: Skip waiting for L2/L3 Ready if dw_pcie_rp::skip_l23_wait is true PCI: dwc: Fail dw_pcie_host_init() if dw_pcie_wait_for_link() returns -ETIMEDOUT PCI: dwc: Rework the error print of dw_pcie_wait_for_link() PCI: dwc: Rename and move ltssm_status_string() to pcie-designware.c PCI: dwc: Return -EIO from dw_pcie_wait_for_link() if device is not active PCI: dwc: Return -ENODEV from dw_pcie_wait_for_link() if device is not found PCI: dwc: Use cfg0_base as iMSI-RX target address to support 32-bit MSI devices PCI: dwc: ep: Cache MSI outbound iATU mapping Revert "PCI: dwc: Don't wait for link up if driver can detect Link Up event" Revert "PCI: qcom: Enumerate endpoints based on Link up event in 'global_irq' interrupt" Revert "PCI: qcom: Enable MSI interrupts together with Link up if 'Global IRQ' is supported" Revert "PCI: qcom: Don't wait for link if we can detect Link Up" Revert "PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ" Revert "PCI: dw-rockchip: Don't wait for link since we can detect Link Up" PCI: dwc: Skip PME_Turn_Off broadcast and L2/L3 transition during suspend if link is not up PCI: dw-rockchip: Change get_ltssm() to provide L1 Substates info PCI: dwc: Add L1 Substates context to ltssm_status of debugfs PCI: qcom: Remove DPC Extended Capability PCI: qcom: Remove MSI-X Capability for Root Ports PCI: dwc: Remove MSI/MSIX capability for Root Port if iMSI-RX is used as MSI controller PCI: dwc: Add new APIs to remove standard and extended Capability PCI: Add preceding capability position support in PCI_FIND_NEXT_*_CAP macros
2 parents cb3ca56 + 43d324e commit 93c398b

30 files changed

Lines changed: 1296 additions & 350 deletions

Documentation/PCI/endpoint/pci-endpoint.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,30 @@ by the PCI endpoint function driver.
9595
Register space of the function driver is usually configured
9696
using this API.
9797

98+
Some endpoint controllers also support calling pci_epc_set_bar() again
99+
for the same BAR (without calling pci_epc_clear_bar()) to update inbound
100+
address translations after the host has programmed the BAR base address.
101+
Endpoint function drivers can check this capability via the
102+
dynamic_inbound_mapping EPC feature bit.
103+
104+
When pci_epf_bar.num_submap is non-zero, the endpoint function driver is
105+
requesting BAR subrange mapping using pci_epf_bar.submap. This requires
106+
the EPC to advertise support via the subrange_mapping EPC feature bit.
107+
108+
When an EPF driver wants to make use of the inbound subrange mapping
109+
feature, it requires that the BAR base address has been programmed by
110+
the host during enumeration. Thus, it needs to call pci_epc_set_bar()
111+
twice for the same BAR (requires dynamic_inbound_mapping): first with
112+
num_submap set to zero and configuring the BAR size, then after the PCIe
113+
link is up and the host enumerates the endpoint and programs the BAR
114+
base address, again with num_submap set to non-zero value.
115+
116+
Note that when making use of the inbound subrange mapping feature, the
117+
EPF driver must not call pci_epc_clear_bar() between the two
118+
pci_epc_set_bar() calls, because clearing the BAR can clear/disable the
119+
BAR register or BAR decode on the endpoint while the host still expects
120+
the assigned BAR address to remain valid.
121+
98122
* pci_epc_clear_bar()
99123

100124
The PCI endpoint function driver should use pci_epc_clear_bar() to reset

Documentation/PCI/endpoint/pci-test-howto.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,25 @@ device, the following commands can be used::
8484
# echo 32 > functions/pci_epf_test/func1/msi_interrupts
8585
# echo 2048 > functions/pci_epf_test/func1/msix_interrupts
8686

87+
By default, pci-epf-test uses the following BAR sizes::
88+
89+
# grep . functions/pci_epf_test/func1/pci_epf_test.0/bar?_size
90+
functions/pci_epf_test/func1/pci_epf_test.0/bar0_size:131072
91+
functions/pci_epf_test/func1/pci_epf_test.0/bar1_size:131072
92+
functions/pci_epf_test/func1/pci_epf_test.0/bar2_size:131072
93+
functions/pci_epf_test/func1/pci_epf_test.0/bar3_size:131072
94+
functions/pci_epf_test/func1/pci_epf_test.0/bar4_size:131072
95+
functions/pci_epf_test/func1/pci_epf_test.0/bar5_size:1048576
96+
97+
The user can override a default value using e.g.::
98+
# echo 1048576 > functions/pci_epf_test/func1/pci_epf_test.0/bar1_size
99+
100+
Overriding the default BAR sizes can only be done before binding the
101+
pci-epf-test device to a PCI endpoint controller driver.
102+
103+
Note: Some endpoint controllers might have fixed-size BARs or reserved BARs;
104+
for such controllers, the corresponding BAR size in configfs will be ignored.
105+
87106

88107
Binding pci-epf-test Device to EP Controller
89108
--------------------------------------------

drivers/misc/pci_endpoint_test.c

Lines changed: 202 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#define COMMAND_COPY BIT(5)
4040
#define COMMAND_ENABLE_DOORBELL BIT(6)
4141
#define COMMAND_DISABLE_DOORBELL BIT(7)
42+
#define COMMAND_BAR_SUBRANGE_SETUP BIT(8)
43+
#define COMMAND_BAR_SUBRANGE_CLEAR BIT(9)
4244

4345
#define PCI_ENDPOINT_TEST_STATUS 0x8
4446
#define STATUS_READ_SUCCESS BIT(0)
@@ -55,6 +57,10 @@
5557
#define STATUS_DOORBELL_ENABLE_FAIL BIT(11)
5658
#define STATUS_DOORBELL_DISABLE_SUCCESS BIT(12)
5759
#define STATUS_DOORBELL_DISABLE_FAIL BIT(13)
60+
#define STATUS_BAR_SUBRANGE_SETUP_SUCCESS BIT(14)
61+
#define STATUS_BAR_SUBRANGE_SETUP_FAIL BIT(15)
62+
#define STATUS_BAR_SUBRANGE_CLEAR_SUCCESS BIT(16)
63+
#define STATUS_BAR_SUBRANGE_CLEAR_FAIL BIT(17)
5864

5965
#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c
6066
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
@@ -77,6 +83,7 @@
7783
#define CAP_MSI BIT(1)
7884
#define CAP_MSIX BIT(2)
7985
#define CAP_INTX BIT(3)
86+
#define CAP_SUBRANGE_MAPPING BIT(4)
8087

8188
#define PCI_ENDPOINT_TEST_DB_BAR 0x34
8289
#define PCI_ENDPOINT_TEST_DB_OFFSET 0x38
@@ -100,6 +107,8 @@
100107

101108
#define PCI_DEVICE_ID_ROCKCHIP_RK3588 0x3588
102109

110+
#define PCI_ENDPOINT_TEST_BAR_SUBRANGE_NSUB 2
111+
103112
static DEFINE_IDA(pci_endpoint_test_ida);
104113

105114
#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
@@ -414,6 +423,193 @@ static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
414423
return 0;
415424
}
416425

426+
static u8 pci_endpoint_test_subrange_sig_byte(enum pci_barno barno,
427+
unsigned int subno)
428+
{
429+
return 0x50 + (barno * 8) + subno;
430+
}
431+
432+
static u8 pci_endpoint_test_subrange_test_byte(enum pci_barno barno,
433+
unsigned int subno)
434+
{
435+
return 0xa0 + (barno * 8) + subno;
436+
}
437+
438+
static int pci_endpoint_test_bar_subrange_cmd(struct pci_endpoint_test *test,
439+
enum pci_barno barno, u32 command,
440+
u32 ok_bit, u32 fail_bit)
441+
{
442+
struct pci_dev *pdev = test->pdev;
443+
struct device *dev = &pdev->dev;
444+
int irq_type = test->irq_type;
445+
u32 status;
446+
447+
if (irq_type < PCITEST_IRQ_TYPE_INTX ||
448+
irq_type > PCITEST_IRQ_TYPE_MSIX) {
449+
dev_err(dev, "Invalid IRQ type\n");
450+
return -EINVAL;
451+
}
452+
453+
reinit_completion(&test->irq_raised);
454+
455+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
456+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
457+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
458+
/* Reuse SIZE as a command parameter: bar number. */
459+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, barno);
460+
pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, command);
461+
462+
if (!wait_for_completion_timeout(&test->irq_raised,
463+
msecs_to_jiffies(1000)))
464+
return -ETIMEDOUT;
465+
466+
status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
467+
if (status & fail_bit)
468+
return -EIO;
469+
470+
if (!(status & ok_bit))
471+
return -EIO;
472+
473+
return 0;
474+
}
475+
476+
static int pci_endpoint_test_bar_subrange_setup(struct pci_endpoint_test *test,
477+
enum pci_barno barno)
478+
{
479+
return pci_endpoint_test_bar_subrange_cmd(test, barno,
480+
COMMAND_BAR_SUBRANGE_SETUP,
481+
STATUS_BAR_SUBRANGE_SETUP_SUCCESS,
482+
STATUS_BAR_SUBRANGE_SETUP_FAIL);
483+
}
484+
485+
static int pci_endpoint_test_bar_subrange_clear(struct pci_endpoint_test *test,
486+
enum pci_barno barno)
487+
{
488+
return pci_endpoint_test_bar_subrange_cmd(test, barno,
489+
COMMAND_BAR_SUBRANGE_CLEAR,
490+
STATUS_BAR_SUBRANGE_CLEAR_SUCCESS,
491+
STATUS_BAR_SUBRANGE_CLEAR_FAIL);
492+
}
493+
494+
static int pci_endpoint_test_bar_subrange(struct pci_endpoint_test *test,
495+
enum pci_barno barno)
496+
{
497+
u32 nsub = PCI_ENDPOINT_TEST_BAR_SUBRANGE_NSUB;
498+
struct device *dev = &test->pdev->dev;
499+
size_t sub_size, buf_size;
500+
resource_size_t bar_size;
501+
void __iomem *bar_addr;
502+
void *read_buf = NULL;
503+
int ret, clear_ret;
504+
size_t off, chunk;
505+
u32 i, exp, val;
506+
u8 pattern;
507+
508+
if (!(test->ep_caps & CAP_SUBRANGE_MAPPING))
509+
return -EOPNOTSUPP;
510+
511+
/*
512+
* The test register BAR is not safe to reprogram and write/read
513+
* over its full size. BAR_TEST already special-cases it to a tiny
514+
* range. For subrange mapping tests, let's simply skip it.
515+
*/
516+
if (barno == test->test_reg_bar)
517+
return -EBUSY;
518+
519+
bar_size = pci_resource_len(test->pdev, barno);
520+
if (!bar_size)
521+
return -ENODATA;
522+
523+
bar_addr = test->bar[barno];
524+
if (!bar_addr)
525+
return -ENOMEM;
526+
527+
ret = pci_endpoint_test_bar_subrange_setup(test, barno);
528+
if (ret)
529+
return ret;
530+
531+
if (bar_size % nsub || bar_size / nsub > SIZE_MAX) {
532+
ret = -EINVAL;
533+
goto out_clear;
534+
}
535+
536+
sub_size = bar_size / nsub;
537+
if (sub_size < sizeof(u32)) {
538+
ret = -ENOSPC;
539+
goto out_clear;
540+
}
541+
542+
/* Limit the temporary buffer size */
543+
buf_size = min_t(size_t, sub_size, SZ_1M);
544+
545+
read_buf = kmalloc(buf_size, GFP_KERNEL);
546+
if (!read_buf) {
547+
ret = -ENOMEM;
548+
goto out_clear;
549+
}
550+
551+
/*
552+
* Step 1: verify EP-provided signature per subrange. This detects
553+
* whether the EP actually applied the submap order.
554+
*/
555+
for (i = 0; i < nsub; i++) {
556+
exp = (u32)pci_endpoint_test_subrange_sig_byte(barno, i) *
557+
0x01010101U;
558+
val = ioread32(bar_addr + (i * sub_size));
559+
if (val != exp) {
560+
dev_err(dev,
561+
"BAR%d subrange%u signature mismatch @%#zx: exp %#08x got %#08x\n",
562+
barno, i, (size_t)i * sub_size, exp, val);
563+
ret = -EIO;
564+
goto out_clear;
565+
}
566+
val = ioread32(bar_addr + (i * sub_size) + sub_size - sizeof(u32));
567+
if (val != exp) {
568+
dev_err(dev,
569+
"BAR%d subrange%u signature mismatch @%#zx: exp %#08x got %#08x\n",
570+
barno, i,
571+
((size_t)i * sub_size) + sub_size - sizeof(u32),
572+
exp, val);
573+
ret = -EIO;
574+
goto out_clear;
575+
}
576+
}
577+
578+
/* Step 2: write unique pattern per subrange (write all first). */
579+
for (i = 0; i < nsub; i++) {
580+
pattern = pci_endpoint_test_subrange_test_byte(barno, i);
581+
memset_io(bar_addr + (i * sub_size), pattern, sub_size);
582+
}
583+
584+
/* Step 3: read back and verify (read all after all writes). */
585+
for (i = 0; i < nsub; i++) {
586+
pattern = pci_endpoint_test_subrange_test_byte(barno, i);
587+
for (off = 0; off < sub_size; off += chunk) {
588+
void *bad;
589+
590+
chunk = min_t(size_t, buf_size, sub_size - off);
591+
memcpy_fromio(read_buf, bar_addr + (i * sub_size) + off,
592+
chunk);
593+
bad = memchr_inv(read_buf, pattern, chunk);
594+
if (bad) {
595+
size_t bad_off = (u8 *)bad - (u8 *)read_buf;
596+
597+
dev_err(dev,
598+
"BAR%d subrange%u data mismatch @%#zx (pattern %#02x)\n",
599+
barno, i, (size_t)i * sub_size + off + bad_off,
600+
pattern);
601+
ret = -EIO;
602+
goto out_clear;
603+
}
604+
}
605+
}
606+
607+
out_clear:
608+
kfree(read_buf);
609+
clear_ret = pci_endpoint_test_bar_subrange_clear(test, barno);
610+
return ret ?: clear_ret;
611+
}
612+
417613
static int pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
418614
{
419615
u32 val;
@@ -936,12 +1132,17 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
9361132

9371133
switch (cmd) {
9381134
case PCITEST_BAR:
1135+
case PCITEST_BAR_SUBRANGE:
9391136
bar = arg;
9401137
if (bar <= NO_BAR || bar > BAR_5)
9411138
goto ret;
9421139
if (is_am654_pci_dev(pdev) && bar == BAR_0)
9431140
goto ret;
944-
ret = pci_endpoint_test_bar(test, bar);
1141+
1142+
if (cmd == PCITEST_BAR)
1143+
ret = pci_endpoint_test_bar(test, bar);
1144+
else
1145+
ret = pci_endpoint_test_bar_subrange(test, bar);
9451146
break;
9461147
case PCITEST_BARS:
9471148
ret = pci_endpoint_test_bars(test);

drivers/pci/controller/cadence/pcie-cadence.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap)
1414
{
1515
return PCI_FIND_NEXT_CAP(cdns_pcie_read_cfg, PCI_CAPABILITY_LIST,
16-
cap, pcie);
16+
cap, NULL, pcie);
1717
}
1818
EXPORT_SYMBOL_GPL(cdns_pcie_find_capability);
1919

2020
u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap)
2121
{
22-
return PCI_FIND_NEXT_EXT_CAP(cdns_pcie_read_cfg, 0, cap, pcie);
22+
return PCI_FIND_NEXT_EXT_CAP(cdns_pcie_read_cfg, 0, cap, NULL, pcie);
2323
}
2424
EXPORT_SYMBOL_GPL(cdns_pcie_find_ext_capability);
2525

drivers/pci/controller/dwc/pci-dra7xx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
424424
}
425425

426426
static const struct pci_epc_features dra7xx_pcie_epc_features = {
427+
DWC_EPC_COMMON_FEATURES,
427428
.linkup_notifier = true,
428429
.msi_capable = true,
429430
};

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ enum imx_pcie_variants {
114114
#define IMX_PCIE_FLAG_BROKEN_SUSPEND BIT(9)
115115
#define IMX_PCIE_FLAG_HAS_LUT BIT(10)
116116
#define IMX_PCIE_FLAG_8GT_ECN_ERR051586 BIT(11)
117+
#define IMX_PCIE_FLAG_SKIP_L23_READY BIT(12)
117118

118119
#define imx_check_flag(pci, val) (pci->drvdata->flags & val)
119120

@@ -1387,6 +1388,7 @@ static int imx_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
13871388
}
13881389

13891390
static const struct pci_epc_features imx8m_pcie_epc_features = {
1391+
DWC_EPC_COMMON_FEATURES,
13901392
.msi_capable = true,
13911393
.bar[BAR_1] = { .type = BAR_RESERVED, },
13921394
.bar[BAR_3] = { .type = BAR_RESERVED, },
@@ -1396,6 +1398,7 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
13961398
};
13971399

13981400
static const struct pci_epc_features imx8q_pcie_epc_features = {
1401+
DWC_EPC_COMMON_FEATURES,
13991402
.msi_capable = true,
14001403
.bar[BAR_1] = { .type = BAR_RESERVED, },
14011404
.bar[BAR_3] = { .type = BAR_RESERVED, },
@@ -1416,6 +1419,7 @@ static const struct pci_epc_features imx8q_pcie_epc_features = {
14161419
* BAR5 | Enable | 32-bit | 64 KB | Programmable Size
14171420
*/
14181421
static const struct pci_epc_features imx95_pcie_epc_features = {
1422+
DWC_EPC_COMMON_FEATURES,
14191423
.msi_capable = true,
14201424
.bar[BAR_1] = { .type = BAR_FIXED, .fixed_size = SZ_64K, },
14211425
.align = SZ_4K,
@@ -1777,6 +1781,8 @@ static int imx_pcie_probe(struct platform_device *pdev)
17771781
*/
17781782
imx_pcie_add_lut_by_rid(imx_pcie, 0);
17791783
} else {
1784+
if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_SKIP_L23_READY))
1785+
pci->pp.skip_l23_ready = true;
17801786
pci->pp.use_atu_msg = true;
17811787
ret = dw_pcie_host_init(&pci->pp);
17821788
if (ret < 0)
@@ -1838,6 +1844,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
18381844
.variant = IMX6QP,
18391845
.flags = IMX_PCIE_FLAG_IMX_PHY |
18401846
IMX_PCIE_FLAG_SPEED_CHANGE_WORKAROUND |
1847+
IMX_PCIE_FLAG_SKIP_L23_READY |
18411848
IMX_PCIE_FLAG_SUPPORTS_SUSPEND,
18421849
.dbi_length = 0x200,
18431850
.gpr = "fsl,imx6q-iomuxc-gpr",
@@ -1854,6 +1861,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
18541861
.variant = IMX7D,
18551862
.flags = IMX_PCIE_FLAG_SUPPORTS_SUSPEND |
18561863
IMX_PCIE_FLAG_HAS_APP_RESET |
1864+
IMX_PCIE_FLAG_SKIP_L23_READY |
18571865
IMX_PCIE_FLAG_HAS_PHY_RESET,
18581866
.gpr = "fsl,imx7d-iomuxc-gpr",
18591867
.mode_off[0] = IOMUXC_GPR12,

drivers/pci/controller/dwc/pci-keystone.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
930930
}
931931

932932
static const struct pci_epc_features ks_pcie_am654_epc_features = {
933+
DWC_EPC_COMMON_FEATURES,
933934
.msi_capable = true,
934935
.msix_capable = true,
935936
.bar[BAR_0] = { .type = BAR_RESERVED, },

0 commit comments

Comments
 (0)