You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.5 KiB
82 lines
3.5 KiB
10 years ago
|
From 1bc7c02e7f37ddfa09cb0db330ee8cd4034d6410 Mon Sep 17 00:00:00 2001
|
||
|
From: Geert Uytterhoeven <geert+renesas@glider.be>
|
||
|
Date: Thu, 7 May 2015 11:27:11 +0200
|
||
|
Subject: [PATCH 1/4] ARM: l2c: Add support for the "arm, shared-override"
|
||
|
property
|
||
|
|
||
|
"CoreLink Level 2 Cache Controller L2C-310", p. 2-15, section 2.3.2
|
||
|
Shareable attribute" states:
|
||
|
|
||
|
"The default behavior of the cache controller with respect to the
|
||
|
shareable attribute is to transform Normal Memory Non-cacheable
|
||
|
transactions into:
|
||
|
- cacheable no allocate for reads
|
||
|
- write through no write allocate for writes."
|
||
|
|
||
|
Depending on the system architecture, this may cause memory corruption
|
||
|
in the presence of bus mastering devices (e.g. OHCI). To avoid such
|
||
|
corruption, the default behavior can be disabled by setting the Shared
|
||
|
Override bit in the Auxiliary Control register.
|
||
|
|
||
|
Currently the Shared Override bit can be set only using C code:
|
||
|
- by calling l2x0_init() directly, which is deprecated,
|
||
|
- by setting/clearing the bit in the machine_desc.l2c_aux_val/mask
|
||
|
fields, but using values differing from 0/~0 is also deprecated.
|
||
|
|
||
|
Hence add support for an "arm,shared-override" device tree property for
|
||
|
the l2c device node. By specifying this property, affected systems can
|
||
|
indicate that non-cacheable transactions must not be transformed.
|
||
|
Then, it's up to the OS to decide. The current behavior is to set the
|
||
|
"shared attribute override enable" bit, as there may exist kernel linear
|
||
|
mappings and cacheable aliases for the DMA buffers, even if CMA is
|
||
|
enabled.
|
||
|
|
||
|
See also commit 1a8e41cd672f894b ("ARM: 6395/1: VExpress: Set bit 22 in
|
||
|
the PL310 (cache controller) AuxCtlr register"):
|
||
|
|
||
|
"Clearing bit 22 in the PL310 Auxiliary Control register (shared
|
||
|
attribute override enable) has the side effect of transforming
|
||
|
Normal Shared Non-cacheable reads into Cacheable no-allocate reads.
|
||
|
|
||
|
Coherent DMA buffers in Linux always have a Cacheable alias via the
|
||
|
kernel linear mapping and the processor can speculatively load
|
||
|
cache lines into the PL310 controller. With bit 22 cleared,
|
||
|
Non-cacheable reads would unexpectedly hit such cache lines leading
|
||
|
to buffer corruption."
|
||
|
|
||
|
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||
|
---
|
||
|
Documentation/devicetree/bindings/arm/l2cc.txt | 6 ++++++
|
||
|
arch/arm/mm/cache-l2x0.c | 5 +++++
|
||
|
2 files changed, 11 insertions(+)
|
||
|
|
||
|
--- a/Documentation/devicetree/bindings/arm/l2cc.txt
|
||
|
+++ b/Documentation/devicetree/bindings/arm/l2cc.txt
|
||
|
@@ -72,6 +72,12 @@ Optional properties:
|
||
|
- prefetch-instr : Instruction prefetch. Value: <0> (forcibly disable),
|
||
|
<1> (forcibly enable), property absent (retain settings set by
|
||
|
firmware)
|
||
|
+- arm,shared-override : The default behavior of the pl310 cache controller with
|
||
|
+ respect to the shareable attribute is to transform "normal memory
|
||
|
+ non-cacheable transactions" into "cacheable no allocate" (for reads) or
|
||
|
+ "write through no write allocate" (for writes).
|
||
|
+ On systems where this may cause DMA buffer corruption, this property must be
|
||
|
+ specified to indicate that such transforms are precluded.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
--- a/arch/arm/mm/cache-l2x0.c
|
||
|
+++ b/arch/arm/mm/cache-l2x0.c
|
||
|
@@ -1171,6 +1171,11 @@ static void __init l2c310_of_parse(const
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ if (of_property_read_bool(np, "arm,shared-override")) {
|
||
|
+ *aux_val |= L2C_AUX_CTRL_SHARED_OVERRIDE;
|
||
|
+ *aux_mask &= ~L2C_AUX_CTRL_SHARED_OVERRIDE;
|
||
|
+ }
|
||
|
+
|
||
|
prefetch = l2x0_saved_regs.prefetch_ctrl;
|
||
|
|
||
|
ret = of_property_read_u32(np, "arm,double-linefill", &val);
|