diff options
Diffstat (limited to 'arch/sh/boards')
-rw-r--r-- | arch/sh/boards/mach-sdk7786/fpga.c | 43 |
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 99f903c8b23..3e4ec66a041 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; } |