diff options
Diffstat (limited to 'arch/mips/txx9')
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 @@ | |||
1 | config TOSHIBA_FPCIB0 | ||
2 | bool "FPCIB0 Backplane Support" | ||
3 | depends on TOSHIBA_RBTX4927 | ||
4 | |||
5 | if TOSHIBA_RBTX4938 | ||
6 | |||
7 | comment "Multiplex Pin Select" | ||
8 | choice | ||
9 | prompt "PIO[58:61]" | ||
10 | default TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
11 | |||
12 | config TOSHIBA_RBTX4938_MPLEX_PIO58_61 | ||
13 | bool "PIO" | ||
14 | config TOSHIBA_RBTX4938_MPLEX_NAND | ||
15 | bool "NAND" | ||
16 | config TOSHIBA_RBTX4938_MPLEX_ATA | ||
17 | bool "ATA" | ||
18 | |||
19 | endchoice | ||
20 | |||
21 | config 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 | |||
28 | endif | ||
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 | |||
5 | obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o | ||
6 | obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o | ||
7 | obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o | ||
8 | obj-$(CONFIG_KGDB) += dbgio.o | ||
9 | |||
10 | EXTRA_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 | |||
36 | extern u8 txx9_sio_kdbg_rd(void); | ||
37 | extern int txx9_sio_kdbg_wr( u8 ch ); | ||
38 | |||
39 | u8 getDebugChar(void) | ||
40 | { | ||
41 | return (txx9_sio_kdbg_rd()); | ||
42 | } | ||
43 | |||
44 | int 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 | |||
34 | void __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 | |||
41 | asmlinkage 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 | |||
20 | void __init | ||
21 | tx4938_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 | |||
28 | int toshiba_rbtx4938_irq_nested(int irq); | ||
29 | |||
30 | asmlinkage 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 | |||
36 | static 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 | |||
125 | unsigned 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 | |||
19 | static unsigned int __init | ||
20 | tx4938_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 | |||
107 | unsigned int __init | ||
108 | tx4938_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 | |||
58 | static unsigned long g_smsc_fdc37m81x_base = 0; | ||
59 | |||
60 | static 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 | |||
67 | static 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 | |||
73 | void 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 | |||
81 | void 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 | |||
88 | u8 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 | |||
98 | void smsc_fdc37m81x_config_set(u8 reg, u8 val) | ||
99 | { | ||
100 | if (g_smsc_fdc37m81x_base) | ||
101 | smsc_dc37m81x_wr(reg, val); | ||
102 | } | ||
103 | |||
104 | unsigned 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 | ||
130 | void 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 | |||
136 | void 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 | |||
5 | obj-y += prom.o init.o irq.o setup.o | ||
6 | obj-$(CONFIG_KGDB) += kgdb_io.o | ||
7 | |||
8 | EXTRA_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 | |||
34 | extern void __init prom_init_cmdline(void); | ||
35 | |||
36 | const char *get_system_type(void) | ||
37 | { | ||
38 | return "Toshiba" | ||
39 | #ifdef CONFIG_TOSHIBA_JMR3927 | ||
40 | " JMR_TX3927" | ||
41 | #endif | ||
42 | ; | ||
43 | } | ||
44 | |||
45 | extern void puts(const char *cp); | ||
46 | |||
47 | void __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 | |||
48 | static 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 | */ | ||
59 | static 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 | } | ||
69 | static 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 | |||
80 | asmlinkage 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 | |||
92 | static 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 | |||
106 | static struct irqaction ioc_action = { | ||
107 | .handler = jmr3927_ioc_interrupt, | ||
108 | .mask = CPU_MASK_NONE, | ||
109 | .name = "IOC", | ||
110 | }; | ||
111 | |||
112 | static 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 | } | ||
120 | static struct irqaction pcierr_action = { | ||
121 | .handler = jmr3927_pcierr_interrupt, | ||
122 | .mask = CPU_MASK_NONE, | ||
123 | .name = "PCI error", | ||
124 | }; | ||
125 | |||
126 | static void __init jmr3927_irq_init(void); | ||
127 | |||
128 | void __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 | |||
157 | static 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 | |||
165 | static 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 | |||
38 | static int remoteDebugInitialized = 0; | ||
39 | static void debugInit(int baud); | ||
40 | |||
41 | int 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 | |||
62 | unsigned 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 | |||
95 | static 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 | |||
45 | char * __init prom_getcmdline(void) | ||
46 | { | ||
47 | return &(arcs_cmdline[0]); | ||
48 | } | ||
49 | |||
50 | void __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 | |||
71 | void __init prom_free_prom_memory(void) | ||
72 | { | ||
73 | } | ||
74 | |||
75 | #define TIMEOUT 0xffffff | ||
76 | |||
77 | void | ||
78 | prom_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 | |||
91 | void | ||
92 | puts(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 | |||
50 | extern void puts(const char *cp); | ||
51 | |||
52 | /* don't enable - see errata */ | ||
53 | static int jmr3927_ccfg_toeon; | ||
54 | |||
55 | static 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 | |||
67 | static void jmr3927_machine_restart(char *command) | ||
68 | { | ||
69 | local_irq_disable(); | ||
70 | puts("Rebooting..."); | ||
71 | do_reset(); | ||
72 | } | ||
73 | |||
74 | static void jmr3927_machine_halt(void) | ||
75 | { | ||
76 | puts("JMR-TX3927 halted.\n"); | ||
77 | while (1); | ||
78 | } | ||
79 | |||
80 | static void jmr3927_machine_power_off(void) | ||
81 | { | ||
82 | puts("JMR-TX3927 halted. Please turn off the power.\n"); | ||
83 | while (1); | ||
84 | } | ||
85 | |||
86 | void __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 | |||
97 | extern char * __init prom_getcmdline(void); | ||
98 | static void jmr3927_board_init(void); | ||
99 | extern struct resource pci_io_resource; | ||
100 | extern struct resource pci_mem_resource; | ||
101 | |||
102 | void __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 | |||
192 | static void tx3927_setup(void); | ||
193 | |||
194 | static 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 | |||
210 | static 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. */ | ||
369 | unsigned 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 | } | ||
380 | EXPORT_SYMBOL(__swizzle_addr_b); | ||
381 | |||
382 | static 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 | } | ||
393 | device_initcall(jmr3927_rtc_init); | ||
394 | |||
395 | /* Watchdog support */ | ||
396 | |||
397 | static 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 | |||
409 | static int __init jmr3927_wdt_init(void) | ||
410 | { | ||
411 | return txx9_wdt_init(TX3927_TMR_REG(2)); | ||
412 | } | ||
413 | device_initcall(jmr3927_wdt_init); | ||
414 | |||
415 | /* Minimum CLK support */ | ||
416 | |||
417 | struct 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 | } | ||
423 | EXPORT_SYMBOL(clk_get); | ||
424 | |||
425 | int clk_enable(struct clk *clk) | ||
426 | { | ||
427 | return 0; | ||
428 | } | ||
429 | EXPORT_SYMBOL(clk_enable); | ||
430 | |||
431 | void clk_disable(struct clk *clk) | ||
432 | { | ||
433 | } | ||
434 | EXPORT_SYMBOL(clk_disable); | ||
435 | |||
436 | unsigned long clk_get_rate(struct clk *clk) | ||
437 | { | ||
438 | return (unsigned long)clk; | ||
439 | } | ||
440 | EXPORT_SYMBOL(clk_get_rate); | ||
441 | |||
442 | void clk_put(struct clk *clk) | ||
443 | { | ||
444 | } | ||
445 | EXPORT_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 @@ | |||
1 | obj-y += prom.o setup.o irq.o | ||
2 | |||
3 | EXTRA_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 | /* | ||
30 | IRQ Device | ||
31 | 00 RBTX4927-ISA/00 | ||
32 | 01 RBTX4927-ISA/01 PS2/Keyboard | ||
33 | 02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) | ||
34 | 03 RBTX4927-ISA/03 | ||
35 | 04 RBTX4927-ISA/04 | ||
36 | 05 RBTX4927-ISA/05 | ||
37 | 06 RBTX4927-ISA/06 | ||
38 | 07 RBTX4927-ISA/07 | ||
39 | 08 RBTX4927-ISA/08 | ||
40 | 09 RBTX4927-ISA/09 | ||
41 | 10 RBTX4927-ISA/10 | ||
42 | 11 RBTX4927-ISA/11 | ||
43 | 12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) | ||
44 | 13 RBTX4927-ISA/13 | ||
45 | 14 RBTX4927-ISA/14 IDE | ||
46 | 15 RBTX4927-ISA/15 | ||
47 | |||
48 | 16 TX4927-CP0/00 Software 0 | ||
49 | 17 TX4927-CP0/01 Software 1 | ||
50 | 18 TX4927-CP0/02 Cascade TX4927-CP0 | ||
51 | 19 TX4927-CP0/03 Multiplexed -- do not use | ||
52 | 20 TX4927-CP0/04 Multiplexed -- do not use | ||
53 | 21 TX4927-CP0/05 Multiplexed -- do not use | ||
54 | 22 TX4927-CP0/06 Multiplexed -- do not use | ||
55 | 23 TX4927-CP0/07 CPU TIMER | ||
56 | |||
57 | 24 TX4927-PIC/00 | ||
58 | 25 TX4927-PIC/01 | ||
59 | 26 TX4927-PIC/02 | ||
60 | 27 TX4927-PIC/03 Cascade RBTX4927-IOC | ||
61 | 28 TX4927-PIC/04 | ||
62 | 29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet | ||
63 | 30 TX4927-PIC/06 | ||
64 | 31 TX4927-PIC/07 | ||
65 | 32 TX4927-PIC/08 TX4927 SerialIO Channel 0 | ||
66 | 33 TX4927-PIC/09 TX4927 SerialIO Channel 1 | ||
67 | 34 TX4927-PIC/10 | ||
68 | 35 TX4927-PIC/11 | ||
69 | 36 TX4927-PIC/12 | ||
70 | 37 TX4927-PIC/13 | ||
71 | 38 TX4927-PIC/14 | ||
72 | 39 TX4927-PIC/15 | ||
73 | 40 TX4927-PIC/16 TX4927 PCI PCI-C | ||
74 | 41 TX4927-PIC/17 | ||
75 | 42 TX4927-PIC/18 | ||
76 | 43 TX4927-PIC/19 | ||
77 | 44 TX4927-PIC/20 | ||
78 | 45 TX4927-PIC/21 | ||
79 | 46 TX4927-PIC/22 TX4927 PCI PCI-ERR | ||
80 | 47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) | ||
81 | 48 TX4927-PIC/24 | ||
82 | 49 TX4927-PIC/25 | ||
83 | 50 TX4927-PIC/26 | ||
84 | 51 TX4927-PIC/27 | ||
85 | 52 TX4927-PIC/28 | ||
86 | 53 TX4927-PIC/29 | ||
87 | 54 TX4927-PIC/30 | ||
88 | 55 TX4927-PIC/31 | ||
89 | |||
90 | 56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] | ||
91 | 57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] | ||
92 | 58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] | ||
93 | 59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] | ||
94 | 60 RBTX4927-IOC/04 | ||
95 | 61 RBTX4927-IOC/05 | ||
96 | 62 RBTX4927-IOC/06 | ||
97 | 63 RBTX4927-IOC/07 | ||
98 | |||
99 | NOTES: | ||
100 | SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 | ||
101 | SouthBridge/ISA/pin=0 no pci irq used by this device | ||
102 | SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 | ||
103 | SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 | ||
104 | SouthBridge/PMC/pin=0 no pci irq used by this device | ||
105 | SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 | ||
106 | SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) | ||
107 | JP7 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 | |||
128 | extern int tx4927_using_backplane; | ||
129 | |||
130 | static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); | ||
131 | static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); | ||
132 | |||
133 | #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" | ||
134 | static 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 | |||
144 | int 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 | |||
163 | static 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 | |||
170 | static 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 | |||
183 | static 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 | |||
192 | static 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 | |||
202 | void __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 | |||
39 | void __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 | |||
58 | void __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 | |||
78 | void __init prom_free_prom_memory(void) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | const char *get_system_type(void) | ||
83 | { | ||
84 | return "Toshiba RBTX4927/RBTX4937"; | ||
85 | } | ||
86 | |||
87 | char * __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*/ | ||
70 | extern void toshiba_rbtx4927_restart(char *command); | ||
71 | extern void toshiba_rbtx4927_halt(void); | ||
72 | extern void toshiba_rbtx4927_power_off(void); | ||
73 | |||
74 | int tx4927_using_backplane = 0; | ||
75 | |||
76 | extern void toshiba_rbtx4927_irq_setup(void); | ||
77 | |||
78 | char *prom_getcmdline(void); | ||
79 | |||
80 | #ifdef CONFIG_PCI | ||
81 | #undef TX4927_SUPPORT_COMMAND_IO | ||
82 | #undef TX4927_SUPPORT_PCI_66 | ||
83 | int tx4927_cpu_clock = 100000000; /* 100MHz */ | ||
84 | unsigned long mips_pci_io_base; | ||
85 | unsigned long mips_pci_io_size; | ||
86 | unsigned long mips_pci_mem_base; | ||
87 | unsigned long mips_pci_mem_size; | ||
88 | /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ | ||
89 | unsigned long mips_pci_io_pciaddr = 0; | ||
90 | unsigned long mips_memory_upper; | ||
91 | static int tx4927_ccfg_toeon = 1; | ||
92 | static int tx4927_pcic_trdyto = 0; /* default: disabled */ | ||
93 | unsigned long tx4927_ce_base[8]; | ||
94 | int tx4927_pci66 = 0; /* 0:auto */ | ||
95 | #endif | ||
96 | |||
97 | char *toshiba_name = ""; | ||
98 | |||
99 | #ifdef CONFIG_PCI | ||
100 | extern struct pci_controller tx4927_controller; | ||
101 | |||
102 | static 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) \ | ||
119 | static 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 | |||
127 | EARLY_PCI_OP(read, byte, u8 *) | ||
128 | EARLY_PCI_OP(read, dword, u32 *) | ||
129 | EARLY_PCI_OP(write, byte, u8) | ||
130 | EARLY_PCI_OP(write, dword, u32) | ||
131 | |||
132 | static 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 | |||
238 | arch_initcall(tx4927_pcibios_init); | ||
239 | |||
240 | extern struct resource pci_io_resource; | ||
241 | extern struct resource pci_mem_resource; | ||
242 | |||
243 | void __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 | |||
425 | static void __noreturn wait_forever(void) | ||
426 | { | ||
427 | while (1) | ||
428 | if (cpu_wait) | ||
429 | (*cpu_wait)(); | ||
430 | } | ||
431 | |||
432 | void 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 | |||
452 | void toshiba_rbtx4927_halt(void) | ||
453 | { | ||
454 | printk(KERN_NOTICE "System Halted\n"); | ||
455 | local_irq_disable(); | ||
456 | wait_forever(); | ||
457 | /* no return */ | ||
458 | } | ||
459 | |||
460 | void toshiba_rbtx4927_power_off(void) | ||
461 | { | ||
462 | toshiba_rbtx4927_halt(); | ||
463 | /* no return */ | ||
464 | } | ||
465 | |||
466 | void __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 | |||
612 | void __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 | |||
621 | static 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 | } | ||
632 | device_initcall(toshiba_rbtx4927_rtc_init); | ||
633 | |||
634 | static 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 | } | ||
651 | device_initcall(rbtx4927_ne_init); | ||
652 | |||
653 | /* Watchdog support */ | ||
654 | |||
655 | static 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 | |||
667 | static int __init rbtx4927_wdt_init(void) | ||
668 | { | ||
669 | return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL); | ||
670 | } | ||
671 | device_initcall(rbtx4927_wdt_init); | ||
672 | |||
673 | /* Minimum CLK support */ | ||
674 | |||
675 | struct 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 | } | ||
681 | EXPORT_SYMBOL(clk_get); | ||
682 | |||
683 | int clk_enable(struct clk *clk) | ||
684 | { | ||
685 | return 0; | ||
686 | } | ||
687 | EXPORT_SYMBOL(clk_enable); | ||
688 | |||
689 | void clk_disable(struct clk *clk) | ||
690 | { | ||
691 | } | ||
692 | EXPORT_SYMBOL(clk_disable); | ||
693 | |||
694 | unsigned long clk_get_rate(struct clk *clk) | ||
695 | { | ||
696 | return (unsigned long)clk; | ||
697 | } | ||
698 | EXPORT_SYMBOL(clk_get_rate); | ||
699 | |||
700 | void clk_put(struct clk *clk) | ||
701 | { | ||
702 | } | ||
703 | EXPORT_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 @@ | |||
1 | obj-y += prom.o setup.o irq.o spi_eeprom.o | ||
2 | |||
3 | EXTRA_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 | /* | ||
14 | IRQ Device | ||
15 | |||
16 | 16 TX4938-CP0/00 Software 0 | ||
17 | 17 TX4938-CP0/01 Software 1 | ||
18 | 18 TX4938-CP0/02 Cascade TX4938-CP0 | ||
19 | 19 TX4938-CP0/03 Multiplexed -- do not use | ||
20 | 20 TX4938-CP0/04 Multiplexed -- do not use | ||
21 | 21 TX4938-CP0/05 Multiplexed -- do not use | ||
22 | 22 TX4938-CP0/06 Multiplexed -- do not use | ||
23 | 23 TX4938-CP0/07 CPU TIMER | ||
24 | |||
25 | 24 TX4938-PIC/00 | ||
26 | 25 TX4938-PIC/01 | ||
27 | 26 TX4938-PIC/02 Cascade RBTX4938-IOC | ||
28 | 27 TX4938-PIC/03 RBTX4938 RTL-8019AS Ethernet | ||
29 | 28 TX4938-PIC/04 | ||
30 | 29 TX4938-PIC/05 TX4938 ETH1 | ||
31 | 30 TX4938-PIC/06 TX4938 ETH0 | ||
32 | 31 TX4938-PIC/07 | ||
33 | 32 TX4938-PIC/08 TX4938 SIO 0 | ||
34 | 33 TX4938-PIC/09 TX4938 SIO 1 | ||
35 | 34 TX4938-PIC/10 TX4938 DMA0 | ||
36 | 35 TX4938-PIC/11 TX4938 DMA1 | ||
37 | 36 TX4938-PIC/12 TX4938 DMA2 | ||
38 | 37 TX4938-PIC/13 TX4938 DMA3 | ||
39 | 38 TX4938-PIC/14 | ||
40 | 39 TX4938-PIC/15 | ||
41 | 40 TX4938-PIC/16 TX4938 PCIC | ||
42 | 41 TX4938-PIC/17 TX4938 TMR0 | ||
43 | 42 TX4938-PIC/18 TX4938 TMR1 | ||
44 | 43 TX4938-PIC/19 TX4938 TMR2 | ||
45 | 44 TX4938-PIC/20 | ||
46 | 45 TX4938-PIC/21 | ||
47 | 46 TX4938-PIC/22 TX4938 PCIERR | ||
48 | 47 TX4938-PIC/23 | ||
49 | 48 TX4938-PIC/24 | ||
50 | 49 TX4938-PIC/25 | ||
51 | 50 TX4938-PIC/26 | ||
52 | 51 TX4938-PIC/27 | ||
53 | 52 TX4938-PIC/28 | ||
54 | 53 TX4938-PIC/29 | ||
55 | 54 TX4938-PIC/30 | ||
56 | 55 TX4938-PIC/31 TX4938 SPI | ||
57 | |||
58 | 56 RBTX4938-IOC/00 PCI-D | ||
59 | 57 RBTX4938-IOC/01 PCI-C | ||
60 | 58 RBTX4938-IOC/02 PCI-B | ||
61 | 59 RBTX4938-IOC/03 PCI-A | ||
62 | 60 RBTX4938-IOC/04 RTC | ||
63 | 61 RBTX4938-IOC/05 ATA | ||
64 | 62 RBTX4938-IOC/06 MODEM | ||
65 | 63 RBTX4938-IOC/07 SWINT | ||
66 | */ | ||
67 | #include <linux/init.h> | ||
68 | #include <linux/interrupt.h> | ||
69 | #include <asm/txx9/rbtx4938.h> | ||
70 | |||
71 | static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); | ||
72 | static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); | ||
73 | |||
74 | #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" | ||
75 | static 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 | |||
83 | int | ||
84 | toshiba_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 | |||
96 | static 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 | /**********************************************************************************/ | ||
106 | static void __init | ||
107 | toshiba_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 | |||
120 | static void | ||
121 | toshiba_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 | |||
131 | static void | ||
132 | toshiba_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 | |||
142 | void __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 | |||
22 | void __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 | |||
41 | void __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 | |||
55 | void __init prom_free_prom_memory(void) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | void __init prom_fixup_mem_map(unsigned long start, unsigned long end) | ||
60 | { | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | const char *get_system_type(void) | ||
65 | { | ||
66 | return "Toshiba RBTX4938"; | ||
67 | } | ||
68 | |||
69 | char * __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 | |||
37 | extern char * __init prom_getcmdline(void); | ||
38 | static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); | ||
39 | |||
40 | /* These functions are used for rebooting or halting the machine*/ | ||
41 | extern void rbtx4938_machine_restart(char *command); | ||
42 | extern void rbtx4938_machine_halt(void); | ||
43 | extern void rbtx4938_machine_power_off(void); | ||
44 | |||
45 | /* clocks */ | ||
46 | unsigned int txx9_master_clock; | ||
47 | unsigned int txx9_cpu_clock; | ||
48 | unsigned int txx9_gbus_clock; | ||
49 | |||
50 | unsigned long rbtx4938_ce_base[8]; | ||
51 | unsigned long rbtx4938_ce_size[8]; | ||
52 | int txboard_pci66_mode; | ||
53 | static int tx4938_pcic_trdyto; /* default: disabled */ | ||
54 | static int tx4938_pcic_retryto; /* default: disabled */ | ||
55 | static int tx4938_ccfg_toeon = 1; | ||
56 | |||
57 | struct tx4938_pcic_reg *pcicptrs[4] = { | ||
58 | tx4938_pcicptr /* default setting for TX4938 */ | ||
59 | }; | ||
60 | |||
61 | static struct { | ||
62 | unsigned long base; | ||
63 | unsigned long size; | ||
64 | } phys_regions[16] __initdata; | ||
65 | static int num_phys_regions __initdata; | ||
66 | |||
67 | #define PHYS_REGION_MINSIZE 0x10000 | ||
68 | |||
69 | void 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 | |||
80 | void rbtx4938_machine_power_off(void) | ||
81 | { | ||
82 | rbtx4938_machine_halt(); | ||
83 | /* no return */ | ||
84 | } | ||
85 | |||
86 | void 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 | |||
98 | void __init | ||
99 | txboard_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 | } | ||
109 | unsigned long __init | ||
110 | txboard_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 | } | ||
128 | unsigned long __init | ||
129 | txboard_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 | } | ||
142 | unsigned long __init | ||
143 | txboard_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 | } | ||
152 | unsigned long __init | ||
153 | txboard_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 | } | ||
162 | unsigned long __init | ||
163 | txboard_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 | ||
174 | void __init | ||
175 | tx4938_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 | |||
295 | int __init | ||
296 | tx4938_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 | |||
332 | void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) | ||
333 | { | ||
334 | pcicptrs[ch] = pcicptr; | ||
335 | } | ||
336 | |||
337 | struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) | ||
338 | { | ||
339 | return pcicptrs[ch]; | ||
340 | } | ||
341 | |||
342 | static 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) \ | ||
359 | static 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 | |||
367 | EARLY_PCI_OP(read, word, u16 *) | ||
368 | |||
369 | int 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 | |||
405 | int __init | ||
406 | tx4938_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 | |||
450 | extern struct pci_controller tx4938_pci_controller[]; | ||
451 | static 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 | |||
562 | arch_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 | ||
575 | static 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 | } | ||
608 | device_initcall(rbtx4938_ethaddr_init); | ||
609 | #endif /* CONFIG_PCI */ | ||
610 | |||
611 | static void __init rbtx4938_spi_setup(void) | ||
612 | { | ||
613 | /* set SPI_SEL */ | ||
614 | tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; | ||
615 | } | ||
616 | |||
617 | static struct resource rbtx4938_fpga_resource; | ||
618 | |||
619 | static char pcode_str[8]; | ||
620 | static 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 | |||
627 | void __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 | ||
787 | static 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 | |||
832 | void 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 | |||
842 | void __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 | |||
851 | void __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 | |||
954 | static 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 | } | ||
971 | device_initcall(rbtx4938_ne_init); | ||
972 | |||
973 | /* GPIO support */ | ||
974 | |||
975 | int gpio_to_irq(unsigned gpio) | ||
976 | { | ||
977 | return -EINVAL; | ||
978 | } | ||
979 | |||
980 | int irq_to_gpio(unsigned irq) | ||
981 | { | ||
982 | return -EINVAL; | ||
983 | } | ||
984 | |||
985 | static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock); | ||
986 | |||
987 | static 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 | |||
1003 | static 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 | |||
1010 | static 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 | |||
1020 | static 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 | |||
1036 | static 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 | |||
1062 | static 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 | } | ||
1068 | arch_initcall(rbtx4938_arch_init); | ||
1069 | |||
1070 | /* Watchdog support */ | ||
1071 | |||
1072 | static 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 | |||
1084 | static int __init rbtx4938_wdt_init(void) | ||
1085 | { | ||
1086 | return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL); | ||
1087 | } | ||
1088 | device_initcall(rbtx4938_wdt_init); | ||
1089 | |||
1090 | /* Minimum CLK support */ | ||
1091 | |||
1092 | struct 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 | } | ||
1100 | EXPORT_SYMBOL(clk_get); | ||
1101 | |||
1102 | int clk_enable(struct clk *clk) | ||
1103 | { | ||
1104 | return 0; | ||
1105 | } | ||
1106 | EXPORT_SYMBOL(clk_enable); | ||
1107 | |||
1108 | void clk_disable(struct clk *clk) | ||
1109 | { | ||
1110 | } | ||
1111 | EXPORT_SYMBOL(clk_disable); | ||
1112 | |||
1113 | unsigned long clk_get_rate(struct clk *clk) | ||
1114 | { | ||
1115 | return (unsigned long)clk; | ||
1116 | } | ||
1117 | EXPORT_SYMBOL(clk_get_rate); | ||
1118 | |||
1119 | void clk_put(struct clk *clk) | ||
1120 | { | ||
1121 | } | ||
1122 | EXPORT_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 */ | ||
21 | int __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 | |||
43 | static struct read_param { | ||
44 | int chipid; | ||
45 | int address; | ||
46 | unsigned char *buf; | ||
47 | int len; | ||
48 | } *read_param; | ||
49 | |||
50 | static 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 | |||
75 | static struct spi_driver early_seeprom_driver __initdata = { | ||
76 | .driver = { | ||
77 | .name = "at25", | ||
78 | .owner = THIS_MODULE, | ||
79 | }, | ||
80 | .probe = early_seeprom_probe, | ||
81 | }; | ||
82 | |||
83 | int __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 = ¶m; | ||
95 | ret = spi_register_driver(&early_seeprom_driver); | ||
96 | if (!ret) | ||
97 | spi_unregister_driver(&early_seeprom_driver); | ||
98 | return ret; | ||
99 | } | ||