Skip to content

Commit 728a748

Browse files
committed
Merge tag 'pci-v5.13-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI fixes from Bjorn Helgaas: - Clear 64-bit flag for host bridge windows below 4GB to fix a resource allocation regression added in -rc1 (Punit Agrawal) - Fix tegra194 MCFG quirk build regressions added in -rc1 (Jon Hunter) - Avoid secondary bus resets on TI KeyStone C667X devices (Antti Järvinen) - Avoid secondary bus resets on some NVIDIA GPUs (Shanker Donthineni) - Work around FLR erratum on Huawei Intelligent NIC VF (Chiqijun) - Avoid broken ATS on AMD Navi14 GPU (Evan Quan) - Trust Broadcom BCM57414 NIC to isolate functions even though it doesn't advertise ACS support (Sriharsha Basavapatna) - Work around AMD RS690 BIOSes that don't configure DMA above 4GB (Mikel Rychliski) - Fix panic during PIO transfer on Aardvark controller (Pali Rohár) * tag 'pci-v5.13-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI: aardvark: Fix kernel panic during PIO transfer PCI: Add AMD RS690 quirk to enable 64-bit DMA PCI: Add ACS quirk for Broadcom BCM57414 NIC PCI: Mark AMD Navi14 GPU ATS as broken PCI: Work around Huawei Intelligent NIC VF FLR erratum PCI: Mark some NVIDIA GPUs to avoid bus reset PCI: Mark TI C667X to avoid bus reset PCI: tegra194: Fix MCFG quirk build regressions PCI: of: Clear 64-bit flag for non-prefetchable memory below 4GB
2 parents 9620ad8 + f181399 commit 728a748

File tree

7 files changed

+306
-131
lines changed

7 files changed

+306
-131
lines changed

arch/x86/pci/fixup.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,48 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar);
779779
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar);
780780
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar);
781781

782+
#define RS690_LOWER_TOP_OF_DRAM2 0x30
783+
#define RS690_LOWER_TOP_OF_DRAM2_VALID 0x1
784+
#define RS690_UPPER_TOP_OF_DRAM2 0x31
785+
#define RS690_HTIU_NB_INDEX 0xA8
786+
#define RS690_HTIU_NB_INDEX_WR_ENABLE 0x100
787+
#define RS690_HTIU_NB_DATA 0xAC
788+
789+
/*
790+
* Some BIOS implementations support RAM above 4GB, but do not configure the
791+
* PCI host to respond to bus master accesses for these addresses. These
792+
* implementations set the TOP_OF_DRAM_SLOT1 register correctly, so PCI DMA
793+
* works as expected for addresses below 4GB.
794+
*
795+
* Reference: "AMD RS690 ASIC Family Register Reference Guide" (pg. 2-57)
796+
* https://www.amd.com/system/files/TechDocs/43372_rs690_rrg_3.00o.pdf
797+
*/
798+
static void rs690_fix_64bit_dma(struct pci_dev *pdev)
799+
{
800+
u32 val = 0;
801+
phys_addr_t top_of_dram = __pa(high_memory - 1) + 1;
802+
803+
if (top_of_dram <= (1ULL << 32))
804+
return;
805+
806+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
807+
RS690_LOWER_TOP_OF_DRAM2);
808+
pci_read_config_dword(pdev, RS690_HTIU_NB_DATA, &val);
809+
810+
if (val)
811+
return;
812+
813+
pci_info(pdev, "Adjusting top of DRAM to %pa for 64-bit DMA support\n", &top_of_dram);
814+
815+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
816+
RS690_UPPER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE);
817+
pci_write_config_dword(pdev, RS690_HTIU_NB_DATA, top_of_dram >> 32);
818+
819+
pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX,
820+
RS690_LOWER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE);
821+
pci_write_config_dword(pdev, RS690_HTIU_NB_DATA,
822+
top_of_dram | RS690_LOWER_TOP_OF_DRAM2_VALID);
823+
}
824+
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7910, rs690_fix_64bit_dma);
825+
782826
#endif

