diff mbox

[U-Boot,1/1] ARMv7 TLB: Fixed TTBR0 and Table Descriptors to allow caching

Message ID 1428002040-64396-1-git-send-email-bryan.brinsko@rockwellcollins.com
State Not Applicable
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Bryan Brinsko April 2, 2015, 7:14 p.m. UTC
The TTBR0 register and Table Descriptors of the ARMv7 TLB weren't being
properly set to allow for the configuration specified caching modes to
be active over DRAM. This commit fixes those issues.

Signed-off-by: Bryan Brinsko <bryan.brinsko@rockwellcollins.com>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
Cc: Marek Vasut <marex@denx.de>
---
 arch/arm/include/asm/system.h | 37 +++++++++++++++++++++++++++++++++++++
 arch/arm/lib/cache-cp15.c     | 14 ++++++++++++++
 2 files changed, 51 insertions(+)
diff mbox

Patch

diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 2a5bed2..9cd2f1e 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -196,6 +196,28 @@  static inline void set_dacr(unsigned int val)
 	isb();
 }
 
+#ifdef CONFIG_ARMV7
+/* Short-Descriptor Translation Table Level 1 Bits */
+#define TTB_SECT_NS_MASK	(1 << 19)
+#define TTB_SECT_NG_MASK	(1 << 17)
+#define TTB_SECT_S_MASK		(1 << 16)
+/* Note: TTB AP bits are set elsewhere */
+#define TTB_SECT_TEX(x)		((x & 0x7) << 12)
+#define TTB_SECT_DOMAIN(x)	((x & 0xf) << 5)
+#define TTB_SECT_XN_MASK	(1 << 4)
+#define TTB_SECT_C_MASK		(1 << 3)
+#define TTB_SECT_B_MASK		(1 << 2)
+#define TTB_SECT			(2 << 0)
+
+/* options available for data cache on each page */
+enum dcache_option {
+	DCACHE_OFF = TTB_SECT_S_MASK | TTB_SECT_DOMAIN(0) |
+					TTB_SECT_XN_MASK | TTB_SECT,
+	DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
+	DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
+	DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
+};
+#else
 /* options available for data cache on each page */
 enum dcache_option {
 	DCACHE_OFF = 0x12,
@@ -203,6 +225,7 @@  enum dcache_option {
 	DCACHE_WRITEBACK = 0x1e,
 	DCACHE_WRITEALLOC = 0x16,
 };
+#endif
 
 /* Size of an MMU section */
 enum {
@@ -210,6 +233,20 @@  enum {
 	MMU_SECTION_SIZE	= 1 << MMU_SECTION_SHIFT,
 };
 
+#ifdef CONFIG_ARMV7
+/* TTBR0 bits */
+#define TTBR0_BASE_ADDR_MASK	0xFFFFC000
+#define TTBR0_RGN_NC			(0 << 3)
+#define TTBR0_RGN_WBWA			(1 << 3)
+#define TTBR0_RGN_WT			(2 << 3)
+#define TTBR0_RGN_WB			(3 << 3)
+/* TTBR0[6] is IRGN[0] and TTBR[0] is IRGN[1] */
+#define TTBR0_IRGN_NC			(0 << 0 | 0 << 6)
+#define TTBR0_IRGN_WBWA			(0 << 0 | 1 << 6)
+#define TTBR0_IRGN_WT			(1 << 0 | 0 << 6)
+#define TTBR0_IRGN_WB			(1 << 0 | 1 << 6)
+#endif
+
 /**
  * Change the cache settings for a region.
  *
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 0291afa..c65e068 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -96,9 +96,23 @@  static inline void mmu_setup(void)
 		dram_bank_mmu_setup(i);
 	}
 
+#ifdef CONFIG_ARMV7
+	/* Set TTBR0 */
+	reg = gd->arch.tlb_addr & TTBR0_BASE_ADDR_MASK;
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+	reg |= TTBR0_RGN_WT | TTBR0_IRGN_WT;
+#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
+	reg |= TTBR0_RGN_WBWA | TTBR0_IRGN_WBWA;
+#else
+	reg |= TTBR0_RGN_WB | TTBR0_IRGN_WB;
+#endif
+	asm volatile("mcr p15, 0, %0, c2, c0, 0"
+		     : : "r" (reg) : "memory");
+#else
 	/* Copy the page table address to cp15 */
 	asm volatile("mcr p15, 0, %0, c2, c0, 0"
 		     : : "r" (gd->arch.tlb_addr) : "memory");
+#endif
 	/* Set the access control to all-supervisor */
 	asm volatile("mcr p15, 0, %0, c3, c0, 0"
 		     : : "r" (~0));