summaryrefslogtreecommitdiffstats
path: root/arch/sh/boards
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-20 10:25:19 +0100
committerPaul Mundt <lethal@linux-sh.org>2010-01-20 10:25:19 +0100
commitd9116d07f60383cef134c43a0ba15ec4375310fc (patch)
tree076c1698dcd4886b1f4e9c1311eb0cf8b68cdef9 /arch/sh/boards
parentsh: Correct iounmap fixmap teardown. (diff)
downloadlinux-d9116d07f60383cef134c43a0ba15ec4375310fc.tar.xz
linux-d9116d07f60383cef134c43a0ba15ec4375310fc.zip
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>
Diffstat (limited to 'arch/sh/boards')
-rw-r--r--arch/sh/boards/mach-sdk7786/fpga.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c
index 99f903c8b238..3e4ec66a0417 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 @@ void __init sdk7786_fpga_init(void)
{
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;
}