aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/txx9
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 21:07:59 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-15 21:07:59 -0400
commit84c3d4aaec3338201b449034beac41635866bddf (patch)
tree3412951682fb2dd4feb8a5532f8efbaf8b345933 /arch/mips/txx9
parent43d2548bb2ef7e6d753f91468a746784041e522d (diff)
parentfafa3a3f16723997f039a0193997464d66dafd8f (diff)
Merge commit 'origin/master'
Manual merge of: arch/powerpc/Kconfig arch/powerpc/kernel/stacktrace.c arch/powerpc/mm/slice.c arch/ppc/kernel/smp.c
Diffstat (limited to 'arch/mips/txx9')
-rw-r--r--arch/mips/txx9/Kconfig115
-rw-r--r--arch/mips/txx9/generic/Makefile12
-rw-r--r--arch/mips/txx9/generic/dbgio.c48
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c37
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c25
-rw-r--r--arch/mips/txx9/generic/mem_tx4927.c141
-rw-r--r--arch/mips/txx9/generic/mem_tx4938.c124
-rw-r--r--arch/mips/txx9/generic/pci.c388
-rw-r--r--arch/mips/txx9/generic/setup.c212
-rw-r--r--arch/mips/txx9/generic/smsc_fdc37m81x.c172
-rw-r--r--arch/mips/txx9/jmr3927/Makefile8
-rw-r--r--arch/mips/txx9/jmr3927/irq.c171
-rw-r--r--arch/mips/txx9/jmr3927/kgdb_io.c105
-rw-r--r--arch/mips/txx9/jmr3927/prom.c76
-rw-r--r--arch/mips/txx9/jmr3927/setup.c375
-rw-r--r--arch/mips/txx9/rbtx4927/Makefile3
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c199
-rw-r--r--arch/mips/txx9/rbtx4927/prom.c45
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c443
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile3
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c169
-rw-r--r--arch/mips/txx9/rbtx4938/prom.c29
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c625
-rw-r--r--arch/mips/txx9/rbtx4938/spi_eeprom.c99
24 files changed, 3624 insertions, 0 deletions
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
new file mode 100644
index 000000000000..b92a134ef124
--- /dev/null
+++ b/arch/mips/txx9/Kconfig
@@ -0,0 +1,115 @@
1config TOSHIBA_JMR3927
2 bool "Toshiba JMR-TX3927 board"
3 depends on MACH_TX39XX
4 select SOC_TX3927
5
6config TOSHIBA_RBTX4927
7 bool "Toshiba RBTX49[23]7 board"
8 depends on MACH_TX49XX
9 select SOC_TX4927
10 help
11 This Toshiba board is based on the TX4927 processor. Say Y here to
12 support this machine type
13
14config TOSHIBA_RBTX4938
15 bool "Toshiba RBTX4938 board"
16 depends on MACH_TX49XX
17 select SOC_TX4938
18 help
19 This Toshiba board is based on the TX4938 processor. Say Y here to
20 support this machine type
21
22config SOC_TX3927
23 bool
24 select CEVT_TXX9
25 select DMA_NONCOHERENT
26 select HAS_TXX9_SERIAL
27 select HW_HAS_PCI
28 select IRQ_TXX9
29 select SWAP_IO_SPACE
30 select SYS_HAS_CPU_TX39XX
31 select SYS_SUPPORTS_32BIT_KERNEL
32 select SYS_SUPPORTS_LITTLE_ENDIAN
33 select SYS_SUPPORTS_BIG_ENDIAN
34 select GENERIC_HARDIRQS_NO__DO_IRQ
35 select GPIO_TXX9
36
37config SOC_TX4927
38 bool
39 select CEVT_R4K
40 select CSRC_R4K
41 select CEVT_TXX9
42 select DMA_NONCOHERENT
43 select HAS_TXX9_SERIAL
44 select HW_HAS_PCI
45 select IRQ_CPU
46 select IRQ_TXX9
47 select PCI_TX4927
48 select SWAP_IO_SPACE
49 select SYS_HAS_CPU_TX49XX
50 select SYS_SUPPORTS_32BIT_KERNEL
51 select SYS_SUPPORTS_64BIT_KERNEL
52 select SYS_SUPPORTS_LITTLE_ENDIAN
53 select SYS_SUPPORTS_BIG_ENDIAN
54 select SYS_SUPPORTS_KGDB
55 select GENERIC_HARDIRQS_NO__DO_IRQ
56 select GPIO_TXX9
57
58config SOC_TX4938
59 bool
60 select CEVT_R4K
61 select CSRC_R4K
62 select CEVT_TXX9
63 select DMA_NONCOHERENT
64 select HAS_TXX9_SERIAL
65 select HW_HAS_PCI
66 select IRQ_CPU
67 select IRQ_TXX9
68 select PCI_TX4927
69 select SWAP_IO_SPACE
70 select SYS_HAS_CPU_TX49XX
71 select SYS_SUPPORTS_32BIT_KERNEL
72 select SYS_SUPPORTS_64BIT_KERNEL
73 select SYS_SUPPORTS_LITTLE_ENDIAN
74 select SYS_SUPPORTS_BIG_ENDIAN
75 select SYS_SUPPORTS_KGDB
76 select GENERIC_HARDIRQS_NO__DO_IRQ
77 select GPIO_TXX9
78
79config TOSHIBA_FPCIB0
80 bool "FPCIB0 Backplane Support"
81 depends on PCI && (MACH_TX39XX || MACH_TX49XX)
82 select I8259
83
84config PICMG_PCI_BACKPLANE_DEFAULT
85 bool "Support for PICMG PCI Backplane"
86 depends on PCI && (MACH_TX39XX || MACH_TX49XX)
87 default y if !TOSHIBA_FPCIB0
88
89if TOSHIBA_RBTX4938
90
91comment "Multiplex Pin Select"
92choice
93 prompt "PIO[58:61]"
94 default TOSHIBA_RBTX4938_MPLEX_PIO58_61
95
96config TOSHIBA_RBTX4938_MPLEX_PIO58_61
97 bool "PIO"
98config TOSHIBA_RBTX4938_MPLEX_NAND
99 bool "NAND"
100config TOSHIBA_RBTX4938_MPLEX_ATA
101 bool "ATA"
102
103endchoice
104
105config TX4938_NAND_BOOT
106 depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
107 bool "NAND Boot Support (EXPERIMENTAL)"
108 help
109 This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
110 Select this option if you need to use NAND boot.
111
112endif
113
114config PCI_TX4927
115 bool
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
new file mode 100644
index 000000000000..668fdaad6448
--- /dev/null
+++ b/arch/mips/txx9/generic/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for common code for TXx9 based systems
3#
4
5obj-y += setup.o
6obj-$(CONFIG_PCI) += pci.o
7obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o irq_tx4927.o
8obj-$(CONFIG_SOC_TX4938) += mem_tx4938.o irq_tx4938.o
9obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
10obj-$(CONFIG_KGDB) += dbgio.o
11
12EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/generic/dbgio.c b/arch/mips/txx9/generic/dbgio.c
new file mode 100644
index 000000000000..33b9c672a322
--- /dev/null
+++ b/arch/mips/txx9/generic/dbgio.c
@@ -0,0 +1,48 @@
1/*
2 * linux/arch/mips/tx4938/common/dbgio.c
3 *
4 * kgdb interface for gdb
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * Copyright 2005 MontaVista Software Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
24 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
32 */
33
34#include <linux/types>
35
36extern u8 txx9_sio_kdbg_rd(void);
37extern int txx9_sio_kdbg_wr( u8 ch );
38
39u8 getDebugChar(void)
40{
41 return (txx9_sio_kdbg_rd());
42}
43
44int putDebugChar(u8 byte)
45{
46 return (txx9_sio_kdbg_wr(byte));
47}
48
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
new file mode 100644
index 000000000000..6377bd8a9050
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -0,0 +1,37 @@
1/*
2 * Common tx4927 irq handler
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
14 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
16 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
17 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
19 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
20 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26#include <linux/init.h>
27#include <linux/interrupt.h>
28#include <asm/irq_cpu.h>
29#include <asm/txx9/tx4927.h>
30
31void __init tx4927_irq_init(void)
32{
33 mips_cpu_irq_init();
34 txx9_irq_init(TX4927_IRC_REG);
35 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
36 handle_simple_irq);
37}
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
new file mode 100644
index 000000000000..5fc86c9c9d2f
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -0,0 +1,25 @@
1/*
2 * linux/arch/mips/tx4938/common/irq.c
3 *
4 * Common tx4938 irq handler
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <asm/irq_cpu.h>
17#include <asm/txx9/tx4938.h>
18
19void __init tx4938_irq_init(void)
20{
21 mips_cpu_irq_init();
22 txx9_irq_init(TX4938_IRC_REG);
23 set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
24 handle_simple_irq);
25}
diff --git a/arch/mips/txx9/generic/mem_tx4927.c b/arch/mips/txx9/generic/mem_tx4927.c
new file mode 100644
index 000000000000..12dfc377bf2f
--- /dev/null
+++ b/arch/mips/txx9/generic/mem_tx4927.c
@@ -0,0 +1,141 @@
1/*
2 * linux/arch/mips/tx4927/common/tx4927_prom.c
3 *
4 * common tx4927 memory interface
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * Copyright 2001-2002 MontaVista Software Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
24 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31
32#include <linux/init.h>
33#include <linux/types.h>
34#include <linux/io.h>
35
36static unsigned int __init tx4927_process_sdccr(unsigned long addr)
37{
38 u64 val;
39 unsigned int sdccr_ce;
40 unsigned int sdccr_bs;
41 unsigned int sdccr_rs;
42 unsigned int sdccr_cs;
43 unsigned int sdccr_mw;
44 unsigned int bs = 0;
45 unsigned int rs = 0;
46 unsigned int cs = 0;
47 unsigned int mw = 0;
48 unsigned int msize = 0;
49
50 val = __raw_readq((void __iomem *)addr);
51
52 /* MVMCP -- need #defs for these bits masks */
53 sdccr_ce = ((val & (1 << 10)) >> 10);
54 sdccr_bs = ((val & (1 << 8)) >> 8);
55 sdccr_rs = ((val & (3 << 5)) >> 5);
56 sdccr_cs = ((val & (3 << 2)) >> 2);
57 sdccr_mw = ((val & (1 << 0)) >> 0);
58
59 if (sdccr_ce) {
60 switch (sdccr_bs) {
61 case 0:{
62 bs = 2;
63 break;
64 }
65 case 1:{
66 bs = 4;
67 break;
68 }
69 }
70 switch (sdccr_rs) {
71 case 0:{
72 rs = 2048;
73 break;
74 }
75 case 1:{
76 rs = 4096;
77 break;
78 }
79 case 2:{
80 rs = 8192;
81 break;
82 }
83 case 3:{
84 rs = 0;
85 break;
86 }
87 }
88 switch (sdccr_cs) {
89 case 0:{
90 cs = 256;
91 break;
92 }
93 case 1:{
94 cs = 512;
95 break;
96 }
97 case 2:{
98 cs = 1024;
99 break;
100 }
101 case 3:{
102 cs = 2048;
103 break;
104 }
105 }
106 switch (sdccr_mw) {
107 case 0:{
108 mw = 8;
109 break;
110 } /* 8 bytes = 64 bits */
111 case 1:{
112 mw = 4;
113 break;
114 } /* 4 bytes = 32 bits */
115 }
116 }
117
118 /* bytes per chip MB per chip num chips */
119 msize = (((rs * cs * mw) / (1024 * 1024)) * bs);
120
121 return (msize);
122}
123
124
125unsigned int __init tx4927_get_mem_size(void)
126{
127 unsigned int c0;
128 unsigned int c1;
129 unsigned int c2;
130 unsigned int c3;
131 unsigned int total;
132
133 /* MVMCP -- need #defs for these registers */
134 c0 = tx4927_process_sdccr(0xff1f8000);
135 c1 = tx4927_process_sdccr(0xff1f8008);
136 c2 = tx4927_process_sdccr(0xff1f8010);
137 c3 = tx4927_process_sdccr(0xff1f8018);
138 total = c0 + c1 + c2 + c3;
139
140 return (total);
141}
diff --git a/arch/mips/txx9/generic/mem_tx4938.c b/arch/mips/txx9/generic/mem_tx4938.c
new file mode 100644
index 000000000000..20baeaeba4cd
--- /dev/null
+++ b/arch/mips/txx9/generic/mem_tx4938.c
@@ -0,0 +1,124 @@
1/*
2 * linux/arch/mips/tx4938/common/prom.c
3 *
4 * common tx4938 memory interface
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/io.h>
18
19static unsigned int __init
20tx4938_process_sdccr(u64 * addr)
21{
22 u64 val;
23 unsigned int sdccr_ce;
24 unsigned int sdccr_rs;
25 unsigned int sdccr_cs;
26 unsigned int sdccr_mw;
27 unsigned int rs = 0;
28 unsigned int cs = 0;
29 unsigned int mw = 0;
30 unsigned int bc = 4;
31 unsigned int msize = 0;
32
33 val = ____raw_readq((void __iomem *)addr);
34
35 /* MVMCP -- need #defs for these bits masks */
36 sdccr_ce = ((val & (1 << 10)) >> 10);
37 sdccr_rs = ((val & (3 << 5)) >> 5);
38 sdccr_cs = ((val & (7 << 2)) >> 2);
39 sdccr_mw = ((val & (1 << 0)) >> 0);
40
41 if (sdccr_ce) {
42 switch (sdccr_rs) {
43 case 0:{
44 rs = 2048;
45 break;
46 }
47 case 1:{
48 rs = 4096;
49 break;
50 }
51 case 2:{
52 rs = 8192;
53 break;
54 }
55 default:{
56 rs = 0;
57 break;
58 }
59 }
60 switch (sdccr_cs) {
61 case 0:{
62 cs = 256;
63 break;
64 }
65 case 1:{
66 cs = 512;
67 break;
68 }
69 case 2:{
70 cs = 1024;
71 break;
72 }
73 case 3:{
74 cs = 2048;
75 break;
76 }
77 case 4:{
78 cs = 4096;
79 break;
80 }
81 default:{
82 cs = 0;
83 break;
84 }
85 }
86 switch (sdccr_mw) {
87 case 0:{
88 mw = 8;
89 break;
90 } /* 8 bytes = 64 bits */
91 case 1:{
92 mw = 4;
93 break;
94 } /* 4 bytes = 32 bits */
95 }
96 }
97
98 /* bytes per chip MB per chip bank count */
99 msize = (((rs * cs * mw) / (1024 * 1024)) * (bc));
100
101 /* MVMCP -- bc hard coded to 4 from table 9.3.1 */
102 /* boad supports bc=2 but no way to detect */
103
104 return (msize);
105}
106
107unsigned int __init
108tx4938_get_mem_size(void)
109{
110 unsigned int c0;
111 unsigned int c1;
112 unsigned int c2;
113 unsigned int c3;
114 unsigned int total;
115
116 /* MVMCP -- need #defs for these registers */
117 c0 = tx4938_process_sdccr((u64 *) 0xff1f8000);
118 c1 = tx4938_process_sdccr((u64 *) 0xff1f8008);
119 c2 = tx4938_process_sdccr((u64 *) 0xff1f8010);
120 c3 = tx4938_process_sdccr((u64 *) 0xff1f8018);
121 total = c0 + c1 + c2 + c3;
122
123 return (total);
124}
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
new file mode 100644
index 000000000000..0b92d8c13208
--- /dev/null
+++ b/arch/mips/txx9/generic/pci.c
@@ -0,0 +1,388 @@
1/*
2 * linux/arch/mips/txx9/pci.c
3 *
4 * Based on linux/arch/mips/txx9/rbtx4927/setup.c,
5 * linux/arch/mips/txx9/rbtx4938/setup.c,
6 * and RBTX49xx patch from CELF patch archive.
7 *
8 * Copyright 2001-2005 MontaVista Software Inc.
9 * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
10 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16#include <linux/delay.h>
17#include <linux/jiffies.h>
18#include <linux/io.h>
19#include <asm/txx9/generic.h>
20#include <asm/txx9/pci.h>
21#ifdef CONFIG_TOSHIBA_FPCIB0
22#include <linux/interrupt.h>
23#include <asm/i8259.h>
24#include <asm/txx9/smsc_fdc37m81x.h>
25#endif
26
27static int __init
28early_read_config_word(struct pci_controller *hose,
29 int top_bus, int bus, int devfn, int offset, u16 *value)
30{
31 struct pci_dev fake_dev;
32 struct pci_bus fake_bus;
33
34 fake_dev.bus = &fake_bus;
35 fake_dev.sysdata = hose;
36 fake_dev.devfn = devfn;
37 fake_bus.number = bus;
38 fake_bus.sysdata = hose;
39 fake_bus.ops = hose->pci_ops;
40
41 if (bus != top_bus)
42 /* Fake a parent bus structure. */
43 fake_bus.parent = &fake_bus;
44 else
45 fake_bus.parent = NULL;
46
47 return pci_read_config_word(&fake_dev, offset, value);
48}
49
50int __init txx9_pci66_check(struct pci_controller *hose, int top_bus,
51 int current_bus)
52{
53 u32 pci_devfn;
54 unsigned short vid;
55 int cap66 = -1;
56 u16 stat;
57
58 /* It seems SLC90E66 needs some time after PCI reset... */
59 mdelay(80);
60
61 printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
62
63 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
64 if (PCI_FUNC(pci_devfn))
65 continue;
66 if (early_read_config_word(hose, top_bus, current_bus,
67 pci_devfn, PCI_VENDOR_ID, &vid) !=
68 PCIBIOS_SUCCESSFUL)
69 continue;
70 if (vid == 0xffff)
71 continue;
72
73 /* check 66MHz capability */
74 if (cap66 < 0)
75 cap66 = 1;
76 if (cap66) {
77 early_read_config_word(hose, top_bus, current_bus,
78 pci_devfn, PCI_STATUS, &stat);
79 if (!(stat & PCI_STATUS_66MHZ)) {
80 printk(KERN_DEBUG
81 "PCI: %02x:%02x not 66MHz capable.\n",
82 current_bus, pci_devfn);
83 cap66 = 0;
84 break;
85 }
86 }
87 }
88 return cap66 > 0;
89}
90
91static struct resource primary_pci_mem_res[2] = {
92 { .name = "PCI MEM" },
93 { .name = "PCI MMIO" },
94};
95static struct resource primary_pci_io_res = { .name = "PCI IO" };
96struct pci_controller txx9_primary_pcic = {
97 .mem_resource = &primary_pci_mem_res[0],
98 .io_resource = &primary_pci_io_res,
99};
100
101#ifdef CONFIG_64BIT
102int txx9_pci_mem_high __initdata = 1;
103#else
104int txx9_pci_mem_high __initdata;
105#endif
106
107/*
108 * allocate pci_controller and resources.
109 * mem_base, io_base: physical addresss. 0 for auto assignment.
110 * mem_size and io_size means max size on auto assignment.
111 * pcic must be &txx9_primary_pcic or NULL.
112 */
113struct pci_controller *__init
114txx9_alloc_pci_controller(struct pci_controller *pcic,
115 unsigned long mem_base, unsigned long mem_size,
116 unsigned long io_base, unsigned long io_size)
117{
118 struct pcic {
119 struct pci_controller c;
120 struct resource r_mem[2];
121 struct resource r_io;
122 } *new = NULL;
123 int min_size = 0x10000;
124
125 if (!pcic) {
126 new = kzalloc(sizeof(*new), GFP_KERNEL);
127 if (!new)
128 return NULL;
129 new->r_mem[0].name = "PCI mem";
130 new->r_mem[1].name = "PCI mmio";
131 new->r_io.name = "PCI io";
132 new->c.mem_resource = new->r_mem;
133 new->c.io_resource = &new->r_io;
134 pcic = &new->c;
135 } else
136 BUG_ON(pcic != &txx9_primary_pcic);
137 pcic->io_resource->flags = IORESOURCE_IO;
138
139 /*
140 * for auto assignment, first search a (big) region for PCI
141 * MEM, then search a region for PCI IO.
142 */
143 if (mem_base) {
144 pcic->mem_resource[0].start = mem_base;
145 pcic->mem_resource[0].end = mem_base + mem_size - 1;
146 if (request_resource(&iomem_resource, &pcic->mem_resource[0]))
147 goto free_and_exit;
148 } else {
149 unsigned long min = 0, max = 0x20000000; /* low 512MB */
150 if (!mem_size) {
151 /* default size for auto assignment */
152 if (txx9_pci_mem_high)
153 mem_size = 0x20000000; /* mem:512M(max) */
154 else
155 mem_size = 0x08000000; /* mem:128M(max) */
156 }
157 if (txx9_pci_mem_high) {
158 min = 0x20000000;
159 max = 0xe0000000;
160 }
161 /* search free region for PCI MEM */
162 for (; mem_size >= min_size; mem_size /= 2) {
163 if (allocate_resource(&iomem_resource,
164 &pcic->mem_resource[0],
165 mem_size, min, max,
166 mem_size, NULL, NULL) == 0)
167 break;
168 }
169 if (mem_size < min_size)
170 goto free_and_exit;
171 }
172
173 pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
174 if (io_base) {
175 pcic->mem_resource[1].start = io_base;
176 pcic->mem_resource[1].end = io_base + io_size - 1;
177 if (request_resource(&iomem_resource, &pcic->mem_resource[1]))
178 goto release_and_exit;
179 } else {
180 if (!io_size)
181 /* default size for auto assignment */
182 io_size = 0x01000000; /* io:16M(max) */
183 /* search free region for PCI IO in low 512MB */
184 for (; io_size >= min_size; io_size /= 2) {
185 if (allocate_resource(&iomem_resource,
186 &pcic->mem_resource[1],
187 io_size, 0, 0x20000000,
188 io_size, NULL, NULL) == 0)
189 break;
190 }
191 if (io_size < min_size)
192 goto release_and_exit;
193 io_base = pcic->mem_resource[1].start;
194 }
195
196 pcic->mem_resource[0].flags = IORESOURCE_MEM;
197 if (pcic == &txx9_primary_pcic &&
198 mips_io_port_base == (unsigned long)-1) {
199 /* map ioport 0 to PCI I/O space address 0 */
200 set_io_port_base(IO_BASE + pcic->mem_resource[1].start);
201 pcic->io_resource->start = 0;
202 pcic->io_offset = 0; /* busaddr == ioaddr */
203 pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start;
204 } else {
205 /* physaddr to ioaddr */
206 pcic->io_resource->start =
207 io_base - (mips_io_port_base - IO_BASE);
208 pcic->io_offset = io_base - (mips_io_port_base - IO_BASE);
209 pcic->io_map_base = mips_io_port_base;
210 }
211 pcic->io_resource->end = pcic->io_resource->start + io_size - 1;
212
213 pcic->mem_offset = 0; /* busaddr == physaddr */
214
215 printk(KERN_INFO "PCI: IO 0x%08llx-0x%08llx MEM 0x%08llx-0x%08llx\n",
216 (unsigned long long)pcic->mem_resource[1].start,
217 (unsigned long long)pcic->mem_resource[1].end,
218 (unsigned long long)pcic->mem_resource[0].start,
219 (unsigned long long)pcic->mem_resource[0].end);
220
221 /* register_pci_controller() will request MEM resource */
222 release_resource(&pcic->mem_resource[0]);
223 return pcic;
224 release_and_exit:
225 release_resource(&pcic->mem_resource[0]);
226 free_and_exit:
227 kfree(new);
228 printk(KERN_ERR "PCI: Failed to allocate resources.\n");
229 return NULL;
230}
231
232static int __init
233txx9_arch_pci_init(void)
234{
235 PCIBIOS_MIN_IO = 0x8000; /* reseve legacy I/O space */
236 return 0;
237}
238arch_initcall(txx9_arch_pci_init);
239
240/* IRQ/IDSEL mapping */
241int txx9_pci_option =
242#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT
243 TXX9_PCI_OPT_PICMG |
244#endif
245 TXX9_PCI_OPT_CLK_AUTO;
246
247enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT;
248
249#ifdef CONFIG_TOSHIBA_FPCIB0
250static irqreturn_t i8259_interrupt(int irq, void *dev_id)
251{
252 int isairq;
253
254 isairq = i8259_irq();
255 if (unlikely(isairq <= I8259A_IRQ_BASE))
256 return IRQ_NONE;
257 generic_handle_irq(isairq);
258 return IRQ_HANDLED;
259}
260
261static int __init
262txx9_i8259_irq_setup(int irq)
263{
264 int err;
265
266 init_i8259_irqs();
267 err = request_irq(irq, &i8259_interrupt, IRQF_DISABLED|IRQF_SHARED,
268 "cascade(i8259)", (void *)(long)irq);
269 if (!err)
270 printk(KERN_INFO "PCI-ISA bridge PIC (irq %d)\n", irq);
271 return err;
272}
273
274static void __init quirk_slc90e66_bridge(struct pci_dev *dev)
275{
276 int irq; /* PCI/ISA Bridge interrupt */
277 u8 reg_64;
278 u32 reg_b0;
279 u8 reg_e1;
280 irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */
281 if (!irq)
282 return;
283 txx9_i8259_irq_setup(irq);
284 pci_read_config_byte(dev, 0x64, &reg_64);
285 pci_read_config_dword(dev, 0xb0, &reg_b0);
286 pci_read_config_byte(dev, 0xe1, &reg_e1);
287 /* serial irq control */
288 reg_64 = 0xd0;
289 /* serial irq pin */
290 reg_b0 |= 0x00010000;
291 /* ide irq on isa14 */
292 reg_e1 &= 0xf0;
293 reg_e1 |= 0x0d;
294 pci_write_config_byte(dev, 0x64, reg_64);
295 pci_write_config_dword(dev, 0xb0, reg_b0);
296 pci_write_config_byte(dev, 0xe1, reg_e1);
297
298 smsc_fdc37m81x_init(0x3f0);
299 smsc_fdc37m81x_config_beg();
300 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
301 SMSC_FDC37M81X_KBD);
302 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
303 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
304 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
305 1);
306 smsc_fdc37m81x_config_end();
307}
308
309static void quirk_slc90e66_ide(struct pci_dev *dev)
310{
311 unsigned char dat;
312 int regs[2] = {0x41, 0x43};
313 int i;
314
315 /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
316 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14);
317 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat);
318 printk(KERN_INFO "PCI: %s: IRQ %02x", pci_name(dev), dat);
319 /* enable SMSC SLC90E66 IDE */
320 for (i = 0; i < ARRAY_SIZE(regs); i++) {
321 pci_read_config_byte(dev, regs[i], &dat);
322 pci_write_config_byte(dev, regs[i], dat | 0x80);
323 pci_read_config_byte(dev, regs[i], &dat);
324 printk(KERN_CONT " IDETIM%d %02x", i, dat);
325 }
326 pci_read_config_byte(dev, 0x5c, &dat);
327 /*
328 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
329 *
330 * This line of code is intended to provide the user with a work
331 * around solution to the anomalies cited in SMSC's anomaly sheet
332 * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
333 *
334 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
335 */
336 dat |= 0x01;
337 pci_write_config_byte(dev, regs[i], dat);
338 pci_read_config_byte(dev, 0x5c, &dat);
339 printk(KERN_CONT " REG5C %02x", dat);
340 printk(KERN_CONT "\n");
341}
342#endif /* CONFIG_TOSHIBA_FPCIB0 */
343
344static void final_fixup(struct pci_dev *dev)
345{
346 unsigned char bist;
347
348 /* Do build-in self test */
349 if (pci_read_config_byte(dev, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL &&
350 (bist & PCI_BIST_CAPABLE)) {
351 unsigned long timeout;
352 pci_set_power_state(dev, PCI_D0);
353 printk(KERN_INFO "PCI: %s BIST...", pci_name(dev));
354 pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START);
355 timeout = jiffies + HZ * 2; /* timeout after 2 sec */
356 do {
357 pci_read_config_byte(dev, PCI_BIST, &bist);
358 if (time_after(jiffies, timeout))
359 break;
360 } while (bist & PCI_BIST_START);
361 if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START))
362 printk(KERN_CONT "failed. (0x%x)\n", bist);
363 else
364 printk(KERN_CONT "OK.\n");
365 }
366}
367
368#ifdef CONFIG_TOSHIBA_FPCIB0
369#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
370DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
371 quirk_slc90e66_bridge);
372DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
373 quirk_slc90e66_ide);
374DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
375 quirk_slc90e66_ide);
376#endif
377DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
378DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
379
380int pcibios_plat_dev_init(struct pci_dev *dev)
381{
382 return 0;
383}
384
385int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
386{
387 return txx9_board_vec->pci_map_irq(dev, slot, pin);
388}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
new file mode 100644
index 000000000000..5afc5d5cab03
--- /dev/null
+++ b/arch/mips/txx9/generic/setup.c
@@ -0,0 +1,212 @@
1/*
2 * linux/arch/mips/txx9/generic/setup.c
3 *
4 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
5 * and RBTX49xx patch from CELF patch archive.
6 *
7 * 2003-2005 (c) MontaVista Software, Inc.
8 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/string.h>
19#include <linux/module.h>
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <asm/bootinfo.h>
23#include <asm/txx9/generic.h>
24#ifdef CONFIG_CPU_TX49XX
25#include <asm/txx9/tx4938.h>
26#endif
27
28/* EBUSC settings of TX4927, etc. */
29struct resource txx9_ce_res[8];
30static char txx9_ce_res_name[8][4]; /* "CEn" */
31
32/* pcode, internal register */
33char txx9_pcode_str[8];
34static struct resource txx9_reg_res = {
35 .name = txx9_pcode_str,
36 .flags = IORESOURCE_MEM,
37};
38void __init
39txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size)
40{
41 int i;
42
43 for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) {
44 sprintf(txx9_ce_res_name[i], "CE%d", i);
45 txx9_ce_res[i].flags = IORESOURCE_MEM;
46 txx9_ce_res[i].name = txx9_ce_res_name[i];
47 }
48
49 sprintf(txx9_pcode_str, "TX%x", pcode);
50 if (base) {
51 txx9_reg_res.start = base & 0xfffffffffULL;
52 txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1);
53 request_resource(&iomem_resource, &txx9_reg_res);
54 }
55}
56
57/* clocks */
58unsigned int txx9_master_clock;
59unsigned int txx9_cpu_clock;
60unsigned int txx9_gbus_clock;
61
62
63/* Minimum CLK support */
64
65struct clk *clk_get(struct device *dev, const char *id)
66{
67 if (!strcmp(id, "spi-baseclk"))
68 return (struct clk *)(txx9_gbus_clock / 2 / 4);
69 if (!strcmp(id, "imbus_clk"))
70 return (struct clk *)(txx9_gbus_clock / 2);
71 return ERR_PTR(-ENOENT);
72}
73EXPORT_SYMBOL(clk_get);
74
75int clk_enable(struct clk *clk)
76{
77 return 0;
78}
79EXPORT_SYMBOL(clk_enable);
80
81void clk_disable(struct clk *clk)
82{
83}
84EXPORT_SYMBOL(clk_disable);
85
86unsigned long clk_get_rate(struct clk *clk)
87{
88 return (unsigned long)clk;
89}
90EXPORT_SYMBOL(clk_get_rate);
91
92void clk_put(struct clk *clk)
93{
94}
95EXPORT_SYMBOL(clk_put);
96
97extern struct txx9_board_vec jmr3927_vec;
98extern struct txx9_board_vec rbtx4927_vec;
99extern struct txx9_board_vec rbtx4937_vec;
100extern struct txx9_board_vec rbtx4938_vec;
101
102struct txx9_board_vec *txx9_board_vec __initdata;
103static char txx9_system_type[32];
104
105void __init prom_init_cmdline(void)
106{
107 int argc = (int)fw_arg0;
108 char **argv = (char **)fw_arg1;
109 int i; /* Always ignore the "-c" at argv[0] */
110
111 /* ignore all built-in args if any f/w args given */
112 if (argc > 1)
113 *arcs_cmdline = '\0';
114
115 for (i = 1; i < argc; i++) {
116 if (i != 1)
117 strcat(arcs_cmdline, " ");
118 strcat(arcs_cmdline, argv[i]);
119 }
120}
121
122void __init prom_init(void)
123{
124#ifdef CONFIG_CPU_TX39XX
125 txx9_board_vec = &jmr3927_vec;
126#endif
127#ifdef CONFIG_CPU_TX49XX
128 switch (TX4938_REV_PCODE()) {
129 case 0x4927:
130 txx9_board_vec = &rbtx4927_vec;
131 break;
132 case 0x4937:
133 txx9_board_vec = &rbtx4937_vec;
134 break;
135 case 0x4938:
136 txx9_board_vec = &rbtx4938_vec;
137 break;
138 }
139#endif
140
141 strcpy(txx9_system_type, txx9_board_vec->system);
142
143 txx9_board_vec->prom_init();
144}
145
146void __init prom_free_prom_memory(void)
147{
148}
149
150const char *get_system_type(void)
151{
152 return txx9_system_type;
153}
154
155char * __init prom_getcmdline(void)
156{
157 return &(arcs_cmdline[0]);
158}
159
160/* wrappers */
161void __init plat_mem_setup(void)
162{
163 txx9_board_vec->mem_setup();
164}
165
166void __init arch_init_irq(void)
167{
168 txx9_board_vec->irq_setup();
169}
170
171void __init plat_time_init(void)
172{
173 txx9_board_vec->time_init();
174}
175
176static int __init _txx9_arch_init(void)
177{
178 if (txx9_board_vec->arch_init)
179 txx9_board_vec->arch_init();
180 return 0;
181}
182arch_initcall(_txx9_arch_init);
183
184static int __init _txx9_device_init(void)
185{
186 if (txx9_board_vec->device_init)
187 txx9_board_vec->device_init();
188 return 0;
189}
190device_initcall(_txx9_device_init);
191
192int (*txx9_irq_dispatch)(int pending);
193asmlinkage void plat_irq_dispatch(void)
194{
195 int pending = read_c0_status() & read_c0_cause() & ST0_IM;
196 int irq = txx9_irq_dispatch(pending);
197
198 if (likely(irq >= 0))
199 do_IRQ(irq);
200 else
201 spurious_interrupt();
202}
203
204/* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */
205#ifdef NEEDS_TXX9_SWIZZLE_ADDR_B
206static unsigned long __swizzle_addr_none(unsigned long port)
207{
208 return port;
209}
210unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none;
211EXPORT_SYMBOL(__swizzle_addr_b);
212#endif
diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c
new file mode 100644
index 000000000000..69e487467fa5
--- /dev/null
+++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c
@@ -0,0 +1,172 @@
1/*
2 * Interface for smsc fdc48m81x Super IO chip
3 *
4 * Author: MontaVista Software, Inc. source@mvista.com
5 *
6 * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 * Copyright 2004 (c) MontaVista Software, Inc.
12 */
13#include <linux/init.h>
14#include <linux/types.h>
15#include <asm/io.h>
16#include <asm/txx9/smsc_fdc37m81x.h>
17
18#define DEBUG
19
20/* Common Registers */
21#define SMSC_FDC37M81X_CONFIG_INDEX 0x00
22#define SMSC_FDC37M81X_CONFIG_DATA 0x01
23#define SMSC_FDC37M81X_CONF 0x02
24#define SMSC_FDC37M81X_INDEX 0x03
25#define SMSC_FDC37M81X_DNUM 0x07
26#define SMSC_FDC37M81X_DID 0x20
27#define SMSC_FDC37M81X_DREV 0x21
28#define SMSC_FDC37M81X_PCNT 0x22
29#define SMSC_FDC37M81X_PMGT 0x23
30#define SMSC_FDC37M81X_OSC 0x24
31#define SMSC_FDC37M81X_CONFPA0 0x26
32#define SMSC_FDC37M81X_CONFPA1 0x27
33#define SMSC_FDC37M81X_TEST4 0x2B
34#define SMSC_FDC37M81X_TEST5 0x2C
35#define SMSC_FDC37M81X_TEST1 0x2D
36#define SMSC_FDC37M81X_TEST2 0x2E
37#define SMSC_FDC37M81X_TEST3 0x2F
38
39/* Logical device numbers */
40#define SMSC_FDC37M81X_FDD 0x00
41#define SMSC_FDC37M81X_SERIAL1 0x04
42#define SMSC_FDC37M81X_SERIAL2 0x05
43#define SMSC_FDC37M81X_KBD 0x07
44
45/* Logical device Config Registers */
46#define SMSC_FDC37M81X_ACTIVE 0x30
47#define SMSC_FDC37M81X_BASEADDR0 0x60
48#define SMSC_FDC37M81X_BASEADDR1 0x61
49#define SMSC_FDC37M81X_INT 0x70
50#define SMSC_FDC37M81X_INT2 0x72
51#define SMSC_FDC37M81X_MODE 0xF0
52
53/* Chip Config Values */
54#define SMSC_FDC37M81X_CONFIG_ENTER 0x55
55#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa
56#define SMSC_FDC37M81X_CHIP_ID 0x4d
57
58static unsigned long g_smsc_fdc37m81x_base = 0;
59
60static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
61{
62 outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
63
64 return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
65}
66
67static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
68{
69 outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
70 outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
71}
72
73void smsc_fdc37m81x_config_beg(void)
74{
75 if (g_smsc_fdc37m81x_base) {
76 outb(SMSC_FDC37M81X_CONFIG_ENTER,
77 g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
78 }
79}
80
81void smsc_fdc37m81x_config_end(void)
82{
83 if (g_smsc_fdc37m81x_base)
84 outb(SMSC_FDC37M81X_CONFIG_EXIT,
85 g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
86}
87
88u8 smsc_fdc37m81x_config_get(u8 reg)
89{
90 u8 val = 0;
91
92 if (g_smsc_fdc37m81x_base)
93 val = smsc_fdc37m81x_rd(reg);
94
95 return val;
96}
97
98void smsc_fdc37m81x_config_set(u8 reg, u8 val)
99{
100 if (g_smsc_fdc37m81x_base)
101 smsc_dc37m81x_wr(reg, val);
102}
103
104unsigned long __init smsc_fdc37m81x_init(unsigned long port)
105{
106 const int field = sizeof(unsigned long) * 2;
107 u8 chip_id;
108
109 if (g_smsc_fdc37m81x_base)
110 printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n",
111 field, g_smsc_fdc37m81x_base);
112
113 g_smsc_fdc37m81x_base = port;
114
115 smsc_fdc37m81x_config_beg();
116
117 chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
118 if (chip_id == SMSC_FDC37M81X_CHIP_ID)
119 smsc_fdc37m81x_config_end();
120 else {
121 printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n",
122 chip_id);
123 g_smsc_fdc37m81x_base = 0;
124 }
125
126 return g_smsc_fdc37m81x_base;
127}
128
129#ifdef DEBUG
130void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg)
131{
132 printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
133 smsc_fdc37m81x_rd(reg));
134}
135
136void smsc_fdc37m81x_config_dump(void)
137{
138 u8 orig;
139 char *fname = "smsc_fdc37m81x_config_dump()";
140
141 smsc_fdc37m81x_config_beg();
142
143 orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
144
145 printk("%s: common\n", fname);
146 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
147 SMSC_FDC37M81X_DNUM);
148 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
149 SMSC_FDC37M81X_DID);
150 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
151 SMSC_FDC37M81X_DREV);
152 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
153 SMSC_FDC37M81X_PCNT);
154 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
155 SMSC_FDC37M81X_PMGT);
156
157 printk("%s: keyboard\n", fname);
158 smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
159 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
160 SMSC_FDC37M81X_ACTIVE);
161 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
162 SMSC_FDC37M81X_INT);
163 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
164 SMSC_FDC37M81X_INT2);
165 smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
166 SMSC_FDC37M81X_LDCR_F0);
167
168 smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
169
170 smsc_fdc37m81x_config_end();
171}
172#endif
diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile
new file mode 100644
index 000000000000..ba292c945669
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for TOSHIBA JMR-TX3927 board
3#
4
5obj-y += prom.o irq.o setup.o
6obj-$(CONFIG_KGDB) += kgdb_io.o
7
8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
new file mode 100644
index 000000000000..070c9a115e57
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -0,0 +1,171 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2000-2001 Toshiba Corporation
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/init.h>
33#include <linux/sched.h>
34#include <linux/types.h>
35#include <linux/interrupt.h>
36
37#include <asm/io.h>
38#include <asm/mipsregs.h>
39#include <asm/system.h>
40
41#include <asm/processor.h>
42#include <asm/txx9/generic.h>
43#include <asm/txx9/jmr3927.h>
44
45#if JMR3927_IRQ_END > NR_IRQS
46#error JMR3927_IRQ_END > NR_IRQS
47#endif
48
49static unsigned char irc_level[TX3927_NUM_IR] = {
50 5, 5, 5, 5, 5, 5, /* INT[5:0] */
51 7, 7, /* SIO */
52 5, 5, 5, 0, 0, /* DMA, PIO, PCI */
53 6, 6, 6 /* TMR */
54};
55
56/*
57 * CP0_STATUS is a thread's resource (saved/restored on context switch).
58 * So disable_irq/enable_irq MUST handle IOC/IRC registers.
59 */
60static void mask_irq_ioc(unsigned int irq)
61{
62 /* 0: mask */
63 unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
64 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
65 unsigned int bit = 1 << irq_nr;
66 jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
67 /* flush write buffer */
68 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
69}
70static void unmask_irq_ioc(unsigned int irq)
71{
72 /* 0: mask */
73 unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
74 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
75 unsigned int bit = 1 << irq_nr;
76 jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
77 /* flush write buffer */
78 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
79}
80
81static int jmr3927_ioc_irqroute(void)
82{
83 unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
84 int i;
85
86 for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
87 if (istat & (1 << i))
88 return JMR3927_IRQ_IOC + i;
89 }
90 return -1;
91}
92
93static int jmr3927_irq_dispatch(int pending)
94{
95 int irq;
96
97 if ((pending & CAUSEF_IP7) == 0)
98 return -1;
99 irq = (pending >> CAUSEB_IP2) & 0x0f;
100 irq += JMR3927_IRQ_IRC;
101 if (irq == JMR3927_IRQ_IOCINT)
102 irq = jmr3927_ioc_irqroute();
103 return irq;
104}
105
106#ifdef CONFIG_PCI
107static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id)
108{
109 printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
110 printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
111 tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
112
113 return IRQ_HANDLED;
114}
115static struct irqaction pcierr_action = {
116 .handler = jmr3927_pcierr_interrupt,
117 .mask = CPU_MASK_NONE,
118 .name = "PCI error",
119};
120#endif
121
122static void __init jmr3927_irq_init(void);
123
124void __init jmr3927_irq_setup(void)
125{
126 txx9_irq_dispatch = jmr3927_irq_dispatch;
127 /* Now, interrupt control disabled, */
128 /* all IRC interrupts are masked, */
129 /* all IRC interrupt mode are Low Active. */
130
131 /* mask all IOC interrupts */
132 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
133 /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
134 jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
135
136 /* clear PCI Soft interrupts */
137 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
138 /* clear PCI Reset interrupts */
139 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
140
141 jmr3927_irq_init();
142
143 /* setup IOC interrupt 1 (PCI, MODEM) */
144 set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
145
146#ifdef CONFIG_PCI
147 setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action);
148#endif
149
150 /* enable all CPU interrupt bits. */
151 set_c0_status(ST0_IM); /* IE bit is still 0. */
152}
153
154static struct irq_chip jmr3927_irq_ioc = {
155 .name = "jmr3927_ioc",
156 .ack = mask_irq_ioc,
157 .mask = mask_irq_ioc,
158 .mask_ack = mask_irq_ioc,
159 .unmask = unmask_irq_ioc,
160};
161
162static void __init jmr3927_irq_init(void)
163{
164 u32 i;
165
166 txx9_irq_init(TX3927_IRC_REG);
167 for (i = 0; i < TXx9_MAX_IR; i++)
168 txx9_irq_set_pri(i, irc_level[i]);
169 for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)
170 set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq);
171}
diff --git a/arch/mips/txx9/jmr3927/kgdb_io.c b/arch/mips/txx9/jmr3927/kgdb_io.c
new file mode 100644
index 000000000000..5bd757e56f79
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/kgdb_io.c
@@ -0,0 +1,105 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Low level uart routines to directly access a TX[34]927 SIO.
4 *
5 * Copyright 2001 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ahennessy@mvista.com or source@mvista.com
8 *
9 * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c
10 *
11 * Copyright (C) 2000-2001 Toshiba Corporation
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34#include <asm/txx9/jmr3927.h>
35
36#define TIMEOUT 0xffffff
37
38static int remoteDebugInitialized = 0;
39static void debugInit(int baud);
40
41int putDebugChar(unsigned char c)
42{
43 int i = 0;
44
45 if (!remoteDebugInitialized) {
46 remoteDebugInitialized = 1;
47 debugInit(38400);
48 }
49
50 do {
51 slow_down();
52 i++;
53 if (i>TIMEOUT) {
54 break;
55 }
56 } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS));
57 tx3927_sioptr(0)->tfifo = c;
58
59 return 1;
60}
61
62unsigned char getDebugChar(void)
63{
64 int i = 0;
65 int dicr;
66 char c;
67
68 if (!remoteDebugInitialized) {
69 remoteDebugInitialized = 1;
70 debugInit(38400);
71 }
72
73 /* diable RX int. */
74 dicr = tx3927_sioptr(0)->dicr;
75 tx3927_sioptr(0)->dicr = 0;
76
77 do {
78 slow_down();
79 i++;
80 if (i>TIMEOUT) {
81 break;
82 }
83 } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID)
84 ;
85 c = tx3927_sioptr(0)->rfifo;
86
87 /* clear RX int. status */
88 tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS;
89 /* enable RX int. */
90 tx3927_sioptr(0)->dicr = dicr;
91
92 return c;
93}
94
95static void debugInit(int baud)
96{
97 tx3927_sioptr(0)->lcr = 0x020;
98 tx3927_sioptr(0)->dicr = 0;
99 tx3927_sioptr(0)->disr = 0x4100;
100 tx3927_sioptr(0)->cisr = 0x014;
101 tx3927_sioptr(0)->fcr = 0;
102 tx3927_sioptr(0)->flcr = 0x02;
103 tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) |
104 TXx927_SIBGR_BCLK_T0;
105}
diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c
new file mode 100644
index 000000000000..2cadb423face
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/prom.c
@@ -0,0 +1,76 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * PROM library initialisation code, assuming a version of
4 * pmon is the boot code.
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ahennessy@mvista.com
9 *
10 * Based on arch/mips/au1000/common/prom.c
11 *
12 * This file was derived from Carsten Langgaard's
13 * arch/mips/mips-boards/xx files.
14 *
15 * Carsten Langgaard, carstenl@mips.com
16 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version.
22 *
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
26 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * You should have received a copy of the GNU General Public License along
35 * with this program; if not, write to the Free Software Foundation, Inc.,
36 * 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38#include <linux/init.h>
39#include <asm/bootinfo.h>
40#include <asm/txx9/generic.h>
41#include <asm/txx9/jmr3927.h>
42
43#define TIMEOUT 0xffffff
44
45void
46prom_putchar(char c)
47{
48 int i = 0;
49
50 do {
51 i++;
52 if (i>TIMEOUT)
53 break;
54 } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
55 tx3927_sioptr(1)->tfifo = c;
56 return;
57}
58
59void
60puts(const char *cp)
61{
62 while (*cp)
63 prom_putchar(*cp++);
64 prom_putchar('\r');
65 prom_putchar('\n');
66}
67
68void __init jmr3927_prom_init(void)
69{
70 /* CCFG */
71 if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
72 puts("Warning: TX3927 TLB off\n");
73
74 prom_init_cmdline();
75 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
76}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
new file mode 100644
index 000000000000..5e35ef73c5a5
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -0,0 +1,375 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
8 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
10 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
11 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
12 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
13 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
14 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
16 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Copyright 2001 MontaVista Software Inc.
23 * Author: MontaVista Software, Inc.
24 * ahennessy@mvista.com
25 *
26 * Copyright (C) 2000-2001 Toshiba Corporation
27 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
28 */
29
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/ioport.h>
34#include <linux/delay.h>
35#include <linux/pm.h>
36#include <linux/platform_device.h>
37#include <linux/gpio.h>
38#ifdef CONFIG_SERIAL_TXX9
39#include <linux/serial_core.h>
40#endif
41#include <asm/txx9tmr.h>
42#include <asm/txx9pio.h>
43#include <asm/reboot.h>
44#include <asm/txx9/generic.h>
45#include <asm/txx9/pci.h>
46#include <asm/txx9/jmr3927.h>
47#include <asm/mipsregs.h>
48
49extern void puts(const char *cp);
50
51/* don't enable - see errata */
52static int jmr3927_ccfg_toeon;
53
54static inline void do_reset(void)
55{
56#if 1 /* Resetting PCI bus */
57 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
58 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
59 (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */
60 mdelay(1);
61 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
62#endif
63 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
64}
65
66static void jmr3927_machine_restart(char *command)
67{
68 local_irq_disable();
69 puts("Rebooting...");
70 do_reset();
71}
72
73static void jmr3927_machine_halt(void)
74{
75 puts("JMR-TX3927 halted.\n");
76 while (1);
77}
78
79static void jmr3927_machine_power_off(void)
80{
81 puts("JMR-TX3927 halted. Please turn off the power.\n");
82 while (1);
83}
84
85static void __init jmr3927_time_init(void)
86{
87 txx9_clockevent_init(TX3927_TMR_REG(0),
88 TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0),
89 JMR3927_IMCLK);
90 txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK);
91}
92
93#define DO_WRITE_THROUGH
94#define DO_ENABLE_CACHE
95
96static void jmr3927_board_init(void);
97
98static void __init jmr3927_mem_setup(void)
99{
100 char *argptr;
101
102 set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
103
104 _machine_restart = jmr3927_machine_restart;
105 _machine_halt = jmr3927_machine_halt;
106 pm_power_off = jmr3927_machine_power_off;
107
108 /*
109 * IO/MEM resources.
110 */
111 ioport_resource.start = 0;
112 ioport_resource.end = 0xffffffff;
113 iomem_resource.start = 0;
114 iomem_resource.end = 0xffffffff;
115
116 /* Reboot on panic */
117 panic_timeout = 180;
118
119 /* cache setup */
120 {
121 unsigned int conf;
122#ifdef DO_ENABLE_CACHE
123 int mips_ic_disable = 0, mips_dc_disable = 0;
124#else
125 int mips_ic_disable = 1, mips_dc_disable = 1;
126#endif
127#ifdef DO_WRITE_THROUGH
128 int mips_config_cwfon = 0;
129 int mips_config_wbon = 0;
130#else
131 int mips_config_cwfon = 1;
132 int mips_config_wbon = 1;
133#endif
134
135 conf = read_c0_conf();
136 conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON);
137 conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
138 conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
139 conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
140 conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
141
142 write_c0_conf(conf);
143 write_c0_cache(0);
144 }
145
146 /* initialize board */
147 jmr3927_board_init();
148
149 argptr = prom_getcmdline();
150
151 if ((argptr = strstr(argptr, "toeon")) != NULL)
152 jmr3927_ccfg_toeon = 1;
153 argptr = prom_getcmdline();
154 if ((argptr = strstr(argptr, "ip=")) == NULL) {
155 argptr = prom_getcmdline();
156 strcat(argptr, " ip=bootp");
157 }
158
159#ifdef CONFIG_SERIAL_TXX9
160 {
161 extern int early_serial_txx9_setup(struct uart_port *port);
162 int i;
163 struct uart_port req;
164 for(i = 0; i < 2; i++) {
165 memset(&req, 0, sizeof(req));
166 req.line = i;
167 req.iotype = UPIO_MEM;
168 req.membase = (unsigned char __iomem *)TX3927_SIO_REG(i);
169 req.mapbase = TX3927_SIO_REG(i);
170 req.irq = i == 0 ?
171 JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1;
172 if (i == 0)
173 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
174 req.uartclk = JMR3927_IMCLK;
175 early_serial_txx9_setup(&req);
176 }
177 }
178#ifdef CONFIG_SERIAL_TXX9_CONSOLE
179 argptr = prom_getcmdline();
180 if ((argptr = strstr(argptr, "console=")) == NULL) {
181 argptr = prom_getcmdline();
182 strcat(argptr, " console=ttyS1,115200");
183 }
184#endif
185#endif
186}
187
188static void tx3927_setup(void);
189
190static void __init jmr3927_pci_setup(void)
191{
192#ifdef CONFIG_PCI
193 int extarb = !(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB);
194 struct pci_controller *c;
195
196 c = txx9_alloc_pci_controller(&txx9_primary_pcic,
197 JMR3927_PCIMEM, JMR3927_PCIMEM_SIZE,
198 JMR3927_PCIIO, JMR3927_PCIIO_SIZE);
199 register_pci_controller(c);
200 if (!extarb) {
201 /* Reset PCI Bus */
202 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
203 udelay(100);
204 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
205 JMR3927_IOC_RESET_ADDR);
206 udelay(100);
207 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
208 }
209 tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb);
210#endif /* CONFIG_PCI */
211}
212
213static void __init jmr3927_board_init(void)
214{
215 tx3927_setup();
216 jmr3927_pci_setup();
217
218 /* SIO0 DTR on */
219 jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
220
221 jmr3927_led_set(0);
222
223 printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
224 jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
225 jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
226 jmr3927_dipsw1(), jmr3927_dipsw2(),
227 jmr3927_dipsw3(), jmr3927_dipsw4());
228}
229
230static void __init tx3927_setup(void)
231{
232 int i;
233
234 txx9_cpu_clock = JMR3927_CORECLK;
235 txx9_gbus_clock = JMR3927_GBUSCLK;
236 /* SDRAMC are configured by PROM */
237
238 /* ROMC */
239 tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
240 tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
241 tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
242 tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
243
244 /* CCFG */
245 /* enable Timeout BusError */
246 if (jmr3927_ccfg_toeon)
247 tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
248
249 /* clear BusErrorOnWrite flag */
250 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
251 /* Disable PCI snoop */
252 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
253 /* do reset on watchdog */
254 tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
255
256#ifdef DO_WRITE_THROUGH
257 /* Enable PCI SNOOP - with write through only */
258 tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
259#endif
260
261 /* Pin selection */
262 tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
263 tx3927_ccfgptr->pcfg |=
264 TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
265 (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
266
267 printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
268 tx3927_ccfgptr->crir,
269 tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
270
271 /* TMR */
272 for (i = 0; i < TX3927_NR_TMR; i++)
273 txx9_tmr_init(TX3927_TMR_REG(i));
274
275 /* DMA */
276 tx3927_dmaptr->mcr = 0;
277 for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) {
278 /* reset channel */
279 tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
280 tx3927_dmaptr->ch[i].ccr = 0;
281 }
282 /* enable DMA */
283#ifdef __BIG_ENDIAN
284 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
285#else
286 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
287#endif
288
289 /* PIO */
290 /* PIO[15:12] connected to LEDs */
291 __raw_writel(0x0000f000, &tx3927_pioptr->dir);
292 __raw_writel(0, &tx3927_pioptr->maskcpu);
293 __raw_writel(0, &tx3927_pioptr->maskext);
294 txx9_gpio_init(TX3927_PIO_REG, 0, 16);
295 gpio_request(11, "dipsw1");
296 gpio_request(10, "dipsw2");
297 {
298 unsigned int conf;
299
300 conf = read_c0_conf();
301 if (!(conf & TX39_CONF_ICE))
302 printk("TX3927 I-Cache disabled.\n");
303 if (!(conf & TX39_CONF_DCE))
304 printk("TX3927 D-Cache disabled.\n");
305 else if (!(conf & TX39_CONF_WBON))
306 printk("TX3927 D-Cache WriteThrough.\n");
307 else if (!(conf & TX39_CONF_CWFON))
308 printk("TX3927 D-Cache WriteBack.\n");
309 else
310 printk("TX3927 D-Cache WriteBack (CWF) .\n");
311 }
312}
313
314/* This trick makes rtc-ds1742 driver usable as is. */
315static unsigned long jmr3927_swizzle_addr_b(unsigned long port)
316{
317 if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR)
318 return port;
319 port = (port & 0xffff0000) | (port & 0x7fff << 1);
320#ifdef __BIG_ENDIAN
321 return port;
322#else
323 return port | 1;
324#endif
325}
326
327static int __init jmr3927_rtc_init(void)
328{
329 static struct resource __initdata res = {
330 .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE,
331 .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1,
332 .flags = IORESOURCE_MEM,
333 };
334 struct platform_device *dev;
335 dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1);
336 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
337}
338
339/* Watchdog support */
340
341static int __init txx9_wdt_init(unsigned long base)
342{
343 struct resource res = {
344 .start = base,
345 .end = base + 0x100 - 1,
346 .flags = IORESOURCE_MEM,
347 };
348 struct platform_device *dev =
349 platform_device_register_simple("txx9wdt", -1, &res, 1);
350 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
351}
352
353static int __init jmr3927_wdt_init(void)
354{
355 return txx9_wdt_init(TX3927_TMR_REG(2));
356}
357
358static void __init jmr3927_device_init(void)
359{
360 __swizzle_addr_b = jmr3927_swizzle_addr_b;
361 jmr3927_rtc_init();
362 jmr3927_wdt_init();
363}
364
365struct txx9_board_vec jmr3927_vec __initdata = {
366 .system = "Toshiba JMR_TX3927",
367 .prom_init = jmr3927_prom_init,
368 .mem_setup = jmr3927_mem_setup,
369 .irq_setup = jmr3927_irq_setup,
370 .time_init = jmr3927_time_init,
371 .device_init = jmr3927_device_init,
372#ifdef CONFIG_PCI
373 .pci_map_irq = jmr3927_pci_map_irq,
374#endif
375};
diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile
new file mode 100644
index 000000000000..f3e1f597b4f1
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/Makefile
@@ -0,0 +1,3 @@
1obj-y += prom.o setup.o irq.o
2
3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
new file mode 100644
index 000000000000..70f13211bc2a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -0,0 +1,199 @@
1/*
2 * Toshiba RBTX4927 specific interrupt handlers
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29/*
30IRQ Device
3100 RBTX4927-ISA/00
3201 RBTX4927-ISA/01 PS2/Keyboard
3302 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15)
3403 RBTX4927-ISA/03
3504 RBTX4927-ISA/04
3605 RBTX4927-ISA/05
3706 RBTX4927-ISA/06
3807 RBTX4927-ISA/07
3908 RBTX4927-ISA/08
4009 RBTX4927-ISA/09
4110 RBTX4927-ISA/10
4211 RBTX4927-ISA/11
4312 RBTX4927-ISA/12 PS2/Mouse (not supported at this time)
4413 RBTX4927-ISA/13
4514 RBTX4927-ISA/14 IDE
4615 RBTX4927-ISA/15
47
4816 TX4927-CP0/00 Software 0
4917 TX4927-CP0/01 Software 1
5018 TX4927-CP0/02 Cascade TX4927-CP0
5119 TX4927-CP0/03 Multiplexed -- do not use
5220 TX4927-CP0/04 Multiplexed -- do not use
5321 TX4927-CP0/05 Multiplexed -- do not use
5422 TX4927-CP0/06 Multiplexed -- do not use
5523 TX4927-CP0/07 CPU TIMER
56
5724 TX4927-PIC/00
5825 TX4927-PIC/01
5926 TX4927-PIC/02
6027 TX4927-PIC/03 Cascade RBTX4927-IOC
6128 TX4927-PIC/04
6229 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet
6330 TX4927-PIC/06
6431 TX4927-PIC/07
6532 TX4927-PIC/08 TX4927 SerialIO Channel 0
6633 TX4927-PIC/09 TX4927 SerialIO Channel 1
6734 TX4927-PIC/10
6835 TX4927-PIC/11
6936 TX4927-PIC/12
7037 TX4927-PIC/13
7138 TX4927-PIC/14
7239 TX4927-PIC/15
7340 TX4927-PIC/16 TX4927 PCI PCI-C
7441 TX4927-PIC/17
7542 TX4927-PIC/18
7643 TX4927-PIC/19
7744 TX4927-PIC/20
7845 TX4927-PIC/21
7946 TX4927-PIC/22 TX4927 PCI PCI-ERR
8047 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used)
8148 TX4927-PIC/24
8249 TX4927-PIC/25
8350 TX4927-PIC/26
8451 TX4927-PIC/27
8552 TX4927-PIC/28
8653 TX4927-PIC/29
8754 TX4927-PIC/30
8855 TX4927-PIC/31
89
9056 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4]
9157 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5]
9258 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported]
9359 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6]
9460 RBTX4927-IOC/04
9561 RBTX4927-IOC/05
9662 RBTX4927-IOC/06
9763 RBTX4927-IOC/07
98
99NOTES:
100SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58
101SouthBridge/ISA/pin=0 no pci irq used by this device
102SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14
103SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59
104SouthBridge/PMC/pin=0 no pci irq used by this device
105SuperIO/PS2/Keyboard, using INTR via ISA IRQ1
106SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported)
107JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6
108*/
109
110#include <linux/init.h>
111#include <linux/types.h>
112#include <linux/interrupt.h>
113#include <asm/io.h>
114#include <asm/mipsregs.h>
115#include <asm/txx9/generic.h>
116#include <asm/txx9/rbtx4927.h>
117
118static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
119static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
120
121#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
122static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
123 .name = TOSHIBA_RBTX4927_IOC_NAME,
124 .ack = toshiba_rbtx4927_irq_ioc_disable,
125 .mask = toshiba_rbtx4927_irq_ioc_disable,
126 .mask_ack = toshiba_rbtx4927_irq_ioc_disable,
127 .unmask = toshiba_rbtx4927_irq_ioc_enable,
128};
129#define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL
130#define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL
131
132static int toshiba_rbtx4927_irq_nested(int sw_irq)
133{
134 u8 level3;
135
136 level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f;
137 if (level3)
138 sw_irq = RBTX4927_IRQ_IOC + fls(level3) - 1;
139 return (sw_irq);
140}
141
142static void __init toshiba_rbtx4927_irq_ioc_init(void)
143{
144 int i;
145
146 for (i = RBTX4927_IRQ_IOC;
147 i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
148 set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
149 handle_level_irq);
150 set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
151}
152
153static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
154{
155 unsigned char v;
156
157 v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
158 v |= (1 << (irq - RBTX4927_IRQ_IOC));
159 writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB);
160}
161
162static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
163{
164 unsigned char v;
165
166 v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
167 v &= ~(1 << (irq - RBTX4927_IRQ_IOC));
168 writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB);
169 mmiowb();
170}
171
172
173static int rbtx4927_irq_dispatch(int pending)
174{
175 int irq;
176
177 if (pending & STATUSF_IP7) /* cpu timer */
178 irq = MIPS_CPU_IRQ_BASE + 7;
179 else if (pending & STATUSF_IP2) { /* tx4927 pic */
180 irq = txx9_irq();
181 if (irq == RBTX4927_IRQ_IOCINT)
182 irq = toshiba_rbtx4927_irq_nested(irq);
183 } else if (pending & STATUSF_IP0) /* user line 0 */
184 irq = MIPS_CPU_IRQ_BASE + 0;
185 else if (pending & STATUSF_IP1) /* user line 1 */
186 irq = MIPS_CPU_IRQ_BASE + 1;
187 else
188 irq = -1;
189 return irq;
190}
191
192void __init rbtx4927_irq_setup(void)
193{
194 txx9_irq_dispatch = rbtx4927_irq_dispatch;
195 tx4927_irq_init();
196 toshiba_rbtx4927_irq_ioc_init();
197 /* Onboard 10M Ether: High Active */
198 set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
199}
diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c
new file mode 100644
index 000000000000..942e627d2dc1
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/prom.c
@@ -0,0 +1,45 @@
1/*
2 * rbtx4927 specific prom routines
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * Copyright (C) 2004 MontaVista Software Inc.
10 * Author: Manish Lachwani, mlachwani@mvista.com
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/init.h>
33#include <asm/bootinfo.h>
34#include <asm/txx9/generic.h>
35#include <asm/txx9/rbtx4927.h>
36
37void __init rbtx4927_prom_init(void)
38{
39 extern int tx4927_get_mem_size(void);
40 int msize;
41
42 prom_init_cmdline();
43 msize = tx4927_get_mem_size();
44 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
45}
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
new file mode 100644
index 000000000000..1657fd935da8
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -0,0 +1,443 @@
1/*
2 * Toshiba rbtx4927 specific setup
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * Copyright 2001-2002 MontaVista Software Inc.
8 *
9 * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
10 * Copyright (C) 2000 RidgeRun, Inc.
11 * Author: RidgeRun, Inc.
12 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
13 *
14 * Copyright 2001 MontaVista Software Inc.
15 * Author: jsun@mvista.com or jsun@junsun.net
16 *
17 * Copyright 2002 MontaVista Software Inc.
18 * Author: Michael Pruznick, michael_pruznick@mvista.com
19 *
20 * Copyright (C) 2000-2001 Toshiba Corporation
21 *
22 * Copyright (C) 2004 MontaVista Software Inc.
23 * Author: Manish Lachwani, mlachwani@mvista.com
24 *
25 * This program is free software; you can redistribute it and/or modify it
26 * under the terms of the GNU General Public License as published by the
27 * Free Software Foundation; either version 2 of the License, or (at your
28 * option) any later version.
29 *
30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
31 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
33 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
36 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * You should have received a copy of the GNU General Public License along
42 * with this program; if not, write to the Free Software Foundation, Inc.,
43 * 675 Mass Ave, Cambridge, MA 02139, USA.
44 */
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/types.h>
48#include <linux/ioport.h>
49#include <linux/interrupt.h>
50#include <linux/pm.h>
51#include <linux/platform_device.h>
52#include <linux/delay.h>
53#include <asm/io.h>
54#include <asm/processor.h>
55#include <asm/reboot.h>
56#include <asm/time.h>
57#include <asm/txx9tmr.h>
58#include <asm/txx9/generic.h>
59#include <asm/txx9/pci.h>
60#include <asm/txx9/rbtx4927.h>
61#include <asm/txx9/tx4938.h> /* for TX4937 */
62#ifdef CONFIG_SERIAL_TXX9
63#include <linux/serial_core.h>
64#endif
65
66static int tx4927_ccfg_toeon = 1;
67
68#ifdef CONFIG_PCI
69static void __init tx4927_pci_setup(void)
70{
71 int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB);
72 struct pci_controller *c = &txx9_primary_pcic;
73
74 register_pci_controller(c);
75
76 if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66)
77 txx9_pci_option =
78 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
79 TXX9_PCI_OPT_CLK_66; /* already configured */
80
81 /* Reset PCI Bus */
82 writeb(1, rbtx4927_pcireset_addr);
83 /* Reset PCIC */
84 txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
85 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
86 TXX9_PCI_OPT_CLK_66)
87 tx4927_pciclk66_setup();
88 mdelay(10);
89 /* clear PCIC reset */
90 txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
91 writeb(0, rbtx4927_pcireset_addr);
92 iob();
93
94 tx4927_report_pciclk();
95 tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
96 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
97 TXX9_PCI_OPT_CLK_AUTO &&
98 txx9_pci66_check(c, 0, 0)) {
99 /* Reset PCI Bus */
100 writeb(1, rbtx4927_pcireset_addr);
101 /* Reset PCIC */
102 txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
103 tx4927_pciclk66_setup();
104 mdelay(10);
105 /* clear PCIC reset */
106 txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
107 writeb(0, rbtx4927_pcireset_addr);
108 iob();
109 /* Reinitialize PCIC */
110 tx4927_report_pciclk();
111 tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
112 }
113}
114
115static void __init tx4937_pci_setup(void)
116{
117 int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
118 struct pci_controller *c = &txx9_primary_pcic;
119
120 register_pci_controller(c);
121
122 if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
123 txx9_pci_option =
124 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
125 TXX9_PCI_OPT_CLK_66; /* already configured */
126
127 /* Reset PCI Bus */
128 writeb(1, rbtx4927_pcireset_addr);
129 /* Reset PCIC */
130 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
131 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
132 TXX9_PCI_OPT_CLK_66)
133 tx4938_pciclk66_setup();
134 mdelay(10);
135 /* clear PCIC reset */
136 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
137 writeb(0, rbtx4927_pcireset_addr);
138 iob();
139
140 tx4938_report_pciclk();
141 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
142 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
143 TXX9_PCI_OPT_CLK_AUTO &&
144 txx9_pci66_check(c, 0, 0)) {
145 /* Reset PCI Bus */
146 writeb(1, rbtx4927_pcireset_addr);
147 /* Reset PCIC */
148 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
149 tx4938_pciclk66_setup();
150 mdelay(10);
151 /* clear PCIC reset */
152 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
153 writeb(0, rbtx4927_pcireset_addr);
154 iob();
155 /* Reinitialize PCIC */
156 tx4938_report_pciclk();
157 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
158 }
159}
160
161static void __init rbtx4927_arch_init(void)
162{
163 tx4927_pci_setup();
164}
165
166static void __init rbtx4937_arch_init(void)
167{
168 tx4937_pci_setup();
169}
170#else
171#define rbtx4927_arch_init NULL
172#define rbtx4937_arch_init NULL
173#endif /* CONFIG_PCI */
174
175static void __noreturn wait_forever(void)
176{
177 while (1)
178 if (cpu_wait)
179 (*cpu_wait)();
180}
181
182static void toshiba_rbtx4927_restart(char *command)
183{
184 printk(KERN_NOTICE "System Rebooting...\n");
185
186 /* enable the s/w reset register */
187 writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE);
188
189 /* wait for enable to be seen */
190 while ((readb(RBTX4927_SW_RESET_ENABLE) &
191 RBTX4927_SW_RESET_ENABLE_SET) == 0x00);
192
193 /* do a s/w reset */
194 writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO);
195
196 /* do something passive while waiting for reset */
197 local_irq_disable();
198 wait_forever();
199 /* no return */
200}
201
202static void toshiba_rbtx4927_halt(void)
203{
204 printk(KERN_NOTICE "System Halted\n");
205 local_irq_disable();
206 wait_forever();
207 /* no return */
208}
209
210static void toshiba_rbtx4927_power_off(void)
211{
212 toshiba_rbtx4927_halt();
213 /* no return */
214}
215
216static void __init rbtx4927_mem_setup(void)
217{
218 int i;
219 u32 cp0_config;
220 char *argptr;
221
222 /* f/w leaves this on at startup */
223 clear_c0_status(ST0_ERL);
224
225 /* enable caches -- HCP5 does this, pmon does not */
226 cp0_config = read_c0_config();
227 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
228 write_c0_config(cp0_config);
229
230 ioport_resource.end = 0xffffffff;
231 iomem_resource.end = 0xffffffff;
232
233 _machine_restart = toshiba_rbtx4927_restart;
234 _machine_halt = toshiba_rbtx4927_halt;
235 pm_power_off = toshiba_rbtx4927_power_off;
236
237 for (i = 0; i < TX4927_NR_TMR; i++)
238 txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL);
239
240#ifdef CONFIG_PCI
241 txx9_alloc_pci_controller(&txx9_primary_pcic,
242 RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE,
243 RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE);
244#else
245 set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET);
246#endif
247
248 /* CCFG */
249 /* do reset on watchdog */
250 tx4927_ccfg_set(TX4927_CCFG_WR);
251 /* enable Timeout BusError */
252 if (tx4927_ccfg_toeon)
253 tx4927_ccfg_set(TX4927_CCFG_TOE);
254
255#ifdef CONFIG_SERIAL_TXX9
256 {
257 extern int early_serial_txx9_setup(struct uart_port *port);
258 struct uart_port req;
259 for(i = 0; i < 2; i++) {
260 memset(&req, 0, sizeof(req));
261 req.line = i;
262 req.iotype = UPIO_MEM;
263 req.membase = (char *)(0xff1ff300 + i * 0x100);
264 req.mapbase = 0xff1ff300 + i * 0x100;
265 req.irq = TXX9_IRQ_BASE + TX4927_IR_SIO(i);
266 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
267 req.uartclk = 50000000;
268 early_serial_txx9_setup(&req);
269 }
270 }
271#ifdef CONFIG_SERIAL_TXX9_CONSOLE
272 argptr = prom_getcmdline();
273 if (strstr(argptr, "console=") == NULL) {
274 strcat(argptr, " console=ttyS0,38400");
275 }
276#endif
277#endif
278
279#ifdef CONFIG_ROOT_NFS
280 argptr = prom_getcmdline();
281 if (strstr(argptr, "root=") == NULL) {
282 strcat(argptr, " root=/dev/nfs rw");
283 }
284#endif
285
286#ifdef CONFIG_IP_PNP
287 argptr = prom_getcmdline();
288 if (strstr(argptr, "ip=") == NULL) {
289 strcat(argptr, " ip=any");
290 }
291#endif
292}
293
294static void __init rbtx49x7_common_time_init(void)
295{
296 /* change default value to udelay/mdelay take reasonable time */
297 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
298
299 mips_hpt_frequency = txx9_cpu_clock / 2;
300 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS)
301 txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
302 TXX9_IRQ_BASE + 17,
303 50000000);
304}
305
306static void __init rbtx4927_time_init(void)
307{
308 /*
309 * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
310 *
311 * For TX4927:
312 * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
313 * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
314 * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
315 * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
316 * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
317 * i.e. S9[3]: ON (83MHz), OFF (100MHz)
318 */
319 switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) &
320 TX4927_CCFG_PCIDIVMODE_MASK) {
321 case TX4927_CCFG_PCIDIVMODE_2_5:
322 case TX4927_CCFG_PCIDIVMODE_5:
323 txx9_cpu_clock = 166666666; /* 166MHz */
324 break;
325 default:
326 txx9_cpu_clock = 200000000; /* 200MHz */
327 }
328
329 rbtx49x7_common_time_init();
330}
331
332static void __init rbtx4937_time_init(void)
333{
334 /*
335 * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
336 *
337 * For TX4937:
338 * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
339 * PCIDIVMODE[10] is 0.
340 * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
341 * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
342 * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
343 * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
344 * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
345 * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
346 */
347 switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) &
348 TX4938_CCFG_PCIDIVMODE_MASK) {
349 case TX4938_CCFG_PCIDIVMODE_8:
350 case TX4938_CCFG_PCIDIVMODE_4:
351 txx9_cpu_clock = 266666666; /* 266MHz */
352 break;
353 case TX4938_CCFG_PCIDIVMODE_9:
354 case TX4938_CCFG_PCIDIVMODE_4_5:
355 txx9_cpu_clock = 300000000; /* 300MHz */
356 break;
357 default:
358 txx9_cpu_clock = 333333333; /* 333MHz */
359 }
360
361 rbtx49x7_common_time_init();
362}
363
364static int __init toshiba_rbtx4927_rtc_init(void)
365{
366 static struct resource __initdata res = {
367 .start = 0x1c010000,
368 .end = 0x1c010000 + 0x800 - 1,
369 .flags = IORESOURCE_MEM,
370 };
371 struct platform_device *dev =
372 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
373 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
374}
375
376static int __init rbtx4927_ne_init(void)
377{
378 static struct resource __initdata res[] = {
379 {
380 .start = RBTX4927_RTL_8019_BASE,
381 .end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
382 .flags = IORESOURCE_IO,
383 }, {
384 .start = RBTX4927_RTL_8019_IRQ,
385 .flags = IORESOURCE_IRQ,
386 }
387 };
388 struct platform_device *dev =
389 platform_device_register_simple("ne", -1,
390 res, ARRAY_SIZE(res));
391 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
392}
393
394/* Watchdog support */
395
396static int __init txx9_wdt_init(unsigned long base)
397{
398 struct resource res = {
399 .start = base,
400 .end = base + 0x100 - 1,
401 .flags = IORESOURCE_MEM,
402 };
403 struct platform_device *dev =
404 platform_device_register_simple("txx9wdt", -1, &res, 1);
405 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
406}
407
408static int __init rbtx4927_wdt_init(void)
409{
410 return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
411}
412
413static void __init rbtx4927_device_init(void)
414{
415 toshiba_rbtx4927_rtc_init();
416 rbtx4927_ne_init();
417 rbtx4927_wdt_init();
418}
419
420struct txx9_board_vec rbtx4927_vec __initdata = {
421 .system = "Toshiba RBTX4927",
422 .prom_init = rbtx4927_prom_init,
423 .mem_setup = rbtx4927_mem_setup,
424 .irq_setup = rbtx4927_irq_setup,
425 .time_init = rbtx4927_time_init,
426 .device_init = rbtx4927_device_init,
427 .arch_init = rbtx4927_arch_init,
428#ifdef CONFIG_PCI
429 .pci_map_irq = rbtx4927_pci_map_irq,
430#endif
431};
432struct txx9_board_vec rbtx4937_vec __initdata = {
433 .system = "Toshiba RBTX4937",
434 .prom_init = rbtx4927_prom_init,
435 .mem_setup = rbtx4927_mem_setup,
436 .irq_setup = rbtx4927_irq_setup,
437 .time_init = rbtx4937_time_init,
438 .device_init = rbtx4927_device_init,
439 .arch_init = rbtx4937_arch_init,
440#ifdef CONFIG_PCI
441 .pci_map_irq = rbtx4927_pci_map_irq,
442#endif
443};
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
new file mode 100644
index 000000000000..9dcc52ae5b9d
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -0,0 +1,3 @@
1obj-y += prom.o setup.o irq.o spi_eeprom.o
2
3EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
new file mode 100644
index 000000000000..3971a061657a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -0,0 +1,169 @@
1/*
2 * Toshiba RBTX4938 specific interrupt handlers
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12
13/*
14IRQ Device
15
1616 TX4938-CP0/00 Software 0
1717 TX4938-CP0/01 Software 1
1818 TX4938-CP0/02 Cascade TX4938-CP0
1919 TX4938-CP0/03 Multiplexed -- do not use
2020 TX4938-CP0/04 Multiplexed -- do not use
2121 TX4938-CP0/05 Multiplexed -- do not use
2222 TX4938-CP0/06 Multiplexed -- do not use
2323 TX4938-CP0/07 CPU TIMER
24
2524 TX4938-PIC/00
2625 TX4938-PIC/01
2726 TX4938-PIC/02 Cascade RBTX4938-IOC
2827 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet
2928 TX4938-PIC/04
3029 TX4938-PIC/05 TX4938 ETH1
3130 TX4938-PIC/06 TX4938 ETH0
3231 TX4938-PIC/07
3332 TX4938-PIC/08 TX4938 SIO 0
3433 TX4938-PIC/09 TX4938 SIO 1
3534 TX4938-PIC/10 TX4938 DMA0
3635 TX4938-PIC/11 TX4938 DMA1
3736 TX4938-PIC/12 TX4938 DMA2
3837 TX4938-PIC/13 TX4938 DMA3
3938 TX4938-PIC/14
4039 TX4938-PIC/15
4140 TX4938-PIC/16 TX4938 PCIC
4241 TX4938-PIC/17 TX4938 TMR0
4342 TX4938-PIC/18 TX4938 TMR1
4443 TX4938-PIC/19 TX4938 TMR2
4544 TX4938-PIC/20
4645 TX4938-PIC/21
4746 TX4938-PIC/22 TX4938 PCIERR
4847 TX4938-PIC/23
4948 TX4938-PIC/24
5049 TX4938-PIC/25
5150 TX4938-PIC/26
5251 TX4938-PIC/27
5352 TX4938-PIC/28
5453 TX4938-PIC/29
5554 TX4938-PIC/30
5655 TX4938-PIC/31 TX4938 SPI
57
5856 RBTX4938-IOC/00 PCI-D
5957 RBTX4938-IOC/01 PCI-C
6058 RBTX4938-IOC/02 PCI-B
6159 RBTX4938-IOC/03 PCI-A
6260 RBTX4938-IOC/04 RTC
6361 RBTX4938-IOC/05 ATA
6462 RBTX4938-IOC/06 MODEM
6563 RBTX4938-IOC/07 SWINT
66*/
67#include <linux/init.h>
68#include <linux/interrupt.h>
69#include <asm/mipsregs.h>
70#include <asm/txx9/generic.h>
71#include <asm/txx9/rbtx4938.h>
72
73static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
74static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
75
76#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
77static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
78 .name = TOSHIBA_RBTX4938_IOC_NAME,
79 .ack = toshiba_rbtx4938_irq_ioc_disable,
80 .mask = toshiba_rbtx4938_irq_ioc_disable,
81 .mask_ack = toshiba_rbtx4938_irq_ioc_disable,
82 .unmask = toshiba_rbtx4938_irq_ioc_enable,
83};
84
85static int toshiba_rbtx4938_irq_nested(int sw_irq)
86{
87 u8 level3;
88
89 level3 = readb(rbtx4938_imstat_addr);
90 if (level3)
91 /* must use fls so onboard ATA has priority */
92 sw_irq = RBTX4938_IRQ_IOC + fls(level3) - 1;
93 return sw_irq;
94}
95
96/**********************************************************************************/
97/* Functions for ioc */
98/**********************************************************************************/
99static void __init
100toshiba_rbtx4938_irq_ioc_init(void)
101{
102 int i;
103
104 for (i = RBTX4938_IRQ_IOC;
105 i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
106 set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
107 handle_level_irq);
108
109 set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
110}
111
112static void
113toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
114{
115 unsigned char v;
116
117 v = readb(rbtx4938_imask_addr);
118 v |= (1 << (irq - RBTX4938_IRQ_IOC));
119 writeb(v, rbtx4938_imask_addr);
120 mmiowb();
121}
122
123static void
124toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
125{
126 unsigned char v;
127
128 v = readb(rbtx4938_imask_addr);
129 v &= ~(1 << (irq - RBTX4938_IRQ_IOC));
130 writeb(v, rbtx4938_imask_addr);
131 mmiowb();
132}
133
134static int rbtx4938_irq_dispatch(int pending)
135{
136 int irq;
137
138 if (pending & STATUSF_IP7)
139 irq = MIPS_CPU_IRQ_BASE + 7;
140 else if (pending & STATUSF_IP2) {
141 irq = txx9_irq();
142 if (irq == RBTX4938_IRQ_IOCINT)
143 irq = toshiba_rbtx4938_irq_nested(irq);
144 } else if (pending & STATUSF_IP1)
145 irq = MIPS_CPU_IRQ_BASE + 0;
146 else if (pending & STATUSF_IP0)
147 irq = MIPS_CPU_IRQ_BASE + 1;
148 else
149 irq = -1;
150 return irq;
151}
152
153void __init rbtx4938_irq_setup(void)
154{
155 txx9_irq_dispatch = rbtx4938_irq_dispatch;
156 /* Now, interrupt control disabled, */
157 /* all IRC interrupts are masked, */
158 /* all IRC interrupt mode are Low Active. */
159
160 /* mask all IOC interrupts */
161 writeb(0, rbtx4938_imask_addr);
162
163 /* clear SoftInt interrupts */
164 writeb(0, rbtx4938_softint_addr);
165 tx4938_irq_init();
166 toshiba_rbtx4938_irq_ioc_init();
167 /* Onboard 10M Ether: High Active */
168 set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
169}
diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c
new file mode 100644
index 000000000000..fbb37458ddb2
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/prom.c
@@ -0,0 +1,29 @@
1/*
2 * rbtx4938 specific prom routines
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12
13#include <linux/init.h>
14#include <linux/bootmem.h>
15#include <asm/bootinfo.h>
16#include <asm/txx9/generic.h>
17#include <asm/txx9/rbtx4938.h>
18
19void __init rbtx4938_prom_init(void)
20{
21 extern int tx4938_get_mem_size(void);
22 int msize;
23#ifndef CONFIG_TX4938_NAND_BOOT
24 prom_init_cmdline();
25#endif
26
27 msize = tx4938_get_mem_size();
28 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
29}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
new file mode 100644
index 000000000000..aaa987ae0f83
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -0,0 +1,625 @@
1/*
2 * Setup pointers to hardware-dependent routines.
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/types.h>
14#include <linux/ioport.h>
15#include <linux/delay.h>
16#include <linux/interrupt.h>
17#include <linux/console.h>
18#include <linux/pm.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21
22#include <asm/reboot.h>
23#include <asm/time.h>
24#include <asm/txx9tmr.h>
25#include <asm/io.h>
26#include <asm/txx9/generic.h>
27#include <asm/txx9/pci.h>
28#include <asm/txx9/rbtx4938.h>
29#ifdef CONFIG_SERIAL_TXX9
30#include <linux/serial_core.h>
31#endif
32#include <linux/spi/spi.h>
33#include <asm/txx9/spi.h>
34#include <asm/txx9pio.h>
35
36static int tx4938_ccfg_toeon = 1;
37
38static void rbtx4938_machine_halt(void)
39{
40 printk(KERN_NOTICE "System Halted\n");
41 local_irq_disable();
42
43 while (1)
44 __asm__(".set\tmips3\n\t"
45 "wait\n\t"
46 ".set\tmips0");
47}
48
49static void rbtx4938_machine_power_off(void)
50{
51 rbtx4938_machine_halt();
52 /* no return */
53}
54
55static void rbtx4938_machine_restart(char *command)
56{
57 local_irq_disable();
58
59 printk("Rebooting...");
60 writeb(1, rbtx4938_softresetlock_addr);
61 writeb(1, rbtx4938_sfvol_addr);
62 writeb(1, rbtx4938_softreset_addr);
63 while(1)
64 ;
65}
66
67static void __init rbtx4938_pci_setup(void)
68{
69#ifdef CONFIG_PCI
70 int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
71 struct pci_controller *c = &txx9_primary_pcic;
72
73 register_pci_controller(c);
74
75 if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
76 txx9_pci_option =
77 (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
78 TXX9_PCI_OPT_CLK_66; /* already configured */
79
80 /* Reset PCI Bus */
81 writeb(0, rbtx4938_pcireset_addr);
82 /* Reset PCIC */
83 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
84 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
85 TXX9_PCI_OPT_CLK_66)
86 tx4938_pciclk66_setup();
87 mdelay(10);
88 /* clear PCIC reset */
89 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
90 writeb(1, rbtx4938_pcireset_addr);
91 iob();
92
93 tx4938_report_pciclk();
94 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
95 if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
96 TXX9_PCI_OPT_CLK_AUTO &&
97 txx9_pci66_check(c, 0, 0)) {
98 /* Reset PCI Bus */
99 writeb(0, rbtx4938_pcireset_addr);
100 /* Reset PCIC */
101 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
102 tx4938_pciclk66_setup();
103 mdelay(10);
104 /* clear PCIC reset */
105 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
106 writeb(1, rbtx4938_pcireset_addr);
107 iob();
108 /* Reinitialize PCIC */
109 tx4938_report_pciclk();
110 tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
111 }
112
113 if (__raw_readq(&tx4938_ccfgptr->pcfg) &
114 (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) {
115 /* Reset PCIC1 */
116 txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
117 /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
118 if (!(__raw_readq(&tx4938_ccfgptr->ccfg)
119 & TX4938_CCFG_PCI1DMD))
120 tx4938_ccfg_set(TX4938_CCFG_PCI1_66);
121 mdelay(10);
122 /* clear PCIC1 reset */
123 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
124 tx4938_report_pci1clk();
125
126 /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
127 c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
128 register_pci_controller(c);
129 tx4927_pcic_setup(tx4938_pcic1ptr, c, 0);
130 }
131#endif /* CONFIG_PCI */
132}
133
134/* SPI support */
135
136/* chip select for SPI devices */
137#define SEEPROM1_CS 7 /* PIO7 */
138#define SEEPROM2_CS 0 /* IOC */
139#define SEEPROM3_CS 1 /* IOC */
140#define SRTC_CS 2 /* IOC */
141
142static int __init rbtx4938_ethaddr_init(void)
143{
144#ifdef CONFIG_PCI
145 unsigned char dat[17];
146 unsigned char sum;
147 int i;
148
149 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
150 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
151 printk(KERN_ERR "seeprom: read error.\n");
152 return -ENODEV;
153 } else {
154 if (strcmp(dat, "MAC") != 0)
155 printk(KERN_WARNING "seeprom: bad signature.\n");
156 for (i = 0, sum = 0; i < sizeof(dat); i++)
157 sum += dat[i];
158 if (sum)
159 printk(KERN_WARNING "seeprom: bad checksum.\n");
160 }
161 for (i = 0; i < 2; i++) {
162 unsigned int id =
163 TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0);
164 struct platform_device *pdev;
165 if (!(__raw_readq(&tx4938_ccfgptr->pcfg) &
166 (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
167 continue;
168 pdev = platform_device_alloc("tc35815-mac", id);
169 if (!pdev ||
170 platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
171 platform_device_add(pdev))
172 platform_device_put(pdev);
173 }
174#endif /* CONFIG_PCI */
175 return 0;
176}
177
178static void __init rbtx4938_spi_setup(void)
179{
180 /* set SPI_SEL */
181 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL);
182}
183
184static struct resource rbtx4938_fpga_resource;
185static struct resource tx4938_sdram_resource[4];
186static struct resource tx4938_sram_resource;
187
188void __init tx4938_board_setup(void)
189{
190 int i;
191 unsigned long divmode;
192 int cpuclk = 0;
193 unsigned long pcode = TX4938_REV_PCODE();
194
195 ioport_resource.start = 0;
196 ioport_resource.end = 0xffffffff;
197 iomem_resource.start = 0;
198 iomem_resource.end = 0xffffffff; /* expand to 4GB */
199
200 txx9_reg_res_init(pcode, TX4938_REG_BASE,
201 TX4938_REG_SIZE);
202 /* SDRAMC,EBUSC are configured by PROM */
203 for (i = 0; i < 8; i++) {
204 if (!(TX4938_EBUSC_CR(i) & 0x8))
205 continue; /* disabled */
206 txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i);
207 txx9_ce_res[i].end =
208 txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1;
209 request_resource(&iomem_resource, &txx9_ce_res[i]);
210 }
211
212 /* clocks */
213 if (txx9_master_clock) {
214 u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg);
215 /* calculate gbus_clock and cpu_clock_freq from master_clock */
216 divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
217 switch (divmode) {
218 case TX4938_CCFG_DIVMODE_8:
219 case TX4938_CCFG_DIVMODE_10:
220 case TX4938_CCFG_DIVMODE_12:
221 case TX4938_CCFG_DIVMODE_16:
222 case TX4938_CCFG_DIVMODE_18:
223 txx9_gbus_clock = txx9_master_clock * 4; break;
224 default:
225 txx9_gbus_clock = txx9_master_clock;
226 }
227 switch (divmode) {
228 case TX4938_CCFG_DIVMODE_2:
229 case TX4938_CCFG_DIVMODE_8:
230 cpuclk = txx9_gbus_clock * 2; break;
231 case TX4938_CCFG_DIVMODE_2_5:
232 case TX4938_CCFG_DIVMODE_10:
233 cpuclk = txx9_gbus_clock * 5 / 2; break;
234 case TX4938_CCFG_DIVMODE_3:
235 case TX4938_CCFG_DIVMODE_12:
236 cpuclk = txx9_gbus_clock * 3; break;
237 case TX4938_CCFG_DIVMODE_4:
238 case TX4938_CCFG_DIVMODE_16:
239 cpuclk = txx9_gbus_clock * 4; break;
240 case TX4938_CCFG_DIVMODE_4_5:
241 case TX4938_CCFG_DIVMODE_18:
242 cpuclk = txx9_gbus_clock * 9 / 2; break;
243 }
244 txx9_cpu_clock = cpuclk;
245 } else {
246 u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg);
247 if (txx9_cpu_clock == 0) {
248 txx9_cpu_clock = 300000000; /* 300MHz */
249 }
250 /* calculate gbus_clock and master_clock from cpu_clock_freq */
251 cpuclk = txx9_cpu_clock;
252 divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
253 switch (divmode) {
254 case TX4938_CCFG_DIVMODE_2:
255 case TX4938_CCFG_DIVMODE_8:
256 txx9_gbus_clock = cpuclk / 2; break;
257 case TX4938_CCFG_DIVMODE_2_5:
258 case TX4938_CCFG_DIVMODE_10:
259 txx9_gbus_clock = cpuclk * 2 / 5; break;
260 case TX4938_CCFG_DIVMODE_3:
261 case TX4938_CCFG_DIVMODE_12:
262 txx9_gbus_clock = cpuclk / 3; break;
263 case TX4938_CCFG_DIVMODE_4:
264 case TX4938_CCFG_DIVMODE_16:
265 txx9_gbus_clock = cpuclk / 4; break;
266 case TX4938_CCFG_DIVMODE_4_5:
267 case TX4938_CCFG_DIVMODE_18:
268 txx9_gbus_clock = cpuclk * 2 / 9; break;
269 }
270 switch (divmode) {
271 case TX4938_CCFG_DIVMODE_8:
272 case TX4938_CCFG_DIVMODE_10:
273 case TX4938_CCFG_DIVMODE_12:
274 case TX4938_CCFG_DIVMODE_16:
275 case TX4938_CCFG_DIVMODE_18:
276 txx9_master_clock = txx9_gbus_clock / 4; break;
277 default:
278 txx9_master_clock = txx9_gbus_clock;
279 }
280 }
281 /* change default value to udelay/mdelay take reasonable time */
282 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
283
284 /* CCFG */
285 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
286 tx4938_ccfg_set(TX4938_CCFG_WDRST | TX4938_CCFG_BEOW);
287 /* do reset on watchdog */
288 tx4938_ccfg_set(TX4938_CCFG_WR);
289 /* clear PCIC1 reset */
290 txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
291
292 /* enable Timeout BusError */
293 if (tx4938_ccfg_toeon)
294 tx4938_ccfg_set(TX4938_CCFG_TOE);
295
296 /* DMA selection */
297 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL);
298
299 /* Use external clock for external arbiter */
300 if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB))
301 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL);
302
303 printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
304 txx9_pcode_str,
305 (cpuclk + 500000) / 1000000,
306 (txx9_master_clock + 500000) / 1000000,
307 (__u32)____raw_readq(&tx4938_ccfgptr->crir),
308 (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg),
309 (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg));
310
311 printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str);
312 for (i = 0; i < 4; i++) {
313 unsigned long long cr = tx4938_sdramcptr->cr[i];
314 unsigned long ram_base, ram_size;
315 if (!((unsigned long)cr & 0x00000400))
316 continue; /* disabled */
317 ram_base = (unsigned long)(cr >> 49) << 21;
318 ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
319 if (ram_base >= 0x20000000)
320 continue; /* high memory (ignore) */
321 printk(" CR%d:%016Lx", i, cr);
322 tx4938_sdram_resource[i].name = "SDRAM";
323 tx4938_sdram_resource[i].start = ram_base;
324 tx4938_sdram_resource[i].end = ram_base + ram_size - 1;
325 tx4938_sdram_resource[i].flags = IORESOURCE_MEM;
326 request_resource(&iomem_resource, &tx4938_sdram_resource[i]);
327 }
328 printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
329
330 /* SRAM */
331 if (tx4938_sramcptr->cr & 1) {
332 unsigned int size = 0x800;
333 unsigned long base =
334 (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
335 tx4938_sram_resource.name = "SRAM";
336 tx4938_sram_resource.start = base;
337 tx4938_sram_resource.end = base + size - 1;
338 tx4938_sram_resource.flags = IORESOURCE_MEM;
339 request_resource(&iomem_resource, &tx4938_sram_resource);
340 }
341
342 /* TMR */
343 for (i = 0; i < TX4938_NR_TMR; i++)
344 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
345
346 /* enable DMA */
347 for (i = 0; i < 2; i++)
348 ____raw_writeq(TX4938_DMA_MCR_MSTEN,
349 (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
350
351 /* PIO */
352 __raw_writel(0, &tx4938_pioptr->maskcpu);
353 __raw_writel(0, &tx4938_pioptr->maskext);
354
355#ifdef CONFIG_PCI
356 txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
357#endif
358}
359
360static void __init rbtx4938_time_init(void)
361{
362 mips_hpt_frequency = txx9_cpu_clock / 2;
363 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS)
364 txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL,
365 TXX9_IRQ_BASE + TX4938_IR_TMR(0),
366 txx9_gbus_clock / 2);
367}
368
369static void __init rbtx4938_mem_setup(void)
370{
371 unsigned long long pcfg;
372 char *argptr;
373
374 iomem_resource.end = 0xffffffff; /* 4GB */
375
376 if (txx9_master_clock == 0)
377 txx9_master_clock = 25000000; /* 25MHz */
378 tx4938_board_setup();
379#ifndef CONFIG_PCI
380 set_io_port_base(RBTX4938_ETHER_BASE);
381#endif
382
383#ifdef CONFIG_SERIAL_TXX9
384 {
385 extern int early_serial_txx9_setup(struct uart_port *port);
386 int i;
387 struct uart_port req;
388 for(i = 0; i < 2; i++) {
389 memset(&req, 0, sizeof(req));
390 req.line = i;
391 req.iotype = UPIO_MEM;
392 req.membase = (char *)(0xff1ff300 + i * 0x100);
393 req.mapbase = 0xff1ff300 + i * 0x100;
394 req.irq = RBTX4938_IRQ_IRC_SIO(i);
395 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
396 req.uartclk = 50000000;
397 early_serial_txx9_setup(&req);
398 }
399 }
400#ifdef CONFIG_SERIAL_TXX9_CONSOLE
401 argptr = prom_getcmdline();
402 if (strstr(argptr, "console=") == NULL) {
403 strcat(argptr, " console=ttyS0,38400");
404 }
405#endif
406#endif
407
408#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
409 printk("PIOSEL: disabling both ata and nand selection\n");
410 local_irq_disable();
411 txx9_clear64(&tx4938_ccfgptr->pcfg,
412 TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
413#endif
414
415#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
416 printk("PIOSEL: enabling nand selection\n");
417 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
418 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
419#endif
420
421#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
422 printk("PIOSEL: enabling ata selection\n");
423 txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
424 txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
425#endif
426
427#ifdef CONFIG_IP_PNP
428 argptr = prom_getcmdline();
429 if (strstr(argptr, "ip=") == NULL) {
430 strcat(argptr, " ip=any");
431 }
432#endif
433
434
435#ifdef CONFIG_FB
436 {
437 conswitchp = &dummy_con;
438 }
439#endif
440
441 rbtx4938_spi_setup();
442 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */
443 /* fixup piosel */
444 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
445 TX4938_PCFG_ATA_SEL)
446 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
447 rbtx4938_piosel_addr);
448 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
449 TX4938_PCFG_NDF_SEL)
450 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
451 rbtx4938_piosel_addr);
452 else
453 writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
454 rbtx4938_piosel_addr);
455
456 rbtx4938_fpga_resource.name = "FPGA Registers";
457 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
458 rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
459 rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
460 if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
461 printk("request resource for fpga failed\n");
462
463 _machine_restart = rbtx4938_machine_restart;
464 _machine_halt = rbtx4938_machine_halt;
465 pm_power_off = rbtx4938_machine_power_off;
466
467 writeb(0xff, rbtx4938_led_addr);
468 printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
469 readb(rbtx4938_fpga_rev_addr),
470 readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
471}
472
473static int __init rbtx4938_ne_init(void)
474{
475 struct resource res[] = {
476 {
477 .start = RBTX4938_RTL_8019_BASE,
478 .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
479 .flags = IORESOURCE_IO,
480 }, {
481 .start = RBTX4938_RTL_8019_IRQ,
482 .flags = IORESOURCE_IRQ,
483 }
484 };
485 struct platform_device *dev =
486 platform_device_register_simple("ne", -1,
487 res, ARRAY_SIZE(res));
488 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
489}
490
491/* GPIO support */
492
493int gpio_to_irq(unsigned gpio)
494{
495 return -EINVAL;
496}
497
498int irq_to_gpio(unsigned irq)
499{
500 return -EINVAL;
501}
502
503static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
504
505static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
506 int value)
507{
508 u8 val;
509 unsigned long flags;
510 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
511 val = readb(rbtx4938_spics_addr);
512 if (value)
513 val |= 1 << offset;
514 else
515 val &= ~(1 << offset);
516 writeb(val, rbtx4938_spics_addr);
517 mmiowb();
518 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
519}
520
521static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
522 unsigned int offset, int value)
523{
524 rbtx4938_spi_gpio_set(chip, offset, value);
525 return 0;
526}
527
528static struct gpio_chip rbtx4938_spi_gpio_chip = {
529 .set = rbtx4938_spi_gpio_set,
530 .direction_output = rbtx4938_spi_gpio_dir_out,
531 .label = "RBTX4938-SPICS",
532 .base = 16,
533 .ngpio = 3,
534};
535
536/* SPI support */
537
538static void __init txx9_spi_init(unsigned long base, int irq)
539{
540 struct resource res[] = {
541 {
542 .start = base,
543 .end = base + 0x20 - 1,
544 .flags = IORESOURCE_MEM,
545 }, {
546 .start = irq,
547 .flags = IORESOURCE_IRQ,
548 },
549 };
550 platform_device_register_simple("spi_txx9", 0,
551 res, ARRAY_SIZE(res));
552}
553
554static int __init rbtx4938_spi_init(void)
555{
556 struct spi_board_info srtc_info = {
557 .modalias = "rtc-rs5c348",
558 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
559 .bus_num = 0,
560 .chip_select = 16 + SRTC_CS,
561 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
562 .mode = SPI_MODE_1 | SPI_CS_HIGH,
563 };
564 spi_register_board_info(&srtc_info, 1);
565 spi_eeprom_register(SEEPROM1_CS);
566 spi_eeprom_register(16 + SEEPROM2_CS);
567 spi_eeprom_register(16 + SEEPROM3_CS);
568 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
569 gpio_direction_output(16 + SRTC_CS, 0);
570 gpio_request(SEEPROM1_CS, "seeprom1");
571 gpio_direction_output(SEEPROM1_CS, 1);
572 gpio_request(16 + SEEPROM2_CS, "seeprom2");
573 gpio_direction_output(16 + SEEPROM2_CS, 1);
574 gpio_request(16 + SEEPROM3_CS, "seeprom3");
575 gpio_direction_output(16 + SEEPROM3_CS, 1);
576 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
577 return 0;
578}
579
580static void __init rbtx4938_arch_init(void)
581{
582 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16);
583 gpiochip_add(&rbtx4938_spi_gpio_chip);
584 rbtx4938_pci_setup();
585 rbtx4938_spi_init();
586}
587
588/* Watchdog support */
589
590static int __init txx9_wdt_init(unsigned long base)
591{
592 struct resource res = {
593 .start = base,
594 .end = base + 0x100 - 1,
595 .flags = IORESOURCE_MEM,
596 };
597 struct platform_device *dev =
598 platform_device_register_simple("txx9wdt", -1, &res, 1);
599 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
600}
601
602static int __init rbtx4938_wdt_init(void)
603{
604 return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
605}
606
607static void __init rbtx4938_device_init(void)
608{
609 rbtx4938_ethaddr_init();
610 rbtx4938_ne_init();
611 rbtx4938_wdt_init();
612}
613
614struct txx9_board_vec rbtx4938_vec __initdata = {
615 .system = "Toshiba RBTX4938",
616 .prom_init = rbtx4938_prom_init,
617 .mem_setup = rbtx4938_mem_setup,
618 .irq_setup = rbtx4938_irq_setup,
619 .time_init = rbtx4938_time_init,
620 .device_init = rbtx4938_device_init,
621 .arch_init = rbtx4938_arch_init,
622#ifdef CONFIG_PCI
623 .pci_map_irq = rbtx4938_pci_map_irq,
624#endif
625};
diff --git a/arch/mips/txx9/rbtx4938/spi_eeprom.c b/arch/mips/txx9/rbtx4938/spi_eeprom.c
new file mode 100644
index 000000000000..a7ea8b041c1d
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/spi_eeprom.c
@@ -0,0 +1,99 @@
1/*
2 * spi_eeprom.c
3 * Copyright (C) 2000-2001 Toshiba Corporation
4 *
5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
6 * terms of the GNU General Public License version 2. This program is
7 * licensed "as is" without any warranty of any kind, whether express
8 * or implied.
9 *
10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
11 */
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/spi/spi.h>
15#include <linux/spi/eeprom.h>
16#include <asm/txx9/spi.h>
17
18#define AT250X0_PAGE_SIZE 8
19
20/* register board information for at25 driver */
21int __init spi_eeprom_register(int chipid)
22{
23 static struct spi_eeprom eeprom = {
24 .name = "at250x0",
25 .byte_len = 128,
26 .page_size = AT250X0_PAGE_SIZE,
27 .flags = EE_ADDR1,
28 };
29 struct spi_board_info info = {
30 .modalias = "at25",
31 .max_speed_hz = 1500000, /* 1.5Mbps */
32 .bus_num = 0,
33 .chip_select = chipid,
34 .platform_data = &eeprom,
35 /* Mode 0: High-Active, Sample-Then-Shift */
36 };
37
38 return spi_register_board_info(&info, 1);
39}
40
41/* simple temporary spi driver to provide early access to seeprom. */
42
43static struct read_param {
44 int chipid;
45 int address;
46 unsigned char *buf;
47 int len;
48} *read_param;
49
50static int __init early_seeprom_probe(struct spi_device *spi)
51{
52 int stat = 0;
53 u8 cmd[2];
54 int len = read_param->len;
55 char *buf = read_param->buf;
56 int address = read_param->address;
57
58 dev_info(&spi->dev, "spiclk %u KHz.\n",
59 (spi->max_speed_hz + 500) / 1000);
60 if (read_param->chipid != spi->chip_select)
61 return -ENODEV;
62 while (len > 0) {
63 /* spi_write_then_read can only work with small chunk */
64 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
65 cmd[0] = 0x03; /* AT25_READ */
66 cmd[1] = address;
67 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
68 buf += c;
69 len -= c;
70 address += c;
71 }
72 return stat;
73}
74
75static struct spi_driver early_seeprom_driver __initdata = {
76 .driver = {
77 .name = "at25",
78 .owner = THIS_MODULE,
79 },
80 .probe = early_seeprom_probe,
81};
82
83int __init spi_eeprom_read(int chipid, int address,
84 unsigned char *buf, int len)
85{
86 int ret;
87 struct read_param param = {
88 .chipid = chipid,
89 .address = address,
90 .buf = buf,
91 .len = len
92 };
93
94 read_param = &param;
95 ret = spi_register_driver(&early_seeprom_driver);
96 if (!ret)
97 spi_unregister_driver(&early_seeprom_driver);
98 return ret;
99}