Merge branch 'frankjpliu/master' into 'master' (merge request !61)
arm64: Work around Ampere Altra erratum #82288 PCIE_65
This commit is contained in:
commit
69591b8c51
|
@ -52,6 +52,9 @@ stable kernels.
|
|||
| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Ampere | Altra | #82288 | ALTRA_ERRATUM_82288 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
| Ampere | AmpereOne | AC03_CPU_38 | AMPERE_ERRATUM_AC03_CPU_38 |
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
+----------------+-----------------+-----------------+-----------------------------+
|
||||
|
|
|
@ -439,6 +439,27 @@ config AMPERE_ERRATUM_AC03_CPU_38
|
|||
config ARM64_WORKAROUND_CLEAN_CACHE
|
||||
bool
|
||||
|
||||
config ALTRA_ERRATUM_82288
|
||||
bool "Ampere Altra: 82288: PCIE_65: PCIe Root Port outbound write combining issue"
|
||||
default y
|
||||
help
|
||||
This option adds an alternative code sequence to work around
|
||||
Ampere Altra erratum 82288.
|
||||
|
||||
PCIe device drivers may map MMIO space as Normal, non-cacheable
|
||||
memory attribute (e.g. Linux kernel drivers mapping MMIO
|
||||
using ioremap_wc). This may be for the purpose of enabling write
|
||||
combining or unaligned accesses. This can result in data corruption
|
||||
on the PCIe interface’s outbound MMIO writes due to issues with the
|
||||
write-combining operation.
|
||||
|
||||
The workaround modifies software that maps PCIe MMIO space as Normal,
|
||||
non-cacheable memory (e.g. ioremap_wc) to instead Device,
|
||||
non-gatheringmemory (e.g. ioremap). And all memory operations on PCIe
|
||||
MMIO space must be strictly aligned.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_ERRATUM_826319
|
||||
bool "Cortex-A53: 826319: System might deadlock if a write cannot complete until read data is accepted"
|
||||
default y
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#define pcibios_assign_all_busses() \
|
||||
(pci_has_flag(PCI_REASSIGN_ALL_BUS))
|
||||
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
extern bool __read_mostly have_altra_erratum_82288;
|
||||
#endif
|
||||
|
||||
#define arch_can_pci_mmap_wc() 1
|
||||
|
||||
/* Generic PCI */
|
||||
|
|
|
@ -230,11 +230,6 @@ static inline pte_t pte_mkyoung(pte_t pte)
|
|||
return set_pte_bit(pte, __pgprot(PTE_AF));
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
return set_pte_bit(pte, __pgprot(PTE_SPECIAL));
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkcont(pte_t pte)
|
||||
{
|
||||
pte = set_pte_bit(pte, __pgprot(PTE_CONT));
|
||||
|
@ -581,6 +576,27 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
|
|||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
|
||||
PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
|
||||
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
extern bool have_altra_erratum_82288;
|
||||
#endif
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
phys_addr_t phys = __pte_to_phys(pte);
|
||||
pgprot_t prot = __pgprot(pte_val(pte) & ~PTE_ADDR_MASK);
|
||||
|
||||
if (unlikely(have_altra_erratum_82288) &&
|
||||
(phys < 0x80000000 ||
|
||||
(phys >= 0x200000000000 && phys < 0x400000000000) ||
|
||||
(phys >= 0x600000000000 && phys < 0x800000000000))) {
|
||||
pte = __pte(__phys_to_pte_val(phys) | pgprot_val(pgprot_device(prot)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return set_pte_bit(pte, __pgprot(PTE_SPECIAL));
|
||||
}
|
||||
|
||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||
struct file;
|
||||
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
|
|
|
@ -6243,3 +6243,12 @@ static void pci_fixup_d3cold_delay_1sec(struct pci_dev *pdev)
|
|||
pdev->d3cold_delay = 1000;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(0x5555, 0x0004, pci_fixup_d3cold_delay_1sec);
|
||||
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
static void quirk_altra_erratum_82288(struct pci_dev *dev)
|
||||
{
|
||||
pr_info_once("Write combining PCI maps disabled due to hardware erratum\n");
|
||||
have_altra_erratum_82288 = true;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMPERE, 0xe100, quirk_altra_erratum_82288);
|
||||
#endif
|
||||
|
|
19
mm/ioremap.c
19
mm/ioremap.c
|
@ -11,6 +11,21 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/ioremap.h>
|
||||
#include <linux/pgtable.h>
|
||||
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
bool have_altra_erratum_82288 __read_mostly;
|
||||
EXPORT_SYMBOL(have_altra_erratum_82288);
|
||||
|
||||
static bool is_altra_pci(phys_addr_t phys_addr, size_t size)
|
||||
{
|
||||
phys_addr_t end = phys_addr + size;
|
||||
|
||||
return (phys_addr < 0x80000000 ||
|
||||
(end > 0x200000000000 && phys_addr < 0x400000000000) ||
|
||||
(end > 0x600000000000 && phys_addr < 0x800000000000));
|
||||
}
|
||||
#endif
|
||||
|
||||
void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size,
|
||||
pgprot_t prot)
|
||||
|
@ -40,6 +55,10 @@ void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size,
|
|||
vaddr = (unsigned long)area->addr;
|
||||
area->phys_addr = phys_addr;
|
||||
|
||||
#ifdef CONFIG_ALTRA_ERRATUM_82288
|
||||
if (unlikely(have_altra_erratum_82288 && is_altra_pci(phys_addr, size)))
|
||||
prot = pgprot_device(prot);
|
||||
#endif
|
||||
if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
|
||||
free_vm_area(area);
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue