summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/xtensa/include/asm/initialize_mmu.h9
-rw-r--r--arch/xtensa/include/asm/io.h10
-rw-r--r--arch/xtensa/include/asm/vectors.h8
-rw-r--r--arch/xtensa/kernel/setup.c37
-rw-r--r--arch/xtensa/mm/mmu.c16
5 files changed, 75 insertions, 5 deletions
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h
index a2078a2e5476..600781edc8a3 100644
--- a/arch/xtensa/include/asm/initialize_mmu.h
+++ b/arch/xtensa/include/asm/initialize_mmu.h
@@ -26,6 +26,9 @@
 #include <asm/pgtable.h>
 #include <asm/vectors.h>
 
+#define CA_BYPASS	(_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
+#define CA_WRITEBACK	(_PAGE_CA_WB     | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
+
 #ifdef __ASSEMBLY__
 
 #define XTENSA_HWVERSION_RC_2009_0 230000
@@ -80,8 +83,6 @@
 	/* Step 2: map 0x40000000..0x47FFFFFF to paddr containing this code
 	 * and jump to the new mapping.
 	 */
-#define CA_BYPASS	(_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
-#define CA_WRITEBACK	(_PAGE_CA_WB     | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
 
 	srli	a3, a0, 27
 	slli	a3, a3, 27
@@ -124,12 +125,12 @@
 	witlb	a4, a5
 
 	movi	a5, XCHAL_KIO_CACHED_VADDR + 6
-	movi	a4, XCHAL_KIO_PADDR + CA_WRITEBACK
+	movi	a4, XCHAL_KIO_DEFAULT_PADDR + CA_WRITEBACK
 	wdtlb	a4, a5
 	witlb	a4, a5
 
 	movi	a5, XCHAL_KIO_BYPASS_VADDR + 6
-	movi	a4, XCHAL_KIO_PADDR + CA_BYPASS
+	movi	a4, XCHAL_KIO_DEFAULT_PADDR + CA_BYPASS
 	wdtlb	a4, a5
 	witlb	a4, a5
 
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 1482a3636381..2a042d430c25 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -24,6 +24,16 @@
 #define IO_SPACE_LIMIT ~0
 
 #ifdef CONFIG_MMU
+
+#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF
+extern unsigned long xtensa_kio_paddr;
+
+static inline unsigned long xtensa_get_kio_paddr(void)
+{
+	return xtensa_kio_paddr;
+}
+#endif
+
 /*
  * Return the virtual address for the specified bus memory.
  * Note that we currently don't support any address outside the KIO segment.
diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h
index 221a60d804d5..5791b45d5a5d 100644
--- a/arch/xtensa/include/asm/vectors.h
+++ b/arch/xtensa/include/asm/vectors.h
@@ -22,9 +22,15 @@
 
 #define XCHAL_KIO_CACHED_VADDR		0xe0000000
 #define XCHAL_KIO_BYPASS_VADDR		0xf0000000
-#define XCHAL_KIO_PADDR			0xf0000000
+#define XCHAL_KIO_DEFAULT_PADDR		0xf0000000
 #define XCHAL_KIO_SIZE			0x10000000
 
+#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF
+#define XCHAL_KIO_PADDR			xtensa_get_kio_paddr()
+#else
+#define XCHAL_KIO_PADDR			XCHAL_KIO_DEFAULT_PADDR
+#endif
+
 #if defined(CONFIG_MMU)
 
 /* Will Become VECBASE */
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index f38badeb7747..7d12af1317f1 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -212,6 +212,42 @@ static int __init parse_bootparam(const bp_tag_t* tag)
 #ifdef CONFIG_OF
 bool __initdata dt_memory_scan = false;
 
+#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
+unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
+EXPORT_SYMBOL(xtensa_kio_paddr);
+
+static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	const __be32 *ranges;
+	unsigned long len;
+
+	if (depth > 1)
+		return 0;
+
+	if (!of_flat_dt_is_compatible(node, "simple-bus"))
+		return 0;
+
+	ranges = of_get_flat_dt_prop(node, "ranges", &len);
+	if (!ranges)
+		return 1;
+	if (len == 0)
+		return 1;
+
+	xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
+	/* round down to nearest 256MB boundary */
+	xtensa_kio_paddr &= 0xf0000000;
+
+	return 1;
+}
+#else
+static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
+		int depth, void *data)
+{
+	return 1;
+}
+#endif
+
 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
 	if (!dt_memory_scan)
@@ -232,6 +268,7 @@ void __init early_init_devtree(void *params)
 		dt_memory_scan = true;
 
 	early_init_dt_scan(params);
+	of_scan_flat_dt(xtensa_dt_io_area, NULL);
 
 	if (!command_line[0])
 		strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
index 5bb8e3c61d85..36ec171698b8 100644
--- a/arch/xtensa/mm/mmu.c
+++ b/arch/xtensa/mm/mmu.c
@@ -13,6 +13,8 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 #include <asm/page.h>
+#include <asm/initialize_mmu.h>
+#include <asm/io.h>
 
 void __init paging_init(void)
 {
@@ -37,6 +39,20 @@ void init_mmu(void)
 	set_itlbcfg_register(0);
 	set_dtlbcfg_register(0);
 #endif
+#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && CONFIG_OF
+	/*
+	 * Update the IO area mapping in case xtensa_kio_paddr has changed
+	 */
+	write_dtlb_entry(__pte(xtensa_kio_paddr + CA_WRITEBACK),
+			XCHAL_KIO_CACHED_VADDR + 6);
+	write_itlb_entry(__pte(xtensa_kio_paddr + CA_WRITEBACK),
+			XCHAL_KIO_CACHED_VADDR + 6);
+	write_dtlb_entry(__pte(xtensa_kio_paddr + CA_BYPASS),
+			XCHAL_KIO_BYPASS_VADDR + 6);
+	write_itlb_entry(__pte(xtensa_kio_paddr + CA_BYPASS),
+			XCHAL_KIO_BYPASS_VADDR + 6);
+#endif
+
 	local_flush_tlb_all();
 
 	/* Set rasid register to a known value. */