drivers/pci/controller/dwc/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o
1818
obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
1919
obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
2020
obj-$(CONFIG_PCI_MESON) += pci-meson.o
21+
obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
2122
obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
2223
obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
2324

@@ -38,6 +39,6 @@ ifdef CONFIG_ACPI
3839
ifdef CONFIG_PCI_QUIRKS
3940
obj-$(CONFIG_ARM64) += pcie-al.o
4041
obj-$(CONFIG_ARM64) += pcie-hisi.o
41-
obj-$(CONFIG_ARM64) += pcie-tegra194.o
42+
obj-$(CONFIG_ARM64) += pcie-tegra194-acpi.o
4243
endif
4344
endif
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* ACPI quirks for Tegra194 PCIe host controller
4+
*
5+
* Copyright (C) 2021 NVIDIA Corporation.
6+
*
7+
* Author: Vidya Sagar <[email protected]>
8+
*/
9+
10+
#include <linux/pci.h>
11+
#include <linux/pci-acpi.h>
12+
#include <linux/pci-ecam.h>
13+
14+
#include "pcie-designware.h"
15+
16+
struct tegra194_pcie_ecam {
17+
void __iomem *config_base;
18+
void __iomem *iatu_base;
19+
void __iomem *dbi_base;
20+
};
21+
22+
static int tegra194_acpi_init(struct pci_config_window *cfg)
23+
{
24+
struct device *dev = cfg->parent;
25+
struct tegra194_pcie_ecam *pcie_ecam;
26+
27+
pcie_ecam = devm_kzalloc(dev, sizeof(*pcie_ecam), GFP_KERNEL);
28+
if (!pcie_ecam)
29+
return -ENOMEM;
30+
31+
pcie_ecam->config_base = cfg->win;
32+
pcie_ecam->iatu_base = cfg->win + SZ_256K;
33+
pcie_ecam->dbi_base = cfg->win + SZ_512K;
34+
cfg->priv = pcie_ecam;
35+
36+
return 0;
37+
}
38+
39+
static void atu_reg_write(struct tegra194_pcie_ecam *pcie_ecam, int index,
40+
u32 val, u32 reg)
41+
{
42+
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
43+
44+
writel(val, pcie_ecam->iatu_base + offset + reg);
45+
}
46+
47+
static void program_outbound_atu(struct tegra194_pcie_ecam *pcie_ecam,
48+
int index, int type, u64 cpu_addr,
49+
u64 pci_addr, u64 size)
50+
{
51+
atu_reg_write(pcie_ecam, index, lower_32_bits(cpu_addr),
52+
PCIE_ATU_LOWER_BASE);
53+
atu_reg_write(pcie_ecam, index, upper_32_bits(cpu_addr),
54+
PCIE_ATU_UPPER_BASE);
55+
atu_reg_write(pcie_ecam, index, lower_32_bits(pci_addr),
56+
PCIE_ATU_LOWER_TARGET);
57+
atu_reg_write(pcie_ecam, index, lower_32_bits(cpu_addr + size - 1),
58+
PCIE_ATU_LIMIT);
59+
atu_reg_write(pcie_ecam, index, upper_32_bits(pci_addr),
60+
PCIE_ATU_UPPER_TARGET);
61+
atu_reg_write(pcie_ecam, index, type, PCIE_ATU_CR1);
62+
atu_reg_write(pcie_ecam, index, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
63+
}
64+
65+
static void __iomem *tegra194_map_bus(struct pci_bus *bus,
66+
unsigned int devfn, int where)
67+
{
68+
struct pci_config_window *cfg = bus->sysdata;
69+
struct tegra194_pcie_ecam *pcie_ecam = cfg->priv;
70+
u32 busdev;
71+
int type;
72+
73+
if (bus->number < cfg->busr.start || bus->number > cfg->busr.end)
74+
return NULL;
75+
76+
if (bus->number == cfg->busr.start) {
77+
if (PCI_SLOT(devfn) == 0)
78+
return pcie_ecam->dbi_base + where;
79+
else
80+
return NULL;
81+
}
82+
83+
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
84+
PCIE_ATU_FUNC(PCI_FUNC(devfn));
85+
86+
if (bus->parent->number == cfg->busr.start) {
87+
if (PCI_SLOT(devfn) == 0)
88+
type = PCIE_ATU_TYPE_CFG0;
89+
else
90+
return NULL;
91+
} else {
92+
type = PCIE_ATU_TYPE_CFG1;
93+
}
94+
95+
program_outbound_atu(pcie_ecam, 0, type, cfg->res.start, busdev,
96+
SZ_256K);
97+
98+
return pcie_ecam->config_base + where;
99+
}
100+
101+
const struct pci_ecam_ops tegra194_pcie_ops = {
102+
.init = tegra194_acpi_init,
103+
.pci_ops = {
104+
.map_bus = tegra194_map_bus,
105+
.read = pci_generic_config_read,
106+
.write = pci_generic_config_write,
107+
}
108+
};

drivers/pci/controller/dwc/pcie-tegra194.c

Lines changed: 18 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
#include <linux/of_irq.h>
2323
#include <linux/of_pci.h>
2424
#include <linux/pci.h>
25-
#include <linux/pci-acpi.h>
26-
#include <linux/pci-ecam.h>
2725
#include <linux/phy/phy.h>
2826
#include <linux/pinctrl/consumer.h>
2927
#include <linux/platform_device.h>
@@ -247,24 +245,6 @@ static const unsigned int pcie_gen_freq[] = {
247245
GEN4_CORE_CLK_FREQ
248246
};
249247

250-
static const u32 event_cntr_ctrl_offset[] = {
251-
0x1d8,
252-
0x1a8,
253-
0x1a8,
254-
0x1a8,
255-
0x1c4,
256-
0x1d8
257-
};
258-
259-
static const u32 event_cntr_data_offset[] = {
260-
0x1dc,
261-
0x1ac,
262-
0x1ac,
263-
0x1ac,
264-
0x1c8,
265-
0x1dc
266-
};
267-
268248
struct tegra_pcie_dw {
269249
struct device *dev;
270250
struct resource *appl_res;
@@ -313,104 +293,6 @@ struct tegra_pcie_dw_of_data {
313293
enum dw_pcie_device_mode mode;
314294
};
315295

316-
#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
317-
struct tegra194_pcie_ecam {
318-
void __iomem *config_base;
319-
void __iomem *iatu_base;
320-
void __iomem *dbi_base;
321-
};
322-
323-
static int tegra194_acpi_init(struct pci_config_window *cfg)
324-
{
325-
struct device *dev = cfg->parent;
326-
struct tegra194_pcie_ecam *pcie_ecam;
327-
328-
pcie_ecam = devm_kzalloc(dev, sizeof(*pcie_ecam), GFP_KERNEL);
329-
if (!pcie_ecam)
330-
return -ENOMEM;
331-
332-
pcie_ecam->config_base = cfg->win;
333-
pcie_ecam->iatu_base = cfg->win + SZ_256K;
334-
pcie_ecam->dbi_base = cfg->win + SZ_512K;
335-
cfg->priv = pcie_ecam;
336-
337-
return 0;
338-
}
339-
340-
static void atu_reg_write(struct tegra194_pcie_ecam *pcie_ecam, int index,
341-
u32 val, u32 reg)
342-
{
343-
u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
344-
345-
writel(val, pcie_ecam->iatu_base + offset + reg);
346-
}
347-
348-
static void program_outbound_atu(struct tegra194_pcie_ecam *pcie_ecam,
349-
int index, int type, u64 cpu_addr,
350-
u64 pci_addr, u64 size)
351-
{
352-
atu_reg_write(pcie_ecam, index, lower_32_bits(cpu_addr),
353-
PCIE_ATU_LOWER_BASE);
354-
atu_reg_write(pcie_ecam, index, upper_32_bits(cpu_addr),
355-
PCIE_ATU_UPPER_BASE);
356-
atu_reg_write(pcie_ecam, index, lower_32_bits(pci_addr),
357-
PCIE_ATU_LOWER_TARGET);
358-
atu_reg_write(pcie_ecam, index, lower_32_bits(cpu_addr + size - 1),
359-
PCIE_ATU_LIMIT);
360-
atu_reg_write(pcie_ecam, index, upper_32_bits(pci_addr),
361-
PCIE_ATU_UPPER_TARGET);
362-
atu_reg_write(pcie_ecam, index, type, PCIE_ATU_CR1);
363-
atu_reg_write(pcie_ecam, index, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
364-
}
365-
366-
static void __iomem *tegra194_map_bus(struct pci_bus *bus,
367-
unsigned int devfn, int where)
368-
{
369-
struct pci_config_window *cfg = bus->sysdata;
370-
struct tegra194_pcie_ecam *pcie_ecam = cfg->priv;
371-
u32 busdev;
372-
int type;
373-
374-
if (bus->number < cfg->busr.start || bus->number > cfg->busr.end)
375-
return NULL;
376-
377-
if (bus->number == cfg->busr.start) {
378-
if (PCI_SLOT(devfn) == 0)
379-
return pcie_ecam->dbi_base + where;
380-
else
381-
return NULL;
382-
}
383-
384-
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
385-
PCIE_ATU_FUNC(PCI_FUNC(devfn));
386-
387-
if (bus->parent->number == cfg->busr.start) {
388-
if (PCI_SLOT(devfn) == 0)
389-
type = PCIE_ATU_TYPE_CFG0;
390-
else
391-
return NULL;
392-
} else {
393-
type = PCIE_ATU_TYPE_CFG1;
394-
}
395-
396-
program_outbound_atu(pcie_ecam, 0, type, cfg->res.start, busdev,
397-
SZ_256K);
398-
399-
return pcie_ecam->config_base + where;
400-
}
401-
402-
const struct pci_ecam_ops tegra194_pcie_ops = {
403-
.init = tegra194_acpi_init,
404-
.pci_ops = {
405-
.map_bus = tegra194_map_bus,
406-
.read = pci_generic_config_read,
407-
.write = pci_generic_config_write,
408-
}
409-
};
410-
#endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
411-
412-
#ifdef CONFIG_PCIE_TEGRA194
413-
414296
static inline struct tegra_pcie_dw *to_tegra_pcie(struct dw_pcie *pci)
415297
{
416298
return container_of(pci, struct tegra_pcie_dw, pci);
@@ -694,6 +576,24 @@ static struct pci_ops tegra_pci_ops = {
694576
};
695577

696578
#if defined(CONFIG_PCIEASPM)
579+
static const u32 event_cntr_ctrl_offset[] = {
580+
0x1d8,
581+
0x1a8,
582+
0x1a8,
583+
0x1a8,
584+
0x1c4,
585+
0x1d8
586+
};
587+
588+
static const u32 event_cntr_data_offset[] = {
589+
0x1dc,
590+
0x1ac,
591+
0x1ac,
592+
0x1ac,
593+
0x1c8,
594+
0x1dc
595+
};
596+
697597
static void disable_aspm_l11(struct tegra_pcie_dw *pcie)
698598
{
699599
u32 val;
@@ -2411,5 +2311,3 @@ MODULE_DEVICE_TABLE(of, tegra_pcie_dw_of_match);
24112311
MODULE_AUTHOR("Vidya Sagar <[email protected]>");
24122312
MODULE_DESCRIPTION("NVIDIA PCIe host controller driver");
24132313
MODULE_LICENSE("GPL v2");
2414-
2415-
#endif /* CONFIG_PCIE_TEGRA194 */

0 commit comments

Comments
 (0)