]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Support for Toshiba's RBHMA4500 eval board for the TX4938.
authorRalf Baechle <ralf@linux-mips.org>
Mon, 25 Jul 2005 22:45:45 +0000 (22:45 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Sat, 29 Oct 2005 18:31:57 +0000 (19:31 +0100)
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
24 files changed:
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/pci/Makefile
arch/mips/pci/fixup-tx4938.c [new file with mode: 0644]
arch/mips/pci/ops-tx4938.c [new file with mode: 0644]
arch/mips/tx4938/Kconfig [new file with mode: 0644]
arch/mips/tx4938/common/Makefile [new file with mode: 0644]
arch/mips/tx4938/common/dbgio.c [new file with mode: 0644]
arch/mips/tx4938/common/irq.c [new file with mode: 0644]
arch/mips/tx4938/common/irq_handler.S [new file with mode: 0644]
arch/mips/tx4938/common/prom.c [new file with mode: 0644]
arch/mips/tx4938/common/rtc_rx5c348.c [new file with mode: 0644]
arch/mips/tx4938/common/setup.c [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/Makefile [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/irq.c [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/prom.c [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/setup.c [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c [new file with mode: 0644]
arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c [new file with mode: 0644]
include/asm-mips/bootinfo.h
include/asm-mips/tx4938/rbtx4938.h [new file with mode: 0644]
include/asm-mips/tx4938/spi.h [new file with mode: 0644]
include/asm-mips/tx4938/tx4938.h [new file with mode: 0644]
include/asm-mips/tx4938/tx4938_mips.h [new file with mode: 0644]

index 338c21f3efd33fd461d7e4ae7b09beb4b0bc92e2..1f53fe8a89f16cf56a52a44db486bb4dd992c36b 100644 (file)
@@ -695,6 +695,24 @@ config SOC_AU1500
 config SOC_AU1550
        bool "SOC_AU1550"
 
+config TOSHIBA_RBTX4938
+       bool "Support for Toshiba RBTX4938 board"
+       select HAVE_STD_PC_SERIAL_PORT
+       select DMA_NONCOHERENT
+       select GENERIC_ISA_DMA
+       select HAS_TXX9_SERIAL
+       select HW_HAS_PCI
+       select I8259
+       select ISA
+       select SWAP_IO_SPACE
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_BIG_ENDIAN
+       select TOSHIBA_BOARDS
+       help
+         This Toshiba board is based on the TX4938 processor. Say Y here to
+         support this machine type
+
 endchoice
 
 choice
@@ -837,6 +855,7 @@ config TOSHIBA_FPCIB0
 
 source "arch/mips/sgi-ip27/Kconfig"
 source "arch/mips/sibyte/Kconfig"
+source "arch/mips/tx4938/Kconfig"
 source "arch/mips/philips/pnx8550/common/Kconfig"
 
 config RWSEM_GENERIC_SPINLOCK
index 9c91e70d8ee252f41fc6e9f878406ef3cbd3f0b5..3dc2fb81fb2801f452076c8efbbe6d467ec481b9 100644 (file)
@@ -690,6 +690,13 @@ core-$(CONFIG_TOSHIBA_RBTX4927)    += arch/mips/tx4927/toshiba_rbtx4927/
 core-$(CONFIG_TOSHIBA_RBTX4927)        += arch/mips/tx4927/common/
 load-$(CONFIG_TOSHIBA_RBTX4927)        += 0xffffffff80020000
 
+#
+# Toshiba RBTX4938 board
+#
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/
+core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/
+load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000
+
 cflags-y                       += -Iinclude/asm-mips/mach-generic
 drivers-$(CONFIG_PCI)          += arch/mips/pci/
 
index ea8438b81fedd7b1d7aebfc6e54c8144f5a02a56..6956de95a7e858c0b106cfe5a296edebe48c68e2 100644 (file)
@@ -52,5 +52,6 @@ obj-$(CONFIG_TANBAC_TB0226)   += fixup-tb0226.o
 obj-$(CONFIG_TANBAC_TB0287)    += fixup-tb0287.o
 obj-$(CONFIG_TOSHIBA_JMR3927)  += fixup-jmr3927.o pci-jmr3927.o
 obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
+obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o
 obj-$(CONFIG_VICTOR_MPC30X)    += fixup-mpc30x.o
 obj-$(CONFIG_ZAO_CAPCELLA)     += fixup-capcella.o
diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c
new file mode 100644 (file)
index 0000000..f455520
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Toshiba rbtx4938 pci routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/tx4938/rbtx4938.h>
+
+extern struct pci_controller tx4938_pci_controller[];
+
+int pci_get_irq(struct pci_dev *dev, int pin)
+{
+       int irq = pin;
+       u8 slot = PCI_SLOT(dev->devfn);
+       struct pci_controller *controller = (struct pci_controller *)dev->sysdata;
+
+       if (controller == &tx4938_pci_controller[1]) {
+               /* TX4938 PCIC1 */
+               switch (slot) {
+               case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+                       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL)
+                               return RBTX4938_IRQ_IRC + TX4938_IR_ETH0;
+                       break;
+               case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+                       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL)
+                               return RBTX4938_IRQ_IRC + TX4938_IR_ETH1;
+                       break;
+               }
+               return 0;
+       }
+
+       /* IRQ rotation */
+       irq--;  /* 0-3 */
+       if (dev->bus->parent == NULL &&
+           (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) {
+               /* PCI CardSlot (IDSEL=A23) */
+               /* PCIA => PCIA (IDSEL=A23) */
+               irq = (irq + 0 + slot) % 4;
+       } else {
+               /* PCI Backplane */
+               irq = (irq + 33 - slot) % 4;
+       }
+       irq++;  /* 1-4 */
+
+       switch (irq) {
+       case 1:
+               irq = RBTX4938_IRQ_IOC_PCIA;
+               break;
+       case 2:
+               irq = RBTX4938_IRQ_IOC_PCIB;
+               break;
+       case 3:
+               irq = RBTX4938_IRQ_IOC_PCIC;
+               break;
+       case 4:
+               irq = RBTX4938_IRQ_IOC_PCID;
+               break;
+       }
+       return irq;
+}
+
+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       unsigned char irq = 0;
+
+       irq = pci_get_irq(dev, pin);
+
+       printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n",
+              dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn),
+              PCI_FUNC(dev->devfn), irq);
+
+       return irq;
+}
+
+/*
+ * Do platform specific device initialization at pci_enable_device() time
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       return 0;
+}
+
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
new file mode 100644 (file)
index 0000000..4c0dcfc
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Define the pci_ops for the Toshiba rbtx4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/* initialize in setup */
+struct resource pci_io_resource = {
+       .name   = "pci IO space",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_IO
+};
+
+/* initialize in setup */
+struct resource pci_mem_resource = {
+       .name   = "pci memory space",
+       .start  = 0,
+       .end    = 0,
+       .flags  = IORESOURCE_MEM
+};
+
+struct resource tx4938_pcic1_pci_io_resource = {
+               .name   = "PCI1 IO",
+               .start  = 0,
+               .end    = 0,
+               .flags  = IORESOURCE_IO
+};
+struct resource tx4938_pcic1_pci_mem_resource = {
+               .name   = "PCI1 mem",
+               .start  = 0,
+               .end    = 0,
+               .flags  = IORESOURCE_MEM
+};
+
+static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+{
+       if (bus > 0) {
+               /* Type 1 configuration */
+               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+                   ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
+       } else {
+               if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
+                       return -1;
+
+               /* Type 0 configuration */
+               tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+                   ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
+       }
+       /* clear M_ABORT and Disable M_ABORT Int. */
+       tx4938_pcicptr->pcistatus =
+           (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+           (PCI_STATUS_REC_MASTER_ABORT << 16);
+       tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+
+       return 0;
+}
+
+static int check_abort(int flags)
+{
+       int code = PCIBIOS_SUCCESSFUL;
+       /* wait write cycle completion before checking error status */
+       while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+                               ;
+       if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+               tx4938_pcicptr->pcistatus =
+                   (tx4938_pcicptr->
+                    pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
+                                               << 16);
+               tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+               code = PCIBIOS_DEVICE_NOT_FOUND;
+       }
+       return code;
+}
+
+static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
+                                       int where, int size, u32 * val)
+{
+       int flags, retval, dev, busno, func;
+
+       dev = PCI_SLOT(devfn);
+       func = PCI_FUNC(devfn);
+
+       /* check if the bus is top-level */
+       if (bus->parent != NULL)
+               busno = bus->number;
+       else {
+               busno = 0;
+       }
+
+       if (mkaddr(busno, devfn, where, &flags))
+               return -1;
+
+       switch (size) {
+       case 1:
+               *val = *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+                             ((where & 3) ^ 3));
+#else
+                             (where & 3));
+#endif
+               break;
+       case 2:
+               *val = *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+                               ((where & 3) ^ 2));
+#else
+                               (where & 3));
+#endif
+               break;
+       case 4:
+               *val = tx4938_pcicptr->g2pcfgdata;
+               break;
+       }
+
+       retval = check_abort(flags);
+       if (retval == PCIBIOS_DEVICE_NOT_FOUND)
+               *val = 0xffffffff;
+
+       return retval;
+}
+
+static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+                                               int size, u32 val)
+{
+       int flags, dev, busno, func;
+
+       busno = bus->number;
+       dev = PCI_SLOT(devfn);
+       func = PCI_FUNC(devfn);
+
+       /* check if the bus is top-level */
+       if (bus->parent != NULL) {
+               busno = bus->number;
+       } else {
+               busno = 0;
+       }
+
+       if (mkaddr(busno, devfn, where, &flags))
+               return -1;
+
+       switch (size) {
+       case 1:
+               *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+                         ((where & 3) ^ 3)) = val;
+#else
+                         (where & 3)) = val;
+#endif
+               break;
+       case 2:
+               *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata |
+#ifdef __BIG_ENDIAN
+                       ((where & 0x3) ^ 0x2)) = val;
+#else
+                       (where & 3)) = val;
+#endif
+               break;
+       case 4:
+               tx4938_pcicptr->g2pcfgdata = val;
+               break;
+       }
+
+       return check_abort(flags);
+}
+
+struct pci_ops tx4938_pci_ops = {
+       tx4938_pcibios_read_config,
+       tx4938_pcibios_write_config
+};
+
+struct pci_controller tx4938_pci_controller[] = {
+       /* h/w only supports devices 0x00 to 0x14 */
+       {
+               .pci_ops        = &tx4938_pci_ops,
+               .io_resource    = &pci_io_resource,
+               .mem_resource   = &pci_mem_resource,
+       },
+       /* h/w only supports devices 0x00 to 0x14 */
+       {
+               .pci_ops        = &tx4938_pci_ops,
+               .io_resource    = &tx4938_pcic1_pci_io_resource,
+               .mem_resource   = &tx4938_pcic1_pci_mem_resource,
+        }
+};
diff --git a/arch/mips/tx4938/Kconfig b/arch/mips/tx4938/Kconfig
new file mode 100644 (file)
index 0000000..d90e9cd
--- /dev/null
@@ -0,0 +1,24 @@
+if TOSHIBA_RBTX4938
+
+comment "Multiplex Pin Select"
+choice
+       prompt "PIO[58:61]"
+       default TOSHIBA_RBTX4938_MPLEX_PIO58_61
+
+config TOSHIBA_RBTX4938_MPLEX_PIO58_61
+       bool "PIO"
+config TOSHIBA_RBTX4938_MPLEX_NAND
+       bool "NAND"
+config TOSHIBA_RBTX4938_MPLEX_ATA
+       bool "ATA"
+
+endchoice
+
+config TX4938_NAND_BOOT
+       depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
+       bool "NAND Boot Support (EXPERIMENTAL)"
+       help
+         This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
+         Select this option if you need to use NAND boot.
+
+endif
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
new file mode 100644 (file)
index 0000000..74c95c5
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y  += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o
+obj-$(CONFIG_KGDB) += dbgio.o
+
diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c
new file mode 100644 (file)
index 0000000..bea59ff
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/mips/tx4938/common/dbgio.c
+ *
+ * kgdb interface for gdb
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
+ */
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/tx4938_mips.h>
+
+extern u8 txx9_sio_kdbg_rd(void);
+extern int txx9_sio_kdbg_wr( u8 ch );
+
+u8 getDebugChar(void)
+{
+       return (txx9_sio_kdbg_rd());
+}
+
+int putDebugChar(u8 byte)
+{
+       return (txx9_sio_kdbg_wr(byte));
+}
+
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
new file mode 100644 (file)
index 0000000..4f90d7f
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * linux/arch/mps/tx4938/common/irq.c
+ *
+ * Common tx4938 irq handler
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/tx4938/rbtx4938.h>
+
+/**********************************************************************************/
+/* Forwad definitions for all pic's                                               */
+/**********************************************************************************/
+
+static unsigned int tx4938_irq_cp0_startup(unsigned int irq);
+static void tx4938_irq_cp0_shutdown(unsigned int irq);
+static void tx4938_irq_cp0_enable(unsigned int irq);
+static void tx4938_irq_cp0_disable(unsigned int irq);
+static void tx4938_irq_cp0_mask_and_ack(unsigned int irq);
+static void tx4938_irq_cp0_end(unsigned int irq);
+
+static unsigned int tx4938_irq_pic_startup(unsigned int irq);
+static void tx4938_irq_pic_shutdown(unsigned int irq);
+static void tx4938_irq_pic_enable(unsigned int irq);
+static void tx4938_irq_pic_disable(unsigned int irq);
+static void tx4938_irq_pic_mask_and_ack(unsigned int irq);
+static void tx4938_irq_pic_end(unsigned int irq);
+
+/**********************************************************************************/
+/* Kernel structs for all pic's                                                   */
+/**********************************************************************************/
+DEFINE_SPINLOCK(tx4938_cp0_lock);
+DEFINE_SPINLOCK(tx4938_pic_lock);
+
+#define TX4938_CP0_NAME "TX4938-CP0"
+static struct hw_interrupt_type tx4938_irq_cp0_type = {
+       .typename = TX4938_CP0_NAME,
+       .startup = tx4938_irq_cp0_startup,
+       .shutdown = tx4938_irq_cp0_shutdown,
+       .enable = tx4938_irq_cp0_enable,
+       .disable = tx4938_irq_cp0_disable,
+       .ack = tx4938_irq_cp0_mask_and_ack,
+       .end = tx4938_irq_cp0_end,
+       .set_affinity = NULL
+};
+
+#define TX4938_PIC_NAME "TX4938-PIC"
+static struct hw_interrupt_type tx4938_irq_pic_type = {
+       .typename = TX4938_PIC_NAME,
+       .startup = tx4938_irq_pic_startup,
+       .shutdown = tx4938_irq_pic_shutdown,
+       .enable = tx4938_irq_pic_enable,
+       .disable = tx4938_irq_pic_disable,
+       .ack = tx4938_irq_pic_mask_and_ack,
+       .end = tx4938_irq_pic_end,
+       .set_affinity = NULL
+};
+
+static struct irqaction tx4938_irq_pic_action = {
+       .handler = no_action,
+       .flags = 0,
+       .mask = CPU_MASK_NONE,
+       .name = TX4938_PIC_NAME
+};
+
+/**********************************************************************************/
+/* Functions for cp0                                                              */
+/**********************************************************************************/
+
+#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) )
+
+static void __init
+tx4938_irq_cp0_init(void)
+{
+       int i;
+
+       for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = 0;
+               irq_desc[i].depth = 1;
+               irq_desc[i].handler = &tx4938_irq_cp0_type;
+       }
+
+       return;
+}
+
+static unsigned int
+tx4938_irq_cp0_startup(unsigned int irq)
+{
+       tx4938_irq_cp0_enable(irq);
+
+       return (0);
+}
+
+static void
+tx4938_irq_cp0_shutdown(unsigned int irq)
+{
+       tx4938_irq_cp0_disable(irq);
+}
+
+static void
+tx4938_irq_cp0_enable(unsigned int irq)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+       set_c0_status(tx4938_irq_cp0_mask(irq));
+
+       spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+}
+
+static void
+tx4938_irq_cp0_disable(unsigned int irq)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx4938_cp0_lock, flags);
+
+       clear_c0_status(tx4938_irq_cp0_mask(irq));
+
+       spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
+
+       return;
+}
+
+static void
+tx4938_irq_cp0_mask_and_ack(unsigned int irq)
+{
+       tx4938_irq_cp0_disable(irq);
+
+       return;
+}
+
+static void
+tx4938_irq_cp0_end(unsigned int irq)
+{
+       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+               tx4938_irq_cp0_enable(irq);
+       }
+
+       return;
+}
+
+/**********************************************************************************/
+/* Functions for pic                                                              */
+/**********************************************************************************/
+
+u32
+tx4938_irq_pic_addr(int irq)
+{
+       /* MVMCP -- need to formulize this */
+       irq -= TX4938_IRQ_PIC_BEG;
+
+       switch (irq) {
+       case 17:
+       case 16:
+       case 1:
+       case 0:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL0));
+               }
+       case 19:
+       case 18:
+       case 3:
+       case 2:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL1));
+               }
+       case 21:
+       case 20:
+       case 5:
+       case 4:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL2));
+               }
+       case 23:
+       case 22:
+       case 7:
+       case 6:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL3));
+               }
+       case 25:
+       case 24:
+       case 9:
+       case 8:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL4));
+               }
+       case 27:
+       case 26:
+       case 11:
+       case 10:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL5));
+               }
+       case 29:
+       case 28:
+       case 13:
+       case 12:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL6));
+               }
+       case 31:
+       case 30:
+       case 15:
+       case 14:{
+                       return (TX4938_MKA(TX4938_IRC_IRLVL7));
+               }
+       }
+
+       return (0);
+}
+
+u32
+tx4938_irq_pic_mask(int irq)
+{
+       /* MVMCP -- need to formulize this */
+       irq -= TX4938_IRQ_PIC_BEG;
+
+       switch (irq) {
+       case 31:
+       case 29:
+       case 27:
+       case 25:
+       case 23:
+       case 21:
+       case 19:
+       case 17:{
+                       return (0x07000000);
+               }
+       case 30:
+       case 28:
+       case 26:
+       case 24:
+       case 22:
+       case 20:
+       case 18:
+       case 16:{
+                       return (0x00070000);
+               }
+       case 15:
+       case 13:
+       case 11:
+       case 9:
+       case 7:
+       case 5:
+       case 3:
+       case 1:{
+                       return (0x00000700);
+               }
+       case 14:
+       case 12:
+       case 10:
+       case 8:
+       case 6:
+       case 4:
+       case 2:
+       case 0:{
+                       return (0x00000007);
+               }
+       }
+       return (0x00000000);
+}
+
+static void
+tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits)
+{
+       unsigned long val = 0;
+
+       val = TX4938_RD(pic_reg);
+       val &= (~clr_bits);
+       val |= (set_bits);
+       TX4938_WR(pic_reg, val);
+       mmiowb();
+       TX4938_RD(pic_reg);
+
+       return;
+}
+
+static void __init
+tx4938_irq_pic_init(void)
+{
+       unsigned long flags;
+       int i;
+
+       for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = 0;
+               irq_desc[i].depth = 2;
+               irq_desc[i].handler = &tx4938_irq_pic_type;
+       }
+
+       setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action);
+
+       spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+       TX4938_WR(0xff1ff640, 0x6);     /* irq level mask -- only accept hightest */
+       TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1);     /* irq enable */
+
+       spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+       return;
+}
+
+static unsigned int
+tx4938_irq_pic_startup(unsigned int irq)
+{
+       tx4938_irq_pic_enable(irq);
+
+       return (0);
+}
+
+static void
+tx4938_irq_pic_shutdown(unsigned int irq)
+{
+       tx4938_irq_pic_disable(irq);
+
+       return;
+}
+
+static void
+tx4938_irq_pic_enable(unsigned int irq)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+       tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0,
+                             tx4938_irq_pic_mask(irq));
+
+       spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+       return;
+}
+
+static void
+tx4938_irq_pic_disable(unsigned int irq)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx4938_pic_lock, flags);
+
+       tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq),
+                             tx4938_irq_pic_mask(irq), 0);
+
+       spin_unlock_irqrestore(&tx4938_pic_lock, flags);
+
+       return;
+}
+
+static void
+tx4938_irq_pic_mask_and_ack(unsigned int irq)
+{
+       tx4938_irq_pic_disable(irq);
+
+       return;
+}
+
+static void
+tx4938_irq_pic_end(unsigned int irq)
+{
+       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+               tx4938_irq_pic_enable(irq);
+       }
+
+       return;
+}
+
+/**********************************************************************************/
+/* Main init functions                                                            */
+/**********************************************************************************/
+
+void __init
+tx4938_irq_init(void)
+{
+       extern asmlinkage void tx4938_irq_handler(void);
+
+       tx4938_irq_cp0_init();
+       tx4938_irq_pic_init();
+       set_except_vector(0, tx4938_irq_handler);
+
+       return;
+}
+
+int
+tx4938_irq_nested(void)
+{
+       int sw_irq = 0;
+       u32 level2;
+
+       level2 = TX4938_RD(0xff1ff6a0);
+       if ((level2 & 0x10000) == 0) {
+               level2 &= 0x1f;
+               sw_irq = TX4938_IRQ_PIC_BEG + level2;
+               if (sw_irq == 26) {
+                       {
+                               extern int toshiba_rbtx4938_irq_nested(int sw_irq);
+                               sw_irq = toshiba_rbtx4938_irq_nested(sw_irq);
+                       }
+               }
+       }
+
+       wbflush();
+       return (sw_irq);
+}
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
new file mode 100644 (file)
index 0000000..1b2f72b
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * linux/arch/mips/tx4938/common/handler.S
+ *
+ * Primary interrupt handler for tx4938 based systems
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/tx4938/rbtx4938.h>
+
+
+               .align  5
+               NESTED(tx4938_irq_handler, PT_SIZE, sp)
+               SAVE_ALL
+               CLI
+               .set    at
+
+               mfc0    t0, CP0_CAUSE
+               mfc0    t1, CP0_STATUS
+               and     t0, t1
+
+               andi    t1, t0, STATUSF_IP7     /* cpu timer */
+               bnez    t1, ll_ip7
+
+               /* IP6..IP3 multiplexed -- do not use */
+
+               andi    t1, t0, STATUSF_IP2     /* tx4938 pic */
+               bnez    t1, ll_ip2
+
+               andi    t1, t0, STATUSF_IP1     /* user line 1 */
+               bnez    t1, ll_ip1
+
+               andi    t1, t0, STATUSF_IP0     /* user line 0 */
+               bnez    t1, ll_ip0
+
+               .set    reorder
+
+               nop
+               END(tx4938_irq_handler)
+
+               .align  5
+
+
+ll_ip7:
+               li      a0, TX4938_IRQ_CPU_TIMER
+               move    a1, sp
+               jal     do_IRQ
+               j       ret_from_irq
+
+
+ll_ip2:
+               jal     tx4938_irq_nested
+               nop
+               beqz    v0, goto_spurious_interrupt
+               nop
+               move    a0, v0
+               move    a1, sp
+               jal     do_IRQ
+               j       ret_from_irq
+
+goto_spurious_interrupt:
+               j       ret_from_irq
+
+ll_ip1:
+               li      a0, TX4938_IRQ_USER1
+               move    a1, sp
+               jal     do_IRQ
+               j       ret_from_irq
+
+ll_ip0:
+               li      a0, TX4938_IRQ_USER0
+               move    a1, sp
+               jal     do_IRQ
+               j       ret_from_irq
diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c
new file mode 100644 (file)
index 0000000..3189a65
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * linux/arch/mips/tx4938/common/prom.c
+ *
+ * common tx4938 memory interface
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+static unsigned int __init
+tx4938_process_sdccr(u64 * addr)
+{
+       u64 val;
+       unsigned int sdccr_ce;
+       unsigned int sdccr_rs;
+       unsigned int sdccr_cs;
+       unsigned int sdccr_mw;
+       unsigned int rs = 0;
+       unsigned int cs = 0;
+       unsigned int mw = 0;
+       unsigned int bc = 4;
+       unsigned int msize = 0;
+
+       val = (*((vu64 *) (addr)));
+
+       /* MVMCP -- need #defs for these bits masks */
+       sdccr_ce = ((val & (1 << 10)) >> 10);
+       sdccr_rs = ((val & (3 << 5)) >> 5);
+       sdccr_cs = ((val & (7 << 2)) >> 2);
+       sdccr_mw = ((val & (1 << 0)) >> 0);
+
+       if (sdccr_ce) {
+               switch (sdccr_rs) {
+               case 0:{
+                               rs = 2048;
+                               break;
+                       }
+               case 1:{
+                               rs = 4096;
+                               break;
+                       }
+               case 2:{
+                               rs = 8192;
+                               break;
+                       }
+               default:{
+                               rs = 0;
+                               break;
+                       }
+               }
+               switch (sdccr_cs) {
+               case 0:{
+                               cs = 256;
+                               break;
+                       }
+               case 1:{
+                               cs = 512;
+                               break;
+                       }
+               case 2:{
+                               cs = 1024;
+                               break;
+                       }
+               case 3:{
+                               cs = 2048;
+                               break;
+                       }
+               case 4:{
+                               cs = 4096;
+                               break;
+                       }
+               default:{
+                               cs = 0;
+                               break;
+                       }
+               }
+               switch (sdccr_mw) {
+               case 0:{
+                               mw = 8;
+                               break;
+                       }       /* 8 bytes = 64 bits */
+               case 1:{
+                               mw = 4;
+                               break;
+                       }       /* 4 bytes = 32 bits */
+               }
+       }
+
+       /*           bytes per chip    MB per chip          bank count */
+       msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
+
+       /* MVMCP -- bc hard coded to 4 from table 9.3.1     */
+       /*          boad supports bc=2 but no way to detect */
+
+       return (msize);
+}
+
+unsigned int __init
+tx4938_get_mem_size(void)
+{
+       unsigned int c0;
+       unsigned int c1;
+       unsigned int c2;
+       unsigned int c3;
+       unsigned int total;
+
+       /* MVMCP -- need #defs for these registers */
+       c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
+       c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
+       c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
+       c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
+       total = c0 + c1 + c2 + c3;
+
+       return (total);
+}
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
new file mode 100644 (file)
index 0000000..d249edb
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * RTC routines for RICOH Rx5C348 SPI chip.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/rtc.h>
+#include <linux/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/spi.h>
+
+#define        EPOCH           2000
+
+/* registers */
+#define Rx5C348_REG_SECOND     0
+#define Rx5C348_REG_MINUTE     1
+#define Rx5C348_REG_HOUR       2
+#define Rx5C348_REG_WEEK       3
+#define Rx5C348_REG_DAY        4
+#define Rx5C348_REG_MONTH      5
+#define Rx5C348_REG_YEAR       6
+#define Rx5C348_REG_ADJUST     7
+#define Rx5C348_REG_ALARM_W_MIN        8
+#define Rx5C348_REG_ALARM_W_HOUR       9
+#define Rx5C348_REG_ALARM_W_WEEK       10
+#define Rx5C348_REG_ALARM_D_MIN        11
+#define Rx5C348_REG_ALARM_D_HOUR       12
+#define Rx5C348_REG_CTL1       14
+#define Rx5C348_REG_CTL2       15
+
+/* register bits */
+#define Rx5C348_BIT_PM 0x20    /* REG_HOUR */
+#define Rx5C348_BIT_Y2K        0x80    /* REG_MONTH */
+#define Rx5C348_BIT_24H        0x20    /* REG_CTL1 */
+#define Rx5C348_BIT_XSTP       0x10    /* REG_CTL2 */
+
+/* commands */
+#define Rx5C348_CMD_W(addr)    (((addr) << 4) | 0x08)  /* single write */
+#define Rx5C348_CMD_R(addr)    (((addr) << 4) | 0x0c)  /* single read */
+#define Rx5C348_CMD_MW(addr)   (((addr) << 4) | 0x00)  /* burst write */
+#define Rx5C348_CMD_MR(addr)   (((addr) << 4) | 0x04)  /* burst read */
+
+static struct spi_dev_desc srtc_dev_desc = {
+       .baud           = 1000000,      /* 1.0Mbps @ Vdd 2.0V */
+       .tcss           = 31,
+       .tcsh           = 1,
+       .tcsr           = 62,
+       /* 31us for Tcss (62us for Tcsr) is required for carry operation) */
+       .byteorder      = 1,            /* MSB-First */
+       .polarity       = 0,            /* High-Active */
+       .phase          = 1,            /* Shift-Then-Sample */
+
+};
+static int srtc_chipid;
+static int srtc_24h;
+
+static inline int
+spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
+{
+       unsigned char *inbufs[1], *outbufs[1];
+       unsigned int incounts[2], outcounts[2];
+       inbufs[0] = inbuf;
+       incounts[0] = count;
+       incounts[1] = 0;
+       outbufs[0] = outbuf;
+       outcounts[0] = count;
+       outcounts[1] = 0;
+       return txx9_spi_io(srtc_chipid, &srtc_dev_desc,
+                          inbufs, incounts, outbufs, outcounts, 0);
+}
+
+/*
+ * Conversion between binary and BCD.
+ */
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
+#endif
+
+/* RTC-dependent code for time.c */
+
+static int
+rtc_rx5c348_set_time(unsigned long t)
+{
+       unsigned char inbuf[8];
+       struct rtc_time tm;
+       u8 year, month, day, hour, minute, second, century;
+
+       /* convert */
+       to_tm(t, &tm);
+
+       year = tm.tm_year % 100;
+       month = tm.tm_mon+1;    /* tm_mon starts from 0 to 11 */
+       day = tm.tm_mday;
+       hour = tm.tm_hour;
+       minute = tm.tm_min;
+       second = tm.tm_sec;
+       century = tm.tm_year / 100;
+
+       inbuf[0] = Rx5C348_CMD_MW(Rx5C348_REG_SECOND);
+       BIN_TO_BCD(second);
+       inbuf[1] = second;
+       BIN_TO_BCD(minute);
+       inbuf[2] = minute;
+
+       if (srtc_24h) {
+               BIN_TO_BCD(hour);
+               inbuf[3] = hour;
+       } else {
+               /* hour 0 is AM12, noon is PM12 */
+               inbuf[3] = 0;
+               if (hour >= 12)
+                       inbuf[3] = Rx5C348_BIT_PM;
+               hour = (hour + 11) % 12 + 1;
+               BIN_TO_BCD(hour);
+               inbuf[3] |= hour;
+       }
+       inbuf[4] = 0;   /* ignore week */
+       BIN_TO_BCD(day);
+       inbuf[5] = day;
+       BIN_TO_BCD(month);
+       inbuf[6] = month;
+       if (century >= 20)
+               inbuf[6] |= Rx5C348_BIT_Y2K;
+       BIN_TO_BCD(year);
+       inbuf[7] = year;
+       /* write in one transfer to avoid data inconsistency */
+       return spi_rtc_io(inbuf, NULL, 8);
+}
+
+static unsigned long
+rtc_rx5c348_get_time(void)
+{
+       unsigned char inbuf[8], outbuf[8];
+       unsigned int year, month, day, hour, minute, second;
+
+       inbuf[0] = Rx5C348_CMD_MR(Rx5C348_REG_SECOND);
+       memset(inbuf + 1, 0, 7);
+       /* read in one transfer to avoid data inconsistency */
+       if (spi_rtc_io(inbuf, outbuf, 8))
+               return 0;
+       second = outbuf[1];
+       BCD_TO_BIN(second);
+       minute = outbuf[2];
+       BCD_TO_BIN(minute);
+       if (srtc_24h) {
+               hour = outbuf[3];
+               BCD_TO_BIN(hour);
+       } else {
+               hour = outbuf[3] & ~Rx5C348_BIT_PM;
+               BCD_TO_BIN(hour);
+               hour %= 12;
+               if (outbuf[3] & Rx5C348_BIT_PM)
+                       hour += 12;
+       }
+       day = outbuf[5];
+       BCD_TO_BIN(day);
+       month = outbuf[6] & ~Rx5C348_BIT_Y2K;
+       BCD_TO_BIN(month);
+       year = outbuf[7];
+       BCD_TO_BIN(year);
+       year += EPOCH;
+
+       return mktime(year, month, day, hour, minute, second);
+}
+
+void __init
+rtc_rx5c348_init(int chipid)
+{
+       unsigned char inbuf[2], outbuf[2];
+       srtc_chipid = chipid;
+       /* turn on RTC if it is not on */
+       inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL2);
+       inbuf[1] = 0;
+       spi_rtc_io(inbuf, outbuf, 2);
+       if (outbuf[1] & Rx5C348_BIT_XSTP) {
+               inbuf[0] = Rx5C348_CMD_W(Rx5C348_REG_CTL2);
+               inbuf[1] = 0;
+               spi_rtc_io(inbuf, NULL, 2);
+       }
+
+       inbuf[0] = Rx5C348_CMD_R(Rx5C348_REG_CTL1);
+       inbuf[1] = 0;
+       spi_rtc_io(inbuf, outbuf, 2);
+       if (outbuf[1] & Rx5C348_BIT_24H)
+               srtc_24h = 1;
+
+       /* set the function pointers */
+       rtc_get_time = rtc_rx5c348_get_time;
+       rtc_set_time = rtc_rx5c348_set_time;
+}
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
new file mode 100644 (file)
index 0000000..fc99295
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/mips/tx4938/common/setup.c
+ *
+ * common tx4938 setup routines
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/time.h>
+#include <asm/tx4938/rbtx4938.h>
+
+extern void toshiba_rbtx4938_setup(void);
+extern void rbtx4938_time_init(void);
+
+void __init tx4938_setup(void);
+void __init tx4938_time_init(void);
+void __init tx4938_timer_setup(struct irqaction *irq);
+void dump_cp0(char *key);
+
+void (*__wbflush) (void);
+
+static void
+tx4938_write_buffer_flush(void)
+{
+       mmiowb();
+
+       __asm__ __volatile__(
+               ".set   push\n\t"
+               ".set   noreorder\n\t"
+               "lw     $0,%0\n\t"
+               "nop\n\t"
+               ".set   pop"
+               : /* no output */
+               : "m" (*(int *)KSEG1)
+               : "memory");
+}
+
+void __init
+plat_setup(void)
+{
+       board_time_init = tx4938_time_init;
+       board_timer_setup = tx4938_timer_setup;
+       __wbflush = tx4938_write_buffer_flush;
+       toshiba_rbtx4938_setup();
+}
+
+void __init
+tx4938_time_init(void)
+{
+       rbtx4938_time_init();
+}
+
+void __init
+tx4938_timer_setup(struct irqaction *irq)
+{
+       u32 count;
+       u32 c1;
+       u32 c2;
+
+       setup_irq(TX4938_IRQ_CPU_TIMER, irq);
+
+       c1 = read_c0_count();
+       count = c1 + (mips_hpt_frequency / HZ);
+       write_c0_compare(count);
+       c2 = read_c0_count();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
new file mode 100644 (file)
index 0000000..2269412
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for common code for Toshiba TX4927 based systems
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+obj-y  += prom.o setup.o irq.o spi_eeprom.o spi_txx9.o
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c
new file mode 100644 (file)
index 0000000..230f5a9
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/irq.c
+ *
+ * Toshiba RBTX4938 specific interrupt handlers
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+/*
+IRQ  Device
+
+16   TX4938-CP0/00 Software 0
+17   TX4938-CP0/01 Software 1
+18   TX4938-CP0/02 Cascade TX4938-CP0
+19   TX4938-CP0/03 Multiplexed -- do not use
+20   TX4938-CP0/04 Multiplexed -- do not use
+21   TX4938-CP0/05 Multiplexed -- do not use
+22   TX4938-CP0/06 Multiplexed -- do not use
+23   TX4938-CP0/07 CPU TIMER
+
+24   TX4938-PIC/00
+25   TX4938-PIC/01
+26   TX4938-PIC/02 Cascade RBTX4938-IOC
+27   TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
+28   TX4938-PIC/04
+29   TX4938-PIC/05 TX4938 ETH1
+30   TX4938-PIC/06 TX4938 ETH0
+31   TX4938-PIC/07
+32   TX4938-PIC/08 TX4938 SIO 0
+33   TX4938-PIC/09 TX4938 SIO 1
+34   TX4938-PIC/10 TX4938 DMA0
+35   TX4938-PIC/11 TX4938 DMA1
+36   TX4938-PIC/12 TX4938 DMA2
+37   TX4938-PIC/13 TX4938 DMA3
+38   TX4938-PIC/14
+39   TX4938-PIC/15
+40   TX4938-PIC/16 TX4938 PCIC
+41   TX4938-PIC/17 TX4938 TMR0
+42   TX4938-PIC/18 TX4938 TMR1
+43   TX4938-PIC/19 TX4938 TMR2
+44   TX4938-PIC/20
+45   TX4938-PIC/21
+46   TX4938-PIC/22 TX4938 PCIERR
+47   TX4938-PIC/23
+48   TX4938-PIC/24
+49   TX4938-PIC/25
+50   TX4938-PIC/26
+51   TX4938-PIC/27
+52   TX4938-PIC/28
+53   TX4938-PIC/29
+54   TX4938-PIC/30
+55   TX4938-PIC/31 TX4938 SPI
+
+56 RBTX4938-IOC/00 PCI-D
+57 RBTX4938-IOC/01 PCI-C
+58 RBTX4938-IOC/02 PCI-B
+59 RBTX4938-IOC/03 PCI-A
+60 RBTX4938-IOC/04 RTC
+61 RBTX4938-IOC/05 ATA
+62 RBTX4938-IOC/06 MODEM
+63 RBTX4938-IOC/07 SWINT
+*/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+#include <asm/tx4938/rbtx4938.h>
+
+static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq);
+static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq);
+
+DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock);
+
+#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
+static struct hw_interrupt_type toshiba_rbtx4938_irq_ioc_type = {
+       .typename = TOSHIBA_RBTX4938_IOC_NAME,
+       .startup = toshiba_rbtx4938_irq_ioc_startup,
+       .shutdown = toshiba_rbtx4938_irq_ioc_shutdown,
+       .enable = toshiba_rbtx4938_irq_ioc_enable,
+       .disable = toshiba_rbtx4938_irq_ioc_disable,
+       .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack,
+       .end = toshiba_rbtx4938_irq_ioc_end,
+       .set_affinity = NULL
+};
+
+#define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000
+#define TOSHIBA_RBTX4938_IOC_INTR_STAT 0xb7f0200a
+
+int
+toshiba_rbtx4938_irq_nested(int sw_irq)
+{
+       u8 level3;
+
+       level3 = reg_rd08(TOSHIBA_RBTX4938_IOC_INTR_STAT) & 0xff;
+       if (level3) {
+               /* must use fls so onboard ATA has priority */
+               sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
+       }
+
+       wbflush();
+       return sw_irq;
+}
+
+static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
+       .handler = no_action,
+       .flags = 0,
+       .mask = CPU_MASK_NONE,
+       .name = TOSHIBA_RBTX4938_IOC_NAME,
+};
+
+/**********************************************************************************/
+/* Functions for ioc                                                              */
+/**********************************************************************************/
+static void __init
+toshiba_rbtx4938_irq_ioc_init(void)
+{
+       int i;
+
+       for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
+            i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) {
+               irq_desc[i].status = IRQ_DISABLED;
+               irq_desc[i].action = 0;
+               irq_desc[i].depth = 3;
+               irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type;
+       }
+
+       setup_irq(RBTX4938_IRQ_IOCINT,
+                 &toshiba_rbtx4938_irq_ioc_action);
+}
+
+static unsigned int
+toshiba_rbtx4938_irq_ioc_startup(unsigned int irq)
+{
+       toshiba_rbtx4938_irq_ioc_enable(irq);
+
+       return 0;
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq)
+{
+       toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
+{
+       unsigned long flags;
+       volatile unsigned char v;
+
+       spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+       v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+       v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+       TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+       mmiowb();
+       TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+       spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
+{
+       unsigned long flags;
+       volatile unsigned char v;
+
+       spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags);
+
+       v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+       v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
+       TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v);
+       mmiowb();
+       TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB);
+
+       spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq)
+{
+       toshiba_rbtx4938_irq_ioc_disable(irq);
+}
+
+static void
+toshiba_rbtx4938_irq_ioc_end(unsigned int irq)
+{
+       if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+               toshiba_rbtx4938_irq_ioc_enable(irq);
+       }
+}
+
+extern void __init txx9_spi_irqinit(int irc_irq);
+
+void __init arch_init_irq(void)
+{
+       extern void tx4938_irq_init(void);
+
+       /* Now, interrupt control disabled, */
+       /* all IRC interrupts are masked, */
+       /* all IRC interrupt mode are Low Active. */
+
+       /* mask all IOC interrupts */
+       *rbtx4938_imask_ptr = 0;
+
+       /* clear SoftInt interrupts */
+       *rbtx4938_softint_ptr = 0;
+       tx4938_irq_init();
+       toshiba_rbtx4938_irq_ioc_init();
+       /* Onboard 10M Ether: High Active */
+       TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000040);
+
+       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_SPI_SEL) {
+               txx9_spi_irqinit(RBTX4938_IRQ_IRC_SPI);
+        }
+
+       wbflush();
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
new file mode 100644 (file)
index 0000000..7df8b32
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+ *
+ * rbtx4938 specific prom routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/tx4938.h>
+
+void __init prom_init_cmdline(void)
+{
+       int argc = (int) fw_arg0;
+       char **argv = (char **) fw_arg1;
+       int i;
+
+       /* ignore all built-in args if any f/w args given */
+       if (argc > 1) {
+               *arcs_cmdline = '\0';
+       }
+
+       for (i = 1; i < argc; i++) {
+               if (i != 1) {
+                       strcat(arcs_cmdline, " ");
+               }
+               strcat(arcs_cmdline, argv[i]);
+       }
+}
+
+void __init prom_init(void)
+{
+       extern int tx4938_get_mem_size(void);
+       int msize;
+#ifndef CONFIG_TX4938_NAND_BOOT
+       prom_init_cmdline();
+#endif
+       mips_machgroup = MACH_GROUP_TOSHIBA;
+       mips_machtype = MACH_TOSHIBA_RBTX4938;
+
+       msize = tx4938_get_mem_size();
+       add_memory_region(0, msize << 20, BOOT_MEM_RAM);
+
+       return;
+}
+
+unsigned long  __init prom_free_prom_memory(void)
+{
+       return 0;
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+       return;
+}
+
+const char *get_system_type(void)
+{
+       return "Toshiba RBTX4938";
+}
+
+char * __init prom_getcmdline(void)
+{
+       return &(arcs_cmdline[0]);
+}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
new file mode 100644 (file)
index 0000000..9f1dcc8
--- /dev/null
@@ -0,0 +1,1035 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+ *
+ * Setup pointers to hardware-dependent routines.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <asm/wbflush.h>
+#include <asm/reboot.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/tx4938/rbtx4938.h>
+#ifdef CONFIG_SERIAL_TXX9
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#endif
+
+extern void rbtx4938_time_init(void) __init;
+extern char * __init prom_getcmdline(void);
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void rbtx4938_machine_restart(char *command);
+extern void rbtx4938_machine_halt(void);
+extern void rbtx4938_machine_power_off(void);
+
+/* clocks */
+unsigned int txx9_master_clock;
+unsigned int txx9_cpu_clock;
+unsigned int txx9_gbus_clock;
+
+unsigned long rbtx4938_ce_base[8];
+unsigned long rbtx4938_ce_size[8];
+int txboard_pci66_mode;
+static int tx4938_pcic_trdyto; /* default: disabled */
+static int tx4938_pcic_retryto;        /* default: disabled */
+static int tx4938_ccfg_toeon = 1;
+
+struct tx4938_pcic_reg *pcicptrs[4] = {
+       tx4938_pcicptr  /* default setting for TX4938 */
+};
+
+static struct {
+       unsigned long base;
+       unsigned long size;
+} phys_regions[16] __initdata;
+static int num_phys_regions  __initdata;
+
+#define PHYS_REGION_MINSIZE    0x10000
+
+void rbtx4938_machine_halt(void)
+{
+        printk(KERN_NOTICE "System Halted\n");
+       local_irq_disable();
+
+       while (1)
+               __asm__(".set\tmips3\n\t"
+                       "wait\n\t"
+                       ".set\tmips0");
+}
+
+void rbtx4938_machine_power_off(void)
+{
+        rbtx4938_machine_halt();
+        /* no return */
+}
+
+void rbtx4938_machine_restart(char *command)
+{
+       local_irq_disable();
+
+       printk("Rebooting...");
+       *rbtx4938_softresetlock_ptr = 1;
+       *rbtx4938_sfvol_ptr = 1;
+       *rbtx4938_softreset_ptr = 1;
+       wbflush();
+
+       while(1);
+}
+
+void __init
+txboard_add_phys_region(unsigned long base, unsigned long size)
+{
+       if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
+               printk("phys_region overflow\n");
+               return;
+       }
+       phys_regions[num_phys_regions].base = base;
+       phys_regions[num_phys_regions].size = size;
+       num_phys_regions++;
+}
+unsigned long __init
+txboard_find_free_phys_region(unsigned long begin, unsigned long end,
+                             unsigned long size)
+{
+       unsigned long base;
+       int i;
+
+       for (base = begin / size * size; base < end; base += size) {
+               for (i = 0; i < num_phys_regions; i++) {
+                       if (phys_regions[i].size &&
+                           base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
+                           base + (size - 1) >= phys_regions[i].base)
+                               break;
+               }
+               if (i == num_phys_regions)
+                       return base;
+       }
+       return 0;
+}
+unsigned long __init
+txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
+                                    unsigned long *size)
+{
+       unsigned long sz, base;
+       for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
+               base = txboard_find_free_phys_region(begin, end, sz);
+               if (base) {
+                       *size = sz;
+                       return base;
+               }
+       }
+       return 0;
+}
+unsigned long __init
+txboard_request_phys_region_range(unsigned long begin, unsigned long end,
+                                 unsigned long size)
+{
+       unsigned long base;
+       base = txboard_find_free_phys_region(begin, end, size);
+       if (base)
+               txboard_add_phys_region(base, size);
+       return base;
+}
+unsigned long __init
+txboard_request_phys_region(unsigned long size)
+{
+       unsigned long base;
+       unsigned long begin = 0, end = 0x20000000;      /* search low 512MB */
+       base = txboard_find_free_phys_region(begin, end, size);
+       if (base)
+               txboard_add_phys_region(base, size);
+       return base;
+}
+unsigned long __init
+txboard_request_phys_region_shrink(unsigned long *size)
+{
+       unsigned long base;
+       unsigned long begin = 0, end = 0x20000000;      /* search low 512MB */
+       base = txboard_find_free_phys_region_shrink(begin, end, size);
+       if (base)
+               txboard_add_phys_region(base, *size);
+       return base;
+}
+
+#ifdef CONFIG_PCI
+void __init
+tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
+                 struct pci_controller *channel,
+                 unsigned long pci_io_base,
+                 int extarb)
+{
+       int i;
+
+       /* Disable All Initiator Space */
+       pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
+                             TX4938_PCIC_PCICCFG_G2PMEN(1)|
+                             TX4938_PCIC_PCICCFG_G2PMEN(2)|
+                             TX4938_PCIC_PCICCFG_G2PIOEN);
+
+       /* GB->PCI mappings */
+       pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
+       pcicptr->g2piogbase = pci_io_base |
+#ifdef __BIG_ENDIAN
+               TX4938_PCIC_G2PIOGBASE_ECHG
+#else
+               TX4938_PCIC_G2PIOGBASE_BSDIS
+#endif
+               ;
+       pcicptr->g2piopbase = 0;
+       for (i = 0; i < 3; i++) {
+               pcicptr->g2pmmask[i] = 0;
+               pcicptr->g2pmgbase[i] = 0;
+               pcicptr->g2pmpbase[i] = 0;
+       }
+       if (channel->mem_resource->end) {
+               pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
+               pcicptr->g2pmgbase[0] = channel->mem_resource->start |
+#ifdef __BIG_ENDIAN
+                       TX4938_PCIC_G2PMnGBASE_ECHG
+#else
+                       TX4938_PCIC_G2PMnGBASE_BSDIS
+#endif
+                       ;
+               pcicptr->g2pmpbase[0] = channel->mem_resource->start;
+       }
+       /* PCI->GB mappings (I/O 256B) */
+       pcicptr->p2giopbase = 0; /* 256B */
+       pcicptr->p2giogbase = 0;
+       /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
+       pcicptr->p2gm0plbase = 0;
+       pcicptr->p2gm0pubase = 0;
+       pcicptr->p2gmgbase[0] = 0 |
+               TX4938_PCIC_P2GMnGBASE_TMEMEN |
+#ifdef __BIG_ENDIAN
+               TX4938_PCIC_P2GMnGBASE_TECHG
+#else
+               TX4938_PCIC_P2GMnGBASE_TBSDIS
+#endif
+               ;
+       /* PCI->GB mappings (MEM 16MB) */
+       pcicptr->p2gm1plbase = 0xffffffff;
+       pcicptr->p2gm1pubase = 0xffffffff;
+       pcicptr->p2gmgbase[1] = 0;
+       /* PCI->GB mappings (MEM 1MB) */
+       pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
+       pcicptr->p2gmgbase[2] = 0;
+
+       pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
+       /* Enable Initiator Memory Space */
+       if (channel->mem_resource->end)
+               pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
+       /* Enable Initiator I/O Space */
+       if (channel->io_resource->end)
+               pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
+       /* Enable Initiator Config */
+       pcicptr->pciccfg |=
+               TX4938_PCIC_PCICCFG_ICAEN |
+               TX4938_PCIC_PCICCFG_TCAR;
+
+       /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
+       pcicptr->pcicfg1 = 0;
+
+       pcicptr->g2ptocnt &= ~0xffff;
+
+       if (tx4938_pcic_trdyto >= 0) {
+               pcicptr->g2ptocnt &= ~0xff;
+               pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
+       }
+
+       if (tx4938_pcic_retryto >= 0) {
+               pcicptr->g2ptocnt &= ~0xff00;
+               pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
+       }
+
+       /* Clear All Local Bus Status */
+       pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
+       /* Enable All Local Bus Interrupts */
+       pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
+       /* Clear All Initiator Status */
+       pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
+       /* Enable All Initiator Interrupts */
+       pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
+       /* Clear All PCI Status Error */
+       pcicptr->pcistatus =
+               (pcicptr->pcistatus & 0x0000ffff) |
+               (TX4938_PCIC_PCISTATUS_ALL << 16);
+       /* Enable All PCI Status Error Interrupts */
+       pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
+
+       if (!extarb) {
+               /* Reset Bus Arbiter */
+               pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
+               pcicptr->pbabm = 0;
+               /* Enable Bus Arbiter */
+               pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
+       }
+
+      /* PCIC Int => IRC IRQ16 */
+       pcicptr->pcicfg2 =
+                   (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
+
+       pcicptr->pcistatus = PCI_COMMAND_MASTER |
+               PCI_COMMAND_MEMORY |
+               PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+}
+
+int __init
+tx4938_report_pciclk(void)
+{
+       unsigned long pcode = TX4938_REV_PCODE();
+       int pciclk = 0;
+       printk("TX%lx PCIC --%s PCICLK:",
+              pcode,
+              (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
+       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+
+               switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
+               case TX4938_CCFG_PCIDIVMODE_4:
+                       pciclk = txx9_cpu_clock / 4; break;
+               case TX4938_CCFG_PCIDIVMODE_4_5:
+                       pciclk = txx9_cpu_clock * 2 / 9; break;
+               case TX4938_CCFG_PCIDIVMODE_5:
+                       pciclk = txx9_cpu_clock / 5; break;
+               case TX4938_CCFG_PCIDIVMODE_5_5:
+                       pciclk = txx9_cpu_clock * 2 / 11; break;
+               case TX4938_CCFG_PCIDIVMODE_8:
+                       pciclk = txx9_cpu_clock / 8; break;
+               case TX4938_CCFG_PCIDIVMODE_9:
+                       pciclk = txx9_cpu_clock / 9; break;
+               case TX4938_CCFG_PCIDIVMODE_10:
+                       pciclk = txx9_cpu_clock / 10; break;
+               case TX4938_CCFG_PCIDIVMODE_11:
+                       pciclk = txx9_cpu_clock / 11; break;
+               }
+               printk("Internal(%dMHz)", pciclk / 1000000);
+       } else {
+               printk("External");
+               pciclk = -1;
+       }
+       printk("\n");
+       return pciclk;
+}
+
+void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
+{
+       pcicptrs[ch] = pcicptr;
+}
+
+struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
+{
+       return pcicptrs[ch];
+}
+
+static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
+                                    int top_bus, int busnr, int devfn)
+{
+       static struct pci_dev dev;
+       static struct pci_bus bus;
+
+       dev.sysdata = (void *)hose;
+       dev.devfn = devfn;
+       bus.number = busnr;
+       bus.ops = hose->pci_ops;
+       bus.parent = NULL;
+       dev.bus = &bus;
+
+       return &dev;
+}
+
+#define EARLY_PCI_OP(rw, size, type)                                    \
+static int early_##rw##_config_##size(struct pci_controller *hose,      \
+        int top_bus, int bus, int devfn, int offset, type value)        \
+{                                                                       \
+        return pci_##rw##_config_##size(                                \
+                fake_pci_dev(hose, top_bus, bus, devfn),                \
+                offset, value);                                         \
+}
+
+EARLY_PCI_OP(read, word, u16 *)
+
+int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
+{
+       u32 pci_devfn;
+       unsigned short vid;
+       int devfn_start = 0;
+       int devfn_stop = 0xff;
+       int cap66 = -1;
+       u16 stat;
+
+       printk("PCI: Checking 66MHz capabilities...\n");
+
+       for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
+               early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+                                      PCI_VENDOR_ID, &vid);
+
+               if (vid == 0xffff) continue;
+
+               /* check 66MHz capability */
+               if (cap66 < 0)
+                       cap66 = 1;
+               if (cap66) {
+                       early_read_config_word(hose, top_bus, current_bus, pci_devfn,
+                                              PCI_STATUS, &stat);
+                       if (!(stat & PCI_STATUS_66MHZ)) {
+                               printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
+                                      current_bus, pci_devfn);
+                               cap66 = 0;
+                               break;
+                       }
+               }
+       }
+       return cap66 > 0;
+}
+
+int __init
+tx4938_pciclk66_setup(void)
+{
+       int pciclk;
+
+       /* Assert M66EN */
+       tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
+       /* Double PCICLK (if possible) */
+       if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
+               unsigned int pcidivmode =
+                       tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
+               switch (pcidivmode) {
+               case TX4938_CCFG_PCIDIVMODE_8:
+               case TX4938_CCFG_PCIDIVMODE_4:
+                       pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
+                       pciclk = txx9_cpu_clock / 4;
+                       break;
+               case TX4938_CCFG_PCIDIVMODE_9:
+               case TX4938_CCFG_PCIDIVMODE_4_5:
+                       pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
+                       pciclk = txx9_cpu_clock * 2 / 9;
+                       break;
+               case TX4938_CCFG_PCIDIVMODE_10:
+               case TX4938_CCFG_PCIDIVMODE_5:
+                       pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
+                       pciclk = txx9_cpu_clock / 5;
+                       break;
+               case TX4938_CCFG_PCIDIVMODE_11:
+               case TX4938_CCFG_PCIDIVMODE_5_5:
+               default:
+                       pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
+                       pciclk = txx9_cpu_clock * 2 / 11;
+                       break;
+               }
+               tx4938_ccfgptr->ccfg =
+                       (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
+                       | pcidivmode;
+               printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
+                      (unsigned long)tx4938_ccfgptr->ccfg);
+       } else {
+               pciclk = -1;
+       }
+       return pciclk;
+}
+
+extern struct pci_controller tx4938_pci_controller[];
+static int __init tx4938_pcibios_init(void)
+{
+       unsigned long mem_base[2];
+       unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0,TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
+       unsigned long io_base[2];
+       unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0,TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
+       /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
+       int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
+
+       PCIBIOS_MIN_IO = 0x00001000UL;
+       PCIBIOS_MIN_MEM = 0x01000000UL;
+
+       mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
+       io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
+
+       printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+              (unsigned short)(tx4938_pcicptr->pciid >> 16),
+              (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
+              (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
+              extarb ? "External" : "Internal");
+
+       /* setup PCI area */
+       tx4938_pci_controller[0].io_resource->start = io_base[0];
+       tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
+       tx4938_pci_controller[0].mem_resource->start = mem_base[0];
+       tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
+
+       set_tx4938_pcicptr(0, tx4938_pcicptr);
+
+       register_pci_controller(&tx4938_pci_controller[0]);
+
+       if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
+               printk("TX4938_CCFG_PCI66 already configured\n");
+               txboard_pci66_mode = -1; /* already configured */
+       }
+
+       /* Reset PCI Bus */
+       *rbtx4938_pcireset_ptr = 0;
+       /* Reset PCIC */
+       tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+       if (txboard_pci66_mode > 0)
+               tx4938_pciclk66_setup();
+       mdelay(10);
+       /* clear PCIC reset */
+       tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+       *rbtx4938_pcireset_ptr = 1;
+       wbflush();
+       tx4938_report_pcic_status1(tx4938_pcicptr);
+
+       tx4938_report_pciclk();
+       tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+       if (txboard_pci66_mode == 0 &&
+           txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
+               /* Reset PCI Bus */
+               *rbtx4938_pcireset_ptr = 0;
+               /* Reset PCIC */
+               tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
+               tx4938_pciclk66_setup();
+               mdelay(10);
+               /* clear PCIC reset */
+               tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
+               *rbtx4938_pcireset_ptr = 1;
+               wbflush();
+               /* Reinitialize PCIC */
+               tx4938_report_pciclk();
+               tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
+       }
+
+       mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
+       io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
+       /* Reset PCIC1 */
+       tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
+       /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
+       if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
+               tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
+       else
+               tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
+       mdelay(10);
+       /* clear PCIC1 reset */
+       tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+       tx4938_report_pcic_status1(tx4938_pcic1ptr);
+
+       printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
+              (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
+              (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
+              (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
+       printk("%s PCICLK:%dMHz\n",
+              (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
+              txx9_gbus_clock /
+              ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
+              1000000);
+
+       /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
+       tx4938_pci_controller[1].io_resource->start =
+               io_base[1] - io_base[0];
+       tx4938_pci_controller[1].io_resource->end =
+               io_base[1] - io_base[0] + io_size[1] - 1;
+       tx4938_pci_controller[1].mem_resource->start = mem_base[1];
+       tx4938_pci_controller[1].mem_resource->end =
+               mem_base[1] + mem_size[1] - 1;
+       set_tx4938_pcicptr(1, tx4938_pcic1ptr);
+
+       register_pci_controller(&tx4938_pci_controller[1]);
+
+       tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
+
+       /* map ioport 0 to PCI I/O space address 0 */
+       set_io_port_base(KSEG1 + io_base[0]);
+
+       return 0;
+}
+
+arch_initcall(tx4938_pcibios_init);
+
+#endif /* CONFIG_PCI */
+
+/* SPI support */
+
+/* chip select for SPI devices */
+#define        SEEPROM1_CS     7       /* PIO7 */
+#define        SEEPROM2_CS     0       /* IOC */
+#define        SEEPROM3_CS     1       /* IOC */
+#define        SRTC_CS 2       /* IOC */
+
+static int rbtx4938_spi_cs_func(int chipid, int on)
+{
+       unsigned char bit;
+       switch (chipid) {
+       case RBTX4938_SEEPROM1_CHIPID:
+               if (on)
+                       tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS);
+               else
+                       tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+               return 0;
+               break;
+       case RBTX4938_SEEPROM2_CHIPID:
+               bit = (1 << SEEPROM2_CS);
+               break;
+       case RBTX4938_SEEPROM3_CHIPID:
+               bit = (1 << SEEPROM3_CS);
+               break;
+       case RBTX4938_SRTC_CHIPID:
+               bit = (1 << SRTC_CS);
+               break;
+       default:
+               return -ENODEV;
+       }
+       /* bit1,2,4 are low active, bit3 is high active */
+       *rbtx4938_spics_ptr =
+               (*rbtx4938_spics_ptr & ~bit) |
+               ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit);
+       return 0;
+}
+
+#ifdef CONFIG_PCI
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+
+int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+{
+       struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
+       static unsigned char dat[17];
+       static int read_dat = 0;
+       int ch = 0;
+
+       if (channel != &tx4938_pci_controller[1])
+               return -ENODEV;
+       /* TX4938 PCIC1 */
+       switch (PCI_SLOT(dev->devfn)) {
+       case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
+               ch = 0;
+               break;
+       case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
+               ch = 1;
+               break;
+       default:
+               return -ENODEV;
+       }
+       if (!read_dat) {
+               unsigned char sum;
+               int i;
+               read_dat = 1;
+               /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
+               if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID,
+                                   0, dat, sizeof(dat))) {
+                       printk(KERN_ERR "seeprom: read error.\n");
+               } else {
+                       if (strcmp(dat, "MAC") != 0)
+                               printk(KERN_WARNING "seeprom: bad signature.\n");
+                       for (i = 0, sum = 0; i < sizeof(dat); i++)
+                               sum += dat[i];
+                       if (sum)
+                               printk(KERN_WARNING "seeprom: bad checksum.\n");
+               }
+       }
+       memcpy(addr, &dat[4 + 6 * ch], 6);
+       return 0;
+}
+#endif /* CONFIG_PCI */
+
+extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
+static void __init rbtx4938_spi_setup(void)
+{
+       /* set SPI_SEL */
+       tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
+       /* chip selects for SPI devices */
+       tx4938_pioptr->dout |= (1 << SEEPROM1_CS);
+       tx4938_pioptr->dir |= (1 << SEEPROM1_CS);
+       txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func);
+}
+
+static struct resource rbtx4938_fpga_resource;
+
+static char pcode_str[8];
+static struct resource tx4938_reg_resource = {
+       pcode_str, TX4938_REG_BASE, TX4938_REG_BASE+TX4938_REG_SIZE, IORESOURCE_MEM
+};
+
+void __init tx4938_board_setup(void)
+{
+       int i;
+       unsigned long divmode;
+       int cpuclk = 0;
+       unsigned long pcode = TX4938_REV_PCODE();
+
+       ioport_resource.start = 0x1000;
+       ioport_resource.end = 0xffffffff;
+       iomem_resource.start = 0x1000;
+       iomem_resource.end = 0xffffffff;        /* expand to 4GB */
+
+       sprintf(pcode_str, "TX%lx", pcode);
+       /* SDRAMC,EBUSC are configured by PROM */
+       for (i = 0; i < 8; i++) {
+               if (!(tx4938_ebuscptr->cr[i] & 0x8))
+                       continue;       /* disabled */
+               rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
+               txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
+       }
+
+       /* clocks */
+       if (txx9_master_clock) {
+               /* calculate gbus_clock and cpu_clock from master_clock */
+               divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+               switch (divmode) {
+               case TX4938_CCFG_DIVMODE_8:
+               case TX4938_CCFG_DIVMODE_10:
+               case TX4938_CCFG_DIVMODE_12:
+               case TX4938_CCFG_DIVMODE_16:
+               case TX4938_CCFG_DIVMODE_18:
+                       txx9_gbus_clock = txx9_master_clock * 4; break;
+               default:
+                       txx9_gbus_clock = txx9_master_clock;
+               }
+               switch (divmode) {
+               case TX4938_CCFG_DIVMODE_2:
+               case TX4938_CCFG_DIVMODE_8:
+                       cpuclk = txx9_gbus_clock * 2; break;
+               case TX4938_CCFG_DIVMODE_2_5:
+               case TX4938_CCFG_DIVMODE_10:
+                       cpuclk = txx9_gbus_clock * 5 / 2; break;
+               case TX4938_CCFG_DIVMODE_3:
+               case TX4938_CCFG_DIVMODE_12:
+                       cpuclk = txx9_gbus_clock * 3; break;
+               case TX4938_CCFG_DIVMODE_4:
+               case TX4938_CCFG_DIVMODE_16:
+                       cpuclk = txx9_gbus_clock * 4; break;
+               case TX4938_CCFG_DIVMODE_4_5:
+               case TX4938_CCFG_DIVMODE_18:
+                       cpuclk = txx9_gbus_clock * 9 / 2; break;
+               }
+               txx9_cpu_clock = cpuclk;
+       } else {
+               if (txx9_cpu_clock == 0) {
+                       txx9_cpu_clock = 300000000;     /* 300MHz */
+               }
+               /* calculate gbus_clock and master_clock from cpu_clock */
+               cpuclk = txx9_cpu_clock;
+               divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
+               switch (divmode) {
+               case TX4938_CCFG_DIVMODE_2:
+               case TX4938_CCFG_DIVMODE_8:
+                       txx9_gbus_clock = cpuclk / 2; break;
+               case TX4938_CCFG_DIVMODE_2_5:
+               case TX4938_CCFG_DIVMODE_10:
+                       txx9_gbus_clock = cpuclk * 2 / 5; break;
+               case TX4938_CCFG_DIVMODE_3:
+               case TX4938_CCFG_DIVMODE_12:
+                       txx9_gbus_clock = cpuclk / 3; break;
+               case TX4938_CCFG_DIVMODE_4:
+               case TX4938_CCFG_DIVMODE_16:
+                       txx9_gbus_clock = cpuclk / 4; break;
+               case TX4938_CCFG_DIVMODE_4_5:
+               case TX4938_CCFG_DIVMODE_18:
+                       txx9_gbus_clock = cpuclk * 2 / 9; break;
+               }
+               switch (divmode) {
+               case TX4938_CCFG_DIVMODE_8:
+               case TX4938_CCFG_DIVMODE_10:
+               case TX4938_CCFG_DIVMODE_12:
+               case TX4938_CCFG_DIVMODE_16:
+               case TX4938_CCFG_DIVMODE_18:
+                       txx9_master_clock = txx9_gbus_clock / 4; break;
+               default:
+                       txx9_master_clock = txx9_gbus_clock;
+               }
+       }
+       /* change default value to udelay/mdelay take reasonable time */
+       loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+       /* CCFG */
+       /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
+       tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
+       /* clear PCIC1 reset */
+       if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
+               tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
+
+       /* enable Timeout BusError */
+       if (tx4938_ccfg_toeon)
+               tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
+
+       /* DMA selection */
+       tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
+
+       /* Use external clock for external arbiter */
+       if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
+               tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
+
+       printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
+              pcode_str,
+              cpuclk / 1000000, txx9_master_clock / 1000000,
+              (unsigned long)tx4938_ccfgptr->crir,
+              tx4938_ccfgptr->ccfg,
+              tx4938_ccfgptr->pcfg);
+
+       printk("%s SDRAMC --", pcode_str);
+       for (i = 0; i < 4; i++) {
+               unsigned long long cr = tx4938_sdramcptr->cr[i];
+               unsigned long ram_base, ram_size;
+               if (!((unsigned long)cr & 0x00000400))
+                       continue;       /* disabled */
+               ram_base = (unsigned long)(cr >> 49) << 21;
+               ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
+               if (ram_base >= 0x20000000)
+                       continue;       /* high memory (ignore) */
+               printk(" CR%d:%016Lx", i, cr);
+               txboard_add_phys_region(ram_base, ram_size);
+       }
+       printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
+
+       /* SRAM */
+       if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
+               unsigned int size = 0x800;
+               unsigned long base =
+                       (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
+                txboard_add_phys_region(base, size);
+       }
+
+       /* IRC */
+       /* disable interrupt control */
+       tx4938_ircptr->cer = 0;
+
+       /* TMR */
+       /* disable all timers */
+       for (i = 0; i < TX4938_NR_TMR; i++) {
+               tx4938_tmrptr(i)->tcr  = 0x00000020;
+               tx4938_tmrptr(i)->tisr = 0;
+               tx4938_tmrptr(i)->cpra = 0xffffffff;
+               tx4938_tmrptr(i)->itmr = 0;
+               tx4938_tmrptr(i)->ccdr = 0;
+               tx4938_tmrptr(i)->pgmr = 0;
+       }
+
+       /* enable DMA */
+       TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
+       TX4938_WR64(0xff1fb950, TX4938_DMA_MCR_MSTEN);
+
+       /* PIO */
+       tx4938_pioptr->maskcpu = 0;
+       tx4938_pioptr->maskext = 0;
+
+       /* TX4938 internal registers */
+       if (request_resource(&iomem_resource, &tx4938_reg_resource))
+               printk("request resource for internal registers failed\n");
+}
+
+#ifdef CONFIG_PCI
+static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
+{
+       unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
+       unsigned long g2pstatus = pcicptr->g2pstatus;
+       unsigned long pcicstatus = pcicptr->pcicstatus;
+       static struct {
+               unsigned long flag;
+               const char *str;
+       } pcistat_tbl[] = {
+               { PCI_STATUS_DETECTED_PARITY,   "DetectedParityError" },
+               { PCI_STATUS_SIG_SYSTEM_ERROR,  "SignaledSystemError" },
+               { PCI_STATUS_REC_MASTER_ABORT,  "ReceivedMasterAbort" },
+               { PCI_STATUS_REC_TARGET_ABORT,  "ReceivedTargetAbort" },
+               { PCI_STATUS_SIG_TARGET_ABORT,  "SignaledTargetAbort" },
+               { PCI_STATUS_PARITY,    "MasterParityError" },
+       }, g2pstat_tbl[] = {
+               { TX4938_PCIC_G2PSTATUS_TTOE,   "TIOE" },
+               { TX4938_PCIC_G2PSTATUS_RTOE,   "RTOE" },
+       }, pcicstat_tbl[] = {
+               { TX4938_PCIC_PCICSTATUS_PME,   "PME" },
+               { TX4938_PCIC_PCICSTATUS_TLB,   "TLB" },
+               { TX4938_PCIC_PCICSTATUS_NIB,   "NIB" },
+               { TX4938_PCIC_PCICSTATUS_ZIB,   "ZIB" },
+               { TX4938_PCIC_PCICSTATUS_PERR,  "PERR" },
+               { TX4938_PCIC_PCICSTATUS_SERR,  "SERR" },
+               { TX4938_PCIC_PCICSTATUS_GBE,   "GBE" },
+               { TX4938_PCIC_PCICSTATUS_IWB,   "IWB" },
+       };
+       int i;
+
+       printk("pcistat:%04x(", pcistatus);
+       for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
+               if (pcistatus & pcistat_tbl[i].flag)
+                       printk("%s ", pcistat_tbl[i].str);
+       printk("), g2pstatus:%08lx(", g2pstatus);
+       for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
+               if (g2pstatus & g2pstat_tbl[i].flag)
+                       printk("%s ", g2pstat_tbl[i].str);
+       printk("), pcicstatus:%08lx(", pcicstatus);
+       for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
+               if (pcicstatus & pcicstat_tbl[i].flag)
+                       printk("%s ", pcicstat_tbl[i].str);
+       printk(")\n");
+}
+
+void tx4938_report_pcic_status(void)
+{
+       int i;
+       struct tx4938_pcic_reg *pcicptr;
+       for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
+               tx4938_report_pcic_status1(pcicptr);
+}
+
+#endif /* CONFIG_PCI */
+
+/* We use onchip r4k counter or TMR timer as our system wide timer
+ * interrupt running at 100HZ. */
+
+extern void __init rtc_rx5c348_init(int chipid);
+void __init rbtx4938_time_init(void)
+{
+       rtc_rx5c348_init(RBTX4938_SRTC_CHIPID);
+       mips_hpt_frequency = txx9_cpu_clock / 2;
+}
+
+void __init toshiba_rbtx4938_setup(void)
+{
+       unsigned long long pcfg;
+       char *argptr;
+
+       iomem_resource.end = 0xffffffff;        /* 4GB */
+
+       if (txx9_master_clock == 0)
+               txx9_master_clock = 25000000; /* 25MHz */
+       tx4938_board_setup();
+       /* setup irq stuff */
+       TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM0), 0x00000000);    /* irq trigger */
+       TX4938_WR(TX4938_MKA(TX4938_IRC_IRDM1), 0x00000000);    /* irq trigger */
+       /* setup serial stuff */
+       TX4938_WR(0xff1ff314, 0x00000000);      /* h/w flow control off */
+       TX4938_WR(0xff1ff414, 0x00000000);      /* h/w flow control off */
+
+#ifndef CONFIG_PCI
+       set_io_port_base(RBTX4938_ETHER_BASE);
+#endif
+
+#ifdef CONFIG_SERIAL_TXX9
+       {
+               extern int early_serial_txx9_setup(struct uart_port *port);
+               int i;
+               struct uart_port req;
+               for(i = 0; i < 2; i++) {
+                       memset(&req, 0, sizeof(req));
+                       req.line = i;
+                       req.iotype = UPIO_MEM;
+                       req.membase = (char *)(0xff1ff300 + i * 0x100);
+                       req.mapbase = 0xff1ff300 + i * 0x100;
+                       req.irq = 32 + i;
+                       req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+                       req.uartclk = 50000000;
+                       early_serial_txx9_setup(&req);
+               }
+       }
+#ifdef CONFIG_SERIAL_TXX9_CONSOLE
+        argptr = prom_getcmdline();
+        if (strstr(argptr, "console=") == NULL) {
+                strcat(argptr, " console=ttyS0,38400");
+        }
+#endif
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
+       printk("PIOSEL: disabling both ata and nand selection\n");
+       local_irq_disable();
+       tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
+       printk("PIOSEL: enabling nand selection\n");
+       tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
+       tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
+       printk("PIOSEL: enabling ata selection\n");
+       tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
+       tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
+#endif
+
+#ifdef CONFIG_IP_PNP
+       argptr = prom_getcmdline();
+       if (strstr(argptr, "ip=") == NULL) {
+               strcat(argptr, " ip=any");
+       }
+#endif
+
+
+#ifdef CONFIG_FB
+       {
+               conswitchp = &dummy_con;
+       }
+#endif
+
+       rbtx4938_spi_setup();
+       pcfg = tx4938_ccfgptr->pcfg;    /* updated */
+       /* fixup piosel */
+       if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+           TX4938_PCFG_ATA_SEL) {
+               *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x04;
+       }
+       else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+           TX4938_PCFG_NDF_SEL) {
+               *rbtx4938_piosel_ptr = (*rbtx4938_piosel_ptr & 0x03) | 0x08;
+       }
+       else {
+               *rbtx4938_piosel_ptr &= ~(0x08 | 0x04);
+       }
+
+       rbtx4938_fpga_resource.name = "FPGA Registers";
+       rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
+       rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
+       rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+       if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
+               printk("request resource for fpga failed\n");
+
+       /* disable all OnBoard I/O interrupts */
+       *rbtx4938_imask_ptr = 0;
+
+       _machine_restart = rbtx4938_machine_restart;
+       _machine_halt = rbtx4938_machine_halt;
+       _machine_power_off = rbtx4938_machine_power_off;
+
+       *rbtx4938_led_ptr = 0xff;
+       printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr);
+       printk(" DIPSW:%02x,%02x\n",
+              *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr);
+}
+
+#ifdef CONFIG_PROC_FS
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid);
+static int __init tx4938_spi_proc_setup(void)
+{
+       struct proc_dir_entry *tx4938_spi_eeprom_dir;
+
+       tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0);
+
+       if (!tx4938_spi_eeprom_dir)
+               return -ENOMEM;
+
+       /* don't allow user access to RBTX4938_SEEPROM1_CHIPID
+        * as it contains eth0 and eth1 MAC addresses
+        */
+       spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID);
+       spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID);
+
+       return 0;
+}
+
+__initcall(tx4938_spi_proc_setup);
+#endif
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
new file mode 100644 (file)
index 0000000..951a208
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_eeprom.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+/* ATMEL 250x0 instructions */
+#define        ATMEL_WREN      0x06
+#define        ATMEL_WRDI      0x04
+#define ATMEL_RDSR     0x05
+#define ATMEL_WRSR     0x01
+#define        ATMEL_READ      0x03
+#define        ATMEL_WRITE     0x02
+
+#define ATMEL_SR_BSY   0x01
+#define ATMEL_SR_WEN   0x02
+#define ATMEL_SR_BP0   0x04
+#define ATMEL_SR_BP1   0x08
+
+DEFINE_SPINLOCK(spi_eeprom_lock);
+
+static struct spi_dev_desc seeprom_dev_desc = {
+       .baud           = 1500000,      /* 1.5Mbps */
+       .tcss           = 1,
+       .tcsh           = 1,
+       .tcsr           = 1,
+       .byteorder      = 1,            /* MSB-First */
+       .polarity       = 0,            /* High-Active */
+       .phase          = 0,            /* Sample-Then-Shift */
+
+};
+static inline int
+spi_eeprom_io(int chipid,
+             unsigned char **inbufs, unsigned int *incounts,
+             unsigned char **outbufs, unsigned int *outcounts)
+{
+       return txx9_spi_io(chipid, &seeprom_dev_desc,
+                          inbufs, incounts, outbufs, outcounts, 0);
+}
+
+int spi_eeprom_write_enable(int chipid, int enable)
+{
+       unsigned char inbuf[1];
+       unsigned char *inbufs[1];
+       unsigned int incounts[2];
+       unsigned long flags;
+       int stat;
+       inbuf[0] = enable ? ATMEL_WREN : ATMEL_WRDI;
+       inbufs[0] = inbuf;
+       incounts[0] = sizeof(inbuf);
+       incounts[1] = 0;
+       spin_lock_irqsave(&spi_eeprom_lock, flags);
+       stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+       return stat;
+}
+
+static int spi_eeprom_read_status_nolock(int chipid)
+{
+       unsigned char inbuf[2], outbuf[2];
+       unsigned char *inbufs[1], *outbufs[1];
+       unsigned int incounts[2], outcounts[2];
+       int stat;
+       inbuf[0] = ATMEL_RDSR;
+       inbuf[1] = 0;
+       inbufs[0] = inbuf;
+       incounts[0] = sizeof(inbuf);
+       incounts[1] = 0;
+       outbufs[0] = outbuf;
+       outcounts[0] = sizeof(outbuf);
+       outcounts[1] = 0;
+       stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+       if (stat < 0)
+               return stat;
+       return outbuf[1];
+}
+
+int spi_eeprom_read_status(int chipid)
+{
+       unsigned long flags;
+       int stat;
+       spin_lock_irqsave(&spi_eeprom_lock, flags);
+       stat = spi_eeprom_read_status_nolock(chipid);
+       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+       return stat;
+}
+
+int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len)
+{
+       unsigned char inbuf[2];
+       unsigned char *inbufs[2], *outbufs[2];
+       unsigned int incounts[2], outcounts[3];
+       unsigned long flags;
+       int stat;
+       inbuf[0] = ATMEL_READ;
+       inbuf[1] = address;
+       inbufs[0] = inbuf;
+       inbufs[1] = NULL;
+       incounts[0] = sizeof(inbuf);
+       incounts[1] = 0;
+       outbufs[0] = NULL;
+       outbufs[1] = buf;
+       outcounts[0] = 2;
+       outcounts[1] = len;
+       outcounts[2] = 0;
+       spin_lock_irqsave(&spi_eeprom_lock, flags);
+       stat = spi_eeprom_io(chipid, inbufs, incounts, outbufs, outcounts);
+       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+       return stat;
+}
+
+int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len)
+{
+       unsigned char inbuf[2];
+       unsigned char *inbufs[2];
+       unsigned int incounts[3];
+       unsigned long flags;
+       int i, stat;
+
+       if (address / 8 != (address + len - 1) / 8)
+               return -EINVAL;
+       stat = spi_eeprom_write_enable(chipid, 1);
+       if (stat < 0)
+               return stat;
+       stat = spi_eeprom_read_status(chipid);
+       if (stat < 0)
+               return stat;
+       if (!(stat & ATMEL_SR_WEN))
+               return -EPERM;
+
+       inbuf[0] = ATMEL_WRITE;
+       inbuf[1] = address;
+       inbufs[0] = inbuf;
+       inbufs[1] = buf;
+       incounts[0] = sizeof(inbuf);
+       incounts[1] = len;
+       incounts[2] = 0;
+       spin_lock_irqsave(&spi_eeprom_lock, flags);
+       stat = spi_eeprom_io(chipid, inbufs, incounts, NULL, NULL);
+       if (stat < 0)
+               goto unlock_return;
+
+       /* write start.  max 10ms */
+       for (i = 10; i > 0; i--) {
+               int stat = spi_eeprom_read_status_nolock(chipid);
+               if (stat < 0)
+                       goto unlock_return;
+               if (!(stat & ATMEL_SR_BSY))
+                       break;
+               mdelay(1);
+       }
+       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+       if (i == 0)
+               return -EIO;
+       return len;
+ unlock_return:
+       spin_unlock_irqrestore(&spi_eeprom_lock, flags);
+       return stat;
+}
+
+#ifdef CONFIG_PROC_FS
+#define MAX_SIZE       0x80    /* for ATMEL 25010 */
+static int spi_eeprom_read_proc(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+       unsigned int size = MAX_SIZE;
+       if (spi_eeprom_read((int)data, 0, (unsigned char *)page, size) < 0)
+               size = 0;
+       return size;
+}
+
+static int spi_eeprom_write_proc(struct file *file, const char *buffer,
+                                unsigned long count, void *data)
+{
+       unsigned int size = MAX_SIZE;
+       int i;
+       if (file->f_pos >= size)
+               return -EIO;
+       if (file->f_pos + count > size)
+               count = size - file->f_pos;
+       for (i = 0; i < count; i += 8) {
+               int len = count - i < 8 ? count - i : 8;
+               if (spi_eeprom_write((int)data, file->f_pos,
+                                    (unsigned char *)buffer, len) < 0) {
+                       count = -EIO;
+                       break;
+               }
+               buffer += len;
+               file->f_pos += len;
+       }
+       return count;
+}
+
+__init void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid)
+{
+       struct proc_dir_entry *entry;
+       char name[128];
+       sprintf(name, "seeprom-%d", chipid);
+       entry = create_proc_entry(name, 0600, dir);
+       if (entry) {
+               entry->read_proc = spi_eeprom_read_proc;
+               entry->write_proc = spi_eeprom_write_proc;
+               entry->data = (void *)chipid;
+       }
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
new file mode 100644 (file)
index 0000000..fae3136
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <asm/tx4938/spi.h>
+#include <asm/tx4938/tx4938.h>
+
+static int (*txx9_spi_cs_func)(int chipid, int on);
+static DEFINE_SPINLOCK(txx9_spi_lock);
+
+extern unsigned int txx9_gbus_clock;
+
+#define SPI_FIFO_SIZE  4
+
+void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on))
+{
+       txx9_spi_cs_func = cs_func;
+       /* enter config mode */
+       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
+static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       /* disable rx intr */
+       tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
+       wake_up(&txx9_spi_wait);
+}
+static struct irqaction txx9_spi_action = {
+       txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
+};
+
+void __init txx9_spi_irqinit(int irc_irq)
+{
+       setup_irq(irc_irq, &txx9_spi_action);
+}
+
+int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+               unsigned char **inbufs, unsigned int *incounts,
+               unsigned char **outbufs, unsigned int *outcounts,
+               int cansleep)
+{
+       unsigned int incount, outcount;
+       unsigned char *inp, *outp;
+       int ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&txx9_spi_lock, flags);
+       if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {
+               spin_unlock_irqrestore(&txx9_spi_lock, flags);
+               return -EBUSY;
+       }
+       /* enter config mode */
+       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+       tx4938_spiptr->cr0 =
+               (desc->byteorder ? TXx9_SPCR0_SBOS : 0) |
+               (desc->polarity ? TXx9_SPCR0_SPOL : 0) |
+               (desc->phase ? TXx9_SPCR0_SPHA : 0) |
+               0x08;
+       tx4938_spiptr->cr1 =
+               (((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |
+               0x08 /* 8 bit only */;
+       /* enter active mode */
+       tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;
+       spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+       /* CS ON */
+       if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {
+               spin_unlock_irqrestore(&txx9_spi_lock, flags);
+               return ret;
+       }
+       udelay(desc->tcss);
+
+       /* do scatter IO */
+       inp = inbufs ? *inbufs : NULL;
+       outp = outbufs ? *outbufs : NULL;
+       incount = 0;
+       outcount = 0;
+       while (1) {
+               unsigned char data;
+               unsigned int count;
+               int i;
+               if (!incount) {
+                       incount = incounts ? *incounts++ : 0;
+                       inp = (incount && inbufs) ? *inbufs++ : NULL;
+               }
+               if (!outcount) {
+                       outcount = outcounts ? *outcounts++ : 0;
+                       outp = (outcount && outbufs) ? *outbufs++ : NULL;
+               }
+               if (!inp && !outp)
+                       break;
+               count = SPI_FIFO_SIZE;
+               if (incount)
+                       count = min(count, incount);
+               if (outcount)
+                       count = min(count, outcount);
+
+               /* now tx must be idle... */
+               while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))
+                       ;
+
+               tx4938_spiptr->cr0 =
+                       (tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |
+                       ((count - 1) << 12);
+               if (cansleep) {
+                       /* enable rx intr */
+                       tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;
+               }
+               /* send */
+               for (i = 0; i < count; i++)
+                       tx4938_spiptr->dr = inp ? *inp++ : 0;
+               /* wait all rx data */
+               if (cansleep) {
+                       wait_event(txx9_spi_wait,
+                                  tx4938_spiptr->sr & TXx9_SPSR_SRRDY);
+               } else {
+                       while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))
+                               ;
+               }
+               /* receive */
+               for (i = 0; i < count; i++) {
+                       data = tx4938_spiptr->dr;
+                       if (outp)
+                               *outp++ = data;
+               }
+               if (incount)
+                       incount -= count;
+               if (outcount)
+                       outcount -= count;
+       }
+
+       /* CS OFF */
+       udelay(desc->tcsh);
+       txx9_spi_cs_func(chipid, 0);
+       udelay(desc->tcsr);
+
+       spin_lock_irqsave(&txx9_spi_lock, flags);
+       /* enter config mode */
+       tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;
+       spin_unlock_irqrestore(&txx9_spi_lock, flags);
+
+       return 0;
+}
index 3870a76efc3bd4e364b0b665e2dd8a6d7406f1ba..14fc88f2722640bc364ad563f700cffc22e171c8 100644 (file)
 #define  MACH_TOSHIBA_JMR3927  3       /* JMR-TX3927 CPU/IO board */
 #define  MACH_TOSHIBA_RBTX4927 4
 #define  MACH_TOSHIBA_RBTX4937 5
