sh: mach-sdk7786: FPGA updates.
Paul Mundt [Wed, 20 Jan 2010 06:08:36 +0000 (15:08 +0900)]
This does a bit of refactoring of the FPGA management code. The primary
FPGA initialization is moved out to its own file in preparation for
implementing some of the more complex capabilities, a complete set of
register definitions is provided, and all of the existing users in the
board code are moved over to use the new interface instead of setting up
overlapping mappings. This also corrects the FPGA size, which previously
was chomped off at the SDIF control register.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

arch/sh/boards/mach-sdk7786/Makefile
arch/sh/boards/mach-sdk7786/fpga.c [new file with mode: 0644]
arch/sh/boards/mach-sdk7786/setup.c
arch/sh/include/mach-sdk7786/mach/fpga.h [new file with mode: 0644]

index f663768..50c8065 100644 (file)
@@ -1 +1 @@
-obj-y  := setup.o
+obj-y  := setup.o fpga.o
diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c
new file mode 100644 (file)
index 0000000..99f903c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * SDK7786 FPGA Support.
+ *
+ * Copyright (C) 2010  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bcd.h>
+#include <mach/fpga.h>
+
+#define FPGA_REGS_BASE 0x07fff800
+#define FPGA_REGS_SIZE 0x490
+
+void __iomem *sdk7786_fpga_base;
+
+void __init sdk7786_fpga_init(void)
+{
+       u16 version, date;
+
+       sdk7786_fpga_base = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE);
+       if (unlikely(!sdk7786_fpga_base)) {
+               panic("FPGA remapping failed.\n");
+               return;
+       }
+
+       version = fpga_read_reg(FPGAVR);
+       date = fpga_read_reg(FPGADR);
+
+       pr_info("\tFPGA version:\t%d.%d (built on %d/%d/%d)\n",
+               bcd2bin(version >> 8) & 0xf, bcd2bin(version & 0xf),
+               ((date >> 12) & 0xf) + 2000,
+               (date >> 8) & 0xf, bcd2bin(date & 0xff));
+}
index 0e4b1c3..8dbbdea 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/machvec.h>
 #include <asm/heartbeat.h>
 #include <asm/sizes.h>
+#include <mach/fpga.h>
 
 static struct resource heartbeat_resource = {
        .start          = 0x07fff8b0,
@@ -103,27 +104,17 @@ static struct platform_device *sh7786_devices[] __initdata = {
        &smbus_pcie_device,
 };
 
-#define SBCR_REGS_BASE 0x07fff990
-
-#define SCBR_I2CMEN    (1 << 0)        /* FPGA I2C master enable */
-#define SCBR_I2CCEN    (1 << 1)        /* CPU I2C master enable */
-
 static int sdk7786_i2c_setup(void)
 {
-       void __iomem *sbcr;
        unsigned int tmp;
 
-       sbcr = ioremap_nocache(SBCR_REGS_BASE, SZ_16);
-
        /*
         * Hand over I2C control to the FPGA.
         */
-       tmp = ioread16(sbcr);
+       tmp = fpga_read_reg(SBCR);
        tmp &= ~SCBR_I2CCEN;
        tmp |= SCBR_I2CMEN;
-       iowrite16(tmp, sbcr);
-
-       iounmap(sbcr);
+       fpga_write_reg(tmp, SBCR);
 
        return i2c_register_board_info(0, sdk7786_i2c_devices,
                                       ARRAY_SIZE(sdk7786_i2c_devices));
@@ -141,43 +132,6 @@ static int __init sdk7786_devices_setup(void)
 }
 __initcall(sdk7786_devices_setup);
 
-#define FPGA_REGS_BASE 0x07fff800
-#define FPGA_REGS_SIZE 1152
-
-#define INTASR         0x010
-#define INTAMR         0x020
-#define INTBSR         0x090
-#define INTBMR         0x0a0
-#define INTMSR         0x130
-
-#define IASELR1                0x210
-#define IASELR2                0x220
-#define IASELR3                0x230
-#define IASELR4                0x240
-#define IASELR5                0x250
-#define IASELR6                0x260
-#define IASELR7                0x270
-#define IASELR8                0x280
-#define IASELR9                0x290
-#define IASELR10       0x2a0
-#define IASELR11       0x2b0
-#define IASELR12       0x2c0
-#define IASELR13       0x2d0
-#define IASELR14       0x2e0
-#define IASELR15       0x2f0
-
-static void __iomem *fpga_regs;
-
-static u16 fpga_read_reg(unsigned int reg)
-{
-       return __raw_readw(fpga_regs + reg);
-}
-
-static void fpga_write_reg(u16 val, unsigned int reg)
-{
-       __raw_writew(val, fpga_regs + reg);
-}
-
 enum {
        ATA_IRQ_BIT             = 1,
        SPI_BUSY_BIT            = 2,
@@ -197,12 +151,6 @@ static void __init init_sdk7786_IRQ(void)
 {
        unsigned int tmp;
 
-       fpga_regs = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE);
-       if (!fpga_regs) {
-               printk(KERN_ERR "Couldn't map FPGA registers\n");
-               return;
-       }
-
        /* Enable priority encoding for all IRLs */
        fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR);
 
@@ -219,21 +167,9 @@ static void __init init_sdk7786_IRQ(void)
        plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
 }
 
