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