ANDROID: arm64: Add support for system cache memory type

Non-coherent devices on systems that support a system or
last level cache may want to request that allocations be
cached in the system cache. For memory that is allocated
by the kernel, and used for DMA with devices, the memory
attributes used for CPU access should match the memory
attributes that will be used for device access.

The memory attributes that need to be programmed into
the MAIR for system cache usage are:

0xf4 - Normal memory, outer write back read/write allocate,
inner non-cacheable.

There is currently no support for this memory attribute for
CPU mappings, so add it.

Bug: 176778547
Change-Id: I3abc7becd408f20ac5499cbbe3c6c6f53f784107
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Isaac J. Manjarres 2021-01-12 14:17:41 -08:00 committed by Suren Baghdasaryan
parent 084fab46dd
commit 261c5080bb
5 changed files with 21 additions and 1 deletions

View File

@ -138,6 +138,7 @@
#define MT_DEVICE_nGnRnE 4
#define MT_DEVICE_nGnRE 5
#define MT_DEVICE_GRE 6
#define MT_NORMAL_iNC_oWB 7
/*
* Memory types for Stage-2 translation

View File

@ -496,6 +496,15 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
/*
* Mark the prot value as outer cacheable and inner non-cacheable. Non-coherent
* devices on a system with support for a system or last level cache use these
* attributes to cache allocations in the system cache.
*/
#define pgprot_syscached(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
PTE_ATTRINDX(MT_NORMAL_iNC_oWB) | PTE_PXN | PTE_UXN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,

View File

@ -631,6 +631,7 @@
#define MAIR_ATTR_NORMAL_TAGGED UL(0xf0)
#define MAIR_ATTR_NORMAL UL(0xff)
#define MAIR_ATTR_MASK UL(0xff)
#define MAIR_ATTR_NORMAL_iNC_oWB UL(0xf4)
/* Position the attr at the correct index */
#define MAIR_ATTRIDX(attr, idx) ((attr) << ((idx) * 8))

View File

@ -56,7 +56,8 @@
MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) | \
MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) | \
MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT) | \
MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED))
MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED) | \
MAIR_ATTRIDX(MAIR_ATTR_NORMAL_iNC_oWB, MT_NORMAL_iNC_oWB))
#ifdef CONFIG_CPU_PM
/**

View File

@ -258,6 +258,14 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
#define pgprot_dmacoherent(prot) pgprot_noncached(prot)
#endif
/*
* If there is no system cache pgprot, then fallback to dmacoherent
* pgprot, as the expectation is that the device is not coherent.
*/
#ifndef pgprot_syscached
#define pgprot_syscached(prot) pgprot_dmacoherent(prot)
#endif
pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
#else
static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,