Merge commit '305b07680f' into orion/master
authorNicolas Pitre <nico@cam.org>
Mon, 16 Mar 2009 01:41:23 +0000 (21:41 -0400)
committerNicolas Pitre <nico@cam.org>
Mon, 16 Mar 2009 01:41:23 +0000 (21:41 -0400)
22 files changed:
arch/arm/configs/orion5x_defconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/common.h
arch/arm/mach-kirkwood/db88f6281-bp-setup.c
arch/arm/mach-kirkwood/include/mach/kirkwood.h
arch/arm/mach-kirkwood/mpp.c [new file with mode: 0644]
arch/arm/mach-kirkwood/mpp.h [new file with mode: 0644]
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mv78xx0/common.h
arch/arm/mach-mv78xx0/db78x00-bp-setup.c
arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
arch/arm/mach-mv78xx0/pcie.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/ts78xx-fpga.h [new file with mode: 0644]
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/plat-orion/gpio.c
arch/arm/plat-orion/include/plat/gpio.h
arch/arm/plat-orion/include/plat/mvsdio.h [new file with mode: 0644]

index a8ee698..020e6a8 100644 (file)
@@ -481,7 +481,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_PLATFORM=y
 # CONFIG_MTD_ALAUDA is not set
 CONFIG_MTD_NAND_ORION=y
 # CONFIG_MTD_ONENAND is not set
@@ -1177,7 +1177,7 @@ CONFIG_RTC_DRV_S35390A=y
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_M48T86=y
 # CONFIG_RTC_DRV_M48T59 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
index b96c55d..fdff35c 100644 (file)
@@ -1,4 +1,4 @@
-obj-y                          += common.o addr-map.o irq.o pcie.o
+obj-y                          += common.o addr-map.o irq.o pcie.o mpp.o
 
 obj-$(CONFIG_MACH_DB88F6281_BP)                += db88f6281-bp-setup.o
 obj-$(CONFIG_MACH_RD88F6192_NAS)       += rd88f6192-nas-setup.o
index b3404b7..9f01255 100644 (file)
@@ -24,6 +24,7 @@
 #include <mach/kirkwood.h>
 #include <plat/cache-feroceon-l2.h>
 #include <plat/ehci-orion.h>
+#include <plat/mvsdio.h>
 #include <plat/mv_xor.h>
 #include <plat/orion_nand.h>
 #include <plat/time.h>
@@ -254,7 +255,7 @@ static struct resource kirkwood_rtc_resource = {
        .flags  = IORESOURCE_MEM,
 };
 
-void __init kirkwood_rtc_init(void)
+static void __init kirkwood_rtc_init(void)
 {
        platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
 }
