aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/txx9
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-07-10 11:31:36 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-07-15 13:44:35 -0400
commit22b1d707ffc99faebd86257ad19d5bb9fc624734 (patch)
tree9bd0bcd3878611d74db29e17f3c6e951f4656e61 /arch/mips/txx9
parent14476007c90005c8992b786c15a59cca31f53268 (diff)
[MIPS] TXx9: Reorganize code
Move arch/mips/{jmr3927,tx4927,tx4938} into arch/mips/txx9/ tree. This will help more code sharing and maintainance. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/txx9')
-rw-r--r--arch/mips/txx9/Kconfig28
-rw-r--r--arch/mips/txx9/generic/Makefile10
-rw-r--r--arch/mips/txx9/generic/dbgio.c48
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c64
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c48
-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/smsc_fdc37m81x.c172
-rw-r--r--arch/mips/txx9/jmr3927/Makefile8
-rw-r--r--arch/mips/txx9/jmr3927/init.c57
-rw-r--r--arch/mips/txx9/jmr3927/irq.c174
-rw-r--r--arch/mips/txx9/jmr3927/kgdb_io.c105
-rw-r--r--arch/mips/txx9/jmr3927/prom.c98
-rw-r--r--arch/mips/txx9/jmr3927/setup.c445
-rw-r--r--arch/mips/txx9/rbtx4927/Makefile3
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c214
-rw-r--r--arch/mips/txx9/rbtx4927/prom.c91
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c703
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile3
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c159
-rw-r--r--arch/mips/txx9/rbtx4938/prom.c72
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c1122
-rw-r--r--arch/mips/txx9/rbtx4938/spi_eeprom.c99
23 files changed, 3988 insertions, 0 deletions
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
new file mode 100644
index 000000000000..98d103402b10
--- /dev/null
+++ b/arch/mips/txx9/Kconfig
@@ -0,0 +1,28 @@
1config TOSHIBA_FPCIB0
2 bool "FPCIB0 Backplane Support"
3 depends on TOSHIBA_RBTX4927
4
5if TOSHIBA_RBTX4938
6
7comment "Multiplex Pin Select"
8choice
9 prompt "PIO[58:61]"
10 default TOSHIBA_RBTX4938_MPLEX_PIO58_61
11
12config TOSHIBA_RBTX4938_MPLEX_PIO58_61
13 bool "PIO"
14config TOSHIBA_RBTX4938_MPLEX_NAND
15 bool "NAND"
16config TOSHIBA_RBTX4938_MPLEX_ATA
17 bool "ATA"
18
19endchoice
20
21config TX4938_NAND_BOOT
22 depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND
23 bool "NAND Boot Support (EXPERIMENTAL)"
24 help
25 This is only for Toshiba RBTX4938 reference board, which has NAND IPL.
26 Select this option if you need to use NAND boot.
27
28endif
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
new file mode 100644
index 000000000000..8cb4a7e81473
--- /dev/null
+++ b/arch/mips/txx9/generic/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for common code for TXx9 based systems
3#
4
5obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o
6obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o
7obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
8obj-$(CONFIG_KGDB) += dbgio.o
9
10EXTRA_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..685ecc2ed551
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -0,0 +1,64 @@
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/mipsregs.h>
30#ifdef CONFIG_TOSHIBA_RBTX4927
31#include <asm/txx9/rbtx4927.h>
32#endif
33
34void __init tx4927_irq_init(void)
35{
36 mips_cpu_irq_init();
37 txx9_irq_init(TX4927_IRC_REG);
38 set_irq_chained_handler(TX4927_IRQ_NEST_PIC_ON_CP0, handle_simple_irq);
39}
40
41asmlinkage void plat_irq_dispatch(void)
42{
43 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
44
45 if (pending & STATUSF_IP7) /* cpu timer */
46 do_IRQ(TX4927_IRQ_CPU_TIMER);
47 else if (pending & STATUSF_IP2) { /* tx4927 pic */
48 int irq = txx9_irq();
49#ifdef CONFIG_TOSHIBA_RBTX4927
50 if (irq == TX4927_IRQ_NEST_EXT_ON_PIC)
51 irq = toshiba_rbtx4927_irq_nested(irq);
52#endif
53 if (unlikely(irq < 0)) {
54 spurious_interrupt();
55 return;
56 }
57 do_IRQ(irq);
58 } else if (pending & STATUSF_IP0) /* user line 0 */
59 do_IRQ(TX4927_IRQ_USER0);
60 else if (pending & STATUSF_IP1) /* user line 1 */
61 do_IRQ(TX4927_IRQ_USER1);
62 else
63 spurious_interrupt();
64}
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
new file mode 100644
index 000000000000..0886d9138818
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -0,0 +1,48 @@
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/mipsregs.h>
18#include <asm/txx9/rbtx4938.h>
19
20void __init
21tx4938_irq_init(void)
22{
23 mips_cpu_irq_init();
24 txx9_irq_init(TX4938_IRC_REG);
25 set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq);
26}
27
28int toshiba_rbtx4938_irq_nested(int irq);
29
30asmlinkage void plat_irq_dispatch(void)
31{
32 unsigned int pending = read_c0_cause() & read_c0_status();
33
34 if (pending & STATUSF_IP7)
35 do_IRQ(TX4938_IRQ_CPU_TIMER);
36 else if (pending & STATUSF_IP2) {
37 int irq = txx9_irq();
38 if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0))
39 irq = toshiba_rbtx4938_irq_nested(irq);
40 if (irq >= 0)
41 do_IRQ(irq);
42 else
43 spurious_interrupt();
44 } else if (pending & STATUSF_IP1)
45 do_IRQ(TX4938_IRQ_USER1);
46 else if (pending & STATUSF_IP0)
47 do_IRQ(TX4938_IRQ_USER0);
48}
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/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..5f83ea375225
--- /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 init.o irq.o setup.o
6obj-$(CONFIG_KGDB) += kgdb_io.o
7
8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/jmr3927/init.c b/arch/mips/txx9/jmr3927/init.c
new file mode 100644
index 000000000000..1bbb5343baf4
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/init.c
@@ -0,0 +1,57 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * arch/mips/jmr3927/common/init.c
7 *
8 * Copyright (C) 2000-2001 Toshiba Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30#include <linux/init.h>
31#include <asm/bootinfo.h>
32#include <asm/txx9/jmr3927.h>
33
34extern void __init prom_init_cmdline(void);
35
36const char *get_system_type(void)
37{
38 return "Toshiba"
39#ifdef CONFIG_TOSHIBA_JMR3927
40 " JMR_TX3927"
41#endif
42 ;
43}
44
45extern void puts(const char *cp);
46
47void __init prom_init(void)
48{
49#ifdef CONFIG_TOSHIBA_JMR3927
50 /* CCFG */
51 if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
52 puts("Warning: TX3927 TLB off\n");
53#endif
54
55 prom_init_cmdline();
56 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
57}
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
new file mode 100644
index 000000000000..85e1daf15c7b
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -0,0 +1,174 @@
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/jmr3927.h>
43
44#if JMR3927_IRQ_END > NR_IRQS
45#error JMR3927_IRQ_END > NR_IRQS
46#endif
47
48static unsigned char irc_level[TX3927_NUM_IR] = {
49 5, 5, 5, 5, 5, 5, /* INT[5:0] */
50 7, 7, /* SIO */
51 5, 5, 5, 0, 0, /* DMA, PIO, PCI */
52 6, 6, 6 /* TMR */
53};
54
55/*
56 * CP0_STATUS is a thread's resource (saved/restored on context switch).
57 * So disable_irq/enable_irq MUST handle IOC/IRC registers.
58 */
59static void mask_irq_ioc(unsigned int irq)
60{
61 /* 0: mask */
62 unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
63 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
64 unsigned int bit = 1 << irq_nr;
65 jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
66 /* flush write buffer */
67 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
68}
69static void unmask_irq_ioc(unsigned int irq)
70{
71 /* 0: mask */
72 unsigned int irq_nr = irq - JMR3927_IRQ_IOC;
73 unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
74 unsigned int bit = 1 << irq_nr;
75 jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
76 /* flush write buffer */
77 (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
78}
79
80asmlinkage void plat_irq_dispatch(void)
81{
82 unsigned long cp0_cause = read_c0_cause();
83 int irq;
84
85 if ((cp0_cause & CAUSEF_IP7) == 0)
86 return;
87 irq = (cp0_cause >> CAUSEB_IP2) & 0x0f;
88
89 do_IRQ(irq + JMR3927_IRQ_IRC);
90}
91
92static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id)
93{
94 unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
95 int i;
96
97 for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
98 if (istat & (1 << i)) {
99 irq = JMR3927_IRQ_IOC + i;
100 do_IRQ(irq);
101 }
102 }
103 return IRQ_HANDLED;
104}
105
106static struct irqaction ioc_action = {
107 .handler = jmr3927_ioc_interrupt,
108 .mask = CPU_MASK_NONE,
109 .name = "IOC",
110};
111
112static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id)
113{
114 printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
115 printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
116 tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
117
118 return IRQ_HANDLED;
119}
120static struct irqaction pcierr_action = {
121 .handler = jmr3927_pcierr_interrupt,
122 .mask = CPU_MASK_NONE,
123 .name = "PCI error",
124};
125
126static void __init jmr3927_irq_init(void);
127
128void __init arch_init_irq(void)
129{
130 /* Now, interrupt control disabled, */
131 /* all IRC interrupts are masked, */
132 /* all IRC interrupt mode are Low Active. */
133
134 /* mask all IOC interrupts */
135 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
136 /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
137 jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
138
139 /* clear PCI Soft interrupts */
140 jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
141 /* clear PCI Reset interrupts */
142 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
143
144 jmr3927_irq_init();
145
146 /* setup IOC interrupt 1 (PCI, MODEM) */
147 setup_irq(JMR3927_IRQ_IOCINT, &ioc_action);
148
149#ifdef CONFIG_PCI
150 setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action);
151#endif
152
153 /* enable all CPU interrupt bits. */
154 set_c0_status(ST0_IM); /* IE bit is still 0. */
155}
156
157static struct irq_chip jmr3927_irq_ioc = {
158 .name = "jmr3927_ioc",
159 .ack = mask_irq_ioc,
160 .mask = mask_irq_ioc,
161 .mask_ack = mask_irq_ioc,
162 .unmask = unmask_irq_ioc,
163};
164
165static void __init jmr3927_irq_init(void)
166{
167 u32 i;
168
169 txx9_irq_init(TX3927_IRC_REG);
170 for (i = 0; i < TXx9_MAX_IR; i++)
171 txx9_irq_set_pri(i, irc_level[i]);
172 for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)
173 set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq);
174}
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..8bc1049b622e
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/prom.c
@@ -0,0 +1,98 @@
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/kernel.h>
39#include <linux/init.h>
40#include <linux/string.h>
41
42#include <asm/bootinfo.h>
43#include <asm/txx9/tx3927.h>
44
45char * __init prom_getcmdline(void)
46{
47 return &(arcs_cmdline[0]);
48}
49
50void __init prom_init_cmdline(void)
51{
52 char *cp;
53 int actr;
54 int prom_argc = fw_arg0;
55 char **prom_argv = (char **) fw_arg1;
56
57 actr = 1; /* Always ignore argv[0] */
58
59 cp = &(arcs_cmdline[0]);
60 while(actr < prom_argc) {
61 strcpy(cp, prom_argv[actr]);
62 cp += strlen(prom_argv[actr]);
63 *cp++ = ' ';
64 actr++;
65 }
66 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
67 --cp;
68 *cp = '\0';
69}
70
71void __init prom_free_prom_memory(void)
72{
73}
74
75#define TIMEOUT 0xffffff
76
77void
78prom_putchar(char c)
79{
80 int i = 0;
81
82 do {
83 i++;
84 if (i>TIMEOUT)
85 break;
86 } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS));
87 tx3927_sioptr(1)->tfifo = c;
88 return;
89}
90
91void
92puts(const char *cp)
93{
94 while (*cp)
95 prom_putchar(*cp++);
96 prom_putchar('\r');
97 prom_putchar('\n');
98}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
new file mode 100644
index 000000000000..41e0f3b3af2c
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -0,0 +1,445 @@
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/pci.h>
34#include <linux/ioport.h>
35#include <linux/delay.h>
36#include <linux/pm.h>
37#include <linux/platform_device.h>
38#include <linux/clk.h>
39#include <linux/gpio.h>
40#ifdef CONFIG_SERIAL_TXX9
41#include <linux/serial_core.h>
42#endif
43
44#include <asm/txx9tmr.h>
45#include <asm/txx9pio.h>
46#include <asm/reboot.h>
47#include <asm/txx9/jmr3927.h>
48#include <asm/mipsregs.h>
49
50extern void puts(const char *cp);
51
52/* don't enable - see errata */
53static int jmr3927_ccfg_toeon;
54
55static inline void do_reset(void)
56{
57#if 1 /* Resetting PCI bus */
58 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
59 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
60 (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */
61 mdelay(1);
62 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
63#endif
64 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
65}
66
67static void jmr3927_machine_restart(char *command)
68{
69 local_irq_disable();
70 puts("Rebooting...");
71 do_reset();
72}
73
74static void jmr3927_machine_halt(void)
75{
76 puts("JMR-TX3927 halted.\n");
77 while (1);
78}
79
80static void jmr3927_machine_power_off(void)
81{
82 puts("JMR-TX3927 halted. Please turn off the power.\n");
83 while (1);
84}
85
86void __init plat_time_init(void)
87{
88 txx9_clockevent_init(TX3927_TMR_REG(0),
89 TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0),
90 JMR3927_IMCLK);
91 txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK);
92}
93
94#define DO_WRITE_THROUGH
95#define DO_ENABLE_CACHE
96
97extern char * __init prom_getcmdline(void);
98static void jmr3927_board_init(void);
99extern struct resource pci_io_resource;
100extern struct resource pci_mem_resource;
101
102void __init plat_mem_setup(void)
103{
104 char *argptr;
105
106 set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
107
108 _machine_restart = jmr3927_machine_restart;
109 _machine_halt = jmr3927_machine_halt;
110 pm_power_off = jmr3927_machine_power_off;
111
112 /*
113 * IO/MEM resources.
114 */
115 ioport_resource.start = pci_io_resource.start;
116 ioport_resource.end = pci_io_resource.end;
117 iomem_resource.start = 0;
118 iomem_resource.end = 0xffffffff;
119
120 /* Reboot on panic */
121 panic_timeout = 180;
122
123 /* cache setup */
124 {
125 unsigned int conf;
126#ifdef DO_ENABLE_CACHE
127 int mips_ic_disable = 0, mips_dc_disable = 0;
128#else
129 int mips_ic_disable = 1, mips_dc_disable = 1;
130#endif
131#ifdef DO_WRITE_THROUGH
132 int mips_config_cwfon = 0;
133 int mips_config_wbon = 0;
134#else
135 int mips_config_cwfon = 1;
136 int mips_config_wbon = 1;
137#endif
138
139 conf = read_c0_conf();
140 conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON);
141 conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
142 conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
143 conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
144 conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
145
146 write_c0_conf(conf);
147 write_c0_cache(0);
148 }
149
150 /* initialize board */
151 jmr3927_board_init();
152
153 argptr = prom_getcmdline();
154
155 if ((argptr = strstr(argptr, "toeon")) != NULL)
156 jmr3927_ccfg_toeon = 1;
157 argptr = prom_getcmdline();
158 if ((argptr = strstr(argptr, "ip=")) == NULL) {
159 argptr = prom_getcmdline();
160 strcat(argptr, " ip=bootp");
161 }
162
163#ifdef CONFIG_SERIAL_TXX9
164 {
165 extern int early_serial_txx9_setup(struct uart_port *port);
166 int i;
167 struct uart_port req;
168 for(i = 0; i < 2; i++) {
169 memset(&req, 0, sizeof(req));
170 req.line = i;
171 req.iotype = UPIO_MEM;
172 req.membase = (unsigned char __iomem *)TX3927_SIO_REG(i);
173 req.mapbase = TX3927_SIO_REG(i);
174 req.irq = i == 0 ?
175 JMR3927_IRQ_IRC_SIO0 : JMR3927_IRQ_IRC_SIO1;
176 if (i == 0)
177 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
178 req.uartclk = JMR3927_IMCLK;
179 early_serial_txx9_setup(&req);
180 }
181 }
182#ifdef CONFIG_SERIAL_TXX9_CONSOLE
183 argptr = prom_getcmdline();
184 if ((argptr = strstr(argptr, "console=")) == NULL) {
185 argptr = prom_getcmdline();
186 strcat(argptr, " console=ttyS1,115200");
187 }
188#endif
189#endif
190}
191
192static void tx3927_setup(void);
193
194static void __init jmr3927_board_init(void)
195{
196 tx3927_setup();
197
198 /* SIO0 DTR on */
199 jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
200
201 jmr3927_led_set(0);
202
203 printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
204 jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
205 jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
206 jmr3927_dipsw1(), jmr3927_dipsw2(),
207 jmr3927_dipsw3(), jmr3927_dipsw4());
208}
209
210static void __init tx3927_setup(void)
211{
212 int i;
213#ifdef CONFIG_PCI
214 unsigned long mips_pci_io_base = JMR3927_PCIIO;
215 unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE;
216 unsigned long mips_pci_mem_base = JMR3927_PCIMEM;
217 unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE;
218 /* for legacy I/O, PCI I/O PCI Bus address must be 0 */
219 unsigned long mips_pci_io_pciaddr = 0;
220#endif
221
222 /* SDRAMC are configured by PROM */
223
224 /* ROMC */
225 tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
226 tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
227 tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
228 tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
229
230 /* CCFG */
231 /* enable Timeout BusError */
232 if (jmr3927_ccfg_toeon)
233 tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
234
235 /* clear BusErrorOnWrite flag */
236 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
237 /* Disable PCI snoop */
238 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
239 /* do reset on watchdog */
240 tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
241
242#ifdef DO_WRITE_THROUGH
243 /* Enable PCI SNOOP - with write through only */
244 tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
245#endif
246
247 /* Pin selection */
248 tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
249 tx3927_ccfgptr->pcfg |=
250 TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
251 (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
252
253 printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
254 tx3927_ccfgptr->crir,
255 tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
256
257 /* TMR */
258 for (i = 0; i < TX3927_NR_TMR; i++)
259 txx9_tmr_init(TX3927_TMR_REG(i));
260
261 /* DMA */
262 tx3927_dmaptr->mcr = 0;
263 for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) {
264 /* reset channel */
265 tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
266 tx3927_dmaptr->ch[i].ccr = 0;
267 }
268 /* enable DMA */
269#ifdef __BIG_ENDIAN
270 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
271#else
272 tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
273#endif
274
275#ifdef CONFIG_PCI
276 /* PCIC */
277 printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:",
278 tx3927_pcicptr->did, tx3927_pcicptr->vid,
279 tx3927_pcicptr->rid);
280 if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) {
281 printk("External\n");
282 /* XXX */
283 } else {
284 printk("Internal\n");
285
286 /* Reset PCI Bus */
287 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
288 udelay(100);
289 jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
290 JMR3927_IOC_RESET_ADDR);
291 udelay(100);
292 jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
293
294
295 /* Disable External PCI Config. Access */
296 tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD;
297#ifdef __BIG_ENDIAN
298 tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE |
299 TX3927_PCIC_LBC_TIBSE |
300 TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE;
301#endif
302 /* LB->PCI mappings */
303 tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1);
304 tx3927_pcicptr->ilbioma = mips_pci_io_base;
305 tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr;
306 tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1);
307 tx3927_pcicptr->ilbmma = mips_pci_mem_base;
308 tx3927_pcicptr->ipbmma = mips_pci_mem_base;
309 /* PCI->LB mappings */
310 tx3927_pcicptr->iobas = 0xffffffff;
311 tx3927_pcicptr->ioba = 0;
312 tx3927_pcicptr->tlbioma = 0;
313 tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1);
314 tx3927_pcicptr->mba = 0;
315 tx3927_pcicptr->tlbmma = 0;
316 /* Enable Direct mapping Address Space Decoder */
317 tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE;
318
319 /* Clear All Local Bus Status */
320 tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
321 /* Enable All Local Bus Interrupts */
322 tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL;
323 /* Clear All PCI Status Error */
324 tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL;
325 /* Enable All PCI Status Error Interrupts */
326 tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL;
327
328 /* PCIC Int => IRC IRQ10 */
329 tx3927_pcicptr->il = TX3927_IR_PCI;
330 /* Target Control (per errata) */
331 tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E;
332
333 /* Enable Bus Arbiter */
334 tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN;
335
336 tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER |
337 PCI_COMMAND_MEMORY |
338 PCI_COMMAND_IO |
339 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
340 }
341#endif /* CONFIG_PCI */
342
343 /* PIO */
344 /* PIO[15:12] connected to LEDs */
345 __raw_writel(0x0000f000, &tx3927_pioptr->dir);
346 __raw_writel(0, &tx3927_pioptr->maskcpu);
347 __raw_writel(0, &tx3927_pioptr->maskext);
348 txx9_gpio_init(TX3927_PIO_REG, 0, 16);
349 gpio_request(11, "dipsw1");
350 gpio_request(10, "dipsw2");
351 {
352 unsigned int conf;
353
354 conf = read_c0_conf();
355 if (!(conf & TX39_CONF_ICE))
356 printk("TX3927 I-Cache disabled.\n");
357 if (!(conf & TX39_CONF_DCE))
358 printk("TX3927 D-Cache disabled.\n");
359 else if (!(conf & TX39_CONF_WBON))
360 printk("TX3927 D-Cache WriteThrough.\n");
361 else if (!(conf & TX39_CONF_CWFON))
362 printk("TX3927 D-Cache WriteBack.\n");
363 else
364 printk("TX3927 D-Cache WriteBack (CWF) .\n");
365 }
366}
367
368/* This trick makes rtc-ds1742 driver usable as is. */
369unsigned long __swizzle_addr_b(unsigned long port)
370{
371 if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR)
372 return port;
373 port = (port & 0xffff0000) | (port & 0x7fff << 1);
374#ifdef __BIG_ENDIAN
375 return port;
376#else
377 return port | 1;
378#endif
379}
380EXPORT_SYMBOL(__swizzle_addr_b);
381
382static int __init jmr3927_rtc_init(void)
383{
384 static struct resource __initdata res = {
385 .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE,
386 .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1,
387 .flags = IORESOURCE_MEM,
388 };
389 struct platform_device *dev;
390 dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1);
391 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
392}
393device_initcall(jmr3927_rtc_init);
394
395/* Watchdog support */
396
397static int __init txx9_wdt_init(unsigned long base)
398{
399 struct resource res = {
400 .start = base,
401 .end = base + 0x100 - 1,
402 .flags = IORESOURCE_MEM,
403 };
404 struct platform_device *dev =
405 platform_device_register_simple("txx9wdt", -1, &res, 1);
406 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
407}
408
409static int __init jmr3927_wdt_init(void)
410{
411 return txx9_wdt_init(TX3927_TMR_REG(2));
412}
413device_initcall(jmr3927_wdt_init);
414
415/* Minimum CLK support */
416
417struct clk *clk_get(struct device *dev, const char *id)
418{
419 if (!strcmp(id, "imbus_clk"))
420 return (struct clk *)JMR3927_IMCLK;
421 return ERR_PTR(-ENOENT);
422}
423EXPORT_SYMBOL(clk_get);
424
425int clk_enable(struct clk *clk)
426{
427 return 0;
428}
429EXPORT_SYMBOL(clk_enable);
430
431void clk_disable(struct clk *clk)
432{
433}
434EXPORT_SYMBOL(clk_disable);
435
436unsigned long clk_get_rate(struct clk *clk)
437{
438 return (unsigned long)clk;
439}
440EXPORT_SYMBOL(clk_get_rate);
441
442void clk_put(struct clk *clk)
443{
444}
445EXPORT_SYMBOL(clk_put);
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..936e50e91d95
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -0,0 +1,214 @@
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#ifdef CONFIG_TOSHIBA_FPCIB0
115#include <asm/i8259.h>
116#endif
117#include <asm/txx9/rbtx4927.h>
118
119#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0
120#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7
121
122#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */
123#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */
124
125#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC
126#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2)
127
128extern int tx4927_using_backplane;
129
130static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq);
131static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq);
132
133#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
134static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
135 .name = TOSHIBA_RBTX4927_IOC_NAME,
136 .ack = toshiba_rbtx4927_irq_ioc_disable,
137 .mask = toshiba_rbtx4927_irq_ioc_disable,
138 .mask_ack = toshiba_rbtx4927_irq_ioc_disable,
139 .unmask = toshiba_rbtx4927_irq_ioc_enable,
140};
141#define TOSHIBA_RBTX4927_IOC_INTR_ENAB (void __iomem *)0xbc002000UL
142#define TOSHIBA_RBTX4927_IOC_INTR_STAT (void __iomem *)0xbc002006UL
143
144int toshiba_rbtx4927_irq_nested(int sw_irq)
145{
146 u8 level3;
147
148 level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f;
149 if (level3) {
150 sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1;
151#ifdef CONFIG_TOSHIBA_FPCIB0
152 if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC &&
153 tx4927_using_backplane) {
154 int irq = i8259_irq();
155 if (irq >= 0)
156 sw_irq = irq;
157 }
158#endif
159 }
160 return (sw_irq);
161}
162
163static struct irqaction toshiba_rbtx4927_irq_ioc_action = {
164 .handler = no_action,
165 .flags = IRQF_SHARED,
166 .mask = CPU_MASK_NONE,
167 .name = TOSHIBA_RBTX4927_IOC_NAME
168};
169
170static void __init toshiba_rbtx4927_irq_ioc_init(void)
171{
172 int i;
173
174 for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG;
175 i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++)
176 set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
177 handle_level_irq);
178
179 setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC,
180 &toshiba_rbtx4927_irq_ioc_action);
181}
182
183static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq)
184{
185 unsigned char v;
186
187 v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
188 v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG));
189 writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB);
190}
191
192static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq)
193{
194 unsigned char v;
195
196 v = readb(TOSHIBA_RBTX4927_IOC_INTR_ENAB);
197 v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG));
198 writeb(v, TOSHIBA_RBTX4927_IOC_INTR_ENAB);
199 mmiowb();
200}
201
202void __init arch_init_irq(void)
203{
204 extern void tx4927_irq_init(void);
205
206 tx4927_irq_init();
207 toshiba_rbtx4927_irq_ioc_init();
208#ifdef CONFIG_TOSHIBA_FPCIB0
209 if (tx4927_using_backplane)
210 init_i8259_irqs();
211#endif
212 /* Onboard 10M Ether: High Active */
213 set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
214}
diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c
new file mode 100644
index 000000000000..0020bbee838b
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/prom.c
@@ -0,0 +1,91 @@
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 <linux/string.h>
34#include <asm/bootinfo.h>
35#include <asm/cpu.h>
36#include <asm/mipsregs.h>
37#include <asm/txx9/tx4927.h>
38
39void __init prom_init_cmdline(void)
40{
41 int argc = (int) fw_arg0;
42 char **argv = (char **) fw_arg1;
43 int i; /* Always ignore the "-c" at argv[0] */
44
45 /* ignore all built-in args if any f/w args given */
46 if (argc > 1) {
47 *arcs_cmdline = '\0';
48 }
49
50 for (i = 1; i < argc; i++) {
51 if (i != 1) {
52 strcat(arcs_cmdline, " ");
53 }
54 strcat(arcs_cmdline, argv[i]);
55 }
56}
57
58void __init prom_init(void)
59{
60 extern int tx4927_get_mem_size(void);
61 extern char* toshiba_name;
62 int msize;
63
64 prom_init_cmdline();
65
66 if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) {
67 mips_machtype = MACH_TOSHIBA_RBTX4927;
68 toshiba_name = "TX4927";
69 } else {
70 mips_machtype = MACH_TOSHIBA_RBTX4937;
71 toshiba_name = "TX4937";
72 }
73
74 msize = tx4927_get_mem_size();
75 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
76}
77
78void __init prom_free_prom_memory(void)
79{
80}
81
82const char *get_system_type(void)
83{
84 return "Toshiba RBTX4927/RBTX4937";
85}
86
87char * __init prom_getcmdline(void)
88{
89 return &(arcs_cmdline[0]);
90}
91
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
new file mode 100644
index 000000000000..df1b6e99b666
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -0,0 +1,703 @@
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/pci.h>
51#include <linux/pm.h>
52#include <linux/platform_device.h>
53#include <linux/clk.h>
54
55#include <asm/bootinfo.h>
56#include <asm/io.h>
57#include <asm/processor.h>
58#include <asm/reboot.h>
59#include <asm/time.h>
60#include <asm/txx9tmr.h>
61#ifdef CONFIG_TOSHIBA_FPCIB0
62#include <asm/txx9/smsc_fdc37m81x.h>
63#endif
64#include <asm/txx9/rbtx4927.h>
65#ifdef CONFIG_SERIAL_TXX9
66#include <linux/serial_core.h>
67#endif
68
69/* These functions are used for rebooting or halting the machine*/
70extern void toshiba_rbtx4927_restart(char *command);
71extern void toshiba_rbtx4927_halt(void);
72extern void toshiba_rbtx4927_power_off(void);
73
74int tx4927_using_backplane = 0;
75
76extern void toshiba_rbtx4927_irq_setup(void);
77
78char *prom_getcmdline(void);
79
80#ifdef CONFIG_PCI
81#undef TX4927_SUPPORT_COMMAND_IO
82#undef TX4927_SUPPORT_PCI_66
83int tx4927_cpu_clock = 100000000; /* 100MHz */
84unsigned long mips_pci_io_base;
85unsigned long mips_pci_io_size;
86unsigned long mips_pci_mem_base;
87unsigned long mips_pci_mem_size;
88/* for legacy I/O, PCI I/O PCI Bus address must be 0 */
89unsigned long mips_pci_io_pciaddr = 0;
90unsigned long mips_memory_upper;
91static int tx4927_ccfg_toeon = 1;
92static int tx4927_pcic_trdyto = 0; /* default: disabled */
93unsigned long tx4927_ce_base[8];
94int tx4927_pci66 = 0; /* 0:auto */
95#endif
96
97char *toshiba_name = "";
98
99#ifdef CONFIG_PCI
100extern struct pci_controller tx4927_controller;
101
102static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
103 int top_bus, int busnr, int devfn)
104{
105 static struct pci_dev dev;
106 static struct pci_bus bus;
107
108 dev.sysdata = (void *)hose;
109 dev.devfn = devfn;
110 bus.number = busnr;
111 bus.ops = hose->pci_ops;
112 bus.parent = NULL;
113 dev.bus = &bus;
114
115 return &dev;
116}
117
118#define EARLY_PCI_OP(rw, size, type) \
119static int early_##rw##_config_##size(struct pci_controller *hose, \
120 int top_bus, int bus, int devfn, int offset, type value) \
121{ \
122 return pci_##rw##_config_##size( \
123 fake_pci_dev(hose, top_bus, bus, devfn), \
124 offset, value); \
125}
126
127EARLY_PCI_OP(read, byte, u8 *)
128EARLY_PCI_OP(read, dword, u32 *)
129EARLY_PCI_OP(write, byte, u8)
130EARLY_PCI_OP(write, dword, u32)
131
132static int __init tx4927_pcibios_init(void)
133{
134 unsigned int id;
135 u32 pci_devfn;
136 int devfn_start = 0;
137 int devfn_stop = 0xff;
138 int busno = 0; /* One bus on the Toshiba */
139 struct pci_controller *hose = &tx4927_controller;
140
141 for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) {
142 early_read_config_dword(hose, busno, busno, pci_devfn,
143 PCI_VENDOR_ID, &id);
144
145 if (id == 0xffffffff) {
146 continue;
147 }
148
149 if (id == 0x94601055) {
150 u8 v08_64;
151 u32 v32_b0;
152 u8 v08_e1;
153
154 early_read_config_byte(hose, busno, busno,
155 pci_devfn, 0x64, &v08_64);
156 early_read_config_dword(hose, busno, busno,
157 pci_devfn, 0xb0, &v32_b0);
158 early_read_config_byte(hose, busno, busno,
159 pci_devfn, 0xe1, &v08_e1);
160
161 /* serial irq control */
162 v08_64 = 0xd0;
163
164 /* serial irq pin */
165 v32_b0 |= 0x00010000;
166
167 /* ide irq on isa14 */
168 v08_e1 &= 0xf0;
169 v08_e1 |= 0x0d;
170
171 early_write_config_byte(hose, busno, busno,
172 pci_devfn, 0x64, v08_64);
173 early_write_config_dword(hose, busno, busno,
174 pci_devfn, 0xb0, v32_b0);
175 early_write_config_byte(hose, busno, busno,
176 pci_devfn, 0xe1, v08_e1);
177 }
178
179 if (id == 0x91301055) {
180 u8 v08_04;
181 u8 v08_09;
182 u8 v08_41;
183 u8 v08_43;
184 u8 v08_5c;
185
186 early_read_config_byte(hose, busno, busno,
187 pci_devfn, 0x04, &v08_04);
188 early_read_config_byte(hose, busno, busno,
189 pci_devfn, 0x09, &v08_09);
190 early_read_config_byte(hose, busno, busno,
191 pci_devfn, 0x41, &v08_41);
192 early_read_config_byte(hose, busno, busno,
193 pci_devfn, 0x43, &v08_43);
194 early_read_config_byte(hose, busno, busno,
195 pci_devfn, 0x5c, &v08_5c);
196
197 /* enable ide master/io */
198 v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO);
199
200 /* enable ide native mode */
201 v08_09 |= 0x05;
202
203 /* enable primary ide */
204 v08_41 |= 0x80;
205
206 /* enable secondary ide */
207 v08_43 |= 0x80;
208
209 /*
210 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
211 *
212 * This line of code is intended to provide the user with a work
213 * around solution to the anomalies cited in SMSC's anomaly sheet
214 * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
215 *
216 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
217 */
218 v08_5c |= 0x01;
219
220 early_write_config_byte(hose, busno, busno,
221 pci_devfn, 0x5c, v08_5c);
222 early_write_config_byte(hose, busno, busno,
223 pci_devfn, 0x04, v08_04);
224 early_write_config_byte(hose, busno, busno,
225 pci_devfn, 0x09, v08_09);
226 early_write_config_byte(hose, busno, busno,
227 pci_devfn, 0x41, v08_41);
228 early_write_config_byte(hose, busno, busno,
229 pci_devfn, 0x43, v08_43);
230 }
231
232 }
233
234 register_pci_controller(&tx4927_controller);
235 return 0;
236}
237
238arch_initcall(tx4927_pcibios_init);
239
240extern struct resource pci_io_resource;
241extern struct resource pci_mem_resource;
242
243void __init tx4927_pci_setup(void)
244{
245 static int called = 0;
246 extern unsigned int tx4927_get_mem_size(void);
247
248 mips_memory_upper = tx4927_get_mem_size() << 20;
249 mips_memory_upper += KSEG0;
250 mips_pci_io_base = TX4927_PCIIO;
251 mips_pci_io_size = TX4927_PCIIO_SIZE;
252 mips_pci_mem_base = TX4927_PCIMEM;
253 mips_pci_mem_size = TX4927_PCIMEM_SIZE;
254
255 if (!called) {
256 printk
257 ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
258 toshiba_name,
259 (unsigned short) (tx4927_pcicptr->pciid >> 16),
260 (unsigned short) (tx4927_pcicptr->pciid & 0xffff),
261 (unsigned short) (tx4927_pcicptr->pciccrev & 0xff),
262 (!(tx4927_ccfgptr->
263 ccfg & TX4927_CCFG_PCIXARB)) ? "External" :
264 "Internal");
265 called = 1;
266 }
267 printk("%s PCIC --%s PCICLK:", toshiba_name,
268 (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : "");
269 if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) {
270 int pciclk = 0;
271 if (mips_machtype == MACH_TOSHIBA_RBTX4937)
272 switch ((unsigned long) tx4927_ccfgptr->
273 ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
274 case TX4937_CCFG_PCIDIVMODE_4:
275 pciclk = tx4927_cpu_clock / 4;
276 break;
277 case TX4937_CCFG_PCIDIVMODE_4_5:
278 pciclk = tx4927_cpu_clock * 2 / 9;
279 break;
280 case TX4937_CCFG_PCIDIVMODE_5:
281 pciclk = tx4927_cpu_clock / 5;
282 break;
283 case TX4937_CCFG_PCIDIVMODE_5_5:
284 pciclk = tx4927_cpu_clock * 2 / 11;
285 break;
286 case TX4937_CCFG_PCIDIVMODE_8:
287 pciclk = tx4927_cpu_clock / 8;
288 break;
289 case TX4937_CCFG_PCIDIVMODE_9:
290 pciclk = tx4927_cpu_clock / 9;
291 break;
292 case TX4937_CCFG_PCIDIVMODE_10:
293 pciclk = tx4927_cpu_clock / 10;
294 break;
295 case TX4937_CCFG_PCIDIVMODE_11:
296 pciclk = tx4927_cpu_clock / 11;
297 break;
298 }
299
300 else
301 switch ((unsigned long) tx4927_ccfgptr->
302 ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
303 case TX4927_CCFG_PCIDIVMODE_2_5:
304 pciclk = tx4927_cpu_clock * 2 / 5;
305 break;
306 case TX4927_CCFG_PCIDIVMODE_3:
307 pciclk = tx4927_cpu_clock / 3;
308 break;
309 case TX4927_CCFG_PCIDIVMODE_5:
310 pciclk = tx4927_cpu_clock / 5;
311 break;
312 case TX4927_CCFG_PCIDIVMODE_6:
313 pciclk = tx4927_cpu_clock / 6;
314 break;
315 }
316
317 printk("Internal(%dMHz)", pciclk / 1000000);
318 } else
319 printk("External");
320 printk("\n");
321
322 /* GB->PCI mappings */
323 tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4;
324 tx4927_pcicptr->g2piogbase = mips_pci_io_base |
325#ifdef __BIG_ENDIAN
326 TX4927_PCIC_G2PIOGBASE_ECHG
327#else
328 TX4927_PCIC_G2PIOGBASE_BSDIS
329#endif
330 ;
331
332 tx4927_pcicptr->g2piopbase = 0;
333
334 tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4;
335 tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base |
336#ifdef __BIG_ENDIAN
337 TX4927_PCIC_G2PMnGBASE_ECHG
338#else
339 TX4927_PCIC_G2PMnGBASE_BSDIS
340#endif
341 ;
342 tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base;
343
344 tx4927_pcicptr->g2pmmask[1] = 0;
345 tx4927_pcicptr->g2pmgbase[1] = 0;
346 tx4927_pcicptr->g2pmpbase[1] = 0;
347 tx4927_pcicptr->g2pmmask[2] = 0;
348 tx4927_pcicptr->g2pmgbase[2] = 0;
349 tx4927_pcicptr->g2pmpbase[2] = 0;
350
351
352 /* PCI->GB mappings (I/O 256B) */
353 tx4927_pcicptr->p2giopbase = 0; /* 256B */
354
355 /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */
356 tx4927_pcicptr->p2gm0plbase = 0;
357 tx4927_pcicptr->p2gm0pubase = 0;
358 tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN |
359#ifdef __BIG_ENDIAN
360 TX4927_PCIC_P2GMnGBASE_TECHG
361#else
362 TX4927_PCIC_P2GMnGBASE_TBSDIS
363#endif
364 ;
365
366 /* PCI->GB mappings (MEM 16MB) -not used */
367 tx4927_pcicptr->p2gm1plbase = 0xffffffff;
368 tx4927_pcicptr->p2gm1pubase = 0xffffffff;
369 tx4927_pcicptr->p2gmgbase[1] = 0;
370
371 /* PCI->GB mappings (MEM 1MB) -not used */
372 tx4927_pcicptr->p2gm2pbase = 0xffffffff;
373 tx4927_pcicptr->p2gmgbase[2] = 0;
374
375
376 /* Enable Initiator Memory 0 Space, I/O Space, Config */
377 tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK;
378 tx4927_pcicptr->pciccfg |=
379 TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE |
380 TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR;
381
382
383 /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
384 tx4927_pcicptr->pcicfg1 = 0;
385
386 if (tx4927_pcic_trdyto >= 0) {
387 tx4927_pcicptr->g2ptocnt &= ~0xff;
388 tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff);
389 }
390
391 /* Clear All Local Bus Status */
392 tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL;
393 /* Enable All Local Bus Interrupts */
394 tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL;
395 /* Clear All Initiator Status */
396 tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL;
397 /* Enable All Initiator Interrupts */
398 tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL;
399 /* Clear All PCI Status Error */
400 tx4927_pcicptr->pcistatus =
401 (tx4927_pcicptr->pcistatus & 0x0000ffff) |
402 (TX4927_PCIC_PCISTATUS_ALL << 16);
403 /* Enable All PCI Status Error Interrupts */
404 tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL;
405
406 /* PCIC Int => IRC IRQ16 */
407 tx4927_pcicptr->pcicfg2 =
408 (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC;
409
410 if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) {
411 /* XXX */
412 } else {
413 /* Reset Bus Arbiter */
414 tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA;
415 /* Enable Bus Arbiter */
416 tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN;
417 }
418
419 tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER |
420 PCI_COMMAND_MEMORY |
421 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
422}
423#endif /* CONFIG_PCI */
424
425static void __noreturn wait_forever(void)
426{
427 while (1)
428 if (cpu_wait)
429 (*cpu_wait)();
430}
431
432void toshiba_rbtx4927_restart(char *command)
433{
434 printk(KERN_NOTICE "System Rebooting...\n");
435
436 /* enable the s/w reset register */
437 writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE);
438
439 /* wait for enable to be seen */
440 while ((readb(RBTX4927_SW_RESET_ENABLE) &
441 RBTX4927_SW_RESET_ENABLE_SET) == 0x00);
442
443 /* do a s/w reset */
444 writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO);
445
446 /* do something passive while waiting for reset */
447 local_irq_disable();
448 wait_forever();
449 /* no return */
450}
451
452void toshiba_rbtx4927_halt(void)
453{
454 printk(KERN_NOTICE "System Halted\n");
455 local_irq_disable();
456 wait_forever();
457 /* no return */
458}
459
460void toshiba_rbtx4927_power_off(void)
461{
462 toshiba_rbtx4927_halt();
463 /* no return */
464}
465
466void __init plat_mem_setup(void)
467{
468 int i;
469 u32 cp0_config;
470 char *argptr;
471
472 printk("CPU is %s\n", toshiba_name);
473
474 /* f/w leaves this on at startup */
475 clear_c0_status(ST0_ERL);
476
477 /* enable caches -- HCP5 does this, pmon does not */
478 cp0_config = read_c0_config();
479 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
480 write_c0_config(cp0_config);
481
482 set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET);
483
484 ioport_resource.end = 0xffffffff;
485 iomem_resource.end = 0xffffffff;
486
487 _machine_restart = toshiba_rbtx4927_restart;
488 _machine_halt = toshiba_rbtx4927_halt;
489 pm_power_off = toshiba_rbtx4927_power_off;
490
491 for (i = 0; i < TX4927_NR_TMR; i++)
492 txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL);
493
494#ifdef CONFIG_PCI
495
496 /* PCIC */
497 /*
498 * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
499 *
500 * For TX4927:
501 * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
502 * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
503 * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
504 * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
505 * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
506 * i.e. S9[3]: ON (83MHz), OFF (100MHz)
507 *
508 * For TX4937:
509 * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
510 * PCIDIVMODE[10] is 0.
511 * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
512 * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
513 * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
514 * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
515 * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
516 * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
517 *
518 */
519 if (mips_machtype == MACH_TOSHIBA_RBTX4937)
520 switch ((unsigned long)tx4927_ccfgptr->
521 ccfg & TX4937_CCFG_PCIDIVMODE_MASK) {
522 case TX4937_CCFG_PCIDIVMODE_8:
523 case TX4937_CCFG_PCIDIVMODE_4:
524 tx4927_cpu_clock = 266666666; /* 266MHz */
525 break;
526 case TX4937_CCFG_PCIDIVMODE_9:
527 case TX4937_CCFG_PCIDIVMODE_4_5:
528 tx4927_cpu_clock = 300000000; /* 300MHz */
529 break;
530 default:
531 tx4927_cpu_clock = 333333333; /* 333MHz */
532 }
533 else
534 switch ((unsigned long)tx4927_ccfgptr->
535 ccfg & TX4927_CCFG_PCIDIVMODE_MASK) {
536 case TX4927_CCFG_PCIDIVMODE_2_5:
537 case TX4927_CCFG_PCIDIVMODE_5:
538 tx4927_cpu_clock = 166666666; /* 166MHz */
539 break;
540 default:
541 tx4927_cpu_clock = 200000000; /* 200MHz */
542 }
543
544 /* CCFG */
545 /* do reset on watchdog */
546 tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR;
547 /* enable Timeout BusError */
548 if (tx4927_ccfg_toeon)
549 tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE;
550
551 tx4927_pci_setup();
552 if (tx4927_using_backplane == 1)
553 printk("backplane board IS installed\n");
554 else
555 printk("No Backplane \n");
556
557 /* this is on ISA bus behind PCI bus, so need PCI up first */
558#ifdef CONFIG_TOSHIBA_FPCIB0
559 if (tx4927_using_backplane) {
560 smsc_fdc37m81x_init(0x3f0);
561 smsc_fdc37m81x_config_beg();
562 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
563 SMSC_FDC37M81X_KBD);
564 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
565 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
566 smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
567 1);
568 smsc_fdc37m81x_config_end();
569 }
570#endif
571#endif /* CONFIG_PCI */
572
573#ifdef CONFIG_SERIAL_TXX9
574 {
575 extern int early_serial_txx9_setup(struct uart_port *port);
576 struct uart_port req;
577 for(i = 0; i < 2; i++) {
578 memset(&req, 0, sizeof(req));
579 req.line = i;
580 req.iotype = UPIO_MEM;
581 req.membase = (char *)(0xff1ff300 + i * 0x100);
582 req.mapbase = 0xff1ff300 + i * 0x100;
583 req.irq = TX4927_IRQ_PIC_BEG + 8 + i;
584 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
585 req.uartclk = 50000000;
586 early_serial_txx9_setup(&req);
587 }
588 }
589#ifdef CONFIG_SERIAL_TXX9_CONSOLE
590 argptr = prom_getcmdline();
591 if (strstr(argptr, "console=") == NULL) {
592 strcat(argptr, " console=ttyS0,38400");
593 }
594#endif
595#endif
596
597#ifdef CONFIG_ROOT_NFS
598 argptr = prom_getcmdline();
599 if (strstr(argptr, "root=") == NULL) {
600 strcat(argptr, " root=/dev/nfs rw");
601 }
602#endif
603
604#ifdef CONFIG_IP_PNP
605 argptr = prom_getcmdline();
606 if (strstr(argptr, "ip=") == NULL) {
607 strcat(argptr, " ip=any");
608 }
609#endif
610}
611
612void __init plat_time_init(void)
613{
614 mips_hpt_frequency = tx4927_cpu_clock / 2;
615 if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
616 txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
617 TXX9_IRQ_BASE + 17,
618 50000000);
619}
620
621static int __init toshiba_rbtx4927_rtc_init(void)
622{
623 static struct resource __initdata res = {
624 .start = 0x1c010000,
625 .end = 0x1c010000 + 0x800 - 1,
626 .flags = IORESOURCE_MEM,
627 };
628 struct platform_device *dev =
629 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
630 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
631}
632device_initcall(toshiba_rbtx4927_rtc_init);
633
634static int __init rbtx4927_ne_init(void)
635{
636 static struct resource __initdata res[] = {
637 {
638 .start = RBTX4927_RTL_8019_BASE,
639 .end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
640 .flags = IORESOURCE_IO,
641 }, {
642 .start = RBTX4927_RTL_8019_IRQ,
643 .flags = IORESOURCE_IRQ,
644 }
645 };
646 struct platform_device *dev =
647 platform_device_register_simple("ne", -1,
648 res, ARRAY_SIZE(res));
649 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
650}
651device_initcall(rbtx4927_ne_init);
652
653/* Watchdog support */
654
655static int __init txx9_wdt_init(unsigned long base)
656{
657 struct resource res = {
658 .start = base,
659 .end = base + 0x100 - 1,
660 .flags = IORESOURCE_MEM,
661 };
662 struct platform_device *dev =
663 platform_device_register_simple("txx9wdt", -1, &res, 1);
664 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
665}
666
667static int __init rbtx4927_wdt_init(void)
668{
669 return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
670}
671device_initcall(rbtx4927_wdt_init);
672
673/* Minimum CLK support */
674
675struct clk *clk_get(struct device *dev, const char *id)
676{
677 if (!strcmp(id, "imbus_clk"))
678 return (struct clk *)50000000;
679 return ERR_PTR(-ENOENT);
680}
681EXPORT_SYMBOL(clk_get);
682
683int clk_enable(struct clk *clk)
684{
685 return 0;
686}
687EXPORT_SYMBOL(clk_enable);
688
689void clk_disable(struct clk *clk)
690{
691}
692EXPORT_SYMBOL(clk_disable);
693
694unsigned long clk_get_rate(struct clk *clk)
695{
696 return (unsigned long)clk;
697}
698EXPORT_SYMBOL(clk_get_rate);
699
700void clk_put(struct clk *clk)
701{
702}
703EXPORT_SYMBOL(clk_put);
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..f4984820251a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -0,0 +1,159 @@
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/txx9/rbtx4938.h>
70
71static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq);
72static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq);
73
74#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
75static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
76 .name = TOSHIBA_RBTX4938_IOC_NAME,
77 .ack = toshiba_rbtx4938_irq_ioc_disable,
78 .mask = toshiba_rbtx4938_irq_ioc_disable,
79 .mask_ack = toshiba_rbtx4938_irq_ioc_disable,
80 .unmask = toshiba_rbtx4938_irq_ioc_enable,
81};
82
83int
84toshiba_rbtx4938_irq_nested(int sw_irq)
85{
86 u8 level3;
87
88 level3 = readb(rbtx4938_imstat_addr);
89 if (level3)
90 /* must use fls so onboard ATA has priority */
91 sw_irq = TOSHIBA_RBTX4938_IRQ_IOC_BEG + fls(level3) - 1;
92
93 return sw_irq;
94}
95
96static struct irqaction toshiba_rbtx4938_irq_ioc_action = {
97 .handler = no_action,
98 .flags = 0,
99 .mask = CPU_MASK_NONE,
100 .name = TOSHIBA_RBTX4938_IOC_NAME,
101};
102
103/**********************************************************************************/
104/* Functions for ioc */
105/**********************************************************************************/
106static void __init
107toshiba_rbtx4938_irq_ioc_init(void)
108{
109 int i;
110
111 for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG;
112 i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++)
113 set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
114 handle_level_irq);
115
116 setup_irq(RBTX4938_IRQ_IOCINT,
117 &toshiba_rbtx4938_irq_ioc_action);
118}
119
120static void
121toshiba_rbtx4938_irq_ioc_enable(unsigned int irq)
122{
123 unsigned char v;
124
125 v = readb(rbtx4938_imask_addr);
126 v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
127 writeb(v, rbtx4938_imask_addr);
128 mmiowb();
129}
130
131static void
132toshiba_rbtx4938_irq_ioc_disable(unsigned int irq)
133{
134 unsigned char v;
135
136 v = readb(rbtx4938_imask_addr);
137 v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG));
138 writeb(v, rbtx4938_imask_addr);
139 mmiowb();
140}
141
142void __init arch_init_irq(void)
143{
144 extern void tx4938_irq_init(void);
145
146 /* Now, interrupt control disabled, */
147 /* all IRC interrupts are masked, */
148 /* all IRC interrupt mode are Low Active. */
149
150 /* mask all IOC interrupts */
151 writeb(0, rbtx4938_imask_addr);
152
153 /* clear SoftInt interrupts */
154 writeb(0, rbtx4938_softint_addr);
155 tx4938_irq_init();
156 toshiba_rbtx4938_irq_ioc_init();
157 /* Onboard 10M Ether: High Active */
158 set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
159}
diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c
new file mode 100644
index 000000000000..134fcc2dc7d2
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/prom.c
@@ -0,0 +1,72 @@
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/mm.h>
15#include <linux/sched.h>
16#include <linux/bootmem.h>
17
18#include <asm/addrspace.h>
19#include <asm/bootinfo.h>
20#include <asm/txx9/tx4938.h>
21
22void __init prom_init_cmdline(void)
23{
24 int argc = (int) fw_arg0;
25 char **argv = (char **) fw_arg1;
26 int i;
27
28 /* ignore all built-in args if any f/w args given */
29 if (argc > 1) {
30 *arcs_cmdline = '\0';
31 }
32
33 for (i = 1; i < argc; i++) {
34 if (i != 1) {
35 strcat(arcs_cmdline, " ");
36 }
37 strcat(arcs_cmdline, argv[i]);
38 }
39}
40
41void __init prom_init(void)
42{
43 extern int tx4938_get_mem_size(void);
44 int msize;
45#ifndef CONFIG_TX4938_NAND_BOOT
46 prom_init_cmdline();
47#endif
48
49 msize = tx4938_get_mem_size();
50 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
51
52 return;
53}
54
55void __init prom_free_prom_memory(void)
56{
57}
58
59void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
60{
61 return;
62}
63
64const char *get_system_type(void)
65{
66 return "Toshiba RBTX4938";
67}
68
69char * __init prom_getcmdline(void)
70{
71 return &(arcs_cmdline[0]);
72}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
new file mode 100644
index 000000000000..bbd572c9675b
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -0,0 +1,1122 @@
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/pci.h>
19#include <linux/pm.h>
20#include <linux/platform_device.h>
21#include <linux/clk.h>
22#include <linux/gpio.h>
23
24#include <asm/reboot.h>
25#include <asm/time.h>
26#include <asm/txx9tmr.h>
27#include <asm/io.h>
28#include <asm/bootinfo.h>
29#include <asm/txx9/rbtx4938.h>
30#ifdef CONFIG_SERIAL_TXX9
31#include <linux/serial_core.h>
32#endif
33#include <linux/spi/spi.h>
34#include <asm/txx9/spi.h>
35#include <asm/txx9pio.h>
36
37extern char * __init prom_getcmdline(void);
38static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr);
39
40/* These functions are used for rebooting or halting the machine*/
41extern void rbtx4938_machine_restart(char *command);
42extern void rbtx4938_machine_halt(void);
43extern void rbtx4938_machine_power_off(void);
44
45/* clocks */
46unsigned int txx9_master_clock;
47unsigned int txx9_cpu_clock;
48unsigned int txx9_gbus_clock;
49
50unsigned long rbtx4938_ce_base[8];
51unsigned long rbtx4938_ce_size[8];
52int txboard_pci66_mode;
53static int tx4938_pcic_trdyto; /* default: disabled */
54static int tx4938_pcic_retryto; /* default: disabled */
55static int tx4938_ccfg_toeon = 1;
56
57struct tx4938_pcic_reg *pcicptrs[4] = {
58 tx4938_pcicptr /* default setting for TX4938 */
59};
60
61static struct {
62 unsigned long base;
63 unsigned long size;
64} phys_regions[16] __initdata;
65static int num_phys_regions __initdata;
66
67#define PHYS_REGION_MINSIZE 0x10000
68
69void rbtx4938_machine_halt(void)
70{
71 printk(KERN_NOTICE "System Halted\n");
72 local_irq_disable();
73
74 while (1)
75 __asm__(".set\tmips3\n\t"
76 "wait\n\t"
77 ".set\tmips0");
78}
79
80void rbtx4938_machine_power_off(void)
81{
82 rbtx4938_machine_halt();
83 /* no return */
84}
85
86void rbtx4938_machine_restart(char *command)
87{
88 local_irq_disable();
89
90 printk("Rebooting...");
91 writeb(1, rbtx4938_softresetlock_addr);
92 writeb(1, rbtx4938_sfvol_addr);
93 writeb(1, rbtx4938_softreset_addr);
94 while(1)
95 ;
96}
97
98void __init
99txboard_add_phys_region(unsigned long base, unsigned long size)
100{
101 if (num_phys_regions >= ARRAY_SIZE(phys_regions)) {
102 printk("phys_region overflow\n");
103 return;
104 }
105 phys_regions[num_phys_regions].base = base;
106 phys_regions[num_phys_regions].size = size;
107 num_phys_regions++;
108}
109unsigned long __init
110txboard_find_free_phys_region(unsigned long begin, unsigned long end,
111 unsigned long size)
112{
113 unsigned long base;
114 int i;
115
116 for (base = begin / size * size; base < end; base += size) {
117 for (i = 0; i < num_phys_regions; i++) {
118 if (phys_regions[i].size &&
119 base <= phys_regions[i].base + (phys_regions[i].size - 1) &&
120 base + (size - 1) >= phys_regions[i].base)
121 break;
122 }
123 if (i == num_phys_regions)
124 return base;
125 }
126 return 0;
127}
128unsigned long __init
129txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end,
130 unsigned long *size)
131{
132 unsigned long sz, base;
133 for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) {
134 base = txboard_find_free_phys_region(begin, end, sz);
135 if (base) {
136 *size = sz;
137 return base;
138 }
139 }
140 return 0;
141}
142unsigned long __init
143txboard_request_phys_region_range(unsigned long begin, unsigned long end,
144 unsigned long size)
145{
146 unsigned long base;
147 base = txboard_find_free_phys_region(begin, end, size);
148 if (base)
149 txboard_add_phys_region(base, size);
150 return base;
151}
152unsigned long __init
153txboard_request_phys_region(unsigned long size)
154{
155 unsigned long base;
156 unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
157 base = txboard_find_free_phys_region(begin, end, size);
158 if (base)
159 txboard_add_phys_region(base, size);
160 return base;
161}
162unsigned long __init
163txboard_request_phys_region_shrink(unsigned long *size)
164{
165 unsigned long base;
166 unsigned long begin = 0, end = 0x20000000; /* search low 512MB */
167 base = txboard_find_free_phys_region_shrink(begin, end, size);
168 if (base)
169 txboard_add_phys_region(base, *size);
170 return base;
171}
172
173#ifdef CONFIG_PCI
174void __init
175tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr,
176 struct pci_controller *channel,
177 unsigned long pci_io_base,
178 int extarb)
179{
180 int i;
181
182 /* Disable All Initiator Space */
183 pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)|
184 TX4938_PCIC_PCICCFG_G2PMEN(1)|
185 TX4938_PCIC_PCICCFG_G2PMEN(2)|
186 TX4938_PCIC_PCICCFG_G2PIOEN);
187
188 /* GB->PCI mappings */
189 pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4;
190 pcicptr->g2piogbase = pci_io_base |
191#ifdef __BIG_ENDIAN
192 TX4938_PCIC_G2PIOGBASE_ECHG
193#else
194 TX4938_PCIC_G2PIOGBASE_BSDIS
195#endif
196 ;
197 pcicptr->g2piopbase = 0;
198 for (i = 0; i < 3; i++) {
199 pcicptr->g2pmmask[i] = 0;
200 pcicptr->g2pmgbase[i] = 0;
201 pcicptr->g2pmpbase[i] = 0;
202 }
203 if (channel->mem_resource->end) {
204 pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4;
205 pcicptr->g2pmgbase[0] = channel->mem_resource->start |
206#ifdef __BIG_ENDIAN
207 TX4938_PCIC_G2PMnGBASE_ECHG
208#else
209 TX4938_PCIC_G2PMnGBASE_BSDIS
210#endif
211 ;
212 pcicptr->g2pmpbase[0] = channel->mem_resource->start;
213 }
214 /* PCI->GB mappings (I/O 256B) */
215 pcicptr->p2giopbase = 0; /* 256B */
216 pcicptr->p2giogbase = 0;
217 /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
218 pcicptr->p2gm0plbase = 0;
219 pcicptr->p2gm0pubase = 0;
220 pcicptr->p2gmgbase[0] = 0 |
221 TX4938_PCIC_P2GMnGBASE_TMEMEN |
222#ifdef __BIG_ENDIAN
223 TX4938_PCIC_P2GMnGBASE_TECHG
224#else
225 TX4938_PCIC_P2GMnGBASE_TBSDIS
226#endif
227 ;
228 /* PCI->GB mappings (MEM 16MB) */
229 pcicptr->p2gm1plbase = 0xffffffff;
230 pcicptr->p2gm1pubase = 0xffffffff;
231 pcicptr->p2gmgbase[1] = 0;
232 /* PCI->GB mappings (MEM 1MB) */
233 pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */
234 pcicptr->p2gmgbase[2] = 0;
235
236 pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK;
237 /* Enable Initiator Memory Space */
238 if (channel->mem_resource->end)
239 pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0);
240 /* Enable Initiator I/O Space */
241 if (channel->io_resource->end)
242 pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN;
243 /* Enable Initiator Config */
244 pcicptr->pciccfg |=
245 TX4938_PCIC_PCICCFG_ICAEN |
246 TX4938_PCIC_PCICCFG_TCAR;
247
248 /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
249 pcicptr->pcicfg1 = 0;
250
251 pcicptr->g2ptocnt &= ~0xffff;
252
253 if (tx4938_pcic_trdyto >= 0) {
254 pcicptr->g2ptocnt &= ~0xff;
255 pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff);
256 }
257
258 if (tx4938_pcic_retryto >= 0) {
259 pcicptr->g2ptocnt &= ~0xff00;
260 pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00);
261 }
262
263 /* Clear All Local Bus Status */
264 pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL;
265 /* Enable All Local Bus Interrupts */
266 pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL;
267 /* Clear All Initiator Status */
268 pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL;
269 /* Enable All Initiator Interrupts */
270 pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL;
271 /* Clear All PCI Status Error */
272 pcicptr->pcistatus =
273 (pcicptr->pcistatus & 0x0000ffff) |
274 (TX4938_PCIC_PCISTATUS_ALL << 16);
275 /* Enable All PCI Status Error Interrupts */
276 pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL;
277
278 if (!extarb) {
279 /* Reset Bus Arbiter */
280 pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA;
281 pcicptr->pbabm = 0;
282 /* Enable Bus Arbiter */
283 pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN;
284 }
285
286 /* PCIC Int => IRC IRQ16 */
287 pcicptr->pcicfg2 =
288 (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC;
289
290 pcicptr->pcistatus = PCI_COMMAND_MASTER |
291 PCI_COMMAND_MEMORY |
292 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
293}
294
295int __init
296tx4938_report_pciclk(void)
297{
298 unsigned long pcode = TX4938_REV_PCODE();
299 int pciclk = 0;
300 printk("TX%lx PCIC --%s PCICLK:",
301 pcode,
302 (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : "");
303 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
304
305 switch ((unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK) {
306 case TX4938_CCFG_PCIDIVMODE_4:
307 pciclk = txx9_cpu_clock / 4; break;
308 case TX4938_CCFG_PCIDIVMODE_4_5:
309 pciclk = txx9_cpu_clock * 2 / 9; break;
310 case TX4938_CCFG_PCIDIVMODE_5:
311 pciclk = txx9_cpu_clock / 5; break;
312 case TX4938_CCFG_PCIDIVMODE_5_5:
313 pciclk = txx9_cpu_clock * 2 / 11; break;
314 case TX4938_CCFG_PCIDIVMODE_8:
315 pciclk = txx9_cpu_clock / 8; break;
316 case TX4938_CCFG_PCIDIVMODE_9:
317 pciclk = txx9_cpu_clock / 9; break;
318 case TX4938_CCFG_PCIDIVMODE_10:
319 pciclk = txx9_cpu_clock / 10; break;
320 case TX4938_CCFG_PCIDIVMODE_11:
321 pciclk = txx9_cpu_clock / 11; break;
322 }
323 printk("Internal(%dMHz)", pciclk / 1000000);
324 } else {
325 printk("External");
326 pciclk = -1;
327 }
328 printk("\n");
329 return pciclk;
330}
331
332void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr)
333{
334 pcicptrs[ch] = pcicptr;
335}
336
337struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch)
338{
339 return pcicptrs[ch];
340}
341
342static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
343 int top_bus, int busnr, int devfn)
344{
345 static struct pci_dev dev;
346 static struct pci_bus bus;
347
348 dev.sysdata = bus.sysdata = hose;
349 dev.devfn = devfn;
350 bus.number = busnr;
351 bus.ops = hose->pci_ops;
352 bus.parent = NULL;
353 dev.bus = &bus;
354
355 return &dev;
356}
357
358#define EARLY_PCI_OP(rw, size, type) \
359static int early_##rw##_config_##size(struct pci_controller *hose, \
360 int top_bus, int bus, int devfn, int offset, type value) \
361{ \
362 return pci_##rw##_config_##size( \
363 fake_pci_dev(hose, top_bus, bus, devfn), \
364 offset, value); \
365}
366
367EARLY_PCI_OP(read, word, u16 *)
368
369int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus)
370{
371 u32 pci_devfn;
372 unsigned short vid;
373 int devfn_start = 0;
374 int devfn_stop = 0xff;
375 int cap66 = -1;
376 u16 stat;
377
378 printk("PCI: Checking 66MHz capabilities...\n");
379
380 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
381 if (early_read_config_word(hose, top_bus, current_bus,
382 pci_devfn, PCI_VENDOR_ID,
383 &vid) != PCIBIOS_SUCCESSFUL)
384 continue;
385
386 if (vid == 0xffff) continue;
387
388 /* check 66MHz capability */
389 if (cap66 < 0)
390 cap66 = 1;
391 if (cap66) {
392 early_read_config_word(hose, top_bus, current_bus, pci_devfn,
393 PCI_STATUS, &stat);
394 if (!(stat & PCI_STATUS_66MHZ)) {
395 printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n",
396 current_bus, pci_devfn);
397 cap66 = 0;
398 break;
399 }
400 }
401 }
402 return cap66 > 0;
403}
404
405int __init
406tx4938_pciclk66_setup(void)
407{
408 int pciclk;
409
410 /* Assert M66EN */
411 tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
412 /* Double PCICLK (if possible) */
413 if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) {
414 unsigned int pcidivmode =
415 tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIDIVMODE_MASK;
416 switch (pcidivmode) {
417 case TX4938_CCFG_PCIDIVMODE_8:
418 case TX4938_CCFG_PCIDIVMODE_4:
419 pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
420 pciclk = txx9_cpu_clock / 4;
421 break;
422 case TX4938_CCFG_PCIDIVMODE_9:
423 case TX4938_CCFG_PCIDIVMODE_4_5:
424 pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
425 pciclk = txx9_cpu_clock * 2 / 9;
426 break;
427 case TX4938_CCFG_PCIDIVMODE_10:
428 case TX4938_CCFG_PCIDIVMODE_5:
429 pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
430 pciclk = txx9_cpu_clock / 5;
431 break;
432 case TX4938_CCFG_PCIDIVMODE_11:
433 case TX4938_CCFG_PCIDIVMODE_5_5:
434 default:
435 pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
436 pciclk = txx9_cpu_clock * 2 / 11;
437 break;
438 }
439 tx4938_ccfgptr->ccfg =
440 (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK)
441 | pcidivmode;
442 printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
443 (unsigned long)tx4938_ccfgptr->ccfg);
444 } else {
445 pciclk = -1;
446 }
447 return pciclk;
448}
449
450extern struct pci_controller tx4938_pci_controller[];
451static int __init tx4938_pcibios_init(void)
452{
453 unsigned long mem_base[2];
454 unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */
455 unsigned long io_base[2];
456 unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */
457 /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */
458 int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
459
460 PCIBIOS_MIN_IO = 0x00001000UL;
461
462 mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
463 io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
464
465 printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
466 (unsigned short)(tx4938_pcicptr->pciid >> 16),
467 (unsigned short)(tx4938_pcicptr->pciid & 0xffff),
468 (unsigned short)(tx4938_pcicptr->pciccrev & 0xff),
469 extarb ? "External" : "Internal");
470
471 /* setup PCI area */
472 tx4938_pci_controller[0].io_resource->start = io_base[0];
473 tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1;
474 tx4938_pci_controller[0].mem_resource->start = mem_base[0];
475 tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1;
476
477 set_tx4938_pcicptr(0, tx4938_pcicptr);
478
479 register_pci_controller(&tx4938_pci_controller[0]);
480
481 if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) {
482 printk("TX4938_CCFG_PCI66 already configured\n");
483 txboard_pci66_mode = -1; /* already configured */
484 }
485
486 /* Reset PCI Bus */
487 writeb(0, rbtx4938_pcireset_addr);
488 /* Reset PCIC */
489 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
490 if (txboard_pci66_mode > 0)
491 tx4938_pciclk66_setup();
492 mdelay(10);
493 /* clear PCIC reset */
494 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
495 writeb(1, rbtx4938_pcireset_addr);
496 mmiowb();
497 tx4938_report_pcic_status1(tx4938_pcicptr);
498
499 tx4938_report_pciclk();
500 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
501 if (txboard_pci66_mode == 0 &&
502 txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) {
503 /* Reset PCI Bus */
504 writeb(0, rbtx4938_pcireset_addr);
505 /* Reset PCIC */
506 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST;
507 tx4938_pciclk66_setup();
508 mdelay(10);
509 /* clear PCIC reset */
510 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST;
511 writeb(1, rbtx4938_pcireset_addr);
512 mmiowb();
513 /* Reinitialize PCIC */
514 tx4938_report_pciclk();
515 tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb);
516 }
517
518 mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]);
519 io_base[1] = txboard_request_phys_region_shrink(&io_size[1]);
520 /* Reset PCIC1 */
521 tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST;
522 /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
523 if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD))
524 tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66;
525 else
526 tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66;
527 mdelay(10);
528 /* clear PCIC1 reset */
529 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
530 tx4938_report_pcic_status1(tx4938_pcic1ptr);
531
532 printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x",
533 (unsigned short)(tx4938_pcic1ptr->pciid >> 16),
534 (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff),
535 (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff));
536 printk("%s PCICLK:%dMHz\n",
537 (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "",
538 txx9_gbus_clock /
539 ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) /
540 1000000);
541
542 /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */
543 tx4938_pci_controller[1].io_resource->start =
544 io_base[1] - io_base[0];
545 tx4938_pci_controller[1].io_resource->end =
546 io_base[1] - io_base[0] + io_size[1] - 1;
547 tx4938_pci_controller[1].mem_resource->start = mem_base[1];
548 tx4938_pci_controller[1].mem_resource->end =
549 mem_base[1] + mem_size[1] - 1;
550 set_tx4938_pcicptr(1, tx4938_pcic1ptr);
551
552 register_pci_controller(&tx4938_pci_controller[1]);
553
554 tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb);
555
556 /* map ioport 0 to PCI I/O space address 0 */
557 set_io_port_base(KSEG1 + io_base[0]);
558
559 return 0;
560}
561
562arch_initcall(tx4938_pcibios_init);
563
564#endif /* CONFIG_PCI */
565
566/* SPI support */
567
568/* chip select for SPI devices */
569#define SEEPROM1_CS 7 /* PIO7 */
570#define SEEPROM2_CS 0 /* IOC */
571#define SEEPROM3_CS 1 /* IOC */
572#define SRTC_CS 2 /* IOC */
573
574#ifdef CONFIG_PCI
575static int __init rbtx4938_ethaddr_init(void)
576{
577 unsigned char dat[17];
578 unsigned char sum;
579 int i;
580
581 /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
582 if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
583 printk(KERN_ERR "seeprom: read error.\n");
584 return -ENODEV;
585 } else {
586 if (strcmp(dat, "MAC") != 0)
587 printk(KERN_WARNING "seeprom: bad signature.\n");
588 for (i = 0, sum = 0; i < sizeof(dat); i++)
589 sum += dat[i];
590 if (sum)
591 printk(KERN_WARNING "seeprom: bad checksum.\n");
592 }
593 for (i = 0; i < 2; i++) {
594 unsigned int id =
595 TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0);
596 struct platform_device *pdev;
597 if (!(tx4938_ccfgptr->pcfg &
598 (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
599 continue;
600 pdev = platform_device_alloc("tc35815-mac", id);
601 if (!pdev ||
602 platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
603 platform_device_add(pdev))
604 platform_device_put(pdev);
605 }
606 return 0;
607}
608device_initcall(rbtx4938_ethaddr_init);
609#endif /* CONFIG_PCI */
610
611static void __init rbtx4938_spi_setup(void)
612{
613 /* set SPI_SEL */
614 tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL;
615}
616
617static struct resource rbtx4938_fpga_resource;
618
619static char pcode_str[8];
620static struct resource tx4938_reg_resource = {
621 .start = TX4938_REG_BASE,
622 .end = TX4938_REG_BASE + TX4938_REG_SIZE,
623 .name = pcode_str,
624 .flags = IORESOURCE_MEM
625};
626
627void __init tx4938_board_setup(void)
628{
629 int i;
630 unsigned long divmode;
631 int cpuclk = 0;
632 unsigned long pcode = TX4938_REV_PCODE();
633
634 ioport_resource.start = 0x1000;
635 ioport_resource.end = 0xffffffff;
636 iomem_resource.start = 0x1000;
637 iomem_resource.end = 0xffffffff; /* expand to 4GB */
638
639 sprintf(pcode_str, "TX%lx", pcode);
640 /* SDRAMC,EBUSC are configured by PROM */
641 for (i = 0; i < 8; i++) {
642 if (!(tx4938_ebuscptr->cr[i] & 0x8))
643 continue; /* disabled */
644 rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i);
645 txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i));
646 }
647
648 /* clocks */
649 if (txx9_master_clock) {
650 /* calculate gbus_clock and cpu_clock_freq from master_clock */
651 divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
652 switch (divmode) {
653 case TX4938_CCFG_DIVMODE_8:
654 case TX4938_CCFG_DIVMODE_10:
655 case TX4938_CCFG_DIVMODE_12:
656 case TX4938_CCFG_DIVMODE_16:
657 case TX4938_CCFG_DIVMODE_18:
658 txx9_gbus_clock = txx9_master_clock * 4; break;
659 default:
660 txx9_gbus_clock = txx9_master_clock;
661 }
662 switch (divmode) {
663 case TX4938_CCFG_DIVMODE_2:
664 case TX4938_CCFG_DIVMODE_8:
665 cpuclk = txx9_gbus_clock * 2; break;
666 case TX4938_CCFG_DIVMODE_2_5:
667 case TX4938_CCFG_DIVMODE_10:
668 cpuclk = txx9_gbus_clock * 5 / 2; break;
669 case TX4938_CCFG_DIVMODE_3:
670 case TX4938_CCFG_DIVMODE_12:
671 cpuclk = txx9_gbus_clock * 3; break;
672 case TX4938_CCFG_DIVMODE_4:
673 case TX4938_CCFG_DIVMODE_16:
674 cpuclk = txx9_gbus_clock * 4; break;
675 case TX4938_CCFG_DIVMODE_4_5:
676 case TX4938_CCFG_DIVMODE_18:
677 cpuclk = txx9_gbus_clock * 9 / 2; break;
678 }
679 txx9_cpu_clock = cpuclk;
680 } else {
681 if (txx9_cpu_clock == 0) {
682 txx9_cpu_clock = 300000000; /* 300MHz */
683 }
684 /* calculate gbus_clock and master_clock from cpu_clock_freq */
685 cpuclk = txx9_cpu_clock;
686 divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK;
687 switch (divmode) {
688 case TX4938_CCFG_DIVMODE_2:
689 case TX4938_CCFG_DIVMODE_8:
690 txx9_gbus_clock = cpuclk / 2; break;
691 case TX4938_CCFG_DIVMODE_2_5:
692 case TX4938_CCFG_DIVMODE_10:
693 txx9_gbus_clock = cpuclk * 2 / 5; break;
694 case TX4938_CCFG_DIVMODE_3:
695 case TX4938_CCFG_DIVMODE_12:
696 txx9_gbus_clock = cpuclk / 3; break;
697 case TX4938_CCFG_DIVMODE_4:
698 case TX4938_CCFG_DIVMODE_16:
699 txx9_gbus_clock = cpuclk / 4; break;
700 case TX4938_CCFG_DIVMODE_4_5:
701 case TX4938_CCFG_DIVMODE_18:
702 txx9_gbus_clock = cpuclk * 2 / 9; break;
703 }
704 switch (divmode) {
705 case TX4938_CCFG_DIVMODE_8:
706 case TX4938_CCFG_DIVMODE_10:
707 case TX4938_CCFG_DIVMODE_12:
708 case TX4938_CCFG_DIVMODE_16:
709 case TX4938_CCFG_DIVMODE_18:
710 txx9_master_clock = txx9_gbus_clock / 4; break;
711 default:
712 txx9_master_clock = txx9_gbus_clock;
713 }
714 }
715 /* change default value to udelay/mdelay take reasonable time */
716 loops_per_jiffy = txx9_cpu_clock / HZ / 2;
717
718 /* CCFG */
719 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
720 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
721 /* do reset on watchdog */
722 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR;
723 /* clear PCIC1 reset */
724 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
725 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
726
727 /* enable Timeout BusError */
728 if (tx4938_ccfg_toeon)
729 tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE;
730
731 /* DMA selection */
732 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL;
733
734 /* Use external clock for external arbiter */
735 if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB))
736 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL;
737
738 printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n",
739 pcode_str,
740 cpuclk / 1000000, txx9_master_clock / 1000000,
741 (unsigned long)tx4938_ccfgptr->crir,
742 tx4938_ccfgptr->ccfg,
743 tx4938_ccfgptr->pcfg);
744
745 printk("%s SDRAMC --", pcode_str);
746 for (i = 0; i < 4; i++) {
747 unsigned long long cr = tx4938_sdramcptr->cr[i];
748 unsigned long ram_base, ram_size;
749 if (!((unsigned long)cr & 0x00000400))
750 continue; /* disabled */
751 ram_base = (unsigned long)(cr >> 49) << 21;
752 ram_size = ((unsigned long)(cr >> 33) + 1) << 21;
753 if (ram_base >= 0x20000000)
754 continue; /* high memory (ignore) */
755 printk(" CR%d:%016Lx", i, cr);
756 txboard_add_phys_region(ram_base, ram_size);
757 }
758 printk(" TR:%09Lx\n", tx4938_sdramcptr->tr);
759
760 /* SRAM */
761 if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) {
762 unsigned int size = 0x800;
763 unsigned long base =
764 (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1);
765 txboard_add_phys_region(base, size);
766 }
767
768 /* TMR */
769 for (i = 0; i < TX4938_NR_TMR; i++)
770 txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
771
772 /* enable DMA */
773 for (i = 0; i < 2; i++)
774 ____raw_writeq(TX4938_DMA_MCR_MSTEN,
775 (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
776
777 /* PIO */
778 __raw_writel(0, &tx4938_pioptr->maskcpu);
779 __raw_writel(0, &tx4938_pioptr->maskext);
780
781 /* TX4938 internal registers */
782 if (request_resource(&iomem_resource, &tx4938_reg_resource))
783 printk("request resource for internal registers failed\n");
784}
785
786#ifdef CONFIG_PCI
787static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr)
788{
789 unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16);
790 unsigned long g2pstatus = pcicptr->g2pstatus;
791 unsigned long pcicstatus = pcicptr->pcicstatus;
792 static struct {
793 unsigned long flag;
794 const char *str;
795 } pcistat_tbl[] = {
796 { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" },
797 { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" },
798 { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" },
799 { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" },
800 { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" },
801 { PCI_STATUS_PARITY, "MasterParityError" },
802 }, g2pstat_tbl[] = {
803 { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" },
804 { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" },
805 }, pcicstat_tbl[] = {
806 { TX4938_PCIC_PCICSTATUS_PME, "PME" },
807 { TX4938_PCIC_PCICSTATUS_TLB, "TLB" },
808 { TX4938_PCIC_PCICSTATUS_NIB, "NIB" },
809 { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" },
810 { TX4938_PCIC_PCICSTATUS_PERR, "PERR" },
811 { TX4938_PCIC_PCICSTATUS_SERR, "SERR" },
812 { TX4938_PCIC_PCICSTATUS_GBE, "GBE" },
813 { TX4938_PCIC_PCICSTATUS_IWB, "IWB" },
814 };
815 int i;
816
817 printk("pcistat:%04x(", pcistatus);
818 for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
819 if (pcistatus & pcistat_tbl[i].flag)
820 printk("%s ", pcistat_tbl[i].str);
821 printk("), g2pstatus:%08lx(", g2pstatus);
822 for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
823 if (g2pstatus & g2pstat_tbl[i].flag)
824 printk("%s ", g2pstat_tbl[i].str);
825 printk("), pcicstatus:%08lx(", pcicstatus);
826 for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
827 if (pcicstatus & pcicstat_tbl[i].flag)
828 printk("%s ", pcicstat_tbl[i].str);
829 printk(")\n");
830}
831
832void tx4938_report_pcic_status(void)
833{
834 int i;
835 struct tx4938_pcic_reg *pcicptr;
836 for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++)
837 tx4938_report_pcic_status1(pcicptr);
838}
839
840#endif /* CONFIG_PCI */
841
842void __init plat_time_init(void)
843{
844 mips_hpt_frequency = txx9_cpu_clock / 2;
845 if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS)
846 txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL,
847 TXX9_IRQ_BASE + TX4938_IR_TMR(0),
848 txx9_gbus_clock / 2);
849}
850
851void __init plat_mem_setup(void)
852{
853 unsigned long long pcfg;
854 char *argptr;
855
856 iomem_resource.end = 0xffffffff; /* 4GB */
857
858 if (txx9_master_clock == 0)
859 txx9_master_clock = 25000000; /* 25MHz */
860 tx4938_board_setup();
861#ifndef CONFIG_PCI
862 set_io_port_base(RBTX4938_ETHER_BASE);
863#endif
864
865#ifdef CONFIG_SERIAL_TXX9
866 {
867 extern int early_serial_txx9_setup(struct uart_port *port);
868 int i;
869 struct uart_port req;
870 for(i = 0; i < 2; i++) {
871 memset(&req, 0, sizeof(req));
872 req.line = i;
873 req.iotype = UPIO_MEM;
874 req.membase = (char *)(0xff1ff300 + i * 0x100);
875 req.mapbase = 0xff1ff300 + i * 0x100;
876 req.irq = RBTX4938_IRQ_IRC_SIO(i);
877 req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
878 req.uartclk = 50000000;
879 early_serial_txx9_setup(&req);
880 }
881 }
882#ifdef CONFIG_SERIAL_TXX9_CONSOLE
883 argptr = prom_getcmdline();
884 if (strstr(argptr, "console=") == NULL) {
885 strcat(argptr, " console=ttyS0,38400");
886 }
887#endif
888#endif
889
890#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
891 printk("PIOSEL: disabling both ata and nand selection\n");
892 local_irq_disable();
893 tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
894#endif
895
896#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
897 printk("PIOSEL: enabling nand selection\n");
898 tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL;
899 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL;
900#endif
901
902#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
903 printk("PIOSEL: enabling ata selection\n");
904 tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL;
905 tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL;
906#endif
907
908#ifdef CONFIG_IP_PNP
909 argptr = prom_getcmdline();
910 if (strstr(argptr, "ip=") == NULL) {
911 strcat(argptr, " ip=any");
912 }
913#endif
914
915
916#ifdef CONFIG_FB
917 {
918 conswitchp = &dummy_con;
919 }
920#endif
921
922 rbtx4938_spi_setup();
923 pcfg = tx4938_ccfgptr->pcfg; /* updated */
924 /* fixup piosel */
925 if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
926 TX4938_PCFG_ATA_SEL)
927 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
928 rbtx4938_piosel_addr);
929 else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
930 TX4938_PCFG_NDF_SEL)
931 writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
932 rbtx4938_piosel_addr);
933 else
934 writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
935 rbtx4938_piosel_addr);
936
937 rbtx4938_fpga_resource.name = "FPGA Registers";
938 rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
939 rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
940 rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
941 if (request_resource(&iomem_resource, &rbtx4938_fpga_resource))
942 printk("request resource for fpga failed\n");
943
944 _machine_restart = rbtx4938_machine_restart;
945 _machine_halt = rbtx4938_machine_halt;
946 pm_power_off = rbtx4938_machine_power_off;
947
948 writeb(0xff, rbtx4938_led_addr);
949 printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
950 readb(rbtx4938_fpga_rev_addr),
951 readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
952}
953
954static int __init rbtx4938_ne_init(void)
955{
956 struct resource res[] = {
957 {
958 .start = RBTX4938_RTL_8019_BASE,
959 .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
960 .flags = IORESOURCE_IO,
961 }, {
962 .start = RBTX4938_RTL_8019_IRQ,
963 .flags = IORESOURCE_IRQ,
964 }
965 };
966 struct platform_device *dev =
967 platform_device_register_simple("ne", -1,
968 res, ARRAY_SIZE(res));
969 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
970}
971device_initcall(rbtx4938_ne_init);
972
973/* GPIO support */
974
975int gpio_to_irq(unsigned gpio)
976{
977 return -EINVAL;
978}
979
980int irq_to_gpio(unsigned irq)
981{
982 return -EINVAL;
983}
984
985static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
986
987static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
988 int value)
989{
990 u8 val;
991 unsigned long flags;
992 spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
993 val = readb(rbtx4938_spics_addr);
994 if (value)
995 val |= 1 << offset;
996 else
997 val &= ~(1 << offset);
998 writeb(val, rbtx4938_spics_addr);
999 mmiowb();
1000 spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
1001}
1002
1003static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
1004 unsigned int offset, int value)
1005{
1006 rbtx4938_spi_gpio_set(chip, offset, value);
1007 return 0;
1008}
1009
1010static struct gpio_chip rbtx4938_spi_gpio_chip = {
1011 .set = rbtx4938_spi_gpio_set,
1012 .direction_output = rbtx4938_spi_gpio_dir_out,
1013 .label = "RBTX4938-SPICS",
1014 .base = 16,
1015 .ngpio = 3,
1016};
1017
1018/* SPI support */
1019
1020static void __init txx9_spi_init(unsigned long base, int irq)
1021{
1022 struct resource res[] = {
1023 {
1024 .start = base,
1025 .end = base + 0x20 - 1,
1026 .flags = IORESOURCE_MEM,
1027 }, {
1028 .start = irq,
1029 .flags = IORESOURCE_IRQ,
1030 },
1031 };
1032 platform_device_register_simple("spi_txx9", 0,
1033 res, ARRAY_SIZE(res));
1034}
1035
1036static int __init rbtx4938_spi_init(void)
1037{
1038 struct spi_board_info srtc_info = {
1039 .modalias = "rtc-rs5c348",
1040 .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
1041 .bus_num = 0,
1042 .chip_select = 16 + SRTC_CS,
1043 /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
1044 .mode = SPI_MODE_1 | SPI_CS_HIGH,
1045 };
1046 spi_register_board_info(&srtc_info, 1);
1047 spi_eeprom_register(SEEPROM1_CS);
1048 spi_eeprom_register(16 + SEEPROM2_CS);
1049 spi_eeprom_register(16 + SEEPROM3_CS);
1050 gpio_request(16 + SRTC_CS, "rtc-rs5c348");
1051 gpio_direction_output(16 + SRTC_CS, 0);
1052 gpio_request(SEEPROM1_CS, "seeprom1");
1053 gpio_direction_output(SEEPROM1_CS, 1);
1054 gpio_request(16 + SEEPROM2_CS, "seeprom2");
1055 gpio_direction_output(16 + SEEPROM2_CS, 1);
1056 gpio_request(16 + SEEPROM3_CS, "seeprom3");
1057 gpio_direction_output(16 + SEEPROM3_CS, 1);
1058 txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI);
1059 return 0;
1060}
1061
1062static int __init rbtx4938_arch_init(void)
1063{
1064 txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16);
1065 gpiochip_add(&rbtx4938_spi_gpio_chip);
1066 return rbtx4938_spi_init();
1067}
1068arch_initcall(rbtx4938_arch_init);
1069
1070/* Watchdog support */
1071
1072static int __init txx9_wdt_init(unsigned long base)
1073{
1074 struct resource res = {
1075 .start = base,
1076 .end = base + 0x100 - 1,
1077 .flags = IORESOURCE_MEM,
1078 };
1079 struct platform_device *dev =
1080 platform_device_register_simple("txx9wdt", -1, &res, 1);
1081 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1082}
1083
1084static int __init rbtx4938_wdt_init(void)
1085{
1086 return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
1087}
1088device_initcall(rbtx4938_wdt_init);
1089
1090/* Minimum CLK support */
1091
1092struct clk *clk_get(struct device *dev, const char *id)
1093{
1094 if (!strcmp(id, "spi-baseclk"))
1095 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1096 if (!strcmp(id, "imbus_clk"))
1097 return (struct clk *)(txx9_gbus_clock / 2);
1098 return ERR_PTR(-ENOENT);
1099}
1100EXPORT_SYMBOL(clk_get);
1101
1102int clk_enable(struct clk *clk)
1103{
1104 return 0;
1105}
1106EXPORT_SYMBOL(clk_enable);
1107
1108void clk_disable(struct clk *clk)
1109{
1110}
1111EXPORT_SYMBOL(clk_disable);
1112
1113unsigned long clk_get_rate(struct clk *clk)
1114{
1115 return (unsigned long)clk;
1116}
1117EXPORT_SYMBOL(clk_get_rate);
1118
1119void clk_put(struct clk *clk)
1120{
1121}
1122EXPORT_SYMBOL(clk_put);
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}