sh: mach-sdk7786: Probe system FPGA area mapping.

This implements dynamic probing for the system FPGA. The system reset
controller contains a fixed magic read word in order to identify the
FPGA. This just utilizes a simple loop that scans across all of the fixed
physical areas (area 0 through area 6) to locate the FPGA.

The FPGA also contains register information detailing the area mappings
and chip select settings for all of the other blocks, so this needs to be
done before we can set up anything else.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c
index 99f903c..3e4ec66 100644
--- a/arch/sh/boards/mach-sdk7786/fpga.c
+++ b/arch/sh/boards/mach-sdk7786/fpga.c
@@ -11,9 +11,44 @@
 #include <linux/io.h>
 #include <linux/bcd.h>
 #include <mach/fpga.h>
+#include <asm/sizes.h>
 
-#define FPGA_REGS_BASE	0x07fff800
-#define FPGA_REGS_SIZE	0x490
+#define FPGA_REGS_OFFSET	0x03fff800
+#define FPGA_REGS_SIZE		0x490
+
+/*
+ * The FPGA can be mapped in any of the generally available areas,
+ * so we attempt to scan for it using the fixed SRSTR read magic.
+ *
+ * Once the FPGA is located, the rest of the mapping data for the other
+ * components can be determined dynamically from its section mapping
+ * registers.
+ */
+static void __iomem *sdk7786_fpga_probe(void)
+{
+	unsigned long area;
+	void __iomem *base;
+
+	/*
+	 * Iterate over all of the areas where the FPGA could be mapped.
+	 * The possible range is anywhere from area 0 through 6, area 7
+	 * is reserved.
+	 */
+	for (area = PA_AREA0; area < PA_AREA7; area += SZ_64M) {
+		base = ioremap_nocache(area + FPGA_REGS_OFFSET, FPGA_REGS_SIZE);
+		if (!base) {
+			/* Failed to remap this area, move along. */
+			continue;
+		}
+
+		if (ioread16(base + SRSTR) == SRSTR_MAGIC)
+			return base;	/* Found it! */
+
+		iounmap(base);
+	}
+
+	return NULL;
+}
 
 void __iomem *sdk7786_fpga_base;
 
@@ -21,9 +56,9 @@
 {
 	u16 version, date;
 
-	sdk7786_fpga_base = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE);
+	sdk7786_fpga_base = sdk7786_fpga_probe();
 	if (unlikely(!sdk7786_fpga_base)) {
-		panic("FPGA remapping failed.\n");
+		panic("FPGA detection failed.\n");
 		return;
 	}
 
diff --git a/arch/sh/include/cpu-sh4/cpu/addrspace.h b/arch/sh/include/cpu-sh4/cpu/addrspace.h
index a3fa733..d51da25 100644
--- a/arch/sh/include/cpu-sh4/cpu/addrspace.h
+++ b/arch/sh/include/cpu-sh4/cpu/addrspace.h
@@ -28,6 +28,15 @@
 #define P4SEG_TLB_DATA	0xf7000000
 #define P4SEG_REG_BASE	0xff000000
 
+#define PA_AREA0	0x00000000
+#define PA_AREA1	0x04000000
+#define PA_AREA2	0x08000000
+#define PA_AREA3	0x0c000000
+#define PA_AREA4	0x10000000
+#define PA_AREA5	0x14000000
+#define PA_AREA6	0x18000000
+#define PA_AREA7	0x1c000000
+
 #define PA_AREA5_IO	0xb4000000	/* Area 5 IO Memory */
 #define PA_AREA6_IO	0xb8000000	/* Area 6 IO Memory */
 
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
index a85d985..2120d67 100644
--- a/arch/sh/include/mach-sdk7786/mach/fpga.h
+++ b/arch/sh/include/mach-sdk7786/mach/fpga.h
@@ -6,6 +6,8 @@
 #include <linux/bitops.h>
 
 #define SRSTR		0x000
+#define  SRSTR_MAGIC	0x1971	/* Fixed magical read value */
+
 #define INTASR		0x010
 #define INTAMR		0x020
 #define MODSWR		0x030