@@ -296,6 +297,50 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
 
 
 /*****************************************************************************
+ * SD/SDIO/MMC
+ ****************************************************************************/
+static struct resource mvsdio_resources[] = {
+       [0] = {
+               .start  = SDIO_PHYS_BASE,
+               .end    = SDIO_PHYS_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_KIRKWOOD_SDIO,
+               .end    = IRQ_KIRKWOOD_SDIO,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static u64 mvsdio_dmamask = 0xffffffffUL;
+
+static struct platform_device kirkwood_sdio = {
+       .name           = "mvsdio",
+       .id             = -1,
+       .dev            = {
+               .dma_mask = &mvsdio_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mvsdio_resources),
+       .resource       = mvsdio_resources,
+};
+
+void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
+{
+       u32 dev, rev;
+
+       kirkwood_pcie_id(&dev, &rev);
+       if (rev == 0)  /* catch all Kirkwood Z0's */
+               mvsdio_data->clock = 100000000;
+       else
+               mvsdio_data->clock = 200000000;
+       mvsdio_data->dram = &kirkwood_mbus_dram_info;
+       kirkwood_sdio.dev.platform_data = mvsdio_data;
+       platform_device_register(&kirkwood_sdio);
+}
+
+
+/*****************************************************************************
  * SPI
  ****************************************************************************/
 static struct orion_spi_info kirkwood_spi_plat_data = {
@@ -502,7 +547,7 @@ static struct platform_device kirkwood_xor01_channel = {
        },
 };
 
-void __init kirkwood_xor0_init(void)
+static void __init kirkwood_xor0_init(void)
 {
        platform_device_register(&kirkwood_xor0_shared);
 
@@ -600,7 +645,7 @@ static struct platform_device kirkwood_xor11_channel = {
        },
 };
 
-void __init kirkwood_xor1_init(void)
+static void __init kirkwood_xor1_init(void)
 {
        platform_device_register(&kirkwood_xor1_shared);
 
@@ -708,4 +753,9 @@ void __init kirkwood_init(void)
 #ifdef CONFIG_CACHE_FEROCEON_L2
        kirkwood_l2_init();
 #endif
+
+       /* internal devices that every board has */
+       kirkwood_rtc_init();
+       kirkwood_xor0_init();
+       kirkwood_xor1_init();
 }
index fe367c1..9e52826 100644 (file)
@@ -14,6 +14,7 @@
 struct dsa_platform_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
+struct mvsdio_platform_data;
 
 /*
  * Basic Kirkwood init functions used early by machine-setup.
@@ -33,13 +34,11 @@ void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
 void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
 void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
 void kirkwood_pcie_init(void);
-void kirkwood_rtc_init(void);
 void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
+void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
 void kirkwood_spi_init(void);
 void kirkwood_uart0_init(void);
 void kirkwood_uart1_init(void);
-void kirkwood_xor0_init(void);
-void kirkwood_xor1_init(void);
 
 extern struct sys_timer kirkwood_timer;
 
index a14c294..5505d58 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
+#include <plat/orion_nand.h>
+#include <plat/mvsdio.h>
 #include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition db88f6281_nand_parts[] = {
+       {
+               .name = "u-boot",
+               .offset = 0,
+               .size = SZ_1M
+       }, {
+               .name = "uImage",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size = SZ_4M
+       }, {
+               .name = "root",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size = MTDPART_SIZ_FULL
+       },
+};
+
+static struct resource db88f6281_nand_resource = {
+       .flags          = IORESOURCE_MEM,
+       .start          = KIRKWOOD_NAND_MEM_PHYS_BASE,
+       .end            = KIRKWOOD_NAND_MEM_PHYS_BASE +
+                         KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data db88f6281_nand_data = {
+       .parts          = db88f6281_nand_parts,
+       .nr_parts       = ARRAY_SIZE(db88f6281_nand_parts),
+       .cle            = 0,
+       .ale            = 1,
+       .width          = 8,
+       .chip_delay     = 25,
+};
+
+static struct platform_device db88f6281_nand_flash = {
+       .name           = "orion_nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &db88f6281_nand_data,
+       },
+       .resource       = &db88f6281_nand_resource,
+       .num_resources  = 1,
+};
 
 static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
@@ -32,18 +73,32 @@ static struct mv_sata_platform_data db88f6281_sata_data = {
        .n_ports        = 2,
 };
 
+static struct mvsdio_platform_data db88f6281_mvsdio_data = {
+       .gpio_write_protect     = 37,
+       .gpio_card_detect       = 38,
+};
+
+static unsigned int db88f6281_mpp_config[] __initdata = {
+       MPP37_GPIO,
+       MPP38_GPIO,
+       0
+};
+
 static void __init db88f6281_init(void)
 {
        /*
         * Basic setup. Needs to be called early.
         */
        kirkwood_init();
+       kirkwood_mpp_conf(db88f6281_mpp_config);
 
        kirkwood_ehci_init();
        kirkwood_ge00_init(&db88f6281_ge00_data);
-       kirkwood_rtc_init();
        kirkwood_sata_init(&db88f6281_sata_data);
        kirkwood_uart0_init();
+       kirkwood_sdio_init(&db88f6281_mvsdio_data);
+       
+       platform_device_register(&db88f6281_nand_flash);
 }
 
 static int __init db88f6281_pci_init(void)
index ada480c..d3db30f 100644 (file)
 
 #define SATA_PHYS_BASE         (KIRKWOOD_REGS_PHYS_BASE | 0x80000)
 
+#define SDIO_PHYS_BASE         (KIRKWOOD_REGS_PHYS_BASE | 0x90000)
+
 
 #endif
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
new file mode 100644 (file)
index 0000000..63c4493
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-kirkwood/mpp.c
+ *
+ * MPP functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init kirkwood_variant(void)
+{
+       u32 dev, rev;
+
+       kirkwood_pcie_id(&dev, &rev);
+
+       if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
+               return MPP_F6281_MASK;
+       if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
+               return MPP_F6192_MASK;
+       if (dev == MV88F6180_DEV_ID)
+               return MPP_F6180_MASK;
+
+       printk(KERN_ERR "MPP setup: unknown kirkwood variant "
+                       "(dev %#x rev %#x)\n", dev, rev);
+       return 0;
+}
+
+#define MPP_CTRL(i)    (DEV_BUS_VIRT_BASE + (i) * 4)
+#define MPP_NR_REGS    (1 + MPP_MAX/8)
+
+void __init kirkwood_mpp_conf(unsigned int *mpp_list)
+{
+       u32 mpp_ctrl[MPP_NR_REGS];
+       unsigned int variant_mask;
+       int i;
+
+       variant_mask = kirkwood_variant();
+       if (!variant_mask)
+               return;
+
+       printk(KERN_DEBUG "initial MPP regs:");
+       for (i = 0; i < MPP_NR_REGS; i++) {
+               mpp_ctrl[i] = readl(MPP_CTRL(i));
+               printk(" %08x", mpp_ctrl[i]);
+       }
+       printk("\n");
+
+       while (*mpp_list) {
+               unsigned int num = MPP_NUM(*mpp_list);
+               unsigned int sel = MPP_SEL(*mpp_list);
+               int shift, gpio_mode;
+
+               if (num > MPP_MAX) {
+                       printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP "
+                                       "number (%u)\n", num);
+                       continue;
+               }
+               if (!(*mpp_list & variant_mask)) {
+                       printk(KERN_WARNING
+                              "kirkwood_mpp_conf: requested MPP%u config "
+                              "unavailable on this hardware\n", num);
+                       continue;
+               }
+
+               shift = (num & 7) << 2;
+               mpp_ctrl[num / 8] &= ~(0xf << shift);
+               mpp_ctrl[num / 8] |= sel << shift;
+
+               gpio_mode = 0;
+               if (*mpp_list & MPP_INPUT_MASK)
+                       gpio_mode |= GPIO_INPUT_OK;
+               if (*mpp_list & MPP_OUTPUT_MASK)
+                       gpio_mode |= GPIO_OUTPUT_OK;
+               if (sel != 0)
+                       gpio_mode = 0;
+               orion_gpio_set_valid(num, gpio_mode);
+
+               mpp_list++;
+       }
+
+       printk(KERN_DEBUG "  final MPP regs:");
+       for (i = 0; i < MPP_NR_REGS; i++) {
+               writel(mpp_ctrl[i], MPP_CTRL(i));
+               printk(" %08x", mpp_ctrl[i]);
+       }
+       printk("\n");
+}
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h
new file mode 100644 (file)
index 0000000..45cccb7
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins
+ *
+ * Copyright 2009: Marvell Technology Group Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __KIRKWOOD_MPP_H
+#define __KIRKWOOD_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \
+       /* MPP number */                ((_num) & 0xff) | \
+       /* MPP select value */          (((_sel) & 0xf) << 8) | \
+       /* may be input signal */       ((!!(_in)) << 12) | \
+       /* may be output signal */      ((!!(_out)) << 13) | \
+       /* available on F6180 */        ((!!(_F6180)) << 14) | \
+       /* available on F6190 */        ((!!(_F6190)) << 15) | \
+       /* available on F6192 */        ((!!(_F6192)) << 16) | \
+       /* available on F6281 */        ((!!(_F6281)) << 17))
+
+#define MPP_NUM(x)     ((x) & 0xff)
+#define MPP_SEL(x)     (((x) >> 8) & 0xf)
+
+                               /*   num sel  i  o  6180 6190 6192 6281 */
+
+#define MPP_INPUT_MASK         MPP(  0, 0x0, 1, 0, 0,   0,   0,   0    )
+#define MPP_OUTPUT_MASK                MPP(  0, 0x0, 0, 1, 0,   0,   0,   0    )
+
+#define MPP_F6180_MASK         MPP(  0, 0x0, 0, 0, 1,   0,   0,   0    )
+#define MPP_F6190_MASK         MPP(  0, 0x0, 0, 0, 0,   1,   0,   0    )
+#define MPP_F6192_MASK         MPP(  0, 0x0, 0, 0, 0,   0,   1,   0    )
+#define MPP_F6281_MASK         MPP(  0, 0x0, 0, 0, 0,   0,   0,   1    )
+
+#define MPP0_GPIO              MPP(  0, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP0_NF_IO2            MPP(  0, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP0_SPI_SCn           MPP(  0, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP1_GPO               MPP(  1, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP1_NF_IO3            MPP(  1, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP1_SPI_MOSI          MPP(  1, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP2_GPO               MPP(  2, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP2_NF_IO4            MPP(  2, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP2_SPI_SCK           MPP(  2, 0x2, 0, 1, 1,   1,   1,   1    )
+
+#define MPP3_GPO               MPP(  3, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP3_NF_IO5            MPP(  3, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP3_SPI_MISO          MPP(  3, 0x2, 1, 0, 1,   1,   1,   1    )
+
+#define MPP4_GPIO              MPP(  4, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP4_NF_IO6            MPP(  4, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP4_UART0_RXD         MPP(  4, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP4_SATA1_ACTn                MPP(  4, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP4_PTP_CLK           MPP(  4, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP5_GPO               MPP(  5, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP5_NF_IO7            MPP(  5, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP5_UART0_TXD         MPP(  5, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP5_PTP_TRIG_GEN      MPP(  5, 0x4, 0, 1, 1,   1,   1,   1    )
+#define MPP5_SATA0_ACTn                MPP(  5, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP6_SYSRST_OUTn       MPP(  6, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP6_SPI_MOSI          MPP(  6, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP6_PTP_TRIG_GEN      MPP(  6, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP7_GPO               MPP(  7, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PEX_RST_OUTn      MPP(  7, 0x1, 0, 1, 1,   1,   1,   1    )
+#define MPP7_SPI_SCn           MPP(  7, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP7_PTP_TRIG_GEN      MPP(  7, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP8_GPIO              MPP(  8, 0x0, 1, 1, 1,    1,  1,   1    )
+#define MPP8_TW_SDA            MPP(  8, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP8_UART0_RTS         MPP(  8, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP8_UART1_RTS         MPP(  8, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP8_MII0_RXERR                MPP(  8, 0x4, 1, 0, 0,   1,   1,   1    )
+#define MPP8_SATA1_PRESENTn    MPP(  8, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP8_PTP_CLK           MPP(  8, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP8_MII0_COL          MPP(  8, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP9_GPIO              MPP(  9, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP9_TW_SCK            MPP(  9, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP9_UART0_CTS         MPP(  9, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP9_UART1_CTS         MPP(  9, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP9_SATA0_PRESENTn    MPP(  9, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP9_PTP_EVENT_REQ     MPP(  9, 0xc, 1, 0, 1,   1,   1,   1    )
+#define MPP9_MII0_CRS          MPP(  9, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP10_GPO              MPP( 10, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SPI_SCK          MPP( 10, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP10_UArt0_TXD                MPP( 10, 0X3, 0, 1, 1,   1,   1,   1    )
+#define MPP10_SATA1_ACTn       MPP( 10, 0x5, 0, 1, 0,   0,   1,   1    )
+#define MPP10_PTP_TRIG_GEN     MPP( 10, 0xc, 0, 1, 1,   1,   1,   1    )
+
+#define MPP11_GPIO             MPP( 11, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP11_SPI_MISO         MPP( 11, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP11_UArt0_RXD                MPP( 11, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_EVENT_REQ    MPP( 11, 0x4, 1, 0, 1,   1,   1,   1    )
+#define MPP11_PTP_TRIG_GEN     MPP( 11, 0xc, 0, 1, 1,   1,   1,   1    )
+#define MPP11_PTP_CLK          MPP( 11, 0xd, 1, 0, 1,   1,   1,   1    )
+#define MPP11_SATA0_ACTn       MPP( 11, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP12_GPO              MPP( 12, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP12_SD_CLK           MPP( 12, 0x1, 0, 1, 1,   1,   1,   1    )
+
+#define MPP13_GPIO             MPP( 13, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP13_SD_CMD           MPP( 13, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP13_UART1_TXD                MPP( 13, 0x3, 0, 1, 1,   1,   1,   1    )
+
+#define MPP14_GPIO             MPP( 14, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP14_SD_D0            MPP( 14, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP14_UART1_RXD                MPP( 14, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP14_SATA1_PRESENTn   MPP( 14, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP14_MII0_COL         MPP( 14, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP15_GPIO             MPP( 15, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP15_SD_D1            MPP( 15, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP15_UART0_RTS                MPP( 15, 0x2, 0, 1, 1,   1,   1,   1    )
+#define MPP15_UART1_TXD                MPP( 15, 0x3, 0, 1, 1,   1,   1,   1    )
+#define MPP15_SATA0_ACTn       MPP( 15, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP16_GPIO             MPP( 16, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP16_SD_D2            MPP( 16, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP16_UART0_CTS                MPP( 16, 0x2, 1, 0, 1,   1,   1,   1    )
+#define MPP16_UART1_RXD                MPP( 16, 0x3, 1, 0, 1,   1,   1,   1    )
+#define MPP16_SATA1_ACTn       MPP( 16, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP16_MII0_CRS         MPP( 16, 0xd, 1, 0, 1,   1,   1,   1    )
+
+#define MPP17_GPIO             MPP( 17, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SD_D3            MPP( 17, 0x1, 1, 1, 1,   1,   1,   1    )
+#define MPP17_SATA0_PRESENTn   MPP( 17, 0x4, 0, 1, 0,   1,   1,   1    )
+
+#define MPP18_GPO              MPP( 18, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP18_NF_IO0           MPP( 18, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP19_GPO              MPP( 19, 0x0, 0, 1, 1,   1,   1,   1    )
+#define MPP19_NF_IO1           MPP( 19, 0x1, 1, 1, 1,   1,   1,   1    )
+
+#define MPP20_GPIO             MPP( 20, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP20_TSMP0            MPP( 20, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP20_TDM_CH0_TX_QL    MPP( 20, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP20_GE1_0            MPP( 20, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP20_AUDIO_SPDIFI     MPP( 20, 0x4, 1, 0, 0,   0,   1,   1    )
+#define MPP20_SATA1_ACTn       MPP( 20, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP21_GPIO             MPP( 21, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP21_TSMP1            MPP( 21, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP21_TDM_CH0_RX_QL    MPP( 21, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP21_GE1_1            MPP( 21, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP21_AUDIO_SPDIFO     MPP( 21, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP21_SATA0_ACTn       MPP( 21, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP22_GPIO             MPP( 22, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP22_TSMP2            MPP( 22, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP22_TDM_CH2_TX_QL    MPP( 22, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP22_GE1_2            MPP( 22, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP22_AUDIO_SPDIFRMKCLK        MPP( 22, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP22_SATA1_PRESENTn   MPP( 22, 0x5, 0, 1, 0,   0,   1,   1    )
+
+#define MPP23_GPIO             MPP( 23, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP23_TSMP3            MPP( 23, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP23_TDM_CH2_RX_QL    MPP( 23, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP23_GE1_3            MPP( 23, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP23_AUDIO_I2SBCLK    MPP( 23, 0x4, 0, 1, 0,   0,   1,   1    )
+#define MPP23_SATA0_PRESENTn   MPP( 23, 0x5, 0, 1, 0,   1,   1,   1    )
+
+#define MPP24_GPIO             MPP( 24, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP24_TSMP4            MPP( 24, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP24_TDM_SPI_CS0      DEV( 24, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP24_GE1_4            MPP( 24, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP24_AUDIO_I2SDO      MPP( 24, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP25_GPIO             MPP( 25, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP25_TSMP5            MPP( 25, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP25_TDM_SPI_SCK      MPP( 25, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP25_GE1_5            MPP( 25, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP25_AUDIO_I2SLRCLK   MPP( 25, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP26_GPIO             MPP( 26, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP26_TSMP6            MPP( 26, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP26_TDM_SPI_MISO     MPP( 26, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP26_GE1_6            MPP( 26, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP26_AUDIO_I2SMCLK    MPP( 26, 0x4, 0, 1, 0,   0,   1,   1    )
+
+#define MPP27_GPIO             MPP( 27, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP27_TSMP7            MPP( 27, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP27_TDM_SPI_MOSI     MPP( 27, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP27_GE1_7            MPP( 27, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP27_AUDIO_I2SDI      MPP( 27, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP28_GPIO             MPP( 28, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP28_TSMP8            MPP( 28, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP28_TDM_CODEC_INTn   MPP( 28, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP28_GE1_8            MPP( 28, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP28_AUDIO_EXTCLK     MPP( 28, 0x4, 1, 0, 0,   0,   1,   1    )
+
+#define MPP29_GPIO             MPP( 29, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP29_TSMP9            MPP( 29, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP29_TDM_CODEC_RSTn   MPP( 29, 0x2, 0, 0, 0,   0,   1,   1    )
+#define MPP29_GE1_9            MPP( 29, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP30_GPIO             MPP( 30, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP30_TSMP10           MPP( 30, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP30_TDM_PCLK         MPP( 30, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP30_GE1_10           MPP( 30, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP31_GPIO             MPP( 31, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP31_TSMP11           MPP( 31, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP31_TDM_FS           MPP( 31, 0x2, 1, 1, 0,   0,   1,   1    )
+#define MPP31_GE1_11           MPP( 31, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP32_GPIO             MPP( 32, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP32_TSMP12           MPP( 32, 0x1, 1, 1, 0,   0,   1,   1    )
+#define MPP32_TDM_DRX          MPP( 32, 0x2, 1, 0, 0,   0,   1,   1    )
+#define MPP32_GE1_12           MPP( 32, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP33_GPIO             MPP( 33, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP33_TDM_DTX          MPP( 33, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP33_GE1_13           MPP( 33, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP34_GPIO             MPP( 34, 0x0, 1, 1, 0,   1,   1,   1    )
+#define MPP34_TDM_SPI_CS1      MPP( 34, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP34_GE1_14           MPP( 34, 0x3, 0, 0, 0,   1,   1,   1    )
+
+#define MPP35_GPIO             MPP( 35, 0x0, 1, 1, 1,   1,   1,   1    )
+#define MPP35_TDM_CH0_TX_QL    MPP( 35, 0x2, 0, 1, 0,   0,   1,   1    )
+#define MPP35_GE1_15           MPP( 35, 0x3, 0, 0, 0,   1,   1,   1    )
+#define MPP35_SATA0_ACTn       MPP( 35, 0x5, 0, 1, 0,   1,   1,   1    )
+#define MPP35_MII0_RXERR       MPP( 35, 0xc, 1, 0, 1,   1,   1,   1    )
+
+#define MPP36_GPIO             MPP( 36, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP36_TSMP0            MPP( 36, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP36_TDM_SPI_CS1      MPP( 36, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP36_AUDIO_SPDIFI     MPP( 36, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP37_GPIO             MPP( 37, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP37_TSMP1            MPP( 37, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP37_TDM_CH2_TX_QL    MPP( 37, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP37_AUDIO_SPDIFO     MPP( 37, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP38_GPIO             MPP( 38, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP38_TSMP2            MPP( 38, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP38_TDM_CH2_RX_QL    MPP( 38, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP38_AUDIO_SPDIFRMLCLK        MPP( 38, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP39_GPIO             MPP( 39, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP39_TSMP3            MPP( 39, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP39_TDM_SPI_CS0      MPP( 39, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP39_AUDIO_I2SBCLK    MPP( 39, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP40_GPIO             MPP( 40, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP40_TSMP4            MPP( 40, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP40_TDM_SPI_SCK      MPP( 40, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP40_AUDIO_I2SDO      MPP( 40, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP41_GPIO             MPP( 41, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP41_TSMP5            MPP( 41, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP41_TDM_SPI_MISO     MPP( 41, 0x2, 1, 0, 0,   0,   0,   1    )
+#define MPP41_AUDIO_I2SLRC     MPP( 41, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP42_GPIO             MPP( 42, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP42_TSMP6            MPP( 42, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP42_TDM_SPI_MOSI     MPP( 42, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP42_AUDIO_I2SMCLK    MPP( 42, 0x4, 0, 1, 1,   0,   0,   1    )
+
+#define MPP43_GPIO             MPP( 43, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP43_TSMP7            MPP( 43, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP43_TDM_CODEC_INTn   MPP( 43, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP43_AUDIO_I2SDI      MPP( 43, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP44_GPIO             MPP( 44, 0x0, 1, 1, 1,   0,   0,   1    )
+#define MPP44_TSMP8            MPP( 44, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP44_TDM_CODEC_RSTn   MPP( 44, 0x2, 0, 0, 0,   0,   0,   1    )
+#define MPP44_AUDIO_EXTCLK     MPP( 44, 0x4, 1, 0, 1,   0,   0,   1    )
+
+#define MPP45_GPIO             MPP( 45, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TSMP9            MPP( 45, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP45_TDM_PCLK         MPP( 45, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP46_GPIO             MPP( 46, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TSMP10           MPP( 46, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP46_TDM_FS           MPP( 46, 0x2, 1, 1, 0,   0,   0,   1    )
+
+#define MPP47_GPIO             MPP( 47, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TSMP11           MPP( 47, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP47_TDM_DRX          MPP( 47, 0x2, 1, 0, 0,   0,   0,   1    )
+
+#define MPP48_GPIO             MPP( 48, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TSMP12           MPP( 48, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP48_TDM_DTX          MPP( 48. 0x2, 0, 1, 0,   0,   0,   1    )
+
+#define MPP49_GPIO             MPP( 49, 0x0, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TSMP9            MPP( 49, 0x1, 1, 1, 0,   0,   0,   1    )
+#define MPP49_TDM_CH0_RX_QL    MPP( 49, 0x2, 0, 1, 0,   0,   0,   1    )
+#define MPP49_PTP_CLK          MPP( 49, 0x5, 1, 0, 0,   0,   0,   1    )
+
+#define MPP_MAX                        49
+
+void kirkwood_mpp_conf(unsigned int *mpp_list);
+
+#endif
index b1d1a87..2f0e4ef 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/spi/flash.h>
@@ -23,7 +20,6 @@
 #include <linux/spi/orion_spi.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
 #include "common.h"
 