-#define MODSWR_REGS    0x07fff830
-
 static int sdk7786_mode_pins(void)
 {
-       void __iomem *modswr;
-       int pin_states;
-
-       modswr = ioremap_nocache(MODSWR_REGS, SZ_16);
-       if (!modswr)
-               return -ENXIO;
-
-       pin_states = ioread16(modswr);
-       iounmap(modswr);
-
-       return pin_states;
+       return fpga_read_reg(MODSWR);
 }
 
 static int sdk7786_clk_init(void)
@@ -260,7 +196,11 @@ static int sdk7786_clk_init(void)
 /* Initialize the board */
 static void __init sdk7786_setup(char **cmdline_p)
 {
-       printk(KERN_INFO "Renesas Technology Corp. SDK7786 support.\n");
+       pr_info("Renesas Technology Europe SDK7786 support:\n");
+
+       sdk7786_fpga_init();
+
+       pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
 }
 
 /*
diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h
new file mode 100644 (file)
index 0000000..a85d985
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef __MACH_SDK7786_FPGA_H
+#define __MACH_SDK7786_FPGA_H
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+#define SRSTR          0x000
+#define INTASR         0x010
+#define INTAMR         0x020
+#define MODSWR         0x030
+#define INTTESTR       0x040
+#define SYSSR          0x050
+#define NRGPR          0x060
+#define NMISR          0x070
+
+#define NMIMR          0x080
+#define  NMIMR_MAN_NMIM        BIT(0)  /* Manual NMI mask */
+#define  NMIMR_AUX_NMIM        BIT(1)  /* Auxiliary NMI mask */
+
+#define INTBSR         0x090
+#define INTBMR         0x0a0
+#define USRLEDR                0x0b0
+#define MAPSWR         0x0c0
+#define FPGAVR         0x0d0
+#define FPGADR         0x0e0
+#define PCBRR          0x0f0
+#define RSR            0x100
+#define EXTASR         0x110
+#define SPCAR          0x120
+#define INTMSR         0x130
+#define PCIECR         0x140
+#define FAER           0x150
+#define USRGPIR                0x160
+/* 0x170 reserved */
+#define LCLASR         0x180
+
+#define SBCR           0x190
+#define  SCBR_I2CMEN   BIT(0)  /* FPGA I2C master enable */
+#define  SCBR_I2CCEN   BIT(1)  /* CPU I2C master enable */
+
+#define PWRCR          0x1a0
+#define SPCBR          0x1b0
+#define SPICR          0x1c0
+#define SPIDR          0x1d0
+#define I2CCR          0x1e0
+#define I2CDR          0x1f0
+#define FPGACR         0x200
+#define IASELR1                0x210
+#define IASELR2                0x220
+#define IASELR3                0x230
+#define IASELR4                0x240
+#define IASELR5                0x250
+#define IASELR6                0x260
+#define IASELR7                0x270
+#define IASELR8                0x280
+#define IASELR9                0x290
+#define IASELR10       0x2a0
+#define IASELR11       0x2b0
+#define IASELR12       0x2c0
+#define IASELR13       0x2d0
+#define IASELR14       0x2e0
+#define IASELR15       0x2f0
+/* 0x300 reserved */
+#define IBSELR1                0x310
+#define IBSELR2                0x320
+#define IBSELR3                0x330
+#define IBSELR4                0x340
+#define IBSELR5                0x350
+#define IBSELR6                0x360
+#define IBSELR7                0x370
+#define IBSELR8                0x380
+#define IBSELR9                0x390
+#define IBSELR10       0x3a0
+#define IBSELR11       0x3b0
+#define IBSELR12       0x3c0
+#define IBSELR13       0x3d0
+#define IBSELR14       0x3e0
+#define IBSELR15       0x3f0
+#define USRACR         0x400
+#define BEEPR          0x410
+#define USRLCDR                0x420
+#define SMBCR          0x430
+#define SMBDR          0x440
+#define USBCR          0x450
+#define AMSR           0x460
+#define ACCR           0x470
+#define SDIFCR         0x480
+
+/* arch/sh/boards/mach-sdk7786/fpga.c */
+extern void __iomem *sdk7786_fpga_base;
+extern void sdk7786_fpga_init(void);
+
+#define SDK7786_FPGA_REGADDR(reg)      (sdk7786_fpga_base + (reg))
+
+/*
+ * A convenience wrapper from register offset to internal I2C address,
+ * when the FPGA is in I2C slave mode.
+ */
+#define SDK7786_FPGA_I2CADDR(reg)      ((reg) >> 3)
+
+static inline u16 fpga_read_reg(unsigned int reg)
+{
+       return ioread16(sdk7786_fpga_base + reg);
+}
+
+static inline void fpga_write_reg(u16 val, unsigned int reg)
+{
+       iowrite16(val, sdk7786_fpga_base + reg);
+}
+
+#endif /* __MACH_SDK7786_FPGA_H */