+#define  MACH_TOSHIBA_RBTX4938 6
 
 #define GROUP_TOSHIBA_NAMES    { "Pallas", "TopasCE", "JMR", "JMR TX3927", \
                                  "RBTX4927", "RBTX4937" }
diff --git a/include/asm-mips/tx4938/rbtx4938.h b/include/asm-mips/tx4938/rbtx4938.h
new file mode 100644 (file)
index 0000000..0fbedaf
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * linux/include/asm-mips/tx4938/rbtx4938.h
+ * Definitions for TX4937/TX4938
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_RBTX4938_H
+#define __ASM_TX_BOARDS_RBTX4938_H
+
+#include <asm/addrspace.h>
+#include <asm/tx4938/tx4938.h>
+
+/* CS */
+#define RBTX4938_CE0   0x1c000000      /* 64M */
+#define RBTX4938_CE2   0x17f00000      /* 1M */
+
+/* Address map */
+#define RBTX4938_FPGA_REG_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000000)
+#define RBTX4938_FPGA_REV_ADDR (KSEG1 + RBTX4938_CE2 + 0x00000002)
+#define RBTX4938_CONFIG1_ADDR  (KSEG1 + RBTX4938_CE2 + 0x00000004)
+#define RBTX4938_CONFIG2_ADDR  (KSEG1 + RBTX4938_CE2 + 0x00000006)
+#define RBTX4938_CONFIG3_ADDR  (KSEG1 + RBTX4938_CE2 + 0x00000008)
+#define RBTX4938_LED_ADDR      (KSEG1 + RBTX4938_CE2 + 0x00001000)
+#define RBTX4938_DIPSW_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00001002)
+#define RBTX4938_BDIPSW_ADDR   (KSEG1 + RBTX4938_CE2 + 0x00001004)
+#define RBTX4938_IMASK_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00002000)
+#define RBTX4938_IMASK2_ADDR   (KSEG1 + RBTX4938_CE2 + 0x00002002)
+#define RBTX4938_INTPOL_ADDR   (KSEG1 + RBTX4938_CE2 + 0x00002004)
+#define RBTX4938_ISTAT_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00002006)
+#define RBTX4938_ISTAT2_ADDR   (KSEG1 + RBTX4938_CE2 + 0x00002008)
+#define RBTX4938_IMSTAT_ADDR   (KSEG1 + RBTX4938_CE2 + 0x0000200a)
+#define RBTX4938_IMSTAT2_ADDR  (KSEG1 + RBTX4938_CE2 + 0x0000200c)
+#define RBTX4938_SOFTINT_ADDR  (KSEG1 + RBTX4938_CE2 + 0x00003000)
+#define RBTX4938_PIOSEL_ADDR   (KSEG1 + RBTX4938_CE2 + 0x00005000)
+#define RBTX4938_SPICS_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00005002)
+#define RBTX4938_SFPWR_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00005008)
+#define RBTX4938_SFVOL_ADDR    (KSEG1 + RBTX4938_CE2 + 0x0000500a)
+#define RBTX4938_SOFTRESET_ADDR        (KSEG1 + RBTX4938_CE2 + 0x00007000)
+#define RBTX4938_SOFTRESETLOCK_ADDR    (KSEG1 + RBTX4938_CE2 + 0x00007002)
+#define RBTX4938_PCIRESET_ADDR (KSEG1 + RBTX4938_CE2 + 0x00007004)
+#define RBTX4938_ETHER_BASE    (KSEG1 + RBTX4938_CE2 + 0x00020000)
+
+/* Ethernet port address (Jumperless Mode (W12:Open)) */
+#define RBTX4938_ETHER_ADDR    (RBTX4938_ETHER_BASE + 0x280)
+
+/* bits for ISTAT/IMASK/IMSTAT */
+#define RBTX4938_INTB_PCID     0
+#define RBTX4938_INTB_PCIC     1
+#define RBTX4938_INTB_PCIB     2
+#define RBTX4938_INTB_PCIA     3
+#define RBTX4938_INTB_RTC      4
+#define RBTX4938_INTB_ATA      5
+#define RBTX4938_INTB_MODEM    6
+#define RBTX4938_INTB_SWINT    7
+#define RBTX4938_INTF_PCID     (1 << RBTX4938_INTB_PCID)
+#define RBTX4938_INTF_PCIC     (1 << RBTX4938_INTB_PCIC)
+#define RBTX4938_INTF_PCIB     (1 << RBTX4938_INTB_PCIB)
+#define RBTX4938_INTF_PCIA     (1 << RBTX4938_INTB_PCIA)
+#define RBTX4938_INTF_RTC      (1 << RBTX4938_INTB_RTC)
+#define RBTX4938_INTF_ATA      (1 << RBTX4938_INTB_ATA)
+#define RBTX4938_INTF_MODEM    (1 << RBTX4938_INTB_MODEM)
+#define RBTX4938_INTF_SWINT    (1 << RBTX4938_INTB_SWINT)
+
+#define rbtx4938_fpga_rev_ptr  \
+       ((volatile unsigned char *)RBTX4938_FPGA_REV_ADDR)
+#define rbtx4938_led_ptr       \
+       ((volatile unsigned char *)RBTX4938_LED_ADDR)
+#define rbtx4938_dipsw_ptr     \
+       ((volatile unsigned char *)RBTX4938_DIPSW_ADDR)
+#define rbtx4938_bdipsw_ptr    \
+       ((volatile unsigned char *)RBTX4938_BDIPSW_ADDR)
+#define rbtx4938_imask_ptr     \
+       ((volatile unsigned char *)RBTX4938_IMASK_ADDR)
+#define rbtx4938_imask2_ptr    \
+       ((volatile unsigned char *)RBTX4938_IMASK2_ADDR)
+#define rbtx4938_intpol_ptr    \
+       ((volatile unsigned char *)RBTX4938_INTPOL_ADDR)
+#define rbtx4938_istat_ptr     \
+       ((volatile unsigned char *)RBTX4938_ISTAT_ADDR)
+#define rbtx4938_istat2_ptr    \
+       ((volatile unsigned char *)RBTX4938_ISTAT2_ADDR)
+#define rbtx4938_imstat_ptr    \
+       ((volatile unsigned char *)RBTX4938_IMSTAT_ADDR)
+#define rbtx4938_imstat2_ptr   \
+       ((volatile unsigned char *)RBTX4938_IMSTAT2_ADDR)
+#define rbtx4938_softint_ptr   \
+       ((volatile unsigned char *)RBTX4938_SOFTINT_ADDR)
+#define rbtx4938_piosel_ptr    \
+       ((volatile unsigned char *)RBTX4938_PIOSEL_ADDR)
+#define rbtx4938_spics_ptr     \
+       ((volatile unsigned char *)RBTX4938_SPICS_ADDR)
+#define rbtx4938_sfpwr_ptr     \
+       ((volatile unsigned char *)RBTX4938_SFPWR_ADDR)
+#define rbtx4938_sfvol_ptr     \
+       ((volatile unsigned char *)RBTX4938_SFVOL_ADDR)
+#define rbtx4938_softreset_ptr \
+       ((volatile unsigned char *)RBTX4938_SOFTRESET_ADDR)
+#define rbtx4938_softresetlock_ptr     \
+       ((volatile unsigned char *)RBTX4938_SOFTRESETLOCK_ADDR)
+#define rbtx4938_pcireset_ptr  \
+       ((volatile unsigned char *)RBTX4938_PCIRESET_ADDR)
+
+/* SPI */
+#define RBTX4938_SEEPROM1_CHIPID       0
+#define RBTX4938_SEEPROM2_CHIPID       1
+#define RBTX4938_SEEPROM3_CHIPID       2
+#define RBTX4938_SRTC_CHIPID   3
+
+/*
+ * IRQ mappings
+ */
+
+#define RBTX4938_SOFT_INT0     0       /* not used */
+#define RBTX4938_SOFT_INT1     1       /* not used */
+#define RBTX4938_IRC_INT       2
+#define RBTX4938_TIMER_INT     7
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an RBTX4938 machine.  Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define RBTX4938_NR_IRQ_LOCAL  8
+#define RBTX4938_NR_IRQ_IRC    32      /* On-Chip IRC */
+#define RBTX4938_NR_IRQ_IOC    8
+
+#define MI8259_IRQ_ISA_RAW_BEG   0     /* optional backplane i8259 */
+#define MI8259_IRQ_ISA_RAW_END  15
+#define TX4938_IRQ_CP0_RAW_BEG   0     /* tx4938 cpu built-in cp0 */
+#define TX4938_IRQ_CP0_RAW_END   7
+#define TX4938_IRQ_PIC_RAW_BEG   0     /* tx4938 cpu build-in pic */
+#define TX4938_IRQ_PIC_RAW_END  31
+
+#define MI8259_IRQ_ISA_BEG                          MI8259_IRQ_ISA_RAW_BEG     /*  0 */
+#define MI8259_IRQ_ISA_END                          MI8259_IRQ_ISA_RAW_END     /* 15 */
+
+#define TX4938_IRQ_CP0_BEG  ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_BEG)    /* 16 */
+#define TX4938_IRQ_CP0_END  ((MI8259_IRQ_ISA_END+1)+TX4938_IRQ_CP0_RAW_END)    /* 23 */
+
+#define TX4938_IRQ_PIC_BEG  ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_BEG)    /* 24 */
+#define TX4938_IRQ_PIC_END  ((TX4938_IRQ_CP0_END+1)+TX4938_IRQ_PIC_RAW_END)    /* 55 */
+#define TX4938_IRQ_NEST_EXT_ON_PIC  (TX4938_IRQ_PIC_BEG+2)
+#define TX4938_IRQ_NEST_PIC_ON_CP0  (TX4938_IRQ_CP0_BEG+2)
+#define TX4938_IRQ_USER0            (TX4938_IRQ_CP0_BEG+0)
+#define TX4938_IRQ_USER1            (TX4938_IRQ_CP0_BEG+1)
+#define TX4938_IRQ_CPU_TIMER        (TX4938_IRQ_CP0_BEG+7)
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG   0
+#define TOSHIBA_RBTX4938_IRQ_IOC_RAW_END   7
+
+#define TOSHIBA_RBTX4938_IRQ_IOC_BEG  ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_BEG) /* 56 */
+#define TOSHIBA_RBTX4938_IRQ_IOC_END  ((TX4938_IRQ_PIC_END+1)+TOSHIBA_RBTX4938_IRQ_IOC_RAW_END) /* 63 */
+#define RBTX4938_IRQ_LOCAL     TX4938_IRQ_CP0_BEG
+#define RBTX4938_IRQ_IRC       (RBTX4938_IRQ_LOCAL + RBTX4938_NR_IRQ_LOCAL)
+#define RBTX4938_IRQ_IOC       (RBTX4938_IRQ_IRC + RBTX4938_NR_IRQ_IRC)
+#define RBTX4938_IRQ_END       (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC)
+
+#define RBTX4938_IRQ_LOCAL_SOFT0       (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT0)
+#define RBTX4938_IRQ_LOCAL_SOFT1       (RBTX4938_IRQ_LOCAL + RBTX4938_SOFT_INT1)
+#define RBTX4938_IRQ_LOCAL_IRC (RBTX4938_IRQ_LOCAL + RBTX4938_IRC_INT)
+#define RBTX4938_IRQ_LOCAL_TIMER       (RBTX4938_IRQ_LOCAL + RBTX4938_TIMER_INT)
+#define RBTX4938_IRQ_IRC_ECCERR        (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR)
+#define RBTX4938_IRQ_IRC_WTOERR        (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR)
+#define RBTX4938_IRQ_IRC_INT(n)        (RBTX4938_IRQ_IRC + TX4938_IR_INT(n))
+#define RBTX4938_IRQ_IRC_SIO(n)        (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n))
+#define RBTX4938_IRQ_IRC_DMA(ch,n)     (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch,n))
+#define RBTX4938_IRQ_IRC_PIO   (RBTX4938_IRQ_IRC + TX4938_IR_PIO)
+#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC)
+#define RBTX4938_IRQ_IRC_PCIC  (RBTX4938_IRQ_IRC + TX4938_IR_PCIC)
+#define RBTX4938_IRQ_IRC_TMR(n)        (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n))
+#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC)
+#define RBTX4938_IRQ_IRC_PCIERR        (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR)
+#define RBTX4938_IRQ_IRC_PCIPME        (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME)
+#define RBTX4938_IRQ_IRC_ACLC  (RBTX4938_IRQ_IRC + TX4938_IR_ACLC)
+#define RBTX4938_IRQ_IRC_ACLCPME       (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME)
+#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1)
+#define RBTX4938_IRQ_IRC_SPI   (RBTX4938_IRQ_IRC + TX4938_IR_SPI)
+#define RBTX4938_IRQ_IOC_PCID  (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID)
+#define RBTX4938_IRQ_IOC_PCIC  (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC)
+#define RBTX4938_IRQ_IOC_PCIB  (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB)
+#define RBTX4938_IRQ_IOC_PCIA  (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA)
+#define RBTX4938_IRQ_IOC_RTC   (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC)
+#define RBTX4938_IRQ_IOC_ATA   (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA)
+#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM)
+#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT)
+
+
+/* IOC (PCI, etc) */
+#define RBTX4938_IRQ_IOCINT    (TX4938_IRQ_NEST_EXT_ON_PIC)
+/* Onboard 10M Ether */
+#define RBTX4938_IRQ_ETHER     (TX4938_IRQ_NEST_EXT_ON_PIC + 1)
+
+#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base)
+#define RBTX4938_RTL_8019_IRQ  (RBTX4938_IRQ_ETHER)
+
+/* IRCR : Int. Control */
+#define TX4938_IRCR_LOW  0x00000000
+#define TX4938_IRCR_HIGH 0x00000001
+#define TX4938_IRCR_DOWN 0x00000002
+#define TX4938_IRCR_UP   0x00000003
+
+#endif /* __ASM_TX_BOARDS_RBTX4938_H */
diff --git a/include/asm-mips/tx4938/spi.h b/include/asm-mips/tx4938/spi.h
new file mode 100644 (file)
index 0000000..0dbbab8
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * linux/include/asm-mips/tx4938/spi.h
+ * Definitions for TX4937/TX4938 SPI
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_SPI_H
+#define __ASM_TX_BOARDS_TX4938_SPI_H
+
+/* SPI */
+struct spi_dev_desc {
+       unsigned int baud;
+       unsigned short tcss, tcsh, tcsr; /* CS setup/hold/recovery time */
+       unsigned int byteorder:1;       /* 0:LSB-First, 1:MSB-First */
+       unsigned int polarity:1;        /* 0:High-Active */
+       unsigned int phase:1;           /* 0:Sample-Then-Shift */
+};
+
+extern void txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)) __init;
+extern void txx9_spi_irqinit(int irc_irq) __init;
+extern int txx9_spi_io(int chipid, struct spi_dev_desc *desc,
+                      unsigned char **inbufs, unsigned int *incounts,
+                      unsigned char **outbufs, unsigned int *outcounts,
+                      int cansleep);
+extern int spi_eeprom_write_enable(int chipid, int enable);
+extern int spi_eeprom_read_status(int chipid);
+extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
+extern int spi_eeprom_write(int chipid, int address, unsigned char *buf, int len);
+extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid) __init;
+
+#define TXX9_IMCLK     (txx9_gbus_clock / 2)
+
+/*
+* SPI
+*/
+
+/* SPMCR : SPI Master Control */
+#define TXx9_SPMCR_OPMODE      0xc0
+#define TXx9_SPMCR_CONFIG      0x40
+#define TXx9_SPMCR_ACTIVE      0x80
+#define TXx9_SPMCR_SPSTP       0x02
+#define TXx9_SPMCR_BCLR        0x01
+
+/* SPCR0 : SPI Status */
+#define TXx9_SPCR0_TXIFL_MASK  0xc000
+#define TXx9_SPCR0_RXIFL_MASK  0x3000
+#define TXx9_SPCR0_SIDIE       0x0800
+#define TXx9_SPCR0_SOEIE       0x0400
+#define TXx9_SPCR0_RBSIE       0x0200
+#define TXx9_SPCR0_TBSIE       0x0100
+#define TXx9_SPCR0_IFSPSE      0x0010
+#define TXx9_SPCR0_SBOS        0x0004
+#define TXx9_SPCR0_SPHA        0x0002
+#define TXx9_SPCR0_SPOL        0x0001
+
+/* SPSR : SPI Status */
+#define TXx9_SPSR_TBSI 0x8000
+#define TXx9_SPSR_RBSI 0x4000
+#define TXx9_SPSR_TBS_MASK     0x3800
+#define TXx9_SPSR_RBS_MASK     0x0700
+#define TXx9_SPSR_SPOE 0x0080
+#define TXx9_SPSR_IFSD 0x0008
+#define TXx9_SPSR_SIDLE        0x0004
+#define TXx9_SPSR_STRDY        0x0002
+#define TXx9_SPSR_SRRDY        0x0001
+
+#endif /* __ASM_TX_BOARDS_TX4938_SPI_H */
diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h
new file mode 100644 (file)
index 0000000..e25b1a0
--- /dev/null
@@ -0,0 +1,706 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938.h
+ * Definitions for TX4937/TX4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TX_BOARDS_TX4938_H
+#define __ASM_TX_BOARDS_TX4938_H
+
+#include <asm/tx4938/tx4938_mips.h>
+
+#define tx4938_read_nfmc(addr) (*(volatile unsigned int *)(addr))
+#define tx4938_write_nfmc(b,addr) (*(volatile unsigned int *)(addr)) = (b)
+
+#define TX4938_NR_IRQ_LOCAL     TX4938_IRQ_PIC_BEG
+
+#define TX4938_IRQ_IRC_PCIC     (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIC)
+#define TX4938_IRQ_IRC_PCIERR   (TX4938_NR_IRQ_LOCAL + TX4938_IR_PCIERR)
+
+#define TX4938_PCIIO_0 0x10000000
+#define TX4938_PCIIO_1 0x01010000
+#define TX4938_PCIMEM_0 0x08000000
+#define TX4938_PCIMEM_1 0x11000000
+
+#define TX4938_PCIIO_SIZE_0 0x01000000
+#define TX4938_PCIIO_SIZE_1 0x00010000
+#define TX4938_PCIMEM_SIZE_0 0x08000000
+#define TX4938_PCIMEM_SIZE_1 0x00010000
+
+#define TX4938_REG_BASE        0xff1f0000 /* == TX4937_REG_BASE */
+#define TX4938_REG_SIZE        0x00010000 /* == TX4937_REG_SIZE */
+
+/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */
+#define TX4938_NDFMC_REG       (TX4938_REG_BASE + 0x5000)
+#define TX4938_SRAMC_REG       (TX4938_REG_BASE + 0x6000)
+#define TX4938_PCIC1_REG       (TX4938_REG_BASE + 0x7000)
+#define TX4938_SDRAMC_REG      (TX4938_REG_BASE + 0x8000)
+#define TX4938_EBUSC_REG       (TX4938_REG_BASE + 0x9000)
+#define TX4938_DMA_REG(ch)     (TX4938_REG_BASE + 0xb000 + (ch) * 0x800)
+#define TX4938_PCIC_REG                (TX4938_REG_BASE + 0xd000)
+#define TX4938_CCFG_REG                (TX4938_REG_BASE + 0xe000)
+#define TX4938_NR_TMR  3
+#define TX4938_TMR_REG(ch)     ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100)
+#define TX4938_NR_SIO  2
+#define TX4938_SIO_REG(ch)     ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100)
+#define TX4938_PIO_REG         (TX4938_REG_BASE + 0xf500)
+#define TX4938_IRC_REG         (TX4938_REG_BASE + 0xf600)
+#define TX4938_ACLC_REG                (TX4938_REG_BASE + 0xf700)
+#define TX4938_SPI_REG         (TX4938_REG_BASE + 0xf800)
+
+#ifndef _LANGUAGE_ASSEMBLY
+#include <asm/byteorder.h>
+
+#define TX4938_MKA(x) ((u32)( ((u32)(TX4938_REG_BASE)) | ((u32)(x)) ))
+
+#define TX4938_RD08( reg      )   (*(vu08*)(reg))
+#define TX4938_WR08( reg, val )  ((*(vu08*)(reg))=(val))
+
+#define TX4938_RD16( reg      )   (*(vu16*)(reg))
+#define TX4938_WR16( reg, val )  ((*(vu16*)(reg))=(val))
+
+#define TX4938_RD32( reg      )   (*(vu32*)(reg))
+#define TX4938_WR32( reg, val )  ((*(vu32*)(reg))=(val))
+
+#define TX4938_RD64( reg      )   (*(vu64*)(reg))
+#define TX4938_WR64( reg, val )  ((*(vu64*)(reg))=(val))
+
+#define TX4938_RD( reg      ) TX4938_RD32( reg )
+#define TX4938_WR( reg, val ) TX4938_WR32( reg, val )
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+#define _CONST64(c)    c
+#else
+#define _CONST64(c)    c##ull
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+#define endian_def_l2(e1,e2)   \
+       volatile unsigned long e1,e2
+#define endian_def_s2(e1,e2)   \
+       volatile unsigned short e1,e2
+#define endian_def_sb2(e1,e2,e3)       \
+       volatile unsigned short e1;volatile unsigned char e2,e3
+#define endian_def_b2s(e1,e2,e3)       \
+       volatile unsigned char e1,e2;volatile unsigned short e3
+#define endian_def_b4(e1,e2,e3,e4)     \
+       volatile unsigned char e1,e2,e3,e4
+#else
+#define endian_def_l2(e1,e2)   \
+       volatile unsigned long e2,e1
+#define endian_def_s2(e1,e2)   \
+       volatile unsigned short e2,e1
+#define endian_def_sb2(e1,e2,e3)       \
+       volatile unsigned char e3,e2;volatile unsigned short e1
+#define endian_def_b2s(e1,e2,e3)       \
+       volatile unsigned short e3;volatile unsigned char e2,e1
+#define endian_def_b4(e1,e2,e3,e4)     \
+       volatile unsigned char e4,e3,e2,e1
+#endif
+
+
+struct tx4938_sdramc_reg {
+       volatile unsigned long long cr[4];
+       volatile unsigned long long unused0[4];
+       volatile unsigned long long tr;
+       volatile unsigned long long unused1[2];
+       volatile unsigned long long cmd;
+       volatile unsigned long long sfcmd;
+};
+
+struct tx4938_ebusc_reg {
+       volatile unsigned long long cr[8];
+};
+
+struct tx4938_dma_reg {
+       struct tx4938_dma_ch_reg {
+               volatile unsigned long long cha;
+               volatile unsigned long long sar;
+               volatile unsigned long long dar;
+               endian_def_l2(unused0, cntr);
+               endian_def_l2(unused1, sair);
+               endian_def_l2(unused2, dair);
+               endian_def_l2(unused3, ccr);
+               endian_def_l2(unused4, csr);
+       } ch[4];
+       volatile unsigned long long dbr[8];
+       volatile unsigned long long tdhr;
+       volatile unsigned long long midr;
+       endian_def_l2(unused0, mcr);
+};
+
+struct tx4938_pcic_reg {
+       volatile unsigned long pciid;
+       volatile unsigned long pcistatus;
+       volatile unsigned long pciccrev;
+       volatile unsigned long pcicfg1;
+       volatile unsigned long p2gm0plbase;             /* +10 */
+       volatile unsigned long p2gm0pubase;
+       volatile unsigned long p2gm1plbase;
+       volatile unsigned long p2gm1pubase;
+       volatile unsigned long p2gm2pbase;              /* +20 */
+       volatile unsigned long p2giopbase;
+       volatile unsigned long unused0;
+       volatile unsigned long pcisid;
+       volatile unsigned long unused1;         /* +30 */
+       volatile unsigned long pcicapptr;
+       volatile unsigned long unused2;
+       volatile unsigned long pcicfg2;
+       volatile unsigned long g2ptocnt;                /* +40 */
+       volatile unsigned long unused3[15];
+       volatile unsigned long g2pstatus;               /* +80 */
+       volatile unsigned long g2pmask;
+       volatile unsigned long pcisstatus;
+       volatile unsigned long pcimask;
+       volatile unsigned long p2gcfg;          /* +90 */
+       volatile unsigned long p2gstatus;
+       volatile unsigned long p2gmask;
+       volatile unsigned long p2gccmd;
+       volatile unsigned long unused4[24];             /* +a0 */
+       volatile unsigned long pbareqport;              /* +100 */
+       volatile unsigned long pbacfg;
+       volatile unsigned long pbastatus;
+       volatile unsigned long pbamask;
+       volatile unsigned long pbabm;           /* +110 */
+       volatile unsigned long pbacreq;
+       volatile unsigned long pbacgnt;
+       volatile unsigned long pbacstate;
+       volatile unsigned long long g2pmgbase[3];               /* +120 */
+       volatile unsigned long long g2piogbase;
+       volatile unsigned long g2pmmask[3];             /* +140 */
+       volatile unsigned long g2piomask;
+       volatile unsigned long long g2pmpbase[3];               /* +150 */
+       volatile unsigned long long g2piopbase;
+       volatile unsigned long pciccfg;         /* +170 */
+       volatile unsigned long pcicstatus;
+       volatile unsigned long pcicmask;
+       volatile unsigned long unused5;
+       volatile unsigned long long p2gmgbase[3];               /* +180 */
+       volatile unsigned long long p2giogbase;
+       volatile unsigned long g2pcfgadrs;              /* +1a0 */
+       volatile unsigned long g2pcfgdata;
+       volatile unsigned long unused6[8];
+       volatile unsigned long g2pintack;
+       volatile unsigned long g2pspc;
+       volatile unsigned long unused7[12];             /* +1d0 */
+       volatile unsigned long long pdmca;              /* +200 */
+       volatile unsigned long long pdmga;
+       volatile unsigned long long pdmpa;
+       volatile unsigned long long pdmctr;
+       volatile unsigned long long pdmcfg;             /* +220 */
+       volatile unsigned long long pdmsts;
+};
+
+struct tx4938_aclc_reg {
+       volatile unsigned long acctlen;
+       volatile unsigned long acctldis;
+       volatile unsigned long acregacc;
+       volatile unsigned long unused0;
+       volatile unsigned long acintsts;
+       volatile unsigned long acintmsts;
+       volatile unsigned long acinten;
+       volatile unsigned long acintdis;
+       volatile unsigned long acsemaph;
+       volatile unsigned long unused1[7];
+       volatile unsigned long acgpidat;
+       volatile unsigned long acgpodat;
+       volatile unsigned long acslten;
+       volatile unsigned long acsltdis;
+       volatile unsigned long acfifosts;
+       volatile unsigned long unused2[11];
+       volatile unsigned long acdmasts;
+       volatile unsigned long acdmasel;
+       volatile unsigned long unused3[6];
+       volatile unsigned long acaudodat;
+       volatile unsigned long acsurrdat;
+       volatile unsigned long accentdat;
+       volatile unsigned long aclfedat;
+       volatile unsigned long acaudiat;
+       volatile unsigned long unused4;
+       volatile unsigned long acmodoat;
+       volatile unsigned long acmodidat;
+       volatile unsigned long unused5[15];
+       volatile unsigned long acrevid;
+};
+
+
+struct tx4938_tmr_reg {
+       volatile unsigned long tcr;
+       volatile unsigned long tisr;
+       volatile unsigned long cpra;
+       volatile unsigned long cprb;
+       volatile unsigned long itmr;
+       volatile unsigned long unused0[3];
+       volatile unsigned long ccdr;
+       volatile unsigned long unused1[3];
+       volatile unsigned long pgmr;
+       volatile unsigned long unused2[3];
+       volatile unsigned long wtmr;
+       volatile unsigned long unused3[43];
+       volatile unsigned long trr;
+};
+
+struct tx4938_sio_reg {
+       volatile unsigned long lcr;
+       volatile unsigned long dicr;
+       volatile unsigned long disr;
+       volatile unsigned long cisr;
+       volatile unsigned long fcr;
+       volatile unsigned long flcr;
+       volatile unsigned long bgr;
+       volatile unsigned long tfifo;
+       volatile unsigned long rfifo;
+};
+
+struct tx4938_pio_reg {
+       volatile unsigned long dout;
+       volatile unsigned long din;
+       volatile unsigned long dir;
+       volatile unsigned long od;
+       volatile unsigned long flag[2];
+       volatile unsigned long pol;
+       volatile unsigned long intc;
+       volatile unsigned long maskcpu;
+       volatile unsigned long maskext;
+};
+struct tx4938_irc_reg {
+       volatile unsigned long cer;
+       volatile unsigned long cr[2];
+       volatile unsigned long unused0;
+       volatile unsigned long ilr[8];
+       volatile unsigned long unused1[4];
+       volatile unsigned long imr;
+       volatile unsigned long unused2[7];
+       volatile unsigned long scr;
+       volatile unsigned long unused3[7];
+       volatile unsigned long ssr;
+       volatile unsigned long unused4[7];
+       volatile unsigned long csr;
+};
+
+struct tx4938_ndfmc_reg {
+       endian_def_l2(unused0, dtr);
+       endian_def_l2(unused1, mcr);
+       endian_def_l2(unused2, sr);
+       endian_def_l2(unused3, isr);
+       endian_def_l2(unused4, imr);
+       endian_def_l2(unused5, spr);
+       endian_def_l2(unused6, rstr);
+};
+
+struct tx4938_spi_reg {
+       volatile unsigned long mcr;
+       volatile unsigned long cr0;
+       volatile unsigned long cr1;
+       volatile unsigned long fs;
+       volatile unsigned long unused1;
+       volatile unsigned long sr;
+       volatile unsigned long dr;
+       volatile unsigned long unused2;
+};
+
+struct tx4938_sramc_reg {
+       volatile unsigned long long cr;
+};
+
+struct tx4938_ccfg_reg {
+       volatile unsigned long long ccfg;
+       volatile unsigned long long crir;
+       volatile unsigned long long pcfg;
+       volatile unsigned long long tear;
+       volatile unsigned long long clkctr;
+       volatile unsigned long long unused0;
+       volatile unsigned long long garbc;
+       volatile unsigned long long unused1;
+       volatile unsigned long long unused2;
+       volatile unsigned long long ramp;
+       volatile unsigned long long unused3;
+       volatile unsigned long long jmpadr;
+};
+
+#undef endian_def_l2
+#undef endian_def_s2
+#undef endian_def_sb2
+#undef endian_def_b2s
+#undef endian_def_b4
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * NDFMC
+ */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TX4938_NDFMCR_WE       0x80
+#define TX4938_NDFMCR_ECC_ALL  0x60
+#define TX4938_NDFMCR_ECC_RESET        0x60
+#define TX4938_NDFMCR_ECC_READ 0x40
+#define TX4938_NDFMCR_ECC_ON   0x20
+#define TX4938_NDFMCR_ECC_OFF  0x00
+#define TX4938_NDFMCR_CE       0x10
+#define TX4938_NDFMCR_BSPRT    0x04
+#define TX4938_NDFMCR_ALE      0x02
+#define TX4938_NDFMCR_CLE      0x01
+
+/* NDFMCR : NDFMC Status */
+#define TX4938_NDFSR_BUSY      0x80
+
+/* NDFMCR : NDFMC Reset */
+#define TX4938_NDFRSTR_RST     0x01
+
+/*
+ * IRC
+ */
+
+#define TX4938_IR_ECCERR       0
+#define TX4938_IR_WTOERR       1
+#define TX4938_NUM_IR_INT      6
+#define TX4938_IR_INT(n)       (2 + (n))
+#define TX4938_NUM_IR_SIO      2
+#define TX4938_IR_SIO(n)       (8 + (n))
+#define TX4938_NUM_IR_DMA      4
+#define TX4938_IR_DMA(ch,n)    ((ch ? 27 : 10) + (n)) /* 10-13,27-30 */
+#define TX4938_IR_PIO  14
+#define TX4938_IR_PDMAC        15
+#define TX4938_IR_PCIC 16
+#define TX4938_NUM_IR_TMR      3
+#define TX4938_IR_TMR(n)       (17 + (n))
+#define TX4938_IR_NDFMC        21
+#define TX4938_IR_PCIERR       22
+#define TX4938_IR_PCIPME       23
+#define TX4938_IR_ACLC 24
+#define TX4938_IR_ACLCPME      25
+#define TX4938_IR_PCIC1        26
+#define TX4938_IR_SPI  31
+#define TX4938_NUM_IR  32
+/* multiplex */
+#define TX4938_IR_ETH0 TX4938_IR_INT(4)
+#define TX4938_IR_ETH1 TX4938_IR_INT(3)
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4938_CCFG_WDRST      _CONST64(0x0000020000000000)
+#define TX4938_CCFG_WDREXEN    _CONST64(0x0000010000000000)
+#define TX4938_CCFG_BCFG_MASK  _CONST64(0x000000ff00000000)
+#define TX4938_CCFG_TINTDIS    0x01000000
+#define TX4938_CCFG_PCI66      0x00800000
+#define TX4938_CCFG_PCIMODE    0x00400000
+#define TX4938_CCFG_PCI1_66    0x00200000
+#define TX4938_CCFG_DIVMODE_MASK       0x001e0000
+#define TX4938_CCFG_DIVMODE_2  (0x4 << 17)
+#define TX4938_CCFG_DIVMODE_2_5        (0xf << 17)
+#define TX4938_CCFG_DIVMODE_3  (0x5 << 17)
+#define TX4938_CCFG_DIVMODE_4  (0x6 << 17)
+#define TX4938_CCFG_DIVMODE_4_5        (0xd << 17)
+#define TX4938_CCFG_DIVMODE_8  (0x0 << 17)
+#define TX4938_CCFG_DIVMODE_10 (0xb << 17)
+#define TX4938_CCFG_DIVMODE_12 (0x1 << 17)
+#define TX4938_CCFG_DIVMODE_16 (0x2 << 17)
+#define TX4938_CCFG_DIVMODE_18 (0x9 << 17)
+#define TX4938_CCFG_BEOW       0x00010000
+#define TX4938_CCFG_WR 0x00008000
+#define TX4938_CCFG_TOE        0x00004000
+#define TX4938_CCFG_PCIXARB    0x00002000
+#define TX4938_CCFG_PCIDIVMODE_MASK    0x00001c00
+#define TX4938_CCFG_PCIDIVMODE_4       (0x1 << 10)
+#define TX4938_CCFG_PCIDIVMODE_4_5     (0x3 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5       (0x5 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5_5     (0x7 << 10)
+#define TX4938_CCFG_PCIDIVMODE_8       (0x0 << 10)
+#define TX4938_CCFG_PCIDIVMODE_9       (0x2 << 10)
+#define TX4938_CCFG_PCIDIVMODE_10      (0x4 << 10)
+#define TX4938_CCFG_PCIDIVMODE_11      (0x6 << 10)
+#define TX4938_CCFG_PCI1DMD    0x00000100
+#define TX4938_CCFG_SYSSP_MASK 0x000000c0
+#define TX4938_CCFG_ENDIAN     0x00000004
+#define TX4938_CCFG_HALT       0x00000002
+#define TX4938_CCFG_ACEHOLD    0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX4938_PCFG_ETH0_SEL   _CONST64(0x8000000000000000)
+#define TX4938_PCFG_ETH1_SEL   _CONST64(0x4000000000000000)
+#define TX4938_PCFG_ATA_SEL    _CONST64(0x2000000000000000)
+#define TX4938_PCFG_ISA_SEL    _CONST64(0x1000000000000000)
+#define TX4938_PCFG_SPI_SEL    _CONST64(0x0800000000000000)
+#define TX4938_PCFG_NDF_SEL    _CONST64(0x0400000000000000)
+#define TX4938_PCFG_SDCLKDLY_MASK      0x30000000
+#define TX4938_PCFG_SDCLKDLY(d)        ((d)<<28)
+#define TX4938_PCFG_SYSCLKEN   0x08000000
+#define TX4938_PCFG_SDCLKEN_ALL        0x07800000
+#define TX4938_PCFG_SDCLKEN(ch)        (0x00800000<<(ch))
+#define TX4938_PCFG_PCICLKEN_ALL       0x003f0000
+#define TX4938_PCFG_PCICLKEN(ch)       (0x00010000<<(ch))
+#define TX4938_PCFG_SEL2       0x00000200
+#define TX4938_PCFG_SEL1       0x00000100
+#define TX4938_PCFG_DMASEL_ALL 0x0000000f
+#define TX4938_PCFG_DMASEL0_DRQ0       0x00000000
+#define TX4938_PCFG_DMASEL0_SIO1       0x00000001
+#define TX4938_PCFG_DMASEL1_DRQ1       0x00000000
+#define TX4938_PCFG_DMASEL1_SIO1       0x00000002
+#define TX4938_PCFG_DMASEL2_DRQ2       0x00000000
+#define TX4938_PCFG_DMASEL2_SIO0       0x00000004
+#define TX4938_PCFG_DMASEL3_DRQ3       0x00000000
+#define TX4938_PCFG_DMASEL3_SIO0       0x00000008
+
+/* CLKCTR : Clock Control */
+#define TX4938_CLKCTR_NDFCKD   _CONST64(0x0001000000000000)
+#define TX4938_CLKCTR_NDFRST   _CONST64(0x0000000100000000)
+#define TX4938_CLKCTR_ETH1CKD  0x80000000
+#define TX4938_CLKCTR_ETH0CKD  0x40000000
+#define TX4938_CLKCTR_SPICKD   0x20000000
+#define TX4938_CLKCTR_SRAMCKD  0x10000000
+#define TX4938_CLKCTR_PCIC1CKD 0x08000000
+#define TX4938_CLKCTR_DMA1CKD  0x04000000
+#define TX4938_CLKCTR_ACLCKD   0x02000000
+#define TX4938_CLKCTR_PIOCKD   0x01000000
+#define TX4938_CLKCTR_DMACKD   0x00800000
+#define TX4938_CLKCTR_PCICKD   0x00400000
+#define TX4938_CLKCTR_TM0CKD   0x00100000
+#define TX4938_CLKCTR_TM1CKD   0x00080000
+#define TX4938_CLKCTR_TM2CKD   0x00040000
+#define TX4938_CLKCTR_SIO0CKD  0x00020000
+#define TX4938_CLKCTR_SIO1CKD  0x00010000
+#define TX4938_CLKCTR_ETH1RST  0x00008000
+#define TX4938_CLKCTR_ETH0RST  0x00004000
+#define TX4938_CLKCTR_SPIRST   0x00002000
+#define TX4938_CLKCTR_SRAMRST  0x00001000
+#define TX4938_CLKCTR_PCIC1RST 0x00000800
+#define TX4938_CLKCTR_DMA1RST  0x00000400
+#define TX4938_CLKCTR_ACLRST   0x00000200
+#define TX4938_CLKCTR_PIORST   0x00000100
+#define TX4938_CLKCTR_DMARST   0x00000080
+#define TX4938_CLKCTR_PCIRST   0x00000040
+#define TX4938_CLKCTR_TM0RST   0x00000010
+#define TX4938_CLKCTR_TM1RST   0x00000008
+#define TX4938_CLKCTR_TM2RST   0x00000004
+#define TX4938_CLKCTR_SIO0RST  0x00000002
+#define TX4938_CLKCTR_SIO1RST  0x00000001
+
+/* bits for G2PSTATUS/G2PMASK */
+#define TX4938_PCIC_G2PSTATUS_ALL      0x00000003
+#define TX4938_PCIC_G2PSTATUS_TTOE     0x00000002
+#define TX4938_PCIC_G2PSTATUS_RTOE     0x00000001
+
+/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */
+#define TX4938_PCIC_PCISTATUS_ALL      0x0000f900
+
+/* bits for PBACFG */
+#define TX4938_PCIC_PBACFG_FIXPA       0x00000008
+#define TX4938_PCIC_PBACFG_RPBA        0x00000004
+#define TX4938_PCIC_PBACFG_PBAEN       0x00000002
+#define TX4938_PCIC_PBACFG_BMCEN       0x00000001
+
+/* bits for G2PMnGBASE */
+#define TX4938_PCIC_G2PMnGBASE_BSDIS   _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PMnGBASE_ECHG    _CONST64(0x0000001000000000)
+
+/* bits for G2PIOGBASE */
+#define TX4938_PCIC_G2PIOGBASE_BSDIS   _CONST64(0x0000002000000000)
+#define TX4938_PCIC_G2PIOGBASE_ECHG    _CONST64(0x0000001000000000)
+
+/* bits for PCICSTATUS/PCICMASK */
+#define TX4938_PCIC_PCICSTATUS_ALL     0x000007b8
+#define TX4938_PCIC_PCICSTATUS_PME     0x00000400
+#define TX4938_PCIC_PCICSTATUS_TLB     0x00000200
+#define TX4938_PCIC_PCICSTATUS_NIB     0x00000100
+#define TX4938_PCIC_PCICSTATUS_ZIB     0x00000080
+#define TX4938_PCIC_PCICSTATUS_PERR    0x00000020
+#define TX4938_PCIC_PCICSTATUS_SERR    0x00000010
+#define TX4938_PCIC_PCICSTATUS_GBE     0x00000008
+#define TX4938_PCIC_PCICSTATUS_IWB     0x00000002
+#define TX4938_PCIC_PCICSTATUS_E2PDONE 0x00000001
+
+/* bits for PCICCFG */
+#define TX4938_PCIC_PCICCFG_GBWC_MASK  0x0fff0000
+#define TX4938_PCIC_PCICCFG_HRST       0x00000800
+#define TX4938_PCIC_PCICCFG_SRST       0x00000400
+#define TX4938_PCIC_PCICCFG_IRBER      0x00000200
+#define TX4938_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch))
+#define TX4938_PCIC_PCICCFG_G2PM0EN    0x00000100
+#define TX4938_PCIC_PCICCFG_G2PM1EN    0x00000080
+#define TX4938_PCIC_PCICCFG_G2PM2EN    0x00000040
+#define TX4938_PCIC_PCICCFG_G2PIOEN    0x00000020
+#define TX4938_PCIC_PCICCFG_TCAR       0x00000010
+#define TX4938_PCIC_PCICCFG_ICAEN      0x00000008
+
+/* bits for P2GMnGBASE */
+#define TX4938_PCIC_P2GMnGBASE_TMEMEN  _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GMnGBASE_TBSDIS  _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GMnGBASE_TECHG   _CONST64(0x0000001000000000)
+
+/* bits for P2GIOGBASE */
+#define TX4938_PCIC_P2GIOGBASE_TIOEN   _CONST64(0x0000004000000000)
+#define TX4938_PCIC_P2GIOGBASE_TBSDIS  _CONST64(0x0000002000000000)
+#define TX4938_PCIC_P2GIOGBASE_TECHG   _CONST64(0x0000001000000000)
+
+#define TX4938_PCIC_IDSEL_AD_TO_SLOT(ad)       ((ad) - 11)
+#define TX4938_PCIC_MAX_DEVNU  TX4938_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/* bits for PDMCFG */
+#define TX4938_PCIC_PDMCFG_RSTFIFO     0x00200000
+#define TX4938_PCIC_PDMCFG_EXFER       0x00100000
+#define TX4938_PCIC_PDMCFG_REQDLY_MASK 0x00003800
+#define TX4938_PCIC_PDMCFG_REQDLY_NONE (0 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_16   (1 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_32   (2 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_64   (3 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_128  (4 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_256  (5 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_512  (6 << 11)
+#define TX4938_PCIC_PDMCFG_REQDLY_1024 (7 << 11)
+#define TX4938_PCIC_PDMCFG_ERRIE       0x00000400
+#define TX4938_PCIC_PDMCFG_NCCMPIE     0x00000200
+#define TX4938_PCIC_PDMCFG_NTCMPIE     0x00000100
+#define TX4938_PCIC_PDMCFG_CHNEN       0x00000080
+#define TX4938_PCIC_PDMCFG_XFRACT      0x00000040
+#define TX4938_PCIC_PDMCFG_BSWAP       0x00000020
+#define TX4938_PCIC_PDMCFG_XFRSIZE_MASK        0x0000000c
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000
+#define TX4938_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004
+#define TX4938_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008
+#define TX4938_PCIC_PDMCFG_XFRDIRC     0x00000002
+#define TX4938_PCIC_PDMCFG_CHRST       0x00000001
+
+/* bits for PDMSTS */
+#define TX4938_PCIC_PDMSTS_REQCNT_MASK 0x3f000000
+#define TX4938_PCIC_PDMSTS_FIFOCNT_MASK        0x00f00000
+#define TX4938_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000
+#define TX4938_PCIC_PDMSTS_FIFORP_MASK 0x00030000
+#define TX4938_PCIC_PDMSTS_ERRINT      0x00000800
+#define TX4938_PCIC_PDMSTS_DONEINT     0x00000400
+#define TX4938_PCIC_PDMSTS_CHNEN       0x00000200
+#define TX4938_PCIC_PDMSTS_XFRACT      0x00000100
+#define TX4938_PCIC_PDMSTS_ACCMP       0x00000080
+#define TX4938_PCIC_PDMSTS_NCCMP       0x00000040
+#define TX4938_PCIC_PDMSTS_NTCMP       0x00000020
+#define TX4938_PCIC_PDMSTS_CFGERR      0x00000008
+#define TX4938_PCIC_PDMSTS_PCIERR      0x00000004
+#define TX4938_PCIC_PDMSTS_CHNERR      0x00000002
+#define TX4938_PCIC_PDMSTS_DATAERR     0x00000001
+#define TX4938_PCIC_PDMSTS_ALL_CMP     0x000000e0
+#define TX4938_PCIC_PDMSTS_ALL_ERR     0x0000000f
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TX4938_DMA_MCR_RSFIF   0x00000080
+#define TX4938_DMA_MCR_FIFUM(ch)       (0x00000008<<(ch))
+#define TX4938_DMA_MCR_RPRT    0x00000002
+#define TX4938_DMA_MCR_MSTEN   0x00000001
+
+/* bits for CCRn */
+#define TX4938_DMA_CCR_IMMCHN  0x20000000
+#define TX4938_DMA_CCR_USEXFSZ 0x10000000
+#define TX4938_DMA_CCR_LE      0x08000000
+#define TX4938_DMA_CCR_DBINH   0x04000000
+#define TX4938_DMA_CCR_SBINH   0x02000000
+#define TX4938_DMA_CCR_CHRST   0x01000000
+#define TX4938_DMA_CCR_RVBYTE  0x00800000
+#define TX4938_DMA_CCR_ACKPOL  0x00400000
+#define TX4938_DMA_CCR_REQPL   0x00200000
+#define TX4938_DMA_CCR_EGREQ   0x00100000
+#define TX4938_DMA_CCR_CHDN    0x00080000
+#define TX4938_DMA_CCR_DNCTL   0x00060000
+#define TX4938_DMA_CCR_EXTRQ   0x00010000
+#define TX4938_DMA_CCR_INTRQD  0x0000e000
+#define TX4938_DMA_CCR_INTENE  0x00001000
+#define TX4938_DMA_CCR_INTENC  0x00000800
+#define TX4938_DMA_CCR_INTENT  0x00000400
+#define TX4938_DMA_CCR_CHNEN   0x00000200
+#define TX4938_DMA_CCR_XFACT   0x00000100
+#define TX4938_DMA_CCR_SMPCHN  0x00000020
+#define TX4938_DMA_CCR_XFSZ(order)     (((order) << 2) & 0x0000001c)
+#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2)
+#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3)
+#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4)
+#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5)
+#define TX4938_DMA_CCR_XFSZ_16W        TX4938_DMA_CCR_XFSZ(6)
+#define TX4938_DMA_CCR_XFSZ_32W        TX4938_DMA_CCR_XFSZ(7)
+#define TX4938_DMA_CCR_MEMIO   0x00000002
+#define TX4938_DMA_CCR_SNGAD   0x00000001
+
+/* bits for CSRn */
+#define TX4938_DMA_CSR_CHNEN   0x00000400
+#define TX4938_DMA_CSR_STLXFER 0x00000200
+#define TX4938_DMA_CSR_CHNACT  0x00000100
+#define TX4938_DMA_CSR_ABCHC   0x00000080
+#define TX4938_DMA_CSR_NCHNC   0x00000040
+#define TX4938_DMA_CSR_NTRNFC  0x00000020
+#define TX4938_DMA_CSR_EXTDN   0x00000010
+#define TX4938_DMA_CSR_CFERR   0x00000008
+#define TX4938_DMA_CSR_CHERR   0x00000004
+#define TX4938_DMA_CSR_DESERR  0x00000002
+#define TX4938_DMA_CSR_SORERR  0x00000001
+
+/* TX4938 Interrupt Controller (32-bit registers) */
+#define TX4938_IRC_BASE                 0xf510
+#define TX4938_IRC_IRFLAG0              0xf510
+#define TX4938_IRC_IRFLAG1              0xf514
+#define TX4938_IRC_IRPOL                0xf518
+#define TX4938_IRC_IRRCNT               0xf51c
+#define TX4938_IRC_IRMASKINT            0xf520
+#define TX4938_IRC_IRMASKEXT            0xf524
+#define TX4938_IRC_IRDEN                0xf600
+#define TX4938_IRC_IRDM0                0xf604
+#define TX4938_IRC_IRDM1                0xf608
+#define TX4938_IRC_IRLVL0               0xf610
+#define TX4938_IRC_IRLVL1               0xf614
+#define TX4938_IRC_IRLVL2               0xf618
+#define TX4938_IRC_IRLVL3               0xf61c
+#define TX4938_IRC_IRLVL4               0xf620
+#define TX4938_IRC_IRLVL5               0xf624
+#define TX4938_IRC_IRLVL6               0xf628
+#define TX4938_IRC_IRLVL7               0xf62c
+#define TX4938_IRC_IRMSK                0xf640
+#define TX4938_IRC_IREDC                0xf660
+#define TX4938_IRC_IRPND                0xf680
+#define TX4938_IRC_IRCS                 0xf6a0
+#define TX4938_IRC_LIMIT                0xf6ff
+
+
+#ifndef __ASSEMBLY__
+
+#define tx4938_sdramcptr       ((struct tx4938_sdramc_reg *)TX4938_SDRAMC_REG)
+#define tx4938_ebuscptr         ((struct tx4938_ebusc_reg *)TX4938_EBUSC_REG)
+#define tx4938_dmaptr(ch)      ((struct tx4938_dma_reg *)TX4938_DMA_REG(ch))
+#define tx4938_ndfmcptr                ((struct tx4938_ndfmc_reg *)TX4938_NDFMC_REG)
+#define tx4938_ircptr          ((struct tx4938_irc_reg *)TX4938_IRC_REG)
+#define tx4938_pcicptr         ((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
+#define tx4938_pcic1ptr                ((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
+#define tx4938_ccfgptr         ((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
+#define tx4938_tmrptr(ch)      ((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
+#define tx4938_sioptr(ch)      ((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
+#define tx4938_pioptr          ((struct tx4938_pio_reg *)TX4938_PIO_REG)
+#define tx4938_aclcptr         ((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
+#define tx4938_spiptr          ((struct tx4938_spi_reg *)TX4938_SPI_REG)
+#define tx4938_sramcptr                ((struct tx4938_sramc_reg *)TX4938_SRAMC_REG)
+
+
+#define TX4938_REV_MAJ_MIN()   ((unsigned long)tx4938_ccfgptr->crir & 0x00ff)
+#define TX4938_REV_PCODE()     ((unsigned long)tx4938_ccfgptr->crir >> 16)
+
+#define TX4938_SDRAMC_BA(ch)   ((tx4938_sdramcptr->cr[ch] >> 49) << 21)
+#define TX4938_SDRAMC_SIZE(ch) (((tx4938_sdramcptr->cr[ch] >> 33) + 1) << 21)
+
+#define TX4938_EBUSC_BA(ch)    ((tx4938_ebuscptr->cr[ch] >> 48) << 20)
+#define TX4938_EBUSC_SIZE(ch)  \
+       (0x00100000 << ((unsigned long)(tx4938_ebuscptr->cr[ch] >> 8) & 0xf))
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-mips/tx4938/tx4938_mips.h b/include/asm-mips/tx4938/tx4938_mips.h
new file mode 100644 (file)
index 0000000..cf89b20
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * linux/include/asm-mips/tx4938/tx4938_bitmask.h
+ * Generic bitmask definitions
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. 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.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#ifndef TX4938_TX4938_MIPS_H
+#define TX4938_TX4938_MIPS_H
+#ifndef __ASSEMBLY__
+
+#define reg_rd08(r)    ((u8 )(*((vu8 *)(r))))
+#define reg_rd16(r)    ((u16)(*((vu16*)(r))))
+#define reg_rd32(r)    ((u32)(*((vu32*)(r))))
+#define reg_rd64(r)    ((u64)(*((vu64*)(r))))
+
+#define reg_wr08(r,v)  ((*((vu8 *)(r)))=((u8 )(v)))
+#define reg_wr16(r,v)  ((*((vu16*)(r)))=((u16)(v)))
+#define reg_wr32(r,v)  ((*((vu32*)(r)))=((u32)(v)))
+#define reg_wr64(r,v)  ((*((vu64*)(r)))=((u64)(v)))
+
+typedef volatile __signed char vs8;
+typedef volatile unsigned char vu8;
+
+typedef volatile __signed short vs16;
+typedef volatile unsigned short vu16;
+
+typedef volatile __signed int vs32;
+typedef volatile unsigned int vu32;
+
+typedef s8 s08;
+typedef vs8 vs08;
+
+typedef u8 u08;
+typedef vu8 vu08;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef volatile __signed__ long vs64;
+typedef volatile unsigned long vu64;
+
+#else
+
+typedef volatile __signed__ long long vs64;
+typedef volatile unsigned long long vu64;
+
+#endif
+#endif
+#endif