@@ -61,14 +57,11 @@ static void __init rd88f6192_init(void)
 
        kirkwood_ehci_init();
        kirkwood_ge00_init(&rd88f6192_ge00_data);
-       kirkwood_rtc_init();
        kirkwood_sata_init(&rd88f6192_sata_data);
        spi_register_board_info(rd88F6192_spi_slave_info,
                                ARRAY_SIZE(rd88F6192_spi_slave_info));
        kirkwood_spi_init();
        kirkwood_uart0_init();
-       kirkwood_xor0_init();
-       kirkwood_xor1_init();
 }
 
 static int __init rd88f6192_pci_init(void)
index 9a0e905..c3deea5 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/pci.h>
 #include <linux/irq.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include <net/dsa.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
 #include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
 #include <plat/orion_nand.h>
 #include "common.h"
+#include "mpp.h"
 
 static struct mtd_partition rd88f6281_nand_parts[] = {
        {
@@ -91,6 +90,15 @@ static struct mv_sata_platform_data rd88f6281_sata_data = {
        .n_ports        = 2,
 };
 
+static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
+       .gpio_card_detect = 28,
+};
+
+static unsigned int rd88f6281_mpp_config[] __initdata = {
+       MPP28_GPIO,
+       0
+};
+
 static void __init rd88f6281_init(void)
 {
        u32 dev, rev;
@@ -99,6 +107,7 @@ static void __init rd88f6281_init(void)
         * Basic setup. Needs to be called early.
         */
        kirkwood_init();
+       kirkwood_mpp_conf(rd88f6281_mpp_config);
 
        kirkwood_ehci_init();
 
@@ -112,8 +121,8 @@ static void __init rd88f6281_init(void)
        }
        kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
 
-       kirkwood_rtc_init();
        kirkwood_sata_init(&rd88f6281_sata_data);
+       kirkwood_sdio_init(&rd88f6281_mvsdio_data);
        kirkwood_uart0_init();
 
        platform_device_register(&rd88f6281_nand_flash);
index b0e4e0d..a575daa 100644 (file)
@@ -14,7 +14,9 @@
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
+#include <linux/ethtool.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <mach/mv78xx0.h>
@@ -430,9 +432,22 @@ static struct platform_device mv78xx0_ge10 = {
 
 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 {
+       u32 dev, rev;
+
        eth_data->shared = &mv78xx0_ge10_shared;
        mv78xx0_ge10.dev.platform_data = eth_data;
 
+       /*
+        * On the Z0, ge10 and ge11 are internally connected back
+        * to back, and not brought out.
+        */
+       mv78xx0_pcie_id(&dev, &rev);
+       if (dev == MV78X00_Z0_DEV_ID) {
+               eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+               eth_data->speed = SPEED_1000;
+               eth_data->duplex = DUPLEX_FULL;
+       }
+
        platform_device_register(&mv78xx0_ge10_shared);
        platform_device_register(&mv78xx0_ge10);
 }
@@ -484,13 +499,101 @@ static struct platform_device mv78xx0_ge11 = {
 
 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
 {
+       u32 dev, rev;
+
        eth_data->shared = &mv78xx0_ge11_shared;
        mv78xx0_ge11.dev.platform_data = eth_data;
 
+       /*
+        * On the Z0, ge10 and ge11 are internally connected back
+        * to back, and not brought out.
+        */
+       mv78xx0_pcie_id(&dev, &rev);
+       if (dev == MV78X00_Z0_DEV_ID) {
+               eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+               eth_data->speed = SPEED_1000;
+               eth_data->duplex = DUPLEX_FULL;
+       }
+
        platform_device_register(&mv78xx0_ge11_shared);
        platform_device_register(&mv78xx0_ge11);
 }
 
+/*****************************************************************************
+ * I2C bus 0
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
+       .freq_m         = 8, /* assumes 166 MHz TCLK */
+       .freq_n         = 3,
+       .timeout        = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_0_resources[] = {
+       {
+               .name   = "i2c 0 base",
+               .start  = I2C_0_PHYS_BASE,
+               .end    = I2C_0_PHYS_BASE + 0x1f,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "i2c 0 irq",
+               .start  = IRQ_MV78XX0_I2C_0,
+               .end    = IRQ_MV78XX0_I2C_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+
+static struct platform_device mv78xx0_i2c_0 = {
+       .name           = MV64XXX_I2C_CTLR_NAME,
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(mv78xx0_i2c_0_resources),
+       .resource       = mv78xx0_i2c_0_resources,
+       .dev            = {
+               .platform_data  = &mv78xx0_i2c_0_pdata,
+       },
+};
+
+/*****************************************************************************
+ * I2C bus 1
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
+       .freq_m         = 8, /* assumes 166 MHz TCLK */
+       .freq_n         = 3,
+       .timeout        = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_1_resources[] = {
+       {
+               .name   = "i2c 1 base",
+               .start  = I2C_1_PHYS_BASE,
+               .end    = I2C_1_PHYS_BASE + 0x1f,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "i2c 1 irq",
+               .start  = IRQ_MV78XX0_I2C_1,
+               .end    = IRQ_MV78XX0_I2C_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+
+static struct platform_device mv78xx0_i2c_1 = {
+       .name           = MV64XXX_I2C_CTLR_NAME,
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(mv78xx0_i2c_1_resources),
+       .resource       = mv78xx0_i2c_1_resources,
+       .dev            = {
+               .platform_data  = &mv78xx0_i2c_1_pdata,
+       },
+};
+
+void __init mv78xx0_i2c_init(void)
+{
+       platform_device_register(&mv78xx0_i2c_0);
+       platform_device_register(&mv78xx0_i2c_1);
+}
 
 /*****************************************************************************
  * SATA
@@ -719,6 +822,32 @@ struct sys_timer mv78xx0_timer = {
 /*****************************************************************************
  * General
  ****************************************************************************/
+static char * __init mv78xx0_id(void)
+{
+       u32 dev, rev;
+
+       mv78xx0_pcie_id(&dev, &rev);
+
+       if (dev == MV78X00_Z0_DEV_ID) {
+               if (rev == MV78X00_REV_Z0)
+                       return "MV78X00-Z0";
+               else
+                       return "MV78X00-Rev-Unsupported";
+       } else if (dev == MV78100_DEV_ID) {
+               if (rev == MV78100_REV_A0)
+                       return "MV78100-A0";
+               else
+                       return "MV78100-Rev-Unsupported";
+       } else if (dev == MV78200_DEV_ID) {
+               if (rev == MV78100_REV_A0)
+                       return "MV78200-A0";
+               else
+                       return "MV78200-Rev-Unsupported";
+       } else {
+               return "Device-Unknown";
+       }
+}
+
 static int __init is_l2_writethrough(void)
 {
        return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
@@ -737,7 +866,8 @@ void __init mv78xx0_init(void)
        get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
        tclk = get_tclk();
 
-       printk(KERN_INFO "MV78xx0 core #%d, ", core_index);
+       printk(KERN_INFO "%s ", mv78xx0_id());
+       printk("core #%d, ", core_index);
        printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
        printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
        printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
index 78af5de..befc224 100644 (file)
@@ -29,6 +29,8 @@ void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
 void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
                                int maj, int min);
 
+void mv78xx0_pcie_id(u32 *dev, u32 *rev);
+
 void mv78xx0_ehci0_init(void);
 void mv78xx0_ehci1_init(void);
 void mv78xx0_ehci2_init(void);
@@ -42,6 +44,7 @@ void mv78xx0_uart0_init(void);
 void mv78xx0_uart1_init(void);
 void mv78xx0_uart2_init(void);
 void mv78xx0_uart3_init(void);
+void mv78xx0_i2c_init(void);
 
 extern struct sys_timer mv78xx0_timer;
 
index 2e285bb..efdabe0 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
+#include <linux/i2c.h>
 #include <mach/mv78xx0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -28,21 +29,22 @@ static struct mv643xx_eth_platform_data db78x00_ge01_data = {
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge10_data = {
-       .phy_addr       = MV643XX_ETH_PHY_NONE,
-       .speed          = SPEED_1000,
-       .duplex         = DUPLEX_FULL,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(10),
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge11_data = {
-       .phy_addr       = MV643XX_ETH_PHY_NONE,
-       .speed          = SPEED_1000,
-       .duplex         = DUPLEX_FULL,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(11),
 };
 
 static struct mv_sata_platform_data db78x00_sata_data = {
        .n_ports        = 2,
 };
 
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+       I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
 static void __init db78x00_init(void)
 {
        /*
@@ -64,6 +66,8 @@ static void __init db78x00_init(void)
                mv78xx0_sata_init(&db78x00_sata_data);
                mv78xx0_uart0_init();
                mv78xx0_uart2_init();
+               mv78xx0_i2c_init();
+               i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
        } else {
                mv78xx0_uart1_init();
                mv78xx0_uart3_init();
index e930ea5..582cffc 100644 (file)
 #define  TIMER_VIRT_BASE       (BRIDGE_VIRT_BASE | 0x0300)
 
 /*
+ * Supported devices and revisions.
+ */
+#define MV78X00_Z0_DEV_ID      0x6381
+#define MV78X00_REV_Z0         1
+
+#define MV78100_DEV_ID         0x7810
+#define MV78100_REV_A0         1
+
+#define MV78200_DEV_ID         0x7820
+#define MV78200_REV_A0         1
+
+/*
  * Register Map
  */
 #define DDR_VIRT_BASE          (MV78XX0_REGS_VIRT_BASE | 0x00000)
 #define DEV_BUS_VIRT_BASE      (MV78XX0_REGS_VIRT_BASE | 0x10000)
 #define  SAMPLE_AT_RESET_LOW   (DEV_BUS_VIRT_BASE | 0x0030)
 #define  SAMPLE_AT_RESET_HIGH  (DEV_BUS_VIRT_BASE | 0x0034)
+#define  I2C_0_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x1000)
+#define  I2C_1_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x1100)
 #define  UART0_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2000)
 #define  UART0_VIRT_BASE       (DEV_BUS_VIRT_BASE | 0x2000)
 #define  UART1_PHYS_BASE       (DEV_BUS_PHYS_BASE | 0x2100)
index aad3a7a..a560439 100644 (file)
@@ -33,6 +33,12 @@ static struct resource pcie_io_space;
 static struct resource pcie_mem_space;
 
 
+void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
+{
+       *dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE);
+       *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
+}
+
 static void __init mv78xx0_pcie_preinit(void)
 {
        int i;
index f59a8d0..2c7035d 100644 (file)
@@ -71,6 +71,7 @@ config MACH_WRT350N_V2
 
 config MACH_TS78XX
        bool "Technologic Systems TS-78xx"
+       select PM
        help
          Say 'Y' here if you want your kernel to support the
          Technologic Systems TS-78xx platform.
index 0722d65..b31ca4c 100644 (file)
@@ -76,7 +76,7 @@ static int __init dns323_dev_id(void)
 
 static int __init dns323_pci_init(void)
 {
-       /* The 5182 doesn't really use it's PCI bus, and initialising PCI
+       /* The 5182 doesn't really use its PCI bus, and initialising PCI
         * gets in the way of initialising the SATA controller.
         */
        if (machine_is_dns323() && dns323_dev_id() != MV88F5182_DEV_ID)
@@ -418,7 +418,7 @@ static void __init dns323_init(void)
        orion5x_i2c_init();
        orion5x_uart0_init();
 
-       /* The 5182 has it's SATA controller on-chip, and needs it's own little
+       /* The 5182 has its SATA controller on-chip, and needs its own little
         * init routine.
         */
        if (dns323_dev_id() == MV88F5182_DEV_ID)
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h
new file mode 100644 (file)
index 0000000..0a314dd
--- /dev/null
@@ -0,0 +1,29 @@
+#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
+
+/*
+ * get yer id's from http://ts78xx.digriz.org.uk/
+ * do *not* make up your own or 'borrow' any!
+ */
+enum fpga_ids {
+       /* Technologic Systems */
+       TS7800_REV_B2 = FPGAID(0x00b480, 0x02),
+       TS7800_REV_B3 = FPGAID(0x00b480, 0x03),
+};
+
+struct fpga_device {
+       unsigned                present:1;
+       unsigned                init:1;
+};
+
+struct fpga_devices {
+       /* Technologic Systems */
+       struct fpga_device      ts_rtc;
+       struct fpga_device      ts_nand;
+};
+
+struct ts78xx_fpga_data {
+       unsigned int            id;
+       int                     state;
+
+       struct fpga_devices     supports;
+};
index 1368e9f..f5191dd 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/sysfs.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
 #include <linux/ata_platform.h>
 #include <linux/m48t86.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <mach/orion5x.h>
 #include "common.h"
 #include "mpp.h"
+#include "ts78xx-fpga.h"
 
 /*****************************************************************************
  * TS-78xx Info
 #define TS78XX_FPGA_REGS_VIRT_BASE     0xff900000
 #define TS78XX_FPGA_REGS_SIZE          SZ_1M
 
-#define TS78XX_FPGA_REGS_SYSCON_ID     (TS78XX_FPGA_REGS_VIRT_BASE | 0x000)
-#define TS78XX_FPGA_REGS_SYSCON_LCDI   (TS78XX_FPGA_REGS_VIRT_BASE | 0x004)
-#define TS78XX_FPGA_REGS_SYSCON_LCDO   (TS78XX_FPGA_REGS_VIRT_BASE | 0x008)
-
-#define TS78XX_FPGA_REGS_RTC_CTRL      (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
-#define TS78XX_FPGA_REGS_RTC_DATA      (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
-
-/*
- * 512kB NOR flash Device
- */
-#define TS78XX_NOR_BOOT_BASE           0xff800000
-#define TS78XX_NOR_BOOT_SIZE           SZ_512K
+static struct ts78xx_fpga_data ts78xx_fpga = {
+       .id             = 0,
+       .state          = 1,
+/*     .supports       = ... - populated by ts78xx_fpga_supports() */
+};
 
 /*****************************************************************************
  * I/O Address Mapping
@@ -65,73 +61,47 @@ void __init ts78xx_map_io(void)
 }
 
 /*****************************************************************************
- * 512kB NOR Boot Flash - the chip is a M25P40
+ * Ethernet
  ****************************************************************************/
-static struct mtd_partition ts78xx_nor_boot_flash_resources[] = {
-       {
-               .name           = "ts-bootrom",
-               .offset         = 0,
-               /* only the first 256kB is used */
-               .size           = SZ_256K,
-               .mask_flags     = MTD_WRITEABLE,
-       },
-};
-
-static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
-       .width          = 1,
-       .parts          = ts78xx_nor_boot_flash_resources,
-       .nr_parts       = ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
-};
-
-static struct resource ts78xx_nor_boot_flash_resource = {
-       .flags          = IORESOURCE_MEM,
-       .start          = TS78XX_NOR_BOOT_BASE,
-       .end            = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
-};
-
-static struct platform_device ts78xx_nor_boot_flash = {
-       .name           = "physmap-flash",
-       .id             = -1,
-       .dev            = {
-               .platform_data  = &ts78xx_nor_boot_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &ts78xx_nor_boot_flash_resource,
+static struct mv643xx_eth_platform_data ts78xx_eth_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
 };
 
 /*****************************************************************************
- * Ethernet
+ * SATA
  ****************************************************************************/
-static struct mv643xx_eth_platform_data ts78xx_eth_data = {
-       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
+static struct mv_sata_platform_data ts78xx_sata_data = {
+       .n_ports        = 2,
 };
 
 /*****************************************************************************
  * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
  ****************************************************************************/
-#ifdef CONFIG_RTC_DRV_M48T86
-static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
+#define TS_RTC_CTRL    (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
+#define TS_RTC_DATA    (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+
+static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
 {
-       writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
-       return readb(TS78XX_FPGA_REGS_RTC_DATA);
+       writeb(addr, TS_RTC_CTRL);
+       return readb(TS_RTC_DATA);
 }
 
-static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
+static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
 {
-       writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
-       writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
+       writeb(addr, TS_RTC_CTRL);
+       writeb(value, TS_RTC_DATA);
 }
 
-static struct m48t86_ops ts78xx_rtc_ops = {
-       .readbyte       = ts78xx_rtc_readbyte,
-       .writebyte      = ts78xx_rtc_writebyte,
+static struct m48t86_ops ts78xx_ts_rtc_ops = {
+       .readbyte       = ts78xx_ts_rtc_readbyte,
+       .writebyte      = ts78xx_ts_rtc_writebyte,
 };
 
-static struct platform_device ts78xx_rtc_device = {
+static struct platform_device ts78xx_ts_rtc_device = {
        .name           = "rtc-m48t86",
        .id             = -1,
        .dev            = {
-               .platform_data  = &ts78xx_rtc_ops,
+               .platform_data  = &ts78xx_ts_rtc_ops,
        },
        .num_resources  = 0,
 };
@@ -146,59 +116,311 @@ static struct platform_device ts78xx_rtc_device = {
  * TODO: track down a guinea pig without an RTC to see if we can work out a
  *             better RTC detection routine
  */
-static int __init ts78xx_rtc_init(void)
+static int ts78xx_ts_rtc_load(void)
 {
+       int rc;
        unsigned char tmp_rtc0, tmp_rtc1;
 
-       tmp_rtc0 = ts78xx_rtc_readbyte(126);
-       tmp_rtc1 = ts78xx_rtc_readbyte(127);
-
-       ts78xx_rtc_writebyte(0x00, 126);
-       ts78xx_rtc_writebyte(0x55, 127);
-       if (ts78xx_rtc_readbyte(127) == 0x55) {
-               ts78xx_rtc_writebyte(0xaa, 127);
-               if (ts78xx_rtc_readbyte(127) == 0xaa
-                               && ts78xx_rtc_readbyte(126) == 0x00) {
-                       ts78xx_rtc_writebyte(tmp_rtc0, 126);
-                       ts78xx_rtc_writebyte(tmp_rtc1, 127);
-                       platform_device_register(&ts78xx_rtc_device);
-                       return 1;
+       tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
+       tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
+
+       ts78xx_ts_rtc_writebyte(0x00, 126);
+       ts78xx_ts_rtc_writebyte(0x55, 127);
+       if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
+               ts78xx_ts_rtc_writebyte(0xaa, 127);
+               if (ts78xx_ts_rtc_readbyte(127) == 0xaa
+                               && ts78xx_ts_rtc_readbyte(126) == 0x00) {
+                       ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
+                       ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
+
+                       if (ts78xx_fpga.supports.ts_rtc.init == 0) {
+                               rc = platform_device_register(&ts78xx_ts_rtc_device);
+                               if (!rc)
+                                       ts78xx_fpga.supports.ts_rtc.init = 1;
+                       } else
+                               rc = platform_device_add(&ts78xx_ts_rtc_device);
+
+                       return rc;
                }
        }
 
-       return 0;
+       return -ENODEV;
 };
-#else
-static int __init ts78xx_rtc_init(void)
+
+static void ts78xx_ts_rtc_unload(void)
 {
-       return 0;
+       platform_device_del(&ts78xx_ts_rtc_device);
 }
-#endif
 
 /*****************************************************************************
- * SATA
+ * NAND Flash
  ****************************************************************************/
-static struct mv_sata_platform_data ts78xx_sata_data = {
-       .n_ports        = 2,
+#define TS_NAND_CTRL   (TS78XX_FPGA_REGS_VIRT_BASE | 0x800)    /* VIRT */
+#define TS_NAND_DATA   (TS78XX_FPGA_REGS_PHYS_BASE | 0x804)    /* PHYS */
+
+/*
+ * hardware specific access to control-lines
+ *
+ * ctrl:
+ * NAND_NCE: bit 0 -> bit 2
+ * NAND_CLE: bit 1 -> bit 1
+ * NAND_ALE: bit 2 -> bit 0
+ */
+static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+                       unsigned int ctrl)
+{
+       struct nand_chip *this = mtd->priv;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               unsigned char bits;
+
+               bits = (ctrl & NAND_NCE) << 2;
+               bits |= ctrl & NAND_CLE;
+               bits |= (ctrl & NAND_ALE) >> 2;
+
+               writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
+       }
+
+       if (cmd != NAND_CMD_NONE)
+               writeb(cmd, this->IO_ADDR_W);
+}
+
+static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
+{
+       return readb(TS_NAND_CTRL) & 0x20;
+}
+
+const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ts78xx_ts_nand_parts[] = {
+       {
+               .name           = "mbr",
+               .offset         = 0,
+               .size           = SZ_128K,
+               .mask_flags     = MTD_WRITEABLE,
+       }, {
+               .name           = "kernel",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_4M,
+       }, {
+               .name           = "initrd",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_4M,
+       }, {
+               .name           = "rootfs",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       }
 };
 
+static struct platform_nand_data ts78xx_ts_nand_data = {
+       .chip   = {
+               .part_probe_types       = ts_nand_part_probes,
+               .partitions             = ts78xx_ts_nand_parts,
+               .nr_partitions          = ARRAY_SIZE(ts78xx_ts_nand_parts),
+               .chip_delay             = 15,
+               .options                = NAND_USE_FLASH_BBT,
+       },
+       .ctrl   = {
+               /*
+                * The HW ECC offloading functions, used to give about a 9%
+                * performance increase for 'dd if=/dev/mtdblockX' and 5% for
+                * nanddump.  This all however was changed by git commit
+                * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
+                * no performance advantage to be had so we no longer bother
+                */
+               .cmd_ctrl               = ts78xx_ts_nand_cmd_ctrl,
+               .dev_ready              = ts78xx_ts_nand_dev_ready,
+       },
+};
+
+static struct resource ts78xx_ts_nand_resources = {
+       .start          = TS_NAND_DATA,
+       .end            = TS_NAND_DATA + 4,
+       .flags          = IORESOURCE_IO,
+};
+
+static struct platform_device ts78xx_ts_nand_device = {
+       .name           = "gen_nand",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &ts78xx_ts_nand_data,
+       },
+       .resource       = &ts78xx_ts_nand_resources,
+       .num_resources  = 1,
+};
+
+static int ts78xx_ts_nand_load(void)
+{
+       int rc;
+
+       if (ts78xx_fpga.supports.ts_nand.init == 0) {
+               rc = platform_device_register(&ts78xx_ts_nand_device);
+               if (!rc)
+                       ts78xx_fpga.supports.ts_nand.init = 1;
+       } else
+               rc = platform_device_add(&ts78xx_ts_nand_device);
+
+       return rc;
+};
+
+static void ts78xx_ts_nand_unload(void)
+{
+       platform_device_del(&ts78xx_ts_nand_device);
+}
+
 /*****************************************************************************
- * print some information regarding the board
+ * FPGA 'hotplug' support code
  ****************************************************************************/
-static void __init ts78xx_print_board_id(void)
+static void ts78xx_fpga_devices_zero_init(void)
 {
-       unsigned int board_info;
-
-       board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID);
-       printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ",
-                               board_info & 0xff,
-                               (board_info >> 8) & 0xffffff);
-       board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI);
-       printk("JP1=%d, JP2=%d\n",
-                               (board_info >> 30) & 0x1,
-                               (board_info >> 31) & 0x1);
+       ts78xx_fpga.supports.ts_rtc.init = 0;
+       ts78xx_fpga.supports.ts_nand.init = 0;
+}
+
+static void ts78xx_fpga_supports(void)
+{
+       /* TODO: put this 'table' into ts78xx-fpga.h */
+       switch (ts78xx_fpga.id) {
+       case TS7800_REV_B2:
+       case TS7800_REV_B3:
+               ts78xx_fpga.supports.ts_rtc.present = 1;
+               ts78xx_fpga.supports.ts_nand.present = 1;
+               break;
+       default:
+               ts78xx_fpga.supports.ts_rtc.present = 0;
+               ts78xx_fpga.supports.ts_nand.present = 0;
+       }
+}
+
+static int ts78xx_fpga_load_devices(void)
+{
+       int tmp, ret = 0;
+
+       if (ts78xx_fpga.supports.ts_rtc.present == 1) {
+               tmp = ts78xx_ts_rtc_load();
+               if (tmp) {
+                       printk(KERN_INFO "TS-78xx: RTC not registered\n");
+                       ts78xx_fpga.supports.ts_rtc.present = 0;
+               }
+               ret |= tmp;
+       }
+       if (ts78xx_fpga.supports.ts_nand.present == 1) {
+               tmp = ts78xx_ts_nand_load();
+               if (tmp) {
+                       printk(KERN_INFO "TS-78xx: NAND not registered\n");
+                       ts78xx_fpga.supports.ts_nand.present = 0;
+               }
+               ret |= tmp;
+       }
+
+       return ret;
+}
+
+static int ts78xx_fpga_unload_devices(void)
+{
+       int ret = 0;
+
+       if (ts78xx_fpga.supports.ts_rtc.present == 1)
+               ts78xx_ts_rtc_unload();
+       if (ts78xx_fpga.supports.ts_nand.present == 1)
+               ts78xx_ts_nand_unload();
+
+       return ret;
+}
+
+static int ts78xx_fpga_load(void)
+{
+       ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+       printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+                       (ts78xx_fpga.id >> 8) & 0xffffff,
+                       ts78xx_fpga.id & 0xff);
+
+       ts78xx_fpga_supports();
+
+       if (ts78xx_fpga_load_devices()) {
+               ts78xx_fpga.state = -1;
+               return -EBUSY;
+       }
+
+       return 0;
 };
 
+static int ts78xx_fpga_unload(void)
+{
+       unsigned int fpga_id;
+
+       fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+       /*
+        * There does not seem to be a feasible way to block access to the GPIO
+        * pins from userspace (/dev/mem).  This if clause should hopefully warn
+        * those foolish enough not to follow 'policy' :)
+        *
+        * UrJTAG SVN since r1381 can be used to reprogram the FPGA
+        */
+       if (ts78xx_fpga.id != fpga_id) {
+               printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n"
+                       "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
+                       (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
+                       (fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
+               ts78xx_fpga.state = -1;
+               return -EBUSY;
+       }
+
+       if (ts78xx_fpga_unload_devices()) {
+               ts78xx_fpga.state = -1;
+               return -EBUSY;
+       }
+
+       return 0;
+};
+
+static ssize_t ts78xx_fpga_show(struct kobject *kobj,
+                       struct kobj_attribute *attr, char *buf)
+{
+       if (ts78xx_fpga.state < 0)
+               return sprintf(buf, "borked\n");
+
+       return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
+}
+
+static ssize_t ts78xx_fpga_store(struct kobject *kobj,
+                       struct kobj_attribute *attr, const char *buf, size_t n)
+{
+       int value, ret;
+
+       if (ts78xx_fpga.state < 0) {
+               printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+               return -EBUSY;
+       }
+
+       if (strncmp(buf, "online", sizeof("online") - 1) == 0)
+               value = 1;
+       else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
+               value = 0;
+       else {
+               printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+               return -EINVAL;
+       }
+
+       if (ts78xx_fpga.state == value)
+               return n;
+
+       ret = (ts78xx_fpga.state == 0)
+               ? ts78xx_fpga_load()
+               : ts78xx_fpga_unload();
+
+       if (!(ret < 0))
+               ts78xx_fpga.state = value;
+
+       return n;
+}
+
+static struct kobj_attribute ts78xx_fpga_attr =
+       __ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
+
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
@@ -223,30 +445,29 @@ static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
        { 17, MPP_UART },
        { 18, MPP_UART },
        { 19, MPP_UART },
+       /*
+        * MPP[20] PCI Clock Out 1
+        * MPP[21] PCI Clock Out 0
+        * MPP[22] Unused
+        * MPP[23] Unused
+        * MPP[24] Unused
+        * MPP[25] Unused
+        */
        { -1 },
 };
 
 static void __init ts78xx_init(void)
 {
+       int ret;
+
        /*
         * Setup basic Orion functions. Need to be called early.
         */
        orion5x_init();
 
-       ts78xx_print_board_id();
-
        orion5x_mpp_conf(ts78xx_mpp_modes);
 
        /*
-        * MPP[20] PCI Clock Out 1
-        * MPP[21] PCI Clock Out 0
-        * MPP[22] Unused
-        * MPP[23] Unused
-        * MPP[24] Unused
-        * MPP[25] Unused
-        */
-
-       /*
         * Configure peripherals.
         */
        orion5x_ehci0_init();
@@ -257,12 +478,12 @@ static void __init ts78xx_init(void)
        orion5x_uart1_init();
        orion5x_xor_init();
 
-       orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
-                                  TS78XX_NOR_BOOT_SIZE);
-       platform_device_register(&ts78xx_nor_boot_flash);
-
-       if (!ts78xx_rtc_init())
-               printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
+       /* FPGA init */
+       ts78xx_fpga_devices_zero_init();
+       ret = ts78xx_fpga_load();
+       ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
+       if (ret)
+               printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
 }
 
 MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
index 0d12c21..32eb9e3 100644 (file)
@@ -19,7 +19,8 @@
 
 static DEFINE_SPINLOCK(gpio_lock);
 static const char *gpio_label[GPIO_MAX];  /* non null for allocated GPIOs */
-static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
 
 static inline void __set_direction(unsigned pin, int input)
 {
@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin)
 {
        unsigned long flags;
 
-       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
                pr_debug("%s: invalid GPIO %d\n", __func__, pin);
                return -EINVAL;
        }
@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin, int value)
        unsigned long flags;
        u32 u;
 
-       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
                pr_debug("%s: invalid GPIO %d\n", __func__, pin);
                return -EINVAL;
        }
@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const char *label)
        unsigned long flags;
        int ret;
 
-       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+       if (pin >= GPIO_MAX ||
+           !(test_bit(pin, gpio_valid_input) ||
+             test_bit(pin, gpio_valid_output))) {
                pr_debug("%s: invalid GPIO %d\n", __func__, pin);
                return -EINVAL;
        }
@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request);
 
 void gpio_free(unsigned pin)
 {
-       if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+       if (pin >= GPIO_MAX ||
+           !(test_bit(pin, gpio_valid_input) ||
+             test_bit(pin, gpio_valid_output))) {
                pr_debug("%s: invalid GPIO %d\n", __func__, pin);
                return;
        }
@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsigned pin)
        __set_direction(pin, 0);
 }
 
-void __init orion_gpio_set_valid(unsigned pin, int valid)
+void __init orion_gpio_set_valid(unsigned pin, int mode)
 {
-       if (valid)
-               __set_bit(pin, gpio_valid);
+       if (mode == 1)
+               mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
+       if (mode & GPIO_INPUT_OK)
+               __set_bit(pin, gpio_valid_input);
        else
-               __clear_bit(pin, gpio_valid);
+               __clear_bit(pin, gpio_valid_input);
+       if (mode & GPIO_OUTPUT_OK)
+               __set_bit(pin, gpio_valid_output);
+       else
+               __clear_bit(pin, gpio_valid_output);
 }
 
 void orion_gpio_set_blink(unsigned pin, int blink)
index ec743e8..33f6c6a 100644 (file)
@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int value);
  * Orion-specific GPIO API extensions.
  */
 void orion_gpio_set_unused(unsigned pin);
-void orion_gpio_set_valid(unsigned pin, int valid);
 void orion_gpio_set_blink(unsigned pin, int blink);
 
+#define GPIO_BIDI_OK           (1 << 0)
+#define GPIO_INPUT_OK          (1 << 1)
+#define GPIO_OUTPUT_OK         (1 << 2)
+void orion_gpio_set_valid(unsigned pin, int mode);
+
 /*
  * GPIO interrupt handling.
  */
diff --git a/arch/arm/plat-orion/include/plat/mvsdio.h b/arch/arm/plat-orion/include/plat/mvsdio.h
new file mode 100644 (file)
index 0000000..14ca886
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-orion/include/plat/mvsdio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MVSDIO_H
+#define __MACH_MVSDIO_H
+
+#include <linux/mbus.h>
+
+struct mvsdio_platform_data {
+       struct mbus_dram_target_info *dram;
+       unsigned int clock;
+       int gpio_card_detect;
+       int gpio_write_protect;
+};
+
+#endif