aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/platforms
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/platforms
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/ppc/platforms')
-rw-r--r--arch/ppc/platforms/4xx/Kconfig247
-rw-r--r--arch/ppc/platforms/4xx/Makefile27
-rw-r--r--arch/ppc/platforms/4xx/ash.c250
-rw-r--r--arch/ppc/platforms/4xx/ash.h83
-rw-r--r--arch/ppc/platforms/4xx/bubinga.c263
-rw-r--r--arch/ppc/platforms/4xx/bubinga.h69
-rw-r--r--arch/ppc/platforms/4xx/cpci405.c84
-rw-r--r--arch/ppc/platforms/4xx/cpci405.h37
-rw-r--r--arch/ppc/platforms/4xx/ebony.c356
-rw-r--r--arch/ppc/platforms/4xx/ebony.h91
-rw-r--r--arch/ppc/platforms/4xx/ep405.c197
-rw-r--r--arch/ppc/platforms/4xx/ep405.h54
-rw-r--r--arch/ppc/platforms/4xx/ibm405ep.c143
-rw-r--r--arch/ppc/platforms/4xx/ibm405ep.h148
-rw-r--r--arch/ppc/platforms/4xx/ibm405gp.c120
-rw-r--r--arch/ppc/platforms/4xx/ibm405gp.h151
-rw-r--r--arch/ppc/platforms/4xx/ibm405gpr.c117
-rw-r--r--arch/ppc/platforms/4xx/ibm405gpr.h151
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.c164
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.h66
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.c234
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.h74
-rw-r--r--arch/ppc/platforms/4xx/ibm440sp.c131
-rw-r--r--arch/ppc/platforms/4xx/ibm440sp.h64
-rw-r--r--arch/ppc/platforms/4xx/ibmnp405h.c172
-rw-r--r--arch/ppc/platforms/4xx/ibmnp405h.h157
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.c83
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.h238
-rw-r--r--arch/ppc/platforms/4xx/ibmstbx25.c68
-rw-r--r--arch/ppc/platforms/4xx/ibmstbx25.h261
-rw-r--r--arch/ppc/platforms/4xx/luan.c387
-rw-r--r--arch/ppc/platforms/4xx/luan.h80
-rw-r--r--arch/ppc/platforms/4xx/oak.c255
-rw-r--r--arch/ppc/platforms/4xx/oak.h96
-rw-r--r--arch/ppc/platforms/4xx/oak_setup.h50
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c367
-rw-r--r--arch/ppc/platforms/4xx/ocotea.h88
-rw-r--r--arch/ppc/platforms/4xx/redwood5.c110
-rw-r--r--arch/ppc/platforms/4xx/redwood5.h54
-rw-r--r--arch/ppc/platforms/4xx/redwood6.c159
-rw-r--r--arch/ppc/platforms/4xx/redwood6.h55
-rw-r--r--arch/ppc/platforms/4xx/sycamore.c278
-rw-r--r--arch/ppc/platforms/4xx/sycamore.h67
-rw-r--r--arch/ppc/platforms/4xx/virtex-ii_pro.c60
-rw-r--r--arch/ppc/platforms/4xx/virtex-ii_pro.h99
-rw-r--r--arch/ppc/platforms/4xx/walnut.c249
-rw-r--r--arch/ppc/platforms/4xx/walnut.h72
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml300.c146
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml300.h47
-rw-r--r--arch/ppc/platforms/4xx/xparameters/xparameters_ml300.h310
-rw-r--r--arch/ppc/platforms/83xx/Makefile4
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c289
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h51
-rw-r--r--arch/ppc/platforms/85xx/Kconfig76
-rw-r--r--arch/ppc/platforms/85xx/Makefile8
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c218
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.h25
-rw-r--r--arch/ppc/platforms/85xx/mpc8555_cds.h26
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c210
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.h27
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c225
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.h50
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c467
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.h80
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c227
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.h49
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.c203
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.h55
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c355
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.h74
-rw-r--r--arch/ppc/platforms/Makefile53
-rw-r--r--arch/ppc/platforms/adir.h95
-rw-r--r--arch/ppc/platforms/adir_pci.c247
-rw-r--r--arch/ppc/platforms/adir_pic.c130
-rw-r--r--arch/ppc/platforms/adir_setup.c210
-rw-r--r--arch/ppc/platforms/apus_pci.c208
-rw-r--r--arch/ppc/platforms/apus_pci.h34
-rw-r--r--arch/ppc/platforms/apus_setup.c815
-rw-r--r--arch/ppc/platforms/bseip.h38
-rw-r--r--arch/ppc/platforms/ccm.h28
-rw-r--r--arch/ppc/platforms/chestnut.c580
-rw-r--r--arch/ppc/platforms/chestnut.h129
-rw-r--r--arch/ppc/platforms/chrp_pci.c309
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c101
-rw-r--r--arch/ppc/platforms/chrp_setup.c615
-rw-r--r--arch/ppc/platforms/chrp_smp.c98
-rw-r--r--arch/ppc/platforms/chrp_time.c194
-rw-r--r--arch/ppc/platforms/cpci690.c491
-rw-r--r--arch/ppc/platforms/cpci690.h78
-rw-r--r--arch/ppc/platforms/est8260.h35
-rw-r--r--arch/ppc/platforms/ev64260.c651
-rw-r--r--arch/ppc/platforms/ev64260.h128
-rw-r--r--arch/ppc/platforms/fads.h57
-rw-r--r--arch/ppc/platforms/gemini.h168
-rw-r--r--arch/ppc/platforms/gemini_pci.c41
-rw-r--r--arch/ppc/platforms/gemini_prom.S93
-rw-r--r--arch/ppc/platforms/gemini_serial.h41
-rw-r--r--arch/ppc/platforms/gemini_setup.c584
-rw-r--r--arch/ppc/platforms/hdpu.c1062
-rw-r--r--arch/ppc/platforms/hdpu.h82
-rw-r--r--arch/ppc/platforms/hermes.h27
-rw-r--r--arch/ppc/platforms/ip860.h36
-rw-r--r--arch/ppc/platforms/ivms8.h56
-rw-r--r--arch/ppc/platforms/k2.c613
-rw-r--r--arch/ppc/platforms/k2.h82
-rw-r--r--arch/ppc/platforms/katana.c795
-rw-r--r--arch/ppc/platforms/katana.h255
-rw-r--r--arch/ppc/platforms/lantec.h21
-rw-r--r--arch/ppc/platforms/lite5200.c236
-rw-r--r--arch/ppc/platforms/lite5200.h23
-rw-r--r--arch/ppc/platforms/lopec.c411
-rw-r--r--arch/ppc/platforms/lopec.h39
-rw-r--r--arch/ppc/platforms/lwmon.h60
-rw-r--r--arch/ppc/platforms/mbx.h117
-rw-r--r--arch/ppc/platforms/mcpn765.c527
-rw-r--r--arch/ppc/platforms/mcpn765.h122
-rw-r--r--arch/ppc/platforms/mpc5200.c53
-rw-r--r--arch/ppc/platforms/mvme5100.c349
-rw-r--r--arch/ppc/platforms/mvme5100.h91
-rw-r--r--arch/ppc/platforms/pal4.h42
-rw-r--r--arch/ppc/platforms/pal4_pci.c77
-rw-r--r--arch/ppc/platforms/pal4_serial.h39
-rw-r--r--arch/ppc/platforms/pal4_setup.c175
-rw-r--r--arch/ppc/platforms/pcore.c352
-rw-r--r--arch/ppc/platforms/pcore.h39
-rw-r--r--arch/ppc/platforms/pcu_e.h28
-rw-r--r--arch/ppc/platforms/pmac_backlight.c202
-rw-r--r--arch/ppc/platforms/pmac_cache.S325
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c571
-rw-r--r--arch/ppc/platforms/pmac_feature.c2972
-rw-r--r--arch/ppc/platforms/pmac_low_i2c.c513
-rw-r--r--arch/ppc/platforms/pmac_nvram.c584
-rw-r--r--arch/ppc/platforms/pmac_pci.c1125
-rw-r--r--arch/ppc/platforms/pmac_pic.c689
-rw-r--r--arch/ppc/platforms/pmac_pic.h11
-rw-r--r--arch/ppc/platforms/pmac_setup.c745
-rw-r--r--arch/ppc/platforms/pmac_sleep.S390
-rw-r--r--arch/ppc/platforms/pmac_smp.c640
-rw-r--r--arch/ppc/platforms/pmac_time.c292
-rw-r--r--arch/ppc/platforms/powerpmc250.c383
-rw-r--r--arch/ppc/platforms/powerpmc250.h52
-rw-r--r--arch/ppc/platforms/pplus.c917
-rw-r--r--arch/ppc/platforms/pplus.h67
-rw-r--r--arch/ppc/platforms/pq2ads.c26
-rw-r--r--arch/ppc/platforms/pq2ads.h96
-rw-r--r--arch/ppc/platforms/prep_pci.c1336
-rw-r--r--arch/ppc/platforms/prep_setup.c1181
-rw-r--r--arch/ppc/platforms/prpmc750.c364
-rw-r--r--arch/ppc/platforms/prpmc750.h95
-rw-r--r--arch/ppc/platforms/prpmc800.c477
-rw-r--r--arch/ppc/platforms/prpmc800.h82
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c1452
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.h434
-rw-r--r--arch/ppc/platforms/residual.c1034
-rw-r--r--arch/ppc/platforms/rpx8260.h81
-rw-r--r--arch/ppc/platforms/rpxclassic.h119
-rw-r--r--arch/ppc/platforms/rpxhiox.h41
-rw-r--r--arch/ppc/platforms/rpxlite.h96
-rw-r--r--arch/ppc/platforms/sandpoint.c742
-rw-r--r--arch/ppc/platforms/sandpoint.h80
-rw-r--r--arch/ppc/platforms/sbc82xx.c259
-rw-r--r--arch/ppc/platforms/sbc82xx.h36
-rw-r--r--arch/ppc/platforms/sbs8260.h28
-rw-r--r--arch/ppc/platforms/spd8xx.h92
-rw-r--r--arch/ppc/platforms/spruce.c325
-rw-r--r--arch/ppc/platforms/spruce.h71
-rw-r--r--arch/ppc/platforms/tqm8260.h23
-rw-r--r--arch/ppc/platforms/tqm8260_setup.c44
-rw-r--r--arch/ppc/platforms/tqm8xx.h179
169 files changed, 41379 insertions, 0 deletions
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
new file mode 100644
index 000000000000..a0612a86455a
--- /dev/null
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -0,0 +1,247 @@
1config 4xx
2 bool
3 depends on 40x || 44x
4 default y
5
6menu "IBM 4xx options"
7 depends on 4xx
8
9choice
10 prompt "Machine Type"
11 depends on 40x
12 default WALNUT
13
14config ASH
15 bool "Ash"
16 help
17 This option enables support for the IBM NP405H evaluation board.
18
19config BUBINGA
20 bool "Bubinga"
21 help
22 This option enables support for the IBM 405EP evaluation board.
23
24config CPCI405
25 bool "CPCI405"
26 help
27 This option enables support for the CPCI405 board.
28
29config EP405
30 bool "EP405/EP405PC"
31 help
32 This option enables support for the EP405/EP405PC boards.
33
34config OAK
35 bool "Oak"
36 help
37 This option enables support for the IBM 403GCX evaluation board.
38
39config REDWOOD_5
40 bool "Redwood-5"
41 help
42 This option enables support for the IBM STB04 evaluation board.
43
44config REDWOOD_6
45 bool "Redwood-6"
46 help
47 This option enables support for the IBM STBx25xx evaluation board.
48
49config SYCAMORE
50 bool "Sycamore"
51 help
52 This option enables support for the IBM PPC405GPr evaluation board.
53
54config WALNUT
55 bool "Walnut"
56 help
57 This option enables support for the IBM PPC405GP evaluation board.
58
59config XILINX_ML300
60 bool "Xilinx-ML300"
61 help
62 This option enables support for the Xilinx ML300 evaluation board.
63
64endchoice
65
66choice
67 prompt "Machine Type"
68 depends on 44x
69 default EBONY
70
71config EBONY
72 bool "Ebony"
73 help
74 This option enables support for the IBM PPC440GP evaluation board.
75
76config LUAN
77 bool "Luan"
78 help
79 This option enables support for the IBM PPC440SP evaluation board.
80
81config OCOTEA
82 bool "Ocotea"
83 help
84 This option enables support for the IBM PPC440GX evaluation board.
85
86endchoice
87
88config EP405PC
89 bool "EP405PC Support"
90 depends on EP405
91
92
93# It's often necessary to know the specific 4xx processor type.
94# Fortunately, it is impled (so far) from the board type, so we
95# don't need to ask more redundant questions.
96config NP405H
97 bool
98 depends on ASH
99 default y
100
101config 440GP
102 bool
103 depends on EBONY
104 default y
105
106config 440GX
107 bool
108 depends on OCOTEA
109 default y
110
111config 440SP
112 bool
113 depends on LUAN
114 default y
115
116config 440
117 bool
118 depends on 440GP || 440SP
119 default y
120
121config 440A
122 bool
123 depends on 440GX
124 default y
125
126# All 405-based cores up until the 405GPR and 405EP have this errata.
127config IBM405_ERR77
128 bool
129 depends on 40x && !403GCX && !405GPR
130 default y
131
132# All 40x-based cores, up until the 405GPR and 405EP have this errata.
133config IBM405_ERR51
134 bool
135 depends on 40x && !405GPR
136 default y
137
138config BOOKE
139 bool
140 depends on 44x
141 default y
142
143config IBM_OCP
144 bool
145 depends on ASH || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
146 default y
147
148config XILINX_OCP
149 bool
150 depends on XILINX_ML300
151 default y
152
153config IBM_EMAC4
154 bool
155 depends on 440GX || 440SP
156 default y
157
158config BIOS_FIXUP
159 bool
160 depends on BUBINGA || EP405 || SYCAMORE || WALNUT
161 default y
162
163config 403GCX
164 bool
165 depends OAK
166 default y
167
168config 405EP
169 bool
170 depends on BUBINGA
171 default y
172
173config 405GP
174 bool
175 depends on CPCI405 || EP405 || WALNUT
176 default y
177
178config 405GPR
179 bool
180 depends on SYCAMORE
181 default y
182
183config VIRTEX_II_PRO
184 bool
185 depends on XILINX_ML300
186 default y
187
188config STB03xxx
189 bool
190 depends on REDWOOD_5 || REDWOOD_6
191 default y
192
193config EMBEDDEDBOOT
194 bool
195 depends on EP405 || XILINX_ML300
196 default y
197
198config IBM_OPENBIOS
199 bool
200 depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
201 default y
202
203config PPC4xx_DMA
204 bool "PPC4xx DMA controller support"
205 depends on 4xx
206
207config PPC4xx_EDMA
208 bool
209 depends on !STB03xxx && PPC4xx_DMA
210 default y
211
212config PPC_GEN550
213 bool
214 depends on 4xx
215 default y
216
217config PM
218 bool "Power Management support (EXPERIMENTAL)"
219 depends on 4xx && EXPERIMENTAL
220
221choice
222 prompt "TTYS0 device and default console"
223 depends on 40x
224 default UART0_TTYS0
225
226config UART0_TTYS0
227 bool "UART0"
228
229config UART0_TTYS1
230 bool "UART1"
231
232endchoice
233
234config SERIAL_SICC
235 bool "SICC Serial port support"
236 depends on STB03xxx
237
238config UART1_DFLT_CONSOLE
239 bool
240 depends on SERIAL_SICC && UART0_TTYS1
241 default y
242
243config SERIAL_SICC_CONSOLE
244 bool
245 depends on SERIAL_SICC && UART0_TTYS1
246 default y
247endmenu
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
new file mode 100644
index 000000000000..ea470c6adbb6
--- /dev/null
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -0,0 +1,27 @@
1#
2# Makefile for the PowerPC 4xx linux kernel.
3
4obj-$(CONFIG_ASH) += ash.o
5obj-$(CONFIG_CPCI405) += cpci405.o
6obj-$(CONFIG_EBONY) += ebony.o
7obj-$(CONFIG_EP405) += ep405.o
8obj-$(CONFIG_BUBINGA) += bubinga.o
9obj-$(CONFIG_LUAN) += luan.o
10obj-$(CONFIG_OAK) += oak.o
11obj-$(CONFIG_OCOTEA) += ocotea.o
12obj-$(CONFIG_REDWOOD_5) += redwood5.o
13obj-$(CONFIG_REDWOOD_6) += redwood6.o
14obj-$(CONFIG_SYCAMORE) += sycamore.o
15obj-$(CONFIG_WALNUT) += walnut.o
16obj-$(CONFIG_XILINX_ML300) += xilinx_ml300.o
17
18obj-$(CONFIG_405GP) += ibm405gp.o
19obj-$(CONFIG_REDWOOD_5) += ibmstb4.o
20obj-$(CONFIG_NP405H) += ibmnp405h.o
21obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o
22obj-$(CONFIG_440GP) += ibm440gp.o
23obj-$(CONFIG_440GX) += ibm440gx.o
24obj-$(CONFIG_440SP) += ibm440sp.o
25obj-$(CONFIG_405EP) += ibm405ep.o
26obj-$(CONFIG_405GPR) += ibm405gpr.o
27obj-$(CONFIG_VIRTEX_II_PRO) += virtex-ii_pro.o
diff --git a/arch/ppc/platforms/4xx/ash.c b/arch/ppc/platforms/4xx/ash.c
new file mode 100644
index 000000000000..ce2911793716
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ash.c
@@ -0,0 +1,250 @@
1/*
2 * arch/ppc/platforms/4xx/ash.c
3 *
4 * Support for the IBM NP405H ash eval board
5 *
6 * Author: Armin Kuster <akuster@mvista.com>
7 *
8 * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/pagemap.h>
16#include <linux/pci.h>
17
18#include <asm/machdep.h>
19#include <asm/pci-bridge.h>
20#include <asm/io.h>
21#include <asm/ocp.h>
22#include <asm/ibm_ocp_pci.h>
23#include <asm/todc.h>
24
25#ifdef DEBUG
26#define DBG(x...) printk(x)
27#else
28#define DBG(x...)
29#endif
30
31void *ash_rtc_base;
32
33/* Some IRQs unique to Walnut.
34 * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
35 */
36int __init
37ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
38{
39 static char pci_irq_table[][4] =
40 /*
41 * PCI IDSEL/INTPIN->INTLINE
42 * A B C D
43 */
44 {
45 {24, 24, 24, 24}, /* IDSEL 1 - PCI slot 1 */
46 {25, 25, 25, 25}, /* IDSEL 2 - PCI slot 2 */
47 {26, 26, 26, 26}, /* IDSEL 3 - PCI slot 3 */
48 {27, 27, 27, 27}, /* IDSEL 4 - PCI slot 4 */
49 };
50
51 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
52 return PCI_IRQ_TABLE_LOOKUP;
53}
54
55void __init
56ash_setup_arch(void)
57{
58 ppc4xx_setup_arch();
59
60 ibm_ocp_set_emac(0, 3);
61
62#ifdef CONFIG_DEBUG_BRINGUP
63 int i;
64 printk("\n");
65 printk("machine\t: %s\n", PPC4xx_MACHINE_NAME);
66 printk("\n");
67 printk("bi_s_version\t %s\n", bip->bi_s_version);
68 printk("bi_r_version\t %s\n", bip->bi_r_version);
69 printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,
70 bip->bi_memsize / (1024 * 1000));
71 for (i = 0; i < EMAC_NUMS; i++) {
72 printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", i,
73 bip->bi_enetaddr[i][0], bip->bi_enetaddr[i][1],
74 bip->bi_enetaddr[i][2], bip->bi_enetaddr[i][3],
75 bip->bi_enetaddr[i][4], bip->bi_enetaddr[i][5]);
76 }
77 printk("bi_pci_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0,
78 bip->bi_pci_enetaddr[0], bip->bi_pci_enetaddr[1],
79 bip->bi_pci_enetaddr[2], bip->bi_pci_enetaddr[3],
80 bip->bi_pci_enetaddr[4], bip->bi_pci_enetaddr[5]);
81
82 printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n",
83 bip->bi_intfreq, bip->bi_intfreq / 1000000);
84
85 printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n",
86 bip->bi_busfreq, bip->bi_busfreq / 1000000);
87 printk("bi_pci_busfreq\t 0x%8.8x\t pci bus clock:\t %dMHz\n",
88 bip->bi_pci_busfreq, bip->bi_pci_busfreq / 1000000);
89
90 printk("\n");
91#endif
92 /* RTC step for ash */
93 ash_rtc_base = (void *) ASH_RTC_VADDR;
94 TODC_INIT(TODC_TYPE_DS1743, ash_rtc_base, ash_rtc_base, ash_rtc_base,
95 8);
96}
97
98void __init
99bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
100{
101 /*
102 * Expected PCI mapping:
103 *
104 * PLB addr PCI memory addr
105 * --------------------- ---------------------
106 * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
107 * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
108 *
109 * PLB addr PCI io addr
110 * --------------------- ---------------------
111 * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
112 *
113 * The following code is simplified by assuming that the bootrom
114 * has been well behaved in following this mapping.
115 */
116
117#ifdef DEBUG
118 int i;
119
120 printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
121 printk("PCI bridge regs before fixup \n");
122 for (i = 0; i <= 2; i++) {
123 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
124 printk(" pmm%dla\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
125 printk(" pmm%dpcila\t0x%x\n", i,
126 in_le32(&(pcip->pmm[i].pcila)));
127 printk(" pmm%dpciha\t0x%x\n", i,
128 in_le32(&(pcip->pmm[i].pciha)));
129 }
130 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
131 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
132 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
133 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
134 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
135 early_read_config_dword(hose, hose->first_busno,
136 PCI_FUNC(hose->first_busno), bar,
137 &bar_response);
138 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
139 hose->first_busno, PCI_SLOT(hose->first_busno),
140 PCI_FUNC(hose->first_busno), bar, bar_response);
141 }
142
143#endif
144 if (ppc_md.progress)
145 ppc_md.progress("bios_fixup(): enter", 0x800);
146
147 /* added for IBM boot rom version 1.15 bios bar changes -AK */
148
149 /* Disable region first */
150 out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
151 /* PLB starting addr, PCI: 0x80000000 */
152 out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
153 /* PCI start addr, 0x80000000 */
154 out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
155 /* 512MB range of PLB to PCI */
156 out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
157 /* Enable no pre-fetch, enable region */
158 out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
159 (PPC405_PCI_UPPER_MEM -
160 PPC405_PCI_MEM_BASE)) | 0x01));
161
162 /* Disable region one */
163 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
164 out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
165 out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
166 out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
167 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
168
169 /* Disable region two */
170 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
171 out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
172 out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
173 out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
174 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
175
176 /* Enable PTM1 and PTM2, mapped to PLB address 0. */
177
178 out_le32((void *) &(pcip->ptm1la), 0x00000000);
179 out_le32((void *) &(pcip->ptm1ms), 0x00000001);
180 out_le32((void *) &(pcip->ptm2la), 0x00000000);
181 out_le32((void *) &(pcip->ptm2ms), 0x00000001);
182
183 /* Write zero to PTM1 BAR. */
184
185 early_write_config_dword(hose, hose->first_busno,
186 PCI_FUNC(hose->first_busno),
187 PCI_BASE_ADDRESS_1,
188 0x00000000);
189
190 /* Disable PTM2 (unused) */
191
192 out_le32((void *) &(pcip->ptm2la), 0x00000000);
193 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
194
195 /* end work arround */
196 if (ppc_md.progress)
197 ppc_md.progress("bios_fixup(): done", 0x800);
198
199#ifdef DEBUG
200 printk("PCI bridge regs after fixup \n");
201 for (i = 0; i <= 2; i++) {
202 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
203 printk(" pmm%dla\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
204 printk(" pmm%dpcila\t0x%x\n", i,
205 in_le32(&(pcip->pmm[i].pcila)));
206 printk(" pmm%dpciha\t0x%x\n", i,
207 in_le32(&(pcip->pmm[i].pciha)));
208 }
209 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
210 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
211 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
212 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
213
214 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
215 early_read_config_dword(hose, hose->first_busno,
216 PCI_FUNC(hose->first_busno), bar,
217 &bar_response);
218 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
219 hose->first_busno, PCI_SLOT(hose->first_busno),
220 PCI_FUNC(hose->first_busno), bar, bar_response);
221 }
222
223
224#endif
225}
226
227void __init
228ash_map_io(void)
229{
230 ppc4xx_map_io();
231 io_block_mapping(ASH_RTC_VADDR, ASH_RTC_PADDR, ASH_RTC_SIZE, _PAGE_IO);
232}
233
234void __init
235platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
236 unsigned long r6, unsigned long r7)
237{
238 ppc4xx_init(r3, r4, r5, r6, r7);
239
240 ppc_md.setup_arch = ash_setup_arch;
241 ppc_md.setup_io_mappings = ash_map_io;
242
243#ifdef CONFIG_PPC_RTC
244 ppc_md.time_init = todc_time_init;
245 ppc_md.set_rtc_time = todc_set_rtc_time;
246 ppc_md.get_rtc_time = todc_get_rtc_time;
247 ppc_md.nvram_read_val = todc_direct_read_val;
248 ppc_md.nvram_write_val = todc_direct_write_val;
249#endif
250}
diff --git a/arch/ppc/platforms/4xx/ash.h b/arch/ppc/platforms/4xx/ash.h
new file mode 100644
index 000000000000..5f7448ea418d
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ash.h
@@ -0,0 +1,83 @@
1/*
2 * arch/ppc/platforms/4xx/ash.h
3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC
5 * Ash eval board.
6 *
7 * Author: Armin Kuster <akuster@mvista.com>
8 *
9 * 2000-2002 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_ASH_H__
17#define __ASM_ASH_H__
18#include <platforms/4xx/ibmnp405h.h>
19
20#ifndef __ASSEMBLY__
21/*
22 * Data structure defining board information maintained by the boot
23 * ROM on IBM's "Ash" evaluation board. An effort has been made to
24 * keep the field names consistent with the 8xx 'bd_t' board info
25 * structures.
26 */
27
28typedef struct board_info {
29 unsigned char bi_s_version[4]; /* Version of this structure */
30 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
31 unsigned int bi_memsize; /* DRAM installed, in bytes */
32 unsigned char bi_enetaddr[4][6]; /* Local Ethernet MAC address */
33 unsigned char bi_pci_enetaddr[6];
34 unsigned int bi_intfreq; /* Processor speed, in Hz */
35 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
36 unsigned int bi_pci_busfreq; /* PCI speed in Hz */
37} bd_t;
38
39/* Some 4xx parts use a different timebase frequency from the internal clock.
40*/
41#define bi_tbfreq bi_intfreq
42
43/* Memory map for the IBM "Ash" NP405H evaluation board.
44 */
45
46extern void *ash_rtc_base;
47#define ASH_RTC_PADDR ((uint)0xf0000000)
48#define ASH_RTC_VADDR ASH_RTC_PADDR
49#define ASH_RTC_SIZE ((uint)8*1024)
50
51
52/* Early initialization address mapping for block_io.
53 * Standard 405GP map.
54 */
55#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE)
56#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR
57#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
58#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR)
59#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR
60#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
61#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000)
62#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR
63#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
64#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
65#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
66#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
67
68#define NR_BOARD_IRQS 32
69
70#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
71#define BASE_BAUD 201600
72#else
73#define BASE_BAUD 691200
74#endif
75
76#define PPC4xx_MACHINE_NAME "IBM NP405H Ash"
77
78extern char pci_irq_table[][4];
79
80
81#endif /* !__ASSEMBLY__ */
82#endif /* __ASM_ASH_H__ */
83#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
new file mode 100644
index 000000000000..3678abf86313
--- /dev/null
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -0,0 +1,263 @@
1/*
2 * Support for IBM PPC 405EP evaluation board (Bubinga).
3 *
4 * Author: SAW (IBM), derived from walnut.c.
5 * Maintained by MontaVista Software <source@mvista.com>
6 *
7 * 2003 (c) MontaVista Softare 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
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/smp.h>
16#include <linux/threads.h>
17#include <linux/param.h>
18#include <linux/string.h>
19#include <linux/blkdev.h>
20#include <linux/pci.h>
21#include <linux/rtc.h>
22#include <linux/tty.h>
23#include <linux/serial.h>
24#include <linux/serial_core.h>
25
26#include <asm/system.h>
27#include <asm/pci-bridge.h>
28#include <asm/processor.h>
29#include <asm/machdep.h>
30#include <asm/page.h>
31#include <asm/time.h>
32#include <asm/io.h>
33#include <asm/todc.h>
34#include <asm/kgdb.h>
35#include <asm/ocp.h>
36#include <asm/ibm_ocp_pci.h>
37
38#include <platforms/4xx/ibm405ep.h>
39
40#undef DEBUG
41
42#ifdef DEBUG
43#define DBG(x...) printk(x)
44#else
45#define DBG(x...)
46#endif
47
48extern bd_t __res;
49
50void *bubinga_rtc_base;
51
52/* Some IRQs unique to the board
53 * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
54 */
55int __init
56ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
57{
58 static char pci_irq_table[][4] =
59 /*
60 * PCI IDSEL/INTPIN->INTLINE
61 * A B C D
62 */
63 {
64 {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */
65 {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */
66 {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */
67 {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */
68 };
69
70 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
71 return PCI_IRQ_TABLE_LOOKUP;
72};
73
74/* The serial clock for the chip is an internal clock determined by
75 * different clock speeds/dividers.
76 * Calculate the proper input baud rate and setup the serial driver.
77 */
78static void __init
79bubinga_early_serial_map(void)
80{
81 u32 uart_div;
82 int uart_clock;
83 struct uart_port port;
84
85 /* Calculate the serial clock input frequency
86 *
87 * The base baud is the PLL OUTA (provided in the board info
88 * structure) divided by the external UART Divisor, divided
89 * by 16.
90 */
91 uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
92 uart_clock = __res.bi_pllouta_freq / uart_div;
93
94 /* Setup serial port access */
95 memset(&port, 0, sizeof(port));
96 port.membase = (void*)ACTING_UART0_IO_BASE;
97 port.irq = ACTING_UART0_INT;
98 port.uartclk = uart_clock;
99 port.regshift = 0;
100 port.iotype = SERIAL_IO_MEM;
101 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
102 port.line = 0;
103
104 if (early_serial_setup(&port) != 0) {
105 printk("Early serial init of port 0 failed\n");
106 }
107
108 port.membase = (void*)ACTING_UART1_IO_BASE;
109 port.irq = ACTING_UART1_INT;
110 port.line = 1;
111
112 if (early_serial_setup(&port) != 0) {
113 printk("Early serial init of port 1 failed\n");
114 }
115}
116
117void __init
118bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
119{
120
121 unsigned int bar_response, bar;
122 /*
123 * Expected PCI mapping:
124 *
125 * PLB addr PCI memory addr
126 * --------------------- ---------------------
127 * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
128 * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
129 *
130 * PLB addr PCI io addr
131 * --------------------- ---------------------
132 * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
133 *
134 * The following code is simplified by assuming that the bootrom
135 * has been well behaved in following this mapping.
136 */
137
138#ifdef DEBUG
139 int i;
140
141 printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
142 printk("PCI bridge regs before fixup \n");
143 for (i = 0; i <= 3; i++) {
144 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
145 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
146 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
147 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
148 }
149 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
150 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
151 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
152 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
153
154#endif
155
156 /* added for IBM boot rom version 1.15 bios bar changes -AK */
157
158 /* Disable region first */
159 out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
160 /* PLB starting addr, PCI: 0x80000000 */
161 out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
162 /* PCI start addr, 0x80000000 */
163 out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
164 /* 512MB range of PLB to PCI */
165 out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
166 /* Enable no pre-fetch, enable region */
167 out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
168 (PPC405_PCI_UPPER_MEM -
169 PPC405_PCI_MEM_BASE)) | 0x01));
170
171 /* Disable region one */
172 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
173 out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
174 out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
175 out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
176 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
177 out_le32((void *) &(pcip->ptm1ms), 0x00000001);
178
179 /* Disable region two */
180 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
181 out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
182 out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
183 out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
184 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
185 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
186 out_le32((void *) &(pcip->ptm2la), 0x00000000);
187
188 /* Zero config bars */
189 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
190 early_write_config_dword(hose, hose->first_busno,
191 PCI_FUNC(hose->first_busno), bar,
192 0x00000000);
193 early_read_config_dword(hose, hose->first_busno,
194 PCI_FUNC(hose->first_busno), bar,
195 &bar_response);
196 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
197 hose->first_busno, PCI_SLOT(hose->first_busno),
198 PCI_FUNC(hose->first_busno), bar, bar_response);
199 }
200 /* end work arround */
201
202#ifdef DEBUG
203 printk("PCI bridge regs after fixup \n");
204 for (i = 0; i <= 3; i++) {
205 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
206 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
207 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
208 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
209 }
210 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
211 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
212 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
213 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
214
215#endif
216}
217
218void __init
219bubinga_setup_arch(void)
220{
221 ppc4xx_setup_arch();
222
223 ibm_ocp_set_emac(0, 1);
224
225 bubinga_early_serial_map();
226
227 /* RTC step for the evb405ep */
228 bubinga_rtc_base = (void *) BUBINGA_RTC_VADDR;
229 TODC_INIT(TODC_TYPE_DS1743, bubinga_rtc_base, bubinga_rtc_base,
230 bubinga_rtc_base, 8);
231 /* Identify the system */
232 printk("IBM Bubinga port (MontaVista Software, Inc. <source@mvista.com>)\n");
233}
234
235void __init
236bubinga_map_io(void)
237{
238 ppc4xx_map_io();
239 io_block_mapping(BUBINGA_RTC_VADDR,
240 BUBINGA_RTC_PADDR, BUBINGA_RTC_SIZE, _PAGE_IO);
241}
242
243void __init
244platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
245 unsigned long r6, unsigned long r7)
246{
247 ppc4xx_init(r3, r4, r5, r6, r7);
248
249 ppc_md.setup_arch = bubinga_setup_arch;
250 ppc_md.setup_io_mappings = bubinga_map_io;
251
252#ifdef CONFIG_GEN_RTC
253 ppc_md.time_init = todc_time_init;
254 ppc_md.set_rtc_time = todc_set_rtc_time;
255 ppc_md.get_rtc_time = todc_get_rtc_time;
256 ppc_md.nvram_read_val = todc_direct_read_val;
257 ppc_md.nvram_write_val = todc_direct_write_val;
258#endif
259#ifdef CONFIG_KGDB
260 ppc_md.early_serial_map = bubinga_early_serial_map;
261#endif
262}
263
diff --git a/arch/ppc/platforms/4xx/bubinga.h b/arch/ppc/platforms/4xx/bubinga.h
new file mode 100644
index 000000000000..b1df856f8e22
--- /dev/null
+++ b/arch/ppc/platforms/4xx/bubinga.h
@@ -0,0 +1,69 @@
1/*
2 * Support for IBM PPC 405EP evaluation board (Bubinga).
3 *
4 * Author: SAW (IBM), derived from walnut.h.
5 * Maintained by MontaVista Software <source@mvista.com>
6 *
7 * 2003 (c) MontaVista Softare 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
13#ifdef __KERNEL__
14#ifndef __BUBINGA_H__
15#define __BUBINGA_H__
16
17/* 405EP */
18#include <platforms/4xx/ibm405ep.h>
19
20#ifndef __ASSEMBLY__
21/*
22 * Data structure defining board information maintained by the boot
23 * ROM on IBM's evaluation board. An effort has been made to
24 * keep the field names consistent with the 8xx 'bd_t' board info
25 * structures.
26 */
27
28typedef struct board_info {
29 unsigned char bi_s_version[4]; /* Version of this structure */
30 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
31 unsigned int bi_memsize; /* DRAM installed, in bytes */
32 unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */ unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
33 unsigned int bi_intfreq; /* Processor speed, in Hz */
34 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
35 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
36 unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
37 unsigned int bi_pllouta_freq; /* PLL OUTA speed, in Hz */
38} bd_t;
39
40/* Some 4xx parts use a different timebase frequency from the internal clock.
41*/
42#define bi_tbfreq bi_intfreq
43
44
45/* Memory map for the Bubinga board.
46 * Generic 4xx plus RTC.
47 */
48
49extern void *bubinga_rtc_base;
50#define BUBINGA_RTC_PADDR ((uint)0xf0000000)
51#define BUBINGA_RTC_VADDR BUBINGA_RTC_PADDR
52#define BUBINGA_RTC_SIZE ((uint)8*1024)
53
54/* The UART clock is based off an internal clock -
55 * define BASE_BAUD based on the internal clock and divider(s).
56 * Since BASE_BAUD must be a constant, we will initialize it
57 * using clock/divider values which OpenBIOS initializes
58 * for typical configurations at various CPU speeds.
59 * The base baud is calculated as (FWDA / EXT UART DIV / 16)
60 */
61#define BASE_BAUD 0
62
63#define BUBINGA_FPGA_BASE 0xF0300000
64
65#define PPC4xx_MACHINE_NAME "IBM Bubinga"
66
67#endif /* !__ASSEMBLY__ */
68#endif /* __BUBINGA_H__ */
69#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/cpci405.c b/arch/ppc/platforms/4xx/cpci405.c
new file mode 100644
index 000000000000..ff966773a0bf
--- /dev/null
+++ b/arch/ppc/platforms/4xx/cpci405.c
@@ -0,0 +1,84 @@
1/*
2 * arch/ppc/platforms/cpci405.c
3 *
4 * Board setup routines for the esd CPCI-405 cPCI Board.
5 *
6 * Author: Stefan Roese
7 * stefan.roese@esd-electronics.com
8 *
9 * Copyright 2001 esd electronic system design - hannover germany
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 */
17
18#include <linux/config.h>
19#include <linux/init.h>
20#include <linux/pci.h>
21#include <asm/system.h>
22#include <asm/pci-bridge.h>
23#include <asm/machdep.h>
24#include <asm/todc.h>
25#include <asm/ocp.h>
26
27void *cpci405_nvram;
28
29/*
30 * Some IRQs unique to CPCI-405.
31 */
32int __init
33ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
34{
35 static char pci_irq_table[][4] =
36 /*
37 * PCI IDSEL/INTPIN->INTLINE
38 * A B C D
39 */
40 {
41 {28, 28, 28, 28}, /* IDSEL 15 - cPCI slot 8 */
42 {29, 29, 29, 29}, /* IDSEL 16 - cPCI slot 7 */
43 {30, 30, 30, 30}, /* IDSEL 17 - cPCI slot 6 */
44 {27, 27, 27, 27}, /* IDSEL 18 - cPCI slot 5 */
45 {28, 28, 28, 28}, /* IDSEL 19 - cPCI slot 4 */
46 {29, 29, 29, 29}, /* IDSEL 20 - cPCI slot 3 */
47 {30, 30, 30, 30}, /* IDSEL 21 - cPCI slot 2 */
48 };
49 const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4;
50 return PCI_IRQ_TABLE_LOOKUP;
51};
52
53void __init
54cpci405_setup_arch(void)
55{
56 ppc4xx_setup_arch();
57
58 ibm_ocp_set_emac(0, 0);
59
60 TODC_INIT(TODC_TYPE_MK48T35, cpci405_nvram, cpci405_nvram, cpci405_nvram, 8);
61}
62
63void __init
64cpci405_map_io(void)
65{
66 ppc4xx_map_io();
67 cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE);
68}
69
70void __init
71platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
72 unsigned long r6, unsigned long r7)
73{
74 ppc4xx_init(r3, r4, r5, r6, r7);
75
76 ppc_md.setup_arch = cpci405_setup_arch;
77 ppc_md.setup_io_mappings = cpci405_map_io;
78
79 ppc_md.time_init = todc_time_init;
80 ppc_md.set_rtc_time = todc_set_rtc_time;
81 ppc_md.get_rtc_time = todc_get_rtc_time;
82 ppc_md.nvram_read_val = todc_direct_read_val;
83 ppc_md.nvram_write_val = todc_direct_write_val;
84}
diff --git a/arch/ppc/platforms/4xx/cpci405.h b/arch/ppc/platforms/4xx/cpci405.h
new file mode 100644
index 000000000000..e27f7cb650d8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/cpci405.h
@@ -0,0 +1,37 @@
1/*
2 * CPCI-405 board specific definitions
3 *
4 * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com)
5 */
6
7#ifdef __KERNEL__
8#ifndef __ASM_CPCI405_H__
9#define __ASM_CPCI405_H__
10
11#include <linux/config.h>
12
13/* We have a 405GP core */
14#include <platforms/4xx/ibm405gp.h>
15
16#include <asm/ppcboot.h>
17
18#ifndef __ASSEMBLY__
19/* Some 4xx parts use a different timebase frequency from the internal clock.
20*/
21#define bi_tbfreq bi_intfreq
22
23/* Map for the NVRAM space */
24#define CPCI405_NVRAM_PADDR ((uint)0xf0200000)
25#define CPCI405_NVRAM_SIZE ((uint)32*1024)
26
27#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
28#define BASE_BAUD 201600
29#else
30#define BASE_BAUD 691200
31#endif
32
33#define PPC4xx_MACHINE_NAME "esd CPCI-405"
34
35#endif /* !__ASSEMBLY__ */
36#endif /* __ASM_CPCI405_H__ */
37#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
new file mode 100644
index 000000000000..f63bca83e757
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -0,0 +1,356 @@
1/*
2 * arch/ppc/platforms/4xx/ebony.c
3 *
4 * Ebony board specific routines
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 * Copyright 2002-2005 MontaVista Software Inc.
8 *
9 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
10 * Copyright (c) 2003, 2004 Zultys Technologies
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
18#include <linux/config.h>
19#include <linux/stddef.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/errno.h>
23#include <linux/reboot.h>
24#include <linux/pci.h>
25#include <linux/kdev_t.h>
26#include <linux/types.h>
27#include <linux/major.h>
28#include <linux/blkdev.h>
29#include <linux/console.h>
30#include <linux/delay.h>
31#include <linux/ide.h>
32#include <linux/initrd.h>
33#include <linux/irq.h>
34#include <linux/seq_file.h>
35#include <linux/root_dev.h>
36#include <linux/tty.h>
37#include <linux/serial.h>
38#include <linux/serial_core.h>
39
40#include <asm/system.h>
41#include <asm/pgtable.h>
42#include <asm/page.h>
43#include <asm/dma.h>
44#include <asm/io.h>
45#include <asm/machdep.h>
46#include <asm/ocp.h>
47#include <asm/pci-bridge.h>
48#include <asm/time.h>
49#include <asm/todc.h>
50#include <asm/bootinfo.h>
51#include <asm/ppc4xx_pic.h>
52#include <asm/ppcboot.h>
53
54#include <syslib/gen550.h>
55#include <syslib/ibm440gp_common.h>
56
57/*
58 * This is a horrible kludge, we eventually need to abstract this
59 * generic PHY stuff, so the standard phy mode defines can be
60 * easily used from arch code.
61 */
62#include "../../../../drivers/net/ibm_emac/ibm_emac_phy.h"
63
64bd_t __res;
65
66static struct ibm44x_clocks clocks __initdata;
67
68/*
69 * Ebony external IRQ triggering/polarity settings
70 */
71unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
72 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: PCI slot 0 */
73 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ1: PCI slot 1 */
74 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 2 */
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 3 */
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ4: IRDA */
77 (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ5: SMI pushbutton */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ6: PHYs */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ7: AUX */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ10: EXT */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ11: EXT */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ12: EXT */
85};
86
87static void __init
88ebony_calibrate_decr(void)
89{
90 unsigned int freq;
91
92 /*
93 * Determine system clock speed
94 *
95 * If we are on Rev. B silicon, then use
96 * default external system clock. If we are
97 * on Rev. C silicon then errata forces us to
98 * use the internal clock.
99 */
100 switch (PVR_REV(mfspr(SPRN_PVR))) {
101 case PVR_REV(PVR_440GP_RB):
102 freq = EBONY_440GP_RB_SYSCLK;
103 break;
104 case PVR_REV(PVR_440GP_RC1):
105 default:
106 freq = EBONY_440GP_RC_SYSCLK;
107 break;
108 }
109
110 ibm44x_calibrate_decr(freq);
111}
112
113static int
114ebony_show_cpuinfo(struct seq_file *m)
115{
116 seq_printf(m, "vendor\t\t: IBM\n");
117 seq_printf(m, "machine\t\t: Ebony\n");
118
119 return 0;
120}
121
122static inline int
123ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
124{
125 static char pci_irq_table[][4] =
126 /*
127 * PCI IDSEL/INTPIN->INTLINE
128 * A B C D
129 */
130 {
131 { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */
132 { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */
133 { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */
134 { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */
135 };
136
137 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
138 return PCI_IRQ_TABLE_LOOKUP;
139}
140
141#define PCIX_WRITEL(value, offset) \
142 (writel(value, pcix_reg_base + offset))
143
144/*
145 * FIXME: This is only here to "make it work". This will move
146 * to a ibm_pcix.c which will contain a generic IBM PCIX bridge
147 * configuration library. -Matt
148 */
149static void __init
150ebony_setup_pcix(void)
151{
152 void *pcix_reg_base;
153
154 pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
155
156 /* Disable all windows */
157 PCIX_WRITEL(0, PCIX0_POM0SA);
158 PCIX_WRITEL(0, PCIX0_POM1SA);
159 PCIX_WRITEL(0, PCIX0_POM2SA);
160 PCIX_WRITEL(0, PCIX0_PIM0SA);
161 PCIX_WRITEL(0, PCIX0_PIM1SA);
162 PCIX_WRITEL(0, PCIX0_PIM2SA);
163
164 /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */
165 PCIX_WRITEL(0x00000003, PCIX0_POM0LAH);
166 PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
167 PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
168 PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
169 PCIX_WRITEL(0x80000001, PCIX0_POM0SA);
170
171 /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
172 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
173 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
174 PCIX_WRITEL(0x80000007, PCIX0_PIM0SA);
175
176 eieio();
177}
178
179static void __init
180ebony_setup_hose(void)
181{
182 struct pci_controller *hose;
183
184 /* Configure windows on the PCI-X host bridge */
185 ebony_setup_pcix();
186
187 hose = pcibios_alloc_controller();
188
189 if (!hose)
190 return;
191
192 hose->first_busno = 0;
193 hose->last_busno = 0xff;
194
195 hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET;
196
197 pci_init_resource(&hose->io_resource,
198 EBONY_PCI_LOWER_IO,
199 EBONY_PCI_UPPER_IO,
200 IORESOURCE_IO,
201 "PCI host bridge");
202
203 pci_init_resource(&hose->mem_resources[0],
204 EBONY_PCI_LOWER_MEM,
205 EBONY_PCI_UPPER_MEM,
206 IORESOURCE_MEM,
207 "PCI host bridge");
208
209 hose->io_space.start = EBONY_PCI_LOWER_IO;
210 hose->io_space.end = EBONY_PCI_UPPER_IO;
211 hose->mem_space.start = EBONY_PCI_LOWER_MEM;
212 hose->mem_space.end = EBONY_PCI_UPPER_MEM;
213 isa_io_base =
214 (unsigned long)ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE);
215 hose->io_base_virt = (void *)isa_io_base;
216
217 setup_indirect_pci(hose,
218 EBONY_PCI_CFGA_PLB32,
219 EBONY_PCI_CFGD_PLB32);
220 hose->set_cfg_type = 1;
221
222 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
223
224 ppc_md.pci_swizzle = common_swizzle;
225 ppc_md.pci_map_irq = ebony_map_irq;
226}
227
228TODC_ALLOC();
229
230static void __init
231ebony_early_serial_map(void)
232{
233 struct uart_port port;
234
235 /* Setup ioremapped serial port access */
236 memset(&port, 0, sizeof(port));
237 port.membase = ioremap64(PPC440GP_UART0_ADDR, 8);
238 port.irq = 0;
239 port.uartclk = clocks.uart0;
240 port.regshift = 0;
241 port.iotype = SERIAL_IO_MEM;
242 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
243 port.line = 0;
244
245 if (early_serial_setup(&port) != 0) {
246 printk("Early serial init of port 0 failed\n");
247 }
248
249#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
250 /* Configure debug serial access */
251 gen550_init(0, &port);
252#endif
253
254 port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
255 port.irq = 1;
256 port.uartclk = clocks.uart1;
257 port.line = 1;
258
259 if (early_serial_setup(&port) != 0) {
260 printk("Early serial init of port 1 failed\n");
261 }
262
263#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
264 /* Configure debug serial access */
265 gen550_init(1, &port);
266#endif
267}
268
269static void __init
270ebony_setup_arch(void)
271{
272 struct ocp_def *def;
273 struct ocp_func_emac_data *emacdata;
274
275 /* Set mac_addr for each EMAC */
276 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
277 emacdata = def->additions;
278 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
279 emacdata->phy_mode = PHY_MODE_RMII;
280 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
281
282 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1);
283 emacdata = def->additions;
284 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
285 emacdata->phy_mode = PHY_MODE_RMII;
286 memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
287
288 /*
289 * Determine various clocks.
290 * To be completely correct we should get SysClk
291 * from FPGA, because it can be changed by on-board switches
292 * --ebs
293 */
294 ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200);
295 ocp_sys_info.opb_bus_freq = clocks.opb;
296
297 /* Setup TODC access */
298 TODC_INIT(TODC_TYPE_DS1743,
299 0,
300 0,
301 ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE),
302 8);
303
304 /* init to some ~sane value until calibrate_delay() runs */
305 loops_per_jiffy = 50000000/HZ;
306
307 /* Setup PCI host bridge */
308 ebony_setup_hose();
309
310#ifdef CONFIG_BLK_DEV_INITRD
311 if (initrd_start)
312 ROOT_DEV = Root_RAM0;
313 else
314#endif
315#ifdef CONFIG_ROOT_NFS
316 ROOT_DEV = Root_NFS;
317#else
318 ROOT_DEV = Root_HDA1;
319#endif
320
321 ebony_early_serial_map();
322
323 /* Identify the system */
324 printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n");
325}
326
327void __init platform_init(unsigned long r3, unsigned long r4,
328 unsigned long r5, unsigned long r6, unsigned long r7)
329{
330 parse_bootinfo(find_bootinfo());
331
332 /*
333 * If we were passed in a board information, copy it into the
334 * residual data area.
335 */
336 if (r3)
337 __res = *(bd_t *)(r3 + KERNELBASE);
338
339 ibm44x_platform_init();
340
341 ppc_md.setup_arch = ebony_setup_arch;
342 ppc_md.show_cpuinfo = ebony_show_cpuinfo;
343 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
344
345 ppc_md.calibrate_decr = ebony_calibrate_decr;
346 ppc_md.time_init = todc_time_init;
347 ppc_md.set_rtc_time = todc_set_rtc_time;
348 ppc_md.get_rtc_time = todc_get_rtc_time;
349
350 ppc_md.nvram_read_val = todc_direct_read_val;
351 ppc_md.nvram_write_val = todc_direct_write_val;
352#ifdef CONFIG_KGDB
353 ppc_md.early_serial_map = ebony_early_serial_map;
354#endif
355}
356
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
new file mode 100644
index 000000000000..47c391c9174d
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -0,0 +1,91 @@
1/*
2 * arch/ppc/platforms/ebony.h
3 *
4 * Ebony board definitions
5 *
6 * Matt Porter <mporter@mvista.com>
7 *
8 * Copyright 2002 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#ifdef __KERNEL__
17#ifndef __ASM_EBONY_H__
18#define __ASM_EBONY_H__
19
20#include <linux/config.h>
21#include <platforms/4xx/ibm440gp.h>
22
23/* F/W TLB mapping used in bootloader glue to reset EMAC */
24#define PPC44x_EMAC0_MR0 0xE0000800
25
26/* Where to find the MAC info */
27#define EBONY_OPENBIOS_MAC_BASE 0xfffffe0c
28#define EBONY_OPENBIOS_MAC_OFFSET 0x0c
29
30/* Default clock rates for Rev. B and Rev. C silicon */
31#define EBONY_440GP_RB_SYSCLK 33000000
32#define EBONY_440GP_RC_SYSCLK 400000000
33
34/* RTC/NVRAM location */
35#define EBONY_RTC_ADDR 0x0000000148000000ULL
36#define EBONY_RTC_SIZE 0x2000
37
38/* Flash */
39#define EBONY_FPGA_ADDR 0x0000000148300000ULL
40#define EBONY_BOOT_SMALL_FLASH(x) (x & 0x20)
41#define EBONY_ONBRD_FLASH_EN(x) (x & 0x02)
42#define EBONY_FLASH_SEL(x) (x & 0x01)
43#define EBONY_SMALL_FLASH_LOW1 0x00000001ff800000ULL
44#define EBONY_SMALL_FLASH_LOW2 0x00000001ff880000ULL
45#define EBONY_SMALL_FLASH_HIGH1 0x00000001fff00000ULL
46#define EBONY_SMALL_FLASH_HIGH2 0x00000001fff80000ULL
47#define EBONY_SMALL_FLASH_SIZE 0x80000
48#define EBONY_LARGE_FLASH_LOW 0x00000001ff800000ULL
49#define EBONY_LARGE_FLASH_HIGH 0x00000001ffc00000ULL
50#define EBONY_LARGE_FLASH_SIZE 0x400000
51
52#define EBONY_SMALL_FLASH_BASE 0x00000001fff80000ULL
53#define EBONY_LARGE_FLASH_BASE 0x00000001ff800000ULL
54
55/*
56 * Serial port defines
57 */
58
59/* OpenBIOS defined UART mappings, used before early_serial_setup */
60#define UART0_IO_BASE 0xE0000200
61#define UART1_IO_BASE 0xE0000300
62
63/* external Epson SG-615P */
64#define BASE_BAUD 691200
65
66#define STD_UART_OP(num) \
67 { 0, BASE_BAUD, 0, UART##num##_INT, \
68 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
69 iomem_base: UART##num##_IO_BASE, \
70 io_type: SERIAL_IO_MEM},
71
72#define SERIAL_PORT_DFNS \
73 STD_UART_OP(0) \
74 STD_UART_OP(1)
75
76/* PCI support */
77#define EBONY_PCI_LOWER_IO 0x00000000
78#define EBONY_PCI_UPPER_IO 0x0000ffff
79#define EBONY_PCI_LOWER_MEM 0x80002000
80#define EBONY_PCI_UPPER_MEM 0xffffefff
81
82#define EBONY_PCI_CFGREGS_BASE 0x000000020ec00000
83#define EBONY_PCI_CFGA_PLB32 0x0ec00000
84#define EBONY_PCI_CFGD_PLB32 0x0ec00004
85
86#define EBONY_PCI_IO_BASE 0x0000000208000000ULL
87#define EBONY_PCI_IO_SIZE 0x00010000
88#define EBONY_PCI_MEM_OFFSET 0x00000000
89
90#endif /* __ASM_EBONY_H__ */
91#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c
new file mode 100644
index 000000000000..26a07cdb30ec
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ep405.c
@@ -0,0 +1,197 @@
1/*
2 * arch/ppc/platforms/4xx/ep405.c
3 *
4 * Embedded Planet 405GP board
5 * http://www.embeddedplanet.com
6 *
7 * Author: Matthew Locke <mlocke@mvista.com>
8 *
9 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <asm/system.h>
18#include <asm/pci-bridge.h>
19#include <asm/machdep.h>
20#include <asm/todc.h>
21#include <asm/ocp.h>
22#include <asm/ibm_ocp_pci.h>
23
24#undef DEBUG
25#ifdef DEBUG
26#define DBG(x...) printk(x)
27#else
28#define DBG(x...)
29#endif
30
31u8 *ep405_bcsr;
32u8 *ep405_nvram;
33
34static struct {
35 u8 cpld_xirq_select;
36 int pci_idsel;
37 int irq;
38} ep405_devtable[] = {
39#ifdef CONFIG_EP405PC
40 {0x07, 0x0E, 25}, /* EP405PC: USB */
41#endif
42};
43
44int __init
45ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
46{
47 int i;
48
49 /* AFAICT this is only called a few times during PCI setup, so
50 performance is not critical */
51 for (i = 0; i < ARRAY_SIZE(ep405_devtable); i++) {
52 if (idsel == ep405_devtable[i].pci_idsel)
53 return ep405_devtable[i].irq;
54 }
55 return -1;
56};
57
58void __init
59ep405_setup_arch(void)
60{
61 ppc4xx_setup_arch();
62
63 ibm_ocp_set_emac(0, 0);
64
65 if (__res.bi_nvramsize == 512*1024) {
66 /* FIXME: we should properly handle NVRTCs of different sizes */
67 TODC_INIT(TODC_TYPE_DS1557, ep405_nvram, ep405_nvram, ep405_nvram, 8);
68 }
69}
70
71void __init
72bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
73{
74 unsigned int bar_response, bar;
75 /*
76 * Expected PCI mapping:
77 *
78 * PLB addr PCI memory addr
79 * --------------------- ---------------------
80 * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
81 * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
82 *
83 * PLB addr PCI io addr
84 * --------------------- ---------------------
85 * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
86 *
87 */
88
89 /* Disable region zero first */
90 out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
91 /* PLB starting addr, PCI: 0x80000000 */
92 out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
93 /* PCI start addr, 0x80000000 */
94 out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
95 /* 512MB range of PLB to PCI */
96 out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
97 /* Enable no pre-fetch, enable region */
98 out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
99 (PPC405_PCI_UPPER_MEM -
100 PPC405_PCI_MEM_BASE)) | 0x01));
101
102 /* Disable region one */
103 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
104 out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
105 out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
106 out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
107 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
108 out_le32((void *) &(pcip->ptm1ms), 0x00000000);
109
110 /* Disable region two */
111 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
112 out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
113 out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
114 out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
115 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
116 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
117
118 /* Configure PTM (PCI->PLB) region 1 */
119 out_le32((void *) &(pcip->ptm1la), 0x00000000); /* PLB base address */
120 /* Disable PTM region 2 */
121 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
122
123 /* Zero config bars */
124 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
125 early_write_config_dword(hose, hose->first_busno,
126 PCI_FUNC(hose->first_busno), bar,
127 0x00000000);
128 early_read_config_dword(hose, hose->first_busno,
129 PCI_FUNC(hose->first_busno), bar,
130 &bar_response);
131 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
132 hose->first_busno, PCI_SLOT(hose->first_busno),
133 PCI_FUNC(hose->first_busno), bar, bar_response);
134 }
135 /* end work arround */
136}
137
138void __init
139ep405_map_io(void)
140{
141 bd_t *bip = &__res;
142
143 ppc4xx_map_io();
144
145 ep405_bcsr = ioremap(EP405_BCSR_PADDR, EP405_BCSR_SIZE);
146
147 if (bip->bi_nvramsize > 0) {
148 ep405_nvram = ioremap(EP405_NVRAM_PADDR, bip->bi_nvramsize);
149 }
150}
151
152void __init
153ep405_init_IRQ(void)
154{
155 int i;
156
157 ppc4xx_init_IRQ();
158
159 /* Workaround for a bug in the firmware it incorrectly sets
160 the IRQ polarities for XIRQ0 and XIRQ1 */
161 mtdcr(DCRN_UIC_PR(DCRN_UIC0_BASE), 0xffffff80); /* set the polarity */
162 mtdcr(DCRN_UIC_SR(DCRN_UIC0_BASE), 0x00000060); /* clear bogus interrupts */
163
164 /* Activate the XIRQs from the CPLD */
165 writeb(0xf0, ep405_bcsr+10);
166
167 /* Set up IRQ routing */
168 for (i = 0; i < ARRAY_SIZE(ep405_devtable); i++) {
169 if ( (ep405_devtable[i].irq >= 25)
170 && (ep405_devtable[i].irq) <= 31) {
171 writeb(ep405_devtable[i].cpld_xirq_select, ep405_bcsr+5);
172 writeb(ep405_devtable[i].irq - 25, ep405_bcsr+6);
173 }
174 }
175}
176
177void __init
178platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
179 unsigned long r6, unsigned long r7)
180{
181 ppc4xx_init(r3, r4, r5, r6, r7);
182
183 ppc_md.setup_arch = ep405_setup_arch;
184 ppc_md.setup_io_mappings = ep405_map_io;
185 ppc_md.init_IRQ = ep405_init_IRQ;
186
187 ppc_md.nvram_read_val = todc_direct_read_val;
188 ppc_md.nvram_write_val = todc_direct_write_val;
189
190 if (__res.bi_nvramsize == 512*1024) {
191 ppc_md.time_init = todc_time_init;
192 ppc_md.set_rtc_time = todc_set_rtc_time;
193 ppc_md.get_rtc_time = todc_get_rtc_time;
194 } else {
195 printk("EP405: NVRTC size is not 512k (not a DS1557). Not sure what to do with it\n");
196 }
197}
diff --git a/arch/ppc/platforms/4xx/ep405.h b/arch/ppc/platforms/4xx/ep405.h
new file mode 100644
index 000000000000..ea3eb21338fb
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ep405.h
@@ -0,0 +1,54 @@
1/*
2 * arch/ppc/platforms/4xx/ep405.h
3 *
4 * Embedded Planet 405GP board
5 * http://www.embeddedplanet.com
6 *
7 * Author: Matthew Locke <mlocke@mvista.com>
8 *
9 * 2000 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_EP405_H__
17#define __ASM_EP405_H__
18
19/* We have a 405GP core */
20#include <platforms/4xx/ibm405gp.h>
21
22#ifndef __ASSEMBLY__
23
24#include <linux/types.h>
25
26typedef struct board_info {
27 unsigned int bi_memsize; /* DRAM installed, in bytes */
28 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
29 unsigned int bi_intfreq; /* Processor speed, in Hz */
30 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
31 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
32 unsigned int bi_nvramsize; /* Size of the NVRAM/RTC */
33} bd_t;
34
35/* Some 4xx parts use a different timebase frequency from the internal clock.
36*/
37#define bi_tbfreq bi_intfreq
38
39extern u8 *ep405_bcsr;
40extern u8 *ep405_nvram;
41
42/* Map for the BCSR and NVRAM space */
43#define EP405_BCSR_PADDR ((uint)0xf4000000)
44#define EP405_BCSR_SIZE ((uint)16)
45#define EP405_NVRAM_PADDR ((uint)0xf4200000)
46
47/* serial defines */
48#define BASE_BAUD 399193
49
50#define PPC4xx_MACHINE_NAME "Embedded Planet 405GP"
51
52#endif /* !__ASSEMBLY__ */
53#endif /* __ASM_EP405_H__ */
54#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm405ep.c b/arch/ppc/platforms/4xx/ibm405ep.c
new file mode 100644
index 000000000000..6d44567f4dd2
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405ep.c
@@ -0,0 +1,143 @@
1/*
2 * arch/ppc/platforms/ibm405ep.c
3 *
4 * Support for IBM PPC 405EP processors.
5 *
6 * Author: SAW (IBM), derived from ibmnp405l.c.
7 * Maintained by MontaVista Software <source@mvista.com>
8 *
9 * 2003 (c) MontaVista Softare Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is
11 * licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#include <linux/config.h>
16#include <linux/init.h>
17#include <linux/smp.h>
18#include <linux/threads.h>
19#include <linux/param.h>
20#include <linux/string.h>
21
22#include <asm/ibm4xx.h>
23#include <asm/ocp.h>
24#include <asm/ppc4xx_pic.h>
25
26#include <platforms/4xx/ibm405ep.h>
27
28static struct ocp_func_mal_data ibm405ep_mal0_def = {
29 .num_tx_chans = 4, /* Number of TX channels */
30 .num_rx_chans = 2, /* Number of RX channels */
31 .txeob_irq = 11, /* TX End Of Buffer IRQ */
32 .rxeob_irq = 12, /* RX End Of Buffer IRQ */
33 .txde_irq = 13, /* TX Descriptor Error IRQ */
34 .rxde_irq = 14, /* RX Descriptor Error IRQ */
35 .serr_irq = 10, /* MAL System Error IRQ */
36};
37OCP_SYSFS_MAL_DATA()
38
39static struct ocp_func_emac_data ibm405ep_emac0_def = {
40 .rgmii_idx = -1, /* No RGMII */
41 .rgmii_mux = -1, /* No RGMII */
42 .zmii_idx = -1, /* ZMII device index */
43 .zmii_mux = 0, /* ZMII input of this EMAC */
44 .mal_idx = 0, /* MAL device index */
45 .mal_rx_chan = 0, /* MAL rx channel number */
46 .mal_tx_chan = 0, /* MAL tx channel number */
47 .wol_irq = 9, /* WOL interrupt number */
48 .mdio_idx = 0, /* MDIO via EMAC0 */
49 .tah_idx = -1, /* No TAH */
50};
51
52static struct ocp_func_emac_data ibm405ep_emac1_def = {
53 .rgmii_idx = -1, /* No RGMII */
54 .rgmii_mux = -1, /* No RGMII */
55 .zmii_idx = -1, /* ZMII device index */
56 .zmii_mux = 0, /* ZMII input of this EMAC */
57 .mal_idx = 0, /* MAL device index */
58 .mal_rx_chan = 1, /* MAL rx channel number */
59 .mal_tx_chan = 2, /* MAL tx channel number */
60 .wol_irq = 9, /* WOL interrupt number */
61 .mdio_idx = 0, /* MDIO via EMAC0 */
62 .tah_idx = -1, /* No TAH */
63};
64OCP_SYSFS_EMAC_DATA()
65
66static struct ocp_func_iic_data ibm405ep_iic0_def = {
67 .fast_mode = 0, /* Use standad mode (100Khz) */
68};
69OCP_SYSFS_IIC_DATA()
70
71struct ocp_def core_ocp[] = {
72 { .vendor = OCP_VENDOR_IBM,
73 .function = OCP_FUNC_OPB,
74 .index = 0,
75 .paddr = 0xEF600000,
76 .irq = OCP_IRQ_NA,
77 .pm = OCP_CPM_NA,
78 },
79 { .vendor = OCP_VENDOR_IBM,
80 .function = OCP_FUNC_16550,
81 .index = 0,
82 .paddr = UART0_IO_BASE,
83 .irq = UART0_INT,
84 .pm = IBM_CPM_UART0
85 },
86 { .vendor = OCP_VENDOR_IBM,
87 .function = OCP_FUNC_16550,
88 .index = 1,
89 .paddr = UART1_IO_BASE,
90 .irq = UART1_INT,
91 .pm = IBM_CPM_UART1
92 },
93 { .vendor = OCP_VENDOR_IBM,
94 .function = OCP_FUNC_IIC,
95 .paddr = 0xEF600500,
96 .irq = 2,
97 .pm = IBM_CPM_IIC0,
98 .additions = &ibm405ep_iic0_def,
99 .show = &ocp_show_iic_data
100 },
101 { .vendor = OCP_VENDOR_IBM,
102 .function = OCP_FUNC_GPIO,
103 .paddr = 0xEF600700,
104 .irq = OCP_IRQ_NA,
105 .pm = IBM_CPM_GPIO0
106 },
107 { .vendor = OCP_VENDOR_IBM,
108 .function = OCP_FUNC_MAL,
109 .paddr = OCP_PADDR_NA,
110 .irq = OCP_IRQ_NA,
111 .pm = OCP_CPM_NA,
112 .additions = &ibm405ep_mal0_def,
113 .show = &ocp_show_mal_data
114 },
115 { .vendor = OCP_VENDOR_IBM,
116 .function = OCP_FUNC_EMAC,
117 .index = 0,
118 .paddr = EMAC0_BASE,
119 .irq = 15,
120 .pm = OCP_CPM_NA,
121 .additions = &ibm405ep_emac0_def,
122 .show = &ocp_show_emac_data
123 },
124 { .vendor = OCP_VENDOR_IBM,
125 .function = OCP_FUNC_EMAC,
126 .index = 1,
127 .paddr = 0xEF600900,
128 .irq = 17,
129 .pm = OCP_CPM_NA,
130 .additions = &ibm405ep_emac1_def,
131 .show = &ocp_show_emac_data
132 },
133 { .vendor = OCP_VENDOR_INVALID
134 }
135};
136
137/* Polarity and triggering settings for internal interrupt sources */
138struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
139 { .polarity = 0xffff7f80,
140 .triggering = 0x00000000,
141 .ext_irq_mask = 0x0000007f, /* IRQ0 - IRQ6 */
142 }
143};
diff --git a/arch/ppc/platforms/4xx/ibm405ep.h b/arch/ppc/platforms/4xx/ibm405ep.h
new file mode 100644
index 000000000000..e051e3fe8c63
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405ep.h
@@ -0,0 +1,148 @@
1/*
2 * arch/ppc/platforms/4xx/ibm405ep.h
3 *
4 * IBM PPC 405EP processor defines.
5 *
6 * Author: SAW (IBM), derived from ibm405gp.h.
7 * Maintained by MontaVista Software <source@mvista.com>
8 *
9 * 2003 (c) MontaVista Softare Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is
11 * licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_IBM405EP_H__
17#define __ASM_IBM405EP_H__
18
19#include <linux/config.h>
20
21/* ibm405.h at bottom of this file */
22
23/* PCI
24 * PCI Bridge config reg definitions
25 * see 17-19 of manual
26 */
27
28#define PPC405_PCI_CONFIG_ADDR 0xeec00000
29#define PPC405_PCI_CONFIG_DATA 0xeec00004
30
31#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */
32 /* setbat */
33#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */
34#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */
35#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */
36
37#define PPC405_PCI_LOWER_MEM 0x80000000 /* hose_a->mem_space.start */
38#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */
39#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */
40#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */
41
42#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE
43
44#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE)
45#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR
46#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
47#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR)
48#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR
49#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
50#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000)
51#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR
52#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
53#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
54#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
55#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
56
57/* serial port defines */
58#define RS_TABLE_SIZE 2
59
60#define UART0_INT 0
61#define UART1_INT 1
62
63#define PCIL0_BASE 0xEF400000
64#define UART0_IO_BASE 0xEF600300
65#define UART1_IO_BASE 0xEF600400
66#define EMAC0_BASE 0xEF600800
67
68#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i]
69
70#if defined(CONFIG_UART0_TTYS0)
71#define ACTING_UART0_IO_BASE UART0_IO_BASE
72#define ACTING_UART1_IO_BASE UART1_IO_BASE
73#define ACTING_UART0_INT UART0_INT
74#define ACTING_UART1_INT UART1_INT
75#else
76#define ACTING_UART0_IO_BASE UART1_IO_BASE
77#define ACTING_UART1_IO_BASE UART0_IO_BASE
78#define ACTING_UART0_INT UART1_INT
79#define ACTING_UART1_INT UART0_INT
80#endif
81
82#define STD_UART_OP(num) \
83 { 0, BASE_BAUD, 0, ACTING_UART##num##_INT, \
84 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
85 iomem_base: (u8 *)ACTING_UART##num##_IO_BASE, \
86 io_type: SERIAL_IO_MEM},
87
88#define SERIAL_DEBUG_IO_BASE ACTING_UART0_IO_BASE
89#define SERIAL_PORT_DFNS \
90 STD_UART_OP(0) \
91 STD_UART_OP(1)
92
93/* DCR defines */
94#define DCRN_CPMSR_BASE 0x0BA
95#define DCRN_CPMFR_BASE 0x0B9
96
97#define DCRN_CPC0_PLLMR0_BASE 0x0F0
98#define DCRN_CPC0_BOOT_BASE 0x0F1
99#define DCRN_CPC0_CR1_BASE 0x0F2
100#define DCRN_CPC0_EPRCSR_BASE 0x0F3
101#define DCRN_CPC0_PLLMR1_BASE 0x0F4
102#define DCRN_CPC0_UCR_BASE 0x0F5
103#define DCRN_CPC0_UCR_U0DIV 0x07F
104#define DCRN_CPC0_SRR_BASE 0x0F6
105#define DCRN_CPC0_JTAGID_BASE 0x0F7
106#define DCRN_CPC0_SPARE_BASE 0x0F8
107#define DCRN_CPC0_PCI_BASE 0x0F9
108
109
110#define IBM_CPM_GPT 0x80000000 /* GPT interface */
111#define IBM_CPM_PCI 0x40000000 /* PCI bridge */
112#define IBM_CPM_UIC 0x00010000 /* Universal Int Controller */
113#define IBM_CPM_CPU 0x00008000 /* processor core */
114#define IBM_CPM_EBC 0x00002000 /* EBC controller */
115#define IBM_CPM_SDRAM0 0x00004000 /* SDRAM memory controller */
116#define IBM_CPM_GPIO0 0x00001000 /* General Purpose IO */
117#define IBM_CPM_TMRCLK 0x00000400 /* CPU timers */
118#define IBM_CPM_PLB 0x00000100 /* PLB bus arbiter */
119#define IBM_CPM_OPB 0x00000080 /* PLB to OPB bridge */
120#define IBM_CPM_DMA 0x00000040 /* DMA controller */
121#define IBM_CPM_IIC0 0x00000010 /* IIC interface */
122#define IBM_CPM_UART1 0x00000002 /* serial port 0 */
123#define IBM_CPM_UART0 0x00000001 /* serial port 1 */
124#define DFLT_IBM4xx_PM ~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \
125 | IBM_CPM_OPB | IBM_CPM_EBC \
126 | IBM_CPM_SDRAM0 | IBM_CPM_PLB \
127 | IBM_CPM_UIC | IBM_CPM_TMRCLK)
128#define DCRN_DMA0_BASE 0x100
129#define DCRN_DMA1_BASE 0x108
130#define DCRN_DMA2_BASE 0x110
131#define DCRN_DMA3_BASE 0x118
132#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */
133#define DCRN_DMASR_BASE 0x120
134#define DCRN_EBC_BASE 0x012
135#define DCRN_DCP0_BASE 0x014
136#define DCRN_MAL_BASE 0x180
137#define DCRN_OCM0_BASE 0x018
138#define DCRN_PLB0_BASE 0x084
139#define DCRN_PLLMR_BASE 0x0B0
140#define DCRN_POB0_BASE 0x0A0
141#define DCRN_SDRAM0_BASE 0x010
142#define DCRN_UIC0_BASE 0x0C0
143#define UIC0 DCRN_UIC0_BASE
144
145#include <asm/ibm405.h>
146
147#endif /* __ASM_IBM405EP_H__ */
148#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm405gp.c b/arch/ppc/platforms/4xx/ibm405gp.c
new file mode 100644
index 000000000000..dfd7ef3ba5f8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405gp.c
@@ -0,0 +1,120 @@
1/*
2 *
3 * Copyright 2000-2001 MontaVista Software Inc.
4 * Original author: Armin Kuster akuster@mvista.com
5 *
6 * Module name: ibm405gp.c
7 *
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 */
15
16#include <linux/config.h>
17#include <linux/init.h>
18#include <linux/smp.h>
19#include <linux/threads.h>
20#include <linux/param.h>
21#include <linux/string.h>
22#include <platforms/4xx/ibm405gp.h>
23#include <asm/ibm4xx.h>
24#include <asm/ocp.h>
25#include <asm/ppc4xx_pic.h>
26
27static struct ocp_func_emac_data ibm405gp_emac0_def = {
28 .rgmii_idx = -1, /* No RGMII */
29 .rgmii_mux = -1, /* No RGMII */
30 .zmii_idx = -1, /* ZMII device index */
31 .zmii_mux = 0, /* ZMII input of this EMAC */
32 .mal_idx = 0, /* MAL device index */
33 .mal_rx_chan = 0, /* MAL rx channel number */
34 .mal_tx_chan = 0, /* MAL tx channel number */
35 .wol_irq = 9, /* WOL interrupt number */
36 .mdio_idx = -1, /* No shared MDIO */
37 .tah_idx = -1, /* No TAH */
38};
39OCP_SYSFS_EMAC_DATA()
40
41static struct ocp_func_mal_data ibm405gp_mal0_def = {
42 .num_tx_chans = 1, /* Number of TX channels */
43 .num_rx_chans = 1, /* Number of RX channels */
44 .txeob_irq = 11, /* TX End Of Buffer IRQ */
45 .rxeob_irq = 12, /* RX End Of Buffer IRQ */
46 .txde_irq = 13, /* TX Descriptor Error IRQ */
47 .rxde_irq = 14, /* RX Descriptor Error IRQ */
48 .serr_irq = 10, /* MAL System Error IRQ */
49};
50OCP_SYSFS_MAL_DATA()
51
52static struct ocp_func_iic_data ibm405gp_iic0_def = {
53 .fast_mode = 0, /* Use standad mode (100Khz) */
54};
55OCP_SYSFS_IIC_DATA()
56
57struct ocp_def core_ocp[] = {
58 { .vendor = OCP_VENDOR_IBM,
59 .function = OCP_FUNC_OPB,
60 .index = 0,
61 .paddr = 0xEF600000,
62 .irq = OCP_IRQ_NA,
63 .pm = OCP_CPM_NA,
64 },
65 { .vendor = OCP_VENDOR_IBM,
66 .function = OCP_FUNC_16550,
67 .index = 0,
68 .paddr = UART0_IO_BASE,
69 .irq = UART0_INT,
70 .pm = IBM_CPM_UART0
71 },
72 { .vendor = OCP_VENDOR_IBM,
73 .function = OCP_FUNC_16550,
74 .index = 1,
75 .paddr = UART1_IO_BASE,
76 .irq = UART1_INT,
77 .pm = IBM_CPM_UART1
78 },
79 { .vendor = OCP_VENDOR_IBM,
80 .function = OCP_FUNC_IIC,
81 .paddr = 0xEF600500,
82 .irq = 2,
83 .pm = IBM_CPM_IIC0,
84 .additions = &ibm405gp_iic0_def,
85 .show = &ocp_show_iic_data,
86 },
87 { .vendor = OCP_VENDOR_IBM,
88 .function = OCP_FUNC_GPIO,
89 .paddr = 0xEF600700,
90 .irq = OCP_IRQ_NA,
91 .pm = IBM_CPM_GPIO0
92 },
93 { .vendor = OCP_VENDOR_IBM,
94 .function = OCP_FUNC_MAL,
95 .paddr = OCP_PADDR_NA,
96 .irq = OCP_IRQ_NA,
97 .pm = OCP_CPM_NA,
98 .additions = &ibm405gp_mal0_def,
99 .show = &ocp_show_mal_data,
100 },
101 { .vendor = OCP_VENDOR_IBM,
102 .function = OCP_FUNC_EMAC,
103 .index = 0,
104 .paddr = EMAC0_BASE,
105 .irq = 15,
106 .pm = IBM_CPM_EMAC0,
107 .additions = &ibm405gp_emac0_def,
108 .show = &ocp_show_emac_data,
109 },
110 { .vendor = OCP_VENDOR_INVALID
111 }
112};
113
114/* Polarity and triggering settings for internal interrupt sources */
115struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
116 { .polarity = 0xffffff80,
117 .triggering = 0x10000000,
118 .ext_irq_mask = 0x0000007f, /* IRQ0 - IRQ6 */
119 }
120};
diff --git a/arch/ppc/platforms/4xx/ibm405gp.h b/arch/ppc/platforms/4xx/ibm405gp.h
new file mode 100644
index 000000000000..b2b642e81af7
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405gp.h
@@ -0,0 +1,151 @@
1/*
2 * arch/ppc/platforms/4xx/ibm405gp.h
3 *
4 * Author: Armin Kuster akuster@mvista.com
5 *
6 * 2001 (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
12#ifdef __KERNEL__
13#ifndef __ASM_IBM405GP_H__
14#define __ASM_IBM405GP_H__
15
16#include <linux/config.h>
17
18/* ibm405.h at bottom of this file */
19
20/* PCI
21 * PCI Bridge config reg definitions
22 * see 17-19 of manual
23 */
24
25#define PPC405_PCI_CONFIG_ADDR 0xeec00000
26#define PPC405_PCI_CONFIG_DATA 0xeec00004
27
28#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */
29 /* setbat */
30#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */
31#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */
32#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */
33
34#define PPC405_PCI_LOWER_MEM 0x80000000 /* hose_a->mem_space.start */
35#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */
36#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */
37#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */
38
39#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE
40
41#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE)
42#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR
43#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
44#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR)
45#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR
46#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
47#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000)
48#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR
49#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
50#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
51#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
52#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
53
54/* serial port defines */
55#define RS_TABLE_SIZE 2
56
57#define UART0_INT 0
58#define UART1_INT 1
59
60#define PCIL0_BASE 0xEF400000
61#define UART0_IO_BASE 0xEF600300
62#define UART1_IO_BASE 0xEF600400
63#define EMAC0_BASE 0xEF600800
64
65#define BD_EMAC_ADDR(e,i) bi_enetaddr[i]
66
67#define STD_UART_OP(num) \
68 { 0, BASE_BAUD, 0, UART##num##_INT, \
69 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
70 iomem_base: (u8 *)UART##num##_IO_BASE, \
71 io_type: SERIAL_IO_MEM},
72
73#if defined(CONFIG_UART0_TTYS0)
74#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
75#define SERIAL_PORT_DFNS \
76 STD_UART_OP(0) \
77 STD_UART_OP(1)
78#endif
79
80#if defined(CONFIG_UART0_TTYS1)
81#define SERIAL_DEBUG_IO_BASE UART1_IO_BASE
82#define SERIAL_PORT_DFNS \
83 STD_UART_OP(1) \
84 STD_UART_OP(0)
85#endif
86
87/* DCR defines */
88#define DCRN_CHCR_BASE 0x0B1
89#define DCRN_CHPSR_BASE 0x0B4
90#define DCRN_CPMSR_BASE 0x0B8
91#define DCRN_CPMFR_BASE 0x0BA
92
93#define CHR0_U0EC 0x00000080 /* Select external clock for UART0 */
94#define CHR0_U1EC 0x00000040 /* Select external clock for UART1 */
95#define CHR0_UDIV 0x0000003E /* UART internal clock divisor */
96#define CHR1_CETE 0x00800000 /* CPU external timer enable */
97
98#define DCRN_CHPSR_BASE 0x0B4
99#define PSR_PLL_FWD_MASK 0xC0000000
100#define PSR_PLL_FDBACK_MASK 0x30000000
101#define PSR_PLL_TUNING_MASK 0x0E000000
102#define PSR_PLB_CPU_MASK 0x01800000
103#define PSR_OPB_PLB_MASK 0x00600000
104#define PSR_PCI_PLB_MASK 0x00180000
105#define PSR_EB_PLB_MASK 0x00060000
106#define PSR_ROM_WIDTH_MASK 0x00018000
107#define PSR_ROM_LOC 0x00004000
108#define PSR_PCI_ASYNC_EN 0x00001000
109#define PSR_PCI_ARBIT_EN 0x00000400
110
111#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
112#define IBM_CPM_PCI 0x40000000 /* PCI bridge */
113#define IBM_CPM_CPU 0x20000000 /* processor core */
114#define IBM_CPM_DMA 0x10000000 /* DMA controller */
115#define IBM_CPM_OPB 0x08000000 /* PLB to OPB bridge */
116#define IBM_CPM_DCP 0x04000000 /* CodePack */
117#define IBM_CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */
118#define IBM_CPM_SDRAM0 0x01000000 /* SDRAM memory controller */
119#define IBM_CPM_PLB 0x00800000 /* PLB bus arbiter */
120#define IBM_CPM_GPIO0 0x00400000 /* General Purpose IO (??) */
121#define IBM_CPM_UART0 0x00200000 /* serial port 0 */
122#define IBM_CPM_UART1 0x00100000 /* serial port 1 */
123#define IBM_CPM_UIC 0x00080000 /* Universal Interrupt Controller */
124#define IBM_CPM_TMRCLK 0x00040000 /* CPU timers */
125#define IBM_CPM_EMAC0 0x00020000 /* on-chip ethernet MM unit */
126#define DFLT_IBM4xx_PM ~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \
127 | IBM_CPM_OPB | IBM_CPM_EBC \
128 | IBM_CPM_SDRAM0 | IBM_CPM_PLB \
129 | IBM_CPM_UIC | IBM_CPM_TMRCLK)
130
131#define DCRN_DMA0_BASE 0x100
132#define DCRN_DMA1_BASE 0x108
133#define DCRN_DMA2_BASE 0x110
134#define DCRN_DMA3_BASE 0x118
135#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */
136#define DCRN_DMASR_BASE 0x120
137#define DCRN_EBC_BASE 0x012
138#define DCRN_DCP0_BASE 0x014
139#define DCRN_MAL_BASE 0x180
140#define DCRN_OCM0_BASE 0x018
141#define DCRN_PLB0_BASE 0x084
142#define DCRN_PLLMR_BASE 0x0B0
143#define DCRN_POB0_BASE 0x0A0
144#define DCRN_SDRAM0_BASE 0x010
145#define DCRN_UIC0_BASE 0x0C0
146#define UIC0 DCRN_UIC0_BASE
147
148#include <asm/ibm405.h>
149
150#endif /* __ASM_IBM405GP_H__ */
151#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm405gpr.c b/arch/ppc/platforms/4xx/ibm405gpr.c
new file mode 100644
index 000000000000..01c8ccbc7214
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405gpr.c
@@ -0,0 +1,117 @@
1/*
2 * arch/ppc/platforms/4xx/ibm405gpr.c
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2002 (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
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/smp.h>
15#include <linux/threads.h>
16#include <linux/param.h>
17#include <linux/string.h>
18#include <platforms/4xx/ibm405gpr.h>
19#include <asm/ibm4xx.h>
20#include <asm/ocp.h>
21#include <asm/ppc4xx_pic.h>
22
23static struct ocp_func_emac_data ibm405gpr_emac0_def = {
24 .rgmii_idx = -1, /* No RGMII */
25 .rgmii_mux = -1, /* No RGMII */
26 .zmii_idx = -1, /* ZMII device index */
27 .zmii_mux = 0, /* ZMII input of this EMAC */
28 .mal_idx = 0, /* MAL device index */
29 .mal_rx_chan = 0, /* MAL rx channel number */
30 .mal_tx_chan = 0, /* MAL tx channel number */
31 .wol_irq = 9, /* WOL interrupt number */
32 .mdio_idx = -1, /* No shared MDIO */
33 .tah_idx = -1, /* No TAH */
34};
35OCP_SYSFS_EMAC_DATA()
36
37static struct ocp_func_mal_data ibm405gpr_mal0_def = {
38 .num_tx_chans = 1, /* Number of TX channels */
39 .num_rx_chans = 1, /* Number of RX channels */
40 .txeob_irq = 11, /* TX End Of Buffer IRQ */
41 .rxeob_irq = 12, /* RX End Of Buffer IRQ */
42 .txde_irq = 13, /* TX Descriptor Error IRQ */
43 .rxde_irq = 14, /* RX Descriptor Error IRQ */
44 .serr_irq = 10, /* MAL System Error IRQ */
45};
46OCP_SYSFS_MAL_DATA()
47
48static struct ocp_func_iic_data ibm405gpr_iic0_def = {
49 .fast_mode = 0, /* Use standad mode (100Khz) */
50};
51
52OCP_SYSFS_IIC_DATA()
53
54struct ocp_def core_ocp[] = {
55 { .vendor = OCP_VENDOR_IBM,
56 .function = OCP_FUNC_OPB,
57 .index = 0,
58 .paddr = 0xEF600000,
59 .irq = OCP_IRQ_NA,
60 .pm = OCP_CPM_NA,
61 },
62 { .vendor = OCP_VENDOR_IBM,
63 .function = OCP_FUNC_16550,
64 .index = 0,
65 .paddr = UART0_IO_BASE,
66 .irq = UART0_INT,
67 .pm = IBM_CPM_UART0
68 },
69 { .vendor = OCP_VENDOR_IBM,
70 .function = OCP_FUNC_16550,
71 .index = 1,
72 .paddr = UART1_IO_BASE,
73 .irq = UART1_INT,
74 .pm = IBM_CPM_UART1
75 },
76 { .vendor = OCP_VENDOR_IBM,
77 .function = OCP_FUNC_IIC,
78 .paddr = 0xEF600500,
79 .irq = 2,
80 .pm = IBM_CPM_IIC0,
81 .additions = &ibm405gpr_iic0_def,
82 .show = &ocp_show_iic_data,
83 },
84 { .vendor = OCP_VENDOR_IBM,
85 .function = OCP_FUNC_GPIO,
86 .paddr = 0xEF600700,
87 .irq = OCP_IRQ_NA,
88 .pm = IBM_CPM_GPIO0
89 },
90 { .vendor = OCP_VENDOR_IBM,
91 .function = OCP_FUNC_MAL,
92 .paddr = OCP_PADDR_NA,
93 .irq = OCP_IRQ_NA,
94 .pm = OCP_CPM_NA,
95 .additions = &ibm405gpr_mal0_def,
96 .show = &ocp_show_mal_data,
97 },
98 { .vendor = OCP_VENDOR_IBM,
99 .function = OCP_FUNC_EMAC,
100 .index = 0,
101 .paddr = EMAC0_BASE,
102 .irq = 15,
103 .pm = IBM_CPM_EMAC0,
104 .additions = &ibm405gpr_emac0_def,
105 .show = &ocp_show_emac_data,
106 },
107 { .vendor = OCP_VENDOR_INVALID
108 }
109};
110
111/* Polarity and triggering settings for internal interrupt sources */
112struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
113 { .polarity = 0xffffe000,
114 .triggering = 0x10000000,
115 .ext_irq_mask = 0x00001fff, /* IRQ7 - IRQ12, IRQ0 - IRQ6 */
116 }
117};
diff --git a/arch/ppc/platforms/4xx/ibm405gpr.h b/arch/ppc/platforms/4xx/ibm405gpr.h
new file mode 100644
index 000000000000..45412fb4368f
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm405gpr.h
@@ -0,0 +1,151 @@
1/*
2 * arch/ppc/platforms/4xx/ibm405gpr.h
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2002 (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
12#ifdef __KERNEL__
13#ifndef __ASM_IBM405GPR_H__
14#define __ASM_IBM405GPR_H__
15
16#include <linux/config.h>
17
18/* ibm405.h at bottom of this file */
19
20/* PCI
21 * PCI Bridge config reg definitions
22 * see 17-19 of manual
23 */
24
25#define PPC405_PCI_CONFIG_ADDR 0xeec00000
26#define PPC405_PCI_CONFIG_DATA 0xeec00004
27
28#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */
29 /* setbat */
30#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */
31#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */
32#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */
33
34#define PPC405_PCI_LOWER_MEM 0x80000000 /* hose_a->mem_space.start */
35#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */
36#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */
37#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */
38
39#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE
40
41#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE)
42#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR
43#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
44#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR)
45#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR
46#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
47#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000)
48#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR
49#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
50#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
51#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
52#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
53
54/* serial port defines */
55#define RS_TABLE_SIZE 2
56
57#define UART0_INT 0
58#define UART1_INT 1
59
60#define PCIL0_BASE 0xEF400000
61#define UART0_IO_BASE 0xEF600300
62#define UART1_IO_BASE 0xEF600400
63#define EMAC0_BASE 0xEF600800
64
65#define BD_EMAC_ADDR(e,i) bi_enetaddr[i]
66
67#define STD_UART_OP(num) \
68 { 0, BASE_BAUD, 0, UART##num##_INT, \
69 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
70 iomem_base: (u8 *)UART##num##_IO_BASE, \
71 io_type: SERIAL_IO_MEM},
72
73#if defined(CONFIG_UART0_TTYS0)
74#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
75#define SERIAL_PORT_DFNS \
76 STD_UART_OP(0) \
77 STD_UART_OP(1)
78#endif
79
80#if defined(CONFIG_UART0_TTYS1)
81#define SERIAL_DEBUG_IO_BASE UART1_IO_BASE
82#define SERIAL_PORT_DFNS \
83 STD_UART_OP(1) \
84 STD_UART_OP(0)
85#endif
86
87/* DCR defines */
88#define DCRN_CHCR_BASE 0x0B1
89#define DCRN_CHPSR_BASE 0x0B4
90#define DCRN_CPMSR_BASE 0x0B8
91#define DCRN_CPMFR_BASE 0x0BA
92
93#define CHR0_U0EC 0x00000080 /* Select external clock for UART0 */
94#define CHR0_U1EC 0x00000040 /* Select external clock for UART1 */
95#define CHR0_UDIV 0x0000003E /* UART internal clock divisor */
96#define CHR1_CETE 0x00800000 /* CPU external timer enable */
97
98#define DCRN_CHPSR_BASE 0x0B4
99#define PSR_PLL_FWD_MASK 0xC0000000
100#define PSR_PLL_FDBACK_MASK 0x30000000
101#define PSR_PLL_TUNING_MASK 0x0E000000
102#define PSR_PLB_CPU_MASK 0x01800000
103#define PSR_OPB_PLB_MASK 0x00600000
104#define PSR_PCI_PLB_MASK 0x00180000
105#define PSR_EB_PLB_MASK 0x00060000
106#define PSR_ROM_WIDTH_MASK 0x00018000
107#define PSR_ROM_LOC 0x00004000
108#define PSR_PCI_ASYNC_EN 0x00001000
109#define PSR_PCI_ARBIT_EN 0x00000400
110
111#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
112#define IBM_CPM_PCI 0x40000000 /* PCI bridge */
113#define IBM_CPM_CPU 0x20000000 /* processor core */
114#define IBM_CPM_DMA 0x10000000 /* DMA controller */
115#define IBM_CPM_OPB 0x08000000 /* PLB to OPB bridge */
116#define IBM_CPM_DCP 0x04000000 /* CodePack */
117#define IBM_CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */
118#define IBM_CPM_SDRAM0 0x01000000 /* SDRAM memory controller */
119#define IBM_CPM_PLB 0x00800000 /* PLB bus arbiter */
120#define IBM_CPM_GPIO0 0x00400000 /* General Purpose IO (??) */
121#define IBM_CPM_UART0 0x00200000 /* serial port 0 */
122#define IBM_CPM_UART1 0x00100000 /* serial port 1 */
123#define IBM_CPM_UIC 0x00080000 /* Universal Interrupt Controller */
124#define IBM_CPM_TMRCLK 0x00040000 /* CPU timers */
125#define IBM_CPM_EMAC0 0x00020000 /* on-chip ethernet MM unit */
126#define DFLT_IBM4xx_PM ~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \
127 | IBM_CPM_OPB | IBM_CPM_EBC \
128 | IBM_CPM_SDRAM0 | IBM_CPM_PLB \
129 | IBM_CPM_UIC | IBM_CPM_TMRCLK)
130
131#define DCRN_DMA0_BASE 0x100
132#define DCRN_DMA1_BASE 0x108
133#define DCRN_DMA2_BASE 0x110
134#define DCRN_DMA3_BASE 0x118
135#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */
136#define DCRN_DMASR_BASE 0x120
137#define DCRN_EBC_BASE 0x012
138#define DCRN_DCP0_BASE 0x014
139#define DCRN_MAL_BASE 0x180
140#define DCRN_OCM0_BASE 0x018
141#define DCRN_PLB0_BASE 0x084
142#define DCRN_PLLMR_BASE 0x0B0
143#define DCRN_POB0_BASE 0x0A0
144#define DCRN_SDRAM0_BASE 0x010
145#define DCRN_UIC0_BASE 0x0C0
146#define UIC0 DCRN_UIC0_BASE
147
148#include <asm/ibm405.h>
149
150#endif /* __ASM_IBM405GPR_H__ */
151#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c
new file mode 100644
index 000000000000..27615ef8309c
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gp.c
@@ -0,0 +1,164 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440gp.c
3 *
4 * PPC440GP I/O descriptions
5 *
6 * Matt Porter <mporter@mvista.com>
7 * Copyright 2002-2004 MontaVista Software Inc.
8 *
9 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
10 * Copyright (c) 2003, 2004 Zultys Technologies
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 */
18#include <linux/init.h>
19#include <linux/module.h>
20#include <platforms/4xx/ibm440gp.h>
21#include <asm/ocp.h>
22#include <asm/ppc4xx_pic.h>
23
24static struct ocp_func_emac_data ibm440gp_emac0_def = {
25 .rgmii_idx = -1, /* No RGMII */
26 .rgmii_mux = -1, /* No RGMII */
27 .zmii_idx = 0, /* ZMII device index */
28 .zmii_mux = 0, /* ZMII input of this EMAC */
29 .mal_idx = 0, /* MAL device index */
30 .mal_rx_chan = 0, /* MAL rx channel number */
31 .mal_tx_chan = 0, /* MAL tx channel number */
32 .wol_irq = 61, /* WOL interrupt number */
33 .mdio_idx = -1, /* No shared MDIO */
34 .tah_idx = -1, /* No TAH */
35};
36
37static struct ocp_func_emac_data ibm440gp_emac1_def = {
38 .rgmii_idx = -1, /* No RGMII */
39 .rgmii_mux = -1, /* No RGMII */
40 .zmii_idx = 0, /* ZMII device index */
41 .zmii_mux = 1, /* ZMII input of this EMAC */
42 .mal_idx = 0, /* MAL device index */
43 .mal_rx_chan = 1, /* MAL rx channel number */
44 .mal_tx_chan = 2, /* MAL tx channel number */
45 .wol_irq = 63, /* WOL interrupt number */
46 .mdio_idx = -1, /* No shared MDIO */
47 .tah_idx = -1, /* No TAH */
48};
49OCP_SYSFS_EMAC_DATA()
50
51static struct ocp_func_mal_data ibm440gp_mal0_def = {
52 .num_tx_chans = 4, /* Number of TX channels */
53 .num_rx_chans = 2, /* Number of RX channels */
54 .txeob_irq = 10, /* TX End Of Buffer IRQ */
55 .rxeob_irq = 11, /* RX End Of Buffer IRQ */
56 .txde_irq = 33, /* TX Descriptor Error IRQ */
57 .rxde_irq = 34, /* RX Descriptor Error IRQ */
58 .serr_irq = 32, /* MAL System Error IRQ */
59};
60OCP_SYSFS_MAL_DATA()
61
62static struct ocp_func_iic_data ibm440gp_iic0_def = {
63 .fast_mode = 0, /* Use standad mode (100Khz) */
64};
65
66static struct ocp_func_iic_data ibm440gp_iic1_def = {
67 .fast_mode = 0, /* Use standad mode (100Khz) */
68};
69OCP_SYSFS_IIC_DATA()
70
71struct ocp_def core_ocp[] = {
72 { .vendor = OCP_VENDOR_IBM,
73 .function = OCP_FUNC_OPB,
74 .index = 0,
75 .paddr = 0x0000000140000000ULL,
76 .irq = OCP_IRQ_NA,
77 .pm = OCP_CPM_NA,
78 },
79 { .vendor = OCP_VENDOR_IBM,
80 .function = OCP_FUNC_16550,
81 .index = 0,
82 .paddr = PPC440GP_UART0_ADDR,
83 .irq = UART0_INT,
84 .pm = IBM_CPM_UART0,
85 },
86 { .vendor = OCP_VENDOR_IBM,
87 .function = OCP_FUNC_16550,
88 .index = 1,
89 .paddr = PPC440GP_UART1_ADDR,
90 .irq = UART1_INT,
91 .pm = IBM_CPM_UART1,
92 },
93 { .vendor = OCP_VENDOR_IBM,
94 .function = OCP_FUNC_IIC,
95 .index = 0,
96 .paddr = 0x0000000140000400ULL,
97 .irq = 2,
98 .pm = IBM_CPM_IIC0,
99 .additions = &ibm440gp_iic0_def,
100 .show = &ocp_show_iic_data
101 },
102 { .vendor = OCP_VENDOR_IBM,
103 .function = OCP_FUNC_IIC,
104 .index = 1,
105 .paddr = 0x0000000140000500ULL,
106 .irq = 3,
107 .pm = IBM_CPM_IIC1,
108 .additions = &ibm440gp_iic1_def,
109 .show = &ocp_show_iic_data
110 },
111 { .vendor = OCP_VENDOR_IBM,
112 .function = OCP_FUNC_GPIO,
113 .index = 0,
114 .paddr = 0x0000000140000700ULL,
115 .irq = OCP_IRQ_NA,
116 .pm = IBM_CPM_GPIO0,
117 },
118 { .vendor = OCP_VENDOR_IBM,
119 .function = OCP_FUNC_MAL,
120 .paddr = OCP_PADDR_NA,
121 .irq = OCP_IRQ_NA,
122 .pm = OCP_CPM_NA,
123 .additions = &ibm440gp_mal0_def,
124 .show = &ocp_show_mal_data,
125 },
126 { .vendor = OCP_VENDOR_IBM,
127 .function = OCP_FUNC_EMAC,
128 .index = 0,
129 .paddr = 0x0000000140000800ULL,
130 .irq = 60,
131 .pm = OCP_CPM_NA,
132 .additions = &ibm440gp_emac0_def,
133 .show = &ocp_show_emac_data,
134 },
135 { .vendor = OCP_VENDOR_IBM,
136 .function = OCP_FUNC_EMAC,
137 .index = 1,
138 .paddr = 0x0000000140000900ULL,
139 .irq = 62,
140 .pm = OCP_CPM_NA,
141 .additions = &ibm440gp_emac1_def,
142 .show = &ocp_show_emac_data,
143 },
144 { .vendor = OCP_VENDOR_IBM,
145 .function = OCP_FUNC_ZMII,
146 .paddr = 0x0000000140000780ULL,
147 .irq = OCP_IRQ_NA,
148 .pm = OCP_CPM_NA,
149 },
150 { .vendor = OCP_VENDOR_INVALID
151 }
152};
153
154/* Polarity and triggering settings for internal interrupt sources */
155struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
156 { .polarity = 0xfffffe03,
157 .triggering = 0x01c00000,
158 .ext_irq_mask = 0x000001fc, /* IRQ0 - IRQ6 */
159 },
160 { .polarity = 0xffffc0ff,
161 .triggering = 0x00ff8000,
162 .ext_irq_mask = 0x00003f00, /* IRQ7 - IRQ12 */
163 },
164};
diff --git a/arch/ppc/platforms/4xx/ibm440gp.h b/arch/ppc/platforms/4xx/ibm440gp.h
new file mode 100644
index 000000000000..ae1efc03b295
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gp.h
@@ -0,0 +1,66 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440gp.h
3 *
4 * PPC440GP definitions
5 *
6 * Roland Dreier <roland@digitalvampire.org>
7 *
8 * Copyright 2002 Roland Dreier
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This file contains code that was originally in the files ibm44x.h
16 * and ebony.h, which were written by Matt Porter of MontaVista Software Inc.
17 */
18
19#ifdef __KERNEL__
20#ifndef __PPC_PLATFORMS_IBM440GP_H
21#define __PPC_PLATFORMS_IBM440GP_H
22
23#include <linux/config.h>
24
25/* UART */
26#define PPC440GP_UART0_ADDR 0x0000000140000200ULL
27#define PPC440GP_UART1_ADDR 0x0000000140000300ULL
28#define UART0_INT 0
29#define UART1_INT 1
30
31/* Clock and Power Management */
32#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
33#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
34#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
35#define IBM_CPM_CPU 0x02000000 /* processor core */
36#define IBM_CPM_DMA 0x01000000 /* DMA controller */
37#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
38#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
39#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
40#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
41#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
42#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
43#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
44#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
45#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
46#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
47#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
48#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
49#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
50#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
51#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
52
53#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
54 | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
55 | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
56 | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI)
57/*
58 * Serial port defines
59 */
60#define RS_TABLE_SIZE 2
61
62#include <asm/ibm44x.h>
63#include <syslib/ibm440gp_common.h>
64
65#endif /* __PPC_PLATFORMS_IBM440GP_H */
66#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
new file mode 100644
index 000000000000..1f38f42835b4
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gx.c
@@ -0,0 +1,234 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440gx.c
3 *
4 * PPC440GX I/O descriptions
5 *
6 * Matt Porter <mporter@mvista.com>
7 * Copyright 2002-2004 MontaVista Software Inc.
8 *
9 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
10 * Copyright (c) 2003, 2004 Zultys Technologies
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 */
18#include <linux/init.h>
19#include <linux/module.h>
20#include <platforms/4xx/ibm440gx.h>
21#include <asm/ocp.h>
22#include <asm/ppc4xx_pic.h>
23
24static struct ocp_func_emac_data ibm440gx_emac0_def = {
25 .rgmii_idx = -1, /* No RGMII */
26 .rgmii_mux = -1, /* No RGMII */
27 .zmii_idx = 0, /* ZMII device index */
28 .zmii_mux = 0, /* ZMII input of this EMAC */
29 .mal_idx = 0, /* MAL device index */
30 .mal_rx_chan = 0, /* MAL rx channel number */
31 .mal_tx_chan = 0, /* MAL tx channel number */
32 .wol_irq = 61, /* WOL interrupt number */
33 .mdio_idx = -1, /* No shared MDIO */
34 .tah_idx = -1, /* No TAH */
35};
36
37static struct ocp_func_emac_data ibm440gx_emac1_def = {
38 .rgmii_idx = -1, /* No RGMII */
39 .rgmii_mux = -1, /* No RGMII */
40 .zmii_idx = 0, /* ZMII device index */
41 .zmii_mux = 1, /* ZMII input of this EMAC */
42 .mal_idx = 0, /* MAL device index */
43 .mal_rx_chan = 1, /* MAL rx channel number */
44 .mal_tx_chan = 1, /* MAL tx channel number */
45 .wol_irq = 63, /* WOL interrupt number */
46 .mdio_idx = -1, /* No shared MDIO */
47 .tah_idx = -1, /* No TAH */
48};
49
50static struct ocp_func_emac_data ibm440gx_emac2_def = {
51 .rgmii_idx = 0, /* RGMII device index */
52 .rgmii_mux = 0, /* RGMII input of this EMAC */
53 .zmii_idx = 0, /* ZMII device index */
54 .zmii_mux = 2, /* ZMII input of this EMAC */
55 .mal_idx = 0, /* MAL device index */
56 .mal_rx_chan = 2, /* MAL rx channel number */
57 .mal_tx_chan = 2, /* MAL tx channel number */
58 .wol_irq = 65, /* WOL interrupt number */
59 .mdio_idx = -1, /* No shared MDIO */
60 .tah_idx = 0, /* TAH device index */
61 .jumbo = 1, /* Jumbo frames supported */
62};
63
64static struct ocp_func_emac_data ibm440gx_emac3_def = {
65 .rgmii_idx = 0, /* RGMII device index */
66 .rgmii_mux = 1, /* RGMII input of this EMAC */
67 .zmii_idx = 0, /* ZMII device index */
68 .zmii_mux = 3, /* ZMII input of this EMAC */
69 .mal_idx = 0, /* MAL device index */
70 .mal_rx_chan = 3, /* MAL rx channel number */
71 .mal_tx_chan = 3, /* MAL tx channel number */
72 .wol_irq = 67, /* WOL interrupt number */
73 .mdio_idx = -1, /* No shared MDIO */
74 .tah_idx = 1, /* TAH device index */
75 .jumbo = 1, /* Jumbo frames supported */
76};
77OCP_SYSFS_EMAC_DATA()
78
79static struct ocp_func_mal_data ibm440gx_mal0_def = {
80 .num_tx_chans = 4, /* Number of TX channels */
81 .num_rx_chans = 4, /* Number of RX channels */
82 .txeob_irq = 10, /* TX End Of Buffer IRQ */
83 .rxeob_irq = 11, /* RX End Of Buffer IRQ */
84 .txde_irq = 33, /* TX Descriptor Error IRQ */
85 .rxde_irq = 34, /* RX Descriptor Error IRQ */
86 .serr_irq = 32, /* MAL System Error IRQ */
87};
88OCP_SYSFS_MAL_DATA()
89
90static struct ocp_func_iic_data ibm440gx_iic0_def = {
91 .fast_mode = 0, /* Use standad mode (100Khz) */
92};
93
94static struct ocp_func_iic_data ibm440gx_iic1_def = {
95 .fast_mode = 0, /* Use standad mode (100Khz) */
96};
97OCP_SYSFS_IIC_DATA()
98
99struct ocp_def core_ocp[] = {
100 { .vendor = OCP_VENDOR_IBM,
101 .function = OCP_FUNC_OPB,
102 .index = 0,
103 .paddr = 0x0000000140000000ULL,
104 .irq = OCP_IRQ_NA,
105 .pm = OCP_CPM_NA,
106 },
107 { .vendor = OCP_VENDOR_IBM,
108 .function = OCP_FUNC_16550,
109 .index = 0,
110 .paddr = PPC440GX_UART0_ADDR,
111 .irq = UART0_INT,
112 .pm = IBM_CPM_UART0,
113 },
114 { .vendor = OCP_VENDOR_IBM,
115 .function = OCP_FUNC_16550,
116 .index = 1,
117 .paddr = PPC440GX_UART1_ADDR,
118 .irq = UART1_INT,
119 .pm = IBM_CPM_UART1,
120 },
121 { .vendor = OCP_VENDOR_IBM,
122 .function = OCP_FUNC_IIC,
123 .index = 0,
124 .paddr = 0x0000000140000400ULL,
125 .irq = 2,
126 .pm = IBM_CPM_IIC0,
127 .additions = &ibm440gx_iic0_def,
128 .show = &ocp_show_iic_data
129 },
130 { .vendor = OCP_VENDOR_IBM,
131 .function = OCP_FUNC_IIC,
132 .index = 1,
133 .paddr = 0x0000000140000500ULL,
134 .irq = 3,
135 .pm = IBM_CPM_IIC1,
136 .additions = &ibm440gx_iic1_def,
137 .show = &ocp_show_iic_data
138 },
139 { .vendor = OCP_VENDOR_IBM,
140 .function = OCP_FUNC_GPIO,
141 .index = 0,
142 .paddr = 0x0000000140000700ULL,
143 .irq = OCP_IRQ_NA,
144 .pm = IBM_CPM_GPIO0,
145 },
146 { .vendor = OCP_VENDOR_IBM,
147 .function = OCP_FUNC_MAL,
148 .paddr = OCP_PADDR_NA,
149 .irq = OCP_IRQ_NA,
150 .pm = OCP_CPM_NA,
151 .additions = &ibm440gx_mal0_def,
152 .show = &ocp_show_mal_data,
153 },
154 { .vendor = OCP_VENDOR_IBM,
155 .function = OCP_FUNC_EMAC,
156 .index = 0,
157 .paddr = 0x0000000140000800ULL,
158 .irq = 60,
159 .pm = OCP_CPM_NA,
160 .additions = &ibm440gx_emac0_def,
161 .show = &ocp_show_emac_data,
162 },
163 { .vendor = OCP_VENDOR_IBM,
164 .function = OCP_FUNC_EMAC,
165 .index = 1,
166 .paddr = 0x0000000140000900ULL,
167 .irq = 62,
168 .pm = OCP_CPM_NA,
169 .additions = &ibm440gx_emac1_def,
170 .show = &ocp_show_emac_data,
171 },
172 { .vendor = OCP_VENDOR_IBM,
173 .function = OCP_FUNC_EMAC,
174 .index = 2,
175 .paddr = 0x0000000140000C00ULL,
176 .irq = 64,
177 .pm = OCP_CPM_NA,
178 .additions = &ibm440gx_emac2_def,
179 .show = &ocp_show_emac_data,
180 },
181 { .vendor = OCP_VENDOR_IBM,
182 .function = OCP_FUNC_EMAC,
183 .index = 3,
184 .paddr = 0x0000000140000E00ULL,
185 .irq = 66,
186 .pm = OCP_CPM_NA,
187 .additions = &ibm440gx_emac3_def,
188 .show = &ocp_show_emac_data,
189 },
190 { .vendor = OCP_VENDOR_IBM,
191 .function = OCP_FUNC_RGMII,
192 .paddr = 0x0000000140000790ULL,
193 .irq = OCP_IRQ_NA,
194 .pm = OCP_CPM_NA,
195 },
196 { .vendor = OCP_VENDOR_IBM,
197 .function = OCP_FUNC_ZMII,
198 .paddr = 0x0000000140000780ULL,
199 .irq = OCP_IRQ_NA,
200 .pm = OCP_CPM_NA,
201 },
202 { .vendor = OCP_VENDOR_IBM,
203 .function = OCP_FUNC_TAH,
204 .index = 0,
205 .paddr = 0x0000000140000b50ULL,
206 .irq = 68,
207 .pm = OCP_CPM_NA,
208 },
209 { .vendor = OCP_VENDOR_IBM,
210 .function = OCP_FUNC_TAH,
211 .index = 1,
212 .paddr = 0x0000000140000d50ULL,
213 .irq = 69,
214 .pm = OCP_CPM_NA,
215 },
216 { .vendor = OCP_VENDOR_INVALID
217 }
218};
219
220/* Polarity and triggering settings for internal interrupt sources */
221struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
222 { .polarity = 0xfffffe03,
223 .triggering = 0x01c00000,
224 .ext_irq_mask = 0x000001fc, /* IRQ0 - IRQ6 */
225 },
226 { .polarity = 0xffffc0ff,
227 .triggering = 0x00ff8000,
228 .ext_irq_mask = 0x00003f00, /* IRQ7 - IRQ12 */
229 },
230 { .polarity = 0xffff83ff,
231 .triggering = 0x000f83c0,
232 .ext_irq_mask = 0x00007c00, /* IRQ13 - IRQ17 */
233 },
234};
diff --git a/arch/ppc/platforms/4xx/ibm440gx.h b/arch/ppc/platforms/4xx/ibm440gx.h
new file mode 100644
index 000000000000..0b59d8dcd03c
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440gx.h
@@ -0,0 +1,74 @@
1/*
2 * arch/ppc/platforms/ibm440gx.h
3 *
4 * PPC440GX definitions
5 *
6 * Matt Porter <mporter@mvista.com>
7 *
8 * Copyright 2002 Roland Dreier
9 * Copyright 2003 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 */
17
18#ifdef __KERNEL__
19#ifndef __PPC_PLATFORMS_IBM440GX_H
20#define __PPC_PLATFORMS_IBM440GX_H
21
22#include <linux/config.h>
23
24#include <asm/ibm44x.h>
25
26/* UART */
27#define PPC440GX_UART0_ADDR 0x0000000140000200ULL
28#define PPC440GX_UART1_ADDR 0x0000000140000300ULL
29#define UART0_INT 0
30#define UART1_INT 1
31
32/* Clock and Power Management */
33#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
34#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
35#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
36#define IBM_CPM_RGMII 0x10000000 /* RGMII */
37#define IBM_CPM_TAHOE0 0x08000000 /* TAHOE 0 */
38#define IBM_CPM_TAHOE1 0x04000000 /* TAHOE 1 */
39#define IBM_CPM_CPU 0x02000000 /* processor core */
40#define IBM_CPM_DMA 0x01000000 /* DMA controller */
41#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
42#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
43#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
44#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
45#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
46#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
47#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
48#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
49#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
50#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
51#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
52#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
53#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
54#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
55#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
56#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */
57#define IBM_CPM_EMAC1 0x00000010 /* EMAC 1 */
58#define IBM_CPM_EMAC2 0x00000008 /* EMAC 2 */
59#define IBM_CPM_EMAC3 0x00000004 /* EMAC 3 */
60
61#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
62 | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
63 | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
64 | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
65 | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
66 | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
67 | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
68/*
69 * Serial port defines
70 */
71#define RS_TABLE_SIZE 2
72
73#endif /* __PPC_PLATFORMS_IBM440GX_H */
74#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
new file mode 100644
index 000000000000..a203efb47aba
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440sp.c
@@ -0,0 +1,131 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440sp.c
3 *
4 * PPC440SP I/O descriptions
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 * Copyright 2002-2005 MontaVista Software Inc.
8 *
9 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
10 * Copyright (c) 2003, 2004 Zultys Technologies
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 */
18#include <linux/init.h>
19#include <linux/module.h>
20#include <platforms/4xx/ibm440sp.h>
21#include <asm/ocp.h>
22
23static struct ocp_func_emac_data ibm440sp_emac0_def = {
24 .rgmii_idx = -1, /* No RGMII */
25 .rgmii_mux = -1, /* No RGMII */
26 .zmii_idx = -1, /* No ZMII */
27 .zmii_mux = -1, /* No ZMII */
28 .mal_idx = 0, /* MAL device index */
29 .mal_rx_chan = 0, /* MAL rx channel number */
30 .mal_tx_chan = 0, /* MAL tx channel number */
31 .wol_irq = 61, /* WOL interrupt number */
32 .mdio_idx = -1, /* No shared MDIO */
33 .tah_idx = -1, /* No TAH */
34 .jumbo = 1, /* Jumbo frames supported */
35};
36OCP_SYSFS_EMAC_DATA()
37
38static struct ocp_func_mal_data ibm440sp_mal0_def = {
39 .num_tx_chans = 4, /* Number of TX channels */
40 .num_rx_chans = 4, /* Number of RX channels */
41 .txeob_irq = 38, /* TX End Of Buffer IRQ */
42 .rxeob_irq = 39, /* RX End Of Buffer IRQ */
43 .txde_irq = 34, /* TX Descriptor Error IRQ */
44 .rxde_irq = 35, /* RX Descriptor Error IRQ */
45 .serr_irq = 33, /* MAL System Error IRQ */
46};
47OCP_SYSFS_MAL_DATA()
48
49static struct ocp_func_iic_data ibm440sp_iic0_def = {
50 .fast_mode = 0, /* Use standad mode (100Khz) */
51};
52
53static struct ocp_func_iic_data ibm440sp_iic1_def = {
54 .fast_mode = 0, /* Use standad mode (100Khz) */
55};
56OCP_SYSFS_IIC_DATA()
57
58struct ocp_def core_ocp[] = {
59 { .vendor = OCP_VENDOR_IBM,
60 .function = OCP_FUNC_OPB,
61 .index = 0,
62 .paddr = 0x0000000140000000ULL,
63 .irq = OCP_IRQ_NA,
64 .pm = OCP_CPM_NA,
65 },
66 { .vendor = OCP_VENDOR_IBM,
67 .function = OCP_FUNC_16550,
68 .index = 0,
69 .paddr = PPC440SP_UART0_ADDR,
70 .irq = UART0_INT,
71 .pm = IBM_CPM_UART0,
72 },
73 { .vendor = OCP_VENDOR_IBM,
74 .function = OCP_FUNC_16550,
75 .index = 1,
76 .paddr = PPC440SP_UART1_ADDR,
77 .irq = UART1_INT,
78 .pm = IBM_CPM_UART1,
79 },
80 { .vendor = OCP_VENDOR_IBM,
81 .function = OCP_FUNC_16550,
82 .index = 2,
83 .paddr = PPC440SP_UART2_ADDR,
84 .irq = UART2_INT,
85 .pm = IBM_CPM_UART2,
86 },
87 { .vendor = OCP_VENDOR_IBM,
88 .function = OCP_FUNC_IIC,
89 .index = 0,
90 .paddr = 0x00000001f0000400ULL,
91 .irq = 2,
92 .pm = IBM_CPM_IIC0,
93 .additions = &ibm440sp_iic0_def,
94 .show = &ocp_show_iic_data
95 },
96 { .vendor = OCP_VENDOR_IBM,
97 .function = OCP_FUNC_IIC,
98 .index = 1,
99 .paddr = 0x00000001f0000500ULL,
100 .irq = 3,
101 .pm = IBM_CPM_IIC1,
102 .additions = &ibm440sp_iic1_def,
103 .show = &ocp_show_iic_data
104 },
105 { .vendor = OCP_VENDOR_IBM,
106 .function = OCP_FUNC_GPIO,
107 .index = 0,
108 .paddr = 0x00000001f0000700ULL,
109 .irq = OCP_IRQ_NA,
110 .pm = IBM_CPM_GPIO0,
111 },
112 { .vendor = OCP_VENDOR_IBM,
113 .function = OCP_FUNC_MAL,
114 .paddr = OCP_PADDR_NA,
115 .irq = OCP_IRQ_NA,
116 .pm = OCP_CPM_NA,
117 .additions = &ibm440sp_mal0_def,
118 .show = &ocp_show_mal_data,
119 },
120 { .vendor = OCP_VENDOR_IBM,
121 .function = OCP_FUNC_EMAC,
122 .index = 0,
123 .paddr = 0x00000001f0000800ULL,
124 .irq = 60,
125 .pm = OCP_CPM_NA,
126 .additions = &ibm440sp_emac0_def,
127 .show = &ocp_show_emac_data,
128 },
129 { .vendor = OCP_VENDOR_INVALID
130 }
131};
diff --git a/arch/ppc/platforms/4xx/ibm440sp.h b/arch/ppc/platforms/4xx/ibm440sp.h
new file mode 100644
index 000000000000..c71e46a18b9e
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440sp.h
@@ -0,0 +1,64 @@
1/*
2 * arch/ppc/platforms/4xx/ibm440sp.h
3 *
4 * PPC440SP definitions
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2004-2005 MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#ifdef __KERNEL__
17#ifndef __PPC_PLATFORMS_IBM440SP_H
18#define __PPC_PLATFORMS_IBM440SP_H
19
20#include <linux/config.h>
21
22#include <asm/ibm44x.h>
23
24/* UART */
25#define PPC440SP_UART0_ADDR 0x00000001f0000200ULL
26#define PPC440SP_UART1_ADDR 0x00000001f0000300ULL
27#define PPC440SP_UART2_ADDR 0x00000001f0000600ULL
28#define UART0_INT 0
29#define UART1_INT 1
30#define UART2_INT 2
31
32/* Clock and Power Management */
33#define IBM_CPM_IIC0 0x80000000 /* IIC interface */
34#define IBM_CPM_IIC1 0x40000000 /* IIC interface */
35#define IBM_CPM_PCI 0x20000000 /* PCI bridge */
36#define IBM_CPM_CPU 0x02000000 /* processor core */
37#define IBM_CPM_DMA 0x01000000 /* DMA controller */
38#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */
39#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */
40#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */
41#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */
42#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */
43#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */
44#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */
45#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */
46#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */
47#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */
48#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */
49#define IBM_CPM_UART0 0x00000200 /* serial port 0 */
50#define IBM_CPM_UART1 0x00000100 /* serial port 1 */
51#define IBM_CPM_UART2 0x00000100 /* serial port 1 */
52#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */
53#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */
54#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */
55
56#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
57 | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
58 | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
59 | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
60 | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
61 | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
62 | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
63#endif /* __PPC_PLATFORMS_IBM440SP_H */
64#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibmnp405h.c b/arch/ppc/platforms/4xx/ibmnp405h.c
new file mode 100644
index 000000000000..ecdc5be6ae28
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmnp405h.c
@@ -0,0 +1,172 @@
1/*
2 * arch/ppc/platforms/4xx/ibmnp405h.c
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2000-2002 (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
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/ocp.h>
15#include <platforms/4xx/ibmnp405h.h>
16
17static struct ocp_func_emac_data ibmnp405h_emac0_def = {
18 .rgmii_idx = -1, /* No RGMII */
19 .rgmii_mux = -1, /* No RGMII */
20 .zmii_idx = 0, /* ZMII device index */
21 .zmii_mux = 0, /* ZMII input of this EMAC */
22 .mal_idx = 0, /* MAL device index */
23 .mal_rx_chan = 0, /* MAL rx channel number */
24 .mal_tx_chan = 0, /* MAL tx channel number */
25 .wol_irq = 41, /* WOL interrupt number */
26 .mdio_idx = -1, /* No shared MDIO */
27 .tah_idx = -1, /* No TAH */
28};
29
30static struct ocp_func_emac_data ibmnp405h_emac1_def = {
31 .rgmii_idx = -1, /* No RGMII */
32 .rgmii_mux = -1, /* No RGMII */
33 .zmii_idx = 0, /* ZMII device index */
34 .zmii_mux = 1, /* ZMII input of this EMAC */
35 .mal_idx = 0, /* MAL device index */
36 .mal_rx_chan = 1, /* MAL rx channel number */
37 .mal_tx_chan = 1, /* MAL tx channel number */
38 .wol_irq = 41, /* WOL interrupt number */
39 .mdio_idx = -1, /* No shared MDIO */
40 .tah_idx = -1, /* No TAH */
41};
42static struct ocp_func_emac_data ibmnp405h_emac2_def = {
43 .rgmii_idx = -1, /* No RGMII */
44 .rgmii_mux = -1, /* No RGMII */
45 .zmii_idx = 0, /* ZMII device index */
46 .zmii_mux = 2, /* ZMII input of this EMAC */
47 .mal_idx = 0, /* MAL device index */
48 .mal_rx_chan = 2, /* MAL rx channel number */
49 .mal_tx_chan = 2, /* MAL tx channel number */
50 .wol_irq = 41, /* WOL interrupt number */
51 .mdio_idx = -1, /* No shared MDIO */
52 .tah_idx = -1, /* No TAH */
53};
54static struct ocp_func_emac_data ibmnp405h_emac3_def = {
55 .rgmii_idx = -1, /* No RGMII */
56 .rgmii_mux = -1, /* No RGMII */
57 .zmii_idx = 0, /* ZMII device index */
58 .zmii_mux = 3, /* ZMII input of this EMAC */
59 .mal_idx = 0, /* MAL device index */
60 .mal_rx_chan = 3, /* MAL rx channel number */
61 .mal_tx_chan = 3, /* MAL tx channel number */
62 .wol_irq = 41, /* WOL interrupt number */
63 .mdio_idx = -1, /* No shared MDIO */
64 .tah_idx = -1, /* No TAH */
65};
66OCP_SYSFS_EMAC_DATA()
67
68static struct ocp_func_mal_data ibmnp405h_mal0_def = {
69 .num_tx_chans = 8, /* Number of TX channels */
70 .num_rx_chans = 4, /* Number of RX channels */
71 .txeob_irq = 17, /* TX End Of Buffer IRQ */
72 .rxeob_irq = 18, /* RX End Of Buffer IRQ */
73 .txde_irq = 46, /* TX Descriptor Error IRQ */
74 .rxde_irq = 47, /* RX Descriptor Error IRQ */
75 .serr_irq = 45, /* MAL System Error IRQ */
76};
77OCP_SYSFS_MAL_DATA()
78
79static struct ocp_func_iic_data ibmnp405h_iic0_def = {
80 .fast_mode = 0, /* Use standad mode (100Khz) */
81};
82OCP_SYSFS_IIC_DATA()
83
84struct ocp_def core_ocp[] = {
85 { .vendor = OCP_VENDOR_IBM,
86 .function = OCP_FUNC_OPB,
87 .index = 0,
88 .paddr = 0xEF600000,
89 .irq = OCP_IRQ_NA,
90 .pm = OCP_CPM_NA,
91 },
92 { .vendor = OCP_VENDOR_IBM,
93 .function = OCP_FUNC_16550,
94 .index = 0,
95 .paddr = UART0_IO_BASE,
96 .irq = UART0_INT,
97 .pm = IBM_CPM_UART0
98 },
99 { .vendor = OCP_VENDOR_IBM,
100 .function = OCP_FUNC_16550,
101 .index = 1,
102 .paddr = UART1_IO_BASE,
103 .irq = UART1_INT,
104 .pm = IBM_CPM_UART1
105 },
106 { .vendor = OCP_VENDOR_IBM,
107 .function = OCP_FUNC_IIC,
108 .paddr = 0xEF600500,
109 .irq = 2,
110 .pm = IBM_CPM_IIC0,
111 .additions = &ibmnp405h_iic0_def,
112 .show = &ocp_show_iic_data
113 },
114 { .vendor = OCP_VENDOR_IBM,
115 .function = OCP_FUNC_GPIO,
116 .paddr = 0xEF600700,
117 .irq = OCP_IRQ_NA,
118 .pm = IBM_CPM_GPIO0
119 },
120 { .vendor = OCP_VENDOR_IBM,
121 .function = OCP_FUNC_MAL,
122 .paddr = OCP_PADDR_NA,
123 .irq = OCP_IRQ_NA,
124 .pm = OCP_CPM_NA,
125 .additions = &ibmnp405h_mal0_def,
126 .show = &ocp_show_mal_data,
127 },
128 { .vendor = OCP_VENDOR_IBM,
129 .function = OCP_FUNC_EMAC,
130 .index = 0,
131 .paddr = EMAC0_BASE,
132 .irq = 37,
133 .pm = IBM_CPM_EMAC0,
134 .additions = &ibmnp405h_emac0_def,
135 .show = &ocp_show_emac_data,
136 },
137 { .vendor = OCP_VENDOR_IBM,
138 .function = OCP_FUNC_EMAC,
139 .index = 1,
140 .paddr = 0xEF600900,
141 .irq = 38,
142 .pm = IBM_CPM_EMAC1,
143 .additions = &ibmnp405h_emac1_def,
144 .show = &ocp_show_emac_data,
145 },
146 { .vendor = OCP_VENDOR_IBM,
147 .function = OCP_FUNC_EMAC,
148 .index = 2,
149 .paddr = 0xEF600a00,
150 .irq = 39,
151 .pm = IBM_CPM_EMAC2,
152 .additions = &ibmnp405h_emac2_def,
153 .show = &ocp_show_emac_data,
154 },
155 { .vendor = OCP_VENDOR_IBM,
156 .function = OCP_FUNC_EMAC,
157 .index = 3,
158 .paddr = 0xEF600b00,
159 .irq = 40,
160 .pm = IBM_CPM_EMAC3,
161 .additions = &ibmnp405h_emac3_def,
162 .show = &ocp_show_emac_data,
163 },
164 { .vendor = OCP_VENDOR_IBM,
165 .function = OCP_FUNC_ZMII,
166 .paddr = 0xEF600C10,
167 .irq = OCP_IRQ_NA,
168 .pm = OCP_CPM_NA,
169 },
170 { .vendor = OCP_VENDOR_INVALID
171 }
172};
diff --git a/arch/ppc/platforms/4xx/ibmnp405h.h b/arch/ppc/platforms/4xx/ibmnp405h.h
new file mode 100644
index 000000000000..e2c2b06128c8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmnp405h.h
@@ -0,0 +1,157 @@
1/*
2 * arch/ppc/platforms/4xx/ibmnp405h.h
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2002 (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
12#ifdef __KERNEL__
13#ifndef __ASM_IBMNP405H_H__
14#define __ASM_IBMNP405H_H__
15
16#include <linux/config.h>
17
18/* ibm405.h at bottom of this file */
19
20#define PPC405_PCI_CONFIG_ADDR 0xeec00000
21#define PPC405_PCI_CONFIG_DATA 0xeec00004
22#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */
23 /* setbat */
24#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */
25#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */
26#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */
27
28#define PPC405_PCI_LOWER_MEM 0x00000000 /* hose_a->mem_space.start */
29#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */
30#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */
31#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */
32
33#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE
34
35#define PPC4xx_PCI_IO_ADDR ((uint)PPC405_PCI_PHY_IO_BASE)
36#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
37#define PPC4xx_PCI_CFG_ADDR ((uint)PPC405_PCI_CONFIG_ADDR)
38#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
39#define PPC4xx_PCI_LCFG_ADDR ((uint)0xef400000)
40#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
41#define PPC4xx_ONB_IO_ADDR ((uint)0xef600000)
42#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
43
44/* serial port defines */
45#define RS_TABLE_SIZE 4
46
47#define UART0_INT 0
48#define UART1_INT 1
49#define PCIL0_BASE 0xEF400000
50#define UART0_IO_BASE 0xEF600300
51#define UART1_IO_BASE 0xEF600400
52#define OPB0_BASE 0xEF600600
53#define EMAC0_BASE 0xEF600800
54
55#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i]
56
57#define STD_UART_OP(num) \
58 { 0, BASE_BAUD, 0, UART##num##_INT, \
59 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
60 iomem_base:(u8 *) UART##num##_IO_BASE, \
61 io_type: SERIAL_IO_MEM},
62
63#if defined(CONFIG_UART0_TTYS0)
64#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
65#define SERIAL_PORT_DFNS \
66 STD_UART_OP(0) \
67 STD_UART_OP(1)
68#endif
69
70#if defined(CONFIG_UART0_TTYS1)
71#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
72#define SERIAL_PORT_DFNS \
73 STD_UART_OP(1) \
74 STD_UART_OP(0)
75#endif
76
77/* DCR defines */
78/* ------------------------------------------------------------------------- */
79
80#define DCRN_CHCR_BASE 0x0F1
81#define DCRN_CHPSR_BASE 0x0B4
82#define DCRN_CPMSR_BASE 0x0BA
83#define DCRN_CPMFR_BASE 0x0B9
84#define DCRN_CPMER_BASE 0x0B8
85
86/* CPM Clocking & Power Mangement defines */
87#define IBM_CPM_PCI 0x40000000 /* PCI */
88#define IBM_CPM_EMAC2 0x20000000 /* EMAC 2 MII */
89#define IBM_CPM_EMAC3 0x04000000 /* EMAC 3 MII */
90#define IBM_CPM_EMAC0 0x00800000 /* EMAC 0 MII */
91#define IBM_CPM_EMAC1 0x00100000 /* EMAC 1 MII */
92#define IBM_CPM_EMMII 0 /* Shift value for MII */
93#define IBM_CPM_EMRX 1 /* Shift value for recv */
94#define IBM_CPM_EMTX 2 /* Shift value for MAC */
95#define IBM_CPM_UIC1 0x00020000 /* Universal Interrupt Controller */
96#define IBM_CPM_UIC0 0x00010000 /* Universal Interrupt Controller */
97#define IBM_CPM_CPU 0x00008000 /* processor core */
98#define IBM_CPM_EBC 0x00004000 /* ROM/SRAM peripheral controller */
99#define IBM_CPM_SDRAM0 0x00002000 /* SDRAM memory controller */
100#define IBM_CPM_GPIO0 0x00001000 /* General Purpose IO (??) */
101#define IBM_CPM_HDLC 0x00000800 /* HDCL */
102#define IBM_CPM_TMRCLK 0x00000400 /* CPU timers */
103#define IBM_CPM_PLB 0x00000100 /* PLB bus arbiter */
104#define IBM_CPM_OPB 0x00000080 /* PLB to OPB bridge */
105#define IBM_CPM_DMA 0x00000040 /* DMA controller */
106#define IBM_CPM_IIC0 0x00000010 /* IIC interface */
107#define IBM_CPM_UART0 0x00000002 /* serial port 0 */
108#define IBM_CPM_UART1 0x00000001 /* serial port 1 */
109/* this is the default setting for devices put to sleep when booting */
110
111#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC0 | IBM_CPM_UIC1 | IBM_CPM_CPU \
112 | IBM_CPM_EBC | IBM_CPM_SDRAM0 | IBM_CPM_PLB \
113 | IBM_CPM_OPB | IBM_CPM_TMRCLK | IBM_CPM_DMA \
114 | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 | IBM_CPM_EMAC2 \
115 | IBM_CPM_EMAC3 | IBM_CPM_PCI)
116
117#define DCRN_DMA0_BASE 0x100
118#define DCRN_DMA1_BASE 0x108
119#define DCRN_DMA2_BASE 0x110
120#define DCRN_DMA3_BASE 0x118
121#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */
122#define DCRN_DMASR_BASE 0x120
123#define DCRN_EBC_BASE 0x012
124#define DCRN_DCP0_BASE 0x014
125#define DCRN_MAL_BASE 0x180
126#define DCRN_OCM0_BASE 0x018
127#define DCRN_PLB0_BASE 0x084
128#define DCRN_PLLMR_BASE 0x0B0
129#define DCRN_POB0_BASE 0x0A0
130#define DCRN_SDRAM0_BASE 0x010
131#define DCRN_UIC0_BASE 0x0C0
132#define DCRN_UIC1_BASE 0x0D0
133#define DCRN_CPC0_EPRCSR 0x0F3
134
135#define UIC0_UIC1NC 0x00000002
136
137#define CHR1_CETE 0x00000004 /* CPU external timer enable */
138#define UIC0 DCRN_UIC0_BASE
139#define UIC1 DCRN_UIC1_BASE
140
141#undef NR_UICS
142#define NR_UICS 2
143
144/* EMAC DCRN's FIXME: armin */
145#define DCRN_MALRXCTP2R(base) ((base) + 0x42) /* Channel Rx 2 Channel Table Pointer */
146#define DCRN_MALRXCTP3R(base) ((base) + 0x43) /* Channel Rx 3 Channel Table Pointer */
147#define DCRN_MALTXCTP4R(base) ((base) + 0x24) /* Channel Tx 4 Channel Table Pointer */
148#define DCRN_MALTXCTP5R(base) ((base) + 0x25) /* Channel Tx 5 Channel Table Pointer */
149#define DCRN_MALTXCTP6R(base) ((base) + 0x26) /* Channel Tx 6 Channel Table Pointer */
150#define DCRN_MALTXCTP7R(base) ((base) + 0x27) /* Channel Tx 7 Channel Table Pointer */
151#define DCRN_MALRCBS2(base) ((base) + 0x62) /* Channel Rx 2 Channel Buffer Size */
152#define DCRN_MALRCBS3(base) ((base) + 0x63) /* Channel Rx 3 Channel Buffer Size */
153
154#include <asm/ibm405.h>
155
156#endif /* __ASM_IBMNP405H_H__ */
157#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
new file mode 100644
index 000000000000..874d16bab73c
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmstb4.c
@@ -0,0 +1,83 @@
1/*
2 * arch/ppc/platforms/4xx/ibmstb4.c
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2000-2001 (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
12#include <linux/init.h>
13#include <asm/ocp.h>
14#include <platforms/4xx/ibmstb4.h>
15
16static struct ocp_func_iic_data ibmstb4_iic0_def = {
17 .fast_mode = 0, /* Use standad mode (100Khz) */
18};
19
20static struct ocp_func_iic_data ibmstb4_iic1_def = {
21 .fast_mode = 0, /* Use standad mode (100Khz) */
22};
23OCP_SYSFS_IIC_DATA()
24
25struct ocp_def core_ocp[] __initdata = {
26 { .vendor = OCP_VENDOR_IBM,
27 .function = OCP_FUNC_16550,
28 .index = 0,
29 .paddr = UART0_IO_BASE,
30 .irq = UART0_INT,
31 .pm = IBM_CPM_UART0,
32 },
33 { .vendor = OCP_VENDOR_IBM,
34 .function = OCP_FUNC_16550,
35 .index = 1,
36 .paddr = UART1_IO_BASE,
37 .irq = UART1_INT,
38 .pm = IBM_CPM_UART1,
39 },
40 { .vendor = OCP_VENDOR_IBM,
41 .function = OCP_FUNC_16550,
42 .index = 2,
43 .paddr = UART2_IO_BASE,
44 .irq = UART2_INT,
45 .pm = IBM_CPM_UART2,
46 },
47 { .vendor = OCP_VENDOR_IBM,
48 .function = OCP_FUNC_IIC,
49 .paddr = IIC0_BASE,
50 .irq = IIC0_IRQ,
51 .pm = IBM_CPM_IIC0,
52 .additions = &ibmstb4_iic0_def,
53 .show = &ocp_show_iic_data
54 },
55 { .vendor = OCP_VENDOR_IBM,
56 .function = OCP_FUNC_IIC,
57 .paddr = IIC1_BASE,
58 .irq = IIC1_IRQ,
59 .pm = IBM_CPM_IIC1,
60 .additions = &ibmstb4_iic1_def,
61 .show = &ocp_show_iic_data
62 },
63 { .vendor = OCP_VENDOR_IBM,
64 .function = OCP_FUNC_GPIO,
65 .paddr = GPIO0_BASE,
66 .irq = OCP_IRQ_NA,
67 .pm = IBM_CPM_GPIO0,
68 },
69 { .vendor = OCP_VENDOR_IBM,
70 .function = OCP_FUNC_IDE,
71 .paddr = IDE0_BASE,
72 .irq = IDE0_IRQ,
73 .pm = OCP_CPM_NA,
74 },
75 { .vendor = OCP_VENDOR_IBM,
76 .function = OCP_FUNC_USB,
77 .paddr = USB0_BASE,
78 .irq = USB0_IRQ,
79 .pm = OCP_CPM_NA,
80 },
81 { .vendor = OCP_VENDOR_INVALID,
82 }
83};
diff --git a/arch/ppc/platforms/4xx/ibmstb4.h b/arch/ppc/platforms/4xx/ibmstb4.h
new file mode 100644
index 000000000000..bcb4b1ee71f2
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmstb4.h
@@ -0,0 +1,238 @@
1/*
2 * arch/ppc/platforms/4xx/ibmstb4.h
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2001 (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
12#ifdef __KERNEL__
13#ifndef __ASM_IBMSTB4_H__
14#define __ASM_IBMSTB4_H__
15
16#include <linux/config.h>
17
18/* serial port defines */
19#define STB04xxx_IO_BASE ((uint)0xe0000000)
20#define PPC4xx_PCI_IO_ADDR STB04xxx_IO_BASE
21#define PPC4xx_ONB_IO_PADDR STB04xxx_IO_BASE
22#define PPC4xx_ONB_IO_VADDR ((uint)0xe0000000)
23#define PPC4xx_ONB_IO_SIZE ((uint)14*64*1024)
24
25/*
26 * map STB04xxx internal i/o address (0x400x00xx) to an address
27 * which is below the 2GB limit...
28 *
29 * 4000 000x uart1 -> 0xe000 000x
30 * 4001 00xx ppu
31 * 4002 00xx smart card
32 * 4003 000x iic
33 * 4004 000x uart0
34 * 4005 0xxx timer
35 * 4006 00xx gpio
36 * 4007 00xx smart card
37 * 400b 000x iic
38 * 400c 000x scp
39 * 400d 000x modem
40 * 400e 000x uart2
41*/
42#define STB04xxx_MAP_IO_ADDR(a) (((uint)(a)) + (STB04xxx_IO_BASE - 0x40000000))
43
44#define RS_TABLE_SIZE 3
45#define UART0_INT 20
46
47#ifdef __BOOTER__
48#define UART0_IO_BASE 0x40040000
49#else
50#define UART0_IO_BASE 0xe0040000
51#endif
52
53#define UART1_INT 21
54
55#ifdef __BOOTER__
56#define UART1_IO_BASE 0x40000000
57#else
58#define UART1_IO_BASE 0xe0000000
59#endif
60
61#define UART2_INT 31
62#ifdef __BOOTER__
63#define UART2_IO_BASE 0x400e0000
64#else
65#define UART2_IO_BASE 0xe00e0000
66#endif
67
68#define IDE0_BASE 0x400F0000
69#define IDE0_SIZE 0x200
70#define IDE0_IRQ 25
71#define IIC0_BASE 0x40030000
72#define IIC1_BASE 0x400b0000
73#define OPB0_BASE 0x40000000
74#define GPIO0_BASE 0x40060000
75
76#define USB0_IRQ 18
77#define USB0_BASE STB04xxx_MAP_IO_ADDR(0x40010000)
78#define USB0_EXTENT 4096
79
80#define IIC_NUMS 2
81#define UART_NUMS 3
82#define IIC0_IRQ 9
83#define IIC1_IRQ 10
84#define IIC_OWN 0x55
85#define IIC_CLOCK 50
86
87#define BD_EMAC_ADDR(e,i) bi_enetaddr[i]
88
89#define STD_UART_OP(num) \
90 { 0, BASE_BAUD, 0, UART##num##_INT, \
91 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
92 iomem_base: (u8 *)UART##num##_IO_BASE, \
93 io_type: SERIAL_IO_MEM},
94
95#if defined(CONFIG_UART0_TTYS0)
96#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
97#define SERIAL_PORT_DFNS \
98 STD_UART_OP(0) \
99 STD_UART_OP(1) \
100 STD_UART_OP(2)
101#endif
102
103#if defined(CONFIG_UART0_TTYS1)
104#define SERIAL_DEBUG_IO_BASE UART2_IO_BASE
105#define SERIAL_PORT_DFNS \
106 STD_UART_OP(1) \
107 STD_UART_OP(0) \
108 STD_UART_OP(2)
109#endif
110
111#if defined(CONFIG_UART0_TTYS2)
112#define SERIAL_DEBUG_IO_BASE UART2_IO_BASE
113#define SERIAL_PORT_DFNS \
114 STD_UART_OP(2) \
115 STD_UART_OP(0) \
116 STD_UART_OP(1)
117#endif
118
119#define DCRN_BE_BASE 0x090
120#define DCRN_DMA0_BASE 0x0C0
121#define DCRN_DMA1_BASE 0x0C8
122#define DCRN_DMA2_BASE 0x0D0
123#define DCRN_DMA3_BASE 0x0D8
124#define DCRNCAP_DMA_CC 1 /* have DMA chained count capability */
125#define DCRN_DMASR_BASE 0x0E0
126#define DCRN_PLB0_BASE 0x054
127#define DCRN_PLB1_BASE 0x064
128#define DCRN_POB0_BASE 0x0B0
129#define DCRN_SCCR_BASE 0x120
130#define DCRN_UIC0_BASE 0x040
131#define DCRN_BE_BASE 0x090
132#define DCRN_DMA0_BASE 0x0C0
133#define DCRN_DMA1_BASE 0x0C8
134#define DCRN_DMA2_BASE 0x0D0
135#define DCRN_DMA3_BASE 0x0D8
136#define DCRN_CIC_BASE 0x030
137#define DCRN_DMASR_BASE 0x0E0
138#define DCRN_EBIMC_BASE 0x070
139#define DCRN_DCRX_BASE 0x020
140#define DCRN_CPMFR_BASE 0x102
141#define DCRN_SCCR_BASE 0x120
142#define UIC0 DCRN_UIC0_BASE
143
144#define IBM_CPM_IIC0 0x80000000 /* IIC 0 interface */
145#define IBM_CPM_USB0 0x40000000 /* IEEE-1284 */
146#define IBM_CPM_IIC1 0x20000000 /* IIC 1 interface */
147#define IBM_CPM_CPU 0x10000000 /* PPC405B3 clock control */
148#define IBM_CPM_AUD 0x08000000 /* Audio Decoder */
149#define IBM_CPM_EBIU 0x04000000 /* External Bus Interface Unit */
150#define IBM_CPM_SDRAM1 0x02000000 /* SDRAM 1 memory controller */
151#define IBM_CPM_DMA 0x01000000 /* DMA controller */
152#define IBM_CPM_DMA1 0x00800000 /* reserved */
153#define IBM_CPM_XPT1 0x00400000 /* reserved */
154#define IBM_CPM_XPT2 0x00200000 /* reserved */
155#define IBM_CPM_UART1 0x00100000 /* Serial 1 / Infrared */
156#define IBM_CPM_UART0 0x00080000 /* Serial 0 / 16550 */
157#define IBM_CPM_EPI 0x00040000 /* DCR Extension */
158#define IBM_CPM_SC0 0x00020000 /* Smart Card 0 */
159#define IBM_CPM_VID 0x00010000 /* reserved */
160#define IBM_CPM_SC1 0x00008000 /* Smart Card 1 */
161#define IBM_CPM_USBSDRA 0x00004000 /* SDRAM 0 memory controller */
162#define IBM_CPM_XPT0 0x00002000 /* Transport - 54 Mhz */
163#define IBM_CPM_CBS 0x00001000 /* Cross Bar Switch */
164#define IBM_CPM_GPT 0x00000800 /* GPTPWM */
165#define IBM_CPM_GPIO0 0x00000400 /* General Purpose IO 0 */
166#define IBM_CPM_DENC 0x00000200 /* Digital video Encoder */
167#define IBM_CPM_TMRCLK 0x00000100 /* CPU timers */
168#define IBM_CPM_XPT27 0x00000080 /* Transport - 27 Mhz */
169#define IBM_CPM_UIC 0x00000040 /* Universal Interrupt Controller */
170#define IBM_CPM_SSP 0x00000010 /* Modem Serial Interface (SSP) */
171#define IBM_CPM_UART2 0x00000008 /* Serial Control Port */
172#define IBM_CPM_DDIO 0x00000004 /* Descrambler */
173#define IBM_CPM_VID2 0x00000002 /* Video Decoder clock domain 2 */
174
175#define DFLT_IBM4xx_PM ~(IBM_CPM_CPU | IBM_CPM_EBIU | IBM_CPM_SDRAM1 \
176 | IBM_CPM_DMA | IBM_CPM_DMA1 | IBM_CPM_CBS \
177 | IBM_CPM_USBSDRA | IBM_CPM_XPT0 | IBM_CPM_TMRCLK \
178 | IBM_CPM_XPT27 | IBM_CPM_UIC )
179
180#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */
181#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register */
182/* DCRN_BESR */
183#define BESR_DSES 0x80000000 /* Data-Side Error Status */
184#define BESR_DMES 0x40000000 /* DMA Error Status */
185#define BESR_RWS 0x20000000 /* Read/Write Status */
186#define BESR_ETMASK 0x1C000000 /* Error Type */
187#define ET_PROT 0
188#define ET_PARITY 1
189#define ET_NCFG 2
190#define ET_BUSERR 4
191#define ET_BUSTO 6
192
193#define CHR1_CETE 0x00800000 /* CPU external timer enable */
194#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */
195
196#define DCRN_CICCR (DCRN_CIC_BASE + 0x0) /* CIC Control Register */
197#define DCRN_DMAS1 (DCRN_CIC_BASE + 0x1) /* DMA Select1 Register */
198#define DCRN_DMAS2 (DCRN_CIC_BASE + 0x2) /* DMA Select2 Register */
199#define DCRN_CICVCR (DCRN_CIC_BASE + 0x3) /* CIC Video COntro Register */
200#define DCRN_CICSEL3 (DCRN_CIC_BASE + 0x5) /* CIC Select 3 Register */
201#define DCRN_SGPO (DCRN_CIC_BASE + 0x6) /* CIC GPIO Output Register */
202#define DCRN_SGPOD (DCRN_CIC_BASE + 0x7) /* CIC GPIO OD Register */
203#define DCRN_SGPTC (DCRN_CIC_BASE + 0x8) /* CIC GPIO Tristate Ctrl Reg */
204#define DCRN_SGPI (DCRN_CIC_BASE + 0x9) /* CIC GPIO Input Reg */
205
206#define DCRN_DCRXICR (DCRN_DCRX_BASE + 0x0) /* Internal Control Register */
207#define DCRN_DCRXISR (DCRN_DCRX_BASE + 0x1) /* Internal Status Register */
208#define DCRN_DCRXECR (DCRN_DCRX_BASE + 0x2) /* External Control Register */
209#define DCRN_DCRXESR (DCRN_DCRX_BASE + 0x3) /* External Status Register */
210#define DCRN_DCRXTAR (DCRN_DCRX_BASE + 0x4) /* Target Address Register */
211#define DCRN_DCRXTDR (DCRN_DCRX_BASE + 0x5) /* Target Data Register */
212#define DCRN_DCRXIGR (DCRN_DCRX_BASE + 0x6) /* Interrupt Generation Register */
213#define DCRN_DCRXBCR (DCRN_DCRX_BASE + 0x7) /* Line Buffer Control Register */
214
215#define DCRN_BRCRH0 (DCRN_EBIMC_BASE + 0x0) /* Bus Region Config High 0 */
216#define DCRN_BRCRH1 (DCRN_EBIMC_BASE + 0x1) /* Bus Region Config High 1 */
217#define DCRN_BRCRH2 (DCRN_EBIMC_BASE + 0x2) /* Bus Region Config High 2 */
218#define DCRN_BRCRH3 (DCRN_EBIMC_BASE + 0x3) /* Bus Region Config High 3 */
219#define DCRN_BRCRH4 (DCRN_EBIMC_BASE + 0x4) /* Bus Region Config High 4 */
220#define DCRN_BRCRH5 (DCRN_EBIMC_BASE + 0x5) /* Bus Region Config High 5 */
221#define DCRN_BRCRH6 (DCRN_EBIMC_BASE + 0x6) /* Bus Region Config High 6 */
222#define DCRN_BRCRH7 (DCRN_EBIMC_BASE + 0x7) /* Bus Region Config High 7 */
223#define DCRN_BRCR0 (DCRN_EBIMC_BASE + 0x10) /* BRC 0 */
224#define DCRN_BRCR1 (DCRN_EBIMC_BASE + 0x11) /* BRC 1 */
225#define DCRN_BRCR2 (DCRN_EBIMC_BASE + 0x12) /* BRC 2 */
226#define DCRN_BRCR3 (DCRN_EBIMC_BASE + 0x13) /* BRC 3 */
227#define DCRN_BRCR4 (DCRN_EBIMC_BASE + 0x14) /* BRC 4 */
228#define DCRN_BRCR5 (DCRN_EBIMC_BASE + 0x15) /* BRC 5 */
229#define DCRN_BRCR6 (DCRN_EBIMC_BASE + 0x16) /* BRC 6 */
230#define DCRN_BRCR7 (DCRN_EBIMC_BASE + 0x17) /* BRC 7 */
231#define DCRN_BEAR0 (DCRN_EBIMC_BASE + 0x20) /* Bus Error Address Register */
232#define DCRN_BESR0 (DCRN_EBIMC_BASE + 0x21) /* Bus Error Status Register */
233#define DCRN_BIUCR (DCRN_EBIMC_BASE + 0x2A) /* Bus Interfac Unit Ctrl Reg */
234
235#include <asm/ibm405.h>
236
237#endif /* __ASM_IBMSTB4_H__ */
238#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibmstbx25.c b/arch/ppc/platforms/4xx/ibmstbx25.c
new file mode 100644
index 000000000000..b895b9cca57d
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmstbx25.c
@@ -0,0 +1,68 @@
1/*
2 * arch/ppc/platforms/4xx/ibmstbx25.c
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2000-2002 (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
12#include <linux/init.h>
13#include <asm/ocp.h>
14#include <platforms/4xx/ibmstbx25.h>
15#include <asm/ppc4xx_pic.h>
16
17static struct ocp_func_iic_data ibmstbx25_iic0_def = {
18 .fast_mode = 0, /* Use standad mode (100Khz) */
19};
20OCP_SYSFS_IIC_DATA()
21
22struct ocp_def core_ocp[] __initdata = {
23 { .vendor = OCP_VENDOR_IBM,
24 .function = OCP_FUNC_16550,
25 .index = 0,
26 .paddr = UART0_IO_BASE,
27 .irq = UART0_INT,
28 .pm = IBM_CPM_UART0,
29 },
30 { .vendor = OCP_VENDOR_IBM,
31 .function = OCP_FUNC_16550,
32 .index = 1,
33 .paddr = UART1_IO_BASE,
34 .irq = UART1_INT,
35 .pm = IBM_CPM_UART1,
36 },
37 { .vendor = OCP_VENDOR_IBM,
38 .function = OCP_FUNC_16550,
39 .index = 2,
40 .paddr = UART2_IO_BASE,
41 .irq = UART2_INT,
42 .pm = IBM_CPM_UART2,
43 },
44 { .vendor = OCP_VENDOR_IBM,
45 .function = OCP_FUNC_IIC,
46 .paddr = IIC0_BASE,
47 .irq = IIC0_IRQ,
48 .pm = IBM_CPM_IIC0,
49 .additions = &ibmstbx25_iic0_def,
50 .show = &ocp_show_iic_data
51 },
52 { .vendor = OCP_VENDOR_IBM,
53 .function = OCP_FUNC_GPIO,
54 .paddr = GPIO0_BASE,
55 .irq = OCP_IRQ_NA,
56 .pm = IBM_CPM_GPIO0,
57 },
58 { .vendor = OCP_VENDOR_INVALID
59 }
60};
61
62/* Polarity and triggering settings for internal interrupt sources */
63struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
64 { .polarity = 0xffff8f80,
65 .triggering = 0x00000000,
66 .ext_irq_mask = 0x0000707f, /* IRQ7 - IRQ9, IRQ0 - IRQ6 */
67 }
68};
diff --git a/arch/ppc/platforms/4xx/ibmstbx25.h b/arch/ppc/platforms/4xx/ibmstbx25.h
new file mode 100644
index 000000000000..9a2efc366e9c
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibmstbx25.h
@@ -0,0 +1,261 @@
1/*
2 * arch/ppc/platforms/4xx/ibmstbx25.h
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2002 (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
12#ifdef __KERNEL__
13#ifndef __ASM_IBMSTBX25_H__
14#define __ASM_IBMSTBX25_H__
15
16#include <linux/config.h>
17
18/* serial port defines */
19#define STBx25xx_IO_BASE ((uint)0xe0000000)
20#define PPC4xx_ONB_IO_PADDR STBx25xx_IO_BASE
21#define PPC4xx_ONB_IO_VADDR ((uint)0xe0000000)
22#define PPC4xx_ONB_IO_SIZE ((uint)14*64*1024)
23
24/*
25 * map STBxxxx internal i/o address (0x400x00xx) to an address
26 * which is below the 2GB limit...
27 *
28 * 4000 000x uart1 -> 0xe000 000x
29 * 4001 00xx uart2
30 * 4002 00xx smart card
31 * 4003 000x iic
32 * 4004 000x uart0
33 * 4005 0xxx timer
34 * 4006 00xx gpio
35 * 4007 00xx smart card
36 * 400b 000x iic
37 * 400c 000x scp
38 * 400d 000x modem
39 * 400e 000x uart2
40*/
41#define STBx25xx_MAP_IO_ADDR(a) (((uint)(a)) + (STBx25xx_IO_BASE - 0x40000000))
42
43#define RS_TABLE_SIZE 3
44
45#define OPB_BASE_START 0x40000000
46#define EBIU_BASE_START 0xF0100000
47#define DCR_BASE_START 0x0000
48
49#ifdef __BOOTER__
50#define UART1_IO_BASE 0x40000000
51#define UART2_IO_BASE 0x40010000
52#else
53#define UART1_IO_BASE 0xe0000000
54#define UART2_IO_BASE 0xe0010000
55#endif
56#define SC0_BASE 0x40020000 /* smart card #0 */
57#define IIC0_BASE 0x40030000
58#ifdef __BOOTER__
59#define UART0_IO_BASE 0x40040000
60#else
61#define UART0_IO_BASE 0xe0040000
62#endif
63#define SCC0_BASE 0x40040000 /* Serial 0 controller IrdA */
64#define GPT0_BASE 0x40050000 /* General purpose timers */
65#define GPIO0_BASE 0x40060000
66#define SC1_BASE 0x40070000 /* smart card #1 */
67#define SCP0_BASE 0x400C0000 /* Serial Controller Port */
68#define SSP0_BASE 0x400D0000 /* Sync serial port */
69
70#define IDE0_BASE 0xf0100000
71#define REDWOOD_IDE_CTRL 0xf1100000
72
73#define RTCFPC_IRQ 0
74#define XPORT_IRQ 1
75#define AUD_IRQ 2
76#define AID_IRQ 3
77#define DMA0 4
78#define DMA1_IRQ 5
79#define DMA2_IRQ 6
80#define DMA3_IRQ 7
81#define SC0_IRQ 8
82#define IIC0_IRQ 9
83#define IIR0_IRQ 10
84#define GPT0_IRQ 11
85#define GPT1_IRQ 12
86#define SCP0_IRQ 13
87#define SSP0_IRQ 14
88#define GPT2_IRQ 15 /* count down timer */
89#define SC1_IRQ 16
90/* IRQ 17 - 19 external */
91#define UART0_INT 20
92#define UART1_INT 21
93#define UART2_INT 22
94#define XPTDMA_IRQ 23
95#define DCRIDE_IRQ 24
96/* IRQ 25 - 30 external */
97#define IDE0_IRQ 26
98
99#define IIC_NUMS 1
100#define UART_NUMS 3
101#define IIC_OWN 0x55
102#define IIC_CLOCK 50
103
104#define BD_EMAC_ADDR(e,i) bi_enetaddr[i]
105
106#define STD_UART_OP(num) \
107 { 0, BASE_BAUD, 0, UART##num##_INT, \
108 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
109 iomem_base: (u8 *)UART##num##_IO_BASE, \
110 io_type: SERIAL_IO_MEM},
111
112#if defined(CONFIG_UART0_TTYS0)
113#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
114#define SERIAL_PORT_DFNS \
115 STD_UART_OP(0) \
116 STD_UART_OP(1) \
117 STD_UART_OP(2)
118#endif
119
120#if defined(CONFIG_UART0_TTYS1)
121#define SERIAL_DEBUG_IO_BASE UART2_IO_BASE
122#define SERIAL_PORT_DFNS \
123 STD_UART_OP(1) \
124 STD_UART_OP(0) \
125 STD_UART_OP(2)
126#endif
127
128#if defined(CONFIG_UART0_TTYS2)
129#define SERIAL_DEBUG_IO_BASE UART2_IO_BASE
130#define SERIAL_PORT_DFNS \
131 STD_UART_OP(2) \
132 STD_UART_OP(0) \
133 STD_UART_OP(1)
134#endif
135
136#define DCRN_BE_BASE 0x090
137#define DCRN_DMA0_BASE 0x0C0
138#define DCRN_DMA1_BASE 0x0C8
139#define DCRN_DMA2_BASE 0x0D0
140#define DCRN_DMA3_BASE 0x0D8
141#define DCRNCAP_DMA_CC 1 /* have DMA chained count capability */
142#define DCRN_DMASR_BASE 0x0E0
143#define DCRN_PLB0_BASE 0x054
144#define DCRN_PLB1_BASE 0x064
145#define DCRN_POB0_BASE 0x0B0
146#define DCRN_SCCR_BASE 0x120
147#define DCRN_UIC0_BASE 0x040
148#define DCRN_BE_BASE 0x090
149#define DCRN_DMA0_BASE 0x0C0
150#define DCRN_DMA1_BASE 0x0C8
151#define DCRN_DMA2_BASE 0x0D0
152#define DCRN_DMA3_BASE 0x0D8
153#define DCRN_CIC_BASE 0x030
154#define DCRN_DMASR_BASE 0x0E0
155#define DCRN_EBIMC_BASE 0x070
156#define DCRN_DCRX_BASE 0x020
157#define DCRN_CPMFR_BASE 0x102
158#define DCRN_SCCR_BASE 0x120
159#define DCRN_RTCFP_BASE 0x310
160
161#define UIC0 DCRN_UIC0_BASE
162
163#define IBM_CPM_IIC0 0x80000000 /* IIC 0 interface */
164#define IBM_CPM_CPU 0x10000000 /* PPC405B3 clock control */
165#define IBM_CPM_AUD 0x08000000 /* Audio Decoder */
166#define IBM_CPM_EBIU 0x04000000 /* External Bus Interface Unit */
167#define IBM_CPM_IRR 0x02000000 /* Infrared receiver */
168#define IBM_CPM_DMA 0x01000000 /* DMA controller */
169#define IBM_CPM_UART2 0x00200000 /* Serial Control Port */
170#define IBM_CPM_UART1 0x00100000 /* Serial 1 / Infrared */
171#define IBM_CPM_UART0 0x00080000 /* Serial 0 / 16550 */
172#define IBM_PM_DCRIDE 0x00040000 /* DCR timeout & IDE line Mode clock */
173#define IBM_CPM_SC0 0x00020000 /* Smart Card 0 */
174#define IBM_CPM_VID 0x00010000 /* reserved */
175#define IBM_CPM_SC1 0x00008000 /* Smart Card 0 */
176#define IBM_CPM_XPT0 0x00002000 /* Transport - 54 Mhz */
177#define IBM_CPM_CBS 0x00001000 /* Cross Bar Switch */
178#define IBM_CPM_GPT 0x00000800 /* GPTPWM */
179#define IBM_CPM_GPIO0 0x00000400 /* General Purpose IO 0 */
180#define IBM_CPM_DENC 0x00000200 /* Digital video Encoder */
181#define IBM_CPM_C405T 0x00000100 /* CPU timers */
182#define IBM_CPM_XPT27 0x00000080 /* Transport - 27 Mhz */
183#define IBM_CPM_UIC 0x00000040 /* Universal Interrupt Controller */
184#define IBM_CPM_RTCFPC 0x00000020 /* Realtime clock and front panel */
185#define IBM_CPM_SSP 0x00000010 /* Modem Serial Interface (SSP) */
186#define IBM_CPM_VID2 0x00000002 /* Video Decoder clock domain 2 */
187#define DFLT_IBM4xx_PM ~(IBM_CPM_CPU | IBM_CPM_EBIU | IBM_CPM_DMA \
188 | IBM_CPM_CBS | IBM_CPM_XPT0 | IBM_CPM_C405T \
189 | IBM_CPM_XPT27 | IBM_CPM_UIC)
190
191#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */
192#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register */
193/* DCRN_BESR */
194#define BESR_DSES 0x80000000 /* Data-Side Error Status */
195#define BESR_DMES 0x40000000 /* DMA Error Status */
196#define BESR_RWS 0x20000000 /* Read/Write Status */
197#define BESR_ETMASK 0x1C000000 /* Error Type */
198#define ET_PROT 0
199#define ET_PARITY 1
200#define ET_NCFG 2
201#define ET_BUSERR 4
202#define ET_BUSTO 6
203
204#define CHR1_CETE 0x00800000 /* CPU external timer enable */
205#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */
206
207#define DCRN_CICCR (DCRN_CIC_BASE + 0x0) /* CIC Control Register */
208#define DCRN_DMAS1 (DCRN_CIC_BASE + 0x1) /* DMA Select1 Register */
209#define DCRN_DMAS2 (DCRN_CIC_BASE + 0x2) /* DMA Select2 Register */
210#define DCRN_CICVCR (DCRN_CIC_BASE + 0x3) /* CIC Video COntro Register */
211#define DCRN_CICSEL3 (DCRN_CIC_BASE + 0x5) /* CIC Select 3 Register */
212#define DCRN_SGPO (DCRN_CIC_BASE + 0x6) /* CIC GPIO Output Register */
213#define DCRN_SGPOD (DCRN_CIC_BASE + 0x7) /* CIC GPIO OD Register */
214#define DCRN_SGPTC (DCRN_CIC_BASE + 0x8) /* CIC GPIO Tristate Ctrl Reg */
215#define DCRN_SGPI (DCRN_CIC_BASE + 0x9) /* CIC GPIO Input Reg */
216
217#define DCRN_DCRXICR (DCRN_DCRX_BASE + 0x0) /* Internal Control Register */
218#define DCRN_DCRXISR (DCRN_DCRX_BASE + 0x1) /* Internal Status Register */
219#define DCRN_DCRXECR (DCRN_DCRX_BASE + 0x2) /* External Control Register */
220#define DCRN_DCRXESR (DCRN_DCRX_BASE + 0x3) /* External Status Register */
221#define DCRN_DCRXTAR (DCRN_DCRX_BASE + 0x4) /* Target Address Register */
222#define DCRN_DCRXTDR (DCRN_DCRX_BASE + 0x5) /* Target Data Register */
223#define DCRN_DCRXIGR (DCRN_DCRX_BASE + 0x6) /* Interrupt Generation Register */
224#define DCRN_DCRXBCR (DCRN_DCRX_BASE + 0x7) /* Line Buffer Control Register */
225
226#define DCRN_BRCRH0 (DCRN_EBIMC_BASE + 0x0) /* Bus Region Config High 0 */
227#define DCRN_BRCRH1 (DCRN_EBIMC_BASE + 0x1) /* Bus Region Config High 1 */
228#define DCRN_BRCRH2 (DCRN_EBIMC_BASE + 0x2) /* Bus Region Config High 2 */
229#define DCRN_BRCRH3 (DCRN_EBIMC_BASE + 0x3) /* Bus Region Config High 3 */
230#define DCRN_BRCRH4 (DCRN_EBIMC_BASE + 0x4) /* Bus Region Config High 4 */
231#define DCRN_BRCRH5 (DCRN_EBIMC_BASE + 0x5) /* Bus Region Config High 5 */
232#define DCRN_BRCRH6 (DCRN_EBIMC_BASE + 0x6) /* Bus Region Config High 6 */
233#define DCRN_BRCRH7 (DCRN_EBIMC_BASE + 0x7) /* Bus Region Config High 7 */
234#define DCRN_BRCR0 (DCRN_EBIMC_BASE + 0x10) /* BRC 0 */
235#define DCRN_BRCR1 (DCRN_EBIMC_BASE + 0x11) /* BRC 1 */
236#define DCRN_BRCR2 (DCRN_EBIMC_BASE + 0x12) /* BRC 2 */
237#define DCRN_BRCR3 (DCRN_EBIMC_BASE + 0x13) /* BRC 3 */
238#define DCRN_BRCR4 (DCRN_EBIMC_BASE + 0x14) /* BRC 4 */
239#define DCRN_BRCR5 (DCRN_EBIMC_BASE + 0x15) /* BRC 5 */
240#define DCRN_BRCR6 (DCRN_EBIMC_BASE + 0x16) /* BRC 6 */
241#define DCRN_BRCR7 (DCRN_EBIMC_BASE + 0x17) /* BRC 7 */
242#define DCRN_BEAR0 (DCRN_EBIMC_BASE + 0x20) /* Bus Error Address Register */
243#define DCRN_BESR0 (DCRN_EBIMC_BASE + 0x21) /* Bus Error Status Register */
244#define DCRN_BIUCR (DCRN_EBIMC_BASE + 0x2A) /* Bus Interfac Unit Ctrl Reg */
245
246#define DCRN_RTC_FPC0_CNTL (DCRN_RTCFP_BASE + 0x00) /* RTC cntl */
247#define DCRN_RTC_FPC0_INT (DCRN_RTCFP_BASE + 0x01) /* RTC Interrupt */
248#define DCRN_RTC_FPC0_TIME (DCRN_RTCFP_BASE + 0x02) /* RTC time reg */
249#define DCRN_RTC_FPC0_ALRM (DCRN_RTCFP_BASE + 0x03) /* RTC Alarm reg */
250#define DCRN_RTC_FPC0_D1 (DCRN_RTCFP_BASE + 0x04) /* LED Data 1 */
251#define DCRN_RTC_FPC0_D2 (DCRN_RTCFP_BASE + 0x05) /* LED Data 2 */
252#define DCRN_RTC_FPC0_D3 (DCRN_RTCFP_BASE + 0x06) /* LED Data 3 */
253#define DCRN_RTC_FPC0_D4 (DCRN_RTCFP_BASE + 0x07) /* LED Data 4 */
254#define DCRN_RTC_FPC0_D5 (DCRN_RTCFP_BASE + 0x08) /* LED Data 5 */
255#define DCRN_RTC_FPC0_FCNTL (DCRN_RTCFP_BASE + 0x09) /* LED control */
256#define DCRN_RTC_FPC0_BRT (DCRN_RTCFP_BASE + 0x0A) /* Brightness cntl */
257
258#include <asm/ibm405.h>
259
260#endif /* __ASM_IBMSTBX25_H__ */
261#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
new file mode 100644
index 000000000000..1df2339f1f6c
--- /dev/null
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -0,0 +1,387 @@
1/*
2 * arch/ppc/platforms/4xx/luan.c
3 *
4 * Luan board specific routines
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/types.h>
25#include <linux/major.h>
26#include <linux/blkdev.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/ide.h>
30#include <linux/initrd.h>
31#include <linux/irq.h>
32#include <linux/seq_file.h>
33#include <linux/root_dev.h>
34#include <linux/tty.h>
35#include <linux/serial.h>
36#include <linux/serial_core.h>
37
38#include <asm/system.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <asm/dma.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/ocp.h>
45#include <asm/pci-bridge.h>
46#include <asm/time.h>
47#include <asm/todc.h>
48#include <asm/bootinfo.h>
49#include <asm/ppc4xx_pic.h>
50#include <asm/ppcboot.h>
51
52#include <syslib/ibm44x_common.h>
53#include <syslib/ibm440gx_common.h>
54#include <syslib/ibm440sp_common.h>
55
56/*
57 * This is a horrible kludge, we eventually need to abstract this
58 * generic PHY stuff, so the standard phy mode defines can be
59 * easily used from arch code.
60 */
61#include "../../../../drivers/net/ibm_emac/ibm_emac_phy.h"
62
63bd_t __res;
64
65static struct ibm44x_clocks clocks __initdata;
66
67static void __init
68luan_calibrate_decr(void)
69{
70 unsigned int freq;
71
72 if (mfspr(SPRN_CCR1) & CCR1_TCS)
73 freq = LUAN_TMR_CLK;
74 else
75 freq = clocks.cpu;
76
77 ibm44x_calibrate_decr(freq);
78}
79
80static int
81luan_show_cpuinfo(struct seq_file *m)
82{
83 seq_printf(m, "vendor\t\t: IBM\n");
84 seq_printf(m, "machine\t\t: PPC440SP EVB (Luan)\n");
85
86 return 0;
87}
88
89static inline int
90luan_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
91{
92 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
93
94 /* PCIX0 in adapter mode, no host interrupt routing */
95
96 /* PCIX1 */
97 if (hose->index == 0) {
98 static char pci_irq_table[][4] =
99 /*
100 * PCI IDSEL/INTPIN->INTLINE
101 * A B C D
102 */
103 {
104 { 49, 49, 49, 49 }, /* IDSEL 1 - PCIX1 Slot 0 */
105 { 49, 49, 49, 49 }, /* IDSEL 2 - PCIX1 Slot 1 */
106 { 49, 49, 49, 49 }, /* IDSEL 3 - PCIX1 Slot 2 */
107 { 49, 49, 49, 49 }, /* IDSEL 4 - PCIX1 Slot 3 */
108 };
109 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
110 return PCI_IRQ_TABLE_LOOKUP;
111 /* PCIX2 */
112 } else if (hose->index == 1) {
113 static char pci_irq_table[][4] =
114 /*
115 * PCI IDSEL/INTPIN->INTLINE
116 * A B C D
117 */
118 {
119 { 50, 50, 50, 50 }, /* IDSEL 1 - PCIX2 Slot 0 */
120 { 50, 50, 50, 50 }, /* IDSEL 2 - PCIX2 Slot 1 */
121 { 50, 50, 50, 50 }, /* IDSEL 3 - PCIX2 Slot 2 */
122 { 50, 50, 50, 50 }, /* IDSEL 4 - PCIX2 Slot 3 */
123 };
124 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
125 return PCI_IRQ_TABLE_LOOKUP;
126 }
127 return -1;
128}
129
130static void __init luan_set_emacdata(void)
131{
132 struct ocp_def *def;
133 struct ocp_func_emac_data *emacdata;
134
135 /* Set phy_map, phy_mode, and mac_addr for the EMAC */
136 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
137 emacdata = def->additions;
138 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
139 emacdata->phy_mode = PHY_MODE_GMII;
140 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
141}
142
143#define PCIX_READW(offset) \
144 (readw((void *)((u32)pcix_reg_base+offset)))
145
146#define PCIX_WRITEW(value, offset) \
147 (writew(value, (void *)((u32)pcix_reg_base+offset)))
148
149#define PCIX_WRITEL(value, offset) \
150 (writel(value, (void *)((u32)pcix_reg_base+offset)))
151
152static void __init
153luan_setup_pcix(void)
154{
155 int i;
156 void *pcix_reg_base;
157
158 for (i=0;i<3;i++) {
159 pcix_reg_base = ioremap64(PCIX0_REG_BASE + i*PCIX_REG_OFFSET, PCIX_REG_SIZE);
160
161 /* Enable PCIX0 I/O, Mem, and Busmaster cycles */
162 PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND);
163
164 /* Disable all windows */
165 PCIX_WRITEL(0, PCIX0_POM0SA);
166 PCIX_WRITEL(0, PCIX0_POM1SA);
167 PCIX_WRITEL(0, PCIX0_POM2SA);
168 PCIX_WRITEL(0, PCIX0_PIM0SA);
169 PCIX_WRITEL(0, PCIX0_PIM0SAH);
170 PCIX_WRITEL(0, PCIX0_PIM1SA);
171 PCIX_WRITEL(0, PCIX0_PIM2SA);
172 PCIX_WRITEL(0, PCIX0_PIM2SAH);
173
174 /*
175 * Setup 512MB PLB->PCI outbound mem window
176 * (a_n000_0000->0_n000_0000)
177 * */
178 PCIX_WRITEL(0x0000000a, PCIX0_POM0LAH);
179 PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0LAL);
180 PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
181 PCIX_WRITEL(0x80000000 | i*LUAN_PCIX_MEM_SIZE, PCIX0_POM0PCIAL);
182 PCIX_WRITEL(0xe0000001, PCIX0_POM0SA);
183
184 /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
185 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
186 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
187 PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA);
188 PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH);
189
190 iounmap(pcix_reg_base);
191 }
192
193 eieio();
194}
195
196static void __init
197luan_setup_hose(struct pci_controller *hose,
198 int lower_mem,
199 int upper_mem,
200 int cfga,
201 int cfgd,
202 u64 pcix_io_base)
203{
204 char name[20];
205
206 sprintf(name, "PCIX%d host bridge", hose->index);
207
208 hose->pci_mem_offset = LUAN_PCIX_MEM_OFFSET;
209
210 pci_init_resource(&hose->io_resource,
211 LUAN_PCIX_LOWER_IO,
212 LUAN_PCIX_UPPER_IO,
213 IORESOURCE_IO,
214 name);
215
216 pci_init_resource(&hose->mem_resources[0],
217 lower_mem,
218 upper_mem,
219 IORESOURCE_MEM,
220 name);
221
222 hose->io_space.start = LUAN_PCIX_LOWER_IO;
223 hose->io_space.end = LUAN_PCIX_UPPER_IO;
224 hose->mem_space.start = lower_mem;
225 hose->mem_space.end = upper_mem;
226 isa_io_base =
227 (unsigned long)ioremap64(pcix_io_base, PCIX_IO_SIZE);
228 hose->io_base_virt = (void *)isa_io_base;
229
230 setup_indirect_pci(hose, cfga, cfgd);
231 hose->set_cfg_type = 1;
232}
233
234static void __init
235luan_setup_hoses(void)
236{
237 struct pci_controller *hose1, *hose2;
238
239 /* Configure windows on the PCI-X host bridge */
240 luan_setup_pcix();
241
242 /* Allocate hoses for PCIX1 and PCIX2 */
243 hose1 = pcibios_alloc_controller();
244 hose2 = pcibios_alloc_controller();
245 if (!hose1 || !hose2)
246 return;
247
248 /* Setup PCIX1 */
249 hose1->first_busno = 0;
250 hose1->last_busno = 0xff;
251
252 luan_setup_hose(hose1,
253 LUAN_PCIX1_LOWER_MEM,
254 LUAN_PCIX1_UPPER_MEM,
255 PCIX1_CFGA,
256 PCIX1_CFGD,
257 PCIX1_IO_BASE);
258
259 hose1->last_busno = pciauto_bus_scan(hose1, hose1->first_busno);
260
261 /* Setup PCIX2 */
262 hose2->first_busno = hose1->last_busno + 1;
263 hose2->last_busno = 0xff;
264
265 luan_setup_hose(hose2,
266 LUAN_PCIX2_LOWER_MEM,
267 LUAN_PCIX2_UPPER_MEM,
268 PCIX2_CFGA,
269 PCIX2_CFGD,
270 PCIX2_IO_BASE);
271
272 hose2->last_busno = pciauto_bus_scan(hose2, hose2->first_busno);
273
274 ppc_md.pci_swizzle = common_swizzle;
275 ppc_md.pci_map_irq = luan_map_irq;
276}
277
278TODC_ALLOC();
279
280static void __init
281luan_early_serial_map(void)
282{
283 struct uart_port port;
284
285 /* Setup ioremapped serial port access */
286 memset(&port, 0, sizeof(port));
287 port.membase = ioremap64(PPC440SP_UART0_ADDR, 8);
288 port.irq = UART0_INT;
289 port.uartclk = clocks.uart0;
290 port.regshift = 0;
291 port.iotype = SERIAL_IO_MEM;
292 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
293 port.line = 0;
294
295 if (early_serial_setup(&port) != 0) {
296 printk("Early serial init of port 0 failed\n");
297 }
298
299 port.membase = ioremap64(PPC440SP_UART1_ADDR, 8);
300 port.irq = UART1_INT;
301 port.uartclk = clocks.uart1;
302 port.line = 1;
303
304 if (early_serial_setup(&port) != 0) {
305 printk("Early serial init of port 1 failed\n");
306 }
307
308 port.membase = ioremap64(PPC440SP_UART2_ADDR, 8);
309 port.irq = UART2_INT;
310 port.uartclk = BASE_BAUD;
311 port.line = 2;
312
313 if (early_serial_setup(&port) != 0) {
314 printk("Early serial init of port 2 failed\n");
315 }
316}
317
318static void __init
319luan_setup_arch(void)
320{
321 luan_set_emacdata();
322
323#if !defined(CONFIG_BDI_SWITCH)
324 /*
325 * The Abatron BDI JTAG debugger does not tolerate others
326 * mucking with the debug registers.
327 */
328 mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
329#endif
330
331 /*
332 * Determine various clocks.
333 * To be completely correct we should get SysClk
334 * from FPGA, because it can be changed by on-board switches
335 * --ebs
336 */
337 /* 440GX and 440SP clocking is the same -mdp */
338 ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
339 ocp_sys_info.opb_bus_freq = clocks.opb;
340
341 /* init to some ~sane value until calibrate_delay() runs */
342 loops_per_jiffy = 50000000/HZ;
343
344 /* Setup PCIXn host bridges */
345 luan_setup_hoses();
346
347#ifdef CONFIG_BLK_DEV_INITRD
348 if (initrd_start)
349 ROOT_DEV = Root_RAM0;
350 else
351#endif
352#ifdef CONFIG_ROOT_NFS
353 ROOT_DEV = Root_NFS;
354#else
355 ROOT_DEV = Root_HDA1;
356#endif
357
358 luan_early_serial_map();
359
360 /* Identify the system */
361 printk("Luan port (MontaVista Software, Inc. <source@mvista.com>)\n");
362}
363
364void __init platform_init(unsigned long r3, unsigned long r4,
365 unsigned long r5, unsigned long r6, unsigned long r7)
366{
367 parse_bootinfo(find_bootinfo());
368
369 /*
370 * If we were passed in a board information, copy it into the
371 * residual data area.
372 */
373 if (r3)
374 __res = *(bd_t *)(r3 + KERNELBASE);
375
376 ibm44x_platform_init();
377
378 ppc_md.setup_arch = luan_setup_arch;
379 ppc_md.show_cpuinfo = luan_show_cpuinfo;
380 ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
381 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
382
383 ppc_md.calibrate_decr = luan_calibrate_decr;
384#ifdef CONFIG_KGDB
385 ppc_md.early_serial_map = luan_early_serial_map;
386#endif
387}
diff --git a/arch/ppc/platforms/4xx/luan.h b/arch/ppc/platforms/4xx/luan.h
new file mode 100644
index 000000000000..09b444c87816
--- /dev/null
+++ b/arch/ppc/platforms/4xx/luan.h
@@ -0,0 +1,80 @@
1/*
2 * arch/ppc/platforms/4xx/luan.h
3 *
4 * Luan board definitions
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2004-2005 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifdef __KERNEL__
18#ifndef __ASM_LUAN_H__
19#define __ASM_LUAN_H__
20
21#include <linux/config.h>
22#include <platforms/4xx/ibm440sp.h>
23
24/* F/W TLB mapping used in bootloader glue to reset EMAC */
25#define PPC44x_EMAC0_MR0 0xa0000800
26
27/* Location of MAC addresses in PIBS image */
28#define PIBS_FLASH_BASE 0xffe00000
29#define PIBS_MAC_BASE (PIBS_FLASH_BASE+0x1b0400)
30
31/* External timer clock frequency */
32#define LUAN_TMR_CLK 25000000
33
34/* Flash */
35#define LUAN_FPGA_REG_0 0x0000000148300000ULL
36#define LUAN_BOOT_LARGE_FLASH(x) (x & 0x40)
37#define LUAN_SMALL_FLASH_LOW 0x00000001ff900000ULL
38#define LUAN_SMALL_FLASH_HIGH 0x00000001ffe00000ULL
39#define LUAN_SMALL_FLASH_SIZE 0x100000
40#define LUAN_LARGE_FLASH_LOW 0x00000001ff800000ULL
41#define LUAN_LARGE_FLASH_HIGH 0x00000001ffc00000ULL
42#define LUAN_LARGE_FLASH_SIZE 0x400000
43
44/*
45 * Serial port defines
46 */
47#define RS_TABLE_SIZE 3
48
49/* PIBS defined UART mappings, used before early_serial_setup */
50#define UART0_IO_BASE 0xa0000200
51#define UART1_IO_BASE 0xa0000300
52#define UART2_IO_BASE 0xa0000600
53
54#define BASE_BAUD 11059200
55#define STD_UART_OP(num) \
56 { 0, BASE_BAUD, 0, UART##num##_INT, \
57 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
58 iomem_base: UART##num##_IO_BASE, \
59 io_type: SERIAL_IO_MEM},
60
61#define SERIAL_PORT_DFNS \
62 STD_UART_OP(0) \
63 STD_UART_OP(1) \
64 STD_UART_OP(2)
65
66/* PCI support */
67#define LUAN_PCIX_LOWER_IO 0x00000000
68#define LUAN_PCIX_UPPER_IO 0x0000ffff
69#define LUAN_PCIX0_LOWER_MEM 0x80000000
70#define LUAN_PCIX0_UPPER_MEM 0x9fffffff
71#define LUAN_PCIX1_LOWER_MEM 0xa0000000
72#define LUAN_PCIX1_UPPER_MEM 0xbfffffff
73#define LUAN_PCIX2_LOWER_MEM 0xc0000000
74#define LUAN_PCIX2_UPPER_MEM 0xdfffffff
75
76#define LUAN_PCIX_MEM_SIZE 0x20000000
77#define LUAN_PCIX_MEM_OFFSET 0x00000000
78
79#endif /* __ASM_LUAN_H__ */
80#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/oak.c b/arch/ppc/platforms/4xx/oak.c
new file mode 100644
index 000000000000..fa25ee1fa733
--- /dev/null
+++ b/arch/ppc/platforms/4xx/oak.c
@@ -0,0 +1,255 @@
1/*
2 *
3 * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Module name: oak.c
6 *
7 * Description:
8 * Architecture- / platform-specific boot-time initialization code for
9 * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
10 * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
11 * <dan@net4x.com>.
12 *
13 */
14
15#include <linux/config.h>
16#include <linux/init.h>
17#include <linux/smp.h>
18#include <linux/threads.h>
19#include <linux/param.h>
20#include <linux/string.h>
21#include <linux/initrd.h>
22#include <linux/irq.h>
23#include <linux/seq_file.h>
24
25#include <asm/board.h>
26#include <asm/machdep.h>
27#include <asm/page.h>
28#include <asm/bootinfo.h>
29#include <asm/ppc4xx_pic.h>
30#include <asm/time.h>
31
32#include "oak.h"
33
34/* Function Prototypes */
35
36extern void abort(void);
37
38/* Global Variables */
39
40unsigned char __res[sizeof(bd_t)];
41
42
43/*
44 * void __init oak_init()
45 *
46 * Description:
47 * This routine...
48 *
49 * Input(s):
50 * r3 - Optional pointer to a board information structure.
51 * r4 - Optional pointer to the physical starting address of the init RAM
52 * disk.
53 * r5 - Optional pointer to the physical ending address of the init RAM
54 * disk.
55 * r6 - Optional pointer to the physical starting address of any kernel
56 * command-line parameters.
57 * r7 - Optional pointer to the physical ending address of any kernel
58 * command-line parameters.
59 *
60 * Output(s):
61 * N/A
62 *
63 * Returns:
64 * N/A
65 *
66 */
67void __init
68platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
69 unsigned long r6, unsigned long r7)
70{
71 parse_bootinfo(find_bootinfo());
72
73 /*
74 * If we were passed in a board information, copy it into the
75 * residual data area.
76 */
77 if (r3) {
78 memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t));
79 }
80
81#if defined(CONFIG_BLK_DEV_INITRD)
82 /*
83 * If the init RAM disk has been configured in, and there's a valid
84 * starting address for it, set it up.
85 */
86 if (r4) {
87 initrd_start = r4 + KERNELBASE;
88 initrd_end = r5 + KERNELBASE;
89 }
90#endif /* CONFIG_BLK_DEV_INITRD */
91
92 /* Copy the kernel command line arguments to a safe place. */
93
94 if (r6) {
95 *(char *)(r7 + KERNELBASE) = 0;
96 strcpy(cmd_line, (char *)(r6 + KERNELBASE));
97 }
98
99 /* Initialize machine-dependency vectors */
100
101 ppc_md.setup_arch = oak_setup_arch;
102 ppc_md.show_percpuinfo = oak_show_percpuinfo;
103 ppc_md.irq_canonicalize = NULL;
104 ppc_md.init_IRQ = ppc4xx_pic_init;
105 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
106 ppc_md.init = NULL;
107
108 ppc_md.restart = oak_restart;
109 ppc_md.power_off = oak_power_off;
110 ppc_md.halt = oak_halt;
111
112 ppc_md.time_init = oak_time_init;
113 ppc_md.set_rtc_time = oak_set_rtc_time;
114 ppc_md.get_rtc_time = oak_get_rtc_time;
115 ppc_md.calibrate_decr = oak_calibrate_decr;
116}
117
118/*
119 * Document me.
120 */
121void __init
122oak_setup_arch(void)
123{
124 /* XXX - Implement me */
125}
126
127/*
128 * int oak_show_percpuinfo()
129 *
130 * Description:
131 * This routine pretty-prints the platform's internal CPU and bus clock
132 * frequencies into the buffer for usage in /proc/cpuinfo.
133 *
134 * Input(s):
135 * *buffer - Buffer into which CPU and bus clock frequencies are to be
136 * printed.
137 *
138 * Output(s):
139 * *buffer - Buffer with the CPU and bus clock frequencies.
140 *
141 * Returns:
142 * The number of bytes copied into 'buffer' if OK, otherwise zero or less
143 * on error.
144 */
145int
146oak_show_percpuinfo(struct seq_file *m, int i)
147{
148 bd_t *bp = (bd_t *)__res;
149
150 seq_printf(m, "clock\t\t: %dMHz\n"
151 "bus clock\t\t: %dMHz\n",
152 bp->bi_intfreq / 1000000,
153 bp->bi_busfreq / 1000000);
154
155 return 0;
156}
157
158/*
159 * Document me.
160 */
161void
162oak_restart(char *cmd)
163{
164 abort();
165}
166
167/*
168 * Document me.
169 */
170void
171oak_power_off(void)
172{
173 oak_restart(NULL);
174}
175
176/*
177 * Document me.
178 */
179void
180oak_halt(void)
181{
182 oak_restart(NULL);
183}
184
185/*
186 * Document me.
187 */
188long __init
189oak_time_init(void)
190{
191 /* XXX - Implement me */
192 return 0;
193}
194
195/*
196 * Document me.
197 */
198int __init
199oak_set_rtc_time(unsigned long time)
200{
201 /* XXX - Implement me */
202
203 return (0);
204}
205
206/*
207 * Document me.
208 */
209unsigned long __init
210oak_get_rtc_time(void)
211{
212 /* XXX - Implement me */
213
214 return (0);
215}
216
217/*
218 * void __init oak_calibrate_decr()
219 *
220 * Description:
221 * This routine retrieves the internal processor frequency from the board
222 * information structure, sets up the kernel timer decrementer based on
223 * that value, enables the 403 programmable interval timer (PIT) and sets
224 * it up for auto-reload.
225 *
226 * Input(s):
227 * N/A
228 *
229 * Output(s):
230 * N/A
231 *
232 * Returns:
233 * N/A
234 *
235 */
236void __init
237oak_calibrate_decr(void)
238{
239 unsigned int freq;
240 bd_t *bip = (bd_t *)__res;
241
242 freq = bip->bi_intfreq;
243
244 decrementer_count = freq / HZ;
245 count_period_num = 1;
246 count_period_den = freq;
247
248 /* Enable the PIT and set auto-reload of its value */
249
250 mtspr(SPRN_TCR, TCR_PIE | TCR_ARE);
251
252 /* Clear any pending timer interrupts */
253
254 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
255}
diff --git a/arch/ppc/platforms/4xx/oak.h b/arch/ppc/platforms/4xx/oak.h
new file mode 100644
index 000000000000..1b86a4c66b04
--- /dev/null
+++ b/arch/ppc/platforms/4xx/oak.h
@@ -0,0 +1,96 @@
1/*
2 *
3 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Module name: oak.h
6 *
7 * Description:
8 * Macros, definitions, and data structures specific to the IBM PowerPC
9 * 403G{A,B,C,CX} "Oak" evaluation board. Anything specific to the pro-
10 * cessor itself is defined elsewhere.
11 *
12 */
13
14#ifdef __KERNEL__
15#ifndef __ASM_OAK_H__
16#define __ASM_OAK_H__
17
18/* We have an IBM 403G{A,B,C,CX} core */
19#include <asm/ibm403.h>
20
21#define _IO_BASE 0
22#define _ISA_MEM_BASE 0
23#define PCI_DRAM_OFFSET 0
24
25/* Memory map for the "Oak" evaluation board */
26
27#define PPC403SPU_IO_BASE 0x40000000 /* 403 On-chip serial port */
28#define PPC403SPU_IO_SIZE 0x00000008
29#define OAKSERIAL_IO_BASE 0x7E000000 /* NS16550DV serial port */
30#define OAKSERIAL_IO_SIZE 0x00000008
31#define OAKNET_IO_BASE 0xF4000000 /* NS83902AV Ethernet */
32#define OAKNET_IO_SIZE 0x00000040
33#define OAKPROM_IO_BASE 0xFFFE0000 /* AMD 29F010 Flash ROM */
34#define OAKPROM_IO_SIZE 0x00020000
35
36
37/* Interrupt assignments fixed by the hardware implementation */
38
39/* This is annoying kbuild-2.4 problem. -- Tom */
40
41#define PPC403SPU_RX_INT 4 /* AIC_INT4 */
42#define PPC403SPU_TX_INT 5 /* AIC_INT5 */
43#define OAKNET_INT 27 /* AIC_INT27 */
44#define OAKSERIAL_INT 28 /* AIC_INT28 */
45
46#ifndef __ASSEMBLY__
47/*
48 * Data structure defining board information maintained by the boot
49 * ROM on IBM's "Oak" evaluation board. An effort has been made to
50 * keep the field names consistent with the 8xx 'bd_t' board info
51 * structures.
52 */
53
54typedef struct board_info {
55 unsigned char bi_s_version[4]; /* Version of this structure */
56 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
57 unsigned int bi_memsize; /* DRAM installed, in bytes */
58 unsigned char bi_enetaddr[6]; /* Ethernet MAC address */
59 unsigned int bi_intfreq; /* Processor speed, in Hz */
60 unsigned int bi_busfreq; /* Bus speed, in Hz */
61} bd_t;
62
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67extern void oak_init(unsigned long r3,
68 unsigned long ird_start,
69 unsigned long ird_end,
70 unsigned long cline_start,
71 unsigned long cline_end);
72extern void oak_setup_arch(void);
73extern int oak_setup_residual(char *buffer);
74extern void oak_init_IRQ(void);
75extern int oak_get_irq(struct pt_regs *regs);
76extern void oak_restart(char *cmd);
77extern void oak_power_off(void);
78extern void oak_halt(void);
79extern void oak_time_init(void);
80extern int oak_set_rtc_time(unsigned long now);
81extern unsigned long oak_get_rtc_time(void);
82extern void oak_calibrate_decr(void);
83
84#ifdef __cplusplus
85}
86#endif
87
88/* Some 4xx parts use a different timebase frequency from the internal clock.
89*/
90#define bi_tbfreq bi_intfreq
91
92#define PPC4xx_MACHINE_NAME "IBM Oak"
93
94#endif /* !__ASSEMBLY__ */
95#endif /* __ASM_OAK_H__ */
96#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/oak_setup.h b/arch/ppc/platforms/4xx/oak_setup.h
new file mode 100644
index 000000000000..8648bd084df8
--- /dev/null
+++ b/arch/ppc/platforms/4xx/oak_setup.h
@@ -0,0 +1,50 @@
1/*
2 *
3 * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Module name: oak_setup.h
6 *
7 * Description:
8 * Architecture- / platform-specific boot-time initialization code for
9 * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
10 * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
11 * <dan@netx4.com>.
12 *
13 */
14
15#ifndef __OAK_SETUP_H__
16#define __OAK_SETUP_H__
17
18#include <asm/ptrace.h>
19#include <asm/board.h>
20
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26extern unsigned char __res[sizeof(bd_t)];
27
28extern void oak_init(unsigned long r3,
29 unsigned long ird_start,
30 unsigned long ird_end,
31 unsigned long cline_start,
32 unsigned long cline_end);
33extern void oak_setup_arch(void);
34extern int oak_setup_residual(char *buffer);
35extern void oak_init_IRQ(void);
36extern int oak_get_irq(struct pt_regs *regs);
37extern void oak_restart(char *cmd);
38extern void oak_power_off(void);
39extern void oak_halt(void);
40extern void oak_time_init(void);
41extern int oak_set_rtc_time(unsigned long now);
42extern unsigned long oak_get_rtc_time(void);
43extern void oak_calibrate_decr(void);
44
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif /* __OAK_SETUP_H__ */
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
new file mode 100644
index 000000000000..28de707434f1
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -0,0 +1,367 @@
1/*
2 * arch/ppc/platforms/4xx/ocotea.c
3 *
4 * Ocotea board specific routines
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2003-2005 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/types.h>
25#include <linux/major.h>
26#include <linux/blkdev.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/ide.h>
30#include <linux/initrd.h>
31#include <linux/irq.h>
32#include <linux/seq_file.h>
33#include <linux/root_dev.h>
34#include <linux/tty.h>
35#include <linux/serial.h>
36#include <linux/serial_core.h>
37
38#include <asm/system.h>
39#include <asm/pgtable.h>
40#include <asm/page.h>
41#include <asm/dma.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/ocp.h>
45#include <asm/pci-bridge.h>
46#include <asm/time.h>
47#include <asm/todc.h>
48#include <asm/bootinfo.h>
49#include <asm/ppc4xx_pic.h>
50#include <asm/ppcboot.h>
51
52#include <syslib/gen550.h>
53#include <syslib/ibm440gx_common.h>
54
55/*
56 * This is a horrible kludge, we eventually need to abstract this
57 * generic PHY stuff, so the standard phy mode defines can be
58 * easily used from arch code.
59 */
60#include "../../../../drivers/net/ibm_emac/ibm_emac_phy.h"
61
62bd_t __res;
63
64static struct ibm44x_clocks clocks __initdata;
65
66static void __init
67ocotea_calibrate_decr(void)
68{
69 unsigned int freq;
70
71 if (mfspr(SPRN_CCR1) & CCR1_TCS)
72 freq = OCOTEA_TMR_CLK;
73 else
74 freq = clocks.cpu;
75
76 ibm44x_calibrate_decr(freq);
77}
78
79static int
80ocotea_show_cpuinfo(struct seq_file *m)
81{
82 seq_printf(m, "vendor\t\t: IBM\n");
83 seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n");
84 ibm440gx_show_cpuinfo(m);
85 return 0;
86}
87
88static inline int
89ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
90{
91 static char pci_irq_table[][4] =
92 /*
93 * PCI IDSEL/INTPIN->INTLINE
94 * A B C D
95 */
96 {
97 { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */
98 { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */
99 { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */
100 { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */
101 };
102
103 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
104 return PCI_IRQ_TABLE_LOOKUP;
105}
106
107static void __init ocotea_set_emacdata(void)
108{
109 struct ocp_def *def;
110 struct ocp_func_emac_data *emacdata;
111 int i;
112
113 /*
114 * Note: Current rev. board only operates in Group 4a
115 * mode, so we always set EMAC0-1 for SMII and EMAC2-3
116 * for RGMII (though these could run in RTBI just the same).
117 *
118 * The FPGA reg 3 information isn't even suitable for
119 * determining the phy_mode, so if the board becomes
120 * usable in !4a, it will be necessary to parse an environment
121 * variable from the firmware or similar to properly configure
122 * the phy_map/phy_mode.
123 */
124 /* Set phy_map, phy_mode, and mac_addr for each EMAC */
125 for (i=0; i<4; i++) {
126 def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i);
127 emacdata = def->additions;
128 if (i < 2) {
129 emacdata->phy_map = 0x00000001; /* Skip 0x00 */
130 emacdata->phy_mode = PHY_MODE_SMII;
131 }
132 else {
133 emacdata->phy_map = 0x0000ffff; /* Skip 0x00-0x0f */
134 emacdata->phy_mode = PHY_MODE_RGMII;
135 }
136 if (i == 0)
137 memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
138 else if (i == 1)
139 memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
140 else if (i == 2)
141 memcpy(emacdata->mac_addr, __res.bi_enet2addr, 6);
142 else if (i == 3)
143 memcpy(emacdata->mac_addr, __res.bi_enet3addr, 6);
144 }
145}
146
147#define PCIX_READW(offset) \
148 (readw(pcix_reg_base+offset))
149
150#define PCIX_WRITEW(value, offset) \
151 (writew(value, pcix_reg_base+offset))
152
153#define PCIX_WRITEL(value, offset) \
154 (writel(value, pcix_reg_base+offset))
155
156/*
157 * FIXME: This is only here to "make it work". This will move
158 * to a ibm_pcix.c which will contain a generic IBM PCIX bridge
159 * configuration library. -Matt
160 */
161static void __init
162ocotea_setup_pcix(void)
163{
164 void *pcix_reg_base;
165
166 pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
167
168 /* Enable PCIX0 I/O, Mem, and Busmaster cycles */
169 PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND);
170
171 /* Disable all windows */
172 PCIX_WRITEL(0, PCIX0_POM0SA);
173 PCIX_WRITEL(0, PCIX0_POM1SA);
174 PCIX_WRITEL(0, PCIX0_POM2SA);
175 PCIX_WRITEL(0, PCIX0_PIM0SA);
176 PCIX_WRITEL(0, PCIX0_PIM0SAH);
177 PCIX_WRITEL(0, PCIX0_PIM1SA);
178 PCIX_WRITEL(0, PCIX0_PIM2SA);
179 PCIX_WRITEL(0, PCIX0_PIM2SAH);
180
181 /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */
182 PCIX_WRITEL(0x00000003, PCIX0_POM0LAH);
183 PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
184 PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
185 PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
186 PCIX_WRITEL(0x80000001, PCIX0_POM0SA);
187
188 /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
189 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
190 PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
191 PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA);
192
193 eieio();
194}
195
196static void __init
197ocotea_setup_hose(void)
198{
199 struct pci_controller *hose;
200
201 /* Configure windows on the PCI-X host bridge */
202 ocotea_setup_pcix();
203
204 hose = pcibios_alloc_controller();
205
206 if (!hose)
207 return;
208
209 hose->first_busno = 0;
210 hose->last_busno = 0xff;
211
212 hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET;
213
214 pci_init_resource(&hose->io_resource,
215 OCOTEA_PCI_LOWER_IO,
216 OCOTEA_PCI_UPPER_IO,
217 IORESOURCE_IO,
218 "PCI host bridge");
219
220 pci_init_resource(&hose->mem_resources[0],
221 OCOTEA_PCI_LOWER_MEM,
222 OCOTEA_PCI_UPPER_MEM,
223 IORESOURCE_MEM,
224 "PCI host bridge");
225
226 hose->io_space.start = OCOTEA_PCI_LOWER_IO;
227 hose->io_space.end = OCOTEA_PCI_UPPER_IO;
228 hose->mem_space.start = OCOTEA_PCI_LOWER_MEM;
229 hose->mem_space.end = OCOTEA_PCI_UPPER_MEM;
230 isa_io_base =
231 (unsigned long)ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE);
232 hose->io_base_virt = (void *)isa_io_base;
233
234 setup_indirect_pci(hose,
235 OCOTEA_PCI_CFGA_PLB32,
236 OCOTEA_PCI_CFGD_PLB32);
237 hose->set_cfg_type = 1;
238
239 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
240
241 ppc_md.pci_swizzle = common_swizzle;
242 ppc_md.pci_map_irq = ocotea_map_irq;
243}
244
245
246TODC_ALLOC();
247
248static void __init
249ocotea_early_serial_map(void)
250{
251 struct uart_port port;
252
253 /* Setup ioremapped serial port access */
254 memset(&port, 0, sizeof(port));
255 port.membase = ioremap64(PPC440GX_UART0_ADDR, 8);
256 port.irq = UART0_INT;
257 port.uartclk = clocks.uart0;
258 port.regshift = 0;
259 port.iotype = SERIAL_IO_MEM;
260 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
261 port.line = 0;
262
263 if (early_serial_setup(&port) != 0) {
264 printk("Early serial init of port 0 failed\n");
265 }
266
267#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
268 /* Configure debug serial access */
269 gen550_init(0, &port);
270#endif
271
272 port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
273 port.irq = UART1_INT;
274 port.uartclk = clocks.uart1;
275 port.line = 1;
276
277 if (early_serial_setup(&port) != 0) {
278 printk("Early serial init of port 1 failed\n");
279 }
280
281#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
282 /* Configure debug serial access */
283 gen550_init(1, &port);
284#endif
285}
286
287static void __init
288ocotea_setup_arch(void)
289{
290 ocotea_set_emacdata();
291
292 ibm440gx_tah_enable();
293
294 /* Setup TODC access */
295 TODC_INIT(TODC_TYPE_DS1743,
296 0,
297 0,
298 ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE),
299 8);
300
301 /* init to some ~sane value until calibrate_delay() runs */
302 loops_per_jiffy = 50000000/HZ;
303
304 /* Setup PCI host bridge */
305 ocotea_setup_hose();
306
307#ifdef CONFIG_BLK_DEV_INITRD
308 if (initrd_start)
309 ROOT_DEV = Root_RAM0;
310 else
311#endif
312#ifdef CONFIG_ROOT_NFS
313 ROOT_DEV = Root_NFS;
314#else
315 ROOT_DEV = Root_HDA1;
316#endif
317
318 ocotea_early_serial_map();
319
320 /* Identify the system */
321 printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n");
322}
323
324static void __init ocotea_init(void)
325{
326 ibm440gx_l2c_setup(&clocks);
327}
328
329void __init platform_init(unsigned long r3, unsigned long r4,
330 unsigned long r5, unsigned long r6, unsigned long r7)
331{
332 parse_bootinfo(find_bootinfo());
333
334 /*
335 * If we were passed in a board information, copy it into the
336 * residual data area.
337 */
338 if (r3)
339 __res = *(bd_t *)(r3 + KERNELBASE);
340
341 /*
342 * Determine various clocks.
343 * To be completely correct we should get SysClk
344 * from FPGA, because it can be changed by on-board switches
345 * --ebs
346 */
347 ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
348 ocp_sys_info.opb_bus_freq = clocks.opb;
349
350 ibm44x_platform_init();
351
352 ppc_md.setup_arch = ocotea_setup_arch;
353 ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
354 ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
355
356 ppc_md.calibrate_decr = ocotea_calibrate_decr;
357 ppc_md.time_init = todc_time_init;
358 ppc_md.set_rtc_time = todc_set_rtc_time;
359 ppc_md.get_rtc_time = todc_get_rtc_time;
360
361 ppc_md.nvram_read_val = todc_direct_read_val;
362 ppc_md.nvram_write_val = todc_direct_write_val;
363#ifdef CONFIG_KGDB
364 ppc_md.early_serial_map = ocotea_early_serial_map;
365#endif
366 ppc_md.init = ocotea_init;
367}
diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h
new file mode 100644
index 000000000000..202dc8251190
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ocotea.h
@@ -0,0 +1,88 @@
1/*
2 * arch/ppc/platforms/ocotea.h
3 *
4 * Ocotea board definitions
5 *
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2003-2005 MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifdef __KERNEL__
18#ifndef __ASM_OCOTEA_H__
19#define __ASM_OCOTEA_H__
20
21#include <linux/config.h>
22#include <platforms/4xx/ibm440gx.h>
23
24/* F/W TLB mapping used in bootloader glue to reset EMAC */
25#define PPC44x_EMAC0_MR0 0xe0000800
26
27/* Location of MAC addresses in PIBS image */
28#define PIBS_FLASH_BASE 0xfff00000
29#define PIBS_MAC_BASE (PIBS_FLASH_BASE+0xb0500)
30#define PIBS_MAC_SIZE 0x200
31#define PIBS_MAC_OFFSET 0x100
32
33/* External timer clock frequency */
34#define OCOTEA_TMR_CLK 25000000
35
36/* RTC/NVRAM location */
37#define OCOTEA_RTC_ADDR 0x0000000148000000ULL
38#define OCOTEA_RTC_SIZE 0x2000
39
40/* Flash */
41#define OCOTEA_FPGA_REG_0 0x0000000148300000ULL
42#define OCOTEA_BOOT_LARGE_FLASH(x) (x & 0x40)
43#define OCOTEA_SMALL_FLASH_LOW 0x00000001ff900000ULL
44#define OCOTEA_SMALL_FLASH_HIGH 0x00000001fff00000ULL
45#define OCOTEA_SMALL_FLASH_SIZE 0x100000
46#define OCOTEA_LARGE_FLASH_LOW 0x00000001ff800000ULL
47#define OCOTEA_LARGE_FLASH_HIGH 0x00000001ffc00000ULL
48#define OCOTEA_LARGE_FLASH_SIZE 0x400000
49
50/* FPGA_REG_3 (Ethernet Groups) */
51#define OCOTEA_FPGA_REG_3 0x0000000148300003ULL
52
53/*
54 * Serial port defines
55 */
56#define RS_TABLE_SIZE 2
57
58/* OpenBIOS defined UART mappings, used before early_serial_setup */
59#define UART0_IO_BASE 0xE0000200
60#define UART1_IO_BASE 0xE0000300
61
62#define BASE_BAUD 11059200/16
63#define STD_UART_OP(num) \
64 { 0, BASE_BAUD, 0, UART##num##_INT, \
65 (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
66 iomem_base: UART##num##_IO_BASE, \
67 io_type: SERIAL_IO_MEM},
68
69#define SERIAL_PORT_DFNS \
70 STD_UART_OP(0) \
71 STD_UART_OP(1)
72
73/* PCI support */
74#define OCOTEA_PCI_LOWER_IO 0x00000000
75#define OCOTEA_PCI_UPPER_IO 0x0000ffff
76#define OCOTEA_PCI_LOWER_MEM 0x80000000
77#define OCOTEA_PCI_UPPER_MEM 0xffffefff
78
79#define OCOTEA_PCI_CFGREGS_BASE 0x000000020ec00000ULL
80#define OCOTEA_PCI_CFGA_PLB32 0x0ec00000
81#define OCOTEA_PCI_CFGD_PLB32 0x0ec00004
82
83#define OCOTEA_PCI_IO_BASE 0x0000000208000000ULL
84#define OCOTEA_PCI_IO_SIZE 0x00010000
85#define OCOTEA_PCI_MEM_OFFSET 0x00000000
86
87#endif /* __ASM_OCOTEA_H__ */
88#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
new file mode 100644
index 000000000000..2f5e410afbc5
--- /dev/null
+++ b/arch/ppc/platforms/4xx/redwood5.c
@@ -0,0 +1,110 @@
1/*
2 * arch/ppc/platforms/4xx/redwood5.c
3 *
4 * Support for the IBM redwood5 eval board file
5 *
6 * Author: Armin Kuster <akuster@mvista.com>
7 *
8 * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/pagemap.h>
17#include <linux/device.h>
18#include <linux/ioport.h>
19#include <asm/io.h>
20#include <asm/machdep.h>
21
22static struct resource smc91x_resources[] = {
23 [0] = {
24 .start = SMC91111_BASE_ADDR,
25 .end = SMC91111_BASE_ADDR + SMC91111_REG_SIZE - 1,
26 .flags = IORESOURCE_MEM,
27 },
28 [1] = {
29 .start = SMC91111_IRQ,
30 .end = SMC91111_IRQ,
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static struct platform_device smc91x_device = {
36 .name = "smc91x",
37 .id = 0,
38 .num_resources = ARRAY_SIZE(smc91x_resources),
39 .resource = smc91x_resources,
40};
41
42static struct platform_device *redwood5_devs[] __initdata = {
43 &smc91x_device,
44};
45
46static int __init
47redwood5_platform_add_devices(void)
48{
49 return platform_add_devices(redwood5_devs, ARRAY_SIZE(redwood5_devs));
50}
51
52void __init
53redwood5_setup_arch(void)
54{
55 ppc4xx_setup_arch();
56
57#ifdef CONFIG_DEBUG_BRINGUP
58 printk("\n");
59 printk("machine\t: %s\n", PPC4xx_MACHINE_NAME);
60 printk("\n");
61 printk("bi_s_version\t %s\n", bip->bi_s_version);
62 printk("bi_r_version\t %s\n", bip->bi_r_version);
63 printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,bip->bi_memsize/(1024*1000));
64 printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0,
65 bip->bi_enetaddr[0], bip->bi_enetaddr[1],
66 bip->bi_enetaddr[2], bip->bi_enetaddr[3],
67 bip->bi_enetaddr[4], bip->bi_enetaddr[5]);
68
69 printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n",
70 bip->bi_intfreq, bip->bi_intfreq/ 1000000);
71
72 printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n",
73 bip->bi_busfreq, bip->bi_busfreq / 1000000 );
74 printk("bi_tbfreq\t 0x%8.8x\t TB freq:\t %dMHz\n",
75 bip->bi_tbfreq, bip->bi_tbfreq/1000000);
76
77 printk("\n");
78#endif
79 device_initcall(redwood5_platform_add_devices);
80}
81
82void __init
83redwood5_map_io(void)
84{
85 int i;
86
87 ppc4xx_map_io();
88 for (i = 0; i < 16; i++) {
89 unsigned long v, p;
90
91 /* 0x400x0000 -> 0xe00x0000 */
92 p = 0x40000000 | (i << 16);
93 v = STB04xxx_IO_BASE | (i << 16);
94
95 io_block_mapping(v, p, PAGE_SIZE,
96 _PAGE_NO_CACHE | pgprot_val(PAGE_KERNEL) | _PAGE_GUARDED);
97 }
98
99
100}
101
102void __init
103platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
104 unsigned long r6, unsigned long r7)
105{
106 ppc4xx_init(r3, r4, r5, r6, r7);
107
108 ppc_md.setup_arch = redwood5_setup_arch;
109 ppc_md.setup_io_mappings = redwood5_map_io;
110}
diff --git a/arch/ppc/platforms/4xx/redwood5.h b/arch/ppc/platforms/4xx/redwood5.h
new file mode 100644
index 000000000000..264e34fb3fbd
--- /dev/null
+++ b/arch/ppc/platforms/4xx/redwood5.h
@@ -0,0 +1,54 @@
1/*
2 * arch/ppc/platforms/4xx/redwood5.h
3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC
5 * STB03xxx "Redwood" evaluation board.
6 *
7 * Author: Armin Kuster <akuster@mvista.com>
8 *
9 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_REDWOOD5_H__
17#define __ASM_REDWOOD5_H__
18
19/* Redwood5 has an STB04xxx core */
20#include <platforms/4xx/ibmstb4.h>
21
22#ifndef __ASSEMBLY__
23typedef struct board_info {
24 unsigned char bi_s_version[4]; /* Version of this structure */
25 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
26 unsigned int bi_memsize; /* DRAM installed, in bytes */
27 unsigned int bi_dummy; /* field shouldn't exist */
28 unsigned char bi_enetaddr[6]; /* Ethernet MAC address */
29 unsigned int bi_intfreq; /* Processor speed, in Hz */
30 unsigned int bi_busfreq; /* Bus speed, in Hz */
31 unsigned int bi_tbfreq; /* Software timebase freq */
32} bd_t;
33#endif /* !__ASSEMBLY__ */
34
35
36#define SMC91111_BASE_ADDR 0xf2000300
37#define SMC91111_REG_SIZE 16
38#define SMC91111_IRQ 28
39
40#ifdef MAX_HWIFS
41#undef MAX_HWIFS
42#endif
43#define MAX_HWIFS 1
44
45#define _IO_BASE 0
46#define _ISA_MEM_BASE 0
47#define PCI_DRAM_OFFSET 0
48
49#define BASE_BAUD (378000000 / 18 / 16)
50
51#define PPC4xx_MACHINE_NAME "IBM Redwood5"
52
53#endif /* __ASM_REDWOOD5_H__ */
54#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
new file mode 100644
index 000000000000..8b1012994dfc
--- /dev/null
+++ b/arch/ppc/platforms/4xx/redwood6.c
@@ -0,0 +1,159 @@
1/*
2 * arch/ppc/platforms/4xx/redwood6.c
3 *
4 * Author: Armin Kuster <akuster@mvista.com>
5 *
6 * 2002 (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
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/pagemap.h>
15#include <linux/device.h>
16#include <linux/ioport.h>
17#include <asm/io.h>
18#include <asm/ppc4xx_pic.h>
19#include <linux/delay.h>
20#include <asm/machdep.h>
21
22/*
23 * Define external IRQ senses and polarities.
24 */
25unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
26 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 7 */
27 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 8 */
28 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 9 */
29 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 0 */
30 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 1 */
31 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 2 */
32 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 3 */
33 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 4 */
34 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 5 */
35 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 6 */
36};
37
38static struct resource smc91x_resources[] = {
39 [0] = {
40 .start = SMC91111_BASE_ADDR,
41 .end = SMC91111_BASE_ADDR + SMC91111_REG_SIZE - 1,
42 .flags = IORESOURCE_MEM,
43 },
44 [1] = {
45 .start = SMC91111_IRQ,
46 .end = SMC91111_IRQ,
47 .flags = IORESOURCE_IRQ,
48 },
49};
50
51static struct platform_device smc91x_device = {
52 .name = "smc91x",
53 .id = 0,
54 .num_resources = ARRAY_SIZE(smc91x_resources),
55 .resource = smc91x_resources,
56};
57
58static struct platform_device *redwood6_devs[] __initdata = {
59 &smc91x_device,
60};
61
62static int __init
63redwood6_platform_add_devices(void)
64{
65 return platform_add_devices(redwood6_devs, ARRAY_SIZE(redwood6_devs));
66}
67
68
69void __init
70redwood6_setup_arch(void)
71{
72#ifdef CONFIG_IDE
73 void *xilinx, *xilinx_1, *xilinx_2;
74 unsigned short us_reg5;
75#endif
76
77 ppc4xx_setup_arch();
78
79#ifdef CONFIG_IDE
80 xilinx = (unsigned long) ioremap(IDE_XLINUX_MUX_BASE, 0x10);
81 /* init xilinx control registers - enable ide mux, clear reset bit */
82 if (!xilinx) {
83 printk(KERN_CRIT
84 "redwood6_setup_arch() xilinxi ioremap failed\n");
85 return;
86 }
87 xilinx_1 = xilinx + 0xa;
88 xilinx_2 = xilinx + 0xe;
89
90 us_reg5 = readb(xilinx_1);
91 writeb(0x01d1, xilinx_1);
92 writeb(0x0008, xilinx_2);
93
94 udelay(10 * 1000);
95
96 writeb(0x01d1, xilinx_1);
97 writeb(0x0008, xilinx_2);
98#endif
99
100#ifdef DEBUG_BRINGUP
101 bd_t *bip = (bd_t *) __res;
102 printk("\n");
103 printk("machine\t: %s\n", PPC4xx_MACHINE_NAME);
104 printk("\n");
105 printk("bi_s_version\t %s\n", bip->bi_s_version);
106 printk("bi_r_version\t %s\n", bip->bi_r_version);
107 printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,
108 bip->bi_memsize / (1024 * 1000));
109 printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0,
110 bip->bi_enetaddr[0], bip->bi_enetaddr[1], bip->bi_enetaddr[2],
111 bip->bi_enetaddr[3], bip->bi_enetaddr[4], bip->bi_enetaddr[5]);
112
113 printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n",
114 bip->bi_intfreq, bip->bi_intfreq / 1000000);
115
116 printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n",
117 bip->bi_busfreq, bip->bi_busfreq / 1000000);
118 printk("bi_tbfreq\t 0x%8.8x\t TB freq:\t %dMHz\n",
119 bip->bi_tbfreq, bip->bi_tbfreq / 1000000);
120
121 printk("\n");
122#endif
123
124 /* Identify the system */
125 printk(KERN_INFO "IBM Redwood6 (STBx25XX) Platform\n");
126 printk(KERN_INFO
127 "Port by MontaVista Software, Inc. (source@mvista.com)\n");
128
129 device_initcall(redwood6_platform_add_devices);
130}
131
132void __init
133redwood6_map_io(void)
134{
135 int i;
136
137 ppc4xx_map_io();
138 for (i = 0; i < 16; i++) {
139 unsigned long v, p;
140
141 /* 0x400x0000 -> 0xe00x0000 */
142 p = 0x40000000 | (i << 16);
143 v = STBx25xx_IO_BASE | (i << 16);
144
145 io_block_mapping(v, p, PAGE_SIZE,
146 _PAGE_NO_CACHE | pgprot_val(PAGE_KERNEL) |
147 _PAGE_GUARDED);
148 }
149}
150
151void __init
152platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
153 unsigned long r6, unsigned long r7)
154{
155 ppc4xx_init(r3, r4, r5, r6, r7);
156
157 ppc_md.setup_arch = redwood6_setup_arch;
158 ppc_md.setup_io_mappings = redwood6_map_io;
159}
diff --git a/arch/ppc/platforms/4xx/redwood6.h b/arch/ppc/platforms/4xx/redwood6.h
new file mode 100644
index 000000000000..1814b9f5fc3a
--- /dev/null
+++ b/arch/ppc/platforms/4xx/redwood6.h
@@ -0,0 +1,55 @@
1/*
2 * arch/ppc/platforms/4xx/redwood6.h
3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC
5 * STBx25xx "Redwood6" evaluation board.
6 *
7 * Author: Armin Kuster <akuster@mvista.com>
8 *
9 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_REDWOOD5_H__
17#define __ASM_REDWOOD5_H__
18
19/* Redwood6 has an STBx25xx core */
20#include <platforms/4xx/ibmstbx25.h>
21
22#ifndef __ASSEMBLY__
23typedef struct board_info {
24 unsigned char bi_s_version[4]; /* Version of this structure */
25 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
26 unsigned int bi_memsize; /* DRAM installed, in bytes */
27 unsigned int bi_dummy; /* field shouldn't exist */
28 unsigned char bi_enetaddr[6]; /* Ethernet MAC address */
29 unsigned int bi_intfreq; /* Processor speed, in Hz */
30 unsigned int bi_busfreq; /* Bus speed, in Hz */
31 unsigned int bi_tbfreq; /* Software timebase freq */
32} bd_t;
33#endif /* !__ASSEMBLY__ */
34
35#define SMC91111_BASE_ADDR 0xf2030300
36#define SMC91111_REG_SIZE 16
37#define SMC91111_IRQ 27
38#define IDE_XLINUX_MUX_BASE 0xf2040000
39#define IDE_DMA_ADDR 0xfce00000
40
41#ifdef MAX_HWIFS
42#undef MAX_HWIFS
43#endif
44#define MAX_HWIFS 1
45
46#define _IO_BASE 0
47#define _ISA_MEM_BASE 0
48#define PCI_DRAM_OFFSET 0
49
50#define BASE_BAUD (378000000 / 18 / 16)
51
52#define PPC4xx_MACHINE_NAME "IBM Redwood6"
53
54#endif /* __ASM_REDWOOD5_H__ */
55#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
new file mode 100644
index 000000000000..d8019eec4704
--- /dev/null
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -0,0 +1,278 @@
1/*
2 * arch/ppc/platforms/4xx/sycamore.c
3 *
4 * Architecture- / platform-specific boot-time initialization code for
5 * IBM PowerPC 4xx based boards.
6 *
7 * Author: Armin Kuster <akuster@mvista.com>
8 *
9 * 2000-2002 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/smp.h>
17#include <linux/threads.h>
18#include <linux/param.h>
19#include <linux/string.h>
20#include <linux/pci.h>
21#include <linux/rtc.h>
22
23#include <asm/ocp.h>
24#include <asm/ppc4xx_pic.h>
25#include <asm/system.h>
26#include <asm/pci-bridge.h>
27#include <asm/machdep.h>
28#include <asm/page.h>
29#include <asm/time.h>
30#include <asm/io.h>
31#include <asm/ibm_ocp_pci.h>
32#include <asm/todc.h>
33
34#undef DEBUG
35
36#ifdef DEBUG
37#define DBG(x...) printk(x)
38#else
39#define DBG(x...)
40#endif
41
42void *kb_cs;
43void *kb_data;
44void *sycamore_rtc_base;
45
46/*
47 * Define external IRQ senses and polarities.
48 */
49unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
50 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 7 */
51 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 8 */
52 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 9 */
53 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 10 */
54 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 11 */
55 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 12 */
56 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 0 */
57 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 1 */
58 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 2 */
59 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 3 */
60 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 4 */
61 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 5 */
62 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext Int 6 */
63};
64
65
66/* Some IRQs unique to Sycamore.
67 * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
68 */
69int __init
70ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
71{
72 static char pci_irq_table[][4] =
73 /*
74 * PCI IDSEL/INTPIN->INTLINE
75 * A B C D
76 */
77 {
78 {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */
79 {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */
80 {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */
81 {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */
82 };
83
84 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
85 return PCI_IRQ_TABLE_LOOKUP;
86};
87
88void __init
89sycamore_setup_arch(void)
90{
91#define SYCAMORE_PS2_BASE 0xF0100000
92#define SYCAMORE_FPGA_BASE 0xF0300000
93
94 void *fpga_brdc;
95 unsigned char fpga_brdc_data;
96 void *fpga_enable;
97 void *fpga_polarity;
98 void *fpga_status;
99 void *fpga_trigger;
100
101 ppc4xx_setup_arch();
102
103 ibm_ocp_set_emac(0, 1);
104
105 kb_data = ioremap(SYCAMORE_PS2_BASE, 8);
106 if (!kb_data) {
107 printk(KERN_CRIT
108 "sycamore_setup_arch() kb_data ioremap failed\n");
109 return;
110 }
111
112 kb_cs = kb_data + 1;
113
114 fpga_status = ioremap(SYCAMORE_FPGA_BASE, 8);
115 if (!fpga_status) {
116 printk(KERN_CRIT
117 "sycamore_setup_arch() fpga_status ioremap failed\n");
118 return;
119 }
120
121 fpga_enable = fpga_status + 1;
122 fpga_polarity = fpga_status + 2;
123 fpga_trigger = fpga_status + 3;
124 fpga_brdc = fpga_status + 4;
125
126 /* split the keyboard and mouse interrupts */
127 fpga_brdc_data = readb(fpga_brdc);
128 fpga_brdc_data |= 0x80;
129 writeb(fpga_brdc_data, fpga_brdc);
130
131 writeb(0x3, fpga_enable);
132
133 writeb(0x3, fpga_polarity);
134
135 writeb(0x3, fpga_trigger);
136
137 /* RTC step for the sycamore */
138 sycamore_rtc_base = (void *) SYCAMORE_RTC_VADDR;
139 TODC_INIT(TODC_TYPE_DS1743, sycamore_rtc_base, sycamore_rtc_base,
140 sycamore_rtc_base, 8);
141
142 /* Identify the system */
143 printk(KERN_INFO "IBM Sycamore (IBM405GPr) Platform\n");
144 printk(KERN_INFO
145 "Port by MontaVista Software, Inc. (source@mvista.com)\n");
146}
147
148void __init
149bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
150{
151#ifdef CONFIG_PCI
152 unsigned int bar_response, bar;
153 /*
154 * Expected PCI mapping:
155 *
156 * PLB addr PCI memory addr
157 * --------------------- ---------------------
158 * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
159 * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
160 *
161 * PLB addr PCI io addr
162 * --------------------- ---------------------
163 * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
164 *
165 * The following code is simplified by assuming that the bootrom
166 * has been well behaved in following this mapping.
167 */
168
169#ifdef DEBUG
170 int i;
171
172 printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
173 printk("PCI bridge regs before fixup \n");
174 for (i = 0; i <= 3; i++) {
175 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
176 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
177 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
178 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
179 }
180 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
181 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
182 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
183 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
184
185#endif
186
187 /* added for IBM boot rom version 1.15 bios bar changes -AK */
188
189 /* Disable region first */
190 out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
191 /* PLB starting addr, PCI: 0x80000000 */
192 out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
193 /* PCI start addr, 0x80000000 */
194 out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
195 /* 512MB range of PLB to PCI */
196 out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
197 /* Enable no pre-fetch, enable region */
198 out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
199 (PPC405_PCI_UPPER_MEM -
200 PPC405_PCI_MEM_BASE)) | 0x01));
201
202 /* Enable inbound region one - 1GB size */
203 out_le32((void *) &(pcip->ptm1ms), 0xc0000001);
204
205 /* Disable outbound region one */
206 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
207 out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
208 out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
209 out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
210 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
211
212 /* Disable inbound region two */
213 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
214
215 /* Disable outbound region two */
216 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
217 out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
218 out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
219 out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
220 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
221
222 /* Zero config bars */
223 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
224 early_write_config_dword(hose, hose->first_busno,
225 PCI_FUNC(hose->first_busno), bar,
226 0x00000000);
227 early_read_config_dword(hose, hose->first_busno,
228 PCI_FUNC(hose->first_busno), bar,
229 &bar_response);
230 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
231 hose->first_busno, PCI_SLOT(hose->first_busno),
232 PCI_FUNC(hose->first_busno), bar, bar_response);
233 }
234 /* end work arround */
235
236#ifdef DEBUG
237 printk("PCI bridge regs after fixup \n");
238 for (i = 0; i <= 3; i++) {
239 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
240 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
241 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
242 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
243 }
244 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
245 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
246 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
247 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
248
249#endif
250#endif
251
252}
253
254void __init
255sycamore_map_io(void)
256{
257 ppc4xx_map_io();
258 io_block_mapping(SYCAMORE_RTC_VADDR,
259 SYCAMORE_RTC_PADDR, SYCAMORE_RTC_SIZE, _PAGE_IO);
260}
261
262void __init
263platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
264 unsigned long r6, unsigned long r7)
265{
266 ppc4xx_init(r3, r4, r5, r6, r7);
267
268 ppc_md.setup_arch = sycamore_setup_arch;
269 ppc_md.setup_io_mappings = sycamore_map_io;
270
271#ifdef CONFIG_GEN_RTC
272 ppc_md.time_init = todc_time_init;
273 ppc_md.set_rtc_time = todc_set_rtc_time;
274 ppc_md.get_rtc_time = todc_get_rtc_time;
275 ppc_md.nvram_read_val = todc_direct_read_val;
276 ppc_md.nvram_write_val = todc_direct_write_val;
277#endif
278}
diff --git a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
new file mode 100644
index 000000000000..3e7b4e2c8c57
--- /dev/null
+++ b/arch/ppc/platforms/4xx/sycamore.h
@@ -0,0 +1,67 @@
1/*
2 * arch/ppc/platforms/4xx/sycamore.h
3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC
5 * 405GPr "Sycamore" evaluation board.
6 *
7 * Author: Armin Kuster <akuster@mvista.com>
8 *
9 * 2000 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifdef __KERNEL__
16#ifndef __ASM_SYCAMORE_H__
17#define __ASM_SYCAMORE_H__
18
19#include <platforms/4xx/ibm405gpr.h>
20
21#ifndef __ASSEMBLY__
22/*
23 * Data structure defining board information maintained by the boot
24 * ROM on IBM's "Sycamore" evaluation board. An effort has been made to
25 * keep the field names consistent with the 8xx 'bd_t' board info
26 * structures.
27 */
28
29typedef struct board_info {
30 unsigned char bi_s_version[4]; /* Version of this structure */
31 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
32 unsigned int bi_memsize; /* DRAM installed, in bytes */
33 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
34 unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
35 unsigned int bi_intfreq; /* Processor speed, in Hz */
36 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
37 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
38} bd_t;
39
40/* Some 4xx parts use a different timebase frequency from the internal clock.
41*/
42#define bi_tbfreq bi_intfreq
43
44
45/* Memory map for the IBM "Sycamore" 405GP evaluation board.
46 * Generic 4xx plus RTC.
47 */
48
49extern void *sycamore_rtc_base;
50#define SYCAMORE_RTC_PADDR ((uint)0xf0000000)
51#define SYCAMORE_RTC_VADDR SYCAMORE_RTC_PADDR
52#define SYCAMORE_RTC_SIZE ((uint)8*1024)
53
54#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
55#define BASE_BAUD 201600
56#else
57#define BASE_BAUD 691200
58#endif
59
60#define SYCAMORE_PS2_BASE 0xF0100000
61#define SYCAMORE_FPGA_BASE 0xF0300000
62
63#define PPC4xx_MACHINE_NAME "IBM Sycamore"
64
65#endif /* !__ASSEMBLY__ */
66#endif /* __ASM_SYCAMORE_H__ */
67#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/virtex-ii_pro.c b/arch/ppc/platforms/4xx/virtex-ii_pro.c
new file mode 100644
index 000000000000..097cc9d5aca0
--- /dev/null
+++ b/arch/ppc/platforms/4xx/virtex-ii_pro.c
@@ -0,0 +1,60 @@
1/*
2 * arch/ppc/platforms/4xx/virtex-ii_pro.c
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is licensed
9 * "as is" without any warranty of any kind, whether express or implied.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <asm/ocp.h>
15#include "virtex-ii_pro.h"
16
17/* Have OCP take care of the serial ports. */
18struct ocp_def core_ocp[] = {
19#ifdef XPAR_UARTNS550_0_BASEADDR
20 { .vendor = OCP_VENDOR_XILINX,
21 .function = OCP_FUNC_16550,
22 .index = 0,
23 .paddr = XPAR_UARTNS550_0_BASEADDR,
24 .irq = XPAR_INTC_0_UARTNS550_0_VEC_ID,
25 .pm = OCP_CPM_NA
26 },
27#ifdef XPAR_UARTNS550_1_BASEADDR
28 { .vendor = OCP_VENDOR_XILINX,
29 .function = OCP_FUNC_16550,
30 .index = 1,
31 .paddr = XPAR_UARTNS550_1_BASEADDR,
32 .irq = XPAR_INTC_0_UARTNS550_1_VEC_ID,
33 .pm = OCP_CPM_NA
34 },
35#ifdef XPAR_UARTNS550_2_BASEADDR
36 { .vendor = OCP_VENDOR_XILINX,
37 .function = OCP_FUNC_16550,
38 .index = 2,
39 .paddr = XPAR_UARTNS550_2_BASEADDR,
40 .irq = XPAR_INTC_0_UARTNS550_2_VEC_ID,
41 .pm = OCP_CPM_NA
42 },
43#ifdef XPAR_UARTNS550_3_BASEADDR
44 { .vendor = OCP_VENDOR_XILINX,
45 .function = OCP_FUNC_16550,
46 .index = 3,
47 .paddr = XPAR_UARTNS550_3_BASEADDR,
48 .irq = XPAR_INTC_0_UARTNS550_3_VEC_ID,
49 .pm = OCP_CPM_NA
50 },
51#ifdef XPAR_UARTNS550_4_BASEADDR
52#error Edit this file to add more devices.
53#endif /* 4 */
54#endif /* 3 */
55#endif /* 2 */
56#endif /* 1 */
57#endif /* 0 */
58 { .vendor = OCP_VENDOR_INVALID
59 }
60};
diff --git a/arch/ppc/platforms/4xx/virtex-ii_pro.h b/arch/ppc/platforms/4xx/virtex-ii_pro.h
new file mode 100644
index 000000000000..9014c4887339
--- /dev/null
+++ b/arch/ppc/platforms/4xx/virtex-ii_pro.h
@@ -0,0 +1,99 @@
1/*
2 * arch/ppc/platforms/4xx/virtex-ii_pro.h
3 *
4 * Include file that defines the Xilinx Virtex-II Pro processor
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
12 */
13
14#ifdef __KERNEL__
15#ifndef __ASM_VIRTEXIIPRO_H__
16#define __ASM_VIRTEXIIPRO_H__
17
18#include <linux/config.h>
19#include <asm/xparameters.h>
20
21/* serial defines */
22
23#define RS_TABLE_SIZE 4 /* change this and add more devices below
24 if you have more then 4 16x50 UARTs */
25
26#define BASE_BAUD (XPAR_UARTNS550_0_CLOCK_FREQ_HZ/16)
27
28/* The serial ports in the Virtex-II Pro have each I/O byte in the
29 * LSByte of a word. This means that iomem_reg_shift needs to be 2 to
30 * change the byte offsets into word offsets. In addition the base
31 * addresses need to have 3 added to them to get to the LSByte.
32 */
33#define STD_UART_OP(num) \
34 { 0, BASE_BAUD, 0, XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \
35 ASYNC_BOOT_AUTOCONF, \
36 .iomem_base = (u8 *)XPAR_UARTNS550_##num##_BASEADDR + 3, \
37 .iomem_reg_shift = 2, \
38 .io_type = SERIAL_IO_MEM},
39
40#if defined(XPAR_INTC_0_UARTNS550_0_VEC_ID)
41#define ML300_UART0 STD_UART_OP(0)
42#else
43#define ML300_UART0
44#endif
45
46#if defined(XPAR_INTC_0_UARTNS550_1_VEC_ID)
47#define ML300_UART1 STD_UART_OP(1)
48#else
49#define ML300_UART1
50#endif
51
52#if defined(XPAR_INTC_0_UARTNS550_2_VEC_ID)
53#define ML300_UART2 STD_UART_OP(2)
54#else
55#define ML300_UART2
56#endif
57
58#if defined(XPAR_INTC_0_UARTNS550_3_VEC_ID)
59#define ML300_UART3 STD_UART_OP(3)
60#else
61#define ML300_UART3
62#endif
63
64#if defined(XPAR_INTC_0_UARTNS550_4_VEC_ID)
65#error Edit this file to add more devices.
66#elif defined(XPAR_INTC_0_UARTNS550_3_VEC_ID)
67#define NR_SER_PORTS 4
68#elif defined(XPAR_INTC_0_UARTNS550_2_VEC_ID)
69#define NR_SER_PORTS 3
70#elif defined(XPAR_INTC_0_UARTNS550_1_VEC_ID)
71#define NR_SER_PORTS 2
72#elif defined(XPAR_INTC_0_UARTNS550_0_VEC_ID)
73#define NR_SER_PORTS 1
74#else
75#define NR_SER_PORTS 0
76#endif
77
78#if defined(CONFIG_UART0_TTYS0)
79#define SERIAL_PORT_DFNS \
80 ML300_UART0 \
81 ML300_UART1 \
82 ML300_UART2 \
83 ML300_UART3
84#endif
85
86#if defined(CONFIG_UART0_TTYS1)
87#define SERIAL_PORT_DFNS \
88 ML300_UART1 \
89 ML300_UART0 \
90 ML300_UART2 \
91 ML300_UART3
92#endif
93
94#define DCRN_CPMFR_BASE 0
95
96#include <asm/ibm405.h>
97
98#endif /* __ASM_VIRTEXIIPRO_H__ */
99#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
new file mode 100644
index 000000000000..a33eda4b7489
--- /dev/null
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -0,0 +1,249 @@
1/*
2 * arch/ppc/platforms/4xx/walnut.c
3 *
4 * Architecture- / platform-specific boot-time initialization code for
5 * IBM PowerPC 4xx based boards. Adapted from original
6 * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
7 * <dan@net4x.com>.
8 *
9 * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
10 *
11 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16#include <linux/config.h>
17#include <linux/init.h>
18#include <linux/smp.h>
19#include <linux/threads.h>
20#include <linux/param.h>
21#include <linux/string.h>
22#include <linux/pci.h>
23#include <linux/rtc.h>
24
25#include <asm/system.h>
26#include <asm/pci-bridge.h>
27#include <asm/machdep.h>
28#include <asm/page.h>
29#include <asm/time.h>
30#include <asm/io.h>
31#include <asm/ocp.h>
32#include <asm/ibm_ocp_pci.h>
33#include <asm/todc.h>
34
35#undef DEBUG
36
37#ifdef DEBUG
38#define DBG(x...) printk(x)
39#else
40#define DBG(x...)
41#endif
42
43void *kb_cs;
44void *kb_data;
45void *walnut_rtc_base;
46
47/* Some IRQs unique to Walnut.
48 * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
49 */
50int __init
51ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
52{
53 static char pci_irq_table[][4] =
54 /*
55 * PCI IDSEL/INTPIN->INTLINE
56 * A B C D
57 */
58 {
59 {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */
60 {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */
61 {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */
62 {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */
63 };
64
65 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
66 return PCI_IRQ_TABLE_LOOKUP;
67};
68
69void __init
70walnut_setup_arch(void)
71{
72
73 void *fpga_brdc;
74 unsigned char fpga_brdc_data;
75 void *fpga_enable;
76 void *fpga_polarity;
77 void *fpga_status;
78 void *fpga_trigger;
79
80 ppc4xx_setup_arch();
81
82 ibm_ocp_set_emac(0, 0);
83
84 kb_data = ioremap(WALNUT_PS2_BASE, 8);
85 if (!kb_data) {
86 printk(KERN_CRIT
87 "walnut_setup_arch() kb_data ioremap failed\n");
88 return;
89 }
90
91 kb_cs = kb_data + 1;
92
93 fpga_status = ioremap(WALNUT_FPGA_BASE, 8);
94 if (!fpga_status) {
95 printk(KERN_CRIT
96 "walnut_setup_arch() fpga_status ioremap failed\n");
97 return;
98 }
99
100 fpga_enable = fpga_status + 1;
101 fpga_polarity = fpga_status + 2;
102 fpga_trigger = fpga_status + 3;
103 fpga_brdc = fpga_status + 4;
104
105 /* split the keyboard and mouse interrupts */
106 fpga_brdc_data = readb(fpga_brdc);
107 fpga_brdc_data |= 0x80;
108 writeb(fpga_brdc_data, fpga_brdc);
109
110 writeb(0x3, fpga_enable);
111
112 writeb(0x3, fpga_polarity);
113
114 writeb(0x3, fpga_trigger);
115
116 /* RTC step for the walnut */
117 walnut_rtc_base = (void *) WALNUT_RTC_VADDR;
118 TODC_INIT(TODC_TYPE_DS1743, walnut_rtc_base, walnut_rtc_base,
119 walnut_rtc_base, 8);
120 /* Identify the system */
121 printk("IBM Walnut port (C) 2000-2002 MontaVista Software, Inc. (source@mvista.com)\n");
122}
123
124void __init
125bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
126{
127#ifdef CONFIG_PCI
128 unsigned int bar_response, bar;
129 /*
130 * Expected PCI mapping:
131 *
132 * PLB addr PCI memory addr
133 * --------------------- ---------------------
134 * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
135 * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
136 *
137 * PLB addr PCI io addr
138 * --------------------- ---------------------
139 * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
140 *
141 * The following code is simplified by assuming that the bootrom
142 * has been well behaved in following this mapping.
143 */
144
145#ifdef DEBUG
146 int i;
147
148 printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
149 printk("PCI bridge regs before fixup \n");
150 for (i = 0; i <= 3; i++) {
151 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
152 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
153 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
154 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
155 }
156 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
157 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
158 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
159 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
160
161#endif
162
163 /* added for IBM boot rom version 1.15 bios bar changes -AK */
164
165 /* Disable region first */
166 out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
167 /* PLB starting addr, PCI: 0x80000000 */
168 out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
169 /* PCI start addr, 0x80000000 */
170 out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
171 /* 512MB range of PLB to PCI */
172 out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
173 /* Enable no pre-fetch, enable region */
174 out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
175 (PPC405_PCI_UPPER_MEM -
176 PPC405_PCI_MEM_BASE)) | 0x01));
177
178 /* Disable region one */
179 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
180 out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
181 out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
182 out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
183 out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
184 out_le32((void *) &(pcip->ptm1ms), 0x00000000);
185
186 /* Disable region two */
187 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
188 out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
189 out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
190 out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
191 out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
192 out_le32((void *) &(pcip->ptm2ms), 0x00000000);
193
194 /* Zero config bars */
195 for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
196 early_write_config_dword(hose, hose->first_busno,
197 PCI_FUNC(hose->first_busno), bar,
198 0x00000000);
199 early_read_config_dword(hose, hose->first_busno,
200 PCI_FUNC(hose->first_busno), bar,
201 &bar_response);
202 DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
203 hose->first_busno, PCI_SLOT(hose->first_busno),
204 PCI_FUNC(hose->first_busno), bar, bar_response);
205 }
206 /* end work arround */
207
208#ifdef DEBUG
209 printk("PCI bridge regs after fixup \n");
210 for (i = 0; i <= 3; i++) {
211 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
212 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
213 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
214 printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
215 }
216 printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
217 printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
218 printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
219 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
220
221#endif
222#endif
223}
224
225void __init
226walnut_map_io(void)
227{
228 ppc4xx_map_io();
229 io_block_mapping(WALNUT_RTC_VADDR,
230 WALNUT_RTC_PADDR, WALNUT_RTC_SIZE, _PAGE_IO);
231}
232
233void __init
234platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
235 unsigned long r6, unsigned long r7)
236{
237 ppc4xx_init(r3, r4, r5, r6, r7);
238
239 ppc_md.setup_arch = walnut_setup_arch;
240 ppc_md.setup_io_mappings = walnut_map_io;
241
242#ifdef CONFIG_GEN_RTC
243 ppc_md.time_init = todc_time_init;
244 ppc_md.set_rtc_time = todc_set_rtc_time;
245 ppc_md.get_rtc_time = todc_get_rtc_time;
246 ppc_md.nvram_read_val = todc_direct_read_val;
247 ppc_md.nvram_write_val = todc_direct_write_val;
248#endif
249}
diff --git a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
new file mode 100644
index 000000000000..04cfbf3696b9
--- /dev/null
+++ b/arch/ppc/platforms/4xx/walnut.h
@@ -0,0 +1,72 @@
1/*
2 * arch/ppc/platforms/4xx/walnut.h
3 *
4 * Macros, definitions, and data structures specific to the IBM PowerPC
5 * 405GP "Walnut" evaluation board.
6 *
7 * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand
8 * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or
9 * source@mvista.com
10 *
11 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
12 *
13 * 2000 (c) MontaVista, Software, Inc. This file is licensed under
14 * the terms of the GNU General Public License version 2. This program
15 * is licensed "as is" without any warranty of any kind, whether express
16 * or implied.
17 */
18
19#ifdef __KERNEL__
20#ifndef __ASM_WALNUT_H__
21#define __ASM_WALNUT_H__
22
23/* We have a 405GP core */
24#include <platforms/4xx/ibm405gp.h>
25
26#ifndef __ASSEMBLY__
27/*
28 * Data structure defining board information maintained by the boot
29 * ROM on IBM's "Walnut" evaluation board. An effort has been made to
30 * keep the field names consistent with the 8xx 'bd_t' board info
31 * structures.
32 */
33
34typedef struct board_info {
35 unsigned char bi_s_version[4]; /* Version of this structure */
36 unsigned char bi_r_version[30]; /* Version of the IBM ROM */
37 unsigned int bi_memsize; /* DRAM installed, in bytes */
38 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
39 unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
40 unsigned int bi_intfreq; /* Processor speed, in Hz */
41 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
42 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
43} bd_t;
44
45/* Some 4xx parts use a different timebase frequency from the internal clock.
46*/
47#define bi_tbfreq bi_intfreq
48
49
50/* Memory map for the IBM "Walnut" 405GP evaluation board.
51 * Generic 4xx plus RTC.
52 */
53
54extern void *walnut_rtc_base;
55#define WALNUT_RTC_PADDR ((uint)0xf0000000)
56#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR
57#define WALNUT_RTC_SIZE ((uint)8*1024)
58
59#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
60#define BASE_BAUD 201600
61#else
62#define BASE_BAUD 691200
63#endif
64
65#define WALNUT_PS2_BASE 0xF0100000
66#define WALNUT_FPGA_BASE 0xF0300000
67
68#define PPC4xx_MACHINE_NAME "IBM Walnut"
69
70#endif /* !__ASSEMBLY__ */
71#endif /* __ASM_WALNUT_H__ */
72#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.c b/arch/ppc/platforms/4xx/xilinx_ml300.c
new file mode 100644
index 000000000000..0b1b77d986bf
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xilinx_ml300.c
@@ -0,0 +1,146 @@
1/*
2 * arch/ppc/platforms/4xx/xilinx_ml300.c
3 *
4 * Xilinx ML300 evaluation board initialization
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/tty.h>
18#include <linux/serial.h>
19#include <linux/serial_core.h>
20#include <linux/serialP.h>
21#include <asm/io.h>
22#include <asm/machdep.h>
23#include <asm/ocp.h>
24
25#include <platforms/4xx/virtex-ii_pro.h> /* for NR_SER_PORTS */
26
27/*
28 * As an overview of how the following functions (platform_init,
29 * ml300_map_io, ml300_setup_arch and ml300_init_IRQ) fit into the
30 * kernel startup procedure, here's a call tree:
31 *
32 * start_here arch/ppc/kernel/head_4xx.S
33 * early_init arch/ppc/kernel/setup.c
34 * machine_init arch/ppc/kernel/setup.c
35 * platform_init this file
36 * ppc4xx_init arch/ppc/syslib/ppc4xx_setup.c
37 * parse_bootinfo
38 * find_bootinfo
39 * "setup some default ppc_md pointers"
40 * MMU_init arch/ppc/mm/init.c
41 * *ppc_md.setup_io_mappings == ml300_map_io this file
42 * ppc4xx_map_io arch/ppc/syslib/ppc4xx_setup.c
43 * start_kernel init/main.c
44 * setup_arch arch/ppc/kernel/setup.c
45 * #if defined(CONFIG_KGDB)
46 * *ppc_md.kgdb_map_scc() == gen550_kgdb_map_scc
47 * #endif
48 * *ppc_md.setup_arch == ml300_setup_arch this file
49 * ppc4xx_setup_arch arch/ppc/syslib/ppc4xx_setup.c
50 * ppc4xx_find_bridges arch/ppc/syslib/ppc405_pci.c
51 * init_IRQ arch/ppc/kernel/irq.c
52 * *ppc_md.init_IRQ == ml300_init_IRQ this file
53 * ppc4xx_init_IRQ arch/ppc/syslib/ppc4xx_setup.c
54 * ppc4xx_pic_init arch/ppc/syslib/xilinx_pic.c
55 */
56
57#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
58
59static volatile unsigned *powerdown_base =
60 (volatile unsigned *) XPAR_POWER_0_POWERDOWN_BASEADDR;
61
62static void
63xilinx_power_off(void)
64{
65 local_irq_disable();
66 out_be32(powerdown_base, XPAR_POWER_0_POWERDOWN_VALUE);
67 while (1) ;
68}
69#endif
70
71void __init
72ml300_map_io(void)
73{
74 ppc4xx_map_io();
75
76#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
77 powerdown_base = ioremap((unsigned long) powerdown_base,
78 XPAR_POWER_0_POWERDOWN_HIGHADDR -
79 XPAR_POWER_0_POWERDOWN_BASEADDR + 1);
80#endif
81}
82
83static void __init
84ml300_early_serial_map(void)
85{
86#ifdef CONFIG_SERIAL_8250
87 struct serial_state old_ports[] = { SERIAL_PORT_DFNS };
88 struct uart_port port;
89 int i;
90
91 /* Setup ioremapped serial port access */
92 for (i = 0; i < ARRAY_SIZE(old_ports); i++ ) {
93 memset(&port, 0, sizeof(port));
94 port.membase = ioremap((phys_addr_t)(old_ports[i].iomem_base), 16);
95 port.irq = old_ports[i].irq;
96 port.uartclk = old_ports[i].baud_base * 16;
97 port.regshift = old_ports[i].iomem_reg_shift;
98 port.iotype = SERIAL_IO_MEM;
99 port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
100 port.line = i;
101
102 if (early_serial_setup(&port) != 0) {
103 printk("Early serial init of port %d failed\n", i);
104 }
105 }
106#endif /* CONFIG_SERIAL_8250 */
107}
108
109void __init
110ml300_setup_arch(void)
111{
112 ppc4xx_setup_arch(); /* calls ppc4xx_find_bridges() */
113
114 ml300_early_serial_map();
115
116 /* Identify the system */
117 printk(KERN_INFO "Xilinx Virtex-II Pro port\n");
118 printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
119}
120
121/* Called after board_setup_irq from ppc4xx_init_IRQ(). */
122void __init
123ml300_init_irq(void)
124{
125 ppc4xx_init_IRQ();
126}
127
128void __init
129platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
130 unsigned long r6, unsigned long r7)
131{
132 ppc4xx_init(r3, r4, r5, r6, r7);
133
134 ppc_md.setup_arch = ml300_setup_arch;
135 ppc_md.setup_io_mappings = ml300_map_io;
136 ppc_md.init_IRQ = ml300_init_irq;
137
138#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
139 ppc_md.power_off = xilinx_power_off;
140#endif
141
142#ifdef CONFIG_KGDB
143 ppc_md.early_serial_map = ml300_early_serial_map;
144#endif
145}
146
diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.h b/arch/ppc/platforms/4xx/xilinx_ml300.h
new file mode 100644
index 000000000000..f8c588412336
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xilinx_ml300.h
@@ -0,0 +1,47 @@
1/*
2 * arch/ppc/platforms/4xx/xilinx_ml300.h
3 *
4 * Include file that defines the Xilinx ML300 evaluation board
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
12 */
13
14#ifdef __KERNEL__
15#ifndef __ASM_XILINX_ML300_H__
16#define __ASM_XILINX_ML300_H__
17
18/* ML300 has a Xilinx Virtex-II Pro processor */
19#include <platforms/4xx/virtex-ii_pro.h>
20
21#ifndef __ASSEMBLY__
22
23#include <linux/types.h>
24
25typedef struct board_info {
26 unsigned int bi_memsize; /* DRAM installed, in bytes */
27 unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
28 unsigned int bi_intfreq; /* Processor speed, in Hz */
29 unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
30 unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
31} bd_t;
32
33/* Some 4xx parts use a different timebase frequency from the internal clock.
34*/
35#define bi_tbfreq bi_intfreq
36
37#endif /* !__ASSEMBLY__ */
38
39/* We don't need anything mapped. Size of zero will accomplish that. */
40#define PPC4xx_ONB_IO_PADDR 0u
41#define PPC4xx_ONB_IO_VADDR 0u
42#define PPC4xx_ONB_IO_SIZE 0u
43
44#define PPC4xx_MACHINE_NAME "Xilinx ML300"
45
46#endif /* __ASM_XILINX_ML300_H__ */
47#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/xparameters/xparameters_ml300.h b/arch/ppc/platforms/4xx/xparameters/xparameters_ml300.h
new file mode 100644
index 000000000000..97e3f4d4bd54
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xparameters/xparameters_ml300.h
@@ -0,0 +1,310 @@
1/*******************************************************************
2*
3* Author: Xilinx, Inc.
4*
5*
6* This program is free software; you can redistribute it and/or modify it
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*
12* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
13* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
14* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
15* XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
16* FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
17* ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
18* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
19* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
20* WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
21* CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
22* FITNESS FOR A PARTICULAR PURPOSE.
23*
24*
25* Xilinx hardware products are not intended for use in life support
26* appliances, devices, or systems. Use in such applications is
27* expressly prohibited.
28*
29*
30* (c) Copyright 2002-2004 Xilinx Inc.
31* All rights reserved.
32*
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* Description: Driver parameters
39*
40*******************************************************************/
41
42#define XPAR_XPCI_NUM_INSTANCES 1
43#define XPAR_XPCI_CLOCK_HZ 33333333
44#define XPAR_OPB_PCI_REF_0_DEVICE_ID 0
45#define XPAR_OPB_PCI_REF_0_BASEADDR 0x20000000
46#define XPAR_OPB_PCI_REF_0_HIGHADDR 0x3FFFFFFF
47#define XPAR_OPB_PCI_REF_0_CONFIG_ADDR 0x3C000000
48#define XPAR_OPB_PCI_REF_0_CONFIG_DATA 0x3C000004
49#define XPAR_OPB_PCI_REF_0_LCONFIG_ADDR 0x3E000000
50#define XPAR_OPB_PCI_REF_0_MEM_BASEADDR 0x20000000
51#define XPAR_OPB_PCI_REF_0_MEM_HIGHADDR 0x37FFFFFF
52#define XPAR_OPB_PCI_REF_0_IO_BASEADDR 0x38000000
53#define XPAR_OPB_PCI_REF_0_IO_HIGHADDR 0x3BFFFFFF
54
55/******************************************************************/
56
57#define XPAR_XEMAC_NUM_INSTANCES 1
58#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000
59#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF
60#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
61#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
62#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
63#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
64
65/******************************************************************/
66
67#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_0 0
68#define XPAR_MY_OPB_GPIO_0_BASEADDR_0 0x90000000
69#define XPAR_MY_OPB_GPIO_0_HIGHADDR_0 (0x90000000+0x7)
70#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_1 1
71#define XPAR_MY_OPB_GPIO_0_BASEADDR_1 (0x90000000+0x8)
72#define XPAR_MY_OPB_GPIO_0_HIGHADDR_1 (0x90000000+0x1F)
73#define XPAR_XGPIO_NUM_INSTANCES 2
74
75/******************************************************************/
76
77#define XPAR_XIIC_NUM_INSTANCES 1
78#define XPAR_OPB_IIC_0_BASEADDR 0xA8000000
79#define XPAR_OPB_IIC_0_HIGHADDR 0xA80001FF
80#define XPAR_OPB_IIC_0_DEVICE_ID 0
81#define XPAR_OPB_IIC_0_TEN_BIT_ADR 0
82
83/******************************************************************/
84
85#define XPAR_XUARTNS550_NUM_INSTANCES 2
86#define XPAR_XUARTNS550_CLOCK_HZ 100000000
87#define XPAR_OPB_UART16550_0_BASEADDR 0xA0000000
88#define XPAR_OPB_UART16550_0_HIGHADDR 0xA0001FFF
89#define XPAR_OPB_UART16550_0_DEVICE_ID 0
90#define XPAR_OPB_UART16550_1_BASEADDR 0xA0010000
91#define XPAR_OPB_UART16550_1_HIGHADDR 0xA0011FFF
92#define XPAR_OPB_UART16550_1_DEVICE_ID 1
93
94/******************************************************************/
95
96#define XPAR_XSPI_NUM_INSTANCES 1
97#define XPAR_OPB_SPI_0_BASEADDR 0xA4000000
98#define XPAR_OPB_SPI_0_HIGHADDR 0xA400007F
99#define XPAR_OPB_SPI_0_DEVICE_ID 0
100#define XPAR_OPB_SPI_0_FIFO_EXIST 1
101#define XPAR_OPB_SPI_0_SPI_SLAVE_ONLY 0
102#define XPAR_OPB_SPI_0_NUM_SS_BITS 1
103
104/******************************************************************/
105
106#define XPAR_XPS2_NUM_INSTANCES 2
107#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0 0
108#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0 0xA9000000
109#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0 (0xA9000000+0x3F)
110#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1 1
111#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1 (0xA9000000+0x1000)
112#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1 (0xA9000000+0x103F)
113
114/******************************************************************/
115
116#define XPAR_XTOUCHSCREEN_NUM_INSTANCES 1
117#define XPAR_OPB_TSD_REF_0_BASEADDR 0xAA000000
118#define XPAR_OPB_TSD_REF_0_HIGHADDR 0xAA000007
119#define XPAR_OPB_TSD_REF_0_DEVICE_ID 0
120
121/******************************************************************/
122
123#define XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR 0xA6000000
124#define XPAR_OPB_AC97_CONTROLLER_REF_0_HIGHADDR 0xA60000FF
125#define XPAR_OPB_PAR_PORT_REF_0_BASEADDR 0x90010000
126#define XPAR_OPB_PAR_PORT_REF_0_HIGHADDR 0x900100FF
127#define XPAR_PLB_DDR_0_BASEADDR 0x00000000
128#define XPAR_PLB_DDR_0_HIGHADDR 0x0FFFFFFF
129
130/******************************************************************/
131
132#define XPAR_XINTC_HAS_IPR 1
133#define XPAR_INTC_MAX_NUM_INTR_INPUTS 18
134#define XPAR_XINTC_USE_DCR 0
135#define XPAR_XINTC_NUM_INSTANCES 1
136#define XPAR_DCR_INTC_0_BASEADDR 0xD0000FC0
137#define XPAR_DCR_INTC_0_HIGHADDR 0xD0000FDF
138#define XPAR_DCR_INTC_0_DEVICE_ID 0
139#define XPAR_DCR_INTC_0_KIND_OF_INTR 0x00038000
140
141/******************************************************************/
142
143#define XPAR_DCR_INTC_0_MISC_LOGIC_0_PHY_MII_INT_INTR 0
144#define XPAR_DCR_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR 1
145#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_TEMP_CRIT_INTR 2
146#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_IRQ_INTR 3
147#define XPAR_DCR_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR 4
148#define XPAR_DCR_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR 5
149#define XPAR_DCR_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR 6
150#define XPAR_DCR_INTC_0_OPB_UART16550_1_IP2INTC_IRPT_INTR 7
151#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR 8
152#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR 9
153#define XPAR_DCR_INTC_0_OPB_SPI_0_IP2INTC_IRPT_INTR 10
154#define XPAR_DCR_INTC_0_OPB_TSD_REF_0_INTR_INTR 11
155#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_INTR 12
156#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_INTR 13
157#define XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR 14
158#define XPAR_DCR_INTC_0_PLB2OPB_BRIDGE_0_BUS_ERROR_DET_INTR 15
159#define XPAR_DCR_INTC_0_PLB_V34_0_BUS_ERROR_DET_INTR 16
160#define XPAR_DCR_INTC_0_OPB2PLB_BRIDGE_0_BUS_ERROR_DET_INTR 17
161
162/******************************************************************/
163
164#define XPAR_XTFT_NUM_INSTANCES 1
165#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR 0xD0000200
166#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_HIGHADDR 0xD0000207
167#define XPAR_PLB_TFT_CNTLR_REF_0_DEVICE_ID 0
168
169/******************************************************************/
170
171#define XPAR_XSYSACE_MEM_WIDTH 8
172#define XPAR_XSYSACE_NUM_INSTANCES 1
173#define XPAR_OPB_SYSACE_0_BASEADDR 0xCF000000
174#define XPAR_OPB_SYSACE_0_HIGHADDR 0xCF0001FF
175#define XPAR_OPB_SYSACE_0_DEVICE_ID 0
176#define XPAR_OPB_SYSACE_0_MEM_WIDTH 8
177
178/******************************************************************/
179
180#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
181
182/******************************************************************/
183
184/******************************************************************/
185
186/* Linux Redefines */
187
188/******************************************************************/
189
190#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
191#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
192#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
193#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
194#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
195#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
196#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
197#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
198
199/******************************************************************/
200
201#define XPAR_GPIO_0_BASEADDR XPAR_MY_OPB_GPIO_0_BASEADDR_0
202#define XPAR_GPIO_0_HIGHADDR XPAR_MY_OPB_GPIO_0_HIGHADDR_0
203#define XPAR_GPIO_0_DEVICE_ID XPAR_MY_OPB_GPIO_0_DEVICE_ID_0
204#define XPAR_GPIO_1_BASEADDR XPAR_MY_OPB_GPIO_0_BASEADDR_1
205#define XPAR_GPIO_1_HIGHADDR XPAR_MY_OPB_GPIO_0_HIGHADDR_1
206#define XPAR_GPIO_1_DEVICE_ID XPAR_MY_OPB_GPIO_0_DEVICE_ID_1
207
208/******************************************************************/
209
210#define XPAR_IIC_0_BASEADDR XPAR_OPB_IIC_0_BASEADDR
211#define XPAR_IIC_0_HIGHADDR XPAR_OPB_IIC_0_HIGHADDR
212#define XPAR_IIC_0_TEN_BIT_ADR XPAR_OPB_IIC_0_TEN_BIT_ADR
213#define XPAR_IIC_0_DEVICE_ID XPAR_OPB_IIC_0_DEVICE_ID
214
215/******************************************************************/
216
217#define XPAR_SYSACE_0_BASEADDR XPAR_OPB_SYSACE_0_BASEADDR
218#define XPAR_SYSACE_0_HIGHADDR XPAR_OPB_SYSACE_0_HIGHADDR
219#define XPAR_SYSACE_0_DEVICE_ID XPAR_OPB_SYSACE_0_DEVICE_ID
220
221/******************************************************************/
222
223#define XPAR_INTC_0_BASEADDR XPAR_DCR_INTC_0_BASEADDR
224#define XPAR_INTC_0_HIGHADDR XPAR_DCR_INTC_0_HIGHADDR
225#define XPAR_INTC_0_KIND_OF_INTR XPAR_DCR_INTC_0_KIND_OF_INTR
226#define XPAR_INTC_0_DEVICE_ID XPAR_DCR_INTC_0_DEVICE_ID
227
228/******************************************************************/
229
230#define XPAR_INTC_0_EMAC_0_VEC_ID XPAR_DCR_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR
231#define XPAR_INTC_0_IIC_0_VEC_ID XPAR_DCR_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR
232#define XPAR_INTC_0_SYSACE_0_VEC_ID XPAR_DCR_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR
233#define XPAR_INTC_0_UARTNS550_0_VEC_ID XPAR_DCR_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR
234#define XPAR_INTC_0_UARTNS550_1_VEC_ID XPAR_DCR_INTC_0_OPB_UART16550_1_IP2INTC_IRPT_INTR
235#define XPAR_INTC_0_PS2_0_VEC_ID XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR
236#define XPAR_INTC_0_PS2_1_VEC_ID XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR
237#define XPAR_INTC_0_SPI_0_VEC_ID XPAR_DCR_INTC_0_OPB_SPI_0_IP2INTC_IRPT_INTR
238#define XPAR_INTC_0_TOUCHSCREEN_0_VEC_ID XPAR_DCR_INTC_0_OPB_TSD_REF_0_INTR_INTR
239#define XPAR_INTC_0_PCI_0_VEC_ID_A XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR
240#define XPAR_INTC_0_PCI_0_VEC_ID_B XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR
241#define XPAR_INTC_0_PCI_0_VEC_ID_C XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR
242#define XPAR_INTC_0_PCI_0_VEC_ID_D XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR
243
244/******************************************************************/
245
246#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
247#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
248#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
249#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
250#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
251#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
252
253/******************************************************************/
254
255#define XPAR_SPI_0_BASEADDR XPAR_OPB_SPI_0_BASEADDR
256#define XPAR_SPI_0_HIGHADDR XPAR_OPB_SPI_0_HIGHADDR
257#define XPAR_SPI_0_DEVICE_ID XPAR_OPB_SPI_0_DEVICE_ID
258
259/******************************************************************/
260
261#define XPAR_TOUCHSCREEN_0_BASEADDR XPAR_OPB_TSD_REF_0_BASEADDR
262#define XPAR_TOUCHSCREEN_0_HIGHADDR XPAR_OPB_TSD_REF_0_HIGHADDR
263#define XPAR_TOUCHSCREEN_0_DEVICE_ID XPAR_OPB_TSD_REF_0_DEVICE_ID
264
265/******************************************************************/
266
267#define XPAR_TFT_0_BASEADDR XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR
268
269/******************************************************************/
270
271#define XPAR_PCI_0_BASEADDR XPAR_OPB_PCI_REF_0_BASEADDR
272#define XPAR_PCI_0_HIGHADDR XPAR_OPB_PCI_REF_0_HIGHADDR
273#define XPAR_PCI_0_CONFIG_ADDR XPAR_OPB_PCI_REF_0_CONFIG_ADDR
274#define XPAR_PCI_0_CONFIG_DATA XPAR_OPB_PCI_REF_0_CONFIG_DATA
275#define XPAR_PCI_0_LCONFIG_ADDR XPAR_OPB_PCI_REF_0_LCONFIG_ADDR
276#define XPAR_PCI_0_MEM_BASEADDR XPAR_OPB_PCI_REF_0_MEM_BASEADDR
277#define XPAR_PCI_0_MEM_HIGHADDR XPAR_OPB_PCI_REF_0_MEM_HIGHADDR
278#define XPAR_PCI_0_IO_BASEADDR XPAR_OPB_PCI_REF_0_IO_BASEADDR
279#define XPAR_PCI_0_IO_HIGHADDR XPAR_OPB_PCI_REF_0_IO_HIGHADDR
280#define XPAR_PCI_0_CLOCK_FREQ_HZ XPAR_XPCI_CLOCK_HZ
281#define XPAR_PCI_0_DEVICE_ID XPAR_OPB_PCI_REF_0_DEVICE_ID
282
283/******************************************************************/
284
285#define XPAR_PS2_0_BASEADDR XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0
286#define XPAR_PS2_0_HIGHADDR XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0
287#define XPAR_PS2_0_DEVICE_ID XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0
288#define XPAR_PS2_1_BASEADDR XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1
289#define XPAR_PS2_1_HIGHADDR XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1
290#define XPAR_PS2_1_DEVICE_ID XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1
291
292/******************************************************************/
293
294#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
295#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
296#define XPAR_DDR_0_SIZE 0x08000000
297
298/******************************************************************/
299
300#define XPAR_PERSISTENT_0_IIC_0_BASEADDR 0x00000400
301#define XPAR_PERSISTENT_0_IIC_0_HIGHADDR 0x000007FF
302#define XPAR_PERSISTENT_0_IIC_0_EEPROMADDR 0xA0
303
304/******************************************************************/
305
306#define XPAR_POWER_0_POWERDOWN_BASEADDR 0x90000004
307#define XPAR_POWER_0_POWERDOWN_HIGHADDR 0x90000007
308#define XPAR_POWER_0_POWERDOWN_VALUE 0xFF
309
310/******************************************************************/
diff --git a/arch/ppc/platforms/83xx/Makefile b/arch/ppc/platforms/83xx/Makefile
new file mode 100644
index 000000000000..eb55341d6a17
--- /dev/null
+++ b/arch/ppc/platforms/83xx/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for the PowerPC 83xx linux kernel.
3#
4obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
new file mode 100644
index 000000000000..b3b0f51979d2
--- /dev/null
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -0,0 +1,289 @@
1/*
2 * arch/ppc/platforms/83xx/mpc834x_sys.c
3 *
4 * MPC834x SYS board specific routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2005 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/serial.h>
31#include <linux/tty.h> /* for linux/serial_core.h */
32#include <linux/serial_core.h>
33#include <linux/initrd.h>
34#include <linux/module.h>
35#include <linux/fsl_devices.h>
36
37#include <asm/system.h>
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/atomic.h>
41#include <asm/time.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/prom.h>
45#include <asm/ipic.h>
46#include <asm/bootinfo.h>
47#include <asm/pci-bridge.h>
48#include <asm/mpc83xx.h>
49#include <asm/irq.h>
50#include <asm/kgdb.h>
51#include <asm/ppc_sys.h>
52#include <mm/mmu_decl.h>
53
54#include <syslib/ppc83xx_setup.h>
55
56#ifndef CONFIG_PCI
57unsigned long isa_io_base = 0;
58unsigned long isa_mem_base = 0;
59#endif
60
61extern unsigned long total_memory; /* in mm/init */
62
63unsigned char __res[sizeof (bd_t)];
64
65#ifdef CONFIG_PCI
66#error "PCI is not supported"
67/* NEED mpc83xx_map_irq & mpc83xx_exclude_device
68 see platforms/85xx/mpc85xx_ads_common.c */
69#endif /* CONFIG_PCI */
70
71/* ************************************************************************
72 *
73 * Setup the architecture
74 *
75 */
76static void __init
77mpc834x_sys_setup_arch(void)
78{
79 bd_t *binfo = (bd_t *) __res;
80 unsigned int freq;
81 struct gianfar_platform_data *pdata;
82
83 /* get the core frequency */
84 freq = binfo->bi_intfreq;
85
86 /* Set loops_per_jiffy to a half-way reasonable value,
87 for use until calibrate_delay gets called. */
88 loops_per_jiffy = freq / HZ;
89
90#ifdef CONFIG_PCI
91 /* setup PCI host bridges */
92 mpc83xx_sys_setup_hose();
93#endif
94 mpc83xx_early_serial_map();
95
96 /* setup the board related information for the enet controllers */
97 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
98 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
99 pdata->interruptPHY = MPC83xx_IRQ_EXT1;
100 pdata->phyid = 0;
101 /* fixup phy address */
102 pdata->phy_reg_addr += binfo->bi_immr_base;
103 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
104
105 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
106 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
107 pdata->interruptPHY = MPC83xx_IRQ_EXT2;
108 pdata->phyid = 1;
109 /* fixup phy address */
110 pdata->phy_reg_addr += binfo->bi_immr_base;
111 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
112
113#ifdef CONFIG_BLK_DEV_INITRD
114 if (initrd_start)
115 ROOT_DEV = Root_RAM0;
116 else
117#endif
118#ifdef CONFIG_ROOT_NFS
119 ROOT_DEV = Root_NFS;
120#else
121 ROOT_DEV = Root_HDA1;
122#endif
123}
124
125static void __init
126mpc834x_sys_map_io(void)
127{
128 /* we steal the lowest ioremap addr for virt space */
129 io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
130 io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
131}
132
133int
134mpc834x_sys_show_cpuinfo(struct seq_file *m)
135{
136 uint pvid, svid, phid1;
137 bd_t *binfo = (bd_t *) __res;
138 unsigned int freq;
139
140 /* get the core frequency */
141 freq = binfo->bi_intfreq;
142
143 pvid = mfspr(SPRN_PVR);
144 svid = mfspr(SPRN_SVR);
145
146 seq_printf(m, "Vendor\t\t: Freescale Inc.\n");
147 seq_printf(m, "Machine\t\t: mpc%s sys\n", cur_ppc_sys_spec->ppc_sys_name);
148 seq_printf(m, "core clock\t: %d MHz\n"
149 "bus clock\t: %d MHz\n",
150 (int)(binfo->bi_intfreq / 1000000),
151 (int)(binfo->bi_busfreq / 1000000));
152 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
153 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
154
155 /* Display cpu Pll setting */
156 phid1 = mfspr(SPRN_HID1);
157 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
158
159 /* Display the amount of memory */
160 seq_printf(m, "Memory\t\t: %d MB\n", (int)(binfo->bi_memsize / (1024 * 1024)));
161
162 return 0;
163}
164
165
166void __init
167mpc834x_sys_init_IRQ(void)
168{
169 bd_t *binfo = (bd_t *) __res;
170
171 u8 senses[8] = {
172 0, /* EXT 0 */
173 IRQ_SENSE_LEVEL, /* EXT 1 */
174 IRQ_SENSE_LEVEL, /* EXT 2 */
175 0, /* EXT 3 */
176 0, /* EXT 4 */
177 0, /* EXT 5 */
178 0, /* EXT 6 */
179 0, /* EXT 7 */
180 };
181
182 ipic_init(binfo->bi_immr_base + 0x00700, 0, MPC83xx_IPIC_IRQ_OFFSET, senses, 8);
183
184 /* Initialize the default interrupt mapping priorities,
185 * in case the boot rom changed something on us.
186 */
187 ipic_set_default_priority();
188}
189
190static __inline__ void
191mpc834x_sys_set_bat(void)
192{
193 /* we steal the lowest ioremap addr for virt space */
194 mb();
195 mtspr(SPRN_DBAT1U, VIRT_IMMRBAR | 0x1e);
196 mtspr(SPRN_DBAT1L, immrbar | 0x2a);
197 mb();
198}
199
200void __init
201platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
202 unsigned long r6, unsigned long r7)
203{
204 bd_t *binfo = (bd_t *) __res;
205
206 /* parse_bootinfo must always be called first */
207 parse_bootinfo(find_bootinfo());
208
209 /*
210 * If we were passed in a board information, copy it into the
211 * residual data area.
212 */
213 if (r3) {
214 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
215 sizeof (bd_t));
216 }
217
218#if defined(CONFIG_BLK_DEV_INITRD)
219 /*
220 * If the init RAM disk has been configured in, and there's a valid
221 * starting address for it, set it up.
222 */
223 if (r4) {
224 initrd_start = r4 + KERNELBASE;
225 initrd_end = r5 + KERNELBASE;
226 }
227#endif /* CONFIG_BLK_DEV_INITRD */
228
229 /* Copy the kernel command line arguments to a safe place. */
230 if (r6) {
231 *(char *) (r7 + KERNELBASE) = 0;
232 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
233 }
234
235 immrbar = binfo->bi_immr_base;
236
237 mpc834x_sys_set_bat();
238
239#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
240 {
241 struct uart_port p;
242
243 memset(&p, 0, sizeof (p));
244 p.iotype = SERIAL_IO_MEM;
245 p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500);
246 p.uartclk = binfo->bi_busfreq;
247
248 gen550_init(0, &p);
249
250 memset(&p, 0, sizeof (p));
251 p.iotype = SERIAL_IO_MEM;
252 p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600);
253 p.uartclk = binfo->bi_busfreq;
254
255 gen550_init(1, &p);
256 }
257#endif
258
259 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
260
261 /* setup the PowerPC module struct */
262 ppc_md.setup_arch = mpc834x_sys_setup_arch;
263 ppc_md.show_cpuinfo = mpc834x_sys_show_cpuinfo;
264
265 ppc_md.init_IRQ = mpc834x_sys_init_IRQ;
266 ppc_md.get_irq = ipic_get_irq;
267
268 ppc_md.restart = mpc83xx_restart;
269 ppc_md.power_off = mpc83xx_power_off;
270 ppc_md.halt = mpc83xx_halt;
271
272 ppc_md.find_end_of_memory = mpc83xx_find_end_of_memory;
273 ppc_md.setup_io_mappings = mpc834x_sys_map_io;
274
275 ppc_md.time_init = mpc83xx_time_init;
276 ppc_md.set_rtc_time = NULL;
277 ppc_md.get_rtc_time = NULL;
278 ppc_md.calibrate_decr = mpc83xx_calibrate_decr;
279
280 ppc_md.early_serial_map = mpc83xx_early_serial_map;
281#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
282 ppc_md.progress = gen550_progress;
283#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
284
285 if (ppc_md.progress)
286 ppc_md.progress("mpc834x_sys_init(): exit", 0);
287
288 return;
289}
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
new file mode 100644
index 000000000000..f4d055ae19c1
--- /dev/null
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -0,0 +1,51 @@
1/*
2 * arch/ppc/platforms/83xx/mpc834x_sys.h
3 *
4 * MPC834X SYS common board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2005 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC83XX_SYS_H__
18#define __MACH_MPC83XX_SYS_H__
19
20#include <linux/config.h>
21#include <linux/init.h>
22#include <linux/seq_file.h>
23#include <syslib/ppc83xx_setup.h>
24#include <asm/ppcboot.h>
25
26#define VIRT_IMMRBAR ((uint)0xfe000000)
27
28#define BCSR_PHYS_ADDR ((uint)0xf8000000)
29#define BCSR_VIRT_ADDR ((uint)0xfe100000)
30#define BCSR_SIZE ((uint)(32 * 1024))
31
32#ifdef CONFIG_PCI
33/* PCI interrupt controller */
34#define PIRQA MPC83xx_IRQ_IRQ4
35#define PIRQB MPC83xx_IRQ_IRQ5
36#define PIRQC MPC83xx_IRQ_IRQ6
37#define PIRQD MPC83xx_IRQ_IRQ7
38
39#define MPC834x_SYS_PCI1_LOWER_IO 0x00000000
40#define MPC834x_SYS_PCI1_UPPER_IO 0x00ffffff
41
42#define MPC834x_SYS_PCI1_LOWER_MEM 0x80000000
43#define MPC834x_SYS_PCI1_UPPER_MEM 0x9fffffff
44
45#define MPC834x_SYS_PCI1_IO_BASE 0xe2000000
46#define MPC834x_SYS_PCI1_MEM_OFFSET 0x00000000
47
48#define MPC834x_SYS_PCI1_IO_SIZE 0x01000000
49#endif /* CONFIG_PCI */
50
51#endif /* __MACH_MPC83XX_SYS_H__ */
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
new file mode 100644
index 000000000000..ff92e38e7da1
--- /dev/null
+++ b/arch/ppc/platforms/85xx/Kconfig
@@ -0,0 +1,76 @@
1config 85xx
2 bool
3 depends on E500
4 default y
5
6config PPC_INDIRECT_PCI_BE
7 bool
8 depends on 85xx
9 default y
10
11menu "Freescale 85xx options"
12 depends on E500
13
14choice
15 prompt "Machine Type"
16 depends on 85xx
17 default MPC8540_ADS
18
19config MPC8540_ADS
20 bool "Freescale MPC8540 ADS"
21 help
22 This option enables support for the MPC 8540 ADS evaluation board.
23
24config MPC8555_CDS
25 bool "Freescale MPC8555 CDS"
26 help
27 This option enablese support for the MPC8555 CDS evaluation board.
28
29config MPC8560_ADS
30 bool "Freescale MPC8560 ADS"
31 help
32 This option enables support for the MPC 8560 ADS evaluation board.
33
34config SBC8560
35 bool "WindRiver PowerQUICC III SBC8560"
36 help
37 This option enables support for the WindRiver PowerQUICC III
38 SBC8560 board.
39
40config STX_GP3
41 bool "Silicon Turnkey Express GP3"
42 help
43 This option enables support for the Silicon Turnkey Express GP3
44 board.
45
46endchoice
47
48# It's often necessary to know the specific 85xx processor type.
49# Fortunately, it is implied (so far) from the board type, so we
50# don't need to ask more redundant questions.
51config MPC8540
52 bool
53 depends on MPC8540_ADS
54 default y
55
56config MPC8555
57 bool
58 depends on MPC8555_CDS
59 default y
60
61config MPC8560
62 bool
63 depends on SBC8560 || MPC8560_ADS || STX_GP3
64 default y
65
66config 85xx_PCI2
67 bool "Supprt for 2nd PCI host controller"
68 depends on MPC8555_CDS
69 default y
70
71config PPC_GEN550
72 bool
73 depends on MPC8540 || SBC8560 || MPC8555
74 default y
75
76endmenu
diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
new file mode 100644
index 000000000000..854fbd298ba2
--- /dev/null
+++ b/arch/ppc/platforms/85xx/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the PowerPC 85xx linux kernel.
3#
4obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads_common.o mpc8540_ads.o
5obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o
6obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o
7obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o
8obj-$(CONFIG_STX_GP3) += stx_gp3.o
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
new file mode 100644
index 000000000000..4d857d6d633d
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -0,0 +1,218 @@
1/*
2 * arch/ppc/platforms/85xx/mpc8540_ads.c
3 *
4 * MPC8540ADS board specific routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/serial.h>
31#include <linux/tty.h> /* for linux/serial_core.h */
32#include <linux/serial_core.h>
33#include <linux/initrd.h>
34#include <linux/module.h>
35#include <linux/fsl_devices.h>
36
37#include <asm/system.h>
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/atomic.h>
41#include <asm/time.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/prom.h>
45#include <asm/open_pic.h>
46#include <asm/bootinfo.h>
47#include <asm/pci-bridge.h>
48#include <asm/mpc85xx.h>
49#include <asm/irq.h>
50#include <asm/immap_85xx.h>
51#include <asm/kgdb.h>
52#include <asm/ppc_sys.h>
53#include <mm/mmu_decl.h>
54
55#include <syslib/ppc85xx_setup.h>
56
57/* ************************************************************************
58 *
59 * Setup the architecture
60 *
61 */
62static void __init
63mpc8540ads_setup_arch(void)
64{
65 bd_t *binfo = (bd_t *) __res;
66 unsigned int freq;
67 struct gianfar_platform_data *pdata;
68
69 /* get the core frequency */
70 freq = binfo->bi_intfreq;
71
72 if (ppc_md.progress)
73 ppc_md.progress("mpc8540ads_setup_arch()", 0);
74
75 /* Set loops_per_jiffy to a half-way reasonable value,
76 for use until calibrate_delay gets called. */
77 loops_per_jiffy = freq / HZ;
78
79#ifdef CONFIG_PCI
80 /* setup PCI host bridges */
81 mpc85xx_setup_hose();
82#endif
83
84#ifdef CONFIG_SERIAL_8250
85 mpc85xx_early_serial_map();
86#endif
87
88#ifdef CONFIG_SERIAL_TEXT_DEBUG
89 /* Invalidate the entry we stole earlier the serial ports
90 * should be properly mapped */
91 invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
92#endif
93
94 /* setup the board related information for the enet controllers */
95 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
96 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
97 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
98 pdata->phyid = 0;
99 /* fixup phy address */
100 pdata->phy_reg_addr += binfo->bi_immr_base;
101 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
102
103 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
104 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
105 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
106 pdata->phyid = 1;
107 /* fixup phy address */
108 pdata->phy_reg_addr += binfo->bi_immr_base;
109 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
110
111 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
112 pdata->board_flags = 0;
113 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
114 pdata->phyid = 3;
115 /* fixup phy address */
116 pdata->phy_reg_addr += binfo->bi_immr_base;
117 memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
118
119#ifdef CONFIG_BLK_DEV_INITRD
120 if (initrd_start)
121 ROOT_DEV = Root_RAM0;
122 else
123#endif
124#ifdef CONFIG_ROOT_NFS
125 ROOT_DEV = Root_NFS;
126#else
127 ROOT_DEV = Root_HDA1;
128#endif
129}
130
131/* ************************************************************************ */
132void __init
133platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
134 unsigned long r6, unsigned long r7)
135{
136 /* parse_bootinfo must always be called first */
137 parse_bootinfo(find_bootinfo());
138
139 /*
140 * If we were passed in a board information, copy it into the
141 * residual data area.
142 */
143 if (r3) {
144 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
145 sizeof (bd_t));
146 }
147#ifdef CONFIG_SERIAL_TEXT_DEBUG
148 {
149 bd_t *binfo = (bd_t *) __res;
150 struct uart_port p;
151
152 /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
153 settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base,
154 binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
155
156 memset(&p, 0, sizeof (p));
157 p.iotype = SERIAL_IO_MEM;
158 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
159 p.uartclk = binfo->bi_busfreq;
160
161 gen550_init(0, &p);
162
163 memset(&p, 0, sizeof (p));
164 p.iotype = SERIAL_IO_MEM;
165 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
166 p.uartclk = binfo->bi_busfreq;
167
168 gen550_init(1, &p);
169 }
170#endif
171
172#if defined(CONFIG_BLK_DEV_INITRD)
173 /*
174 * If the init RAM disk has been configured in, and there's a valid
175 * starting address for it, set it up.
176 */
177 if (r4) {
178 initrd_start = r4 + KERNELBASE;
179 initrd_end = r5 + KERNELBASE;
180 }
181#endif /* CONFIG_BLK_DEV_INITRD */
182
183 /* Copy the kernel command line arguments to a safe place. */
184
185 if (r6) {
186 *(char *) (r7 + KERNELBASE) = 0;
187 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
188 }
189
190 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
191
192 /* setup the PowerPC module struct */
193 ppc_md.setup_arch = mpc8540ads_setup_arch;
194 ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo;
195
196 ppc_md.init_IRQ = mpc85xx_ads_init_IRQ;
197 ppc_md.get_irq = openpic_get_irq;
198
199 ppc_md.restart = mpc85xx_restart;
200 ppc_md.power_off = mpc85xx_power_off;
201 ppc_md.halt = mpc85xx_halt;
202
203 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
204
205 ppc_md.time_init = NULL;
206 ppc_md.set_rtc_time = NULL;
207 ppc_md.get_rtc_time = NULL;
208 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
209
210#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
211 ppc_md.progress = gen550_progress;
212#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
213
214 if (ppc_md.progress)
215 ppc_md.progress("mpc8540ads_init(): exit", 0);
216
217 return;
218}
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
new file mode 100644
index 000000000000..3d05d7c4a938
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.h
@@ -0,0 +1,25 @@
1/*
2 * arch/ppc/platforms/85xx/mpc8540_ads.h
3 *
4 * MPC8540ADS board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC8540ADS_H__
18#define __MACH_MPC8540ADS_H__
19
20#include <linux/config.h>
21#include <linux/initrd.h>
22#include <syslib/ppc85xx_setup.h>
23#include <platforms/85xx/mpc85xx_ads_common.h>
24
25#endif /* __MACH_MPC8540ADS_H__ */
diff --git a/arch/ppc/platforms/85xx/mpc8555_cds.h b/arch/ppc/platforms/85xx/mpc8555_cds.h
new file mode 100644
index 000000000000..e0e75568bc57
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc8555_cds.h
@@ -0,0 +1,26 @@
1/*
2 * arch/ppc/platforms/mpc8555_cds.h
3 *
4 * MPC8555CDS board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC8555CDS_H__
18#define __MACH_MPC8555CDS_H__
19
20#include <linux/config.h>
21#include <syslib/ppc85xx_setup.h>
22#include <platforms/85xx/mpc85xx_cds_common.h>
23
24#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
25
26#endif /* __MACH_MPC8555CDS_H__ */
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
new file mode 100644
index 000000000000..761b8c7b25d2
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -0,0 +1,210 @@
1/*
2 * arch/ppc/platforms/85xx/mpc8560_ads.c
3 *
4 * MPC8560ADS board specific routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/serial.h>
31#include <linux/tty.h> /* for linux/serial_core.h */
32#include <linux/serial_core.h>
33#include <linux/initrd.h>
34#include <linux/module.h>
35#include <linux/fsl_devices.h>
36
37#include <asm/system.h>
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/atomic.h>
41#include <asm/time.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/prom.h>
45#include <asm/open_pic.h>
46#include <asm/bootinfo.h>
47#include <asm/pci-bridge.h>
48#include <asm/mpc85xx.h>
49#include <asm/irq.h>
50#include <asm/immap_85xx.h>
51#include <asm/kgdb.h>
52#include <asm/ppc_sys.h>
53#include <asm/cpm2.h>
54#include <mm/mmu_decl.h>
55
56#include <syslib/cpm2_pic.h>
57#include <syslib/ppc85xx_common.h>
58#include <syslib/ppc85xx_setup.h>
59
60extern void cpm2_reset(void);
61
62/* ************************************************************************
63 *
64 * Setup the architecture
65 *
66 */
67
68static void __init
69mpc8560ads_setup_arch(void)
70{
71 bd_t *binfo = (bd_t *) __res;
72 unsigned int freq;
73 struct gianfar_platform_data *pdata;
74
75 cpm2_reset();
76
77 /* get the core frequency */
78 freq = binfo->bi_intfreq;
79
80 if (ppc_md.progress)
81 ppc_md.progress("mpc8560ads_setup_arch()", 0);
82
83 /* Set loops_per_jiffy to a half-way reasonable value,
84 for use until calibrate_delay gets called. */
85 loops_per_jiffy = freq / HZ;
86
87#ifdef CONFIG_PCI
88 /* setup PCI host bridges */
89 mpc85xx_setup_hose();
90#endif
91
92 /* setup the board related information for the enet controllers */
93 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
94 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
95 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
96 pdata->phyid = 0;
97 /* fixup phy address */
98 pdata->phy_reg_addr += binfo->bi_immr_base;
99 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
100
101 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
102 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
103 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
104 pdata->phyid = 1;
105 /* fixup phy address */
106 pdata->phy_reg_addr += binfo->bi_immr_base;
107 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
108
109#ifdef CONFIG_BLK_DEV_INITRD
110 if (initrd_start)
111 ROOT_DEV = Root_RAM0;
112 else
113#endif
114#ifdef CONFIG_ROOT_NFS
115 ROOT_DEV = Root_NFS;
116#else
117 ROOT_DEV = Root_HDA1;
118#endif
119}
120
121static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
122{
123 while ((irq = cpm2_get_irq(regs)) >= 0)
124 __do_IRQ(irq, regs);
125 return IRQ_HANDLED;
126}
127
128static struct irqaction cpm2_irqaction = {
129 .handler = cpm2_cascade,
130 .flags = SA_INTERRUPT,
131 .mask = CPU_MASK_NONE,
132 .name = "cpm2_cascade",
133};
134
135static void __init
136mpc8560_ads_init_IRQ(void)
137{
138 /* Setup OpenPIC */
139 mpc85xx_ads_init_IRQ();
140
141 /* Setup CPM2 PIC */
142 cpm2_init_IRQ();
143
144 setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
145
146 return;
147}
148
149
150
151/* ************************************************************************ */
152void __init
153platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
154 unsigned long r6, unsigned long r7)
155{
156 /* parse_bootinfo must always be called first */
157 parse_bootinfo(find_bootinfo());
158
159 /*
160 * If we were passed in a board information, copy it into the
161 * residual data area.
162 */
163 if (r3) {
164 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
165 sizeof (bd_t));
166
167 }
168#if defined(CONFIG_BLK_DEV_INITRD)
169 /*
170 * If the init RAM disk has been configured in, and there's a valid
171 * starting address for it, set it up.
172 */
173 if (r4) {
174 initrd_start = r4 + KERNELBASE;
175 initrd_end = r5 + KERNELBASE;
176 }
177#endif /* CONFIG_BLK_DEV_INITRD */
178
179 /* Copy the kernel command line arguments to a safe place. */
180
181 if (r6) {
182 *(char *) (r7 + KERNELBASE) = 0;
183 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
184 }
185
186 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
187
188 /* setup the PowerPC module struct */
189 ppc_md.setup_arch = mpc8560ads_setup_arch;
190 ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo;
191
192 ppc_md.init_IRQ = mpc8560_ads_init_IRQ;
193 ppc_md.get_irq = openpic_get_irq;
194
195 ppc_md.restart = mpc85xx_restart;
196 ppc_md.power_off = mpc85xx_power_off;
197 ppc_md.halt = mpc85xx_halt;
198
199 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
200
201 ppc_md.time_init = NULL;
202 ppc_md.set_rtc_time = NULL;
203 ppc_md.get_rtc_time = NULL;
204 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
205
206 if (ppc_md.progress)
207 ppc_md.progress("mpc8560ads_init(): exit", 0);
208
209 return;
210}
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.h b/arch/ppc/platforms/85xx/mpc8560_ads.h
new file mode 100644
index 000000000000..7df885d73e9d
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.h
@@ -0,0 +1,27 @@
1/*
2 * arch/ppc/platforms/mpc8560_ads.h
3 *
4 * MPC8540ADS board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC8560ADS_H
18#define __MACH_MPC8560ADS_H
19
20#include <linux/config.h>
21#include <syslib/ppc85xx_setup.h>
22#include <platforms/85xx/mpc85xx_ads_common.h>
23
24#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
25#define PHY_INTERRUPT MPC85xx_IRQ_EXT7
26
27#endif /* __MACH_MPC8560ADS_H */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
new file mode 100644
index 000000000000..ba9f9f562c45
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -0,0 +1,225 @@
1/*
2 * arch/ppc/platforms/85xx/mpc85xx_ads_common.c
3 *
4 * MPC85xx ADS board common routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/serial.h>
30#include <linux/module.h>
31
32#include <asm/system.h>
33#include <asm/pgtable.h>
34#include <asm/page.h>
35#include <asm/atomic.h>
36#include <asm/time.h>
37#include <asm/io.h>
38#include <asm/machdep.h>
39#include <asm/prom.h>
40#include <asm/open_pic.h>
41#include <asm/bootinfo.h>
42#include <asm/pci-bridge.h>
43#include <asm/mpc85xx.h>
44#include <asm/irq.h>
45#include <asm/immap_85xx.h>
46#include <asm/ppc_sys.h>
47
48#include <mm/mmu_decl.h>
49
50#include <platforms/85xx/mpc85xx_ads_common.h>
51
52#ifndef CONFIG_PCI
53unsigned long isa_io_base = 0;
54unsigned long isa_mem_base = 0;
55#endif
56
57extern unsigned long total_memory; /* in mm/init */
58
59unsigned char __res[sizeof (bd_t)];
60
61/* Internal interrupts are all Level Sensitive, and Positive Polarity */
62
63static u_char mpc85xx_ads_openpic_initsenses[] __initdata = {
64 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */
65 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */
66 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */
67 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */
68 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */
69 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */
70 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */
71 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */
72 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */
73 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */
74 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */
85 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */
86 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */
87 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */
89 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */
90 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */
91 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */
92 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */
93 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */
94 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */
95 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */
96 0x0, /* External 0: */
97#if defined(CONFIG_PCI)
98 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI slot 0 */
99 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI slot 1 */
100 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI slot 2 */
101 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 4: PCI slot 3 */
102#else
103 0x0, /* External 1: */
104 0x0, /* External 2: */
105 0x0, /* External 3: */
106 0x0, /* External 4: */
107#endif
108 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
109 0x0, /* External 6: */
110 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */
111 0x0, /* External 8: */
112 0x0, /* External 9: */
113 0x0, /* External 10: */
114 0x0, /* External 11: */
115};
116
117/* ************************************************************************ */
118int
119mpc85xx_ads_show_cpuinfo(struct seq_file *m)
120{
121 uint pvid, svid, phid1;
122 uint memsize = total_memory;
123 bd_t *binfo = (bd_t *) __res;
124 unsigned int freq;
125
126 /* get the core frequency */
127 freq = binfo->bi_intfreq;
128
129 pvid = mfspr(SPRN_PVR);
130 svid = mfspr(SPRN_SVR);
131
132 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
133 seq_printf(m, "Machine\t\t: mpc%sads\n", cur_ppc_sys_spec->ppc_sys_name);
134 seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000);
135 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
136 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
137
138 /* Display cpu Pll setting */
139 phid1 = mfspr(SPRN_HID1);
140 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
141
142 /* Display the amount of memory */
143 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
144
145 return 0;
146}
147
148void __init
149mpc85xx_ads_init_IRQ(void)
150{
151 bd_t *binfo = (bd_t *) __res;
152 /* Determine the Physical Address of the OpenPIC regs */
153 phys_addr_t OpenPIC_PAddr =
154 binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
155 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
156 OpenPIC_InitSenses = mpc85xx_ads_openpic_initsenses;
157 OpenPIC_NumInitSenses = sizeof (mpc85xx_ads_openpic_initsenses);
158
159 /* Skip reserved space and internal sources */
160 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
161 /* Map PIC IRQs 0-11 */
162 openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
163
164 /* we let openpic interrupts starting from an offset, to
165 * leave space for cascading interrupts underneath.
166 */
167 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
168
169 return;
170}
171
172#ifdef CONFIG_PCI
173/*
174 * interrupt routing
175 */
176
177int
178mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
179{
180 static char pci_irq_table[][4] =
181 /*
182 * This is little evil, but works around the fact
183 * that revA boards have IDSEL starting at 18
184 * and others boards (older) start at 12
185 *
186 * PCI IDSEL/INTPIN->INTLINE
187 * A B C D
188 */
189 {
190 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */
191 {PIRQD, PIRQA, PIRQB, PIRQC},
192 {PIRQC, PIRQD, PIRQA, PIRQB},
193 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */
194 {0, 0, 0, 0}, /* -- */
195 {0, 0, 0, 0}, /* -- */
196 {0, 0, 0, 0}, /* -- */
197 {0, 0, 0, 0}, /* -- */
198 {0, 0, 0, 0}, /* -- */
199 {0, 0, 0, 0}, /* -- */
200 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */
201 {PIRQD, PIRQA, PIRQB, PIRQC},
202 {PIRQC, PIRQD, PIRQA, PIRQB},
203 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */
204 {0, 0, 0, 0}, /* -- */
205 {0, 0, 0, 0}, /* -- */
206 {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */
207 {PIRQD, PIRQA, PIRQB, PIRQC},
208 {PIRQC, PIRQD, PIRQA, PIRQB},
209 {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */
210 };
211
212 const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4;
213 return PCI_IRQ_TABLE_LOOKUP;
214}
215
216int
217mpc85xx_exclude_device(u_char bus, u_char devfn)
218{
219 if (bus == 0 && PCI_SLOT(devfn) == 0)
220 return PCIBIOS_DEVICE_NOT_FOUND;
221 else
222 return PCIBIOS_SUCCESSFUL;
223}
224
225#endif /* CONFIG_PCI */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
new file mode 100644
index 000000000000..3875e839cff7
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -0,0 +1,50 @@
1/*
2 * arch/ppc/platforms/85xx/mpc85xx_ads_common.h
3 *
4 * MPC85XX ADS common board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC85XX_ADS_H__
18#define __MACH_MPC85XX_ADS_H__
19
20#include <linux/config.h>
21#include <linux/init.h>
22#include <linux/seq_file.h>
23#include <asm/ppcboot.h>
24
25#define BOARD_CCSRBAR ((uint)0xe0000000)
26#define BCSR_ADDR ((uint)0xf8000000)
27#define BCSR_SIZE ((uint)(32 * 1024))
28
29extern int mpc85xx_ads_show_cpuinfo(struct seq_file *m);
30extern void mpc85xx_ads_init_IRQ(void) __init;
31extern void mpc85xx_ads_map_io(void) __init;
32
33/* PCI interrupt controller */
34#define PIRQA MPC85xx_IRQ_EXT1
35#define PIRQB MPC85xx_IRQ_EXT2
36#define PIRQC MPC85xx_IRQ_EXT3
37#define PIRQD MPC85xx_IRQ_EXT4
38
39#define MPC85XX_PCI1_LOWER_IO 0x00000000
40#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
41
42#define MPC85XX_PCI1_LOWER_MEM 0x80000000
43#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
44
45#define MPC85XX_PCI1_IO_BASE 0xe2000000
46#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
47
48#define MPC85XX_PCI1_IO_SIZE 0x01000000
49
50#endif /* __MACH_MPC85XX_ADS_H__ */
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
new file mode 100644
index 000000000000..6c020d67ad70
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -0,0 +1,467 @@
1/*
2 * arch/ppc/platform/85xx/mpc85xx_cds_common.c
3 *
4 * MPC85xx CDS board specific routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor, Inc
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/serial.h>
30#include <linux/module.h>
31#include <linux/root_dev.h>
32#include <linux/initrd.h>
33#include <linux/tty.h>
34#include <linux/serial_core.h>
35#include <linux/fsl_devices.h>
36
37#include <asm/system.h>
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/atomic.h>
41#include <asm/time.h>
42#include <asm/todc.h>
43#include <asm/io.h>
44#include <asm/machdep.h>
45#include <asm/prom.h>
46#include <asm/open_pic.h>
47#include <asm/bootinfo.h>
48#include <asm/pci-bridge.h>
49#include <asm/mpc85xx.h>
50#include <asm/irq.h>
51#include <asm/immap_85xx.h>
52#include <asm/immap_cpm2.h>
53#include <asm/ppc_sys.h>
54#include <asm/kgdb.h>
55
56#include <mm/mmu_decl.h>
57#include <syslib/cpm2_pic.h>
58#include <syslib/ppc85xx_common.h>
59#include <syslib/ppc85xx_setup.h>
60
61
62#ifndef CONFIG_PCI
63unsigned long isa_io_base = 0;
64unsigned long isa_mem_base = 0;
65#endif
66
67extern unsigned long total_memory; /* in mm/init */
68
69unsigned char __res[sizeof (bd_t)];
70
71static int cds_pci_slot = 2;
72static volatile u8 * cadmus;
73
74/* Internal interrupts are all Level Sensitive, and Positive Polarity */
75
76static u_char mpc85xx_cds_openpic_initsenses[] __initdata = {
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */
85 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */
86 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */
87 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */
89 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */
90 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */
91 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */
92 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */
93 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */
94 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */
95 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */
96 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */
97 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */
98 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */
99 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */
100 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */
101 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */
102 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */
103 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */
104 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */
105 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */
106 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */
107 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */
108 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */
109#if defined(CONFIG_PCI)
110 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 0: PCI1 slot */
111 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI1 slot */
112 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI1 slot */
113 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI1 slot */
114#else
115 0x0, /* External 0: */
116 0x0, /* External 1: */
117 0x0, /* External 2: */
118 0x0, /* External 3: */
119#endif
120 0x0, /* External 4: */
121 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
122 0x0, /* External 6: */
123 0x0, /* External 7: */
124 0x0, /* External 8: */
125 0x0, /* External 9: */
126 0x0, /* External 10: */
127#if defined(CONFIG_85xx_PCI2) && defined(CONFIG_PCI)
128 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 11: PCI2 slot 0 */
129#else
130 0x0, /* External 11: */
131#endif
132};
133
134/* ************************************************************************ */
135int
136mpc85xx_cds_show_cpuinfo(struct seq_file *m)
137{
138 uint pvid, svid, phid1;
139 uint memsize = total_memory;
140 bd_t *binfo = (bd_t *) __res;
141 unsigned int freq;
142
143 /* get the core frequency */
144 freq = binfo->bi_intfreq;
145
146 pvid = mfspr(SPRN_PVR);
147 svid = mfspr(SPRN_SVR);
148
149 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
150 seq_printf(m, "Machine\t\t: CDS - MPC%s (%x)\n", cur_ppc_sys_spec->ppc_sys_name, cadmus[CM_VER]);
151 seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000);
152 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
153 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
154
155 /* Display cpu Pll setting */
156 phid1 = mfspr(SPRN_HID1);
157 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
158
159 /* Display the amount of memory */
160 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
161
162 return 0;
163}
164
165#ifdef CONFIG_CPM2
166static void cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
167{
168 while((irq = cpm2_get_irq(regs)) >= 0)
169 __do_IRQ(irq, regs);
170}
171
172static struct irqaction cpm2_irqaction = {
173 .handler = cpm2_cascade,
174 .flags = SA_INTERRUPT,
175 .mask = CPU_MASK_NONE,
176 .name = "cpm2_cascade",
177};
178#endif /* CONFIG_CPM2 */
179
180void __init
181mpc85xx_cds_init_IRQ(void)
182{
183 bd_t *binfo = (bd_t *) __res;
184
185 /* Determine the Physical Address of the OpenPIC regs */
186 phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
187 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
188 OpenPIC_InitSenses = mpc85xx_cds_openpic_initsenses;
189 OpenPIC_NumInitSenses = sizeof (mpc85xx_cds_openpic_initsenses);
190
191 /* Skip reserved space and internal sources */
192 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
193 /* Map PIC IRQs 0-11 */
194 openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
195
196 /* we let openpic interrupts starting from an offset, to
197 * leave space for cascading interrupts underneath.
198 */
199 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
200
201#ifdef CONFIG_CPM2
202 /* Setup CPM2 PIC */
203 cpm2_init_IRQ();
204
205 setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
206#endif
207
208 return;
209}
210
211#ifdef CONFIG_PCI
212/*
213 * interrupt routing
214 */
215int
216mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
217{
218 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
219
220 if (!hose->index)
221 {
222 /* Handle PCI1 interrupts */
223 char pci_irq_table[][4] =
224 /*
225 * PCI IDSEL/INTPIN->INTLINE
226 * A B C D
227 */
228
229 /* Note IRQ assignment for slots is based on which slot the elysium is
230 * in -- in this setup elysium is in slot #2 (this PIRQA as first
231 * interrupt on slot */
232 {
233 { 0, 1, 2, 3 }, /* 16 - PMC */
234 { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */
235 { 0, 1, 2, 3 }, /* 18 - Slot 1 */
236 { 1, 2, 3, 0 }, /* 19 - Slot 2 */
237 { 2, 3, 0, 1 }, /* 20 - Slot 3 */
238 { 3, 0, 1, 2 }, /* 21 - Slot 4 */
239 };
240
241 const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4;
242 int i, j;
243
244 for (i = 0; i < 6; i++)
245 for (j = 0; j < 4; j++)
246 pci_irq_table[i][j] =
247 ((pci_irq_table[i][j] + 5 -
248 cds_pci_slot) & 0x3) + PIRQ0A;
249
250 return PCI_IRQ_TABLE_LOOKUP;
251 } else {
252 /* Handle PCI2 interrupts (if we have one) */
253 char pci_irq_table[][4] =
254 {
255 /*
256 * We only have one slot and one interrupt
257 * going to PIRQA - PIRQD */
258 { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */
259 };
260
261 const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4;
262
263 return PCI_IRQ_TABLE_LOOKUP;
264 }
265}
266
267#define ARCADIA_HOST_BRIDGE_IDSEL 17
268#define ARCADIA_2ND_BRIDGE_IDSEL 3
269
270extern int mpc85xx_pci1_last_busno;
271
272int
273mpc85xx_exclude_device(u_char bus, u_char devfn)
274{
275 if (bus == 0 && PCI_SLOT(devfn) == 0)
276 return PCIBIOS_DEVICE_NOT_FOUND;
277#ifdef CONFIG_85xx_PCI2
278 if (mpc85xx_pci1_last_busno)
279 if (bus == (mpc85xx_pci1_last_busno + 1) && PCI_SLOT(devfn) == 0)
280 return PCIBIOS_DEVICE_NOT_FOUND;
281#endif
282 /* We explicitly do not go past the Tundra 320 Bridge */
283 if (bus == 1)
284 return PCIBIOS_DEVICE_NOT_FOUND;
285 if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
286 return PCIBIOS_DEVICE_NOT_FOUND;
287 else
288 return PCIBIOS_SUCCESSFUL;
289}
290#endif /* CONFIG_PCI */
291
292TODC_ALLOC();
293
294/* ************************************************************************
295 *
296 * Setup the architecture
297 *
298 */
299static void __init
300mpc85xx_cds_setup_arch(void)
301{
302 bd_t *binfo = (bd_t *) __res;
303 unsigned int freq;
304 struct gianfar_platform_data *pdata;
305
306 /* get the core frequency */
307 freq = binfo->bi_intfreq;
308
309 printk("mpc85xx_cds_setup_arch\n");
310
311#ifdef CONFIG_CPM2
312 cpm2_reset();
313#endif
314
315 cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE);
316 cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1;
317 printk("CDS Version = %x in PCI slot %d\n", cadmus[CM_VER], cds_pci_slot);
318
319 /* Setup TODC access */
320 TODC_INIT(TODC_TYPE_DS1743,
321 0,
322 0,
323 ioremap(CDS_RTC_ADDR, CDS_RTC_SIZE),
324 8);
325
326 /* Set loops_per_jiffy to a half-way reasonable value,
327 for use until calibrate_delay gets called. */
328 loops_per_jiffy = freq / HZ;
329
330#ifdef CONFIG_PCI
331 /* setup PCI host bridges */
332 mpc85xx_setup_hose();
333#endif
334
335#ifdef CONFIG_SERIAL_8250
336 mpc85xx_early_serial_map();
337#endif
338
339#ifdef CONFIG_SERIAL_TEXT_DEBUG
340 /* Invalidate the entry we stole earlier the serial ports
341 * should be properly mapped */
342 invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
343#endif
344
345 /* setup the board related information for the enet controllers */
346 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
347 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
348 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
349 pdata->phyid = 0;
350 /* fixup phy address */
351 pdata->phy_reg_addr += binfo->bi_immr_base;
352 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
353
354 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
355 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
356 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
357 pdata->phyid = 1;
358 /* fixup phy address */
359 pdata->phy_reg_addr += binfo->bi_immr_base;
360 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
361
362
363#ifdef CONFIG_BLK_DEV_INITRD
364 if (initrd_start)
365 ROOT_DEV = Root_RAM0;
366 else
367#endif
368#ifdef CONFIG_ROOT_NFS
369 ROOT_DEV = Root_NFS;
370#else
371 ROOT_DEV = Root_HDA1;
372#endif
373}
374
375/* ************************************************************************ */
376void __init
377platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
378 unsigned long r6, unsigned long r7)
379{
380 /* parse_bootinfo must always be called first */
381 parse_bootinfo(find_bootinfo());
382
383 /*
384 * If we were passed in a board information, copy it into the
385 * residual data area.
386 */
387 if (r3) {
388 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
389 sizeof (bd_t));
390
391 }
392#ifdef CONFIG_SERIAL_TEXT_DEBUG
393 {
394 bd_t *binfo = (bd_t *) __res;
395 struct uart_port p;
396
397 /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
398 settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base,
399 binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
400
401 memset(&p, 0, sizeof (p));
402 p.iotype = SERIAL_IO_MEM;
403 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
404 p.uartclk = binfo->bi_busfreq;
405
406 gen550_init(0, &p);
407
408 memset(&p, 0, sizeof (p));
409 p.iotype = SERIAL_IO_MEM;
410 p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
411 p.uartclk = binfo->bi_busfreq;
412
413 gen550_init(1, &p);
414 }
415#endif
416
417#if defined(CONFIG_BLK_DEV_INITRD)
418 /*
419 * If the init RAM disk has been configured in, and there's a valid
420 * starting address for it, set it up.
421 */
422 if (r4) {
423 initrd_start = r4 + KERNELBASE;
424 initrd_end = r5 + KERNELBASE;
425 }
426#endif /* CONFIG_BLK_DEV_INITRD */
427
428 /* Copy the kernel command line arguments to a safe place. */
429
430 if (r6) {
431 *(char *) (r7 + KERNELBASE) = 0;
432 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
433 }
434
435 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
436
437 /* setup the PowerPC module struct */
438 ppc_md.setup_arch = mpc85xx_cds_setup_arch;
439 ppc_md.show_cpuinfo = mpc85xx_cds_show_cpuinfo;
440
441 ppc_md.init_IRQ = mpc85xx_cds_init_IRQ;
442 ppc_md.get_irq = openpic_get_irq;
443
444 ppc_md.restart = mpc85xx_restart;
445 ppc_md.power_off = mpc85xx_power_off;
446 ppc_md.halt = mpc85xx_halt;
447
448 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
449
450 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
451
452 ppc_md.time_init = todc_time_init;
453 ppc_md.set_rtc_time = todc_set_rtc_time;
454 ppc_md.get_rtc_time = todc_get_rtc_time;
455
456 ppc_md.nvram_read_val = todc_direct_read_val;
457 ppc_md.nvram_write_val = todc_direct_write_val;
458
459#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
460 ppc_md.progress = gen550_progress;
461#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
462
463 if (ppc_md.progress)
464 ppc_md.progress("mpc85xx_cds_init(): exit", 0);
465
466 return;
467}
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
new file mode 100644
index 000000000000..7627d77504bd
--- /dev/null
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -0,0 +1,80 @@
1/*
2 * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
3 *
4 * MPC85xx CDS board definitions
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor, Inc
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef __MACH_MPC85XX_CDS_H__
18#define __MACH_MPC85XX_CDS_H__
19
20#include <linux/config.h>
21#include <linux/serial.h>
22#include <asm/ppcboot.h>
23#include <linux/initrd.h>
24#include <syslib/ppc85xx_setup.h>
25
26#define BOARD_CCSRBAR ((uint)0xe0000000)
27#define CCSRBAR_SIZE ((uint)1024*1024)
28
29/* CADMUS info */
30#define CADMUS_BASE (0xf8004000)
31#define CADMUS_SIZE (256)
32#define CM_VER (0)
33#define CM_CSR (1)
34#define CM_RST (2)
35
36/* CDS NVRAM/RTC */
37#define CDS_RTC_ADDR (0xf8000000)
38#define CDS_RTC_SIZE (8 * 1024)
39
40/* PCI config */
41#define PCI1_CFG_ADDR_OFFSET (0x8000)
42#define PCI1_CFG_DATA_OFFSET (0x8004)
43
44#define PCI2_CFG_ADDR_OFFSET (0x9000)
45#define PCI2_CFG_DATA_OFFSET (0x9004)
46
47/* PCI interrupt controller */
48#define PIRQ0A MPC85xx_IRQ_EXT0
49#define PIRQ0B MPC85xx_IRQ_EXT1
50#define PIRQ0C MPC85xx_IRQ_EXT2
51#define PIRQ0D MPC85xx_IRQ_EXT3
52#define PIRQ1A MPC85xx_IRQ_EXT11
53
54/* PCI 1 memory map */
55#define MPC85XX_PCI1_LOWER_IO 0x00000000
56#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
57
58#define MPC85XX_PCI1_LOWER_MEM 0x80000000
59#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
60
61#define MPC85XX_PCI1_IO_BASE 0xe2000000
62#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
63
64#define MPC85XX_PCI1_IO_SIZE 0x01000000
65
66/* PCI 2 memory map */
67/* Note: the standard PPC fixups will cause IO space to get bumped by
68 * hose->io_base_virt - isa_io_base => MPC85XX_PCI1_IO_SIZE */
69#define MPC85XX_PCI2_LOWER_IO 0x00000000
70#define MPC85XX_PCI2_UPPER_IO 0x00ffffff
71
72#define MPC85XX_PCI2_LOWER_MEM 0xa0000000
73#define MPC85XX_PCI2_UPPER_MEM 0xbfffffff
74
75#define MPC85XX_PCI2_IO_BASE 0xe3000000
76#define MPC85XX_PCI2_MEM_OFFSET 0x00000000
77
78#define MPC85XX_PCI2_IO_SIZE 0x01000000
79
80#endif /* __MACH_MPC85XX_CDS_H__ */
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
new file mode 100644
index 000000000000..9ab05e590c3e
--- /dev/null
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -0,0 +1,227 @@
1/*
2 * arch/ppc/platforms/85xx/sbc8560.c
3 *
4 * Wind River SBC8560 board specific routines
5 *
6 * Maintainer: Kumar Gala <kumar.gala@freescale.com>
7 *
8 * Copyright 2004 Freescale Semiconductor Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/serial.h>
31#include <linux/tty.h> /* for linux/serial_core.h */
32#include <linux/serial_core.h>
33#include <linux/initrd.h>
34#include <linux/module.h>
35#include <linux/fsl_devices.h>
36
37#include <asm/system.h>
38#include <asm/pgtable.h>
39#include <asm/page.h>
40#include <asm/atomic.h>
41#include <asm/time.h>
42#include <asm/io.h>
43#include <asm/machdep.h>
44#include <asm/prom.h>
45#include <asm/open_pic.h>
46#include <asm/bootinfo.h>
47#include <asm/pci-bridge.h>
48#include <asm/mpc85xx.h>
49#include <asm/irq.h>
50#include <asm/immap_85xx.h>
51#include <asm/kgdb.h>
52#include <asm/ppc_sys.h>
53#include <mm/mmu_decl.h>
54
55#include <syslib/ppc85xx_common.h>
56#include <syslib/ppc85xx_setup.h>
57
58#ifdef CONFIG_SERIAL_8250
59static void __init
60sbc8560_early_serial_map(void)
61{
62 struct uart_port uart_req;
63
64 /* Setup serial port access */
65 memset(&uart_req, 0, sizeof (uart_req));
66 uart_req.irq = MPC85xx_IRQ_EXT9;
67 uart_req.flags = STD_COM_FLAGS;
68 uart_req.uartclk = BASE_BAUD * 16;
69 uart_req.iotype = SERIAL_IO_MEM;
70 uart_req.mapbase = UARTA_ADDR;
71 uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE);
72 uart_req.type = PORT_16650;
73
74#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
75 gen550_init(0, &uart_req);
76#endif
77
78 if (early_serial_setup(&uart_req) != 0)
79 printk("Early serial init of port 0 failed\n");
80
81 /* Assume early_serial_setup() doesn't modify uart_req */
82 uart_req.line = 1;
83 uart_req.mapbase = UARTB_ADDR;
84 uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART1_SIZE);
85 uart_req.irq = MPC85xx_IRQ_EXT10;
86
87#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
88 gen550_init(1, &uart_req);
89#endif
90
91 if (early_serial_setup(&uart_req) != 0)
92 printk("Early serial init of port 1 failed\n");
93}
94#endif
95
96/* ************************************************************************
97 *
98 * Setup the architecture
99 *
100 */
101static void __init
102sbc8560_setup_arch(void)
103{
104 bd_t *binfo = (bd_t *) __res;
105 unsigned int freq;
106 struct gianfar_platform_data *pdata;
107
108 /* get the core frequency */
109 freq = binfo->bi_intfreq;
110
111 if (ppc_md.progress)
112 ppc_md.progress("sbc8560_setup_arch()", 0);
113
114 /* Set loops_per_jiffy to a half-way reasonable value,
115 for use until calibrate_delay gets called. */
116 loops_per_jiffy = freq / HZ;
117
118#ifdef CONFIG_PCI
119 /* setup PCI host bridges */
120 mpc85xx_setup_hose();
121#endif
122#ifdef CONFIG_SERIAL_8250
123 sbc8560_early_serial_map();
124#endif
125#ifdef CONFIG_SERIAL_TEXT_DEBUG
126 /* Invalidate the entry we stole earlier the serial ports
127 * should be properly mapped */
128 invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
129#endif
130
131 /* setup the board related information for the enet controllers */
132 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
133 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
134 pdata->interruptPHY = MPC85xx_IRQ_EXT6;
135 pdata->phyid = 25;
136 /* fixup phy address */
137 pdata->phy_reg_addr += binfo->bi_immr_base;
138 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
139
140 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
141 pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
142 pdata->interruptPHY = MPC85xx_IRQ_EXT7;
143 pdata->phyid = 26;
144 /* fixup phy address */
145 pdata->phy_reg_addr += binfo->bi_immr_base;
146 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
147
148#ifdef CONFIG_BLK_DEV_INITRD
149 if (initrd_start)
150 ROOT_DEV = Root_RAM0;
151 else
152#endif
153#ifdef CONFIG_ROOT_NFS
154 ROOT_DEV = Root_NFS;
155#else
156 ROOT_DEV = Root_HDA1;
157#endif
158}
159
160/* ************************************************************************ */
161void __init
162platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
163 unsigned long r6, unsigned long r7)
164{
165 /* parse_bootinfo must always be called first */
166 parse_bootinfo(find_bootinfo());
167
168 /*
169 * If we were passed in a board information, copy it into the
170 * residual data area.
171 */
172 if (r3) {
173 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
174 sizeof (bd_t));
175 }
176
177#ifdef CONFIG_SERIAL_TEXT_DEBUG
178 /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
179 settlbcam(NUM_TLBCAMS - 1, UARTA_ADDR,
180 UARTA_ADDR, 0x1000, _PAGE_IO, 0);
181#endif
182
183#if defined(CONFIG_BLK_DEV_INITRD)
184 /*
185 * If the init RAM disk has been configured in, and there's a valid
186 * starting address for it, set it up.
187 */
188 if (r4) {
189 initrd_start = r4 + KERNELBASE;
190 initrd_end = r5 + KERNELBASE;
191 }
192#endif /* CONFIG_BLK_DEV_INITRD */
193
194 /* Copy the kernel command line arguments to a safe place. */
195
196 if (r6) {
197 *(char *) (r7 + KERNELBASE) = 0;
198 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
199 }
200
201 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
202
203 /* setup the PowerPC module struct */
204 ppc_md.setup_arch = sbc8560_setup_arch;
205 ppc_md.show_cpuinfo = sbc8560_show_cpuinfo;
206
207 ppc_md.init_IRQ = sbc8560_init_IRQ;
208 ppc_md.get_irq = openpic_get_irq;
209
210 ppc_md.restart = mpc85xx_restart;
211 ppc_md.power_off = mpc85xx_power_off;
212 ppc_md.halt = mpc85xx_halt;
213
214 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
215
216 ppc_md.time_init = NULL;
217 ppc_md.set_rtc_time = NULL;
218 ppc_md.get_rtc_time = NULL;
219 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
220
221#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
222 ppc_md.progress = gen550_progress;
223#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
224
225 if (ppc_md.progress)
226 ppc_md.progress("sbc8560_init(): exit", 0);
227}
diff --git a/arch/ppc/platforms/85xx/sbc8560.h b/arch/ppc/platforms/85xx/sbc8560.h
new file mode 100644
index 000000000000..5e1b00c77da5
--- /dev/null
+++ b/arch/ppc/platforms/85xx/sbc8560.h
@@ -0,0 +1,49 @@
1/*
2 * arch/ppc/platforms/85xx/sbc8560.h
3 *
4 * Wind River SBC8560 board definitions
5 *
6 * Copyright 2003 Motorola Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MACH_SBC8560_H__
16#define __MACH_SBC8560_H__
17
18#include <linux/config.h>
19#include <platforms/85xx/sbc85xx.h>
20
21#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
22
23#ifdef CONFIG_SERIAL_MANY_PORTS
24#define RS_TABLE_SIZE 64
25#else
26#define RS_TABLE_SIZE 2
27#endif
28
29/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
30#define BASE_BAUD ( 1843200 / 16 )
31
32#ifdef CONFIG_SERIAL_DETECT_IRQ
33#define STD_COM_FLAGS (ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
34#else
35#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
36#endif
37
38#define STD_SERIAL_PORT_DFNS \
39 { 0, BASE_BAUD, UARTA_ADDR, MPC85xx_IRQ_EXT9, STD_COM_FLAGS, /* ttyS0 */ \
40 iomem_base: (u8 *)UARTA_ADDR, \
41 io_type: SERIAL_IO_MEM }, \
42 { 0, BASE_BAUD, UARTB_ADDR, MPC85xx_IRQ_EXT10, STD_COM_FLAGS, /* ttyS1 */ \
43 iomem_base: (u8 *)UARTB_ADDR, \
44 io_type: SERIAL_IO_MEM },
45
46#define SERIAL_PORT_DFNS \
47 STD_SERIAL_PORT_DFNS
48
49#endif /* __MACH_SBC8560_H__ */
diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c
new file mode 100644
index 000000000000..2d638c1c1bd6
--- /dev/null
+++ b/arch/ppc/platforms/85xx/sbc85xx.c
@@ -0,0 +1,203 @@
1/*
2 * arch/ppc/platform/85xx/sbc85xx.c
3 *
4 * WindRiver PowerQUICC III SBC85xx board common routines
5 *
6 * Copyright 2002, 2003 Motorola Inc.
7 * Copyright 2004 Red Hat, 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
15#include <linux/config.h>
16#include <linux/stddef.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <linux/reboot.h>
21#include <linux/pci.h>
22#include <linux/kdev_t.h>
23#include <linux/major.h>
24#include <linux/console.h>
25#include <linux/delay.h>
26#include <linux/irq.h>
27#include <linux/seq_file.h>
28#include <linux/serial.h>
29#include <linux/module.h>
30
31#include <asm/system.h>
32#include <asm/pgtable.h>
33#include <asm/page.h>
34#include <asm/atomic.h>
35#include <asm/time.h>
36#include <asm/io.h>
37#include <asm/machdep.h>
38#include <asm/prom.h>
39#include <asm/open_pic.h>
40#include <asm/bootinfo.h>
41#include <asm/pci-bridge.h>
42#include <asm/mpc85xx.h>
43#include <asm/irq.h>
44#include <asm/immap_85xx.h>
45#include <asm/ppc_sys.h>
46
47#include <mm/mmu_decl.h>
48
49#include <platforms/85xx/sbc85xx.h>
50
51unsigned char __res[sizeof (bd_t)];
52
53#ifndef CONFIG_PCI
54unsigned long isa_io_base = 0;
55unsigned long isa_mem_base = 0;
56unsigned long pci_dram_offset = 0;
57#endif
58
59extern unsigned long total_memory; /* in mm/init */
60
61/* Internal interrupts are all Level Sensitive, and Positive Polarity */
62
63static u_char sbc8560_openpic_initsenses[] __initdata = {
64 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */
65 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */
66 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */
67 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */
68 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */
69 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */
70 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */
71 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */
72 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */
73 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */
74 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */
85 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */
86 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */
87 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */
89 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */
90 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */
91 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */
92 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */
93 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */
94 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */
95 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */
96 0x0, /* External 0: */
97 0x0, /* External 1: */
98#if defined(CONFIG_PCI)
99 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI slot 0 */
100 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI slot 1 */
101 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 4: PCI slot 2 */
102 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PCI slot 3 */
103#else
104 0x0, /* External 2: */
105 0x0, /* External 3: */
106 0x0, /* External 4: */
107 0x0, /* External 5: */
108#endif
109 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 6: PHY */
110 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */
111 0x0, /* External 8: */
112 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: PHY */
113 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 10: PHY */
114 0x0, /* External 11: */
115};
116
117/* ************************************************************************ */
118int
119sbc8560_show_cpuinfo(struct seq_file *m)
120{
121 uint pvid, svid, phid1;
122 uint memsize = total_memory;
123 bd_t *binfo = (bd_t *) __res;
124 unsigned int freq;
125
126 /* get the core frequency */
127 freq = binfo->bi_intfreq;
128
129 pvid = mfspr(SPRN_PVR);
130 svid = mfspr(SPRN_SVR);
131
132 seq_printf(m, "Vendor\t\t: Wind River\n");
133 seq_printf(m, "Machine\t\t: SBC%s\n", cur_ppc_sys_spec->ppc_sys_name);
134 seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000);
135 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
136 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
137
138 /* Display cpu Pll setting */
139 phid1 = mfspr(SPRN_HID1);
140 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
141
142 /* Display the amount of memory */
143 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
144
145 return 0;
146}
147
148void __init
149sbc8560_init_IRQ(void)
150{
151 bd_t *binfo = (bd_t *) __res;
152 /* Determine the Physical Address of the OpenPIC regs */
153 phys_addr_t OpenPIC_PAddr =
154 binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
155 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
156 OpenPIC_InitSenses = sbc8560_openpic_initsenses;
157 OpenPIC_NumInitSenses = sizeof (sbc8560_openpic_initsenses);
158
159 /* Skip reserved space and internal sources */
160 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
161 /* Map PIC IRQs 0-11 */
162 openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
163
164 /* we let openpic interrupts starting from an offset, to
165 * leave space for cascading interrupts underneath.
166 */
167 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
168
169 return;
170}
171
172/*
173 * interrupt routing
174 */
175
176#ifdef CONFIG_PCI
177int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel,
178 unsigned char pin)
179{
180 static char pci_irq_table[][4] =
181 /*
182 * PCI IDSEL/INTPIN->INTLINE
183 * A B C D
184 */
185 {
186 {PIRQA, PIRQB, PIRQC, PIRQD},
187 {PIRQD, PIRQA, PIRQB, PIRQC},
188 {PIRQC, PIRQD, PIRQA, PIRQB},
189 {PIRQB, PIRQC, PIRQD, PIRQA},
190 };
191
192 const long min_idsel = 12, max_idsel = 15, irqs_per_slot = 4;
193 return PCI_IRQ_TABLE_LOOKUP;
194}
195
196int mpc85xx_exclude_device(u_char bus, u_char devfn)
197{
198 if (bus == 0 && PCI_SLOT(devfn) == 0)
199 return PCIBIOS_DEVICE_NOT_FOUND;
200 else
201 return PCIBIOS_SUCCESSFUL;
202}
203#endif /* CONFIG_PCI */
diff --git a/arch/ppc/platforms/85xx/sbc85xx.h b/arch/ppc/platforms/85xx/sbc85xx.h
new file mode 100644
index 000000000000..7af93c691a6b
--- /dev/null
+++ b/arch/ppc/platforms/85xx/sbc85xx.h
@@ -0,0 +1,55 @@
1/*
2 * arch/ppc/platforms/85xx/sbc85xx.h
3 *
4 * WindRiver PowerQUICC III SBC85xx common board definitions
5 *
6 * Copyright 2003 Motorola Inc.
7 * Copyright 2004 Red Hat, 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 */
15
16#ifndef __PLATFORMS_85XX_SBC85XX_H__
17#define __PLATFORMS_85XX_SBC85XX_H__
18
19#include <linux/config.h>
20#include <linux/init.h>
21#include <linux/seq_file.h>
22#include <asm/ppcboot.h>
23
24#define BOARD_CCSRBAR ((uint)0xff700000)
25#define CCSRBAR_SIZE ((uint)1024*1024)
26
27#define BCSR_ADDR ((uint)0xfc000000)
28#define BCSR_SIZE ((uint)(16 * 1024 * 1024))
29
30#define UARTA_ADDR (BCSR_ADDR + 0x00700000)
31#define UARTB_ADDR (BCSR_ADDR + 0x00800000)
32#define RTC_DEVICE_ADDR (BCSR_ADDR + 0x00900000)
33#define EEPROM_ADDR (BCSR_ADDR + 0x00b00000)
34
35extern int sbc8560_show_cpuinfo(struct seq_file *m);
36extern void sbc8560_init_IRQ(void) __init;
37
38/* PCI interrupt controller */
39#define PIRQA MPC85xx_IRQ_EXT1
40#define PIRQB MPC85xx_IRQ_EXT2
41#define PIRQC MPC85xx_IRQ_EXT3
42#define PIRQD MPC85xx_IRQ_EXT4
43
44#define MPC85XX_PCI1_LOWER_IO 0x00000000
45#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
46
47#define MPC85XX_PCI1_LOWER_MEM 0x80000000
48#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
49
50#define MPC85XX_PCI1_IO_BASE 0xe2000000
51#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
52
53#define MPC85XX_PCI1_IO_SIZE 0x01000000
54
55#endif /* __PLATFORMS_85XX_SBC85XX_H__ */
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
new file mode 100644
index 000000000000..bc95836e417c
--- /dev/null
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -0,0 +1,355 @@
1/*
2 * arch/ppc/platforms/85xx/stx_gp3.c
3 *
4 * STx GP3 board specific routines
5 *
6 * Dan Malek <dan@embeddededge.com>
7 * Copyright 2004 Embedded Edge, LLC
8 *
9 * Copied from mpc8560_ads.c
10 * Copyright 2002, 2003 Motorola Inc.
11 *
12 * Ported to 2.6, Matt Porter <mporter@kernel.crashing.org>
13 * Copyright 2004-2005 MontaVista Software, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20
21#include <linux/config.h>
22#include <linux/stddef.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/errno.h>
26#include <linux/reboot.h>
27#include <linux/pci.h>
28#include <linux/kdev_t.h>
29#include <linux/major.h>
30#include <linux/blkdev.h>
31#include <linux/console.h>
32#include <linux/delay.h>
33#include <linux/irq.h>
34#include <linux/root_dev.h>
35#include <linux/seq_file.h>
36#include <linux/serial.h>
37#include <linux/initrd.h>
38#include <linux/module.h>
39#include <linux/fsl_devices.h>
40#include <linux/interrupt.h>
41
42#include <asm/system.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <asm/atomic.h>
46#include <asm/time.h>
47#include <asm/io.h>
48#include <asm/machdep.h>
49#include <asm/prom.h>
50#include <asm/open_pic.h>
51#include <asm/bootinfo.h>
52#include <asm/pci-bridge.h>
53#include <asm/mpc85xx.h>
54#include <asm/irq.h>
55#include <asm/immap_85xx.h>
56#include <asm/immap_cpm2.h>
57#include <asm/mpc85xx.h>
58#include <asm/ppc_sys.h>
59
60#include <syslib/cpm2_pic.h>
61#include <syslib/ppc85xx_common.h>
62
63extern void cpm2_reset(void);
64
65unsigned char __res[sizeof(bd_t)];
66
67#ifndef CONFIG_PCI
68unsigned long isa_io_base = 0;
69unsigned long isa_mem_base = 0;
70unsigned long pci_dram_offset = 0;
71#endif
72
73/* Internal interrupts are all Level Sensitive, and Positive Polarity */
74static u8 gp3_openpic_initsenses[] __initdata = {
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: L2 Cache */
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: ECM */
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCI/PCI-X */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: RIO Inbound Port Write Error */
85 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: RIO Doorbell Inbound */
86 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: RIO Outbound Message */
87 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: RIO Inbound Message */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 0 Transmit */
89 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 0 Receive */
90 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: Unused */
91 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: Unused */
92 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: Unused */
93 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 0 Receive/Transmit Error */
94 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 1 Transmit */
95 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 1 Receive */
96 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: Unused */
97 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: Unused */
98 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: Unused */
99 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 1 Receive/Transmit Error */
100 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Fast Ethernet */
101 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART */
102 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */
103 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */
104 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */
105 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: CPM */
106 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */
107 0x0, /* External 0: */
108#if defined(CONFIG_PCI)
109 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 1: PCI slot 0 */
110 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI slot 1 */
111 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI slot 2 */
112 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 4: PCI slot 3 */
113#else
114 0x0, /* External 1: */
115 0x0, /* External 2: */
116 0x0, /* External 3: */
117 0x0, /* External 4: */
118#endif
119 0x0, /* External 5: */
120 0x0, /* External 6: */
121 0x0, /* External 7: */
122 0x0, /* External 8: */
123 0x0, /* External 9: */
124 0x0, /* External 10: */
125 0x0, /* External 11: */
126};
127
128/*
129 * Setup the architecture
130 */
131static void __init
132gp3_setup_arch(void)
133{
134 bd_t *binfo = (bd_t *) __res;
135 unsigned int freq;
136 struct gianfar_platform_data *pdata;
137
138 cpm2_reset();
139
140 /* get the core frequency */
141 freq = binfo->bi_intfreq;
142
143 if (ppc_md.progress)
144 ppc_md.progress("gp3_setup_arch()", 0);
145
146 /* Set loops_per_jiffy to a half-way reasonable value,
147 for use until calibrate_delay gets called. */
148 loops_per_jiffy = freq / HZ;
149
150#ifdef CONFIG_PCI
151 /* setup PCI host bridges */
152 mpc85xx_setup_hose();
153#endif
154
155 /* setup the board related information for the enet controllers */
156 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
157/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
158 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
159 pdata->phyid = 2;
160 pdata->phy_reg_addr += binfo->bi_immr_base;
161 memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
162
163 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
164/* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
165 pdata->interruptPHY = MPC85xx_IRQ_EXT5;
166 pdata->phyid = 4;
167 /* fixup phy address */
168 pdata->phy_reg_addr += binfo->bi_immr_base;
169 memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
170
171#ifdef CONFIG_BLK_DEV_INITRD
172 if (initrd_start)
173 ROOT_DEV = Root_RAM0;
174 else
175#endif
176#ifdef CONFIG_ROOT_NFS
177 ROOT_DEV = Root_NFS;
178#else
179 ROOT_DEV = Root_HDA1;
180#endif
181
182 printk ("bi_immr_base = %8.8lx\n", binfo->bi_immr_base);
183}
184
185static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
186{
187 while ((irq = cpm2_get_irq(regs)) >= 0)
188 __do_IRQ(irq, regs);
189
190 return IRQ_HANDLED;
191}
192
193static struct irqaction cpm2_irqaction = {
194 .handler = cpm2_cascade,
195 .flags = SA_INTERRUPT,
196 .mask = CPU_MASK_NONE,
197 .name = "cpm2_cascade",
198};
199
200static void __init
201gp3_init_IRQ(void)
202{
203 int i;
204 bd_t *binfo = (bd_t *) __res;
205
206 /*
207 * Setup OpenPIC
208 */
209
210 /* Determine the Physical Address of the OpenPIC regs */
211 phys_addr_t OpenPIC_PAddr =
212 binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
213 OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE);
214 OpenPIC_InitSenses = gp3_openpic_initsenses;
215 OpenPIC_NumInitSenses = sizeof (gp3_openpic_initsenses);
216
217 /* Skip reserved space and internal sources */
218 openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
219
220 /* Map PIC IRQs 0-11 */
221 openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
222
223 /*
224 * Let openpic interrupts starting from an offset, to
225 * leave space for cascading interrupts underneath.
226 */
227 openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
228
229 /* Setup CPM2 PIC */
230 cpm2_init_IRQ();
231
232 setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction);
233
234 return;
235}
236
237static int
238gp3_show_cpuinfo(struct seq_file *m)
239{
240 uint pvid, svid, phid1;
241 bd_t *binfo = (bd_t *) __res;
242 uint memsize;
243 unsigned int freq;
244 extern unsigned long total_memory; /* in mm/init */
245
246 /* get the core frequency */
247 freq = binfo->bi_intfreq;
248
249 pvid = mfspr(SPRN_PVR);
250 svid = mfspr(SPRN_SVR);
251
252 memsize = total_memory;
253
254 seq_printf(m, "Vendor\t\t: RPC Electronics STx \n");
255 seq_printf(m, "Machine\t\t: GP3 - MPC%s\n", cur_ppc_sys_spec->ppc_sys_name);
256 seq_printf(m, "bus freq\t: %u.%.6u MHz\n", freq / 1000000,
257 freq % 1000000);
258 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
259 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
260
261 /* Display cpu Pll setting */
262 phid1 = mfspr(SPRN_HID1);
263 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
264
265 /* Display the amount of memory */
266 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
267
268 return 0;
269}
270
271#ifdef CONFIG_PCI
272int mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel,
273 unsigned char pin)
274{
275 static char pci_irq_table[][4] =
276 /*
277 * PCI IDSEL/INTPIN->INTLINE
278 * A B C D
279 */
280 {
281 {PIRQA, PIRQB, PIRQC, PIRQD},
282 {PIRQD, PIRQA, PIRQB, PIRQC},
283 {PIRQC, PIRQD, PIRQA, PIRQB},
284 {PIRQB, PIRQC, PIRQD, PIRQA},
285 };
286
287 const long min_idsel = 12, max_idsel = 15, irqs_per_slot = 4;
288 return PCI_IRQ_TABLE_LOOKUP;
289}
290
291int mpc85xx_exclude_device(u_char bus, u_char devfn)
292{
293 if (bus == 0 && PCI_SLOT(devfn) == 0)
294 return PCIBIOS_DEVICE_NOT_FOUND;
295 else
296 return PCIBIOS_SUCCESSFUL;
297}
298#endif /* CONFIG_PCI */
299
300void __init
301platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
302 unsigned long r6, unsigned long r7)
303{
304 /* parse_bootinfo must always be called first */
305 parse_bootinfo(find_bootinfo());
306
307 /*
308 * If we were passed in a board information, copy it into the
309 * residual data area.
310 */
311 if (r3) {
312 memcpy((void *) __res, (void *) (r3 + KERNELBASE),
313 sizeof (bd_t));
314
315 }
316#if defined(CONFIG_BLK_DEV_INITRD)
317 /*
318 * If the init RAM disk has been configured in, and there's a valid
319 * starting address for it, set it up.
320 */
321 if (r4) {
322 initrd_start = r4 + KERNELBASE;
323 initrd_end = r5 + KERNELBASE;
324 }
325#endif /* CONFIG_BLK_DEV_INITRD */
326
327 /* Copy the kernel command line arguments to a safe place. */
328
329 if (r6) {
330 *(char *) (r7 + KERNELBASE) = 0;
331 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
332 }
333
334 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
335
336 /* setup the PowerPC module struct */
337 ppc_md.setup_arch = gp3_setup_arch;
338 ppc_md.show_cpuinfo = gp3_show_cpuinfo;
339
340 ppc_md.init_IRQ = gp3_init_IRQ;
341 ppc_md.get_irq = openpic_get_irq;
342
343 ppc_md.restart = mpc85xx_restart;
344 ppc_md.power_off = mpc85xx_power_off;
345 ppc_md.halt = mpc85xx_halt;
346
347 ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory;
348
349 ppc_md.calibrate_decr = mpc85xx_calibrate_decr;
350
351 if (ppc_md.progress)
352 ppc_md.progress("platform_init(): exit", 0);
353
354 return;
355}
diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
new file mode 100644
index 000000000000..7bcc6c35a417
--- /dev/null
+++ b/arch/ppc/platforms/85xx/stx_gp3.h
@@ -0,0 +1,74 @@
1/*
2 * arch/ppc/platforms/stx8560_gp3.h
3 *
4 * STx GP3 board definitions
5 *
6 * Dan Malek (dan@embeddededge.com)
7 * Copyright 2004 Embedded Edge, LLC
8 *
9 * Ported to 2.6, Matt Porter <mporter@kernel.crashing.org>
10 * Copyright 2004-2005 MontaVista Software, Inc.
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 */
18
19#ifndef __MACH_STX_GP3_H
20#define __MACH_STX_GP3_H
21
22#include <linux/config.h>
23#include <linux/init.h>
24#include <linux/seq_file.h>
25#include <asm/ppcboot.h>
26
27#define BOARD_CCSRBAR ((uint)0xe0000000)
28#define CCSRBAR_SIZE ((uint)1024*1024)
29
30#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
31
32#define BCSR_ADDR ((uint)0xfc000000)
33#define BCSR_SIZE ((uint)(16 * 1024))
34
35#define BCSR_TSEC1_RESET 0x00000080
36#define BCSR_TSEC2_RESET 0x00000040
37#define BCSR_LED1 0x00000008
38#define BCSR_LED2 0x00000004
39#define BCSR_LED3 0x00000002
40#define BCSR_LED4 0x00000001
41
42extern void mpc85xx_setup_hose(void) __init;
43extern void mpc85xx_restart(char *cmd);
44extern void mpc85xx_power_off(void);
45extern void mpc85xx_halt(void);
46extern int mpc85xx_show_cpuinfo(struct seq_file *m);
47extern void mpc85xx_init_IRQ(void) __init;
48extern unsigned long mpc85xx_find_end_of_memory(void) __init;
49extern void mpc85xx_calibrate_decr(void) __init;
50
51#define PCI_CFG_ADDR_OFFSET (0x8000)
52#define PCI_CFG_DATA_OFFSET (0x8004)
53
54/* PCI interrupt controller */
55#define PIRQA MPC85xx_IRQ_EXT1
56#define PIRQB MPC85xx_IRQ_EXT2
57#define PIRQC MPC85xx_IRQ_EXT3
58#define PIRQD MPC85xx_IRQ_EXT4
59#define PCI_MIN_IDSEL 16
60#define PCI_MAX_IDSEL 19
61#define PCI_IRQ_SLOT 4
62
63#define MPC85XX_PCI1_LOWER_IO 0x00000000
64#define MPC85XX_PCI1_UPPER_IO 0x00ffffff
65
66#define MPC85XX_PCI1_LOWER_MEM 0x80000000
67#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff
68
69#define MPC85XX_PCI1_IO_BASE 0xe2000000
70#define MPC85XX_PCI1_MEM_OFFSET 0x00000000
71
72#define MPC85XX_PCI1_IO_SIZE 0x01000000
73
74#endif /* __MACH_STX_GP3_H */
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
new file mode 100644
index 000000000000..5488a053f415
--- /dev/null
+++ b/arch/ppc/platforms/Makefile
@@ -0,0 +1,53 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Extra CFLAGS so we don't have to do relative includes
6CFLAGS_pmac_setup.o += -Iarch/$(ARCH)/mm
7
8obj-$(CONFIG_APUS) += apus_setup.o
9ifeq ($(CONFIG_APUS),y)
10obj-$(CONFIG_PCI) += apus_pci.o
11endif
12obj-$(CONFIG_PPC_PMAC) += pmac_pic.o pmac_setup.o pmac_time.o \
13 pmac_feature.o pmac_pci.o pmac_sleep.o \
14 pmac_low_i2c.o pmac_cache.o
15obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
16 chrp_pegasos_eth.o
17obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
18ifeq ($(CONFIG_PPC_PMAC),y)
19obj-$(CONFIG_NVRAM) += pmac_nvram.o
20obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o
21endif
22obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
23obj-$(CONFIG_PREP_RESIDUAL) += residual.o
24obj-$(CONFIG_ADIR) += adir_setup.o adir_pic.o adir_pci.o
25obj-$(CONFIG_PQ2ADS) += pq2ads.o
26obj-$(CONFIG_TQM8260) += tqm8260_setup.o
27obj-$(CONFIG_CPCI690) += cpci690.o
28obj-$(CONFIG_EV64260) += ev64260.o
29obj-$(CONFIG_CHESTNUT) += chestnut.o
30obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o
31obj-$(CONFIG_K2) += k2.o
32obj-$(CONFIG_LOPEC) += lopec.o
33obj-$(CONFIG_KATANA) += katana.o
34obj-$(CONFIG_HDPU) += hdpu.o
35obj-$(CONFIG_MCPN765) += mcpn765.o
36obj-$(CONFIG_MENF1) += menf1_setup.o menf1_pci.o
37obj-$(CONFIG_MVME5100) += mvme5100.o
38obj-$(CONFIG_PAL4) += pal4_setup.o pal4_pci.o
39obj-$(CONFIG_PCORE) += pcore.o
40obj-$(CONFIG_POWERPMC250) += powerpmc250.o
41obj-$(CONFIG_PPLUS) += pplus.o
42obj-$(CONFIG_PRPMC750) += prpmc750.o
43obj-$(CONFIG_PRPMC800) += prpmc800.o
44obj-$(CONFIG_RADSTONE_PPC7D) += radstone_ppc7d.o
45obj-$(CONFIG_SANDPOINT) += sandpoint.o
46obj-$(CONFIG_SBC82xx) += sbc82xx.o
47obj-$(CONFIG_SPRUCE) += spruce.o
48obj-$(CONFIG_LITE5200) += lite5200.o
49
50ifeq ($(CONFIG_SMP),y)
51obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
52obj-$(CONFIG_PPC_CHRP) += chrp_smp.o
53endif
diff --git a/arch/ppc/platforms/adir.h b/arch/ppc/platforms/adir.h
new file mode 100644
index 000000000000..13a748b46956
--- /dev/null
+++ b/arch/ppc/platforms/adir.h
@@ -0,0 +1,95 @@
1/*
2 * arch/ppc/platforms/adir.h
3 *
4 * Definitions for SBS Adirondack board support
5 *
6 * By Michael Sokolov <msokolov@ivan.Harhan.ORG>
7 */
8
9#ifndef __PPC_PLATFORMS_ADIR_H
10#define __PPC_PLATFORMS_ADIR_H
11
12/*
13 * SBS Adirondack definitions
14 */
15
16/* PPC physical address space layout. We use the one set up by the firmware. */
17#define ADIR_PCI32_MEM_BASE 0x80000000
18#define ADIR_PCI32_MEM_SIZE 0x20000000
19#define ADIR_PCI64_MEM_BASE 0xA0000000
20#define ADIR_PCI64_MEM_SIZE 0x20000000
21#define ADIR_PCI32_IO_BASE 0xC0000000
22#define ADIR_PCI32_IO_SIZE 0x10000000
23#define ADIR_PCI64_IO_BASE 0xD0000000
24#define ADIR_PCI64_IO_SIZE 0x10000000
25#define ADIR_PCI64_PHB 0xFF400000
26#define ADIR_PCI32_PHB 0xFF500000
27
28#define ADIR_PCI64_CONFIG_ADDR (ADIR_PCI64_PHB + 0x000f8000)
29#define ADIR_PCI64_CONFIG_DATA (ADIR_PCI64_PHB + 0x000f8010)
30
31#define ADIR_PCI32_CONFIG_ADDR (ADIR_PCI32_PHB + 0x000f8000)
32#define ADIR_PCI32_CONFIG_DATA (ADIR_PCI32_PHB + 0x000f8010)
33
34/* System memory as seen from PCI */
35#define ADIR_PCI_SYS_MEM_BASE 0x80000000
36
37/* Static virtual mapping of PCI I/O */
38#define ADIR_PCI32_VIRT_IO_BASE 0xFE000000
39#define ADIR_PCI32_VIRT_IO_SIZE 0x01000000
40#define ADIR_PCI64_VIRT_IO_BASE 0xFF000000
41#define ADIR_PCI64_VIRT_IO_SIZE 0x01000000
42
43/* Registers */
44#define ADIR_NVRAM_RTC_ADDR 0x74
45#define ADIR_NVRAM_RTC_DATA 0x75
46
47#define ADIR_BOARD_ID_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF0)
48#define ADIR_CPLD1REV_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF1)
49#define ADIR_CPLD2REV_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF2)
50#define ADIR_FLASHCTL_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF3)
51#define ADIR_CPC710_STAT_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF4)
52#define ADIR_CLOCK_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF5)
53#define ADIR_GPIO_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF8)
54#define ADIR_MISC_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF9)
55#define ADIR_LED_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFFA)
56
57#define ADIR_CLOCK_REG_PD 0x10
58#define ADIR_CLOCK_REG_SPREAD 0x08
59#define ADIR_CLOCK_REG_SEL133 0x04
60#define ADIR_CLOCK_REG_SEL1 0x02
61#define ADIR_CLOCK_REG_SEL0 0x01
62
63#define ADIR_PROCA_INT_MASK (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF0)
64#define ADIR_PROCB_INT_MASK (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF2)
65#define ADIR_PROCA_INT_STAT (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF4)
66#define ADIR_PROCB_INT_STAT (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF6)
67
68/* Linux IRQ numbers */
69#define ADIR_IRQ_NONE -1
70#define ADIR_IRQ_SERIAL2 3
71#define ADIR_IRQ_SERIAL1 4
72#define ADIR_IRQ_FDC 6
73#define ADIR_IRQ_PARALLEL 7
74#define ADIR_IRQ_VIA_AUDIO 10
75#define ADIR_IRQ_VIA_USB 11
76#define ADIR_IRQ_IDE0 14
77#define ADIR_IRQ_IDE1 15
78#define ADIR_IRQ_PCI0_INTA 16
79#define ADIR_IRQ_PCI0_INTB 17
80#define ADIR_IRQ_PCI0_INTC 18
81#define ADIR_IRQ_PCI0_INTD 19
82#define ADIR_IRQ_PCI1_INTA 20
83#define ADIR_IRQ_PCI1_INTB 21
84#define ADIR_IRQ_PCI1_INTC 22
85#define ADIR_IRQ_PCI1_INTD 23
86#define ADIR_IRQ_MBSCSI 24 /* motherboard SCSI */
87#define ADIR_IRQ_MBETH1 25 /* motherboard Ethernet 1 */
88#define ADIR_IRQ_MBETH0 26 /* motherboard Ethernet 0 */
89#define ADIR_IRQ_CPC710_INT1 27
90#define ADIR_IRQ_CPC710_INT2 28
91#define ADIR_IRQ_VT82C686_NMI 29
92#define ADIR_IRQ_VT82C686_INTR 30
93#define ADIR_IRQ_INTERPROC 31
94
95#endif /* __PPC_PLATFORMS_ADIR_H */
diff --git a/arch/ppc/platforms/adir_pci.c b/arch/ppc/platforms/adir_pci.c
new file mode 100644
index 000000000000..f94ac53e0711
--- /dev/null
+++ b/arch/ppc/platforms/adir_pci.c
@@ -0,0 +1,247 @@
1/*
2 * arch/ppc/platforms/adir_pci.c
3 *
4 * PCI support for SBS Adirondack
5 *
6 * By Michael Sokolov <msokolov@ivan.Harhan.ORG>
7 * based on the K2 version by Matt Porter <mporter@mvista.com>
8 */
9
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/pci.h>
13#include <linux/slab.h>
14
15#include <asm/byteorder.h>
16#include <asm/io.h>
17#include <asm/uaccess.h>
18#include <asm/machdep.h>
19#include <asm/pci-bridge.h>
20
21#include <syslib/cpc710.h>
22#include "adir.h"
23
24#undef DEBUG
25#ifdef DEBUG
26#define DBG(x...) printk(x)
27#else
28#define DBG(x...)
29#endif /* DEBUG */
30
31static inline int __init
32adir_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
33{
34#define PCIIRQ(a,b,c,d) {ADIR_IRQ_##a,ADIR_IRQ_##b,ADIR_IRQ_##c,ADIR_IRQ_##d},
35 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
36 /*
37 * The three PCI devices on the motherboard have dedicated lines to the
38 * CPLD interrupt controller, bypassing the standard PCI INTA-D and the
39 * PC interrupt controller. All other PCI devices (slots) have usual
40 * staggered INTA-D lines, resulting in 8 lines total (PCI0 INTA-D and
41 * PCI1 INTA-D). All 8 go to the CPLD interrupt controller. PCI0 INTA-D
42 * also go to the south bridge, so we have the option of taking them
43 * via the CPLD interrupt controller or via the south bridge 8259
44 * 8258 thingy. PCI1 INTA-D can only be taken via the CPLD interrupt
45 * controller. We take all PCI interrupts via the CPLD interrupt
46 * controller as recommended by SBS.
47 *
48 * We also have some monkey business with the PCI devices within the
49 * VT82C686B south bridge itself. This chip actually has 7 functions on
50 * its IDSEL. Function 0 is the actual south bridge, function 1 is IDE,
51 * and function 4 is some special stuff. The other 4 functions are just
52 * regular PCI devices bundled in the chip. 2 and 3 are USB UHCIs and 5
53 * and 6 are audio (not supported on the Adirondack).
54 *
55 * This is where the monkey business begins. PCI devices are supposed
56 * to signal normal PCI interrupts. But the 4 functions in question are
57 * located in the south bridge chip, which is designed with the
58 * assumption that it will be fielding PCI INTA-D interrupts rather
59 * than generating them. Here's what it does. Each of the functions in
60 * question routes its interrupt to one of the IRQs on the 8259 thingy.
61 * Which one? It looks at the Interrupt Line register in the PCI config
62 * space, even though the PCI spec says it's for BIOS/OS interaction
63 * only.
64 *
65 * How do we deal with this? We take these interrupts via 8259 IRQs as
66 * we have to. We return the desired IRQ numbers from this routine when
67 * called for the functions in question. The PCI scan code will then
68 * stick our return value into the Interrupt Line register in the PCI
69 * config space, and the interrupt will actually go there. We identify
70 * these functions within the south bridge IDSEL by their interrupt pin
71 * numbers, as the VT82C686B has 04 in the Interrupt Pin register for
72 * USB and 03 for audio.
73 */
74 if (!hose->index) {
75 static char pci_irq_table[][4] =
76 /*
77 * PCI IDSEL/INTPIN->INTLINE
78 * A B C D
79 */
80 {
81 /* south bridge */ PCIIRQ(IDE0, NONE, VIA_AUDIO, VIA_USB)
82 /* Ethernet 0 */ PCIIRQ(MBETH0, MBETH0, MBETH0, MBETH0)
83 /* PCI0 slot 1 */ PCIIRQ(PCI0_INTB, PCI0_INTC, PCI0_INTD, PCI0_INTA)
84 /* PCI0 slot 2 */ PCIIRQ(PCI0_INTC, PCI0_INTD, PCI0_INTA, PCI0_INTB)
85 /* PCI0 slot 3 */ PCIIRQ(PCI0_INTD, PCI0_INTA, PCI0_INTB, PCI0_INTC)
86 };
87 const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4;
88 return PCI_IRQ_TABLE_LOOKUP;
89 } else {
90 static char pci_irq_table[][4] =
91 /*
92 * PCI IDSEL/INTPIN->INTLINE
93 * A B C D
94 */
95 {
96 /* Ethernet 1 */ PCIIRQ(MBETH1, MBETH1, MBETH1, MBETH1)
97 /* SCSI */ PCIIRQ(MBSCSI, MBSCSI, MBSCSI, MBSCSI)
98 /* PCI1 slot 1 */ PCIIRQ(PCI1_INTB, PCI1_INTC, PCI1_INTD, PCI1_INTA)
99 /* PCI1 slot 2 */ PCIIRQ(PCI1_INTC, PCI1_INTD, PCI1_INTA, PCI1_INTB)
100 /* PCI1 slot 3 */ PCIIRQ(PCI1_INTD, PCI1_INTA, PCI1_INTB, PCI1_INTC)
101 };
102 const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4;
103 return PCI_IRQ_TABLE_LOOKUP;
104 }
105#undef PCIIRQ
106}
107
108static void
109adir_pcibios_fixup_resources(struct pci_dev *dev)
110{
111 int i;
112
113 if ((dev->vendor == PCI_VENDOR_ID_IBM) &&
114 (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64))
115 {
116 DBG("Fixup CPC710 resources\n");
117 for (i=0; i<DEVICE_COUNT_RESOURCE; i++)
118 {
119 dev->resource[i].start = 0;
120 dev->resource[i].end = 0;
121 }
122 }
123}
124
125/*
126 * CPC710 DD3 has an errata causing it to hang the system if a type 0 config
127 * cycle is attempted on its PCI32 interface with a device number > 21.
128 * CPC710's PCI bridges map device numbers 1 through 21 to AD11 through AD31.
129 * Per the PCI spec it MUST accept all other device numbers and do nothing, and
130 * software MUST scan all device numbers without assuming how IDSELs are
131 * mapped. However, as the CPC710 DD3's errata causes such correct scanning
132 * procedure to hang the system, we have no choice but to introduce this hack
133 * of knowingly avoiding device numbers > 21 on PCI0,
134 */
135static int
136adir_exclude_device(u_char bus, u_char devfn)
137{
138 if ((bus == 0) && (PCI_SLOT(devfn) > 21))
139 return PCIBIOS_DEVICE_NOT_FOUND;
140 else
141 return PCIBIOS_SUCCESSFUL;
142}
143
144void adir_find_bridges(void)
145{
146 struct pci_controller *hose_a, *hose_b;
147
148 /* Setup PCI32 hose */
149 hose_a = pcibios_alloc_controller();
150 if (!hose_a)
151 return;
152
153 hose_a->first_busno = 0;
154 hose_a->last_busno = 0xff;
155 hose_a->pci_mem_offset = ADIR_PCI32_MEM_BASE;
156 hose_a->io_space.start = 0;
157 hose_a->io_space.end = ADIR_PCI32_VIRT_IO_SIZE - 1;
158 hose_a->mem_space.start = 0;
159 hose_a->mem_space.end = ADIR_PCI32_MEM_SIZE - 1;
160 hose_a->io_resource.start = 0;
161 hose_a->io_resource.end = ADIR_PCI32_VIRT_IO_SIZE - 1;
162 hose_a->io_resource.flags = IORESOURCE_IO;
163 hose_a->mem_resources[0].start = ADIR_PCI32_MEM_BASE;
164 hose_a->mem_resources[0].end = ADIR_PCI32_MEM_BASE +
165 ADIR_PCI32_MEM_SIZE - 1;
166 hose_a->mem_resources[0].flags = IORESOURCE_MEM;
167 hose_a->io_base_phys = ADIR_PCI32_IO_BASE;
168 hose_a->io_base_virt = (void *) ADIR_PCI32_VIRT_IO_BASE;
169
170 ppc_md.pci_exclude_device = adir_exclude_device;
171 setup_indirect_pci(hose_a, ADIR_PCI32_CONFIG_ADDR,
172 ADIR_PCI32_CONFIG_DATA);
173
174 /* Initialize PCI32 bus registers */
175 early_write_config_byte(hose_a,
176 hose_a->first_busno,
177 PCI_DEVFN(0, 0),
178 CPC710_BUS_NUMBER,
179 hose_a->first_busno);
180 early_write_config_byte(hose_a,
181 hose_a->first_busno,
182 PCI_DEVFN(0, 0),
183 CPC710_SUB_BUS_NUMBER,
184 hose_a->last_busno);
185
186 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
187
188 /* Write out correct max subordinate bus number for hose A */
189 early_write_config_byte(hose_a,
190 hose_a->first_busno,
191 PCI_DEVFN(0, 0),
192 CPC710_SUB_BUS_NUMBER,
193 hose_a->last_busno);
194
195 /* Setup PCI64 hose */
196 hose_b = pcibios_alloc_controller();
197 if (!hose_b)
198 return;
199
200 hose_b->first_busno = hose_a->last_busno + 1;
201 hose_b->last_busno = 0xff;
202 hose_b->pci_mem_offset = ADIR_PCI64_MEM_BASE;
203 hose_b->io_space.start = 0;
204 hose_b->io_space.end = ADIR_PCI64_VIRT_IO_SIZE - 1;
205 hose_b->mem_space.start = 0;
206 hose_b->mem_space.end = ADIR_PCI64_MEM_SIZE - 1;
207 hose_b->io_resource.start = 0;
208 hose_b->io_resource.end = ADIR_PCI64_VIRT_IO_SIZE - 1;
209 hose_b->io_resource.flags = IORESOURCE_IO;
210 hose_b->mem_resources[0].start = ADIR_PCI64_MEM_BASE;
211 hose_b->mem_resources[0].end = ADIR_PCI64_MEM_BASE +
212 ADIR_PCI64_MEM_SIZE - 1;
213 hose_b->mem_resources[0].flags = IORESOURCE_MEM;
214 hose_b->io_base_phys = ADIR_PCI64_IO_BASE;
215 hose_b->io_base_virt = (void *) ADIR_PCI64_VIRT_IO_BASE;
216
217 setup_indirect_pci(hose_b, ADIR_PCI64_CONFIG_ADDR,
218 ADIR_PCI64_CONFIG_DATA);
219
220 /* Initialize PCI64 bus registers */
221 early_write_config_byte(hose_b,
222 0,
223 PCI_DEVFN(0, 0),
224 CPC710_SUB_BUS_NUMBER,
225 0xff);
226
227 early_write_config_byte(hose_b,
228 0,
229 PCI_DEVFN(0, 0),
230 CPC710_BUS_NUMBER,
231 hose_b->first_busno);
232
233 hose_b->last_busno = pciauto_bus_scan(hose_b,
234 hose_b->first_busno);
235
236 /* Write out correct max subordinate bus number for hose B */
237 early_write_config_byte(hose_b,
238 hose_b->first_busno,
239 PCI_DEVFN(0, 0),
240 CPC710_SUB_BUS_NUMBER,
241 hose_b->last_busno);
242
243 ppc_md.pcibios_fixup = NULL;
244 ppc_md.pcibios_fixup_resources = adir_pcibios_fixup_resources;
245 ppc_md.pci_swizzle = common_swizzle;
246 ppc_md.pci_map_irq = adir_map_irq;
247}
diff --git a/arch/ppc/platforms/adir_pic.c b/arch/ppc/platforms/adir_pic.c
new file mode 100644
index 000000000000..9947cba52af5
--- /dev/null
+++ b/arch/ppc/platforms/adir_pic.c
@@ -0,0 +1,130 @@
1/*
2 * arch/ppc/platforms/adir_pic.c
3 *
4 * Interrupt controller support for SBS Adirondack
5 *
6 * By Michael Sokolov <msokolov@ivan.Harhan.ORG>
7 * based on the K2 and SCM versions by Matt Porter <mporter@mvista.com>
8 */
9
10#include <linux/stddef.h>
11#include <linux/init.h>
12#include <linux/sched.h>
13#include <linux/pci.h>
14#include <linux/interrupt.h>
15
16#include <asm/io.h>
17#include <asm/i8259.h>
18#include "adir.h"
19
20static void adir_onboard_pic_enable(unsigned int irq);
21static void adir_onboard_pic_disable(unsigned int irq);
22
23__init static void
24adir_onboard_pic_init(void)
25{
26 volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK;
27
28 /* Disable all Adirondack onboard interrupts */
29 out_be16(maskreg, 0xFFFF);
30}
31
32static int
33adir_onboard_pic_get_irq(void)
34{
35 volatile u_short *statreg = (volatile u_short *) ADIR_PROCA_INT_STAT;
36 int irq;
37 u_short int_status, int_test;
38
39 int_status = in_be16(statreg);
40 for (irq = 0, int_test = 1; irq < 16; irq++, int_test <<= 1) {
41 if (int_status & int_test)
42 break;
43 }
44
45 if (irq == 16)
46 return -1;
47
48 return (irq+16);
49}
50
51static void
52adir_onboard_pic_enable(unsigned int irq)
53{
54 volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK;
55
56 /* Change irq to Adirondack onboard native value */
57 irq -= 16;
58
59 /* Enable requested irq number */
60 out_be16(maskreg, in_be16(maskreg) & ~(1 << irq));
61}
62
63static void
64adir_onboard_pic_disable(unsigned int irq)
65{
66 volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK;
67
68 /* Change irq to Adirondack onboard native value */
69 irq -= 16;
70
71 /* Disable requested irq number */
72 out_be16(maskreg, in_be16(maskreg) | (1 << irq));
73}
74
75static struct hw_interrupt_type adir_onboard_pic = {
76 " ADIR PIC ",
77 NULL,
78 NULL,
79 adir_onboard_pic_enable, /* unmask */
80 adir_onboard_pic_disable, /* mask */
81 adir_onboard_pic_disable, /* mask and ack */
82 NULL,
83 NULL
84};
85
86static struct irqaction noop_action = {
87 .handler = no_action,
88 .flags = SA_INTERRUPT,
89 .mask = CPU_MASK_NONE,
90 .name = "82c59 primary cascade",
91};
92
93/*
94 * Linux interrupt values are assigned as follows:
95 *
96 * 0-15 VT82C686 8259 interrupts
97 * 16-31 Adirondack CPLD interrupts
98 */
99__init void
100adir_init_IRQ(void)
101{
102 int i;
103
104 /* Initialize the cascaded 8259's on the VT82C686 */
105 for (i=0; i<16; i++)
106 irq_desc[i].handler = &i8259_pic;
107 i8259_init(NULL);
108
109 /* Initialize Adirondack CPLD PIC and enable 8259 interrupt cascade */
110 for (i=16; i<32; i++)
111 irq_desc[i].handler = &adir_onboard_pic;
112 adir_onboard_pic_init();
113
114 /* Enable 8259 interrupt cascade */
115 setup_irq(ADIR_IRQ_VT82C686_INTR, &noop_action);
116}
117
118int
119adir_get_irq(struct pt_regs *regs)
120{
121 int irq;
122
123 if ((irq = adir_onboard_pic_get_irq()) < 0)
124 return irq;
125
126 if (irq == ADIR_IRQ_VT82C686_INTR)
127 irq = i8259_irq(regs);
128
129 return irq;
130}
diff --git a/arch/ppc/platforms/adir_setup.c b/arch/ppc/platforms/adir_setup.c
new file mode 100644
index 000000000000..6a6754ee0617
--- /dev/null
+++ b/arch/ppc/platforms/adir_setup.c
@@ -0,0 +1,210 @@
1/*
2 * arch/ppc/platforms/adir_setup.c
3 *
4 * Board setup routines for SBS Adirondack
5 *
6 * By Michael Sokolov <msokolov@ivan.Harhan.ORG>
7 * based on the K2 version by Matt Porter <mporter@mvista.com>
8 */
9
10#include <linux/config.h>
11#include <linux/stddef.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/errno.h>
15#include <linux/reboot.h>
16#include <linux/pci.h>
17#include <linux/kdev_t.h>
18#include <linux/types.h>
19#include <linux/major.h>
20#include <linux/initrd.h>
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/ide.h>
24#include <linux/seq_file.h>
25#include <linux/root_dev.h>
26
27#include <asm/system.h>
28#include <asm/pgtable.h>
29#include <asm/page.h>
30#include <asm/dma.h>
31#include <asm/io.h>
32#include <asm/machdep.h>
33#include <asm/time.h>
34#include <asm/todc.h>
35#include <asm/bootinfo.h>
36
37#include "adir.h"
38
39extern void adir_init_IRQ(void);
40extern int adir_get_irq(struct pt_regs *);
41extern void adir_find_bridges(void);
42extern unsigned long loops_per_jiffy;
43
44static unsigned int cpu_750cx[16] = {
45 5, 15, 14, 0, 4, 13, 0, 9, 6, 11, 8, 10, 16, 12, 7, 0
46};
47
48static int
49adir_get_bus_speed(void)
50{
51 if (!(*((u_char *) ADIR_CLOCK_REG) & ADIR_CLOCK_REG_SEL133))
52 return 100000000;
53 else
54 return 133333333;
55}
56
57static int
58adir_get_cpu_speed(void)
59{
60 unsigned long hid1;
61 int cpu_speed;
62
63 hid1 = mfspr(SPRN_HID1) >> 28;
64
65 hid1 = cpu_750cx[hid1];
66
67 cpu_speed = adir_get_bus_speed()*hid1/2;
68 return cpu_speed;
69}
70
71static void __init
72adir_calibrate_decr(void)
73{
74 int freq, divisor = 4;
75
76 /* determine processor bus speed */
77 freq = adir_get_bus_speed();
78 tb_ticks_per_jiffy = freq / HZ / divisor;
79 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
80}
81
82static int
83adir_show_cpuinfo(struct seq_file *m)
84{
85 seq_printf(m, "vendor\t\t: SBS\n");
86 seq_printf(m, "machine\t\t: Adirondack\n");
87 seq_printf(m, "cpu speed\t: %dMhz\n", adir_get_cpu_speed()/1000000);
88 seq_printf(m, "bus speed\t: %dMhz\n", adir_get_bus_speed()/1000000);
89 seq_printf(m, "memory type\t: SDRAM\n");
90
91 return 0;
92}
93
94extern char cmd_line[];
95
96TODC_ALLOC();
97
98static void __init
99adir_setup_arch(void)
100{
101 unsigned int cpu;
102
103 /* Setup TODC access */
104 TODC_INIT(TODC_TYPE_MC146818, ADIR_NVRAM_RTC_ADDR, 0,
105 ADIR_NVRAM_RTC_DATA, 8);
106
107 /* init to some ~sane value until calibrate_delay() runs */
108 loops_per_jiffy = 50000000/HZ;
109
110 /* Setup PCI host bridges */
111 adir_find_bridges();
112
113#ifdef CONFIG_BLK_DEV_INITRD
114 if (initrd_start)
115 ROOT_DEV = Root_RAM0;
116 else
117#endif
118#ifdef CONFIG_ROOT_NFS
119 ROOT_DEV = Root_NFS;
120#else
121 ROOT_DEV = Root_SDA1;
122#endif
123
124 /* Identify the system */
125 printk("System Identification: SBS Adirondack - PowerPC 750CXe @ %d Mhz\n", adir_get_cpu_speed()/1000000);
126 printk("SBS Adirondack port (C) 2001 SBS Technologies, Inc.\n");
127
128 /* Identify the CPU manufacturer */
129 cpu = mfspr(SPRN_PVR);
130 printk("CPU manufacturer: IBM [rev=%04x]\n", (cpu & 0xffff));
131}
132
133static void
134adir_restart(char *cmd)
135{
136 local_irq_disable();
137 /* SRR0 has system reset vector, SRR1 has default MSR value */
138 /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
139 __asm__ __volatile__
140 ("lis 3,0xfff0\n\t"
141 "ori 3,3,0x0100\n\t"
142 "mtspr 26,3\n\t"
143 "li 3,0\n\t"
144 "mtspr 27,3\n\t"
145 "rfi\n\t");
146 for(;;);
147}
148
149static void
150adir_power_off(void)
151{
152 for(;;);
153}
154
155static void
156adir_halt(void)
157{
158 adir_restart(NULL);
159}
160
161static unsigned long __init
162adir_find_end_of_memory(void)
163{
164 return boot_mem_size;
165}
166
167static void __init
168adir_map_io(void)
169{
170 io_block_mapping(ADIR_PCI32_VIRT_IO_BASE, ADIR_PCI32_IO_BASE,
171 ADIR_PCI32_VIRT_IO_SIZE, _PAGE_IO);
172 io_block_mapping(ADIR_PCI64_VIRT_IO_BASE, ADIR_PCI64_IO_BASE,
173 ADIR_PCI64_VIRT_IO_SIZE, _PAGE_IO);
174}
175
176void __init
177platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
178 unsigned long r6, unsigned long r7)
179{
180 /*
181 * On the Adirondack we use bi_recs and pass the pointer to them in R3.
182 */
183 parse_bootinfo((struct bi_record *) (r3 + KERNELBASE));
184
185 /* Remember, isa_io_base is virtual but isa_mem_base is physical! */
186 isa_io_base = ADIR_PCI32_VIRT_IO_BASE;
187 isa_mem_base = ADIR_PCI32_MEM_BASE;
188 pci_dram_offset = ADIR_PCI_SYS_MEM_BASE;
189
190 ppc_md.setup_arch = adir_setup_arch;
191 ppc_md.show_cpuinfo = adir_show_cpuinfo;
192 ppc_md.irq_canonicalize = NULL;
193 ppc_md.init_IRQ = adir_init_IRQ;
194 ppc_md.get_irq = adir_get_irq;
195 ppc_md.init = NULL;
196
197 ppc_md.find_end_of_memory = adir_find_end_of_memory;
198 ppc_md.setup_io_mappings = adir_map_io;
199
200 ppc_md.restart = adir_restart;
201 ppc_md.power_off = adir_power_off;
202 ppc_md.halt = adir_halt;
203
204 ppc_md.time_init = todc_time_init;
205 ppc_md.set_rtc_time = todc_set_rtc_time;
206 ppc_md.get_rtc_time = todc_get_rtc_time;
207 ppc_md.nvram_read_val = todc_mc146818_read_val;
208 ppc_md.nvram_write_val = todc_mc146818_write_val;
209 ppc_md.calibrate_decr = adir_calibrate_decr;
210}
diff --git a/arch/ppc/platforms/apus_pci.c b/arch/ppc/platforms/apus_pci.c
new file mode 100644
index 000000000000..33dad6db8243
--- /dev/null
+++ b/arch/ppc/platforms/apus_pci.c
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) Michel Dänzer <michdaen@iiic.ethz.ch>
3 *
4 * APUS PCI routines.
5 *
6 * Currently, only B/CVisionPPC cards (Permedia2) are supported.
7 *
8 * Thanks to Geert Uytterhoeven for the idea:
9 * Read values from given config space(s) for the first devices, -1 otherwise
10 *
11 */
12
13#include <linux/config.h>
14#ifdef CONFIG_AMIGA
15
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/delay.h>
19#include <linux/string.h>
20#include <linux/init.h>
21
22#include <asm/io.h>
23#include <asm/pci-bridge.h>
24#include <asm/machdep.h>
25
26#include "apus_pci.h"
27
28
29/* These definitions are mostly adapted from pm2fb.c */
30
31#undef APUS_PCI_MASTER_DEBUG
32#ifdef APUS_PCI_MASTER_DEBUG
33#define DPRINTK(a,b...) printk(KERN_DEBUG "apus_pci: %s: " a, __FUNCTION__ , ## b)
34#else
35#define DPRINTK(a,b...)
36#endif
37
38/*
39 * The _DEFINITIVE_ memory mapping/unmapping functions.
40 * This is due to the fact that they're changing soooo often...
41 */
42#define DEFW() wmb()
43#define DEFR() rmb()
44#define DEFRW() mb()
45
46#define DEVNO(d) ((d)>>3)
47#define FNNO(d) ((d)&7)
48
49
50extern unsigned long powerup_PCI_present;
51
52static struct pci_controller *apus_hose;
53
54
55void *pci_io_base(unsigned int bus)
56{
57 return 0;
58}
59
60
61int
62apus_pcibios_read_config(struct pci_bus *bus, int devfn, int offset,
63 int len, u32 *val)
64{
65 int fnno = FNNO(devfn);
66 int devno = DEVNO(devfn);
67 volatile unsigned char *cfg_data;
68
69 if (bus->number > 0 || devno != 1) {
70 *val = ~0;
71 return PCIBIOS_DEVICE_NOT_FOUND;
72 }
73 /* base address + function offset + offset ^ endianness conversion */
74 /* XXX the fnno<<5 bit seems wacky -- paulus */
75 cfg_data = apus_hose->cfg_data + (fnno<<5) + (offset ^ (len - 1));
76 switch (len) {
77 case 1:
78 *val = readb(cfg_data);
79 break;
80 case 2:
81 *val = readw(cfg_data);
82 break;
83 default:
84 *val = readl(cfg_data);
85 break;
86 }
87
88 DPRINTK("read b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, l: %d, v: 0x%x\n",
89 bus->number, devfn>>3, devfn&7, offset, len, *val);
90 return PCIBIOS_SUCCESSFUL;
91}
92
93int
94apus_pcibios_write_config(struct pci_bus *bus, int devfn, int offset,
95 int len, u32 *val)
96{
97 int fnno = FNNO(devfn);
98 int devno = DEVNO(devfn);
99 volatile unsigned char *cfg_data;
100
101 if (bus->number > 0 || devno != 1) {
102 return PCIBIOS_DEVICE_NOT_FOUND;
103 }
104 /* base address + function offset + offset ^ endianness conversion */
105 /* XXX the fnno<<5 bit seems wacky -- paulus */
106 cfg_data = apus_hose->cfg_data + (fnno<<5) + (offset ^ (len - 1));
107 switch (len) {
108 case 1:
109 writeb(val, cfg_data); DEFW();
110 break;
111 case 2:
112 writew(val, cfg_data); DEFW();
113 break;
114 default:
115 writel(val, cfg_data); DEFW();
116 break;
117 }
118
119 DPRINTK("write b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, l: %d, v: 0x%x\n",
120 bus->number, devfn>>3, devfn&7, offset, len, val);
121 return PCIBIOS_SUCCESSFUL;
122}
123
124static struct pci_ops apus_pci_ops = {
125 apus_pcibios_read_config,
126 apus_pcibios_write_config
127};
128
129static struct resource pci_mem = { "B/CVisionPPC PCI mem", CVPPC_FB_APERTURE_ONE, CVPPC_PCI_CONFIG, IORESOURCE_MEM };
130
131void __init
132apus_pcibios_fixup(void)
133{
134/* struct pci_dev *dev = pci_find_slot(0, 1<<3);
135 unsigned int reg, val, offset;*/
136
137 /* FIXME: interrupt? */
138 /*dev->interrupt = xxx;*/
139
140 request_resource(&iomem_resource, &pci_mem);
141 printk("%s: PCI mem resource requested\n", __FUNCTION__);
142}
143
144static void __init apus_pcibios_fixup_bus(struct pci_bus *bus)
145{
146 bus->resource[1] = &pci_mem;
147}
148
149
150/*
151 * This is from pm2fb.c again
152 *
153 * Check if PCI (B/CVisionPPC) is available, initialize it and set up
154 * the pcibios_* pointers
155 */
156
157
158void __init
159apus_setup_pci_ptrs(void)
160{
161 if (!powerup_PCI_present) {
162 DPRINTK("no PCI bridge detected\n");
163 return;
164 }
165 DPRINTK("Phase5 B/CVisionPPC PCI bridge detected.\n");
166
167 apus_hose = pcibios_alloc_controller();
168 if (!apus_hose) {
169 printk("apus_pci: Can't allocate PCI controller structure\n");
170 return;
171 }
172
173 if (!(apus_hose->cfg_data = ioremap(CVPPC_PCI_CONFIG, 256))) {
174 printk("apus_pci: unable to map PCI config region\n");
175 return;
176 }
177
178 if (!(apus_hose->cfg_addr = ioremap(CSPPC_PCI_BRIDGE, 256))) {
179 printk("apus_pci: unable to map PCI bridge\n");
180 return;
181 }
182
183 writel(CSPPCF_BRIDGE_BIG_ENDIAN, apus_hose->cfg_addr + CSPPC_BRIDGE_ENDIAN);
184 DEFW();
185
186 writel(CVPPC_REGS_REGION, apus_hose->cfg_data+ PCI_BASE_ADDRESS_0);
187 DEFW();
188 writel(CVPPC_FB_APERTURE_ONE, apus_hose->cfg_data + PCI_BASE_ADDRESS_1);
189 DEFW();
190 writel(CVPPC_FB_APERTURE_TWO, apus_hose->cfg_data + PCI_BASE_ADDRESS_2);
191 DEFW();
192 writel(CVPPC_ROM_ADDRESS, apus_hose->cfg_data + PCI_ROM_ADDRESS);
193 DEFW();
194
195 writel(0xef000000 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
196 PCI_COMMAND_MASTER, apus_hose->cfg_data + PCI_COMMAND);
197 DEFW();
198
199 apus_hose->first_busno = 0;
200 apus_hose->last_busno = 0;
201 apus_hose->ops = &apus_pci_ops;
202 ppc_md.pcibios_fixup = apus_pcibios_fixup;
203 ppc_md.pcibios_fixup_bus = apus_pcibios_fixup_bus;
204
205 return;
206}
207
208#endif /* CONFIG_AMIGA */
diff --git a/arch/ppc/platforms/apus_pci.h b/arch/ppc/platforms/apus_pci.h
new file mode 100644
index 000000000000..f15974ae0189
--- /dev/null
+++ b/arch/ppc/platforms/apus_pci.h
@@ -0,0 +1,34 @@
1/*
2 * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer
3 * driver.
4 *
5 * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
6 * --------------------------------------------------------------------------
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file README.legal in the main directory of this archive
9 * for more details.
10 */
11
12#ifndef APUS_PCI_H
13#define APUS_PCI_H
14
15
16#define CSPPC_PCI_BRIDGE 0xfffe0000
17#define CSPPC_BRIDGE_ENDIAN 0x0000
18#define CSPPC_BRIDGE_INT 0x0010
19
20#define CVPPC_PCI_CONFIG 0xfffc0000
21#define CVPPC_ROM_ADDRESS 0xe2000001
22#define CVPPC_REGS_REGION 0xef000000
23#define CVPPC_FB_APERTURE_ONE 0xe0000000
24#define CVPPC_FB_APERTURE_TWO 0xe1000000
25#define CVPPC_FB_SIZE 0x00800000
26
27/* CVPPC_BRIDGE_ENDIAN */
28#define CSPPCF_BRIDGE_BIG_ENDIAN 0x02
29
30/* CVPPC_BRIDGE_INT */
31#define CSPPCF_BRIDGE_ACTIVE_INT2 0x01
32
33
34#endif /* APUS_PCI_H */
diff --git a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c
new file mode 100644
index 000000000000..2f74fde98ebc
--- /dev/null
+++ b/arch/ppc/platforms/apus_setup.c
@@ -0,0 +1,815 @@
1/*
2 * arch/ppc/platforms/apus_setup.c
3 *
4 * Copyright (C) 1998, 1999 Jesper Skov
5 *
6 * Basically what is needed to replace functionality found in
7 * arch/m68k allowing Amiga drivers to work under APUS.
8 * Bits of code and/or ideas from arch/m68k and arch/ppc files.
9 *
10 * TODO:
11 * This file needs a *really* good cleanup. Restructure and optimize.
12 * Make sure it can be compiled for non-APUS configs. Begin to move
13 * Amiga specific stuff into mach/amiga.
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/init.h>
20#include <linux/initrd.h>
21#include <linux/seq_file.h>
22
23/* Needs INITSERIAL call in head.S! */
24#undef APUS_DEBUG
25
26#include <asm/bootinfo.h>
27#include <asm/setup.h>
28#include <asm/amigahw.h>
29#include <asm/amigaints.h>
30#include <asm/amigappc.h>
31#include <asm/pgtable.h>
32#include <asm/dma.h>
33#include <asm/machdep.h>
34#include <asm/time.h>
35
36unsigned long m68k_machtype;
37char debug_device[6] = "";
38
39extern void amiga_init_IRQ(void);
40
41extern void apus_setup_pci_ptrs(void);
42
43void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
44/* machine dependent irq functions */
45void (*mach_init_IRQ) (void) __initdata = NULL;
46void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
47void (*mach_get_model) (char *model) = NULL;
48int (*mach_get_hardware_list) (char *buffer) = NULL;
49int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
50void (*mach_process_int) (int, struct pt_regs *) = NULL;
51/* machine dependent timer functions */
52unsigned long (*mach_gettimeoffset) (void);
53void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
54int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
55int (*mach_set_clock_mmss) (unsigned long) = NULL;
56void (*mach_reset)( void );
57long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
58#if defined(CONFIG_AMIGA_FLOPPY)
59void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
60#endif
61#ifdef CONFIG_HEARTBEAT
62void (*mach_heartbeat) (int) = NULL;
63extern void apus_heartbeat (void);
64#endif
65
66extern unsigned long amiga_model;
67extern unsigned decrementer_count;/* count value for 1e6/HZ microseconds */
68extern unsigned count_period_num; /* 1 decrementer count equals */
69extern unsigned count_period_den; /* count_period_num / count_period_den us */
70
71int num_memory = 0;
72struct mem_info memory[NUM_MEMINFO];/* memory description */
73/* FIXME: Duplicate memory data to avoid conflicts with m68k shared code. */
74int m68k_realnum_memory = 0;
75struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
76
77struct mem_info ramdisk;
78
79extern void amiga_floppy_setup(char *, int *);
80extern void config_amiga(void);
81
82static int __60nsram = 0;
83
84/* for cpuinfo */
85static int __bus_speed = 0;
86static int __speed_test_failed = 0;
87
88/********************************************** COMPILE PROTECTION */
89/* Provide some stubs that links to Amiga specific functions.
90 * This allows CONFIG_APUS to be removed from generic PPC files while
91 * preventing link errors for other PPC targets.
92 */
93unsigned long apus_get_rtc_time(void)
94{
95#ifdef CONFIG_APUS
96 extern unsigned long m68k_get_rtc_time(void);
97
98 return m68k_get_rtc_time ();
99#else
100 return 0;
101#endif
102}
103
104int apus_set_rtc_time(unsigned long nowtime)
105{
106#ifdef CONFIG_APUS
107 extern int m68k_set_rtc_time(unsigned long nowtime);
108
109 return m68k_set_rtc_time (nowtime);
110#else
111 return 0;
112#endif
113}
114
115/*********************************************************** SETUP */
116/* From arch/m68k/kernel/setup.c. */
117void __init apus_setup_arch(void)
118{
119#ifdef CONFIG_APUS
120 extern char cmd_line[];
121 int i;
122 char *p, *q;
123
124 /* Let m68k-shared code know it should do the Amiga thing. */
125 m68k_machtype = MACH_AMIGA;
126
127 /* Parse the command line for arch-specific options.
128 * For the m68k, this is currently only "debug=xxx" to enable printing
129 * certain kernel messages to some machine-specific device. */
130 for( p = cmd_line; p && *p; ) {
131 i = 0;
132 if (!strncmp( p, "debug=", 6 )) {
133 strlcpy( debug_device, p+6, sizeof(debug_device) );
134 if ((q = strchr( debug_device, ' ' ))) *q = 0;
135 i = 1;
136 } else if (!strncmp( p, "60nsram", 7 )) {
137 APUS_WRITE (APUS_REG_WAITSTATE,
138 REGWAITSTATE_SETRESET
139 |REGWAITSTATE_PPCR
140 |REGWAITSTATE_PPCW);
141 __60nsram = 1;
142 i = 1;
143 }
144
145 if (i) {
146 /* option processed, delete it */
147 if ((q = strchr( p, ' ' )))
148 strcpy( p, q+1 );
149 else
150 *p = 0;
151 } else {
152 if ((p = strchr( p, ' ' ))) ++p;
153 }
154 }
155
156 config_amiga();
157
158#if 0 /* Enable for logging - also include logging.o in Makefile rule */
159 {
160#define LOG_SIZE 4096
161 void* base;
162
163 /* Throw away some memory - the P5 firmare stomps on top
164 * of CHIP memory during bootup.
165 */
166 amiga_chip_alloc(0x1000);
167
168 base = amiga_chip_alloc(LOG_SIZE+sizeof(klog_data_t));
169 LOG_INIT(base, base+sizeof(klog_data_t), LOG_SIZE);
170 }
171#endif
172#endif
173}
174
175int
176apus_show_cpuinfo(struct seq_file *m)
177{
178 extern int __map_without_bats;
179 extern unsigned long powerup_PCI_present;
180
181 seq_printf(m, "machine\t\t: Amiga\n");
182 seq_printf(m, "bus speed\t: %d%s", __bus_speed,
183 (__speed_test_failed) ? " [failed]\n" : "\n");
184 seq_printf(m, "using BATs\t: %s\n",
185 (__map_without_bats) ? "No" : "Yes");
186 seq_printf(m, "ram speed\t: %dns\n", (__60nsram) ? 60 : 70);
187 seq_printf(m, "PCI bridge\t: %s\n",
188 (powerup_PCI_present) ? "Yes" : "No");
189 return 0;
190}
191
192static void get_current_tb(unsigned long long *time)
193{
194 __asm __volatile ("1:mftbu 4 \n\t"
195 " mftb 5 \n\t"
196 " mftbu 6 \n\t"
197 " cmpw 4,6 \n\t"
198 " bne 1b \n\t"
199 " stw 4,0(%0)\n\t"
200 " stw 5,4(%0)\n\t"
201 :
202 : "r" (time)
203 : "r4", "r5", "r6");
204}
205
206
207void apus_calibrate_decr(void)
208{
209#ifdef CONFIG_APUS
210 unsigned long freq;
211
212 /* This algorithm for determining the bus speed was
213 contributed by Ralph Schmidt. */
214 unsigned long long start, stop;
215 int bus_speed;
216 int speed_test_failed = 0;
217
218 {
219 unsigned long loop = amiga_eclock / 10;
220
221 get_current_tb (&start);
222 while (loop--) {
223 unsigned char tmp;
224
225 tmp = ciaa.pra;
226 }
227 get_current_tb (&stop);
228 }
229
230 bus_speed = (((unsigned long)(stop-start))*10*4) / 1000000;
231 if (AMI_1200 == amiga_model)
232 bus_speed /= 2;
233
234 if ((bus_speed >= 47) && (bus_speed < 53)) {
235 bus_speed = 50;
236 freq = 12500000;
237 } else if ((bus_speed >= 57) && (bus_speed < 63)) {
238 bus_speed = 60;
239 freq = 15000000;
240 } else if ((bus_speed >= 63) && (bus_speed < 69)) {
241 bus_speed = 67;
242 freq = 16666667;
243 } else {
244 printk ("APUS: Unable to determine bus speed (%d). "
245 "Defaulting to 50MHz", bus_speed);
246 bus_speed = 50;
247 freq = 12500000;
248 speed_test_failed = 1;
249 }
250
251 /* Ease diagnostics... */
252 {
253 extern int __map_without_bats;
254 extern unsigned long powerup_PCI_present;
255
256 printk ("APUS: BATs=%d, BUS=%dMHz",
257 (__map_without_bats) ? 0 : 1,
258 bus_speed);
259 if (speed_test_failed)
260 printk ("[FAILED - please report]");
261
262 printk (", RAM=%dns, PCI bridge=%d\n",
263 (__60nsram) ? 60 : 70,
264 (powerup_PCI_present) ? 1 : 0);
265
266 /* print a bit more if asked politely... */
267 if (!(ciaa.pra & 0x40)){
268 extern unsigned int bat_addrs[4][3];
269 int b;
270 for (b = 0; b < 4; ++b) {
271 printk ("APUS: BAT%d ", b);
272 printk ("%08x-%08x -> %08x\n",
273 bat_addrs[b][0],
274 bat_addrs[b][1],
275 bat_addrs[b][2]);
276 }
277 }
278
279 }
280
281 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
282 freq/1000000, freq%1000000);
283 tb_ticks_per_jiffy = freq / HZ;
284 tb_to_us = mulhwu_scale_factor(freq, 1000000);
285
286 __bus_speed = bus_speed;
287 __speed_test_failed = speed_test_failed;
288#endif
289}
290
291void arch_gettod(int *year, int *mon, int *day, int *hour,
292 int *min, int *sec)
293{
294#ifdef CONFIG_APUS
295 if (mach_gettod)
296 mach_gettod(year, mon, day, hour, min, sec);
297 else
298 *year = *mon = *day = *hour = *min = *sec = 0;
299#endif
300}
301
302/* for "kbd-reset" cmdline param */
303__init
304void kbd_reset_setup(char *str, int *ints)
305{
306}
307
308/*********************************************************** FLOPPY */
309#if defined(CONFIG_AMIGA_FLOPPY)
310__init
311void floppy_setup(char *str, int *ints)
312{
313 if (mach_floppy_setup)
314 mach_floppy_setup (str, ints);
315}
316#endif
317
318/*********************************************************** MEMORY */
319#define KMAP_MAX 32
320unsigned long kmap_chunks[KMAP_MAX*3];
321int kmap_chunk_count = 0;
322
323/* From pgtable.h */
324static __inline__ pte_t *my_find_pte(struct mm_struct *mm,unsigned long va)
325{
326 pgd_t *dir = 0;
327 pmd_t *pmd = 0;
328 pte_t *pte = 0;
329
330 va &= PAGE_MASK;
331
332 dir = pgd_offset( mm, va );
333 if (dir)
334 {
335 pmd = pmd_offset(dir, va & PAGE_MASK);
336 if (pmd && pmd_present(*pmd))
337 {
338 pte = pte_offset(pmd, va);
339 }
340 }
341 return pte;
342}
343
344
345/* Again simulating an m68k/mm/kmap.c function. */
346void kernel_set_cachemode( unsigned long address, unsigned long size,
347 unsigned int cmode )
348{
349 unsigned long mask, flags;
350
351 switch (cmode)
352 {
353 case IOMAP_FULL_CACHING:
354 mask = ~(_PAGE_NO_CACHE | _PAGE_GUARDED);
355 flags = 0;
356 break;
357 case IOMAP_NOCACHE_SER:
358 mask = ~0;
359 flags = (_PAGE_NO_CACHE | _PAGE_GUARDED);
360 break;
361 default:
362 panic ("kernel_set_cachemode() doesn't support mode %d\n",
363 cmode);
364 break;
365 }
366
367 size /= PAGE_SIZE;
368 address &= PAGE_MASK;
369 while (size--)
370 {
371 pte_t *pte;
372
373 pte = my_find_pte(&init_mm, address);
374 if ( !pte )
375 {
376 printk("pte NULL in kernel_set_cachemode()\n");
377 return;
378 }
379
380 pte_val (*pte) &= mask;
381 pte_val (*pte) |= flags;
382 flush_tlb_page(find_vma(&init_mm,address),address);
383
384 address += PAGE_SIZE;
385 }
386}
387
388unsigned long mm_ptov (unsigned long paddr)
389{
390 unsigned long ret;
391 if (paddr < 16*1024*1024)
392 ret = ZTWO_VADDR(paddr);
393 else {
394 int i;
395
396 for (i = 0; i < kmap_chunk_count;){
397 unsigned long phys = kmap_chunks[i++];
398 unsigned long size = kmap_chunks[i++];
399 unsigned long virt = kmap_chunks[i++];
400 if (paddr >= phys
401 && paddr < (phys + size)){
402 ret = virt + paddr - phys;
403 goto exit;
404 }
405 }
406
407 ret = (unsigned long) __va(paddr);
408 }
409exit:
410#ifdef DEBUGPV
411 printk ("PTOV(%lx)=%lx\n", paddr, ret);
412#endif
413 return ret;
414}
415
416int mm_end_of_chunk (unsigned long addr, int len)
417{
418 if (memory[0].addr + memory[0].size == addr + len)
419 return 1;
420 return 0;
421}
422
423/*********************************************************** CACHE */
424
425#define L1_CACHE_BYTES 32
426#define MAX_CACHE_SIZE 8192
427void cache_push(__u32 addr, int length)
428{
429 addr = mm_ptov(addr);
430
431 if (MAX_CACHE_SIZE < length)
432 length = MAX_CACHE_SIZE;
433
434 while(length > 0){
435 __asm ("dcbf 0,%0\n\t"
436 : : "r" (addr));
437 addr += L1_CACHE_BYTES;
438 length -= L1_CACHE_BYTES;
439 }
440 /* Also flush trailing block */
441 __asm ("dcbf 0,%0\n\t"
442 "sync \n\t"
443 : : "r" (addr));
444}
445
446void cache_clear(__u32 addr, int length)
447{
448 if (MAX_CACHE_SIZE < length)
449 length = MAX_CACHE_SIZE;
450
451 addr = mm_ptov(addr);
452
453 __asm ("dcbf 0,%0\n\t"
454 "sync \n\t"
455 "icbi 0,%0 \n\t"
456 "isync \n\t"
457 : : "r" (addr));
458
459 addr += L1_CACHE_BYTES;
460 length -= L1_CACHE_BYTES;
461
462 while(length > 0){
463 __asm ("dcbf 0,%0\n\t"
464 "sync \n\t"
465 "icbi 0,%0 \n\t"
466 "isync \n\t"
467 : : "r" (addr));
468 addr += L1_CACHE_BYTES;
469 length -= L1_CACHE_BYTES;
470 }
471
472 __asm ("dcbf 0,%0\n\t"
473 "sync \n\t"
474 "icbi 0,%0 \n\t"
475 "isync \n\t"
476 : : "r" (addr));
477}
478
479/****************************************************** from setup.c */
480void
481apus_restart(char *cmd)
482{
483 local_irq_disable();
484
485 APUS_WRITE(APUS_REG_LOCK,
486 REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2);
487 APUS_WRITE(APUS_REG_LOCK,
488 REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK3);
489 APUS_WRITE(APUS_REG_LOCK,
490 REGLOCK_BLACKMAGICK2|REGLOCK_BLACKMAGICK3);
491 APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET);
492 APUS_WRITE(APUS_REG_RESET, REGRESET_AMIGARESET);
493 for(;;);
494}
495
496void
497apus_power_off(void)
498{
499 for (;;);
500}
501
502void
503apus_halt(void)
504{
505 apus_restart(NULL);
506}
507
508/****************************************************** IRQ stuff */
509
510static unsigned char last_ipl[8];
511
512int apus_get_irq(struct pt_regs* regs)
513{
514 unsigned char ipl_emu, mask;
515 unsigned int level;
516
517 APUS_READ(APUS_IPL_EMU, ipl_emu);
518 level = (ipl_emu >> 3) & IPLEMU_IPLMASK;
519 mask = IPLEMU_SETRESET|IPLEMU_DISABLEINT|level;
520 level ^= 7;
521
522 /* Save previous IPL value */
523 if (last_ipl[level])
524 return -2;
525 last_ipl[level] = ipl_emu;
526
527 /* Set to current IPL value */
528 APUS_WRITE(APUS_IPL_EMU, mask);
529 APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|level);
530
531
532#ifdef __INTERRUPT_DEBUG
533 printk("<%d:%d>", level, ~ipl_emu & IPLEMU_IPLMASK);
534#endif
535 return level + IRQ_AMIGA_AUTO;
536}
537
538void apus_end_irq(unsigned int irq)
539{
540 unsigned char ipl_emu;
541 unsigned int level = irq - IRQ_AMIGA_AUTO;
542#ifdef __INTERRUPT_DEBUG
543 printk("{%d}", ~last_ipl[level] & IPLEMU_IPLMASK);
544#endif
545 /* Restore IPL to the previous value */
546 ipl_emu = last_ipl[level] & IPLEMU_IPLMASK;
547 APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET|IPLEMU_DISABLEINT|ipl_emu);
548 last_ipl[level] = 0;
549 ipl_emu ^= 7;
550 APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|ipl_emu);
551}
552
553/****************************************************** debugging */
554
555/* some serial hardware definitions */
556#define SDR_OVRUN (1<<15)
557#define SDR_RBF (1<<14)
558#define SDR_TBE (1<<13)
559#define SDR_TSRE (1<<12)
560
561#define AC_SETCLR (1<<15)
562#define AC_UARTBRK (1<<11)
563
564#define SER_DTR (1<<7)
565#define SER_RTS (1<<6)
566#define SER_DCD (1<<5)
567#define SER_CTS (1<<4)
568#define SER_DSR (1<<3)
569
570static __inline__ void ser_RTSon(void)
571{
572 ciab.pra &= ~SER_RTS; /* active low */
573}
574
575int __debug_ser_out( unsigned char c )
576{
577 custom.serdat = c | 0x100;
578 mb();
579 while (!(custom.serdatr & 0x2000))
580 barrier();
581 return 1;
582}
583
584unsigned char __debug_ser_in( void )
585{
586 unsigned char c;
587
588 /* XXX: is that ok?? derived from amiga_ser.c... */
589 while( !(custom.intreqr & IF_RBF) )
590 barrier();
591 c = custom.serdatr;
592 /* clear the interrupt, so that another character can be read */
593 custom.intreq = IF_RBF;
594 return c;
595}
596
597int __debug_serinit( void )
598{
599 unsigned long flags;
600
601 local_irq_save(flags);
602
603 /* turn off Rx and Tx interrupts */
604 custom.intena = IF_RBF | IF_TBE;
605
606 /* clear any pending interrupt */
607 custom.intreq = IF_RBF | IF_TBE;
608
609 local_irq_restore(flags);
610
611 /*
612 * set the appropriate directions for the modem control flags,
613 * and clear RTS and DTR
614 */
615 ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */
616 ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */
617
618#ifdef CONFIG_KGDB
619 /* turn Rx interrupts on for GDB */
620 custom.intena = IF_SETCLR | IF_RBF;
621 ser_RTSon();
622#endif
623
624 return 0;
625}
626
627void __debug_print_hex(unsigned long x)
628{
629 int i;
630 char hexchars[] = "0123456789ABCDEF";
631
632 for (i = 0; i < 8; i++) {
633 __debug_ser_out(hexchars[(x >> 28) & 15]);
634 x <<= 4;
635 }
636 __debug_ser_out('\n');
637 __debug_ser_out('\r');
638}
639
640void __debug_print_string(char* s)
641{
642 unsigned char c;
643 while((c = *s++))
644 __debug_ser_out(c);
645 __debug_ser_out('\n');
646 __debug_ser_out('\r');
647}
648
649static void apus_progress(char *s, unsigned short value)
650{
651 __debug_print_string(s);
652}
653
654/****************************************************** init */
655
656/* The number of spurious interrupts */
657volatile unsigned int num_spurious;
658
659extern struct irqaction amiga_sys_irqaction[AUTO_IRQS];
660
661
662extern void amiga_enable_irq(unsigned int irq);
663extern void amiga_disable_irq(unsigned int irq);
664
665struct hw_interrupt_type amiga_sys_irqctrl = {
666 .typename = "Amiga IPL",
667 .end = apus_end_irq,
668};
669
670struct hw_interrupt_type amiga_irqctrl = {
671 .typename = "Amiga ",
672 .enable = amiga_enable_irq,
673 .disable = amiga_disable_irq,
674};
675
676#define HARDWARE_MAPPED_SIZE (512*1024)
677unsigned long __init apus_find_end_of_memory(void)
678{
679 int shadow = 0;
680 unsigned long total;
681
682 /* The memory size reported by ADOS excludes the 512KB
683 reserved for PPC exception registers and possibly 512KB
684 containing a shadow of the ADOS ROM. */
685 {
686 unsigned long size = memory[0].size;
687
688 /* If 2MB aligned, size was probably user
689 specified. We can't tell anything about shadowing
690 in this case so skip shadow assignment. */
691 if (0 != (size & 0x1fffff)){
692 /* Align to 512KB to ensure correct handling
693 of both memfile and system specified
694 sizes. */
695 size = ((size+0x0007ffff) & 0xfff80000);
696 /* If memory is 1MB aligned, assume
697 shadowing. */
698 shadow = !(size & 0x80000);
699 }
700
701 /* Add the chunk that ADOS does not see. by aligning
702 the size to the nearest 2MB limit upwards. */
703 memory[0].size = ((size+0x001fffff) & 0xffe00000);
704 }
705
706 ppc_memstart = memory[0].addr;
707 ppc_memoffset = PAGE_OFFSET - PPC_MEMSTART;
708 total = memory[0].size;
709
710 /* Remove the memory chunks that are controlled by special
711 Phase5 hardware. */
712
713 /* Remove the upper 512KB if it contains a shadow of
714 the ADOS ROM. FIXME: It might be possible to
715 disable this shadow HW. Check the booter
716 (ppc_boot.c) */
717 if (shadow)
718 total -= HARDWARE_MAPPED_SIZE;
719
720 /* Remove the upper 512KB where the PPC exception
721 vectors are mapped. */
722 total -= HARDWARE_MAPPED_SIZE;
723
724 /* Linux/APUS only handles one block of memory -- the one on
725 the PowerUP board. Other system memory is horrible slow in
726 comparison. The user can use other memory for swapping
727 using the z2ram device. */
728 return total;
729}
730
731static void __init
732apus_map_io(void)
733{
734 /* Map PPC exception vectors. */
735 io_block_mapping(0xfff00000, 0xfff00000, 0x00020000, _PAGE_KERNEL);
736 /* Map chip and ZorroII memory */
737 io_block_mapping(zTwoBase, 0x00000000, 0x01000000, _PAGE_IO);
738}
739
740__init
741void apus_init_IRQ(void)
742{
743 struct irqaction *action;
744 int i;
745
746#ifdef CONFIG_PCI
747 apus_setup_pci_ptrs();
748#endif
749
750 for ( i = 0 ; i < AMI_IRQS; i++ ) {
751 irq_desc[i].status = IRQ_LEVEL;
752 if (i < IRQ_AMIGA_AUTO) {
753 irq_desc[i].handler = &amiga_irqctrl;
754 } else {
755 irq_desc[i].handler = &amiga_sys_irqctrl;
756 action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO];
757 if (action->name)
758 setup_irq(i, action);
759 }
760 }
761
762 amiga_init_IRQ();
763
764}
765
766__init
767void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
768 unsigned long r6, unsigned long r7)
769{
770 extern int parse_bootinfo(const struct bi_record *);
771 extern char _end[];
772
773 /* Parse bootinfo. The bootinfo is located right after
774 the kernel bss */
775 parse_bootinfo((const struct bi_record *)&_end);
776#ifdef CONFIG_BLK_DEV_INITRD
777 /* Take care of initrd if we have one. Use data from
778 bootinfo to avoid the need to initialize PPC
779 registers when kernel is booted via a PPC reset. */
780 if ( ramdisk.addr ) {
781 initrd_start = (unsigned long) __va(ramdisk.addr);
782 initrd_end = (unsigned long)
783 __va(ramdisk.size + ramdisk.addr);
784 }
785#endif /* CONFIG_BLK_DEV_INITRD */
786
787 ISA_DMA_THRESHOLD = 0x00ffffff;
788
789 ppc_md.setup_arch = apus_setup_arch;
790 ppc_md.show_cpuinfo = apus_show_cpuinfo;
791 ppc_md.init_IRQ = apus_init_IRQ;
792 ppc_md.get_irq = apus_get_irq;
793
794#ifdef CONFIG_HEARTBEAT
795 ppc_md.heartbeat = apus_heartbeat;
796 ppc_md.heartbeat_count = 1;
797#endif
798#ifdef APUS_DEBUG
799 __debug_serinit();
800 ppc_md.progress = apus_progress;
801#endif
802 ppc_md.init = NULL;
803
804 ppc_md.restart = apus_restart;
805 ppc_md.power_off = apus_power_off;
806 ppc_md.halt = apus_halt;
807
808 ppc_md.time_init = NULL;
809 ppc_md.set_rtc_time = apus_set_rtc_time;
810 ppc_md.get_rtc_time = apus_get_rtc_time;
811 ppc_md.calibrate_decr = apus_calibrate_decr;
812
813 ppc_md.find_end_of_memory = apus_find_end_of_memory;
814 ppc_md.setup_io_mappings = apus_map_io;
815}
diff --git a/arch/ppc/platforms/bseip.h b/arch/ppc/platforms/bseip.h
new file mode 100644
index 000000000000..691f4a52b0a5
--- /dev/null
+++ b/arch/ppc/platforms/bseip.h
@@ -0,0 +1,38 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Bright Star Engineering ip-Engine board. Copied from the MBX stuff.
4 *
5 * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
6 */
7#ifndef __MACH_BSEIP_DEFS
8#define __MACH_BSEIP_DEFS
9
10#ifndef __ASSEMBLY__
11/* A Board Information structure that is given to a program when
12 * prom starts it up.
13 */
14typedef struct bd_info {
15 unsigned int bi_memstart; /* Memory start address */
16 unsigned int bi_memsize; /* Memory (end) size in bytes */
17 unsigned int bi_intfreq; /* Internal Freq, in Hz */
18 unsigned int bi_busfreq; /* Bus Freq, in Hz */
19 unsigned char bi_enetaddr[6];
20 unsigned int bi_baudrate;
21} bd_t;
22
23extern bd_t m8xx_board_info;
24
25/* Memory map is configured by the PROM startup.
26 * All we need to get started is the IMMR.
27 */
28#define IMAP_ADDR ((uint)0xff000000)
29#define IMAP_SIZE ((uint)(64 * 1024))
30#define PCMCIA_MEM_ADDR ((uint)0x04000000)
31#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
32#endif /* !__ASSEMBLY__ */
33
34/* We don't use the 8259.
35*/
36#define NR_8259_INTS 0
37
38#endif
diff --git a/arch/ppc/platforms/ccm.h b/arch/ppc/platforms/ccm.h
new file mode 100644
index 000000000000..edb87b573831
--- /dev/null
+++ b/arch/ppc/platforms/ccm.h
@@ -0,0 +1,28 @@
1/*
2 * Siemens Card Controller Module specific definitions
3 *
4 * Copyright (C) 2001-2002 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_CCM_H
8#define __MACH_CCM_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define CCM_IMMR_BASE 0xF0000000 /* phys. addr of IMMR */
15#define CCM_IMAP_SIZE (64 * 1024) /* size of mapped area */
16
17#define IMAP_ADDR CCM_IMMR_BASE /* physical base address of IMMR area */
18#define IMAP_SIZE CCM_IMAP_SIZE /* mapped size of IMMR area */
19
20#define FEC_INTERRUPT 13 /* = SIU_LEVEL6 */
21#define DEC_INTERRUPT 11 /* = SIU_LEVEL5 */
22#define CPM_INTERRUPT 9 /* = SIU_LEVEL4 */
23
24/* We don't use the 8259.
25*/
26#define NR_8259_INTS 0
27
28#endif /* __MACH_CCM_H */
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
new file mode 100644
index 000000000000..7786818bd9d0
--- /dev/null
+++ b/arch/ppc/platforms/chestnut.c
@@ -0,0 +1,580 @@
1/*
2 * arch/ppc/platforms/chestnut.c
3 *
4 * Board setup routines for IBM Chestnut
5 *
6 * Author: <source@mvista.com>
7 *
8 * <2004> (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/kdev_t.h>
21#include <linux/major.h>
22#include <linux/blkdev.h>
23#include <linux/console.h>
24#include <linux/root_dev.h>
25#include <linux/initrd.h>
26#include <linux/delay.h>
27#include <linux/seq_file.h>
28#include <linux/ide.h>
29#include <linux/serial.h>
30#include <linux/serial_core.h>
31#include <linux/mtd/physmap.h>
32#include <asm/system.h>
33#include <asm/pgtable.h>
34#include <asm/page.h>
35#include <asm/time.h>
36#include <asm/dma.h>
37#include <asm/io.h>
38#include <linux/irq.h>
39#include <asm/hw_irq.h>
40#include <asm/machdep.h>
41#include <asm/kgdb.h>
42#include <asm/bootinfo.h>
43#include <asm/mv64x60.h>
44#include <platforms/chestnut.h>
45
46static void __iomem *sram_base; /* Virtual addr of Internal SRAM */
47static void __iomem *cpld_base; /* Virtual addr of CPLD Regs */
48
49static mv64x60_handle_t bh;
50
51extern void gen550_progress(char *, unsigned short);
52extern void gen550_init(int, struct uart_port *);
53extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
54
55#define BIT(x) (1<<x)
56#define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \
57 BIT(MV64x60_CPU2DEV_1_WIN) | \
58 BIT(MV64x60_CPU2DEV_2_WIN) | \
59 BIT(MV64x60_CPU2DEV_3_WIN) | \
60 BIT(MV64x60_CPU2BOOT_WIN))
61/**************************************************************************
62 * FUNCTION: chestnut_calibrate_decr
63 *
64 * DESCRIPTION: initialize decrementer interrupt frequency (used as system
65 * timer)
66 *
67 ****/
68static void __init
69chestnut_calibrate_decr(void)
70{
71 ulong freq;
72
73 freq = CHESTNUT_BUS_SPEED / 4;
74
75 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
76 freq/1000000, freq%1000000);
77
78 tb_ticks_per_jiffy = freq / HZ;
79 tb_to_us = mulhwu_scale_factor(freq, 1000000);
80}
81
82static int
83chestnut_show_cpuinfo(struct seq_file *m)
84{
85 seq_printf(m, "vendor\t\t: IBM\n");
86 seq_printf(m, "machine\t\t: 750FX/GX Eval Board (Chestnut/Buckeye)\n");
87
88 return 0;
89}
90
91/**************************************************************************
92 * FUNCTION: chestnut_find_end_of_memory
93 *
94 * DESCRIPTION: ppc_md memory size callback
95 *
96 ****/
97unsigned long __init
98chestnut_find_end_of_memory(void)
99{
100 static int mem_size = 0;
101
102 if (mem_size == 0) {
103 mem_size = mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
104 MV64x60_TYPE_MV64460);
105 }
106 return mem_size;
107}
108
109#if defined(CONFIG_SERIAL_8250)
110static void __init
111chestnut_early_serial_map(void)
112{
113 struct uart_port port;
114
115 /* Setup serial port access */
116 memset(&port, 0, sizeof(port));
117 port.uartclk = BASE_BAUD * 16;
118 port.irq = UART0_INT;
119 port.flags = STD_COM_FLAGS | UPF_IOREMAP;
120 port.iotype = SERIAL_IO_MEM;
121 port.mapbase = CHESTNUT_UART0_IO_BASE;
122 port.regshift = 0;
123
124 if (early_serial_setup(&port) != 0)
125 printk("Early serial init of port 0 failed\n");
126
127 /* Assume early_serial_setup() doesn't modify serial_req */
128 port.line = 1;
129 port.irq = UART1_INT;
130 port.mapbase = CHESTNUT_UART1_IO_BASE;
131
132 if (early_serial_setup(&port) != 0)
133 printk("Early serial init of port 1 failed\n");
134}
135#endif
136
137/**************************************************************************
138 * FUNCTION: chestnut_map_irq
139 *
140 * DESCRIPTION: 0 return since PCI IRQs not needed
141 *
142 ****/
143static int __init
144chestnut_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
145{
146 static char pci_irq_table[][4] = {
147 {CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ,
148 CHESTNUT_PCI_SLOT0_IRQ, CHESTNUT_PCI_SLOT0_IRQ},
149 {CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ,
150 CHESTNUT_PCI_SLOT1_IRQ, CHESTNUT_PCI_SLOT1_IRQ},
151 {CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ,
152 CHESTNUT_PCI_SLOT2_IRQ, CHESTNUT_PCI_SLOT2_IRQ},
153 {CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ,
154 CHESTNUT_PCI_SLOT3_IRQ, CHESTNUT_PCI_SLOT3_IRQ},
155 };
156 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
157
158 return PCI_IRQ_TABLE_LOOKUP;
159}
160
161
162/**************************************************************************
163 * FUNCTION: chestnut_setup_bridge
164 *
165 * DESCRIPTION: initalize board-specific settings on the MV64360
166 *
167 ****/
168static void __init
169chestnut_setup_bridge(void)
170{
171 struct mv64x60_setup_info si;
172 int i;
173
174 if ( ppc_md.progress )
175 ppc_md.progress("chestnut_setup_bridge: enter", 0);
176
177 memset(&si, 0, sizeof(si));
178
179 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
180
181 /* setup only PCI bus 0 (bus 1 not used) */
182 si.pci_0.enable_bus = 1;
183 si.pci_0.pci_io.cpu_base = CHESTNUT_PCI0_IO_PROC_ADDR;
184 si.pci_0.pci_io.pci_base_hi = 0;
185 si.pci_0.pci_io.pci_base_lo = CHESTNUT_PCI0_IO_PCI_ADDR;
186 si.pci_0.pci_io.size = CHESTNUT_PCI0_IO_SIZE;
187 si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */
188 si.pci_0.pci_mem[0].cpu_base = CHESTNUT_PCI0_MEM_PROC_ADDR;
189 si.pci_0.pci_mem[0].pci_base_hi = CHESTNUT_PCI0_MEM_PCI_HI_ADDR;
190 si.pci_0.pci_mem[0].pci_base_lo = CHESTNUT_PCI0_MEM_PCI_LO_ADDR;
191 si.pci_0.pci_mem[0].size = CHESTNUT_PCI0_MEM_SIZE;
192 si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE; /* no swapping */
193 si.pci_0.pci_cmd_bits = 0;
194 si.pci_0.latency_timer = 0x80;
195
196 for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
197#if defined(CONFIG_NOT_COHERENT_CACHE)
198 si.cpu_prot_options[i] = 0;
199 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE;
200 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE;
201 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE;
202
203 si.pci_1.acc_cntl_options[i] =
204 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
205 MV64360_PCI_ACC_CNTL_SWAP_NONE |
206 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
207 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
208#else
209 si.cpu_prot_options[i] = 0;
210 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */
211 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */
212 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */
213
214 si.pci_1.acc_cntl_options[i] =
215 MV64360_PCI_ACC_CNTL_SNOOP_WB |
216 MV64360_PCI_ACC_CNTL_SWAP_NONE |
217 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
218 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
219#endif
220 }
221
222 /* Lookup host bridge - on CPU 0 - no SMP support */
223 if (mv64x60_init(&bh, &si)) {
224 printk("\n\nPCI Bridge initialization failed!\n");
225 }
226
227 pci_dram_offset = 0;
228 ppc_md.pci_swizzle = common_swizzle;
229 ppc_md.pci_map_irq = chestnut_map_irq;
230 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
231
232 mv64x60_set_bus(&bh, 0, 0);
233 bh.hose_a->first_busno = 0;
234 bh.hose_a->last_busno = 0xff;
235 bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
236}
237
238void __init
239chestnut_setup_peripherals(void)
240{
241 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
242 CHESTNUT_BOOT_8BIT_BASE, CHESTNUT_BOOT_8BIT_SIZE, 0);
243 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
244
245 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
246 CHESTNUT_32BIT_BASE, CHESTNUT_32BIT_SIZE, 0);
247 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
248
249 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
250 CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE, 0);
251 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
252 cpld_base = ioremap(CHESTNUT_CPLD_BASE, CHESTNUT_CPLD_SIZE);
253
254 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
255 CHESTNUT_UART_BASE, CHESTNUT_UART_SIZE, 0);
256 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
257
258 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
259 CHESTNUT_FRAM_BASE, CHESTNUT_FRAM_SIZE, 0);
260 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
261
262 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
263 CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
264 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
265
266#ifdef CONFIG_NOT_COHERENT_CACHE
267 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b0);
268#else
269 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);
270#endif
271 sram_base = ioremap(CHESTNUT_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE);
272 memset(sram_base, 0, MV64360_SRAM_SIZE);
273
274 /*
275 * Configure MPP pins for PCI DMA
276 *
277 * PCI Slot GNT pin REQ pin
278 * 0 MPP16 MPP17
279 * 1 MPP18 MPP19
280 * 2 MPP20 MPP21
281 * 3 MPP22 MPP23
282 */
283 mv64x60_write(&bh, MV64x60_MPP_CNTL_2,
284 (0x1 << 0) | /* MPPSel16 PCI0_GNT[0] */
285 (0x1 << 4) | /* MPPSel17 PCI0_REQ[0] */
286 (0x1 << 8) | /* MPPSel18 PCI0_GNT[1] */
287 (0x1 << 12) | /* MPPSel19 PCI0_REQ[1] */
288 (0x1 << 16) | /* MPPSel20 PCI0_GNT[2] */
289 (0x1 << 20) | /* MPPSel21 PCI0_REQ[2] */
290 (0x1 << 24) | /* MPPSel22 PCI0_GNT[3] */
291 (0x1 << 28)); /* MPPSel23 PCI0_REQ[3] */
292 /*
293 * Set unused MPP pins for output, as per schematic note
294 *
295 * Unused Pins: MPP01, MPP02, MPP04, MPP05, MPP06
296 * MPP09, MPP10, MPP13, MPP14, MPP15
297 */
298 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_0,
299 (0xf << 4) | /* MPPSel01 GPIO[1] */
300 (0xf << 8) | /* MPPSel02 GPIO[2] */
301 (0xf << 16) | /* MPPSel04 GPIO[4] */
302 (0xf << 20) | /* MPPSel05 GPIO[5] */
303 (0xf << 24)); /* MPPSel06 GPIO[6] */
304 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1,
305 (0xf << 4) | /* MPPSel09 GPIO[9] */
306 (0xf << 8) | /* MPPSel10 GPIO[10] */
307 (0xf << 20) | /* MPPSel13 GPIO[13] */
308 (0xf << 24) | /* MPPSel14 GPIO[14] */
309 (0xf << 28)); /* MPPSel15 GPIO[15] */
310 mv64x60_set_bits(&bh, MV64x60_GPP_IO_CNTL, /* Output */
311 BIT(1) | BIT(2) | BIT(4) | BIT(5) | BIT(6) |
312 BIT(9) | BIT(10) | BIT(13) | BIT(14) | BIT(15));
313
314 /*
315 * Configure the following MPP pins to indicate a level
316 * triggered interrupt
317 *
318 * MPP24 - Board Reset (just map the MPP & GPP for chestnut_reset)
319 * MPP25 - UART A (high)
320 * MPP26 - UART B (high)
321 * MPP28 - PCI Slot 3 (low)
322 * MPP29 - PCI Slot 2 (low)
323 * MPP30 - PCI Slot 1 (low)
324 * MPP31 - PCI Slot 0 (low)
325 */
326 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3,
327 BIT(3) | BIT(2) | BIT(1) | BIT(0) | /* MPP 24 */
328 BIT(7) | BIT(6) | BIT(5) | BIT(4) | /* MPP 25 */
329 BIT(11) | BIT(10) | BIT(9) | BIT(8) | /* MPP 26 */
330 BIT(19) | BIT(18) | BIT(17) | BIT(16) | /* MPP 28 */
331 BIT(23) | BIT(22) | BIT(21) | BIT(20) | /* MPP 29 */
332 BIT(27) | BIT(26) | BIT(25) | BIT(24) | /* MPP 30 */
333 BIT(31) | BIT(30) | BIT(29) | BIT(28)); /* MPP 31 */
334
335 /*
336 * Define GPP 25 (high), 26 (high), 28 (low), 29 (low), 30 (low),
337 * 31 (low) interrupt polarity input signal and level triggered
338 */
339 mv64x60_clr_bits(&bh, MV64x60_GPP_LEVEL_CNTL, BIT(25) | BIT(26));
340 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL,
341 BIT(28) | BIT(29) | BIT(30) | BIT(31));
342 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL,
343 BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
344 BIT(31));
345
346 /* Config GPP interrupt controller to respond to level trigger */
347 mv64x60_set_bits(&bh, MV64360_COMM_ARBITER_CNTL, BIT(10));
348
349 /*
350 * Dismiss and then enable interrupt on GPP interrupt cause for CPU #0
351 */
352 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE,
353 ~(BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
354 BIT(31)));
355 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK,
356 BIT(25) | BIT(26) | BIT(28) | BIT(29) | BIT(30) |
357 BIT(31));
358
359 /*
360 * Dismiss and then enable interrupt on CPU #0 high cause register
361 * BIT27 summarizes GPP interrupts 24-31
362 */
363 mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, BIT(27));
364
365 if (ppc_md.progress)
366 ppc_md.progress("chestnut_setup_bridge: exit", 0);
367}
368
369/**************************************************************************
370 * FUNCTION: chestnut_setup_arch
371 *
372 * DESCRIPTION: ppc_md machine configuration callback
373 *
374 ****/
375static void __init
376chestnut_setup_arch(void)
377{
378 if (ppc_md.progress)
379 ppc_md.progress("chestnut_setup_arch: enter", 0);
380
381 /* init to some ~sane value until calibrate_delay() runs */
382 loops_per_jiffy = 50000000 / HZ;
383
384 /* if the time base value is greater than bus freq/4 (the TB and
385 * decrementer tick rate) + signed integer rollover value, we
386 * can spend a fair amount of time waiting for the rollover to
387 * happen. To get around this, initialize the time base register
388 * to a "safe" value.
389 */
390 set_tb(0, 0);
391
392#ifdef CONFIG_BLK_DEV_INITRD
393 if (initrd_start)
394 ROOT_DEV = Root_RAM0;
395 else
396#endif
397#ifdef CONFIG_ROOT_NFS
398 ROOT_DEV = Root_NFS;
399#else
400 ROOT_DEV = Root_SDA2;
401#endif
402
403 /*
404 * Set up the L2CR register.
405 */
406 _set_L2CR(_get_L2CR() | L2CR_L2E);
407
408 chestnut_setup_bridge();
409 chestnut_setup_peripherals();
410
411#ifdef CONFIG_DUMMY_CONSOLE
412 conswitchp = &dummy_con;
413#endif
414
415#if defined(CONFIG_SERIAL_8250)
416 chestnut_early_serial_map();
417#endif
418
419 /* Identify the system */
420 printk(KERN_INFO "System Identification: IBM 750FX/GX Eval Board\n");
421 printk(KERN_INFO "IBM 750FX/GX port (C) 2004 MontaVista Software, Inc."
422 " (source@mvista.com)\n");
423
424 if (ppc_md.progress)
425 ppc_md.progress("chestnut_setup_arch: exit", 0);
426}
427
428#ifdef CONFIG_MTD_PHYSMAP
429static struct mtd_partition ptbl;
430
431static int __init
432chestnut_setup_mtd(void)
433{
434 memset(&ptbl, 0, sizeof(ptbl));
435
436 ptbl.name = "User FS";
437 ptbl.size = CHESTNUT_32BIT_SIZE;
438
439 physmap_map.size = CHESTNUT_32BIT_SIZE;
440 physmap_set_partitions(&ptbl, 1);
441 return 0;
442}
443
444arch_initcall(chestnut_setup_mtd);
445#endif
446
447/**************************************************************************
448 * FUNCTION: chestnut_restart
449 *
450 * DESCRIPTION: ppc_md machine reset callback
451 * reset the board via the CPLD command register
452 *
453 ****/
454static void
455chestnut_restart(char *cmd)
456{
457 volatile ulong i = 10000000;
458
459 local_irq_disable();
460
461 /*
462 * Set CPLD Reg 3 bit 0 to 1 to allow MPP signals on reset to work
463 *
464 * MPP24 - board reset
465 */
466 writeb(0x1, cpld_base + 3);
467
468 /* GPP pin tied to MPP earlier */
469 mv64x60_set_bits(&bh, MV64x60_GPP_VALUE_SET, BIT(24));
470
471 while (i-- > 0);
472 panic("restart failed\n");
473}
474
475static void
476chestnut_halt(void)
477{
478 local_irq_disable();
479 for (;;);
480 /* NOTREACHED */
481}
482
483static void
484chestnut_power_off(void)
485{
486 chestnut_halt();
487 /* NOTREACHED */
488}
489
490/**************************************************************************
491 * FUNCTION: chestnut_map_io
492 *
493 * DESCRIPTION: configure fixed memory-mapped IO
494 *
495 ****/
496static void __init
497chestnut_map_io(void)
498{
499#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
500 io_block_mapping(CHESTNUT_UART_BASE, CHESTNUT_UART_BASE, 0x100000,
501 _PAGE_IO);
502#endif
503}
504
505/**************************************************************************
506 * FUNCTION: chestnut_set_bat
507 *
508 * DESCRIPTION: configures a (temporary) bat mapping for early access to
509 * device I/O
510 *
511 ****/
512static __inline__ void
513chestnut_set_bat(void)
514{
515 mb();
516 mtspr(SPRN_DBAT3U, 0xf0001ffe);
517 mtspr(SPRN_DBAT3L, 0xf000002a);
518 mb();
519}
520
521/**************************************************************************
522 * FUNCTION: platform_init
523 *
524 * DESCRIPTION: main entry point for configuring board-specific machine
525 * callbacks
526 *
527 ****/
528void __init
529platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
530 unsigned long r6, unsigned long r7)
531{
532 parse_bootinfo(find_bootinfo());
533
534 /* Copy the kernel command line arguments to a safe place. */
535
536 if (r6) {
537 *(char *) (r7 + KERNELBASE) = 0;
538 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
539 }
540
541 isa_mem_base = 0;
542
543 ppc_md.setup_arch = chestnut_setup_arch;
544 ppc_md.show_cpuinfo = chestnut_show_cpuinfo;
545 ppc_md.irq_canonicalize = NULL;
546 ppc_md.init_IRQ = mv64360_init_irq;
547 ppc_md.get_irq = mv64360_get_irq;
548 ppc_md.init = NULL;
549
550 ppc_md.find_end_of_memory = chestnut_find_end_of_memory;
551 ppc_md.setup_io_mappings = chestnut_map_io;
552
553 ppc_md.restart = chestnut_restart;
554 ppc_md.power_off = chestnut_power_off;
555 ppc_md.halt = chestnut_halt;
556
557 ppc_md.time_init = NULL;
558 ppc_md.set_rtc_time = NULL;
559 ppc_md.get_rtc_time = NULL;
560 ppc_md.calibrate_decr = chestnut_calibrate_decr;
561
562 ppc_md.nvram_read_val = NULL;
563 ppc_md.nvram_write_val = NULL;
564
565 ppc_md.heartbeat = NULL;
566
567 bh.p_base = CONFIG_MV64X60_NEW_BASE;
568
569 chestnut_set_bat();
570
571#if defined(CONFIG_SERIAL_TEXT_DEBUG)
572 ppc_md.progress = gen550_progress;
573#endif
574#if defined(CONFIG_KGDB)
575 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
576#endif
577
578 if (ppc_md.progress)
579 ppc_md.progress("chestnut_init(): exit", 0);
580}
diff --git a/arch/ppc/platforms/chestnut.h b/arch/ppc/platforms/chestnut.h
new file mode 100644
index 000000000000..0400b2be40ab
--- /dev/null
+++ b/arch/ppc/platforms/chestnut.h
@@ -0,0 +1,129 @@
1/*
2 * arch/ppc/platforms/chestnut.h
3 *
4 * Definitions for IBM 750FXGX Eval (Chestnut)
5 *
6 * Author: <source@mvista.com>
7 *
8 * Based on Artesyn Katana code done by Tim Montgomery <timm@artesyncp.com>
9 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
10 * Based on code done by Mark A. Greer <mgreer@mvista.com>
11 *
12 * <2004> (c) MontaVista Software, Inc. This file is licensed under
13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express
15 * or implied.
16 */
17
18/*
19 * This is the CPU physical memory map (windows must be at least 1MB and start
20 * on a boundary that is a multiple of the window size):
21 *
22 * Seems on the IBM 750FXGX Eval board, the MV64460 Registers can be in
23 * only 2 places per switch U17 0x14000000 or 0xf1000000 easily - chose to
24 * implement at 0xf1000000 only at this time
25 *
26 * 0xfff00000-0xffffffff - 8 Flash
27 * 0xffe00000-0xffefffff - BOOT SRAM
28 * 0xffd00000-0xffd00004 - CPLD
29 * 0xffc00000-0xffc0000f - UART
30 * 0xffb00000-0xffb07fff - FRAM
31 * 0xff840000-0xffafffff - *** HOLE ***
32 * 0xff800000-0xff83ffff - MV64460 Integrated SRAM
33 * 0xfe000000-0xff8fffff - *** HOLE ***
34 * 0xfc000000-0xfdffffff - 32bit Flash
35 * 0xf1010000-0xfbffffff - *** HOLE ***
36 * 0xf1000000-0xf100ffff - MV64460 Registers
37 */
38
39#ifndef __PPC_PLATFORMS_CHESTNUT_H__
40#define __PPC_PLATFORMS_CHESTNUT_H__
41
42#define CHESTNUT_BOOT_8BIT_BASE 0xfff00000
43#define CHESTNUT_BOOT_8BIT_SIZE_ACTUAL (1024*1024)
44#define CHESTNUT_BOOT_SRAM_BASE 0xffe00000
45#define CHESTNUT_BOOT_SRAM_SIZE_ACTUAL (1024*1024)
46#define CHESTNUT_CPLD_BASE 0xffd00000
47#define CHESTNUT_CPLD_SIZE_ACTUAL 5
48#define CHESTNUT_CPLD_REG3 (CHESTNUT_CPLD_BASE+3)
49#define CHESTNUT_UART_BASE 0xffc00000
50#define CHESTNUT_UART_SIZE_ACTUAL 16
51#define CHESTNUT_FRAM_BASE 0xffb00000
52#define CHESTNUT_FRAM_SIZE_ACTUAL (32*1024)
53#define CHESTNUT_INTERNAL_SRAM_BASE 0xff800000
54#define CHESTNUT_32BIT_BASE 0xfc000000
55#define CHESTNUT_32BIT_SIZE (32*1024*1024)
56
57#define CHESTNUT_BOOT_8BIT_SIZE max(MV64360_WINDOW_SIZE_MIN, \
58 CHESTNUT_BOOT_8BIT_SIZE_ACTUAL)
59#define CHESTNUT_BOOT_SRAM_SIZE max(MV64360_WINDOW_SIZE_MIN, \
60 CHESTNUT_BOOT_SRAM_SIZE_ACTUAL)
61#define CHESTNUT_CPLD_SIZE max(MV64360_WINDOW_SIZE_MIN, \
62 CHESTNUT_CPLD_SIZE_ACTUAL)
63#define CHESTNUT_UART_SIZE max(MV64360_WINDOW_SIZE_MIN, \
64 CHESTNUT_UART_SIZE_ACTUAL)
65#define CHESTNUT_FRAM_SIZE max(MV64360_WINDOW_SIZE_MIN, \
66 CHESTNUT_FRAM_SIZE_ACTUAL)
67
68#define CHESTNUT_BUS_SPEED 200000000
69#define CHESTNUT_PIBS_DATABASE 0xf0000 /* from PIBS src code */
70
71#define KATANA_ETH0_PHY_ADDR 12
72#define KATANA_ETH1_PHY_ADDR 11
73#define KATANA_ETH2_PHY_ADDR 4
74
75#define CHESTNUT_ETH_TX_QUEUE_SIZE 800
76#define CHESTNUT_ETH_RX_QUEUE_SIZE 400
77
78/*
79 * PCI windows
80 */
81
82#define CHESTNUT_PCI0_MEM_PROC_ADDR 0x80000000
83#define CHESTNUT_PCI0_MEM_PCI_HI_ADDR 0x00000000
84#define CHESTNUT_PCI0_MEM_PCI_LO_ADDR 0x80000000
85#define CHESTNUT_PCI0_MEM_SIZE 0x10000000
86#define CHESTNUT_PCI0_IO_PROC_ADDR 0xa0000000
87#define CHESTNUT_PCI0_IO_PCI_ADDR 0x00000000
88#define CHESTNUT_PCI0_IO_SIZE 0x01000000
89
90/*
91 * Board-specific IRQ info
92 */
93#define CHESTNUT_PCI_SLOT0_IRQ (64 + 31)
94#define CHESTNUT_PCI_SLOT1_IRQ (64 + 30)
95#define CHESTNUT_PCI_SLOT2_IRQ (64 + 29)
96#define CHESTNUT_PCI_SLOT3_IRQ (64 + 28)
97
98/* serial port definitions */
99#define CHESTNUT_UART0_IO_BASE (CHESTNUT_UART_BASE + 8)
100#define CHESTNUT_UART1_IO_BASE CHESTNUT_UART_BASE
101
102#define UART0_INT (64 + 25)
103#define UART1_INT (64 + 26)
104
105#ifdef CONFIG_SERIAL_MANY_PORTS
106#define RS_TABLE_SIZE 64
107#else
108#define RS_TABLE_SIZE 2
109#endif
110
111/* Rate for the 3.6864 Mhz clock for the onboard serial chip */
112#define BASE_BAUD (3686400 / 16)
113
114#ifdef CONFIG_SERIAL_DETECT_IRQ
115#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
116#else
117#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
118#endif
119
120#define STD_UART_OP(num) \
121 { 0, BASE_BAUD, 0, UART##num##_INT, STD_COM_FLAGS, \
122 iomem_base: (u8 *)CHESTNUT_UART##num##_IO_BASE, \
123 io_type: SERIAL_IO_MEM},
124
125#define SERIAL_PORT_DFNS \
126 STD_UART_OP(0) \
127 STD_UART_OP(1)
128
129#endif /* __PPC_PLATFORMS_CHESTNUT_H__ */
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
new file mode 100644
index 000000000000..5bb6492ecf8c
--- /dev/null
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -0,0 +1,309 @@
1/*
2 * CHRP pci routines.
3 */
4
5#include <linux/config.h>
6#include <linux/kernel.h>
7#include <linux/pci.h>
8#include <linux/delay.h>
9#include <linux/string.h>
10#include <linux/init.h>
11#include <linux/ide.h>
12#include <linux/bootmem.h>
13
14#include <asm/io.h>
15#include <asm/pgtable.h>
16#include <asm/irq.h>
17#include <asm/hydra.h>
18#include <asm/prom.h>
19#include <asm/gg2.h>
20#include <asm/machdep.h>
21#include <asm/sections.h>
22#include <asm/pci-bridge.h>
23#include <asm/open_pic.h>
24
25/* LongTrail */
26void __iomem *gg2_pci_config_base;
27
28/*
29 * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
30 * limit the bus number to 3 bits
31 */
32
33int __chrp gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
34 int len, u32 *val)
35{
36 volatile void __iomem *cfg_data;
37 struct pci_controller *hose = bus->sysdata;
38
39 if (bus->number > 7)
40 return PCIBIOS_DEVICE_NOT_FOUND;
41 /*
42 * Note: the caller has already checked that off is
43 * suitably aligned and that len is 1, 2 or 4.
44 */
45 cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
46 switch (len) {
47 case 1:
48 *val = in_8(cfg_data);
49 break;
50 case 2:
51 *val = in_le16(cfg_data);
52 break;
53 default:
54 *val = in_le32(cfg_data);
55 break;
56 }
57 return PCIBIOS_SUCCESSFUL;
58}
59
60int __chrp gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
61 int len, u32 val)
62{
63 volatile void __iomem *cfg_data;
64 struct pci_controller *hose = bus->sysdata;
65
66 if (bus->number > 7)
67 return PCIBIOS_DEVICE_NOT_FOUND;
68 /*
69 * Note: the caller has already checked that off is
70 * suitably aligned and that len is 1, 2 or 4.
71 */
72 cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
73 switch (len) {
74 case 1:
75 out_8(cfg_data, val);
76 break;
77 case 2:
78 out_le16(cfg_data, val);
79 break;
80 default:
81 out_le32(cfg_data, val);
82 break;
83 }
84 return PCIBIOS_SUCCESSFUL;
85}
86
87static struct pci_ops gg2_pci_ops =
88{
89 gg2_read_config,
90 gg2_write_config
91};
92
93/*
94 * Access functions for PCI config space using RTAS calls.
95 */
96int __chrp
97rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
98 int len, u32 *val)
99{
100 struct pci_controller *hose = bus->sysdata;
101 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
102 | (((bus->number - hose->first_busno) & 0xff) << 16)
103 | (hose->index << 24);
104 unsigned long ret = ~0UL;
105 int rval;
106
107 rval = call_rtas("read-pci-config", 2, 2, &ret, addr, len);
108 *val = ret;
109 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
110}
111
112int __chrp
113rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
114 int len, u32 val)
115{
116 struct pci_controller *hose = bus->sysdata;
117 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
118 | (((bus->number - hose->first_busno) & 0xff) << 16)
119 | (hose->index << 24);
120 int rval;
121
122 rval = call_rtas("write-pci-config", 3, 1, NULL, addr, len, val);
123 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
124}
125
126static struct pci_ops rtas_pci_ops =
127{
128 rtas_read_config,
129 rtas_write_config
130};
131
132volatile struct Hydra *Hydra = NULL;
133
134int __init
135hydra_init(void)
136{
137 struct device_node *np;
138
139 np = find_devices("mac-io");
140 if (np == NULL || np->n_addrs == 0)
141 return 0;
142 Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
143 printk("Hydra Mac I/O at %x\n", np->addrs[0].address);
144 printk("Hydra Feature_Control was %x",
145 in_le32(&Hydra->Feature_Control));
146 out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
147 HYDRA_FC_SCSI_CELL_EN |
148 HYDRA_FC_SCCA_ENABLE |
149 HYDRA_FC_SCCB_ENABLE |
150 HYDRA_FC_ARB_BYPASS |
151 HYDRA_FC_MPIC_ENABLE |
152 HYDRA_FC_SLOW_SCC_PCLK |
153 HYDRA_FC_MPIC_IS_MASTER));
154 printk(", now %x\n", in_le32(&Hydra->Feature_Control));
155 return 1;
156}
157
158void __init
159chrp_pcibios_fixup(void)
160{
161 struct pci_dev *dev = NULL;
162 struct device_node *np;
163
164 /* PCI interrupts are controlled by the OpenPIC */
165 for_each_pci_dev(dev) {
166 np = pci_device_to_OF_node(dev);
167 if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
168 dev->irq = np->intrs[0].line;
169 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
170 }
171}
172
173#define PRG_CL_RESET_VALID 0x00010000
174
175static void __init
176setup_python(struct pci_controller *hose, struct device_node *dev)
177{
178 u32 *reg, val;
179 unsigned long addr = dev->addrs[0].address;
180
181 setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
182
183 /* Clear the magic go-slow bit */
184 reg = (u32 *) ioremap(dev->addrs[0].address + 0xf6000, 0x40);
185 val = in_be32(&reg[12]);
186 if (val & PRG_CL_RESET_VALID) {
187 out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
188 in_be32(&reg[12]);
189 }
190 iounmap(reg);
191}
192
193/* Marvell Discovery II based Pegasos 2 */
194static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
195{
196 struct device_node *root = find_path_device("/");
197 struct device_node *rtas;
198
199 rtas = of_find_node_by_name (root, "rtas");
200 if (rtas) {
201 hose->ops = &rtas_pci_ops;
202 } else {
203 printk ("RTAS supporting Pegasos OF not found, please upgrade"
204 " your firmware\n");
205 }
206 pci_assign_all_busses = 1;
207}
208
209void __init
210chrp_find_bridges(void)
211{
212 struct device_node *dev;
213 int *bus_range;
214 int len, index = -1;
215 struct pci_controller *hose;
216 unsigned int *dma;
217 char *model, *machine;
218 int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
219 struct device_node *root = find_path_device("/");
220
221 /*
222 * The PCI host bridge nodes on some machines don't have
223 * properties to adequately identify them, so we have to
224 * look at what sort of machine this is as well.
225 */
226 machine = get_property(root, "model", NULL);
227 if (machine != NULL) {
228 is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
229 is_mot = strncmp(machine, "MOT", 3) == 0;
230 if (strncmp(machine, "Pegasos2", 8) == 0)
231 is_pegasos = 2;
232 else if (strncmp(machine, "Pegasos", 7) == 0)
233 is_pegasos = 1;
234 }
235 for (dev = root->child; dev != NULL; dev = dev->sibling) {
236 if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
237 continue;
238 ++index;
239 /* The GG2 bridge on the LongTrail doesn't have an address */
240 if (dev->n_addrs < 1 && !is_longtrail) {
241 printk(KERN_WARNING "Can't use %s: no address\n",
242 dev->full_name);
243 continue;
244 }
245 bus_range = (int *) get_property(dev, "bus-range", &len);
246 if (bus_range == NULL || len < 2 * sizeof(int)) {
247 printk(KERN_WARNING "Can't get bus-range for %s\n",
248 dev->full_name);
249 continue;
250 }
251 if (bus_range[1] == bus_range[0])
252 printk(KERN_INFO "PCI bus %d", bus_range[0]);
253 else
254 printk(KERN_INFO "PCI buses %d..%d",
255 bus_range[0], bus_range[1]);
256 printk(" controlled by %s", dev->type);
257 if (dev->n_addrs > 0)
258 printk(" at %x", dev->addrs[0].address);
259 printk("\n");
260
261 hose = pcibios_alloc_controller();
262 if (!hose) {
263 printk("Can't allocate PCI controller structure for %s\n",
264 dev->full_name);
265 continue;
266 }
267 hose->arch_data = dev;
268 hose->first_busno = bus_range[0];
269 hose->last_busno = bus_range[1];
270
271 model = get_property(dev, "model", NULL);
272 if (model == NULL)
273 model = "<none>";
274 if (device_is_compatible(dev, "IBM,python")) {
275 setup_python(hose, dev);
276 } else if (is_mot
277 || strncmp(model, "Motorola, Grackle", 17) == 0) {
278 setup_grackle(hose);
279 } else if (is_longtrail) {
280 void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
281 hose->ops = &gg2_pci_ops;
282 hose->cfg_data = p;
283 gg2_pci_config_base = p;
284 } else if (is_pegasos == 1) {
285 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
286 } else if (is_pegasos == 2) {
287 setup_peg2(hose, dev);
288 } else {
289 printk("No methods for %s (model %s), using RTAS\n",
290 dev->full_name, model);
291 hose->ops = &rtas_pci_ops;
292 }
293
294 pci_process_bridge_OF_ranges(hose, dev, index == 0);
295
296 /* check the first bridge for a property that we can
297 use to set pci_dram_offset */
298 dma = (unsigned int *)
299 get_property(dev, "ibm,dma-ranges", &len);
300 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
301 pci_dram_offset = dma[2] - dma[3];
302 printk("pci_dram_offset = %lx\n", pci_dram_offset);
303 }
304 }
305
306 /* Do not fixup interrupts from OF tree on pegasos */
307 if (is_pegasos == 0)
308 ppc_md.pcibios_fixup = chrp_pcibios_fixup;
309}
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
new file mode 100644
index 000000000000..cad5bfa153b2
--- /dev/null
+++ b/arch/ppc/platforms/chrp_pegasos_eth.c
@@ -0,0 +1,101 @@
1/*
2 * arch/ppc/platforms/chrp_pegasos_eth.c
3 *
4 * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
5 * Thanks to :
6 * Dale Farnsworth <dale@farnsworth.org>
7 * Mark A. Greer <mgreer@mvista.com>
8 * Nicolas DET <nd@bplan-gmbh.de>
9 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
10 * And anyone else who helped me on this.
11 */
12
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/device.h>
17#include <linux/mv643xx.h>
18#include <linux/pci.h>
19
20/* Pegasos 2 specific Marvell MV 64361 gigabit ethernet port setup */
21static struct resource mv643xx_eth_shared_resources[] = {
22 [0] = {
23 .name = "ethernet shared base",
24 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
25 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
26 MV643XX_ETH_SHARED_REGS_SIZE - 1,
27 .flags = IORESOURCE_MEM,
28 },
29};
30
31static struct platform_device mv643xx_eth_shared_device = {
32 .name = MV643XX_ETH_SHARED_NAME,
33 .id = 0,
34 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
35 .resource = mv643xx_eth_shared_resources,
36};
37
38static struct resource mv643xx_eth0_resources[] = {
39 [0] = {
40 .name = "eth0 irq",
41 .start = 9,
42 .end = 9,
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static struct mv643xx_eth_platform_data eth0_pd;
48
49static struct platform_device eth0_device = {
50 .name = MV643XX_ETH_NAME,
51 .id = 0,
52 .num_resources = ARRAY_SIZE(mv643xx_eth0_resources),
53 .resource = mv643xx_eth0_resources,
54 .dev = {
55 .platform_data = &eth0_pd,
56 },
57};
58
59static struct resource mv643xx_eth1_resources[] = {
60 [0] = {
61 .name = "eth1 irq",
62 .start = 9,
63 .end = 9,
64 .flags = IORESOURCE_IRQ,
65 },
66};
67
68static struct mv643xx_eth_platform_data eth1_pd;
69
70static struct platform_device eth1_device = {
71 .name = MV643XX_ETH_NAME,
72 .id = 1,
73 .num_resources = ARRAY_SIZE(mv643xx_eth1_resources),
74 .resource = mv643xx_eth1_resources,
75 .dev = {
76 .platform_data = &eth1_pd,
77 },
78};
79
80static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
81 &mv643xx_eth_shared_device,
82 &eth0_device,
83 &eth1_device,
84};
85
86
87int
88mv643xx_eth_add_pds(void)
89{
90 int ret = 0;
91 static struct pci_device_id pci_marvell_mv64360[] = {
92 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
93 { }
94 };
95
96 if (pci_dev_present(pci_marvell_mv64360)) {
97 ret = platform_add_devices(mv643xx_eth_pd_devs, ARRAY_SIZE(mv643xx_eth_pd_devs));
98 }
99 return ret;
100}
101device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
new file mode 100644
index 000000000000..f23c4f320760
--- /dev/null
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -0,0 +1,615 @@
1/*
2 * arch/ppc/platforms/setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 */
8
9/*
10 * bootup setup stuff..
11 */
12
13#include <linux/config.h>
14#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/stddef.h>
19#include <linux/unistd.h>
20#include <linux/ptrace.h>
21#include <linux/slab.h>
22#include <linux/user.h>
23#include <linux/a.out.h>
24#include <linux/tty.h>
25#include <linux/major.h>
26#include <linux/interrupt.h>
27#include <linux/reboot.h>
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/version.h>
31#include <linux/adb.h>
32#include <linux/module.h>
33#include <linux/delay.h>
34#include <linux/ide.h>
35#include <linux/irq.h>
36#include <linux/console.h>
37#include <linux/seq_file.h>
38#include <linux/root_dev.h>
39#include <linux/initrd.h>
40#include <linux/module.h>
41
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/prom.h>
45#include <asm/gg2.h>
46#include <asm/pci-bridge.h>
47#include <asm/dma.h>
48#include <asm/machdep.h>
49#include <asm/irq.h>
50#include <asm/hydra.h>
51#include <asm/sections.h>
52#include <asm/time.h>
53#include <asm/btext.h>
54#include <asm/i8259.h>
55#include <asm/open_pic.h>
56#include <asm/xmon.h>
57
58unsigned long chrp_get_rtc_time(void);
59int chrp_set_rtc_time(unsigned long nowtime);
60void chrp_calibrate_decr(void);
61long chrp_time_init(void);
62
63void chrp_find_bridges(void);
64void chrp_event_scan(void);
65void rtas_display_progress(char *, unsigned short);
66void rtas_indicator_progress(char *, unsigned short);
67void btext_progress(char *, unsigned short);
68
69extern unsigned long pmac_find_end_of_memory(void);
70extern int of_show_percpuinfo(struct seq_file *, int);
71
72int _chrp_type;
73EXPORT_SYMBOL(_chrp_type);
74
75/*
76 * XXX this should be in xmon.h, but putting it there means xmon.h
77 * has to include <linux/interrupt.h> (to get irqreturn_t), which
78 * causes all sorts of problems. -- paulus
79 */
80extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
81
82extern dev_t boot_dev;
83
84extern PTE *Hash, *Hash_end;
85extern unsigned long Hash_size, Hash_mask;
86extern int probingmem;
87extern unsigned long loops_per_jiffy;
88static int max_width;
89
90#ifdef CONFIG_SMP
91extern struct smp_ops_t chrp_smp_ops;
92#endif
93
94static const char *gg2_memtypes[4] = {
95 "FPM", "SDRAM", "EDO", "BEDO"
96};
97static const char *gg2_cachesizes[4] = {
98 "256 KB", "512 KB", "1 MB", "Reserved"
99};
100static const char *gg2_cachetypes[4] = {
101 "Asynchronous", "Reserved", "Flow-Through Synchronous",
102 "Pipelined Synchronous"
103};
104static const char *gg2_cachemodes[4] = {
105 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
106};
107
108int __chrp
109chrp_show_cpuinfo(struct seq_file *m)
110{
111 int i, sdramen;
112 unsigned int t;
113 struct device_node *root;
114 const char *model = "";
115
116 root = find_path_device("/");
117 if (root)
118 model = get_property(root, "model", NULL);
119 seq_printf(m, "machine\t\t: CHRP %s\n", model);
120
121 /* longtrail (goldengate) stuff */
122 if (!strncmp(model, "IBM,LongTrail", 13)) {
123 /* VLSI VAS96011/12 `Golden Gate 2' */
124 /* Memory banks */
125 sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
126 >>31) & 1;
127 for (i = 0; i < (sdramen ? 4 : 6); i++) {
128 t = in_le32(gg2_pci_config_base+
129 GG2_PCI_DRAM_BANK0+
130 i*4);
131 if (!(t & 1))
132 continue;
133 switch ((t>>8) & 0x1f) {
134 case 0x1f:
135 model = "4 MB";
136 break;
137 case 0x1e:
138 model = "8 MB";
139 break;
140 case 0x1c:
141 model = "16 MB";
142 break;
143 case 0x18:
144 model = "32 MB";
145 break;
146 case 0x10:
147 model = "64 MB";
148 break;
149 case 0x00:
150 model = "128 MB";
151 break;
152 default:
153 model = "Reserved";
154 break;
155 }
156 seq_printf(m, "memory bank %d\t: %s %s\n", i, model,
157 gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
158 }
159 /* L2 cache */
160 t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
161 seq_printf(m, "board l2\t: %s %s (%s)\n",
162 gg2_cachesizes[(t>>7) & 3],
163 gg2_cachetypes[(t>>2) & 3],
164 gg2_cachemodes[t & 3]);
165 }
166 return 0;
167}
168
169/*
170 * Fixes for the National Semiconductor PC78308VUL SuperI/O
171 *
172 * Some versions of Open Firmware incorrectly initialize the IRQ settings
173 * for keyboard and mouse
174 */
175static inline void __init sio_write(u8 val, u8 index)
176{
177 outb(index, 0x15c);
178 outb(val, 0x15d);
179}
180
181static inline u8 __init sio_read(u8 index)
182{
183 outb(index, 0x15c);
184 return inb(0x15d);
185}
186
187static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
188 u8 type)
189{
190 u8 level0, type0, active;
191
192 /* select logical device */
193 sio_write(device, 0x07);
194 active = sio_read(0x30);
195 level0 = sio_read(0x70);
196 type0 = sio_read(0x71);
197 if (level0 != level || type0 != type || !active) {
198 printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
199 "remapping to level %d, type %d, active\n",
200 name, level0, type0, !active ? "in" : "", level, type);
201 sio_write(0x01, 0x30);
202 sio_write(level, 0x70);
203 sio_write(type, 0x71);
204 }
205}
206
207static void __init sio_init(void)
208{
209 struct device_node *root;
210
211 if ((root = find_path_device("/")) &&
212 !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
213 /* logical device 0 (KBC/Keyboard) */
214 sio_fixup_irq("keyboard", 0, 1, 2);
215 /* select logical device 1 (KBC/Mouse) */
216 sio_fixup_irq("mouse", 1, 12, 2);
217 }
218}
219
220
221static void __init pegasos_set_l2cr(void)
222{
223 struct device_node *np;
224
225 /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
226 if (_chrp_type != _CHRP_Pegasos)
227 return;
228
229 /* Enable L2 cache if needed */
230 np = find_type_devices("cpu");
231 if (np != NULL) {
232 unsigned int *l2cr = (unsigned int *)
233 get_property (np, "l2cr", NULL);
234 if (l2cr == NULL) {
235 printk ("Pegasos l2cr : no cpu l2cr property found\n");
236 return;
237 }
238 if (!((*l2cr) & 0x80000000)) {
239 printk ("Pegasos l2cr : L2 cache was not active, "
240 "activating\n");
241 _set_L2CR(0);
242 _set_L2CR((*l2cr) | 0x80000000);
243 }
244 }
245}
246
247void __init chrp_setup_arch(void)
248{
249 struct device_node *device;
250
251 /* init to some ~sane value until calibrate_delay() runs */
252 loops_per_jiffy = 50000000/HZ;
253
254#ifdef CONFIG_BLK_DEV_INITRD
255 /* this is fine for chrp */
256 initrd_below_start_ok = 1;
257
258 if (initrd_start)
259 ROOT_DEV = Root_RAM0;
260 else
261#endif
262 ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
263
264 /* On pegasos, enable the L2 cache if not already done by OF */
265 pegasos_set_l2cr();
266
267 /* Lookup PCI host bridges */
268 chrp_find_bridges();
269
270#ifndef CONFIG_PPC64BRIDGE
271 /*
272 * Temporary fixes for PCI devices.
273 * -- Geert
274 */
275 hydra_init(); /* Mac I/O */
276
277#endif /* CONFIG_PPC64BRIDGE */
278
279 /*
280 * Fix the Super I/O configuration
281 */
282 sio_init();
283
284 /* Get the event scan rate for the rtas so we know how
285 * often it expects a heartbeat. -- Cort
286 */
287 if ( rtas_data ) {
288 struct property *p;
289 device = find_devices("rtas");
290 for ( p = device->properties;
291 p && strncmp(p->name, "rtas-event-scan-rate", 20);
292 p = p->next )
293 /* nothing */ ;
294 if ( p && *(unsigned long *)p->value ) {
295 ppc_md.heartbeat = chrp_event_scan;
296 ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1;
297 ppc_md.heartbeat_count = 1;
298 printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n",
299 *(unsigned long *)p->value, ppc_md.heartbeat_reset );
300 }
301 }
302
303 pci_create_OF_bus_map();
304}
305
306void __chrp
307chrp_event_scan(void)
308{
309 unsigned char log[1024];
310 unsigned long ret = 0;
311 /* XXX: we should loop until the hardware says no more error logs -- Cort */
312 call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0,
313 __pa(log), 1024 );
314 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
315}
316
317void __chrp
318chrp_restart(char *cmd)
319{
320 printk("RTAS system-reboot returned %d\n",
321 call_rtas("system-reboot", 0, 1, NULL));
322 for (;;);
323}
324
325void __chrp
326chrp_power_off(void)
327{
328 /* allow power on only with power button press */
329 printk("RTAS power-off returned %d\n",
330 call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff));
331 for (;;);
332}
333
334void __chrp
335chrp_halt(void)
336{
337 chrp_power_off();
338}
339
340u_int __chrp
341chrp_irq_canonicalize(u_int irq)
342{
343 if (irq == 2)
344 return 9;
345 return irq;
346}
347
348/*
349 * Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
350 * Then checks if it has an interrupt-ranges property. If it does then
351 * we have a distributed open-pic, so call openpic_set_sources to tell
352 * the openpic code where to find the interrupt source registers.
353 */
354static void __init chrp_find_openpic(void)
355{
356 struct device_node *np;
357 int len, i;
358 unsigned int *iranges;
359 void *isu;
360
361 np = find_type_devices("open-pic");
362 if (np == NULL || np->n_addrs == 0)
363 return;
364 printk(KERN_INFO "OpenPIC at %x (size %x)\n",
365 np->addrs[0].address, np->addrs[0].size);
366 OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000);
367 if (OpenPIC_Addr == NULL) {
368 printk(KERN_ERR "Failed to map OpenPIC!\n");
369 return;
370 }
371
372 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
373 if (iranges == NULL || len < 2 * sizeof(unsigned int))
374 return; /* not distributed */
375
376 /*
377 * The first pair of cells in interrupt-ranges refers to the
378 * IDU; subsequent pairs refer to the ISUs.
379 */
380 len /= 2 * sizeof(unsigned int);
381 if (np->n_addrs < len) {
382 printk(KERN_ERR "Insufficient addresses for distributed"
383 " OpenPIC (%d < %d)\n", np->n_addrs, len);
384 return;
385 }
386 if (iranges[1] != 0) {
387 printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n",
388 iranges[0], iranges[0] + iranges[1] - 1);
389 openpic_set_sources(iranges[0], iranges[1], NULL);
390 }
391 for (i = 1; i < len; ++i) {
392 iranges += 2;
393 printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n",
394 iranges[0], iranges[0] + iranges[1] - 1,
395 np->addrs[i].address, np->addrs[i].size);
396 isu = ioremap(np->addrs[i].address, np->addrs[i].size);
397 if (isu != NULL)
398 openpic_set_sources(iranges[0], iranges[1], isu);
399 else
400 printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n",
401 np->addrs[i].address);
402 }
403}
404
405#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
406static struct irqaction xmon_irqaction = {
407 .handler = xmon_irq,
408 .mask = CPU_MASK_NONE,
409 .name = "XMON break",
410};
411#endif
412
413void __init chrp_init_IRQ(void)
414{
415 struct device_node *np;
416 int i;
417 unsigned long chrp_int_ack = 0;
418 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
419#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
420 struct device_node *kbd;
421#endif
422
423 for (np = find_devices("pci"); np != NULL; np = np->next) {
424 unsigned int *addrp = (unsigned int *)
425 get_property(np, "8259-interrupt-acknowledge", NULL);
426
427 if (addrp == NULL)
428 continue;
429 chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
430 break;
431 }
432 if (np == NULL)
433 printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
434
435 chrp_find_openpic();
436
437 if (OpenPIC_Addr) {
438 prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
439 OpenPIC_InitSenses = init_senses;
440 OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
441
442 openpic_init(NUM_8259_INTERRUPTS);
443 /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
444 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
445 i8259_irq);
446
447 }
448 for (i = 0; i < NUM_8259_INTERRUPTS; i++)
449 irq_desc[i].handler = &i8259_pic;
450 i8259_init(chrp_int_ack);
451
452#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
453 /* see if there is a keyboard in the device tree
454 with a parent of type "adb" */
455 for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
456 if (kbd->parent && kbd->parent->type
457 && strcmp(kbd->parent->type, "adb") == 0)
458 break;
459 if (kbd)
460 setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
461#endif
462}
463
464void __init
465chrp_init2(void)
466{
467#ifdef CONFIG_NVRAM
468// XX replace this in a more saner way
469// pmac_nvram_init();
470#endif
471
472 request_region(0x20,0x20,"pic1");
473 request_region(0xa0,0x20,"pic2");
474 request_region(0x00,0x20,"dma1");
475 request_region(0x40,0x20,"timer");
476 request_region(0x80,0x10,"dma page reg");
477 request_region(0xc0,0x20,"dma2");
478
479 if (ppc_md.progress)
480 ppc_md.progress(" Have fun! ", 0x7777);
481}
482
483void __init
484chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
485 unsigned long r6, unsigned long r7)
486{
487 struct device_node *root = find_path_device ("/");
488 char *machine = NULL;
489
490#ifdef CONFIG_BLK_DEV_INITRD
491 /* take care of initrd if we have one */
492 if ( r6 )
493 {
494 initrd_start = r6 + KERNELBASE;
495 initrd_end = r6 + r7 + KERNELBASE;
496 }
497#endif /* CONFIG_BLK_DEV_INITRD */
498
499 ISA_DMA_THRESHOLD = ~0L;
500 DMA_MODE_READ = 0x44;
501 DMA_MODE_WRITE = 0x48;
502 isa_io_base = CHRP_ISA_IO_BASE; /* default value */
503
504 if (root)
505 machine = get_property(root, "model", NULL);
506 if (machine && strncmp(machine, "Pegasos", 7) == 0) {
507 _chrp_type = _CHRP_Pegasos;
508 } else if (machine && strncmp(machine, "IBM", 3) == 0) {
509 _chrp_type = _CHRP_IBM;
510 } else if (machine && strncmp(machine, "MOT", 3) == 0) {
511 _chrp_type = _CHRP_Motorola;
512 } else {
513 /* Let's assume it is an IBM chrp if all else fails */
514 _chrp_type = _CHRP_IBM;
515 }
516
517 ppc_md.setup_arch = chrp_setup_arch;
518 ppc_md.show_percpuinfo = of_show_percpuinfo;
519 ppc_md.show_cpuinfo = chrp_show_cpuinfo;
520
521 ppc_md.irq_canonicalize = chrp_irq_canonicalize;
522 ppc_md.init_IRQ = chrp_init_IRQ;
523 if (_chrp_type == _CHRP_Pegasos)
524 ppc_md.get_irq = i8259_irq;
525 else
526 ppc_md.get_irq = openpic_get_irq;
527
528 ppc_md.init = chrp_init2;
529
530 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
531
532 ppc_md.restart = chrp_restart;
533 ppc_md.power_off = chrp_power_off;
534 ppc_md.halt = chrp_halt;
535
536 ppc_md.time_init = chrp_time_init;
537 ppc_md.set_rtc_time = chrp_set_rtc_time;
538 ppc_md.get_rtc_time = chrp_get_rtc_time;
539 ppc_md.calibrate_decr = chrp_calibrate_decr;
540
541 ppc_md.find_end_of_memory = pmac_find_end_of_memory;
542
543 if (rtas_data) {
544 struct device_node *rtas;
545 unsigned int *p;
546
547 rtas = find_devices("rtas");
548 if (rtas != NULL) {
549 if (get_property(rtas, "display-character", NULL)) {
550 ppc_md.progress = rtas_display_progress;
551 p = (unsigned int *) get_property
552 (rtas, "ibm,display-line-length", NULL);
553 if (p)
554 max_width = *p;
555 } else if (get_property(rtas, "set-indicator", NULL))
556 ppc_md.progress = rtas_indicator_progress;
557 }
558 }
559#ifdef CONFIG_BOOTX_TEXT
560 if (ppc_md.progress == NULL && boot_text_mapped)
561 ppc_md.progress = btext_progress;
562#endif
563
564#ifdef CONFIG_SMP
565 ppc_md.smp_ops = &chrp_smp_ops;
566#endif /* CONFIG_SMP */
567
568 /*
569 * Print the banner, then scroll down so boot progress
570 * can be printed. -- Cort
571 */
572 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
573}
574
575void __chrp
576rtas_display_progress(char *s, unsigned short hex)
577{
578 int width;
579 char *os = s;
580
581 if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) )
582 return;
583
584 width = max_width;
585 while ( *os )
586 {
587 if ( (*os == '\n') || (*os == '\r') )
588 width = max_width;
589 else
590 width--;
591 call_rtas( "display-character", 1, 1, NULL, *os++ );
592 /* if we overwrite the screen length */
593 if ( width == 0 )
594 while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
595 os++;
596 }
597
598 /*while ( width-- > 0 )*/
599 call_rtas( "display-character", 1, 1, NULL, ' ' );
600}
601
602void __chrp
603rtas_indicator_progress(char *s, unsigned short hex)
604{
605 call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
606}
607
608#ifdef CONFIG_BOOTX_TEXT
609void
610btext_progress(char *s, unsigned short hex)
611{
612 prom_print(s);
613 prom_print("\n");
614}
615#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
new file mode 100644
index 000000000000..0ea1f7d9e46a
--- /dev/null
+++ b/arch/ppc/platforms/chrp_smp.c
@@ -0,0 +1,98 @@
1/*
2 * Smp support for CHRP machines.
3 *
4 * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
5 * deal of code from the sparc and intel versions.
6 *
7 * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/interrupt.h>
17#include <linux/kernel_stat.h>
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/spinlock.h>
21
22#include <asm/ptrace.h>
23#include <asm/atomic.h>
24#include <asm/irq.h>
25#include <asm/page.h>
26#include <asm/pgtable.h>
27#include <asm/sections.h>
28#include <asm/io.h>
29#include <asm/prom.h>
30#include <asm/smp.h>
31#include <asm/residual.h>
32#include <asm/time.h>
33#include <asm/open_pic.h>
34
35extern unsigned long smp_chrp_cpu_nr;
36
37static int __init
38smp_chrp_probe(void)
39{
40 if (smp_chrp_cpu_nr > 1)
41 openpic_request_IPIs();
42
43 return smp_chrp_cpu_nr;
44}
45
46static void __devinit
47smp_chrp_kick_cpu(int nr)
48{
49 *(unsigned long *)KERNELBASE = nr;
50 asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
51}
52
53static void __devinit
54smp_chrp_setup_cpu(int cpu_nr)
55{
56 if (OpenPIC_Addr)
57 do_openpic_setup_cpu();
58}
59
60static DEFINE_SPINLOCK(timebase_lock);
61static unsigned int timebase_upper = 0, timebase_lower = 0;
62
63void __devinit
64smp_chrp_give_timebase(void)
65{
66 spin_lock(&timebase_lock);
67 call_rtas("freeze-time-base", 0, 1, NULL);
68 timebase_upper = get_tbu();
69 timebase_lower = get_tbl();
70 spin_unlock(&timebase_lock);
71
72 while (timebase_upper || timebase_lower)
73 barrier();
74 call_rtas("thaw-time-base", 0, 1, NULL);
75}
76
77void __devinit
78smp_chrp_take_timebase(void)
79{
80 while (!(timebase_upper || timebase_lower))
81 barrier();
82 spin_lock(&timebase_lock);
83 set_tb(timebase_upper, timebase_lower);
84 timebase_upper = 0;
85 timebase_lower = 0;
86 spin_unlock(&timebase_lock);
87 printk("CPU %i taken timebase\n", smp_processor_id());
88}
89
90/* CHRP with openpic */
91struct smp_ops_t chrp_smp_ops __chrpdata = {
92 .message_pass = smp_openpic_message_pass,
93 .probe = smp_chrp_probe,
94 .kick_cpu = smp_chrp_kick_cpu,
95 .setup_cpu = smp_chrp_setup_cpu,
96 .give_timebase = smp_chrp_give_timebase,
97 .take_timebase = smp_chrp_take_timebase,
98};
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
new file mode 100644
index 000000000000..e2be0c838d8a
--- /dev/null
+++ b/arch/ppc/platforms/chrp_time.c
@@ -0,0 +1,194 @@
1/*
2 * arch/ppc/platforms/chrp_time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 *
6 * Adapted for PowerPC (PReP) by Gary Thomas
7 * Modified by Cort Dougan (cort@cs.nmt.edu).
8 * Copied and modified from arch/i386/kernel/time.c
9 *
10 */
11#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/param.h>
15#include <linux/string.h>
16#include <linux/mm.h>
17#include <linux/interrupt.h>
18#include <linux/time.h>
19#include <linux/timex.h>
20#include <linux/kernel_stat.h>
21#include <linux/mc146818rtc.h>
22#include <linux/init.h>
23#include <linux/bcd.h>
24
25#include <asm/segment.h>
26#include <asm/io.h>
27#include <asm/nvram.h>
28#include <asm/prom.h>
29#include <asm/sections.h>
30#include <asm/time.h>
31
32extern spinlock_t rtc_lock;
33
34static int nvram_as1 = NVRAM_AS1;
35static int nvram_as0 = NVRAM_AS0;
36static int nvram_data = NVRAM_DATA;
37
38long __init chrp_time_init(void)
39{
40 struct device_node *rtcs;
41 int base;
42
43 rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
44 if (rtcs == NULL)
45 rtcs = find_compatible_devices("rtc", "ds1385-rtc");
46 if (rtcs == NULL || rtcs->addrs == NULL)
47 return 0;
48 base = rtcs->addrs[0].address;
49 nvram_as1 = 0;
50 nvram_as0 = base;
51 nvram_data = base + 1;
52
53 return 0;
54}
55
56int __chrp chrp_cmos_clock_read(int addr)
57{
58 if (nvram_as1 != 0)
59 outb(addr>>8, nvram_as1);
60 outb(addr, nvram_as0);
61 return (inb(nvram_data));
62}
63
64void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
65{
66 if (nvram_as1 != 0)
67 outb(addr>>8, nvram_as1);
68 outb(addr, nvram_as0);
69 outb(val, nvram_data);
70 return;
71}
72
73/*
74 * Set the hardware clock. -- Cort
75 */
76int __chrp chrp_set_rtc_time(unsigned long nowtime)
77{
78 unsigned char save_control, save_freq_select;
79 struct rtc_time tm;
80
81 spin_lock(&rtc_lock);
82 to_tm(nowtime, &tm);
83
84 save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
85
86 chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
87
88 save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
89
90 chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
91
92 tm.tm_year -= 1900;
93 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
94 BIN_TO_BCD(tm.tm_sec);
95 BIN_TO_BCD(tm.tm_min);
96 BIN_TO_BCD(tm.tm_hour);
97 BIN_TO_BCD(tm.tm_mon);
98 BIN_TO_BCD(tm.tm_mday);
99 BIN_TO_BCD(tm.tm_year);
100 }
101 chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
102 chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
103 chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
104 chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
105 chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
106 chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
107
108 /* The following flags have to be released exactly in this order,
109 * otherwise the DS12887 (popular MC146818A clone with integrated
110 * battery and quartz) will not reset the oscillator and will not
111 * update precisely 500 ms later. You won't find this mentioned in
112 * the Dallas Semiconductor data sheets, but who believes data
113 * sheets anyway ... -- Markus Kuhn
114 */
115 chrp_cmos_clock_write(save_control, RTC_CONTROL);
116 chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
117
118 if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) )
119 time_state = TIME_OK;
120 spin_unlock(&rtc_lock);
121 return 0;
122}
123
124unsigned long __chrp chrp_get_rtc_time(void)
125{
126 unsigned int year, mon, day, hour, min, sec;
127 int uip, i;
128
129 /* The Linux interpretation of the CMOS clock register contents:
130 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
131 * RTC registers show the second which has precisely just started.
132 * Let's hope other operating systems interpret the RTC the same way.
133 */
134
135 /* Since the UIP flag is set for about 2.2 ms and the clock
136 * is typically written with a precision of 1 jiffy, trying
137 * to obtain a precision better than a few milliseconds is
138 * an illusion. Only consistency is interesting, this also
139 * allows to use the routine for /dev/rtc without a potential
140 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
141 */
142
143 for ( i = 0; i<1000000; i++) {
144 uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
145 sec = chrp_cmos_clock_read(RTC_SECONDS);
146 min = chrp_cmos_clock_read(RTC_MINUTES);
147 hour = chrp_cmos_clock_read(RTC_HOURS);
148 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
149 mon = chrp_cmos_clock_read(RTC_MONTH);
150 year = chrp_cmos_clock_read(RTC_YEAR);
151 uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
152 if ((uip & RTC_UIP)==0) break;
153 }
154
155 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
156 {
157 BCD_TO_BIN(sec);
158 BCD_TO_BIN(min);
159 BCD_TO_BIN(hour);
160 BCD_TO_BIN(day);
161 BCD_TO_BIN(mon);
162 BCD_TO_BIN(year);
163 }
164 if ((year += 1900) < 1970)
165 year += 100;
166 return mktime(year, mon, day, hour, min, sec);
167}
168
169
170void __init chrp_calibrate_decr(void)
171{
172 struct device_node *cpu;
173 unsigned int freq, *fp;
174
175 if (via_calibrate_decr())
176 return;
177
178 /*
179 * The cpu node should have a timebase-frequency property
180 * to tell us the rate at which the decrementer counts.
181 */
182 freq = 16666000; /* hardcoded default */
183 cpu = find_type_devices("cpu");
184 if (cpu != 0) {
185 fp = (unsigned int *)
186 get_property(cpu, "timebase-frequency", NULL);
187 if (fp != 0)
188 freq = *fp;
189 }
190 printk("time_init: decrementer frequency = %u.%.6u MHz\n",
191 freq/1000000, freq%1000000);
192 tb_ticks_per_jiffy = freq / HZ;
193 tb_to_us = mulhwu_scale_factor(freq, 1000000);
194}
diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
new file mode 100644
index 000000000000..507870c9a97a
--- /dev/null
+++ b/arch/ppc/platforms/cpci690.c
@@ -0,0 +1,491 @@
1/*
2 * arch/ppc/platforms/cpci690.c
3 *
4 * Board setup routines for the Force CPCI690 board.
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2003 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This programr
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#include <linux/config.h>
14#include <linux/delay.h>
15#include <linux/pci.h>
16#include <linux/ide.h>
17#include <linux/irq.h>
18#include <linux/fs.h>
19#include <linux/seq_file.h>
20#include <linux/console.h>
21#include <linux/initrd.h>
22#include <linux/root_dev.h>
23#include <linux/mv643xx.h>
24#include <asm/bootinfo.h>
25#include <asm/machdep.h>
26#include <asm/todc.h>
27#include <asm/time.h>
28#include <asm/mv64x60.h>
29#include <platforms/cpci690.h>
30
31#define BOARD_VENDOR "Force"
32#define BOARD_MACHINE "CPCI690"
33
34/* Set IDE controllers into Native mode? */
35#define SET_PCI_IDE_NATIVE
36
37static struct mv64x60_handle bh;
38static u32 cpci690_br_base;
39
40static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */
41 18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
42};
43
44TODC_ALLOC();
45
46static int __init
47cpci690_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
48{
49 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
50
51 if (hose->index == 0) {
52 static char pci_irq_table[][4] =
53 /*
54 * PCI IDSEL/INTPIN->INTLINE
55 * A B C D
56 */
57 {
58 { 90, 91, 88, 89}, /* IDSEL 30/20 - Sentinel */
59 };
60
61 const long min_idsel = 20, max_idsel = 20, irqs_per_slot = 4;
62 return PCI_IRQ_TABLE_LOOKUP;
63 } else {
64 static char pci_irq_table[][4] =
65 /*
66 * PCI IDSEL/INTPIN->INTLINE
67 * A B C D
68 */
69 {
70 { 93, 94, 95, 92}, /* IDSEL 28/18 - PMC slot 2 */
71 { 0, 0, 0, 0}, /* IDSEL 29/19 - Not used */
72 { 94, 95, 92, 93}, /* IDSEL 30/20 - PMC slot 1 */
73 };
74
75 const long min_idsel = 18, max_idsel = 20, irqs_per_slot = 4;
76 return PCI_IRQ_TABLE_LOOKUP;
77 }
78}
79
80static int
81cpci690_get_cpu_speed(void)
82{
83 unsigned long hid1;
84
85 hid1 = mfspr(SPRN_HID1) >> 28;
86 return CPCI690_BUS_FREQ * cpu_7xx[hid1]/2;
87}
88
89#define KB (1024UL)
90#define MB (1024UL * KB)
91#define GB (1024UL * MB)
92
93unsigned long __init
94cpci690_find_end_of_memory(void)
95{
96 u32 mem_ctlr_size;
97 static u32 board_size;
98 static u8 first_time = 1;
99
100 if (first_time) {
101 /* Using cpci690_set_bat() mapping ==> virt addr == phys addr */
102 switch (in_8((u8 *) (cpci690_br_base +
103 CPCI690_BR_MEM_CTLR)) & 0x07) {
104 case 0x01:
105 board_size = 256*MB;
106 break;
107 case 0x02:
108 board_size = 512*MB;
109 break;
110 case 0x03:
111 board_size = 768*MB;
112 break;
113 case 0x04:
114 board_size = 1*GB;
115 break;
116 case 0x05:
117 board_size = 1*GB + 512*MB;
118 break;
119 case 0x06:
120 board_size = 2*GB;
121 break;
122 default:
123 board_size = 0xffffffff; /* use mem ctlr size */
124 } /* switch */
125
126 mem_ctlr_size = mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
127 MV64x60_TYPE_GT64260A);
128
129 /* Check that mem ctlr & board reg agree. If not, pick MIN. */
130 if (board_size != mem_ctlr_size) {
131 printk(KERN_WARNING "Board register & memory controller"
132 "mem size disagree (board reg: 0x%lx, "
133 "mem ctlr: 0x%lx)\n",
134 (ulong)board_size, (ulong)mem_ctlr_size);
135 board_size = min(board_size, mem_ctlr_size);
136 }
137
138 first_time = 0;
139 } /* if */
140
141 return board_size;
142}
143
144static void __init
145cpci690_setup_bridge(void)
146{
147 struct mv64x60_setup_info si;
148 int i;
149
150 memset(&si, 0, sizeof(si));
151
152 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
153
154 si.pci_0.enable_bus = 1;
155 si.pci_0.pci_io.cpu_base = CPCI690_PCI0_IO_START_PROC_ADDR;
156 si.pci_0.pci_io.pci_base_hi = 0;
157 si.pci_0.pci_io.pci_base_lo = CPCI690_PCI0_IO_START_PCI_ADDR;
158 si.pci_0.pci_io.size = CPCI690_PCI0_IO_SIZE;
159 si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
160 si.pci_0.pci_mem[0].cpu_base = CPCI690_PCI0_MEM_START_PROC_ADDR;
161 si.pci_0.pci_mem[0].pci_base_hi = CPCI690_PCI0_MEM_START_PCI_HI_ADDR;
162 si.pci_0.pci_mem[0].pci_base_lo = CPCI690_PCI0_MEM_START_PCI_LO_ADDR;
163 si.pci_0.pci_mem[0].size = CPCI690_PCI0_MEM_SIZE;
164 si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
165 si.pci_0.pci_cmd_bits = 0;
166 si.pci_0.latency_timer = 0x80;
167
168 si.pci_1.enable_bus = 1;
169 si.pci_1.pci_io.cpu_base = CPCI690_PCI1_IO_START_PROC_ADDR;
170 si.pci_1.pci_io.pci_base_hi = 0;
171 si.pci_1.pci_io.pci_base_lo = CPCI690_PCI1_IO_START_PCI_ADDR;
172 si.pci_1.pci_io.size = CPCI690_PCI1_IO_SIZE;
173 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
174 si.pci_1.pci_mem[0].cpu_base = CPCI690_PCI1_MEM_START_PROC_ADDR;
175 si.pci_1.pci_mem[0].pci_base_hi = CPCI690_PCI1_MEM_START_PCI_HI_ADDR;
176 si.pci_1.pci_mem[0].pci_base_lo = CPCI690_PCI1_MEM_START_PCI_LO_ADDR;
177 si.pci_1.pci_mem[0].size = CPCI690_PCI1_MEM_SIZE;
178 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
179 si.pci_1.pci_cmd_bits = 0;
180 si.pci_1.latency_timer = 0x80;
181
182 for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
183 si.cpu_prot_options[i] = 0;
184 si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB;
185 si.pci_0.acc_cntl_options[i] =
186 GT64260_PCI_ACC_CNTL_DREADEN |
187 GT64260_PCI_ACC_CNTL_RDPREFETCH |
188 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
189 GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
190 GT64260_PCI_ACC_CNTL_SWAP_NONE |
191 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
192 si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB;
193 si.pci_1.acc_cntl_options[i] =
194 GT64260_PCI_ACC_CNTL_DREADEN |
195 GT64260_PCI_ACC_CNTL_RDPREFETCH |
196 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
197 GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
198 GT64260_PCI_ACC_CNTL_SWAP_NONE |
199 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
200 si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB;
201 }
202
203 /* Lookup PCI host bridges */
204 if (mv64x60_init(&bh, &si))
205 printk(KERN_ERR "Bridge initialization failed.\n");
206
207 pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
208 ppc_md.pci_swizzle = common_swizzle;
209 ppc_md.pci_map_irq = cpci690_map_irq;
210 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
211
212 mv64x60_set_bus(&bh, 0, 0);
213 bh.hose_a->first_busno = 0;
214 bh.hose_a->last_busno = 0xff;
215 bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
216
217 bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
218 mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
219 bh.hose_b->last_busno = 0xff;
220 bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
221 bh.hose_b->first_busno);
222}
223
224static void __init
225cpci690_setup_peripherals(void)
226{
227 /* Set up windows to CPLD, RTC/TODC, IPMI. */
228 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, CPCI690_BR_BASE,
229 CPCI690_BR_SIZE, 0);
230 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
231 cpci690_br_base = (u32)ioremap(CPCI690_BR_BASE, CPCI690_BR_SIZE);
232
233 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, CPCI690_TODC_BASE,
234 CPCI690_TODC_SIZE, 0);
235 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
236 TODC_INIT(TODC_TYPE_MK48T35, 0, 0,
237 ioremap(CPCI690_TODC_BASE, CPCI690_TODC_SIZE), 8);
238
239 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, CPCI690_IPMI_BASE,
240 CPCI690_IPMI_SIZE, 0);
241 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
242
243 mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31));
244 mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31));
245
246 mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */
247
248 /*
249 * Turn off timer/counters. Not turning off watchdog timer because
250 * can't read its reg on the 64260A so don't know if we'll be enabling
251 * or disabling.
252 */
253 mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
254 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
255 mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL,
256 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
257
258 /*
259 * Set MPSC Multiplex RMII
260 * NOTE: ethernet driver modifies bit 0 and 1
261 */
262 mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
263
264#define GPP_EXTERNAL_INTERRUPTS \
265 ((1<<24) | (1<<25) | (1<<26) | (1<<27) | \
266 (1<<28) | (1<<29) | (1<<30) | (1<<31))
267 /* PCI interrupts are inputs */
268 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS);
269 /* PCI interrupts are active low */
270 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS);
271
272 /* Clear any pending interrupts for these inputs and enable them. */
273 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS);
274 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS);
275
276 /* Route MPP interrupt inputs to GPP */
277 mv64x60_write(&bh, MV64x60_MPP_CNTL_2, 0x00000000);
278 mv64x60_write(&bh, MV64x60_MPP_CNTL_3, 0x00000000);
279}
280
281static void __init
282cpci690_setup_arch(void)
283{
284 if (ppc_md.progress)
285 ppc_md.progress("cpci690_setup_arch: enter", 0);
286#ifdef CONFIG_BLK_DEV_INITRD
287 if (initrd_start)
288 ROOT_DEV = Root_RAM0;
289 else
290#endif
291#ifdef CONFIG_ROOT_NFS
292 ROOT_DEV = Root_NFS;
293#else
294 ROOT_DEV = Root_SDA2;
295#endif
296
297 if (ppc_md.progress)
298 ppc_md.progress("cpci690_setup_arch: Enabling L2 cache", 0);
299
300 /* Enable L2 and L3 caches (if 745x) */
301 _set_L2CR(_get_L2CR() | L2CR_L2E);
302 _set_L3CR(_get_L3CR() | L3CR_L3E);
303
304 if (ppc_md.progress)
305 ppc_md.progress("cpci690_setup_arch: Initializing bridge", 0);
306
307 cpci690_setup_bridge(); /* set up PCI bridge(s) */
308 cpci690_setup_peripherals(); /* set up chip selects/GPP/MPP etc */
309
310 if (ppc_md.progress)
311 ppc_md.progress("cpci690_setup_arch: bridge init complete", 0);
312
313 printk(KERN_INFO "%s %s port (C) 2003 MontaVista Software, Inc. "
314 "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
315
316 if (ppc_md.progress)
317 ppc_md.progress("cpci690_setup_arch: exit", 0);
318}
319
320/* Platform device data fixup routines. */
321#if defined(CONFIG_SERIAL_MPSC)
322static void __init
323cpci690_fixup_mpsc_pdata(struct platform_device *pdev)
324{
325 struct mpsc_pdata *pdata;
326
327 pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
328
329 pdata->max_idle = 40;
330 pdata->default_baud = CPCI690_MPSC_BAUD;
331 pdata->brg_clk_src = CPCI690_MPSC_CLK_SRC;
332 pdata->brg_clk_freq = CPCI690_BUS_FREQ;
333}
334
335static int __init
336cpci690_platform_notify(struct device *dev)
337{
338 static struct {
339 char *bus_id;
340 void ((*rtn)(struct platform_device *pdev));
341 } dev_map[] = {
342 { MPSC_CTLR_NAME ".0", cpci690_fixup_mpsc_pdata },
343 { MPSC_CTLR_NAME ".1", cpci690_fixup_mpsc_pdata },
344 };
345 struct platform_device *pdev;
346 int i;
347
348 if (dev && dev->bus_id)
349 for (i=0; i<ARRAY_SIZE(dev_map); i++)
350 if (!strncmp(dev->bus_id, dev_map[i].bus_id,
351 BUS_ID_SIZE)) {
352
353 pdev = container_of(dev,
354 struct platform_device, dev);
355 dev_map[i].rtn(pdev);
356 }
357
358 return 0;
359}
360#endif
361
362static void
363cpci690_reset_board(void)
364{
365 u32 i = 10000;
366
367 local_irq_disable();
368 out_8((u8 *)(cpci690_br_base + CPCI690_BR_SW_RESET), 0x11);
369
370 while (i != 0) i++;
371 panic("restart failed\n");
372}
373
374static void
375cpci690_restart(char *cmd)
376{
377 cpci690_reset_board();
378}
379
380static void
381cpci690_halt(void)
382{
383 while (1);
384 /* NOTREACHED */
385}
386
387static void
388cpci690_power_off(void)
389{
390 cpci690_halt();
391 /* NOTREACHED */
392}
393
394static int
395cpci690_show_cpuinfo(struct seq_file *m)
396{
397 seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n");
398 seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n");
399 seq_printf(m, "cpu MHz\t\t: %d\n", cpci690_get_cpu_speed()/1000/1000);
400 seq_printf(m, "bus MHz\t\t: %d\n", CPCI690_BUS_FREQ/1000/1000);
401
402 return 0;
403}
404
405static void __init
406cpci690_calibrate_decr(void)
407{
408 ulong freq;
409
410 freq = CPCI690_BUS_FREQ / 4;
411
412 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
413 freq/1000000, freq%1000000);
414
415 tb_ticks_per_jiffy = freq / HZ;
416 tb_to_us = mulhwu_scale_factor(freq, 1000000);
417}
418
419static __inline__ void
420cpci690_set_bat(u32 addr, u32 size)
421{
422 addr &= 0xfffe0000;
423 size &= 0x1ffe0000;
424 size = ((size >> 17) - 1) << 2;
425
426 mb();
427 mtspr(SPRN_DBAT1U, addr | size | 0x2); /* Vs == 1; Vp == 0 */
428 mtspr(SPRN_DBAT1L, addr | 0x2a); /* WIMG bits == 0101; PP == r/w access */
429 mb();
430}
431
432#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
433static void __init
434cpci690_map_io(void)
435{
436 io_block_mapping(CONFIG_MV64X60_NEW_BASE, CONFIG_MV64X60_NEW_BASE,
437 128 * KB, _PAGE_IO);
438}
439#endif
440
441void __init
442platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
443 unsigned long r6, unsigned long r7)
444{
445#ifdef CONFIG_BLK_DEV_INITRD
446 initrd_start=initrd_end=0;
447 initrd_below_start_ok=0;
448#endif /* CONFIG_BLK_DEV_INITRD */
449
450 parse_bootinfo(find_bootinfo());
451
452 loops_per_jiffy = cpci690_get_cpu_speed() / HZ;
453
454 isa_mem_base = 0;
455
456 ppc_md.setup_arch = cpci690_setup_arch;
457 ppc_md.show_cpuinfo = cpci690_show_cpuinfo;
458 ppc_md.init_IRQ = gt64260_init_irq;
459 ppc_md.get_irq = gt64260_get_irq;
460 ppc_md.restart = cpci690_restart;
461 ppc_md.power_off = cpci690_power_off;
462 ppc_md.halt = cpci690_halt;
463 ppc_md.find_end_of_memory = cpci690_find_end_of_memory;
464 ppc_md.time_init = todc_time_init;
465 ppc_md.set_rtc_time = todc_set_rtc_time;
466 ppc_md.get_rtc_time = todc_get_rtc_time;
467 ppc_md.nvram_read_val = todc_direct_read_val;
468 ppc_md.nvram_write_val = todc_direct_write_val;
469 ppc_md.calibrate_decr = cpci690_calibrate_decr;
470
471 /*
472 * Need to map in board regs (used by cpci690_find_end_of_memory())
473 * and the bridge's regs (used by progress);
474 */
475 cpci690_set_bat(CPCI690_BR_BASE, 32 * MB);
476 cpci690_br_base = CPCI690_BR_BASE;
477
478#ifdef CONFIG_SERIAL_TEXT_DEBUG
479 ppc_md.setup_io_mappings = cpci690_map_io;
480 ppc_md.progress = mv64x60_mpsc_progress;
481 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
482#endif /* CONFIG_SERIAL_TEXT_DEBUG */
483#ifdef CONFIG_KGDB
484 ppc_md.setup_io_mappings = cpci690_map_io;
485 ppc_md.early_serial_map = cpci690_early_serial_map;
486#endif /* CONFIG_KGDB */
487
488#if defined(CONFIG_SERIAL_MPSC)
489 platform_notify = cpci690_platform_notify;
490#endif
491}
diff --git a/arch/ppc/platforms/cpci690.h b/arch/ppc/platforms/cpci690.h
new file mode 100644
index 000000000000..36cd2673c742
--- /dev/null
+++ b/arch/ppc/platforms/cpci690.h
@@ -0,0 +1,78 @@
1/*
2 * arch/ppc/platforms/cpci690.h
3 *
4 * Definitions for Force CPCI690
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2003 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14/*
15 * The GT64260 has 2 PCI buses each with 1 window from the CPU bus to
16 * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
17 */
18
19#ifndef __PPC_PLATFORMS_CPCI690_H
20#define __PPC_PLATFORMS_CPCI690_H
21
22/*
23 * Define bd_t to pass in the MAC addresses used by the GT64260's enet ctlrs.
24 */
25#define CPCI690_BI_MAGIC 0xFE8765DC
26
27typedef struct board_info {
28 u32 bi_magic;
29 u8 bi_enetaddr[3][6];
30} bd_t;
31
32/* PCI bus Resource setup */
33#define CPCI690_PCI0_MEM_START_PROC_ADDR 0x80000000
34#define CPCI690_PCI0_MEM_START_PCI_HI_ADDR 0x00000000
35#define CPCI690_PCI0_MEM_START_PCI_LO_ADDR 0x80000000
36#define CPCI690_PCI0_MEM_SIZE 0x10000000
37#define CPCI690_PCI0_IO_START_PROC_ADDR 0xa0000000
38#define CPCI690_PCI0_IO_START_PCI_ADDR 0x00000000
39#define CPCI690_PCI0_IO_SIZE 0x01000000
40
41#define CPCI690_PCI1_MEM_START_PROC_ADDR 0x90000000
42#define CPCI690_PCI1_MEM_START_PCI_HI_ADDR 0x00000000
43#define CPCI690_PCI1_MEM_START_PCI_LO_ADDR 0x90000000
44#define CPCI690_PCI1_MEM_SIZE 0x10000000
45#define CPCI690_PCI1_IO_START_PROC_ADDR 0xa1000000
46#define CPCI690_PCI1_IO_START_PCI_ADDR 0x01000000
47#define CPCI690_PCI1_IO_SIZE 0x01000000
48
49/* Board Registers */
50#define CPCI690_BR_BASE 0xf0000000
51#define CPCI690_BR_SIZE_ACTUAL 0x8
52#define CPCI690_BR_SIZE max(GT64260_WINDOW_SIZE_MIN, \
53 CPCI690_BR_SIZE_ACTUAL)
54#define CPCI690_BR_LED_CNTL 0x00
55#define CPCI690_BR_SW_RESET 0x01
56#define CPCI690_BR_MISC_STATUS 0x02
57#define CPCI690_BR_SWITCH_STATUS 0x03
58#define CPCI690_BR_MEM_CTLR 0x04
59#define CPCI690_BR_LAST_RESET_1 0x05
60#define CPCI690_BR_LAST_RESET_2 0x06
61
62#define CPCI690_TODC_BASE 0xf0100000
63#define CPCI690_TODC_SIZE_ACTUAL 0x8000 /* Size or NVRAM + RTC */
64#define CPCI690_TODC_SIZE max(GT64260_WINDOW_SIZE_MIN, \
65 CPCI690_TODC_SIZE_ACTUAL)
66#define CPCI690_MAC_OFFSET 0x7c10 /* MAC in RTC NVRAM */
67
68#define CPCI690_IPMI_BASE 0xf0200000
69#define CPCI690_IPMI_SIZE_ACTUAL 0x10 /* 16 bytes of IPMI */
70#define CPCI690_IPMI_SIZE max(GT64260_WINDOW_SIZE_MIN, \
71 CPCI690_IPMI_SIZE_ACTUAL)
72
73#define CPCI690_MPSC_BAUD 9600
74#define CPCI690_MPSC_CLK_SRC 8 /* TCLK */
75
76#define CPCI690_BUS_FREQ 133333333
77
78#endif /* __PPC_PLATFORMS_CPCI690_H */
diff --git a/arch/ppc/platforms/est8260.h b/arch/ppc/platforms/est8260.h
new file mode 100644
index 000000000000..adba68ecf57b
--- /dev/null
+++ b/arch/ppc/platforms/est8260.h
@@ -0,0 +1,35 @@
1/* Board information for the EST8260, which should be generic for
2 * all 8260 boards. The IMMR is now given to us so the hard define
3 * will soon be removed. All of the clock values are computed from
4 * the configuration SCMR and the Power-On-Reset word.
5 */
6#ifndef __EST8260_PLATFORM
7#define __EST8260_PLATFORM
8
9#define CPM_MAP_ADDR ((uint)0xf0000000)
10
11#define BOOTROM_RESTART_ADDR ((uint)0xff000104)
12
13/* For our show_cpuinfo hooks. */
14#define CPUINFO_VENDOR "EST Corporation"
15#define CPUINFO_MACHINE "SBC8260 PowerPC"
16
17/* A Board Information structure that is given to a program when
18 * prom starts it up.
19 */
20typedef struct bd_info {
21 unsigned int bi_memstart; /* Memory start address */
22 unsigned int bi_memsize; /* Memory (end) size in bytes */
23 unsigned int bi_intfreq; /* Internal Freq, in Hz */
24 unsigned int bi_busfreq; /* Bus Freq, in MHz */
25 unsigned int bi_cpmfreq; /* CPM Freq, in MHz */
26 unsigned int bi_brgfreq; /* BRG Freq, in MHz */
27 unsigned int bi_vco; /* VCO Out from PLL */
28 unsigned int bi_baudrate; /* Default console baud rate */
29 unsigned int bi_immr; /* IMMR when called from boot rom */
30 unsigned char bi_enetaddr[6];
31} bd_t;
32
33extern bd_t m8xx_board_info;
34
35#endif /* __EST8260_PLATFORM */
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
new file mode 100644
index 000000000000..aa50637a5cfb
--- /dev/null
+++ b/arch/ppc/platforms/ev64260.c
@@ -0,0 +1,651 @@
1/*
2 * arch/ppc/platforms/ev64260.c
3 *
4 * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board.
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14/*
15 * The EV-64260-BP port is the result of hard work from many people from
16 * many companies. In particular, employees of Marvell/Galileo, Mission
17 * Critical Linux, Xyterra, and MontaVista Software were heavily involved.
18 *
19 * Note: I have not been able to get *all* PCI slots to work reliably
20 * at 66 MHz. I recommend setting jumpers J15 & J16 to short pins 1&2
21 * so that 33 MHz is used. --MAG
22 * Note: The 750CXe and 7450 are not stable with a 125MHz or 133MHz TCLK/SYSCLK.
23 * At 100MHz, they are solid.
24 */
25#include <linux/config.h>
26
27#include <linux/delay.h>
28#include <linux/pci.h>
29#include <linux/ide.h>
30#include <linux/irq.h>
31#include <linux/fs.h>
32#include <linux/seq_file.h>
33#include <linux/console.h>
34#include <linux/initrd.h>
35#include <linux/root_dev.h>
36#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
37#include <linux/serial.h>
38#include <linux/tty.h>
39#include <linux/serial_core.h>
40#else
41#include <linux/mv643xx.h>
42#endif
43#include <asm/bootinfo.h>
44#include <asm/machdep.h>
45#include <asm/mv64x60.h>
46#include <asm/todc.h>
47#include <asm/time.h>
48
49#include <platforms/ev64260.h>
50
51#define BOARD_VENDOR "Marvell/Galileo"
52#define BOARD_MACHINE "EV-64260-BP"
53
54static struct mv64x60_handle bh;
55
56#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
57extern void gen550_progress(char *, unsigned short);
58extern void gen550_init(int, struct uart_port *);
59#endif
60
61static const unsigned int cpu_7xx[16] = { /* 7xx & 74xx (but not 745x) */
62 18, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
63};
64static const unsigned int cpu_745x[2][16] = { /* PLL_EXT 0 & 1 */
65 { 1, 15, 14, 2, 4, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 },
66 { 0, 30, 0, 2, 0, 26, 0, 18, 0, 22, 20, 24, 28, 32, 0, 0 }
67};
68
69
70TODC_ALLOC();
71
72static int
73ev64260_get_bus_speed(void)
74{
75 return 100000000;
76}
77
78static int
79ev64260_get_cpu_speed(void)
80{
81 unsigned long pvr, hid1, pll_ext;
82
83 pvr = PVR_VER(mfspr(SPRN_PVR));
84
85 if (pvr != PVR_VER(PVR_7450)) {
86 hid1 = mfspr(SPRN_HID1) >> 28;
87 return ev64260_get_bus_speed() * cpu_7xx[hid1]/2;
88 }
89 else {
90 hid1 = (mfspr(SPRN_HID1) & 0x0001e000) >> 13;
91 pll_ext = 0; /* No way to read; must get from schematic */
92 return ev64260_get_bus_speed() * cpu_745x[pll_ext][hid1]/2;
93 }
94}
95
96unsigned long __init
97ev64260_find_end_of_memory(void)
98{
99 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
100 MV64x60_TYPE_GT64260A);
101}
102
103/*
104 * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing.
105 * Note: By playing with J8 and JP1-4, you can get 2 IRQ's from the first
106 * PCI bus (in which cast, INTPIN B would be EV64260_PCI_1_IRQ).
107 * This is the most IRQs you can get from one bus with this board, though.
108 */
109static int __init
110ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
111{
112 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
113
114 if (hose->index == 0) {
115 static char pci_irq_table[][4] =
116 /*
117 * PCI IDSEL/INTPIN->INTLINE
118 * A B C D
119 */
120 {
121 {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 0 */
122 {EV64260_PCI_0_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 0 */
123 };
124
125 const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
126 return PCI_IRQ_TABLE_LOOKUP;
127 }
128 else {
129 static char pci_irq_table[][4] =
130 /*
131 * PCI IDSEL/INTPIN->INTLINE
132 * A B C D
133 */
134 {
135 { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 7 - PCI bus 1 */
136 { EV64260_PCI_1_IRQ,0,0,0}, /* IDSEL 8 - PCI bus 1 */
137 };
138
139 const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4;
140 return PCI_IRQ_TABLE_LOOKUP;
141 }
142}
143
144static void __init
145ev64260_setup_peripherals(void)
146{
147 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
148 EV64260_EMB_FLASH_BASE, EV64260_EMB_FLASH_SIZE, 0);
149 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
150 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
151 EV64260_EXT_SRAM_BASE, EV64260_EXT_SRAM_SIZE, 0);
152 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
153 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
154 EV64260_TODC_BASE, EV64260_TODC_SIZE, 0);
155 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
156 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
157 EV64260_UART_BASE, EV64260_UART_SIZE, 0);
158 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
159 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
160 EV64260_EXT_FLASH_BASE, EV64260_EXT_FLASH_SIZE, 0);
161 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
162
163 TODC_INIT(TODC_TYPE_DS1501, 0, 0,
164 ioremap(EV64260_TODC_BASE, EV64260_TODC_SIZE), 8);
165
166 mv64x60_clr_bits(&bh, MV64x60_CPU_CONFIG,((1<<12) | (1<<28) | (1<<29)));
167 mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<27));
168
169 if (ev64260_get_bus_speed() > 100000000)
170 mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1<<23));
171
172 mv64x60_set_bits(&bh, MV64x60_PCI0_PCI_DECODE_CNTL, ((1<<0) | (1<<3)));
173 mv64x60_set_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, ((1<<0) | (1<<3)));
174
175 /*
176 * Enabling of PCI internal-vs-external arbitration
177 * is a platform- and errata-dependent decision.
178 */
179 if (bh.type == MV64x60_TYPE_GT64260A ) {
180 mv64x60_set_bits(&bh, MV64x60_PCI0_ARBITER_CNTL, (1<<31));
181 mv64x60_set_bits(&bh, MV64x60_PCI1_ARBITER_CNTL, (1<<31));
182 }
183
184 mv64x60_set_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */
185
186 /*
187 * Turn off timer/counters. Not turning off watchdog timer because
188 * can't read its reg on the 64260A so don't know if we'll be enabling
189 * or disabling.
190 */
191 mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
192 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
193 mv64x60_clr_bits(&bh, GT64260_TIMR_CNTR_4_7_CNTL,
194 ((1<<0) | (1<<8) | (1<<16) | (1<<24)));
195
196 /*
197 * Set MPSC Multiplex RMII
198 * NOTE: ethernet driver modifies bit 0 and 1
199 */
200 mv64x60_write(&bh, GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
201
202 /*
203 * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260
204 * bridge as interrupt inputs (via the General Purpose Ports (GPP)
205 * register). Need to route the MPP inputs to the GPP and set the
206 * polarity correctly.
207 *
208 * In MPP Control 2 Register
209 * MPP 21 -> GPP 21 (DUART channel A intr) bits 20-23 -> 0
210 * MPP 22 -> GPP 22 (DUART channel B intr) bits 24-27 -> 0
211 */
212 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_2, (0xf<<20) | (0xf<<24) );
213
214 /*
215 * In MPP Control 3 Register
216 * MPP 26 -> GPP 26 (RTC INT) bits 8-11 -> 0
217 * MPP 27 -> GPP 27 (PCI 0 INTA) bits 12-15 -> 0
218 * MPP 29 -> GPP 29 (PCI 1 INTA) bits 20-23 -> 0
219 */
220 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_3, (0xf<<8)|(0xf<<12)|(0xf<<20));
221
222#define GPP_EXTERNAL_INTERRUPTS \
223 ((1<<21) | (1<<22) | (1<<26) | (1<<27) | (1<<29))
224 /* DUART & PCI interrupts are inputs */
225 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, GPP_EXTERNAL_INTERRUPTS);
226 /* DUART & PCI interrupts are active low */
227 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, GPP_EXTERNAL_INTERRUPTS);
228
229 /* Clear any pending interrupts for these inputs and enable them. */
230 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~GPP_EXTERNAL_INTERRUPTS);
231 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, GPP_EXTERNAL_INTERRUPTS);
232
233 return;
234}
235
236static void __init
237ev64260_setup_bridge(void)
238{
239 struct mv64x60_setup_info si;
240 int i;
241
242 memset(&si, 0, sizeof(si));
243
244 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
245
246 si.pci_0.enable_bus = 1;
247 si.pci_0.pci_io.cpu_base = EV64260_PCI0_IO_CPU_BASE;
248 si.pci_0.pci_io.pci_base_hi = 0;
249 si.pci_0.pci_io.pci_base_lo = EV64260_PCI0_IO_PCI_BASE;
250 si.pci_0.pci_io.size = EV64260_PCI0_IO_SIZE;
251 si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
252 si.pci_0.pci_mem[0].cpu_base = EV64260_PCI0_MEM_CPU_BASE;
253 si.pci_0.pci_mem[0].pci_base_hi = 0;
254 si.pci_0.pci_mem[0].pci_base_lo = EV64260_PCI0_MEM_PCI_BASE;
255 si.pci_0.pci_mem[0].size = EV64260_PCI0_MEM_SIZE;
256 si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
257 si.pci_0.pci_cmd_bits = 0;
258 si.pci_0.latency_timer = 0x8;
259
260 si.pci_1.enable_bus = 1;
261 si.pci_1.pci_io.cpu_base = EV64260_PCI1_IO_CPU_BASE;
262 si.pci_1.pci_io.pci_base_hi = 0;
263 si.pci_1.pci_io.pci_base_lo = EV64260_PCI1_IO_PCI_BASE;
264 si.pci_1.pci_io.size = EV64260_PCI1_IO_SIZE;
265 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
266 si.pci_1.pci_mem[0].cpu_base = EV64260_PCI1_MEM_CPU_BASE;
267 si.pci_1.pci_mem[0].pci_base_hi = 0;
268 si.pci_1.pci_mem[0].pci_base_lo = EV64260_PCI1_MEM_PCI_BASE;
269 si.pci_1.pci_mem[0].size = EV64260_PCI1_MEM_SIZE;
270 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
271 si.pci_1.pci_cmd_bits = 0;
272 si.pci_1.latency_timer = 0x8;
273
274 for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
275 si.cpu_prot_options[i] = 0;
276 si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB;
277 si.pci_0.acc_cntl_options[i] =
278 GT64260_PCI_ACC_CNTL_DREADEN |
279 GT64260_PCI_ACC_CNTL_RDPREFETCH |
280 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
281 GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
282 GT64260_PCI_ACC_CNTL_SWAP_NONE |
283 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
284 si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB;
285 si.pci_1.acc_cntl_options[i] =
286 GT64260_PCI_ACC_CNTL_DREADEN |
287 GT64260_PCI_ACC_CNTL_RDPREFETCH |
288 GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
289 GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
290 GT64260_PCI_ACC_CNTL_SWAP_NONE |
291 GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
292 si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB;
293 }
294
295 /* Lookup PCI host bridges */
296 if (mv64x60_init(&bh, &si))
297 printk(KERN_ERR "Bridge initialization failed.\n");
298
299 pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
300 ppc_md.pci_swizzle = common_swizzle;
301 ppc_md.pci_map_irq = ev64260_map_irq;
302 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
303
304 mv64x60_set_bus(&bh, 0, 0);
305 bh.hose_a->first_busno = 0;
306 bh.hose_a->last_busno = 0xff;
307 bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
308
309 bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
310 mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
311 bh.hose_b->last_busno = 0xff;
312 bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
313 bh.hose_b->first_busno);
314
315 return;
316}
317
318#if defined(CONFIG_SERIAL_8250) && !defined(CONFIG_SERIAL_MPSC_CONSOLE)
319static void __init
320ev64260_early_serial_map(void)
321{
322 struct uart_port port;
323 static char first_time = 1;
324
325 if (first_time) {
326 memset(&port, 0, sizeof(port));
327
328 port.membase = ioremap(EV64260_SERIAL_0, EV64260_UART_SIZE);
329 port.irq = EV64260_UART_0_IRQ;
330 port.uartclk = BASE_BAUD * 16;
331 port.regshift = 2;
332 port.iotype = SERIAL_IO_MEM;
333 port.flags = STD_COM_FLAGS;
334
335#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
336 gen550_init(0, &port);
337#endif
338
339 if (early_serial_setup(&port) != 0)
340 printk(KERN_WARNING "Early serial init of port 0"
341 "failed\n");
342
343 first_time = 0;
344 }
345
346 return;
347}
348#elif defined(CONFIG_SERIAL_MPSC_CONSOLE)
349static void __init
350ev64260_early_serial_map(void)
351{
352}
353#endif
354
355static void __init
356ev64260_setup_arch(void)
357{
358 if (ppc_md.progress)
359 ppc_md.progress("ev64260_setup_arch: enter", 0);
360
361#ifdef CONFIG_BLK_DEV_INITRD
362 if (initrd_start)
363 ROOT_DEV = Root_RAM0;
364 else
365#endif
366#ifdef CONFIG_ROOT_NFS
367 ROOT_DEV = Root_NFS;
368#else
369 ROOT_DEV = Root_SDA2;
370#endif
371
372 if (ppc_md.progress)
373 ppc_md.progress("ev64260_setup_arch: Enabling L2 cache", 0);
374
375 /* Enable L2 and L3 caches (if 745x) */
376 _set_L2CR(_get_L2CR() | L2CR_L2E);
377 _set_L3CR(_get_L3CR() | L3CR_L3E);
378
379 if (ppc_md.progress)
380 ppc_md.progress("ev64260_setup_arch: Initializing bridge", 0);
381
382 ev64260_setup_bridge(); /* set up PCI bridge(s) */
383 ev64260_setup_peripherals(); /* set up chip selects/GPP/MPP etc */
384
385 if (ppc_md.progress)
386 ppc_md.progress("ev64260_setup_arch: bridge init complete", 0);
387
388#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_MPSC_CONSOLE)
389 ev64260_early_serial_map();
390#endif
391
392 printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc."
393 "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
394
395 if (ppc_md.progress)
396 ppc_md.progress("ev64260_setup_arch: exit", 0);
397
398 return;
399}
400
401/* Platform device data fixup routines. */
402#if defined(CONFIG_SERIAL_MPSC)
403static void __init
404ev64260_fixup_mpsc_pdata(struct platform_device *pdev)
405{
406 struct mpsc_pdata *pdata;
407
408 pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
409
410 pdata->max_idle = 40;
411 pdata->default_baud = EV64260_DEFAULT_BAUD;
412 pdata->brg_clk_src = EV64260_MPSC_CLK_SRC;
413 pdata->brg_clk_freq = EV64260_MPSC_CLK_FREQ;
414
415 return;
416}
417
418static int __init
419ev64260_platform_notify(struct device *dev)
420{
421 static struct {
422 char *bus_id;
423 void ((*rtn)(struct platform_device *pdev));
424 } dev_map[] = {
425 { MPSC_CTLR_NAME ".0", ev64260_fixup_mpsc_pdata },
426 { MPSC_CTLR_NAME ".1", ev64260_fixup_mpsc_pdata },
427 };
428 struct platform_device *pdev;
429 int i;
430
431 if (dev && dev->bus_id)
432 for (i=0; i<ARRAY_SIZE(dev_map); i++)
433 if (!strncmp(dev->bus_id, dev_map[i].bus_id,
434 BUS_ID_SIZE)) {
435
436 pdev = container_of(dev,
437 struct platform_device, dev);
438 dev_map[i].rtn(pdev);
439 }
440
441 return 0;
442}
443#endif
444
445static void
446ev64260_reset_board(void *addr)
447{
448 local_irq_disable();
449
450 /* disable and invalidate the L2 cache */
451 _set_L2CR(0);
452 _set_L2CR(0x200000);
453
454 /* flush and disable L1 I/D cache */
455 __asm__ __volatile__
456 ("mfspr 3,1008\n\t"
457 "ori 5,5,0xcc00\n\t"
458 "ori 4,3,0xc00\n\t"
459 "andc 5,3,5\n\t"
460 "sync\n\t"
461 "mtspr 1008,4\n\t"
462 "isync\n\t"
463 "sync\n\t"
464 "mtspr 1008,5\n\t"
465 "isync\n\t"
466 "sync\n\t");
467
468 /* unmap any other random cs's that might overlap with bootcs */
469 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, 0, 0, 0);
470 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
471 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, 0, 0, 0);
472 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
473 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN, 0, 0, 0);
474 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
475 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN, 0, 0, 0);
476 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
477
478 /* map bootrom back in to gt @ reset defaults */
479 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
480 0xff800000, 8*1024*1024, 0);
481 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
482
483 /* move reg base back to default, setup default pci0 */
484 mv64x60_write(&bh, MV64x60_INTERNAL_SPACE_DECODE,
485 (1<<24) | CONFIG_MV64X60_BASE >> 20);
486
487 /* NOTE: FROM NOW ON no more GT_REGS accesses.. 0x1 is not mapped
488 * via BAT or MMU, and MSR IR/DR is ON */
489 /* SRR0 has system reset vector, SRR1 has default MSR value */
490 /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
491 /* NOTE: assumes reset vector is at 0xfff00100 */
492 __asm__ __volatile__
493 ("mtspr 26, %0\n\t"
494 "li 4,(1<<6)\n\t"
495 "mtspr 27,4\n\t"
496 "rfi\n\t"
497 :: "r" (addr):"r4");
498
499 return;
500}
501
502static void
503ev64260_restart(char *cmd)
504{
505 volatile ulong i = 10000000;
506
507 ev64260_reset_board((void *)0xfff00100);
508
509 while (i-- > 0);
510 panic("restart failed\n");
511}
512
513static void
514ev64260_halt(void)
515{
516 local_irq_disable();
517 while (1);
518 /* NOTREACHED */
519}
520
521static void
522ev64260_power_off(void)
523{
524 ev64260_halt();
525 /* NOTREACHED */
526}
527
528static int
529ev64260_show_cpuinfo(struct seq_file *m)
530{
531 uint pvid;
532
533 pvid = mfspr(SPRN_PVR);
534 seq_printf(m, "vendor\t\t: " BOARD_VENDOR "\n");
535 seq_printf(m, "machine\t\t: " BOARD_MACHINE "\n");
536 seq_printf(m, "cpu MHz\t\t: %d\n", ev64260_get_cpu_speed()/1000/1000);
537 seq_printf(m, "bus MHz\t\t: %d\n", ev64260_get_bus_speed()/1000/1000);
538
539 return 0;
540}
541
542/* DS1501 RTC has too much variation to use RTC for calibration */
543static void __init
544ev64260_calibrate_decr(void)
545{
546 ulong freq;
547
548 freq = ev64260_get_bus_speed()/4;
549
550 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
551 freq/1000000, freq%1000000);
552
553 tb_ticks_per_jiffy = freq / HZ;
554 tb_to_us = mulhwu_scale_factor(freq, 1000000);
555
556 return;
557}
558
559/*
560 * Set BAT 3 to map 0xfb000000 to 0xfc000000 of physical memory space.
561 */
562static __inline__ void
563ev64260_set_bat(void)
564{
565 mb();
566 mtspr(SPRN_DBAT1U, 0xfb0001fe);
567 mtspr(SPRN_DBAT1L, 0xfb00002a);
568 mb();
569
570 return;
571}
572
573#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
574static void __init
575ev64260_map_io(void)
576{
577 io_block_mapping(0xfb000000, 0xfb000000, 0x01000000, _PAGE_IO);
578}
579#endif
580
581void __init
582platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
583 unsigned long r6, unsigned long r7)
584{
585#ifdef CONFIG_BLK_DEV_INITRD
586 extern int initrd_below_start_ok;
587
588 initrd_start=initrd_end=0;
589 initrd_below_start_ok=0;
590#endif /* CONFIG_BLK_DEV_INITRD */
591
592 parse_bootinfo(find_bootinfo());
593
594 isa_mem_base = 0;
595 isa_io_base = EV64260_PCI0_IO_CPU_BASE;
596 pci_dram_offset = EV64260_PCI0_MEM_CPU_BASE;
597
598 loops_per_jiffy = ev64260_get_cpu_speed() / HZ;
599
600 ppc_md.setup_arch = ev64260_setup_arch;
601 ppc_md.show_cpuinfo = ev64260_show_cpuinfo;
602 ppc_md.init_IRQ = gt64260_init_irq;
603 ppc_md.get_irq = gt64260_get_irq;
604
605 ppc_md.restart = ev64260_restart;
606 ppc_md.power_off = ev64260_power_off;
607 ppc_md.halt = ev64260_halt;
608
609 ppc_md.find_end_of_memory = ev64260_find_end_of_memory;
610
611 ppc_md.init = NULL;
612
613 ppc_md.time_init = todc_time_init;
614 ppc_md.set_rtc_time = todc_set_rtc_time;
615 ppc_md.get_rtc_time = todc_get_rtc_time;
616 ppc_md.nvram_read_val = todc_direct_read_val;
617 ppc_md.nvram_write_val = todc_direct_write_val;
618 ppc_md.calibrate_decr = ev64260_calibrate_decr;
619
620 bh.p_base = CONFIG_MV64X60_NEW_BASE;
621
622 ev64260_set_bat();
623
624#ifdef CONFIG_SERIAL_8250
625#if defined(CONFIG_SERIAL_TEXT_DEBUG)
626 ppc_md.setup_io_mappings = ev64260_map_io;
627 ppc_md.progress = gen550_progress;
628#endif
629#if defined(CONFIG_KGDB)
630 ppc_md.setup_io_mappings = ev64260_map_io;
631 ppc_md.early_serial_map = ev64260_early_serial_map;
632#endif
633#elif defined(CONFIG_SERIAL_MPSC_CONSOLE)
634#ifdef CONFIG_SERIAL_TEXT_DEBUG
635 ppc_md.setup_io_mappings = ev64260_map_io;
636 ppc_md.progress = mv64x60_mpsc_progress;
637 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
638#endif /* CONFIG_SERIAL_TEXT_DEBUG */
639#ifdef CONFIG_KGDB
640 ppc_md.setup_io_mappings = ev64260_map_io;
641 ppc_md.early_serial_map = ev64260_early_serial_map;
642#endif /* CONFIG_KGDB */
643
644#endif
645
646#if defined(CONFIG_SERIAL_MPSC)
647 platform_notify = ev64260_platform_notify;
648#endif
649
650 return;
651}
diff --git a/arch/ppc/platforms/ev64260.h b/arch/ppc/platforms/ev64260.h
new file mode 100644
index 000000000000..bedffced3a02
--- /dev/null
+++ b/arch/ppc/platforms/ev64260.h
@@ -0,0 +1,128 @@
1/*
2 * arch/ppc/platforms/ev64260.h
3 *
4 * Definitions for Marvell/Galileo EV-64260-BP Evaluation Board.
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14/*
15 * The MV64x60 has 2 PCI buses each with 1 window from the CPU bus to
16 * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
17 * We'll only use one PCI MEM window on each PCI bus.
18 *
19 * This is the CPU physical memory map (windows must be at least 1MB and start
20 * on a boundary that is a multiple of the window size):
21 *
22 * 0xfc000000-0xffffffff - External FLASH on device module
23 * 0xfbf00000-0xfbffffff - Embedded (on board) FLASH
24 * 0xfbe00000-0xfbefffff - GT64260 Registers (preferably)
25 * but really a config option
26 * 0xfbd00000-0xfbdfffff - External SRAM on device module
27 * 0xfbc00000-0xfbcfffff - TODC chip on device module
28 * 0xfbb00000-0xfbbfffff - External UART on device module
29 * 0xa2000000-0xfbafffff - <hole>
30 * 0xa1000000-0xa1ffffff - PCI 1 I/O (defined in gt64260.h)
31 * 0xa0000000-0xa0ffffff - PCI 0 I/O (defined in gt64260.h)
32 * 0x90000000-0x9fffffff - PCI 1 MEM (defined in gt64260.h)
33 * 0x80000000-0x8fffffff - PCI 0 MEM (defined in gt64260.h)
34 */
35
36#ifndef __PPC_PLATFORMS_EV64260_H
37#define __PPC_PLATFORMS_EV64260_H
38
39/* PCI mappings */
40#define EV64260_PCI0_IO_CPU_BASE 0xa0000000
41#define EV64260_PCI0_IO_PCI_BASE 0x00000000
42#define EV64260_PCI0_IO_SIZE 0x01000000
43
44#define EV64260_PCI0_MEM_CPU_BASE 0x80000000
45#define EV64260_PCI0_MEM_PCI_BASE 0x80000000
46#define EV64260_PCI0_MEM_SIZE 0x10000000
47
48#define EV64260_PCI1_IO_CPU_BASE (EV64260_PCI0_IO_CPU_BASE + \
49 EV64260_PCI0_IO_SIZE)
50#define EV64260_PCI1_IO_PCI_BASE (EV64260_PCI0_IO_PCI_BASE + \
51 EV64260_PCI0_IO_SIZE)
52#define EV64260_PCI1_IO_SIZE 0x01000000
53
54#define EV64260_PCI1_MEM_CPU_BASE (EV64260_PCI0_MEM_CPU_BASE + \
55 EV64260_PCI0_MEM_SIZE)
56#define EV64260_PCI1_MEM_PCI_BASE (EV64260_PCI0_MEM_PCI_BASE + \
57 EV64260_PCI0_MEM_SIZE)
58#define EV64260_PCI1_MEM_SIZE 0x10000000
59
60/* CPU Physical Memory Map setup (other than PCI) */
61#define EV64260_EXT_FLASH_BASE 0xfc000000
62#define EV64260_EMB_FLASH_BASE 0xfbf00000
63#define EV64260_EXT_SRAM_BASE 0xfbd00000
64#define EV64260_TODC_BASE 0xfbc00000
65#define EV64260_UART_BASE 0xfbb00000
66
67#define EV64260_EXT_FLASH_SIZE_ACTUAL 0x04000000 /* <= 64MB Extern FLASH */
68#define EV64260_EMB_FLASH_SIZE_ACTUAL 0x00080000 /* 512KB of Embed FLASH */
69#define EV64260_EXT_SRAM_SIZE_ACTUAL 0x00100000 /* 1MB SDRAM */
70#define EV64260_TODC_SIZE_ACTUAL 0x00000020 /* 32 bytes for TODC */
71#define EV64260_UART_SIZE_ACTUAL 0x00000040 /* 64 bytes for DUART */
72
73#define EV64260_EXT_FLASH_SIZE max(GT64260_WINDOW_SIZE_MIN, \
74 EV64260_EXT_FLASH_SIZE_ACTUAL)
75#define EV64260_EMB_FLASH_SIZE max(GT64260_WINDOW_SIZE_MIN, \
76 EV64260_EMB_FLASH_SIZE_ACTUAL)
77#define EV64260_EXT_SRAM_SIZE max(GT64260_WINDOW_SIZE_MIN, \
78 EV64260_EXT_SRAM_SIZE_ACTUAL)
79#define EV64260_TODC_SIZE max(GT64260_WINDOW_SIZE_MIN, \
80 EV64260_TODC_SIZE_ACTUAL)
81/* Assembler in bootwrapper blows up if 'max' is used */
82#define EV64260_UART_SIZE GT64260_WINDOW_SIZE_MIN
83#define EV64260_UART_END ((EV64260_UART_BASE + \
84 EV64260_UART_SIZE - 1) & 0xfff00000)
85
86/* Board-specific IRQ info */
87#define EV64260_UART_0_IRQ 85
88#define EV64260_UART_1_IRQ 86
89#define EV64260_PCI_0_IRQ 91
90#define EV64260_PCI_1_IRQ 93
91
92/* Serial port setup */
93#define EV64260_DEFAULT_BAUD 115200
94
95#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
96#define SERIAL_PORT_DFNS
97
98#define EV64260_MPSC_CLK_SRC 8 /* TCLK */
99#define EV64260_MPSC_CLK_FREQ 100000000 /* 100MHz clk */
100#else
101#define EV64260_SERIAL_0 (EV64260_UART_BASE + 0x20)
102#define EV64260_SERIAL_1 EV64260_UART_BASE
103
104#define BASE_BAUD (EV64260_DEFAULT_BAUD * 2)
105
106#ifdef CONFIG_SERIAL_MANY_PORTS
107#define RS_TABLE_SIZE 64
108#else
109#define RS_TABLE_SIZE 2
110#endif
111
112#ifdef CONFIG_SERIAL_DETECT_IRQ
113#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
114#else
115#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
116#endif
117
118/* Required for bootloader's ns16550.c code */
119#define STD_SERIAL_PORT_DFNS \
120 { 0, BASE_BAUD, EV64260_SERIAL_0, EV64260_UART_0_IRQ, STD_COM_FLAGS, \
121 iomem_base: (u8 *)EV64260_SERIAL_0, /* ttyS0 */ \
122 iomem_reg_shift: 2, \
123 io_type: SERIAL_IO_MEM },
124
125#define SERIAL_PORT_DFNS \
126 STD_SERIAL_PORT_DFNS
127#endif
128#endif /* __PPC_PLATFORMS_EV64260_H */
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
new file mode 100644
index 000000000000..632b8178ce66
--- /dev/null
+++ b/arch/ppc/platforms/fads.h
@@ -0,0 +1,57 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Motorola 860T FADS board. Copied from the MBX stuff.
4 *
5 * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
6 */
7#ifdef __KERNEL__
8#ifndef __ASM_FADS_H__
9#define __ASM_FADS_H__
10
11#include <linux/config.h>
12
13#include <asm/ppcboot.h>
14
15/* Memory map is configured by the PROM startup.
16 * I tried to follow the FADS manual, although the startup PROM
17 * dictates this and we simply have to move some of the physical
18 * addresses for Linux.
19 */
20#define BCSR_ADDR ((uint)0xff010000)
21#define BCSR_SIZE ((uint)(64 * 1024))
22#define BCSR0 ((uint)0xff010000)
23#define BCSR1 ((uint)0xff010004)
24#define BCSR2 ((uint)0xff010008)
25#define BCSR3 ((uint)0xff01000c)
26#define BCSR4 ((uint)0xff010010)
27
28#define IMAP_ADDR ((uint)0xff000000)
29#define IMAP_SIZE ((uint)(64 * 1024))
30
31#define PCMCIA_MEM_ADDR ((uint)0xff020000)
32#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
33
34/* Bits of interest in the BCSRs.
35 */
36#define BCSR1_ETHEN ((uint)0x20000000)
37#define BCSR1_RS232EN_1 ((uint)0x01000000)
38#define BCSR1_RS232EN_2 ((uint)0x00040000)
39#define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */
40#define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */
41#define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */
42#define BCSR4_FETHCFG0 ((uint)0x04000000) /* PHY autoneg mode */
43#define BCSR4_FETHCFG1 ((uint)0x00400000) /* PHY autoneg mode */
44#define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */
45#define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */
46
47/* Interrupt level assignments.
48 */
49#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */
50#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */
51
52/* We don't use the 8259.
53 */
54#define NR_8259_INTS 0
55
56#endif /* __ASM_FADS_H__ */
57#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/gemini.h b/arch/ppc/platforms/gemini.h
new file mode 100644
index 000000000000..06de59248918
--- /dev/null
+++ b/arch/ppc/platforms/gemini.h
@@ -0,0 +1,168 @@
1/*
2 * arch/ppc/platforms/gemini.h
3 *
4 *
5 * Onboard registers and descriptions for Synergy Microsystems'
6 * "Gemini" boards.
7 *
8 */
9#ifdef __KERNEL__
10#ifndef __PPC_GEMINI_H
11#define __PPC_GEMINI_H
12
13/* Registers */
14
15#define GEMINI_SERIAL_B (0xffeffb00)
16#define GEMINI_SERIAL_A (0xffeffb08)
17#define GEMINI_USWITCH (0xffeffd00)
18#define GEMINI_BREV (0xffeffe00)
19#define GEMINI_BECO (0xffeffe08)
20#define GEMINI_FEAT (0xffeffe10)
21#define GEMINI_BSTAT (0xffeffe18)
22#define GEMINI_CPUSTAT (0xffeffe20)
23#define GEMINI_L2CFG (0xffeffe30)
24#define GEMINI_MEMCFG (0xffeffe38)
25#define GEMINI_FLROM (0xffeffe40)
26#define GEMINI_P0PCI (0xffeffe48)
27#define GEMINI_FLWIN (0xffeffe50)
28#define GEMINI_P0INTMASK (0xffeffe60)
29#define GEMINI_P0INTAP (0xffeffe68)
30#define GEMINI_PCIERR (0xffeffe70)
31#define GEMINI_LEDBASE (0xffeffe80)
32#define GEMINI_RTC (0xffe9fff8)
33#define GEMINI_LEDS 8
34#define GEMINI_SWITCHES 8
35
36
37/* Flash ROM bit definitions */
38#define GEMINI_FLS_WEN (1<<0)
39#define GEMINI_FLS_JMP (1<<6)
40#define GEMINI_FLS_BOOT (1<<7)
41
42/* Memory bit definitions */
43#define GEMINI_MEM_TYPE_MASK 0xc0
44#define GEMINI_MEM_SIZE_MASK 0x38
45#define GEMINI_MEM_BANK_MASK 0x07
46
47/* L2 cache bit definitions */
48#define GEMINI_L2_SIZE_MASK 0xc0
49#define GEMINI_L2_RATIO_MASK 0x03
50
51/* Timebase register bit definitons */
52#define GEMINI_TIMEB0_EN (1<<0)
53#define GEMINI_TIMEB1_EN (1<<1)
54#define GEMINI_TIMEB2_EN (1<<2)
55#define GEMINI_TIMEB3_EN (1<<3)
56
57/* CPU status bit definitions */
58#define GEMINI_CPU_ID_MASK 0x03
59#define GEMINI_CPU_COUNT_MASK 0x0c
60#define GEMINI_CPU0_HALTED (1<<4)
61#define GEMINI_CPU1_HALTED (1<<5)
62#define GEMINI_CPU2_HALTED (1<<6)
63#define GEMINI_CPU3_HALTED (1<<7)
64
65/* Board status bit definitions */
66#define GEMINI_BRD_FAIL (1<<0) /* FAIL led is lit */
67#define GEMINI_BRD_BUS_MASK 0x0c /* PowerPC bus speed */
68
69/* Board family/feature bit descriptions */
70#define GEMINI_FEAT_HAS_FLASH (1<<0)
71#define GEMINI_FEAT_HAS_ETH (1<<1)
72#define GEMINI_FEAT_HAS_SCSI (1<<2)
73#define GEMINI_FEAT_HAS_P0 (1<<3)
74#define GEMINI_FEAT_FAM_MASK 0xf0
75
76/* Mod/ECO bit definitions */
77#define GEMINI_ECO_LEVEL_MASK 0x0f
78#define GEMINI_MOD_MASK 0xf0
79
80/* Type/revision bit definitions */
81#define GEMINI_REV_MASK 0x0f
82#define GEMINI_TYPE_MASK 0xf0
83
84/* User switch definitions */
85#define GEMINI_SWITCH_VERBOSE 1 /* adds "debug" to boot cmd line */
86#define GEMINI_SWITCH_SINGLE_USER 7 /* boots into "single-user" mode */
87
88#define SGS_RTC_CONTROL 0
89#define SGS_RTC_SECONDS 1
90#define SGS_RTC_MINUTES 2
91#define SGS_RTC_HOURS 3
92#define SGS_RTC_DAY 4
93#define SGS_RTC_DAY_OF_MONTH 5
94#define SGS_RTC_MONTH 6
95#define SGS_RTC_YEAR 7
96
97#define SGS_RTC_SET 0x80
98#define SGS_RTC_IS_STOPPED 0x80
99
100#define GRACKLE_CONFIG_ADDR_ADDR (0xfec00000)
101#define GRACKLE_CONFIG_DATA_ADDR (0xfee00000)
102
103#define GEMINI_BOOT_INIT (0xfff00100)
104
105#ifndef __ASSEMBLY__
106
107static inline void grackle_write( unsigned long addr, unsigned long data )
108{
109 __asm__ __volatile__(
110 " stwbrx %1, 0, %0\n \
111 sync\n \
112 stwbrx %3, 0, %2\n \
113 sync "
114 : /* no output */
115 : "r" (GRACKLE_CONFIG_ADDR_ADDR), "r" (addr),
116 "r" (GRACKLE_CONFIG_DATA_ADDR), "r" (data));
117}
118
119static inline unsigned long grackle_read( unsigned long addr )
120{
121 unsigned long val;
122
123 __asm__ __volatile__(
124 " stwbrx %1, 0, %2\n \
125 sync\n \
126 lwbrx %0, 0, %3\n \
127 sync "
128 : "=r" (val)
129 : "r" (addr), "r" (GRACKLE_CONFIG_ADDR_ADDR),
130 "r" (GRACKLE_CONFIG_DATA_ADDR));
131
132 return val;
133}
134
135static inline void gemini_led_on( int led )
136{
137 if (led >= 0 && led < GEMINI_LEDS)
138 *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 1;
139}
140
141static inline void gemini_led_off(int led)
142{
143 if (led >= 0 && led < GEMINI_LEDS)
144 *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 0;
145}
146
147static inline int gemini_led_val(int led)
148{
149 int val = 0;
150 if (led >= 0 && led < GEMINI_LEDS)
151 val = *(unsigned char *)(GEMINI_LEDBASE + (led<<3));
152 return (val & 0x1);
153}
154
155/* returns processor id from the board */
156static inline int gemini_processor(void)
157{
158 unsigned char cpu = *(unsigned char *)(GEMINI_CPUSTAT);
159 return (int) ((cpu == 0) ? 4 : (cpu & GEMINI_CPU_ID_MASK));
160}
161
162
163extern void _gemini_reboot(void);
164extern void gemini_prom_init(void);
165extern void gemini_init_l2(void);
166#endif /* __ASSEMBLY__ */
167#endif
168#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/gemini_pci.c b/arch/ppc/platforms/gemini_pci.c
new file mode 100644
index 000000000000..95656091ba2b
--- /dev/null
+++ b/arch/ppc/platforms/gemini_pci.c
@@ -0,0 +1,41 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <linux/slab.h>
5
6#include <asm/machdep.h>
7#include <platforms/gemini.h>
8#include <asm/byteorder.h>
9#include <asm/io.h>
10#include <asm/uaccess.h>
11#include <asm/pci-bridge.h>
12
13void __init gemini_pcibios_fixup(void)
14{
15 int i;
16 struct pci_dev *dev = NULL;
17
18 for_each_pci_dev(dev) {
19 for(i = 0; i < 6; i++) {
20 if (dev->resource[i].flags & IORESOURCE_IO) {
21 dev->resource[i].start |= (0xfe << 24);
22 dev->resource[i].end |= (0xfe << 24);
23 }
24 }
25 }
26}
27
28
29/* The "bootloader" for Synergy boards does none of this for us, so we need to
30 lay it all out ourselves... --Dan */
31void __init gemini_find_bridges(void)
32{
33 struct pci_controller* hose;
34
35 ppc_md.pcibios_fixup = gemini_pcibios_fixup;
36
37 hose = pcibios_alloc_controller();
38 if (!hose)
39 return;
40 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
41}
diff --git a/arch/ppc/platforms/gemini_prom.S b/arch/ppc/platforms/gemini_prom.S
new file mode 100644
index 000000000000..8c5065d56505
--- /dev/null
+++ b/arch/ppc/platforms/gemini_prom.S
@@ -0,0 +1,93 @@
1/*
2 * arch/ppc/platforms/gemini_prom.S
3 *
4 * Not really prom support code (yet), but sort of anti-prom code. The current
5 * bootloader does a number of things it shouldn't and doesn't do things that it
6 * should. The stuff in here is mainly a hodge-podge collection of setup code
7 * to get the board up and running.
8 * ---Dan
9 */
10
11#include <linux/config.h>
12#include <asm/reg.h>
13#include <asm/page.h>
14#include <platforms/gemini.h>
15#include <asm/ppc_asm.h>
16
17/*
18 * On 750's the MMU is on when Linux is booted, so we need to clear out the
19 * bootloader's BAT settings, make sure we're in supervisor state (gotcha!),
20 * and turn off the MMU.
21 *
22 */
23
24_GLOBAL(gemini_prom_init)
25#ifdef CONFIG_SMP
26 /* Since the MMU's on, get stuff in rom space that we'll need */
27 lis r4,GEMINI_CPUSTAT@h
28 ori r4,r4,GEMINI_CPUSTAT@l
29 lbz r5,0(r4)
30 andi. r5,r5,3
31 mr r24,r5 /* cpu # used later on */
32#endif
33 mfmsr r4
34 li r3,MSR_PR /* ensure supervisor! */
35 ori r3,r3,MSR_IR|MSR_DR
36 andc r4,r4,r3
37 mtmsr r4
38 isync
39#if 0
40 /* zero out the bats now that the MMU is off */
41prom_no_mmu:
42 li r3,0
43 mtspr SPRN_IBAT0U,r3
44 mtspr SPRN_IBAT0L,r3
45 mtspr SPRN_IBAT1U,r3
46 mtspr SPRN_IBAT1L,r3
47 mtspr SPRN_IBAT2U,r3
48 mtspr SPRN_IBAT2L,r3
49 mtspr SPRN_IBAT3U,r3
50 mtspr SPRN_IBAT3L,r3
51
52 mtspr SPRN_DBAT0U,r3
53 mtspr SPRN_DBAT0L,r3
54 mtspr SPRN_DBAT1U,r3
55 mtspr SPRN_DBAT1L,r3
56 mtspr SPRN_DBAT2U,r3
57 mtspr SPRN_DBAT2L,r3
58 mtspr SPRN_DBAT3U,r3
59 mtspr SPRN_DBAT3L,r3
60#endif
61
62 /* the bootloader (as far as I'm currently aware) doesn't mess with page
63 tables, but since we're already here, might as well zap these, too */
64 li r4,0
65 mtspr SPRN_SDR1,r4
66
67 li r4,16
68 mtctr r4
69 li r3,0
70 li r4,0
713: mtsrin r3,r4
72 addi r3,r3,1
73 bdnz 3b
74
75#ifdef CONFIG_SMP
76 /* The 750 book (and Mot/IBM support) says that this will "assist" snooping
77 when in SMP. Not sure yet whether this should stay or leave... */
78 mfspr r4,SPRN_HID0
79 ori r4,r4,HID0_ABE
80 mtspr SPRN_HID0,r4
81 sync
82#endif /* CONFIG_SMP */
83 blr
84
85/* apparently, SMon doesn't pay attention to HID0[SRST]. Disable the MMU and
86 branch to 0xfff00100 */
87_GLOBAL(_gemini_reboot)
88 lis r5,GEMINI_BOOT_INIT@h
89 ori r5,r5,GEMINI_BOOT_INIT@l
90 li r6,MSR_IP
91 mtspr SPRN_SRR0,r5
92 mtspr SPRN_SRR1,r6
93 rfi
diff --git a/arch/ppc/platforms/gemini_serial.h b/arch/ppc/platforms/gemini_serial.h
new file mode 100644
index 000000000000..69855aeec888
--- /dev/null
+++ b/arch/ppc/platforms/gemini_serial.h
@@ -0,0 +1,41 @@
1#ifdef __KERNEL__
2#ifndef __ASMPPC_GEMINI_SERIAL_H
3#define __ASMPPC_GEMINI_SERIAL_H
4
5#include <linux/config.h>
6#include <platforms/gemini.h>
7
8#ifdef CONFIG_SERIAL_MANY_PORTS
9#define RS_TABLE_SIZE 64
10#else
11#define RS_TABLE_SIZE 4
12#endif
13
14/* Rate for the 24.576 Mhz clock for the onboard serial chip */
15#define BASE_BAUD (24576000 / 16)
16
17#ifdef CONFIG_SERIAL_DETECT_IRQ
18#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
19#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ)
20#else
21#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
22#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF)
23#endif
24
25#define STD_SERIAL_PORT_DEFNS \
26 { 0, BASE_BAUD, GEMINI_SERIAL_A, 15, STD_COM_FLAGS }, /* ttyS0 */ \
27 { 0, BASE_BAUD, GEMINI_SERIAL_B, 14, STD_COM_FLAGS }, /* ttyS1 */ \
28
29#ifdef CONFIG_GEMINI_PU32
30#define PU32_SERIAL_PORT_DEFNS \
31 { 0, BASE_BAUD, NULL, 0, STD_COM_FLAGS },
32#else
33#define PU32_SERIAL_PORT_DEFNS
34#endif
35
36#define SERIAL_PORT_DFNS \
37 STD_SERIAL_PORT_DEFNS \
38 PU32_SERIAL_PORT_DEFNS
39
40#endif
41#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
new file mode 100644
index 000000000000..1a42cb9b1134
--- /dev/null
+++ b/arch/ppc/platforms/gemini_setup.c
@@ -0,0 +1,584 @@
1/*
2 * arch/ppc/platforms/gemini_setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 * Synergy Microsystems board support by Dan Cox (dan@synergymicro.com)
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/stddef.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/reboot.h>
17#include <linux/pci.h>
18#include <linux/time.h>
19#include <linux/kdev_t.h>
20#include <linux/types.h>
21#include <linux/major.h>
22#include <linux/initrd.h>
23#include <linux/console.h>
24#include <linux/irq.h>
25#include <linux/seq_file.h>
26#include <linux/root_dev.h>
27#include <linux/bcd.h>
28
29#include <asm/system.h>
30#include <asm/pgtable.h>
31#include <asm/page.h>
32#include <asm/dma.h>
33#include <asm/io.h>
34#include <asm/m48t35.h>
35#include <platforms/gemini.h>
36#include <asm/time.h>
37#include <asm/open_pic.h>
38#include <asm/bootinfo.h>
39
40void gemini_find_bridges(void);
41static int gemini_get_clock_speed(void);
42extern void gemini_pcibios_fixup(void);
43
44static char *gemini_board_families[] = {
45 "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR"
46};
47static int gemini_board_count = sizeof(gemini_board_families) /
48 sizeof(gemini_board_families[0]);
49
50static unsigned int cpu_7xx[16] = {
51 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
52};
53static unsigned int cpu_6xx[16] = {
54 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0
55};
56
57/*
58 * prom_init is the Gemini version of prom.c:prom_init. We only need
59 * the BSS clearing code, so I copied that out of prom.c. This is a
60 * lot simpler than hacking prom.c so it will build with Gemini. -VAL
61 */
62
63#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
64
65unsigned long
66prom_init(void)
67{
68 unsigned long offset = reloc_offset();
69 unsigned long phys;
70 extern char __bss_start, _end;
71
72 /* First zero the BSS -- use memset, some arches don't have
73 * caches on yet */
74 memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
75
76 /* Default */
77 phys = offset + KERNELBASE;
78
79 gemini_prom_init();
80
81 return phys;
82}
83
84int
85gemini_show_cpuinfo(struct seq_file *m)
86{
87 unsigned char reg, rev;
88 char *family;
89 unsigned int type;
90
91 reg = readb(GEMINI_FEAT);
92 family = gemini_board_families[((reg>>4) & 0xf)];
93 if (((reg>>4) & 0xf) > gemini_board_count)
94 printk(KERN_ERR "cpuinfo(): unable to determine board family\n");
95
96 reg = readb(GEMINI_BREV);
97 type = (reg>>4) & 0xf;
98 rev = reg & 0xf;
99
100 reg = readb(GEMINI_BECO);
101
102 seq_printf(m, "machine\t\t: Gemini %s%d, rev %c, eco %d\n",
103 family, type, (rev + 'A'), (reg & 0xf));
104
105 seq_printf(m, "board\t\t: Gemini %s", family);
106 if (type > 9)
107 seq_printf(m, "%c", (type - 10) + 'A');
108 else
109 seq_printf(m, "%d", type);
110
111 seq_printf(m, ", rev %c, eco %d\n", (rev + 'A'), (reg & 0xf));
112
113 seq_printf(m, "clock\t\t: %dMhz\n", gemini_get_clock_speed());
114
115 return 0;
116}
117
118static u_char gemini_openpic_initsenses[] = {
119 1,
120 1,
121 1,
122 1,
123 0,
124 0,
125 1, /* remainder are level-triggered */
126};
127
128#define GEMINI_MPIC_ADDR (0xfcfc0000)
129#define GEMINI_MPIC_PCI_CFG (0x80005800)
130
131void __init gemini_openpic_init(void)
132{
133
134 OpenPIC_Addr = (volatile struct OpenPIC *)
135 grackle_read(GEMINI_MPIC_PCI_CFG + 0x10);
136 OpenPIC_InitSenses = gemini_openpic_initsenses;
137 OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses );
138
139 ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE);
140}
141
142
143extern unsigned long loops_per_jiffy;
144extern int root_mountflags;
145extern char cmd_line[];
146
147void
148gemini_heartbeat(void)
149{
150 static unsigned long led = GEMINI_LEDBASE+(4*8);
151 static char direction = 8;
152
153
154 /* We only want to do this on 1 CPU */
155 if (smp_processor_id())
156 return;
157 *(char *)led = 0;
158 if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) ||
159 (led + direction) < (GEMINI_LEDBASE+(4*8)) )
160 direction *= -1;
161 led += direction;
162 *(char *)led = 0xff;
163 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
164}
165
166void __init gemini_setup_arch(void)
167{
168 extern char cmd_line[];
169
170
171 loops_per_jiffy = 50000000/HZ;
172
173#ifdef CONFIG_BLK_DEV_INITRD
174 /* bootable off CDROM */
175 if (initrd_start)
176 ROOT_DEV = Root_SR0;
177 else
178#endif
179 ROOT_DEV = Root_SDA1;
180
181 /* nothing but serial consoles... */
182 sprintf(cmd_line, "%s console=ttyS0", cmd_line);
183
184 printk("Boot arguments: %s\n", cmd_line);
185
186 ppc_md.heartbeat = gemini_heartbeat;
187 ppc_md.heartbeat_reset = HZ/8;
188 ppc_md.heartbeat_count = 1;
189
190 /* Lookup PCI hosts */
191 gemini_find_bridges();
192 /* take special pains to map the MPIC, since it isn't mapped yet */
193 gemini_openpic_init();
194 /* start the L2 */
195 gemini_init_l2();
196}
197
198
199int
200gemini_get_clock_speed(void)
201{
202 unsigned long hid1, pvr;
203 int clock;
204
205 pvr = mfspr(SPRN_PVR);
206 hid1 = (mfspr(SPRN_HID1) >> 28) & 0xf;
207 if (PVR_VER(pvr) == 8 ||
208 PVR_VER(pvr) == 12)
209 hid1 = cpu_7xx[hid1];
210 else
211 hid1 = cpu_6xx[hid1];
212
213 switch((readb(GEMINI_BSTAT) & 0xc) >> 2) {
214
215 case 0:
216 default:
217 clock = (hid1*100)/3;
218 break;
219
220 case 1:
221 clock = (hid1*125)/3;
222 break;
223
224 case 2:
225 clock = (hid1*50);
226 break;
227 }
228
229 return clock;
230}
231
232void __init gemini_init_l2(void)
233{
234 unsigned char reg, brev, fam, creg;
235 unsigned long cache;
236 unsigned long pvr;
237
238 reg = readb(GEMINI_L2CFG);
239 brev = readb(GEMINI_BREV);
240 fam = readb(GEMINI_FEAT);
241 pvr = mfspr(SPRN_PVR);
242
243 switch(PVR_VER(pvr)) {
244
245 case 8:
246 if (reg & 0xc0)
247 cache = (((reg >> 6) & 0x3) << 28);
248 else
249 cache = 0x3 << 28;
250
251#ifdef CONFIG_SMP
252 /* Pre-3.0 processor revs had snooping errata. Leave
253 their L2's disabled with SMP. -- Dan */
254 if (PVR_CFG(pvr) < 3) {
255 printk("Pre-3.0 750; L2 left disabled!\n");
256 return;
257 }
258#endif /* CONFIG_SMP */
259
260 /* Special case: VGM5-B's came before L2 ratios were set on
261 the board. Processor speed shouldn't be too high, so
262 set L2 ratio to 1:1.5. */
263 if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0)
264 reg |= 1;
265
266 /* determine best cache ratio based upon what the board
267 tells us (which sometimes _may_ not be true) and
268 the processor speed. */
269 else {
270 if (gemini_get_clock_speed() > 250)
271 reg = 2;
272 }
273 break;
274 case 12:
275 {
276 static unsigned long l2_size_val = 0;
277
278 if (!l2_size_val)
279 l2_size_val = _get_L2CR();
280 cache = l2_size_val;
281 break;
282 }
283 case 4:
284 case 9:
285 creg = readb(GEMINI_CPUSTAT);
286 if (((creg & 0xc) >> 2) != 1)
287 printk("Dual-604 boards don't support the use of L2\n");
288 else
289 writeb(1, GEMINI_L2CFG);
290 return;
291 default:
292 printk("Unknown processor; L2 left disabled\n");
293 return;
294 }
295
296 cache |= ((1<<reg) << 25);
297 cache |= (L2CR_L2RAM_MASK|L2CR_L2CTL|L2CR_L2DO);
298 _set_L2CR(0);
299 _set_L2CR(cache | L2CR_L2E);
300
301}
302
303void
304gemini_restart(char *cmd)
305{
306 local_irq_disable();
307 /* make a clean restart, not via the MPIC */
308 _gemini_reboot();
309 for(;;);
310}
311
312void
313gemini_power_off(void)
314{
315 for(;;);
316}
317
318void
319gemini_halt(void)
320{
321 gemini_restart(NULL);
322}
323
324void __init gemini_init_IRQ(void)
325{
326 /* gemini has no 8259 */
327 openpic_init(1, 0, 0, -1);
328}
329
330#define gemini_rtc_read(x) (readb(GEMINI_RTC+(x)))
331#define gemini_rtc_write(val,x) (writeb((val),(GEMINI_RTC+(x))))
332
333/* ensure that the RTC is up and running */
334long __init gemini_time_init(void)
335{
336 unsigned char reg;
337
338 reg = gemini_rtc_read(M48T35_RTC_CONTROL);
339
340 if ( reg & M48T35_RTC_STOPPED ) {
341 printk(KERN_INFO "M48T35 real-time-clock was stopped. Now starting...\n");
342 gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL);
343 gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL);
344 }
345 return 0;
346}
347
348#undef DEBUG_RTC
349
350unsigned long
351gemini_get_rtc_time(void)
352{
353 unsigned int year, mon, day, hour, min, sec;
354 unsigned char reg;
355
356 reg = gemini_rtc_read(M48T35_RTC_CONTROL);
357 gemini_rtc_write((reg|M48T35_RTC_READ), M48T35_RTC_CONTROL);
358#ifdef DEBUG_RTC
359 printk("get rtc: reg = %x\n", reg);
360#endif
361
362 do {
363 sec = gemini_rtc_read(M48T35_RTC_SECONDS);
364 min = gemini_rtc_read(M48T35_RTC_MINUTES);
365 hour = gemini_rtc_read(M48T35_RTC_HOURS);
366 day = gemini_rtc_read(M48T35_RTC_DOM);
367 mon = gemini_rtc_read(M48T35_RTC_MONTH);
368 year = gemini_rtc_read(M48T35_RTC_YEAR);
369 } while( sec != gemini_rtc_read(M48T35_RTC_SECONDS));
370#ifdef DEBUG_RTC
371 printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n",
372 sec, min, hour, day, mon, year);
373#endif
374
375 gemini_rtc_write(reg, M48T35_RTC_CONTROL);
376
377 BCD_TO_BIN(sec);
378 BCD_TO_BIN(min);
379 BCD_TO_BIN(hour);
380 BCD_TO_BIN(day);
381 BCD_TO_BIN(mon);
382 BCD_TO_BIN(year);
383
384 if ((year += 1900) < 1970)
385 year += 100;
386#ifdef DEBUG_RTC
387 printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n",
388 sec, min, hour, day, mon, year);
389#endif
390
391 return mktime( year, mon, day, hour, min, sec );
392}
393
394
395int
396gemini_set_rtc_time( unsigned long now )
397{
398 unsigned char reg;
399 struct rtc_time tm;
400
401 to_tm( now, &tm );
402
403 reg = gemini_rtc_read(M48T35_RTC_CONTROL);
404#ifdef DEBUG_RTC
405 printk("set rtc: reg = %x\n", reg);
406#endif
407
408 gemini_rtc_write((reg|M48T35_RTC_SET), M48T35_RTC_CONTROL);
409#ifdef DEBUG_RTC
410 printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
411 tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
412#endif
413
414 tm.tm_year -= 1900;
415 BIN_TO_BCD(tm.tm_sec);
416 BIN_TO_BCD(tm.tm_min);
417 BIN_TO_BCD(tm.tm_hour);
418 BIN_TO_BCD(tm.tm_mon);
419 BIN_TO_BCD(tm.tm_mday);
420 BIN_TO_BCD(tm.tm_year);
421#ifdef DEBUG_RTC
422 printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
423 tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
424#endif
425
426 gemini_rtc_write(tm.tm_sec, M48T35_RTC_SECONDS);
427 gemini_rtc_write(tm.tm_min, M48T35_RTC_MINUTES);
428 gemini_rtc_write(tm.tm_hour, M48T35_RTC_HOURS);
429 gemini_rtc_write(tm.tm_mday, M48T35_RTC_DOM);
430 gemini_rtc_write(tm.tm_mon, M48T35_RTC_MONTH);
431 gemini_rtc_write(tm.tm_year, M48T35_RTC_YEAR);
432
433 /* done writing */
434 gemini_rtc_write(reg, M48T35_RTC_CONTROL);
435
436 if ((time_state == TIME_ERROR) || (time_state == TIME_BAD))
437 time_state = TIME_OK;
438
439 return 0;
440}
441
442/* use the RTC to determine the decrementer count */
443void __init gemini_calibrate_decr(void)
444{
445 int freq, divisor;
446 unsigned char reg;
447
448 /* determine processor bus speed */
449 reg = readb(GEMINI_BSTAT);
450
451 switch(((reg & 0x0c)>>2)&0x3) {
452 case 0:
453 default:
454 freq = 66667;
455 break;
456 case 1:
457 freq = 83000;
458 break;
459 case 2:
460 freq = 100000;
461 break;
462 }
463
464 freq *= 1000;
465 divisor = 4;
466 tb_ticks_per_jiffy = freq / HZ / divisor;
467 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
468}
469
470unsigned long __init gemini_find_end_of_memory(void)
471{
472 unsigned long total;
473 unsigned char reg;
474
475 reg = readb(GEMINI_MEMCFG);
476 total = ((1<<((reg & 0x7) - 1)) *
477 (8<<((reg >> 3) & 0x7)));
478 total *= (1024*1024);
479 return total;
480}
481
482static void __init
483gemini_map_io(void)
484{
485 io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
486 io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
487}
488
489#ifdef CONFIG_SMP
490static int
491smp_gemini_probe(void)
492{
493 int i, nr;
494
495 nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2;
496 if (nr == 0)
497 nr = 4;
498
499 if (nr > 1) {
500 openpic_request_IPIs();
501 for (i = 1; i < nr; ++i)
502 smp_hw_index[i] = i;
503 }
504
505 return nr;
506}
507
508static void
509smp_gemini_kick_cpu(int nr)
510{
511 openpic_reset_processor_phys(1 << nr);
512 openpic_reset_processor_phys(0);
513}
514
515static void
516smp_gemini_setup_cpu(int cpu_nr)
517{
518 if (OpenPIC_Addr)
519 do_openpic_setup_cpu();
520 if (cpu_nr > 0)
521 gemini_init_l2();
522}
523
524static struct smp_ops_t gemini_smp_ops = {
525 smp_openpic_message_pass,
526 smp_gemini_probe,
527 smp_gemini_kick_cpu,
528 smp_gemini_setup_cpu,
529 .give_timebase = smp_generic_give_timebase,
530 .take_timebase = smp_generic_take_timebase,
531};
532#endif /* CONFIG_SMP */
533
534void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
535 unsigned long r6, unsigned long r7)
536{
537 int i;
538
539 /* Restore BATs for now */
540 mtspr(SPRN_DBAT3U, 0xf0001fff);
541 mtspr(SPRN_DBAT3L, 0xf000002a);
542
543 parse_bootinfo(find_bootinfo());
544
545 for(i = 0; i < GEMINI_LEDS; i++)
546 gemini_led_off(i);
547
548 ISA_DMA_THRESHOLD = 0;
549 DMA_MODE_READ = 0;
550 DMA_MODE_WRITE = 0;
551
552#ifdef CONFIG_BLK_DEV_INITRD
553 if ( r4 )
554 {
555 initrd_start = r4 + KERNELBASE;
556 initrd_end = r5 + KERNELBASE;
557 }
558#endif
559
560 ppc_md.setup_arch = gemini_setup_arch;
561 ppc_md.show_cpuinfo = gemini_show_cpuinfo;
562 ppc_md.irq_canonicalize = NULL;
563 ppc_md.init_IRQ = gemini_init_IRQ;
564 ppc_md.get_irq = openpic_get_irq;
565 ppc_md.init = NULL;
566
567 ppc_md.restart = gemini_restart;
568 ppc_md.power_off = gemini_power_off;
569 ppc_md.halt = gemini_halt;
570
571 ppc_md.time_init = gemini_time_init;
572 ppc_md.set_rtc_time = gemini_set_rtc_time;
573 ppc_md.get_rtc_time = gemini_get_rtc_time;
574 ppc_md.calibrate_decr = gemini_calibrate_decr;
575
576 ppc_md.find_end_of_memory = gemini_find_end_of_memory;
577 ppc_md.setup_io_mappings = gemini_map_io;
578
579 ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
580
581#ifdef CONFIG_SMP
582 ppc_md.smp_ops = &gemini_smp_ops;
583#endif /* CONFIG_SMP */
584}
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
new file mode 100644
index 000000000000..b659d7b3d747
--- /dev/null
+++ b/arch/ppc/platforms/hdpu.c
@@ -0,0 +1,1062 @@
1
2/*
3 * arch/ppc/platforms/hdpu_setup.c
4 *
5 * Board setup routines for the Sky Computers HDPU Compute Blade.
6 *
7 * Written by Brian Waite <waite@skycomputers.com>
8 *
9 * Based on code done by - Mark A. Greer <mgreer@mvista.com>
10 * Rabeeh Khoury - rabeeh@galileo.co.il
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
18#include <linux/config.h>
19
20#include <linux/pci.h>
21#include <linux/delay.h>
22#include <linux/irq.h>
23#include <linux/ide.h>
24#include <linux/seq_file.h>
25
26#include <linux/initrd.h>
27#include <linux/root_dev.h>
28#include <linux/smp.h>
29
30#include <asm/time.h>
31#include <asm/machdep.h>
32#include <asm/todc.h>
33#include <asm/mv64x60.h>
34#include <asm/ppcboot.h>
35#include <platforms/hdpu.h>
36#include <linux/mv643xx.h>
37#include <linux/hdpu_features.h>
38#include <linux/device.h>
39#include <linux/mtd/physmap.h>
40
41#define BOARD_VENDOR "Sky Computers"
42#define BOARD_MACHINE "HDPU-CB-A"
43
44bd_t ppcboot_bd;
45int ppcboot_bd_valid = 0;
46
47static mv64x60_handle_t bh;
48
49extern char cmd_line[];
50
51unsigned long hdpu_find_end_of_memory(void);
52void hdpu_mpsc_progress(char *s, unsigned short hex);
53void hdpu_heartbeat(void);
54
55static void parse_bootinfo(unsigned long r3,
56 unsigned long r4, unsigned long r5,
57 unsigned long r6, unsigned long r7);
58static void hdpu_set_l1pe(void);
59static void hdpu_cpustate_set(unsigned char new_state);
60#ifdef CONFIG_SMP
61static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
62static unsigned int timebase_upper = 0, timebase_lower = 0;
63extern int smp_tb_synchronized;
64
65void __devinit hdpu_tben_give(void);
66void __devinit hdpu_tben_take(void);
67#endif
68
69static int __init
70hdpu_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
71{
72 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
73
74 if (hose->index == 0) {
75 static char pci_irq_table[][4] = {
76 {HDPU_PCI_0_IRQ, 0, 0, 0},
77 {HDPU_PCI_0_IRQ, 0, 0, 0},
78 };
79
80 const long min_idsel = 1, max_idsel = 2, irqs_per_slot = 4;
81 return PCI_IRQ_TABLE_LOOKUP;
82 } else {
83 static char pci_irq_table[][4] = {
84 {HDPU_PCI_1_IRQ, 0, 0, 0},
85 };
86
87 const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
88 return PCI_IRQ_TABLE_LOOKUP;
89 }
90}
91
92static void __init hdpu_intr_setup(void)
93{
94 mv64x60_write(&bh, MV64x60_GPP_IO_CNTL,
95 (1 | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) |
96 (1 << 6) | (1 << 7) | (1 << 12) | (1 << 16) |
97 (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21) |
98 (1 << 22) | (1 << 23) | (1 << 24) | (1 << 25) |
99 (1 << 26) | (1 << 27) | (1 << 28) | (1 << 29)));
100
101 /* XXXX Erranum FEr PCI-#8 */
102 mv64x60_clr_bits(&bh, MV64x60_PCI0_CMD, (1 << 5) | (1 << 9));
103 mv64x60_clr_bits(&bh, MV64x60_PCI1_CMD, (1 << 5) | (1 << 9));
104
105 /*
106 * Dismiss and then enable interrupt on GPP interrupt cause
107 * for CPU #0
108 */
109 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~((1 << 8) | (1 << 13)));
110 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, (1 << 8) | (1 << 13));
111
112 /*
113 * Dismiss and then enable interrupt on CPU #0 high cause reg
114 * BIT25 summarizes GPP interrupts 8-15
115 */
116 mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, (1 << 25));
117}
118
119static void __init hdpu_setup_peripherals(void)
120{
121 unsigned int val;
122
123 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
124 HDPU_EMB_FLASH_BASE, HDPU_EMB_FLASH_SIZE, 0);
125 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
126
127 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
128 HDPU_TBEN_BASE, HDPU_TBEN_SIZE, 0);
129 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
130
131 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
132 HDPU_NEXUS_ID_BASE, HDPU_NEXUS_ID_SIZE, 0);
133 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
134
135 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
136 HDPU_INTERNAL_SRAM_BASE,
137 HDPU_INTERNAL_SRAM_SIZE, 0);
138 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
139
140 bh.ci->disable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN);
141 mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN, 0, 0, 0);
142
143 mv64x60_clr_bits(&bh, MV64x60_PCI0_PCI_DECODE_CNTL, (1 << 3));
144 mv64x60_clr_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, (1 << 3));
145 mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
146 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));
147
148 /* Enable pipelining */
149 mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1 << 13));
150 /* Enable Snoop Pipelineing */
151 mv64x60_set_bits(&bh, MV64360_D_UNIT_CONTROL_HIGH, (1 << 24));
152
153 /*
154 * Change DRAM read buffer assignment.
155 * Assign read buffer 0 dedicated only for CPU,
156 * and the rest read buffer 1.
157 */
158 val = mv64x60_read(&bh, MV64360_SDRAM_CONFIG);
159 val = val & 0x03ffffff;
160 val = val | 0xf8000000;
161 mv64x60_write(&bh, MV64360_SDRAM_CONFIG, val);
162
163 /*
164 * Configure internal SRAM -
165 * Cache coherent write back, if CONFIG_MV64360_SRAM_CACHE_COHERENT set
166 * Parity enabled.
167 * Parity error propagation
168 * Arbitration not parked for CPU only
169 * Other bits are reserved.
170 */
171#ifdef CONFIG_MV64360_SRAM_CACHE_COHERENT
172 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);
173#else
174 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b0);
175#endif
176
177 hdpu_intr_setup();
178}
179
180static void __init hdpu_setup_bridge(void)
181{
182 struct mv64x60_setup_info si;
183 int i;
184
185 memset(&si, 0, sizeof(si));
186
187 si.phys_reg_base = HDPU_BRIDGE_REG_BASE;
188 si.pci_0.enable_bus = 1;
189 si.pci_0.pci_io.cpu_base = HDPU_PCI0_IO_START_PROC_ADDR;
190 si.pci_0.pci_io.pci_base_hi = 0;
191 si.pci_0.pci_io.pci_base_lo = HDPU_PCI0_IO_START_PCI_ADDR;
192 si.pci_0.pci_io.size = HDPU_PCI0_IO_SIZE;
193 si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
194 si.pci_0.pci_mem[0].cpu_base = HDPU_PCI0_MEM_START_PROC_ADDR;
195 si.pci_0.pci_mem[0].pci_base_hi = HDPU_PCI0_MEM_START_PCI_HI_ADDR;
196 si.pci_0.pci_mem[0].pci_base_lo = HDPU_PCI0_MEM_START_PCI_LO_ADDR;
197 si.pci_0.pci_mem[0].size = HDPU_PCI0_MEM_SIZE;
198 si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
199 si.pci_0.pci_cmd_bits = 0;
200 si.pci_0.latency_timer = 0x80;
201
202 si.pci_1.enable_bus = 1;
203 si.pci_1.pci_io.cpu_base = HDPU_PCI1_IO_START_PROC_ADDR;
204 si.pci_1.pci_io.pci_base_hi = 0;
205 si.pci_1.pci_io.pci_base_lo = HDPU_PCI1_IO_START_PCI_ADDR;
206 si.pci_1.pci_io.size = HDPU_PCI1_IO_SIZE;
207 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
208 si.pci_1.pci_mem[0].cpu_base = HDPU_PCI1_MEM_START_PROC_ADDR;
209 si.pci_1.pci_mem[0].pci_base_hi = HDPU_PCI1_MEM_START_PCI_HI_ADDR;
210 si.pci_1.pci_mem[0].pci_base_lo = HDPU_PCI1_MEM_START_PCI_LO_ADDR;
211 si.pci_1.pci_mem[0].size = HDPU_PCI1_MEM_SIZE;
212 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
213 si.pci_1.pci_cmd_bits = 0;
214 si.pci_1.latency_timer = 0x80;
215
216 for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) {
217#if defined(CONFIG_NOT_COHERENT_CACHE)
218 si.cpu_prot_options[i] = 0;
219 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE;
220 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE;
221 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE;
222
223 si.pci_1.acc_cntl_options[i] =
224 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
225 MV64360_PCI_ACC_CNTL_SWAP_NONE |
226 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
227 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
228
229 si.pci_0.acc_cntl_options[i] =
230 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
231 MV64360_PCI_ACC_CNTL_SWAP_NONE |
232 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
233 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
234
235#else
236 si.cpu_prot_options[i] = 0;
237 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_WB; /* errata */
238 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_WB; /* errata */
239 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_WB; /* errata */
240
241 si.pci_0.acc_cntl_options[i] =
242 MV64360_PCI_ACC_CNTL_SNOOP_WB |
243 MV64360_PCI_ACC_CNTL_SWAP_NONE |
244 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
245 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
246
247 si.pci_1.acc_cntl_options[i] =
248 MV64360_PCI_ACC_CNTL_SNOOP_WB |
249 MV64360_PCI_ACC_CNTL_SWAP_NONE |
250 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
251 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
252#endif
253 }
254
255 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_INIT_PCI);
256
257 /* Lookup PCI host bridges */
258 mv64x60_init(&bh, &si);
259 pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */
260 ppc_md.pci_swizzle = common_swizzle;
261 ppc_md.pci_map_irq = hdpu_map_irq;
262
263 mv64x60_set_bus(&bh, 0, 0);
264 bh.hose_a->first_busno = 0;
265 bh.hose_a->last_busno = 0xff;
266 bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
267
268 bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
269 mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
270 bh.hose_b->last_busno = 0xff;
271 bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
272 bh.hose_b->first_busno);
273
274 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
275
276 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_INIT_REG);
277 /*
278 * Enabling of PCI internal-vs-external arbitration
279 * is a platform- and errata-dependent decision.
280 */
281 return;
282}
283
284#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
285static void __init hdpu_early_serial_map(void)
286{
287#ifdef CONFIG_KGDB
288 static char first_time = 1;
289
290#if defined(CONFIG_KGDB_TTYS0)
291#define KGDB_PORT 0
292#elif defined(CONFIG_KGDB_TTYS1)
293#define KGDB_PORT 1
294#else
295#error "Invalid kgdb_tty port"
296#endif
297
298 if (first_time) {
299 gt_early_mpsc_init(KGDB_PORT,
300 B9600 | CS8 | CREAD | HUPCL | CLOCAL);
301 first_time = 0;
302 }
303
304 return;
305#endif
306}
307#endif
308
309static void hdpu_init2(void)
310{
311 return;
312}
313
314#if defined(CONFIG_MV643XX_ETH)
315static void __init hdpu_fixup_eth_pdata(struct platform_device *pd)
316{
317
318 struct mv643xx_eth_platform_data *eth_pd;
319 eth_pd = pd->dev.platform_data;
320
321 eth_pd->port_serial_control =
322 mv64x60_read(&bh, MV643XX_ETH_PORT_SERIAL_CONTROL_REG(pd->id) & ~1);
323
324 eth_pd->force_phy_addr = 1;
325 eth_pd->phy_addr = pd->id;
326 eth_pd->tx_queue_size = 400;
327 eth_pd->rx_queue_size = 800;
328}
329#endif
330
331static void __init hdpu_fixup_mpsc_pdata(struct platform_device *pd)
332{
333
334 struct mpsc_pdata *pdata;
335
336 pdata = (struct mpsc_pdata *)pd->dev.platform_data;
337
338 pdata->max_idle = 40;
339 if (ppcboot_bd_valid)
340 pdata->default_baud = ppcboot_bd.bi_baudrate;
341 else
342 pdata->default_baud = HDPU_DEFAULT_BAUD;
343 pdata->brg_clk_src = HDPU_MPSC_CLK_SRC;
344 pdata->brg_clk_freq = HDPU_MPSC_CLK_FREQ;
345}
346
347#if defined(CONFIG_HDPU_FEATURES)
348static void __init hdpu_fixup_cpustate_pdata(struct platform_device *pd)
349{
350 struct platform_device *pds[1];
351 pds[0] = pd;
352 mv64x60_pd_fixup(&bh, pds, 1);
353}
354#endif
355
356static int __init hdpu_platform_notify(struct device *dev)
357{
358 static struct {
359 char *bus_id;
360 void ((*rtn) (struct platform_device * pdev));
361 } dev_map[] = {
362 {
363 MPSC_CTLR_NAME ".0", hdpu_fixup_mpsc_pdata},
364#if defined(CONFIG_MV643XX_ETH)
365 {
366 MV643XX_ETH_NAME ".0", hdpu_fixup_eth_pdata},
367#endif
368#if defined(CONFIG_HDPU_FEATURES)
369 {
370 HDPU_CPUSTATE_NAME ".0", hdpu_fixup_cpustate_pdata},
371#endif
372 };
373 struct platform_device *pdev;
374 int i;
375
376 if (dev && dev->bus_id)
377 for (i = 0; i < ARRAY_SIZE(dev_map); i++)
378 if (!strncmp(dev->bus_id, dev_map[i].bus_id,
379 BUS_ID_SIZE)) {
380
381 pdev = container_of(dev,
382 struct platform_device,
383 dev);
384 dev_map[i].rtn(pdev);
385 }
386
387 return 0;
388}
389
390static void __init hdpu_setup_arch(void)
391{
392 if (ppc_md.progress)
393 ppc_md.progress("hdpu_setup_arch: enter", 0);
394#ifdef CONFIG_BLK_DEV_INITRD
395 if (initrd_start)
396 ROOT_DEV = Root_RAM0;
397 else
398#endif
399#ifdef CONFIG_ROOT_NFS
400 ROOT_DEV = Root_NFS;
401#else
402 ROOT_DEV = Root_SDA2;
403#endif
404
405 ppc_md.heartbeat = hdpu_heartbeat;
406
407 ppc_md.heartbeat_reset = HZ;
408 ppc_md.heartbeat_count = 1;
409
410 if (ppc_md.progress)
411 ppc_md.progress("hdpu_setup_arch: Enabling L2 cache", 0);
412
413 /* Enable L1 Parity Bits */
414 hdpu_set_l1pe();
415
416 /* Enable L2 and L3 caches (if 745x) */
417 _set_L2CR(0x80080000);
418
419 if (ppc_md.progress)
420 ppc_md.progress("hdpu_setup_arch: enter", 0);
421
422 hdpu_setup_bridge();
423
424 hdpu_setup_peripherals();
425
426#ifdef CONFIG_SERIAL_MPSC_CONSOLE
427 hdpu_early_serial_map();
428#endif
429
430 printk("SKY HDPU Compute Blade \n");
431
432 if (ppc_md.progress)
433 ppc_md.progress("hdpu_setup_arch: exit", 0);
434
435 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_OK);
436 return;
437}
438static void __init hdpu_init_irq(void)
439{
440 mv64360_init_irq();
441}
442
443static void __init hdpu_set_l1pe()
444{
445 unsigned long ictrl;
446 asm volatile ("mfspr %0, 1011":"=r" (ictrl):);
447 ictrl |= ICTRL_EICE | ICTRL_EDC | ICTRL_EICP;
448 asm volatile ("mtspr 1011, %0"::"r" (ictrl));
449}
450
451/*
452 * Set BAT 1 to map 0xf1000000 to end of physical memory space.
453 */
454static __inline__ void hdpu_set_bat(void)
455{
456 mb();
457 mtspr(SPRN_DBAT1U, 0xf10001fe);
458 mtspr(SPRN_DBAT1L, 0xf100002a);
459 mb();
460
461 return;
462}
463
464unsigned long __init hdpu_find_end_of_memory(void)
465{
466 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
467 MV64x60_TYPE_MV64360);
468}
469
470static void hdpu_reset_board(void)
471{
472 volatile int infinite = 1;
473
474 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_RESET);
475
476 local_irq_disable();
477
478 /* Clear all the LEDs */
479 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, ((1 << 4) |
480 (1 << 5) | (1 << 6)));
481
482 /* disable and invalidate the L2 cache */
483 _set_L2CR(0);
484 _set_L2CR(0x200000);
485
486 /* flush and disable L1 I/D cache */
487 __asm__ __volatile__
488 ("\n"
489 "mfspr 3,1008\n"
490 "ori 5,5,0xcc00\n"
491 "ori 4,3,0xc00\n"
492 "andc 5,3,5\n"
493 "sync\n"
494 "mtspr 1008,4\n"
495 "isync\n" "sync\n" "mtspr 1008,5\n" "isync\n" "sync\n");
496
497 /* Hit the reset bit */
498 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, (1 << 3));
499
500 while (infinite)
501 infinite = infinite;
502
503 return;
504}
505
506static void hdpu_restart(char *cmd)
507{
508 volatile ulong i = 10000000;
509
510 hdpu_reset_board();
511
512 while (i-- > 0) ;
513 panic("restart failed\n");
514}
515
516static void hdpu_halt(void)
517{
518 local_irq_disable();
519
520 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_HALT);
521
522 /* Clear all the LEDs */
523 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, ((1 << 4) | (1 << 5) |
524 (1 << 6)));
525 while (1) ;
526 /* NOTREACHED */
527}
528
529static void hdpu_power_off(void)
530{
531 hdpu_halt();
532 /* NOTREACHED */
533}
534
535static int hdpu_show_cpuinfo(struct seq_file *m)
536{
537 uint pvid;
538
539 pvid = mfspr(SPRN_PVR);
540 seq_printf(m, "vendor\t\t: Sky Computers\n");
541 seq_printf(m, "machine\t\t: HDPU Compute Blade\n");
542 seq_printf(m, "PVID\t\t: 0x%x, vendor: %s\n",
543 pvid, (pvid & (1 << 15) ? "IBM" : "Motorola"));
544
545 return 0;
546}
547
548static void __init hdpu_calibrate_decr(void)
549{
550 ulong freq;
551
552 if (ppcboot_bd_valid)
553 freq = ppcboot_bd.bi_busfreq / 4;
554 else
555 freq = 133000000;
556
557 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
558 freq / 1000000, freq % 1000000);
559
560 tb_ticks_per_jiffy = freq / HZ;
561 tb_to_us = mulhwu_scale_factor(freq, 1000000);
562
563 return;
564}
565
566static void parse_bootinfo(unsigned long r3,
567 unsigned long r4, unsigned long r5,
568 unsigned long r6, unsigned long r7)
569{
570 bd_t *bd = NULL;
571 char *cmdline_start = NULL;
572 int cmdline_len = 0;
573
574 if (r3) {
575 if ((r3 & 0xf0000000) == 0)
576 r3 += KERNELBASE;
577 if ((r3 & 0xf0000000) == KERNELBASE) {
578 bd = (void *)r3;
579
580 memcpy(&ppcboot_bd, bd, sizeof(ppcboot_bd));
581 ppcboot_bd_valid = 1;
582 }
583 }
584#ifdef CONFIG_BLK_DEV_INITRD
585 if (r4 && r5 && r5 > r4) {
586 if ((r4 & 0xf0000000) == 0)
587 r4 += KERNELBASE;
588 if ((r5 & 0xf0000000) == 0)
589 r5 += KERNELBASE;
590 if ((r4 & 0xf0000000) == KERNELBASE) {
591 initrd_start = r4;
592 initrd_end = r5;
593 initrd_below_start_ok = 1;
594 }
595 }
596#endif /* CONFIG_BLK_DEV_INITRD */
597
598 if (r6 && r7 && r7 > r6) {
599 if ((r6 & 0xf0000000) == 0)
600 r6 += KERNELBASE;
601 if ((r7 & 0xf0000000) == 0)
602 r7 += KERNELBASE;
603 if ((r6 & 0xf0000000) == KERNELBASE) {
604 cmdline_start = (void *)r6;
605 cmdline_len = (r7 - r6);
606 strncpy(cmd_line, cmdline_start, cmdline_len);
607 }
608 }
609}
610
611#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
612static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
613{
614 return check_region(from, extent);
615}
616
617static void
618hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
619{
620 request_region(from, extent, name);
621 return;
622}
623
624static void hdpu_ide_release_region(ide_ioreg_t from, unsigned int extent)
625{
626 release_region(from, extent);
627 return;
628}
629
630static void __init
631hdpu_ide_pci_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
632 ide_ioreg_t ctrl_port, int *irq)
633{
634 struct pci_dev *dev;
635
636 pci_for_each_dev(dev) {
637 if (((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) ||
638 ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID)) {
639 hw->irq = dev->irq;
640
641 if (irq != NULL) {
642 *irq = dev->irq;
643 }
644 }
645 }
646
647 return;
648}
649#endif
650
651void hdpu_heartbeat(void)
652{
653 if (mv64x60_read(&bh, MV64x60_GPP_VALUE) & (1 << 5))
654 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, (1 << 5));
655 else
656 mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, (1 << 5));
657
658 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
659
660}
661
662static void __init hdpu_map_io(void)
663{
664 io_block_mapping(0xf1000000, 0xf1000000, 0x20000, _PAGE_IO);
665}
666
667#ifdef CONFIG_SMP
668char hdpu_smp0[] = "SMP Cpu #0";
669char hdpu_smp1[] = "SMP Cpu #1";
670
671static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id,
672 struct pt_regs *regs)
673{
674 volatile unsigned int doorbell;
675
676 doorbell = mv64x60_read(&bh, MV64360_CPU0_DOORBELL);
677
678 /* Ack the doorbell interrupts */
679 mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, doorbell);
680
681 if (doorbell & 1) {
682 smp_message_recv(0, regs);
683 }
684 if (doorbell & 2) {
685 smp_message_recv(1, regs);
686 }
687 if (doorbell & 4) {
688 smp_message_recv(2, regs);
689 }
690 if (doorbell & 8) {
691 smp_message_recv(3, regs);
692 }
693 return IRQ_HANDLED;
694}
695
696static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id,
697 struct pt_regs *regs)
698{
699 volatile unsigned int doorbell;
700
701 doorbell = mv64x60_read(&bh, MV64360_CPU1_DOORBELL);
702
703 /* Ack the doorbell interrupts */
704 mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, doorbell);
705
706 if (doorbell & 1) {
707 smp_message_recv(0, regs);
708 }
709 if (doorbell & 2) {
710 smp_message_recv(1, regs);
711 }
712 if (doorbell & 4) {
713 smp_message_recv(2, regs);
714 }
715 if (doorbell & 8) {
716 smp_message_recv(3, regs);
717 }
718 return IRQ_HANDLED;
719}
720
721static void smp_hdpu_CPU_two(void)
722{
723 __asm__ __volatile__
724 ("\n"
725 "lis 3,0x0000\n"
726 "ori 3,3,0x00c0\n"
727 "mtspr 26, 3\n" "li 4,0\n" "mtspr 27,4\n" "rfi");
728
729}
730
731static int smp_hdpu_probe(void)
732{
733 int *cpu_count_reg;
734 int num_cpus = 0;
735
736 cpu_count_reg = ioremap(HDPU_NEXUS_ID_BASE, HDPU_NEXUS_ID_SIZE);
737 if (cpu_count_reg) {
738 num_cpus = (*cpu_count_reg >> 20) & 0x3;
739 iounmap(cpu_count_reg);
740 }
741
742 /* Validate the bits in the CPLD. If we could not map the reg, return 2.
743 * If the register reported 0 or 3, return 2.
744 * Older CPLD revisions set these bits to all ones (val = 3).
745 */
746 if ((num_cpus < 1) || (num_cpus > 2)) {
747 printk
748 ("Unable to determine the number of processors %d . deafulting to 2.\n",
749 num_cpus);
750 num_cpus = 2;
751 }
752 return num_cpus;
753}
754
755static void
756smp_hdpu_message_pass(int target, int msg, unsigned long data, int wait)
757{
758 if (msg > 0x3) {
759 printk("SMP %d: smp_message_pass: unknown msg %d\n",
760 smp_processor_id(), msg);
761 return;
762 }
763 switch (target) {
764 case MSG_ALL:
765 mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);
766 mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);
767 break;
768 case MSG_ALL_BUT_SELF:
769 if (smp_processor_id())
770 mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);
771 else
772 mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);
773 break;
774 default:
775 if (target == 0)
776 mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);
777 else
778 mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);
779 break;
780 }
781}
782
783static void smp_hdpu_kick_cpu(int nr)
784{
785 volatile unsigned int *bootaddr;
786
787 if (ppc_md.progress)
788 ppc_md.progress("smp_hdpu_kick_cpu", 0);
789
790 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_CPU1_KICK);
791
792 /* Disable BootCS. Must also reduce the windows size to zero. */
793 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
794 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, 0, 0, 0);
795
796 bootaddr = ioremap(HDPU_INTERNAL_SRAM_BASE, HDPU_INTERNAL_SRAM_SIZE);
797 if (!bootaddr) {
798 if (ppc_md.progress)
799 ppc_md.progress("smp_hdpu_kick_cpu: ioremap failed", 0);
800 return;
801 }
802
803 memcpy((void *)(bootaddr + 0x40), (void *)&smp_hdpu_CPU_two, 0x20);
804
805 /* map SRAM to 0xfff00000 */
806 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
807
808 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
809 0xfff00000, HDPU_INTERNAL_SRAM_SIZE, 0);
810 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
811
812 /* Enable CPU1 arbitration */
813 mv64x60_clr_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1 << 9));
814
815 /*
816 * Wait 100mSecond until other CPU has reached __secondary_start.
817 * When it reaches, it is permittable to rever the SRAM mapping etc...
818 */
819 mdelay(100);
820 *(unsigned long *)KERNELBASE = nr;
821 asm volatile ("dcbf 0,%0"::"r" (KERNELBASE):"memory");
822
823 iounmap(bootaddr);
824
825 /* Set up window for internal sram (256KByte insize) */
826 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
827 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
828 HDPU_INTERNAL_SRAM_BASE,
829 HDPU_INTERNAL_SRAM_SIZE, 0);
830 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
831 /*
832 * Set up windows for embedded FLASH (using boot CS window).
833 */
834
835 bh.ci->disable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
836 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
837 HDPU_EMB_FLASH_BASE, HDPU_EMB_FLASH_SIZE, 0);
838 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
839}
840
841static void smp_hdpu_setup_cpu(int cpu_nr)
842{
843 if (cpu_nr == 0) {
844 if (ppc_md.progress)
845 ppc_md.progress("smp_hdpu_setup_cpu 0", 0);
846 mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, 0xff);
847 mv64x60_write(&bh, MV64360_CPU0_DOORBELL_MASK, 0xff);
848 request_irq(60, hdpu_smp_cpu0_int_handler,
849 SA_INTERRUPT, hdpu_smp0, 0);
850 }
851
852 if (cpu_nr == 1) {
853 if (ppc_md.progress)
854 ppc_md.progress("smp_hdpu_setup_cpu 1", 0);
855
856 hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR |
857 CPUSTATE_KERNEL_CPU1_OK);
858
859 /* Enable L1 Parity Bits */
860 hdpu_set_l1pe();
861
862 /* Enable L2 cache */
863 _set_L2CR(0);
864 _set_L2CR(0x80080000);
865
866 mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, 0x0);
867 mv64x60_write(&bh, MV64360_CPU1_DOORBELL_MASK, 0xff);
868 request_irq(28, hdpu_smp_cpu1_int_handler,
869 SA_INTERRUPT, hdpu_smp1, 0);
870 }
871
872}
873
874void __devinit hdpu_tben_give()
875{
876 volatile unsigned long *val = 0;
877
878 /* By writing 0 to the TBEN_BASE, the timebases is frozen */
879 val = ioremap(HDPU_TBEN_BASE, 4);
880 *val = 0;
881 mb();
882
883 spin_lock(&timebase_lock);
884 timebase_upper = get_tbu();
885 timebase_lower = get_tbl();
886 spin_unlock(&timebase_lock);
887
888 while (timebase_upper || timebase_lower)
889 barrier();
890
891 /* By writing 1 to the TBEN_BASE, the timebases is thawed */
892 *val = 1;
893 mb();
894
895 iounmap(val);
896
897}
898
899void __devinit hdpu_tben_take()
900{
901 while (!(timebase_upper || timebase_lower))
902 barrier();
903
904 spin_lock(&timebase_lock);
905 set_tb(timebase_upper, timebase_lower);
906 timebase_upper = 0;
907 timebase_lower = 0;
908 spin_unlock(&timebase_lock);
909}
910
911static struct smp_ops_t hdpu_smp_ops = {
912 .message_pass = smp_hdpu_message_pass,
913 .probe = smp_hdpu_probe,
914 .kick_cpu = smp_hdpu_kick_cpu,
915 .setup_cpu = smp_hdpu_setup_cpu,
916 .give_timebase = hdpu_tben_give,
917 .take_timebase = hdpu_tben_take,
918};
919#endif /* CONFIG_SMP */
920
921void __init
922platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
923 unsigned long r6, unsigned long r7)
924{
925 parse_bootinfo(r3, r4, r5, r6, r7);
926
927 isa_mem_base = 0;
928
929 ppc_md.setup_arch = hdpu_setup_arch;
930 ppc_md.init = hdpu_init2;
931 ppc_md.show_cpuinfo = hdpu_show_cpuinfo;
932 ppc_md.init_IRQ = hdpu_init_irq;
933 ppc_md.get_irq = mv64360_get_irq;
934 ppc_md.restart = hdpu_restart;
935 ppc_md.power_off = hdpu_power_off;
936 ppc_md.halt = hdpu_halt;
937 ppc_md.find_end_of_memory = hdpu_find_end_of_memory;
938 ppc_md.calibrate_decr = hdpu_calibrate_decr;
939 ppc_md.setup_io_mappings = hdpu_map_io;
940
941 bh.p_base = CONFIG_MV64X60_NEW_BASE;
942 bh.v_base = (unsigned long *)bh.p_base;
943
944 hdpu_set_bat();
945
946#if defined(CONFIG_SERIAL_TEXT_DEBUG)
947 ppc_md.progress = hdpu_mpsc_progress; /* embedded UART */
948 mv64x60_progress_init(bh.p_base);
949#endif /* CONFIG_SERIAL_TEXT_DEBUG */
950
951#ifdef CONFIG_SMP
952 ppc_md.smp_ops = &hdpu_smp_ops;
953#endif /* CONFIG_SMP */
954
955#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
956 platform_notify = hdpu_platform_notify;
957#endif
958 return;
959}
960
961#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
962/* SMP safe version of the serial text debug routine. Uses Semaphore 0 */
963void hdpu_mpsc_progress(char *s, unsigned short hex)
964{
965 while (mv64x60_read(&bh, MV64360_WHO_AM_I) !=
966 mv64x60_read(&bh, MV64360_SEMAPHORE_0)) {
967 }
968 mv64x60_mpsc_progress(s, hex);
969 mv64x60_write(&bh, MV64360_SEMAPHORE_0, 0xff);
970}
971#endif
972
973static void hdpu_cpustate_set(unsigned char new_state)
974{
975 unsigned int state = (new_state << 21);
976 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, (0xff << 21));
977 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, state);
978}
979
980#ifdef CONFIG_MTD_PHYSMAP
981static struct mtd_partition hdpu_partitions[] = {
982 {
983 .name = "Root FS",
984 .size = 0x03400000,
985 .offset = 0,
986 .mask_flags = 0,
987 },{
988 .name = "User FS",
989 .size = 0x00800000,
990 .offset = 0x03400000,
991 .mask_flags = 0,
992 },{
993 .name = "Kernel Image",
994 .size = 0x002C0000,
995 .offset = 0x03C00000,
996 .mask_flags = 0,
997 },{
998 .name = "bootEnv",
999 .size = 0x00040000,
1000 .offset = 0x03EC0000,
1001 .mask_flags = 0,
1002 },{
1003 .name = "bootROM",
1004 .size = 0x00100000,
1005 .offset = 0x03F00000,
1006 .mask_flags = 0,
1007 }
1008};
1009
1010static int __init hdpu_setup_mtd(void)
1011{
1012
1013 physmap_set_partitions(hdpu_partitions, 5);
1014 return 0;
1015}
1016
1017arch_initcall(hdpu_setup_mtd);
1018#endif
1019
1020#ifdef CONFIG_HDPU_FEATURES
1021
1022static struct resource hdpu_cpustate_resources[] = {
1023 [0] = {
1024 .name = "addr base",
1025 .start = MV64x60_GPP_VALUE_SET,
1026 .end = MV64x60_GPP_VALUE_CLR + 1,
1027 .flags = IORESOURCE_MEM,
1028 },
1029};
1030
1031static struct resource hdpu_nexus_resources[] = {
1032 [0] = {
1033 .name = "nexus register",
1034 .start = HDPU_NEXUS_ID_BASE,
1035 .end = HDPU_NEXUS_ID_BASE + HDPU_NEXUS_ID_SIZE,
1036 .flags = IORESOURCE_MEM,
1037 },
1038};
1039
1040static struct platform_device hdpu_cpustate_device = {
1041 .name = HDPU_CPUSTATE_NAME,
1042 .id = 0,
1043 .num_resources = ARRAY_SIZE(hdpu_cpustate_resources),
1044 .resource = hdpu_cpustate_resources,
1045};
1046
1047static struct platform_device hdpu_nexus_device = {
1048 .name = HDPU_NEXUS_NAME,
1049 .id = 0,
1050 .num_resources = ARRAY_SIZE(hdpu_nexus_resources),
1051 .resource = hdpu_nexus_resources,
1052};
1053
1054static int __init hdpu_add_pds(void)
1055{
1056 platform_device_register(&hdpu_cpustate_device);
1057 platform_device_register(&hdpu_nexus_device);
1058 return 0;
1059}
1060
1061arch_initcall(hdpu_add_pds);
1062#endif
diff --git a/arch/ppc/platforms/hdpu.h b/arch/ppc/platforms/hdpu.h
new file mode 100644
index 000000000000..07c3cffb5c7b
--- /dev/null
+++ b/arch/ppc/platforms/hdpu.h
@@ -0,0 +1,82 @@
1/*
2 * arch/ppc/platforms/hdpu.h
3 *
4 * Definitions for Sky Computers HDPU board.
5 *
6 * Brian Waite <waite@skycomputers.com>
7 *
8 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
9 * Based on code done by Mark A. Greer <mgreer@mvista.com>
10 * Based on code done by Tim Montgomery <timm@artesyncp.com>
11 *
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
19/*
20 * The MV64360 has 2 PCI buses each with 1 window from the CPU bus to
21 * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
22 * We'll only use one PCI MEM window on each PCI bus.
23 *
24 * This is the CPU physical memory map (windows must be at least 64K and start
25 * on a boundary that is a multiple of the window size):
26 *
27 * 0x80000000-0x8fffffff - PCI 0 MEM
28 * 0xa0000000-0xafffffff - PCI 1 MEM
29 * 0xc0000000-0xc0ffffff - PCI 0 I/O
30 * 0xc1000000-0xc1ffffff - PCI 1 I/O
31
32 * 0xf1000000-0xf100ffff - MV64360 Registers
33 * 0xf1010000-0xfb9fffff - HOLE
34 * 0xfbfa0000-0xfbfaffff - TBEN
35 * 0xfbf00000-0xfbfbffff - NEXUS
36 * 0xfbfc0000-0xfbffffff - Internal SRAM
37 * 0xfc000000-0xffffffff - Boot window
38 */
39
40#ifndef __PPC_PLATFORMS_HDPU_H
41#define __PPC_PLATFORMS_HDPU_H
42
43/* CPU Physical Memory Map setup. */
44#define HDPU_BRIDGE_REG_BASE 0xf1000000
45
46#define HDPU_TBEN_BASE 0xfbfa0000
47#define HDPU_TBEN_SIZE 0x00010000
48#define HDPU_NEXUS_ID_BASE 0xfbfb0000
49#define HDPU_NEXUS_ID_SIZE 0x00010000
50#define HDPU_INTERNAL_SRAM_BASE 0xfbfc0000
51#define HDPU_INTERNAL_SRAM_SIZE 0x00040000
52#define HDPU_EMB_FLASH_BASE 0xfc000000
53#define HDPU_EMB_FLASH_SIZE 0x04000000
54
55/* PCI Mappings */
56
57#define HDPU_PCI0_MEM_START_PROC_ADDR 0x80000000
58#define HDPU_PCI0_MEM_START_PCI_HI_ADDR 0x00000000
59#define HDPU_PCI0_MEM_START_PCI_LO_ADDR HDPU_PCI0_MEM_START_PROC_ADDR
60#define HDPU_PCI0_MEM_SIZE 0x10000000
61
62#define HDPU_PCI1_MEM_START_PROC_ADDR 0xc0000000
63#define HDPU_PCI1_MEM_START_PCI_HI_ADDR 0x00000000
64#define HDPU_PCI1_MEM_START_PCI_LO_ADDR HDPU_PCI1_MEM_START_PROC_ADDR
65#define HDPU_PCI1_MEM_SIZE 0x20000000
66
67#define HDPU_PCI0_IO_START_PROC_ADDR 0xc0000000
68#define HDPU_PCI0_IO_START_PCI_ADDR 0x00000000
69#define HDPU_PCI0_IO_SIZE 0x01000000
70
71#define HDPU_PCI1_IO_START_PROC_ADDR 0xc1000000
72#define HDPU_PCI1_IO_START_PCI_ADDR 0x01000000
73#define HDPU_PCI1_IO_SIZE 0x01000000
74
75#define HDPU_DEFAULT_BAUD 115200
76#define HDPU_MPSC_CLK_SRC 8 /* TCLK */
77#define HDPU_MPSC_CLK_FREQ 133000000 /* 133 Mhz */
78
79#define HDPU_PCI_0_IRQ (8+64)
80#define HDPU_PCI_1_IRQ (13+64)
81
82#endif /* __PPC_PLATFORMS_HDPU_H */
diff --git a/arch/ppc/platforms/hermes.h b/arch/ppc/platforms/hermes.h
new file mode 100644
index 000000000000..198fc590b9f5
--- /dev/null
+++ b/arch/ppc/platforms/hermes.h
@@ -0,0 +1,27 @@
1/*
2 * Multidata HERMES-PRO ( / SL ) board specific definitions
3 *
4 * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_HERMES_H
8#define __MACH_HERMES_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define HERMES_IMMR_BASE 0xFF000000 /* phys. addr of IMMR */
15#define HERMES_IMAP_SIZE (64 * 1024) /* size of mapped area */
16
17#define IMAP_ADDR HERMES_IMMR_BASE /* physical base address of IMMR area */
18#define IMAP_SIZE HERMES_IMAP_SIZE /* mapped size of IMMR area */
19
20#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */
21#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */
22
23/* We don't use the 8259.
24*/
25#define NR_8259_INTS 0
26
27#endif /* __MACH_HERMES_H */
diff --git a/arch/ppc/platforms/ip860.h b/arch/ppc/platforms/ip860.h
new file mode 100644
index 000000000000..8c3836c5f054
--- /dev/null
+++ b/arch/ppc/platforms/ip860.h
@@ -0,0 +1,36 @@
1/*
2 * MicroSys IP860 VMEBus board specific definitions
3 *
4 * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_IP860_H
8#define __MACH_IP860_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define IP860_IMMR_BASE 0xF1000000 /* phys. addr of IMMR */
15#define IP860_IMAP_SIZE (64 * 1024) /* size of mapped area */
16
17#define IMAP_ADDR IP860_IMMR_BASE /* physical base address of IMMR area */
18#define IMAP_SIZE IP860_IMAP_SIZE /* mapped size of IMMR area */
19
20/*
21 * MPC8xx Chip Select Usage
22 */
23#define IP860_BOOT_CS 0 /* Boot (VMEBus or Flash) Chip Select 0 */
24#define IP860_FLASH_CS 1 /* Flash is on Chip Select 1 */
25#define IP860_SDRAM_CS 2 /* SDRAM is on Chip Select 2 */
26#define IP860_SRAM_CS 3 /* SRAM is on Chip Select 3 */
27#define IP860_BCSR_CS 4 /* BCSR is on Chip Select 4 */
28#define IP860_IP_CS 5 /* IP Slots are on Chip Select 5 */
29#define IP860_VME_STD_CS 6 /* VME Standard I/O is on Chip Select 6 */
30#define IP860_VME_SHORT_CS 7 /* VME Short I/O is on Chip Select 7 */
31
32/* We don't use the 8259.
33*/
34#define NR_8259_INTS 0
35
36#endif /* __MACH_IP860_H */
diff --git a/arch/ppc/platforms/ivms8.h b/arch/ppc/platforms/ivms8.h
new file mode 100644
index 000000000000..d4be310f8084
--- /dev/null
+++ b/arch/ppc/platforms/ivms8.h
@@ -0,0 +1,56 @@
1/*
2 * Speech Design Integrated Voicemail board specific definitions
3 * - IVMS8 (small, 8 channels)
4 * - IVML24 (large, 24 channels)
5 *
6 * In 2.5 when we force a new bootloader, we can merge these two, and add
7 * in _MACH_'s for them. -- Tom
8 *
9 * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de)
10 */
11
12#ifdef __KERNEL__
13#ifndef __ASM_IVMS8_H__
14#define __ASM_IVMS8_H__
15
16#include <linux/config.h>
17
18#include <asm/ppcboot.h>
19
20#define IVMS_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */
21#define IVMS_IMAP_SIZE (64 * 1024) /* size of mapped area */
22
23#define IMAP_ADDR IVMS_IMMR_BASE /* phys. base address of IMMR area */
24#define IMAP_SIZE IVMS_IMAP_SIZE /* mapped size of IMMR area */
25
26#define PCMCIA_MEM_ADDR ((uint)0xFE100000)
27#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
28
29#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */
30#define IDE0_INTERRUPT 10 /* = IRQ5 */
31#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */
32#define PHY_INTERRUPT 12 /* = IRQ6 */
33
34/* override the default number of IDE hardware interfaces */
35#define MAX_HWIFS 1
36
37/*
38 * Definitions for IDE0 Interface
39 */
40#define IDE0_BASE_OFFSET 0x0000 /* Offset in PCMCIA memory */
41#define IDE0_DATA_REG_OFFSET 0x0000
42#define IDE0_ERROR_REG_OFFSET 0x0081
43#define IDE0_NSECTOR_REG_OFFSET 0x0082
44#define IDE0_SECTOR_REG_OFFSET 0x0083
45#define IDE0_LCYL_REG_OFFSET 0x0084
46#define IDE0_HCYL_REG_OFFSET 0x0085
47#define IDE0_SELECT_REG_OFFSET 0x0086
48#define IDE0_STATUS_REG_OFFSET 0x0087
49#define IDE0_CONTROL_REG_OFFSET 0x0106
50#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */
51
52/* We don't use the 8259. */
53#define NR_8259_INTS 0
54
55#endif /* __ASM_IVMS8_H__ */
56#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/k2.c b/arch/ppc/platforms/k2.c
new file mode 100644
index 000000000000..aacb438708ff
--- /dev/null
+++ b/arch/ppc/platforms/k2.c
@@ -0,0 +1,613 @@
1/*
2 * arch/ppc/platforms/k2.c
3 *
4 * Board setup routines for SBS K2
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * Updated by: Randy Vinson <rvinson@mvista.com.
9 *
10 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/types.h>
25#include <linux/major.h>
26#include <linux/initrd.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/ide.h>
30#include <linux/irq.h>
31#include <linux/seq_file.h>
32#include <linux/root_dev.h>
33
34#include <asm/system.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <asm/dma.h>
38#include <asm/io.h>
39#include <asm/machdep.h>
40#include <asm/time.h>
41#include <asm/i8259.h>
42#include <asm/todc.h>
43#include <asm/bootinfo.h>
44
45#include <syslib/cpc710.h>
46#include "k2.h"
47
48extern unsigned long loops_per_jiffy;
49extern void gen550_progress(char *, unsigned short);
50
51static unsigned int cpu_7xx[16] = {
52 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
53};
54static unsigned int cpu_6xx[16] = {
55 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0
56};
57
58static inline int __init
59k2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
60{
61 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
62 /*
63 * Check our hose index. If we are zero then we are on the
64 * local PCI hose, otherwise we are on the cPCI hose.
65 */
66 if (!hose->index) {
67 static char pci_irq_table[][4] =
68 /*
69 * PCI IDSEL/INTPIN->INTLINE
70 * A B C D
71 */
72 {
73 {1, 0, 0, 0}, /* Ethernet */
74 {5, 5, 5, 5}, /* PMC Site 1 */
75 {6, 6, 6, 6}, /* PMC Site 2 */
76 {0, 0, 0, 0}, /* unused */
77 {0, 0, 0, 0}, /* unused */
78 {0, 0, 0, 0}, /* PCI-ISA Bridge */
79 {0, 0, 0, 0}, /* unused */
80 {0, 0, 0, 0}, /* unused */
81 {0, 0, 0, 0}, /* unused */
82 {0, 0, 0, 0}, /* unused */
83 {0, 0, 0, 0}, /* unused */
84 {0, 0, 0, 0}, /* unused */
85 {0, 0, 0, 0}, /* unused */
86 {0, 0, 0, 0}, /* unused */
87 {15, 0, 0, 0}, /* M5229 IDE */
88 };
89 const long min_idsel = 3, max_idsel = 17, irqs_per_slot = 4;
90 return PCI_IRQ_TABLE_LOOKUP;
91 } else {
92 static char pci_irq_table[][4] =
93 /*
94 * PCI IDSEL/INTPIN->INTLINE
95 * A B C D
96 */
97 {
98 {10, 11, 12, 9}, /* cPCI slot 8 */
99 {11, 12, 9, 10}, /* cPCI slot 7 */
100 {12, 9, 10, 11}, /* cPCI slot 6 */
101 {9, 10, 11, 12}, /* cPCI slot 5 */
102 {10, 11, 12, 9}, /* cPCI slot 4 */
103 {11, 12, 9, 10}, /* cPCI slot 3 */
104 {12, 9, 10, 11}, /* cPCI slot 2 */
105 };
106 const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4;
107 return PCI_IRQ_TABLE_LOOKUP;
108 }
109}
110
111void k2_pcibios_fixup(void)
112{
113#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
114 struct pci_dev *ide_dev;
115
116 /*
117 * Enable DMA support on hdc
118 */
119 ide_dev = pci_get_device(PCI_VENDOR_ID_AL,
120 PCI_DEVICE_ID_AL_M5229, NULL);
121
122 if (ide_dev) {
123
124 unsigned long ide_dma_base;
125
126 ide_dma_base = pci_resource_start(ide_dev, 4);
127 outb(0x00, ide_dma_base + 0x2);
128 outb(0x20, ide_dma_base + 0xa);
129 pci_dev_put(ide_dev);
130 }
131#endif
132}
133
134void k2_pcibios_fixup_resources(struct pci_dev *dev)
135{
136 int i;
137
138 if ((dev->vendor == PCI_VENDOR_ID_IBM) &&
139 (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64)) {
140 pr_debug("Fixup CPC710 resources\n");
141 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
142 dev->resource[i].start = 0;
143 dev->resource[i].end = 0;
144 }
145 }
146}
147
148void k2_setup_hoses(void)
149{
150 struct pci_controller *hose_a, *hose_b;
151
152 /*
153 * Reconfigure CPC710 memory map so
154 * we have some more PCI memory space.
155 */
156
157 /* Set FPHB mode */
158 __raw_writel(0x808000e0, PGCHP); /* Set FPHB mode */
159
160 /* PCI32 mappings */
161 __raw_writel(0x00000000, K2_PCI32_BAR + PIBAR); /* PCI I/O base */
162 __raw_writel(0x00000000, K2_PCI32_BAR + PMBAR); /* PCI Mem base */
163 __raw_writel(0xf0000000, K2_PCI32_BAR + MSIZE); /* 256MB */
164 __raw_writel(0xfff00000, K2_PCI32_BAR + IOSIZE); /* 1MB */
165 __raw_writel(0xc0000000, K2_PCI32_BAR + SMBAR); /* Base@0xc0000000 */
166 __raw_writel(0x80000000, K2_PCI32_BAR + SIBAR); /* Base@0x80000000 */
167 __raw_writel(0x000000c0, K2_PCI32_BAR + PSSIZE); /* 1GB space */
168 __raw_writel(0x000000c0, K2_PCI32_BAR + PPSIZE); /* 1GB space */
169 __raw_writel(0x00000000, K2_PCI32_BAR + BARPS); /* Base@0x00000000 */
170 __raw_writel(0x00000000, K2_PCI32_BAR + BARPP); /* Base@0x00000000 */
171 __raw_writel(0x00000080, K2_PCI32_BAR + PSBAR); /* Base@0x80 */
172 __raw_writel(0x00000000, K2_PCI32_BAR + PPBAR);
173
174 __raw_writel(0xc0000000, K2_PCI32_BAR + BPMDLK);
175 __raw_writel(0xd0000000, K2_PCI32_BAR + TPMDLK);
176 __raw_writel(0x80000000, K2_PCI32_BAR + BIODLK);
177 __raw_writel(0x80100000, K2_PCI32_BAR + TIODLK);
178 __raw_writel(0xe0008000, K2_PCI32_BAR + DLKCTRL);
179 __raw_writel(0xffffffff, K2_PCI32_BAR + DLKDEV);
180
181 /* PCI64 mappings */
182 __raw_writel(0x00100000, K2_PCI64_BAR + PIBAR); /* PCI I/O base */
183 __raw_writel(0x10000000, K2_PCI64_BAR + PMBAR); /* PCI Mem base */
184 __raw_writel(0xf0000000, K2_PCI64_BAR + MSIZE); /* 256MB */
185 __raw_writel(0xfff00000, K2_PCI64_BAR + IOSIZE); /* 1MB */
186 __raw_writel(0xd0000000, K2_PCI64_BAR + SMBAR); /* Base@0xd0000000 */
187 __raw_writel(0x80100000, K2_PCI64_BAR + SIBAR); /* Base@0x80100000 */
188 __raw_writel(0x000000c0, K2_PCI64_BAR + PSSIZE); /* 1GB space */
189 __raw_writel(0x000000c0, K2_PCI64_BAR + PPSIZE); /* 1GB space */
190 __raw_writel(0x00000000, K2_PCI64_BAR + BARPS); /* Base@0x00000000 */
191 __raw_writel(0x00000000, K2_PCI64_BAR + BARPP); /* Base@0x00000000 */
192
193 /* Setup PCI32 hose */
194 hose_a = pcibios_alloc_controller();
195 if (!hose_a)
196 return;
197
198 hose_a->first_busno = 0;
199 hose_a->last_busno = 0xff;
200 hose_a->pci_mem_offset = K2_PCI32_MEM_BASE;
201
202 pci_init_resource(&hose_a->io_resource,
203 K2_PCI32_LOWER_IO,
204 K2_PCI32_UPPER_IO,
205 IORESOURCE_IO, "PCI32 host bridge");
206
207 pci_init_resource(&hose_a->mem_resources[0],
208 K2_PCI32_LOWER_MEM + K2_PCI32_MEM_BASE,
209 K2_PCI32_UPPER_MEM + K2_PCI32_MEM_BASE,
210 IORESOURCE_MEM, "PCI32 host bridge");
211
212 hose_a->io_space.start = K2_PCI32_LOWER_IO;
213 hose_a->io_space.end = K2_PCI32_UPPER_IO;
214 hose_a->mem_space.start = K2_PCI32_LOWER_MEM;
215 hose_a->mem_space.end = K2_PCI32_UPPER_MEM;
216 hose_a->io_base_virt = (void *)K2_ISA_IO_BASE;
217
218 setup_indirect_pci(hose_a, K2_PCI32_CONFIG_ADDR, K2_PCI32_CONFIG_DATA);
219
220 /* Initialize PCI32 bus registers */
221 early_write_config_byte(hose_a,
222 hose_a->first_busno,
223 PCI_DEVFN(0, 0),
224 CPC710_BUS_NUMBER, hose_a->first_busno);
225
226 early_write_config_byte(hose_a,
227 hose_a->first_busno,
228 PCI_DEVFN(0, 0),
229 CPC710_SUB_BUS_NUMBER, hose_a->last_busno);
230
231 /* Enable PCI interrupt polling */
232 early_write_config_byte(hose_a,
233 hose_a->first_busno,
234 PCI_DEVFN(8, 0), 0x45, 0x80);
235
236 /* Route polled PCI interrupts */
237 early_write_config_byte(hose_a,
238 hose_a->first_busno,
239 PCI_DEVFN(8, 0), 0x48, 0x58);
240
241 early_write_config_byte(hose_a,
242 hose_a->first_busno,
243 PCI_DEVFN(8, 0), 0x49, 0x07);
244
245 early_write_config_byte(hose_a,
246 hose_a->first_busno,
247 PCI_DEVFN(8, 0), 0x4a, 0x31);
248
249 early_write_config_byte(hose_a,
250 hose_a->first_busno,
251 PCI_DEVFN(8, 0), 0x4b, 0xb9);
252
253 /* route secondary IDE channel interrupt to IRQ 15 */
254 early_write_config_byte(hose_a,
255 hose_a->first_busno,
256 PCI_DEVFN(8, 0), 0x75, 0x0f);
257
258 /* enable IDE controller IDSEL */
259 early_write_config_byte(hose_a,
260 hose_a->first_busno,
261 PCI_DEVFN(8, 0), 0x58, 0x48);
262
263 /* Enable IDE function */
264 early_write_config_byte(hose_a,
265 hose_a->first_busno,
266 PCI_DEVFN(17, 0), 0x50, 0x03);
267
268 /* Set M5229 IDE controller to native mode */
269 early_write_config_byte(hose_a,
270 hose_a->first_busno,
271 PCI_DEVFN(17, 0), PCI_CLASS_PROG, 0xdf);
272
273 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
274
275 /* Write out correct max subordinate bus number for hose A */
276 early_write_config_byte(hose_a,
277 hose_a->first_busno,
278 PCI_DEVFN(0, 0),
279 CPC710_SUB_BUS_NUMBER, hose_a->last_busno);
280
281 /* Only setup PCI64 hose if we are in the system slot */
282 if (!(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK)) {
283 /* Setup PCI64 hose */
284 hose_b = pcibios_alloc_controller();
285 if (!hose_b)
286 return;
287
288 hose_b->first_busno = hose_a->last_busno + 1;
289 hose_b->last_busno = 0xff;
290
291 /* Reminder: quit changing the following, it is correct. */
292 hose_b->pci_mem_offset = K2_PCI32_MEM_BASE;
293
294 pci_init_resource(&hose_b->io_resource,
295 K2_PCI64_LOWER_IO,
296 K2_PCI64_UPPER_IO,
297 IORESOURCE_IO, "PCI64 host bridge");
298
299 pci_init_resource(&hose_b->mem_resources[0],
300 K2_PCI64_LOWER_MEM + K2_PCI32_MEM_BASE,
301 K2_PCI64_UPPER_MEM + K2_PCI32_MEM_BASE,
302 IORESOURCE_MEM, "PCI64 host bridge");
303
304 hose_b->io_space.start = K2_PCI64_LOWER_IO;
305 hose_b->io_space.end = K2_PCI64_UPPER_IO;
306 hose_b->mem_space.start = K2_PCI64_LOWER_MEM;
307 hose_b->mem_space.end = K2_PCI64_UPPER_MEM;
308 hose_b->io_base_virt = (void *)K2_ISA_IO_BASE;
309
310 setup_indirect_pci(hose_b,
311 K2_PCI64_CONFIG_ADDR, K2_PCI64_CONFIG_DATA);
312
313 /* Initialize PCI64 bus registers */
314 early_write_config_byte(hose_b,
315 0,
316 PCI_DEVFN(0, 0),
317 CPC710_SUB_BUS_NUMBER, 0xff);
318
319 early_write_config_byte(hose_b,
320 0,
321 PCI_DEVFN(0, 0),
322 CPC710_BUS_NUMBER, hose_b->first_busno);
323
324 hose_b->last_busno = pciauto_bus_scan(hose_b,
325 hose_b->first_busno);
326
327 /* Write out correct max subordinate bus number for hose B */
328 early_write_config_byte(hose_b,
329 hose_b->first_busno,
330 PCI_DEVFN(0, 0),
331 CPC710_SUB_BUS_NUMBER,
332 hose_b->last_busno);
333
334 /* Configure PCI64 PSBAR */
335 early_write_config_dword(hose_b,
336 hose_b->first_busno,
337 PCI_DEVFN(0, 0),
338 PCI_BASE_ADDRESS_0,
339 K2_PCI64_SYS_MEM_BASE);
340 }
341
342 /* Configure i8259 level/edge settings */
343 outb(0x62, 0x4d0);
344 outb(0xde, 0x4d1);
345
346#ifdef CONFIG_CPC710_DATA_GATHERING
347 {
348 unsigned int tmp;
349 tmp = __raw_readl(ABCNTL);
350 /* Enable data gathering on both PCI interfaces */
351 __raw_writel(tmp | 0x05000000, ABCNTL);
352 }
353#endif
354
355 ppc_md.pcibios_fixup = k2_pcibios_fixup;
356 ppc_md.pcibios_fixup_resources = k2_pcibios_fixup_resources;
357 ppc_md.pci_swizzle = common_swizzle;
358 ppc_md.pci_map_irq = k2_map_irq;
359}
360
361static int k2_get_bus_speed(void)
362{
363 int bus_speed;
364 unsigned char board_id;
365
366 board_id = *(unsigned char *)K2_BOARD_ID_REG;
367
368 switch (K2_BUS_SPD(board_id)) {
369
370 case 0:
371 default:
372 bus_speed = 100000000;
373 break;
374
375 case 1:
376 bus_speed = 83333333;
377 break;
378
379 case 2:
380 bus_speed = 75000000;
381 break;
382
383 case 3:
384 bus_speed = 66666666;
385 break;
386 }
387 return bus_speed;
388}
389
390static int k2_get_cpu_speed(void)
391{
392 unsigned long hid1;
393 int cpu_speed;
394
395 hid1 = mfspr(SPRN_HID1) >> 28;
396
397 if ((mfspr(SPRN_PVR) >> 16) == 8)
398 hid1 = cpu_7xx[hid1];
399 else
400 hid1 = cpu_6xx[hid1];
401
402 cpu_speed = k2_get_bus_speed() * hid1 / 2;
403 return cpu_speed;
404}
405
406static void __init k2_calibrate_decr(void)
407{
408 int freq, divisor = 4;
409
410 /* determine processor bus speed */
411 freq = k2_get_bus_speed();
412 tb_ticks_per_jiffy = freq / HZ / divisor;
413 tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
414}
415
416static int k2_show_cpuinfo(struct seq_file *m)
417{
418 unsigned char k2_geo_bits, k2_system_slot;
419
420 seq_printf(m, "vendor\t\t: SBS\n");
421 seq_printf(m, "machine\t\t: K2\n");
422 seq_printf(m, "cpu speed\t: %dMhz\n", k2_get_cpu_speed() / 1000000);
423 seq_printf(m, "bus speed\t: %dMhz\n", k2_get_bus_speed() / 1000000);
424 seq_printf(m, "memory type\t: SDRAM\n");
425
426 k2_geo_bits = readb(K2_MSIZ_GEO_REG) & K2_GEO_ADR_MASK;
427 k2_system_slot = !(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK);
428 seq_printf(m, "backplane\t: %s slot board",
429 k2_system_slot ? "System" : "Non system");
430 seq_printf(m, "with geographical address %x\n", k2_geo_bits);
431
432 return 0;
433}
434
435TODC_ALLOC();
436
437static void __init k2_setup_arch(void)
438{
439 unsigned int cpu;
440
441 /* Setup TODC access */
442 TODC_INIT(TODC_TYPE_MK48T37, 0, 0,
443 ioremap(K2_RTC_BASE_ADDRESS, K2_RTC_SIZE), 8);
444
445 /* init to some ~sane value until calibrate_delay() runs */
446 loops_per_jiffy = 50000000 / HZ;
447
448 /* make FLASH transactions higher priority than PCI to avoid deadlock */
449 __raw_writel(__raw_readl(SIOC1) | 0x80000000, SIOC1);
450
451 /* Set hardware to access FLASH page 2 */
452 __raw_writel(1 << 29, GPOUT);
453
454 /* Setup PCI host bridges */
455 k2_setup_hoses();
456
457#ifdef CONFIG_BLK_DEV_INITRD
458 if (initrd_start)
459 ROOT_DEV = Root_RAM0;
460 else
461#endif
462#ifdef CONFIG_ROOT_NFS
463 ROOT_DEV = Root_NFS;
464#else
465 ROOT_DEV = Root_HDC1;
466#endif
467
468 /* Identify the system */
469 printk(KERN_INFO "System Identification: SBS K2 - PowerPC 750 @ "
470 "%d Mhz\n", k2_get_cpu_speed() / 1000000);
471 printk(KERN_INFO "Port by MontaVista Software, Inc. "
472 "(source@mvista.com)\n");
473
474 /* Identify the CPU manufacturer */
475 cpu = PVR_REV(mfspr(SPRN_PVR));
476 printk(KERN_INFO "CPU manufacturer: %s [rev=%04x]\n",
477 (cpu & (1 << 15)) ? "IBM" : "Motorola", cpu);
478}
479
480static void k2_restart(char *cmd)
481{
482 local_irq_disable();
483
484 /* Flip FLASH back to page 1 to access firmware image */
485 __raw_writel(0, GPOUT);
486
487 /* SRR0 has system reset vector, SRR1 has default MSR value */
488 /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
489 mtspr(SPRN_SRR0, 0xfff00100);
490 mtspr(SPRN_SRR1, 0);
491 __asm__ __volatile__("rfi\n\t");
492
493 /* not reached */
494 for (;;) ;
495}
496
497static void k2_power_off(void)
498{
499 for (;;) ;
500}
501
502static void k2_halt(void)
503{
504 k2_restart(NULL);
505}
506
507/*
508 * Set BAT 3 to map PCI32 I/O space.
509 */
510static __inline__ void k2_set_bat(void)
511{
512 /* wait for all outstanding memory accesses to complete */
513 mb();
514
515 /* setup DBATs */
516 mtspr(SPRN_DBAT2U, 0x80001ffe);
517 mtspr(SPRN_DBAT2L, 0x8000002a);
518 mtspr(SPRN_DBAT3U, 0xf0001ffe);
519 mtspr(SPRN_DBAT3L, 0xf000002a);
520
521 /* wait for updates */
522 mb();
523}
524
525static unsigned long __init k2_find_end_of_memory(void)
526{
527 unsigned long total;
528 unsigned char msize = 7; /* Default to 128MB */
529
530 msize = K2_MEM_SIZE(readb(K2_MSIZ_GEO_REG));
531
532 switch (msize) {
533 case 2:
534 /*
535 * This will break without a lowered
536 * KERNELBASE or CONFIG_HIGHMEM on.
537 * It seems non 1GB builds exist yet,
538 * though.
539 */
540 total = K2_MEM_SIZE_1GB;
541 break;
542 case 3:
543 case 4:
544 total = K2_MEM_SIZE_512MB;
545 break;
546 case 5:
547 case 6:
548 total = K2_MEM_SIZE_256MB;
549 break;
550 case 7:
551 total = K2_MEM_SIZE_128MB;
552 break;
553 default:
554 printk
555 ("K2: Invalid memory size detected, defaulting to 128MB\n");
556 total = K2_MEM_SIZE_128MB;
557 break;
558 }
559 return total;
560}
561
562static void __init k2_map_io(void)
563{
564 io_block_mapping(K2_PCI32_IO_BASE,
565 K2_PCI32_IO_BASE, 0x00200000, _PAGE_IO);
566 io_block_mapping(0xff000000, 0xff000000, 0x01000000, _PAGE_IO);
567}
568
569static void __init k2_init_irq(void)
570{
571 int i;
572
573 for (i = 0; i < 16; i++)
574 irq_desc[i].handler = &i8259_pic;
575
576 i8259_init(0);
577}
578
579void __init platform_init(unsigned long r3, unsigned long r4,
580 unsigned long r5, unsigned long r6, unsigned long r7)
581{
582 parse_bootinfo((struct bi_record *)(r3 + KERNELBASE));
583
584 k2_set_bat();
585
586 isa_io_base = K2_ISA_IO_BASE;
587 isa_mem_base = K2_ISA_MEM_BASE;
588 pci_dram_offset = K2_PCI32_SYS_MEM_BASE;
589
590 ppc_md.setup_arch = k2_setup_arch;
591 ppc_md.show_cpuinfo = k2_show_cpuinfo;
592 ppc_md.init_IRQ = k2_init_irq;
593 ppc_md.get_irq = i8259_irq;
594
595 ppc_md.find_end_of_memory = k2_find_end_of_memory;
596 ppc_md.setup_io_mappings = k2_map_io;
597
598 ppc_md.restart = k2_restart;
599 ppc_md.power_off = k2_power_off;
600 ppc_md.halt = k2_halt;
601
602 ppc_md.time_init = todc_time_init;
603 ppc_md.set_rtc_time = todc_set_rtc_time;
604 ppc_md.get_rtc_time = todc_get_rtc_time;
605 ppc_md.calibrate_decr = k2_calibrate_decr;
606
607 ppc_md.nvram_read_val = todc_direct_read_val;
608 ppc_md.nvram_write_val = todc_direct_write_val;
609
610#ifdef CONFIG_SERIAL_TEXT_DEBUG
611 ppc_md.progress = gen550_progress;
612#endif
613}
diff --git a/arch/ppc/platforms/k2.h b/arch/ppc/platforms/k2.h
new file mode 100644
index 000000000000..78326aba1988
--- /dev/null
+++ b/arch/ppc/platforms/k2.h
@@ -0,0 +1,82 @@
1/*
2 * arch/ppc/platforms/k2.h
3 *
4 * Definitions for SBS K2 board support
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __PPC_PLATFORMS_K2_H
15#define __PPC_PLATFORMS_K2_H
16
17/*
18 * SBS K2 definitions
19 */
20
21#define K2_PCI64_BAR 0xff400000
22#define K2_PCI32_BAR 0xff500000
23
24#define K2_PCI64_CONFIG_ADDR (K2_PCI64_BAR + 0x000f8000)
25#define K2_PCI64_CONFIG_DATA (K2_PCI64_BAR + 0x000f8010)
26
27#define K2_PCI32_CONFIG_ADDR (K2_PCI32_BAR + 0x000f8000)
28#define K2_PCI32_CONFIG_DATA (K2_PCI32_BAR + 0x000f8010)
29
30#define K2_PCI64_MEM_BASE 0xd0000000
31#define K2_PCI64_IO_BASE 0x80100000
32
33#define K2_PCI32_MEM_BASE 0xc0000000
34#define K2_PCI32_IO_BASE 0x80000000
35
36#define K2_PCI32_SYS_MEM_BASE 0x80000000
37#define K2_PCI64_SYS_MEM_BASE K2_PCI32_SYS_MEM_BASE
38
39#define K2_PCI32_LOWER_MEM 0x00000000
40#define K2_PCI32_UPPER_MEM 0x0fffffff
41#define K2_PCI32_LOWER_IO 0x00000000
42#define K2_PCI32_UPPER_IO 0x000fffff
43
44#define K2_PCI64_LOWER_MEM 0x10000000
45#define K2_PCI64_UPPER_MEM 0x1fffffff
46#define K2_PCI64_LOWER_IO 0x00100000
47#define K2_PCI64_UPPER_IO 0x001fffff
48
49#define K2_ISA_IO_BASE K2_PCI32_IO_BASE
50#define K2_ISA_MEM_BASE K2_PCI32_MEM_BASE
51
52#define K2_BOARD_ID_REG (K2_ISA_IO_BASE + 0x800)
53#define K2_MISC_REG (K2_ISA_IO_BASE + 0x804)
54#define K2_MSIZ_GEO_REG (K2_ISA_IO_BASE + 0x808)
55#define K2_HOT_SWAP_REG (K2_ISA_IO_BASE + 0x80c)
56#define K2_PLD2_REG (K2_ISA_IO_BASE + 0x80e)
57#define K2_PLD3_REG (K2_ISA_IO_BASE + 0x80f)
58
59#define K2_BUS_SPD(board_id) (board_id >> 2) & 3
60
61#define K2_RTC_BASE_OFFSET 0x90000
62#define K2_RTC_BASE_ADDRESS (K2_PCI32_MEM_BASE + K2_RTC_BASE_OFFSET)
63#define K2_RTC_SIZE 0x8000
64
65#define K2_MEM_SIZE_MASK 0xe0
66#define K2_MEM_SIZE(size_reg) (size_reg & K2_MEM_SIZE_MASK) >> 5
67#define K2_MEM_SIZE_1GB 0x40000000
68#define K2_MEM_SIZE_512MB 0x20000000
69#define K2_MEM_SIZE_256MB 0x10000000
70#define K2_MEM_SIZE_128MB 0x08000000
71
72#define K2_L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */
73#define K2_L2CACHE_512KB 0x00 /* 512KB */
74#define K2_L2CACHE_256KB 0x01 /* 256KB */
75#define K2_L2CACHE_1MB 0x02 /* 1MB */
76#define K2_L2CACHE_NONE 0x03 /* None */
77
78#define K2_GEO_ADR_MASK 0x1f
79
80#define K2_SYS_SLOT_MASK 0x08
81
82#endif /* __PPC_PLATFORMS_K2_H */
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
new file mode 100644
index 000000000000..eda922ac3167
--- /dev/null
+++ b/arch/ppc/platforms/katana.c
@@ -0,0 +1,795 @@
1/*
2 * arch/ppc/platforms/katana.c
3 *
4 * Board setup routines for the Artesyn Katana cPCI boards.
5 *
6 * Author: Tim Montgomery <timm@artesyncp.com>
7 * Maintained by: Mark A. Greer <mgreer@mvista.com>
8 *
9 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
10 * Based on code done by - Mark A. Greer <mgreer@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/*
18 * Supports the Artesyn 750i, 752i, and 3750. The 752i is virtually identical
19 * to the 750i except that it has an mv64460 bridge.
20 */
21#include <linux/config.h>
22#include <linux/kernel.h>
23#include <linux/pci.h>
24#include <linux/kdev_t.h>
25#include <linux/console.h>
26#include <linux/initrd.h>
27#include <linux/root_dev.h>
28#include <linux/delay.h>
29#include <linux/seq_file.h>
30#include <linux/bootmem.h>
31#include <linux/mtd/physmap.h>
32#include <linux/mv643xx.h>
33#ifdef CONFIG_BOOTIMG
34#include <linux/bootimg.h>
35#endif
36#include <asm/page.h>
37#include <asm/time.h>
38#include <asm/smp.h>
39#include <asm/todc.h>
40#include <asm/bootinfo.h>
41#include <asm/ppcboot.h>
42#include <asm/mv64x60.h>
43#include <platforms/katana.h>
44
45static struct mv64x60_handle bh;
46static katana_id_t katana_id;
47static void __iomem *cpld_base;
48static void __iomem *sram_base;
49
50static u32 katana_flash_size_0;
51static u32 katana_flash_size_1;
52
53static u32 katana_bus_frequency;
54
55unsigned char __res[sizeof(bd_t)];
56
57/* PCI Interrupt routing */
58static int __init
59katana_irq_lookup_750i(unsigned char idsel, unsigned char pin)
60{
61 static char pci_irq_table[][4] = {
62 /*
63 * PCI IDSEL/INTPIN->INTLINE
64 * A B C D
65 */
66 /* IDSEL 4 (PMC 1) */
67 { KATANA_PCI_INTB_IRQ_750i, KATANA_PCI_INTC_IRQ_750i,
68 KATANA_PCI_INTD_IRQ_750i, KATANA_PCI_INTA_IRQ_750i },
69 /* IDSEL 5 (PMC 2) */
70 { KATANA_PCI_INTC_IRQ_750i, KATANA_PCI_INTD_IRQ_750i,
71 KATANA_PCI_INTA_IRQ_750i, KATANA_PCI_INTB_IRQ_750i },
72 /* IDSEL 6 (T8110) */
73 {KATANA_PCI_INTD_IRQ_750i, 0, 0, 0 },
74 };
75 const long min_idsel = 4, max_idsel = 6, irqs_per_slot = 4;
76
77 return PCI_IRQ_TABLE_LOOKUP;
78}
79
80static int __init
81katana_irq_lookup_3750(unsigned char idsel, unsigned char pin)
82{
83 static char pci_irq_table[][4] = {
84 /*
85 * PCI IDSEL/INTPIN->INTLINE
86 * A B C D
87 */
88 { KATANA_PCI_INTA_IRQ_3750, 0, 0, 0 }, /* IDSEL 3 (BCM5691) */
89 { KATANA_PCI_INTB_IRQ_3750, 0, 0, 0 }, /* IDSEL 4 (MV64360 #2)*/
90 { KATANA_PCI_INTC_IRQ_3750, 0, 0, 0 }, /* IDSEL 5 (MV64360 #3)*/
91 };
92 const long min_idsel = 3, max_idsel = 5, irqs_per_slot = 4;
93
94 return PCI_IRQ_TABLE_LOOKUP;
95}
96
97static int __init
98katana_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
99{
100 switch (katana_id) {
101 case KATANA_ID_750I:
102 case KATANA_ID_752I:
103 return katana_irq_lookup_750i(idsel, pin);
104
105 case KATANA_ID_3750:
106 return katana_irq_lookup_3750(idsel, pin);
107
108 default:
109 printk(KERN_ERR "Bogus board ID\n");
110 return 0;
111 }
112}
113
114/* Board info retrieval routines */
115void __init
116katana_get_board_id(void)
117{
118 switch (in_8(cpld_base + KATANA_CPLD_PRODUCT_ID)) {
119 case KATANA_PRODUCT_ID_3750:
120 katana_id = KATANA_ID_3750;
121 break;
122
123 case KATANA_PRODUCT_ID_750i:
124 katana_id = KATANA_ID_750I;
125 break;
126
127 case KATANA_PRODUCT_ID_752i:
128 katana_id = KATANA_ID_752I;
129 break;
130
131 default:
132 printk(KERN_ERR "Unsupported board\n");
133 }
134}
135
136int __init
137katana_get_proc_num(void)
138{
139 u16 val;
140 u8 save_exclude;
141 static int proc = -1;
142 static u8 first_time = 1;
143
144 if (first_time) {
145 if (katana_id != KATANA_ID_3750)
146 proc = 0;
147 else {
148 save_exclude = mv64x60_pci_exclude_bridge;
149 mv64x60_pci_exclude_bridge = 0;
150
151 early_read_config_word(bh.hose_a, 0,
152 PCI_DEVFN(0,0), PCI_DEVICE_ID, &val);
153
154 mv64x60_pci_exclude_bridge = save_exclude;
155
156 switch(val) {
157 case PCI_DEVICE_ID_KATANA_3750_PROC0:
158 proc = 0;
159 break;
160
161 case PCI_DEVICE_ID_KATANA_3750_PROC1:
162 proc = 1;
163 break;
164
165 case PCI_DEVICE_ID_KATANA_3750_PROC2:
166 proc = 2;
167 break;
168
169 default:
170 printk(KERN_ERR "Bogus Device ID\n");
171 }
172 }
173
174 first_time = 0;
175 }
176
177 return proc;
178}
179
180static inline int
181katana_is_monarch(void)
182{
183 return in_8(cpld_base + KATANA_CPLD_BD_CFG_3) &
184 KATANA_CPLD_BD_CFG_3_MONARCH;
185}
186
187static void __init
188katana_setup_bridge(void)
189{
190 struct pci_controller hose;
191 struct mv64x60_setup_info si;
192 void __iomem *vaddr;
193 int i;
194 u16 val;
195 u8 save_exclude;
196
197 /*
198 * Some versions of the Katana firmware mistakenly change the vendor
199 * & device id fields in the bridge's pci device (visible via pci
200 * config accesses). This breaks mv64x60_init() because those values
201 * are used to identify the type of bridge that's there. Artesyn
202 * claims that the subsystem vendor/device id's will have the correct
203 * Marvell values so this code puts back the correct values from there.
204 */
205 memset(&hose, 0, sizeof(hose));
206 vaddr = ioremap(CONFIG_MV64X60_NEW_BASE, MV64x60_INTERNAL_SPACE_SIZE);
207 setup_indirect_pci_nomap(&hose, vaddr + MV64x60_PCI0_CONFIG_ADDR,
208 vaddr + MV64x60_PCI0_CONFIG_DATA);
209 save_exclude = mv64x60_pci_exclude_bridge;
210 mv64x60_pci_exclude_bridge = 0;
211
212 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val);
213
214 if (val != PCI_VENDOR_ID_MARVELL) {
215 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0),
216 PCI_SUBSYSTEM_VENDOR_ID, &val);
217 early_write_config_word(&hose, 0, PCI_DEVFN(0, 0),
218 PCI_VENDOR_ID, val);
219 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0),
220 PCI_SUBSYSTEM_ID, &val);
221 early_write_config_word(&hose, 0, PCI_DEVFN(0, 0),
222 PCI_DEVICE_ID, val);
223 }
224
225 mv64x60_pci_exclude_bridge = save_exclude;
226 iounmap(vaddr);
227
228 memset(&si, 0, sizeof(si));
229
230 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
231
232 si.pci_1.enable_bus = 1;
233 si.pci_1.pci_io.cpu_base = KATANA_PCI1_IO_START_PROC_ADDR;
234 si.pci_1.pci_io.pci_base_hi = 0;
235 si.pci_1.pci_io.pci_base_lo = KATANA_PCI1_IO_START_PCI_ADDR;
236 si.pci_1.pci_io.size = KATANA_PCI1_IO_SIZE;
237 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
238 si.pci_1.pci_mem[0].cpu_base = KATANA_PCI1_MEM_START_PROC_ADDR;
239 si.pci_1.pci_mem[0].pci_base_hi = KATANA_PCI1_MEM_START_PCI_HI_ADDR;
240 si.pci_1.pci_mem[0].pci_base_lo = KATANA_PCI1_MEM_START_PCI_LO_ADDR;
241 si.pci_1.pci_mem[0].size = KATANA_PCI1_MEM_SIZE;
242 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
243 si.pci_1.pci_cmd_bits = 0;
244 si.pci_1.latency_timer = 0x80;
245
246 for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) {
247#if defined(CONFIG_NOT_COHERENT_CACHE)
248 si.cpu_prot_options[i] = 0;
249 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE;
250 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE;
251 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE;
252
253 si.pci_1.acc_cntl_options[i] =
254 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
255 MV64360_PCI_ACC_CNTL_SWAP_NONE |
256 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
257 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
258#else
259 si.cpu_prot_options[i] = 0;
260 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE; /* errata */
261 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE; /* errata */
262 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE; /* errata */
263
264 si.pci_1.acc_cntl_options[i] =
265 MV64360_PCI_ACC_CNTL_SNOOP_WB |
266 MV64360_PCI_ACC_CNTL_SWAP_NONE |
267 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
268 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
269#endif
270 }
271
272 /* Lookup PCI host bridges */
273 if (mv64x60_init(&bh, &si))
274 printk(KERN_WARNING "Bridge initialization failed.\n");
275
276 pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */
277 ppc_md.pci_swizzle = common_swizzle;
278 ppc_md.pci_map_irq = katana_map_irq;
279 ppc_md.pci_exclude_device = mv64x60_pci_exclude_device;
280
281 mv64x60_set_bus(&bh, 1, 0);
282 bh.hose_b->first_busno = 0;
283 bh.hose_b->last_busno = 0xff;
284}
285
286/* Bridge & platform setup routines */
287void __init
288katana_intr_setup(void)
289{
290 /* MPP 8, 9, and 10 */
291 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0xfff);
292
293 /* MPP 14 */
294 if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I))
295 mv64x60_clr_bits(&bh, MV64x60_MPP_CNTL_1, 0x0f000000);
296
297 /*
298 * Define GPP 8,9,and 10 interrupt polarity as active low
299 * input signal and level triggered
300 */
301 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, 0x700);
302 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, 0x700);
303
304 if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {
305 mv64x60_set_bits(&bh, MV64x60_GPP_LEVEL_CNTL, (1<<14));
306 mv64x60_clr_bits(&bh, MV64x60_GPP_IO_CNTL, (1<<14));
307 }
308
309 /* Config GPP intr ctlr to respond to level trigger */
310 mv64x60_set_bits(&bh, MV64x60_COMM_ARBITER_CNTL, (1<<10));
311
312 /* Erranum FEr PCI-#8 */
313 mv64x60_clr_bits(&bh, MV64x60_PCI0_CMD, (1<<5) | (1<<9));
314 mv64x60_clr_bits(&bh, MV64x60_PCI1_CMD, (1<<5) | (1<<9));
315
316 /*
317 * Dismiss and then enable interrupt on GPP interrupt cause
318 * for CPU #0
319 */
320 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~0x700);
321 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, 0x700);
322
323 if ((katana_id == KATANA_ID_750I) || (katana_id == KATANA_ID_752I)) {
324 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1<<14));
325 mv64x60_set_bits(&bh, MV64x60_GPP_INTR_MASK, (1<<14));
326 }
327
328 /*
329 * Dismiss and then enable interrupt on CPU #0 high cause reg
330 * BIT25 summarizes GPP interrupts 8-15
331 */
332 mv64x60_set_bits(&bh, MV64360_IC_CPU0_INTR_MASK_HI, (1<<25));
333}
334
335void __init
336katana_setup_peripherals(void)
337{
338 u32 base;
339
340 /* Set up windows for boot CS, soldered & socketed flash, and CPLD */
341 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
342 KATANA_BOOT_WINDOW_BASE, KATANA_BOOT_WINDOW_SIZE, 0);
343 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
344
345 /* Assume firmware set up window sizes correctly for dev 0 & 1 */
346 mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN, &base,
347 &katana_flash_size_0);
348
349 if (katana_flash_size_0 > 0) {
350 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
351 KATANA_SOLDERED_FLASH_BASE, katana_flash_size_0, 0);
352 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_0_WIN);
353 }
354
355 mv64x60_get_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN, &base,
356 &katana_flash_size_1);
357
358 if (katana_flash_size_1 > 0) {
359 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
360 (KATANA_SOLDERED_FLASH_BASE + katana_flash_size_0),
361 katana_flash_size_1, 0);
362 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
363 }
364
365 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
366 KATANA_SOCKET_BASE, KATANA_SOCKETED_FLASH_SIZE, 0);
367 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
368
369 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
370 KATANA_CPLD_BASE, KATANA_CPLD_SIZE, 0);
371 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
372 cpld_base = ioremap(KATANA_CPLD_BASE, KATANA_CPLD_SIZE);
373
374 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
375 KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
376 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
377 sram_base = ioremap(KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE);
378
379 /* Set up Enet->SRAM window */
380 mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN,
381 KATANA_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0x2);
382 bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN);
383
384 /* Give enet r/w access to memory region */
385 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_0, (0x3 << (4 << 1)));
386 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_1, (0x3 << (4 << 1)));
387 mv64x60_set_bits(&bh, MV64360_ENET2MEM_ACC_PROT_2, (0x3 << (4 << 1)));
388
389 mv64x60_clr_bits(&bh, MV64x60_PCI1_PCI_DECODE_CNTL, (1 << 3));
390 mv64x60_clr_bits(&bh, MV64x60_TIMR_CNTR_0_3_CNTL,
391 ((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24)));
392
393 /* Must wait until window set up before retrieving board id */
394 katana_get_board_id();
395
396 /* Enumerate pci bus (must know board id before getting proc number) */
397 if (katana_get_proc_num() == 0)
398 bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b, 0);
399
400#if defined(CONFIG_NOT_COHERENT_CACHE)
401 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x00160000);
402#else
403 mv64x60_write(&bh, MV64360_SRAM_CONFIG, 0x001600b2);
404#endif
405
406 /*
407 * Setting the SRAM to 0. Note that this generates parity errors on
408 * internal data path in SRAM since it's first time accessing it
409 * while after reset it's not configured.
410 */
411 memset(sram_base, 0, MV64360_SRAM_SIZE);
412
413 /* Only processor zero [on 3750] is an PCI interrupt controller */
414 if (katana_get_proc_num() == 0)
415 katana_intr_setup();
416}
417
418static void __init
419katana_enable_ipmi(void)
420{
421 u8 reset_out;
422
423 /* Enable access to IPMI ctlr by clearing IPMI PORTSEL bit in CPLD */
424 reset_out = in_8(cpld_base + KATANA_CPLD_RESET_OUT);
425 reset_out &= ~KATANA_CPLD_RESET_OUT_PORTSEL;
426 out_8(cpld_base + KATANA_CPLD_RESET_OUT, reset_out);
427}
428
429static void __init
430katana_setup_arch(void)
431{
432 if (ppc_md.progress)
433 ppc_md.progress("katana_setup_arch: enter", 0);
434
435 set_tb(0, 0);
436
437#ifdef CONFIG_BLK_DEV_INITRD
438 if (initrd_start)
439 ROOT_DEV = Root_RAM0;
440 else
441#endif
442#ifdef CONFIG_ROOT_NFS
443 ROOT_DEV = Root_NFS;
444#else
445 ROOT_DEV = Root_SDA2;
446#endif
447
448 /*
449 * Set up the L2CR register.
450 *
451 * 750FX has only L2E, L2PE (bits 2-8 are reserved)
452 * DD2.0 has bug that requires the L2 to be in WRT mode
453 * avoid dirty data in cache
454 */
455 if (PVR_REV(mfspr(SPRN_PVR)) == 0x0200) {
456 printk(KERN_INFO "DD2.0 detected. Setting L2 cache"
457 "to Writethrough mode\n");
458 _set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2WT);
459 } else
460 _set_L2CR(L2CR_L2E | L2CR_L2PE);
461
462 if (ppc_md.progress)
463 ppc_md.progress("katana_setup_arch: calling setup_bridge", 0);
464
465 katana_setup_bridge();
466 katana_setup_peripherals();
467 katana_enable_ipmi();
468
469 katana_bus_frequency = katana_bus_freq(cpld_base);
470
471 printk(KERN_INFO "Artesyn Communication Products, LLC - Katana(TM)\n");
472 if (ppc_md.progress)
473 ppc_md.progress("katana_setup_arch: exit", 0);
474}
475
476/* Platform device data fixup routines. */
477#if defined(CONFIG_SERIAL_MPSC)
478static void __init
479katana_fixup_mpsc_pdata(struct platform_device *pdev)
480{
481 struct mpsc_pdata *pdata;
482
483 pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
484
485 pdata->max_idle = 40;
486 pdata->default_baud = KATANA_DEFAULT_BAUD;
487 pdata->brg_clk_src = KATANA_MPSC_CLK_SRC;
488 /*
489 * TCLK (not SysCLk) is routed to BRG, then to the MPSC. On most parts,
490 * TCLK == SysCLK but on 64460, they are separate pins.
491 * SysCLK can go up to 200 MHz but TCLK can only go up to 133 MHz.
492 */
493 pdata->brg_clk_freq = min(katana_bus_frequency, MV64x60_TCLK_FREQ_MAX);
494}
495#endif
496
497#if defined(CONFIG_MV643XX_ETH)
498static void __init
499katana_fixup_eth_pdata(struct platform_device *pdev)
500{
501 struct mv643xx_eth_platform_data *eth_pd;
502 static u16 phy_addr[] = {
503 KATANA_ETH0_PHY_ADDR,
504 KATANA_ETH1_PHY_ADDR,
505 KATANA_ETH2_PHY_ADDR,
506 };
507
508 eth_pd = pdev->dev.platform_data;
509 eth_pd->force_phy_addr = 1;
510 eth_pd->phy_addr = phy_addr[pdev->id];
511 eth_pd->tx_queue_size = KATANA_ETH_TX_QUEUE_SIZE;
512 eth_pd->rx_queue_size = KATANA_ETH_RX_QUEUE_SIZE;
513}
514#endif
515
516static int __init
517katana_platform_notify(struct device *dev)
518{
519 static struct {
520 char *bus_id;
521 void ((*rtn)(struct platform_device *pdev));
522 } dev_map[] = {
523#if defined(CONFIG_SERIAL_MPSC)
524 { MPSC_CTLR_NAME ".0", katana_fixup_mpsc_pdata },
525 { MPSC_CTLR_NAME ".1", katana_fixup_mpsc_pdata },
526#endif
527#if defined(CONFIG_MV643XX_ETH)
528 { MV643XX_ETH_NAME ".0", katana_fixup_eth_pdata },
529 { MV643XX_ETH_NAME ".1", katana_fixup_eth_pdata },
530 { MV643XX_ETH_NAME ".2", katana_fixup_eth_pdata },
531#endif
532 };
533 struct platform_device *pdev;
534 int i;
535
536 if (dev && dev->bus_id)
537 for (i=0; i<ARRAY_SIZE(dev_map); i++)
538 if (!strncmp(dev->bus_id, dev_map[i].bus_id,
539 BUS_ID_SIZE)) {
540
541 pdev = container_of(dev,
542 struct platform_device, dev);
543 dev_map[i].rtn(pdev);
544 }
545
546 return 0;
547}
548
549#ifdef CONFIG_MTD_PHYSMAP
550
551#ifndef MB
552#define MB (1 << 20)
553#endif
554
555/*
556 * MTD Layout depends on amount of soldered FLASH in system. Sizes in MB.
557 *
558 * FLASH Amount: 128 64 32 16
559 * ------------- --- -- -- --
560 * Monitor: 1 1 1 1
561 * Primary Kernel: 1.5 1.5 1.5 1.5
562 * Primary fs: 30 30 <end> <end>
563 * Secondary Kernel: 1.5 1.5 N/A N/A
564 * Secondary fs: <end> <end> N/A N/A
565 * User: <overlays entire FLASH except for "Monitor" section>
566 */
567static int __init
568katana_setup_mtd(void)
569{
570 u32 size;
571 int ptbl_entries;
572 static struct mtd_partition *ptbl;
573
574 size = katana_flash_size_0 + katana_flash_size_1;
575 if (!size)
576 return -ENOMEM;
577
578 ptbl_entries = (size >= (64*MB)) ? 6 : 4;
579
580 if ((ptbl = kmalloc(ptbl_entries * sizeof(struct mtd_partition),
581 GFP_KERNEL)) == NULL) {
582
583 printk(KERN_WARNING "Can't alloc MTD partition table\n");
584 return -ENOMEM;
585 }
586 memset(ptbl, 0, ptbl_entries * sizeof(struct mtd_partition));
587
588 ptbl[0].name = "Monitor";
589 ptbl[0].size = KATANA_MTD_MONITOR_SIZE;
590 ptbl[1].name = "Primary Kernel";
591 ptbl[1].offset = MTDPART_OFS_NXTBLK;
592 ptbl[1].size = 0x00180000; /* 1.5 MB */
593 ptbl[2].name = "Primary Filesystem";
594 ptbl[2].offset = MTDPART_OFS_APPEND;
595 ptbl[2].size = MTDPART_SIZ_FULL; /* Correct for 16 & 32 MB */
596 ptbl[ptbl_entries-1].name = "User FLASH";
597 ptbl[ptbl_entries-1].offset = KATANA_MTD_MONITOR_SIZE;
598 ptbl[ptbl_entries-1].size = MTDPART_SIZ_FULL;
599
600 if (size >= (64*MB)) {
601 ptbl[2].size = 30*MB;
602 ptbl[3].name = "Secondary Kernel";
603 ptbl[3].offset = MTDPART_OFS_NXTBLK;
604 ptbl[3].size = 0x00180000; /* 1.5 MB */
605 ptbl[4].name = "Secondary Filesystem";
606 ptbl[4].offset = MTDPART_OFS_APPEND;
607 ptbl[4].size = MTDPART_SIZ_FULL;
608 }
609
610 physmap_map.size = size;
611 physmap_set_partitions(ptbl, ptbl_entries);
612 return 0;
613}
614
615arch_initcall(katana_setup_mtd);
616#endif
617
618static void
619katana_restart(char *cmd)
620{
621 ulong i = 10000000;
622
623 /* issue hard reset to the reset command register */
624 out_8(cpld_base + KATANA_CPLD_RST_CMD, KATANA_CPLD_RST_CMD_HR);
625
626 while (i-- > 0) ;
627 panic("restart failed\n");
628}
629
630static void
631katana_halt(void)
632{
633 u8 v;
634
635 if (katana_id == KATANA_ID_752I) {
636 v = in_8(cpld_base + HSL_PLD_BASE + HSL_PLD_HOT_SWAP_OFF);
637 v |= HSL_PLD_HOT_SWAP_LED_BIT;
638 out_8(cpld_base + HSL_PLD_BASE + HSL_PLD_HOT_SWAP_OFF, v);
639 }
640
641 while (1) ;
642 /* NOTREACHED */
643}
644
645static void
646katana_power_off(void)
647{
648 katana_halt();
649 /* NOTREACHED */
650}
651
652static int
653katana_show_cpuinfo(struct seq_file *m)
654{
655 seq_printf(m, "vendor\t\t: Artesyn Communication Products, LLC\n");
656
657 seq_printf(m, "board\t\t: ");
658
659 switch (katana_id) {
660 case KATANA_ID_3750:
661 seq_printf(m, "Katana 3750\n");
662 break;
663
664 case KATANA_ID_750I:
665 seq_printf(m, "Katana 750i\n");
666 break;
667
668 case KATANA_ID_752I:
669 seq_printf(m, "Katana 752i\n");
670 break;
671
672 default:
673 seq_printf(m, "Unknown\n");
674 break;
675 }
676
677 seq_printf(m, "product ID\t: 0x%x\n",
678 in_8(cpld_base + KATANA_CPLD_PRODUCT_ID));
679 seq_printf(m, "hardware rev\t: 0x%x\n",
680 in_8(cpld_base+KATANA_CPLD_HARDWARE_VER));
681 seq_printf(m, "PLD rev\t\t: 0x%x\n",
682 in_8(cpld_base + KATANA_CPLD_PLD_VER));
683 seq_printf(m, "PLB freq\t: %ldMhz\n",
684 (long)katana_bus_frequency / 1000000);
685 seq_printf(m, "PCI\t\t: %sMonarch\n", katana_is_monarch()? "" : "Non-");
686
687 return 0;
688}
689
690static void __init
691katana_calibrate_decr(void)
692{
693 u32 freq;
694
695 freq = katana_bus_frequency / 4;
696
697 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
698 (long)freq / 1000000, (long)freq % 1000000);
699
700 tb_ticks_per_jiffy = freq / HZ;
701 tb_to_us = mulhwu_scale_factor(freq, 1000000);
702}
703
704unsigned long __init
705katana_find_end_of_memory(void)
706{
707 return mv64x60_get_mem_size(CONFIG_MV64X60_NEW_BASE,
708 MV64x60_TYPE_MV64360);
709}
710
711#if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00)
712extern ulong m41t00_get_rtc_time(void);
713extern int m41t00_set_rtc_time(ulong);
714
715static int __init
716katana_rtc_hookup(void)
717{
718 struct timespec tv;
719
720 ppc_md.get_rtc_time = m41t00_get_rtc_time;
721 ppc_md.set_rtc_time = m41t00_set_rtc_time;
722
723 tv.tv_nsec = 0;
724 tv.tv_sec = (ppc_md.get_rtc_time)();
725 do_settimeofday(&tv);
726
727 return 0;
728}
729late_initcall(katana_rtc_hookup);
730#endif
731
732static inline void
733katana_set_bat(void)
734{
735 mb();
736 mtspr(SPRN_DBAT2U, 0xf0001ffe);
737 mtspr(SPRN_DBAT2L, 0xf000002a);
738 mb();
739}
740
741#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
742static void __init
743katana_map_io(void)
744{
745 io_block_mapping(0xf8100000, 0xf8100000, 0x00020000, _PAGE_IO);
746}
747#endif
748
749void __init
750platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
751 unsigned long r6, unsigned long r7)
752{
753 parse_bootinfo(find_bootinfo());
754
755 /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer)
756 * are non-zero, then we should use the board info from the bd_t
757 * structure and the cmdline pointed to by r6 instead of the
758 * information from birecs, if any. Otherwise, use the information
759 * from birecs as discovered by the preceeding call to
760 * parse_bootinfo(). This rule should work with both PPCBoot, which
761 * uses a bd_t board info structure, and the kernel boot wrapper,
762 * which uses birecs.
763 */
764 if (r3 && r6) {
765 /* copy board info structure */
766 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
767 /* copy command line */
768 *(char *)(r7+KERNELBASE) = 0;
769 strcpy(cmd_line, (char *)(r6+KERNELBASE));
770 }
771
772 isa_mem_base = 0;
773
774 ppc_md.setup_arch = katana_setup_arch;
775 ppc_md.show_cpuinfo = katana_show_cpuinfo;
776 ppc_md.init_IRQ = mv64360_init_irq;
777 ppc_md.get_irq = mv64360_get_irq;
778 ppc_md.restart = katana_restart;
779 ppc_md.power_off = katana_power_off;
780 ppc_md.halt = katana_halt;
781 ppc_md.find_end_of_memory = katana_find_end_of_memory;
782 ppc_md.calibrate_decr = katana_calibrate_decr;
783
784#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
785 ppc_md.setup_io_mappings = katana_map_io;
786 ppc_md.progress = mv64x60_mpsc_progress;
787 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
788#endif
789
790#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)
791 platform_notify = katana_platform_notify;
792#endif
793
794 katana_set_bat(); /* Need for katana_find_end_of_memory and progress */
795}
diff --git a/arch/ppc/platforms/katana.h b/arch/ppc/platforms/katana.h
new file mode 100644
index 000000000000..b82ed81950f5
--- /dev/null
+++ b/arch/ppc/platforms/katana.h
@@ -0,0 +1,255 @@
1/*
2 * arch/ppc/platforms/katana.h
3 *
4 * Definitions for Artesyn Katana750i/3750 board.
5 *
6 * Author: Tim Montgomery <timm@artesyncp.com>
7 * Maintained by: Mark A. Greer <mgreer@mvista.com>
8 *
9 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
10 * Based on code done by Mark A. Greer <mgreer@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
18/*
19 * The MV64360 has 2 PCI buses each with 1 window from the CPU bus to
20 * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
21 * We'll only use one PCI MEM window on each PCI bus.
22 *
23 * This is the CPU physical memory map (windows must be at least 64 KB and start
24 * on a boundary that is a multiple of the window size):
25 *
26 * 0xff800000-0xffffffff - Boot window
27 * 0xf8400000-0xf843ffff - Internal SRAM
28 * 0xf8200000-0xf83fffff - CPLD
29 * 0xf8100000-0xf810ffff - MV64360 Registers (CONFIG_MV64X60_NEW_BASE)
30 * 0xf8000000-0xf80fffff - Socketed FLASH
31 * 0xe0000000-0xefffffff - Soldered FLASH
32 * 0xc0000000-0xc3ffffff - PCI I/O (second hose)
33 * 0x80000000-0xbfffffff - PCI MEM (second hose)
34 */
35
36#ifndef __PPC_PLATFORMS_KATANA_H
37#define __PPC_PLATFORMS_KATANA_H
38
39/* CPU Physical Memory Map setup. */
40#define KATANA_BOOT_WINDOW_BASE 0xff800000
41#define KATANA_BOOT_WINDOW_SIZE 0x00800000 /* 8 MB */
42#define KATANA_INTERNAL_SRAM_BASE 0xf8400000
43#define KATANA_CPLD_BASE 0xf8200000
44#define KATANA_CPLD_SIZE 0x00200000 /* 2 MB */
45#define KATANA_SOCKET_BASE 0xf8000000
46#define KATANA_SOCKETED_FLASH_SIZE 0x00100000 /* 1 MB */
47#define KATANA_SOLDERED_FLASH_BASE 0xe0000000
48#define KATANA_SOLDERED_FLASH_SIZE 0x10000000 /* 256 MB */
49
50#define KATANA_PCI1_MEM_START_PROC_ADDR 0x80000000
51#define KATANA_PCI1_MEM_START_PCI_HI_ADDR 0x00000000
52#define KATANA_PCI1_MEM_START_PCI_LO_ADDR 0x80000000
53#define KATANA_PCI1_MEM_SIZE 0x40000000 /* 1 GB */
54#define KATANA_PCI1_IO_START_PROC_ADDR 0xc0000000
55#define KATANA_PCI1_IO_START_PCI_ADDR 0x00000000
56#define KATANA_PCI1_IO_SIZE 0x04000000 /* 64 MB */
57
58/* Board-specific IRQ info */
59#define KATANA_PCI_INTA_IRQ_3750 64+8
60#define KATANA_PCI_INTB_IRQ_3750 64+9
61#define KATANA_PCI_INTC_IRQ_3750 64+10
62
63#define KATANA_PCI_INTA_IRQ_750i 64+8
64#define KATANA_PCI_INTB_IRQ_750i 64+9
65#define KATANA_PCI_INTC_IRQ_750i 64+10
66#define KATANA_PCI_INTD_IRQ_750i 64+14
67
68#define KATANA_CPLD_RST_EVENT 0x00000000
69#define KATANA_CPLD_RST_CMD 0x00001000
70#define KATANA_CPLD_PCI_ERR_INT_EN 0x00002000
71#define KATANA_CPLD_PCI_ERR_INT_PEND 0x00003000
72#define KATANA_CPLD_PRODUCT_ID 0x00004000
73#define KATANA_CPLD_EREADY 0x00005000
74
75#define KATANA_CPLD_HARDWARE_VER 0x00007000
76#define KATANA_CPLD_PLD_VER 0x00008000
77#define KATANA_CPLD_BD_CFG_0 0x00009000
78#define KATANA_CPLD_BD_CFG_1 0x0000a000
79#define KATANA_CPLD_BD_CFG_3 0x0000c000
80#define KATANA_CPLD_LED 0x0000d000
81#define KATANA_CPLD_RESET_OUT 0x0000e000
82
83#define KATANA_CPLD_RST_EVENT_INITACT 0x80
84#define KATANA_CPLD_RST_EVENT_SW 0x40
85#define KATANA_CPLD_RST_EVENT_WD 0x20
86#define KATANA_CPLD_RST_EVENT_COPS 0x10
87#define KATANA_CPLD_RST_EVENT_COPH 0x08
88#define KATANA_CPLD_RST_EVENT_CPCI 0x02
89#define KATANA_CPLD_RST_EVENT_FP 0x01
90
91#define KATANA_CPLD_RST_CMD_SCL 0x80
92#define KATANA_CPLD_RST_CMD_SDA 0x40
93#define KATANA_CPLD_RST_CMD_I2C 0x10
94#define KATANA_CPLD_RST_CMD_FR 0x08
95#define KATANA_CPLD_RST_CMD_SR 0x04
96#define KATANA_CPLD_RST_CMD_HR 0x01
97
98#define KATANA_CPLD_BD_CFG_0_SYSCLK_MASK 0xc0
99#define KATANA_CPLD_BD_CFG_0_SYSCLK_200 0x00
100#define KATANA_CPLD_BD_CFG_0_SYSCLK_166 0x80
101#define KATANA_CPLD_BD_CFG_0_SYSCLK_133 0xc0
102#define KATANA_CPLD_BD_CFG_0_SYSCLK_100 0x40
103
104#define KATANA_CPLD_BD_CFG_1_FL_BANK_MASK 0x03
105#define KATANA_CPLD_BD_CFG_1_FL_BANK_16MB 0x00
106#define KATANA_CPLD_BD_CFG_1_FL_BANK_32MB 0x01
107#define KATANA_CPLD_BD_CFG_1_FL_BANK_64MB 0x02
108#define KATANA_CPLD_BD_CFG_1_FL_BANK_128MB 0x03
109
110#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_MASK 0x04
111#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_ONE 0x00
112#define KATANA_CPLD_BD_CFG_1_FL_NUM_BANKS_TWO 0x04
113
114#define KATANA_CPLD_BD_CFG_3_MONARCH 0x04
115
116#define KATANA_CPLD_RESET_OUT_PORTSEL 0x80
117#define KATANA_CPLD_RESET_OUT_WD 0x20
118#define KATANA_CPLD_RESET_OUT_COPH 0x08
119#define KATANA_CPLD_RESET_OUT_PCI_RST_PCI 0x02
120#define KATANA_CPLD_RESET_OUT_PCI_RST_FP 0x01
121
122#define KATANA_MBOX_RESET_REQUEST 0xC83A
123#define KATANA_MBOX_RESET_ACK 0xE430
124#define KATANA_MBOX_RESET_DONE 0x32E5
125
126#define HSL_PLD_BASE 0x00010000
127#define HSL_PLD_J4SGA_REG_OFF 0
128#define HSL_PLD_J4GA_REG_OFF 1
129#define HSL_PLD_J2GA_REG_OFF 2
130#define HSL_PLD_HOT_SWAP_OFF 6
131#define HSL_PLD_HOT_SWAP_LED_BIT 0x1
132#define GA_MASK 0x1f
133#define HSL_PLD_SIZE 0x1000
134#define K3750_GPP_GEO_ADDR_PINS 0xf8000000
135#define K3750_GPP_GEO_ADDR_SHIFT 27
136
137#define K3750_GPP_EVENT_PROC_0 (1 << 21)
138#define K3750_GPP_EVENT_PROC_1_2 (1 << 2)
139
140#define PCI_VENDOR_ID_ARTESYN 0x1223
141#define PCI_DEVICE_ID_KATANA_3750_PROC0 0x0041
142#define PCI_DEVICE_ID_KATANA_3750_PROC1 0x0042
143#define PCI_DEVICE_ID_KATANA_3750_PROC2 0x0043
144
145#define COPROC_MEM_FUNCTION 0
146#define COPROC_MEM_BAR 0
147#define COPROC_REGS_FUNCTION 0
148#define COPROC_REGS_BAR 4
149#define COPROC_FLASH_FUNCTION 2
150#define COPROC_FLASH_BAR 4
151
152#define KATANA_IPMB_LOCAL_I2C_ADDR 0x08
153
154#define KATANA_DEFAULT_BAUD 9600
155#define KATANA_MPSC_CLK_SRC 8 /* TCLK */
156
157#define KATANA_MTD_MONITOR_SIZE (1 << 20) /* 1 MB */
158
159#define KATANA_ETH0_PHY_ADDR 12
160#define KATANA_ETH1_PHY_ADDR 11
161#define KATANA_ETH2_PHY_ADDR 4
162
163#define KATANA_PRODUCT_ID_3750 0x01
164#define KATANA_PRODUCT_ID_750i 0x02
165#define KATANA_PRODUCT_ID_752i 0x04
166
167#define KATANA_ETH_TX_QUEUE_SIZE 800
168#define KATANA_ETH_RX_QUEUE_SIZE 400
169
170#define KATANA_ETH_PORT_CONFIG_VALUE \
171 ETH_UNICAST_NORMAL_MODE | \
172 ETH_DEFAULT_RX_QUEUE_0 | \
173 ETH_DEFAULT_RX_ARP_QUEUE_0 | \
174 ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP | \
175 ETH_RECEIVE_BC_IF_IP | \
176 ETH_RECEIVE_BC_IF_ARP | \
177 ETH_CAPTURE_TCP_FRAMES_DIS | \
178 ETH_CAPTURE_UDP_FRAMES_DIS | \
179 ETH_DEFAULT_RX_TCP_QUEUE_0 | \
180 ETH_DEFAULT_RX_UDP_QUEUE_0 | \
181 ETH_DEFAULT_RX_BPDU_QUEUE_0
182
183#define KATANA_ETH_PORT_CONFIG_EXTEND_VALUE \
184 ETH_SPAN_BPDU_PACKETS_AS_NORMAL | \
185 ETH_PARTITION_DISABLE
186
187#define GT_ETH_IPG_INT_RX(value) \
188 ((value & 0x3fff) << 8)
189
190#define KATANA_ETH_PORT_SDMA_CONFIG_VALUE \
191 ETH_RX_BURST_SIZE_4_64BIT | \
192 GT_ETH_IPG_INT_RX(0) | \
193 ETH_TX_BURST_SIZE_4_64BIT
194
195#define KATANA_ETH_PORT_SERIAL_CONTROL_VALUE \
196 ETH_FORCE_LINK_PASS | \
197 ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \
198 ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
199 ETH_ADV_SYMMETRIC_FLOW_CTRL | \
200 ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
201 ETH_FORCE_BP_MODE_NO_JAM | \
202 BIT9 | \
203 ETH_DO_NOT_FORCE_LINK_FAIL | \
204 ETH_RETRANSMIT_16_ATTEMPTS | \
205 ETH_ENABLE_AUTO_NEG_SPEED_GMII | \
206 ETH_DTE_ADV_0 | \
207 ETH_DISABLE_AUTO_NEG_BYPASS | \
208 ETH_AUTO_NEG_NO_CHANGE | \
209 ETH_MAX_RX_PACKET_9700BYTE | \
210 ETH_CLR_EXT_LOOPBACK | \
211 ETH_SET_FULL_DUPLEX_MODE | \
212 ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
213
214#ifndef __ASSEMBLY__
215
216typedef enum {
217 KATANA_ID_3750,
218 KATANA_ID_750I,
219 KATANA_ID_752I,
220 KATANA_ID_MAX
221} katana_id_t;
222
223#endif
224
225static inline u32
226katana_bus_freq(void __iomem *cpld_base)
227{
228 u8 bd_cfg_0;
229
230 bd_cfg_0 = in_8(cpld_base + KATANA_CPLD_BD_CFG_0);
231
232 switch (bd_cfg_0 & KATANA_CPLD_BD_CFG_0_SYSCLK_MASK) {
233 case KATANA_CPLD_BD_CFG_0_SYSCLK_200:
234 return 200000000;
235 break;
236
237 case KATANA_CPLD_BD_CFG_0_SYSCLK_166:
238 return 166666666;
239 break;
240
241 case KATANA_CPLD_BD_CFG_0_SYSCLK_133:
242 return 133333333;
243 break;
244
245 case KATANA_CPLD_BD_CFG_0_SYSCLK_100:
246 return 100000000;
247 break;
248
249 default:
250 return 133333333;
251 break;
252 }
253}
254
255#endif /* __PPC_PLATFORMS_KATANA_H */
diff --git a/arch/ppc/platforms/lantec.h b/arch/ppc/platforms/lantec.h
new file mode 100644
index 000000000000..8c87642c510f
--- /dev/null
+++ b/arch/ppc/platforms/lantec.h
@@ -0,0 +1,21 @@
1/*
2 * LANTEC board specific definitions
3 *
4 * Copyright (c) 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_LANTEC_H
8#define __MACH_LANTEC_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define IMAP_ADDR 0xFFF00000 /* physical base address of IMMR area */
15#define IMAP_SIZE (64 * 1024) /* mapped size of IMMR area */
16
17/* We don't use the 8259.
18*/
19#define NR_8259_INTS 0
20
21#endif /* __MACH_LANTEC_H */
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
new file mode 100644
index 000000000000..b604cf8b3cae
--- /dev/null
+++ b/arch/ppc/platforms/lite5200.c
@@ -0,0 +1,236 @@
1/*
2 * arch/ppc/platforms/lite5200.c
3 *
4 * Platform support file for the Freescale LITE5200 based on MPC52xx.
5 * A maximum of this file should be moved to syslib/mpc52xx_?????
6 * so that new platform based on MPC52xx need a minimal platform file
7 * ( avoid code duplication )
8 *
9 *
10 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
11 *
12 * Based on the 2.4 code written by Kent Borg,
13 * Dale Farnsworth <dale.farnsworth@mvista.com> and
14 * Wolfgang Denk <wd@denx.de>
15 *
16 * Copyright 2004-2005 Sylvain Munaut <tnt@246tNt.com>
17 * Copyright 2003 Motorola Inc.
18 * Copyright 2003 MontaVista Software Inc.
19 * Copyright 2003 DENX Software Engineering (wd@denx.de)
20 *
21 * This file is licensed under the terms of the GNU General Public License
22 * version 2. This program is licensed "as is" without any warranty of any
23 * kind, whether express or implied.
24 */
25
26#include <linux/config.h>
27#include <linux/initrd.h>
28#include <linux/seq_file.h>
29#include <linux/kdev_t.h>
30#include <linux/root_dev.h>
31#include <linux/console.h>
32#include <linux/module.h>
33
34#include <asm/bootinfo.h>
35#include <asm/io.h>
36#include <asm/mpc52xx.h>
37#include <asm/ppc_sys.h>
38
39#include <syslib/mpc52xx_pci.h>
40
41
42extern int powersave_nap;
43
44/* Board data given by U-Boot */
45bd_t __res;
46EXPORT_SYMBOL(__res); /* For modules */
47
48
49/* ======================================================================== */
50/* Platform specific code */
51/* ======================================================================== */
52
53/* Supported PSC function in "preference" order */
54struct mpc52xx_psc_func mpc52xx_psc_functions[] = {
55 { .id = 0,
56 .func = "uart",
57 },
58 { .id = -1, /* End entry */
59 .func = NULL,
60 }
61 };
62
63
64static int
65lite5200_show_cpuinfo(struct seq_file *m)
66{
67 seq_printf(m, "machine\t\t: Freescale LITE5200\n");
68 return 0;
69}
70
71#ifdef CONFIG_PCI
72static int
73lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
74{
75 return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1;
76}
77#endif
78
79static void __init
80lite5200_setup_cpu(void)
81{
82 struct mpc52xx_cdm __iomem *cdm;
83 struct mpc52xx_gpio __iomem *gpio;
84 struct mpc52xx_intr __iomem *intr;
85 struct mpc52xx_xlb __iomem *xlb;
86
87 u32 port_config;
88 u32 intr_ctrl;
89
90 /* Map zones */
91 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
92 gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
93 xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
94 intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
95
96 if (!cdm || !gpio || !xlb || !intr) {
97 printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during"
98 "lite5200_setup_cpu\n");
99 goto unmap_regs;
100 }
101
102 /* Use internal 48 Mhz */
103 out_8(&cdm->ext_48mhz_en, 0x00);
104 out_8(&cdm->fd_enable, 0x01);
105 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
106 out_be16(&cdm->fd_counters, 0x0001);
107 else
108 out_be16(&cdm->fd_counters, 0x5555);
109
110 /* Get port mux config */
111 port_config = in_be32(&gpio->port_config);
112
113 /* 48Mhz internal, pin is GPIO */
114 port_config &= ~0x00800000;
115
116 /* USB port */
117 port_config &= ~0x00007000; /* Differential mode - USB1 only */
118 port_config |= 0x00001000;
119
120 /* Commit port config */
121 out_be32(&gpio->port_config, port_config);
122
123 /* Configure the XLB Arbiter */
124 out_be32(&xlb->master_pri_enable, 0xff);
125 out_be32(&xlb->master_priority, 0x11111111);
126
127 /* Enable ram snooping for 1GB window */
128 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
129 out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
130
131 /* IRQ[0-3] setup : IRQ0 - Level Active Low */
132 /* IRQ[1-3] - Level Active High */
133 intr_ctrl = in_be32(&intr->ctrl);
134 intr_ctrl &= ~0x00ff0000;
135 intr_ctrl |= 0x00c00000;
136 out_be32(&intr->ctrl, intr_ctrl);
137
138 /* Unmap reg zone */
139unmap_regs:
140 if (cdm) iounmap(cdm);
141 if (gpio) iounmap(gpio);
142 if (xlb) iounmap(xlb);
143 if (intr) iounmap(intr);
144}
145
146static void __init
147lite5200_setup_arch(void)
148{
149 /* CPU & Port mux setup */
150 lite5200_setup_cpu();
151
152#ifdef CONFIG_PCI
153 /* PCI Bridge setup */
154 mpc52xx_find_bridges();
155#endif
156}
157
158void __init
159platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
160 unsigned long r6, unsigned long r7)
161{
162 /* Generic MPC52xx platform initialization */
163 /* TODO Create one and move a max of stuff in it.
164 Put this init in the syslib */
165
166 struct bi_record *bootinfo = find_bootinfo();
167
168 if (bootinfo)
169 parse_bootinfo(bootinfo);
170 else {
171 /* Load the bd_t board info structure */
172 if (r3)
173 memcpy((void*)&__res,(void*)(r3+KERNELBASE),
174 sizeof(bd_t));
175
176#ifdef CONFIG_BLK_DEV_INITRD
177 /* Load the initrd */
178 if (r4) {
179 initrd_start = r4 + KERNELBASE;
180 initrd_end = r5 + KERNELBASE;
181 }
182#endif
183
184 /* Load the command line */
185 if (r6) {
186 *(char *)(r7+KERNELBASE) = 0;
187 strcpy(cmd_line, (char *)(r6+KERNELBASE));
188 }
189 }
190
191 /* PPC Sys identification */
192 identify_ppc_sys_by_id(mfspr(SPRN_SVR));
193
194 /* BAT setup */
195 mpc52xx_set_bat();
196
197 /* No ISA bus by default */
198 isa_io_base = 0;
199 isa_mem_base = 0;
200
201 /* Powersave */
202 /* This is provided as an example on how to do it. But you
203 need to be aware that NAP disable bus snoop and that may
204 be required for some devices to work properly, like USB ... */
205 /* powersave_nap = 1; */
206
207
208 /* Setup the ppc_md struct */
209 ppc_md.setup_arch = lite5200_setup_arch;
210 ppc_md.show_cpuinfo = lite5200_show_cpuinfo;
211 ppc_md.show_percpuinfo = NULL;
212 ppc_md.init_IRQ = mpc52xx_init_irq;
213 ppc_md.get_irq = mpc52xx_get_irq;
214
215#ifdef CONFIG_PCI
216 ppc_md.pci_map_irq = lite5200_map_irq;
217#endif
218
219 ppc_md.find_end_of_memory = mpc52xx_find_end_of_memory;
220 ppc_md.setup_io_mappings = mpc52xx_map_io;
221
222 ppc_md.restart = mpc52xx_restart;
223 ppc_md.power_off = mpc52xx_power_off;
224 ppc_md.halt = mpc52xx_halt;
225
226 /* No time keeper on the LITE5200 */
227 ppc_md.time_init = NULL;
228 ppc_md.get_rtc_time = NULL;
229 ppc_md.set_rtc_time = NULL;
230
231 ppc_md.calibrate_decr = mpc52xx_calibrate_decr;
232#ifdef CONFIG_SERIAL_TEXT_DEBUG
233 ppc_md.progress = mpc52xx_progress;
234#endif
235}
236
diff --git a/arch/ppc/platforms/lite5200.h b/arch/ppc/platforms/lite5200.h
new file mode 100644
index 000000000000..c1de2aa47175
--- /dev/null
+++ b/arch/ppc/platforms/lite5200.h
@@ -0,0 +1,23 @@
1/*
2 * arch/ppc/platforms/lite5200.h
3 *
4 * Definitions for Freescale LITE5200 : MPC52xx Standard Development
5 * Platform board support
6 *
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
8 *
9 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#ifndef __PLATFORMS_LITE5200_H__
17#define __PLATFORMS_LITE5200_H__
18
19/* Serial port used for low-level debug */
20#define MPC52xx_PF_CONSOLE_PORT 1 /* PSC1 */
21
22
23#endif /* __PLATFORMS_LITE5200_H__ */
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
new file mode 100644
index 000000000000..a5569525e0af
--- /dev/null
+++ b/arch/ppc/platforms/lopec.c
@@ -0,0 +1,411 @@
1/*
2 * arch/ppc/platforms/lopec.c
3 *
4 * Setup routines for the Motorola LoPEC.
5 *
6 * Author: Dan Cox
7 * Maintainer: Tom Rini <trini@kernel.crashing.org>
8 *
9 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#include <linux/config.h>
16#include <linux/types.h>
17#include <linux/delay.h>
18#include <linux/pci_ids.h>
19#include <linux/ioport.h>
20#include <linux/init.h>
21#include <linux/ide.h>
22#include <linux/seq_file.h>
23#include <linux/initrd.h>
24#include <linux/console.h>
25#include <linux/root_dev.h>
26#include <linux/pci.h>
27
28#include <asm/machdep.h>
29#include <asm/pci-bridge.h>
30#include <asm/io.h>
31#include <asm/open_pic.h>
32#include <asm/i8259.h>
33#include <asm/todc.h>
34#include <asm/bootinfo.h>
35#include <asm/mpc10x.h>
36#include <asm/hw_irq.h>
37#include <asm/prep_nvram.h>
38#include <asm/kgdb.h>
39
40/*
41 * Define all of the IRQ senses and polarities. Taken from the
42 * LoPEC Programmer's Reference Guide.
43 */
44static u_char lopec_openpic_initsenses[16] __initdata = {
45 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ 0 */
46 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 1 */
47 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ 2 */
48 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 3 */
49 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ 4 */
50 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ 5 */
51 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 6 */
52 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 7 */
53 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 8 */
54 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 9 */
55 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 10 */
56 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 11 */
57 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ 12 */
58 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ 13 */
59 (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ 14 */
60 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE) /* IRQ 15 */
61};
62
63static inline int __init
64lopec_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
65{
66 int irq;
67 static char pci_irq_table[][4] = {
68 {16, 0, 0, 0}, /* ID 11 - Winbond */
69 {22, 0, 0, 0}, /* ID 12 - SCSI */
70 {0, 0, 0, 0}, /* ID 13 - nothing */
71 {17, 0, 0, 0}, /* ID 14 - 82559 Ethernet */
72 {27, 0, 0, 0}, /* ID 15 - USB */
73 {23, 0, 0, 0}, /* ID 16 - PMC slot 1 */
74 {24, 0, 0, 0}, /* ID 17 - PMC slot 2 */
75 {25, 0, 0, 0}, /* ID 18 - PCI slot */
76 {0, 0, 0, 0}, /* ID 19 - nothing */
77 {0, 0, 0, 0}, /* ID 20 - nothing */
78 {0, 0, 0, 0}, /* ID 21 - nothing */
79 {0, 0, 0, 0}, /* ID 22 - nothing */
80 {0, 0, 0, 0}, /* ID 23 - nothing */
81 {0, 0, 0, 0}, /* ID 24 - PMC slot 1b */
82 {0, 0, 0, 0}, /* ID 25 - nothing */
83 {0, 0, 0, 0} /* ID 26 - PMC Slot 2b */
84 };
85 const long min_idsel = 11, max_idsel = 26, irqs_per_slot = 4;
86
87 irq = PCI_IRQ_TABLE_LOOKUP;
88 if (!irq)
89 return 0;
90
91 return irq;
92}
93
94static void __init
95lopec_setup_winbond_83553(struct pci_controller *hose)
96{
97 int devfn;
98
99 devfn = PCI_DEVFN(11,0);
100
101 /* IDE interrupt routing (primary 14, secondary 15) */
102 early_write_config_byte(hose, 0, devfn, 0x43, 0xef);
103 /* PCI interrupt routing */
104 early_write_config_word(hose, 0, devfn, 0x44, 0x0000);
105
106 /* ISA-PCI address decoder */
107 early_write_config_byte(hose, 0, devfn, 0x48, 0xf0);
108
109 /* RTC, kb, not used in PPC */
110 early_write_config_byte(hose, 0, devfn, 0x4d, 0x00);
111 early_write_config_byte(hose, 0, devfn, 0x4e, 0x04);
112 devfn = PCI_DEVFN(11, 1);
113 early_write_config_byte(hose, 0, devfn, 0x09, 0x8f);
114 early_write_config_dword(hose, 0, devfn, 0x40, 0x00ff0011);
115}
116
117static void __init
118lopec_find_bridges(void)
119{
120 struct pci_controller *hose;
121
122 hose = pcibios_alloc_controller();
123 if (!hose)
124 return;
125
126 hose->first_busno = 0;
127 hose->last_busno = 0xff;
128
129 if (mpc10x_bridge_init(hose, MPC10X_MEM_MAP_B, MPC10X_MEM_MAP_B,
130 MPC10X_MAPB_EUMB_BASE) == 0) {
131
132 hose->mem_resources[0].end = 0xffffffff;
133 lopec_setup_winbond_83553(hose);
134 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
135 ppc_md.pci_swizzle = common_swizzle;
136 ppc_md.pci_map_irq = lopec_map_irq;
137 }
138}
139
140static int
141lopec_show_cpuinfo(struct seq_file *m)
142{
143 seq_printf(m, "machine\t\t: Motorola LoPEC\n");
144 return 0;
145}
146
147static u32
148lopec_irq_canonicalize(u32 irq)
149{
150 if (irq == 2)
151 return 9;
152 else
153 return irq;
154}
155
156static void
157lopec_restart(char *cmd)
158{
159#define LOPEC_SYSSTAT1 0xffe00000
160 /* force a hard reset, if possible */
161 unsigned char reg = *((unsigned char *) LOPEC_SYSSTAT1);
162 reg |= 0x80;
163 *((unsigned char *) LOPEC_SYSSTAT1) = reg;
164
165 local_irq_disable();
166 while(1);
167#undef LOPEC_SYSSTAT1
168}
169
170static void
171lopec_halt(void)
172{
173 local_irq_disable();
174 while(1);
175}
176
177static void
178lopec_power_off(void)
179{
180 lopec_halt();
181}
182
183#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
184int lopec_ide_ports_known = 0;
185static unsigned long lopec_ide_regbase[MAX_HWIFS];
186static unsigned long lopec_ide_ctl_regbase[MAX_HWIFS];
187static unsigned long lopec_idedma_regbase;
188
189static void
190lopec_ide_probe(void)
191{
192 struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
193 PCI_DEVICE_ID_WINBOND_82C105,
194 NULL);
195 lopec_ide_ports_known = 1;
196
197 if (dev) {
198 lopec_ide_regbase[0] = dev->resource[0].start;
199 lopec_ide_regbase[1] = dev->resource[2].start;
200 lopec_ide_ctl_regbase[0] = dev->resource[1].start;
201 lopec_ide_ctl_regbase[1] = dev->resource[3].start;
202 lopec_idedma_regbase = dev->resource[4].start;
203 pci_dev_put(dev);
204 }
205}
206
207static int
208lopec_ide_default_irq(unsigned long base)
209{
210 if (lopec_ide_ports_known == 0)
211 lopec_ide_probe();
212
213 if (base == lopec_ide_regbase[0])
214 return 14;
215 else if (base == lopec_ide_regbase[1])
216 return 15;
217 else
218 return 0;
219}
220
221static unsigned long
222lopec_ide_default_io_base(int index)
223{
224 if (lopec_ide_ports_known == 0)
225 lopec_ide_probe();
226 return lopec_ide_regbase[index];
227}
228
229static void __init
230lopec_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data,
231 unsigned long ctl, int *irq)
232{
233 unsigned long reg = data;
234 uint alt_status_base;
235 int i;
236
237 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
238 hw->io_ports[i] = reg++;
239
240 if (data == lopec_ide_regbase[0]) {
241 alt_status_base = lopec_ide_ctl_regbase[0] + 2;
242 hw->irq = 14;
243 } else if (data == lopec_ide_regbase[1]) {
244 alt_status_base = lopec_ide_ctl_regbase[1] + 2;
245 hw->irq = 15;
246 } else {
247 alt_status_base = 0;
248 hw->irq = 0;
249 }
250
251 if (ctl)
252 hw->io_ports[IDE_CONTROL_OFFSET] = ctl;
253 else
254 hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base;
255
256 if (irq != NULL)
257 *irq = hw->irq;
258
259}
260#endif /* BLK_DEV_IDE */
261
262static void __init
263lopec_init_IRQ(void)
264{
265 int i;
266
267 /*
268 * Provide the open_pic code with the correct table of interrupts.
269 */
270 OpenPIC_InitSenses = lopec_openpic_initsenses;
271 OpenPIC_NumInitSenses = sizeof(lopec_openpic_initsenses);
272
273 mpc10x_set_openpic();
274
275 /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
276 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
277 &i8259_irq);
278
279 /* Map i8259 interrupts */
280 for(i = 0; i < NUM_8259_INTERRUPTS; i++)
281 irq_desc[i].handler = &i8259_pic;
282
283 /*
284 * The EPIC allows for a read in the range of 0xFEF00000 ->
285 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
286 */
287 i8259_init(0xfef00000);
288}
289
290static int __init
291lopec_request_io(void)
292{
293 outb(0x00, 0x4d0);
294 outb(0xc0, 0x4d1);
295
296 request_region(0x00, 0x20, "dma1");
297 request_region(0x20, 0x20, "pic1");
298 request_region(0x40, 0x20, "timer");
299 request_region(0x80, 0x10, "dma page reg");
300 request_region(0xa0, 0x20, "pic2");
301 request_region(0xc0, 0x20, "dma2");
302
303 return 0;
304}
305
306device_initcall(lopec_request_io);
307
308static void __init
309lopec_map_io(void)
310{
311 io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
312 io_block_mapping(0xb0000000, 0xb0000000, 0x10000000, _PAGE_IO);
313}
314
315/*
316 * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
317 */
318static __inline__ void
319lopec_set_bat(void)
320{
321 mb();
322 mtspr(SPRN_DBAT1U, 0xf8000ffe);
323 mtspr(SPRN_DBAT1L, 0xf800002a);
324 mb();
325}
326
327TODC_ALLOC();
328
329static void __init
330lopec_setup_arch(void)
331{
332
333 TODC_INIT(TODC_TYPE_MK48T37, 0, 0,
334 ioremap(0xffe80000, 0x8000), 8);
335
336 loops_per_jiffy = 100000000/HZ;
337
338 lopec_find_bridges();
339
340#ifdef CONFIG_BLK_DEV_INITRD
341 if (initrd_start)
342 ROOT_DEV = Root_RAM0;
343 else
344#elif defined(CONFIG_ROOT_NFS)
345 ROOT_DEV = Root_NFS;
346#elif defined(CONFIG_BLK_DEV_IDEDISK)
347 ROOT_DEV = Root_HDA1;
348#else
349 ROOT_DEV = Root_SDA1;
350#endif
351
352#ifdef CONFIG_PPCBUG_NVRAM
353 /* Read in NVRAM data */
354 init_prep_nvram();
355
356 /* if no bootargs, look in NVRAM */
357 if ( cmd_line[0] == '\0' ) {
358 char *bootargs;
359 bootargs = prep_nvram_get_var("bootargs");
360 if (bootargs != NULL) {
361 strcpy(cmd_line, bootargs);
362 /* again.. */
363 strcpy(saved_command_line, cmd_line);
364 }
365 }
366#endif
367}
368
369void __init
370platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
371 unsigned long r6, unsigned long r7)
372{
373 parse_bootinfo(find_bootinfo());
374 lopec_set_bat();
375
376 isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
377 isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
378 pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
379 ISA_DMA_THRESHOLD = 0x00ffffff;
380 DMA_MODE_READ = 0x44;
381 DMA_MODE_WRITE = 0x48;
382
383 ppc_md.setup_arch = lopec_setup_arch;
384 ppc_md.show_cpuinfo = lopec_show_cpuinfo;
385 ppc_md.irq_canonicalize = lopec_irq_canonicalize;
386 ppc_md.init_IRQ = lopec_init_IRQ;
387 ppc_md.get_irq = openpic_get_irq;
388
389 ppc_md.restart = lopec_restart;
390 ppc_md.power_off = lopec_power_off;
391 ppc_md.halt = lopec_halt;
392
393 ppc_md.setup_io_mappings = lopec_map_io;
394
395 ppc_md.time_init = todc_time_init;
396 ppc_md.set_rtc_time = todc_set_rtc_time;
397 ppc_md.get_rtc_time = todc_get_rtc_time;
398 ppc_md.calibrate_decr = todc_calibrate_decr;
399
400 ppc_md.nvram_read_val = todc_direct_read_val;
401 ppc_md.nvram_write_val = todc_direct_write_val;
402
403#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
404 ppc_ide_md.default_irq = lopec_ide_default_irq;
405 ppc_ide_md.default_io_base = lopec_ide_default_io_base;
406 ppc_ide_md.ide_init_hwif = lopec_ide_init_hwif_ports;
407#endif
408#ifdef CONFIG_SERIAL_TEXT_DEBUG
409 ppc_md.progress = gen550_progress;
410#endif
411}
diff --git a/arch/ppc/platforms/lopec.h b/arch/ppc/platforms/lopec.h
new file mode 100644
index 000000000000..5490edb2d263
--- /dev/null
+++ b/arch/ppc/platforms/lopec.h
@@ -0,0 +1,39 @@
1/*
2 * include/asm-ppc/lopec_serial.h
3 *
4 * Definitions for Motorola LoPEC board.
5 *
6 * Author: Dan Cox
7 * danc@mvista.com (or, alternately, source@mvista.com)
8 *
9 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15#ifndef __H_LOPEC_SERIAL
16#define __H_LOPEC_SERIAL
17
18#define RS_TABLE_SIZE 3
19
20#define BASE_BAUD (1843200 / 16)
21
22#ifdef CONFIG_SERIAL_DETECT_IRQ
23#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
24#else
25#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
26#endif
27
28#define SERIAL_PORT_DFNS \
29 { 0, BASE_BAUD, 0xffe10000, 29, STD_COM_FLAGS, \
30 iomem_base: (u8 *) 0xffe10000, \
31 io_type: SERIAL_IO_MEM }, \
32 { 0, BASE_BAUD, 0xffe11000, 20, STD_COM_FLAGS, \
33 iomem_base: (u8 *) 0xffe11000, \
34 io_type: SERIAL_IO_MEM }, \
35 { 0, BASE_BAUD, 0xffe12000, 21, STD_COM_FLAGS, \
36 iomem_base: (u8 *) 0xffe12000, \
37 io_type: SERIAL_IO_MEM }
38
39#endif
diff --git a/arch/ppc/platforms/lwmon.h b/arch/ppc/platforms/lwmon.h
new file mode 100644
index 000000000000..995bf5112df0
--- /dev/null
+++ b/arch/ppc/platforms/lwmon.h
@@ -0,0 +1,60 @@
1/*
2 * Liebherr LWMON board specific definitions
3 *
4 * Copyright (c) 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_LWMON_H
8#define __MACH_LWMON_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define IMAP_ADDR 0xFFF00000 /* physical base address of IMMR area */
15#define IMAP_SIZE (64 * 1024) /* mapped size of IMMR area */
16
17/*-----------------------------------------------------------------------
18 * PCMCIA stuff
19 *-----------------------------------------------------------------------
20 *
21 */
22#define PCMCIA_MEM_SIZE ( 64 << 20 )
23
24#define MAX_HWIFS 1 /* overwrite default in include/asm-ppc/ide.h */
25
26/*
27 * Definitions for IDE0 Interface
28 */
29#define IDE0_BASE_OFFSET 0
30#define IDE0_DATA_REG_OFFSET (PCMCIA_MEM_SIZE + 0x320)
31#define IDE0_ERROR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 1)
32#define IDE0_NSECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 2)
33#define IDE0_SECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 3)
34#define IDE0_LCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 4)
35#define IDE0_HCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 5)
36#define IDE0_SELECT_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 6)
37#define IDE0_STATUS_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 7)
38#define IDE0_CONTROL_REG_OFFSET 0x0106
39#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */
40
41#define IDE0_INTERRUPT 13
42
43/*
44 * Definitions for I2C devices
45 */
46#define I2C_ADDR_AUDIO 0x28 /* Audio volume control */
47#define I2C_ADDR_SYSMON 0x2E /* LM87 System Monitor */
48#define I2C_ADDR_RTC 0x51 /* PCF8563 RTC */
49#define I2C_ADDR_POWER_A 0x52 /* PCMCIA/USB power switch, channel A */
50#define I2C_ADDR_POWER_B 0x53 /* PCMCIA/USB power switch, channel B */
51#define I2C_ADDR_KEYBD 0x56 /* PIC LWE keyboard */
52#define I2C_ADDR_PICIO 0x57 /* PIC IO Expander */
53#define I2C_ADDR_EEPROM 0x58 /* EEPROM AT24C164 */
54
55
56/* We don't use the 8259.
57*/
58#define NR_8259_INTS 0
59
60#endif /* __MACH_LWMON_H */
diff --git a/arch/ppc/platforms/mbx.h b/arch/ppc/platforms/mbx.h
new file mode 100644
index 000000000000..fe81ca4ea0a2
--- /dev/null
+++ b/arch/ppc/platforms/mbx.h
@@ -0,0 +1,117 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Motorola MBX boards. This was originally created for the
4 * MBX860, and probably needs revisions for other boards (like the 821).
5 * When this file gets out of control, we can split it up into more
6 * meaningful pieces.
7 *
8 * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
9 */
10#ifdef __KERNEL__
11#ifndef __MACH_MBX_DEFS
12#define __MACH_MBX_DEFS
13
14#ifndef __ASSEMBLY__
15/* A Board Information structure that is given to a program when
16 * EPPC-Bug starts it up.
17 */
18typedef struct bd_info {
19 unsigned int bi_tag; /* Should be 0x42444944 "BDID" */
20 unsigned int bi_size; /* Size of this structure */
21 unsigned int bi_revision; /* revision of this structure */
22 unsigned int bi_bdate; /* EPPCbug date, i.e. 0x11061997 */
23 unsigned int bi_memstart; /* Memory start address */
24 unsigned int bi_memsize; /* Memory (end) size in bytes */
25 unsigned int bi_intfreq; /* Internal Freq, in Hz */
26 unsigned int bi_busfreq; /* Bus Freq, in Hz */
27 unsigned int bi_clun; /* Boot device controller */
28 unsigned int bi_dlun; /* Boot device logical dev */
29
30 /* These fields are not part of the board information structure
31 * provided by the boot rom. They are filled in by embed_config.c
32 * so we have the information consistent with other platforms.
33 */
34 unsigned char bi_enetaddr[6];
35 unsigned int bi_baudrate;
36} bd_t;
37
38/* Memory map for the MBX as configured by EPPC-Bug. We could reprogram
39 * The SIU and PCI bridge, and try to use larger MMU pages, but the
40 * performance gain is not measureable and it certainly complicates the
41 * generic MMU model.
42 *
43 * In a effort to minimize memory usage for embedded applications, any
44 * PCI driver or ISA driver must request or map the region required by
45 * the device. For convenience (and since we can map up to 4 Mbytes with
46 * a single page table page), the MMU initialization will map the
47 * NVRAM, Status/Control registers, CPM Dual Port RAM, and the PCI
48 * Bridge CSRs 1:1 into the kernel address space.
49 */
50#define PCI_ISA_IO_ADDR ((unsigned)0x80000000)
51#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024))
52#define PCI_IDE_ADDR ((unsigned)0x81000000)
53#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000)
54#define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024))
55#define PCMCIA_MEM_ADDR ((uint)0xe0000000)
56#define PCMCIA_MEM_SIZE ((uint)(64 * 1024 * 1024))
57#define PCMCIA_DMA_ADDR ((uint)0xe4000000)
58#define PCMCIA_DMA_SIZE ((uint)(64 * 1024 * 1024))
59#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000)
60#define PCMCIA_ATTRB_SIZE ((uint)(64 * 1024 * 1024))
61#define PCMCIA_IO_ADDR ((uint)0xec000000)
62#define PCMCIA_IO_SIZE ((uint)(64 * 1024 * 1024))
63#define NVRAM_ADDR ((uint)0xfa000000)
64#define NVRAM_SIZE ((uint)(1 * 1024 * 1024))
65#define MBX_CSR_ADDR ((uint)0xfa100000)
66#define MBX_CSR_SIZE ((uint)(1 * 1024 * 1024))
67#define IMAP_ADDR ((uint)0xfa200000)
68#define IMAP_SIZE ((uint)(64 * 1024))
69#define PCI_CSR_ADDR ((uint)0xfa210000)
70#define PCI_CSR_SIZE ((uint)(64 * 1024))
71
72/* Map additional physical space into well known virtual addresses. Due
73 * to virtual address mapping, these physical addresses are not accessible
74 * in a 1:1 virtual to physical mapping.
75 */
76#define ISA_IO_VIRT_ADDR ((uint)0xfa220000)
77#define ISA_IO_VIRT_SIZE ((uint)64 * 1024)
78
79/* Interrupt assignments.
80 * These are defined (and fixed) by the MBX hardware implementation.
81 */
82#define POWER_FAIL_INT SIU_IRQ0 /* Power fail */
83#define TEMP_HILO_INT SIU_IRQ1 /* Temperature sensor */
84#define QSPAN_INT SIU_IRQ2 /* PCI Bridge (DMA CTLR?) */
85#define ISA_BRIDGE_INT SIU_IRQ3 /* All those PC things */
86#define COMM_L_INT SIU_IRQ6 /* MBX Comm expansion connector pin */
87#define STOP_ABRT_INT SIU_IRQ7 /* Stop/Abort header pin */
88
89/* CPM Ethernet through SCCx.
90 *
91 * Bits in parallel I/O port registers that have to be set/cleared
92 * to configure the pins for SCC1 use. The TCLK and RCLK seem unique
93 * to the MBX860 board. Any two of the four available clocks could be
94 * used, and the MPC860 cookbook manual has an example using different
95 * clock pins.
96 */
97#define PA_ENET_RXD ((ushort)0x0001)
98#define PA_ENET_TXD ((ushort)0x0002)
99#define PA_ENET_TCLK ((ushort)0x0200)
100#define PA_ENET_RCLK ((ushort)0x0800)
101#define PC_ENET_TENA ((ushort)0x0001)
102#define PC_ENET_CLSN ((ushort)0x0010)
103#define PC_ENET_RENA ((ushort)0x0020)
104
105/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
106 * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
107 */
108#define SICR_ENET_MASK ((uint)0x000000ff)
109#define SICR_ENET_CLKRT ((uint)0x0000003d)
110
111/* The MBX uses the 8259.
112*/
113#define NR_8259_INTS 16
114
115#endif /* !__ASSEMBLY__ */
116#endif /* __MACH_MBX_DEFS */
117#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/mcpn765.c b/arch/ppc/platforms/mcpn765.c
new file mode 100644
index 000000000000..e88d294ea593
--- /dev/null
+++ b/arch/ppc/platforms/mcpn765.c
@@ -0,0 +1,527 @@
1/*
2 * arch/ppc/platforms/mcpn765.c
3 *
4 * Board setup routines for the Motorola MCG MCPN765 cPCI Board.
5 *
6 * Author: Mark A. Greer
7 * mgreer@mvista.com
8 *
9 * Modified by Randy Vinson (rvinson@mvista.com)
10 *
11 * 2001-2002 (c) MontaVista, Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17/*
18 * This file adds support for the Motorola MCG MCPN765.
19 */
20#include <linux/config.h>
21#include <linux/stddef.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/errno.h>
25#include <linux/reboot.h>
26#include <linux/pci.h>
27#include <linux/kdev_t.h>
28#include <linux/major.h>
29#include <linux/initrd.h>
30#include <linux/console.h>
31#include <linux/delay.h>
32#include <linux/irq.h>
33#include <linux/seq_file.h>
34#include <linux/root_dev.h>
35#include <linux/serial.h>
36#include <linux/tty.h> /* for linux/serial_core.h */
37#include <linux/serial_core.h>
38#include <linux/slab.h>
39
40#include <asm/system.h>
41#include <asm/pgtable.h>
42#include <asm/page.h>
43#include <asm/time.h>
44#include <asm/dma.h>
45#include <asm/byteorder.h>
46#include <asm/io.h>
47#include <asm/machdep.h>
48#include <asm/prom.h>
49#include <asm/smp.h>
50#include <asm/open_pic.h>
51#include <asm/i8259.h>
52#include <asm/todc.h>
53#include <asm/pci-bridge.h>
54#include <asm/irq.h>
55#include <asm/uaccess.h>
56#include <asm/bootinfo.h>
57#include <asm/hawk.h>
58#include <asm/kgdb.h>
59
60#include "mcpn765.h"
61
62static u_char mcpn765_openpic_initsenses[] __initdata = {
63 (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE),/* 16: i8259 cascade */
64 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 17: COM1,2,3,4 */
65 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 18: Enet 1 (front) */
66 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 19: HAWK WDT XXXX */
67 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 20: 21554 bridge */
68 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 21: cPCI INTA# */
69 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 22: cPCI INTB# */
70 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 23: cPCI INTC# */
71 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 24: cPCI INTD# */
72 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 25: PMC1 INTA#,PMC2 INTB#*/
73 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 26: PMC1 INTB#,PMC2 INTC#*/
74 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 27: PMC1 INTC#,PMC2 INTD#*/
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 28: PMC1 INTD#,PMC2 INTA#*/
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 29: Enet 2 (J3) */
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 30: Abort Switch */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* 31: RTC Alarm */
79};
80
81extern void mcpn765_set_VIA_IDE_native(void);
82
83extern u_int openpic_irq(void);
84extern char cmd_line[];
85
86extern void gen550_progress(char *, unsigned short);
87extern void gen550_init(int, struct uart_port *);
88
89int use_of_interrupt_tree = 0;
90
91static void mcpn765_halt(void);
92
93TODC_ALLOC();
94
95/*
96 * Motorola MCG MCPN765 interrupt routing.
97 */
98static inline int
99mcpn765_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
100{
101 static char pci_irq_table[][4] =
102 /*
103 * PCI IDSEL/INTPIN->INTLINE
104 * A B C D
105 */
106 {
107 { 14, 0, 0, 0 }, /* IDSEL 11 - have to manually set */
108 { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
109 { 0, 0, 0, 0 }, /* IDSEL 13 - unused */
110 { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */
111 { 0, 0, 0, 0 }, /* IDSEL 15 - unused */
112 { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */
113 { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */
114 { 0, 0, 0, 0 }, /* IDSEL 18 - PMC 2B Connector XXXX */
115 { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 1 */
116 { 20, 0, 0, 0 }, /* IDSEL 20 - 21554 cPCI bridge */
117 };
118
119 const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4;
120 return PCI_IRQ_TABLE_LOOKUP;
121}
122
123void __init
124mcpn765_set_VIA_IDE_legacy(void)
125{
126 unsigned short vend, dev;
127
128 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
129 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
130
131 if ((vend == PCI_VENDOR_ID_VIA) &&
132 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
133
134 unsigned char temp;
135
136 /* put back original "standard" port base addresses */
137 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
138 PCI_BASE_ADDRESS_0, 0x1f1);
139 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
140 PCI_BASE_ADDRESS_1, 0x3f5);
141 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
142 PCI_BASE_ADDRESS_2, 0x171);
143 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
144 PCI_BASE_ADDRESS_3, 0x375);
145 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
146 PCI_BASE_ADDRESS_4, 0xcc01);
147
148 /* put into legacy mode */
149 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
150 &temp);
151 temp &= ~0x05;
152 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
153 temp);
154 }
155}
156
157void
158mcpn765_set_VIA_IDE_native(void)
159{
160 unsigned short vend, dev;
161
162 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
163 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
164
165 if ((vend == PCI_VENDOR_ID_VIA) &&
166 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
167
168 unsigned char temp;
169
170 /* put into native mode */
171 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
172 &temp);
173 temp |= 0x05;
174 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
175 temp);
176 }
177}
178
179/*
180 * Initialize the VIA 82c586b.
181 */
182static void __init
183mcpn765_setup_via_82c586b(void)
184{
185 struct pci_dev *dev;
186 u_char c;
187
188 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
189 PCI_DEVICE_ID_VIA_82C586_0,
190 NULL)) == NULL) {
191 printk("No VIA ISA bridge found\n");
192 mcpn765_halt();
193 /* NOTREACHED */
194 }
195
196 /*
197 * If the firmware left the EISA 4d0/4d1 ports enabled, make sure
198 * IRQ 14 is set for edge.
199 */
200 pci_read_config_byte(dev, 0x47, &c);
201
202 if (c & (1<<5)) {
203 c = inb(0x4d1);
204 c &= ~(1<<6);
205 outb(c, 0x4d1);
206 }
207
208 /* Disable PNP IRQ routing since we use the Hawk's MPIC */
209 pci_write_config_dword(dev, 0x54, 0);
210 pci_write_config_byte(dev, 0x58, 0);
211
212 pci_dev_put(dev);
213 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
214 PCI_DEVICE_ID_VIA_82C586_1,
215 NULL)) == NULL) {
216 printk("No VIA ISA bridge found\n");
217 mcpn765_halt();
218 /* NOTREACHED */
219 }
220
221 /*
222 * PPCBug doesn't set the enable bits for the IDE device.
223 * Turn them on now.
224 */
225 pci_read_config_byte(dev, 0x40, &c);
226 c |= 0x03;
227 pci_write_config_byte(dev, 0x40, c);
228 pci_dev_put(dev);
229
230 return;
231}
232
233void __init
234mcpn765_pcibios_fixup(void)
235{
236 /* Do MCPN765 board specific initialization. */
237 mcpn765_setup_via_82c586b();
238}
239
240void __init
241mcpn765_find_bridges(void)
242{
243 struct pci_controller *hose;
244
245 hose = pcibios_alloc_controller();
246
247 if (!hose)
248 return;
249
250 hose->first_busno = 0;
251 hose->last_busno = 0xff;
252 hose->pci_mem_offset = MCPN765_PCI_PHY_MEM_OFFSET;
253
254 pci_init_resource(&hose->io_resource,
255 MCPN765_PCI_IO_START,
256 MCPN765_PCI_IO_END,
257 IORESOURCE_IO,
258 "PCI host bridge");
259
260 pci_init_resource(&hose->mem_resources[0],
261 MCPN765_PCI_MEM_START,
262 MCPN765_PCI_MEM_END,
263 IORESOURCE_MEM,
264 "PCI host bridge");
265
266 hose->io_space.start = MCPN765_PCI_IO_START;
267 hose->io_space.end = MCPN765_PCI_IO_END;
268 hose->mem_space.start = MCPN765_PCI_MEM_START;
269 hose->mem_space.end = MCPN765_PCI_MEM_END - HAWK_MPIC_SIZE;
270
271 if (hawk_init(hose,
272 MCPN765_HAWK_PPC_REG_BASE,
273 MCPN765_PROC_PCI_MEM_START,
274 MCPN765_PROC_PCI_MEM_END - HAWK_MPIC_SIZE,
275 MCPN765_PROC_PCI_IO_START,
276 MCPN765_PROC_PCI_IO_END,
277 MCPN765_PCI_MEM_END - HAWK_MPIC_SIZE + 1) != 0) {
278 printk("Could not initialize HAWK bridge\n");
279 }
280
281 /* VIA IDE BAR decoders are only 16-bits wide. PCI Auto Config
282 * will reassign the bars outside of 16-bit I/O space, which will
283 * "break" things. To prevent this, we'll set the IDE chip into
284 * legacy mode and seed the bars with their legacy addresses (in 16-bit
285 * I/O space). The Auto Config code will skip the IDE contoller in
286 * legacy mode, so our bar values will stick.
287 */
288 mcpn765_set_VIA_IDE_legacy();
289
290 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
291
292 /* Now that we've got 16-bit addresses in the bars, we can switch the
293 * IDE controller back into native mode so we can do "modern" resource
294 * and interrupt management.
295 */
296 mcpn765_set_VIA_IDE_native();
297
298 ppc_md.pcibios_fixup = mcpn765_pcibios_fixup;
299 ppc_md.pcibios_fixup_bus = NULL;
300 ppc_md.pci_swizzle = common_swizzle;
301 ppc_md.pci_map_irq = mcpn765_map_irq;
302
303 return;
304}
305static void __init
306mcpn765_setup_arch(void)
307{
308 struct pci_controller *hose;
309
310 if ( ppc_md.progress )
311 ppc_md.progress("mcpn765_setup_arch: enter", 0);
312
313 loops_per_jiffy = 50000000 / HZ;
314
315#ifdef CONFIG_BLK_DEV_INITRD
316 if (initrd_start)
317 ROOT_DEV = Root_RAM0;
318 else
319#endif
320#ifdef CONFIG_ROOT_NFS
321 ROOT_DEV = Root_NFS;
322#else
323 ROOT_DEV = Root_SDA2;
324#endif
325
326 if ( ppc_md.progress )
327 ppc_md.progress("mcpn765_setup_arch: find_bridges", 0);
328
329 /* Lookup PCI host bridges */
330 mcpn765_find_bridges();
331
332 hose = pci_bus_to_hose(0);
333 isa_io_base = (ulong)hose->io_base_virt;
334
335 TODC_INIT(TODC_TYPE_MK48T37,
336 (MCPN765_PHYS_NVRAM_AS0 - isa_io_base),
337 (MCPN765_PHYS_NVRAM_AS1 - isa_io_base),
338 (MCPN765_PHYS_NVRAM_DATA - isa_io_base),
339 8);
340
341 OpenPIC_InitSenses = mcpn765_openpic_initsenses;
342 OpenPIC_NumInitSenses = sizeof(mcpn765_openpic_initsenses);
343
344 printk("Motorola MCG MCPN765 cPCI Non-System Board\n");
345 printk("MCPN765 port (MontaVista Software, Inc. (source@mvista.com))\n");
346
347 if ( ppc_md.progress )
348 ppc_md.progress("mcpn765_setup_arch: exit", 0);
349
350 return;
351}
352
353static void __init
354mcpn765_init2(void)
355{
356
357 request_region(0x00,0x20,"dma1");
358 request_region(0x20,0x20,"pic1");
359 request_region(0x40,0x20,"timer");
360 request_region(0x80,0x10,"dma page reg");
361 request_region(0xa0,0x20,"pic2");
362 request_region(0xc0,0x20,"dma2");
363
364 return;
365}
366
367/*
368 * Interrupt setup and service.
369 * Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC.
370 */
371static void __init
372mcpn765_init_IRQ(void)
373{
374 int i;
375
376 if ( ppc_md.progress )
377 ppc_md.progress("init_irq: enter", 0);
378
379 openpic_init(NUM_8259_INTERRUPTS);
380 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
381 i8259_irq);
382
383 for(i=0; i < NUM_8259_INTERRUPTS; i++)
384 irq_desc[i].handler = &i8259_pic;
385
386 i8259_init(0);
387
388 if ( ppc_md.progress )
389 ppc_md.progress("init_irq: exit", 0);
390
391 return;
392}
393
394static u32
395mcpn765_irq_canonicalize(u32 irq)
396{
397 if (irq == 2)
398 return 9;
399 else
400 return irq;
401}
402
403static unsigned long __init
404mcpn765_find_end_of_memory(void)
405{
406 return hawk_get_mem_size(MCPN765_HAWK_SMC_BASE);
407}
408
409static void __init
410mcpn765_map_io(void)
411{
412 io_block_mapping(0xfe800000, 0xfe800000, 0x00800000, _PAGE_IO);
413}
414
415static void
416mcpn765_reset_board(void)
417{
418 local_irq_disable();
419
420 /* set VIA IDE controller into native mode */
421 mcpn765_set_VIA_IDE_native();
422
423 /* Set exception prefix high - to the firmware */
424 _nmask_and_or_msr(0, MSR_IP);
425
426 out_8((u_char *)MCPN765_BOARD_MODRST_REG, 0x01);
427
428 return;
429}
430
431static void
432mcpn765_restart(char *cmd)
433{
434 volatile ulong i = 10000000;
435
436 mcpn765_reset_board();
437
438 while (i-- > 0);
439 panic("restart failed\n");
440}
441
442static void
443mcpn765_power_off(void)
444{
445 mcpn765_halt();
446 /* NOTREACHED */
447}
448
449static void
450mcpn765_halt(void)
451{
452 local_irq_disable();
453 while (1);
454 /* NOTREACHED */
455}
456
457static int
458mcpn765_show_cpuinfo(struct seq_file *m)
459{
460 seq_printf(m, "vendor\t\t: Motorola MCG\n");
461 seq_printf(m, "machine\t\t: MCPN765\n");
462
463 return 0;
464}
465
466/*
467 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
468 */
469static __inline__ void
470mcpn765_set_bat(void)
471{
472 mb();
473 mtspr(SPRN_DBAT1U, 0xfe8000fe);
474 mtspr(SPRN_DBAT1L, 0xfe80002a);
475 mb();
476}
477
478void __init
479platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
480 unsigned long r6, unsigned long r7)
481{
482 parse_bootinfo(find_bootinfo());
483
484 /* Map in board regs, etc. */
485 mcpn765_set_bat();
486
487 isa_mem_base = MCPN765_ISA_MEM_BASE;
488 pci_dram_offset = MCPN765_PCI_DRAM_OFFSET;
489 ISA_DMA_THRESHOLD = 0x00ffffff;
490 DMA_MODE_READ = 0x44;
491 DMA_MODE_WRITE = 0x48;
492
493 ppc_md.setup_arch = mcpn765_setup_arch;
494 ppc_md.show_cpuinfo = mcpn765_show_cpuinfo;
495 ppc_md.irq_canonicalize = mcpn765_irq_canonicalize;
496 ppc_md.init_IRQ = mcpn765_init_IRQ;
497 ppc_md.get_irq = openpic_get_irq;
498 ppc_md.init = mcpn765_init2;
499
500 ppc_md.restart = mcpn765_restart;
501 ppc_md.power_off = mcpn765_power_off;
502 ppc_md.halt = mcpn765_halt;
503
504 ppc_md.find_end_of_memory = mcpn765_find_end_of_memory;
505 ppc_md.setup_io_mappings = mcpn765_map_io;
506
507 ppc_md.time_init = todc_time_init;
508 ppc_md.set_rtc_time = todc_set_rtc_time;
509 ppc_md.get_rtc_time = todc_get_rtc_time;
510 ppc_md.calibrate_decr = todc_calibrate_decr;
511
512 ppc_md.nvram_read_val = todc_m48txx_read_val;
513 ppc_md.nvram_write_val = todc_m48txx_write_val;
514
515 ppc_md.heartbeat = NULL;
516 ppc_md.heartbeat_reset = 0;
517 ppc_md.heartbeat_count = 0;
518
519#ifdef CONFIG_SERIAL_TEXT_DEBUG
520 ppc_md.progress = gen550_progress;
521#endif
522#ifdef CONFIG_KGDB
523 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
524#endif
525
526 return;
527}
diff --git a/arch/ppc/platforms/mcpn765.h b/arch/ppc/platforms/mcpn765.h
new file mode 100644
index 000000000000..4d35ecad097b
--- /dev/null
+++ b/arch/ppc/platforms/mcpn765.h
@@ -0,0 +1,122 @@
1/*
2 * arch/ppc/platforms/mcpn765.h
3 *
4 * Definitions for Motorola MCG MCPN765 cPCI Board.
5 *
6 * Author: Mark A. Greer
7 * mgreer@mvista.com
8 *
9 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15/*
16 * From Processor to PCI:
17 * PCI Mem Space: 0x80000000 - 0xc0000000 -> 0x80000000 - 0xc0000000 (1 GB)
18 * PCI I/O Space: 0xfd800000 - 0xfe000000 -> 0x00000000 - 0x00800000 (8 MB)
19 * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area
20 * MPIC in PCI Mem Space: 0xfe800000 - 0xfe830000 (not all used by MPIC)
21 *
22 * From PCI to Processor:
23 * System Memory: 0x00000000 -> 0x00000000
24 */
25
26#ifndef __PPC_PLATFORMS_MCPN765_H
27#define __PPC_PLATFORMS_MCPN765_H
28#include <linux/config.h>
29
30/* PCI Memory space mapping info */
31#define MCPN765_PCI_MEM_SIZE 0x40000000U
32#define MCPN765_PROC_PCI_MEM_START 0x80000000U
33#define MCPN765_PROC_PCI_MEM_END (MCPN765_PROC_PCI_MEM_START + \
34 MCPN765_PCI_MEM_SIZE - 1)
35#define MCPN765_PCI_MEM_START 0x80000000U
36#define MCPN765_PCI_MEM_END (MCPN765_PCI_MEM_START + \
37 MCPN765_PCI_MEM_SIZE - 1)
38
39/* PCI I/O space mapping info */
40#define MCPN765_PCI_IO_SIZE 0x00800000U
41#define MCPN765_PROC_PCI_IO_START 0xfd800000U
42#define MCPN765_PROC_PCI_IO_END (MCPN765_PROC_PCI_IO_START + \
43 MCPN765_PCI_IO_SIZE - 1)
44#define MCPN765_PCI_IO_START 0x00000000U
45#define MCPN765_PCI_IO_END (MCPN765_PCI_IO_START + \
46 MCPN765_PCI_IO_SIZE - 1)
47
48/* System memory mapping info */
49#define MCPN765_PCI_DRAM_OFFSET 0x00000000U
50#define MCPN765_PCI_PHY_MEM_OFFSET 0x00000000U
51
52#define MCPN765_ISA_MEM_BASE 0x00000000U
53#define MCPN765_ISA_IO_BASE MCPN765_PROC_PCI_IO_START
54
55/* Define base addresses for important sets of registers */
56#define MCPN765_HAWK_MPIC_BASE 0xfe800000U
57#define MCPN765_HAWK_SMC_BASE 0xfef80000U
58#define MCPN765_HAWK_PPC_REG_BASE 0xfeff0000U
59
60/* Define MCPN765 board register addresses. */
61#define MCPN765_BOARD_STATUS_REG 0xfef88080U
62#define MCPN765_BOARD_MODFAIL_REG 0xfef88090U
63#define MCPN765_BOARD_MODRST_REG 0xfef880a0U
64#define MCPN765_BOARD_TBEN_REG 0xfef880c0U
65#define MCPN765_BOARD_GEOGRAPHICAL_REG 0xfef880e8U
66#define MCPN765_BOARD_EXT_FEATURE_REG 0xfef880f0U
67#define MCPN765_BOARD_LAST_RESET_REG 0xfef880f8U
68
69/* Defines for UART */
70
71/* Define the UART base addresses */
72#define MCPN765_SERIAL_1 0xfef88000
73#define MCPN765_SERIAL_2 0xfef88200
74#define MCPN765_SERIAL_3 0xfef88400
75#define MCPN765_SERIAL_4 0xfef88600
76
77#ifdef CONFIG_SERIAL_MANY_PORTS
78#define RS_TABLE_SIZE 64
79#else
80#define RS_TABLE_SIZE 4
81#endif
82
83/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
84#define BASE_BAUD ( 1843200 / 16 )
85#define UART_CLK 1843200
86
87#ifdef CONFIG_SERIAL_DETECT_IRQ
88#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
89#else
90#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
91#endif
92
93/* All UART IRQ's are wire-OR'd to IRQ 17 */
94#define STD_SERIAL_PORT_DFNS \
95 { 0, BASE_BAUD, MCPN765_SERIAL_1, 17, STD_COM_FLAGS, /* ttyS0 */\
96 iomem_base: (u8 *)MCPN765_SERIAL_1, \
97 iomem_reg_shift: 4, \
98 io_type: SERIAL_IO_MEM }, \
99 { 0, BASE_BAUD, MCPN765_SERIAL_2, 17, STD_COM_FLAGS, /* ttyS1 */\
100 iomem_base: (u8 *)MCPN765_SERIAL_2, \
101 iomem_reg_shift: 4, \
102 io_type: SERIAL_IO_MEM }, \
103 { 0, BASE_BAUD, MCPN765_SERIAL_3, 17, STD_COM_FLAGS, /* ttyS2 */\
104 iomem_base: (u8 *)MCPN765_SERIAL_3, \
105 iomem_reg_shift: 4, \
106 io_type: SERIAL_IO_MEM }, \
107 { 0, BASE_BAUD, MCPN765_SERIAL_4, 17, STD_COM_FLAGS, /* ttyS3 */\
108 iomem_base: (u8 *)MCPN765_SERIAL_4, \
109 iomem_reg_shift: 4, \
110 io_type: SERIAL_IO_MEM },
111
112#define SERIAL_PORT_DFNS \
113 STD_SERIAL_PORT_DFNS
114
115/* Define the NVRAM/RTC address strobe & data registers */
116#define MCPN765_PHYS_NVRAM_AS0 0xfef880c8U
117#define MCPN765_PHYS_NVRAM_AS1 0xfef880d0U
118#define MCPN765_PHYS_NVRAM_DATA 0xfef880d8U
119
120extern void mcpn765_find_bridges(void);
121
122#endif /* __PPC_PLATFORMS_MCPN765_H */
diff --git a/arch/ppc/platforms/mpc5200.c b/arch/ppc/platforms/mpc5200.c
new file mode 100644
index 000000000000..a58db438c162
--- /dev/null
+++ b/arch/ppc/platforms/mpc5200.c
@@ -0,0 +1,53 @@
1/*
2 * arch/ppc/platforms/mpc5200.c
3 *
4 * OCP Definitions for the boards based on MPC5200 processor. Contains
5 * definitions for every common peripherals. (Mostly all but PSCs)
6 *
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
8 *
9 * Copyright 2004 Sylvain Munaut <tnt@246tNt.com>
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <asm/ocp.h>
17#include <asm/mpc52xx.h>
18
19
20static struct ocp_fs_i2c_data mpc5200_i2c_def = {
21 .flags = FS_I2C_CLOCK_5200,
22};
23
24
25/* Here is the core_ocp struct.
26 * With all the devices common to all board. Even if port multiplexing is
27 * not setup for them (if the user don't want them, just don't select the
28 * config option). The potentially conflicting devices (like PSCs) goes in
29 * board specific file.
30 */
31struct ocp_def core_ocp[] = {
32 {
33 .vendor = OCP_VENDOR_FREESCALE,
34 .function = OCP_FUNC_IIC,
35 .index = 0,
36 .paddr = MPC52xx_I2C1,
37 .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C1 - Buggy */
38 .pm = OCP_CPM_NA,
39 .additions = &mpc5200_i2c_def,
40 },
41 {
42 .vendor = OCP_VENDOR_FREESCALE,
43 .function = OCP_FUNC_IIC,
44 .index = 1,
45 .paddr = MPC52xx_I2C2,
46 .irq = OCP_IRQ_NA, /* MPC52xx_IRQ_I2C2 - Buggy */
47 .pm = OCP_CPM_NA,
48 .additions = &mpc5200_i2c_def,
49 },
50 { /* Terminating entry */
51 .vendor = OCP_VENDOR_INVALID
52 }
53};
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
new file mode 100644
index 000000000000..b292b44b760c
--- /dev/null
+++ b/arch/ppc/platforms/mvme5100.c
@@ -0,0 +1,349 @@
1/*
2 * arch/ppc/platforms/mvme5100.c
3 *
4 * Board setup routines for the Motorola MVME5100.
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/pci.h>
20#include <linux/initrd.h>
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/irq.h>
24#include <linux/ide.h>
25#include <linux/seq_file.h>
26#include <linux/kdev_t.h>
27#include <linux/root_dev.h>
28
29#include <asm/system.h>
30#include <asm/pgtable.h>
31#include <asm/page.h>
32#include <asm/dma.h>
33#include <asm/io.h>
34#include <asm/machdep.h>
35#include <asm/open_pic.h>
36#include <asm/i8259.h>
37#include <asm/todc.h>
38#include <asm/pci-bridge.h>
39#include <asm/bootinfo.h>
40#include <asm/hawk.h>
41
42#include <platforms/pplus.h>
43#include <platforms/mvme5100.h>
44
45static u_char mvme5100_openpic_initsenses[16] __initdata = {
46 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* i8259 cascade */
47 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* TL16C550 UART 1,2 */
48 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Enet1 front panel or P2 */
49 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Hawk Watchdog 1,2 */
50 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* DS1621 thermal alarm */
51 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Universe II LINT0# */
52 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Universe II LINT1# */
53 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Universe II LINT2# */
54 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Universe II LINT3# */
55 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PMC1 INTA#, PMC2 INTB# */
56 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PMC1 INTB#, PMC2 INTC# */
57 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PMC1 INTC#, PMC2 INTD# */
58 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PMC1 INTD#, PMC2 INTA# */
59 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Enet 2 (front panel) */
60 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Abort Switch */
61 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* RTC Alarm */
62};
63
64static inline int
65mvme5100_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
66{
67 int irq;
68
69 static char pci_irq_table[][4] =
70 /*
71 * PCI IDSEL/INTPIN->INTLINE
72 * A B C D
73 */
74 {
75 { 0, 0, 0, 0 }, /* IDSEL 11 - Winbond */
76 { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
77 { 21, 22, 23, 24 }, /* IDSEL 13 - Universe II */
78 { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */
79 { 0, 0, 0, 0 }, /* IDSEL 15 - unused */
80 { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */
81 { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */
82 { 0, 0, 0, 0 }, /* IDSEL 18 - unused */
83 { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */
84 { 0, 0, 0, 0 }, /* IDSEL 20 - PMCSPAN */
85 };
86
87 const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4;
88 irq = PCI_IRQ_TABLE_LOOKUP;
89 /* If lookup is zero, always return 0 */
90 if (!irq)
91 return 0;
92 else
93#ifdef CONFIG_MVME5100_IPMC761_PRESENT
94 /* If IPMC761 present, return table value */
95 return irq;
96#else
97 /* If IPMC761 not present, we don't have an i8259 so adjust */
98 return (irq - NUM_8259_INTERRUPTS);
99#endif
100}
101
102static void
103mvme5100_pcibios_fixup_resources(struct pci_dev *dev)
104{
105 int i;
106
107 if ((dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
108 (dev->device == PCI_DEVICE_ID_MOTOROLA_HAWK))
109 for (i=0; i<DEVICE_COUNT_RESOURCE; i++)
110 {
111 dev->resource[i].start = 0;
112 dev->resource[i].end = 0;
113 }
114}
115
116static void __init
117mvme5100_setup_bridge(void)
118{
119 struct pci_controller* hose;
120
121 hose = pcibios_alloc_controller();
122
123 if (!hose)
124 return;
125
126 hose->first_busno = 0;
127 hose->last_busno = 0xff;
128 hose->pci_mem_offset = MVME5100_PCI_MEM_OFFSET;
129
130 pci_init_resource(&hose->io_resource, MVME5100_PCI_LOWER_IO,
131 MVME5100_PCI_UPPER_IO, IORESOURCE_IO,
132 "PCI host bridge");
133
134 pci_init_resource(&hose->mem_resources[0], MVME5100_PCI_LOWER_MEM,
135 MVME5100_PCI_UPPER_MEM, IORESOURCE_MEM,
136 "PCI host bridge");
137
138 hose->io_space.start = MVME5100_PCI_LOWER_IO;
139 hose->io_space.end = MVME5100_PCI_UPPER_IO;
140 hose->mem_space.start = MVME5100_PCI_LOWER_MEM;
141 hose->mem_space.end = MVME5100_PCI_UPPER_MEM;
142 hose->io_base_virt = (void *)MVME5100_ISA_IO_BASE;
143
144 /* Use indirect method of Hawk */
145 setup_indirect_pci(hose, MVME5100_PCI_CONFIG_ADDR,
146 MVME5100_PCI_CONFIG_DATA);
147
148 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
149
150 ppc_md.pcibios_fixup_resources = mvme5100_pcibios_fixup_resources;
151 ppc_md.pci_swizzle = common_swizzle;
152 ppc_md.pci_map_irq = mvme5100_map_irq;
153}
154
155static void __init
156mvme5100_setup_arch(void)
157{
158 if ( ppc_md.progress )
159 ppc_md.progress("mvme5100_setup_arch: enter", 0);
160
161 loops_per_jiffy = 50000000 / HZ;
162
163#ifdef CONFIG_BLK_DEV_INITRD
164 if (initrd_start)
165 ROOT_DEV = Root_RAM0;
166 else
167#endif
168#ifdef CONFIG_ROOT_NFS
169 ROOT_DEV = Root_NFS;
170#else
171 ROOT_DEV = Root_SDA2;
172#endif
173
174 if ( ppc_md.progress )
175 ppc_md.progress("mvme5100_setup_arch: find_bridges", 0);
176
177 /* Setup PCI host bridge */
178 mvme5100_setup_bridge();
179
180 /* Find and map our OpenPIC */
181 hawk_mpic_init(MVME5100_PCI_MEM_OFFSET);
182 OpenPIC_InitSenses = mvme5100_openpic_initsenses;
183 OpenPIC_NumInitSenses = sizeof(mvme5100_openpic_initsenses);
184
185 printk("MVME5100 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
186
187 if ( ppc_md.progress )
188 ppc_md.progress("mvme5100_setup_arch: exit", 0);
189
190 return;
191}
192
193static void __init
194mvme5100_init2(void)
195{
196#ifdef CONFIG_MVME5100_IPMC761_PRESENT
197 request_region(0x00,0x20,"dma1");
198 request_region(0x20,0x20,"pic1");
199 request_region(0x40,0x20,"timer");
200 request_region(0x80,0x10,"dma page reg");
201 request_region(0xa0,0x20,"pic2");
202 request_region(0xc0,0x20,"dma2");
203#endif
204 return;
205}
206
207/*
208 * Interrupt setup and service.
209 * Have MPIC on HAWK and cascaded 8259s on Winbond cascaded to MPIC.
210 */
211static void __init
212mvme5100_init_IRQ(void)
213{
214#ifdef CONFIG_MVME5100_IPMC761_PRESENT
215 int i;
216#endif
217
218 if ( ppc_md.progress )
219 ppc_md.progress("init_irq: enter", 0);
220
221 openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
222#ifdef CONFIG_MVME5100_IPMC761_PRESENT
223 openpic_init(NUM_8259_INTERRUPTS);
224 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
225 &i8259_irq);
226
227 /* Map i8259 interrupts. */
228 for (i = 0; i < NUM_8259_INTERRUPTS; i++)
229 irq_desc[i].handler = &i8259_pic;
230
231 i8259_init(0);
232#else
233 openpic_init(0);
234#endif
235
236 if ( ppc_md.progress )
237 ppc_md.progress("init_irq: exit", 0);
238
239 return;
240}
241
242/*
243 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
244 */
245static __inline__ void
246mvme5100_set_bat(void)
247{
248 mb();
249 mtspr(SPRN_DBAT1U, 0xf0001ffe);
250 mtspr(SPRN_DBAT1L, 0xf000002a);
251 mb();
252}
253
254static unsigned long __init
255mvme5100_find_end_of_memory(void)
256{
257 return hawk_get_mem_size(MVME5100_HAWK_SMC_BASE);
258}
259
260static void __init
261mvme5100_map_io(void)
262{
263 io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
264 ioremap_base = 0xfe000000;
265}
266
267static void
268mvme5100_reset_board(void)
269{
270 local_irq_disable();
271
272 /* Set exception prefix high - to the firmware */
273 _nmask_and_or_msr(0, MSR_IP);
274
275 out_8((u_char *)MVME5100_BOARD_MODRST_REG, 0x01);
276
277 return;
278}
279
280static void
281mvme5100_restart(char *cmd)
282{
283 volatile ulong i = 10000000;
284
285 mvme5100_reset_board();
286
287 while (i-- > 0);
288 panic("restart failed\n");
289}
290
291static void
292mvme5100_halt(void)
293{
294 local_irq_disable();
295 while (1);
296}
297
298static void
299mvme5100_power_off(void)
300{
301 mvme5100_halt();
302}
303
304static int
305mvme5100_show_cpuinfo(struct seq_file *m)
306{
307 seq_printf(m, "vendor\t\t: Motorola\n");
308 seq_printf(m, "machine\t\t: MVME5100\n");
309
310 return 0;
311}
312
313TODC_ALLOC();
314
315void __init
316platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
317 unsigned long r6, unsigned long r7)
318{
319 parse_bootinfo(find_bootinfo());
320 mvme5100_set_bat();
321
322 isa_io_base = MVME5100_ISA_IO_BASE;
323 isa_mem_base = MVME5100_ISA_MEM_BASE;
324 pci_dram_offset = MVME5100_PCI_DRAM_OFFSET;
325
326 ppc_md.setup_arch = mvme5100_setup_arch;
327 ppc_md.show_cpuinfo = mvme5100_show_cpuinfo;
328 ppc_md.init_IRQ = mvme5100_init_IRQ;
329 ppc_md.get_irq = openpic_get_irq;
330 ppc_md.init = mvme5100_init2;
331
332 ppc_md.restart = mvme5100_restart;
333 ppc_md.power_off = mvme5100_power_off;
334 ppc_md.halt = mvme5100_halt;
335
336 ppc_md.find_end_of_memory = mvme5100_find_end_of_memory;
337 ppc_md.setup_io_mappings = mvme5100_map_io;
338
339 TODC_INIT(TODC_TYPE_MK48T37, MVME5100_NVRAM_AS0, MVME5100_NVRAM_AS1,
340 MVME5100_NVRAM_DATA, 8);
341
342 ppc_md.time_init = todc_time_init;
343 ppc_md.set_rtc_time = todc_set_rtc_time;
344 ppc_md.get_rtc_time = todc_get_rtc_time;
345 ppc_md.calibrate_decr = todc_calibrate_decr;
346
347 ppc_md.nvram_read_val = todc_m48txx_read_val;
348 ppc_md.nvram_write_val = todc_m48txx_write_val;
349}
diff --git a/arch/ppc/platforms/mvme5100.h b/arch/ppc/platforms/mvme5100.h
new file mode 100644
index 000000000000..edd479439a4e
--- /dev/null
+++ b/arch/ppc/platforms/mvme5100.h
@@ -0,0 +1,91 @@
1/*
2 * include/asm-ppc/platforms/mvme5100.h
3 *
4 * Definitions for Motorola MVME5100.
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifdef __KERNEL__
15#ifndef __ASM_MVME5100_H__
16#define __ASM_MVME5100_H__
17
18#define MVME5100_HAWK_SMC_BASE 0xfef80000
19
20#define MVME5100_PCI_CONFIG_ADDR 0xfe000cf8
21#define MVME5100_PCI_CONFIG_DATA 0xfe000cfc
22
23#define MVME5100_PCI_IO_BASE 0xfe000000
24#define MVME5100_PCI_MEM_BASE 0x80000000
25
26#define MVME5100_PCI_MEM_OFFSET 0x00000000
27
28#define MVME5100_PCI_DRAM_OFFSET 0x00000000
29#define MVME5100_ISA_MEM_BASE 0x00000000
30#define MVME5100_ISA_IO_BASE MVME5100_PCI_IO_BASE
31
32#define MVME5100_PCI_LOWER_MEM 0x80000000
33#define MVME5100_PCI_UPPER_MEM 0xf3f7ffff
34#define MVME5100_PCI_LOWER_IO 0x00000000
35#define MVME5100_PCI_UPPER_IO 0x0077ffff
36
37/* MVME5100 board register addresses. */
38#define MVME5100_BOARD_STATUS_REG 0xfef88080
39#define MVME5100_BOARD_MODFAIL_REG 0xfef88090
40#define MVME5100_BOARD_MODRST_REG 0xfef880a0
41#define MVME5100_BOARD_TBEN_REG 0xfef880c0
42#define MVME5100_BOARD_SW_READ_REG 0xfef880e0
43#define MVME5100_BOARD_GEO_ADDR_REG 0xfef880e8
44#define MVME5100_BOARD_EXT_FEATURE1_REG 0xfef880f0
45#define MVME5100_BOARD_EXT_FEATURE2_REG 0xfef88100
46
47/* Define the NVRAM/RTC address strobe & data registers */
48#define MVME5100_PHYS_NVRAM_AS0 0xfef880c8
49#define MVME5100_PHYS_NVRAM_AS1 0xfef880d0
50#define MVME5100_PHYS_NVRAM_DATA 0xfef880d8
51
52#define MVME5100_NVRAM_AS0 (MVME5100_PHYS_NVRAM_AS0 - MVME5100_ISA_IO_BASE)
53#define MVME5100_NVRAM_AS1 (MVME5100_PHYS_NVRAM_AS1 - MVME5100_ISA_IO_BASE)
54#define MVME5100_NVRAM_DATA (MVME5100_PHYS_NVRAM_DATA - MVME5100_ISA_IO_BASE)
55
56/* UART clock, addresses, and irq */
57#define MVME5100_BASE_BAUD 1843200
58#define MVME5100_SERIAL_1 0xfef88000
59#define MVME5100_SERIAL_2 0xfef88200
60#ifdef CONFIG_MVME5100_IPMC761_PRESENT
61#define MVME5100_SERIAL_IRQ 17
62#else
63#define MVME5100_SERIAL_IRQ 1
64#endif
65
66#define RS_TABLE_SIZE 4
67
68#define BASE_BAUD ( MVME5100_BASE_BAUD / 16 )
69
70#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
71
72/* All UART IRQ's are wire-OR'd to one MPIC IRQ */
73#define STD_SERIAL_PORT_DFNS \
74 { 0, BASE_BAUD, MVME5100_SERIAL_1, \
75 MVME5100_SERIAL_IRQ, \
76 STD_COM_FLAGS, /* ttyS0 */ \
77 iomem_base: (unsigned char *)MVME5100_SERIAL_1, \
78 iomem_reg_shift: 4, \
79 io_type: SERIAL_IO_MEM }, \
80 { 0, BASE_BAUD, MVME5100_SERIAL_2, \
81 MVME5100_SERIAL_IRQ, \
82 STD_COM_FLAGS, /* ttyS1 */ \
83 iomem_base: (unsigned char *)MVME5100_SERIAL_2, \
84 iomem_reg_shift: 4, \
85 io_type: SERIAL_IO_MEM },
86
87#define SERIAL_PORT_DFNS \
88 STD_SERIAL_PORT_DFNS
89
90#endif /* __ASM_MVME5100_H__ */
91#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/pal4.h b/arch/ppc/platforms/pal4.h
new file mode 100644
index 000000000000..641a11a31657
--- /dev/null
+++ b/arch/ppc/platforms/pal4.h
@@ -0,0 +1,42 @@
1/*
2 * arch/ppc/platforms/pal4.h
3 *
4 * Definitions for SBS Palomar IV board
5 *
6 * Author: Dan Cox
7 *
8 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __PPC_PLATFORMS_PAL4_H
15#define __PPC_PLATFORMS_PAL4_H
16
17#define PAL4_NVRAM 0xfffc0000
18#define PAL4_NVRAM_SIZE 0x8000
19
20#define PAL4_DRAM 0xfff80000
21#define PAL4_DRAM_BR_MASK 0xc0
22#define PAL4_DRAM_BR_SHIFT 6
23#define PAL4_DRAM_RESET 0x10
24#define PAL4_DRAM_EREADY 0x40
25
26#define PAL4_MISC 0xfff80004
27#define PAL4_MISC_FB_MASK 0xc0
28#define PAL4_MISC_FLASH 0x20 /* StratFlash mapping: 1->0xff80, 0->0xfff0 */
29#define PAL4_MISC_MISC 0x08
30#define PAL4_MISC_BITF 0x02
31#define PAL4_MISC_NVKS 0x01
32
33#define PAL4_L2 0xfff80008
34#define PAL4_L2_MASK 0x07
35
36#define PAL4_PLDR 0xfff8000c
37
38/* Only two Ethernet devices on the board... */
39#define PAL4_ETH 31
40#define PAL4_INTA 20
41
42#endif /* __PPC_PLATFORMS_PAL4_H */
diff --git a/arch/ppc/platforms/pal4_pci.c b/arch/ppc/platforms/pal4_pci.c
new file mode 100644
index 000000000000..c3b1b757a48b
--- /dev/null
+++ b/arch/ppc/platforms/pal4_pci.c
@@ -0,0 +1,77 @@
1/*
2 * arch/ppc/platforms/pal4_pci.c
3 *
4 * PCI support for SBS Palomar IV
5 *
6 * Author: Dan Cox
7 *
8 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/pci.h>
17
18#include <asm/byteorder.h>
19#include <asm/machdep.h>
20#include <asm/io.h>
21#include <asm/pci-bridge.h>
22#include <asm/uaccess.h>
23
24#include <syslib/cpc700.h>
25
26#include "pal4.h"
27
28/* not much to this.... */
29static inline int __init
30pal4_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
31{
32 if (idsel == 9)
33 return PAL4_ETH;
34 else
35 return PAL4_INTA + (idsel - 3);
36}
37
38void __init
39pal4_find_bridges(void)
40{
41 struct pci_controller *hose;
42
43 hose = pcibios_alloc_controller();
44 if (!hose)
45 return;
46
47 hose->first_busno = 0;
48 hose->last_busno = 0xff;
49 hose->pci_mem_offset = 0;
50
51 /* Could snatch these from the CPC700.... */
52 pci_init_resource(&hose->io_resource,
53 0x0,
54 0x03ffffff,
55 IORESOURCE_IO,
56 "PCI host bridge");
57
58 pci_init_resource(&hose->mem_resources[0],
59 0x90000000,
60 0x9fffffff,
61 IORESOURCE_MEM,
62 "PCI host bridge");
63
64 hose->io_space.start = 0x00800000;
65 hose->io_space.end = 0x03ffffff;
66 hose->mem_space.start = 0x90000000;
67 hose->mem_space.end = 0x9fffffff;
68 hose->io_base_virt = (void *) 0xf8000000;
69
70 setup_indirect_pci(hose, CPC700_PCI_CONFIG_ADDR,
71 CPC700_PCI_CONFIG_DATA);
72
73 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
74
75 ppc_md.pci_swizzle = common_swizzle;
76 ppc_md.pci_map_irq = pal4_map_irq;
77}
diff --git a/arch/ppc/platforms/pal4_serial.h b/arch/ppc/platforms/pal4_serial.h
new file mode 100644
index 000000000000..a715c66e1adf
--- /dev/null
+++ b/arch/ppc/platforms/pal4_serial.h
@@ -0,0 +1,39 @@
1/*
2 * arch/ppc/platforms/pal4_serial.h
3 *
4 * Definitions for SBS PalomarIV serial support
5 *
6 * Author: Dan Cox
7 *
8 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __PPC_PAL4_SERIAL_H
15#define __PPC_PAL4_SERIAL_H
16
17#define CPC700_SERIAL_1 0xff600300
18#define CPC700_SERIAL_2 0xff600400
19
20#define RS_TABLE_SIZE 2
21#define BASE_BAUD (33333333 / 4 / 16)
22
23#ifdef CONFIG_SERIAL_DETECT_IRQ
24#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
25#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ)
26#else
27#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
28#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF)
29#endif
30
31#define SERIAL_PORT_DFNS \
32 {0, BASE_BAUD, CPC700_SERIAL_1, 3, STD_COM_FLAGS, \
33 iomem_base: (unsigned char *) CPC700_SERIAL_1, \
34 io_type: SERIAL_IO_MEM}, /* ttyS0 */ \
35 {0, BASE_BAUD, CPC700_SERIAL_2, 4, STD_COM_FLAGS, \
36 iomem_base: (unsigned char *) CPC700_SERIAL_2, \
37 io_type: SERIAL_IO_MEM}
38
39#endif
diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
new file mode 100644
index 000000000000..12446b93e38c
--- /dev/null
+++ b/arch/ppc/platforms/pal4_setup.c
@@ -0,0 +1,175 @@
1/*
2 * arch/ppc/platforms/pal4_setup.c
3 *
4 * Board setup routines for the SBS PalomarIV.
5 *
6 * Author: Dan Cox
7 *
8 * 2002 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/time.h>
21#include <linux/irq.h>
22#include <linux/kdev_t.h>
23#include <linux/initrd.h>
24#include <linux/console.h>
25#include <linux/seq_file.h>
26#include <linux/root_dev.h>
27
28#include <asm/io.h>
29#include <asm/todc.h>
30#include <asm/bootinfo.h>
31
32#include <syslib/cpc700.h>
33
34#include "pal4.h"
35
36extern void pal4_find_bridges(void);
37
38unsigned int cpc700_irq_assigns[][2] = {
39 {1, 1}, /* IRQ 0: ECC correctable error */
40 {1, 1}, /* IRQ 1: PCI write to memory range */
41 {0, 1}, /* IRQ 2: PCI write to command register */
42 {0, 1}, /* IRQ 3: UART 0 */
43 {0, 1}, /* IRQ 4: UART 1 */
44 {0, 1}, /* IRQ 5: ICC 0 */
45 {0, 1}, /* IRQ 6: ICC 1 */
46 {0, 1}, /* IRQ 7: GPT compare 0 */
47 {0, 1}, /* IRQ 8: GPT compare 1 */
48 {0, 1}, /* IRQ 9: GPT compare 2 */
49 {0, 1}, /* IRQ 10: GPT compare 3 */
50 {0, 1}, /* IRQ 11: GPT compare 4 */
51 {0, 1}, /* IRQ 12: GPT capture 0 */
52 {0, 1}, /* IRQ 13: GPT capture 1 */
53 {0, 1}, /* IRQ 14: GPT capture 2 */
54 {0, 1}, /* IRQ 15: GPT capture 3 */
55 {0, 1}, /* IRQ 16: GPT capture 4 */
56 {0, 0}, /* IRQ 17: reserved */
57 {0, 0}, /* IRQ 18: reserved */
58 {0, 0}, /* IRQ 19: reserved */
59 {0, 0}, /* IRQ 20: reserved */
60 {0, 1}, /* IRQ 21: Ethernet */
61 {0, 0}, /* IRQ 22: reserved */
62 {0, 0}, /* IRQ 23: reserved */
63 {0, 0}, /* IRQ 24: resreved */
64 {0, 0}, /* IRQ 25: reserved */
65 {0, 0}, /* IRQ 26: reserved */
66 {0, 0}, /* IRQ 27: reserved */
67 {0, 0}, /* IRQ 28: reserved */
68 {0, 0}, /* IRQ 29: reserved */
69 {0, 0}, /* IRQ 30: reserved */
70 {0, 0}, /* IRQ 31: reserved */
71};
72
73static int
74pal4_show_cpuinfo(struct seq_file *m)
75{
76 seq_printf(m, "board\t\t: SBS Palomar IV\n");
77
78 return 0;
79}
80
81static void
82pal4_restart(char *cmd)
83{
84 local_irq_disable();
85 __asm__ __volatile__("lis 3,0xfff0\n \
86 ori 3,3,0x100\n \
87 mtspr 26,3\n \
88 li 3,0\n \
89 mtspr 27,3\n \
90 rfi");
91
92 for(;;);
93}
94
95static void
96pal4_power_off(void)
97{
98 local_irq_disable();
99 for(;;);
100}
101
102static void
103pal4_halt(void)
104{
105 pal4_power_off();
106}
107
108TODC_ALLOC();
109
110static void __init
111pal4_setup_arch(void)
112{
113 unsigned long l2;
114
115 TODC_INIT(TODC_TYPE_MK48T37, 0, 0,
116 ioremap(PAL4_NVRAM, PAL4_NVRAM_SIZE), 8);
117
118 pal4_find_bridges();
119
120#ifdef CONFIG_BLK_DEV_INITRD
121 if (initrd_start)
122 ROOT_DEV = Root_RAM0;
123 else
124#endif
125 ROOT_DEV = Root_NFS;
126
127 /* The L2 gets disabled in the bootloader, but all the proper
128 bits should be present from the fw, so just re-enable it */
129 l2 = _get_L2CR();
130 if (!(l2 & L2CR_L2E)) {
131 /* presume that it was initially set if the size is
132 still present. */
133 if (l2 ^ L2CR_L2SIZ_MASK)
134 _set_L2CR(l2 | L2CR_L2E);
135 else
136 printk("L2 not set by firmware; left disabled.\n");
137 }
138}
139
140static void __init
141pal4_map_io(void)
142{
143 io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
144}
145
146void __init
147platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
148 unsigned long r6, unsigned long r7)
149{
150 parse_bootinfo(find_bootinfo());
151
152 isa_io_base = 0 /*PAL4_ISA_IO_BASE*/;
153 pci_dram_offset = 0 /*PAL4_PCI_SYS_MEM_BASE*/;
154
155 ppc_md.setup_arch = pal4_setup_arch;
156 ppc_md.show_cpuinfo = pal4_show_cpuinfo;
157
158 ppc_md.setup_io_mappings = pal4_map_io;
159
160 ppc_md.init_IRQ = cpc700_init_IRQ;
161 ppc_md.get_irq = cpc700_get_irq;
162
163 ppc_md.restart = pal4_restart;
164 ppc_md.halt = pal4_halt;
165 ppc_md.power_off = pal4_power_off;
166
167 ppc_md.time_init = todc_time_init;
168 ppc_md.set_rtc_time = todc_set_rtc_time;
169 ppc_md.get_rtc_time = todc_get_rtc_time;
170 ppc_md.calibrate_decr = todc_calibrate_decr;
171
172 ppc_md.nvram_read_val = todc_direct_read_val;
173 ppc_md.nvram_write_val = todc_direct_write_val;
174}
175
diff --git a/arch/ppc/platforms/pcore.c b/arch/ppc/platforms/pcore.c
new file mode 100644
index 000000000000..d7191630a650
--- /dev/null
+++ b/arch/ppc/platforms/pcore.c
@@ -0,0 +1,352 @@
1/*
2 * arch/ppc/platforms/pcore_setup.c
3 *
4 * Setup routines for Force PCORE boards
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/kdev_t.h>
22#include <linux/types.h>
23#include <linux/major.h>
24#include <linux/initrd.h>
25#include <linux/console.h>
26#include <linux/irq.h>
27#include <linux/seq_file.h>
28#include <linux/root_dev.h>
29
30#include <asm/io.h>
31#include <asm/machdep.h>
32#include <asm/time.h>
33#include <asm/i8259.h>
34#include <asm/mpc10x.h>
35#include <asm/todc.h>
36#include <asm/bootinfo.h>
37#include <asm/kgdb.h>
38
39#include "pcore.h"
40
41extern unsigned long loops_per_jiffy;
42
43static int board_type;
44
45static inline int __init
46pcore_6750_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
47{
48 static char pci_irq_table[][4] =
49 /*
50 * PCI IDSEL/INTPIN->INTLINE
51 * A B C D
52 */
53 {
54 {9, 10, 11, 12}, /* IDSEL 24 - DEC 21554 */
55 {10, 0, 0, 0}, /* IDSEL 25 - DEC 21143 */
56 {11, 12, 9, 10}, /* IDSEL 26 - PMC I */
57 {12, 9, 10, 11}, /* IDSEL 27 - PMC II */
58 {0, 0, 0, 0}, /* IDSEL 28 - unused */
59 {0, 0, 9, 0}, /* IDSEL 29 - unused */
60 {0, 0, 0, 0}, /* IDSEL 30 - Winbond */
61 };
62 const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4;
63 return PCI_IRQ_TABLE_LOOKUP;
64};
65
66static inline int __init
67pcore_680_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
68{
69 static char pci_irq_table[][4] =
70 /*
71 * PCI IDSEL/INTPIN->INTLINE
72 * A B C D
73 */
74 {
75 {9, 10, 11, 12}, /* IDSEL 24 - Sentinel */
76 {10, 0, 0, 0}, /* IDSEL 25 - i82559 #1 */
77 {11, 12, 9, 10}, /* IDSEL 26 - PMC I */
78 {12, 9, 10, 11}, /* IDSEL 27 - PMC II */
79 {9, 0, 0, 0}, /* IDSEL 28 - i82559 #2 */
80 {0, 0, 0, 0}, /* IDSEL 29 - unused */
81 {0, 0, 0, 0}, /* IDSEL 30 - Winbond */
82 };
83 const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4;
84 return PCI_IRQ_TABLE_LOOKUP;
85};
86
87void __init
88pcore_pcibios_fixup(void)
89{
90 struct pci_dev *dev;
91
92 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
93 PCI_DEVICE_ID_WINBOND_83C553,
94 0)))
95 {
96 /* Reroute interrupts both IDE channels to 15 */
97 pci_write_config_byte(dev,
98 PCORE_WINBOND_IDE_INT,
99 0xff);
100
101 /* Route INTA-D to IRQ9-12, respectively */
102 pci_write_config_word(dev,
103 PCORE_WINBOND_PCI_INT,
104 0x9abc);
105
106 /*
107 * Set up 8259 edge/level triggering
108 */
109 outb(0x00, PCORE_WINBOND_PRI_EDG_LVL);
110 outb(0x1e, PCORE_WINBOND_SEC_EDG_LVL);
111 pci_dev_put(dev);
112 }
113}
114
115int __init
116pcore_find_bridges(void)
117{
118 struct pci_controller* hose;
119 int host_bridge, board_type;
120
121 hose = pcibios_alloc_controller();
122 if (!hose)
123 return 0;
124
125 mpc10x_bridge_init(hose,
126 MPC10X_MEM_MAP_B,
127 MPC10X_MEM_MAP_B,
128 MPC10X_MAPB_EUMB_BASE);
129
130 /* Determine board type */
131 early_read_config_dword(hose,
132 0,
133 PCI_DEVFN(0,0),
134 PCI_VENDOR_ID,
135 &host_bridge);
136 if (host_bridge == MPC10X_BRIDGE_106)
137 board_type = PCORE_TYPE_6750;
138 else /* MPC10X_BRIDGE_107 */
139 board_type = PCORE_TYPE_680;
140
141 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
142
143 ppc_md.pcibios_fixup = pcore_pcibios_fixup;
144 ppc_md.pci_swizzle = common_swizzle;
145
146 if (board_type == PCORE_TYPE_6750)
147 ppc_md.pci_map_irq = pcore_6750_map_irq;
148 else /* PCORE_TYPE_680 */
149 ppc_md.pci_map_irq = pcore_680_map_irq;
150
151 return board_type;
152}
153
154/* Dummy variable to satisfy mpc10x_common.o */
155void *OpenPIC_Addr;
156
157static int
158pcore_show_cpuinfo(struct seq_file *m)
159{
160 seq_printf(m, "vendor\t\t: Force Computers\n");
161
162 if (board_type == PCORE_TYPE_6750)
163 seq_printf(m, "machine\t\t: PowerCore 6750\n");
164 else /* PCORE_TYPE_680 */
165 seq_printf(m, "machine\t\t: PowerCore 680\n");
166
167 seq_printf(m, "L2\t\t: " );
168 if (board_type == PCORE_TYPE_6750)
169 switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK)
170 {
171 case PCORE_DCCR_L2_0KB:
172 seq_printf(m, "nocache");
173 break;
174 case PCORE_DCCR_L2_256KB:
175 seq_printf(m, "256KB");
176 break;
177 case PCORE_DCCR_L2_1MB:
178 seq_printf(m, "1MB");
179 break;
180 case PCORE_DCCR_L2_512KB:
181 seq_printf(m, "512KB");
182 break;
183 default:
184 seq_printf(m, "error");
185 break;
186 }
187 else /* PCORE_TYPE_680 */
188 switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK)
189 {
190 case PCORE_DCCR_L2_2MB:
191 seq_printf(m, "2MB");
192 break;
193 case PCORE_DCCR_L2_256KB:
194 seq_printf(m, "reserved");
195 break;
196 case PCORE_DCCR_L2_1MB:
197 seq_printf(m, "1MB");
198 break;
199 case PCORE_DCCR_L2_512KB:
200 seq_printf(m, "512KB");
201 break;
202 default:
203 seq_printf(m, "error");
204 break;
205 }
206
207 seq_printf(m, "\n");
208
209 return 0;
210}
211
212static void __init
213pcore_setup_arch(void)
214{
215 /* init to some ~sane value until calibrate_delay() runs */
216 loops_per_jiffy = 50000000/HZ;
217
218 /* Lookup PCI host bridges */
219 board_type = pcore_find_bridges();
220
221#ifdef CONFIG_BLK_DEV_INITRD
222 if (initrd_start)
223 ROOT_DEV = Root_RAM0;
224 else
225#endif
226#ifdef CONFIG_ROOT_NFS
227 ROOT_DEV = Root_NFS;
228#else
229 ROOT_DEV = Root_SDA2;
230#endif
231
232 printk(KERN_INFO "Force PowerCore ");
233 if (board_type == PCORE_TYPE_6750)
234 printk("6750\n");
235 else
236 printk("680\n");
237 printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
238 _set_L2CR(L2CR_L2E | _get_L2CR());
239
240}
241
242static void
243pcore_restart(char *cmd)
244{
245 local_irq_disable();
246 /* Hard reset */
247 writeb(0x11, 0xfe000332);
248 while(1);
249}
250
251static void
252pcore_halt(void)
253{
254 local_irq_disable();
255 /* Turn off user LEDs */
256 writeb(0x00, 0xfe000300);
257 while (1);
258}
259
260static void
261pcore_power_off(void)
262{
263 pcore_halt();
264}
265
266
267static void __init
268pcore_init_IRQ(void)
269{
270 int i;
271
272 for ( i = 0 ; i < 16 ; i++ )
273 irq_desc[i].handler = &i8259_pic;
274
275 i8259_init(0);
276}
277
278/*
279 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
280 */
281static __inline__ void
282pcore_set_bat(void)
283{
284 mb();
285 mtspr(SPRN_DBAT3U, 0xf0001ffe);
286 mtspr(SPRN_DBAT3L, 0xfe80002a);
287 mb();
288
289}
290
291static unsigned long __init
292pcore_find_end_of_memory(void)
293{
294
295 return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
296}
297
298static void __init
299pcore_map_io(void)
300{
301 io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
302}
303
304TODC_ALLOC();
305
306void __init
307platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
308 unsigned long r6, unsigned long r7)
309{
310 parse_bootinfo(find_bootinfo());
311
312 /* Cover I/O space with a BAT */
313 /* yuck, better hope your ram size is a power of 2 -- paulus */
314 pcore_set_bat();
315
316 isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
317 isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
318 pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
319
320 ppc_md.setup_arch = pcore_setup_arch;
321 ppc_md.show_cpuinfo = pcore_show_cpuinfo;
322 ppc_md.init_IRQ = pcore_init_IRQ;
323 ppc_md.get_irq = i8259_irq;
324
325 ppc_md.find_end_of_memory = pcore_find_end_of_memory;
326 ppc_md.setup_io_mappings = pcore_map_io;
327
328 ppc_md.restart = pcore_restart;
329 ppc_md.power_off = pcore_power_off;
330 ppc_md.halt = pcore_halt;
331
332 TODC_INIT(TODC_TYPE_MK48T59,
333 PCORE_NVRAM_AS0,
334 PCORE_NVRAM_AS1,
335 PCORE_NVRAM_DATA,
336 8);
337
338 ppc_md.time_init = todc_time_init;
339 ppc_md.get_rtc_time = todc_get_rtc_time;
340 ppc_md.set_rtc_time = todc_set_rtc_time;
341 ppc_md.calibrate_decr = todc_calibrate_decr;
342
343 ppc_md.nvram_read_val = todc_m48txx_read_val;
344 ppc_md.nvram_write_val = todc_m48txx_write_val;
345
346#ifdef CONFIG_SERIAL_TEXT_DEBUG
347 ppc_md.progress = gen550_progress;
348#endif
349#ifdef CONFIG_KGDB
350 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
351#endif
352}
diff --git a/arch/ppc/platforms/pcore.h b/arch/ppc/platforms/pcore.h
new file mode 100644
index 000000000000..c6a26e764926
--- /dev/null
+++ b/arch/ppc/platforms/pcore.h
@@ -0,0 +1,39 @@
1/*
2 * arch/ppc/platforms/pcore.h
3 *
4 * Definitions for Force PowerCore board support
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifndef __PPC_PLATFORMS_PCORE_H
15#define __PPC_PLATFORMS_PCORE_H
16
17#include <asm/mpc10x.h>
18
19#define PCORE_TYPE_6750 1
20#define PCORE_TYPE_680 2
21
22#define PCORE_NVRAM_AS0 0x73
23#define PCORE_NVRAM_AS1 0x75
24#define PCORE_NVRAM_DATA 0x77
25
26#define PCORE_DCCR_REG (MPC10X_MAPB_ISA_IO_BASE + 0x308)
27#define PCORE_DCCR_L2_MASK 0xc0
28#define PCORE_DCCR_L2_0KB 0x00
29#define PCORE_DCCR_L2_256KB 0x40
30#define PCORE_DCCR_L2_512KB 0xc0
31#define PCORE_DCCR_L2_1MB 0x80
32#define PCORE_DCCR_L2_2MB 0x00
33
34#define PCORE_WINBOND_IDE_INT 0x43
35#define PCORE_WINBOND_PCI_INT 0x44
36#define PCORE_WINBOND_PRI_EDG_LVL 0x4d0
37#define PCORE_WINBOND_SEC_EDG_LVL 0x4d1
38
39#endif /* __PPC_PLATFORMS_PCORE_H */
diff --git a/arch/ppc/platforms/pcu_e.h b/arch/ppc/platforms/pcu_e.h
new file mode 100644
index 000000000000..91a820a6fbc4
--- /dev/null
+++ b/arch/ppc/platforms/pcu_e.h
@@ -0,0 +1,28 @@
1/*
2 * Siemens PCU E board specific definitions
3 *
4 * Copyright (c) 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __MACH_PCU_E_H
8#define __MACH_PCU_E_H
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define PCU_E_IMMR_BASE 0xFE000000 /* phys. addr of IMMR */
15#define PCU_E_IMAP_SIZE (64 * 1024) /* size of mapped area */
16
17#define IMAP_ADDR PCU_E_IMMR_BASE /* physical base address of IMMR area */
18#define IMAP_SIZE PCU_E_IMAP_SIZE /* mapped size of IMMR area */
19
20#define FEC_INTERRUPT 15 /* = SIU_LEVEL7 */
21#define DEC_INTERRUPT 13 /* = SIU_LEVEL6 */
22#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */
23
24/* We don't use the 8259.
25*/
26#define NR_8259_INTS 0
27
28#endif /* __MACH_PCU_E_H */
diff --git a/arch/ppc/platforms/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c
new file mode 100644
index 000000000000..ed2b1cebc19a
--- /dev/null
+++ b/arch/ppc/platforms/pmac_backlight.c
@@ -0,0 +1,202 @@
1/*
2 * Miscellaneous procedures for dealing with the PowerMac hardware.
3 * Contains support for the backlight.
4 *
5 * Copyright (C) 2000 Benjamin Herrenschmidt
6 *
7 */
8
9#include <linux/config.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/stddef.h>
13#include <linux/reboot.h>
14#include <linux/nvram.h>
15#include <linux/console.h>
16#include <asm/sections.h>
17#include <asm/ptrace.h>
18#include <asm/io.h>
19#include <asm/pgtable.h>
20#include <asm/system.h>
21#include <asm/prom.h>
22#include <asm/machdep.h>
23#include <asm/nvram.h>
24#include <asm/backlight.h>
25
26#include <linux/adb.h>
27#include <linux/pmu.h>
28
29static struct backlight_controller *backlighter;
30static void* backlighter_data;
31static int backlight_autosave;
32static int backlight_level = BACKLIGHT_MAX;
33static int backlight_enabled = 1;
34static int backlight_req_level = -1;
35static int backlight_req_enable = -1;
36
37static void backlight_callback(void *);
38static DECLARE_WORK(backlight_work, backlight_callback, NULL);
39
40void __pmac register_backlight_controller(struct backlight_controller *ctrler,
41 void *data, char *type)
42{
43 struct device_node* bk_node;
44 char *prop;
45 int valid = 0;
46
47 /* There's already a matching controller, bail out */
48 if (backlighter != NULL)
49 return;
50
51 bk_node = find_devices("backlight");
52
53#ifdef CONFIG_ADB_PMU
54 /* Special case for the old PowerBook since I can't test on it */
55 backlight_autosave = machine_is_compatible("AAPL,3400/2400")
56 || machine_is_compatible("AAPL,3500");
57 if ((backlight_autosave
58 || machine_is_compatible("AAPL,PowerBook1998")
59 || machine_is_compatible("PowerBook1,1"))
60 && !strcmp(type, "pmu"))
61 valid = 1;
62#endif
63 if (bk_node) {
64 prop = get_property(bk_node, "backlight-control", NULL);
65 if (prop && !strncmp(prop, type, strlen(type)))
66 valid = 1;
67 }
68 if (!valid)
69 return;
70 backlighter = ctrler;
71 backlighter_data = data;
72
73 if (bk_node && !backlight_autosave)
74 prop = get_property(bk_node, "bklt", NULL);
75 else
76 prop = NULL;
77 if (prop) {
78 backlight_level = ((*prop)+1) >> 1;
79 if (backlight_level > BACKLIGHT_MAX)
80 backlight_level = BACKLIGHT_MAX;
81 }
82
83#ifdef CONFIG_ADB_PMU
84 if (backlight_autosave) {
85 struct adb_request req;
86 pmu_request(&req, NULL, 2, 0xd9, 0);
87 while (!req.complete)
88 pmu_poll();
89 backlight_level = req.reply[0] >> 4;
90 }
91#endif
92 acquire_console_sem();
93 if (!backlighter->set_enable(1, backlight_level, data))
94 backlight_enabled = 1;
95 release_console_sem();
96
97 printk(KERN_INFO "Registered \"%s\" backlight controller,"
98 "level: %d/15\n", type, backlight_level);
99}
100EXPORT_SYMBOL(register_backlight_controller);
101
102void __pmac unregister_backlight_controller(struct backlight_controller
103 *ctrler, void *data)
104{
105 /* We keep the current backlight level (for now) */
106 if (ctrler == backlighter && data == backlighter_data)
107 backlighter = NULL;
108}
109EXPORT_SYMBOL(unregister_backlight_controller);
110
111static int __pmac __set_backlight_enable(int enable)
112{
113 int rc;
114
115 if (!backlighter)
116 return -ENODEV;
117 acquire_console_sem();
118 rc = backlighter->set_enable(enable, backlight_level,
119 backlighter_data);
120 if (!rc)
121 backlight_enabled = enable;
122 release_console_sem();
123 return rc;
124}
125int __pmac set_backlight_enable(int enable)
126{
127 if (!backlighter)
128 return -ENODEV;
129 backlight_req_enable = enable;
130 schedule_work(&backlight_work);
131 return 0;
132}
133
134EXPORT_SYMBOL(set_backlight_enable);
135
136int __pmac get_backlight_enable(void)
137{
138 if (!backlighter)
139 return -ENODEV;
140 return backlight_enabled;
141}
142EXPORT_SYMBOL(get_backlight_enable);
143
144static int __pmac __set_backlight_level(int level)
145{
146 int rc = 0;
147
148 if (!backlighter)
149 return -ENODEV;
150 if (level < BACKLIGHT_MIN)
151 level = BACKLIGHT_OFF;
152 if (level > BACKLIGHT_MAX)
153 level = BACKLIGHT_MAX;
154 acquire_console_sem();
155 if (backlight_enabled)
156 rc = backlighter->set_level(level, backlighter_data);
157 if (!rc)
158 backlight_level = level;
159 release_console_sem();
160 if (!rc && !backlight_autosave) {
161 level <<=1;
162 if (level & 0x10)
163 level |= 0x01;
164 // -- todo: save to property "bklt"
165 }
166 return rc;
167}
168int __pmac set_backlight_level(int level)
169{
170 if (!backlighter)
171 return -ENODEV;
172 backlight_req_level = level;
173 schedule_work(&backlight_work);
174 return 0;
175}
176
177EXPORT_SYMBOL(set_backlight_level);
178
179int __pmac get_backlight_level(void)
180{
181 if (!backlighter)
182 return -ENODEV;
183 return backlight_level;
184}
185EXPORT_SYMBOL(get_backlight_level);
186
187static void backlight_callback(void *dummy)
188{
189 int level, enable;
190
191 do {
192 level = backlight_req_level;
193 enable = backlight_req_enable;
194 mb();
195
196 if (level >= 0)
197 __set_backlight_level(level);
198 if (enable >= 0)
199 __set_backlight_enable(enable);
200 } while(cmpxchg(&backlight_req_level, level, -1) != level ||
201 cmpxchg(&backlight_req_enable, enable, -1) != enable);
202}
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
new file mode 100644
index 000000000000..c00e0352044d
--- /dev/null
+++ b/arch/ppc/platforms/pmac_cache.S
@@ -0,0 +1,325 @@
1/*
2 * This file contains low-level cache management functions
3 * used for sleep and CPU speed changes on Apple machines.
4 * (In fact the only thing that is Apple-specific is that we assume
5 * that we can read from ROM at physical address 0xfff00000.)
6 *
7 * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
8 * Benjamin Herrenschmidt (benh@kernel.crashing.org)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 */
16
17#include <linux/config.h>
18#include <asm/processor.h>
19#include <asm/ppc_asm.h>
20#include <asm/cputable.h>
21
22/*
23 * Flush and disable all data caches (dL1, L2, L3). This is used
24 * when going to sleep, when doing a PMU based cpufreq transition,
25 * or when "offlining" a CPU on SMP machines. This code is over
26 * paranoid, but I've had enough issues with various CPU revs and
27 * bugs that I decided it was worth beeing over cautious
28 */
29
30_GLOBAL(flush_disable_caches)
31BEGIN_FTR_SECTION
32 b flush_disable_745x
33END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
34BEGIN_FTR_SECTION
35 b flush_disable_75x
36END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
37 b __flush_disable_L1
38
39/* This is the code for G3 and 74[01]0 */
40flush_disable_75x:
41 mflr r10
42
43 /* Turn off EE and DR in MSR */
44 mfmsr r11
45 rlwinm r0,r11,0,~MSR_EE
46 rlwinm r0,r0,0,~MSR_DR
47 sync
48 mtmsr r0
49 isync
50
51 /* Stop DST streams */
52BEGIN_FTR_SECTION
53 DSSALL
54 sync
55END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
56
57 /* Stop DPM */
58 mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
59 rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
60 sync
61 mtspr SPRN_HID0,r4 /* Disable DPM */
62 sync
63
64 /* disp-flush L1 */
65 li r4,0x4000
66 mtctr r4
67 lis r4,0xfff0
681: lwzx r0,r0,r4
69 addi r4,r4,32
70 bdnz 1b
71 sync
72 isync
73
74 /* disable / invalidate / enable L1 data */
75 mfspr r3,SPRN_HID0
76 rlwinm r0,r0,0,~HID0_DCE
77 mtspr SPRN_HID0,r3
78 sync
79 isync
80 ori r3,r3,HID0_DCE|HID0_DCI
81 sync
82 isync
83 mtspr SPRN_HID0,r3
84 xori r3,r3,HID0_DCI
85 mtspr SPRN_HID0,r3
86 sync
87
88 /* Get the current enable bit of the L2CR into r4 */
89 mfspr r5,SPRN_L2CR
90 /* Set to data-only (pre-745x bit) */
91 oris r3,r5,L2CR_L2DO@h
92 b 2f
93 /* When disabling L2, code must be in L1 */
94 .balign 32
951: mtspr SPRN_L2CR,r3
963: sync
97 isync
98 b 1f
992: b 3f
1003: sync
101 isync
102 b 1b
1031: /* disp-flush L2. The interesting thing here is that the L2 can be
104 * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
105 * but that is probbaly fine. We disp-flush over 4Mb to be safe
106 */
107 lis r4,2
108 mtctr r4
109 lis r4,0xfff0
1101: lwzx r0,r0,r4
111 addi r4,r4,32
112 bdnz 1b
113 sync
114 isync
115 /* now disable L2 */
116 rlwinm r5,r5,0,~L2CR_L2E
117 b 2f
118 /* When disabling L2, code must be in L1 */
119 .balign 32
1201: mtspr SPRN_L2CR,r5
1213: sync
122 isync
123 b 1f
1242: b 3f
1253: sync
126 isync
127 b 1b
1281: sync
129 isync
130 /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
131 oris r4,r5,L2CR_L2I@h
132 mtspr SPRN_L2CR,r4
133 sync
134 isync
135 xoris r4,r4,L2CR_L2I@h
136 sync
137 mtspr SPRN_L2CR,r4
138 sync
139
140 /* now disable the L1 data cache */
141 mfspr r0,SPRN_HID0
142 rlwinm r0,r0,0,~HID0_DCE
143 mtspr SPRN_HID0,r0
144 sync
145 isync
146
147 /* Restore HID0[DPM] to whatever it was before */
148 sync
149 mtspr SPRN_HID0,r8
150 sync
151
152 /* restore DR and EE */
153 sync
154 mtmsr r11
155 isync
156
157 mtlr r10
158 blr
159
160/* This code is for 745x processors */
161flush_disable_745x:
162 /* Turn off EE and DR in MSR */
163 mfmsr r11
164 rlwinm r0,r11,0,~MSR_EE
165 rlwinm r0,r0,0,~MSR_DR
166 sync
167 mtmsr r0
168 isync
169
170 /* Stop prefetch streams */
171 DSSALL
172 sync
173
174 /* Disable L2 prefetching */
175 mfspr r0,SPRN_MSSCR0
176 rlwinm r0,r0,0,0,29
177 mtspr SPRN_MSSCR0,r0
178 sync
179 isync
180 lis r4,0
181 dcbf 0,r4
182 dcbf 0,r4
183 dcbf 0,r4
184 dcbf 0,r4
185 dcbf 0,r4
186 dcbf 0,r4
187 dcbf 0,r4
188 dcbf 0,r4
189
190 /* Due to a bug with the HW flush on some CPU revs, we occasionally
191 * experience data corruption. I'm adding a displacement flush along
192 * with a dcbf loop over a few Mb to "help". The problem isn't totally
193 * fixed by this in theory, but at least, in practice, I couldn't reproduce
194 * it even with a big hammer...
195 */
196
197 lis r4,0x0002
198 mtctr r4
199 li r4,0
2001:
201 lwzx r0,r0,r4
202 addi r4,r4,32 /* Go to start of next cache line */
203 bdnz 1b
204 isync
205
206 /* Now, flush the first 4MB of memory */
207 lis r4,0x0002
208 mtctr r4
209 li r4,0
210 sync
2111:
212 dcbf 0,r4
213 addi r4,r4,32 /* Go to start of next cache line */
214 bdnz 1b
215
216 /* Flush and disable the L1 data cache */
217 mfspr r6,SPRN_LDSTCR
218 lis r3,0xfff0 /* read from ROM for displacement flush */
219 li r4,0xfe /* start with only way 0 unlocked */
220 li r5,128 /* 128 lines in each way */
2211: mtctr r5
222 rlwimi r6,r4,0,24,31
223 mtspr SPRN_LDSTCR,r6
224 sync
225 isync
2262: lwz r0,0(r3) /* touch each cache line */
227 addi r3,r3,32
228 bdnz 2b
229 rlwinm r4,r4,1,24,30 /* move on to the next way */
230 ori r4,r4,1
231 cmpwi r4,0xff /* all done? */
232 bne 1b
233 /* now unlock the L1 data cache */
234 li r4,0
235 rlwimi r6,r4,0,24,31
236 sync
237 mtspr SPRN_LDSTCR,r6
238 sync
239 isync
240
241 /* Flush the L2 cache using the hardware assist */
242 mfspr r3,SPRN_L2CR
243 cmpwi r3,0 /* check if it is enabled first */
244 bge 4f
245 oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
246 b 2f
247 /* When disabling/locking L2, code must be in L1 */
248 .balign 32
2491: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
2503: sync
251 isync
252 b 1f
2532: b 3f
2543: sync
255 isync
256 b 1b
2571: sync
258 isync
259 ori r0,r3,L2CR_L2HWF_745x
260 sync
261 mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
2623: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
263 andi. r0,r0,L2CR_L2HWF_745x
264 bne 3b
265 sync
266 rlwinm r3,r3,0,~L2CR_L2E
267 b 2f
268 /* When disabling L2, code must be in L1 */
269 .balign 32
2701: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
2713: sync
272 isync
273 b 1f
2742: b 3f
2753: sync
276 isync
277 b 1b
2781: sync
279 isync
280 oris r4,r3,L2CR_L2I@h
281 mtspr SPRN_L2CR,r4
282 sync
283 isync
2841: mfspr r4,SPRN_L2CR
285 andis. r0,r4,L2CR_L2I@h
286 bne 1b
287 sync
288
289BEGIN_FTR_SECTION
290 /* Flush the L3 cache using the hardware assist */
2914: mfspr r3,SPRN_L3CR
292 cmpwi r3,0 /* check if it is enabled */
293 bge 6f
294 oris r0,r3,L3CR_L3IO@h
295 ori r0,r0,L3CR_L3DO
296 sync
297 mtspr SPRN_L3CR,r0 /* lock the L3 cache */
298 sync
299 isync
300 ori r0,r0,L3CR_L3HWF
301 sync
302 mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
3035: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
304 andi. r0,r0,L3CR_L3HWF
305 bne 5b
306 rlwinm r3,r3,0,~L3CR_L3E
307 sync
308 mtspr SPRN_L3CR,r3 /* disable the L3 cache */
309 sync
310 ori r4,r3,L3CR_L3I
311 mtspr SPRN_L3CR,r4
3121: mfspr r4,SPRN_L3CR
313 andi. r0,r4,L3CR_L3I
314 bne 1b
315 sync
316END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
317
3186: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
319 rlwinm r0,r0,0,~HID0_DCE
320 mtspr SPRN_HID0,r0
321 sync
322 isync
323 mtmsr r11 /* restore DR and EE */
324 isync
325 blr
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
new file mode 100644
index 000000000000..9c85f9ca1cfb
--- /dev/null
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -0,0 +1,571 @@
1/*
2 * arch/ppc/platforms/pmac_cpufreq.c
3 *
4 * Copyright (C) 2002 - 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/kernel.h>
18#include <linux/delay.h>
19#include <linux/sched.h>
20#include <linux/adb.h>
21#include <linux/pmu.h>
22#include <linux/slab.h>
23#include <linux/cpufreq.h>
24#include <linux/init.h>
25#include <linux/sysdev.h>
26#include <linux/i2c.h>
27#include <linux/hardirq.h>
28#include <asm/prom.h>
29#include <asm/machdep.h>
30#include <asm/irq.h>
31#include <asm/pmac_feature.h>
32#include <asm/mmu_context.h>
33#include <asm/sections.h>
34#include <asm/cputable.h>
35#include <asm/time.h>
36#include <asm/system.h>
37#include <asm/open_pic.h>
38
39/* WARNING !!! This will cause calibrate_delay() to be called,
40 * but this is an __init function ! So you MUST go edit
41 * init/main.c to make it non-init before enabling DEBUG_FREQ
42 */
43#undef DEBUG_FREQ
44
45/*
46 * There is a problem with the core cpufreq code on SMP kernels,
47 * it won't recalculate the Bogomips properly
48 */
49#ifdef CONFIG_SMP
50#warning "WARNING, CPUFREQ not recommended on SMP kernels"
51#endif
52
53extern void low_choose_7447a_dfs(int dfs);
54extern void low_choose_750fx_pll(int pll);
55extern void low_sleep_handler(void);
56
57/*
58 * Currently, PowerMac cpufreq supports only high & low frequencies
59 * that are set by the firmware
60 */
61static unsigned int low_freq;
62static unsigned int hi_freq;
63static unsigned int cur_freq;
64
65/*
66 * Different models uses different mecanisms to switch the frequency
67 */
68static int (*set_speed_proc)(int low_speed);
69
70/*
71 * Some definitions used by the various speedprocs
72 */
73static u32 voltage_gpio;
74static u32 frequency_gpio;
75static u32 slew_done_gpio;
76
77
78#define PMAC_CPU_LOW_SPEED 1
79#define PMAC_CPU_HIGH_SPEED 0
80
81/* There are only two frequency states for each processor. Values
82 * are in kHz for the time being.
83 */
84#define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED
85#define CPUFREQ_LOW PMAC_CPU_LOW_SPEED
86
87static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
88 {CPUFREQ_HIGH, 0},
89 {CPUFREQ_LOW, 0},
90 {0, CPUFREQ_TABLE_END},
91};
92
93static inline void wakeup_decrementer(void)
94{
95 set_dec(tb_ticks_per_jiffy);
96 /* No currently-supported powerbook has a 601,
97 * so use get_tbl, not native
98 */
99 last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
100}
101
102#ifdef DEBUG_FREQ
103static inline void debug_calc_bogomips(void)
104{
105 /* This will cause a recalc of bogomips and display the
106 * result. We backup/restore the value to avoid affecting the
107 * core cpufreq framework's own calculation.
108 */
109 extern void calibrate_delay(void);
110
111 unsigned long save_lpj = loops_per_jiffy;
112 calibrate_delay();
113 loops_per_jiffy = save_lpj;
114}
115#endif /* DEBUG_FREQ */
116
117/* Switch CPU speed under 750FX CPU control
118 */
119static int __pmac cpu_750fx_cpu_speed(int low_speed)
120{
121#ifdef DEBUG_FREQ
122 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
123#endif
124#ifdef CONFIG_6xx
125 low_choose_750fx_pll(low_speed);
126#endif
127#ifdef DEBUG_FREQ
128 printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
129 debug_calc_bogomips();
130#endif
131
132 return 0;
133}
134
135/* Switch CPU speed using DFS */
136static int __pmac dfs_set_cpu_speed(int low_speed)
137{
138 if (low_speed == 0) {
139 /* ramping up, set voltage first */
140 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
141 /* Make sure we sleep for at least 1ms */
142 msleep(1);
143 }
144
145 /* set frequency */
146 low_choose_7447a_dfs(low_speed);
147
148 if (low_speed == 1) {
149 /* ramping down, set voltage last */
150 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
151 msleep(1);
152 }
153
154 return 0;
155}
156
157static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu)
158{
159 if (mfspr(SPRN_HID1) & HID1_DFS)
160 return low_freq;
161 else
162 return hi_freq;
163}
164
165
166/* Switch CPU speed using slewing GPIOs
167 */
168static int __pmac gpios_set_cpu_speed(int low_speed)
169{
170 int gpio;
171
172 /* If ramping up, set voltage first */
173 if (low_speed == 0) {
174 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
175 /* Delay is way too big but it's ok, we schedule */
176 msleep(10);
177 }
178
179 /* Set frequency */
180 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
181 low_speed ? 0x04 : 0x05);
182 udelay(200);
183 do {
184 set_current_state(TASK_UNINTERRUPTIBLE);
185 schedule_timeout(1);
186 gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
187 } while((gpio & 0x02) == 0);
188
189 /* If ramping down, set voltage last */
190 if (low_speed == 1) {
191 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
192 /* Delay is way too big but it's ok, we schedule */
193 msleep(10);
194 }
195
196#ifdef DEBUG_FREQ
197 debug_calc_bogomips();
198#endif
199
200 return 0;
201}
202
203/* Switch CPU speed under PMU control
204 */
205static int __pmac pmu_set_cpu_speed(int low_speed)
206{
207 struct adb_request req;
208 unsigned long save_l2cr;
209 unsigned long save_l3cr;
210
211 preempt_disable();
212
213#ifdef DEBUG_FREQ
214 printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
215#endif
216 /* Disable all interrupt sources on openpic */
217 openpic_set_priority(0xf);
218
219 /* Make sure the decrementer won't interrupt us */
220 asm volatile("mtdec %0" : : "r" (0x7fffffff));
221 /* Make sure any pending DEC interrupt occuring while we did
222 * the above didn't re-enable the DEC */
223 mb();
224 asm volatile("mtdec %0" : : "r" (0x7fffffff));
225
226 /* We can now disable MSR_EE */
227 local_irq_disable();
228
229 /* Giveup the FPU & vec */
230 enable_kernel_fp();
231
232#ifdef CONFIG_ALTIVEC
233 if (cpu_has_feature(CPU_FTR_ALTIVEC))
234 enable_kernel_altivec();
235#endif /* CONFIG_ALTIVEC */
236
237 /* Save & disable L2 and L3 caches */
238 save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
239 save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
240
241 /* Send the new speed command. My assumption is that this command
242 * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
243 */
244 pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
245 while (!req.complete)
246 pmu_poll();
247
248 /* Prepare the northbridge for the speed transition */
249 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
250
251 /* Call low level code to backup CPU state and recover from
252 * hardware reset
253 */
254 low_sleep_handler();
255
256 /* Restore the northbridge */
257 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
258
259 /* Restore L2 cache */
260 if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
261 _set_L2CR(save_l2cr);
262 /* Restore L3 cache */
263 if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
264 _set_L3CR(save_l3cr);
265
266 /* Restore userland MMU context */
267 set_context(current->active_mm->context, current->active_mm->pgd);
268
269#ifdef DEBUG_FREQ
270 printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
271#endif
272
273 /* Restore low level PMU operations */
274 pmu_unlock();
275
276 /* Restore decrementer */
277 wakeup_decrementer();
278
279 /* Restore interrupts */
280 openpic_set_priority(0);
281
282 /* Let interrupts flow again ... */
283 local_irq_enable();
284
285#ifdef DEBUG_FREQ
286 debug_calc_bogomips();
287#endif
288
289 preempt_enable();
290
291 return 0;
292}
293
294static int __pmac do_set_cpu_speed(int speed_mode)
295{
296 struct cpufreq_freqs freqs;
297
298 freqs.old = cur_freq;
299 freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
300 freqs.cpu = smp_processor_id();
301
302 if (freqs.old == freqs.new)
303 return 0;
304
305 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
306 set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
307 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
308 cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
309
310 return 0;
311}
312
313static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy)
314{
315 return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
316}
317
318static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy,
319 unsigned int target_freq,
320 unsigned int relation)
321{
322 unsigned int newstate = 0;
323
324 if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
325 target_freq, relation, &newstate))
326 return -EINVAL;
327
328 return do_set_cpu_speed(newstate);
329}
330
331unsigned int __pmac pmac_get_one_cpufreq(int i)
332{
333 /* Supports only one CPU for now */
334 return (i == 0) ? cur_freq : 0;
335}
336
337static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
338{
339 if (policy->cpu != 0)
340 return -ENODEV;
341
342 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
343 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
344 policy->cur = cur_freq;
345
346 return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]);
347}
348
349static u32 __pmac read_gpio(struct device_node *np)
350{
351 u32 *reg = (u32 *)get_property(np, "reg", NULL);
352
353 if (reg == NULL)
354 return 0;
355 /* That works for all keylargos but shall be fixed properly
356 * some day...
357 */
358 return 0x50 + (*reg);
359}
360
361static struct cpufreq_driver pmac_cpufreq_driver = {
362 .verify = pmac_cpufreq_verify,
363 .target = pmac_cpufreq_target,
364 .init = pmac_cpufreq_cpu_init,
365 .name = "powermac",
366 .owner = THIS_MODULE,
367};
368
369
370static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
371{
372 struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
373 "voltage-gpio");
374 struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
375 "frequency-gpio");
376 struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
377 "slewing-done");
378 u32 *value;
379
380 /*
381 * Check to see if it's GPIO driven or PMU only
382 *
383 * The way we extract the GPIO address is slightly hackish, but it
384 * works well enough for now. We need to abstract the whole GPIO
385 * stuff sooner or later anyway
386 */
387
388 if (volt_gpio_np)
389 voltage_gpio = read_gpio(volt_gpio_np);
390 if (freq_gpio_np)
391 frequency_gpio = read_gpio(freq_gpio_np);
392 if (slew_done_gpio_np)
393 slew_done_gpio = read_gpio(slew_done_gpio_np);
394
395 /* If we use the frequency GPIOs, calculate the min/max speeds based
396 * on the bus frequencies
397 */
398 if (frequency_gpio && slew_done_gpio) {
399 int lenp, rc;
400 u32 *freqs, *ratio;
401
402 freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
403 lenp /= sizeof(u32);
404 if (freqs == NULL || lenp != 2) {
405 printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
406 return 1;
407 }
408 ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
409 if (ratio == NULL) {
410 printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
411 return 1;
412 }
413
414 /* Get the min/max bus frequencies */
415 low_freq = min(freqs[0], freqs[1]);
416 hi_freq = max(freqs[0], freqs[1]);
417
418 /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
419 * frequency, it claims it to be around 84Mhz on some models while
420 * it appears to be approx. 101Mhz on all. Let's hack around here...
421 * fortunately, we don't need to be too precise
422 */
423 if (low_freq < 98000000)
424 low_freq = 101000000;
425
426 /* Convert those to CPU core clocks */
427 low_freq = (low_freq * (*ratio)) / 2000;
428 hi_freq = (hi_freq * (*ratio)) / 2000;
429
430 /* Now we get the frequencies, we read the GPIO to see what is out current
431 * speed
432 */
433 rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
434 cur_freq = (rc & 0x01) ? hi_freq : low_freq;
435
436 set_speed_proc = gpios_set_cpu_speed;
437 return 1;
438 }
439
440 /* If we use the PMU, look for the min & max frequencies in the
441 * device-tree
442 */
443 value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
444 if (!value)
445 return 1;
446 low_freq = (*value) / 1000;
447 /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
448 * here */
449 if (low_freq < 100000)
450 low_freq *= 10;
451
452 value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
453 if (!value)
454 return 1;
455 hi_freq = (*value) / 1000;
456 set_speed_proc = pmu_set_cpu_speed;
457
458 return 0;
459}
460
461static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
462{
463 struct device_node *volt_gpio_np;
464 u32 *reg;
465 struct cpufreq_driver *driver = &pmac_cpufreq_driver;
466
467 /* Look for voltage GPIO */
468 volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
469 reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
470 voltage_gpio = *reg;
471 if (!volt_gpio_np){
472 printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
473 return 1;
474 }
475
476 /* OF only reports the high frequency */
477 hi_freq = cur_freq;
478 low_freq = cur_freq/2;
479
480 /* Read actual frequency from CPU */
481 driver->get = dfs_get_cpu_speed;
482 cur_freq = driver->get(0);
483 set_speed_proc = dfs_set_cpu_speed;
484
485 return 0;
486}
487
488/* Currently, we support the following machines:
489 *
490 * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
491 * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
492 * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
493 * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
494 * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
495 * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
496 * - Recent MacRISC3 laptops
497 * - All new machines with 7447A CPUs
498 */
499static int __init pmac_cpufreq_setup(void)
500{
501 struct device_node *cpunode;
502 u32 *value;
503
504 if (strstr(cmd_line, "nocpufreq"))
505 return 0;
506
507 /* Assume only one CPU */
508 cpunode = find_type_devices("cpu");
509 if (!cpunode)
510 goto out;
511
512 /* Get current cpu clock freq */
513 value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
514 if (!value)
515 goto out;
516 cur_freq = (*value) / 1000;
517
518 /* Check for 7447A based MacRISC3 */
519 if (machine_is_compatible("MacRISC3") &&
520 get_property(cpunode, "dynamic-power-step", NULL) &&
521 PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
522 pmac_cpufreq_init_7447A(cpunode);
523 /* Check for other MacRISC3 machines */
524 } else if (machine_is_compatible("PowerBook3,4") ||
525 machine_is_compatible("PowerBook3,5") ||
526 machine_is_compatible("MacRISC3")) {
527 pmac_cpufreq_init_MacRISC3(cpunode);
528 /* Else check for iBook2 500/600 */
529 } else if (machine_is_compatible("PowerBook4,1")) {
530 hi_freq = cur_freq;
531 low_freq = 400000;
532 set_speed_proc = pmu_set_cpu_speed;
533 }
534 /* Else check for TiPb 400 & 500 */
535 else if (machine_is_compatible("PowerBook3,2")) {
536 /* We only know about the 400 MHz and the 500Mhz model
537 * they both have 300 MHz as low frequency
538 */
539 if (cur_freq < 350000 || cur_freq > 550000)
540 goto out;
541 hi_freq = cur_freq;
542 low_freq = 300000;
543 set_speed_proc = pmu_set_cpu_speed;
544 }
545 /* Else check for 750FX */
546 else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) {
547 if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
548 goto out;
549 hi_freq = cur_freq;
550 value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
551 if (!value)
552 goto out;
553 low_freq = (*value) / 1000;
554 set_speed_proc = cpu_750fx_cpu_speed;
555 }
556out:
557 if (set_speed_proc == NULL)
558 return -ENODEV;
559
560 pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
561 pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
562
563 printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
564 printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
565 low_freq/1000, hi_freq/1000, cur_freq/1000);
566
567 return cpufreq_register_driver(&pmac_cpufreq_driver);
568}
569
570module_init(pmac_cpufreq_setup);
571
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
new file mode 100644
index 000000000000..8e60550863a6
--- /dev/null
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -0,0 +1,2972 @@
1/*
2 * arch/ppc/platforms/pmac_feature.c
3 *
4 * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
5 * Ben. Herrenschmidt (benh@kernel.crashing.org)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * TODO:
13 *
14 * - Replace mdelay with some schedule loop if possible
15 * - Shorten some obfuscated delays on some routines (like modem
16 * power)
17 * - Refcount some clocks (see darwin)
18 * - Split split split...
19 *
20 */
21#include <linux/config.h>
22#include <linux/types.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/spinlock.h>
28#include <linux/adb.h>
29#include <linux/pmu.h>
30#include <linux/ioport.h>
31#include <linux/pci.h>
32#include <asm/sections.h>
33#include <asm/errno.h>
34#include <asm/ohare.h>
35#include <asm/heathrow.h>
36#include <asm/keylargo.h>
37#include <asm/uninorth.h>
38#include <asm/io.h>
39#include <asm/prom.h>
40#include <asm/machdep.h>
41#include <asm/pmac_feature.h>
42#include <asm/dbdma.h>
43#include <asm/pci-bridge.h>
44#include <asm/pmac_low_i2c.h>
45
46#undef DEBUG_FEATURE
47
48#ifdef DEBUG_FEATURE
49#define DBG(fmt,...) printk(KERN_DEBUG fmt)
50#else
51#define DBG(fmt,...)
52#endif
53
54#ifdef CONFIG_6xx
55extern int powersave_lowspeed;
56#endif
57
58extern int powersave_nap;
59extern struct device_node *k2_skiplist[2];
60
61
62/*
63 * We use a single global lock to protect accesses. Each driver has
64 * to take care of its own locking
65 */
66static DEFINE_SPINLOCK(feature_lock __pmacdata);
67
68#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags);
69#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags);
70
71
72/*
73 * Instance of some macio stuffs
74 */
75struct macio_chip macio_chips[MAX_MACIO_CHIPS] __pmacdata;
76
77struct macio_chip* __pmac
78macio_find(struct device_node* child, int type)
79{
80 while(child) {
81 int i;
82
83 for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
84 if (child == macio_chips[i].of_node &&
85 (!type || macio_chips[i].type == type))
86 return &macio_chips[i];
87 child = child->parent;
88 }
89 return NULL;
90}
91
92static const char* macio_names[] __pmacdata =
93{
94 "Unknown",
95 "Grand Central",
96 "OHare",
97 "OHareII",
98 "Heathrow",
99 "Gatwick",
100 "Paddington",
101 "Keylargo",
102 "Pangea",
103 "Intrepid",
104 "K2"
105};
106
107
108
109/*
110 * Uninorth reg. access. Note that Uni-N regs are big endian
111 */
112
113#define UN_REG(r) (uninorth_base + ((r) >> 2))
114#define UN_IN(r) (in_be32(UN_REG(r)))
115#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
116#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
117#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
118
119static struct device_node* uninorth_node __pmacdata;
120static u32 __iomem * uninorth_base __pmacdata;
121static u32 uninorth_rev __pmacdata;
122static int uninorth_u3 __pmacdata;
123static void __iomem *u3_ht;
124
125/*
126 * For each motherboard family, we have a table of functions pointers
127 * that handle the various features.
128 */
129
130typedef long (*feature_call)(struct device_node* node, long param, long value);
131
132struct feature_table_entry {
133 unsigned int selector;
134 feature_call function;
135};
136
137struct pmac_mb_def
138{
139 const char* model_string;
140 const char* model_name;
141 int model_id;
142 struct feature_table_entry* features;
143 unsigned long board_flags;
144};
145static struct pmac_mb_def pmac_mb __pmacdata;
146
147/*
148 * Here are the chip specific feature functions
149 */
150
151static inline int __pmac
152simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value)
153{
154 struct macio_chip* macio;
155 unsigned long flags;
156
157 macio = macio_find(node, type);
158 if (!macio)
159 return -ENODEV;
160 LOCK(flags);
161 if (value)
162 MACIO_BIS(reg, mask);
163 else
164 MACIO_BIC(reg, mask);
165 (void)MACIO_IN32(reg);
166 UNLOCK(flags);
167
168 return 0;
169}
170
171#ifndef CONFIG_POWER4
172
173static long __pmac
174ohare_htw_scc_enable(struct device_node* node, long param, long value)
175{
176 struct macio_chip* macio;
177 unsigned long chan_mask;
178 unsigned long fcr;
179 unsigned long flags;
180 int htw, trans;
181 unsigned long rmask;
182
183 macio = macio_find(node, 0);
184 if (!macio)
185 return -ENODEV;
186 if (!strcmp(node->name, "ch-a"))
187 chan_mask = MACIO_FLAG_SCCA_ON;
188 else if (!strcmp(node->name, "ch-b"))
189 chan_mask = MACIO_FLAG_SCCB_ON;
190 else
191 return -ENODEV;
192
193 htw = (macio->type == macio_heathrow || macio->type == macio_paddington
194 || macio->type == macio_gatwick);
195 /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
196 trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
197 pmac_mb.model_id != PMAC_TYPE_YIKES);
198 if (value) {
199#ifdef CONFIG_ADB_PMU
200 if ((param & 0xfff) == PMAC_SCC_IRDA)
201 pmu_enable_irled(1);
202#endif /* CONFIG_ADB_PMU */
203 LOCK(flags);
204 fcr = MACIO_IN32(OHARE_FCR);
205 /* Check if scc cell need enabling */
206 if (!(fcr & OH_SCC_ENABLE)) {
207 fcr |= OH_SCC_ENABLE;
208 if (htw) {
209 /* Side effect: this will also power up the
210 * modem, but it's too messy to figure out on which
211 * ports this controls the tranceiver and on which
212 * it controls the modem
213 */
214 if (trans)
215 fcr &= ~HRW_SCC_TRANS_EN_N;
216 MACIO_OUT32(OHARE_FCR, fcr);
217 fcr |= (rmask = HRW_RESET_SCC);
218 MACIO_OUT32(OHARE_FCR, fcr);
219 } else {
220 fcr |= (rmask = OH_SCC_RESET);
221 MACIO_OUT32(OHARE_FCR, fcr);
222 }
223 UNLOCK(flags);
224 (void)MACIO_IN32(OHARE_FCR);
225 mdelay(15);
226 LOCK(flags);
227 fcr &= ~rmask;
228 MACIO_OUT32(OHARE_FCR, fcr);
229 }
230 if (chan_mask & MACIO_FLAG_SCCA_ON)
231 fcr |= OH_SCCA_IO;
232 if (chan_mask & MACIO_FLAG_SCCB_ON)
233 fcr |= OH_SCCB_IO;
234 MACIO_OUT32(OHARE_FCR, fcr);
235 macio->flags |= chan_mask;
236 UNLOCK(flags);
237 if (param & PMAC_SCC_FLAG_XMON)
238 macio->flags |= MACIO_FLAG_SCC_LOCKED;
239 } else {
240 if (macio->flags & MACIO_FLAG_SCC_LOCKED)
241 return -EPERM;
242 LOCK(flags);
243 fcr = MACIO_IN32(OHARE_FCR);
244 if (chan_mask & MACIO_FLAG_SCCA_ON)
245 fcr &= ~OH_SCCA_IO;
246 if (chan_mask & MACIO_FLAG_SCCB_ON)
247 fcr &= ~OH_SCCB_IO;
248 MACIO_OUT32(OHARE_FCR, fcr);
249 if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
250 fcr &= ~OH_SCC_ENABLE;
251 if (htw && trans)
252 fcr |= HRW_SCC_TRANS_EN_N;
253 MACIO_OUT32(OHARE_FCR, fcr);
254 }
255 macio->flags &= ~(chan_mask);
256 UNLOCK(flags);
257 mdelay(10);
258#ifdef CONFIG_ADB_PMU
259 if ((param & 0xfff) == PMAC_SCC_IRDA)
260 pmu_enable_irled(0);
261#endif /* CONFIG_ADB_PMU */
262 }
263 return 0;
264}
265
266static long __pmac
267ohare_floppy_enable(struct device_node* node, long param, long value)
268{
269 return simple_feature_tweak(node, macio_ohare,
270 OHARE_FCR, OH_FLOPPY_ENABLE, value);
271}
272
273static long __pmac
274ohare_mesh_enable(struct device_node* node, long param, long value)
275{
276 return simple_feature_tweak(node, macio_ohare,
277 OHARE_FCR, OH_MESH_ENABLE, value);
278}
279
280static long __pmac
281ohare_ide_enable(struct device_node* node, long param, long value)
282{
283 switch(param) {
284 case 0:
285 /* For some reason, setting the bit in set_initial_features()
286 * doesn't stick. I'm still investigating... --BenH.
287 */
288 if (value)
289 simple_feature_tweak(node, macio_ohare,
290 OHARE_FCR, OH_IOBUS_ENABLE, 1);
291 return simple_feature_tweak(node, macio_ohare,
292 OHARE_FCR, OH_IDE0_ENABLE, value);
293 case 1:
294 return simple_feature_tweak(node, macio_ohare,
295 OHARE_FCR, OH_BAY_IDE_ENABLE, value);
296 default:
297 return -ENODEV;
298 }
299}
300
301static long __pmac
302ohare_ide_reset(struct device_node* node, long param, long value)
303{
304 switch(param) {
305 case 0:
306 return simple_feature_tweak(node, macio_ohare,
307 OHARE_FCR, OH_IDE0_RESET_N, !value);
308 case 1:
309 return simple_feature_tweak(node, macio_ohare,
310 OHARE_FCR, OH_IDE1_RESET_N, !value);
311 default:
312 return -ENODEV;
313 }
314}
315
316static long __pmac
317ohare_sleep_state(struct device_node* node, long param, long value)
318{
319 struct macio_chip* macio = &macio_chips[0];
320
321 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
322 return -EPERM;
323 if (value == 1) {
324 MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
325 } else if (value == 0) {
326 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
327 }
328
329 return 0;
330}
331
332static long __pmac
333heathrow_modem_enable(struct device_node* node, long param, long value)
334{
335 struct macio_chip* macio;
336 u8 gpio;
337 unsigned long flags;
338
339 macio = macio_find(node, macio_unknown);
340 if (!macio)
341 return -ENODEV;
342 gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
343 if (!value) {
344 LOCK(flags);
345 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
346 UNLOCK(flags);
347 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
348 mdelay(250);
349 }
350 if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
351 pmac_mb.model_id != PMAC_TYPE_YIKES) {
352 LOCK(flags);
353 if (value)
354 MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
355 else
356 MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
357 UNLOCK(flags);
358 (void)MACIO_IN32(HEATHROW_FCR);
359 mdelay(250);
360 }
361 if (value) {
362 LOCK(flags);
363 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
364 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
365 UNLOCK(flags); mdelay(250); LOCK(flags);
366 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
367 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
368 UNLOCK(flags); mdelay(250); LOCK(flags);
369 MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
370 (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
371 UNLOCK(flags); mdelay(250);
372 }
373 return 0;
374}
375
376static long __pmac
377heathrow_floppy_enable(struct device_node* node, long param, long value)
378{
379 return simple_feature_tweak(node, macio_unknown,
380 HEATHROW_FCR,
381 HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
382 value);
383}
384
385static long __pmac
386heathrow_mesh_enable(struct device_node* node, long param, long value)
387{
388 struct macio_chip* macio;
389 unsigned long flags;
390
391 macio = macio_find(node, macio_unknown);
392 if (!macio)
393 return -ENODEV;
394 LOCK(flags);
395 /* Set clear mesh cell enable */
396 if (value)
397 MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
398 else
399 MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
400 (void)MACIO_IN32(HEATHROW_FCR);
401 udelay(10);
402 /* Set/Clear termination power */
403 if (value)
404 MACIO_BIC(HEATHROW_MBCR, 0x04000000);
405 else
406 MACIO_BIS(HEATHROW_MBCR, 0x04000000);
407 (void)MACIO_IN32(HEATHROW_MBCR);
408 udelay(10);
409 UNLOCK(flags);
410
411 return 0;
412}
413
414static long __pmac
415heathrow_ide_enable(struct device_node* node, long param, long value)
416{
417 switch(param) {
418 case 0:
419 return simple_feature_tweak(node, macio_unknown,
420 HEATHROW_FCR, HRW_IDE0_ENABLE, value);
421 case 1:
422 return simple_feature_tweak(node, macio_unknown,
423 HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
424 default:
425 return -ENODEV;
426 }
427}
428
429static long __pmac
430heathrow_ide_reset(struct device_node* node, long param, long value)
431{
432 switch(param) {
433 case 0:
434 return simple_feature_tweak(node, macio_unknown,
435 HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
436 case 1:
437 return simple_feature_tweak(node, macio_unknown,
438 HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
439 default:
440 return -ENODEV;
441 }
442}
443
444static long __pmac
445heathrow_bmac_enable(struct device_node* node, long param, long value)
446{
447 struct macio_chip* macio;
448 unsigned long flags;
449
450 macio = macio_find(node, 0);
451 if (!macio)
452 return -ENODEV;
453 if (value) {
454 LOCK(flags);
455 MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
456 MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
457 UNLOCK(flags);
458 (void)MACIO_IN32(HEATHROW_FCR);
459 mdelay(10);
460 LOCK(flags);
461 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
462 UNLOCK(flags);
463 (void)MACIO_IN32(HEATHROW_FCR);
464 mdelay(10);
465 } else {
466 LOCK(flags);
467 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
468 UNLOCK(flags);
469 }
470 return 0;
471}
472
473static long __pmac
474heathrow_sound_enable(struct device_node* node, long param, long value)
475{
476 struct macio_chip* macio;
477 unsigned long flags;
478
479 /* B&W G3 and Yikes don't support that properly (the
480 * sound appear to never come back after beeing shut down).
481 */
482 if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
483 pmac_mb.model_id == PMAC_TYPE_YIKES)
484 return 0;
485
486 macio = macio_find(node, 0);
487 if (!macio)
488 return -ENODEV;
489 if (value) {
490 LOCK(flags);
491 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
492 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
493 UNLOCK(flags);
494 (void)MACIO_IN32(HEATHROW_FCR);
495 } else {
496 LOCK(flags);
497 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
498 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
499 UNLOCK(flags);
500 }
501 return 0;
502}
503
504static u32 save_fcr[6] __pmacdata;
505static u32 save_mbcr __pmacdata;
506static u32 save_gpio_levels[2] __pmacdata;
507static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
508static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata;
509static u32 save_unin_clock_ctl __pmacdata;
510static struct dbdma_regs save_dbdma[13] __pmacdata;
511static struct dbdma_regs save_alt_dbdma[13] __pmacdata;
512
513static void __pmac
514dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
515{
516 int i;
517
518 /* Save state & config of DBDMA channels */
519 for (i=0; i<13; i++) {
520 volatile struct dbdma_regs __iomem * chan = (void __iomem *)
521 (macio->base + ((0x8000+i*0x100)>>2));
522 save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
523 save[i].cmdptr = in_le32(&chan->cmdptr);
524 save[i].intr_sel = in_le32(&chan->intr_sel);
525 save[i].br_sel = in_le32(&chan->br_sel);
526 save[i].wait_sel = in_le32(&chan->wait_sel);
527 }
528}
529
530static void __pmac
531dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
532{
533 int i;
534
535 /* Save state & config of DBDMA channels */
536 for (i=0; i<13; i++) {
537 volatile struct dbdma_regs __iomem * chan = (void __iomem *)
538 (macio->base + ((0x8000+i*0x100)>>2));
539 out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
540 while (in_le32(&chan->status) & ACTIVE)
541 mb();
542 out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
543 out_le32(&chan->cmdptr, save[i].cmdptr);
544 out_le32(&chan->intr_sel, save[i].intr_sel);
545 out_le32(&chan->br_sel, save[i].br_sel);
546 out_le32(&chan->wait_sel, save[i].wait_sel);
547 }
548}
549
550static void __pmac
551heathrow_sleep(struct macio_chip* macio, int secondary)
552{
553 if (secondary) {
554 dbdma_save(macio, save_alt_dbdma);
555 save_fcr[2] = MACIO_IN32(0x38);
556 save_fcr[3] = MACIO_IN32(0x3c);
557 } else {
558 dbdma_save(macio, save_dbdma);
559 save_fcr[0] = MACIO_IN32(0x38);
560 save_fcr[1] = MACIO_IN32(0x3c);
561 save_mbcr = MACIO_IN32(0x34);
562 /* Make sure sound is shut down */
563 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
564 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
565 /* This seems to be necessary as well or the fan
566 * keeps coming up and battery drains fast */
567 MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
568 MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
569 /* Make sure eth is down even if module or sleep
570 * won't work properly */
571 MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
572 }
573 /* Make sure modem is shut down */
574 MACIO_OUT8(HRW_GPIO_MODEM_RESET,
575 MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
576 MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
577 MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
578
579 /* Let things settle */
580 (void)MACIO_IN32(HEATHROW_FCR);
581}
582
583static void __pmac
584heathrow_wakeup(struct macio_chip* macio, int secondary)
585{
586 if (secondary) {
587 MACIO_OUT32(0x38, save_fcr[2]);
588 (void)MACIO_IN32(0x38);
589 mdelay(1);
590 MACIO_OUT32(0x3c, save_fcr[3]);
591 (void)MACIO_IN32(0x38);
592 mdelay(10);
593 dbdma_restore(macio, save_alt_dbdma);
594 } else {
595 MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
596 (void)MACIO_IN32(0x38);
597 mdelay(1);
598 MACIO_OUT32(0x3c, save_fcr[1]);
599 (void)MACIO_IN32(0x38);
600 mdelay(1);
601 MACIO_OUT32(0x34, save_mbcr);
602 (void)MACIO_IN32(0x38);
603 mdelay(10);
604 dbdma_restore(macio, save_dbdma);
605 }
606}
607
608static long __pmac
609heathrow_sleep_state(struct device_node* node, long param, long value)
610{
611 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
612 return -EPERM;
613 if (value == 1) {
614 if (macio_chips[1].type == macio_gatwick)
615 heathrow_sleep(&macio_chips[0], 1);
616 heathrow_sleep(&macio_chips[0], 0);
617 } else if (value == 0) {
618 heathrow_wakeup(&macio_chips[0], 0);
619 if (macio_chips[1].type == macio_gatwick)
620 heathrow_wakeup(&macio_chips[0], 1);
621 }
622 return 0;
623}
624
625static long __pmac
626core99_scc_enable(struct device_node* node, long param, long value)
627{
628 struct macio_chip* macio;
629 unsigned long flags;
630 unsigned long chan_mask;
631 u32 fcr;
632
633 macio = macio_find(node, 0);
634 if (!macio)
635 return -ENODEV;
636 if (!strcmp(node->name, "ch-a"))
637 chan_mask = MACIO_FLAG_SCCA_ON;
638 else if (!strcmp(node->name, "ch-b"))
639 chan_mask = MACIO_FLAG_SCCB_ON;
640 else
641 return -ENODEV;
642
643 if (value) {
644 int need_reset_scc = 0;
645 int need_reset_irda = 0;
646
647 LOCK(flags);
648 fcr = MACIO_IN32(KEYLARGO_FCR0);
649 /* Check if scc cell need enabling */
650 if (!(fcr & KL0_SCC_CELL_ENABLE)) {
651 fcr |= KL0_SCC_CELL_ENABLE;
652 need_reset_scc = 1;
653 }
654 if (chan_mask & MACIO_FLAG_SCCA_ON) {
655 fcr |= KL0_SCCA_ENABLE;
656 /* Don't enable line drivers for I2S modem */
657 if ((param & 0xfff) == PMAC_SCC_I2S1)
658 fcr &= ~KL0_SCC_A_INTF_ENABLE;
659 else
660 fcr |= KL0_SCC_A_INTF_ENABLE;
661 }
662 if (chan_mask & MACIO_FLAG_SCCB_ON) {
663 fcr |= KL0_SCCB_ENABLE;
664 /* Perform irda specific inits */
665 if ((param & 0xfff) == PMAC_SCC_IRDA) {
666 fcr &= ~KL0_SCC_B_INTF_ENABLE;
667 fcr |= KL0_IRDA_ENABLE;
668 fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
669 fcr |= KL0_IRDA_SOURCE1_SEL;
670 fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
671 fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
672 need_reset_irda = 1;
673 } else
674 fcr |= KL0_SCC_B_INTF_ENABLE;
675 }
676 MACIO_OUT32(KEYLARGO_FCR0, fcr);
677 macio->flags |= chan_mask;
678 if (need_reset_scc) {
679 MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
680 (void)MACIO_IN32(KEYLARGO_FCR0);
681 UNLOCK(flags);
682 mdelay(15);
683 LOCK(flags);
684 MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
685 }
686 if (need_reset_irda) {
687 MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
688 (void)MACIO_IN32(KEYLARGO_FCR0);
689 UNLOCK(flags);
690 mdelay(15);
691 LOCK(flags);
692 MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
693 }
694 UNLOCK(flags);
695 if (param & PMAC_SCC_FLAG_XMON)
696 macio->flags |= MACIO_FLAG_SCC_LOCKED;
697 } else {
698 if (macio->flags & MACIO_FLAG_SCC_LOCKED)
699 return -EPERM;
700 LOCK(flags);
701 fcr = MACIO_IN32(KEYLARGO_FCR0);
702 if (chan_mask & MACIO_FLAG_SCCA_ON)
703 fcr &= ~KL0_SCCA_ENABLE;
704 if (chan_mask & MACIO_FLAG_SCCB_ON) {
705 fcr &= ~KL0_SCCB_ENABLE;
706 /* Perform irda specific clears */
707 if ((param & 0xfff) == PMAC_SCC_IRDA) {
708 fcr &= ~KL0_IRDA_ENABLE;
709 fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
710 fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
711 fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
712 }
713 }
714 MACIO_OUT32(KEYLARGO_FCR0, fcr);
715 if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
716 fcr &= ~KL0_SCC_CELL_ENABLE;
717 MACIO_OUT32(KEYLARGO_FCR0, fcr);
718 }
719 macio->flags &= ~(chan_mask);
720 UNLOCK(flags);
721 mdelay(10);
722 }
723 return 0;
724}
725
726static long __pmac
727core99_modem_enable(struct device_node* node, long param, long value)
728{
729 struct macio_chip* macio;
730 u8 gpio;
731 unsigned long flags;
732
733 /* Hack for internal USB modem */
734 if (node == NULL) {
735 if (macio_chips[0].type != macio_keylargo)
736 return -ENODEV;
737 node = macio_chips[0].of_node;
738 }
739 macio = macio_find(node, 0);
740 if (!macio)
741 return -ENODEV;
742 gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
743 gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
744 gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
745
746 if (!value) {
747 LOCK(flags);
748 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
749 UNLOCK(flags);
750 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
751 mdelay(250);
752 }
753 LOCK(flags);
754 if (value) {
755 MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
756 UNLOCK(flags);
757 (void)MACIO_IN32(KEYLARGO_FCR2);
758 mdelay(250);
759 } else {
760 MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
761 UNLOCK(flags);
762 }
763 if (value) {
764 LOCK(flags);
765 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
766 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
767 UNLOCK(flags); mdelay(250); LOCK(flags);
768 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
769 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
770 UNLOCK(flags); mdelay(250); LOCK(flags);
771 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
772 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
773 UNLOCK(flags); mdelay(250);
774 }
775 return 0;
776}
777
778static long __pmac
779pangea_modem_enable(struct device_node* node, long param, long value)
780{
781 struct macio_chip* macio;
782 u8 gpio;
783 unsigned long flags;
784
785 /* Hack for internal USB modem */
786 if (node == NULL) {
787 if (macio_chips[0].type != macio_pangea &&
788 macio_chips[0].type != macio_intrepid)
789 return -ENODEV;
790 node = macio_chips[0].of_node;
791 }
792 macio = macio_find(node, 0);
793 if (!macio)
794 return -ENODEV;
795 gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
796 gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
797 gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
798
799 if (!value) {
800 LOCK(flags);
801 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
802 UNLOCK(flags);
803 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
804 mdelay(250);
805 }
806 LOCK(flags);
807 if (value) {
808 MACIO_OUT8(KL_GPIO_MODEM_POWER,
809 KEYLARGO_GPIO_OUTPUT_ENABLE);
810 UNLOCK(flags);
811 (void)MACIO_IN32(KEYLARGO_FCR2);
812 mdelay(250);
813 } else {
814 MACIO_OUT8(KL_GPIO_MODEM_POWER,
815 KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
816 UNLOCK(flags);
817 }
818 if (value) {
819 LOCK(flags);
820 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
821 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
822 UNLOCK(flags); mdelay(250); LOCK(flags);
823 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
824 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
825 UNLOCK(flags); mdelay(250); LOCK(flags);
826 MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
827 (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
828 UNLOCK(flags); mdelay(250);
829 }
830 return 0;
831}
832
833static long __pmac
834core99_ata100_enable(struct device_node* node, long value)
835{
836 unsigned long flags;
837 struct pci_dev *pdev = NULL;
838 u8 pbus, pid;
839
840 if (uninorth_rev < 0x24)
841 return -ENODEV;
842
843 LOCK(flags);
844 if (value)
845 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
846 else
847 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
848 (void)UN_IN(UNI_N_CLOCK_CNTL);
849 UNLOCK(flags);
850 udelay(20);
851
852 if (value) {
853 if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
854 pdev = pci_find_slot(pbus, pid);
855 if (pdev == NULL)
856 return 0;
857 pci_enable_device(pdev);
858 pci_set_master(pdev);
859 }
860 return 0;
861}
862
863static long __pmac
864core99_ide_enable(struct device_node* node, long param, long value)
865{
866 /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
867 * based ata-100
868 */
869 switch(param) {
870 case 0:
871 return simple_feature_tweak(node, macio_unknown,
872 KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
873 case 1:
874 return simple_feature_tweak(node, macio_unknown,
875 KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
876 case 2:
877 return simple_feature_tweak(node, macio_unknown,
878 KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
879 case 3:
880 return core99_ata100_enable(node, value);
881 default:
882 return -ENODEV;
883 }
884}
885
886static long __pmac
887core99_ide_reset(struct device_node* node, long param, long value)
888{
889 switch(param) {
890 case 0:
891 return simple_feature_tweak(node, macio_unknown,
892 KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
893 case 1:
894 return simple_feature_tweak(node, macio_unknown,
895 KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
896 case 2:
897 return simple_feature_tweak(node, macio_unknown,
898 KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
899 default:
900 return -ENODEV;
901 }
902}
903
904static long __pmac
905core99_gmac_enable(struct device_node* node, long param, long value)
906{
907 unsigned long flags;
908
909 LOCK(flags);
910 if (value)
911 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
912 else
913 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
914 (void)UN_IN(UNI_N_CLOCK_CNTL);
915 UNLOCK(flags);
916 udelay(20);
917
918 return 0;
919}
920
921static long __pmac
922core99_gmac_phy_reset(struct device_node* node, long param, long value)
923{
924 unsigned long flags;
925 struct macio_chip* macio;
926
927 macio = &macio_chips[0];
928 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
929 macio->type != macio_intrepid)
930 return -ENODEV;
931
932 LOCK(flags);
933 MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
934 (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
935 UNLOCK(flags);
936 mdelay(10);
937 LOCK(flags);
938 MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
939 KEYLARGO_GPIO_OUTOUT_DATA);
940 UNLOCK(flags);
941 mdelay(10);
942
943 return 0;
944}
945
946static long __pmac
947core99_sound_chip_enable(struct device_node* node, long param, long value)
948{
949 struct macio_chip* macio;
950 unsigned long flags;
951
952 macio = macio_find(node, 0);
953 if (!macio)
954 return -ENODEV;
955
956 /* Do a better probe code, screamer G4 desktops &
957 * iMacs can do that too, add a recalibrate in
958 * the driver as well
959 */
960 if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
961 pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
962 LOCK(flags);
963 if (value)
964 MACIO_OUT8(KL_GPIO_SOUND_POWER,
965 KEYLARGO_GPIO_OUTPUT_ENABLE |
966 KEYLARGO_GPIO_OUTOUT_DATA);
967 else
968 MACIO_OUT8(KL_GPIO_SOUND_POWER,
969 KEYLARGO_GPIO_OUTPUT_ENABLE);
970 (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
971 UNLOCK(flags);
972 }
973 return 0;
974}
975
976static long __pmac
977core99_airport_enable(struct device_node* node, long param, long value)
978{
979 struct macio_chip* macio;
980 unsigned long flags;
981 int state;
982
983 macio = macio_find(node, 0);
984 if (!macio)
985 return -ENODEV;
986
987 /* Hint: we allow passing of macio itself for the sake of the
988 * sleep code
989 */
990 if (node != macio->of_node &&
991 (!node->parent || node->parent != macio->of_node))
992 return -ENODEV;
993 state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
994 if (value == state)
995 return 0;
996 if (value) {
997 /* This code is a reproduction of OF enable-cardslot
998 * and init-wireless methods, slightly hacked until
999 * I got it working.
1000 */
1001 LOCK(flags);
1002 MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
1003 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
1004 UNLOCK(flags);
1005 mdelay(10);
1006 LOCK(flags);
1007 MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
1008 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
1009 UNLOCK(flags);
1010
1011 mdelay(10);
1012
1013 LOCK(flags);
1014 MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
1015 (void)MACIO_IN32(KEYLARGO_FCR2);
1016 udelay(10);
1017 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
1018 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
1019 udelay(10);
1020 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
1021 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
1022 udelay(10);
1023 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
1024 (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
1025 udelay(10);
1026 MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
1027 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
1028 udelay(10);
1029 MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
1030 (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
1031 UNLOCK(flags);
1032 udelay(10);
1033 MACIO_OUT32(0x1c000, 0);
1034 mdelay(1);
1035 MACIO_OUT8(0x1a3e0, 0x41);
1036 (void)MACIO_IN8(0x1a3e0);
1037 udelay(10);
1038 LOCK(flags);
1039 MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
1040 (void)MACIO_IN32(KEYLARGO_FCR2);
1041 UNLOCK(flags);
1042 mdelay(100);
1043
1044 macio->flags |= MACIO_FLAG_AIRPORT_ON;
1045 } else {
1046 LOCK(flags);
1047 MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
1048 (void)MACIO_IN32(KEYLARGO_FCR2);
1049 MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
1050 MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
1051 MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
1052 MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
1053 MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
1054 (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
1055 UNLOCK(flags);
1056
1057 macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
1058 }
1059 return 0;
1060}
1061
1062#ifdef CONFIG_SMP
1063static long __pmac
1064core99_reset_cpu(struct device_node* node, long param, long value)
1065{
1066 unsigned int reset_io = 0;
1067 unsigned long flags;
1068 struct macio_chip* macio;
1069 struct device_node* np;
1070 const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
1071 KL_GPIO_RESET_CPU1,
1072 KL_GPIO_RESET_CPU2,
1073 KL_GPIO_RESET_CPU3 };
1074
1075 macio = &macio_chips[0];
1076 if (macio->type != macio_keylargo)
1077 return -ENODEV;
1078
1079 np = find_path_device("/cpus");
1080 if (np == NULL)
1081 return -ENODEV;
1082 for (np = np->child; np != NULL; np = np->sibling) {
1083 u32* num = (u32 *)get_property(np, "reg", NULL);
1084 u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
1085 if (num == NULL || rst == NULL)
1086 continue;
1087 if (param == *num) {
1088 reset_io = *rst;
1089 break;
1090 }
1091 }
1092 if (np == NULL || reset_io == 0)
1093 reset_io = dflt_reset_lines[param];
1094
1095 LOCK(flags);
1096 MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
1097 (void)MACIO_IN8(reset_io);
1098 udelay(1);
1099 MACIO_OUT8(reset_io, 0);
1100 (void)MACIO_IN8(reset_io);
1101 UNLOCK(flags);
1102
1103 return 0;
1104}
1105#endif /* CONFIG_SMP */
1106
1107static long __pmac
1108core99_usb_enable(struct device_node* node, long param, long value)
1109{
1110 struct macio_chip* macio;
1111 unsigned long flags;
1112 char* prop;
1113 int number;
1114 u32 reg;
1115
1116 macio = &macio_chips[0];
1117 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1118 macio->type != macio_intrepid)
1119 return -ENODEV;
1120
1121 prop = (char *)get_property(node, "AAPL,clock-id", NULL);
1122 if (!prop)
1123 return -ENODEV;
1124 if (strncmp(prop, "usb0u048", 8) == 0)
1125 number = 0;
1126 else if (strncmp(prop, "usb1u148", 8) == 0)
1127 number = 2;
1128 else if (strncmp(prop, "usb2u248", 8) == 0)
1129 number = 4;
1130 else
1131 return -ENODEV;
1132
1133 /* Sorry for the brute-force locking, but this is only used during
1134 * sleep and the timing seem to be critical
1135 */
1136 LOCK(flags);
1137 if (value) {
1138 /* Turn ON */
1139 if (number == 0) {
1140 MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
1141 (void)MACIO_IN32(KEYLARGO_FCR0);
1142 UNLOCK(flags);
1143 mdelay(1);
1144 LOCK(flags);
1145 MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
1146 } else if (number == 2) {
1147 MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
1148 UNLOCK(flags);
1149 (void)MACIO_IN32(KEYLARGO_FCR0);
1150 mdelay(1);
1151 LOCK(flags);
1152 MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
1153 } else if (number == 4) {
1154 MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
1155 UNLOCK(flags);
1156 (void)MACIO_IN32(KEYLARGO_FCR1);
1157 mdelay(1);
1158 LOCK(flags);
1159 MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
1160 }
1161 if (number < 4) {
1162 reg = MACIO_IN32(KEYLARGO_FCR4);
1163 reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
1164 KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
1165 reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
1166 KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
1167 MACIO_OUT32(KEYLARGO_FCR4, reg);
1168 (void)MACIO_IN32(KEYLARGO_FCR4);
1169 udelay(10);
1170 } else {
1171 reg = MACIO_IN32(KEYLARGO_FCR3);
1172 reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
1173 KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
1174 reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
1175 KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
1176 MACIO_OUT32(KEYLARGO_FCR3, reg);
1177 (void)MACIO_IN32(KEYLARGO_FCR3);
1178 udelay(10);
1179 }
1180 if (macio->type == macio_intrepid) {
1181 /* wait for clock stopped bits to clear */
1182 u32 test0 = 0, test1 = 0;
1183 u32 status0, status1;
1184 int timeout = 1000;
1185
1186 UNLOCK(flags);
1187 switch (number) {
1188 case 0:
1189 test0 = UNI_N_CLOCK_STOPPED_USB0;
1190 test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
1191 break;
1192 case 2:
1193 test0 = UNI_N_CLOCK_STOPPED_USB1;
1194 test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
1195 break;
1196 case 4:
1197 test0 = UNI_N_CLOCK_STOPPED_USB2;
1198 test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
1199 break;
1200 }
1201 do {
1202 if (--timeout <= 0) {
1203 printk(KERN_ERR "core99_usb_enable: "
1204 "Timeout waiting for clocks\n");
1205 break;
1206 }
1207 mdelay(1);
1208 status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
1209 status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
1210 } while ((status0 & test0) | (status1 & test1));
1211 LOCK(flags);
1212 }
1213 } else {
1214 /* Turn OFF */
1215 if (number < 4) {
1216 reg = MACIO_IN32(KEYLARGO_FCR4);
1217 reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
1218 KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
1219 reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
1220 KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
1221 MACIO_OUT32(KEYLARGO_FCR4, reg);
1222 (void)MACIO_IN32(KEYLARGO_FCR4);
1223 udelay(1);
1224 } else {
1225 reg = MACIO_IN32(KEYLARGO_FCR3);
1226 reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
1227 KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
1228 reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
1229 KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
1230 MACIO_OUT32(KEYLARGO_FCR3, reg);
1231 (void)MACIO_IN32(KEYLARGO_FCR3);
1232 udelay(1);
1233 }
1234 if (number == 0) {
1235 if (macio->type != macio_intrepid)
1236 MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
1237 (void)MACIO_IN32(KEYLARGO_FCR0);
1238 udelay(1);
1239 MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
1240 (void)MACIO_IN32(KEYLARGO_FCR0);
1241 } else if (number == 2) {
1242 if (macio->type != macio_intrepid)
1243 MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
1244 (void)MACIO_IN32(KEYLARGO_FCR0);
1245 udelay(1);
1246 MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
1247 (void)MACIO_IN32(KEYLARGO_FCR0);
1248 } else if (number == 4) {
1249 udelay(1);
1250 MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
1251 (void)MACIO_IN32(KEYLARGO_FCR1);
1252 }
1253 udelay(1);
1254 }
1255 UNLOCK(flags);
1256
1257 return 0;
1258}
1259
1260static long __pmac
1261core99_firewire_enable(struct device_node* node, long param, long value)
1262{
1263 unsigned long flags;
1264 struct macio_chip* macio;
1265
1266 macio = &macio_chips[0];
1267 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1268 macio->type != macio_intrepid)
1269 return -ENODEV;
1270 if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
1271 return -ENODEV;
1272
1273 LOCK(flags);
1274 if (value) {
1275 UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
1276 (void)UN_IN(UNI_N_CLOCK_CNTL);
1277 } else {
1278 UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
1279 (void)UN_IN(UNI_N_CLOCK_CNTL);
1280 }
1281 UNLOCK(flags);
1282 mdelay(1);
1283
1284 return 0;
1285}
1286
1287static long __pmac
1288core99_firewire_cable_power(struct device_node* node, long param, long value)
1289{
1290 unsigned long flags;
1291 struct macio_chip* macio;
1292
1293 /* Trick: we allow NULL node */
1294 if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
1295 return -ENODEV;
1296 macio = &macio_chips[0];
1297 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1298 macio->type != macio_intrepid)
1299 return -ENODEV;
1300 if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
1301 return -ENODEV;
1302
1303 LOCK(flags);
1304 if (value) {
1305 MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
1306 MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
1307 udelay(10);
1308 } else {
1309 MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
1310 MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
1311 }
1312 UNLOCK(flags);
1313 mdelay(1);
1314
1315 return 0;
1316}
1317
1318static long __pmac
1319intrepid_aack_delay_enable(struct device_node* node, long param, long value)
1320{
1321 unsigned long flags;
1322
1323 if (uninorth_rev < 0xd2)
1324 return -ENODEV;
1325
1326 LOCK(flags);
1327 if (param)
1328 UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
1329 else
1330 UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
1331 UNLOCK(flags);
1332
1333 return 0;
1334}
1335
1336
1337#endif /* CONFIG_POWER4 */
1338
1339static long __pmac
1340core99_read_gpio(struct device_node* node, long param, long value)
1341{
1342 struct macio_chip* macio = &macio_chips[0];
1343
1344 return MACIO_IN8(param);
1345}
1346
1347
1348static long __pmac
1349core99_write_gpio(struct device_node* node, long param, long value)
1350{
1351 struct macio_chip* macio = &macio_chips[0];
1352
1353 MACIO_OUT8(param, (u8)(value & 0xff));
1354 return 0;
1355}
1356
1357#ifdef CONFIG_POWER4
1358
1359static long __pmac
1360g5_gmac_enable(struct device_node* node, long param, long value)
1361{
1362 struct macio_chip* macio = &macio_chips[0];
1363 unsigned long flags;
1364 u8 pbus, pid;
1365
1366 LOCK(flags);
1367 if (value) {
1368 MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
1369 mb();
1370 k2_skiplist[0] = NULL;
1371 } else {
1372 k2_skiplist[0] = node;
1373 mb();
1374 MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
1375 }
1376
1377 UNLOCK(flags);
1378 mdelay(1);
1379
1380 return 0;
1381}
1382
1383static long __pmac
1384g5_fw_enable(struct device_node* node, long param, long value)
1385{
1386 struct macio_chip* macio = &macio_chips[0];
1387 unsigned long flags;
1388
1389 LOCK(flags);
1390 if (value) {
1391 MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
1392 mb();
1393 k2_skiplist[1] = NULL;
1394 } else {
1395 k2_skiplist[1] = node;
1396 mb();
1397 MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
1398 }
1399
1400 UNLOCK(flags);
1401 mdelay(1);
1402
1403 return 0;
1404}
1405
1406static long __pmac
1407g5_mpic_enable(struct device_node* node, long param, long value)
1408{
1409 unsigned long flags;
1410
1411 if (node->parent == NULL || strcmp(node->parent->name, "u3"))
1412 return 0;
1413
1414 LOCK(flags);
1415 UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
1416 UNLOCK(flags);
1417
1418 return 0;
1419}
1420
1421#ifdef CONFIG_SMP
1422static long __pmac
1423g5_reset_cpu(struct device_node* node, long param, long value)
1424{
1425 unsigned int reset_io = 0;
1426 unsigned long flags;
1427 struct macio_chip* macio;
1428 struct device_node* np;
1429
1430 macio = &macio_chips[0];
1431 if (macio->type != macio_keylargo2)
1432 return -ENODEV;
1433
1434 np = find_path_device("/cpus");
1435 if (np == NULL)
1436 return -ENODEV;
1437 for (np = np->child; np != NULL; np = np->sibling) {
1438 u32* num = (u32 *)get_property(np, "reg", NULL);
1439 u32* rst = (u32 *)get_property(np, "soft-reset", NULL);
1440 if (num == NULL || rst == NULL)
1441 continue;
1442 if (param == *num) {
1443 reset_io = *rst;
1444 break;
1445 }
1446 }
1447 if (np == NULL || reset_io == 0)
1448 return -ENODEV;
1449
1450 LOCK(flags);
1451 MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
1452 (void)MACIO_IN8(reset_io);
1453 udelay(1);
1454 MACIO_OUT8(reset_io, 0);
1455 (void)MACIO_IN8(reset_io);
1456 UNLOCK(flags);
1457
1458 return 0;
1459}
1460#endif /* CONFIG_SMP */
1461
1462/*
1463 * This can be called from pmac_smp so isn't static
1464 *
1465 * This takes the second CPU off the bus on dual CPU machines
1466 * running UP
1467 */
1468void __pmac g5_phy_disable_cpu1(void)
1469{
1470 UN_OUT(U3_API_PHY_CONFIG_1, 0);
1471}
1472
1473#endif /* CONFIG_POWER4 */
1474
1475#ifndef CONFIG_POWER4
1476
1477static void __pmac
1478keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
1479{
1480 u32 temp;
1481
1482 if (sleep_mode) {
1483 mdelay(1);
1484 MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
1485 (void)MACIO_IN32(KEYLARGO_FCR0);
1486 mdelay(1);
1487 }
1488
1489 MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1490 KL0_SCC_CELL_ENABLE |
1491 KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
1492 KL0_IRDA_CLK19_ENABLE);
1493
1494 MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
1495 MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
1496
1497 MACIO_BIC(KEYLARGO_FCR1,
1498 KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
1499 KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
1500 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1501 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1502 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
1503 KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
1504 KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
1505 KL1_UIDE_ENABLE);
1506
1507 MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
1508 MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
1509
1510 temp = MACIO_IN32(KEYLARGO_FCR3);
1511 if (macio->rev >= 2) {
1512 temp |= KL3_SHUTDOWN_PLL2X;
1513 if (sleep_mode)
1514 temp |= KL3_SHUTDOWN_PLL_TOTAL;
1515 }
1516
1517 temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
1518 KL3_SHUTDOWN_PLLKW35;
1519 if (sleep_mode)
1520 temp |= KL3_SHUTDOWN_PLLKW12;
1521 temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
1522 | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
1523 if (sleep_mode)
1524 temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
1525 MACIO_OUT32(KEYLARGO_FCR3, temp);
1526
1527 /* Flush posted writes & wait a bit */
1528 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1529}
1530
1531static void __pmac
1532pangea_shutdown(struct macio_chip* macio, int sleep_mode)
1533{
1534 u32 temp;
1535
1536 MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1537 KL0_SCC_CELL_ENABLE |
1538 KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
1539
1540 MACIO_BIC(KEYLARGO_FCR1,
1541 KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
1542 KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
1543 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1544 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1545 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
1546 KL1_UIDE_ENABLE);
1547 if (pmac_mb.board_flags & PMAC_MB_MOBILE)
1548 MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
1549
1550 MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
1551
1552 temp = MACIO_IN32(KEYLARGO_FCR3);
1553 temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
1554 KL3_SHUTDOWN_PLLKW35;
1555 temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
1556 | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
1557 if (sleep_mode)
1558 temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
1559 MACIO_OUT32(KEYLARGO_FCR3, temp);
1560
1561 /* Flush posted writes & wait a bit */
1562 (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
1563}
1564
1565static void __pmac
1566intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
1567{
1568 u32 temp;
1569
1570 MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
1571 KL0_SCC_CELL_ENABLE);
1572
1573 MACIO_BIC(KEYLARGO_FCR1,
1574 /*KL1_USB2_CELL_ENABLE |*/
1575 KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
1576 KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
1577 KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE);
1578 if (pmac_mb.board_flags & PMAC_MB_MOBILE)
1579 MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
1580
1581 temp = MACIO_IN32(KEYLARGO_FCR3);
1582 temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
1583 KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
1584 if (sleep_mode)
1585 temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
1586 MACIO_OUT32(KEYLARGO_FCR3, temp);
1587
1588 /* Flush posted writes & wait a bit */
1589 (void)MACIO_IN32(KEYLARGO_FCR0);
1590 mdelay(10);
1591}
1592
1593static int __pmac
1594core99_sleep(void)
1595{
1596 struct macio_chip* macio;
1597 int i;
1598
1599 macio = &macio_chips[0];
1600 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1601 macio->type != macio_intrepid)
1602 return -ENODEV;
1603
1604 /* The device-tree contains that in the hwclock node */
1605 if (macio->type == macio_intrepid) {
1606 UN_OUT(UNI_N_CLOCK_SPREADING, 0);
1607 mdelay(40);
1608 }
1609
1610 /* We power off the wireless slot in case it was not done
1611 * by the driver. We don't power it on automatically however
1612 */
1613 if (macio->flags & MACIO_FLAG_AIRPORT_ON)
1614 core99_airport_enable(macio->of_node, 0, 0);
1615
1616 /* We power off the FW cable. Should be done by the driver... */
1617 if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
1618 core99_firewire_enable(NULL, 0, 0);
1619 core99_firewire_cable_power(NULL, 0, 0);
1620 }
1621
1622 /* We make sure int. modem is off (in case driver lost it) */
1623 if (macio->type == macio_keylargo)
1624 core99_modem_enable(macio->of_node, 0, 0);
1625 else
1626 pangea_modem_enable(macio->of_node, 0, 0);
1627
1628 /* We make sure the sound is off as well */
1629 core99_sound_chip_enable(macio->of_node, 0, 0);
1630
1631 /*
1632 * Save various bits of KeyLargo
1633 */
1634
1635 /* Save the state of the various GPIOs */
1636 save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
1637 save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
1638 for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
1639 save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
1640 for (i=0; i<KEYLARGO_GPIO_CNT; i++)
1641 save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
1642
1643 /* Save the FCRs */
1644 if (macio->type == macio_keylargo)
1645 save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
1646 save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
1647 save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
1648 save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
1649 save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
1650 save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
1651 if (macio->type == macio_pangea || macio->type == macio_intrepid)
1652 save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
1653
1654 /* Save state & config of DBDMA channels */
1655 dbdma_save(macio, save_dbdma);
1656
1657 /*
1658 * Turn off as much as we can
1659 */
1660 if (macio->type == macio_pangea)
1661 pangea_shutdown(macio, 1);
1662 else if (macio->type == macio_intrepid)
1663 intrepid_shutdown(macio, 1);
1664 else if (macio->type == macio_keylargo)
1665 keylargo_shutdown(macio, 1);
1666
1667 /*
1668 * Put the host bridge to sleep
1669 */
1670
1671 save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
1672 /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
1673 * enabled !
1674 */
1675 UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
1676 ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
1677 udelay(100);
1678 UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
1679 UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
1680 mdelay(10);
1681
1682 /*
1683 * FIXME: A bit of black magic with OpenPIC (don't ask me why)
1684 */
1685 if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
1686 MACIO_BIS(0x506e0, 0x00400000);
1687 MACIO_BIS(0x506e0, 0x80000000);
1688 }
1689 return 0;
1690}
1691
1692static int __pmac
1693core99_wake_up(void)
1694{
1695 struct macio_chip* macio;
1696 int i;
1697
1698 macio = &macio_chips[0];
1699 if (macio->type != macio_keylargo && macio->type != macio_pangea &&
1700 macio->type != macio_intrepid)
1701 return -ENODEV;
1702
1703 /*
1704 * Wakeup the host bridge
1705 */
1706 UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
1707 udelay(10);
1708 UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
1709 udelay(10);
1710
1711 /*
1712 * Restore KeyLargo
1713 */
1714
1715 if (macio->type == macio_keylargo) {
1716 MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
1717 (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
1718 }
1719 MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
1720 (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
1721 MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
1722 (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
1723 MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
1724 (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
1725 MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
1726 (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
1727 MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
1728 (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
1729 if (macio->type == macio_pangea || macio->type == macio_intrepid) {
1730 MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
1731 (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
1732 }
1733
1734 dbdma_restore(macio, save_dbdma);
1735
1736 MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
1737 MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
1738 for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
1739 MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
1740 for (i=0; i<KEYLARGO_GPIO_CNT; i++)
1741 MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
1742
1743 /* FIXME more black magic with OpenPIC ... */
1744 if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
1745 MACIO_BIC(0x506e0, 0x00400000);
1746 MACIO_BIC(0x506e0, 0x80000000);
1747 }
1748
1749 UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
1750 udelay(100);
1751
1752 /* Restore clock spreading */
1753 if (macio->type == macio_intrepid) {
1754 UN_OUT(UNI_N_CLOCK_SPREADING, 2);
1755 mdelay(40);
1756 }
1757
1758 return 0;
1759}
1760
1761static long __pmac
1762core99_sleep_state(struct device_node* node, long param, long value)
1763{
1764 /* Param == 1 means to enter the "fake sleep" mode that is
1765 * used for CPU speed switch
1766 */
1767 if (param == 1) {
1768 if (value == 1) {
1769 UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
1770 UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
1771 } else {
1772 UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
1773 udelay(10);
1774 UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
1775 udelay(10);
1776 }
1777 return 0;
1778 }
1779 if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
1780 return -EPERM;
1781
1782#ifdef CONFIG_CPU_FREQ_PMAC
1783 /* XXX should be elsewhere */
1784 if (machine_is_compatible("PowerBook6,5") ||
1785 machine_is_compatible("PowerBook6,4") ||
1786 machine_is_compatible("PowerBook5,5") ||
1787 machine_is_compatible("PowerBook5,4")) {
1788 struct device_node *volt_gpio_np;
1789 u32 *reg = NULL;
1790
1791 volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
1792 if (volt_gpio_np != NULL)
1793 reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
1794 if (reg != NULL) {
1795 /* Set the CPU voltage high if sleeping */
1796 if (value == 1) {
1797 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
1798 *reg, 0x05);
1799 } else if (value == 0 && (mfspr(SPRN_HID1) & HID1_DFS)) {
1800 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL,
1801 *reg, 0x04);
1802 }
1803 mdelay(2);
1804 }
1805 }
1806#endif /* CONFIG_CPU_FREQ_PMAC */
1807
1808 if (value == 1)
1809 return core99_sleep();
1810 else if (value == 0)
1811 return core99_wake_up();
1812 return 0;
1813}
1814
1815#endif /* CONFIG_POWER4 */
1816
1817static long __pmac
1818generic_dev_can_wake(struct device_node* node, long param, long value)
1819{
1820 /* Todo: eventually check we are really dealing with on-board
1821 * video device ...
1822 */
1823
1824 if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
1825 pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
1826 return 0;
1827}
1828
1829static long __pmac
1830generic_get_mb_info(struct device_node* node, long param, long value)
1831{
1832 switch(param) {
1833 case PMAC_MB_INFO_MODEL:
1834 return pmac_mb.model_id;
1835 case PMAC_MB_INFO_FLAGS:
1836 return pmac_mb.board_flags;
1837 case PMAC_MB_INFO_NAME:
1838 /* hack hack hack... but should work */
1839 *((const char **)value) = pmac_mb.model_name;
1840 return 0;
1841 }
1842 return -EINVAL;
1843}
1844
1845
1846/*
1847 * Table definitions
1848 */
1849
1850/* Used on any machine
1851 */
1852static struct feature_table_entry any_features[] __pmacdata = {
1853 { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
1854 { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
1855 { 0, NULL }
1856};
1857
1858#ifndef CONFIG_POWER4
1859
1860/* OHare based motherboards. Currently, we only use these on the
1861 * 2400,3400 and 3500 series powerbooks. Some older desktops seem
1862 * to have issues with turning on/off those asic cells
1863 */
1864static struct feature_table_entry ohare_features[] __pmacdata = {
1865 { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
1866 { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
1867 { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
1868 { PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
1869 { PMAC_FTR_IDE_RESET, ohare_ide_reset},
1870 { PMAC_FTR_SLEEP_STATE, ohare_sleep_state },
1871 { 0, NULL }
1872};
1873
1874/* Heathrow desktop machines (Beige G3).
1875 * Separated as some features couldn't be properly tested
1876 * and the serial port control bits appear to confuse it.
1877 */
1878static struct feature_table_entry heathrow_desktop_features[] __pmacdata = {
1879 { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
1880 { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
1881 { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
1882 { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
1883 { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
1884 { 0, NULL }
1885};
1886
1887/* Heathrow based laptop, that is the Wallstreet and mainstreet
1888 * powerbooks.
1889 */
1890static struct feature_table_entry heathrow_laptop_features[] __pmacdata = {
1891 { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
1892 { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
1893 { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
1894 { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
1895 { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
1896 { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
1897 { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
1898 { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
1899 { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
1900 { 0, NULL }
1901};
1902
1903/* Paddington based machines
1904 * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
1905 */
1906static struct feature_table_entry paddington_features[] __pmacdata = {
1907 { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
1908 { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
1909 { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
1910 { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
1911 { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
1912 { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
1913 { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
1914 { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
1915 { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
1916 { 0, NULL }
1917};
1918
1919/* Core99 & MacRISC 2 machines (all machines released since the
1920 * iBook (included), that is all AGP machines, except pangea
1921 * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
1922 * used on iBook2 & iMac "flow power".
1923 */
1924static struct feature_table_entry core99_features[] __pmacdata = {
1925 { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
1926 { PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
1927 { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
1928 { PMAC_FTR_IDE_RESET, core99_ide_reset },
1929 { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
1930 { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
1931 { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
1932 { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
1933 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
1934 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
1935 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1936 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
1937#ifdef CONFIG_SMP
1938 { PMAC_FTR_RESET_CPU, core99_reset_cpu },
1939#endif /* CONFIG_SMP */
1940 { PMAC_FTR_READ_GPIO, core99_read_gpio },
1941 { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
1942 { 0, NULL }
1943};
1944
1945/* RackMac
1946 */
1947static struct feature_table_entry rackmac_features[] __pmacdata = {
1948 { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
1949 { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
1950 { PMAC_FTR_IDE_RESET, core99_ide_reset },
1951 { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
1952 { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
1953 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
1954 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
1955 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1956 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
1957#ifdef CONFIG_SMP
1958 { PMAC_FTR_RESET_CPU, core99_reset_cpu },
1959#endif /* CONFIG_SMP */
1960 { PMAC_FTR_READ_GPIO, core99_read_gpio },
1961 { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
1962 { 0, NULL }
1963};
1964
1965/* Pangea features
1966 */
1967static struct feature_table_entry pangea_features[] __pmacdata = {
1968 { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
1969 { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
1970 { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
1971 { PMAC_FTR_IDE_RESET, core99_ide_reset },
1972 { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
1973 { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
1974 { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
1975 { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
1976 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
1977 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
1978 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1979 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
1980 { PMAC_FTR_READ_GPIO, core99_read_gpio },
1981 { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
1982 { 0, NULL }
1983};
1984
1985/* Intrepid features
1986 */
1987static struct feature_table_entry intrepid_features[] __pmacdata = {
1988 { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
1989 { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
1990 { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
1991 { PMAC_FTR_IDE_RESET, core99_ide_reset },
1992 { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
1993 { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
1994 { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
1995 { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
1996 { PMAC_FTR_USB_ENABLE, core99_usb_enable },
1997 { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
1998 { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
1999 { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
2000 { PMAC_FTR_READ_GPIO, core99_read_gpio },
2001 { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
2002 { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
2003 { 0, NULL }
2004};
2005
2006#else /* CONFIG_POWER4 */
2007
2008/* G5 features
2009 */
2010static struct feature_table_entry g5_features[] __pmacdata = {
2011 { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
2012 { PMAC_FTR_1394_ENABLE, g5_fw_enable },
2013 { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
2014#ifdef CONFIG_SMP
2015 { PMAC_FTR_RESET_CPU, g5_reset_cpu },
2016#endif /* CONFIG_SMP */
2017 { PMAC_FTR_READ_GPIO, core99_read_gpio },
2018 { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
2019 { 0, NULL }
2020};
2021
2022#endif /* CONFIG_POWER4 */
2023
2024static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
2025#ifndef CONFIG_POWER4
2026 /*
2027 * Desktops
2028 */
2029
2030 { "AAPL,8500", "PowerMac 8500/8600",
2031 PMAC_TYPE_PSURGE, NULL,
2032 0
2033 },
2034 { "AAPL,9500", "PowerMac 9500/9600",
2035 PMAC_TYPE_PSURGE, NULL,
2036 0
2037 },
2038 { "AAPL,7200", "PowerMac 7200",
2039 PMAC_TYPE_PSURGE, NULL,
2040 0
2041 },
2042 { "AAPL,7300", "PowerMac 7200/7300",
2043 PMAC_TYPE_PSURGE, NULL,
2044 0
2045 },
2046 { "AAPL,7500", "PowerMac 7500",
2047 PMAC_TYPE_PSURGE, NULL,
2048 0
2049 },
2050 { "AAPL,ShinerESB", "Apple Network Server",
2051 PMAC_TYPE_ANS, NULL,
2052 0
2053 },
2054 { "AAPL,e407", "Alchemy",
2055 PMAC_TYPE_ALCHEMY, NULL,
2056 0
2057 },
2058 { "AAPL,e411", "Gazelle",
2059 PMAC_TYPE_GAZELLE, NULL,
2060 0
2061 },
2062 { "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
2063 PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
2064 0
2065 },
2066 { "AAPL,PowerMac G3", "PowerMac G3 (Silk)",
2067 PMAC_TYPE_SILK, heathrow_desktop_features,
2068 0
2069 },
2070 { "PowerMac1,1", "Blue&White G3",
2071 PMAC_TYPE_YOSEMITE, paddington_features,
2072 0
2073 },
2074 { "PowerMac1,2", "PowerMac G4 PCI Graphics",
2075 PMAC_TYPE_YIKES, paddington_features,
2076 0
2077 },
2078 { "PowerMac2,1", "iMac FireWire",
2079 PMAC_TYPE_FW_IMAC, core99_features,
2080 PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
2081 },
2082 { "PowerMac2,2", "iMac FireWire",
2083 PMAC_TYPE_FW_IMAC, core99_features,
2084 PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
2085 },
2086 { "PowerMac3,1", "PowerMac G4 AGP Graphics",
2087 PMAC_TYPE_SAWTOOTH, core99_features,
2088 PMAC_MB_OLD_CORE99
2089 },
2090 { "PowerMac3,2", "PowerMac G4 AGP Graphics",
2091 PMAC_TYPE_SAWTOOTH, core99_features,
2092 PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
2093 },
2094 { "PowerMac3,3", "PowerMac G4 AGP Graphics",
2095 PMAC_TYPE_SAWTOOTH, core99_features,
2096 PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
2097 },
2098 { "PowerMac3,4", "PowerMac G4 Silver",
2099 PMAC_TYPE_QUICKSILVER, core99_features,
2100 PMAC_MB_MAY_SLEEP
2101 },
2102 { "PowerMac3,5", "PowerMac G4 Silver",
2103 PMAC_TYPE_QUICKSILVER, core99_features,
2104 PMAC_MB_MAY_SLEEP
2105 },
2106 { "PowerMac3,6", "PowerMac G4 Windtunnel",
2107 PMAC_TYPE_WINDTUNNEL, core99_features,
2108 PMAC_MB_MAY_SLEEP,
2109 },
2110 { "PowerMac4,1", "iMac \"Flower Power\"",
2111 PMAC_TYPE_PANGEA_IMAC, pangea_features,
2112 PMAC_MB_MAY_SLEEP
2113 },
2114 { "PowerMac4,2", "Flat panel iMac",
2115 PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features,
2116 PMAC_MB_CAN_SLEEP
2117 },
2118 { "PowerMac4,4", "eMac",
2119 PMAC_TYPE_EMAC, core99_features,
2120 PMAC_MB_MAY_SLEEP
2121 },
2122 { "PowerMac5,1", "PowerMac G4 Cube",
2123 PMAC_TYPE_CUBE, core99_features,
2124 PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
2125 },
2126 { "PowerMac6,1", "Flat panel iMac",
2127 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2128 PMAC_MB_MAY_SLEEP,
2129 },
2130 { "PowerMac6,3", "Flat panel iMac",
2131 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2132 PMAC_MB_MAY_SLEEP,
2133 },
2134 { "PowerMac6,4", "eMac",
2135 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2136 PMAC_MB_MAY_SLEEP,
2137 },
2138 { "PowerMac10,1", "Mac mini",
2139 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2140 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER,
2141 },
2142 { "iMac,1", "iMac (first generation)",
2143 PMAC_TYPE_ORIG_IMAC, paddington_features,
2144 0
2145 },
2146
2147 /*
2148 * Xserve's
2149 */
2150
2151 { "RackMac1,1", "XServe",
2152 PMAC_TYPE_RACKMAC, rackmac_features,
2153 0,
2154 },
2155 { "RackMac1,2", "XServe rev. 2",
2156 PMAC_TYPE_RACKMAC, rackmac_features,
2157 0,
2158 },
2159
2160 /*
2161 * Laptops
2162 */
2163
2164 { "AAPL,3400/2400", "PowerBook 3400",
2165 PMAC_TYPE_HOOPER, ohare_features,
2166 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
2167 },
2168 { "AAPL,3500", "PowerBook 3500",
2169 PMAC_TYPE_KANGA, ohare_features,
2170 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
2171 },
2172 { "AAPL,PowerBook1998", "PowerBook Wallstreet",
2173 PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
2174 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
2175 },
2176 { "PowerBook1,1", "PowerBook 101 (Lombard)",
2177 PMAC_TYPE_101_PBOOK, paddington_features,
2178 PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE
2179 },
2180 { "PowerBook2,1", "iBook (first generation)",
2181 PMAC_TYPE_ORIG_IBOOK, core99_features,
2182 PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
2183 },
2184 { "PowerBook2,2", "iBook FireWire",
2185 PMAC_TYPE_FW_IBOOK, core99_features,
2186 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
2187 PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
2188 },
2189 { "PowerBook3,1", "PowerBook Pismo",
2190 PMAC_TYPE_PISMO, core99_features,
2191 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
2192 PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
2193 },
2194 { "PowerBook3,2", "PowerBook Titanium",
2195 PMAC_TYPE_TITANIUM, core99_features,
2196 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2197 },
2198 { "PowerBook3,3", "PowerBook Titanium II",
2199 PMAC_TYPE_TITANIUM2, core99_features,
2200 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2201 },
2202 { "PowerBook3,4", "PowerBook Titanium III",
2203 PMAC_TYPE_TITANIUM3, core99_features,
2204 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2205 },
2206 { "PowerBook3,5", "PowerBook Titanium IV",
2207 PMAC_TYPE_TITANIUM4, core99_features,
2208 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2209 },
2210 { "PowerBook4,1", "iBook 2",
2211 PMAC_TYPE_IBOOK2, pangea_features,
2212 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2213 },
2214 { "PowerBook4,2", "iBook 2",
2215 PMAC_TYPE_IBOOK2, pangea_features,
2216 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2217 },
2218 { "PowerBook4,3", "iBook 2 rev. 2",
2219 PMAC_TYPE_IBOOK2, pangea_features,
2220 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
2221 },
2222 { "PowerBook5,1", "PowerBook G4 17\"",
2223 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2224 PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2225 },
2226 { "PowerBook5,2", "PowerBook G4 15\"",
2227 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2228 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2229 },
2230 { "PowerBook5,3", "PowerBook G4 17\"",
2231 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2232 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2233 },
2234 { "PowerBook5,4", "PowerBook G4 15\"",
2235 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2236 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2237 },
2238 { "PowerBook5,5", "PowerBook G4 17\"",
2239 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2240 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2241 },
2242 { "PowerBook5,6", "PowerBook G4 15\"",
2243 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2244 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2245 },
2246 { "PowerBook5,7", "PowerBook G4 17\"",
2247 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2248 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2249 },
2250 { "PowerBook6,1", "PowerBook G4 12\"",
2251 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2252 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2253 },
2254 { "PowerBook6,2", "PowerBook G4",
2255 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2256 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2257 },
2258 { "PowerBook6,3", "iBook G4",
2259 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2260 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2261 },
2262 { "PowerBook6,4", "PowerBook G4 12\"",
2263 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2264 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2265 },
2266 { "PowerBook6,5", "iBook G4",
2267 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2268 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2269 },
2270 { "PowerBook6,8", "PowerBook G4 12\"",
2271 PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
2272 PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
2273 },
2274#else /* CONFIG_POWER4 */
2275 { "PowerMac7,2", "PowerMac G5",
2276 PMAC_TYPE_POWERMAC_G5, g5_features,
2277 0,
2278 },
2279#endif /* CONFIG_POWER4 */
2280};
2281
2282/*
2283 * The toplevel feature_call callback
2284 */
2285long __pmac
2286pmac_do_feature_call(unsigned int selector, ...)
2287{
2288 struct device_node* node;
2289 long param, value;
2290 int i;
2291 feature_call func = NULL;
2292 va_list args;
2293
2294 if (pmac_mb.features)
2295 for (i=0; pmac_mb.features[i].function; i++)
2296 if (pmac_mb.features[i].selector == selector) {
2297 func = pmac_mb.features[i].function;
2298 break;
2299 }
2300 if (!func)
2301 for (i=0; any_features[i].function; i++)
2302 if (any_features[i].selector == selector) {
2303 func = any_features[i].function;
2304 break;
2305 }
2306 if (!func)
2307 return -ENODEV;
2308
2309 va_start(args, selector);
2310 node = (struct device_node*)va_arg(args, void*);
2311 param = va_arg(args, long);
2312 value = va_arg(args, long);
2313 va_end(args);
2314
2315 return func(node, param, value);
2316}
2317
2318static int __init
2319probe_motherboard(void)
2320{
2321 int i;
2322 struct macio_chip* macio = &macio_chips[0];
2323 const char* model = NULL;
2324 struct device_node *dt;
2325
2326 /* Lookup known motherboard type in device-tree. First try an
2327 * exact match on the "model" property, then try a "compatible"
2328 * match is none is found.
2329 */
2330 dt = find_devices("device-tree");
2331 if (dt != NULL)
2332 model = (const char *) get_property(dt, "model", NULL);
2333 for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
2334 if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
2335 pmac_mb = pmac_mb_defs[i];
2336 goto found;
2337 }
2338 }
2339 for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
2340 if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
2341 pmac_mb = pmac_mb_defs[i];
2342 goto found;
2343 }
2344 }
2345
2346 /* Fallback to selection depending on mac-io chip type */
2347 switch(macio->type) {
2348#ifndef CONFIG_POWER4
2349 case macio_grand_central:
2350 pmac_mb.model_id = PMAC_TYPE_PSURGE;
2351 pmac_mb.model_name = "Unknown PowerSurge";
2352 break;
2353 case macio_ohare:
2354 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
2355 pmac_mb.model_name = "Unknown OHare-based";
2356 break;
2357 case macio_heathrow:
2358 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
2359 pmac_mb.model_name = "Unknown Heathrow-based";
2360 pmac_mb.features = heathrow_desktop_features;
2361 break;
2362 case macio_paddington:
2363 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
2364 pmac_mb.model_name = "Unknown Paddington-based";
2365 pmac_mb.features = paddington_features;
2366 break;
2367 case macio_keylargo:
2368 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
2369 pmac_mb.model_name = "Unknown Keylargo-based";
2370 pmac_mb.features = core99_features;
2371 break;
2372 case macio_pangea:
2373 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
2374 pmac_mb.model_name = "Unknown Pangea-based";
2375 pmac_mb.features = pangea_features;
2376 break;
2377 case macio_intrepid:
2378 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
2379 pmac_mb.model_name = "Unknown Intrepid-based";
2380 pmac_mb.features = intrepid_features;
2381 break;
2382#else /* CONFIG_POWER4 */
2383 case macio_keylargo2:
2384 pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
2385 pmac_mb.model_name = "Unknown G5";
2386 pmac_mb.features = g5_features;
2387 break;
2388#endif /* CONFIG_POWER4 */
2389 default:
2390 return -ENODEV;
2391 }
2392found:
2393#ifndef CONFIG_POWER4
2394 /* Fixup Hooper vs. Comet */
2395 if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
2396 u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
2397 if (!mach_id_ptr)
2398 return -ENODEV;
2399 /* Here, I used to disable the media-bay on comet. It
2400 * appears this is wrong, the floppy connector is actually
2401 * a kind of media-bay and works with the current driver.
2402 */
2403 if (__raw_readl(mach_id_ptr) & 0x20000000UL)
2404 pmac_mb.model_id = PMAC_TYPE_COMET;
2405 iounmap(mach_id_ptr);
2406 }
2407#endif /* CONFIG_POWER4 */
2408
2409#ifdef CONFIG_6xx
2410 /* Set default value of powersave_nap on machines that support it.
2411 * It appears that uninorth rev 3 has a problem with it, we don't
2412 * enable it on those. In theory, the flush-on-lock property is
2413 * supposed to be set when not supported, but I'm not very confident
2414 * that all Apple OF revs did it properly, I do it the paranoid way.
2415 */
2416 while (uninorth_base && uninorth_rev > 3) {
2417 struct device_node* np = find_path_device("/cpus");
2418 if (!np || !np->child) {
2419 printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
2420 break;
2421 }
2422 np = np->child;
2423 /* Nap mode not supported on SMP */
2424 if (np->sibling)
2425 break;
2426 /* Nap mode not supported if flush-on-lock property is present */
2427 if (get_property(np, "flush-on-lock", NULL))
2428 break;
2429 powersave_nap = 1;
2430 printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
2431 break;
2432 }
2433
2434 /* On CPUs that support it (750FX), lowspeed by default during
2435 * NAP mode
2436 */
2437 powersave_lowspeed = 1;
2438#endif /* CONFIG_6xx */
2439#ifdef CONFIG_POWER4
2440 powersave_nap = 1;
2441#endif
2442 /* Check for "mobile" machine */
2443 if (model && (strncmp(model, "PowerBook", 9) == 0
2444 || strncmp(model, "iBook", 5) == 0))
2445 pmac_mb.board_flags |= PMAC_MB_MOBILE;
2446
2447
2448 printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
2449 return 0;
2450}
2451
2452/* Initialize the Core99 UniNorth host bridge and memory controller
2453 */
2454static void __init
2455probe_uninorth(void)
2456{
2457 unsigned long actrl;
2458
2459 /* Locate core99 Uni-N */
2460 uninorth_node = of_find_node_by_name(NULL, "uni-n");
2461 /* Locate G5 u3 */
2462 if (uninorth_node == NULL) {
2463 uninorth_node = of_find_node_by_name(NULL, "u3");
2464 uninorth_u3 = 1;
2465 }
2466 if (uninorth_node && uninorth_node->n_addrs > 0) {
2467 unsigned long address = uninorth_node->addrs[0].address;
2468 uninorth_base = ioremap(address, 0x40000);
2469 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2470 if (uninorth_u3)
2471 u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
2472 } else
2473 uninorth_node = NULL;
2474
2475 if (!uninorth_node)
2476 return;
2477
2478 printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
2479 uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
2480 printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
2481
2482 /* Set the arbitrer QAck delay according to what Apple does
2483 */
2484 if (uninorth_rev < 0x11) {
2485 actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
2486 actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
2487 UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
2488 UN_OUT(UNI_N_ARB_CTRL, actrl);
2489 }
2490
2491 /* Some more magic as done by them in recent MacOS X on UniNorth
2492 * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
2493 * memory timeout
2494 */
2495 if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
2496 UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
2497}
2498
2499static void __init
2500probe_one_macio(const char* name, const char* compat, int type)
2501{
2502 struct device_node* node;
2503 int i;
2504 volatile u32 __iomem * base;
2505 u32* revp;
2506
2507 node = find_devices(name);
2508 if (!node || !node->n_addrs)
2509 return;
2510 if (compat)
2511 do {
2512 if (device_is_compatible(node, compat))
2513 break;
2514 node = node->next;
2515 } while (node);
2516 if (!node)
2517 return;
2518 for(i=0; i<MAX_MACIO_CHIPS; i++) {
2519 if (!macio_chips[i].of_node)
2520 break;
2521 if (macio_chips[i].of_node == node)
2522 return;
2523 }
2524 if (i >= MAX_MACIO_CHIPS) {
2525 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
2526 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
2527 return;
2528 }
2529 base = ioremap(node->addrs[0].address, node->addrs[0].size);
2530 if (!base) {
2531 printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
2532 return;
2533 }
2534 if (type == macio_keylargo) {
2535 u32* did = (u32 *)get_property(node, "device-id", NULL);
2536 if (*did == 0x00000025)
2537 type = macio_pangea;
2538 if (*did == 0x0000003e)
2539 type = macio_intrepid;
2540 }
2541 macio_chips[i].of_node = node;
2542 macio_chips[i].type = type;
2543 macio_chips[i].base = base;
2544 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
2545 macio_chips[i].name = macio_names[type];
2546 revp = (u32 *)get_property(node, "revision-id", NULL);
2547 if (revp)
2548 macio_chips[i].rev = *revp;
2549 printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
2550 macio_names[type], macio_chips[i].rev, macio_chips[i].base);
2551}
2552
2553static int __init
2554probe_macios(void)
2555{
2556 /* Warning, ordering is important */
2557 probe_one_macio("gc", NULL, macio_grand_central);
2558 probe_one_macio("ohare", NULL, macio_ohare);
2559 probe_one_macio("pci106b,7", NULL, macio_ohareII);
2560 probe_one_macio("mac-io", "keylargo", macio_keylargo);
2561 probe_one_macio("mac-io", "paddington", macio_paddington);
2562 probe_one_macio("mac-io", "gatwick", macio_gatwick);
2563 probe_one_macio("mac-io", "heathrow", macio_heathrow);
2564 probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
2565
2566 /* Make sure the "main" macio chip appear first */
2567 if (macio_chips[0].type == macio_gatwick
2568 && macio_chips[1].type == macio_heathrow) {
2569 struct macio_chip temp = macio_chips[0];
2570 macio_chips[0] = macio_chips[1];
2571 macio_chips[1] = temp;
2572 }
2573 if (macio_chips[0].type == macio_ohareII
2574 && macio_chips[1].type == macio_ohare) {
2575 struct macio_chip temp = macio_chips[0];
2576 macio_chips[0] = macio_chips[1];
2577 macio_chips[1] = temp;
2578 }
2579 macio_chips[0].lbus.index = 0;
2580 macio_chips[1].lbus.index = 1;
2581
2582 return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
2583}
2584
2585static void __init
2586initial_serial_shutdown(struct device_node* np)
2587{
2588 int len;
2589 struct slot_names_prop {
2590 int count;
2591 char name[1];
2592 } *slots;
2593 char *conn;
2594 int port_type = PMAC_SCC_ASYNC;
2595 int modem = 0;
2596
2597 slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
2598 conn = get_property(np, "AAPL,connector", &len);
2599 if (conn && (strcmp(conn, "infrared") == 0))
2600 port_type = PMAC_SCC_IRDA;
2601 else if (device_is_compatible(np, "cobalt"))
2602 modem = 1;
2603 else if (slots && slots->count > 0) {
2604 if (strcmp(slots->name, "IrDA") == 0)
2605 port_type = PMAC_SCC_IRDA;
2606 else if (strcmp(slots->name, "Modem") == 0)
2607 modem = 1;
2608 }
2609 if (modem)
2610 pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
2611 pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
2612}
2613
2614static void __init
2615set_initial_features(void)
2616{
2617 struct device_node* np;
2618
2619 /* That hack appears to be necessary for some StarMax motherboards
2620 * but I'm not too sure it was audited for side-effects on other
2621 * ohare based machines...
2622 * Since I still have difficulties figuring the right way to
2623 * differenciate them all and since that hack was there for a long
2624 * time, I'll keep it around
2625 */
2626 if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) {
2627 struct macio_chip* macio = &macio_chips[0];
2628 MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
2629 } else if (macio_chips[0].type == macio_ohare) {
2630 struct macio_chip* macio = &macio_chips[0];
2631 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
2632 } else if (macio_chips[1].type == macio_ohare) {
2633 struct macio_chip* macio = &macio_chips[1];
2634 MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
2635 }
2636
2637#ifdef CONFIG_POWER4
2638 if (macio_chips[0].type == macio_keylargo2) {
2639#ifndef CONFIG_SMP
2640 /* On SMP machines running UP, we have the second CPU eating
2641 * bus cycles. We need to take it off the bus. This is done
2642 * from pmac_smp for SMP kernels running on one CPU
2643 */
2644 np = of_find_node_by_type(NULL, "cpu");
2645 if (np != NULL)
2646 np = of_find_node_by_type(np, "cpu");
2647 if (np != NULL) {
2648 g5_phy_disable_cpu1();
2649 of_node_put(np);
2650 }
2651#endif /* CONFIG_SMP */
2652 /* Enable GMAC for now for PCI probing. It will be disabled
2653 * later on after PCI probe
2654 */
2655 np = of_find_node_by_name(NULL, "ethernet");
2656 while(np) {
2657 if (device_is_compatible(np, "K2-GMAC"))
2658 g5_gmac_enable(np, 0, 1);
2659 np = of_find_node_by_name(np, "ethernet");
2660 }
2661
2662 /* Enable FW before PCI probe. Will be disabled later on
2663 * Note: We should have a batter way to check that we are
2664 * dealing with uninorth internal cell and not a PCI cell
2665 * on the external PCI. The code below works though.
2666 */
2667 np = of_find_node_by_name(NULL, "firewire");
2668 while(np) {
2669 if (device_is_compatible(np, "pci106b,5811")) {
2670 macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
2671 g5_fw_enable(np, 0, 1);
2672 }
2673 np = of_find_node_by_name(np, "firewire");
2674 }
2675 }
2676#else /* CONFIG_POWER4 */
2677
2678 if (macio_chips[0].type == macio_keylargo ||
2679 macio_chips[0].type == macio_pangea ||
2680 macio_chips[0].type == macio_intrepid) {
2681 /* Enable GMAC for now for PCI probing. It will be disabled
2682 * later on after PCI probe
2683 */
2684 np = of_find_node_by_name(NULL, "ethernet");
2685 while(np) {
2686 if (np->parent
2687 && device_is_compatible(np->parent, "uni-north")
2688 && device_is_compatible(np, "gmac"))
2689 core99_gmac_enable(np, 0, 1);
2690 np = of_find_node_by_name(np, "ethernet");
2691 }
2692
2693 /* Enable FW before PCI probe. Will be disabled later on
2694 * Note: We should have a batter way to check that we are
2695 * dealing with uninorth internal cell and not a PCI cell
2696 * on the external PCI. The code below works though.
2697 */
2698 np = of_find_node_by_name(NULL, "firewire");
2699 while(np) {
2700 if (np->parent
2701 && device_is_compatible(np->parent, "uni-north")
2702 && (device_is_compatible(np, "pci106b,18") ||
2703 device_is_compatible(np, "pci106b,30") ||
2704 device_is_compatible(np, "pci11c1,5811"))) {
2705 macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
2706 core99_firewire_enable(np, 0, 1);
2707 }
2708 np = of_find_node_by_name(np, "firewire");
2709 }
2710
2711 /* Enable ATA-100 before PCI probe. */
2712 np = of_find_node_by_name(NULL, "ata-6");
2713 while(np) {
2714 if (np->parent
2715 && device_is_compatible(np->parent, "uni-north")
2716 && device_is_compatible(np, "kauai-ata")) {
2717 core99_ata100_enable(np, 1);
2718 }
2719 np = of_find_node_by_name(np, "ata-6");
2720 }
2721
2722 /* Switch airport off */
2723 np = find_devices("radio");
2724 while(np) {
2725 if (np && np->parent == macio_chips[0].of_node) {
2726 macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
2727 core99_airport_enable(np, 0, 0);
2728 }
2729 np = np->next;
2730 }
2731 }
2732
2733 /* On all machines that support sound PM, switch sound off */
2734 if (macio_chips[0].of_node)
2735 pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
2736 macio_chips[0].of_node, 0, 0);
2737
2738 /* While on some desktop G3s, we turn it back on */
2739 if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
2740 && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
2741 pmac_mb.model_id == PMAC_TYPE_SILK)) {
2742 struct macio_chip* macio = &macio_chips[0];
2743 MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
2744 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
2745 }
2746
2747 /* Hack for bumping clock speed on the new PowerBooks and the
2748 * iBook G4. This implements the "platform-do-clockspreading" OF
2749 * property. For safety, we also check the product ID in the
2750 * device-tree to make reasonably sure we won't set wrong values
2751 * in the clock chip.
2752 *
2753 * Of course, ultimately, we have to implement a real parser for
2754 * the platform-do-* stuff...
2755 */
2756 while (machine_is_compatible("PowerBook5,2") ||
2757 machine_is_compatible("PowerBook5,3") ||
2758 machine_is_compatible("PowerBook6,2") ||
2759 machine_is_compatible("PowerBook6,3")) {
2760 struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
2761 struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
2762 u8 buffer[9];
2763 u32 *productID;
2764 int i, rc, changed = 0;
2765
2766 if (dt == NULL)
2767 break;
2768 productID = (u32 *)get_property(dt, "pid#", NULL);
2769 if (productID == NULL)
2770 break;
2771 while(ui2c) {
2772 struct device_node *p = of_get_parent(ui2c);
2773 if (p && !strcmp(p->name, "uni-n"))
2774 break;
2775 ui2c = of_find_node_by_type(ui2c, "i2c");
2776 }
2777 if (ui2c == NULL)
2778 break;
2779 DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
2780 rc = pmac_low_i2c_open(ui2c, 1);
2781 if (rc != 0)
2782 break;
2783 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
2784 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
2785 DBG("read result: %d,", rc);
2786 if (rc != 0) {
2787 pmac_low_i2c_close(ui2c);
2788 break;
2789 }
2790 for (i=0; i<9; i++)
2791 DBG(" %02x", buffer[i]);
2792 DBG("\n");
2793
2794 switch(*productID) {
2795 case 0x1182: /* AlBook 12" rev 2 */
2796 case 0x1183: /* iBook G4 12" */
2797 buffer[0] = (buffer[0] & 0x8f) | 0x70;
2798 buffer[2] = (buffer[2] & 0x7f) | 0x00;
2799 buffer[5] = (buffer[5] & 0x80) | 0x31;
2800 buffer[6] = (buffer[6] & 0x40) | 0xb0;
2801 buffer[7] = (buffer[7] & 0x00) | 0xc0;
2802 buffer[8] = (buffer[8] & 0x00) | 0x30;
2803 changed = 1;
2804 break;
2805 case 0x3142: /* AlBook 15" (ATI M10) */
2806 case 0x3143: /* AlBook 17" (ATI M10) */
2807 buffer[0] = (buffer[0] & 0xaf) | 0x50;
2808 buffer[2] = (buffer[2] & 0x7f) | 0x00;
2809 buffer[5] = (buffer[5] & 0x80) | 0x31;
2810 buffer[6] = (buffer[6] & 0x40) | 0xb0;
2811 buffer[7] = (buffer[7] & 0x00) | 0xd0;
2812 buffer[8] = (buffer[8] & 0x00) | 0x30;
2813 changed = 1;
2814 break;
2815 default:
2816 DBG("i2c-hwclock: Machine model not handled\n");
2817 break;
2818 }
2819 if (!changed) {
2820 pmac_low_i2c_close(ui2c);
2821 break;
2822 }
2823 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
2824 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
2825 DBG("write result: %d,", rc);
2826 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
2827 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
2828 DBG("read result: %d,", rc);
2829 if (rc != 0) {
2830 pmac_low_i2c_close(ui2c);
2831 break;
2832 }
2833 for (i=0; i<9; i++)
2834 DBG(" %02x", buffer[i]);
2835 pmac_low_i2c_close(ui2c);
2836 break;
2837 }
2838
2839#endif /* CONFIG_POWER4 */
2840
2841 /* On all machines, switch modem & serial ports off */
2842 np = find_devices("ch-a");
2843 while(np) {
2844 initial_serial_shutdown(np);
2845 np = np->next;
2846 }
2847 np = find_devices("ch-b");
2848 while(np) {
2849 initial_serial_shutdown(np);
2850 np = np->next;
2851 }
2852}
2853
2854void __init
2855pmac_feature_init(void)
2856{
2857 /* Detect the UniNorth memory controller */
2858 probe_uninorth();
2859
2860 /* Probe mac-io controllers */
2861 if (probe_macios()) {
2862 printk(KERN_WARNING "No mac-io chip found\n");
2863 return;
2864 }
2865
2866 /* Setup low-level i2c stuffs */
2867 pmac_init_low_i2c();
2868
2869 /* Probe machine type */
2870 if (probe_motherboard())
2871 printk(KERN_WARNING "Unknown PowerMac !\n");
2872
2873 /* Set some initial features (turn off some chips that will
2874 * be later turned on)
2875 */
2876 set_initial_features();
2877}
2878
2879int __init
2880pmac_feature_late_init(void)
2881{
2882 struct device_node* np;
2883
2884 /* Request some resources late */
2885 if (uninorth_node)
2886 request_OF_resource(uninorth_node, 0, NULL);
2887 np = find_devices("hammerhead");
2888 if (np)
2889 request_OF_resource(np, 0, NULL);
2890 np = find_devices("interrupt-controller");
2891 if (np)
2892 request_OF_resource(np, 0, NULL);
2893 return 0;
2894}
2895
2896device_initcall(pmac_feature_late_init);
2897
2898#ifdef CONFIG_POWER4
2899
2900static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
2901{
2902 int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
2903 int bits[8] = { 8,16,0,32,2,4,0,0 };
2904 int freq = (frq >> 8) & 0xf;
2905
2906 if (freqs[freq] == 0)
2907 printk("%s: Unknown HT link frequency %x\n", name, freq);
2908 else
2909 printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
2910 name, freqs[freq],
2911 bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
2912}
2913
2914void __init pmac_check_ht_link(void)
2915{
2916 u32 ufreq, freq, ucfg, cfg;
2917 struct device_node *pcix_node;
2918 u8 px_bus, px_devfn;
2919 struct pci_controller *px_hose;
2920
2921 (void)in_be32(u3_ht + U3_HT_LINK_COMMAND);
2922 ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG);
2923 ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ);
2924 dump_HT_speeds("U3 HyperTransport", cfg, freq);
2925
2926 pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
2927 if (pcix_node == NULL) {
2928 printk("No PCI-X bridge found\n");
2929 return;
2930 }
2931 if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
2932 printk("PCI-X bridge found but not matched to pci\n");
2933 return;
2934 }
2935 px_hose = pci_find_hose_for_OF_device(pcix_node);
2936 if (px_hose == NULL) {
2937 printk("PCI-X bridge found but not matched to host\n");
2938 return;
2939 }
2940 early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
2941 early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
2942 dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
2943 early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
2944 early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
2945 dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
2946}
2947
2948#endif /* CONFIG_POWER4 */
2949
2950/*
2951 * Early video resume hook
2952 */
2953
2954static void (*pmac_early_vresume_proc)(void *data) __pmacdata;
2955static void *pmac_early_vresume_data __pmacdata;
2956
2957void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
2958{
2959 if (_machine != _MACH_Pmac)
2960 return;
2961 preempt_disable();
2962 pmac_early_vresume_proc = proc;
2963 pmac_early_vresume_data = data;
2964 preempt_enable();
2965}
2966EXPORT_SYMBOL(pmac_set_early_video_resume);
2967
2968void __pmac pmac_call_early_video_resume(void)
2969{
2970 if (pmac_early_vresume_proc)
2971 pmac_early_vresume_proc(pmac_early_vresume_data);
2972}
diff --git a/arch/ppc/platforms/pmac_low_i2c.c b/arch/ppc/platforms/pmac_low_i2c.c
new file mode 100644
index 000000000000..d07579f2b8b9
--- /dev/null
+++ b/arch/ppc/platforms/pmac_low_i2c.c
@@ -0,0 +1,513 @@
1/*
2 * arch/ppc/platforms/pmac_low_i2c.c
3 *
4 * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * This file contains some low-level i2c access routines that
12 * need to be used by various bits of the PowerMac platform code
13 * at times where the real asynchronous & interrupt driven driver
14 * cannot be used. The API borrows some semantics from the darwin
15 * driver in order to ease the implementation of the platform
16 * properties parser
17 */
18
19#include <linux/config.h>
20#include <linux/types.h>
21#include <linux/delay.h>
22#include <linux/sched.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/adb.h>
26#include <linux/pmu.h>
27#include <asm/keylargo.h>
28#include <asm/uninorth.h>
29#include <asm/io.h>
30#include <asm/prom.h>
31#include <asm/machdep.h>
32#include <asm/pmac_low_i2c.h>
33
34#define MAX_LOW_I2C_HOST 4
35
36#if 1
37#define DBG(x...) do {\
38 printk(KERN_DEBUG "KW:" x); \
39 } while(0)
40#else
41#define DBGG(x...)
42#endif
43
44struct low_i2c_host;
45
46typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len);
47
48struct low_i2c_host
49{
50 struct device_node *np; /* OF device node */
51 struct semaphore mutex; /* Access mutex for use by i2c-keywest */
52 low_i2c_func_t func; /* Access function */
53 int is_open : 1; /* Poor man's access control */
54 int mode; /* Current mode */
55 int channel; /* Current channel */
56 int num_channels; /* Number of channels */
57 unsigned long base; /* For keywest-i2c, base address */
58 int bsteps; /* And register stepping */
59 int speed; /* And speed */
60};
61
62static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST];
63
64/* No locking is necessary on allocation, we are running way before
65 * anything can race with us
66 */
67static struct low_i2c_host *find_low_i2c_host(struct device_node *np)
68{
69 int i;
70
71 for (i = 0; i < MAX_LOW_I2C_HOST; i++)
72 if (low_i2c_hosts[i].np == np)
73 return &low_i2c_hosts[i];
74 return NULL;
75}
76
77/*
78 *
79 * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's)
80 *
81 */
82
83/*
84 * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h,
85 * should be moved somewhere in include/asm-ppc/
86 */
87/* Register indices */
88typedef enum {
89 reg_mode = 0,
90 reg_control,
91 reg_status,
92 reg_isr,
93 reg_ier,
94 reg_addr,
95 reg_subaddr,
96 reg_data
97} reg_t;
98
99
100/* Mode register */
101#define KW_I2C_MODE_100KHZ 0x00
102#define KW_I2C_MODE_50KHZ 0x01
103#define KW_I2C_MODE_25KHZ 0x02
104#define KW_I2C_MODE_DUMB 0x00
105#define KW_I2C_MODE_STANDARD 0x04
106#define KW_I2C_MODE_STANDARDSUB 0x08
107#define KW_I2C_MODE_COMBINED 0x0C
108#define KW_I2C_MODE_MODE_MASK 0x0C
109#define KW_I2C_MODE_CHAN_MASK 0xF0
110
111/* Control register */
112#define KW_I2C_CTL_AAK 0x01
113#define KW_I2C_CTL_XADDR 0x02
114#define KW_I2C_CTL_STOP 0x04
115#define KW_I2C_CTL_START 0x08
116
117/* Status register */
118#define KW_I2C_STAT_BUSY 0x01
119#define KW_I2C_STAT_LAST_AAK 0x02
120#define KW_I2C_STAT_LAST_RW 0x04
121#define KW_I2C_STAT_SDA 0x08
122#define KW_I2C_STAT_SCL 0x10
123
124/* IER & ISR registers */
125#define KW_I2C_IRQ_DATA 0x01
126#define KW_I2C_IRQ_ADDR 0x02
127#define KW_I2C_IRQ_STOP 0x04
128#define KW_I2C_IRQ_START 0x08
129#define KW_I2C_IRQ_MASK 0x0F
130
131/* State machine states */
132enum {
133 state_idle,
134 state_addr,
135 state_read,
136 state_write,
137 state_stop,
138 state_dead
139};
140
141#define WRONG_STATE(name) do {\
142 printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \
143 name, __kw_state_names[state], isr); \
144 } while(0)
145
146static const char *__kw_state_names[] = {
147 "state_idle",
148 "state_addr",
149 "state_read",
150 "state_write",
151 "state_stop",
152 "state_dead"
153};
154
155static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg)
156{
157 return in_8(((volatile u8 *)host->base)
158 + (((unsigned)reg) << host->bsteps));
159}
160
161static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val)
162{
163 out_8(((volatile u8 *)host->base)
164 + (((unsigned)reg) << host->bsteps), val);
165 (void)__kw_read_reg(host, reg_subaddr);
166}
167
168#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
169#define kw_read_reg(reg) __kw_read_reg(host, reg)
170
171
172/* Don't schedule, the g5 fan controller is too
173 * timing sensitive
174 */
175static u8 kw_wait_interrupt(struct low_i2c_host* host)
176{
177 int i;
178 u8 isr;
179
180 for (i = 0; i < 200000; i++) {
181 isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
182 if (isr != 0)
183 return isr;
184 udelay(1);
185 }
186 return isr;
187}
188
189static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr)
190{
191 u8 ack;
192
193 if (isr == 0) {
194 if (state != state_stop) {
195 DBG("KW: Timeout !\n");
196 *rc = -EIO;
197 goto stop;
198 }
199 if (state == state_stop) {
200 ack = kw_read_reg(reg_status);
201 if (!(ack & KW_I2C_STAT_BUSY)) {
202 state = state_idle;
203 kw_write_reg(reg_ier, 0x00);
204 }
205 }
206 return state;
207 }
208
209 if (isr & KW_I2C_IRQ_ADDR) {
210 ack = kw_read_reg(reg_status);
211 if (state != state_addr) {
212 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
213 WRONG_STATE("KW_I2C_IRQ_ADDR");
214 *rc = -EIO;
215 goto stop;
216 }
217 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
218 *rc = -ENODEV;
219 DBG("KW: NAK on address\n");
220 return state_stop;
221 } else {
222 if (rw) {
223 state = state_read;
224 if (*len > 1)
225 kw_write_reg(reg_control, KW_I2C_CTL_AAK);
226 } else {
227 state = state_write;
228 kw_write_reg(reg_data, **data);
229 (*data)++; (*len)--;
230 }
231 }
232 kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
233 }
234
235 if (isr & KW_I2C_IRQ_DATA) {
236 if (state == state_read) {
237 **data = kw_read_reg(reg_data);
238 (*data)++; (*len)--;
239 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
240 if ((*len) == 0)
241 state = state_stop;
242 else if ((*len) == 1)
243 kw_write_reg(reg_control, 0);
244 } else if (state == state_write) {
245 ack = kw_read_reg(reg_status);
246 if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
247 DBG("KW: nack on data write\n");
248 *rc = -EIO;
249 goto stop;
250 } else if (*len) {
251 kw_write_reg(reg_data, **data);
252 (*data)++; (*len)--;
253 } else {
254 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
255 state = state_stop;
256 *rc = 0;
257 }
258 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
259 } else {
260 kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
261 WRONG_STATE("KW_I2C_IRQ_DATA");
262 if (state != state_stop) {
263 *rc = -EIO;
264 goto stop;
265 }
266 }
267 }
268
269 if (isr & KW_I2C_IRQ_STOP) {
270 kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
271 if (state != state_stop) {
272 WRONG_STATE("KW_I2C_IRQ_STOP");
273 *rc = -EIO;
274 }
275 return state_idle;
276 }
277
278 if (isr & KW_I2C_IRQ_START)
279 kw_write_reg(reg_isr, KW_I2C_IRQ_START);
280
281 return state;
282
283 stop:
284 kw_write_reg(reg_control, KW_I2C_CTL_STOP);
285 return state_stop;
286}
287
288static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len)
289{
290 u8 mode_reg = host->speed;
291 int state = state_addr;
292 int rc = 0;
293
294 /* Setup mode & subaddress if any */
295 switch(host->mode) {
296 case pmac_low_i2c_mode_dumb:
297 printk(KERN_ERR "low_i2c: Dumb mode not supported !\n");
298 return -EINVAL;
299 case pmac_low_i2c_mode_std:
300 mode_reg |= KW_I2C_MODE_STANDARD;
301 break;
302 case pmac_low_i2c_mode_stdsub:
303 mode_reg |= KW_I2C_MODE_STANDARDSUB;
304 kw_write_reg(reg_subaddr, subaddr);
305 break;
306 case pmac_low_i2c_mode_combined:
307 mode_reg |= KW_I2C_MODE_COMBINED;
308 kw_write_reg(reg_subaddr, subaddr);
309 break;
310 }
311
312 /* Setup channel & clear pending irqs */
313 kw_write_reg(reg_isr, kw_read_reg(reg_isr));
314 kw_write_reg(reg_mode, mode_reg | (host->channel << 4));
315 kw_write_reg(reg_status, 0);
316
317 /* Set up address and r/w bit */
318 kw_write_reg(reg_addr, addr);
319
320 /* Start sending address & disable interrupt*/
321 kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/);
322 kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
323
324 /* State machine, to turn into an interrupt handler */
325 while(state != state_idle) {
326 u8 isr = kw_wait_interrupt(host);
327 state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr);
328 }
329
330 return rc;
331}
332
333static void keywest_low_i2c_add(struct device_node *np)
334{
335 struct low_i2c_host *host = find_low_i2c_host(NULL);
336 unsigned long *psteps, *prate, steps, aoffset = 0;
337 struct device_node *parent;
338
339 if (host == NULL) {
340 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
341 np->full_name);
342 return;
343 }
344 memset(host, 0, sizeof(*host));
345
346 init_MUTEX(&host->mutex);
347 host->np = of_node_get(np);
348 psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
349 steps = psteps ? (*psteps) : 0x10;
350 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
351 steps >>= 1;
352 parent = of_get_parent(np);
353 host->num_channels = 1;
354 if (parent && parent->name[0] == 'u') {
355 host->num_channels = 2;
356 aoffset = 3;
357 }
358 /* Select interface rate */
359 host->speed = KW_I2C_MODE_100KHZ;
360 prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
361 if (prate) switch(*prate) {
362 case 100:
363 host->speed = KW_I2C_MODE_100KHZ;
364 break;
365 case 50:
366 host->speed = KW_I2C_MODE_50KHZ;
367 break;
368 case 25:
369 host->speed = KW_I2C_MODE_25KHZ;
370 break;
371 }
372 host->mode = pmac_low_i2c_mode_std;
373 host->base = (unsigned long)ioremap(np->addrs[0].address + aoffset,
374 np->addrs[0].size);
375 host->func = keywest_low_i2c_func;
376}
377
378/*
379 *
380 * PMU implementation
381 *
382 */
383
384
385#ifdef CONFIG_ADB_PMU
386
387static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len)
388{
389 // TODO
390 return -ENODEV;
391}
392
393static void pmu_low_i2c_add(struct device_node *np)
394{
395 struct low_i2c_host *host = find_low_i2c_host(NULL);
396
397 if (host == NULL) {
398 printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
399 np->full_name);
400 return;
401 }
402 memset(host, 0, sizeof(*host));
403
404 init_MUTEX(&host->mutex);
405 host->np = of_node_get(np);
406 host->num_channels = 3;
407 host->mode = pmac_low_i2c_mode_std;
408 host->func = pmu_low_i2c_func;
409}
410
411#endif /* CONFIG_ADB_PMU */
412
413void __init pmac_init_low_i2c(void)
414{
415 struct device_node *np;
416
417 /* Probe keywest-i2c busses */
418 np = of_find_compatible_node(NULL, "i2c", "keywest-i2c");
419 while(np) {
420 keywest_low_i2c_add(np);
421 np = of_find_compatible_node(np, "i2c", "keywest-i2c");
422 }
423
424#ifdef CONFIG_ADB_PMU
425 /* Probe PMU busses */
426 np = of_find_node_by_name(NULL, "via-pmu");
427 if (np)
428 pmu_low_i2c_add(np);
429#endif /* CONFIG_ADB_PMU */
430
431 /* TODO: Add CUDA support as well */
432}
433
434int pmac_low_i2c_lock(struct device_node *np)
435{
436 struct low_i2c_host *host = find_low_i2c_host(np);
437
438 if (!host)
439 return -ENODEV;
440 down(&host->mutex);
441 return 0;
442}
443EXPORT_SYMBOL(pmac_low_i2c_lock);
444
445int pmac_low_i2c_unlock(struct device_node *np)
446{
447 struct low_i2c_host *host = find_low_i2c_host(np);
448
449 if (!host)
450 return -ENODEV;
451 up(&host->mutex);
452 return 0;
453}
454EXPORT_SYMBOL(pmac_low_i2c_unlock);
455
456
457int pmac_low_i2c_open(struct device_node *np, int channel)
458{
459 struct low_i2c_host *host = find_low_i2c_host(np);
460
461 if (!host)
462 return -ENODEV;
463
464 if (channel >= host->num_channels)
465 return -EINVAL;
466
467 down(&host->mutex);
468 host->is_open = 1;
469 host->channel = channel;
470
471 return 0;
472}
473EXPORT_SYMBOL(pmac_low_i2c_open);
474
475int pmac_low_i2c_close(struct device_node *np)
476{
477 struct low_i2c_host *host = find_low_i2c_host(np);
478
479 if (!host)
480 return -ENODEV;
481
482 host->is_open = 0;
483 up(&host->mutex);
484
485 return 0;
486}
487EXPORT_SYMBOL(pmac_low_i2c_close);
488
489int pmac_low_i2c_setmode(struct device_node *np, int mode)
490{
491 struct low_i2c_host *host = find_low_i2c_host(np);
492
493 if (!host)
494 return -ENODEV;
495 WARN_ON(!host->is_open);
496 host->mode = mode;
497
498 return 0;
499}
500EXPORT_SYMBOL(pmac_low_i2c_setmode);
501
502int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len)
503{
504 struct low_i2c_host *host = find_low_i2c_host(np);
505
506 if (!host)
507 return -ENODEV;
508 WARN_ON(!host->is_open);
509
510 return host->func(host, addrdir, subaddr, data, len);
511}
512EXPORT_SYMBOL(pmac_low_i2c_xfer);
513
diff --git a/arch/ppc/platforms/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c
new file mode 100644
index 000000000000..c9de64205996
--- /dev/null
+++ b/arch/ppc/platforms/pmac_nvram.c
@@ -0,0 +1,584 @@
1/*
2 * arch/ppc/platforms/pmac_nvram.c
3 *
4 * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Todo: - add support for the OF persistent properties
12 */
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/stddef.h>
17#include <linux/string.h>
18#include <linux/nvram.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/adb.h>
24#include <linux/pmu.h>
25#include <linux/bootmem.h>
26#include <linux/completion.h>
27#include <linux/spinlock.h>
28#include <asm/sections.h>
29#include <asm/io.h>
30#include <asm/system.h>
31#include <asm/prom.h>
32#include <asm/machdep.h>
33#include <asm/nvram.h>
34
35#define DEBUG
36
37#ifdef DEBUG
38#define DBG(x...) printk(x)
39#else
40#define DBG(x...)
41#endif
42
43#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
44
45#define CORE99_SIGNATURE 0x5a
46#define CORE99_ADLER_START 0x14
47
48/* On Core99, nvram is either a sharp, a micron or an AMD flash */
49#define SM_FLASH_STATUS_DONE 0x80
50#define SM_FLASH_STATUS_ERR 0x38
51#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0
52#define SM_FLASH_CMD_ERASE_SETUP 0x20
53#define SM_FLASH_CMD_RESET 0xff
54#define SM_FLASH_CMD_WRITE_SETUP 0x40
55#define SM_FLASH_CMD_CLEAR_STATUS 0x50
56#define SM_FLASH_CMD_READ_STATUS 0x70
57
58/* CHRP NVRAM header */
59struct chrp_header {
60 u8 signature;
61 u8 cksum;
62 u16 len;
63 char name[12];
64 u8 data[0];
65};
66
67struct core99_header {
68 struct chrp_header hdr;
69 u32 adler;
70 u32 generation;
71 u32 reserved[2];
72};
73
74/*
75 * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
76 */
77static int nvram_naddrs;
78static volatile unsigned char *nvram_addr;
79static volatile unsigned char *nvram_data;
80static int nvram_mult, is_core_99;
81static int core99_bank = 0;
82static int nvram_partitions[3];
83static DEFINE_SPINLOCK(nv_lock);
84
85extern int pmac_newworld;
86extern int system_running;
87
88static int (*core99_write_bank)(int bank, u8* datas);
89static int (*core99_erase_bank)(int bank);
90
91static char *nvram_image __pmacdata;
92
93
94static unsigned char __pmac core99_nvram_read_byte(int addr)
95{
96 if (nvram_image == NULL)
97 return 0xff;
98 return nvram_image[addr];
99}
100
101static void __pmac core99_nvram_write_byte(int addr, unsigned char val)
102{
103 if (nvram_image == NULL)
104 return;
105 nvram_image[addr] = val;
106}
107
108
109static unsigned char __openfirmware direct_nvram_read_byte(int addr)
110{
111 return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
112}
113
114static void __openfirmware direct_nvram_write_byte(int addr, unsigned char val)
115{
116 out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
117}
118
119
120static unsigned char __pmac indirect_nvram_read_byte(int addr)
121{
122 unsigned char val;
123 unsigned long flags;
124
125 spin_lock_irqsave(&nv_lock, flags);
126 out_8(nvram_addr, addr >> 5);
127 val = in_8(&nvram_data[(addr & 0x1f) << 4]);
128 spin_unlock_irqrestore(&nv_lock, flags);
129
130 return val;
131}
132
133static void __pmac indirect_nvram_write_byte(int addr, unsigned char val)
134{
135 unsigned long flags;
136
137 spin_lock_irqsave(&nv_lock, flags);
138 out_8(nvram_addr, addr >> 5);
139 out_8(&nvram_data[(addr & 0x1f) << 4], val);
140 spin_unlock_irqrestore(&nv_lock, flags);
141}
142
143
144#ifdef CONFIG_ADB_PMU
145
146static void __pmac pmu_nvram_complete(struct adb_request *req)
147{
148 if (req->arg)
149 complete((struct completion *)req->arg);
150}
151
152static unsigned char __pmac pmu_nvram_read_byte(int addr)
153{
154 struct adb_request req;
155 DECLARE_COMPLETION(req_complete);
156
157 req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
158 if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
159 (addr >> 8) & 0xff, addr & 0xff))
160 return 0xff;
161 if (system_state == SYSTEM_RUNNING)
162 wait_for_completion(&req_complete);
163 while (!req.complete)
164 pmu_poll();
165 return req.reply[0];
166}
167
168static void __pmac pmu_nvram_write_byte(int addr, unsigned char val)
169{
170 struct adb_request req;
171 DECLARE_COMPLETION(req_complete);
172
173 req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
174 if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
175 (addr >> 8) & 0xff, addr & 0xff, val))
176 return;
177 if (system_state == SYSTEM_RUNNING)
178 wait_for_completion(&req_complete);
179 while (!req.complete)
180 pmu_poll();
181}
182
183#endif /* CONFIG_ADB_PMU */
184
185
186static u8 __pmac chrp_checksum(struct chrp_header* hdr)
187{
188 u8 *ptr;
189 u16 sum = hdr->signature;
190 for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
191 sum += *ptr;
192 while (sum > 0xFF)
193 sum = (sum & 0xFF) + (sum>>8);
194 return sum;
195}
196
197static u32 __pmac core99_calc_adler(u8 *buffer)
198{
199 int cnt;
200 u32 low, high;
201
202 buffer += CORE99_ADLER_START;
203 low = 1;
204 high = 0;
205 for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
206 if ((cnt % 5000) == 0) {
207 high %= 65521UL;
208 high %= 65521UL;
209 }
210 low += buffer[cnt];
211 high += low;
212 }
213 low %= 65521UL;
214 high %= 65521UL;
215
216 return (high << 16) | low;
217}
218
219static u32 __pmac core99_check(u8* datas)
220{
221 struct core99_header* hdr99 = (struct core99_header*)datas;
222
223 if (hdr99->hdr.signature != CORE99_SIGNATURE) {
224 DBG("Invalid signature\n");
225 return 0;
226 }
227 if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
228 DBG("Invalid checksum\n");
229 return 0;
230 }
231 if (hdr99->adler != core99_calc_adler(datas)) {
232 DBG("Invalid adler\n");
233 return 0;
234 }
235 return hdr99->generation;
236}
237
238static int __pmac sm_erase_bank(int bank)
239{
240 int stat, i;
241 unsigned long timeout;
242
243 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
244
245 DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
246
247 out_8(base, SM_FLASH_CMD_ERASE_SETUP);
248 out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
249 timeout = 0;
250 do {
251 if (++timeout > 1000000) {
252 printk(KERN_ERR "nvram: Sharp/Miron flash erase timeout !\n");
253 break;
254 }
255 out_8(base, SM_FLASH_CMD_READ_STATUS);
256 stat = in_8(base);
257 } while (!(stat & SM_FLASH_STATUS_DONE));
258
259 out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
260 out_8(base, SM_FLASH_CMD_RESET);
261
262 for (i=0; i<NVRAM_SIZE; i++)
263 if (base[i] != 0xff) {
264 printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
265 return -ENXIO;
266 }
267 return 0;
268}
269
270static int __pmac sm_write_bank(int bank, u8* datas)
271{
272 int i, stat = 0;
273 unsigned long timeout;
274
275 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
276
277 DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
278
279 for (i=0; i<NVRAM_SIZE; i++) {
280 out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
281 udelay(1);
282 out_8(base+i, datas[i]);
283 timeout = 0;
284 do {
285 if (++timeout > 1000000) {
286 printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
287 break;
288 }
289 out_8(base, SM_FLASH_CMD_READ_STATUS);
290 stat = in_8(base);
291 } while (!(stat & SM_FLASH_STATUS_DONE));
292 if (!(stat & SM_FLASH_STATUS_DONE))
293 break;
294 }
295 out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
296 out_8(base, SM_FLASH_CMD_RESET);
297 for (i=0; i<NVRAM_SIZE; i++)
298 if (base[i] != datas[i]) {
299 printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
300 return -ENXIO;
301 }
302 return 0;
303}
304
305static int __pmac amd_erase_bank(int bank)
306{
307 int i, stat = 0;
308 unsigned long timeout;
309
310 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
311
312 DBG("nvram: AMD Erasing bank %d...\n", bank);
313
314 /* Unlock 1 */
315 out_8(base+0x555, 0xaa);
316 udelay(1);
317 /* Unlock 2 */
318 out_8(base+0x2aa, 0x55);
319 udelay(1);
320
321 /* Sector-Erase */
322 out_8(base+0x555, 0x80);
323 udelay(1);
324 out_8(base+0x555, 0xaa);
325 udelay(1);
326 out_8(base+0x2aa, 0x55);
327 udelay(1);
328 out_8(base, 0x30);
329 udelay(1);
330
331 timeout = 0;
332 do {
333 if (++timeout > 1000000) {
334 printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
335 break;
336 }
337 stat = in_8(base) ^ in_8(base);
338 } while (stat != 0);
339
340 /* Reset */
341 out_8(base, 0xf0);
342 udelay(1);
343
344 for (i=0; i<NVRAM_SIZE; i++)
345 if (base[i] != 0xff) {
346 printk(KERN_ERR "nvram: AMD flash erase failed !\n");
347 return -ENXIO;
348 }
349 return 0;
350}
351
352static int __pmac amd_write_bank(int bank, u8* datas)
353{
354 int i, stat = 0;
355 unsigned long timeout;
356
357 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
358
359 DBG("nvram: AMD Writing bank %d...\n", bank);
360
361 for (i=0; i<NVRAM_SIZE; i++) {
362 /* Unlock 1 */
363 out_8(base+0x555, 0xaa);
364 udelay(1);
365 /* Unlock 2 */
366 out_8(base+0x2aa, 0x55);
367 udelay(1);
368
369 /* Write single word */
370 out_8(base+0x555, 0xa0);
371 udelay(1);
372 out_8(base+i, datas[i]);
373
374 timeout = 0;
375 do {
376 if (++timeout > 1000000) {
377 printk(KERN_ERR "nvram: AMD flash write timeout !\n");
378 break;
379 }
380 stat = in_8(base) ^ in_8(base);
381 } while (stat != 0);
382 if (stat != 0)
383 break;
384 }
385
386 /* Reset */
387 out_8(base, 0xf0);
388 udelay(1);
389
390 for (i=0; i<NVRAM_SIZE; i++)
391 if (base[i] != datas[i]) {
392 printk(KERN_ERR "nvram: AMD flash write failed !\n");
393 return -ENXIO;
394 }
395 return 0;
396}
397
398static void __init lookup_partitions(void)
399{
400 u8 buffer[17];
401 int i, offset;
402 struct chrp_header* hdr;
403
404 if (pmac_newworld) {
405 nvram_partitions[pmac_nvram_OF] = -1;
406 nvram_partitions[pmac_nvram_XPRAM] = -1;
407 nvram_partitions[pmac_nvram_NR] = -1;
408 hdr = (struct chrp_header *)buffer;
409
410 offset = 0;
411 buffer[16] = 0;
412 do {
413 for (i=0;i<16;i++)
414 buffer[i] = nvram_read_byte(offset+i);
415 if (!strcmp(hdr->name, "common"))
416 nvram_partitions[pmac_nvram_OF] = offset + 0x10;
417 if (!strcmp(hdr->name, "APL,MacOS75")) {
418 nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
419 nvram_partitions[pmac_nvram_NR] = offset + 0x110;
420 }
421 offset += (hdr->len * 0x10);
422 } while(offset < NVRAM_SIZE);
423 } else {
424 nvram_partitions[pmac_nvram_OF] = 0x1800;
425 nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
426 nvram_partitions[pmac_nvram_NR] = 0x1400;
427 }
428 DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
429 DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
430 DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
431}
432
433static void __pmac core99_nvram_sync(void)
434{
435 struct core99_header* hdr99;
436 unsigned long flags;
437
438 if (!is_core_99 || !nvram_data || !nvram_image)
439 return;
440
441 spin_lock_irqsave(&nv_lock, flags);
442 if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
443 NVRAM_SIZE))
444 goto bail;
445
446 DBG("Updating nvram...\n");
447
448 hdr99 = (struct core99_header*)nvram_image;
449 hdr99->generation++;
450 hdr99->hdr.signature = CORE99_SIGNATURE;
451 hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
452 hdr99->adler = core99_calc_adler(nvram_image);
453 core99_bank = core99_bank ? 0 : 1;
454 if (core99_erase_bank)
455 if (core99_erase_bank(core99_bank)) {
456 printk("nvram: Error erasing bank %d\n", core99_bank);
457 goto bail;
458 }
459 if (core99_write_bank)
460 if (core99_write_bank(core99_bank, nvram_image))
461 printk("nvram: Error writing bank %d\n", core99_bank);
462 bail:
463 spin_unlock_irqrestore(&nv_lock, flags);
464
465#ifdef DEBUG
466 mdelay(2000);
467#endif
468}
469
470void __init pmac_nvram_init(void)
471{
472 struct device_node *dp;
473
474 nvram_naddrs = 0;
475
476 dp = find_devices("nvram");
477 if (dp == NULL) {
478 printk(KERN_ERR "Can't find NVRAM device\n");
479 return;
480 }
481 nvram_naddrs = dp->n_addrs;
482 is_core_99 = device_is_compatible(dp, "nvram,flash");
483 if (is_core_99) {
484 int i;
485 u32 gen_bank0, gen_bank1;
486
487 if (nvram_naddrs < 1) {
488 printk(KERN_ERR "nvram: no address\n");
489 return;
490 }
491 nvram_image = alloc_bootmem(NVRAM_SIZE);
492 if (nvram_image == NULL) {
493 printk(KERN_ERR "nvram: can't allocate ram image\n");
494 return;
495 }
496 nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
497 nvram_naddrs = 1; /* Make sure we get the correct case */
498
499 DBG("nvram: Checking bank 0...\n");
500
501 gen_bank0 = core99_check((u8 *)nvram_data);
502 gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
503 core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
504
505 DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
506 DBG("nvram: Active bank is: %d\n", core99_bank);
507
508 for (i=0; i<NVRAM_SIZE; i++)
509 nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
510
511 ppc_md.nvram_read_val = core99_nvram_read_byte;
512 ppc_md.nvram_write_val = core99_nvram_write_byte;
513 ppc_md.nvram_sync = core99_nvram_sync;
514 /*
515 * Maybe we could be smarter here though making an exclusive list
516 * of known flash chips is a bit nasty as older OF didn't provide us
517 * with a useful "compatible" entry. A solution would be to really
518 * identify the chip using flash id commands and base ourselves on
519 * a list of known chips IDs
520 */
521 if (device_is_compatible(dp, "amd-0137")) {
522 core99_erase_bank = amd_erase_bank;
523 core99_write_bank = amd_write_bank;
524 } else {
525 core99_erase_bank = sm_erase_bank;
526 core99_write_bank = sm_write_bank;
527 }
528 } else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
529 nvram_data = ioremap(dp->addrs[0].address + isa_mem_base,
530 dp->addrs[0].size);
531 nvram_mult = 1;
532 ppc_md.nvram_read_val = direct_nvram_read_byte;
533 ppc_md.nvram_write_val = direct_nvram_write_byte;
534 } else if (nvram_naddrs == 1) {
535 nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
536 nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
537 ppc_md.nvram_read_val = direct_nvram_read_byte;
538 ppc_md.nvram_write_val = direct_nvram_write_byte;
539 } else if (nvram_naddrs == 2) {
540 nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
541 nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
542 ppc_md.nvram_read_val = indirect_nvram_read_byte;
543 ppc_md.nvram_write_val = indirect_nvram_write_byte;
544 } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
545#ifdef CONFIG_ADB_PMU
546 nvram_naddrs = -1;
547 ppc_md.nvram_read_val = pmu_nvram_read_byte;
548 ppc_md.nvram_write_val = pmu_nvram_write_byte;
549#endif /* CONFIG_ADB_PMU */
550 } else {
551 printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
552 nvram_naddrs);
553 }
554 lookup_partitions();
555}
556
557int __pmac pmac_get_partition(int partition)
558{
559 return nvram_partitions[partition];
560}
561
562u8 __pmac pmac_xpram_read(int xpaddr)
563{
564 int offset = nvram_partitions[pmac_nvram_XPRAM];
565
566 if (offset < 0)
567 return 0xff;
568
569 return ppc_md.nvram_read_val(xpaddr + offset);
570}
571
572void __pmac pmac_xpram_write(int xpaddr, u8 data)
573{
574 int offset = nvram_partitions[pmac_nvram_XPRAM];
575
576 if (offset < 0)
577 return;
578
579 ppc_md.nvram_write_val(xpaddr + offset, data);
580}
581
582EXPORT_SYMBOL(pmac_get_partition);
583EXPORT_SYMBOL(pmac_xpram_read);
584EXPORT_SYMBOL(pmac_xpram_write);
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
new file mode 100644
index 000000000000..f6ff51924061
--- /dev/null
+++ b/arch/ppc/platforms/pmac_pci.c
@@ -0,0 +1,1125 @@
1/*
2 * Support for PCI bridges found on Power Macintoshes.
3 * At present the "bandit" and "chaos" bridges are supported.
4 * Fortunately you access configuration space in the same
5 * way with either bridge.
6 *
7 * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include <linux/string.h>
19#include <linux/init.h>
20#include <linux/bootmem.h>
21
22#include <asm/sections.h>
23#include <asm/io.h>
24#include <asm/prom.h>
25#include <asm/pci-bridge.h>
26#include <asm/machdep.h>
27#include <asm/pmac_feature.h>
28
29#undef DEBUG
30
31#ifdef DEBUG
32#ifdef CONFIG_XMON
33extern void xmon_printf(const char *fmt, ...);
34#define DBG(x...) xmon_printf(x)
35#else
36#define DBG(x...) printk(x)
37#endif
38#else
39#define DBG(x...)
40#endif
41
42static int add_bridge(struct device_node *dev);
43extern void pmac_check_ht_link(void);
44
45/* XXX Could be per-controller, but I don't think we risk anything by
46 * assuming we won't have both UniNorth and Bandit */
47static int has_uninorth;
48#ifdef CONFIG_POWER4
49static struct pci_controller *u3_agp;
50#endif /* CONFIG_POWER4 */
51
52extern u8 pci_cache_line_size;
53extern int pcibios_assign_bus_offset;
54
55struct device_node *k2_skiplist[2];
56
57/*
58 * Magic constants for enabling cache coherency in the bandit/PSX bridge.
59 */
60#define BANDIT_DEVID_2 8
61#define BANDIT_REVID 3
62
63#define BANDIT_DEVNUM 11
64#define BANDIT_MAGIC 0x50
65#define BANDIT_COHERENT 0x40
66
67static int __init
68fixup_one_level_bus_range(struct device_node *node, int higher)
69{
70 for (; node != 0;node = node->sibling) {
71 int * bus_range;
72 unsigned int *class_code;
73 int len;
74
75 /* For PCI<->PCI bridges or CardBus bridges, we go down */
76 class_code = (unsigned int *) get_property(node, "class-code", NULL);
77 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
78 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
79 continue;
80 bus_range = (int *) get_property(node, "bus-range", &len);
81 if (bus_range != NULL && len > 2 * sizeof(int)) {
82 if (bus_range[1] > higher)
83 higher = bus_range[1];
84 }
85 higher = fixup_one_level_bus_range(node->child, higher);
86 }
87 return higher;
88}
89
90/* This routine fixes the "bus-range" property of all bridges in the
91 * system since they tend to have their "last" member wrong on macs
92 *
93 * Note that the bus numbers manipulated here are OF bus numbers, they
94 * are not Linux bus numbers.
95 */
96static void __init
97fixup_bus_range(struct device_node *bridge)
98{
99 int * bus_range;
100 int len;
101
102 /* Lookup the "bus-range" property for the hose */
103 bus_range = (int *) get_property(bridge, "bus-range", &len);
104 if (bus_range == NULL || len < 2 * sizeof(int)) {
105 printk(KERN_WARNING "Can't get bus-range for %s\n",
106 bridge->full_name);
107 return;
108 }
109 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
110}
111
112/*
113 * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
114 *
115 * The "Bandit" version is present in all early PCI PowerMacs,
116 * and up to the first ones using Grackle. Some machines may
117 * have 2 bandit controllers (2 PCI busses).
118 *
119 * "Chaos" is used in some "Bandit"-type machines as a bridge
120 * for the separate display bus. It is accessed the same
121 * way as bandit, but cannot be probed for devices. It therefore
122 * has its own config access functions.
123 *
124 * The "UniNorth" version is present in all Core99 machines
125 * (iBook, G4, new IMacs, and all the recent Apple machines).
126 * It contains 3 controllers in one ASIC.
127 *
128 * The U3 is the bridge used on G5 machines. It contains an
129 * AGP bus which is dealt with the old UniNorth access routines
130 * and a HyperTransport bus which uses its own set of access
131 * functions.
132 */
133
134#define MACRISC_CFA0(devfn, off) \
135 ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
136 | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
137 | (((unsigned long)(off)) & 0xFCUL))
138
139#define MACRISC_CFA1(bus, devfn, off) \
140 ((((unsigned long)(bus)) << 16) \
141 |(((unsigned long)(devfn)) << 8) \
142 |(((unsigned long)(off)) & 0xFCUL) \
143 |1UL)
144
145static void volatile __iomem * __pmac
146macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
147{
148 unsigned int caddr;
149
150 if (bus == hose->first_busno) {
151 if (dev_fn < (11 << 3))
152 return NULL;
153 caddr = MACRISC_CFA0(dev_fn, offset);
154 } else
155 caddr = MACRISC_CFA1(bus, dev_fn, offset);
156
157 /* Uninorth will return garbage if we don't read back the value ! */
158 do {
159 out_le32(hose->cfg_addr, caddr);
160 } while (in_le32(hose->cfg_addr) != caddr);
161
162 offset &= has_uninorth ? 0x07 : 0x03;
163 return hose->cfg_data + offset;
164}
165
166static int __pmac
167macrisc_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
168 int len, u32 *val)
169{
170 struct pci_controller *hose = bus->sysdata;
171 void volatile __iomem *addr;
172
173 addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
174 if (!addr)
175 return PCIBIOS_DEVICE_NOT_FOUND;
176 /*
177 * Note: the caller has already checked that offset is
178 * suitably aligned and that len is 1, 2 or 4.
179 */
180 switch (len) {
181 case 1:
182 *val = in_8(addr);
183 break;
184 case 2:
185 *val = in_le16(addr);
186 break;
187 default:
188 *val = in_le32(addr);
189 break;
190 }
191 return PCIBIOS_SUCCESSFUL;
192}
193
194static int __pmac
195macrisc_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
196 int len, u32 val)
197{
198 struct pci_controller *hose = bus->sysdata;
199 void volatile __iomem *addr;
200
201 addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
202 if (!addr)
203 return PCIBIOS_DEVICE_NOT_FOUND;
204 /*
205 * Note: the caller has already checked that offset is
206 * suitably aligned and that len is 1, 2 or 4.
207 */
208 switch (len) {
209 case 1:
210 out_8(addr, val);
211 (void) in_8(addr);
212 break;
213 case 2:
214 out_le16(addr, val);
215 (void) in_le16(addr);
216 break;
217 default:
218 out_le32(addr, val);
219 (void) in_le32(addr);
220 break;
221 }
222 return PCIBIOS_SUCCESSFUL;
223}
224
225static struct pci_ops macrisc_pci_ops =
226{
227 macrisc_read_config,
228 macrisc_write_config
229};
230
231/*
232 * Verifiy that a specific (bus, dev_fn) exists on chaos
233 */
234static int __pmac
235chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
236{
237 struct device_node *np;
238 u32 *vendor, *device;
239
240 np = pci_busdev_to_OF_node(bus, devfn);
241 if (np == NULL)
242 return PCIBIOS_DEVICE_NOT_FOUND;
243
244 vendor = (u32 *)get_property(np, "vendor-id", NULL);
245 device = (u32 *)get_property(np, "device-id", NULL);
246 if (vendor == NULL || device == NULL)
247 return PCIBIOS_DEVICE_NOT_FOUND;
248
249 if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
250 && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
251 return PCIBIOS_BAD_REGISTER_NUMBER;
252
253 return PCIBIOS_SUCCESSFUL;
254}
255
256static int __pmac
257chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
258 int len, u32 *val)
259{
260 int result = chaos_validate_dev(bus, devfn, offset);
261 if (result == PCIBIOS_BAD_REGISTER_NUMBER)
262 *val = ~0U;
263 if (result != PCIBIOS_SUCCESSFUL)
264 return result;
265 return macrisc_read_config(bus, devfn, offset, len, val);
266}
267
268static int __pmac
269chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
270 int len, u32 val)
271{
272 int result = chaos_validate_dev(bus, devfn, offset);
273 if (result != PCIBIOS_SUCCESSFUL)
274 return result;
275 return macrisc_write_config(bus, devfn, offset, len, val);
276}
277
278static struct pci_ops chaos_pci_ops =
279{
280 chaos_read_config,
281 chaos_write_config
282};
283
284#ifdef CONFIG_POWER4
285
286/*
287 * These versions of U3 HyperTransport config space access ops do not
288 * implement self-view of the HT host yet
289 */
290
291#define U3_HT_CFA0(devfn, off) \
292 ((((unsigned long)devfn) << 8) | offset)
293#define U3_HT_CFA1(bus, devfn, off) \
294 (U3_HT_CFA0(devfn, off) \
295 + (((unsigned long)bus) << 16) \
296 + 0x01000000UL)
297
298static void volatile __iomem * __pmac
299u3_ht_cfg_access(struct pci_controller* hose, u8 bus, u8 devfn, u8 offset)
300{
301 if (bus == hose->first_busno) {
302 /* For now, we don't self probe U3 HT bridge */
303 if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
304 PCI_SLOT(devfn) < 1)
305 return 0;
306 return hose->cfg_data + U3_HT_CFA0(devfn, offset);
307 } else
308 return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
309}
310
311static int __pmac
312u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
313 int len, u32 *val)
314{
315 struct pci_controller *hose = bus->sysdata;
316 void volatile __iomem *addr;
317 int i;
318
319 struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
320 if (np == NULL)
321 return PCIBIOS_DEVICE_NOT_FOUND;
322
323 /*
324 * When a device in K2 is powered down, we die on config
325 * cycle accesses. Fix that here.
326 */
327 for (i=0; i<2; i++)
328 if (k2_skiplist[i] == np) {
329 switch (len) {
330 case 1:
331 *val = 0xff; break;
332 case 2:
333 *val = 0xffff; break;
334 default:
335 *val = 0xfffffffful; break;
336 }
337 return PCIBIOS_SUCCESSFUL;
338 }
339
340 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
341 if (!addr)
342 return PCIBIOS_DEVICE_NOT_FOUND;
343 /*
344 * Note: the caller has already checked that offset is
345 * suitably aligned and that len is 1, 2 or 4.
346 */
347 switch (len) {
348 case 1:
349 *val = in_8(addr);
350 break;
351 case 2:
352 *val = in_le16(addr);
353 break;
354 default:
355 *val = in_le32(addr);
356 break;
357 }
358 return PCIBIOS_SUCCESSFUL;
359}
360
361static int __pmac
362u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
363 int len, u32 val)
364{
365 struct pci_controller *hose = bus->sysdata;
366 void volatile __iomem *addr;
367 int i;
368
369 struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
370 if (np == NULL)
371 return PCIBIOS_DEVICE_NOT_FOUND;
372 /*
373 * When a device in K2 is powered down, we die on config
374 * cycle accesses. Fix that here.
375 */
376 for (i=0; i<2; i++)
377 if (k2_skiplist[i] == np)
378 return PCIBIOS_SUCCESSFUL;
379
380 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
381 if (!addr)
382 return PCIBIOS_DEVICE_NOT_FOUND;
383 /*
384 * Note: the caller has already checked that offset is
385 * suitably aligned and that len is 1, 2 or 4.
386 */
387 switch (len) {
388 case 1:
389 out_8(addr, val);
390 (void) in_8(addr);
391 break;
392 case 2:
393 out_le16(addr, val);
394 (void) in_le16(addr);
395 break;
396 default:
397 out_le32(addr, val);
398 (void) in_le32(addr);
399 break;
400 }
401 return PCIBIOS_SUCCESSFUL;
402}
403
404static struct pci_ops u3_ht_pci_ops =
405{
406 u3_ht_read_config,
407 u3_ht_write_config
408};
409
410#endif /* CONFIG_POWER4 */
411
412/*
413 * For a bandit bridge, turn on cache coherency if necessary.
414 * N.B. we could clean this up using the hose ops directly.
415 */
416static void __init
417init_bandit(struct pci_controller *bp)
418{
419 unsigned int vendev, magic;
420 int rev;
421
422 /* read the word at offset 0 in config space for device 11 */
423 out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
424 udelay(2);
425 vendev = in_le32(bp->cfg_data);
426 if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
427 PCI_VENDOR_ID_APPLE) {
428 /* read the revision id */
429 out_le32(bp->cfg_addr,
430 (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
431 udelay(2);
432 rev = in_8(bp->cfg_data);
433 if (rev != BANDIT_REVID)
434 printk(KERN_WARNING
435 "Unknown revision %d for bandit\n", rev);
436 } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
437 printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
438 return;
439 }
440
441 /* read the word at offset 0x50 */
442 out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
443 udelay(2);
444 magic = in_le32(bp->cfg_data);
445 if ((magic & BANDIT_COHERENT) != 0)
446 return;
447 magic |= BANDIT_COHERENT;
448 udelay(2);
449 out_le32(bp->cfg_data, magic);
450 printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
451}
452
453
454/*
455 * Tweak the PCI-PCI bridge chip on the blue & white G3s.
456 */
457static void __init
458init_p2pbridge(void)
459{
460 struct device_node *p2pbridge;
461 struct pci_controller* hose;
462 u8 bus, devfn;
463 u16 val;
464
465 /* XXX it would be better here to identify the specific
466 PCI-PCI bridge chip we have. */
467 if ((p2pbridge = find_devices("pci-bridge")) == 0
468 || p2pbridge->parent == NULL
469 || strcmp(p2pbridge->parent->name, "pci") != 0)
470 return;
471 if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
472 DBG("Can't find PCI infos for PCI<->PCI bridge\n");
473 return;
474 }
475 /* Warning: At this point, we have not yet renumbered all busses.
476 * So we must use OF walking to find out hose
477 */
478 hose = pci_find_hose_for_OF_device(p2pbridge);
479 if (!hose) {
480 DBG("Can't find hose for PCI<->PCI bridge\n");
481 return;
482 }
483 if (early_read_config_word(hose, bus, devfn,
484 PCI_BRIDGE_CONTROL, &val) < 0) {
485 printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
486 return;
487 }
488 val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
489 early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
490}
491
492/*
493 * Some Apple desktop machines have a NEC PD720100A USB2 controller
494 * on the motherboard. Open Firmware, on these, will disable the
495 * EHCI part of it so it behaves like a pair of OHCI's. This fixup
496 * code re-enables it ;)
497 */
498static void __init
499fixup_nec_usb2(void)
500{
501 struct device_node *nec;
502
503 for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
504 struct pci_controller *hose;
505 u32 data, *prop;
506 u8 bus, devfn;
507
508 prop = (u32 *)get_property(nec, "vendor-id", NULL);
509 if (prop == NULL)
510 continue;
511 if (0x1033 != *prop)
512 continue;
513 prop = (u32 *)get_property(nec, "device-id", NULL);
514 if (prop == NULL)
515 continue;
516 if (0x0035 != *prop)
517 continue;
518 prop = (u32 *)get_property(nec, "reg", NULL);
519 if (prop == NULL)
520 continue;
521 devfn = (prop[0] >> 8) & 0xff;
522 bus = (prop[0] >> 16) & 0xff;
523 if (PCI_FUNC(devfn) != 0)
524 continue;
525 hose = pci_find_hose_for_OF_device(nec);
526 if (!hose)
527 continue;
528 early_read_config_dword(hose, bus, devfn, 0xe4, &data);
529 if (data & 1UL) {
530 printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n");
531 data &= ~1UL;
532 early_write_config_dword(hose, bus, devfn, 0xe4, data);
533 early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
534 nec->intrs[0].line);
535 }
536 }
537}
538
539void __init
540pmac_find_bridges(void)
541{
542 struct device_node *np, *root;
543 struct device_node *ht = NULL;
544
545 root = of_find_node_by_path("/");
546 if (root == NULL) {
547 printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
548 return;
549 }
550 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
551 if (np->name == NULL)
552 continue;
553 if (strcmp(np->name, "bandit") == 0
554 || strcmp(np->name, "chaos") == 0
555 || strcmp(np->name, "pci") == 0) {
556 if (add_bridge(np) == 0)
557 of_node_get(np);
558 }
559 if (strcmp(np->name, "ht") == 0) {
560 of_node_get(np);
561 ht = np;
562 }
563 }
564 of_node_put(root);
565
566 /* Probe HT last as it relies on the agp resources to be already
567 * setup
568 */
569 if (ht && add_bridge(ht) != 0)
570 of_node_put(ht);
571
572 init_p2pbridge();
573 fixup_nec_usb2();
574
575 /* We are still having some issues with the Xserve G4, enabling
576 * some offset between bus number and domains for now when we
577 * assign all busses should help for now
578 */
579 if (pci_assign_all_busses)
580 pcibios_assign_bus_offset = 0x10;
581
582#ifdef CONFIG_POWER4
583 /* There is something wrong with DMA on U3/HT. I haven't figured out
584 * the details yet, but if I set the cache line size to 128 bytes like
585 * it should, I'm getting memory corruption caused by devices like
586 * sungem (even without the MWI bit set, but maybe sungem doesn't
587 * care). Right now, it appears that setting up a 64 bytes line size
588 * works properly, 64 bytes beeing the max transfer size of HT, I
589 * suppose this is related the way HT/PCI are hooked together. I still
590 * need to dive into more specs though to be really sure of what's
591 * going on. --BenH.
592 *
593 * Ok, apparently, it's just that HT can't do more than 64 bytes
594 * transactions. MWI seem to be meaningless there as well, it may
595 * be worth nop'ing out pci_set_mwi too though I haven't done that
596 * yet.
597 *
598 * Note that it's a bit different for whatever is in the AGP slot.
599 * For now, I don't care, but this can become a real issue, we
600 * should probably hook pci_set_mwi anyway to make sure it sets
601 * the real cache line size in there.
602 */
603 if (machine_is_compatible("MacRISC4"))
604 pci_cache_line_size = 16; /* 64 bytes */
605
606 pmac_check_ht_link();
607#endif /* CONFIG_POWER4 */
608}
609
610#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
611 | (((o) & ~3) << 24))
612
613#define GRACKLE_PICR1_STG 0x00000040
614#define GRACKLE_PICR1_LOOPSNOOP 0x00000010
615
616/* N.B. this is called before bridges is initialized, so we can't
617 use grackle_pcibios_{read,write}_config_dword. */
618static inline void grackle_set_stg(struct pci_controller* bp, int enable)
619{
620 unsigned int val;
621
622 out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
623 val = in_le32(bp->cfg_data);
624 val = enable? (val | GRACKLE_PICR1_STG) :
625 (val & ~GRACKLE_PICR1_STG);
626 out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
627 out_le32(bp->cfg_data, val);
628 (void)in_le32(bp->cfg_data);
629}
630
631static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable)
632{
633 unsigned int val;
634
635 out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
636 val = in_le32(bp->cfg_data);
637 val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
638 (val & ~GRACKLE_PICR1_LOOPSNOOP);
639 out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
640 out_le32(bp->cfg_data, val);
641 (void)in_le32(bp->cfg_data);
642}
643
644static int __init
645setup_uninorth(struct pci_controller* hose, struct reg_property* addr)
646{
647 pci_assign_all_busses = 1;
648 has_uninorth = 1;
649 hose->ops = &macrisc_pci_ops;
650 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
651 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
652 /* We "know" that the bridge at f2000000 has the PCI slots. */
653 return addr->address == 0xf2000000;
654}
655
656static void __init
657setup_bandit(struct pci_controller* hose, struct reg_property* addr)
658{
659 hose->ops = &macrisc_pci_ops;
660 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
661 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
662 init_bandit(hose);
663}
664
665static void __init
666setup_chaos(struct pci_controller* hose, struct reg_property* addr)
667{
668 /* assume a `chaos' bridge */
669 hose->ops = &chaos_pci_ops;
670 hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
671 hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
672}
673
674#ifdef CONFIG_POWER4
675
676static void __init
677setup_u3_agp(struct pci_controller* hose, struct reg_property* addr)
678{
679 /* On G5, we move AGP up to high bus number so we don't need
680 * to reassign bus numbers for HT. If we ever have P2P bridges
681 * on AGP, we'll have to move pci_assign_all_busses to the
682 * pci_controller structure so we enable it for AGP and not for
683 * HT childs.
684 * We hard code the address because of the different size of
685 * the reg address cell, we shall fix that by killing struct
686 * reg_property and using some accessor functions instead
687 */
688 hose->first_busno = 0xf0;
689 hose->last_busno = 0xff;
690 has_uninorth = 1;
691 hose->ops = &macrisc_pci_ops;
692 hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
693 hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
694
695 u3_agp = hose;
696}
697
698static void __init
699setup_u3_ht(struct pci_controller* hose, struct reg_property *addr)
700{
701 struct device_node *np = (struct device_node *)hose->arch_data;
702 int i, cur;
703
704 hose->ops = &u3_ht_pci_ops;
705
706 /* We hard code the address because of the different size of
707 * the reg address cell, we shall fix that by killing struct
708 * reg_property and using some accessor functions instead
709 */
710 hose->cfg_data = ioremap(0xf2000000, 0x02000000);
711
712 /*
713 * /ht node doesn't expose a "ranges" property, so we "remove" regions that
714 * have been allocated to AGP. So far, this version of the code doesn't assign
715 * any of the 0xfxxxxxxx "fine" memory regions to /ht.
716 * We need to fix that sooner or later by either parsing all child "ranges"
717 * properties or figuring out the U3 address space decoding logic and
718 * then read its configuration register (if any).
719 */
720 hose->io_base_phys = 0xf4000000;
721 hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
722 isa_io_base = (unsigned long) hose->io_base_virt;
723 hose->io_resource.name = np->full_name;
724 hose->io_resource.start = 0;
725 hose->io_resource.end = 0x003fffff;
726 hose->io_resource.flags = IORESOURCE_IO;
727 hose->pci_mem_offset = 0;
728 hose->first_busno = 0;
729 hose->last_busno = 0xef;
730 hose->mem_resources[0].name = np->full_name;
731 hose->mem_resources[0].start = 0x80000000;
732 hose->mem_resources[0].end = 0xefffffff;
733 hose->mem_resources[0].flags = IORESOURCE_MEM;
734
735 if (u3_agp == NULL) {
736 DBG("U3 has no AGP, using full resource range\n");
737 return;
738 }
739
740 /* We "remove" the AGP resources from the resources allocated to HT, that
741 * is we create "holes". However, that code does assumptions that so far
742 * happen to be true (cross fingers...), typically that resources in the
743 * AGP node are properly ordered
744 */
745 cur = 0;
746 for (i=0; i<3; i++) {
747 struct resource *res = &u3_agp->mem_resources[i];
748 if (res->flags != IORESOURCE_MEM)
749 continue;
750 /* We don't care about "fine" resources */
751 if (res->start >= 0xf0000000)
752 continue;
753 /* Check if it's just a matter of "shrinking" us in one direction */
754 if (hose->mem_resources[cur].start == res->start) {
755 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
756 cur, hose->mem_resources[cur].start, res->end + 1);
757 hose->mem_resources[cur].start = res->end + 1;
758 continue;
759 }
760 if (hose->mem_resources[cur].end == res->end) {
761 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
762 cur, hose->mem_resources[cur].end, res->start - 1);
763 hose->mem_resources[cur].end = res->start - 1;
764 continue;
765 }
766 /* No, it's not the case, we need a hole */
767 if (cur == 2) {
768 /* not enough resources to make a hole, we drop part of the range */
769 printk(KERN_WARNING "Running out of resources for /ht host !\n");
770 hose->mem_resources[cur].end = res->start - 1;
771 continue;
772 }
773 cur++;
774 DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
775 cur-1, res->start - 1, cur, res->end + 1);
776 hose->mem_resources[cur].name = np->full_name;
777 hose->mem_resources[cur].flags = IORESOURCE_MEM;
778 hose->mem_resources[cur].start = res->end + 1;
779 hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
780 hose->mem_resources[cur-1].end = res->start - 1;
781 }
782}
783
784#endif /* CONFIG_POWER4 */
785
786void __init
787setup_grackle(struct pci_controller *hose)
788{
789 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
790 if (machine_is_compatible("AAPL,PowerBook1998"))
791 grackle_set_loop_snoop(hose, 1);
792#if 0 /* Disabled for now, HW problems ??? */
793 grackle_set_stg(hose, 1);
794#endif
795}
796
797/*
798 * We assume that if we have a G3 powermac, we have one bridge called
799 * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
800 * if we have one or more bandit or chaos bridges, we don't have a MPC106.
801 */
802static int __init
803add_bridge(struct device_node *dev)
804{
805 int len;
806 struct pci_controller *hose;
807 struct reg_property *addr;
808 char* disp_name;
809 int *bus_range;
810 int primary = 1;
811
812 DBG("Adding PCI host bridge %s\n", dev->full_name);
813
814 addr = (struct reg_property *) get_property(dev, "reg", &len);
815 if (addr == NULL || len < sizeof(*addr)) {
816 printk(KERN_WARNING "Can't use %s: no address\n",
817 dev->full_name);
818 return -ENODEV;
819 }
820 bus_range = (int *) get_property(dev, "bus-range", &len);
821 if (bus_range == NULL || len < 2 * sizeof(int)) {
822 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
823 dev->full_name);
824 }
825
826 hose = pcibios_alloc_controller();
827 if (!hose)
828 return -ENOMEM;
829 hose->arch_data = dev;
830 hose->first_busno = bus_range ? bus_range[0] : 0;
831 hose->last_busno = bus_range ? bus_range[1] : 0xff;
832
833 disp_name = NULL;
834#ifdef CONFIG_POWER4
835 if (device_is_compatible(dev, "u3-agp")) {
836 setup_u3_agp(hose, addr);
837 disp_name = "U3-AGP";
838 primary = 0;
839 } else if (device_is_compatible(dev, "u3-ht")) {
840 setup_u3_ht(hose, addr);
841 disp_name = "U3-HT";
842 primary = 1;
843 } else
844#endif /* CONFIG_POWER4 */
845 if (device_is_compatible(dev, "uni-north")) {
846 primary = setup_uninorth(hose, addr);
847 disp_name = "UniNorth";
848 } else if (strcmp(dev->name, "pci") == 0) {
849 /* XXX assume this is a mpc106 (grackle) */
850 setup_grackle(hose);
851 disp_name = "Grackle (MPC106)";
852 } else if (strcmp(dev->name, "bandit") == 0) {
853 setup_bandit(hose, addr);
854 disp_name = "Bandit";
855 } else if (strcmp(dev->name, "chaos") == 0) {
856 setup_chaos(hose, addr);
857 disp_name = "Chaos";
858 primary = 0;
859 }
860 printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
861 disp_name, addr->address, hose->first_busno, hose->last_busno);
862 DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
863 hose, hose->cfg_addr, hose->cfg_data);
864
865 /* Interpret the "ranges" property */
866 /* This also maps the I/O region and sets isa_io/mem_base */
867 pci_process_bridge_OF_ranges(hose, dev, primary);
868
869 /* Fixup "bus-range" OF property */
870 fixup_bus_range(dev);
871
872 return 0;
873}
874
875static void __init
876pcibios_fixup_OF_interrupts(void)
877{
878 struct pci_dev* dev = NULL;
879
880 /*
881 * Open Firmware often doesn't initialize the
882 * PCI_INTERRUPT_LINE config register properly, so we
883 * should find the device node and apply the interrupt
884 * obtained from the OF device-tree
885 */
886 for_each_pci_dev(dev) {
887 struct device_node *node;
888 node = pci_device_to_OF_node(dev);
889 /* this is the node, see if it has interrupts */
890 if (node && node->n_intrs > 0)
891 dev->irq = node->intrs[0].line;
892 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
893 }
894}
895
896void __init
897pmac_pcibios_fixup(void)
898{
899 /* Fixup interrupts according to OF tree */
900 pcibios_fixup_OF_interrupts();
901}
902
903int __pmac
904pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
905{
906 struct device_node* node;
907 int updatecfg = 0;
908 int uninorth_child;
909
910 node = pci_device_to_OF_node(dev);
911
912 /* We don't want to enable USB controllers absent from the OF tree
913 * (iBook second controller)
914 */
915 if (dev->vendor == PCI_VENDOR_ID_APPLE
916 && (dev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10))
917 && !node) {
918 printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
919 pci_name(dev));
920 return -EINVAL;
921 }
922
923 if (!node)
924 return 0;
925
926 uninorth_child = node->parent &&
927 device_is_compatible(node->parent, "uni-north");
928
929 /* Firewire & GMAC were disabled after PCI probe, the driver is
930 * claiming them, we must re-enable them now.
931 */
932 if (uninorth_child && !strcmp(node->name, "firewire") &&
933 (device_is_compatible(node, "pci106b,18") ||
934 device_is_compatible(node, "pci106b,30") ||
935 device_is_compatible(node, "pci11c1,5811"))) {
936 pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
937 pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
938 updatecfg = 1;
939 }
940 if (uninorth_child && !strcmp(node->name, "ethernet") &&
941 device_is_compatible(node, "gmac")) {
942 pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
943 updatecfg = 1;
944 }
945
946 if (updatecfg) {
947 u16 cmd;
948
949 /*
950 * Make sure PCI is correctly configured
951 *
952 * We use old pci_bios versions of the function since, by
953 * default, gmac is not powered up, and so will be absent
954 * from the kernel initial PCI lookup.
955 *
956 * Should be replaced by 2.4 new PCI mechanisms and really
957 * register the device.
958 */
959 pci_read_config_word(dev, PCI_COMMAND, &cmd);
960 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
961 pci_write_config_word(dev, PCI_COMMAND, cmd);
962 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
963 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cache_line_size);
964 }
965
966 return 0;
967}
968
969/* We power down some devices after they have been probed. They'll
970 * be powered back on later on
971 */
972void __init
973pmac_pcibios_after_init(void)
974{
975 struct device_node* nd;
976
977#ifdef CONFIG_BLK_DEV_IDE
978 struct pci_dev *dev = NULL;
979
980 /* OF fails to initialize IDE controllers on macs
981 * (and maybe other machines)
982 *
983 * Ideally, this should be moved to the IDE layer, but we need
984 * to check specifically with Andre Hedrick how to do it cleanly
985 * since the common IDE code seem to care about the fact that the
986 * BIOS may have disabled a controller.
987 *
988 * -- BenH
989 */
990 for_each_pci_dev(dev) {
991 if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
992 pci_enable_device(dev);
993 }
994#endif /* CONFIG_BLK_DEV_IDE */
995
996 nd = find_devices("firewire");
997 while (nd) {
998 if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
999 device_is_compatible(nd, "pci106b,30") ||
1000 device_is_compatible(nd, "pci11c1,5811"))
1001 && device_is_compatible(nd->parent, "uni-north")) {
1002 pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
1003 pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
1004 }
1005 nd = nd->next;
1006 }
1007 nd = find_devices("ethernet");
1008 while (nd) {
1009 if (nd->parent && device_is_compatible(nd, "gmac")
1010 && device_is_compatible(nd->parent, "uni-north"))
1011 pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
1012 nd = nd->next;
1013 }
1014}
1015
1016void pmac_pci_fixup_cardbus(struct pci_dev* dev)
1017{
1018 if (_machine != _MACH_Pmac)
1019 return;
1020 /*
1021 * Fix the interrupt routing on the various cardbus bridges
1022 * used on powerbooks
1023 */
1024 if (dev->vendor != PCI_VENDOR_ID_TI)
1025 return;
1026 if (dev->device == PCI_DEVICE_ID_TI_1130 ||
1027 dev->device == PCI_DEVICE_ID_TI_1131) {
1028 u8 val;
1029 /* Enable PCI interrupt */
1030 if (pci_read_config_byte(dev, 0x91, &val) == 0)
1031 pci_write_config_byte(dev, 0x91, val | 0x30);
1032 /* Disable ISA interrupt mode */
1033 if (pci_read_config_byte(dev, 0x92, &val) == 0)
1034 pci_write_config_byte(dev, 0x92, val & ~0x06);
1035 }
1036 if (dev->device == PCI_DEVICE_ID_TI_1210 ||
1037 dev->device == PCI_DEVICE_ID_TI_1211 ||
1038 dev->device == PCI_DEVICE_ID_TI_1410 ||
1039 dev->device == PCI_DEVICE_ID_TI_1510) {
1040 u8 val;
1041 /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
1042 signal out the MFUNC0 pin */
1043 if (pci_read_config_byte(dev, 0x8c, &val) == 0)
1044 pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
1045 /* Disable ISA interrupt mode */
1046 if (pci_read_config_byte(dev, 0x92, &val) == 0)
1047 pci_write_config_byte(dev, 0x92, val & ~0x06);
1048 }
1049}
1050
1051DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
1052
1053void pmac_pci_fixup_pciata(struct pci_dev* dev)
1054{
1055 u8 progif = 0;
1056
1057 /*
1058 * On PowerMacs, we try to switch any PCI ATA controller to
1059 * fully native mode
1060 */
1061 if (_machine != _MACH_Pmac)
1062 return;
1063 /* Some controllers don't have the class IDE */
1064 if (dev->vendor == PCI_VENDOR_ID_PROMISE)
1065 switch(dev->device) {
1066 case PCI_DEVICE_ID_PROMISE_20246:
1067 case PCI_DEVICE_ID_PROMISE_20262:
1068 case PCI_DEVICE_ID_PROMISE_20263:
1069 case PCI_DEVICE_ID_PROMISE_20265:
1070 case PCI_DEVICE_ID_PROMISE_20267:
1071 case PCI_DEVICE_ID_PROMISE_20268:
1072 case PCI_DEVICE_ID_PROMISE_20269:
1073 case PCI_DEVICE_ID_PROMISE_20270:
1074 case PCI_DEVICE_ID_PROMISE_20271:
1075 case PCI_DEVICE_ID_PROMISE_20275:
1076 case PCI_DEVICE_ID_PROMISE_20276:
1077 case PCI_DEVICE_ID_PROMISE_20277:
1078 goto good;
1079 }
1080 /* Others, check PCI class */
1081 if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
1082 return;
1083 good:
1084 pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
1085 if ((progif & 5) != 5) {
1086 printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev));
1087 (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
1088 if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
1089 (progif & 5) != 5)
1090 printk(KERN_ERR "Rewrite of PROGIF failed !\n");
1091 }
1092}
1093DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
1094
1095
1096/*
1097 * Disable second function on K2-SATA, it's broken
1098 * and disable IO BARs on first one
1099 */
1100void __pmac pmac_pci_fixup_k2_sata(struct pci_dev* dev)
1101{
1102 int i;
1103 u16 cmd;
1104
1105 if (PCI_FUNC(dev->devfn) > 0) {
1106 pci_read_config_word(dev, PCI_COMMAND, &cmd);
1107 cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1108 pci_write_config_word(dev, PCI_COMMAND, cmd);
1109 for (i = 0; i < 6; i++) {
1110 dev->resource[i].start = dev->resource[i].end = 0;
1111 dev->resource[i].flags = 0;
1112 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
1113 }
1114 } else {
1115 pci_read_config_word(dev, PCI_COMMAND, &cmd);
1116 cmd &= ~PCI_COMMAND_IO;
1117 pci_write_config_word(dev, PCI_COMMAND, cmd);
1118 for (i = 0; i < 5; i++) {
1119 dev->resource[i].start = dev->resource[i].end = 0;
1120 dev->resource[i].flags = 0;
1121 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0);
1122 }
1123 }
1124}
1125DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, pmac_pci_fixup_k2_sata);
diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
new file mode 100644
index 000000000000..9f92e1bb7f34
--- /dev/null
+++ b/arch/ppc/platforms/pmac_pic.c
@@ -0,0 +1,689 @@
1/*
2 * Support for the interrupt controllers found on Power Macintosh,
3 * currently Apple's "Grand Central" interrupt controller in all
4 * it's incarnations. OpenPIC support used on newer machines is
5 * in a separate file
6 *
7 * Copyright (C) 1997 Paul Mackerras (paulus@cs.anu.edu.au)
8 *
9 * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 *
16 */
17
18#include <linux/config.h>
19#include <linux/stddef.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/signal.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25#include <linux/sysdev.h>
26#include <linux/adb.h>
27#include <linux/pmu.h>
28
29#include <asm/sections.h>
30#include <asm/io.h>
31#include <asm/smp.h>
32#include <asm/prom.h>
33#include <asm/pci-bridge.h>
34#include <asm/time.h>
35#include <asm/open_pic.h>
36#include <asm/xmon.h>
37#include <asm/pmac_feature.h>
38
39#include "pmac_pic.h"
40
41/*
42 * XXX this should be in xmon.h, but putting it there means xmon.h
43 * has to include <linux/interrupt.h> (to get irqreturn_t), which
44 * causes all sorts of problems. -- paulus
45 */
46extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
47
48struct pmac_irq_hw {
49 unsigned int event;
50 unsigned int enable;
51 unsigned int ack;
52 unsigned int level;
53};
54
55/* Default addresses */
56static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = {
57 (struct pmac_irq_hw *) 0xf3000020,
58 (struct pmac_irq_hw *) 0xf3000010,
59 (struct pmac_irq_hw *) 0xf4000020,
60 (struct pmac_irq_hw *) 0xf4000010,
61};
62
63#define GC_LEVEL_MASK 0x3ff00000
64#define OHARE_LEVEL_MASK 0x1ff00000
65#define HEATHROW_LEVEL_MASK 0x1ff00000
66
67static int max_irqs __pmacdata;
68static int max_real_irqs __pmacdata;
69static u32 level_mask[4] __pmacdata;
70
71static DEFINE_SPINLOCK(pmac_pic_lock __pmacdata);
72
73
74#define GATWICK_IRQ_POOL_SIZE 10
75static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata;
76
77/*
78 * Mark an irq as "lost". This is only used on the pmac
79 * since it can lose interrupts (see pmac_set_irq_mask).
80 * -- Cort
81 */
82void __pmac
83__set_lost(unsigned long irq_nr, int nokick)
84{
85 if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
86 atomic_inc(&ppc_n_lost_interrupts);
87 if (!nokick)
88 set_dec(1);
89 }
90}
91
92static void __pmac
93pmac_mask_and_ack_irq(unsigned int irq_nr)
94{
95 unsigned long bit = 1UL << (irq_nr & 0x1f);
96 int i = irq_nr >> 5;
97 unsigned long flags;
98
99 if ((unsigned)irq_nr >= max_irqs)
100 return;
101
102 clear_bit(irq_nr, ppc_cached_irq_mask);
103 if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
104 atomic_dec(&ppc_n_lost_interrupts);
105 spin_lock_irqsave(&pmac_pic_lock, flags);
106 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
107 out_le32(&pmac_irq_hw[i]->ack, bit);
108 do {
109 /* make sure ack gets to controller before we enable
110 interrupts */
111 mb();
112 } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
113 != (ppc_cached_irq_mask[i] & bit));
114 spin_unlock_irqrestore(&pmac_pic_lock, flags);
115}
116
117static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
118{
119 unsigned long bit = 1UL << (irq_nr & 0x1f);
120 int i = irq_nr >> 5;
121 unsigned long flags;
122
123 if ((unsigned)irq_nr >= max_irqs)
124 return;
125
126 spin_lock_irqsave(&pmac_pic_lock, flags);
127 /* enable unmasked interrupts */
128 out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
129
130 do {
131 /* make sure mask gets to controller before we
132 return to user */
133 mb();
134 } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
135 != (ppc_cached_irq_mask[i] & bit));
136
137 /*
138 * Unfortunately, setting the bit in the enable register
139 * when the device interrupt is already on *doesn't* set
140 * the bit in the flag register or request another interrupt.
141 */
142 if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
143 __set_lost((ulong)irq_nr, nokicklost);
144 spin_unlock_irqrestore(&pmac_pic_lock, flags);
145}
146
147/* When an irq gets requested for the first client, if it's an
148 * edge interrupt, we clear any previous one on the controller
149 */
150static unsigned int __pmac pmac_startup_irq(unsigned int irq_nr)
151{
152 unsigned long bit = 1UL << (irq_nr & 0x1f);
153 int i = irq_nr >> 5;
154
155 if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
156 out_le32(&pmac_irq_hw[i]->ack, bit);
157 set_bit(irq_nr, ppc_cached_irq_mask);
158 pmac_set_irq_mask(irq_nr, 0);
159
160 return 0;
161}
162
163static void __pmac pmac_mask_irq(unsigned int irq_nr)
164{
165 clear_bit(irq_nr, ppc_cached_irq_mask);
166 pmac_set_irq_mask(irq_nr, 0);
167 mb();
168}
169
170static void __pmac pmac_unmask_irq(unsigned int irq_nr)
171{
172 set_bit(irq_nr, ppc_cached_irq_mask);
173 pmac_set_irq_mask(irq_nr, 0);
174}
175
176static void __pmac pmac_end_irq(unsigned int irq_nr)
177{
178 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
179 && irq_desc[irq_nr].action) {
180 set_bit(irq_nr, ppc_cached_irq_mask);
181 pmac_set_irq_mask(irq_nr, 1);
182 }
183}
184
185
186struct hw_interrupt_type pmac_pic = {
187 .typename = " PMAC-PIC ",
188 .startup = pmac_startup_irq,
189 .enable = pmac_unmask_irq,
190 .disable = pmac_mask_irq,
191 .ack = pmac_mask_and_ack_irq,
192 .end = pmac_end_irq,
193};
194
195struct hw_interrupt_type gatwick_pic = {
196 .typename = " GATWICK ",
197 .startup = pmac_startup_irq,
198 .enable = pmac_unmask_irq,
199 .disable = pmac_mask_irq,
200 .ack = pmac_mask_and_ack_irq,
201 .end = pmac_end_irq,
202};
203
204static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
205{
206 int irq, bits;
207
208 for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
209 int i = irq >> 5;
210 bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
211 /* We must read level interrupts from the level register */
212 bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
213 bits &= ppc_cached_irq_mask[i];
214 if (bits == 0)
215 continue;
216 irq += __ilog2(bits);
217 __do_IRQ(irq, regs);
218 return IRQ_HANDLED;
219 }
220 printk("gatwick irq not from gatwick pic\n");
221 return IRQ_NONE;
222}
223
224int
225pmac_get_irq(struct pt_regs *regs)
226{
227 int irq;
228 unsigned long bits = 0;
229
230#ifdef CONFIG_SMP
231 void psurge_smp_message_recv(struct pt_regs *);
232
233 /* IPI's are a hack on the powersurge -- Cort */
234 if ( smp_processor_id() != 0 ) {
235 psurge_smp_message_recv(regs);
236 return -2; /* ignore, already handled */
237 }
238#endif /* CONFIG_SMP */
239 for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
240 int i = irq >> 5;
241 bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
242 /* We must read level interrupts from the level register */
243 bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]);
244 bits &= ppc_cached_irq_mask[i];
245 if (bits == 0)
246 continue;
247 irq += __ilog2(bits);
248 break;
249 }
250
251 return irq;
252}
253
254/* This routine will fix some missing interrupt values in the device tree
255 * on the gatwick mac-io controller used by some PowerBooks
256 */
257static void __init
258pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
259{
260 struct device_node *node;
261 int count;
262
263 memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
264 node = gw->child;
265 count = 0;
266 while(node)
267 {
268 /* Fix SCC */
269 if (strcasecmp(node->name, "escc") == 0)
270 if (node->child) {
271 if (node->child->n_intrs < 3) {
272 node->child->intrs = &gatwick_int_pool[count];
273 count += 3;
274 }
275 node->child->n_intrs = 3;
276 node->child->intrs[0].line = 15+irq_base;
277 node->child->intrs[1].line = 4+irq_base;
278 node->child->intrs[2].line = 5+irq_base;
279 printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
280 node->child->intrs[0].line,
281 node->child->intrs[1].line,
282 node->child->intrs[2].line);
283 }
284 /* Fix media-bay & left SWIM */
285 if (strcasecmp(node->name, "media-bay") == 0) {
286 struct device_node* ya_node;
287
288 if (node->n_intrs == 0)
289 node->intrs = &gatwick_int_pool[count++];
290 node->n_intrs = 1;
291 node->intrs[0].line = 29+irq_base;
292 printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
293 node->intrs[0].line);
294
295 ya_node = node->child;
296 while(ya_node)
297 {
298 if (strcasecmp(ya_node->name, "floppy") == 0) {
299 if (ya_node->n_intrs < 2) {
300 ya_node->intrs = &gatwick_int_pool[count];
301 count += 2;
302 }
303 ya_node->n_intrs = 2;
304 ya_node->intrs[0].line = 19+irq_base;
305 ya_node->intrs[1].line = 1+irq_base;
306 printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
307 ya_node->intrs[0].line, ya_node->intrs[1].line);
308 }
309 if (strcasecmp(ya_node->name, "ata4") == 0) {
310 if (ya_node->n_intrs < 2) {
311 ya_node->intrs = &gatwick_int_pool[count];
312 count += 2;
313 }
314 ya_node->n_intrs = 2;
315 ya_node->intrs[0].line = 14+irq_base;
316 ya_node->intrs[1].line = 3+irq_base;
317 printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
318 ya_node->intrs[0].line, ya_node->intrs[1].line);
319 }
320 ya_node = ya_node->sibling;
321 }
322 }
323 node = node->sibling;
324 }
325 if (count > 10) {
326 printk("WARNING !! Gatwick interrupt pool overflow\n");
327 printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
328 printk(" requested = %d\n", count);
329 }
330}
331
332/*
333 * The PowerBook 3400/2400/3500 can have a combo ethernet/modem
334 * card which includes an ohare chip that acts as a second interrupt
335 * controller. If we find this second ohare, set it up and fix the
336 * interrupt value in the device tree for the ethernet chip.
337 */
338static int __init enable_second_ohare(void)
339{
340 unsigned char bus, devfn;
341 unsigned short cmd;
342 unsigned long addr;
343 struct device_node *irqctrler = find_devices("pci106b,7");
344 struct device_node *ether;
345
346 if (irqctrler == NULL || irqctrler->n_addrs <= 0)
347 return -1;
348 addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40);
349 pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20);
350 max_irqs = 64;
351 if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) {
352 struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler);
353 if (!hose)
354 printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
355 else {
356 early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
357 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
358 cmd &= ~PCI_COMMAND_IO;
359 early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
360 }
361 }
362
363 /* Fix interrupt for the modem/ethernet combo controller. The number
364 in the device tree (27) is bogus (correct for the ethernet-only
365 board but not the combo ethernet/modem board).
366 The real interrupt is 28 on the second controller -> 28+32 = 60.
367 */
368 ether = find_devices("pci1011,14");
369 if (ether && ether->n_intrs > 0) {
370 ether->intrs[0].line = 60;
371 printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n",
372 ether->intrs[0].line);
373 }
374
375 /* Return the interrupt number of the cascade */
376 return irqctrler->intrs[0].line;
377}
378
379#ifdef CONFIG_POWER4
380static irqreturn_t k2u3_action(int cpl, void *dev_id, struct pt_regs *regs)
381{
382 int irq;
383
384 irq = openpic2_get_irq(regs);
385 if (irq != -1)
386 __do_IRQ(irq, regs);
387 return IRQ_HANDLED;
388}
389
390static struct irqaction k2u3_cascade_action = {
391 .handler = k2u3_action,
392 .flags = 0,
393 .mask = CPU_MASK_NONE,
394 .name = "U3->K2 Cascade",
395};
396#endif /* CONFIG_POWER4 */
397
398#ifdef CONFIG_XMON
399static struct irqaction xmon_action = {
400 .handler = xmon_irq,
401 .flags = 0,
402 .mask = CPU_MASK_NONE,
403 .name = "NMI - XMON"
404};
405#endif
406
407static struct irqaction gatwick_cascade_action = {
408 .handler = gatwick_action,
409 .flags = SA_INTERRUPT,
410 .mask = CPU_MASK_NONE,
411 .name = "cascade",
412};
413
414void __init pmac_pic_init(void)
415{
416 int i;
417 struct device_node *irqctrler = NULL;
418 struct device_node *irqctrler2 = NULL;
419 struct device_node *np;
420 unsigned long addr;
421 int irq_cascade = -1;
422
423 /* We first try to detect Apple's new Core99 chipset, since mac-io
424 * is quite different on those machines and contains an IBM MPIC2.
425 */
426 np = find_type_devices("open-pic");
427 while(np) {
428 if (np->parent && !strcmp(np->parent->name, "u3"))
429 irqctrler2 = np;
430 else
431 irqctrler = np;
432 np = np->next;
433 }
434 if (irqctrler != NULL)
435 {
436 if (irqctrler->n_addrs > 0)
437 {
438 unsigned char senses[128];
439
440 printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n",
441 irqctrler->addrs[0].address);
442
443 prom_get_irq_senses(senses, 0, 128);
444 OpenPIC_InitSenses = senses;
445 OpenPIC_NumInitSenses = 128;
446 ppc_md.get_irq = openpic_get_irq;
447 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0);
448 OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
449 irqctrler->addrs[0].size);
450 openpic_init(0);
451
452#ifdef CONFIG_POWER4
453 if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 &&
454 irqctrler2->n_addrs > 0) {
455 printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n",
456 irqctrler2->addrs[0].address,
457 irqctrler2->intrs[0].line);
458 pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
459 OpenPIC2_Addr = ioremap(irqctrler2->addrs[0].address,
460 irqctrler2->addrs[0].size);
461 prom_get_irq_senses(senses, PMAC_OPENPIC2_OFFSET,
462 PMAC_OPENPIC2_OFFSET+128);
463 OpenPIC_InitSenses = senses;
464 OpenPIC_NumInitSenses = 128;
465 openpic2_init(PMAC_OPENPIC2_OFFSET);
466
467 if (setup_irq(irqctrler2->intrs[0].line,
468 &k2u3_cascade_action))
469 printk("Unable to get OpenPIC IRQ for cascade\n");
470 }
471#endif /* CONFIG_POWER4 */
472
473#ifdef CONFIG_XMON
474 {
475 struct device_node* pswitch;
476 int nmi_irq;
477
478 pswitch = find_devices("programmer-switch");
479 if (pswitch && pswitch->n_intrs) {
480 nmi_irq = pswitch->intrs[0].line;
481 openpic_init_nmi_irq(nmi_irq);
482 setup_irq(nmi_irq, &xmon_action);
483 }
484 }
485#endif /* CONFIG_XMON */
486 return;
487 }
488 irqctrler = NULL;
489 }
490
491 /* Get the level/edge settings, assume if it's not
492 * a Grand Central nor an OHare, then it's an Heathrow
493 * (or Paddington).
494 */
495 if (find_devices("gc"))
496 level_mask[0] = GC_LEVEL_MASK;
497 else if (find_devices("ohare")) {
498 level_mask[0] = OHARE_LEVEL_MASK;
499 /* We might have a second cascaded ohare */
500 level_mask[1] = OHARE_LEVEL_MASK;
501 } else {
502 level_mask[0] = HEATHROW_LEVEL_MASK;
503 level_mask[1] = 0;
504 /* We might have a second cascaded heathrow */
505 level_mask[2] = HEATHROW_LEVEL_MASK;
506 level_mask[3] = 0;
507 }
508
509 /*
510 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
511 * 1998 G3 Series PowerBooks have 128,
512 * other powermacs have 32.
513 * The combo ethernet/modem card for the Powerstar powerbooks
514 * (2400/3400/3500, ohare based) has a second ohare chip
515 * effectively making a total of 64.
516 */
517 max_irqs = max_real_irqs = 32;
518 irqctrler = find_devices("mac-io");
519 if (irqctrler)
520 {
521 max_real_irqs = 64;
522 if (irqctrler->next)
523 max_irqs = 128;
524 else
525 max_irqs = 64;
526 }
527 for ( i = 0; i < max_real_irqs ; i++ )
528 irq_desc[i].handler = &pmac_pic;
529
530 /* get addresses of first controller */
531 if (irqctrler) {
532 if (irqctrler->n_addrs > 0) {
533 addr = (unsigned long)
534 ioremap(irqctrler->addrs[0].address, 0x40);
535 for (i = 0; i < 2; ++i)
536 pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
537 (addr + (2 - i) * 0x10);
538 }
539
540 /* get addresses of second controller */
541 irqctrler = irqctrler->next;
542 if (irqctrler && irqctrler->n_addrs > 0) {
543 addr = (unsigned long)
544 ioremap(irqctrler->addrs[0].address, 0x40);
545 for (i = 2; i < 4; ++i)
546 pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
547 (addr + (4 - i) * 0x10);
548 irq_cascade = irqctrler->intrs[0].line;
549 if (device_is_compatible(irqctrler, "gatwick"))
550 pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
551 }
552 } else {
553 /* older powermacs have a GC (grand central) or ohare at
554 f3000000, with interrupt control registers at f3000020. */
555 addr = (unsigned long) ioremap(0xf3000000, 0x40);
556 pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20);
557 }
558
559 /* PowerBooks 3400 and 3500 can have a second controller in a second
560 ohare chip, on the combo ethernet/modem card */
561 if (machine_is_compatible("AAPL,3400/2400")
562 || machine_is_compatible("AAPL,3500"))
563 irq_cascade = enable_second_ohare();
564
565 /* disable all interrupts in all controllers */
566 for (i = 0; i * 32 < max_irqs; ++i)
567 out_le32(&pmac_irq_hw[i]->enable, 0);
568 /* mark level interrupts */
569 for (i = 0; i < max_irqs; i++)
570 if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
571 irq_desc[i].status = IRQ_LEVEL;
572
573 /* get interrupt line of secondary interrupt controller */
574 if (irq_cascade >= 0) {
575 printk(KERN_INFO "irq: secondary controller on irq %d\n",
576 (int)irq_cascade);
577 for ( i = max_real_irqs ; i < max_irqs ; i++ )
578 irq_desc[i].handler = &gatwick_pic;
579 setup_irq(irq_cascade, &gatwick_cascade_action);
580 }
581 printk("System has %d possible interrupts\n", max_irqs);
582 if (max_irqs != max_real_irqs)
583 printk(KERN_DEBUG "%d interrupts on main controller\n",
584 max_real_irqs);
585
586#ifdef CONFIG_XMON
587 setup_irq(20, &xmon_action);
588#endif /* CONFIG_XMON */
589}
590
591#ifdef CONFIG_PM
592/*
593 * These procedures are used in implementing sleep on the powerbooks.
594 * sleep_save_intrs() saves the states of all interrupt enables
595 * and disables all interrupts except for the nominated one.
596 * sleep_restore_intrs() restores the states of all interrupt enables.
597 */
598unsigned long sleep_save_mask[2];
599
600/* This used to be passed by the PMU driver but that link got
601 * broken with the new driver model. We use this tweak for now...
602 */
603static int pmacpic_find_viaint(void)
604{
605 int viaint = -1;
606
607#ifdef CONFIG_ADB_PMU
608 struct device_node *np;
609
610 if (pmu_get_model() != PMU_OHARE_BASED)
611 goto not_found;
612 np = of_find_node_by_name(NULL, "via-pmu");
613 if (np == NULL)
614 goto not_found;
615 viaint = np->intrs[0].line;
616#endif /* CONFIG_ADB_PMU */
617
618not_found:
619 return viaint;
620}
621
622static int pmacpic_suspend(struct sys_device *sysdev, u32 state)
623{
624 int viaint = pmacpic_find_viaint();
625
626 sleep_save_mask[0] = ppc_cached_irq_mask[0];
627 sleep_save_mask[1] = ppc_cached_irq_mask[1];
628 ppc_cached_irq_mask[0] = 0;
629 ppc_cached_irq_mask[1] = 0;
630 if (viaint > 0)
631 set_bit(viaint, ppc_cached_irq_mask);
632 out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
633 if (max_real_irqs > 32)
634 out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
635 (void)in_le32(&pmac_irq_hw[0]->event);
636 /* make sure mask gets to controller before we return to caller */
637 mb();
638 (void)in_le32(&pmac_irq_hw[0]->enable);
639
640 return 0;
641}
642
643static int pmacpic_resume(struct sys_device *sysdev)
644{
645 int i;
646
647 out_le32(&pmac_irq_hw[0]->enable, 0);
648 if (max_real_irqs > 32)
649 out_le32(&pmac_irq_hw[1]->enable, 0);
650 mb();
651 for (i = 0; i < max_real_irqs; ++i)
652 if (test_bit(i, sleep_save_mask))
653 pmac_unmask_irq(i);
654
655 return 0;
656}
657
658#endif /* CONFIG_PM */
659
660static struct sysdev_class pmacpic_sysclass = {
661 set_kset_name("pmac_pic"),
662};
663
664static struct sys_device device_pmacpic = {
665 .id = 0,
666 .cls = &pmacpic_sysclass,
667};
668
669static struct sysdev_driver driver_pmacpic = {
670#ifdef CONFIG_PM
671 .suspend = &pmacpic_suspend,
672 .resume = &pmacpic_resume,
673#endif /* CONFIG_PM */
674};
675
676static int __init init_pmacpic_sysfs(void)
677{
678 if (max_irqs == 0)
679 return -ENODEV;
680
681 printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
682 sysdev_class_register(&pmacpic_sysclass);
683 sysdev_register(&device_pmacpic);
684 sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
685 return 0;
686}
687
688subsys_initcall(init_pmacpic_sysfs);
689
diff --git a/arch/ppc/platforms/pmac_pic.h b/arch/ppc/platforms/pmac_pic.h
new file mode 100644
index 000000000000..664103dfeef9
--- /dev/null
+++ b/arch/ppc/platforms/pmac_pic.h
@@ -0,0 +1,11 @@
1#ifndef __PPC_PLATFORMS_PMAC_PIC_H
2#define __PPC_PLATFORMS_PMAC_PIC_H
3
4#include <linux/irq.h>
5
6extern struct hw_interrupt_type pmac_pic;
7
8void pmac_pic_init(void);
9int pmac_get_irq(struct pt_regs *regs);
10
11#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
new file mode 100644
index 000000000000..4d324b630f4f
--- /dev/null
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -0,0 +1,745 @@
1/*
2 * arch/ppc/platforms/setup.c
3 *
4 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 * Adapted for Power Macintosh by Paul Mackerras
8 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
9 *
10 * Derived from "arch/alpha/kernel/setup.c"
11 * Copyright (C) 1995 Linus Torvalds
12 *
13 * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 *
20 */
21
22/*
23 * bootup setup stuff..
24 */
25
26#include <linux/config.h>
27#include <linux/init.h>
28#include <linux/errno.h>
29#include <linux/sched.h>
30#include <linux/kernel.h>
31#include <linux/mm.h>
32#include <linux/stddef.h>
33#include <linux/unistd.h>
34#include <linux/ptrace.h>
35#include <linux/slab.h>
36#include <linux/user.h>
37#include <linux/a.out.h>
38#include <linux/tty.h>
39#include <linux/string.h>
40#include <linux/delay.h>
41#include <linux/ioport.h>
42#include <linux/major.h>
43#include <linux/initrd.h>
44#include <linux/vt_kern.h>
45#include <linux/console.h>
46#include <linux/ide.h>
47#include <linux/pci.h>
48#include <linux/adb.h>
49#include <linux/cuda.h>
50#include <linux/pmu.h>
51#include <linux/irq.h>
52#include <linux/seq_file.h>
53#include <linux/root_dev.h>
54#include <linux/bitops.h>
55#include <linux/suspend.h>
56
57#include <asm/reg.h>
58#include <asm/sections.h>
59#include <asm/prom.h>
60#include <asm/system.h>
61#include <asm/pgtable.h>
62#include <asm/io.h>
63#include <asm/pci-bridge.h>
64#include <asm/ohare.h>
65#include <asm/mediabay.h>
66#include <asm/machdep.h>
67#include <asm/dma.h>
68#include <asm/bootx.h>
69#include <asm/cputable.h>
70#include <asm/btext.h>
71#include <asm/pmac_feature.h>
72#include <asm/time.h>
73#include <asm/of_device.h>
74#include <asm/mmu_context.h>
75
76#include "pmac_pic.h"
77#include "mem_pieces.h"
78
79#undef SHOW_GATWICK_IRQS
80
81extern long pmac_time_init(void);
82extern unsigned long pmac_get_rtc_time(void);
83extern int pmac_set_rtc_time(unsigned long nowtime);
84extern void pmac_read_rtc_time(void);
85extern void pmac_calibrate_decr(void);
86extern void pmac_pcibios_fixup(void);
87extern void pmac_find_bridges(void);
88extern unsigned long pmac_ide_get_base(int index);
89extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
90 unsigned long data_port, unsigned long ctrl_port, int *irq);
91
92extern void pmac_nvram_update(void);
93extern unsigned char pmac_nvram_read_byte(int addr);
94extern void pmac_nvram_write_byte(int addr, unsigned char val);
95extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
96extern void pmac_pcibios_after_init(void);
97extern int of_show_percpuinfo(struct seq_file *m, int i);
98
99struct device_node *memory_node;
100
101unsigned char drive_info;
102
103int ppc_override_l2cr = 0;
104int ppc_override_l2cr_value;
105int has_l2cache = 0;
106
107static int current_root_goodness = -1;
108
109extern int pmac_newworld;
110
111#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
112
113extern void zs_kgdb_hook(int tty_num);
114static void ohare_init(void);
115#ifdef CONFIG_BOOTX_TEXT
116void pmac_progress(char *s, unsigned short hex);
117#endif
118
119sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
120
121#ifdef CONFIG_SMP
122extern struct smp_ops_t psurge_smp_ops;
123extern struct smp_ops_t core99_smp_ops;
124#endif /* CONFIG_SMP */
125
126int __pmac
127pmac_show_cpuinfo(struct seq_file *m)
128{
129 struct device_node *np;
130 char *pp;
131 int plen;
132 int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
133 NULL, PMAC_MB_INFO_MODEL, 0);
134 unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
135 NULL, PMAC_MB_INFO_FLAGS, 0);
136 char* mbname;
137
138 if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
139 mbname = "Unknown";
140
141 /* find motherboard type */
142 seq_printf(m, "machine\t\t: ");
143 np = find_devices("device-tree");
144 if (np != NULL) {
145 pp = (char *) get_property(np, "model", NULL);
146 if (pp != NULL)
147 seq_printf(m, "%s\n", pp);
148 else
149 seq_printf(m, "PowerMac\n");
150 pp = (char *) get_property(np, "compatible", &plen);
151 if (pp != NULL) {
152 seq_printf(m, "motherboard\t:");
153 while (plen > 0) {
154 int l = strlen(pp) + 1;
155 seq_printf(m, " %s", pp);
156 plen -= l;
157 pp += l;
158 }
159 seq_printf(m, "\n");
160 }
161 } else
162 seq_printf(m, "PowerMac\n");
163
164 /* print parsed model */
165 seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
166 seq_printf(m, "pmac flags\t: %08x\n", mbflags);
167
168 /* find l2 cache info */
169 np = find_devices("l2-cache");
170 if (np == 0)
171 np = find_type_devices("cache");
172 if (np != 0) {
173 unsigned int *ic = (unsigned int *)
174 get_property(np, "i-cache-size", NULL);
175 unsigned int *dc = (unsigned int *)
176 get_property(np, "d-cache-size", NULL);
177 seq_printf(m, "L2 cache\t:");
178 has_l2cache = 1;
179 if (get_property(np, "cache-unified", NULL) != 0 && dc) {
180 seq_printf(m, " %dK unified", *dc / 1024);
181 } else {
182 if (ic)
183 seq_printf(m, " %dK instruction", *ic / 1024);
184 if (dc)
185 seq_printf(m, "%s %dK data",
186 (ic? " +": ""), *dc / 1024);
187 }
188 pp = get_property(np, "ram-type", NULL);
189 if (pp)
190 seq_printf(m, " %s", pp);
191 seq_printf(m, "\n");
192 }
193
194 /* find ram info */
195 np = find_devices("memory");
196 if (np != 0) {
197 int n;
198 struct reg_property *reg = (struct reg_property *)
199 get_property(np, "reg", &n);
200
201 if (reg != 0) {
202 unsigned long total = 0;
203
204 for (n /= sizeof(struct reg_property); n > 0; --n)
205 total += (reg++)->size;
206 seq_printf(m, "memory\t\t: %luMB\n", total >> 20);
207 }
208 }
209
210 /* Checks "l2cr-value" property in the registry */
211 np = find_devices("cpus");
212 if (np == 0)
213 np = find_type_devices("cpu");
214 if (np != 0) {
215 unsigned int *l2cr = (unsigned int *)
216 get_property(np, "l2cr-value", NULL);
217 if (l2cr != 0) {
218 seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr);
219 }
220 }
221
222 /* Indicate newworld/oldworld */
223 seq_printf(m, "pmac-generation\t: %s\n",
224 pmac_newworld ? "NewWorld" : "OldWorld");
225
226
227 return 0;
228}
229
230int __openfirmware
231pmac_show_percpuinfo(struct seq_file *m, int i)
232{
233#ifdef CONFIG_CPU_FREQ_PMAC
234 extern unsigned int pmac_get_one_cpufreq(int i);
235 unsigned int freq = pmac_get_one_cpufreq(i);
236 if (freq != 0) {
237 seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
238 return 0;
239 }
240#endif /* CONFIG_CPU_FREQ_PMAC */
241 return of_show_percpuinfo(m, i);
242}
243
244static volatile u32 *sysctrl_regs;
245
246void __init
247pmac_setup_arch(void)
248{
249 struct device_node *cpu;
250 int *fp;
251 unsigned long pvr;
252
253 pvr = PVR_VER(mfspr(SPRN_PVR));
254
255 /* Set loops_per_jiffy to a half-way reasonable value,
256 for use until calibrate_delay gets called. */
257 cpu = find_type_devices("cpu");
258 if (cpu != 0) {
259 fp = (int *) get_property(cpu, "clock-frequency", NULL);
260 if (fp != 0) {
261 if (pvr == 4 || pvr >= 8)
262 /* 604, G3, G4 etc. */
263 loops_per_jiffy = *fp / HZ;
264 else
265 /* 601, 603, etc. */
266 loops_per_jiffy = *fp / (2*HZ);
267 } else
268 loops_per_jiffy = 50000000 / HZ;
269 }
270
271 /* this area has the CPU identification register
272 and some registers used by smp boards */
273 sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
274 ohare_init();
275
276 /* Lookup PCI hosts */
277 pmac_find_bridges();
278
279 /* Checks "l2cr-value" property in the registry */
280 if (cpu_has_feature(CPU_FTR_L2CR)) {
281 struct device_node *np = find_devices("cpus");
282 if (np == 0)
283 np = find_type_devices("cpu");
284 if (np != 0) {
285 unsigned int *l2cr = (unsigned int *)
286 get_property(np, "l2cr-value", NULL);
287 if (l2cr != 0) {
288 ppc_override_l2cr = 1;
289 ppc_override_l2cr_value = *l2cr;
290 _set_L2CR(0);
291 _set_L2CR(ppc_override_l2cr_value);
292 }
293 }
294 }
295
296 if (ppc_override_l2cr)
297 printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
298 ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
299 ? "enabled" : "disabled");
300
301#ifdef CONFIG_KGDB
302 zs_kgdb_hook(0);
303#endif
304
305#ifdef CONFIG_ADB_CUDA
306 find_via_cuda();
307#else
308 if (find_devices("via-cuda")) {
309 printk("WARNING ! Your machine is Cuda based but your kernel\n");
310 printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
311 }
312#endif
313#ifdef CONFIG_ADB_PMU
314 find_via_pmu();
315#else
316 if (find_devices("via-pmu")) {
317 printk("WARNING ! Your machine is PMU based but your kernel\n");
318 printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
319 }
320#endif
321#ifdef CONFIG_NVRAM
322 pmac_nvram_init();
323#endif
324#ifdef CONFIG_BLK_DEV_INITRD
325 if (initrd_start)
326 ROOT_DEV = Root_RAM0;
327 else
328#endif
329 ROOT_DEV = DEFAULT_ROOT_DEVICE;
330
331#ifdef CONFIG_SMP
332 /* Check for Core99 */
333 if (find_devices("uni-n") || find_devices("u3"))
334 ppc_md.smp_ops = &core99_smp_ops;
335 else
336 ppc_md.smp_ops = &psurge_smp_ops;
337#endif /* CONFIG_SMP */
338
339 pci_create_OF_bus_map();
340}
341
342static void __init ohare_init(void)
343{
344 /*
345 * Turn on the L2 cache.
346 * We assume that we have a PSX memory controller iff
347 * we have an ohare I/O controller.
348 */
349 if (find_devices("ohare") != NULL) {
350 if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
351 if (sysctrl_regs[4] & 0x10)
352 sysctrl_regs[4] |= 0x04000020;
353 else
354 sysctrl_regs[4] |= 0x04000000;
355 if(has_l2cache)
356 printk(KERN_INFO "Level 2 cache enabled\n");
357 }
358 }
359}
360
361extern char *bootpath;
362extern char *bootdevice;
363void *boot_host;
364int boot_target;
365int boot_part;
366extern dev_t boot_dev;
367
368#ifdef CONFIG_SCSI
369void __init
370note_scsi_host(struct device_node *node, void *host)
371{
372 int l;
373 char *p;
374
375 l = strlen(node->full_name);
376 if (bootpath != NULL && bootdevice != NULL
377 && strncmp(node->full_name, bootdevice, l) == 0
378 && (bootdevice[l] == '/' || bootdevice[l] == 0)) {
379 boot_host = host;
380 /*
381 * There's a bug in OF 1.0.5. (Why am I not surprised.)
382 * If you pass a path like scsi/sd@1:0 to canon, it returns
383 * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
384 * That is, the scsi target number doesn't get preserved.
385 * So we pick the target number out of bootpath and use that.
386 */
387 p = strstr(bootpath, "/sd@");
388 if (p != NULL) {
389 p += 4;
390 boot_target = simple_strtoul(p, NULL, 10);
391 p = strchr(p, ':');
392 if (p != NULL)
393 boot_part = simple_strtoul(p + 1, NULL, 10);
394 }
395 }
396}
397#endif
398
399#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
400static dev_t __init
401find_ide_boot(void)
402{
403 char *p;
404 int n;
405 dev_t __init pmac_find_ide_boot(char *bootdevice, int n);
406
407 if (bootdevice == NULL)
408 return 0;
409 p = strrchr(bootdevice, '/');
410 if (p == NULL)
411 return 0;
412 n = p - bootdevice;
413
414 return pmac_find_ide_boot(bootdevice, n);
415}
416#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
417
418void __init
419find_boot_device(void)
420{
421#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
422 boot_dev = find_ide_boot();
423#endif
424}
425
426static int initializing = 1;
427/* TODO: Merge the suspend-to-ram with the common code !!!
428 * currently, this is a stub implementation for suspend-to-disk
429 * only
430 */
431
432#ifdef CONFIG_SOFTWARE_SUSPEND
433
434static int pmac_pm_prepare(suspend_state_t state)
435{
436 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
437
438 return 0;
439}
440
441static int pmac_pm_enter(suspend_state_t state)
442{
443 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
444
445 /* Giveup the lazy FPU & vec so we don't have to back them
446 * up from the low level code
447 */
448 enable_kernel_fp();
449
450#ifdef CONFIG_ALTIVEC
451 if (cur_cpu_spec[0]->cpu_features & CPU_FTR_ALTIVEC)
452 enable_kernel_altivec();
453#endif /* CONFIG_ALTIVEC */
454
455 return 0;
456}
457
458static int pmac_pm_finish(suspend_state_t state)
459{
460 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
461
462 /* Restore userland MMU context */
463 set_context(current->active_mm->context, current->active_mm->pgd);
464
465 return 0;
466}
467
468static struct pm_ops pmac_pm_ops = {
469 .pm_disk_mode = PM_DISK_SHUTDOWN,
470 .prepare = pmac_pm_prepare,
471 .enter = pmac_pm_enter,
472 .finish = pmac_pm_finish,
473};
474
475#endif /* CONFIG_SOFTWARE_SUSPEND */
476
477static int pmac_late_init(void)
478{
479 initializing = 0;
480#ifdef CONFIG_SOFTWARE_SUSPEND
481 pm_set_ops(&pmac_pm_ops);
482#endif /* CONFIG_SOFTWARE_SUSPEND */
483 return 0;
484}
485
486late_initcall(pmac_late_init);
487
488/* can't be __init - can be called whenever a disk is first accessed */
489void __pmac
490note_bootable_part(dev_t dev, int part, int goodness)
491{
492 static int found_boot = 0;
493 char *p;
494
495 if (!initializing)
496 return;
497 if ((goodness <= current_root_goodness) &&
498 ROOT_DEV != DEFAULT_ROOT_DEVICE)
499 return;
500 p = strstr(saved_command_line, "root=");
501 if (p != NULL && (p == saved_command_line || p[-1] == ' '))
502 return;
503
504 if (!found_boot) {
505 find_boot_device();
506 found_boot = 1;
507 }
508 if (!boot_dev || dev == boot_dev) {
509 ROOT_DEV = dev + part;
510 boot_dev = 0;
511 current_root_goodness = goodness;
512 }
513}
514
515void __pmac
516pmac_restart(char *cmd)
517{
518#ifdef CONFIG_ADB_CUDA
519 struct adb_request req;
520#endif /* CONFIG_ADB_CUDA */
521
522 switch (sys_ctrler) {
523#ifdef CONFIG_ADB_CUDA
524 case SYS_CTRLER_CUDA:
525 cuda_request(&req, NULL, 2, CUDA_PACKET,
526 CUDA_RESET_SYSTEM);
527 for (;;)
528 cuda_poll();
529 break;
530#endif /* CONFIG_ADB_CUDA */
531#ifdef CONFIG_ADB_PMU
532 case SYS_CTRLER_PMU:
533 pmu_restart();
534 break;
535#endif /* CONFIG_ADB_PMU */
536 default: ;
537 }
538}
539
540void __pmac
541pmac_power_off(void)
542{
543#ifdef CONFIG_ADB_CUDA
544 struct adb_request req;
545#endif /* CONFIG_ADB_CUDA */
546
547 switch (sys_ctrler) {
548#ifdef CONFIG_ADB_CUDA
549 case SYS_CTRLER_CUDA:
550 cuda_request(&req, NULL, 2, CUDA_PACKET,
551 CUDA_POWERDOWN);
552 for (;;)
553 cuda_poll();
554 break;
555#endif /* CONFIG_ADB_CUDA */
556#ifdef CONFIG_ADB_PMU
557 case SYS_CTRLER_PMU:
558 pmu_shutdown();
559 break;
560#endif /* CONFIG_ADB_PMU */
561 default: ;
562 }
563}
564
565void __pmac
566pmac_halt(void)
567{
568 pmac_power_off();
569}
570
571/*
572 * Read in a property describing some pieces of memory.
573 */
574
575static int __init
576get_mem_prop(char *name, struct mem_pieces *mp)
577{
578 struct reg_property *rp;
579 int i, s;
580 unsigned int *ip;
581 int nac = prom_n_addr_cells(memory_node);
582 int nsc = prom_n_size_cells(memory_node);
583
584 ip = (unsigned int *) get_property(memory_node, name, &s);
585 if (ip == NULL) {
586 printk(KERN_ERR "error: couldn't get %s property on /memory\n",
587 name);
588 return 0;
589 }
590 s /= (nsc + nac) * 4;
591 rp = mp->regions;
592 for (i = 0; i < s; ++i, ip += nac+nsc) {
593 if (nac >= 2 && ip[nac-2] != 0)
594 continue;
595 rp->address = ip[nac-1];
596 if (nsc >= 2 && ip[nac+nsc-2] != 0)
597 rp->size = ~0U;
598 else
599 rp->size = ip[nac+nsc-1];
600 ++rp;
601 }
602 mp->n_regions = rp - mp->regions;
603
604 /* Make sure the pieces are sorted. */
605 mem_pieces_sort(mp);
606 mem_pieces_coalesce(mp);
607 return 1;
608}
609
610/*
611 * On systems with Open Firmware, collect information about
612 * physical RAM and which pieces are already in use.
613 * At this point, we have (at least) the first 8MB mapped with a BAT.
614 * Our text, data, bss use something over 1MB, starting at 0.
615 * Open Firmware may be using 1MB at the 4MB point.
616 */
617unsigned long __init
618pmac_find_end_of_memory(void)
619{
620 unsigned long a, total;
621 struct mem_pieces phys_mem;
622
623 /*
624 * Find out where physical memory is, and check that it
625 * starts at 0 and is contiguous. It seems that RAM is
626 * always physically contiguous on Power Macintoshes.
627 *
628 * Supporting discontiguous physical memory isn't hard,
629 * it just makes the virtual <-> physical mapping functions
630 * more complicated (or else you end up wasting space
631 * in mem_map).
632 */
633 memory_node = find_devices("memory");
634 if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
635 || phys_mem.n_regions == 0)
636 panic("No RAM??");
637 a = phys_mem.regions[0].address;
638 if (a != 0)
639 panic("RAM doesn't start at physical address 0");
640 total = phys_mem.regions[0].size;
641
642 if (phys_mem.n_regions > 1) {
643 printk("RAM starting at 0x%x is not contiguous\n",
644 phys_mem.regions[1].address);
645 printk("Using RAM from 0 to 0x%lx\n", total-1);
646 }
647
648 return total;
649}
650
651void __init
652pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
653 unsigned long r6, unsigned long r7)
654{
655 /* isa_io_base gets set in pmac_find_bridges */
656 isa_mem_base = PMAC_ISA_MEM_BASE;
657 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
658 ISA_DMA_THRESHOLD = ~0L;
659 DMA_MODE_READ = 1;
660 DMA_MODE_WRITE = 2;
661
662 ppc_md.setup_arch = pmac_setup_arch;
663 ppc_md.show_cpuinfo = pmac_show_cpuinfo;
664 ppc_md.show_percpuinfo = pmac_show_percpuinfo;
665 ppc_md.irq_canonicalize = NULL;
666 ppc_md.init_IRQ = pmac_pic_init;
667 ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */
668
669 ppc_md.pcibios_fixup = pmac_pcibios_fixup;
670 ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
671 ppc_md.pcibios_after_init = pmac_pcibios_after_init;
672 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
673
674 ppc_md.restart = pmac_restart;
675 ppc_md.power_off = pmac_power_off;
676 ppc_md.halt = pmac_halt;
677
678 ppc_md.time_init = pmac_time_init;
679 ppc_md.set_rtc_time = pmac_set_rtc_time;
680 ppc_md.get_rtc_time = pmac_get_rtc_time;
681 ppc_md.calibrate_decr = pmac_calibrate_decr;
682
683 ppc_md.find_end_of_memory = pmac_find_end_of_memory;
684
685 ppc_md.feature_call = pmac_do_feature_call;
686
687#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
688#ifdef CONFIG_BLK_DEV_IDE_PMAC
689 ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
690 ppc_ide_md.default_io_base = pmac_ide_get_base;
691#endif /* CONFIG_BLK_DEV_IDE_PMAC */
692#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
693
694#ifdef CONFIG_BOOTX_TEXT
695 ppc_md.progress = pmac_progress;
696#endif /* CONFIG_BOOTX_TEXT */
697
698 if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
699
700}
701
702#ifdef CONFIG_BOOTX_TEXT
703void __init
704pmac_progress(char *s, unsigned short hex)
705{
706 if (boot_text_mapped) {
707 btext_drawstring(s);
708 btext_drawchar('\n');
709 }
710}
711#endif /* CONFIG_BOOTX_TEXT */
712
713static int __init
714pmac_declare_of_platform_devices(void)
715{
716 struct device_node *np;
717
718 np = find_devices("uni-n");
719 if (np) {
720 for (np = np->child; np != NULL; np = np->sibling)
721 if (strncmp(np->name, "i2c", 3) == 0) {
722 of_platform_device_create(np, "uni-n-i2c");
723 break;
724 }
725 }
726 np = find_devices("u3");
727 if (np) {
728 for (np = np->child; np != NULL; np = np->sibling)
729 if (strncmp(np->name, "i2c", 3) == 0) {
730 of_platform_device_create(np, "u3-i2c");
731 break;
732 }
733 }
734
735 np = find_devices("valkyrie");
736 if (np)
737 of_platform_device_create(np, "valkyrie");
738 np = find_devices("platinum");
739 if (np)
740 of_platform_device_create(np, "platinum");
741
742 return 0;
743}
744
745device_initcall(pmac_declare_of_platform_devices);
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
new file mode 100644
index 000000000000..3139b6766ad3
--- /dev/null
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -0,0 +1,390 @@
1/*
2 * This file contains sleep low-level functions for PowerBook G3.
3 * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
4 * and Paul Mackerras (paulus@samba.org).
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <linux/config.h>
14#include <asm/processor.h>
15#include <asm/page.h>
16#include <asm/ppc_asm.h>
17#include <asm/cputable.h>
18#include <asm/cache.h>
19#include <asm/thread_info.h>
20#include <asm/offsets.h>
21
22#define MAGIC 0x4c617273 /* 'Lars' */
23
24/*
25 * Structure for storing CPU registers on the stack.
26 */
27#define SL_SP 0
28#define SL_PC 4
29#define SL_MSR 8
30#define SL_SDR1 0xc
31#define SL_SPRG0 0x10 /* 4 sprg's */
32#define SL_DBAT0 0x20
33#define SL_IBAT0 0x28
34#define SL_DBAT1 0x30
35#define SL_IBAT1 0x38
36#define SL_DBAT2 0x40
37#define SL_IBAT2 0x48
38#define SL_DBAT3 0x50
39#define SL_IBAT3 0x58
40#define SL_TB 0x60
41#define SL_R2 0x68
42#define SL_CR 0x6c
43#define SL_R12 0x70 /* r12 to r31 */
44#define SL_SIZE (SL_R12 + 80)
45
46 .section .text
47 .align 5
48
49#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC)
50
51/* This gets called by via-pmu.c late during the sleep process.
52 * The PMU was already send the sleep command and will shut us down
53 * soon. We need to save all that is needed and setup the wakeup
54 * vector that will be called by the ROM on wakeup
55 */
56_GLOBAL(low_sleep_handler)
57#ifndef CONFIG_6xx
58 blr
59#else
60 mflr r0
61 stw r0,4(r1)
62 stwu r1,-SL_SIZE(r1)
63 mfcr r0
64 stw r0,SL_CR(r1)
65 stw r2,SL_R2(r1)
66 stmw r12,SL_R12(r1)
67
68 /* Save MSR & SDR1 */
69 mfmsr r4
70 stw r4,SL_MSR(r1)
71 mfsdr1 r4
72 stw r4,SL_SDR1(r1)
73
74 /* Get a stable timebase and save it */
751: mftbu r4
76 stw r4,SL_TB(r1)
77 mftb r5
78 stw r5,SL_TB+4(r1)
79 mftbu r3
80 cmpw r3,r4
81 bne 1b
82
83 /* Save SPRGs */
84 mfsprg r4,0
85 stw r4,SL_SPRG0(r1)
86 mfsprg r4,1
87 stw r4,SL_SPRG0+4(r1)
88 mfsprg r4,2
89 stw r4,SL_SPRG0+8(r1)
90 mfsprg r4,3
91 stw r4,SL_SPRG0+12(r1)
92
93 /* Save BATs */
94 mfdbatu r4,0
95 stw r4,SL_DBAT0(r1)
96 mfdbatl r4,0
97 stw r4,SL_DBAT0+4(r1)
98 mfdbatu r4,1
99 stw r4,SL_DBAT1(r1)
100 mfdbatl r4,1
101 stw r4,SL_DBAT1+4(r1)
102 mfdbatu r4,2
103 stw r4,SL_DBAT2(r1)
104 mfdbatl r4,2
105 stw r4,SL_DBAT2+4(r1)
106 mfdbatu r4,3
107 stw r4,SL_DBAT3(r1)
108 mfdbatl r4,3
109 stw r4,SL_DBAT3+4(r1)
110 mfibatu r4,0
111 stw r4,SL_IBAT0(r1)
112 mfibatl r4,0
113 stw r4,SL_IBAT0+4(r1)
114 mfibatu r4,1
115 stw r4,SL_IBAT1(r1)
116 mfibatl r4,1
117 stw r4,SL_IBAT1+4(r1)
118 mfibatu r4,2
119 stw r4,SL_IBAT2(r1)
120 mfibatl r4,2
121 stw r4,SL_IBAT2+4(r1)
122 mfibatu r4,3
123 stw r4,SL_IBAT3(r1)
124 mfibatl r4,3
125 stw r4,SL_IBAT3+4(r1)
126
127 /* Backup various CPU config stuffs */
128 bl __save_cpu_setup
129
130 /* The ROM can wake us up via 2 different vectors:
131 * - On wallstreet & lombard, we must write a magic
132 * value 'Lars' at address 4 and a pointer to a
133 * memory location containing the PC to resume from
134 * at address 0.
135 * - On Core99, we must store the wakeup vector at
136 * address 0x80 and eventually it's parameters
137 * at address 0x84. I've have some trouble with those
138 * parameters however and I no longer use them.
139 */
140 lis r5,grackle_wake_up@ha
141 addi r5,r5,grackle_wake_up@l
142 tophys(r5,r5)
143 stw r5,SL_PC(r1)
144 lis r4,KERNELBASE@h
145 tophys(r5,r1)
146 addi r5,r5,SL_PC
147 lis r6,MAGIC@ha
148 addi r6,r6,MAGIC@l
149 stw r5,0(r4)
150 stw r6,4(r4)
151 /* Setup stuffs at 0x80-0x84 for Core99 */
152 lis r3,core99_wake_up@ha
153 addi r3,r3,core99_wake_up@l
154 tophys(r3,r3)
155 stw r3,0x80(r4)
156 stw r5,0x84(r4)
157 /* Store a pointer to our backup storage into
158 * a kernel global
159 */
160 lis r3,sleep_storage@ha
161 addi r3,r3,sleep_storage@l
162 stw r5,0(r3)
163
164 /* Flush & disable all caches */
165 bl flush_disable_caches
166
167 /* Turn off data relocation. */
168 mfmsr r3 /* Save MSR in r7 */
169 rlwinm r3,r3,0,28,26 /* Turn off DR bit */
170 sync
171 mtmsr r3
172 isync
173
174BEGIN_FTR_SECTION
175 /* Flush any pending L2 data prefetches to work around HW bug */
176 sync
177 lis r3,0xfff0
178 lwz r0,0(r3) /* perform cache-inhibited load to ROM */
179 sync /* (caches are disabled at this point) */
180END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
181
182/*
183 * Set the HID0 and MSR for sleep.
184 */
185 mfspr r2,SPRN_HID0
186 rlwinm r2,r2,0,10,7 /* clear doze, nap */
187 oris r2,r2,HID0_SLEEP@h
188 sync
189 isync
190 mtspr SPRN_HID0,r2
191 sync
192
193/* This loop puts us back to sleep in case we have a spurrious
194 * wakeup so that the host bridge properly stays asleep. The
195 * CPU will be turned off, either after a known time (about 1
196 * second) on wallstreet & lombard, or as soon as the CPU enters
197 * SLEEP mode on core99
198 */
199 mfmsr r2
200 oris r2,r2,MSR_POW@h
2011: sync
202 mtmsr r2
203 isync
204 b 1b
205
206/*
207 * Here is the resume code.
208 */
209
210
211/*
212 * Core99 machines resume here
213 * r4 has the physical address of SL_PC(sp) (unused)
214 */
215_GLOBAL(core99_wake_up)
216 /* Make sure HID0 no longer contains any sleep bit and that data cache
217 * is disabled
218 */
219 mfspr r3,SPRN_HID0
220 rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
221 rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
222 mtspr SPRN_HID0,r3
223 sync
224 isync
225
226 /* sanitize MSR */
227 mfmsr r3
228 ori r3,r3,MSR_EE|MSR_IP
229 xori r3,r3,MSR_EE|MSR_IP
230 sync
231 isync
232 mtmsr r3
233 sync
234 isync
235
236 /* Recover sleep storage */
237 lis r3,sleep_storage@ha
238 addi r3,r3,sleep_storage@l
239 tophys(r3,r3)
240 lwz r1,0(r3)
241
242 /* Pass thru to older resume code ... */
243/*
244 * Here is the resume code for older machines.
245 * r1 has the physical address of SL_PC(sp).
246 */
247
248grackle_wake_up:
249
250 /* Restore the kernel's segment registers before
251 * we do any r1 memory access as we are not sure they
252 * are in a sane state above the first 256Mb region
253 */
254 li r0,16 /* load up segment register values */
255 mtctr r0 /* for context 0 */
256 lis r3,0x2000 /* Ku = 1, VSID = 0 */
257 li r4,0
2583: mtsrin r3,r4
259 addi r3,r3,0x111 /* increment VSID */
260 addis r4,r4,0x1000 /* address of next segment */
261 bdnz 3b
262 sync
263 isync
264
265 subi r1,r1,SL_PC
266
267 /* Restore various CPU config stuffs */
268 bl __restore_cpu_setup
269
270 /* Invalidate & enable L1 cache, we don't care about
271 * whatever the ROM may have tried to write to memory
272 */
273 bl __inval_enable_L1
274
275 /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
276 lwz r4,SL_SDR1(r1)
277 mtsdr1 r4
278 lwz r4,SL_SPRG0(r1)
279 mtsprg 0,r4
280 lwz r4,SL_SPRG0+4(r1)
281 mtsprg 1,r4
282 lwz r4,SL_SPRG0+8(r1)
283 mtsprg 2,r4
284 lwz r4,SL_SPRG0+12(r1)
285 mtsprg 3,r4
286
287 lwz r4,SL_DBAT0(r1)
288 mtdbatu 0,r4
289 lwz r4,SL_DBAT0+4(r1)
290 mtdbatl 0,r4
291 lwz r4,SL_DBAT1(r1)
292 mtdbatu 1,r4
293 lwz r4,SL_DBAT1+4(r1)
294 mtdbatl 1,r4
295 lwz r4,SL_DBAT2(r1)
296 mtdbatu 2,r4
297 lwz r4,SL_DBAT2+4(r1)
298 mtdbatl 2,r4
299 lwz r4,SL_DBAT3(r1)
300 mtdbatu 3,r4
301 lwz r4,SL_DBAT3+4(r1)
302 mtdbatl 3,r4
303 lwz r4,SL_IBAT0(r1)
304 mtibatu 0,r4
305 lwz r4,SL_IBAT0+4(r1)
306 mtibatl 0,r4
307 lwz r4,SL_IBAT1(r1)
308 mtibatu 1,r4
309 lwz r4,SL_IBAT1+4(r1)
310 mtibatl 1,r4
311 lwz r4,SL_IBAT2(r1)
312 mtibatu 2,r4
313 lwz r4,SL_IBAT2+4(r1)
314 mtibatl 2,r4
315 lwz r4,SL_IBAT3(r1)
316 mtibatu 3,r4
317 lwz r4,SL_IBAT3+4(r1)
318 mtibatl 3,r4
319
320BEGIN_FTR_SECTION
321 li r4,0
322 mtspr SPRN_DBAT4U,r4
323 mtspr SPRN_DBAT4L,r4
324 mtspr SPRN_DBAT5U,r4
325 mtspr SPRN_DBAT5L,r4
326 mtspr SPRN_DBAT6U,r4
327 mtspr SPRN_DBAT6L,r4
328 mtspr SPRN_DBAT7U,r4
329 mtspr SPRN_DBAT7L,r4
330 mtspr SPRN_IBAT4U,r4
331 mtspr SPRN_IBAT4L,r4
332 mtspr SPRN_IBAT5U,r4
333 mtspr SPRN_IBAT5L,r4
334 mtspr SPRN_IBAT6U,r4
335 mtspr SPRN_IBAT6L,r4
336 mtspr SPRN_IBAT7U,r4
337 mtspr SPRN_IBAT7L,r4
338END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
339
340 /* Flush all TLBs */
341 lis r4,0x1000
3421: addic. r4,r4,-0x1000
343 tlbie r4
344 blt 1b
345 sync
346
347 /* restore the MSR and turn on the MMU */
348 lwz r3,SL_MSR(r1)
349 bl turn_on_mmu
350
351 /* get back the stack pointer */
352 tovirt(r1,r1)
353
354 /* Restore TB */
355 li r3,0
356 mttbl r3
357 lwz r3,SL_TB(r1)
358 lwz r4,SL_TB+4(r1)
359 mttbu r3
360 mttbl r4
361
362 /* Restore the callee-saved registers and return */
363 lwz r0,SL_CR(r1)
364 mtcr r0
365 lwz r2,SL_R2(r1)
366 lmw r12,SL_R12(r1)
367 addi r1,r1,SL_SIZE
368 lwz r0,4(r1)
369 mtlr r0
370 blr
371
372turn_on_mmu:
373 mflr r4
374 tovirt(r4,r4)
375 mtsrr0 r4
376 mtsrr1 r3
377 sync
378 isync
379 rfi
380
381#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */
382
383 .section .data
384 .balign L1_CACHE_LINE_SIZE
385sleep_storage:
386 .long 0
387 .balign L1_CACHE_LINE_SIZE, 0
388
389#endif /* CONFIG_6xx */
390 .section .text
diff --git a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
new file mode 100644
index 000000000000..2b88745576a0
--- /dev/null
+++ b/arch/ppc/platforms/pmac_smp.c
@@ -0,0 +1,640 @@
1/*
2 * SMP support for power macintosh.
3 *
4 * We support both the old "powersurge" SMP architecture
5 * and the current Core99 (G4 PowerMac) machines.
6 *
7 * Note that we don't support the very first rev. of
8 * Apple/DayStar 2 CPUs board, the one with the funky
9 * watchdog. Hopefully, none of these should be there except
10 * maybe internally to Apple. I should probably still add some
11 * code to detect this card though and disable SMP. --BenH.
12 *
13 * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
14 * and Ben Herrenschmidt <benh@kernel.crashing.org>.
15 *
16 * Support for DayStar quad CPU cards
17 * Copyright (C) XLR8, Inc. 1994-2000
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version.
23 */
24#include <linux/config.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/smp.h>
28#include <linux/smp_lock.h>
29#include <linux/interrupt.h>
30#include <linux/kernel_stat.h>
31#include <linux/delay.h>
32#include <linux/init.h>
33#include <linux/spinlock.h>
34#include <linux/errno.h>
35#include <linux/hardirq.h>
36
37#include <asm/ptrace.h>
38#include <asm/atomic.h>
39#include <asm/irq.h>
40#include <asm/page.h>
41#include <asm/pgtable.h>
42#include <asm/sections.h>
43#include <asm/io.h>
44#include <asm/prom.h>
45#include <asm/smp.h>
46#include <asm/residual.h>
47#include <asm/machdep.h>
48#include <asm/pmac_feature.h>
49#include <asm/time.h>
50#include <asm/open_pic.h>
51#include <asm/cacheflush.h>
52#include <asm/keylargo.h>
53
54/*
55 * Powersurge (old powermac SMP) support.
56 */
57
58extern void __secondary_start_psurge(void);
59extern void __secondary_start_psurge2(void); /* Temporary horrible hack */
60extern void __secondary_start_psurge3(void); /* Temporary horrible hack */
61
62/* Addresses for powersurge registers */
63#define HAMMERHEAD_BASE 0xf8000000
64#define HHEAD_CONFIG 0x90
65#define HHEAD_SEC_INTR 0xc0
66
67/* register for interrupting the primary processor on the powersurge */
68/* N.B. this is actually the ethernet ROM! */
69#define PSURGE_PRI_INTR 0xf3019000
70
71/* register for storing the start address for the secondary processor */
72/* N.B. this is the PCI config space address register for the 1st bridge */
73#define PSURGE_START 0xf2800000
74
75/* Daystar/XLR8 4-CPU card */
76#define PSURGE_QUAD_REG_ADDR 0xf8800000
77
78#define PSURGE_QUAD_IRQ_SET 0
79#define PSURGE_QUAD_IRQ_CLR 1
80#define PSURGE_QUAD_IRQ_PRIMARY 2
81#define PSURGE_QUAD_CKSTOP_CTL 3
82#define PSURGE_QUAD_PRIMARY_ARB 4
83#define PSURGE_QUAD_BOARD_ID 6
84#define PSURGE_QUAD_WHICH_CPU 7
85#define PSURGE_QUAD_CKSTOP_RDBK 8
86#define PSURGE_QUAD_RESET_CTL 11
87
88#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
89#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
90#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
91#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
92
93/* virtual addresses for the above */
94static volatile u8 *hhead_base;
95static volatile u8 *quad_base;
96static volatile u32 *psurge_pri_intr;
97static volatile u8 *psurge_sec_intr;
98static volatile u32 *psurge_start;
99
100/* values for psurge_type */
101#define PSURGE_NONE -1
102#define PSURGE_DUAL 0
103#define PSURGE_QUAD_OKEE 1
104#define PSURGE_QUAD_COTTON 2
105#define PSURGE_QUAD_ICEGRASS 3
106
107/* what sort of powersurge board we have */
108static int psurge_type = PSURGE_NONE;
109
110/* L2 and L3 cache settings to pass from CPU0 to CPU1 */
111volatile static long int core99_l2_cache;
112volatile static long int core99_l3_cache;
113
114/* Timebase freeze GPIO */
115static unsigned int core99_tb_gpio;
116
117/* Sync flag for HW tb sync */
118static volatile int sec_tb_reset = 0;
119
120static void __init core99_init_caches(int cpu)
121{
122 if (!cpu_has_feature(CPU_FTR_L2CR))
123 return;
124
125 if (cpu == 0) {
126 core99_l2_cache = _get_L2CR();
127 printk("CPU0: L2CR is %lx\n", core99_l2_cache);
128 } else {
129 printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
130 _set_L2CR(0);
131 _set_L2CR(core99_l2_cache);
132 printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
133 }
134
135 if (!cpu_has_feature(CPU_FTR_L3CR))
136 return;
137
138 if (cpu == 0){
139 core99_l3_cache = _get_L3CR();
140 printk("CPU0: L3CR is %lx\n", core99_l3_cache);
141 } else {
142 printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
143 _set_L3CR(0);
144 _set_L3CR(core99_l3_cache);
145 printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
146 }
147}
148
149/*
150 * Set and clear IPIs for powersurge.
151 */
152static inline void psurge_set_ipi(int cpu)
153{
154 if (psurge_type == PSURGE_NONE)
155 return;
156 if (cpu == 0)
157 in_be32(psurge_pri_intr);
158 else if (psurge_type == PSURGE_DUAL)
159 out_8(psurge_sec_intr, 0);
160 else
161 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
162}
163
164static inline void psurge_clr_ipi(int cpu)
165{
166 if (cpu > 0) {
167 switch(psurge_type) {
168 case PSURGE_DUAL:
169 out_8(psurge_sec_intr, ~0);
170 case PSURGE_NONE:
171 break;
172 default:
173 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
174 }
175 }
176}
177
178/*
179 * On powersurge (old SMP powermac architecture) we don't have
180 * separate IPIs for separate messages like openpic does. Instead
181 * we have a bitmap for each processor, where a 1 bit means that
182 * the corresponding message is pending for that processor.
183 * Ideally each cpu's entry would be in a different cache line.
184 * -- paulus.
185 */
186static unsigned long psurge_smp_message[NR_CPUS];
187
188void __pmac psurge_smp_message_recv(struct pt_regs *regs)
189{
190 int cpu = smp_processor_id();
191 int msg;
192
193 /* clear interrupt */
194 psurge_clr_ipi(cpu);
195
196 if (num_online_cpus() < 2)
197 return;
198
199 /* make sure there is a message there */
200 for (msg = 0; msg < 4; msg++)
201 if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
202 smp_message_recv(msg, regs);
203}
204
205irqreturn_t __pmac psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
206{
207 psurge_smp_message_recv(regs);
208 return IRQ_HANDLED;
209}
210
211static void __pmac smp_psurge_message_pass(int target, int msg, unsigned long data,
212 int wait)
213{
214 int i;
215
216 if (num_online_cpus() < 2)
217 return;
218
219 for (i = 0; i < NR_CPUS; i++) {
220 if (!cpu_online(i))
221 continue;
222 if (target == MSG_ALL
223 || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
224 || target == i) {
225 set_bit(msg, &psurge_smp_message[i]);
226 psurge_set_ipi(i);
227 }
228 }
229}
230
231/*
232 * Determine a quad card presence. We read the board ID register, we
233 * force the data bus to change to something else, and we read it again.
234 * It it's stable, then the register probably exist (ugh !)
235 */
236static int __init psurge_quad_probe(void)
237{
238 int type;
239 unsigned int i;
240
241 type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
242 if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
243 || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
244 return PSURGE_DUAL;
245
246 /* looks OK, try a slightly more rigorous test */
247 /* bogus is not necessarily cacheline-aligned,
248 though I don't suppose that really matters. -- paulus */
249 for (i = 0; i < 100; i++) {
250 volatile u32 bogus[8];
251 bogus[(0+i)%8] = 0x00000000;
252 bogus[(1+i)%8] = 0x55555555;
253 bogus[(2+i)%8] = 0xFFFFFFFF;
254 bogus[(3+i)%8] = 0xAAAAAAAA;
255 bogus[(4+i)%8] = 0x33333333;
256 bogus[(5+i)%8] = 0xCCCCCCCC;
257 bogus[(6+i)%8] = 0xCCCCCCCC;
258 bogus[(7+i)%8] = 0x33333333;
259 wmb();
260 asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
261 mb();
262 if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
263 return PSURGE_DUAL;
264 }
265 return type;
266}
267
268static void __init psurge_quad_init(void)
269{
270 int procbits;
271
272 if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
273 procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
274 if (psurge_type == PSURGE_QUAD_ICEGRASS)
275 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
276 else
277 PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
278 mdelay(33);
279 out_8(psurge_sec_intr, ~0);
280 PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
281 PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
282 if (psurge_type != PSURGE_QUAD_ICEGRASS)
283 PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
284 PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
285 mdelay(33);
286 PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
287 mdelay(33);
288 PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
289 mdelay(33);
290}
291
292static int __init smp_psurge_probe(void)
293{
294 int i, ncpus;
295
296 /* We don't do SMP on the PPC601 -- paulus */
297 if (PVR_VER(mfspr(SPRN_PVR)) == 1)
298 return 1;
299
300 /*
301 * The powersurge cpu board can be used in the generation
302 * of powermacs that have a socket for an upgradeable cpu card,
303 * including the 7500, 8500, 9500, 9600.
304 * The device tree doesn't tell you if you have 2 cpus because
305 * OF doesn't know anything about the 2nd processor.
306 * Instead we look for magic bits in magic registers,
307 * in the hammerhead memory controller in the case of the
308 * dual-cpu powersurge board. -- paulus.
309 */
310 if (find_devices("hammerhead") == NULL)
311 return 1;
312
313 hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
314 quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
315 psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
316
317 psurge_type = psurge_quad_probe();
318 if (psurge_type != PSURGE_DUAL) {
319 psurge_quad_init();
320 /* All released cards using this HW design have 4 CPUs */
321 ncpus = 4;
322 } else {
323 iounmap((void *) quad_base);
324 if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
325 /* not a dual-cpu card */
326 iounmap((void *) hhead_base);
327 psurge_type = PSURGE_NONE;
328 return 1;
329 }
330 ncpus = 2;
331 }
332
333 psurge_start = ioremap(PSURGE_START, 4);
334 psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
335
336 /* this is not actually strictly necessary -- paulus. */
337 for (i = 1; i < ncpus; ++i)
338 smp_hw_index[i] = i;
339
340 if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
341
342 return ncpus;
343}
344
345static void __init smp_psurge_kick_cpu(int nr)
346{
347 void (*start)(void) = __secondary_start_psurge;
348 unsigned long a;
349
350 /* may need to flush here if secondary bats aren't setup */
351 for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
352 asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
353 asm volatile("sync");
354
355 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
356
357 /* setup entry point of secondary processor */
358 switch (nr) {
359 case 2:
360 start = __secondary_start_psurge2;
361 break;
362 case 3:
363 start = __secondary_start_psurge3;
364 break;
365 }
366
367 out_be32(psurge_start, __pa(start));
368 mb();
369
370 psurge_set_ipi(nr);
371 udelay(10);
372 psurge_clr_ipi(nr);
373
374 if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
375}
376
377/*
378 * With the dual-cpu powersurge board, the decrementers and timebases
379 * of both cpus are frozen after the secondary cpu is started up,
380 * until we give the secondary cpu another interrupt. This routine
381 * uses this to get the timebases synchronized.
382 * -- paulus.
383 */
384static void __init psurge_dual_sync_tb(int cpu_nr)
385{
386 int t;
387
388 set_dec(tb_ticks_per_jiffy);
389 set_tb(0, 0);
390 last_jiffy_stamp(cpu_nr) = 0;
391
392 if (cpu_nr > 0) {
393 mb();
394 sec_tb_reset = 1;
395 return;
396 }
397
398 /* wait for the secondary to have reset its TB before proceeding */
399 for (t = 10000000; t > 0 && !sec_tb_reset; --t)
400 ;
401
402 /* now interrupt the secondary, starting both TBs */
403 psurge_set_ipi(1);
404
405 smp_tb_synchronized = 1;
406}
407
408static struct irqaction psurge_irqaction = {
409 .handler = psurge_primary_intr,
410 .flags = SA_INTERRUPT,
411 .mask = CPU_MASK_NONE,
412 .name = "primary IPI",
413};
414
415static void __init smp_psurge_setup_cpu(int cpu_nr)
416{
417
418 if (cpu_nr == 0) {
419 /* If we failed to start the second CPU, we should still
420 * send it an IPI to start the timebase & DEC or we might
421 * have them stuck.
422 */
423 if (num_online_cpus() < 2) {
424 if (psurge_type == PSURGE_DUAL)
425 psurge_set_ipi(1);
426 return;
427 }
428 /* reset the entry point so if we get another intr we won't
429 * try to startup again */
430 out_be32(psurge_start, 0x100);
431 if (setup_irq(30, &psurge_irqaction))
432 printk(KERN_ERR "Couldn't get primary IPI interrupt");
433 }
434
435 if (psurge_type == PSURGE_DUAL)
436 psurge_dual_sync_tb(cpu_nr);
437}
438
439void __init smp_psurge_take_timebase(void)
440{
441 /* Dummy implementation */
442}
443
444void __init smp_psurge_give_timebase(void)
445{
446 /* Dummy implementation */
447}
448
449static int __init smp_core99_probe(void)
450{
451#ifdef CONFIG_6xx
452 extern int powersave_nap;
453#endif
454 struct device_node *cpus, *firstcpu;
455 int i, ncpus = 0, boot_cpu = -1;
456 u32 *tbprop;
457
458 if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
459 cpus = firstcpu = find_type_devices("cpu");
460 while(cpus != NULL) {
461 u32 *regprop = (u32 *)get_property(cpus, "reg", NULL);
462 char *stateprop = (char *)get_property(cpus, "state", NULL);
463 if (regprop != NULL && stateprop != NULL &&
464 !strncmp(stateprop, "running", 7))
465 boot_cpu = *regprop;
466 ++ncpus;
467 cpus = cpus->next;
468 }
469 if (boot_cpu == -1)
470 printk(KERN_WARNING "Couldn't detect boot CPU !\n");
471 if (boot_cpu != 0)
472 printk(KERN_WARNING "Boot CPU is %d, unsupported setup !\n", boot_cpu);
473
474 if (machine_is_compatible("MacRISC4")) {
475 extern struct smp_ops_t core99_smp_ops;
476
477 core99_smp_ops.take_timebase = smp_generic_take_timebase;
478 core99_smp_ops.give_timebase = smp_generic_give_timebase;
479 } else {
480 if (firstcpu != NULL)
481 tbprop = (u32 *)get_property(firstcpu, "timebase-enable", NULL);
482 if (tbprop)
483 core99_tb_gpio = *tbprop;
484 else
485 core99_tb_gpio = KL_GPIO_TB_ENABLE;
486 }
487
488 if (ncpus > 1) {
489 openpic_request_IPIs();
490 for (i = 1; i < ncpus; ++i)
491 smp_hw_index[i] = i;
492#ifdef CONFIG_6xx
493 powersave_nap = 0;
494#endif
495 core99_init_caches(0);
496 }
497
498 return ncpus;
499}
500
501static void __init smp_core99_kick_cpu(int nr)
502{
503 unsigned long save_vector, new_vector;
504 unsigned long flags;
505
506 volatile unsigned long *vector
507 = ((volatile unsigned long *)(KERNELBASE+0x100));
508 if (nr < 1 || nr > 3)
509 return;
510 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
511
512 local_irq_save(flags);
513 local_irq_disable();
514
515 /* Save reset vector */
516 save_vector = *vector;
517
518 /* Setup fake reset vector that does
519 * b __secondary_start_psurge - KERNELBASE
520 */
521 switch(nr) {
522 case 1:
523 new_vector = (unsigned long)__secondary_start_psurge;
524 break;
525 case 2:
526 new_vector = (unsigned long)__secondary_start_psurge2;
527 break;
528 case 3:
529 new_vector = (unsigned long)__secondary_start_psurge3;
530 break;
531 }
532 *vector = 0x48000002 + new_vector - KERNELBASE;
533
534 /* flush data cache and inval instruction cache */
535 flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
536
537 /* Put some life in our friend */
538 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
539
540 /* FIXME: We wait a bit for the CPU to take the exception, I should
541 * instead wait for the entry code to set something for me. Well,
542 * ideally, all that crap will be done in prom.c and the CPU left
543 * in a RAM-based wait loop like CHRP.
544 */
545 mdelay(1);
546
547 /* Restore our exception vector */
548 *vector = save_vector;
549 flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
550
551 local_irq_restore(flags);
552 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
553}
554
555static void __init smp_core99_setup_cpu(int cpu_nr)
556{
557 /* Setup L2/L3 */
558 if (cpu_nr != 0)
559 core99_init_caches(cpu_nr);
560
561 /* Setup openpic */
562 do_openpic_setup_cpu();
563
564 if (cpu_nr == 0) {
565#ifdef CONFIG_POWER4
566 extern void g5_phy_disable_cpu1(void);
567
568 /* If we didn't start the second CPU, we must take
569 * it off the bus
570 */
571 if (machine_is_compatible("MacRISC4") &&
572 num_online_cpus() < 2)
573 g5_phy_disable_cpu1();
574#endif /* CONFIG_POWER4 */
575 if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349);
576 }
577}
578
579void __init smp_core99_take_timebase(void)
580{
581 /* Secondary processor "takes" the timebase by freezing
582 * it, resetting its local TB and telling CPU 0 to go on
583 */
584 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
585 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
586 mb();
587
588 set_dec(tb_ticks_per_jiffy);
589 set_tb(0, 0);
590 last_jiffy_stamp(smp_processor_id()) = 0;
591
592 mb();
593 sec_tb_reset = 1;
594}
595
596void __init smp_core99_give_timebase(void)
597{
598 unsigned int t;
599
600 /* Primary processor waits for secondary to have frozen
601 * the timebase, resets local TB, and kick timebase again
602 */
603 /* wait for the secondary to have reset its TB before proceeding */
604 for (t = 1000; t > 0 && !sec_tb_reset; --t)
605 udelay(1000);
606 if (t == 0)
607 printk(KERN_WARNING "Timeout waiting sync on second CPU\n");
608
609 set_dec(tb_ticks_per_jiffy);
610 set_tb(0, 0);
611 last_jiffy_stamp(smp_processor_id()) = 0;
612 mb();
613
614 /* Now, restart the timebase by leaving the GPIO to an open collector */
615 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
616 pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
617
618 smp_tb_synchronized = 1;
619}
620
621
622/* PowerSurge-style Macs */
623struct smp_ops_t psurge_smp_ops __pmacdata = {
624 .message_pass = smp_psurge_message_pass,
625 .probe = smp_psurge_probe,
626 .kick_cpu = smp_psurge_kick_cpu,
627 .setup_cpu = smp_psurge_setup_cpu,
628 .give_timebase = smp_psurge_give_timebase,
629 .take_timebase = smp_psurge_take_timebase,
630};
631
632/* Core99 Macs (dual G4s) */
633struct smp_ops_t core99_smp_ops __pmacdata = {
634 .message_pass = smp_openpic_message_pass,
635 .probe = smp_core99_probe,
636 .kick_cpu = smp_core99_kick_cpu,
637 .setup_cpu = smp_core99_setup_cpu,
638 .give_timebase = smp_core99_give_timebase,
639 .take_timebase = smp_core99_take_timebase,
640};
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
new file mode 100644
index 000000000000..09636546f44e
--- /dev/null
+++ b/arch/ppc/platforms/pmac_time.c
@@ -0,0 +1,292 @@
1/*
2 * Support for periodic interrupts (100 per second) and for getting
3 * the current time from the RTC on Power Macintoshes.
4 *
5 * We use the decrementer register for our periodic interrupts.
6 *
7 * Paul Mackerras August 1996.
8 * Copyright (C) 1996 Paul Mackerras.
9 */
10#include <linux/config.h>
11#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/param.h>
15#include <linux/string.h>
16#include <linux/mm.h>
17#include <linux/init.h>
18#include <linux/time.h>
19#include <linux/adb.h>
20#include <linux/cuda.h>
21#include <linux/pmu.h>
22#include <linux/hardirq.h>
23
24#include <asm/sections.h>
25#include <asm/prom.h>
26#include <asm/system.h>
27#include <asm/io.h>
28#include <asm/pgtable.h>
29#include <asm/machdep.h>
30#include <asm/time.h>
31#include <asm/nvram.h>
32
33/* Apparently the RTC stores seconds since 1 Jan 1904 */
34#define RTC_OFFSET 2082844800
35
36/*
37 * Calibrate the decrementer frequency with the VIA timer 1.
38 */
39#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
40
41/* VIA registers */
42#define RS 0x200 /* skip between registers */
43#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
44#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
45#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
46#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
47#define ACR (11*RS) /* Auxiliary control register */
48#define IFR (13*RS) /* Interrupt flag register */
49
50/* Bits in ACR */
51#define T1MODE 0xc0 /* Timer 1 mode */
52#define T1MODE_CONT 0x40 /* continuous interrupts */
53
54/* Bits in IFR and IER */
55#define T1_INT 0x40 /* Timer 1 interrupt */
56
57extern struct timezone sys_tz;
58
59long __init
60pmac_time_init(void)
61{
62#ifdef CONFIG_NVRAM
63 s32 delta = 0;
64 int dst;
65
66 delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
67 delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
68 delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
69 if (delta & 0x00800000UL)
70 delta |= 0xFF000000UL;
71 dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
72 printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
73 dst ? "on" : "off");
74 return delta;
75#else
76 return 0;
77#endif
78}
79
80unsigned long __pmac
81pmac_get_rtc_time(void)
82{
83#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
84 struct adb_request req;
85 unsigned long now;
86#endif
87
88 /* Get the time from the RTC */
89 switch (sys_ctrler) {
90#ifdef CONFIG_ADB_CUDA
91 case SYS_CTRLER_CUDA:
92 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
93 return 0;
94 while (!req.complete)
95 cuda_poll();
96 if (req.reply_len != 7)
97 printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
98 req.reply_len);
99 now = (req.reply[3] << 24) + (req.reply[4] << 16)
100 + (req.reply[5] << 8) + req.reply[6];
101 return now - RTC_OFFSET;
102#endif /* CONFIG_ADB_CUDA */
103#ifdef CONFIG_ADB_PMU
104 case SYS_CTRLER_PMU:
105 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
106 return 0;
107 while (!req.complete)
108 pmu_poll();
109 if (req.reply_len != 4)
110 printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
111 req.reply_len);
112 now = (req.reply[0] << 24) + (req.reply[1] << 16)
113 + (req.reply[2] << 8) + req.reply[3];
114 return now - RTC_OFFSET;
115#endif /* CONFIG_ADB_PMU */
116 default: ;
117 }
118 return 0;
119}
120
121int __pmac
122pmac_set_rtc_time(unsigned long nowtime)
123{
124#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
125 struct adb_request req;
126#endif
127
128 nowtime += RTC_OFFSET;
129
130 switch (sys_ctrler) {
131#ifdef CONFIG_ADB_CUDA
132 case SYS_CTRLER_CUDA:
133 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
134 nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
135 return 0;
136 while (!req.complete)
137 cuda_poll();
138 if ((req.reply_len != 3) && (req.reply_len != 7))
139 printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
140 req.reply_len);
141 return 1;
142#endif /* CONFIG_ADB_CUDA */
143#ifdef CONFIG_ADB_PMU
144 case SYS_CTRLER_PMU:
145 if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
146 nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
147 return 0;
148 while (!req.complete)
149 pmu_poll();
150 if (req.reply_len != 0)
151 printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
152 req.reply_len);
153 return 1;
154#endif /* CONFIG_ADB_PMU */
155 default:
156 return 0;
157 }
158}
159
160/*
161 * Calibrate the decrementer register using VIA timer 1.
162 * This is used both on powermacs and CHRP machines.
163 */
164int __init
165via_calibrate_decr(void)
166{
167 struct device_node *vias;
168 volatile unsigned char *via;
169 int count = VIA_TIMER_FREQ_6 / 100;
170 unsigned int dstart, dend;
171
172 vias = find_devices("via-cuda");
173 if (vias == 0)
174 vias = find_devices("via-pmu");
175 if (vias == 0)
176 vias = find_devices("via");
177 if (vias == 0 || vias->n_addrs == 0)
178 return 0;
179 via = (volatile unsigned char *)
180 ioremap(vias->addrs[0].address, vias->addrs[0].size);
181
182 /* set timer 1 for continuous interrupts */
183 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
184 /* set the counter to a small value */
185 out_8(&via[T1CH], 2);
186 /* set the latch to `count' */
187 out_8(&via[T1LL], count);
188 out_8(&via[T1LH], count >> 8);
189 /* wait until it hits 0 */
190 while ((in_8(&via[IFR]) & T1_INT) == 0)
191 ;
192 dstart = get_dec();
193 /* clear the interrupt & wait until it hits 0 again */
194 in_8(&via[T1CL]);
195 while ((in_8(&via[IFR]) & T1_INT) == 0)
196 ;
197 dend = get_dec();
198
199 tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
200 tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
201
202 printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
203 tb_ticks_per_jiffy, dstart - dend);
204
205 iounmap((void*)via);
206
207 return 1;
208}
209
210#ifdef CONFIG_PMAC_PBOOK
211/*
212 * Reset the time after a sleep.
213 */
214static int __pmac
215time_sleep_notify(struct pmu_sleep_notifier *self, int when)
216{
217 static unsigned long time_diff;
218 unsigned long flags;
219 unsigned long seq;
220
221 switch (when) {
222 case PBOOK_SLEEP_NOW:
223 do {
224 seq = read_seqbegin_irqsave(&xtime_lock, flags);
225 time_diff = xtime.tv_sec - pmac_get_rtc_time();
226 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
227 break;
228 case PBOOK_WAKE:
229 write_seqlock_irqsave(&xtime_lock, flags);
230 xtime.tv_sec = pmac_get_rtc_time() + time_diff;
231 xtime.tv_nsec = 0;
232 last_rtc_update = xtime.tv_sec;
233 write_sequnlock_irqrestore(&xtime_lock, flags);
234 break;
235 }
236 return PBOOK_SLEEP_OK;
237}
238
239static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
240 time_sleep_notify, SLEEP_LEVEL_MISC,
241};
242#endif /* CONFIG_PMAC_PBOOK */
243
244/*
245 * Query the OF and get the decr frequency.
246 * This was taken from the pmac time_init() when merging the prep/pmac
247 * time functions.
248 */
249void __init
250pmac_calibrate_decr(void)
251{
252 struct device_node *cpu;
253 unsigned int freq, *fp;
254
255#ifdef CONFIG_PMAC_PBOOK
256 pmu_register_sleep_notifier(&time_sleep_notifier);
257#endif /* CONFIG_PMAC_PBOOK */
258
259 /* We assume MacRISC2 machines have correct device-tree
260 * calibration. That's better since the VIA itself seems
261 * to be slightly off. --BenH
262 */
263 if (!machine_is_compatible("MacRISC2") &&
264 !machine_is_compatible("MacRISC3") &&
265 !machine_is_compatible("MacRISC4"))
266 if (via_calibrate_decr())
267 return;
268
269 /* Special case: QuickSilver G4s seem to have a badly calibrated
270 * timebase-frequency in OF, VIA is much better on these. We should
271 * probably implement calibration based on the KL timer on these
272 * machines anyway... -BenH
273 */
274 if (machine_is_compatible("PowerMac3,5"))
275 if (via_calibrate_decr())
276 return;
277 /*
278 * The cpu node should have a timebase-frequency property
279 * to tell us the rate at which the decrementer counts.
280 */
281 cpu = find_type_devices("cpu");
282 if (cpu == 0)
283 panic("can't find cpu node in time_init");
284 fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
285 if (fp == 0)
286 panic("can't get cpu timebase frequency");
287 freq = *fp;
288 printk("time_init: decrementer frequency = %u.%.6u MHz\n",
289 freq/1000000, freq%1000000);
290 tb_ticks_per_jiffy = freq / HZ;
291 tb_to_us = mulhwu_scale_factor(freq, 1000000);
292}
diff --git a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
new file mode 100644
index 000000000000..0abe15159e6c
--- /dev/null
+++ b/arch/ppc/platforms/powerpmc250.c
@@ -0,0 +1,383 @@
1/*
2 * arch/ppc/platforms/powerpmc250.c
3 *
4 * Board setup routines for Force PowerPMC-250 Processor PMC
5 *
6 * Author: Troy Benjegerdes <tbenjegerdes@mvista.com>
7 * Borrowed heavily from prpmc750_*.c by
8 * Matt Porter <mporter@mvista.com>
9 *
10 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/kdev_t.h>
24#include <linux/types.h>
25#include <linux/major.h>
26#include <linux/initrd.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/irq.h>
30#include <linux/slab.h>
31#include <linux/seq_file.h>
32#include <linux/ide.h>
33#include <linux/root_dev.h>
34
35#include <asm/byteorder.h>
36#include <asm/system.h>
37#include <asm/pgtable.h>
38#include <asm/page.h>
39#include <asm/dma.h>
40#include <asm/io.h>
41#include <asm/irq.h>
42#include <asm/machdep.h>
43#include <asm/time.h>
44#include <platforms/powerpmc250.h>
45#include <asm/open_pic.h>
46#include <asm/pci-bridge.h>
47#include <asm/mpc10x.h>
48#include <asm/uaccess.h>
49#include <asm/bootinfo.h>
50
51extern void powerpmc250_find_bridges(void);
52extern unsigned long loops_per_jiffy;
53
54static u_char powerpmc250_openpic_initsenses[] __initdata =
55{
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 1, /* PMC INTA (also MPC107 output interrupt INTA) */
58 1, /* PMC INTB (also I82559 Ethernet controller) */
59 1, /* PMC INTC */
60 1, /* PMC INTD */
61 0, /* DUART interrupt (active high) */
62};
63
64static int
65powerpmc250_show_cpuinfo(struct seq_file *m)
66{
67 seq_printf(m,"machine\t\t: Force PowerPMC250\n");
68
69 return 0;
70}
71
72static void __init
73powerpmc250_setup_arch(void)
74{
75 /* init to some ~sane value until calibrate_delay() runs */
76 loops_per_jiffy = 50000000/HZ;
77
78 /* Lookup PCI host bridges */
79 powerpmc250_find_bridges();
80
81#ifdef CONFIG_BLK_DEV_INITRD
82 if (initrd_start)
83 ROOT_DEV = Root_RAM0;
84 else
85#endif
86#ifdef CONFIG_ROOT_NFS
87 ROOT_DEV = Root_NFS;
88#else
89 ROOT_DEV = Root_SDA2;
90#endif
91
92 printk("Force PowerPMC250 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
93}
94
95#if 0
96/*
97 * Compute the PrPMC750's bus speed using the baud clock as a
98 * reference.
99 */
100unsigned long __init powerpmc250_get_bus_speed(void)
101{
102 unsigned long tbl_start, tbl_end;
103 unsigned long current_state, old_state, bus_speed;
104 unsigned char lcr, dll, dlm;
105 int baud_divisor, count;
106
107 /* Read the UART's baud clock divisor */
108 lcr = readb(PRPMC750_SERIAL_0_LCR);
109 writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR);
110 dll = readb(PRPMC750_SERIAL_0_DLL);
111 dlm = readb(PRPMC750_SERIAL_0_DLM);
112 writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR);
113 baud_divisor = (dlm << 8) | dll;
114
115 /*
116 * Use the baud clock divisor and base baud clock
117 * to determine the baud rate and use that as
118 * the number of baud clock edges we use for
119 * the time base sample. Make it half the baud
120 * rate.
121 */
122 count = PRPMC750_BASE_BAUD / (baud_divisor * 16);
123
124 /* Find the first edge of the baud clock */
125 old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK;
126 do {
127 current_state = readb(PRPMC750_STATUS_REG) &
128 PRPMC750_BAUDOUT_MASK;
129 } while(old_state == current_state);
130
131 old_state = current_state;
132
133 /* Get the starting time base value */
134 tbl_start = get_tbl();
135
136 /*
137 * Loop until we have found a number of edges equal
138 * to half the count (half the baud rate)
139 */
140 do {
141 do {
142 current_state = readb(PRPMC750_STATUS_REG) &
143 PRPMC750_BAUDOUT_MASK;
144 } while(old_state == current_state);
145 old_state = current_state;
146 } while (--count);
147
148 /* Get the ending time base value */
149 tbl_end = get_tbl();
150
151 /* Compute bus speed */
152 bus_speed = (tbl_end-tbl_start)*128;
153
154 return bus_speed;
155}
156#endif
157
158static void __init
159powerpmc250_calibrate_decr(void)
160{
161 unsigned long freq;
162 int divisor = 4;
163
164 //freq = powerpmc250_get_bus_speed();
165#warning hardcoded bus freq
166 freq = 100000000;
167
168 tb_ticks_per_jiffy = freq / (HZ * divisor);
169 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
170}
171
172static void
173powerpmc250_restart(char *cmd)
174{
175 local_irq_disable();
176 /* Hard reset */
177 writeb(0x11, 0xfe000332);
178 while(1);
179}
180
181static void
182powerpmc250_halt(void)
183{
184 local_irq_disable();
185 while (1);
186}
187
188static void
189powerpmc250_power_off(void)
190{
191 powerpmc250_halt();
192}
193
194static void __init
195powerpmc250_init_IRQ(void)
196{
197
198 OpenPIC_InitSenses = powerpmc250_openpic_initsenses;
199 OpenPIC_NumInitSenses = sizeof(powerpmc250_openpic_initsenses);
200 mpc10x_set_openpic();
201}
202
203/*
204 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
205 */
206static __inline__ void
207powerpmc250_set_bat(void)
208{
209 unsigned long bat3u, bat3l;
210 static int mapping_set = 0;
211
212 if (!mapping_set)
213 {
214 __asm__ __volatile__(
215 " lis %0,0xf000\n \
216 ori %1,%0,0x002a\n \
217 ori %0,%0,0x1ffe\n \
218 mtspr 0x21e,%0\n \
219 mtspr 0x21f,%1\n \
220 isync\n \
221 sync "
222 : "=r" (bat3u), "=r" (bat3l));
223
224 mapping_set = 1;
225 }
226 return;
227}
228
229static unsigned long __init
230powerpmc250_find_end_of_memory(void)
231{
232 /* Cover I/O space with a BAT */
233 /* yuck, better hope your ram size is a power of 2 -- paulus */
234 powerpmc250_set_bat();
235
236 return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
237}
238
239static void __init
240powerpmc250_map_io(void)
241{
242 io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
243}
244
245void __init
246platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
247 unsigned long r6, unsigned long r7)
248{
249 parse_bootinfo(find_bootinfo());
250
251#ifdef CONFIG_BLK_DEV_INITRD
252 if ( r4 )
253 {
254 initrd_start = r4 + KERNELBASE;
255 initrd_end = r5 + KERNELBASE;
256 }
257#endif
258
259 /* Copy cmd_line parameters */
260 if ( r6)
261 {
262 *(char *)(r7 + KERNELBASE) = 0;
263 strcpy(cmd_line, (char *)(r6 + KERNELBASE));
264 }
265
266 isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
267 isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
268 pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
269
270 ppc_md.setup_arch = powerpmc250_setup_arch;
271 ppc_md.show_cpuinfo = powerpmc250_show_cpuinfo;
272 ppc_md.init_IRQ = powerpmc250_init_IRQ;
273 ppc_md.get_irq = openpic_get_irq;
274
275 ppc_md.find_end_of_memory = powerpmc250_find_end_of_memory;
276 ppc_md.setup_io_mappings = powerpmc250_map_io;
277
278 ppc_md.restart = powerpmc250_restart;
279 ppc_md.power_off = powerpmc250_power_off;
280 ppc_md.halt = powerpmc250_halt;
281
282 /* PowerPMC250 has no timekeeper part */
283 ppc_md.time_init = NULL;
284 ppc_md.get_rtc_time = NULL;
285 ppc_md.set_rtc_time = NULL;
286 ppc_md.calibrate_decr = powerpmc250_calibrate_decr;
287}
288
289
290/*
291 * (This used to be arch/ppc/platforms/powerpmc250_pci.c)
292 *
293 * PCI support for Force PowerPMC250
294 *
295 */
296
297#undef DEBUG
298#ifdef DEBUG
299#define DBG(x...) printk(x)
300#else
301#define DBG(x...)
302#endif /* DEBUG */
303
304static inline int __init
305powerpmc250_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
306{
307 static char pci_irq_table[][4] =
308 /*
309 * PCI IDSEL/INTPIN->INTLINE
310 * A B C D
311 */
312 {
313 {17, 0, 0, 0}, /* Device 11 - 82559 */
314 {0, 0, 0, 0}, /* 12 */
315 {0, 0, 0, 0}, /* 13 */
316 {0, 0, 0, 0}, /* 14 */
317 {0, 0, 0, 0}, /* 15 */
318 {16, 17, 18, 19}, /* Device 16 - PMC A1?? */
319 };
320 const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
321 return PCI_IRQ_TABLE_LOOKUP;
322};
323
324static int
325powerpmc250_exclude_device(u_char bus, u_char devfn)
326{
327 /*
328 * While doing PCI Scan the MPC107 will 'detect' itself as
329 * device on the PCI Bus, will create an incorrect response and
330 * later will respond incorrectly to Configuration read coming
331 * from another device.
332 *
333 * The work around is that when doing a PCI Scan one
334 * should skip its own device number in the scan.
335 *
336 * The top IDsel is AD13 and the middle is AD14.
337 *
338 * -- Note from force
339 */
340
341 if ((bus == 0) && (PCI_SLOT(devfn) == 13 || PCI_SLOT(devfn) == 14)) {
342 return PCIBIOS_DEVICE_NOT_FOUND;
343 }
344 else {
345 return PCIBIOS_SUCCESSFUL;
346 }
347}
348
349void __init
350powerpmc250_find_bridges(void)
351{
352 struct pci_controller* hose;
353
354 hose = pcibios_alloc_controller();
355 if (!hose){
356 printk("Can't allocate PCI 'hose' structure!!!\n");
357 return;
358 }
359
360 hose->first_busno = 0;
361 hose->last_busno = 0xff;
362
363 if (mpc10x_bridge_init(hose,
364 MPC10X_MEM_MAP_B,
365 MPC10X_MEM_MAP_B,
366 MPC10X_MAPB_EUMB_BASE) == 0) {
367
368 hose->mem_resources[0].end = 0xffffffff;
369
370 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
371
372 /* ppc_md.pcibios_fixup = pcore_pcibios_fixup; */
373 ppc_md.pci_swizzle = common_swizzle;
374
375 ppc_md.pci_exclude_device = powerpmc250_exclude_device;
376 ppc_md.pci_map_irq = powerpmc250_map_irq;
377 } else {
378 if (ppc_md.progress)
379 ppc_md.progress("Bridge init failed", 0x100);
380 printk("Host bridge init failed\n");
381 }
382
383}
diff --git a/arch/ppc/platforms/powerpmc250.h b/arch/ppc/platforms/powerpmc250.h
new file mode 100644
index 000000000000..41a6dc881911
--- /dev/null
+++ b/arch/ppc/platforms/powerpmc250.h
@@ -0,0 +1,52 @@
1/*
2 * include/asm-ppc/platforms/powerpmc250.h
3 *
4 * Definitions for Force PowerPMC-250 board support
5 *
6 * Author: Troy Benjegerdes <tbenjegerdes@mvista.com>
7 *
8 * Borrowed heavily from prpmc750.h by Matt Porter <mporter@mvista.com>
9 *
10 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#ifndef __ASMPPC_POWERPMC250_H
17#define __ASMPPC_POWERPMC250_H
18
19#define POWERPMC250_PCI_CONFIG_ADDR 0x80000cf8
20#define POWERPMC250_PCI_CONFIG_DATA 0x80000cfc
21
22#define POWERPMC250_PCI_PHY_MEM_BASE 0xc0000000
23#define POWERPMC250_PCI_MEM_BASE 0xf0000000
24#define POWERPMC250_PCI_IO_BASE 0x80000000
25
26#define POWERPMC250_ISA_IO_BASE POWERPMC250_PCI_IO_BASE
27#define POWERPMC250_ISA_MEM_BASE POWERPMC250_PCI_MEM_BASE
28#define POWERPMC250_PCI_MEM_OFFSET POWERPMC250_PCI_PHY_MEM_BASE
29
30#define POWERPMC250_SYS_MEM_BASE 0x80000000
31
32#define POWERPMC250_HAWK_SMC_BASE 0xfef80000
33
34#define POWERPMC250_BASE_BAUD 12288000
35#define POWERPMC250_SERIAL 0xff000000
36#define POWERPMC250_SERIAL_IRQ 20
37
38/* UART Defines. */
39#define RS_TABLE_SIZE 1
40
41#define BASE_BAUD (POWERPMC250_BASE_BAUD / 16)
42
43#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
44
45#define SERIAL_PORT_DFNS \
46 { 0, BASE_BAUD, POWERPMC250_SERIAL, POWERPMC250_SERIAL_IRQ, \
47 STD_COM_FLAGS, /* ttyS0 */ \
48 iomem_base: (u8 *)POWERPMC250_SERIAL, \
49 iomem_reg_shift: 0, \
50 io_type: SERIAL_IO_MEM }
51
52#endif /* __ASMPPC_POWERPMC250_H */
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
new file mode 100644
index 000000000000..65705c911795
--- /dev/null
+++ b/arch/ppc/platforms/pplus.c
@@ -0,0 +1,917 @@
1/*
2 * arch/ppc/platforms/pplus.c
3 *
4 * Board and PCI setup routines for MCG PowerPlus
5 *
6 * Author: Randy Vinson <rvinson@mvista.com>
7 *
8 * Derived from original PowerPlus PReP work by
9 * Cort Dougan, Johnnie Peters, Matt Porter, and
10 * Troy Benjegerdes.
11 *
12 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express
15 * or implied.
16 */
17
18#include <linux/config.h>
19#include <linux/kernel.h>
20#include <linux/interrupt.h>
21#include <linux/init.h>
22#include <linux/ioport.h>
23#include <linux/console.h>
24#include <linux/pci.h>
25#include <linux/irq.h>
26#include <linux/ide.h>
27#include <linux/seq_file.h>
28#include <linux/root_dev.h>
29
30#include <asm/system.h>
31#include <asm/io.h>
32#include <asm/pgtable.h>
33#include <asm/dma.h>
34#include <asm/machdep.h>
35#include <asm/prep_nvram.h>
36#include <asm/vga.h>
37#include <asm/i8259.h>
38#include <asm/open_pic.h>
39#include <asm/hawk.h>
40#include <asm/todc.h>
41#include <asm/bootinfo.h>
42#include <asm/kgdb.h>
43#include <asm/reg.h>
44
45#include "pplus.h"
46
47#undef DUMP_DBATS
48
49TODC_ALLOC();
50
51extern void pplus_setup_hose(void);
52extern void pplus_set_VIA_IDE_native(void);
53
54extern unsigned long loops_per_jiffy;
55unsigned char *Motherboard_map_name;
56
57/* Tables for known hardware */
58
59/* Motorola Mesquite */
60static inline int
61mesquite_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
62{
63 static char pci_irq_table[][4] =
64 /*
65 * MPIC interrupts for various IDSEL values (MPIC IRQ0 =
66 * Linux IRQ16 (to leave room for ISA IRQs at 0-15).
67 * PCI IDSEL/INTPIN->INTLINE
68 * A B C D
69 */
70 {
71 {18, 0, 0, 0}, /* IDSEL 14 - Enet 0 */
72 { 0, 0, 0, 0}, /* IDSEL 15 - unused */
73 {19, 19, 19, 19}, /* IDSEL 16 - PMC Slot 1 */
74 { 0, 0, 0, 0}, /* IDSEL 17 - unused */
75 { 0, 0, 0, 0}, /* IDSEL 18 - unused */
76 { 0, 0, 0, 0}, /* IDSEL 19 - unused */
77 {24, 25, 26, 27}, /* IDSEL 20 - P2P bridge (to cPCI 1) */
78 { 0, 0, 0, 0}, /* IDSEL 21 - unused */
79 {28, 29, 30, 31} /* IDSEL 22 - P2P bridge (to cPCI 2) */
80 };
81
82 const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4;
83 return PCI_IRQ_TABLE_LOOKUP;
84}
85
86/* Motorola Sitka */
87static inline int
88sitka_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
89{
90 static char pci_irq_table[][4] =
91 /*
92 * MPIC interrupts for various IDSEL values (MPIC IRQ0 =
93 * Linux IRQ16 (to leave room for ISA IRQs at 0-15).
94 * PCI IDSEL/INTPIN->INTLINE
95 * A B C D
96 */
97 {
98 {18, 0, 0, 0}, /* IDSEL 14 - Enet 0 */
99 { 0, 0, 0, 0}, /* IDSEL 15 - unused */
100 {25, 26, 27, 28}, /* IDSEL 16 - PMC Slot 1 */
101 {28, 25, 26, 27}, /* IDSEL 17 - PMC Slot 2 */
102 { 0, 0, 0, 0}, /* IDSEL 18 - unused */
103 { 0, 0, 0, 0}, /* IDSEL 19 - unused */
104 {20, 0, 0, 0} /* IDSEL 20 - P2P bridge (to cPCI) */
105 };
106
107 const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4;
108 return PCI_IRQ_TABLE_LOOKUP;
109}
110
111/* Motorola MTX */
112static inline int
113MTX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
114{
115 static char pci_irq_table[][4] =
116 /*
117 * MPIC interrupts for various IDSEL values (MPIC IRQ0 =
118 * Linux IRQ16 (to leave room for ISA IRQs at 0-15).
119 * PCI IDSEL/INTPIN->INTLINE
120 * A B C D
121 */
122 {
123 {19, 0, 0, 0}, /* IDSEL 12 - SCSI */
124 { 0, 0, 0, 0}, /* IDSEL 13 - unused */
125 {18, 0, 0, 0}, /* IDSEL 14 - Enet */
126 { 0, 0, 0, 0}, /* IDSEL 15 - unused */
127 {25, 26, 27, 28}, /* IDSEL 16 - PMC Slot 1 */
128 {26, 27, 28, 25}, /* IDSEL 17 - PMC Slot 2 */
129 {27, 28, 25, 26} /* IDSEL 18 - PCI Slot 3 */
130 };
131
132 const long min_idsel = 12, max_idsel = 18, irqs_per_slot = 4;
133 return PCI_IRQ_TABLE_LOOKUP;
134}
135
136/* Motorola MTX Plus */
137/* Secondary bus interrupt routing is not supported yet */
138static inline int
139MTXplus_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
140{
141 static char pci_irq_table[][4] =
142 /*
143 * MPIC interrupts for various IDSEL values (MPIC IRQ0 =
144 * Linux IRQ16 (to leave room for ISA IRQs at 0-15).
145 * PCI IDSEL/INTPIN->INTLINE
146 * A B C D
147 */
148 {
149 {19, 0, 0, 0}, /* IDSEL 12 - SCSI */
150 { 0, 0, 0, 0}, /* IDSEL 13 - unused */
151 {18, 0, 0, 0}, /* IDSEL 14 - Enet 1 */
152 { 0, 0, 0, 0}, /* IDSEL 15 - unused */
153 {25, 26, 27, 28}, /* IDSEL 16 - PCI Slot 1P */
154 {26, 27, 28, 25}, /* IDSEL 17 - PCI Slot 2P */
155 {27, 28, 25, 26}, /* IDSEL 18 - PCI Slot 3P */
156 {26, 0, 0, 0}, /* IDSEL 19 - Enet 2 */
157 { 0, 0, 0, 0} /* IDSEL 20 - P2P Bridge */
158 };
159
160 const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
161 return PCI_IRQ_TABLE_LOOKUP;
162}
163
164static inline int
165Genesis2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
166{
167 /* 2600
168 * Raven 31
169 * ISA 11
170 * SCSI 12 - IRQ3
171 * Univ 13
172 * eth 14 - IRQ2
173 * VGA 15 - IRQ4
174 * PMC1 16 - IRQ9,10,11,12 = PMC1 A-D
175 * PMC2 17 - IRQ12,9,10,11 = A-D
176 * SCSI2 18 - IRQ11
177 * eth2 19 - IRQ10
178 * PCIX 20 - IRQ9,10,11,12 = PCI A-D
179 */
180
181 /* 2400
182 * Hawk 31
183 * ISA 11
184 * Univ 13
185 * eth 14 - IRQ2
186 * PMC1 16 - IRQ9,10,11,12 = PMC A-D
187 * PMC2 17 - IRQ12,9,10,11 = PMC A-D
188 * PCIX 20 - IRQ9,10,11,12 = PMC A-D
189 */
190
191 /* 2300
192 * Raven 31
193 * ISA 11
194 * Univ 13
195 * eth 14 - IRQ2
196 * PMC1 16 - 9,10,11,12 = A-D
197 * PMC2 17 - 9,10,11,12 = B,C,D,A
198 */
199
200 static char pci_irq_table[][4] =
201 /*
202 * MPIC interrupts for various IDSEL values (MPIC IRQ0 =
203 * Linux IRQ16 (to leave room for ISA IRQs at 0-15).
204 * PCI IDSEL/INTPIN->INTLINE
205 * A B C D
206 */
207 {
208 {19, 0, 0, 0}, /* IDSEL 12 - SCSI */
209 { 0, 0, 0, 0}, /* IDSEL 13 - Universe PCI - VME */
210 {18, 0, 0, 0}, /* IDSEL 14 - Enet 1 */
211 { 0, 0, 0, 0}, /* IDSEL 15 - unused */
212 {25, 26, 27, 28}, /* IDSEL 16 - PCI/PMC Slot 1P */
213 {28, 25, 26, 27}, /* IDSEL 17 - PCI/PMC Slot 2P */
214 {27, 28, 25, 26}, /* IDSEL 18 - PCI Slot 3P */
215 {26, 0, 0, 0}, /* IDSEL 19 - Enet 2 */
216 {25, 26, 27, 28} /* IDSEL 20 - P2P Bridge */
217 };
218
219 const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
220 return PCI_IRQ_TABLE_LOOKUP;
221}
222
223#define MOTOROLA_CPUTYPE_REG 0x800
224#define MOTOROLA_BASETYPE_REG 0x803
225#define MPIC_RAVEN_ID 0x48010000
226#define MPIC_HAWK_ID 0x48030000
227#define MOT_PROC2_BIT 0x800
228
229static u_char pplus_openpic_initsenses[] __initdata = {
230 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* MVME2600_INT_SIO */
231 (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_FALCN_ECC_ERR */
232 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_PCI_ETHERNET */
233 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_SCSI */
234 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_PCI_GRAPHICS */
235 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME0 */
236 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME1 */
237 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME2 */
238 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME3 */
239 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTA */
240 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTB */
241 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTC */
242 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTD */
243 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG0 */
244 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG1 */
245 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
246};
247
248int mot_entry = -1;
249int prep_keybd_present = 1;
250int mot_multi = 0;
251
252struct brd_info {
253 /* 0x100 mask assumes for Raven and Hawk boards that the level/edge
254 * are set */
255 int cpu_type;
256 /* 0x200 if this board has a Hawk chip. */
257 int base_type;
258 /* or'ed with 0x80 if this board should be checked for multi CPU */
259 int max_cpu;
260 const char *name;
261 int (*map_irq) (struct pci_dev *, unsigned char, unsigned char);
262};
263struct brd_info mot_info[] = {
264 {0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq},
265 {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq},
266 {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq},
267 {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", mesquite_map_irq},
268 {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_map_irq},
269 {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_map_irq},
270 {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_map_irq},
271 {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_map_irq},
272 {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_map_irq},
273 {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_map_irq},
274 {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_map_irq},
275 {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_map_irq},
276 {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_map_irq},
277 {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_map_irq},
278 {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_map_irq},
279 {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_map_irq},
280 {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_map_irq},
281 {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_map_irq},
282 {0x000, 0x00, 0x00, "", NULL}
283};
284
285void __init pplus_set_board_type(void)
286{
287 unsigned char cpu_type;
288 unsigned char base_mod;
289 int entry;
290 unsigned short devid;
291 unsigned long *ProcInfo = NULL;
292
293 cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
294 base_mod = inb(MOTOROLA_BASETYPE_REG);
295 early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
296
297 for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
298 /* Check for Hawk chip */
299 if (mot_info[entry].cpu_type & 0x200) {
300 if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK)
301 continue;
302 } else {
303 /* store the system config register for later use. */
304 ProcInfo =
305 (unsigned long *)ioremap(PPLUS_SYS_CONFIG_REG, 4);
306
307 /* Check non hawk boards */
308 if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
309 continue;
310
311 if (mot_info[entry].base_type == 0) {
312 mot_entry = entry;
313 break;
314 }
315
316 if (mot_info[entry].base_type != base_mod)
317 continue;
318 }
319
320 if (!(mot_info[entry].max_cpu & 0x80)) {
321 mot_entry = entry;
322 break;
323 }
324
325 /* processor 1 not present and max processor zero indicated */
326 if ((*ProcInfo & MOT_PROC2_BIT)
327 && !(mot_info[entry].max_cpu & 0x7f)) {
328 mot_entry = entry;
329 break;
330 }
331
332 /* processor 1 present and max processor zero indicated */
333 if (!(*ProcInfo & MOT_PROC2_BIT)
334 && (mot_info[entry].max_cpu & 0x7f)) {
335 mot_entry = entry;
336 break;
337 }
338
339 /* Indicate to system if this is a multiprocessor board */
340 if (!(*ProcInfo & MOT_PROC2_BIT))
341 mot_multi = 1;
342 }
343
344 if (mot_entry == -1)
345 /* No particular cpu type found - assume Mesquite (MCP750) */
346 mot_entry = 1;
347
348 Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
349 ppc_md.pci_map_irq = mot_info[mot_entry].map_irq;
350}
351void __init pplus_pib_init(void)
352{
353 unsigned char reg;
354 unsigned short short_reg;
355
356 struct pci_dev *dev = NULL;
357
358 /*
359 * Perform specific configuration for the Via Tech or
360 * or Winbond PCI-ISA-Bridge part.
361 */
362 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
363 PCI_DEVICE_ID_VIA_82C586_1, dev))) {
364 /*
365 * PPCBUG does not set the enable bits
366 * for the IDE device. Force them on here.
367 */
368 pci_read_config_byte(dev, 0x40, &reg);
369
370 reg |= 0x03; /* IDE: Chip Enable Bits */
371 pci_write_config_byte(dev, 0x40, reg);
372 }
373
374 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
375 PCI_DEVICE_ID_VIA_82C586_2,
376 dev)) && (dev->devfn = 0x5a)) {
377 /* Force correct USB interrupt */
378 dev->irq = 11;
379 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
380 }
381
382 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
383 PCI_DEVICE_ID_WINBOND_83C553, dev))) {
384 /* Clear PCI Interrupt Routing Control Register. */
385 short_reg = 0x0000;
386 pci_write_config_word(dev, 0x44, short_reg);
387 /* Route IDE interrupts to IRQ 14 */
388 reg = 0xEE;
389 pci_write_config_byte(dev, 0x43, reg);
390 }
391
392 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
393 PCI_DEVICE_ID_WINBOND_82C105, dev))) {
394 /*
395 * Disable LEGIRQ mode so PCI INTS are routed
396 * directly to the 8259 and enable both channels
397 */
398 pci_write_config_dword(dev, 0x40, 0x10ff0033);
399
400 /* Force correct IDE interrupt */
401 dev->irq = 14;
402 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
403 }
404 pci_dev_put(dev);
405}
406
407void __init pplus_set_VIA_IDE_legacy(void)
408{
409 unsigned short vend, dev;
410
411 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
412 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
413
414 if ((vend == PCI_VENDOR_ID_VIA) &&
415 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
416 unsigned char temp;
417
418 /* put back original "standard" port base addresses */
419 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
420 PCI_BASE_ADDRESS_0, 0x1f1);
421 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
422 PCI_BASE_ADDRESS_1, 0x3f5);
423 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
424 PCI_BASE_ADDRESS_2, 0x171);
425 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
426 PCI_BASE_ADDRESS_3, 0x375);
427 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
428 PCI_BASE_ADDRESS_4, 0xcc01);
429
430 /* put into legacy mode */
431 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
432 &temp);
433 temp &= ~0x05;
434 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
435 temp);
436 }
437}
438
439void pplus_set_VIA_IDE_native(void)
440{
441 unsigned short vend, dev;
442
443 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
444 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
445
446 if ((vend == PCI_VENDOR_ID_VIA) &&
447 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
448 unsigned char temp;
449
450 /* put into native mode */
451 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
452 &temp);
453 temp |= 0x05;
454 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
455 temp);
456 }
457}
458
459void __init pplus_pcibios_fixup(void)
460{
461
462 unsigned char reg;
463 unsigned short devid;
464 unsigned char base_mod;
465
466 printk(KERN_INFO "Setting PCI interrupts for a \"%s\"\n",
467 Motherboard_map_name);
468
469 /* Setup the Winbond or Via PIB */
470 pplus_pib_init();
471
472 /* Set up floppy in PS/2 mode */
473 outb(0x09, SIO_CONFIG_RA);
474 reg = inb(SIO_CONFIG_RD);
475 reg = (reg & 0x3F) | 0x40;
476 outb(reg, SIO_CONFIG_RD);
477 outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
478
479 /* This is a hack. If this is a 2300 or 2400 mot board then there is
480 * no keyboard controller and we have to indicate that.
481 */
482
483 early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
484 base_mod = inb(MOTOROLA_BASETYPE_REG);
485 if ((devid == PCI_DEVICE_ID_MOTOROLA_HAWK) ||
486 (base_mod == 0xF9) || (base_mod == 0xFA) || (base_mod == 0xE1))
487 prep_keybd_present = 0;
488}
489
490void __init pplus_find_bridges(void)
491{
492 struct pci_controller *hose;
493
494 hose = pcibios_alloc_controller();
495 if (!hose)
496 return;
497
498 hose->first_busno = 0;
499 hose->last_busno = 0xff;
500
501 hose->pci_mem_offset = PREP_ISA_MEM_BASE;
502 hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
503
504 pci_init_resource(&hose->io_resource, PPLUS_PCI_IO_START,
505 PPLUS_PCI_IO_END, IORESOURCE_IO, "PCI host bridge");
506 pci_init_resource(&hose->mem_resources[0], PPLUS_PROC_PCI_MEM_START,
507 PPLUS_PROC_PCI_MEM_END, IORESOURCE_MEM,
508 "PCI host bridge");
509
510 hose->io_space.start = PPLUS_PCI_IO_START;
511 hose->io_space.end = PPLUS_PCI_IO_END;
512 hose->mem_space.start = PPLUS_PCI_MEM_START;
513 hose->mem_space.end = PPLUS_PCI_MEM_END - HAWK_MPIC_SIZE;
514
515 if (hawk_init(hose, PPLUS_HAWK_PPC_REG_BASE, PPLUS_PROC_PCI_MEM_START,
516 PPLUS_PROC_PCI_MEM_END - HAWK_MPIC_SIZE,
517 PPLUS_PROC_PCI_IO_START, PPLUS_PROC_PCI_IO_END,
518 PPLUS_PROC_PCI_MEM_END - HAWK_MPIC_SIZE + 1)
519 != 0) {
520 printk(KERN_CRIT "Could not initialize host bridge\n");
521
522 }
523
524 pplus_set_VIA_IDE_legacy();
525
526 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
527
528 ppc_md.pcibios_fixup = pplus_pcibios_fixup;
529 ppc_md.pci_swizzle = common_swizzle;
530}
531
532static int pplus_show_cpuinfo(struct seq_file *m)
533{
534 seq_printf(m, "vendor\t\t: Motorola MCG\n");
535 seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name);
536
537 return 0;
538}
539
540static void __init pplus_setup_arch(void)
541{
542 struct pci_controller *hose;
543
544 if (ppc_md.progress)
545 ppc_md.progress("pplus_setup_arch: enter", 0);
546
547 /* init to some ~sane value until calibrate_delay() runs */
548 loops_per_jiffy = 50000000;
549
550 if (ppc_md.progress)
551 ppc_md.progress("pplus_setup_arch: find_bridges", 0);
552
553 /* Setup PCI host bridge */
554 pplus_find_bridges();
555
556 hose = pci_bus_to_hose(0);
557 isa_io_base = (ulong) hose->io_base_virt;
558
559 if (ppc_md.progress)
560 ppc_md.progress("pplus_setup_arch: set_board_type", 0);
561
562 pplus_set_board_type();
563
564 /* Enable L2. Assume we don't need to flush -- Cort */
565 *(unsigned char *)(PPLUS_L2_CONTROL_REG) |= 3;
566
567#ifdef CONFIG_BLK_DEV_INITRD
568 if (initrd_start)
569 ROOT_DEV = Root_RAM0;
570 else
571#endif
572#ifdef CONFIG_ROOT_NFS
573 ROOT_DEV = Root_NFS;
574#else
575 ROOT_DEV = Root_SDA2;
576#endif
577
578 printk(KERN_INFO "Motorola PowerPlus Platform\n");
579 printk(KERN_INFO
580 "Port by MontaVista Software, Inc. (source@mvista.com)\n");
581
582#ifdef CONFIG_VGA_CONSOLE
583 /* remap the VGA memory */
584 vgacon_remap_base = (unsigned long)ioremap(PPLUS_ISA_MEM_BASE,
585 0x08000000);
586 conswitchp = &vga_con;
587#endif
588#ifdef CONFIG_PPCBUG_NVRAM
589 /* Read in NVRAM data */
590 init_prep_nvram();
591
592 /* if no bootargs, look in NVRAM */
593 if (cmd_line[0] == '\0') {
594 char *bootargs;
595 bootargs = prep_nvram_get_var("bootargs");
596 if (bootargs != NULL) {
597 strcpy(cmd_line, bootargs);
598 /* again.. */
599 strcpy(saved_command_line, cmd_line);
600 }
601 }
602#endif
603 if (ppc_md.progress)
604 ppc_md.progress("pplus_setup_arch: exit", 0);
605}
606
607static void pplus_restart(char *cmd)
608{
609 unsigned long i = 10000;
610
611 local_irq_disable();
612
613 /* set VIA IDE controller into native mode */
614 pplus_set_VIA_IDE_native();
615
616 /* set exception prefix high - to the prom */
617 _nmask_and_or_msr(0, MSR_IP);
618
619 /* make sure bit 0 (reset) is a 0 */
620 outb(inb(0x92) & ~1L, 0x92);
621 /* signal a reset to system control port A - soft reset */
622 outb(inb(0x92) | 1, 0x92);
623
624 while (i != 0)
625 i++;
626 panic("restart failed\n");
627}
628
629static void pplus_halt(void)
630{
631 /* set exception prefix high - to the prom */
632 _nmask_and_or_msr(MSR_EE, MSR_IP);
633
634 /* make sure bit 0 (reset) is a 0 */
635 outb(inb(0x92) & ~1L, 0x92);
636 /* signal a reset to system control port A - soft reset */
637 outb(inb(0x92) | 1, 0x92);
638
639 while (1) ;
640 /*
641 * Not reached
642 */
643}
644
645static void pplus_power_off(void)
646{
647 pplus_halt();
648}
649
650static unsigned int pplus_irq_canonicalize(u_int irq)
651{
652 if (irq == 2)
653 return 9;
654 else
655 return irq;
656}
657
658static void __init pplus_init_IRQ(void)
659{
660 int i;
661
662 if (ppc_md.progress)
663 ppc_md.progress("init_irq: enter", 0);
664
665 OpenPIC_InitSenses = pplus_openpic_initsenses;
666 OpenPIC_NumInitSenses = sizeof(pplus_openpic_initsenses);
667
668 if (OpenPIC_Addr != NULL) {
669
670 openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
671 openpic_init(NUM_8259_INTERRUPTS);
672 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
673 i8259_irq);
674 ppc_md.get_irq = openpic_get_irq;
675 }
676
677 for (i = 0; i < NUM_8259_INTERRUPTS; i++)
678 irq_desc[i].handler = &i8259_pic;
679
680 i8259_init(0);
681
682 if (ppc_md.progress)
683 ppc_md.progress("init_irq: exit", 0);
684}
685
686#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
687/*
688 * IDE stuff.
689 */
690static int pplus_ide_default_irq(unsigned long base)
691{
692 switch (base) {
693 case 0x1f0:
694 return 14;
695 case 0x170:
696 return 15;
697 default:
698 return 0;
699 }
700}
701
702static unsigned long pplus_ide_default_io_base(int index)
703{
704 switch (index) {
705 case 0:
706 return 0x1f0;
707 case 1:
708 return 0x170;
709 default:
710 return 0;
711 }
712}
713
714static void __init
715pplus_ide_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
716 unsigned long ctrl_port, int *irq)
717{
718 unsigned long reg = data_port;
719 int i;
720
721 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
722 hw->io_ports[i] = reg;
723 reg += 1;
724 }
725
726 if (ctrl_port)
727 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
728 else
729 hw->io_ports[IDE_CONTROL_OFFSET] =
730 hw->io_ports[IDE_DATA_OFFSET] + 0x206;
731
732 if (irq != NULL)
733 *irq = pplus_ide_default_irq(data_port);
734}
735#endif
736
737#ifdef CONFIG_SMP
738/* PowerPlus (MTX) support */
739static int __init smp_pplus_probe(void)
740{
741 extern int mot_multi;
742
743 if (mot_multi) {
744 openpic_request_IPIs();
745 smp_hw_index[1] = 1;
746 return 2;
747 }
748
749 return 1;
750}
751
752static void __init smp_pplus_kick_cpu(int nr)
753{
754 *(unsigned long *)KERNELBASE = nr;
755 asm volatile ("dcbf 0,%0"::"r" (KERNELBASE):"memory");
756 printk(KERN_INFO "CPU1 reset, waiting\n");
757}
758
759static void __init smp_pplus_setup_cpu(int cpu_nr)
760{
761 if (OpenPIC_Addr)
762 do_openpic_setup_cpu();
763}
764
765static struct smp_ops_t pplus_smp_ops = {
766 smp_openpic_message_pass,
767 smp_pplus_probe,
768 smp_pplus_kick_cpu,
769 smp_pplus_setup_cpu,
770 .give_timebase = smp_generic_give_timebase,
771 .take_timebase = smp_generic_take_timebase,
772};
773#endif /* CONFIG_SMP */
774
775#ifdef DUMP_DBATS
776static void print_dbat(int idx, u32 bat)
777{
778
779 char str[64];
780
781 sprintf(str, "DBAT%c%c = 0x%08x\n",
782 (char)((idx - DBAT0U) / 2) + '0', (idx & 1) ? 'L' : 'U', bat);
783 ppc_md.progress(str, 0);
784}
785
786#define DUMP_DBAT(x) \
787 do { \
788 u32 __temp = mfspr(x);\
789 print_dbat(x, __temp); \
790 } while (0)
791
792static void dump_dbats(void)
793{
794 if (ppc_md.progress) {
795 DUMP_DBAT(DBAT0U);
796 DUMP_DBAT(DBAT0L);
797 DUMP_DBAT(DBAT1U);
798 DUMP_DBAT(DBAT1L);
799 DUMP_DBAT(DBAT2U);
800 DUMP_DBAT(DBAT2L);
801 DUMP_DBAT(DBAT3U);
802 DUMP_DBAT(DBAT3L);
803 }
804}
805#endif
806
807static unsigned long __init pplus_find_end_of_memory(void)
808{
809 unsigned long total;
810
811 if (ppc_md.progress)
812 ppc_md.progress("pplus_find_end_of_memory", 0);
813
814#ifdef DUMP_DBATS
815 dump_dbats();
816#endif
817
818 total = hawk_get_mem_size(PPLUS_HAWK_SMC_BASE);
819 return (total);
820}
821
822static void __init pplus_map_io(void)
823{
824 io_block_mapping(PPLUS_ISA_IO_BASE, PPLUS_ISA_IO_BASE, 0x10000000,
825 _PAGE_IO);
826 io_block_mapping(0xfef80000, 0xfef80000, 0x00080000, _PAGE_IO);
827}
828
829static void __init pplus_init2(void)
830{
831#ifdef CONFIG_NVRAM
832 request_region(PREP_NVRAM_AS0, 0x8, "nvram");
833#endif
834 request_region(0x20, 0x20, "pic1");
835 request_region(0xa0, 0x20, "pic2");
836 request_region(0x00, 0x20, "dma1");
837 request_region(0x40, 0x20, "timer");
838 request_region(0x80, 0x10, "dma page reg");
839 request_region(0xc0, 0x20, "dma2");
840}
841
842/*
843 * Set BAT 2 to access 0x8000000 so progress messages will work and set BAT 3
844 * to 0xf0000000 to access Falcon/Raven or Hawk registers
845 */
846static __inline__ void pplus_set_bat(void)
847{
848 /* wait for all outstanding memory accesses to complete */
849 mb();
850
851 /* setup DBATs */
852 mtspr(SPRN_DBAT2U, 0x80001ffe);
853 mtspr(SPRN_DBAT2L, 0x8000002a);
854 mtspr(SPRN_DBAT3U, 0xf0001ffe);
855 mtspr(SPRN_DBAT3L, 0xf000002a);
856
857 /* wait for updates */
858 mb();
859}
860
861void __init
862platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
863 unsigned long r6, unsigned long r7)
864{
865 parse_bootinfo(find_bootinfo());
866
867 /* Map in board regs, etc. */
868 pplus_set_bat();
869
870 isa_io_base = PREP_ISA_IO_BASE;
871 isa_mem_base = PREP_ISA_MEM_BASE;
872 pci_dram_offset = PREP_PCI_DRAM_OFFSET;
873 ISA_DMA_THRESHOLD = 0x00ffffff;
874 DMA_MODE_READ = 0x44;
875 DMA_MODE_WRITE = 0x48;
876
877 ppc_md.setup_arch = pplus_setup_arch;
878 ppc_md.show_cpuinfo = pplus_show_cpuinfo;
879 ppc_md.irq_canonicalize = pplus_irq_canonicalize;
880 ppc_md.init_IRQ = pplus_init_IRQ;
881 /* this gets changed later on if we have an OpenPIC -- Cort */
882 ppc_md.get_irq = i8259_irq;
883 ppc_md.init = pplus_init2;
884
885 ppc_md.restart = pplus_restart;
886 ppc_md.power_off = pplus_power_off;
887 ppc_md.halt = pplus_halt;
888
889 TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
890 PREP_NVRAM_DATA, 8);
891
892 ppc_md.time_init = todc_time_init;
893 ppc_md.set_rtc_time = todc_set_rtc_time;
894 ppc_md.get_rtc_time = todc_get_rtc_time;
895 ppc_md.calibrate_decr = todc_calibrate_decr;
896 ppc_md.nvram_read_val = todc_m48txx_read_val;
897 ppc_md.nvram_write_val = todc_m48txx_write_val;
898
899 ppc_md.find_end_of_memory = pplus_find_end_of_memory;
900 ppc_md.setup_io_mappings = pplus_map_io;
901
902#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
903 ppc_ide_md.default_irq = pplus_ide_default_irq;
904 ppc_ide_md.default_io_base = pplus_ide_default_io_base;
905 ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports;
906#endif
907
908#ifdef CONFIG_SERIAL_TEXT_DEBUG
909 ppc_md.progress = gen550_progress;
910#endif /* CONFIG_SERIAL_TEXT_DEBUG */
911#ifdef CONFIG_KGDB
912 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
913#endif
914#ifdef CONFIG_SMP
915 ppc_md.smp_ops = &pplus_smp_ops;
916#endif /* CONFIG_SMP */
917}
diff --git a/arch/ppc/platforms/pplus.h b/arch/ppc/platforms/pplus.h
new file mode 100644
index 000000000000..90f0cb2d409f
--- /dev/null
+++ b/arch/ppc/platforms/pplus.h
@@ -0,0 +1,67 @@
1/*
2 * arch/ppc/platforms/pplus.h
3 *
4 * Definitions for Motorola MCG Falcon/Raven & HAWK North Bridge & Memory ctlr.
5 *
6 * Author: Mark A. Greerinclude/asm-ppc/hawk.h
7 * mgreer@mvista.com
8 *
9 * Modified by Randy Vinson (rvinson@mvista.com)
10 *
11 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15 */
16
17#ifndef __PPC_PPLUS_H
18#define __PPC_PPLUS_H
19
20#include <asm/io.h>
21
22/*
23 * Due to limiations imposed by legacy hardware (primaryily IDE controllers),
24 * the PPLUS boards operate using a PReP address map.
25 *
26 * From Processor (physical) -> PCI:
27 * PCI Mem Space: 0xc0000000 - 0xfe000000 -> 0x00000000 - 0x3e000000 (768 MB)
28 * PCI I/O Space: 0x80000000 - 0x90000000 -> 0x00000000 - 0x10000000 (256 MB)
29 * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area
30 *
31 * From PCI -> Processor (physical):
32 * System Memory: 0x80000000 -> 0x00000000
33 */
34
35#define PPLUS_ISA_MEM_BASE PREP_ISA_MEM_BASE
36#define PPLUS_ISA_IO_BASE PREP_ISA_IO_BASE
37
38/* PCI Memory space mapping info */
39#define PPLUS_PCI_MEM_SIZE 0x30000000U
40#define PPLUS_PROC_PCI_MEM_START PPLUS_ISA_MEM_BASE
41#define PPLUS_PROC_PCI_MEM_END (PPLUS_PROC_PCI_MEM_START + \
42 PPLUS_PCI_MEM_SIZE - 1)
43#define PPLUS_PCI_MEM_START 0x00000000U
44#define PPLUS_PCI_MEM_END (PPLUS_PCI_MEM_START + \
45 PPLUS_PCI_MEM_SIZE - 1)
46
47/* PCI I/O space mapping info */
48#define PPLUS_PCI_IO_SIZE 0x10000000U
49#define PPLUS_PROC_PCI_IO_START PPLUS_ISA_IO_BASE
50#define PPLUS_PROC_PCI_IO_END (PPLUS_PROC_PCI_IO_START + \
51 PPLUS_PCI_IO_SIZE - 1)
52#define PPLUS_PCI_IO_START 0x00000000U
53#define PPLUS_PCI_IO_END (PPLUS_PCI_IO_START + \
54 PPLUS_PCI_IO_SIZE - 1)
55/* System memory mapping info */
56#define PPLUS_PCI_DRAM_OFFSET PREP_PCI_DRAM_OFFSET
57#define PPLUS_PCI_PHY_MEM_OFFSET (PPLUS_ISA_MEM_BASE-PPLUS_PCI_MEM_START)
58
59/* Define base addresses for important sets of registers */
60#define PPLUS_HAWK_SMC_BASE 0xfef80000U
61#define PPLUS_HAWK_PPC_REG_BASE 0xfeff0000U
62#define PPLUS_SYS_CONFIG_REG 0xfef80400U
63#define PPLUS_L2_CONTROL_REG 0x8000081cU
64
65#define PPLUS_VGA_MEM_BASE 0xf0000000U
66
67#endif /* __PPC_PPLUS_H */
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
new file mode 100644
index 000000000000..6a1475c1e128
--- /dev/null
+++ b/arch/ppc/platforms/pq2ads.c
@@ -0,0 +1,26 @@
1/*
2 * arch/ppc/platforms/pq2ads.c
3 *
4 * PQ2ADS platform support
5 *
6 * Author: Kumar Gala <kumar.gala@freescale.com>
7 * Derived from: est8260_setup.c by Allen Curtis
8 *
9 * Copyright 2004 Freescale Semiconductor, 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
17#include <linux/init.h>
18
19#include <asm/mpc8260.h>
20
21void __init
22m82xx_board_setup(void)
23{
24 /* Enable the 2nd UART port */
25 *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
26}
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
new file mode 100644
index 000000000000..cf5e5dd06d63
--- /dev/null
+++ b/arch/ppc/platforms/pq2ads.h
@@ -0,0 +1,96 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Motorola MPC8260ADS/MPC8266ADS-PCI boards.
4 * Copied from the RPX-Classic and SBS8260 stuff.
5 *
6 * Copyright (c) 2001 Dan Malek (dan@mvista.com)
7 */
8#ifdef __KERNEL__
9#ifndef __MACH_ADS8260_DEFS
10#define __MACH_ADS8260_DEFS
11
12#include <linux/config.h>
13
14#include <asm/ppcboot.h>
15
16/* Memory map is configured by the PROM startup.
17 * We just map a few things we need. The CSR is actually 4 byte-wide
18 * registers that can be accessed as 8-, 16-, or 32-bit values.
19 */
20#define CPM_MAP_ADDR ((uint)0xf0000000)
21#define BCSR_ADDR ((uint)0xf4500000)
22#define BCSR_SIZE ((uint)(32 * 1024))
23
24#define BOOTROM_RESTART_ADDR ((uint)0xff000104)
25
26/* For our show_cpuinfo hooks. */
27#define CPUINFO_VENDOR "Motorola"
28#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
29
30/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
31 * only on word boundaries.
32 * Not all are used (yet), or are interesting to us (yet).
33 */
34
35/* Things of interest in the CSR.
36*/
37#define BCSR0_LED0 ((uint)0x02000000) /* 0 == on */
38#define BCSR0_LED1 ((uint)0x01000000) /* 0 == on */
39#define BCSR1_FETHIEN ((uint)0x08000000) /* 0 == enable */
40#define BCSR1_FETH_RST ((uint)0x04000000) /* 0 == reset */
41#define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 == enable */
42#define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 == enable */
43#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable */
44#define BCSR3_FETH2_RST ((uint)0x80000000) /* 0 == reset */
45
46#define PHY_INTERRUPT SIU_INT_IRQ7
47
48#ifdef CONFIG_PCI
49/* PCI interrupt controller */
50#define PCI_INT_STAT_REG 0xF8200000
51#define PCI_INT_MASK_REG 0xF8200004
52#define PIRQA (NR_SIU_INTS + 0)
53#define PIRQB (NR_SIU_INTS + 1)
54#define PIRQC (NR_SIU_INTS + 2)
55#define PIRQD (NR_SIU_INTS + 3)
56
57/*
58 * PCI memory map definitions for MPC8266ADS-PCI.
59 *
60 * processor view
61 * local address PCI address target
62 * 0x80000000-0x9FFFFFFF 0x80000000-0x9FFFFFFF PCI mem with prefetch
63 * 0xA0000000-0xBFFFFFFF 0xA0000000-0xBFFFFFFF PCI mem w/o prefetch
64 * 0xF4000000-0xF7FFFFFF 0x00000000-0x03FFFFFF PCI IO
65 *
66 * PCI master view
67 * local address PCI address target
68 * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory
69 */
70
71/* window for a PCI master to access MPC8266 memory */
72#define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */
73#define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */
74
75/* window for the processor to access PCI memory with prefetching */
76#define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */
77#define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */
78#define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */
79
80/* window for the processor to access PCI memory without prefetching */
81#define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */
82#define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */
83#define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */
84
85/* window for the processor to access PCI I/O */
86#define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */
87#define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */
88#define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */
89
90#define _IO_BASE PCI_MSTR_IO_LOCAL
91#define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL
92#define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS
93#endif /* CONFIG_PCI */
94
95#endif /* __MACH_ADS8260_DEFS */
96#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
new file mode 100644
index 000000000000..8cd80eb447bd
--- /dev/null
+++ b/arch/ppc/platforms/prep_pci.c
@@ -0,0 +1,1336 @@
1/*
2 * PReP pci functions.
3 * Originally by Gary Thomas
4 * rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
5 *
6 * The motherboard routes/maps will disappear shortly. -- Cort
7 */
8
9#include <linux/config.h>
10#include <linux/types.h>
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14
15#include <asm/sections.h>
16#include <asm/byteorder.h>
17#include <asm/io.h>
18#include <asm/ptrace.h>
19#include <asm/prom.h>
20#include <asm/pci-bridge.h>
21#include <asm/residual.h>
22#include <asm/irq.h>
23#include <asm/machdep.h>
24#include <asm/open_pic.h>
25
26extern void (*setup_ibm_pci)(char *irq_lo, char *irq_hi);
27
28/* Which PCI interrupt line does a given device [slot] use? */
29/* Note: This really should be two dimensional based in slot/pin used */
30static unsigned char *Motherboard_map;
31unsigned char *Motherboard_map_name;
32
33/* How is the 82378 PIRQ mapping setup? */
34static unsigned char *Motherboard_routes;
35
36static void (*Motherboard_non0)(struct pci_dev *);
37
38static void Powerplus_Map_Non0(struct pci_dev *);
39
40/* Used for Motorola to store system config register */
41static unsigned long *ProcInfo;
42
43/* Tables for known hardware */
44
45/* Motorola PowerStackII - Utah */
46static char Utah_pci_IRQ_map[23] __prepdata =
47{
48 0, /* Slot 0 - unused */
49 0, /* Slot 1 - unused */
50 5, /* Slot 2 - SCSI - NCR825A */
51 0, /* Slot 3 - unused */
52 3, /* Slot 4 - Ethernet - DEC2114x */
53 0, /* Slot 5 - unused */
54 2, /* Slot 6 - PCI Card slot #1 */
55 3, /* Slot 7 - PCI Card slot #2 */
56 5, /* Slot 8 - PCI Card slot #3 */
57 5, /* Slot 9 - PCI Bridge */
58 /* added here in case we ever support PCI bridges */
59 /* Secondary PCI bus cards are at slot-9,6 & slot-9,7 */
60 0, /* Slot 10 - unused */
61 0, /* Slot 11 - unused */
62 5, /* Slot 12 - SCSI - NCR825A */
63 0, /* Slot 13 - unused */
64 3, /* Slot 14 - enet */
65 0, /* Slot 15 - unused */
66 2, /* Slot 16 - unused */
67 3, /* Slot 17 - unused */
68 5, /* Slot 18 - unused */
69 0, /* Slot 19 - unused */
70 0, /* Slot 20 - unused */
71 0, /* Slot 21 - unused */
72 0, /* Slot 22 - unused */
73};
74
75static char Utah_pci_IRQ_routes[] __prepdata =
76{
77 0, /* Line 0 - Unused */
78 9, /* Line 1 */
79 10, /* Line 2 */
80 11, /* Line 3 */
81 14, /* Line 4 */
82 15, /* Line 5 */
83};
84
85/* Motorola PowerStackII - Omaha */
86/* no integrated SCSI or ethernet */
87static char Omaha_pci_IRQ_map[23] __prepdata =
88{
89 0, /* Slot 0 - unused */
90 0, /* Slot 1 - unused */
91 3, /* Slot 2 - Winbond EIDE */
92 0, /* Slot 3 - unused */
93 0, /* Slot 4 - unused */
94 0, /* Slot 5 - unused */
95 1, /* Slot 6 - PCI slot 1 */
96 2, /* Slot 7 - PCI slot 2 */
97 3, /* Slot 8 - PCI slot 3 */
98 4, /* Slot 9 - PCI slot 4 */ /* needs indirect access */
99 0, /* Slot 10 - unused */
100 0, /* Slot 11 - unused */
101 0, /* Slot 12 - unused */
102 0, /* Slot 13 - unused */
103 0, /* Slot 14 - unused */
104 0, /* Slot 15 - unused */
105 1, /* Slot 16 - PCI slot 1 */
106 2, /* Slot 17 - PCI slot 2 */
107 3, /* Slot 18 - PCI slot 3 */
108 4, /* Slot 19 - PCI slot 4 */ /* needs indirect access */
109 0,
110 0,
111 0,
112};
113
114static char Omaha_pci_IRQ_routes[] __prepdata =
115{
116 0, /* Line 0 - Unused */
117 9, /* Line 1 */
118 11, /* Line 2 */
119 14, /* Line 3 */
120 15 /* Line 4 */
121};
122
123/* Motorola PowerStack */
124static char Blackhawk_pci_IRQ_map[19] __prepdata =
125{
126 0, /* Slot 0 - unused */
127 0, /* Slot 1 - unused */
128 0, /* Slot 2 - unused */
129 0, /* Slot 3 - unused */
130 0, /* Slot 4 - unused */
131 0, /* Slot 5 - unused */
132 0, /* Slot 6 - unused */
133 0, /* Slot 7 - unused */
134 0, /* Slot 8 - unused */
135 0, /* Slot 9 - unused */
136 0, /* Slot 10 - unused */
137 0, /* Slot 11 - unused */
138 3, /* Slot 12 - SCSI */
139 0, /* Slot 13 - unused */
140 1, /* Slot 14 - Ethernet */
141 0, /* Slot 15 - unused */
142 1, /* Slot P7 */
143 2, /* Slot P6 */
144 3, /* Slot P5 */
145};
146
147static char Blackhawk_pci_IRQ_routes[] __prepdata =
148{
149 0, /* Line 0 - Unused */
150 9, /* Line 1 */
151 11, /* Line 2 */
152 15, /* Line 3 */
153 15 /* Line 4 */
154};
155
156/* Motorola Mesquite */
157static char Mesquite_pci_IRQ_map[23] __prepdata =
158{
159 0, /* Slot 0 - unused */
160 0, /* Slot 1 - unused */
161 0, /* Slot 2 - unused */
162 0, /* Slot 3 - unused */
163 0, /* Slot 4 - unused */
164 0, /* Slot 5 - unused */
165 0, /* Slot 6 - unused */
166 0, /* Slot 7 - unused */
167 0, /* Slot 8 - unused */
168 0, /* Slot 9 - unused */
169 0, /* Slot 10 - unused */
170 0, /* Slot 11 - unused */
171 0, /* Slot 12 - unused */
172 0, /* Slot 13 - unused */
173 2, /* Slot 14 - Ethernet */
174 0, /* Slot 15 - unused */
175 3, /* Slot 16 - PMC */
176 0, /* Slot 17 - unused */
177 0, /* Slot 18 - unused */
178 0, /* Slot 19 - unused */
179 0, /* Slot 20 - unused */
180 0, /* Slot 21 - unused */
181 0, /* Slot 22 - unused */
182};
183
184/* Motorola Sitka */
185static char Sitka_pci_IRQ_map[21] __prepdata =
186{
187 0, /* Slot 0 - unused */
188 0, /* Slot 1 - unused */
189 0, /* Slot 2 - unused */
190 0, /* Slot 3 - unused */
191 0, /* Slot 4 - unused */
192 0, /* Slot 5 - unused */
193 0, /* Slot 6 - unused */
194 0, /* Slot 7 - unused */
195 0, /* Slot 8 - unused */
196 0, /* Slot 9 - unused */
197 0, /* Slot 10 - unused */
198 0, /* Slot 11 - unused */
199 0, /* Slot 12 - unused */
200 0, /* Slot 13 - unused */
201 2, /* Slot 14 - Ethernet */
202 0, /* Slot 15 - unused */
203 9, /* Slot 16 - PMC 1 */
204 12, /* Slot 17 - PMC 2 */
205 0, /* Slot 18 - unused */
206 0, /* Slot 19 - unused */
207 4, /* Slot 20 - NT P2P bridge */
208};
209
210/* Motorola MTX */
211static char MTX_pci_IRQ_map[23] __prepdata =
212{
213 0, /* Slot 0 - unused */
214 0, /* Slot 1 - unused */
215 0, /* Slot 2 - unused */
216 0, /* Slot 3 - unused */
217 0, /* Slot 4 - unused */
218 0, /* Slot 5 - unused */
219 0, /* Slot 6 - unused */
220 0, /* Slot 7 - unused */
221 0, /* Slot 8 - unused */
222 0, /* Slot 9 - unused */
223 0, /* Slot 10 - unused */
224 0, /* Slot 11 - unused */
225 3, /* Slot 12 - SCSI */
226 0, /* Slot 13 - unused */
227 2, /* Slot 14 - Ethernet */
228 0, /* Slot 15 - unused */
229 9, /* Slot 16 - PCI/PMC slot 1 */
230 10, /* Slot 17 - PCI/PMC slot 2 */
231 11, /* Slot 18 - PCI slot 3 */
232 0, /* Slot 19 - unused */
233 0, /* Slot 20 - unused */
234 0, /* Slot 21 - unused */
235 0, /* Slot 22 - unused */
236};
237
238/* Motorola MTX Plus */
239/* Secondary bus interrupt routing is not supported yet */
240static char MTXplus_pci_IRQ_map[23] __prepdata =
241{
242 0, /* Slot 0 - unused */
243 0, /* Slot 1 - unused */
244 0, /* Slot 2 - unused */
245 0, /* Slot 3 - unused */
246 0, /* Slot 4 - unused */
247 0, /* Slot 5 - unused */
248 0, /* Slot 6 - unused */
249 0, /* Slot 7 - unused */
250 0, /* Slot 8 - unused */
251 0, /* Slot 9 - unused */
252 0, /* Slot 10 - unused */
253 0, /* Slot 11 - unused */
254 3, /* Slot 12 - SCSI */
255 0, /* Slot 13 - unused */
256 2, /* Slot 14 - Ethernet 1 */
257 0, /* Slot 15 - unused */
258 9, /* Slot 16 - PCI slot 1P */
259 10, /* Slot 17 - PCI slot 2P */
260 11, /* Slot 18 - PCI slot 3P */
261 10, /* Slot 19 - Ethernet 2 */
262 0, /* Slot 20 - P2P Bridge */
263 0, /* Slot 21 - unused */
264 0, /* Slot 22 - unused */
265};
266
267static char Raven_pci_IRQ_routes[] __prepdata =
268{
269 0, /* This is a dummy structure */
270};
271
272/* Motorola MVME16xx */
273static char Genesis_pci_IRQ_map[16] __prepdata =
274{
275 0, /* Slot 0 - unused */
276 0, /* Slot 1 - unused */
277 0, /* Slot 2 - unused */
278 0, /* Slot 3 - unused */
279 0, /* Slot 4 - unused */
280 0, /* Slot 5 - unused */
281 0, /* Slot 6 - unused */
282 0, /* Slot 7 - unused */
283 0, /* Slot 8 - unused */
284 0, /* Slot 9 - unused */
285 0, /* Slot 10 - unused */
286 0, /* Slot 11 - unused */
287 3, /* Slot 12 - SCSI */
288 0, /* Slot 13 - unused */
289 1, /* Slot 14 - Ethernet */
290 0, /* Slot 15 - unused */
291};
292
293static char Genesis_pci_IRQ_routes[] __prepdata =
294{
295 0, /* Line 0 - Unused */
296 10, /* Line 1 */
297 11, /* Line 2 */
298 14, /* Line 3 */
299 15 /* Line 4 */
300};
301
302static char Genesis2_pci_IRQ_map[23] __prepdata =
303{
304 0, /* Slot 0 - unused */
305 0, /* Slot 1 - unused */
306 0, /* Slot 2 - unused */
307 0, /* Slot 3 - unused */
308 0, /* Slot 4 - unused */
309 0, /* Slot 5 - unused */
310 0, /* Slot 6 - unused */
311 0, /* Slot 7 - unused */
312 0, /* Slot 8 - unused */
313 0, /* Slot 9 - unused */
314 0, /* Slot 10 - unused */
315 0, /* Slot 11 - IDE */
316 3, /* Slot 12 - SCSI */
317 5, /* Slot 13 - Universe PCI - VME Bridge */
318 2, /* Slot 14 - Ethernet */
319 0, /* Slot 15 - unused */
320 9, /* Slot 16 - PMC 1 */
321 12, /* Slot 17 - pci */
322 11, /* Slot 18 - pci */
323 10, /* Slot 19 - pci */
324 0, /* Slot 20 - pci */
325 0, /* Slot 21 - unused */
326 0, /* Slot 22 - unused */
327};
328
329/* Motorola Series-E */
330static char Comet_pci_IRQ_map[23] __prepdata =
331{
332 0, /* Slot 0 - unused */
333 0, /* Slot 1 - unused */
334 0, /* Slot 2 - unused */
335 0, /* Slot 3 - unused */
336 0, /* Slot 4 - unused */
337 0, /* Slot 5 - unused */
338 0, /* Slot 6 - unused */
339 0, /* Slot 7 - unused */
340 0, /* Slot 8 - unused */
341 0, /* Slot 9 - unused */
342 0, /* Slot 10 - unused */
343 0, /* Slot 11 - unused */
344 3, /* Slot 12 - SCSI */
345 0, /* Slot 13 - unused */
346 1, /* Slot 14 - Ethernet */
347 0, /* Slot 15 - unused */
348 1, /* Slot 16 - PCI slot 1 */
349 2, /* Slot 17 - PCI slot 2 */
350 3, /* Slot 18 - PCI slot 3 */
351 4, /* Slot 19 - PCI bridge */
352 0,
353 0,
354 0,
355};
356
357static char Comet_pci_IRQ_routes[] __prepdata =
358{
359 0, /* Line 0 - Unused */
360 10, /* Line 1 */
361 11, /* Line 2 */
362 14, /* Line 3 */
363 15 /* Line 4 */
364};
365
366/* Motorola Series-EX */
367static char Comet2_pci_IRQ_map[23] __prepdata =
368{
369 0, /* Slot 0 - unused */
370 0, /* Slot 1 - unused */
371 3, /* Slot 2 - SCSI - NCR825A */
372 0, /* Slot 3 - unused */
373 1, /* Slot 4 - Ethernet - DEC2104X */
374 0, /* Slot 5 - unused */
375 1, /* Slot 6 - PCI slot 1 */
376 2, /* Slot 7 - PCI slot 2 */
377 3, /* Slot 8 - PCI slot 3 */
378 4, /* Slot 9 - PCI bridge */
379 0, /* Slot 10 - unused */
380 0, /* Slot 11 - unused */
381 3, /* Slot 12 - SCSI - NCR825A */
382 0, /* Slot 13 - unused */
383 1, /* Slot 14 - Ethernet - DEC2104X */
384 0, /* Slot 15 - unused */
385 1, /* Slot 16 - PCI slot 1 */
386 2, /* Slot 17 - PCI slot 2 */
387 3, /* Slot 18 - PCI slot 3 */
388 4, /* Slot 19 - PCI bridge */
389 0,
390 0,
391 0,
392};
393
394static char Comet2_pci_IRQ_routes[] __prepdata =
395{
396 0, /* Line 0 - Unused */
397 10, /* Line 1 */
398 11, /* Line 2 */
399 14, /* Line 3 */
400 15, /* Line 4 */
401};
402
403/*
404 * ibm 830 (and 850?).
405 * This is actually based on the Carolina motherboard
406 * -- Cort
407 */
408static char ibm8xx_pci_IRQ_map[23] __prepdata = {
409 0, /* Slot 0 - unused */
410 0, /* Slot 1 - unused */
411 0, /* Slot 2 - unused */
412 0, /* Slot 3 - unused */
413 0, /* Slot 4 - unused */
414 0, /* Slot 5 - unused */
415 0, /* Slot 6 - unused */
416 0, /* Slot 7 - unused */
417 0, /* Slot 8 - unused */
418 0, /* Slot 9 - unused */
419 0, /* Slot 10 - unused */
420 0, /* Slot 11 - FireCoral */
421 4, /* Slot 12 - Ethernet PCIINTD# */
422 2, /* Slot 13 - PCI Slot #2 */
423 2, /* Slot 14 - S3 Video PCIINTD# */
424 0, /* Slot 15 - onboard SCSI (INDI) [1] */
425 3, /* Slot 16 - NCR58C810 RS6000 Only PCIINTC# */
426 0, /* Slot 17 - unused */
427 2, /* Slot 18 - PCI Slot 2 PCIINTx# (See below) */
428 0, /* Slot 19 - unused */
429 0, /* Slot 20 - unused */
430 0, /* Slot 21 - unused */
431 2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
432};
433
434static char ibm8xx_pci_IRQ_routes[] __prepdata = {
435 0, /* Line 0 - unused */
436 15, /* Line 1 */
437 15, /* Line 2 */
438 15, /* Line 3 */
439 15, /* Line 4 */
440};
441
442/*
443 * a 6015 ibm board
444 * -- Cort
445 */
446static char ibm6015_pci_IRQ_map[23] __prepdata = {
447 0, /* Slot 0 - unused */
448 0, /* Slot 1 - unused */
449 0, /* Slot 2 - unused */
450 0, /* Slot 3 - unused */
451 0, /* Slot 4 - unused */
452 0, /* Slot 5 - unused */
453 0, /* Slot 6 - unused */
454 0, /* Slot 7 - unused */
455 0, /* Slot 8 - unused */
456 0, /* Slot 9 - unused */
457 0, /* Slot 10 - unused */
458 0, /* Slot 11 - */
459 1, /* Slot 12 - SCSI */
460 2, /* Slot 13 - */
461 2, /* Slot 14 - */
462 1, /* Slot 15 - */
463 1, /* Slot 16 - */
464 0, /* Slot 17 - */
465 2, /* Slot 18 - */
466 0, /* Slot 19 - */
467 0, /* Slot 20 - */
468 0, /* Slot 21 - */
469 2, /* Slot 22 - */
470};
471
472static char ibm6015_pci_IRQ_routes[] __prepdata = {
473 0, /* Line 0 - unused */
474 13, /* Line 1 */
475 15, /* Line 2 */
476 15, /* Line 3 */
477 15, /* Line 4 */
478};
479
480
481/* IBM Nobis and Thinkpad 850 */
482static char Nobis_pci_IRQ_map[23] __prepdata ={
483 0, /* Slot 0 - unused */
484 0, /* Slot 1 - unused */
485 0, /* Slot 2 - unused */
486 0, /* Slot 3 - unused */
487 0, /* Slot 4 - unused */
488 0, /* Slot 5 - unused */
489 0, /* Slot 6 - unused */
490 0, /* Slot 7 - unused */
491 0, /* Slot 8 - unused */
492 0, /* Slot 9 - unused */
493 0, /* Slot 10 - unused */
494 0, /* Slot 11 - unused */
495 3, /* Slot 12 - SCSI */
496 0, /* Slot 13 - unused */
497 0, /* Slot 14 - unused */
498 0, /* Slot 15 - unused */
499};
500
501static char Nobis_pci_IRQ_routes[] __prepdata = {
502 0, /* Line 0 - Unused */
503 13, /* Line 1 */
504 13, /* Line 2 */
505 13, /* Line 3 */
506 13 /* Line 4 */
507};
508
509/*
510 * IBM RS/6000 43p/140 -- paulus
511 * XXX we should get all this from the residual data
512 */
513static char ibm43p_pci_IRQ_map[23] __prepdata = {
514 0, /* Slot 0 - unused */
515 0, /* Slot 1 - unused */
516 0, /* Slot 2 - unused */
517 0, /* Slot 3 - unused */
518 0, /* Slot 4 - unused */
519 0, /* Slot 5 - unused */
520 0, /* Slot 6 - unused */
521 0, /* Slot 7 - unused */
522 0, /* Slot 8 - unused */
523 0, /* Slot 9 - unused */
524 0, /* Slot 10 - unused */
525 0, /* Slot 11 - FireCoral ISA bridge */
526 6, /* Slot 12 - Ethernet */
527 0, /* Slot 13 - openpic */
528 0, /* Slot 14 - unused */
529 0, /* Slot 15 - unused */
530 7, /* Slot 16 - NCR58C825a onboard scsi */
531 0, /* Slot 17 - unused */
532 2, /* Slot 18 - PCI Slot 2 PCIINTx# (See below) */
533 0, /* Slot 19 - unused */
534 0, /* Slot 20 - unused */
535 0, /* Slot 21 - unused */
536 1, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */
537};
538
539static char ibm43p_pci_IRQ_routes[] __prepdata = {
540 0, /* Line 0 - unused */
541 15, /* Line 1 */
542 15, /* Line 2 */
543 15, /* Line 3 */
544 15, /* Line 4 */
545};
546
547/* Motorola PowerPlus architecture PCI IRQ tables */
548/* Interrupt line values for INTA-D on primary/secondary MPIC inputs */
549
550struct powerplus_irq_list
551{
552 unsigned char primary[4]; /* INT A-D */
553 unsigned char secondary[4]; /* INT A-D */
554};
555
556/*
557 * For standard PowerPlus boards, bus 0 PCI INTs A-D are routed to
558 * OpenPIC inputs 9-12. PCI INTs A-D from the on board P2P bridge
559 * are routed to OpenPIC inputs 5-8. These values are offset by
560 * 16 in the table to reflect the Linux kernel interrupt value.
561 */
562struct powerplus_irq_list Powerplus_pci_IRQ_list __prepdata =
563{
564 {25, 26, 27, 28},
565 {21, 22, 23, 24}
566};
567
568/*
569 * For the MCP750 (system slot board), cPCI INTs A-D are routed to
570 * OpenPIC inputs 8-11 and the PMC INTs A-D are routed to OpenPIC
571 * input 3. On a hot swap MCP750, the companion card PCI INTs A-D
572 * are routed to OpenPIC inputs 12-15. These values are offset by
573 * 16 in the table to reflect the Linux kernel interrupt value.
574 */
575struct powerplus_irq_list Mesquite_pci_IRQ_list __prepdata =
576{
577 {24, 25, 26, 27},
578 {28, 29, 30, 31}
579};
580
581/*
582 * This table represents the standard PCI swizzle defined in the
583 * PCI bus specification.
584 */
585static unsigned char prep_pci_intpins[4][4] __prepdata =
586{
587 { 1, 2, 3, 4}, /* Buses 0, 4, 8, ... */
588 { 2, 3, 4, 1}, /* Buses 1, 5, 9, ... */
589 { 3, 4, 1, 2}, /* Buses 2, 6, 10 ... */
590 { 4, 1, 2, 3}, /* Buses 3, 7, 11 ... */
591};
592
593/* We have to turn on LEVEL mode for changed IRQ's */
594/* All PCI IRQ's need to be level mode, so this should be something
595 * other than hard-coded as well... IRQ's are individually mappable
596 * to either edge or level.
597 */
598
599/*
600 * 8259 edge/level control definitions
601 */
602#define ISA8259_M_ELCR 0x4d0
603#define ISA8259_S_ELCR 0x4d1
604
605#define ELCRS_INT15_LVL 0x80
606#define ELCRS_INT14_LVL 0x40
607#define ELCRS_INT12_LVL 0x10
608#define ELCRS_INT11_LVL 0x08
609#define ELCRS_INT10_LVL 0x04
610#define ELCRS_INT9_LVL 0x02
611#define ELCRS_INT8_LVL 0x01
612#define ELCRM_INT7_LVL 0x80
613#define ELCRM_INT5_LVL 0x20
614
615#if 0
616/*
617 * PCI config space access.
618 */
619#define CFGADDR(dev) ((1<<(dev>>3)) | ((dev&7)<<8))
620#define DEVNO(dev) (dev>>3)
621
622#define MIN_DEVNR 11
623#define MAX_DEVNR 22
624
625static int __prep
626prep_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
627 int len, u32 *val)
628{
629 struct pci_controller *hose = bus->sysdata;
630 volatile void __iomem *cfg_data;
631
632 if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
633 || DEVNO(devfn) > MAX_DEVNR)
634 return PCIBIOS_DEVICE_NOT_FOUND;
635
636 /*
637 * Note: the caller has already checked that offset is
638 * suitably aligned and that len is 1, 2 or 4.
639 */
640 cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
641 switch (len) {
642 case 1:
643 *val = in_8(cfg_data);
644 break;
645 case 2:
646 *val = in_le16(cfg_data);
647 break;
648 default:
649 *val = in_le32(cfg_data);
650 break;
651 }
652 return PCIBIOS_SUCCESSFUL;
653}
654
655static int __prep
656prep_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
657 int len, u32 val)
658{
659 struct pci_controller *hose = bus->sysdata;
660 volatile void __iomem *cfg_data;
661
662 if (bus->number != 0 || DEVNO(devfn) < MIN_DEVNR
663 || DEVNO(devfn) > MAX_DEVNR)
664 return PCIBIOS_DEVICE_NOT_FOUND;
665
666 /*
667 * Note: the caller has already checked that offset is
668 * suitably aligned and that len is 1, 2 or 4.
669 */
670 cfg_data = hose->cfg_data + CFGADDR(devfn) + offset;
671 switch (len) {
672 case 1:
673 out_8(cfg_data, val);
674 break;
675 case 2:
676 out_le16(cfg_data, val);
677 break;
678 default:
679 out_le32(cfg_data, val);
680 break;
681 }
682 return PCIBIOS_SUCCESSFUL;
683}
684
685static struct pci_ops prep_pci_ops =
686{
687 prep_read_config,
688 prep_write_config
689};
690#endif
691
692#define MOTOROLA_CPUTYPE_REG 0x800
693#define MOTOROLA_BASETYPE_REG 0x803
694#define MPIC_RAVEN_ID 0x48010000
695#define MPIC_HAWK_ID 0x48030000
696#define MOT_PROC2_BIT 0x800
697
698static u_char prep_openpic_initsenses[] __initdata = {
699 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* MVME2600_INT_SIO */
700 (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_FALCN_ECC_ERR */
701 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_ETHERNET */
702 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_SCSI */
703 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_GRAPHICS */
704 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME0 */
705 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME1 */
706 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME2 */
707 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME3 */
708 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTA */
709 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTB */
710 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTC */
711 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTD */
712 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG0 */
713 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG1 */
714};
715
716#define MOT_RAVEN_PRESENT 0x1
717#define MOT_HAWK_PRESENT 0x2
718
719int mot_entry = -1;
720int prep_keybd_present = 1;
721int MotMPIC;
722int mot_multi;
723
724int __init
725raven_init(void)
726{
727 unsigned int devid;
728 unsigned int pci_membase;
729 unsigned char base_mod;
730
731 /* Check to see if the Raven chip exists. */
732 if ( _prep_type != _PREP_Motorola) {
733 OpenPIC_Addr = NULL;
734 return 0;
735 }
736
737 /* Check to see if this board is a type that might have a Raven. */
738 if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) {
739 OpenPIC_Addr = NULL;
740 return 0;
741 }
742
743 /* Check the first PCI device to see if it is a Raven. */
744 early_read_config_dword(NULL, 0, 0, PCI_VENDOR_ID, &devid);
745
746 switch (devid & 0xffff0000) {
747 case MPIC_RAVEN_ID:
748 MotMPIC = MOT_RAVEN_PRESENT;
749 break;
750 case MPIC_HAWK_ID:
751 MotMPIC = MOT_HAWK_PRESENT;
752 break;
753 default:
754 OpenPIC_Addr = NULL;
755 return 0;
756 }
757
758
759 /* Read the memory base register. */
760 early_read_config_dword(NULL, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
761
762 if (pci_membase == 0) {
763 OpenPIC_Addr = NULL;
764 return 0;
765 }
766
767 /* Map the Raven MPIC registers to virtual memory. */
768 OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000);
769
770 OpenPIC_InitSenses = prep_openpic_initsenses;
771 OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses);
772
773 ppc_md.get_irq = openpic_get_irq;
774
775 /* If raven is present on Motorola store the system config register
776 * for later use.
777 */
778 ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);
779
780 /* Indicate to system if this is a multiprocessor board */
781 if (!(*ProcInfo & MOT_PROC2_BIT)) {
782 mot_multi = 1;
783 }
784
785 /* This is a hack. If this is a 2300 or 2400 mot board then there is
786 * no keyboard controller and we have to indicate that.
787 */
788 base_mod = inb(MOTOROLA_BASETYPE_REG);
789 if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) ||
790 (base_mod == 0xFA) || (base_mod == 0xE1))
791 prep_keybd_present = 0;
792
793 return 1;
794}
795
796struct mot_info {
797 int cpu_type; /* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */
798 /* 0x200 if this board has a Hawk chip. */
799 int base_type;
800 int max_cpu; /* ored with 0x80 if this board should be checked for multi CPU */
801 const char *name;
802 unsigned char *map;
803 unsigned char *routes;
804 void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
805 struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
806 unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
807} mot_info[] __prepdata = {
808 {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
809 {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
810 {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
811 {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes, NULL, NULL, 0x00},
812 {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes, NULL, NULL, 0x00},
813 {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes, NULL, NULL, 0x00},
814 {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes, NULL, NULL, 0x00},
815 {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xFF},
816 {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
817 {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xC0},
818 {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
819 {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
820 {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
821 {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
822 {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
823 {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
824 {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
825 {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
826 {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
827 {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
828 {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
829 {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
830 {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
831 {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
832 {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
833 {0x000, 0x00, 0x00, "", NULL, NULL, NULL, NULL, 0x00}
834};
835
836void __init
837ibm_prep_init(void)
838{
839 if (have_residual_data) {
840 u32 addr, real_addr, len, offset;
841 PPC_DEVICE *mpic;
842 PnP_TAG_PACKET *pkt;
843
844 /* Use the PReP residual data to determine if an OpenPIC is
845 * present. If so, get the large vendor packet which will
846 * tell us the base address and length in memory.
847 * If we are successful, ioremap the memory area and set
848 * OpenPIC_Addr (this indicates that the OpenPIC was found).
849 */
850 mpic = residual_find_device(-1, NULL, SystemPeripheral,
851 ProgrammableInterruptController, MPIC, 0);
852 if (!mpic)
853 return;
854
855 pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
856 mpic->AllocatedOffset, 9, 0);
857
858 if (!pkt)
859 return;
860
861#define p pkt->L4_Pack.L4_Data.L4_PPCPack
862 if (p.PPCData[1] == 32) {
863 switch (p.PPCData[0]) {
864 case 1: offset = PREP_ISA_IO_BASE; break;
865 case 2: offset = PREP_ISA_MEM_BASE; break;
866 default: return; /* Not I/O or memory?? */
867 }
868 }
869 else
870 return; /* Not a 32-bit address */
871
872 real_addr = ld_le32((unsigned int *) (p.PPCData + 4));
873 if (real_addr == 0xffffffff)
874 return;
875
876 /* Adjust address to be as seen by CPU */
877 addr = real_addr + offset;
878
879 len = ld_le32((unsigned int *) (p.PPCData + 12));
880 if (!len)
881 return;
882#undef p
883 OpenPIC_Addr = ioremap(addr, len);
884 ppc_md.get_irq = openpic_get_irq;
885
886 OpenPIC_InitSenses = prep_openpic_initsenses;
887 OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses);
888
889 printk(KERN_INFO "MPIC at 0x%08x (0x%08x), length 0x%08x "
890 "mapped to 0x%p\n", addr, real_addr, len, OpenPIC_Addr);
891 }
892}
893
894static void __init
895ibm43p_pci_map_non0(struct pci_dev *dev)
896{
897 unsigned char intpin;
898 static unsigned char bridge_intrs[4] = { 3, 4, 5, 8 };
899
900 if (dev == NULL)
901 return;
902 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin);
903 if (intpin < 1 || intpin > 4)
904 return;
905 intpin = (PCI_SLOT(dev->devfn) + intpin - 1) & 3;
906 dev->irq = openpic_to_irq(bridge_intrs[intpin]);
907 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
908}
909
910void __init
911prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
912{
913 if (have_residual_data) {
914 Motherboard_map_name = res->VitalProductData.PrintableModel;
915 Motherboard_map = NULL;
916 Motherboard_routes = NULL;
917 residual_irq_mask(irq_edge_mask_lo, irq_edge_mask_hi);
918 }
919}
920
921void __init
922prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
923{
924 Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";
925 Motherboard_map = ibm6015_pci_IRQ_map;
926 Motherboard_routes = ibm6015_pci_IRQ_routes;
927 *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
928 *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
929}
930
931void __init
932prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
933{
934 Motherboard_map_name = "IBM Thinkpad 850/860";
935 Motherboard_map = Nobis_pci_IRQ_map;
936 Motherboard_routes = Nobis_pci_IRQ_routes;
937 *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
938 *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
939}
940
941void __init
942prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
943{
944 Motherboard_map_name = "IBM 7248, PowerSeries 830/850 (Carolina)";
945 Motherboard_map = ibm8xx_pci_IRQ_map;
946 Motherboard_routes = ibm8xx_pci_IRQ_routes;
947 *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
948 *irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */
949}
950
951void __init
952prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
953{
954 Motherboard_map_name = "IBM 43P-140 (Tiger1)";
955 Motherboard_map = ibm43p_pci_IRQ_map;
956 Motherboard_routes = ibm43p_pci_IRQ_routes;
957 Motherboard_non0 = ibm43p_pci_map_non0;
958 *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
959 *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
960}
961
962void __init
963prep_route_pci_interrupts(void)
964{
965 unsigned char *ibc_pirq = (unsigned char *)0x80800860;
966 unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
967 int i;
968
969 if ( _prep_type == _PREP_Motorola)
970 {
971 unsigned short irq_mode;
972 unsigned char cpu_type;
973 unsigned char base_mod;
974 int entry;
975
976 cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
977 base_mod = inb(MOTOROLA_BASETYPE_REG);
978
979 for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
980 if (mot_info[entry].cpu_type & 0x200) { /* Check for Hawk chip */
981 if (!(MotMPIC & MOT_HAWK_PRESENT))
982 continue;
983 } else { /* Check non hawk boards */
984 if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
985 continue;
986
987 if (mot_info[entry].base_type == 0) {
988 mot_entry = entry;
989 break;
990 }
991
992 if (mot_info[entry].base_type != base_mod)
993 continue;
994 }
995
996 if (!(mot_info[entry].max_cpu & 0x80)) {
997 mot_entry = entry;
998 break;
999 }
1000
1001 /* processor 1 not present and max processor zero indicated */
1002 if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) {
1003 mot_entry = entry;
1004 break;
1005 }
1006
1007 /* processor 1 present and max processor zero indicated */
1008 if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) {
1009 mot_entry = entry;
1010 break;
1011 }
1012 }
1013
1014 if (mot_entry == -1) /* No particular cpu type found - assume Blackhawk */
1015 mot_entry = 3;
1016
1017 Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
1018 Motherboard_map = mot_info[mot_entry].map;
1019 Motherboard_routes = mot_info[mot_entry].routes;
1020 Motherboard_non0 = mot_info[mot_entry].map_non0_bus;
1021
1022 if (!(mot_info[entry].cpu_type & 0x100)) {
1023 /* AJF adjust level/edge control according to routes */
1024 irq_mode = 0;
1025 for (i = 1; i <= 4; i++)
1026 irq_mode |= ( 1 << Motherboard_routes[i] );
1027 outb( irq_mode & 0xff, 0x4d0 );
1028 outb( (irq_mode >> 8) & 0xff, 0x4d1 );
1029 }
1030 } else if ( _prep_type == _PREP_IBM ) {
1031 unsigned char irq_edge_mask_lo, irq_edge_mask_hi;
1032 unsigned short irq_edge_mask;
1033 int i;
1034
1035 setup_ibm_pci(&irq_edge_mask_lo, &irq_edge_mask_hi);
1036
1037 outb(inb(0x04d0)|irq_edge_mask_lo, 0x4d0); /* primary 8259 */
1038 outb(inb(0x04d1)|irq_edge_mask_hi, 0x4d1); /* cascaded 8259 */
1039
1040 irq_edge_mask = (irq_edge_mask_hi << 8) | irq_edge_mask_lo;
1041 for (i = 0; i < 16; ++i, irq_edge_mask >>= 1)
1042 if (irq_edge_mask & 1)
1043 irq_desc[i].status |= IRQ_LEVEL;
1044 } else {
1045 printk("No known machine pci routing!\n");
1046 return;
1047 }
1048
1049 /* Set up mapping from slots */
1050 if (Motherboard_routes) {
1051 for (i = 1; i <= 4; i++)
1052 ibc_pirq[i-1] = Motherboard_routes[i];
1053
1054 /* Enable PCI interrupts */
1055 *ibc_pcicon |= 0x20;
1056 }
1057}
1058
1059void __init
1060prep_pib_init(void)
1061{
1062 unsigned char reg;
1063 unsigned short short_reg;
1064
1065 struct pci_dev *dev = NULL;
1066
1067 if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) {
1068 /*
1069 * Perform specific configuration for the Via Tech or
1070 * or Winbond PCI-ISA-Bridge part.
1071 */
1072 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
1073 PCI_DEVICE_ID_VIA_82C586_1, dev))) {
1074 /*
1075 * PPCBUG does not set the enable bits
1076 * for the IDE device. Force them on here.
1077 */
1078 pci_read_config_byte(dev, 0x40, &reg);
1079
1080 reg |= 0x03; /* IDE: Chip Enable Bits */
1081 pci_write_config_byte(dev, 0x40, reg);
1082 }
1083 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
1084 PCI_DEVICE_ID_VIA_82C586_2,
1085 dev)) && (dev->devfn = 0x5a)) {
1086 /* Force correct USB interrupt */
1087 dev->irq = 11;
1088 pci_write_config_byte(dev,
1089 PCI_INTERRUPT_LINE,
1090 dev->irq);
1091 }
1092 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
1093 PCI_DEVICE_ID_WINBOND_83C553, dev))) {
1094 /* Clear PCI Interrupt Routing Control Register. */
1095 short_reg = 0x0000;
1096 pci_write_config_word(dev, 0x44, short_reg);
1097 if (OpenPIC_Addr){
1098 /* Route IDE interrupts to IRQ 14 */
1099 reg = 0xEE;
1100 pci_write_config_byte(dev, 0x43, reg);
1101 }
1102 }
1103 pci_dev_put(dev);
1104 }
1105
1106 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
1107 PCI_DEVICE_ID_WINBOND_82C105, dev))){
1108 if (OpenPIC_Addr){
1109 /*
1110 * Disable LEGIRQ mode so PCI INTS are routed
1111 * directly to the 8259 and enable both channels
1112 */
1113 pci_write_config_dword(dev, 0x40, 0x10ff0033);
1114
1115 /* Force correct IDE interrupt */
1116 dev->irq = 14;
1117 pci_write_config_byte(dev,
1118 PCI_INTERRUPT_LINE,
1119 dev->irq);
1120 } else {
1121 /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */
1122 pci_write_config_dword(dev, 0x40, 0x10ff08a1);
1123 }
1124 }
1125 pci_dev_put(dev);
1126}
1127
1128static void __init
1129Powerplus_Map_Non0(struct pci_dev *dev)
1130{
1131 struct pci_bus *pbus; /* Parent bus structure pointer */
1132 struct pci_dev *tdev = dev; /* Temporary device structure */
1133 unsigned int devnum; /* Accumulated device number */
1134 unsigned char intline; /* Linux interrupt value */
1135 unsigned char intpin; /* PCI interrupt pin */
1136
1137 /* Check for valid PCI dev pointer */
1138 if (dev == NULL) return;
1139
1140 /* Initialize bridge IDSEL variable */
1141 devnum = PCI_SLOT(tdev->devfn);
1142
1143 /* Read the interrupt pin of the device and adjust for indexing */
1144 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &intpin);
1145
1146 /* If device doesn't request an interrupt, return */
1147 if ( (intpin < 1) || (intpin > 4) )
1148 return;
1149
1150 intpin--;
1151
1152 /*
1153 * Walk up to bus 0, adjusting the interrupt pin for the standard
1154 * PCI bus swizzle.
1155 */
1156 do {
1157 intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
1158 pbus = tdev->bus; /* up one level */
1159 tdev = pbus->self;
1160 devnum = PCI_SLOT(tdev->devfn);
1161 } while(tdev->bus->number);
1162
1163 /* Use the primary interrupt inputs by default */
1164 intline = mot_info[mot_entry].pci_irq_list->primary[intpin];
1165
1166 /*
1167 * If the board has secondary interrupt inputs, walk the bus and
1168 * note the devfn of the bridge from bus 0. If it is the same as
1169 * the devfn of the bus bridge with secondary inputs, use those.
1170 * Otherwise, assume it's a PMC site and get the interrupt line
1171 * value from the interrupt routing table.
1172 */
1173 if (mot_info[mot_entry].secondary_bridge_devfn) {
1174 pbus = dev->bus;
1175
1176 while (pbus->primary != 0)
1177 pbus = pbus->parent;
1178
1179 if ((pbus->self)->devfn != 0xA0) {
1180 if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn)
1181 intline = mot_info[mot_entry].pci_irq_list->secondary[intpin];
1182 else {
1183 if ((char *)(mot_info[mot_entry].map) == (char *)Mesquite_pci_IRQ_map)
1184 intline = mot_info[mot_entry].map[((pbus->self)->devfn)/8] + 16;
1185 else {
1186 int i;
1187 for (i=0;i<3;i++)
1188 intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
1189 intline = mot_info[mot_entry].pci_irq_list->primary[intpin];
1190 }
1191 }
1192 }
1193 }
1194
1195 /* Write calculated interrupt value to header and device list */
1196 dev->irq = intline;
1197 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)dev->irq);
1198}
1199
1200void __init
1201prep_pcibios_fixup(void)
1202{
1203 struct pci_dev *dev = NULL;
1204 int irq;
1205 int have_openpic = (OpenPIC_Addr != NULL);
1206
1207 prep_route_pci_interrupts();
1208
1209 printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
1210
1211 /* Iterate through all the PCI devices, setting the IRQ */
1212 for_each_pci_dev(dev) {
1213 /*
1214 * If we have residual data, then this is easy: query the
1215 * residual data for the IRQ line allocated to the device.
1216 * This works the same whether we have an OpenPic or not.
1217 */
1218 if (have_residual_data) {
1219 irq = residual_pcidev_irq(dev);
1220 dev->irq = have_openpic ? openpic_to_irq(irq) : irq;
1221 }
1222 /*
1223 * If we don't have residual data, then we need to use
1224 * tables to determine the IRQ. The table organisation
1225 * is different depending on whether there is an OpenPIC
1226 * or not. The tables are only used for bus 0, so check
1227 * this first.
1228 */
1229 else if (dev->bus->number == 0) {
1230 irq = Motherboard_map[PCI_SLOT(dev->devfn)];
1231 dev->irq = have_openpic ? openpic_to_irq(irq)
1232 : Motherboard_routes[irq];
1233 }
1234 /*
1235 * Finally, if we don't have residual data and the bus is
1236 * non-zero, use the callback (if provided)
1237 */
1238 else {
1239 if (Motherboard_non0 != NULL)
1240 Motherboard_non0(dev);
1241
1242 continue;
1243 }
1244
1245 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
1246 }
1247
1248 /* Setup the Winbond or Via PIB */
1249 prep_pib_init();
1250}
1251
1252static void __init
1253prep_pcibios_after_init(void)
1254{
1255#if 0
1256 struct pci_dev *dev;
1257
1258 /* If there is a WD 90C, reset the IO BAR to 0x0 (it started that
1259 * way, but the PCI layer relocated it because it thought 0x0 was
1260 * invalid for a BAR).
1261 * If you don't do this, the card's VGA base will be <IO BAR>+0xc0000
1262 * instead of 0xc0000. vgacon.c (for example) is completely unaware of
1263 * this little quirk.
1264 */
1265 dev = pci_get_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL);
1266 if (dev) {
1267 dev->resource[1].end -= dev->resource[1].start;
1268 dev->resource[1].start = 0;
1269 /* tell the hardware */
1270 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x0);
1271 pci_dev_put(dev);
1272 }
1273#endif
1274}
1275
1276static void __init
1277prep_init_resource(struct resource *res, unsigned long start,
1278 unsigned long end, int flags)
1279{
1280 res->flags = flags;
1281 res->start = start;
1282 res->end = end;
1283 res->name = "PCI host bridge";
1284 res->parent = NULL;
1285 res->sibling = NULL;
1286 res->child = NULL;
1287}
1288
1289void __init
1290prep_find_bridges(void)
1291{
1292 struct pci_controller* hose;
1293
1294 hose = pcibios_alloc_controller();
1295 if (!hose)
1296 return;
1297
1298 hose->first_busno = 0;
1299 hose->last_busno = 0xff;
1300 hose->pci_mem_offset = PREP_ISA_MEM_BASE;
1301 hose->io_base_phys = PREP_ISA_IO_BASE;
1302 hose->io_base_virt = ioremap(PREP_ISA_IO_BASE, 0x800000);
1303 prep_init_resource(&hose->io_resource, 0, 0x007fffff, IORESOURCE_IO);
1304 prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,
1305 IORESOURCE_MEM);
1306 setup_indirect_pci(hose, PREP_ISA_IO_BASE + 0xcf8,
1307 PREP_ISA_IO_BASE + 0xcfc);
1308
1309 printk("PReP architecture\n");
1310
1311 if (have_residual_data) {
1312 PPC_DEVICE *hostbridge;
1313
1314 hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
1315 BridgeController, PCIBridge, -1, 0);
1316 if (hostbridge &&
1317 ((hostbridge->DeviceId.Interface == PCIBridgeIndirect) ||
1318 (hostbridge->DeviceId.Interface == PCIBridgeRS6K))) {
1319 PnP_TAG_PACKET * pkt;
1320 pkt = PnP_find_large_vendor_packet(
1321 res->DevicePnPHeap+hostbridge->AllocatedOffset,
1322 3, 0);
1323 if(pkt) {
1324#define p pkt->L4_Pack.L4_Data.L4_PPCPack
1325 setup_indirect_pci(hose,
1326 ld_le32((unsigned *) (p.PPCData)),
1327 ld_le32((unsigned *) (p.PPCData+8)));
1328#undef p
1329 } else
1330 setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);
1331 }
1332 }
1333
1334 ppc_md.pcibios_fixup = prep_pcibios_fixup;
1335 ppc_md.pcibios_after_init = prep_pcibios_after_init;
1336}
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
new file mode 100644
index 000000000000..bc926be95472
--- /dev/null
+++ b/arch/ppc/platforms/prep_setup.c
@@ -0,0 +1,1181 @@
1/*
2 * arch/ppc/platforms/setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 *
8 * Support for PReP (Motorola MTX/MVME)
9 * by Troy Benjegerdes (hozer@drgw.net)
10 */
11
12/*
13 * bootup setup stuff..
14 */
15
16#include <linux/config.h>
17#include <linux/delay.h>
18#include <linux/module.h>
19#include <linux/errno.h>
20#include <linux/sched.h>
21#include <linux/kernel.h>
22#include <linux/mm.h>
23#include <linux/stddef.h>
24#include <linux/unistd.h>
25#include <linux/ptrace.h>
26#include <linux/slab.h>
27#include <linux/user.h>
28#include <linux/a.out.h>
29#include <linux/tty.h>
30#include <linux/major.h>
31#include <linux/interrupt.h>
32#include <linux/reboot.h>
33#include <linux/init.h>
34#include <linux/initrd.h>
35#include <linux/ioport.h>
36#include <linux/console.h>
37#include <linux/timex.h>
38#include <linux/pci.h>
39#include <linux/ide.h>
40#include <linux/seq_file.h>
41#include <linux/root_dev.h>
42
43#include <asm/sections.h>
44#include <asm/mmu.h>
45#include <asm/processor.h>
46#include <asm/residual.h>
47#include <asm/io.h>
48#include <asm/pgtable.h>
49#include <asm/cache.h>
50#include <asm/dma.h>
51#include <asm/machdep.h>
52#include <asm/mc146818rtc.h>
53#include <asm/mk48t59.h>
54#include <asm/prep_nvram.h>
55#include <asm/raven.h>
56#include <asm/vga.h>
57#include <asm/time.h>
58#include <asm/mpc10x.h>
59#include <asm/i8259.h>
60#include <asm/open_pic.h>
61#include <asm/pci-bridge.h>
62#include <asm/todc.h>
63
64TODC_ALLOC();
65
66unsigned char ucSystemType;
67unsigned char ucBoardRev;
68unsigned char ucBoardRevMaj, ucBoardRevMin;
69
70extern unsigned char prep_nvram_read_val(int addr);
71extern void prep_nvram_write_val(int addr,
72 unsigned char val);
73extern unsigned char rs_nvram_read_val(int addr);
74extern void rs_nvram_write_val(int addr,
75 unsigned char val);
76extern void ibm_prep_init(void);
77
78extern void prep_find_bridges(void);
79
80int _prep_type;
81
82extern void prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
83extern void prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
84extern void prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
85extern void prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
86extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
87
88
89#define cached_21 (((char *)(ppc_cached_irq_mask))[3])
90#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])
91
92/* for the mac fs */
93dev_t boot_dev;
94
95#ifdef CONFIG_SOUND_CS4232
96long ppc_cs4232_dma, ppc_cs4232_dma2;
97#endif
98
99extern PTE *Hash, *Hash_end;
100extern unsigned long Hash_size, Hash_mask;
101extern int probingmem;
102extern unsigned long loops_per_jiffy;
103
104#ifdef CONFIG_SOUND_CS4232
105EXPORT_SYMBOL(ppc_cs4232_dma);
106EXPORT_SYMBOL(ppc_cs4232_dma2);
107#endif
108
109/* useful ISA ports */
110#define PREP_SYSCTL 0x81c
111/* present in the IBM reference design; possibly identical in Mot boxes: */
112#define PREP_IBM_SIMM_ID 0x803 /* SIMM size: 32 or 8 MiB */
113#define PREP_IBM_SIMM_PRESENCE 0x804
114#define PREP_IBM_EQUIPMENT 0x80c
115#define PREP_IBM_L2INFO 0x80d
116#define PREP_IBM_PM1 0x82a /* power management register 1 */
117#define PREP_IBM_PLANAR 0x852 /* planar ID - identifies the motherboard */
118#define PREP_IBM_DISP 0x8c0 /* 4-digit LED display */
119
120/* Equipment Present Register masks: */
121#define PREP_IBM_EQUIPMENT_RESERVED 0x80
122#define PREP_IBM_EQUIPMENT_SCSIFUSE 0x40
123#define PREP_IBM_EQUIPMENT_L2_COPYBACK 0x08
124#define PREP_IBM_EQUIPMENT_L2_256 0x04
125#define PREP_IBM_EQUIPMENT_CPU 0x02
126#define PREP_IBM_EQUIPMENT_L2 0x01
127
128/* planar ID values: */
129/* Sandalfoot/Sandalbow (6015/7020) */
130#define PREP_IBM_SANDALFOOT 0xfc
131/* Woodfield, Thinkpad 850/860 (6042/7249) */
132#define PREP_IBM_THINKPAD 0xff /* planar ID unimplemented */
133/* PowerSeries 830/850 (6050/6070) */
134#define PREP_IBM_CAROLINA_IDE_0 0xf0
135#define PREP_IBM_CAROLINA_IDE_1 0xf1
136#define PREP_IBM_CAROLINA_IDE_2 0xf2
137#define PREP_IBM_CAROLINA_IDE_3 0xf3
138/* 7248-43P */
139#define PREP_IBM_CAROLINA_SCSI_0 0xf4
140#define PREP_IBM_CAROLINA_SCSI_1 0xf5
141#define PREP_IBM_CAROLINA_SCSI_2 0xf6
142#define PREP_IBM_CAROLINA_SCSI_3 0xf7 /* missing from Carolina Tech Spec */
143/* Tiger1 (7043-140) */
144#define PREP_IBM_TIGER1_133 0xd1
145#define PREP_IBM_TIGER1_166 0xd2
146#define PREP_IBM_TIGER1_180 0xd3
147#define PREP_IBM_TIGER1_xxx 0xd4 /* unknown, but probably exists */
148#define PREP_IBM_TIGER1_333 0xd5 /* missing from Tiger Tech Spec */
149
150/* setup_ibm_pci:
151 * set Motherboard_map_name, Motherboard_map, Motherboard_routes.
152 * return 8259 edge/level masks.
153 */
154void (*setup_ibm_pci)(char *irq_lo, char *irq_hi);
155
156extern char *Motherboard_map_name; /* for use in *_cpuinfo */
157
158/*
159 * As found in the PReP reference implementation.
160 * Used by Thinkpad, Sandalfoot (6015/7020), and all Motorola PReP.
161 */
162static void __init
163prep_gen_enable_l2(void)
164{
165 outb(inb(PREP_SYSCTL) | 0x3, PREP_SYSCTL);
166}
167
168/* Used by Carolina and Tiger1 */
169static void __init
170prep_carolina_enable_l2(void)
171{
172 outb(inb(PREP_SYSCTL) | 0xc0, PREP_SYSCTL);
173}
174
175/* cpuinfo code common to all IBM PReP */
176static void __prep
177prep_ibm_cpuinfo(struct seq_file *m)
178{
179 unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
180
181 seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name);
182
183 seq_printf(m, "upgrade cpu\t: ");
184 if (equip_reg & PREP_IBM_EQUIPMENT_CPU) {
185 seq_printf(m, "not ");
186 }
187 seq_printf(m, "present\n");
188
189 /* print info about the SCSI fuse */
190 seq_printf(m, "scsi fuse\t: ");
191 if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE)
192 seq_printf(m, "ok");
193 else
194 seq_printf(m, "bad");
195 seq_printf(m, "\n");
196
197 /* print info about SIMMs */
198 if (have_residual_data) {
199 int i;
200 seq_printf(m, "simms\t\t: ");
201 for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
202 if (res->Memories[i].SIMMSize != 0)
203 seq_printf(m, "%d:%ldMiB ", i,
204 (res->Memories[i].SIMMSize > 1024) ?
205 res->Memories[i].SIMMSize>>20 :
206 res->Memories[i].SIMMSize);
207 }
208 seq_printf(m, "\n");
209 }
210}
211
212static int __prep
213prep_gen_cpuinfo(struct seq_file *m)
214{
215 prep_ibm_cpuinfo(m);
216 return 0;
217}
218
219static int __prep
220prep_sandalfoot_cpuinfo(struct seq_file *m)
221{
222 unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
223
224 prep_ibm_cpuinfo(m);
225
226 /* report amount and type of L2 cache present */
227 seq_printf(m, "L2 cache\t: ");
228 if (equip_reg & PREP_IBM_EQUIPMENT_L2) {
229 seq_printf(m, "not present");
230 } else {
231 if (equip_reg & PREP_IBM_EQUIPMENT_L2_256)
232 seq_printf(m, "256KiB");
233 else
234 seq_printf(m, "unknown size");
235
236 if (equip_reg & PREP_IBM_EQUIPMENT_L2_COPYBACK)
237 seq_printf(m, ", copy-back");
238 else
239 seq_printf(m, ", write-through");
240 }
241 seq_printf(m, "\n");
242
243 return 0;
244}
245
246static int __prep
247prep_thinkpad_cpuinfo(struct seq_file *m)
248{
249 unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
250 char *cpubus_speed, *pci_speed;
251
252 prep_ibm_cpuinfo(m);
253
254 /* report amount and type of L2 cache present */
255 seq_printf(m, "l2 cache\t: ");
256 if ((equip_reg & 0x1) == 0) {
257 switch ((equip_reg & 0xc) >> 2) {
258 case 0x0:
259 seq_printf(m, "128KiB look-aside 2-way write-through\n");
260 break;
261 case 0x1:
262 seq_printf(m, "512KiB look-aside direct-mapped write-back\n");
263 break;
264 case 0x2:
265 seq_printf(m, "256KiB look-aside 2-way write-through\n");
266 break;
267 case 0x3:
268 seq_printf(m, "256KiB look-aside direct-mapped write-back\n");
269 break;
270 }
271 } else {
272 seq_printf(m, "not present\n");
273 }
274
275 /* report bus speeds because we can */
276 if ((equip_reg & 0x80) == 0) {
277 switch ((equip_reg & 0x30) >> 4) {
278 case 0x1:
279 cpubus_speed = "50";
280 pci_speed = "25";
281 break;
282 case 0x3:
283 cpubus_speed = "66";
284 pci_speed = "33";
285 break;
286 default:
287 cpubus_speed = "unknown";
288 pci_speed = "unknown";
289 break;
290 }
291 } else {
292 switch ((equip_reg & 0x30) >> 4) {
293 case 0x1:
294 cpubus_speed = "25";
295 pci_speed = "25";
296 break;
297 case 0x2:
298 cpubus_speed = "60";
299 pci_speed = "30";
300 break;
301 case 0x3:
302 cpubus_speed = "33";
303 pci_speed = "33";
304 break;
305 default:
306 cpubus_speed = "unknown";
307 pci_speed = "unknown";
308 break;
309 }
310 }
311 seq_printf(m, "60x bus\t\t: %sMHz\n", cpubus_speed);
312 seq_printf(m, "pci bus\t\t: %sMHz\n", pci_speed);
313
314 return 0;
315}
316
317static int __prep
318prep_carolina_cpuinfo(struct seq_file *m)
319{
320 unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
321
322 prep_ibm_cpuinfo(m);
323
324 /* report amount and type of L2 cache present */
325 seq_printf(m, "l2 cache\t: ");
326 if ((equip_reg & 0x1) == 0) {
327 unsigned int l2_reg = inb(PREP_IBM_L2INFO);
328
329 /* L2 size */
330 if ((l2_reg & 0x60) == 0)
331 seq_printf(m, "256KiB");
332 else if ((l2_reg & 0x60) == 0x20)
333 seq_printf(m, "512KiB");
334 else
335 seq_printf(m, "unknown size");
336
337 /* L2 type */
338 if ((l2_reg & 0x3) == 0)
339 seq_printf(m, ", async");
340 else if ((l2_reg & 0x3) == 1)
341 seq_printf(m, ", sync");
342 else
343 seq_printf(m, ", unknown type");
344
345 seq_printf(m, "\n");
346 } else {
347 seq_printf(m, "not present\n");
348 }
349
350 return 0;
351}
352
353static int __prep
354prep_tiger1_cpuinfo(struct seq_file *m)
355{
356 unsigned int l2_reg = inb(PREP_IBM_L2INFO);
357
358 prep_ibm_cpuinfo(m);
359
360 /* report amount and type of L2 cache present */
361 seq_printf(m, "l2 cache\t: ");
362 if ((l2_reg & 0xf) == 0xf) {
363 seq_printf(m, "not present\n");
364 } else {
365 if (l2_reg & 0x8)
366 seq_printf(m, "async, ");
367 else
368 seq_printf(m, "sync burst, ");
369
370 if (l2_reg & 0x4)
371 seq_printf(m, "parity, ");
372 else
373 seq_printf(m, "no parity, ");
374
375 switch (l2_reg & 0x3) {
376 case 0x0:
377 seq_printf(m, "256KiB\n");
378 break;
379 case 0x1:
380 seq_printf(m, "512KiB\n");
381 break;
382 case 0x2:
383 seq_printf(m, "1MiB\n");
384 break;
385 default:
386 seq_printf(m, "unknown size\n");
387 break;
388 }
389 }
390
391 return 0;
392}
393
394
395/* Used by all Motorola PReP */
396static int __prep
397prep_mot_cpuinfo(struct seq_file *m)
398{
399 unsigned int cachew = *((unsigned char *)CACHECRBA);
400
401 seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name);
402
403 /* report amount and type of L2 cache present */
404 seq_printf(m, "l2 cache\t: ");
405 switch (cachew & L2CACHE_MASK) {
406 case L2CACHE_512KB:
407 seq_printf(m, "512KiB");
408 break;
409 case L2CACHE_256KB:
410 seq_printf(m, "256KiB");
411 break;
412 case L2CACHE_1MB:
413 seq_printf(m, "1MiB");
414 break;
415 case L2CACHE_NONE:
416 seq_printf(m, "none\n");
417 goto no_l2;
418 break;
419 default:
420 seq_printf(m, "%x\n", cachew);
421 }
422
423 seq_printf(m, ", parity %s",
424 (cachew & L2CACHE_PARITY)? "enabled" : "disabled");
425
426 seq_printf(m, " SRAM:");
427
428 switch ( ((cachew & 0xf0) >> 4) & ~(0x3) ) {
429 case 1: seq_printf(m, "synchronous, parity, flow-through\n");
430 break;
431 case 2: seq_printf(m, "asynchronous, no parity\n");
432 break;
433 case 3: seq_printf(m, "asynchronous, parity\n");
434 break;
435 default:seq_printf(m, "synchronous, pipelined, no parity\n");
436 break;
437 }
438
439no_l2:
440 /* print info about SIMMs */
441 if (have_residual_data) {
442 int i;
443 seq_printf(m, "simms\t\t: ");
444 for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
445 if (res->Memories[i].SIMMSize != 0)
446 seq_printf(m, "%d:%ldM ", i,
447 (res->Memories[i].SIMMSize > 1024) ?
448 res->Memories[i].SIMMSize>>20 :
449 res->Memories[i].SIMMSize);
450 }
451 seq_printf(m, "\n");
452 }
453
454 return 0;
455}
456
457static void __prep
458prep_restart(char *cmd)
459{
460#define PREP_SP92 0x92 /* Special Port 92 */
461 local_irq_disable(); /* no interrupts */
462
463 /* set exception prefix high - to the prom */
464 _nmask_and_or_msr(0, MSR_IP);
465
466 /* make sure bit 0 (reset) is a 0 */
467 outb( inb(PREP_SP92) & ~1L , PREP_SP92);
468 /* signal a reset to system control port A - soft reset */
469 outb( inb(PREP_SP92) | 1 , PREP_SP92);
470
471 while ( 1 ) ;
472 /* not reached */
473#undef PREP_SP92
474}
475
476static void __prep
477prep_halt(void)
478{
479 local_irq_disable(); /* no interrupts */
480
481 /* set exception prefix high - to the prom */
482 _nmask_and_or_msr(0, MSR_IP);
483
484 while ( 1 ) ;
485 /* not reached */
486}
487
488/* Carrera is the power manager in the Thinkpads. Unfortunately not much is
489 * known about it, so we can't power down.
490 */
491static void __prep
492prep_carrera_poweroff(void)
493{
494 prep_halt();
495}
496
497/*
498 * On most IBM PReP's, power management is handled by a Signetics 87c750
499 * behind the Utah component on the ISA bus. To access the 750 you must write
500 * a series of nibbles to port 0x82a (decoded by the Utah). This is described
501 * somewhat in the IBM Carolina Technical Specification.
502 * -Hollis
503 */
504static void __prep
505utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
506{
507 /*
508 * byte1: 0 0 0 1 0 d a5 a4
509 * byte2: 0 0 0 1 a3 a2 a1 a0
510 *
511 * d = the bit's value, enabled or disabled
512 * (a5 a4 a3) = the byte number, minus 20
513 * (a2 a1 a0) = the bit number
514 *
515 * example: set the 5th bit of byte 21 (21.5)
516 * a5 a4 a3 = 001 (byte 1)
517 * a2 a1 a0 = 101 (bit 5)
518 *
519 * byte1 = 0001 0100 (0x14)
520 * byte2 = 0001 1101 (0x1d)
521 */
522 unsigned char byte1=0x10, byte2=0x10;
523
524 /* the 750's '20.0' is accessed as '0.0' through Utah (which adds 20) */
525 bytenum -= 20;
526
527 byte1 |= (!!value) << 2; /* set d */
528 byte1 |= (bytenum >> 1) & 0x3; /* set a5, a4 */
529
530 byte2 |= (bytenum & 0x1) << 3; /* set a3 */
531 byte2 |= bitnum & 0x7; /* set a2, a1, a0 */
532
533 outb(byte1, PREP_IBM_PM1); /* first nibble */
534 mb();
535 udelay(100); /* important: let controller recover */
536
537 outb(byte2, PREP_IBM_PM1); /* second nibble */
538 mb();
539 udelay(100); /* important: let controller recover */
540}
541
542static void __prep
543prep_sig750_poweroff(void)
544{
545 /* tweak the power manager found in most IBM PRePs (except Thinkpads) */
546
547 local_irq_disable();
548 /* set exception prefix high - to the prom */
549 _nmask_and_or_msr(0, MSR_IP);
550
551 utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */
552
553 while (1) ;
554 /* not reached */
555}
556
557static int __prep
558prep_show_percpuinfo(struct seq_file *m, int i)
559{
560 /* PREP's without residual data will give incorrect values here */
561 seq_printf(m, "clock\t\t: ");
562 if (have_residual_data)
563 seq_printf(m, "%ldMHz\n",
564 (res->VitalProductData.ProcessorHz > 1024) ?
565 res->VitalProductData.ProcessorHz / 1000000 :
566 res->VitalProductData.ProcessorHz);
567 else
568 seq_printf(m, "???\n");
569
570 return 0;
571}
572
573#ifdef CONFIG_SOUND_CS4232
574static long __init masktoint(unsigned int i)
575{
576 int t = -1;
577 while (i >> ++t)
578 ;
579 return (t-1);
580}
581
582/*
583 * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h
584 * to distinguish sound dma-channels from others. This is because
585 * blocksize on 16 bit dma-channels 5,6,7 is 128k, but
586 * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3
587 */
588
589static void __init prep_init_sound(void)
590{
591 PPC_DEVICE *audiodevice = NULL;
592
593 /*
594 * Get the needed resource informations from residual data.
595 *
596 */
597 if (have_residual_data)
598 audiodevice = residual_find_device(~0, NULL,
599 MultimediaController, AudioController, -1, 0);
600
601 if (audiodevice != NULL) {
602 PnP_TAG_PACKET *pkt;
603
604 pkt = PnP_find_packet((unsigned char *)&res->DevicePnPHeap[audiodevice->AllocatedOffset],
605 S5_Packet, 0);
606 if (pkt != NULL)
607 ppc_cs4232_dma = masktoint(pkt->S5_Pack.DMAMask);
608 pkt = PnP_find_packet((unsigned char*)&res->DevicePnPHeap[audiodevice->AllocatedOffset],
609 S5_Packet, 1);
610 if (pkt != NULL)
611 ppc_cs4232_dma2 = masktoint(pkt->S5_Pack.DMAMask);
612 }
613
614 /*
615 * These are the PReP specs' defaults for the cs4231. We use these
616 * as fallback incase we don't have residual data.
617 * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7
618 * will use the other values.
619 */
620 if (audiodevice == NULL) {
621 switch (_prep_type) {
622 case _PREP_IBM:
623 ppc_cs4232_dma = 1;
624 ppc_cs4232_dma2 = -1;
625 break;
626 default:
627 ppc_cs4232_dma = 6;
628 ppc_cs4232_dma2 = 7;
629 }
630 }
631
632 /*
633 * Find a way to push these informations to the cs4232 driver
634 * Give it out with printk, when not in cmd_line?
635 * Append it to cmd_line and saved_command_line?
636 * Format is cs4232=io,irq,dma,dma2
637 */
638}
639#endif /* CONFIG_SOUND_CS4232 */
640
641/*
642 * Fill out screen_info according to the residual data. This allows us to use
643 * at least vesafb.
644 */
645static void __init
646prep_init_vesa(void)
647{
648#if (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA16_MODULE) || \
649 defined(CONFIG_FB_VESA))
650 PPC_DEVICE *vgadev = NULL;
651
652 if (have_residual_data)
653 vgadev = residual_find_device(~0, NULL, DisplayController,
654 SVGAController, -1, 0);
655
656 if (vgadev != NULL) {
657 PnP_TAG_PACKET *pkt;
658
659 pkt = PnP_find_large_vendor_packet(
660 (unsigned char *)&res->DevicePnPHeap[vgadev->AllocatedOffset],
661 0x04, 0); /* 0x04 = Display Tag */
662 if (pkt != NULL) {
663 unsigned char *ptr = (unsigned char *)pkt;
664
665 if (ptr[4]) {
666 /* graphics mode */
667 screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB;
668
669 screen_info.lfb_depth = ptr[4] * 8;
670
671 screen_info.lfb_width = swab16(*(short *)(ptr+6));
672 screen_info.lfb_height = swab16(*(short *)(ptr+8));
673 screen_info.lfb_linelength = swab16(*(short *)(ptr+10));
674
675 screen_info.lfb_base = swab32(*(long *)(ptr+12));
676 screen_info.lfb_size = swab32(*(long *)(ptr+20)) / 65536;
677 }
678 }
679 }
680#endif
681}
682
683/*
684 * Set DBAT 2 to access 0x80000000 so early progress messages will work
685 */
686static __inline__ void
687prep_set_bat(void)
688{
689 /* wait for all outstanding memory access to complete */
690 mb();
691
692 /* setup DBATs */
693 mtspr(SPRN_DBAT2U, 0x80001ffe);
694 mtspr(SPRN_DBAT2L, 0x8000002a);
695
696 /* wait for updates */
697 mb();
698}
699
700/*
701 * IBM 3-digit status LED
702 */
703static unsigned int ibm_statusled_base __prepdata;
704
705static void __prep
706ibm_statusled_progress(char *s, unsigned short hex);
707
708static int __prep
709ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
710 void * dummy3)
711{
712 ibm_statusled_progress(NULL, 0x505); /* SOS */
713 return NOTIFY_DONE;
714}
715
716static struct notifier_block ibm_statusled_block __prepdata = {
717 ibm_statusled_panic,
718 NULL,
719 INT_MAX /* try to do it first */
720};
721
722static void __prep
723ibm_statusled_progress(char *s, unsigned short hex)
724{
725 static int notifier_installed;
726 /*
727 * Progress uses 4 digits and we have only 3. So, we map 0xffff to
728 * 0xfff for display switch off. Out of range values are mapped to
729 * 0xeff, as I'm told 0xf00 and above are reserved for hardware codes.
730 * Install the panic notifier when the display is first switched off.
731 */
732 if (hex == 0xffff) {
733 hex = 0xfff;
734 if (!notifier_installed) {
735 ++notifier_installed;
736 notifier_chain_register(&panic_notifier_list,
737 &ibm_statusled_block);
738 }
739 }
740 else
741 if (hex > 0xfff)
742 hex = 0xeff;
743
744 mb();
745 outw(hex, ibm_statusled_base);
746}
747
748static void __init
749ibm_statusled_init(void)
750{
751 /*
752 * The IBM 3-digit LED display is specified in the residual data
753 * as an operator panel device, type "System Status LED". Find
754 * that device and determine its address. We validate all the
755 * other parameters on the off-chance another, similar device
756 * exists.
757 */
758 if (have_residual_data) {
759 PPC_DEVICE *led;
760 PnP_TAG_PACKET *pkt;
761
762 led = residual_find_device(~0, NULL, SystemPeripheral,
763 OperatorPanel, SystemStatusLED, 0);
764 if (!led)
765 return;
766
767 pkt = PnP_find_packet((unsigned char *)
768 &res->DevicePnPHeap[led->AllocatedOffset], S8_Packet, 0);
769 if (!pkt)
770 return;
771
772 if (pkt->S8_Pack.IOInfo != ISAAddr16bit)
773 return;
774 if (*(unsigned short *)pkt->S8_Pack.RangeMin !=
775 *(unsigned short *)pkt->S8_Pack.RangeMax)
776 return;
777 if (pkt->S8_Pack.IOAlign != 2)
778 return;
779 if (pkt->S8_Pack.IONum != 2)
780 return;
781
782 ibm_statusled_base = ld_le16((unsigned short *)
783 (pkt->S8_Pack.RangeMin));
784 ppc_md.progress = ibm_statusled_progress;
785 }
786}
787
788static void __init
789prep_setup_arch(void)
790{
791 unsigned char reg;
792 int is_ide=0;
793
794 /* init to some ~sane value until calibrate_delay() runs */
795 loops_per_jiffy = 50000000;
796
797 /* Lookup PCI host bridges */
798 prep_find_bridges();
799
800 /* Set up floppy in PS/2 mode */
801 outb(0x09, SIO_CONFIG_RA);
802 reg = inb(SIO_CONFIG_RD);
803 reg = (reg & 0x3F) | 0x40;
804 outb(reg, SIO_CONFIG_RD);
805 outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
806
807 switch ( _prep_type )
808 {
809 case _PREP_IBM:
810 reg = inb(PREP_IBM_PLANAR);
811 printk(KERN_INFO "IBM planar ID: %02x", reg);
812 switch (reg) {
813 case PREP_IBM_SANDALFOOT:
814 prep_gen_enable_l2();
815 setup_ibm_pci = prep_sandalfoot_setup_pci;
816 ppc_md.power_off = prep_sig750_poweroff;
817 ppc_md.show_cpuinfo = prep_sandalfoot_cpuinfo;
818 break;
819 case PREP_IBM_THINKPAD:
820 prep_gen_enable_l2();
821 setup_ibm_pci = prep_thinkpad_setup_pci;
822 ppc_md.power_off = prep_carrera_poweroff;
823 ppc_md.show_cpuinfo = prep_thinkpad_cpuinfo;
824 break;
825 default:
826 if (have_residual_data) {
827 prep_gen_enable_l2();
828 setup_ibm_pci = prep_residual_setup_pci;
829 ppc_md.power_off = prep_halt;
830 ppc_md.show_cpuinfo = prep_gen_cpuinfo;
831 break;
832 }
833 else
834 printk(" - unknown! Assuming Carolina");
835 /* fall through */
836 case PREP_IBM_CAROLINA_IDE_0:
837 case PREP_IBM_CAROLINA_IDE_1:
838 case PREP_IBM_CAROLINA_IDE_2:
839 case PREP_IBM_CAROLINA_IDE_3:
840 is_ide = 1;
841 case PREP_IBM_CAROLINA_SCSI_0:
842 case PREP_IBM_CAROLINA_SCSI_1:
843 case PREP_IBM_CAROLINA_SCSI_2:
844 case PREP_IBM_CAROLINA_SCSI_3:
845 prep_carolina_enable_l2();
846 setup_ibm_pci = prep_carolina_setup_pci;
847 ppc_md.power_off = prep_sig750_poweroff;
848 ppc_md.show_cpuinfo = prep_carolina_cpuinfo;
849 break;
850 case PREP_IBM_TIGER1_133:
851 case PREP_IBM_TIGER1_166:
852 case PREP_IBM_TIGER1_180:
853 case PREP_IBM_TIGER1_xxx:
854 case PREP_IBM_TIGER1_333:
855 prep_carolina_enable_l2();
856 setup_ibm_pci = prep_tiger1_setup_pci;
857 ppc_md.power_off = prep_sig750_poweroff;
858 ppc_md.show_cpuinfo = prep_tiger1_cpuinfo;
859 break;
860 }
861 printk("\n");
862
863 /* default root device */
864 if (is_ide)
865 ROOT_DEV = MKDEV(IDE0_MAJOR, 3);
866 else
867 ROOT_DEV = MKDEV(SCSI_DISK0_MAJOR, 3);
868
869 break;
870 case _PREP_Motorola:
871 prep_gen_enable_l2();
872 ppc_md.power_off = prep_halt;
873 ppc_md.show_cpuinfo = prep_mot_cpuinfo;
874
875#ifdef CONFIG_BLK_DEV_INITRD
876 if (initrd_start)
877 ROOT_DEV = Root_RAM0;
878 else
879#endif
880#ifdef CONFIG_ROOT_NFS
881 ROOT_DEV = Root_NFS;
882#else
883 ROOT_DEV = Root_SDA2;
884#endif
885 break;
886 }
887
888 /* Read in NVRAM data */
889 init_prep_nvram();
890
891 /* if no bootargs, look in NVRAM */
892 if ( cmd_line[0] == '\0' ) {
893 char *bootargs;
894 bootargs = prep_nvram_get_var("bootargs");
895 if (bootargs != NULL) {
896 strcpy(cmd_line, bootargs);
897 /* again.. */
898 strcpy(saved_command_line, cmd_line);
899 }
900 }
901
902#ifdef CONFIG_SOUND_CS4232
903 prep_init_sound();
904#endif /* CONFIG_SOUND_CS4232 */
905
906 prep_init_vesa();
907
908 switch (_prep_type) {
909 case _PREP_Motorola:
910 raven_init();
911 break;
912 case _PREP_IBM:
913 ibm_prep_init();
914 break;
915 }
916
917#ifdef CONFIG_VGA_CONSOLE
918 /* vgacon.c needs to know where we mapped IO memory in io_block_mapping() */
919 vgacon_remap_base = 0xf0000000;
920 conswitchp = &vga_con;
921#endif
922}
923
924/*
925 * First, see if we can get this information from the residual data.
926 * This is important on some IBM PReP systems. If we cannot, we let the
927 * TODC code handle doing this.
928 */
929static void __init
930prep_calibrate_decr(void)
931{
932 if (have_residual_data) {
933 unsigned long freq, divisor = 4;
934
935 if ( res->VitalProductData.ProcessorBusHz ) {
936 freq = res->VitalProductData.ProcessorBusHz;
937 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
938 (freq/divisor)/1000000,
939 (freq/divisor)%1000000);
940 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
941 tb_ticks_per_jiffy = freq / HZ / divisor;
942 }
943 }
944 else
945 todc_calibrate_decr();
946}
947
948static unsigned int __prep
949prep_irq_canonicalize(u_int irq)
950{
951 if (irq == 2)
952 {
953 return 9;
954 }
955 else
956 {
957 return irq;
958 }
959}
960
961static void __init
962prep_init_IRQ(void)
963{
964 int i;
965 unsigned int pci_viddid, pci_did;
966
967 if (OpenPIC_Addr != NULL) {
968 openpic_init(NUM_8259_INTERRUPTS);
969 /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
970 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
971 i8259_irq);
972 }
973 for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
974 irq_desc[i].handler = &i8259_pic;
975
976 if (have_residual_data) {
977 i8259_init(residual_isapic_addr());
978 return;
979 }
980
981 /* If we have a Raven PCI bridge or a Hawk PCI bridge / Memory
982 * controller, we poll (as they have a different int-ack address). */
983 early_read_config_dword(NULL, 0, 0, PCI_VENDOR_ID, &pci_viddid);
984 pci_did = (pci_viddid & 0xffff0000) >> 16;
985 if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
986 && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
987 || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
988 i8259_init(0);
989 else
990 /* PCI interrupt ack address given in section 6.1.8 of the
991 * PReP specification. */
992 i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR);
993}
994
995#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
996/*
997 * IDE stuff.
998 */
999static int __prep
1000prep_ide_default_irq(unsigned long base)
1001{
1002 switch (base) {
1003 case 0x1f0: return 13;
1004 case 0x170: return 13;
1005 case 0x1e8: return 11;
1006 case 0x168: return 10;
1007 case 0xfff0: return 14; /* MCP(N)750 ide0 */
1008 case 0xffe0: return 15; /* MCP(N)750 ide1 */
1009 default: return 0;
1010 }
1011}
1012
1013static unsigned long __prep
1014prep_ide_default_io_base(int index)
1015{
1016 switch (index) {
1017 case 0: return 0x1f0;
1018 case 1: return 0x170;
1019 case 2: return 0x1e8;
1020 case 3: return 0x168;
1021 default:
1022 return 0;
1023 }
1024}
1025#endif
1026
1027#ifdef CONFIG_SMP
1028/* PReP (MTX) support */
1029static int __init
1030smp_prep_probe(void)
1031{
1032 extern int mot_multi;
1033
1034 if (mot_multi) {
1035 openpic_request_IPIs();
1036 smp_hw_index[1] = 1;
1037 return 2;
1038 }
1039
1040 return 1;
1041}
1042
1043static void __init
1044smp_prep_kick_cpu(int nr)
1045{
1046 *(unsigned long *)KERNELBASE = nr;
1047 asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
1048 printk("CPU1 released, waiting\n");
1049}
1050
1051static void __init
1052smp_prep_setup_cpu(int cpu_nr)
1053{
1054 if (OpenPIC_Addr)
1055 do_openpic_setup_cpu();
1056}
1057
1058static struct smp_ops_t prep_smp_ops __prepdata = {
1059 smp_openpic_message_pass,
1060 smp_prep_probe,
1061 smp_prep_kick_cpu,
1062 smp_prep_setup_cpu,
1063 .give_timebase = smp_generic_give_timebase,
1064 .take_timebase = smp_generic_take_timebase,
1065};
1066#endif /* CONFIG_SMP */
1067
1068/*
1069 * Setup the bat mappings we're going to load that cover
1070 * the io areas. RAM was mapped by mapin_ram().
1071 * -- Cort
1072 */
1073static void __init
1074prep_map_io(void)
1075{
1076 io_block_mapping(0x80000000, PREP_ISA_IO_BASE, 0x10000000, _PAGE_IO);
1077 io_block_mapping(0xf0000000, PREP_ISA_MEM_BASE, 0x08000000, _PAGE_IO);
1078}
1079
1080static int __init
1081prep_request_io(void)
1082{
1083 if (_machine == _MACH_prep) {
1084#ifdef CONFIG_NVRAM
1085 request_region(PREP_NVRAM_AS0, 0x8, "nvram");
1086#endif
1087 request_region(0x00,0x20,"dma1");
1088 request_region(0x40,0x20,"timer");
1089 request_region(0x80,0x10,"dma page reg");
1090 request_region(0xc0,0x20,"dma2");
1091 }
1092
1093 return 0;
1094}
1095
1096device_initcall(prep_request_io);
1097
1098void __init
1099prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
1100 unsigned long r6, unsigned long r7)
1101{
1102#ifdef CONFIG_PREP_RESIDUAL
1103 /* make a copy of residual data */
1104 if ( r3 ) {
1105 memcpy((void *)res,(void *)(r3+KERNELBASE),
1106 sizeof(RESIDUAL));
1107 }
1108#endif
1109
1110 isa_io_base = PREP_ISA_IO_BASE;
1111 isa_mem_base = PREP_ISA_MEM_BASE;
1112 pci_dram_offset = PREP_PCI_DRAM_OFFSET;
1113 ISA_DMA_THRESHOLD = 0x00ffffff;
1114 DMA_MODE_READ = 0x44;
1115 DMA_MODE_WRITE = 0x48;
1116
1117 /* figure out what kind of prep workstation we are */
1118 if (have_residual_data) {
1119 if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
1120 _prep_type = _PREP_IBM;
1121 else
1122 _prep_type = _PREP_Motorola;
1123 }
1124 else {
1125 /* assume motorola if no residual (netboot?) */
1126 _prep_type = _PREP_Motorola;
1127 }
1128
1129#ifdef CONFIG_PREP_RESIDUAL
1130 /* Switch off all residual data processing if the user requests it */
1131 if (strstr(cmd_line, "noresidual") != NULL)
1132 res = NULL;
1133#endif
1134
1135 /* Initialise progress early to get maximum benefit */
1136 prep_set_bat();
1137 ibm_statusled_init();
1138
1139 ppc_md.setup_arch = prep_setup_arch;
1140 ppc_md.show_percpuinfo = prep_show_percpuinfo;
1141 ppc_md.show_cpuinfo = NULL; /* set in prep_setup_arch() */
1142 ppc_md.irq_canonicalize = prep_irq_canonicalize;
1143 ppc_md.init_IRQ = prep_init_IRQ;
1144 /* this gets changed later on if we have an OpenPIC -- Cort */
1145 ppc_md.get_irq = i8259_irq;
1146
1147 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
1148
1149 ppc_md.restart = prep_restart;
1150 ppc_md.power_off = NULL; /* set in prep_setup_arch() */
1151 ppc_md.halt = prep_halt;
1152
1153 ppc_md.nvram_read_val = prep_nvram_read_val;
1154 ppc_md.nvram_write_val = prep_nvram_write_val;
1155
1156 ppc_md.time_init = todc_time_init;
1157 if (_prep_type == _PREP_IBM) {
1158 ppc_md.rtc_read_val = todc_mc146818_read_val;
1159 ppc_md.rtc_write_val = todc_mc146818_write_val;
1160 TODC_INIT(TODC_TYPE_MC146818, RTC_PORT(0), NULL, RTC_PORT(1),
1161 8);
1162 } else {
1163 TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
1164 PREP_NVRAM_DATA, 8);
1165 }
1166
1167 ppc_md.calibrate_decr = prep_calibrate_decr;
1168 ppc_md.set_rtc_time = todc_set_rtc_time;
1169 ppc_md.get_rtc_time = todc_get_rtc_time;
1170
1171 ppc_md.setup_io_mappings = prep_map_io;
1172
1173#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
1174 ppc_ide_md.default_irq = prep_ide_default_irq;
1175 ppc_ide_md.default_io_base = prep_ide_default_io_base;
1176#endif
1177
1178#ifdef CONFIG_SMP
1179 ppc_md.smp_ops = &prep_smp_ops;
1180#endif /* CONFIG_SMP */
1181}
diff --git a/arch/ppc/platforms/prpmc750.c b/arch/ppc/platforms/prpmc750.c
new file mode 100644
index 000000000000..c894e1ab5934
--- /dev/null
+++ b/arch/ppc/platforms/prpmc750.c
@@ -0,0 +1,364 @@
1/*
2 * arch/ppc/platforms/prpmc750_setup.c
3 *
4 * Board setup routines for Motorola PrPMC750
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/kdev_t.h>
22#include <linux/types.h>
23#include <linux/major.h>
24#include <linux/initrd.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/seq_file.h>
29#include <linux/ide.h>
30#include <linux/root_dev.h>
31#include <linux/slab.h>
32
33#include <asm/byteorder.h>
34#include <asm/system.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <asm/dma.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40#include <asm/machdep.h>
41#include <asm/pci-bridge.h>
42#include <asm/uaccess.h>
43#include <asm/time.h>
44#include <asm/open_pic.h>
45#include <asm/bootinfo.h>
46#include <asm/hawk.h>
47
48#include "prpmc750.h"
49
50extern unsigned long loops_per_jiffy;
51
52extern void gen550_progress(char *, unsigned short);
53
54static u_char prpmc750_openpic_initsenses[] __initdata =
55{
56 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT0 */
57 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UART */
58 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_DEBUGINT */
59 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HAWK_WDT */
60 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */
61 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_ABORT */
62 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT1 */
63 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT2 */
64 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_HOSTINT3 */
65 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTA */
66 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTB */
67 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTC */
68 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_PMC_INTD */
69 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */
70 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */
71 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC750_INT_UNUSED */
72};
73
74/*
75 * Motorola PrPMC750/PrPMC800 in PrPMCBASE or PrPMC-Carrier
76 * Combined irq tables. Only Base has IDSEL 14, only Carrier has 21 and 22.
77 */
78static inline int
79prpmc_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
80{
81 static char pci_irq_table[][4] =
82 /*
83 * PCI IDSEL/INTPIN->INTLINE
84 * A B C D
85 */
86 {
87 {12, 0, 0, 0}, /* IDSEL 14 - Ethernet, base */
88 {0, 0, 0, 0}, /* IDSEL 15 - unused */
89 {10, 11, 12, 9}, /* IDSEL 16 - PMC A1, PMC1 */
90 {10, 11, 12, 9}, /* IDSEL 17 - PrPMC-A-B, PMC2-B */
91 {11, 12, 9, 10}, /* IDSEL 18 - PMC A1-B, PMC1-B */
92 {0, 0, 0, 0}, /* IDSEL 19 - unused */
93 {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */
94 {11, 12, 9, 10}, /* IDSEL 21 - PMC A2, carrier */
95 {12, 9, 10, 11}, /* IDSEL 22 - PMC A2-B, carrier */
96 };
97 const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4;
98 return PCI_IRQ_TABLE_LOOKUP;
99};
100
101static void __init prpmc750_pcibios_fixup(void)
102{
103 struct pci_dev *dev;
104 unsigned short wtmp;
105
106 /*
107 * Kludge to clean up after PPC6BUG which doesn't
108 * configure the CL5446 VGA card. Also the
109 * resource subsystem doesn't fixup the
110 * PCI mem resources on the CL5446.
111 */
112 if ((dev = pci_get_device(PCI_VENDOR_ID_CIRRUS,
113 PCI_DEVICE_ID_CIRRUS_5446, 0))) {
114 dev->resource[0].start += PRPMC750_PCI_PHY_MEM_OFFSET;
115 dev->resource[0].end += PRPMC750_PCI_PHY_MEM_OFFSET;
116 pci_read_config_word(dev, PCI_COMMAND, &wtmp);
117 pci_write_config_word(dev, PCI_COMMAND, wtmp | 3);
118 /* Enable Color mode in MISC reg */
119 outb(0x03, 0x3c2);
120 /* Select DRAM config reg */
121 outb(0x0f, 0x3c4);
122 /* Set proper DRAM config */
123 outb(0xdf, 0x3c5);
124 pci_dev_put(dev);
125 }
126}
127
128void __init prpmc750_find_bridges(void)
129{
130 struct pci_controller *hose;
131
132 hose = pcibios_alloc_controller();
133 if (!hose)
134 return;
135
136 hose->first_busno = 0;
137 hose->last_busno = 0xff;
138 hose->io_base_virt = (void *)PRPMC750_ISA_IO_BASE;
139 hose->pci_mem_offset = PRPMC750_PCI_PHY_MEM_OFFSET;
140
141 pci_init_resource(&hose->io_resource,
142 PRPMC750_PCI_IO_START,
143 PRPMC750_PCI_IO_END,
144 IORESOURCE_IO, "PCI host bridge");
145
146 pci_init_resource(&hose->mem_resources[0],
147 PRPMC750_PROC_PCI_MEM_START,
148 PRPMC750_PROC_PCI_MEM_END,
149 IORESOURCE_MEM, "PCI host bridge");
150
151 hose->io_space.start = PRPMC750_PCI_IO_START;
152 hose->io_space.end = PRPMC750_PCI_IO_END;
153 hose->mem_space.start = PRPMC750_PCI_MEM_START;
154 hose->mem_space.end = PRPMC750_PCI_MEM_END - HAWK_MPIC_SIZE;
155
156 if (hawk_init(hose, PRPMC750_HAWK_PPC_REG_BASE,
157 PRPMC750_PROC_PCI_MEM_START,
158 PRPMC750_PROC_PCI_MEM_END - HAWK_MPIC_SIZE,
159 PRPMC750_PROC_PCI_IO_START, PRPMC750_PROC_PCI_IO_END,
160 PRPMC750_PROC_PCI_MEM_END - HAWK_MPIC_SIZE + 1)
161 != 0) {
162 printk(KERN_CRIT "Could not initialize host bridge\n");
163 }
164
165 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
166
167 ppc_md.pcibios_fixup = prpmc750_pcibios_fixup;
168 ppc_md.pci_swizzle = common_swizzle;
169 ppc_md.pci_map_irq = prpmc_map_irq;
170}
171static int prpmc750_show_cpuinfo(struct seq_file *m)
172{
173 seq_printf(m, "machine\t\t: PrPMC750\n");
174
175 return 0;
176}
177
178static void __init prpmc750_setup_arch(void)
179{
180 /* init to some ~sane value until calibrate_delay() runs */
181 loops_per_jiffy = 50000000 / HZ;
182
183 /* Lookup PCI host bridges */
184 prpmc750_find_bridges();
185
186#ifdef CONFIG_BLK_DEV_INITRD
187 if (initrd_start)
188 ROOT_DEV = Root_RAM0;
189 else
190#endif
191#ifdef CONFIG_ROOT_NFS
192 ROOT_DEV = Root_NFS;
193#else
194 ROOT_DEV = Root_SDA2;
195#endif
196
197 OpenPIC_InitSenses = prpmc750_openpic_initsenses;
198 OpenPIC_NumInitSenses = sizeof(prpmc750_openpic_initsenses);
199
200 printk(KERN_INFO "Port by MontaVista Software, Inc. "
201 "(source@mvista.com)\n");
202}
203
204/*
205 * Compute the PrPMC750's bus speed using the baud clock as a
206 * reference.
207 */
208static unsigned long __init prpmc750_get_bus_speed(void)
209{
210 unsigned long tbl_start, tbl_end;
211 unsigned long current_state, old_state, bus_speed;
212 unsigned char lcr, dll, dlm;
213 int baud_divisor, count;
214
215 /* Read the UART's baud clock divisor */
216 lcr = readb(PRPMC750_SERIAL_0_LCR);
217 writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR);
218 dll = readb(PRPMC750_SERIAL_0_DLL);
219 dlm = readb(PRPMC750_SERIAL_0_DLM);
220 writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR);
221 baud_divisor = (dlm << 8) | dll;
222
223 /*
224 * Use the baud clock divisor and base baud clock
225 * to determine the baud rate and use that as
226 * the number of baud clock edges we use for
227 * the time base sample. Make it half the baud
228 * rate.
229 */
230 count = PRPMC750_BASE_BAUD / (baud_divisor * 16);
231
232 /* Find the first edge of the baud clock */
233 old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK;
234 do {
235 current_state = readb(PRPMC750_STATUS_REG) &
236 PRPMC750_BAUDOUT_MASK;
237 } while (old_state == current_state);
238
239 old_state = current_state;
240
241 /* Get the starting time base value */
242 tbl_start = get_tbl();
243
244 /*
245 * Loop until we have found a number of edges equal
246 * to half the count (half the baud rate)
247 */
248 do {
249 do {
250 current_state = readb(PRPMC750_STATUS_REG) &
251 PRPMC750_BAUDOUT_MASK;
252 } while (old_state == current_state);
253 old_state = current_state;
254 } while (--count);
255
256 /* Get the ending time base value */
257 tbl_end = get_tbl();
258
259 /* Compute bus speed */
260 bus_speed = (tbl_end - tbl_start) * 128;
261
262 return bus_speed;
263}
264
265static void __init prpmc750_calibrate_decr(void)
266{
267 unsigned long freq;
268 int divisor = 4;
269
270 freq = prpmc750_get_bus_speed();
271
272 tb_ticks_per_jiffy = freq / (HZ * divisor);
273 tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
274}
275
276static void prpmc750_restart(char *cmd)
277{
278 local_irq_disable();
279 writeb(PRPMC750_MODRST_MASK, PRPMC750_MODRST_REG);
280 while (1) ;
281}
282
283static void prpmc750_halt(void)
284{
285 local_irq_disable();
286 while (1) ;
287}
288
289static void prpmc750_power_off(void)
290{
291 prpmc750_halt();
292}
293
294static void __init prpmc750_init_IRQ(void)
295{
296 openpic_init(0);
297}
298
299/*
300 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
301 */
302static __inline__ void prpmc750_set_bat(void)
303{
304 mb();
305 mtspr(SPRN_DBAT1U, 0xf0001ffe);
306 mtspr(SPRN_DBAT1L, 0xf000002a);
307 mb();
308}
309
310/*
311 * We need to read the Falcon/Hawk memory controller
312 * to properly determine this value
313 */
314static unsigned long __init prpmc750_find_end_of_memory(void)
315{
316 /* Read the memory size from the Hawk SMC */
317 return hawk_get_mem_size(PRPMC750_HAWK_SMC_BASE);
318}
319
320static void __init prpmc750_map_io(void)
321{
322 io_block_mapping(PRPMC750_ISA_IO_BASE, PRPMC750_ISA_IO_BASE,
323 0x10000000, _PAGE_IO);
324#if 0
325 io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO);
326#endif
327 io_block_mapping(0xf8000000, 0xf8000000, 0x08000000, _PAGE_IO);
328}
329
330void __init
331platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
332 unsigned long r6, unsigned long r7)
333{
334 parse_bootinfo(find_bootinfo());
335
336 /* Cover the Hawk registers with a BAT */
337 prpmc750_set_bat();
338
339 isa_io_base = PRPMC750_ISA_IO_BASE;
340 isa_mem_base = PRPMC750_ISA_MEM_BASE;
341 pci_dram_offset = PRPMC750_PCI_DRAM_OFFSET;
342
343 ppc_md.setup_arch = prpmc750_setup_arch;
344 ppc_md.show_cpuinfo = prpmc750_show_cpuinfo;
345 ppc_md.init_IRQ = prpmc750_init_IRQ;
346 ppc_md.get_irq = openpic_get_irq;
347
348 ppc_md.find_end_of_memory = prpmc750_find_end_of_memory;
349 ppc_md.setup_io_mappings = prpmc750_map_io;
350
351 ppc_md.restart = prpmc750_restart;
352 ppc_md.power_off = prpmc750_power_off;
353 ppc_md.halt = prpmc750_halt;
354
355 /* PrPMC750 has no timekeeper part */
356 ppc_md.time_init = NULL;
357 ppc_md.get_rtc_time = NULL;
358 ppc_md.set_rtc_time = NULL;
359 ppc_md.calibrate_decr = prpmc750_calibrate_decr;
360
361#ifdef CONFIG_SERIAL_TEXT_DEBUG
362 ppc_md.progress = gen550_progress;
363#endif /* CONFIG_SERIAL_TEXT_DEBUG */
364}
diff --git a/arch/ppc/platforms/prpmc750.h b/arch/ppc/platforms/prpmc750.h
new file mode 100644
index 000000000000..015b4f52c3eb
--- /dev/null
+++ b/arch/ppc/platforms/prpmc750.h
@@ -0,0 +1,95 @@
1/*
2 * include/asm-ppc/platforms/prpmc750.h
3 *
4 * Definitions for Motorola PrPMC750 board support
5 *
6 * Author: Matt Porter <mporter@mvista.com>
7 *
8 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#ifdef __KERNEL__
15#ifndef __ASM_PRPMC750_H__
16#define __ASM_PRPMC750_H__
17
18/*
19 * Due to limiations imposed by legacy hardware (primaryily IDE controllers),
20 * the PrPMC750 carrier board operates using a PReP address map.
21 *
22 * From Processor (physical) -> PCI:
23 * PCI Mem Space: 0xc0000000 - 0xfe000000 -> 0x00000000 - 0x3e000000 (768 MB)
24 * PCI I/O Space: 0x80000000 - 0x90000000 -> 0x00000000 - 0x10000000 (256 MB)
25 * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area
26 *
27 * From PCI -> Processor (physical):
28 * System Memory: 0x80000000 -> 0x00000000
29 */
30
31#define PRPMC750_ISA_IO_BASE PREP_ISA_IO_BASE
32#define PRPMC750_ISA_MEM_BASE PREP_ISA_MEM_BASE
33
34/* PCI Memory space mapping info */
35#define PRPMC750_PCI_MEM_SIZE 0x30000000U
36#define PRPMC750_PROC_PCI_MEM_START PRPMC750_ISA_MEM_BASE
37#define PRPMC750_PROC_PCI_MEM_END (PRPMC750_PROC_PCI_MEM_START + \
38 PRPMC750_PCI_MEM_SIZE - 1)
39#define PRPMC750_PCI_MEM_START 0x00000000U
40#define PRPMC750_PCI_MEM_END (PRPMC750_PCI_MEM_START + \
41 PRPMC750_PCI_MEM_SIZE - 1)
42
43/* PCI I/O space mapping info */
44#define PRPMC750_PCI_IO_SIZE 0x10000000U
45#define PRPMC750_PROC_PCI_IO_START PRPMC750_ISA_IO_BASE
46#define PRPMC750_PROC_PCI_IO_END (PRPMC750_PROC_PCI_IO_START + \
47 PRPMC750_PCI_IO_SIZE - 1)
48#define PRPMC750_PCI_IO_START 0x00000000U
49#define PRPMC750_PCI_IO_END (PRPMC750_PCI_IO_START + \
50 PRPMC750_PCI_IO_SIZE - 1)
51
52/* System memory mapping info */
53#define PRPMC750_PCI_DRAM_OFFSET PREP_PCI_DRAM_OFFSET
54#define PRPMC750_PCI_PHY_MEM_OFFSET (PRPMC750_ISA_MEM_BASE-PRPMC750_PCI_MEM_START)
55
56/* Register address definitions */
57#define PRPMC750_HAWK_SMC_BASE 0xfef80000U
58#define PRPMC750_HAWK_PPC_REG_BASE 0xfeff0000U
59
60#define PRPMC750_BASE_BAUD 1843200
61#define PRPMC750_SERIAL_0 0xfef88000
62#define PRPMC750_SERIAL_0_DLL (PRPMC750_SERIAL_0 + (UART_DLL << 4))
63#define PRPMC750_SERIAL_0_DLM (PRPMC750_SERIAL_0 + (UART_DLM << 4))
64#define PRPMC750_SERIAL_0_LCR (PRPMC750_SERIAL_0 + (UART_LCR << 4))
65
66#define PRPMC750_STATUS_REG 0xfef88080
67#define PRPMC750_BAUDOUT_MASK 0x02
68#define PRPMC750_MONARCH_MASK 0x01
69
70#define PRPMC750_MODRST_REG 0xfef880a0
71#define PRPMC750_MODRST_MASK 0x01
72
73#define PRPMC750_PIRQ_REG 0xfef880b0
74#define PRPMC750_SEL1_MASK 0x02
75#define PRPMC750_SEL0_MASK 0x01
76
77#define PRPMC750_TBEN_REG 0xfef880c0
78#define PRPMC750_TBEN_MASK 0x01
79
80/* UART Defines. */
81#define RS_TABLE_SIZE 4
82
83/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
84#define BASE_BAUD (PRPMC750_BASE_BAUD / 16)
85
86#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
87
88#define SERIAL_PORT_DFNS \
89 { 0, BASE_BAUD, PRPMC750_SERIAL_0, 1, STD_COM_FLAGS, \
90 iomem_base: (unsigned char *)PRPMC750_SERIAL_0, \
91 iomem_reg_shift: 4, \
92 io_type: SERIAL_IO_MEM } /* ttyS0 */
93
94#endif /* __ASM_PRPMC750_H__ */
95#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/prpmc800.c b/arch/ppc/platforms/prpmc800.c
new file mode 100644
index 000000000000..8b09fa69b35b
--- /dev/null
+++ b/arch/ppc/platforms/prpmc800.c
@@ -0,0 +1,477 @@
1/*
2 * arch/ppc/platforms/prpmc800.c
3 *
4 * Author: Dale Farnsworth <dale.farnsworth@mvista.com>
5 *
6 * 2001-2004 (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
12#include <linux/config.h>
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/reboot.h>
18#include <linux/pci.h>
19#include <linux/kdev_t.h>
20#include <linux/types.h>
21#include <linux/major.h>
22#include <linux/initrd.h>
23#include <linux/console.h>
24#include <linux/delay.h>
25#include <linux/irq.h>
26#include <linux/seq_file.h>
27#include <linux/ide.h>
28#include <linux/root_dev.h>
29#include <linux/harrier_defs.h>
30
31#include <asm/byteorder.h>
32#include <asm/system.h>
33#include <asm/pgtable.h>
34#include <asm/page.h>
35#include <asm/dma.h>
36#include <asm/io.h>
37#include <asm/irq.h>
38#include <asm/machdep.h>
39#include <asm/time.h>
40#include <asm/pci-bridge.h>
41#include <asm/open_pic.h>
42#include <asm/bootinfo.h>
43#include <asm/harrier.h>
44
45#include "prpmc800.h"
46
47#define HARRIER_REVI_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_REVI_OFF)
48#define HARRIER_UCTL_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_UCTL_OFF)
49#define HARRIER_MISC_CSR_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_MISC_CSR_OFF)
50#define HARRIER_IFEVP_REG (PRPMC800_HARRIER_MPIC_BASE+HARRIER_MPIC_IFEVP_OFF)
51#define HARRIER_IFEDE_REG (PRPMC800_HARRIER_MPIC_BASE+HARRIER_MPIC_IFEDE_OFF)
52#define HARRIER_FEEN_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_FEEN_OFF)
53#define HARRIER_FEMA_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_FEMA_OFF)
54
55#define HARRIER_VENI_REG (PRPMC800_HARRIER_XCSR_BASE + HARRIER_VENI_OFF)
56#define HARRIER_MISC_CSR (PRPMC800_HARRIER_XCSR_BASE + \
57 HARRIER_MISC_CSR_OFF)
58
59#define MONARCH (monarch != 0)
60#define NON_MONARCH (monarch == 0)
61
62extern int mpic_init(void);
63extern unsigned long loops_per_jiffy;
64extern void gen550_progress(char *, unsigned short);
65
66static int monarch = 0;
67static int found_self = 0;
68static int self = 0;
69
70static u_char prpmc800_openpic_initsenses[] __initdata =
71{
72 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HOSTINT0 */
73 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
74 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_DEBUGINT */
75 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HARRIER_WDT */
76 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
77 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
78 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HOSTINT1 */
79 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HOSTINT2 */
80 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HOSTINT3 */
81 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_PMC_INTA */
82 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_PMC_INTB */
83 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_PMC_INTC */
84 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_PMC_INTD */
85 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
86 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
87 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_UNUSED */
88 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* PRPMC800_INT_HARRIER_INT (UARTS, ABORT, DMA) */
89};
90
91/*
92 * Motorola PrPMC750/PrPMC800 in PrPMCBASE or PrPMC-Carrier
93 * Combined irq tables. Only Base has IDSEL 14, only Carrier has 21 and 22.
94 */
95static inline int
96prpmc_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
97{
98 static char pci_irq_table[][4] =
99 /*
100 * PCI IDSEL/INTPIN->INTLINE
101 * A B C D
102 */
103 {
104 {12, 0, 0, 0}, /* IDSEL 14 - Ethernet, base */
105 {0, 0, 0, 0}, /* IDSEL 15 - unused */
106 {10, 11, 12, 9}, /* IDSEL 16 - PMC A1, PMC1 */
107 {10, 11, 12, 9}, /* IDSEL 17 - PrPMC-A-B, PMC2-B */
108 {11, 12, 9, 10}, /* IDSEL 18 - PMC A1-B, PMC1-B */
109 {0, 0, 0, 0}, /* IDSEL 19 - unused */
110 {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */
111 {11, 12, 9, 10}, /* IDSEL 21 - PMC A2, carrier */
112 {12, 9, 10, 11}, /* IDSEL 22 - PMC A2-B, carrier */
113 };
114 const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4;
115 return PCI_IRQ_TABLE_LOOKUP;
116};
117
118static int
119prpmc_read_config_dword(struct pci_controller *hose, u8 bus, u8 devfn,
120 int offset, u32 * val)
121{
122 /* paranoia */
123 if ((hose == NULL) ||
124 (hose->cfg_addr == NULL) || (hose->cfg_data == NULL))
125 return PCIBIOS_DEVICE_NOT_FOUND;
126
127 out_be32(hose->cfg_addr, ((offset & 0xfc) << 24) | (devfn << 16)
128 | ((bus - hose->bus_offset) << 8) | 0x80);
129 *val = in_le32((u32 *) (hose->cfg_data + (offset & 3)));
130
131 return PCIBIOS_SUCCESSFUL;
132}
133
134#define HARRIER_PCI_VEND_DEV_ID (PCI_VENDOR_ID_MOTOROLA | \
135 (PCI_DEVICE_ID_MOTOROLA_HARRIER << 16))
136static int prpmc_self(u8 bus, u8 devfn)
137{
138 /*
139 * Harriers always view themselves as being on bus 0. If we're not
140 * looking at bus 0, we're not going to find ourselves.
141 */
142 if (bus != 0)
143 return PCIBIOS_DEVICE_NOT_FOUND;
144 else {
145 int result;
146 int val;
147 struct pci_controller *hose;
148
149 hose = pci_bus_to_hose(bus);
150
151 /* See if target device is a Harrier */
152 result = prpmc_read_config_dword(hose, bus, devfn,
153 PCI_VENDOR_ID, &val);
154 if ((result != PCIBIOS_SUCCESSFUL) ||
155 (val != HARRIER_PCI_VEND_DEV_ID))
156 return PCIBIOS_DEVICE_NOT_FOUND;
157
158 /*
159 * LBA bit is set if target Harrier == initiating Harrier
160 * (i.e. if we are reading our own PCI header).
161 */
162 result = prpmc_read_config_dword(hose, bus, devfn,
163 HARRIER_LBA_OFF, &val);
164 if ((result != PCIBIOS_SUCCESSFUL) ||
165 ((val & HARRIER_LBA_MSK) != HARRIER_LBA_MSK))
166 return PCIBIOS_DEVICE_NOT_FOUND;
167
168 /* It's us, save our location for later */
169 self = devfn;
170 found_self = 1;
171 return PCIBIOS_SUCCESSFUL;
172 }
173}
174
175static int prpmc_exclude_device(u8 bus, u8 devfn)
176{
177 /*
178 * Monarch is allowed to access all PCI devices. Non-monarch is
179 * only allowed to access its own Harrier.
180 */
181
182 if (MONARCH)
183 return PCIBIOS_SUCCESSFUL;
184 if (found_self)
185 if ((bus == 0) && (devfn == self))
186 return PCIBIOS_SUCCESSFUL;
187 else
188 return PCIBIOS_DEVICE_NOT_FOUND;
189 else
190 return prpmc_self(bus, devfn);
191}
192
193void __init prpmc800_find_bridges(void)
194{
195 struct pci_controller *hose;
196 int host_bridge;
197
198 hose = pcibios_alloc_controller();
199 if (!hose)
200 return;
201
202 hose->first_busno = 0;
203 hose->last_busno = 0xff;
204
205 ppc_md.pci_exclude_device = prpmc_exclude_device;
206 ppc_md.pcibios_fixup = NULL;
207 ppc_md.pcibios_fixup_bus = NULL;
208 ppc_md.pci_swizzle = common_swizzle;
209 ppc_md.pci_map_irq = prpmc_map_irq;
210
211 setup_indirect_pci(hose,
212 PRPMC800_PCI_CONFIG_ADDR, PRPMC800_PCI_CONFIG_DATA);
213
214 /* Get host bridge vendor/dev id */
215
216 host_bridge = in_be32((uint *) (HARRIER_VENI_REG));
217
218 if (host_bridge != HARRIER_VEND_DEV_ID) {
219 printk(KERN_CRIT "Host bridge 0x%x not supported\n",
220 host_bridge);
221 return;
222 }
223
224 monarch = in_be32((uint *) HARRIER_MISC_CSR) & HARRIER_SYSCON;
225
226 printk(KERN_INFO "Running as %s.\n",
227 MONARCH ? "Monarch" : "Non-Monarch");
228
229 hose->io_space.start = PRPMC800_PCI_IO_START;
230 hose->io_space.end = PRPMC800_PCI_IO_END;
231 hose->io_base_virt = (void *)PRPMC800_ISA_IO_BASE;
232 hose->pci_mem_offset = PRPMC800_PCI_PHY_MEM_OFFSET;
233
234 pci_init_resource(&hose->io_resource,
235 PRPMC800_PCI_IO_START, PRPMC800_PCI_IO_END,
236 IORESOURCE_IO, "PCI host bridge");
237
238 if (MONARCH) {
239 hose->mem_space.start = PRPMC800_PCI_MEM_START;
240 hose->mem_space.end = PRPMC800_PCI_MEM_END;
241
242 pci_init_resource(&hose->mem_resources[0],
243 PRPMC800_PCI_MEM_START,
244 PRPMC800_PCI_MEM_END,
245 IORESOURCE_MEM, "PCI host bridge");
246
247 if (harrier_init(hose,
248 PRPMC800_HARRIER_XCSR_BASE,
249 PRPMC800_PROC_PCI_MEM_START,
250 PRPMC800_PROC_PCI_MEM_END,
251 PRPMC800_PROC_PCI_IO_START,
252 PRPMC800_PROC_PCI_IO_END,
253 PRPMC800_HARRIER_MPIC_BASE) != 0)
254 printk(KERN_CRIT "Could not initialize HARRIER "
255 "bridge\n");
256
257 harrier_release_eready(PRPMC800_HARRIER_XCSR_BASE);
258 harrier_wait_eready(PRPMC800_HARRIER_XCSR_BASE);
259 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
260
261 } else {
262 pci_init_resource(&hose->mem_resources[0],
263 PRPMC800_NM_PCI_MEM_START,
264 PRPMC800_NM_PCI_MEM_END,
265 IORESOURCE_MEM, "PCI host bridge");
266
267 hose->mem_space.start = PRPMC800_NM_PCI_MEM_START;
268 hose->mem_space.end = PRPMC800_NM_PCI_MEM_END;
269
270 if (harrier_init(hose,
271 PRPMC800_HARRIER_XCSR_BASE,
272 PRPMC800_NM_PROC_PCI_MEM_START,
273 PRPMC800_NM_PROC_PCI_MEM_END,
274 PRPMC800_PROC_PCI_IO_START,
275 PRPMC800_PROC_PCI_IO_END,
276 PRPMC800_HARRIER_MPIC_BASE) != 0)
277 printk(KERN_CRIT "Could not initialize HARRIER "
278 "bridge\n");
279
280 harrier_setup_nonmonarch(PRPMC800_HARRIER_XCSR_BASE,
281 HARRIER_ITSZ_1MB);
282 harrier_release_eready(PRPMC800_HARRIER_XCSR_BASE);
283 }
284}
285
286static int prpmc800_show_cpuinfo(struct seq_file *m)
287{
288 seq_printf(m, "machine\t\t: PrPMC800\n");
289
290 return 0;
291}
292
293static void __init prpmc800_setup_arch(void)
294{
295 /* init to some ~sane value until calibrate_delay() runs */
296 loops_per_jiffy = 50000000 / HZ;
297
298 /* Lookup PCI host bridges */
299 prpmc800_find_bridges();
300
301#ifdef CONFIG_BLK_DEV_INITRD
302 if (initrd_start)
303 ROOT_DEV = Root_RAM0;
304 else
305#endif
306#ifdef CONFIG_ROOT_NFS
307 ROOT_DEV = Root_NFS;
308#else
309 ROOT_DEV = Root_SDA2;
310#endif
311
312 printk(KERN_INFO "Port by MontaVista Software, Inc. "
313 "(source@mvista.com)\n");
314}
315
316/*
317 * Compute the PrPMC800's tbl frequency using the baud clock as a reference.
318 */
319static void __init prpmc800_calibrate_decr(void)
320{
321 unsigned long tbl_start, tbl_end;
322 unsigned long current_state, old_state, tb_ticks_per_second;
323 unsigned int count;
324 unsigned int harrier_revision;
325
326 harrier_revision = readb(HARRIER_REVI_REG);
327 if (harrier_revision < 2) {
328 /* XTAL64 was broken in harrier revision 1 */
329 printk(KERN_INFO "time_init: Harrier revision %d, assuming "
330 "100 Mhz bus\n", harrier_revision);
331 tb_ticks_per_second = 100000000 / 4;
332 tb_ticks_per_jiffy = tb_ticks_per_second / HZ;
333 tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000);
334 return;
335 }
336
337 /*
338 * The XTAL64 bit oscillates at the 1/64 the base baud clock
339 * Set count to XTAL64 cycles per second. Since we'll count
340 * half-cycles, we'll reach the count in half a second.
341 */
342 count = PRPMC800_BASE_BAUD / 64;
343
344 /* Find the first edge of the baud clock */
345 old_state = readb(HARRIER_UCTL_REG) & HARRIER_XTAL64_MASK;
346 do {
347 current_state = readb(HARRIER_UCTL_REG) & HARRIER_XTAL64_MASK;
348 } while (old_state == current_state);
349
350 old_state = current_state;
351
352 /* Get the starting time base value */
353 tbl_start = get_tbl();
354
355 /*
356 * Loop until we have found a number of edges (half-cycles)
357 * equal to the count (half a second)
358 */
359 do {
360 do {
361 current_state = readb(HARRIER_UCTL_REG) &
362 HARRIER_XTAL64_MASK;
363 } while (old_state == current_state);
364 old_state = current_state;
365 } while (--count);
366
367 /* Get the ending time base value */
368 tbl_end = get_tbl();
369
370 /* We only counted for half a second, so double to get ticks/second */
371 tb_ticks_per_second = (tbl_end - tbl_start) * 2;
372 tb_ticks_per_jiffy = tb_ticks_per_second / HZ;
373 tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000);
374}
375
376static void prpmc800_restart(char *cmd)
377{
378 ulong temp;
379
380 local_irq_disable();
381 temp = in_be32((uint *) HARRIER_MISC_CSR_REG);
382 temp |= HARRIER_RSTOUT;
383 out_be32((uint *) HARRIER_MISC_CSR_REG, temp);
384 while (1) ;
385}
386
387static void prpmc800_halt(void)
388{
389 local_irq_disable();
390 while (1) ;
391}
392
393static void prpmc800_power_off(void)
394{
395 prpmc800_halt();
396}
397
398static void __init prpmc800_init_IRQ(void)
399{
400 OpenPIC_InitSenses = prpmc800_openpic_initsenses;
401 OpenPIC_NumInitSenses = sizeof(prpmc800_openpic_initsenses);
402
403 /* Setup external interrupt sources. */
404 openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
405 /* Setup internal UART interrupt source. */
406 openpic_set_sources(16, 1, OpenPIC_Addr + 0x10200);
407
408 /* Do the MPIC initialization based on the above settings. */
409 openpic_init(0);
410
411 /* enable functional exceptions for uarts and abort */
412 out_8((u8 *) HARRIER_FEEN_REG, (HARRIER_FE_UA0 | HARRIER_FE_UA1));
413 out_8((u8 *) HARRIER_FEMA_REG, ~(HARRIER_FE_UA0 | HARRIER_FE_UA1));
414}
415
416/*
417 * Set BAT 3 to map 0xf0000000 to end of physical memory space.
418 */
419static __inline__ void prpmc800_set_bat(void)
420{
421 mb();
422 mtspr(SPRN_DBAT1U, 0xf0001ffe);
423 mtspr(SPRN_DBAT1L, 0xf000002a);
424 mb();
425}
426
427/*
428 * We need to read the Harrier memory controller
429 * to properly determine this value
430 */
431static unsigned long __init prpmc800_find_end_of_memory(void)
432{
433 /* Read the memory size from the Harrier XCSR */
434 return harrier_get_mem_size(PRPMC800_HARRIER_XCSR_BASE);
435}
436
437static void __init prpmc800_map_io(void)
438{
439 io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
440 io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO);
441}
442
443void __init
444platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
445 unsigned long r6, unsigned long r7)
446{
447 parse_bootinfo(find_bootinfo());
448
449 prpmc800_set_bat();
450
451 isa_io_base = PRPMC800_ISA_IO_BASE;
452 isa_mem_base = PRPMC800_ISA_MEM_BASE;
453 pci_dram_offset = PRPMC800_PCI_DRAM_OFFSET;
454
455 ppc_md.setup_arch = prpmc800_setup_arch;
456 ppc_md.show_cpuinfo = prpmc800_show_cpuinfo;
457 ppc_md.init_IRQ = prpmc800_init_IRQ;
458 ppc_md.get_irq = openpic_get_irq;
459
460 ppc_md.find_end_of_memory = prpmc800_find_end_of_memory;
461 ppc_md.setup_io_mappings = prpmc800_map_io;
462
463 ppc_md.restart = prpmc800_restart;
464 ppc_md.power_off = prpmc800_power_off;
465 ppc_md.halt = prpmc800_halt;
466
467 /* PrPMC800 has no timekeeper part */
468 ppc_md.time_init = NULL;
469 ppc_md.get_rtc_time = NULL;
470 ppc_md.set_rtc_time = NULL;
471 ppc_md.calibrate_decr = prpmc800_calibrate_decr;
472#ifdef CONFIG_SERIAL_TEXT_DEBUG
473 ppc_md.progress = gen550_progress;
474#else /* !CONFIG_SERIAL_TEXT_DEBUG */
475 ppc_md.progress = NULL;
476#endif /* CONFIG_SERIAL_TEXT_DEBUG */
477}
diff --git a/arch/ppc/platforms/prpmc800.h b/arch/ppc/platforms/prpmc800.h
new file mode 100644
index 000000000000..e53ec9b42a35
--- /dev/null
+++ b/arch/ppc/platforms/prpmc800.h
@@ -0,0 +1,82 @@
1/*
2 * include/asm-ppc/platforms/prpmc800.h
3 *
4 * Definitions for Motorola PrPMC800 board support
5 *
6 * Author: Dale Farnsworth <dale.farnsworth@mvista.com>
7 *
8 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13 /*
14 * From Processor to PCI:
15 * PCI Mem Space: 0x80000000 - 0xa0000000 -> 0x80000000 - 0xa0000000 (512 MB)
16 * PCI I/O Space: 0xfe400000 - 0xfeef0000 -> 0x00000000 - 0x00b00000 (11 MB)
17 * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area
18 *
19 * From PCI to Processor:
20 * System Memory: 0x00000000 -> 0x00000000
21 */
22
23#ifndef __ASMPPC_PRPMC800_H
24#define __ASMPPC_PRPMC800_H
25
26#define PRPMC800_PCI_CONFIG_ADDR 0xfe000cf8
27#define PRPMC800_PCI_CONFIG_DATA 0xfe000cfc
28
29#define PRPMC800_PROC_PCI_IO_START 0xfe400000U
30#define PRPMC800_PROC_PCI_IO_END 0xfeefffffU
31#define PRPMC800_PCI_IO_START 0x00000000U
32#define PRPMC800_PCI_IO_END 0x00afffffU
33
34#define PRPMC800_PROC_PCI_MEM_START 0x80000000U
35#define PRPMC800_PROC_PCI_MEM_END 0x9fffffffU
36#define PRPMC800_PCI_MEM_START 0x80000000U
37#define PRPMC800_PCI_MEM_END 0x9fffffffU
38
39#define PRPMC800_NM_PROC_PCI_MEM_START 0x40000000U
40#define PRPMC800_NM_PROC_PCI_MEM_END 0xdfffffffU
41#define PRPMC800_NM_PCI_MEM_START 0x40000000U
42#define PRPMC800_NM_PCI_MEM_END 0xdfffffffU
43
44#define PRPMC800_PCI_DRAM_OFFSET 0x00000000U
45#define PRPMC800_PCI_PHY_MEM_OFFSET 0x00000000U
46
47#define PRPMC800_ISA_IO_BASE PRPMC800_PROC_PCI_IO_START
48#define PRPMC800_ISA_MEM_BASE 0x00000000U
49
50#define PRPMC800_HARRIER_XCSR_BASE HARRIER_DEFAULT_XCSR_BASE
51#define PRPMC800_HARRIER_MPIC_BASE 0xff000000
52
53#define PRPMC800_SERIAL_1 0xfeff00c0
54
55#define PRPMC800_BASE_BAUD 1843200
56
57/*
58 * interrupt vector number and priority for harrier internal interrupt
59 * sources
60 */
61#define PRPMC800_INT_IRQ 16
62#define PRPMC800_INT_PRI 15
63
64/* UART Defines. */
65#define RS_TABLE_SIZE 4
66
67/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
68#define BASE_BAUD (PRPMC800_BASE_BAUD / 16)
69
70#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
71
72/* UARTS are at IRQ 16 */
73#define STD_SERIAL_PORT_DFNS \
74 { 0, BASE_BAUD, PRPMC800_SERIAL_1, 16, STD_COM_FLAGS, /* ttyS0 */\
75 iomem_base: (unsigned char *)PRPMC800_SERIAL_1, \
76 iomem_reg_shift: 0, \
77 io_type: SERIAL_IO_MEM },
78
79#define SERIAL_PORT_DFNS \
80 STD_SERIAL_PORT_DFNS
81
82#endif /* __ASMPPC_PRPMC800_H */
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
new file mode 100644
index 000000000000..2a99b43737a8
--- /dev/null
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -0,0 +1,1452 @@
1/*
2 * arch/ppc/platforms/radstone_ppc7d.c
3 *
4 * Board setup routines for the Radstone PPC7D boards.
5 *
6 * Author: James Chapman <jchapman@katalix.com>
7 *
8 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
9 * Based on code done by - Mark A. Greer <mgreer@mvista.com>
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
17/* Radstone PPC7D boards are rugged VME boards with PPC 7447A CPUs,
18 * Discovery-II, dual gigabit ethernet, dual PMC, USB, keyboard/mouse,
19 * 4 serial ports, 2 high speed serial ports (MPSCs) and optional
20 * SCSI / VGA.
21 */
22
23#include <linux/config.h>
24#include <linux/stddef.h>
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/errno.h>
28#include <linux/reboot.h>
29#include <linux/pci.h>
30#include <linux/kdev_t.h>
31#include <linux/major.h>
32#include <linux/initrd.h>
33#include <linux/console.h>
34#include <linux/delay.h>
35#include <linux/irq.h>
36#include <linux/ide.h>
37#include <linux/seq_file.h>
38#include <linux/root_dev.h>
39#include <linux/serial.h>
40#include <linux/tty.h> /* for linux/serial_core.h */
41#include <linux/serial_core.h>
42#include <linux/mv643xx.h>
43#include <linux/netdevice.h>
44
45#include <asm/system.h>
46#include <asm/pgtable.h>
47#include <asm/page.h>
48#include <asm/time.h>
49#include <asm/dma.h>
50#include <asm/io.h>
51#include <asm/machdep.h>
52#include <asm/prom.h>
53#include <asm/smp.h>
54#include <asm/vga.h>
55#include <asm/open_pic.h>
56#include <asm/i8259.h>
57#include <asm/todc.h>
58#include <asm/bootinfo.h>
59#include <asm/mpc10x.h>
60#include <asm/pci-bridge.h>
61#include <asm/mv64x60.h>
62#include <asm/i8259.h>
63
64#include "radstone_ppc7d.h"
65
66#undef DEBUG
67
68#define PPC7D_RST_PIN 17 /* GPP17 */
69
70extern u32 mv64360_irq_base;
71
72static struct mv64x60_handle bh;
73static int ppc7d_has_alma;
74
75extern void gen550_progress(char *, unsigned short);
76extern void gen550_init(int, struct uart_port *);
77
78/* residual data */
79unsigned char __res[sizeof(bd_t)];
80
81/*****************************************************************************
82 * Serial port code
83 *****************************************************************************/
84
85#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)
86static void __init ppc7d_early_serial_map(void)
87{
88#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
89 mv64x60_progress_init(CONFIG_MV64X60_NEW_BASE);
90#elif defined(CONFIG_SERIAL_8250)
91 struct uart_port serial_req;
92
93 /* Setup serial port access */
94 memset(&serial_req, 0, sizeof(serial_req));
95 serial_req.uartclk = UART_CLK;
96 serial_req.irq = 4;
97 serial_req.flags = STD_COM_FLAGS;
98 serial_req.iotype = SERIAL_IO_MEM;
99 serial_req.membase = (u_char *) PPC7D_SERIAL_0;
100
101 gen550_init(0, &serial_req);
102 if (early_serial_setup(&serial_req) != 0)
103 printk(KERN_ERR "Early serial init of port 0 failed\n");
104
105 /* Assume early_serial_setup() doesn't modify serial_req */
106 serial_req.line = 1;
107 serial_req.irq = 3;
108 serial_req.membase = (u_char *) PPC7D_SERIAL_1;
109
110 gen550_init(1, &serial_req);
111 if (early_serial_setup(&serial_req) != 0)
112 printk(KERN_ERR "Early serial init of port 1 failed\n");
113#else
114#error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX
115#endif
116}
117#endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */
118
119/*****************************************************************************
120 * Low-level board support code
121 *****************************************************************************/
122
123static unsigned long __init ppc7d_find_end_of_memory(void)
124{
125 bd_t *bp = (bd_t *) __res;
126
127 if (bp->bi_memsize)
128 return bp->bi_memsize;
129
130 return (256 * 1024 * 1024);
131}
132
133static void __init ppc7d_map_io(void)
134{
135 /* remove temporary mapping */
136 mtspr(SPRN_DBAT3U, 0x00000000);
137 mtspr(SPRN_DBAT3L, 0x00000000);
138
139 io_block_mapping(0xe8000000, 0xe8000000, 0x08000000, _PAGE_IO);
140 io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
141}
142
143static void ppc7d_restart(char *cmd)
144{
145 u32 data;
146
147 /* Disable GPP17 interrupt */
148 data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
149 data &= ~(1 << PPC7D_RST_PIN);
150 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data);
151
152 /* Configure MPP17 as GPP */
153 data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2);
154 data &= ~(0x0000000f << 4);
155 mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data);
156
157 /* Enable pin GPP17 for output */
158 data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL);
159 data |= (1 << PPC7D_RST_PIN);
160 mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data);
161
162 /* Toggle GPP9 pin to reset the board */
163 mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, 1 << PPC7D_RST_PIN);
164 mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, 1 << PPC7D_RST_PIN);
165
166 for (;;) ; /* Spin until reset happens */
167 /* NOTREACHED */
168}
169
170static void ppc7d_power_off(void)
171{
172 u32 data;
173
174 local_irq_disable();
175
176 /* Ensure that internal MV643XX watchdog is disabled.
177 * The Disco watchdog uses MPP17 on this hardware.
178 */
179 data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2);
180 data &= ~(0x0000000f << 4);
181 mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data);
182
183 data = mv64x60_read(&bh, MV64x60_WDT_WDC);
184 if (data & 0x80000000) {
185 mv64x60_write(&bh, MV64x60_WDT_WDC, 1 << 24);
186 mv64x60_write(&bh, MV64x60_WDT_WDC, 2 << 24);
187 }
188
189 for (;;) ; /* No way to shut power off with software */
190 /* NOTREACHED */
191}
192
193static void ppc7d_halt(void)
194{
195 ppc7d_power_off();
196 /* NOTREACHED */
197}
198
199static unsigned long ppc7d_led_no_pulse;
200
201static int __init ppc7d_led_pulse_disable(char *str)
202{
203 ppc7d_led_no_pulse = 1;
204 return 1;
205}
206
207/* This kernel option disables the heartbeat pulsing of a board LED */
208__setup("ledoff", ppc7d_led_pulse_disable);
209
210static void ppc7d_heartbeat(void)
211{
212 u32 data32;
213 u8 data8;
214 static int max706_wdog = 0;
215
216 /* Unfortunately we can't access the LED control registers
217 * during early init because they're on the CPLD which is the
218 * other side of a PCI bridge which goes unreachable during
219 * PCI scan. So write the LEDs only if the MV64360 watchdog is
220 * enabled (i.e. userspace apps are running so kernel is up)..
221 */
222 data32 = mv64x60_read(&bh, MV64x60_WDT_WDC);
223 if (data32 & 0x80000000) {
224 /* Enable MAX706 watchdog if not done already */
225 if (!max706_wdog) {
226 outb(3, PPC7D_CPLD_RESET);
227 max706_wdog = 1;
228 }
229
230 /* Hit the MAX706 watchdog */
231 outb(0, PPC7D_CPLD_WATCHDOG_TRIG);
232
233 /* Pulse LED DS219 if not disabled */
234 if (!ppc7d_led_no_pulse) {
235 static int led_on = 0;
236
237 data8 = inb(PPC7D_CPLD_LEDS);
238 if (led_on)
239 data8 &= ~PPC7D_CPLD_LEDS_DS219_MASK;
240 else
241 data8 |= PPC7D_CPLD_LEDS_DS219_MASK;
242
243 outb(data8, PPC7D_CPLD_LEDS);
244 led_on = !led_on;
245 }
246 }
247 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
248}
249
250static int ppc7d_show_cpuinfo(struct seq_file *m)
251{
252 u8 val;
253 u8 val1, val2;
254 static int flash_sizes[4] = { 64, 32, 0, 16 };
255 static int flash_banks[4] = { 4, 3, 2, 1 };
256 static char *pci_modes[] = { "PCI33", "PCI66",
257 "Unknown", "Unknown",
258 "PCIX33", "PCIX66",
259 "PCIX100", "PCIX133"
260 };
261
262 seq_printf(m, "vendor\t\t: Radstone Technology\n");
263 seq_printf(m, "machine\t\t: PPC7D\n");
264
265 val = inb(PPC7D_CPLD_BOARD_REVISION);
266 val1 = (val & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5;
267 val2 = (val & PPC7D_CPLD_BOARD_REVISION_LETTER_MASK);
268 seq_printf(m, "revision\t: %hd%c%c\n",
269 val1,
270 (val2 <= 0x18) ? 'A' + val2 : 'Y',
271 (val2 > 0x18) ? 'A' + (val2 - 0x19) : ' ');
272
273 val = inb(PPC7D_CPLD_MOTHERBOARD_TYPE);
274 val1 = val & PPC7D_CPLD_MB_TYPE_PLL_MASK;
275 val2 = val & (PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK |
276 PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK);
277 seq_printf(m, "bus speed\t: %dMHz\n",
278 (val1 == PPC7D_CPLD_MB_TYPE_PLL_133) ? 133 :
279 (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 :
280 (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0);
281
282 val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND);
283 val1 = val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK;
284 seq_printf(m, "SDRAM\t\t: %d%c",
285 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_128M) ? 128 :
286 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_256M) ? 256 :
287 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_512M) ? 512 : 1,
288 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_1G) ? 'G' : 'M');
289 if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) {
290 seq_printf(m, " [ECC %sabled]",
291 (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" :
292 "dis");
293 }
294 seq_printf(m, "\n");
295
296 val1 = (val & PPC7D_CPLD_FLASH_DEV_SIZE_MASK);
297 val2 = (val & PPC7D_CPLD_FLASH_BANK_NUM_MASK) >> 2;
298 seq_printf(m, "FLASH\t\t: %d banks of %dM, total %dM\n",
299 flash_banks[val2], flash_sizes[val1],
300 flash_banks[val2] * flash_sizes[val1]);
301
302 val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL);
303 val1 = inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT);
304 seq_printf(m, " write links\t: %s%s%s%s\n",
305 (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "WRITE " : "",
306 (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "BOOT " : "",
307 (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "USER " : "",
308 (val & (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK |
309 PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK |
310 PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK)) ==
311 0 ? "NONE" : "");
312 seq_printf(m, " write sector h/w enables: %s%s%s%s%s\n",
313 (val & PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK) ? "RECOVERY " :
314 "",
315 (val & PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK) ? "BOOT " : "",
316 (val & PPD7D_CPLD_FLASH_CNTL_USER_WR_MASK) ? "USER " : "",
317 (val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) ? "NVRAM " :
318 "",
319 (((val &
320 (PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK |
321 PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK |
322 PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK)) == 0)
323 && ((val1 & PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK) ==
324 0)) ? "NONE" : "");
325 val1 =
326 inb(PPC7D_CPLD_SW_FLASH_WRITE_PROTECT) &
327 (PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK |
328 PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK);
329 seq_printf(m, " software sector enables: %s%s%s\n",
330 (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK) ? "SYSBOOT "
331 : "",
332 (val1 & PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK) ? "USER " : "",
333 (val1 == 0) ? "NONE " : "");
334
335 seq_printf(m, "Boot options\t: %s%s%s%s\n",
336 (val & PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK) ?
337 "ALTERNATE " : "",
338 (val & PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK) ? "VME " :
339 "",
340 (val & PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK) ? "RECOVERY "
341 : "",
342 ((val &
343 (PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK |
344 PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK |
345 PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK)) ==
346 0) ? "NONE" : "");
347
348 val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_1);
349 seq_printf(m, "Fitted modules\t: %s%s%s%s\n",
350 (val & PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK) ? "" : "PMC1 ",
351 (val & PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK) ? "" : "PMC2 ",
352 (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) ? "AFIX " : "",
353 ((val & (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK |
354 PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK |
355 PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK)) ==
356 (PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK |
357 PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK)) ? "NONE" : "");
358
359 if (val & PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK) {
360 static const char *ids[] = {
361 "unknown",
362 "1553 (Dual Channel)",
363 "1553 (Single Channel)",
364 "8-bit SCSI + VGA",
365 "16-bit SCSI + VGA",
366 "1553 (Single Channel with sideband)",
367 "1553 (Dual Channel with sideband)",
368 NULL
369 };
370 u8 id = __raw_readb((void *)PPC7D_AFIX_REG_BASE + 0x03);
371 seq_printf(m, "AFIX module\t: 0x%hx [%s]\n", id,
372 id < 7 ? ids[id] : "unknown");
373 }
374
375 val = inb(PPC7D_CPLD_PCI_CONFIG);
376 val1 = (val & PPC7D_CPLD_PCI_CONFIG_PCI0_MASK) >> 4;
377 val2 = (val & PPC7D_CPLD_PCI_CONFIG_PCI1_MASK);
378 seq_printf(m, "PCI#0\t\t: %s\nPCI#1\t\t: %s\n",
379 pci_modes[val1], pci_modes[val2]);
380
381 val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2);
382 seq_printf(m, "PMC1\t\t: %s\nPMC2\t\t: %s\n",
383 (val & PPC7D_CPLD_EQPT_PRES_3_PMC1_V_MASK) ? "3.3v" : "5v",
384 (val & PPC7D_CPLD_EQPT_PRES_3_PMC2_V_MASK) ? "3.3v" : "5v");
385 seq_printf(m, "PMC power source: %s\n",
386 (val & PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_MASK) ? "VME" :
387 "internal");
388
389 val = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_4);
390 val2 = inb(PPC7D_CPLD_EQUIPMENT_PRESENT_2);
391 seq_printf(m, "Fit options\t: %s%s%s%s%s%s%s\n",
392 (val & PPC7D_CPLD_EQPT_PRES_4_LPT_MASK) ? "LPT " : "",
393 (val & PPC7D_CPLD_EQPT_PRES_4_PS2_FITTED) ? "PS2 " : "",
394 (val & PPC7D_CPLD_EQPT_PRES_4_USB2_FITTED) ? "USB2 " : "",
395 (val2 & PPC7D_CPLD_EQPT_PRES_2_UNIVERSE_MASK) ? "VME " : "",
396 (val2 & PPC7D_CPLD_EQPT_PRES_2_COM36_MASK) ? "COM3-6 " : "",
397 (val2 & PPC7D_CPLD_EQPT_PRES_2_GIGE_MASK) ? "eth0 " : "",
398 (val2 & PPC7D_CPLD_EQPT_PRES_2_DUALGIGE_MASK) ? "eth1 " :
399 "");
400
401 val = inb(PPC7D_CPLD_ID_LINK);
402 val1 = val & (PPC7D_CPLD_ID_LINK_E6_MASK |
403 PPC7D_CPLD_ID_LINK_E7_MASK |
404 PPC7D_CPLD_ID_LINK_E12_MASK |
405 PPC7D_CPLD_ID_LINK_E13_MASK);
406
407 val = inb(PPC7D_CPLD_FLASH_WRITE_CNTL) &
408 (PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK |
409 PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK |
410 PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK);
411
412 seq_printf(m, "Board links present: %s%s%s%s%s%s%s%s\n",
413 (val1 & PPC7D_CPLD_ID_LINK_E6_MASK) ? "E6 " : "",
414 (val1 & PPC7D_CPLD_ID_LINK_E7_MASK) ? "E7 " : "",
415 (val & PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK) ? "E9 " : "",
416 (val & PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK) ? "E10 " : "",
417 (val & PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK) ? "E11 " : "",
418 (val1 & PPC7D_CPLD_ID_LINK_E12_MASK) ? "E12 " : "",
419 (val1 & PPC7D_CPLD_ID_LINK_E13_MASK) ? "E13 " : "",
420 ((val == 0) && (val1 == 0)) ? "NONE" : "");
421
422 val = inb(PPC7D_CPLD_WDOG_RESETSW_MASK);
423 seq_printf(m, "Front panel reset switch: %sabled\n",
424 (val & PPC7D_CPLD_WDOG_RESETSW_MASK) ? "dis" : "en");
425
426 return 0;
427}
428
429static void __init ppc7d_calibrate_decr(void)
430{
431 ulong freq;
432
433 freq = 100000000 / 4;
434
435 pr_debug("time_init: decrementer frequency = %lu.%.6lu MHz\n",
436 freq / 1000000, freq % 1000000);
437
438 tb_ticks_per_jiffy = freq / HZ;
439 tb_to_us = mulhwu_scale_factor(freq, 1000000);
440}
441
442/*****************************************************************************
443 * Interrupt stuff
444 *****************************************************************************/
445
446static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id, struct pt_regs *regs)
447{
448 u32 temp = mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
449 if (temp & (1 << 28)) {
450 i8259_irq(regs);
451 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, temp & (~(1 << 28)));
452 return IRQ_HANDLED;
453 }
454
455 return IRQ_NONE;
456}
457
458/*
459 * Each interrupt cause is assigned an IRQ number.
460 * Southbridge has 16*2 (two 8259's) interrupts.
461 * Discovery-II has 96 interrupts (cause-hi, cause-lo, gpp x 32).
462 * If multiple interrupts are pending, get_irq() returns the
463 * lowest pending irq number first.
464 *
465 *
466 * IRQ # Source Trig Active
467 * =============================================================
468 *
469 * Southbridge
470 * -----------
471 * IRQ # Source Trig
472 * =============================================================
473 * 0 ISA High Resolution Counter Edge
474 * 1 Keyboard Edge
475 * 2 Cascade From (IRQ 8-15) Edge
476 * 3 Com 2 (Uart 2) Edge
477 * 4 Com 1 (Uart 1) Edge
478 * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level
479 * 6 GPIO Level
480 * 7 LPT Edge
481 * 8 RTC Alarm Edge
482 * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level
483 * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level
484 * 11 USB2 Level
485 * 12 Mouse Edge
486 * 13 Reserved internally by Ali M1535+
487 * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level
488 * 15 COM 5/6 Level
489 *
490 * 16..112 Discovery-II...
491 *
492 * MPP28 Southbridge Edge High
493 *
494 *
495 * Interrupts are cascaded through to the Discovery-II.
496 *
497 * PCI ---
498 * \
499 * CPLD --> ALI1535 -------> DISCOVERY-II
500 * INTF MPP28
501 */
502static void __init ppc7d_init_irq(void)
503{
504 int irq;
505
506 pr_debug("%s\n", __FUNCTION__);
507 i8259_init(0);
508 mv64360_init_irq();
509
510 /* IRQ 0..15 are handled by the cascaded 8259's of the Ali1535 */
511 for (irq = 0; irq < 16; irq++) {
512 irq_desc[irq].handler = &i8259_pic;
513 }
514 /* IRQs 5,6,9,10,11,14,15 are level sensitive */
515 irq_desc[5].status |= IRQ_LEVEL;
516 irq_desc[6].status |= IRQ_LEVEL;
517 irq_desc[9].status |= IRQ_LEVEL;
518 irq_desc[10].status |= IRQ_LEVEL;
519 irq_desc[11].status |= IRQ_LEVEL;
520 irq_desc[14].status |= IRQ_LEVEL;
521 irq_desc[15].status |= IRQ_LEVEL;
522
523 /* GPP28 is edge triggered */
524 irq_desc[mv64360_irq_base + MV64x60_IRQ_GPP28].status &= ~IRQ_LEVEL;
525}
526
527static u32 ppc7d_irq_canonicalize(u32 irq)
528{
529 if ((irq >= 16) && (irq < (16 + 96)))
530 irq -= 16;
531
532 return irq;
533}
534
535static int ppc7d_get_irq(struct pt_regs *regs)
536{
537 int irq;
538
539 irq = mv64360_get_irq(regs);
540 if (irq == (mv64360_irq_base + MV64x60_IRQ_GPP28))
541 irq = i8259_irq(regs);
542 return irq;
543}
544
545/*
546 * 9 PCI Int A/PMC 2/AFIX IRQW ID1 (2,0) Level
547 * 10 PCI Int B/PMC 1/AFIX IRQX ID2 (2,1) Level
548 * 14 PCI Int C/VME/AFIX IRQY ID3 (2,6) Level
549 * 5 PCI Int D/AFIX IRQZ ID4 (2,7) Level
550 */
551static int __init ppc7d_map_irq(struct pci_dev *dev, unsigned char idsel,
552 unsigned char pin)
553{
554 static const char pci_irq_table[][4] =
555 /*
556 * PCI IDSEL/INTPIN->INTLINE
557 * A B C D
558 */
559 {
560 {10, 14, 5, 9}, /* IDSEL 10 - PMC2 / AFIX IRQW */
561 {9, 10, 14, 5}, /* IDSEL 11 - PMC1 / AFIX IRQX */
562 {5, 9, 10, 14}, /* IDSEL 12 - AFIX IRQY */
563 {14, 5, 9, 10}, /* IDSEL 13 - AFIX IRQZ */
564 };
565 const long min_idsel = 10, max_idsel = 14, irqs_per_slot = 4;
566
567 pr_debug("%s: %04x/%04x/%x: idsel=%hx pin=%hu\n", __FUNCTION__,
568 dev->vendor, dev->device, PCI_FUNC(dev->devfn), idsel, pin);
569
570 return PCI_IRQ_TABLE_LOOKUP;
571}
572
573void __init ppc7d_intr_setup(void)
574{
575 u32 data;
576
577 /*
578 * Define GPP 28 interrupt polarity as active high
579 * input signal and level triggered
580 */
581 data = mv64x60_read(&bh, MV64x60_GPP_LEVEL_CNTL);
582 data &= ~(1 << 28);
583 mv64x60_write(&bh, MV64x60_GPP_LEVEL_CNTL, data);
584 data = mv64x60_read(&bh, MV64x60_GPP_IO_CNTL);
585 data &= ~(1 << 28);
586 mv64x60_write(&bh, MV64x60_GPP_IO_CNTL, data);
587
588 /* Config GPP intr ctlr to respond to level trigger */
589 data = mv64x60_read(&bh, MV64x60_COMM_ARBITER_CNTL);
590 data |= (1 << 10);
591 mv64x60_write(&bh, MV64x60_COMM_ARBITER_CNTL, data);
592
593 /* XXXX Erranum FEr PCI-#8 */
594 data = mv64x60_read(&bh, MV64x60_PCI0_CMD);
595 data &= ~((1 << 5) | (1 << 9));
596 mv64x60_write(&bh, MV64x60_PCI0_CMD, data);
597 data = mv64x60_read(&bh, MV64x60_PCI1_CMD);
598 data &= ~((1 << 5) | (1 << 9));
599 mv64x60_write(&bh, MV64x60_PCI1_CMD, data);
600
601 /*
602 * Dismiss and then enable interrupt on GPP interrupt cause
603 * for CPU #0
604 */
605 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, ~(1 << 28));
606 data = mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
607 data |= (1 << 28);
608 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, data);
609
610 /*
611 * Dismiss and then enable interrupt on CPU #0 high cause reg
612 * BIT27 summarizes GPP interrupts 23-31
613 */
614 mv64x60_write(&bh, MV64360_IC_MAIN_CAUSE_HI, ~(1 << 27));
615 data = mv64x60_read(&bh, MV64360_IC_CPU0_INTR_MASK_HI);
616 data |= (1 << 27);
617 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI, data);
618}
619
620/*****************************************************************************
621 * Platform device data fixup routines.
622 *****************************************************************************/
623
624#if defined(CONFIG_SERIAL_MPSC)
625static void __init ppc7d_fixup_mpsc_pdata(struct platform_device *pdev)
626{
627 struct mpsc_pdata *pdata;
628
629 pdata = (struct mpsc_pdata *)pdev->dev.platform_data;
630
631 pdata->max_idle = 40;
632 pdata->default_baud = PPC7D_DEFAULT_BAUD;
633 pdata->brg_clk_src = PPC7D_MPSC_CLK_SRC;
634 pdata->brg_clk_freq = PPC7D_MPSC_CLK_FREQ;
635
636 return;
637}
638#endif
639
640#if defined(CONFIG_MV643XX_ETH)
641static void __init ppc7d_fixup_eth_pdata(struct platform_device *pdev)
642{
643 struct mv643xx_eth_platform_data *eth_pd;
644 static u16 phy_addr[] = {
645 PPC7D_ETH0_PHY_ADDR,
646 PPC7D_ETH1_PHY_ADDR,
647 PPC7D_ETH2_PHY_ADDR,
648 };
649 int i;
650
651 eth_pd = pdev->dev.platform_data;
652 eth_pd->force_phy_addr = 1;
653 eth_pd->phy_addr = phy_addr[pdev->id];
654 eth_pd->tx_queue_size = PPC7D_ETH_TX_QUEUE_SIZE;
655 eth_pd->rx_queue_size = PPC7D_ETH_RX_QUEUE_SIZE;
656
657 /* Adjust IRQ by mv64360_irq_base */
658 for (i = 0; i < pdev->num_resources; i++) {
659 struct resource *r = &pdev->resource[i];
660
661 if (r->flags & IORESOURCE_IRQ) {
662 r->start += mv64360_irq_base;
663 r->end += mv64360_irq_base;
664 pr_debug("%s, uses IRQ %d\n", pdev->name,
665 (int)r->start);
666 }
667 }
668
669}
670#endif
671
672#if defined(CONFIG_I2C_MV64XXX)
673static void __init
674ppc7d_fixup_i2c_pdata(struct platform_device *pdev)
675{
676 struct mv64xxx_i2c_pdata *pdata;
677 int i;
678
679 pdata = pdev->dev.platform_data;
680 if (pdata == NULL) {
681 pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
682 if (pdata == NULL)
683 return;
684
685 memset(pdata, 0, sizeof(*pdata));
686 pdev->dev.platform_data = pdata;
687 }
688
689 /* divisors M=8, N=3 for 100kHz I2C from 133MHz system clock */
690 pdata->freq_m = 8;
691 pdata->freq_n = 3;
692 pdata->timeout = 500;
693 pdata->retries = 3;
694
695 /* Adjust IRQ by mv64360_irq_base */
696 for (i = 0; i < pdev->num_resources; i++) {
697 struct resource *r = &pdev->resource[i];
698
699 if (r->flags & IORESOURCE_IRQ) {
700 r->start += mv64360_irq_base;
701 r->end += mv64360_irq_base;
702 pr_debug("%s, uses IRQ %d\n", pdev->name, (int) r->start);
703 }
704 }
705}
706#endif
707
708static int __init ppc7d_platform_notify(struct device *dev)
709{
710 static struct {
711 char *bus_id;
712 void ((*rtn) (struct platform_device * pdev));
713 } dev_map[] = {
714#if defined(CONFIG_SERIAL_MPSC)
715 { MPSC_CTLR_NAME ".0", ppc7d_fixup_mpsc_pdata },
716 { MPSC_CTLR_NAME ".1", ppc7d_fixup_mpsc_pdata },
717#endif
718#if defined(CONFIG_MV643XX_ETH)
719 { MV643XX_ETH_NAME ".0", ppc7d_fixup_eth_pdata },
720 { MV643XX_ETH_NAME ".1", ppc7d_fixup_eth_pdata },
721 { MV643XX_ETH_NAME ".2", ppc7d_fixup_eth_pdata },
722#endif
723#if defined(CONFIG_I2C_MV64XXX)
724 { MV64XXX_I2C_CTLR_NAME ".0", ppc7d_fixup_i2c_pdata },
725#endif
726 };
727 struct platform_device *pdev;
728 int i;
729
730 if (dev && dev->bus_id)
731 for (i = 0; i < ARRAY_SIZE(dev_map); i++)
732 if (!strncmp(dev->bus_id, dev_map[i].bus_id,
733 BUS_ID_SIZE)) {
734
735 pdev = container_of(dev,
736 struct platform_device,
737 dev);
738 dev_map[i].rtn(pdev);
739 }
740
741 return 0;
742}
743
744/*****************************************************************************
745 * PCI device fixups.
746 * These aren't really fixups per se. They are used to init devices as they
747 * are found during PCI scan.
748 *
749 * The PPC7D has an HB8 PCI-X bridge which must be set up during a PCI
750 * scan in order to find other devices on its secondary side.
751 *****************************************************************************/
752
753static void __init ppc7d_fixup_hb8(struct pci_dev *dev)
754{
755 u16 val16;
756
757 if (dev->bus->number == 0) {
758 pr_debug("PCI: HB8 init\n");
759
760 pci_write_config_byte(dev, 0x1c,
761 ((PPC7D_PCI0_IO_START_PCI_ADDR & 0xf000)
762 >> 8) | 0x01);
763 pci_write_config_byte(dev, 0x1d,
764 (((PPC7D_PCI0_IO_START_PCI_ADDR +
765 PPC7D_PCI0_IO_SIZE -
766 1) & 0xf000) >> 8) | 0x01);
767 pci_write_config_word(dev, 0x30,
768 PPC7D_PCI0_IO_START_PCI_ADDR >> 16);
769 pci_write_config_word(dev, 0x32,
770 ((PPC7D_PCI0_IO_START_PCI_ADDR +
771 PPC7D_PCI0_IO_SIZE -
772 1) >> 16) & 0xffff);
773
774 pci_write_config_word(dev, 0x20,
775 PPC7D_PCI0_MEM0_START_PCI_LO_ADDR >> 16);
776 pci_write_config_word(dev, 0x22,
777 ((PPC7D_PCI0_MEM0_START_PCI_LO_ADDR +
778 PPC7D_PCI0_MEM0_SIZE -
779 1) >> 16) & 0xffff);
780 pci_write_config_word(dev, 0x24, 0);
781 pci_write_config_word(dev, 0x26, 0);
782 pci_write_config_dword(dev, 0x28, 0);
783 pci_write_config_dword(dev, 0x2c, 0);
784
785 pci_read_config_word(dev, 0x3e, &val16);
786 val16 |= ((1 << 5) | (1 << 1)); /* signal master aborts and
787 * SERR to primary
788 */
789 val16 &= ~(1 << 2); /* ISA disable, so all ISA
790 * ports forwarded to secondary
791 */
792 pci_write_config_word(dev, 0x3e, val16);
793 }
794}
795
796DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0028, ppc7d_fixup_hb8);
797
798/* This should perhaps be a separate driver as we're actually initializing
799 * the chip for this board here. It's hardly a fixup...
800 */
801static void __init ppc7d_fixup_ali1535(struct pci_dev *dev)
802{
803 pr_debug("PCI: ALI1535 init\n");
804
805 if (dev->bus->number == 1) {
806 /* Configure the ISA Port Settings */
807 pci_write_config_byte(dev, 0x43, 0x00);
808
809 /* Disable PCI Interrupt polling mode */
810 pci_write_config_byte(dev, 0x45, 0x00);
811
812 /* Multifunction pin select INTFJ -> INTF */
813 pci_write_config_byte(dev, 0x78, 0x00);
814
815 /* Set PCI INT -> IRQ Routing control in for external
816 * pins south bridge.
817 */
818 pci_write_config_byte(dev, 0x48, 0x31); /* [7-4] INT B -> IRQ10
819 * [3-0] INT A -> IRQ9
820 */
821 pci_write_config_byte(dev, 0x49, 0x5D); /* [7-4] INT D -> IRQ5
822 * [3-0] INT C -> IRQ14
823 */
824
825 /* PPC7D setup */
826 /* NEC USB device on IRQ 11 (INTE) - INTF disabled */
827 pci_write_config_byte(dev, 0x4A, 0x09);
828
829 /* GPIO on IRQ 6 */
830 pci_write_config_byte(dev, 0x76, 0x07);
831
832 /* SIRQ I (COMS 5/6) use IRQ line 15.
833 * Positive (not subtractive) address decode.
834 */
835 pci_write_config_byte(dev, 0x44, 0x0f);
836
837 /* SIRQ II disabled */
838 pci_write_config_byte(dev, 0x75, 0x0);
839
840 /* On board USB and RTC disabled */
841 pci_write_config_word(dev, 0x52, (1 << 14));
842 pci_write_config_byte(dev, 0x74, 0x00);
843
844 /* On board IDE disabled */
845 pci_write_config_byte(dev, 0x58, 0x00);
846
847 /* Decode 32-bit addresses */
848 pci_write_config_byte(dev, 0x5b, 0);
849
850 /* Disable docking IO */
851 pci_write_config_word(dev, 0x5c, 0x0000);
852
853 /* Disable modem, enable sound */
854 pci_write_config_byte(dev, 0x77, (1 << 6));
855
856 /* Disable hot-docking mode */
857 pci_write_config_byte(dev, 0x7d, 0x00);
858 }
859}
860
861DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1533, ppc7d_fixup_ali1535);
862
863static int ppc7d_pci_exclude_device(u8 bus, u8 devfn)
864{
865 /* Early versions of this board were fitted with IBM ALMA
866 * PCI-VME bridge chips. The PCI config space of these devices
867 * was not set up correctly and causes PCI scan problems.
868 */
869 if ((bus == 1) && (PCI_SLOT(devfn) == 4) && ppc7d_has_alma)
870 return PCIBIOS_DEVICE_NOT_FOUND;
871
872 return mv64x60_pci_exclude_device(bus, devfn);
873}
874
875/* This hook is called when each PCI bus is probed.
876 */
877static void ppc7d_pci_fixup_bus(struct pci_bus *bus)
878{
879 pr_debug("PCI BUS %hu: %lx/%lx %lx/%lx %lx/%lx %lx/%lx\n",
880 bus->number,
881 bus->resource[0] ? bus->resource[0]->start : 0,
882 bus->resource[0] ? bus->resource[0]->end : 0,
883 bus->resource[1] ? bus->resource[1]->start : 0,
884 bus->resource[1] ? bus->resource[1]->end : 0,
885 bus->resource[2] ? bus->resource[2]->start : 0,
886 bus->resource[2] ? bus->resource[2]->end : 0,
887 bus->resource[3] ? bus->resource[3]->start : 0,
888 bus->resource[3] ? bus->resource[3]->end : 0);
889
890 if ((bus->number == 1) && (bus->resource[2] != NULL)) {
891 /* Hide PCI window 2 of Bus 1 which is used only to
892 * map legacy ISA memory space.
893 */
894 bus->resource[2]->start = 0;
895 bus->resource[2]->end = 0;
896 bus->resource[2]->flags = 0;
897 }
898}
899
900/*****************************************************************************
901 * Board device setup code
902 *****************************************************************************/
903
904void __init ppc7d_setup_peripherals(void)
905{
906 u32 val32;
907
908 /* Set up windows for boot CS */
909 mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
910 PPC7D_BOOT_WINDOW_BASE, PPC7D_BOOT_WINDOW_SIZE,
911 0);
912 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);
913
914 /* Boot firmware configures the following DevCS addresses.
915 * DevCS0 - board control/status
916 * DevCS1 - test registers
917 * DevCS2 - AFIX port/address registers (for identifying)
918 * DevCS3 - FLASH
919 *
920 * We don't use DevCS0, DevCS1.
921 */
922 val32 = mv64x60_read(&bh, MV64360_CPU_BAR_ENABLE);
923 val32 |= ((1 << 4) | (1 << 5));
924 mv64x60_write(&bh, MV64360_CPU_BAR_ENABLE, val32);
925 mv64x60_write(&bh, MV64x60_CPU2DEV_0_BASE, 0);
926 mv64x60_write(&bh, MV64x60_CPU2DEV_0_SIZE, 0);
927 mv64x60_write(&bh, MV64x60_CPU2DEV_1_BASE, 0);
928 mv64x60_write(&bh, MV64x60_CPU2DEV_1_SIZE, 0);
929
930 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
931 PPC7D_AFIX_REG_BASE, PPC7D_AFIX_REG_SIZE, 0);
932 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_2_WIN);
933
934 mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
935 PPC7D_FLASH_BASE, PPC7D_FLASH_SIZE_ACTUAL, 0);
936 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_3_WIN);
937
938 mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
939 PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE,
940 0);
941 bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
942
943 /* Set up Enet->SRAM window */
944 mv64x60_set_32bit_window(&bh, MV64x60_ENET2MEM_4_WIN,
945 PPC7D_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE,
946 0x2);
947 bh.ci->enable_window_32bit(&bh, MV64x60_ENET2MEM_4_WIN);
948
949 /* Give enet r/w access to memory region */
950 val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_0);
951 val32 |= (0x3 << (4 << 1));
952 mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_0, val32);
953 val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_1);
954 val32 |= (0x3 << (4 << 1));
955 mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_1, val32);
956 val32 = mv64x60_read(&bh, MV64360_ENET2MEM_ACC_PROT_2);
957 val32 |= (0x3 << (4 << 1));
958 mv64x60_write(&bh, MV64360_ENET2MEM_ACC_PROT_2, val32);
959
960 val32 = mv64x60_read(&bh, MV64x60_TIMR_CNTR_0_3_CNTL);
961 val32 &= ~((1 << 0) | (1 << 8) | (1 << 16) | (1 << 24));
962 mv64x60_write(&bh, MV64x60_TIMR_CNTR_0_3_CNTL, val32);
963
964 /* Enumerate pci bus.
965 *
966 * We scan PCI#0 first (the bus with the HB8 and other
967 * on-board peripherals). We must configure the 64360 before
968 * each scan, according to the bus number assignments. Busses
969 * are assigned incrementally, starting at 0. PCI#0 is
970 * usually assigned bus#0, the secondary side of the HB8 gets
971 * bus#1 and PCI#1 (second PMC site) gets bus#2. However, if
972 * any PMC card has a PCI bridge, these bus assignments will
973 * change.
974 */
975
976 /* Turn off PCI retries */
977 val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG);
978 val32 |= (1 << 17);
979 mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32);
980
981 /* Scan PCI#0 */
982 mv64x60_set_bus(&bh, 0, 0);
983 bh.hose_a->first_busno = 0;
984 bh.hose_a->last_busno = 0xff;
985 bh.hose_a->last_busno = pciauto_bus_scan(bh.hose_a, 0);
986 printk(KERN_INFO "PCI#0: first=%d last=%d\n",
987 bh.hose_a->first_busno, bh.hose_a->last_busno);
988
989 /* Scan PCI#1 */
990 bh.hose_b->first_busno = bh.hose_a->last_busno + 1;
991 mv64x60_set_bus(&bh, 1, bh.hose_b->first_busno);
992 bh.hose_b->last_busno = 0xff;
993 bh.hose_b->last_busno = pciauto_bus_scan(bh.hose_b,
994 bh.hose_b->first_busno);
995 printk(KERN_INFO "PCI#1: first=%d last=%d\n",
996 bh.hose_b->first_busno, bh.hose_b->last_busno);
997
998 /* Turn on PCI retries */
999 val32 = mv64x60_read(&bh, MV64x60_CPU_CONFIG);
1000 val32 &= ~(1 << 17);
1001 mv64x60_write(&bh, MV64x60_CPU_CONFIG, val32);
1002
1003 /* Setup interrupts */
1004 ppc7d_intr_setup();
1005}
1006
1007static void __init ppc7d_setup_bridge(void)
1008{
1009 struct mv64x60_setup_info si;
1010 int i;
1011 u32 temp;
1012
1013 mv64360_irq_base = 16; /* first 16 intrs are 2 x 8259's */
1014
1015 memset(&si, 0, sizeof(si));
1016
1017 si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
1018
1019 si.pci_0.enable_bus = 1;
1020 si.pci_0.pci_io.cpu_base = PPC7D_PCI0_IO_START_PROC_ADDR;
1021 si.pci_0.pci_io.pci_base_hi = 0;
1022 si.pci_0.pci_io.pci_base_lo = PPC7D_PCI0_IO_START_PCI_ADDR;
1023 si.pci_0.pci_io.size = PPC7D_PCI0_IO_SIZE;
1024 si.pci_0.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
1025 si.pci_0.pci_mem[0].cpu_base = PPC7D_PCI0_MEM0_START_PROC_ADDR;
1026 si.pci_0.pci_mem[0].pci_base_hi = PPC7D_PCI0_MEM0_START_PCI_HI_ADDR;
1027 si.pci_0.pci_mem[0].pci_base_lo = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR;
1028 si.pci_0.pci_mem[0].size = PPC7D_PCI0_MEM0_SIZE;
1029 si.pci_0.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
1030 si.pci_0.pci_mem[1].cpu_base = PPC7D_PCI0_MEM1_START_PROC_ADDR;
1031 si.pci_0.pci_mem[1].pci_base_hi = PPC7D_PCI0_MEM1_START_PCI_HI_ADDR;
1032 si.pci_0.pci_mem[1].pci_base_lo = PPC7D_PCI0_MEM1_START_PCI_LO_ADDR;
1033 si.pci_0.pci_mem[1].size = PPC7D_PCI0_MEM1_SIZE;
1034 si.pci_0.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE;
1035 si.pci_0.pci_cmd_bits = 0;
1036 si.pci_0.latency_timer = 0x80;
1037
1038 si.pci_1.enable_bus = 1;
1039 si.pci_1.pci_io.cpu_base = PPC7D_PCI1_IO_START_PROC_ADDR;
1040 si.pci_1.pci_io.pci_base_hi = 0;
1041 si.pci_1.pci_io.pci_base_lo = PPC7D_PCI1_IO_START_PCI_ADDR;
1042 si.pci_1.pci_io.size = PPC7D_PCI1_IO_SIZE;
1043 si.pci_1.pci_io.swap = MV64x60_CPU2PCI_SWAP_NONE;
1044 si.pci_1.pci_mem[0].cpu_base = PPC7D_PCI1_MEM0_START_PROC_ADDR;
1045 si.pci_1.pci_mem[0].pci_base_hi = PPC7D_PCI1_MEM0_START_PCI_HI_ADDR;
1046 si.pci_1.pci_mem[0].pci_base_lo = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR;
1047 si.pci_1.pci_mem[0].size = PPC7D_PCI1_MEM0_SIZE;
1048 si.pci_1.pci_mem[0].swap = MV64x60_CPU2PCI_SWAP_NONE;
1049 si.pci_1.pci_mem[1].cpu_base = PPC7D_PCI1_MEM1_START_PROC_ADDR;
1050 si.pci_1.pci_mem[1].pci_base_hi = PPC7D_PCI1_MEM1_START_PCI_HI_ADDR;
1051 si.pci_1.pci_mem[1].pci_base_lo = PPC7D_PCI1_MEM1_START_PCI_LO_ADDR;
1052 si.pci_1.pci_mem[1].size = PPC7D_PCI1_MEM1_SIZE;
1053 si.pci_1.pci_mem[1].swap = MV64x60_CPU2PCI_SWAP_NONE;
1054 si.pci_1.pci_cmd_bits = 0;
1055 si.pci_1.latency_timer = 0x80;
1056
1057 /* Don't clear the SRAM window since we use it for debug */
1058 si.window_preserve_mask_32_lo = (1 << MV64x60_CPU2SRAM_WIN);
1059
1060 printk(KERN_INFO "PCI: MV64360 PCI#0 IO at %x, size %x\n",
1061 si.pci_0.pci_io.cpu_base, si.pci_0.pci_io.size);
1062 printk(KERN_INFO "PCI: MV64360 PCI#1 IO at %x, size %x\n",
1063 si.pci_1.pci_io.cpu_base, si.pci_1.pci_io.size);
1064
1065 for (i = 0; i < MV64x60_CPU2MEM_WINDOWS; i++) {
1066#if defined(CONFIG_NOT_COHERENT_CACHE)
1067 si.cpu_prot_options[i] = 0;
1068 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_NONE;
1069 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_NONE;
1070 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_NONE;
1071
1072 si.pci_0.acc_cntl_options[i] =
1073 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
1074 MV64360_PCI_ACC_CNTL_SWAP_NONE |
1075 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
1076 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
1077
1078 si.pci_1.acc_cntl_options[i] =
1079 MV64360_PCI_ACC_CNTL_SNOOP_NONE |
1080 MV64360_PCI_ACC_CNTL_SWAP_NONE |
1081 MV64360_PCI_ACC_CNTL_MBURST_128_BYTES |
1082 MV64360_PCI_ACC_CNTL_RDSIZE_256_BYTES;
1083#else
1084 si.cpu_prot_options[i] = 0;
1085 /* All PPC7D hardware uses B0 or newer MV64360 silicon which
1086 * does not have snoop bugs.
1087 */
1088 si.enet_options[i] = MV64360_ENET2MEM_SNOOP_WB;
1089 si.mpsc_options[i] = MV64360_MPSC2MEM_SNOOP_WB;
1090 si.idma_options[i] = MV64360_IDMA2MEM_SNOOP_WB;
1091
1092 si.pci_0.acc_cntl_options[i] =
1093 MV64360_PCI_ACC_CNTL_SNOOP_WB |
1094 MV64360_PCI_ACC_CNTL_SWAP_NONE |
1095 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
1096 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
1097
1098 si.pci_1.acc_cntl_options[i] =
1099 MV64360_PCI_ACC_CNTL_SNOOP_WB |
1100 MV64360_PCI_ACC_CNTL_SWAP_NONE |
1101 MV64360_PCI_ACC_CNTL_MBURST_32_BYTES |
1102 MV64360_PCI_ACC_CNTL_RDSIZE_32_BYTES;
1103#endif
1104 }
1105
1106 /* Lookup PCI host bridges */
1107 if (mv64x60_init(&bh, &si))
1108 printk(KERN_ERR "MV64360 initialization failed.\n");
1109
1110 pr_debug("MV64360 regs @ %lx/%p\n", bh.p_base, bh.v_base);
1111
1112 /* Enable WB Cache coherency on SRAM */
1113 temp = mv64x60_read(&bh, MV64360_SRAM_CONFIG);
1114 pr_debug("SRAM_CONFIG: %x\n", temp);
1115#if defined(CONFIG_NOT_COHERENT_CACHE)
1116 mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp & ~0x2);
1117#else
1118 mv64x60_write(&bh, MV64360_SRAM_CONFIG, temp | 0x2);
1119#endif
1120 /* If system operates with internal bus arbiter (CPU master
1121 * control bit8) clear AACK Delay bit [25] in CPU
1122 * configuration register.
1123 */
1124 temp = mv64x60_read(&bh, MV64x60_CPU_MASTER_CNTL);
1125 if (temp & (1 << 8)) {
1126 temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG);
1127 mv64x60_write(&bh, MV64x60_CPU_CONFIG, (temp & ~(1 << 25)));
1128 }
1129
1130 /* Data and address parity is enabled */
1131 temp = mv64x60_read(&bh, MV64x60_CPU_CONFIG);
1132 mv64x60_write(&bh, MV64x60_CPU_CONFIG,
1133 (temp | (1 << 26) | (1 << 19)));
1134
1135 pci_dram_offset = 0; /* sys mem at same addr on PCI & cpu bus */
1136 ppc_md.pci_swizzle = common_swizzle;
1137 ppc_md.pci_map_irq = ppc7d_map_irq;
1138 ppc_md.pci_exclude_device = ppc7d_pci_exclude_device;
1139
1140 mv64x60_set_bus(&bh, 0, 0);
1141 bh.hose_a->first_busno = 0;
1142 bh.hose_a->last_busno = 0xff;
1143 bh.hose_a->mem_space.start = PPC7D_PCI0_MEM0_START_PCI_LO_ADDR;
1144 bh.hose_a->mem_space.end =
1145 PPC7D_PCI0_MEM0_START_PCI_LO_ADDR + PPC7D_PCI0_MEM0_SIZE;
1146
1147 /* These will be set later, as a result of PCI0 scan */
1148 bh.hose_b->first_busno = 0;
1149 bh.hose_b->last_busno = 0xff;
1150 bh.hose_b->mem_space.start = PPC7D_PCI1_MEM0_START_PCI_LO_ADDR;
1151 bh.hose_b->mem_space.end =
1152 PPC7D_PCI1_MEM0_START_PCI_LO_ADDR + PPC7D_PCI1_MEM0_SIZE;
1153
1154 pr_debug("MV64360: PCI#0 IO decode %08x/%08x IO remap %08x\n",
1155 mv64x60_read(&bh, 0x48), mv64x60_read(&bh, 0x50),
1156 mv64x60_read(&bh, 0xf0));
1157}
1158
1159static void __init ppc7d_setup_arch(void)
1160{
1161 int port;
1162
1163 loops_per_jiffy = 100000000 / HZ;
1164
1165#ifdef CONFIG_BLK_DEV_INITRD
1166 if (initrd_start)
1167 ROOT_DEV = Root_RAM0;
1168 else
1169#endif
1170#ifdef CONFIG_ROOT_NFS
1171 ROOT_DEV = Root_NFS;
1172#else
1173 ROOT_DEV = Root_HDA1;
1174#endif
1175
1176 if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) ||
1177 (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
1178 /* 745x is different. We only want to pass along enable. */
1179 _set_L2CR(L2CR_L2E);
1180 else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
1181 /* All modules have 1MB of L2. We also assume that an
1182 * L2 divisor of 3 will work.
1183 */
1184 _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
1185 | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
1186
1187 if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)
1188 /* No L3 cache */
1189 _set_L3CR(0);
1190
1191#ifdef CONFIG_DUMMY_CONSOLE
1192 conswitchp = &dummy_con;
1193#endif
1194
1195 /* Lookup PCI host bridges */
1196 if (ppc_md.progress)
1197 ppc_md.progress("ppc7d_setup_arch: calling setup_bridge", 0);
1198
1199 ppc7d_setup_bridge();
1200 ppc7d_setup_peripherals();
1201
1202 /* Disable ethernet. It might have been setup by the bootrom */
1203 for (port = 0; port < 3; port++)
1204 mv64x60_write(&bh, MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port),
1205 0x0000ff00);
1206
1207 /* Clear queue pointers to ensure they are all initialized,
1208 * otherwise since queues 1-7 are unused, they have random
1209 * pointers which look strange in register dumps. Don't bother
1210 * with queue 0 since it will be initialized later.
1211 */
1212 for (port = 0; port < 3; port++) {
1213 mv64x60_write(&bh,
1214 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port),
1215 0x00000000);
1216 mv64x60_write(&bh,
1217 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port),
1218 0x00000000);
1219 mv64x60_write(&bh,
1220 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port),
1221 0x00000000);
1222 mv64x60_write(&bh,
1223 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port),
1224 0x00000000);
1225 mv64x60_write(&bh,
1226 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port),
1227 0x00000000);
1228 mv64x60_write(&bh,
1229 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port),
1230 0x00000000);
1231 mv64x60_write(&bh,
1232 MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port),
1233 0x00000000);
1234 }
1235
1236 printk(KERN_INFO "Radstone Technology PPC7D\n");
1237 if (ppc_md.progress)
1238 ppc_md.progress("ppc7d_setup_arch: exit", 0);
1239}
1240
1241/* This kernel command line parameter can be used to have the target
1242 * wait for a JTAG debugger to attach. Of course, a JTAG debugger
1243 * with hardware breakpoint support can have the target stop at any
1244 * location during init, but this is a convenience feature that makes
1245 * it easier in the common case of loading the code using the ppcboot
1246 * bootloader..
1247 */
1248static unsigned long ppc7d_wait_debugger;
1249
1250static int __init ppc7d_waitdbg(char *str)
1251{
1252 ppc7d_wait_debugger = 1;
1253 return 1;
1254}
1255
1256__setup("waitdbg", ppc7d_waitdbg);
1257
1258/* Second phase board init, called after other (architecture common)
1259 * low-level services have been initialized.
1260 */
1261static void ppc7d_init2(void)
1262{
1263 unsigned long flags;
1264 u32 data;
1265 u8 data8;
1266
1267 pr_debug("%s: enter\n", __FUNCTION__);
1268
1269 /* Wait for debugger? */
1270 if (ppc7d_wait_debugger) {
1271 printk("Waiting for debugger...\n");
1272
1273 while (readl(&ppc7d_wait_debugger)) ;
1274 }
1275
1276 /* Hook up i8259 interrupt which is connected to GPP28 */
1277 request_irq(mv64360_irq_base + MV64x60_IRQ_GPP28, ppc7d_i8259_intr,
1278 SA_INTERRUPT, "I8259 (GPP28) interrupt", (void *)0);
1279
1280 /* Configure MPP16 as watchdog NMI, MPP17 as watchdog WDE */
1281 spin_lock_irqsave(&mv64x60_lock, flags);
1282 data = mv64x60_read(&bh, MV64x60_MPP_CNTL_2);
1283 data &= ~(0x0000000f << 0);
1284 data |= (0x00000004 << 0);
1285 data &= ~(0x0000000f << 4);
1286 data |= (0x00000004 << 4);
1287 mv64x60_write(&bh, MV64x60_MPP_CNTL_2, data);
1288 spin_unlock_irqrestore(&mv64x60_lock, flags);
1289
1290 /* All LEDs off */
1291 data8 = inb(PPC7D_CPLD_LEDS);
1292 data8 &= ~0x08;
1293 data8 |= 0x07;
1294 outb(data8, PPC7D_CPLD_LEDS);
1295
1296 pr_debug("%s: exit\n", __FUNCTION__);
1297}
1298
1299/* Called from machine_init(), early, before any of the __init functions
1300 * have run. We must init software-configurable pins before other functions
1301 * such as interrupt controllers are initialised.
1302 */
1303void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
1304 unsigned long r6, unsigned long r7)
1305{
1306 u8 val8;
1307 u8 rev_num;
1308
1309 /* Map 0xe0000000-0xffffffff early because we need access to SRAM
1310 * and the ISA memory space (for serial port) here. This mapping
1311 * is redone properly in ppc7d_map_io() later.
1312 */
1313 mtspr(SPRN_DBAT3U, 0xe0003fff);
1314 mtspr(SPRN_DBAT3L, 0xe000002a);
1315
1316 /*
1317 * Zero SRAM. Note that this generates parity errors on
1318 * internal data path in SRAM if it's first time accessing it
1319 * after reset.
1320 *
1321 * We do this ASAP to avoid parity errors when reading
1322 * uninitialized SRAM.
1323 */
1324 memset((void *)PPC7D_INTERNAL_SRAM_BASE, 0, MV64360_SRAM_SIZE);
1325
1326 pr_debug("platform_init: r3-r7: %lx %lx %lx %lx %lx\n",
1327 r3, r4, r5, r6, r7);
1328
1329 parse_bootinfo(find_bootinfo());
1330
1331 /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer)
1332 * are non-zero, then we should use the board info from the bd_t
1333 * structure and the cmdline pointed to by r6 instead of the
1334 * information from birecs, if any. Otherwise, use the information
1335 * from birecs as discovered by the preceeding call to
1336 * parse_bootinfo(). This rule should work with both PPCBoot, which
1337 * uses a bd_t board info structure, and the kernel boot wrapper,
1338 * which uses birecs.
1339 */
1340 if (r3 && r6) {
1341 bd_t *bp = (bd_t *) __res;
1342
1343 /* copy board info structure */
1344 memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t));
1345 /* copy command line */
1346 *(char *)(r7 + KERNELBASE) = 0;
1347 strcpy(cmd_line, (char *)(r6 + KERNELBASE));
1348
1349 printk(KERN_INFO "Board info data:-\n");
1350 printk(KERN_INFO " Internal freq: %lu MHz, bus freq: %lu MHz\n",
1351 bp->bi_intfreq, bp->bi_busfreq);
1352 printk(KERN_INFO " Memory: %lx, size %lx\n", bp->bi_memstart,
1353 bp->bi_memsize);
1354 printk(KERN_INFO " Console baudrate: %lu\n", bp->bi_baudrate);
1355 printk(KERN_INFO " Ethernet address: "
1356 "%02x:%02x:%02x:%02x:%02x:%02x\n",
1357 bp->bi_enetaddr[0], bp->bi_enetaddr[1],
1358 bp->bi_enetaddr[2], bp->bi_enetaddr[3],
1359 bp->bi_enetaddr[4], bp->bi_enetaddr[5]);
1360 }
1361#ifdef CONFIG_BLK_DEV_INITRD
1362 /* take care of initrd if we have one */
1363 if (r4) {
1364 initrd_start = r4 + KERNELBASE;
1365 initrd_end = r5 + KERNELBASE;
1366 printk(KERN_INFO "INITRD @ %lx/%lx\n", initrd_start, initrd_end);
1367 }
1368#endif /* CONFIG_BLK_DEV_INITRD */
1369
1370 /* Map in board regs, etc. */
1371 isa_io_base = 0xe8000000;
1372 isa_mem_base = 0xe8000000;
1373 pci_dram_offset = 0x00000000;
1374 ISA_DMA_THRESHOLD = 0x00ffffff;
1375 DMA_MODE_READ = 0x44;
1376 DMA_MODE_WRITE = 0x48;
1377
1378 ppc_md.setup_arch = ppc7d_setup_arch;
1379 ppc_md.init = ppc7d_init2;
1380 ppc_md.show_cpuinfo = ppc7d_show_cpuinfo;
1381 ppc_md.irq_canonicalize = ppc7d_irq_canonicalize;
1382 ppc_md.init_IRQ = ppc7d_init_irq;
1383 ppc_md.get_irq = ppc7d_get_irq;
1384
1385 ppc_md.restart = ppc7d_restart;
1386 ppc_md.power_off = ppc7d_power_off;
1387 ppc_md.halt = ppc7d_halt;
1388
1389 ppc_md.find_end_of_memory = ppc7d_find_end_of_memory;
1390 ppc_md.setup_io_mappings = ppc7d_map_io;
1391
1392 ppc_md.time_init = NULL;
1393 ppc_md.set_rtc_time = NULL;
1394 ppc_md.get_rtc_time = NULL;
1395 ppc_md.calibrate_decr = ppc7d_calibrate_decr;
1396 ppc_md.nvram_read_val = NULL;
1397 ppc_md.nvram_write_val = NULL;
1398
1399 ppc_md.heartbeat = ppc7d_heartbeat;
1400 ppc_md.heartbeat_reset = HZ;
1401 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
1402
1403 ppc_md.pcibios_fixup_bus = ppc7d_pci_fixup_bus;
1404
1405#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH) || \
1406 defined(CONFIG_I2C_MV64XXX)
1407 platform_notify = ppc7d_platform_notify;
1408#endif
1409
1410#ifdef CONFIG_SERIAL_MPSC
1411 /* On PPC7D, we must configure MPSC support via CPLD control
1412 * registers.
1413 */
1414 outb(PPC7D_CPLD_RTS_COM4_SCLK |
1415 PPC7D_CPLD_RTS_COM56_ENABLED, PPC7D_CPLD_RTS);
1416 outb(PPC7D_CPLD_COMS_COM3_TCLKEN |
1417 PPC7D_CPLD_COMS_COM3_TXEN |
1418 PPC7D_CPLD_COMS_COM4_TCLKEN |
1419 PPC7D_CPLD_COMS_COM4_TXEN, PPC7D_CPLD_COMS);
1420#endif /* CONFIG_SERIAL_MPSC */
1421
1422#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)
1423 ppc7d_early_serial_map();
1424#ifdef CONFIG_SERIAL_TEXT_DEBUG
1425#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
1426 ppc_md.progress = mv64x60_mpsc_progress;
1427#elif defined(CONFIG_SERIAL_8250)
1428 ppc_md.progress = gen550_progress;
1429#else
1430#error CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG has no supported CONFIG_SERIAL_XXX
1431#endif /* CONFIG_SERIAL_8250 */
1432#endif /* CONFIG_SERIAL_TEXT_DEBUG */
1433#endif /* CONFIG_KGDB || CONFIG_SERIAL_TEXT_DEBUG */
1434
1435 /* Enable write access to user flash. This is necessary for
1436 * flash probe.
1437 */
1438 val8 = readb((void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT);
1439 writeb(val8 | (PPC7D_CPLD_SW_FLASH_WRPROT_ENABLED &
1440 PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK),
1441 (void *)isa_io_base + PPC7D_CPLD_SW_FLASH_WRITE_PROTECT);
1442
1443 /* Determine if this board has IBM ALMA VME devices */
1444 val8 = readb((void *)isa_io_base + PPC7D_CPLD_BOARD_REVISION);
1445 rev_num = (val8 & PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK) >> 5;
1446 if (rev_num <= 1)
1447 ppc7d_has_alma = 1;
1448
1449#ifdef DEBUG
1450 console_printk[0] = 8;
1451#endif
1452}
diff --git a/arch/ppc/platforms/radstone_ppc7d.h b/arch/ppc/platforms/radstone_ppc7d.h
new file mode 100644
index 000000000000..4546fff2b0c3
--- /dev/null
+++ b/arch/ppc/platforms/radstone_ppc7d.h
@@ -0,0 +1,434 @@
1/*
2 * arch/ppc/platforms/radstone_ppc7d.h
3 *
4 * Board definitions for the Radstone PPC7D boards.
5 *
6 * Author: James Chapman <jchapman@katalix.com>
7 *
8 * Based on code done by Rabeeh Khoury - rabeeh@galileo.co.il
9 * Based on code done by - Mark A. Greer <mgreer@mvista.com>
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
17/*
18 * The MV64360 has 2 PCI buses each with 1 window from the CPU bus to
19 * PCI I/O space and 4 windows from the CPU bus to PCI MEM space.
20 * We'll only use one PCI MEM window on each PCI bus.
21 *
22 * This is the CPU physical memory map (windows must be at least 1MB
23 * and start on a boundary that is a multiple of the window size):
24 *
25 * 0xff800000-0xffffffff - Boot window
26 * 0xff000000-0xff000fff - AFIX registers (DevCS2)
27 * 0xfef00000-0xfef0ffff - Internal MV64x60 registers
28 * 0xfef40000-0xfef7ffff - Internal SRAM
29 * 0xfef00000-0xfef0ffff - MV64360 Registers
30 * 0x70000000-0x7fffffff - soldered flash (DevCS3)
31 * 0xe8000000-0xe9ffffff - PCI I/O
32 * 0x80000000-0xbfffffff - PCI MEM
33 */
34
35#ifndef __PPC_PLATFORMS_PPC7D_H
36#define __PPC_PLATFORMS_PPC7D_H
37
38#include <asm/ppcboot.h>
39
40/*****************************************************************************
41 * CPU Physical Memory Map setup.
42 *****************************************************************************/
43
44#define PPC7D_BOOT_WINDOW_BASE 0xff800000
45#define PPC7D_AFIX_REG_BASE 0xff000000
46#define PPC7D_INTERNAL_SRAM_BASE 0xfef40000
47#define PPC7D_FLASH_BASE 0x70000000
48
49#define PPC7D_BOOT_WINDOW_SIZE_ACTUAL 0x00800000 /* 8MB */
50#define PPC7D_FLASH_SIZE_ACTUAL 0x10000000 /* 256MB */
51
52#define PPC7D_BOOT_WINDOW_SIZE max(MV64360_WINDOW_SIZE_MIN, \
53 PPC7D_BOOT_WINDOW_SIZE_ACTUAL)
54#define PPC7D_FLASH_SIZE max(MV64360_WINDOW_SIZE_MIN, \
55 PPC7D_FLASH_SIZE_ACTUAL)
56#define PPC7D_AFIX_REG_SIZE max(MV64360_WINDOW_SIZE_MIN, 0xff)
57
58
59#define PPC7D_PCI0_MEM0_START_PROC_ADDR 0x80000000UL
60#define PPC7D_PCI0_MEM0_START_PCI_HI_ADDR 0x00000000UL
61#define PPC7D_PCI0_MEM0_START_PCI_LO_ADDR 0x80000000UL
62#define PPC7D_PCI0_MEM0_SIZE 0x20000000UL
63#define PPC7D_PCI0_MEM1_START_PROC_ADDR 0xe8010000UL
64#define PPC7D_PCI0_MEM1_START_PCI_HI_ADDR 0x00000000UL
65#define PPC7D_PCI0_MEM1_START_PCI_LO_ADDR 0x00000000UL
66#define PPC7D_PCI0_MEM1_SIZE 0x000f0000UL
67#define PPC7D_PCI0_IO_START_PROC_ADDR 0xe8000000UL
68#define PPC7D_PCI0_IO_START_PCI_ADDR 0x00000000UL
69#define PPC7D_PCI0_IO_SIZE 0x00010000UL
70
71#define PPC7D_PCI1_MEM0_START_PROC_ADDR 0xa0000000UL
72#define PPC7D_PCI1_MEM0_START_PCI_HI_ADDR 0x00000000UL
73#define PPC7D_PCI1_MEM0_START_PCI_LO_ADDR 0xa0000000UL
74#define PPC7D_PCI1_MEM0_SIZE 0x20000000UL
75#define PPC7D_PCI1_MEM1_START_PROC_ADDR 0xe9800000UL
76#define PPC7D_PCI1_MEM1_START_PCI_HI_ADDR 0x00000000UL
77#define PPC7D_PCI1_MEM1_START_PCI_LO_ADDR 0x00000000UL
78#define PPC7D_PCI1_MEM1_SIZE 0x00800000UL
79#define PPC7D_PCI1_IO_START_PROC_ADDR 0xe9000000UL
80#define PPC7D_PCI1_IO_START_PCI_ADDR 0x00000000UL
81#define PPC7D_PCI1_IO_SIZE 0x00010000UL
82
83#define PPC7D_DEFAULT_BAUD 9600
84#define PPC7D_MPSC_CLK_SRC 8 /* TCLK */
85#define PPC7D_MPSC_CLK_FREQ 133333333 /* 133.3333... MHz */
86
87#define PPC7D_ETH0_PHY_ADDR 8
88#define PPC7D_ETH1_PHY_ADDR 9
89#define PPC7D_ETH2_PHY_ADDR 0
90
91#define PPC7D_ETH_TX_QUEUE_SIZE 400
92#define PPC7D_ETH_RX_QUEUE_SIZE 400
93
94#define PPC7D_ETH_PORT_CONFIG_VALUE \
95 MV64340_ETH_UNICAST_NORMAL_MODE | \
96 MV64340_ETH_DEFAULT_RX_QUEUE_0 | \
97 MV64340_ETH_DEFAULT_RX_ARP_QUEUE_0 | \
98 MV64340_ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP | \
99 MV64340_ETH_RECEIVE_BC_IF_IP | \
100 MV64340_ETH_RECEIVE_BC_IF_ARP | \
101 MV64340_ETH_CAPTURE_TCP_FRAMES_DIS | \
102 MV64340_ETH_CAPTURE_UDP_FRAMES_DIS | \
103 MV64340_ETH_DEFAULT_RX_TCP_QUEUE_0 | \
104 MV64340_ETH_DEFAULT_RX_UDP_QUEUE_0 | \
105 MV64340_ETH_DEFAULT_RX_BPDU_QUEUE_0
106
107#define PPC7D_ETH_PORT_CONFIG_EXTEND_VALUE \
108 MV64340_ETH_SPAN_BPDU_PACKETS_AS_NORMAL | \
109 MV64340_ETH_PARTITION_DISABLE
110
111#define GT_ETH_IPG_INT_RX(value) \
112 ((value & 0x3fff) << 8)
113
114#define PPC7D_ETH_PORT_SDMA_CONFIG_VALUE \
115 MV64340_ETH_RX_BURST_SIZE_4_64BIT | \
116 GT_ETH_IPG_INT_RX(0) | \
117 MV64340_ETH_TX_BURST_SIZE_4_64BIT
118
119#define PPC7D_ETH_PORT_SERIAL_CONTROL_VALUE \
120 MV64340_ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \
121 MV64340_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
122 MV64340_ETH_ADV_SYMMETRIC_FLOW_CTRL | \
123 MV64340_ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
124 MV64340_ETH_FORCE_BP_MODE_NO_JAM | \
125 (1 << 9) | \
126 MV64340_ETH_DO_NOT_FORCE_LINK_FAIL | \
127 MV64340_ETH_RETRANSMIT_16_ATTEMPTS | \
128 MV64340_ETH_ENABLE_AUTO_NEG_SPEED_GMII | \
129 MV64340_ETH_DTE_ADV_0 | \
130 MV64340_ETH_DISABLE_AUTO_NEG_BYPASS | \
131 MV64340_ETH_AUTO_NEG_NO_CHANGE | \
132 MV64340_ETH_MAX_RX_PACKET_9700BYTE | \
133 MV64340_ETH_CLR_EXT_LOOPBACK | \
134 MV64340_ETH_SET_FULL_DUPLEX_MODE | \
135 MV64340_ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
136
137/*****************************************************************************
138 * Serial defines.
139 *****************************************************************************/
140
141#define PPC7D_SERIAL_0 0xe80003f8
142#define PPC7D_SERIAL_1 0xe80002f8
143
144#define RS_TABLE_SIZE 2
145
146/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
147#define UART_CLK 1843200
148#define BASE_BAUD ( UART_CLK / 16 )
149
150#ifdef CONFIG_SERIAL_DETECT_IRQ
151#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ)
152#else
153#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF)
154#endif
155
156#define STD_SERIAL_PORT_DFNS \
157 { 0, BASE_BAUD, PPC7D_SERIAL_0, 4, STD_COM_FLAGS, /* ttyS0 */ \
158 iomem_base: (u8 *)PPC7D_SERIAL_0, \
159 io_type: SERIAL_IO_MEM, }, \
160 { 0, BASE_BAUD, PPC7D_SERIAL_1, 3, STD_COM_FLAGS, /* ttyS1 */ \
161 iomem_base: (u8 *)PPC7D_SERIAL_1, \
162 io_type: SERIAL_IO_MEM },
163
164#define SERIAL_PORT_DFNS \
165 STD_SERIAL_PORT_DFNS
166
167/*****************************************************************************
168 * CPLD defines.
169 *
170 * Register map:-
171 *
172 * 0000 to 000F South Bridge DMA 1 Control
173 * 0020 and 0021 South Bridge Interrupt 1 Control
174 * 0040 to 0043 South Bridge Counter Control
175 * 0060 Keyboard
176 * 0061 South Bridge NMI Status and Control
177 * 0064 Keyboard
178 * 0071 and 0072 RTC R/W
179 * 0078 to 007B South Bridge BIOS Timer
180 * 0080 to 0090 South Bridge DMA Pages
181 * 00A0 and 00A1 South Bridge Interrupt 2 Control
182 * 00C0 to 00DE South Bridge DMA 2 Control
183 * 02E8 to 02EF COM6 R/W
184 * 02F8 to 02FF South Bridge COM2 R/W
185 * 03E8 to 03EF COM5 R/W
186 * 03F8 to 03FF South Bridge COM1 R/W
187 * 040A South Bridge DMA Scatter/Gather RO
188 * 040B DMA 1 Extended Mode WO
189 * 0410 to 043F South Bridge DMA Scatter/Gather
190 * 0481 to 048B South Bridge DMA High Pages
191 * 04D0 and 04D1 South Bridge Edge/Level Control
192 * 04D6 DMA 2 Extended Mode WO
193 * 0804 Memory Configuration RO
194 * 0806 Memory Configuration Extend RO
195 * 0808 SCSI Activity LED R/W
196 * 080C Equipment Present 1 RO
197 * 080E Equipment Present 2 RO
198 * 0810 Equipment Present 3 RO
199 * 0812 Equipment Present 4 RO
200 * 0818 Key Lock RO
201 * 0820 LEDS R/W
202 * 0824 COMs R/W
203 * 0826 RTS R/W
204 * 0828 Reset R/W
205 * 082C Watchdog Trig R/W
206 * 082E Interrupt R/W
207 * 0830 Interrupt Status RO
208 * 0832 PCI configuration RO
209 * 0854 Board Revision RO
210 * 0858 Extended ID RO
211 * 0864 ID Link RO
212 * 0866 Motherboard Type RO
213 * 0868 FLASH Write control RO
214 * 086A Software FLASH write protect R/W
215 * 086E FLASH Control R/W
216 *****************************************************************************/
217
218#define PPC7D_CPLD_MEM_CONFIG 0x0804
219#define PPC7D_CPLD_MEM_CONFIG_EXTEND 0x0806
220#define PPC7D_CPLD_SCSI_ACTIVITY_LED 0x0808
221#define PPC7D_CPLD_EQUIPMENT_PRESENT_1 0x080C
222#define PPC7D_CPLD_EQUIPMENT_PRESENT_2 0x080E
223#define PPC7D_CPLD_EQUIPMENT_PRESENT_3 0x0810
224#define PPC7D_CPLD_EQUIPMENT_PRESENT_4 0x0812
225#define PPC7D_CPLD_KEY_LOCK 0x0818
226#define PPC7D_CPLD_LEDS 0x0820
227#define PPC7D_CPLD_COMS 0x0824
228#define PPC7D_CPLD_RTS 0x0826
229#define PPC7D_CPLD_RESET 0x0828
230#define PPC7D_CPLD_WATCHDOG_TRIG 0x082C
231#define PPC7D_CPLD_INTR 0x082E
232#define PPC7D_CPLD_INTR_STATUS 0x0830
233#define PPC7D_CPLD_PCI_CONFIG 0x0832
234#define PPC7D_CPLD_BOARD_REVISION 0x0854
235#define PPC7D_CPLD_EXTENDED_ID 0x0858
236#define PPC7D_CPLD_ID_LINK 0x0864
237#define PPC7D_CPLD_MOTHERBOARD_TYPE 0x0866
238#define PPC7D_CPLD_FLASH_WRITE_CNTL 0x0868
239#define PPC7D_CPLD_SW_FLASH_WRITE_PROTECT 0x086A
240#define PPC7D_CPLD_FLASH_CNTL 0x086E
241
242/* MEMORY_CONFIG_EXTEND */
243#define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0
244#define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0
245#define PPC7D_CPLD_SDRAM_BANK_SIZE_256M 0x40
246#define PPC7D_CPLD_SDRAM_BANK_SIZE_512M 0x80
247#define PPC7D_CPLD_SDRAM_BANK_SIZE_1G 0xc0
248#define PPC7D_CPLD_FLASH_DEV_SIZE_MASK 0x03
249#define PPC7D_CPLD_FLASH_BANK_NUM_MASK 0x0c
250#define PPC7D_CPLD_FLASH_DEV_SIZE_64M 0
251#define PPC7D_CPLD_FLASH_DEV_SIZE_32M 1
252#define PPC7D_CPLD_FLASH_DEV_SIZE_16M 3
253#define PPC7D_CPLD_FLASH_BANK_NUM_4 0x00
254#define PPC7D_CPLD_FLASH_BANK_NUM_3 0x04
255#define PPC7D_CPLD_FLASH_BANK_NUM_2 0x08
256#define PPC7D_CPLD_FLASH_BANK_NUM_1 0x0c
257
258/* SCSI_LED */
259#define PPC7D_CPLD_SCSI_ACTIVITY_LED_OFF 0
260#define PPC7D_CPLD_SCSI_ACTIVITY_LED_ON 1
261
262/* EQUIPMENT_PRESENT_1 */
263#define PPC7D_CPLD_EQPT_PRES_1_FITTED 0
264#define PPC7D_CPLD_EQPT_PRES_1_PMC2_MASK (0x80 >> 2)
265#define PPC7D_CPLD_EQPT_PRES_1_PMC1_MASK (0x80 >> 3)
266#define PPC7D_CPLD_EQPT_PRES_1_AFIX_MASK (0x80 >> 4)
267
268/* EQUIPMENT_PRESENT_2 */
269#define PPC7D_CPLD_EQPT_PRES_2_FITTED !0
270#define PPC7D_CPLD_EQPT_PRES_2_UNIVERSE_MASK (0x80 >> 0)
271#define PPC7D_CPLD_EQPT_PRES_2_COM36_MASK (0x80 >> 2)
272#define PPC7D_CPLD_EQPT_PRES_2_GIGE_MASK (0x80 >> 3)
273#define PPC7D_CPLD_EQPT_PRES_2_DUALGIGE_MASK (0x80 >> 4)
274
275/* EQUIPMENT_PRESENT_3 */
276#define PPC7D_CPLD_EQPT_PRES_3_PMC2_V_MASK (0x80 >> 3)
277#define PPC7D_CPLD_EQPT_PRES_3_PMC2_5V (0 >> 3)
278#define PPC7D_CPLD_EQPT_PRES_3_PMC2_3V (0x80 >> 3)
279#define PPC7D_CPLD_EQPT_PRES_3_PMC1_V_MASK (0x80 >> 4)
280#define PPC7D_CPLD_EQPT_PRES_3_PMC1_5V (0 >> 4)
281#define PPC7D_CPLD_EQPT_PRES_3_PMC1_3V (0x80 >> 4)
282#define PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_MASK (0x80 >> 5)
283#define PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_INTER (0 >> 5)
284#define PPC7D_CPLD_EQPT_PRES_3_PMC_POWER_VME (0x80 >> 5)
285
286/* EQUIPMENT_PRESENT_4 */
287#define PPC7D_CPLD_EQPT_PRES_4_LPT_MASK (0x80 >> 2)
288#define PPC7D_CPLD_EQPT_PRES_4_LPT_FITTED (0x80 >> 2)
289#define PPC7D_CPLD_EQPT_PRES_4_PS2_USB2_MASK (0xc0 >> 6)
290#define PPC7D_CPLD_EQPT_PRES_4_PS2_FITTED (0x40 >> 6)
291#define PPC7D_CPLD_EQPT_PRES_4_USB2_FITTED (0x80 >> 6)
292
293/* CPLD_LEDS */
294#define PPC7D_CPLD_LEDS_ON (!0)
295#define PPC7D_CPLD_LEDS_OFF (0)
296#define PPC7D_CPLD_LEDS_NVRAM_PAGE_MASK (0xc0 >> 2)
297#define PPC7D_CPLD_LEDS_DS201_MASK (0x80 >> 4)
298#define PPC7D_CPLD_LEDS_DS219_MASK (0x80 >> 5)
299#define PPC7D_CPLD_LEDS_DS220_MASK (0x80 >> 6)
300#define PPC7D_CPLD_LEDS_DS221_MASK (0x80 >> 7)
301
302/* CPLD_COMS */
303#define PPC7D_CPLD_COMS_COM3_TCLKEN (0x80 >> 0)
304#define PPC7D_CPLD_COMS_COM3_RTCLKEN (0x80 >> 1)
305#define PPC7D_CPLD_COMS_COM3_MODE_MASK (0x80 >> 2)
306#define PPC7D_CPLD_COMS_COM3_MODE_RS232 (0)
307#define PPC7D_CPLD_COMS_COM3_MODE_RS422 (0x80 >> 2)
308#define PPC7D_CPLD_COMS_COM3_TXEN (0x80 >> 3)
309#define PPC7D_CPLD_COMS_COM4_TCLKEN (0x80 >> 4)
310#define PPC7D_CPLD_COMS_COM4_RTCLKEN (0x80 >> 5)
311#define PPC7D_CPLD_COMS_COM4_MODE_MASK (0x80 >> 6)
312#define PPC7D_CPLD_COMS_COM4_MODE_RS232 (0)
313#define PPC7D_CPLD_COMS_COM4_MODE_RS422 (0x80 >> 6)
314#define PPC7D_CPLD_COMS_COM4_TXEN (0x80 >> 7)
315
316/* CPLD_RTS */
317#define PPC7D_CPLD_RTS_COM36_LOOPBACK (0x80 >> 0)
318#define PPC7D_CPLD_RTS_COM4_SCLK (0x80 >> 1)
319#define PPC7D_CPLD_RTS_COM3_TXFUNC_MASK (0xc0 >> 2)
320#define PPC7D_CPLD_RTS_COM3_TXFUNC_DISABLED (0 >> 2)
321#define PPC7D_CPLD_RTS_COM3_TXFUNC_ENABLED (0x80 >> 2)
322#define PPC7D_CPLD_RTS_COM3_TXFUNC_ENABLED_RTG3 (0xc0 >> 2)
323#define PPC7D_CPLD_RTS_COM3_TXFUNC_ENABLED_RTG3S (0xc0 >> 2)
324#define PPC7D_CPLD_RTS_COM56_MODE_MASK (0x80 >> 4)
325#define PPC7D_CPLD_RTS_COM56_MODE_RS232 (0)
326#define PPC7D_CPLD_RTS_COM56_MODE_RS422 (0x80 >> 4)
327#define PPC7D_CPLD_RTS_COM56_ENABLE_MASK (0x80 >> 5)
328#define PPC7D_CPLD_RTS_COM56_DISABLED (0)
329#define PPC7D_CPLD_RTS_COM56_ENABLED (0x80 >> 5)
330#define PPC7D_CPLD_RTS_COM4_TXFUNC_MASK (0xc0 >> 6)
331#define PPC7D_CPLD_RTS_COM4_TXFUNC_DISABLED (0 >> 6)
332#define PPC7D_CPLD_RTS_COM4_TXFUNC_ENABLED (0x80 >> 6)
333#define PPC7D_CPLD_RTS_COM4_TXFUNC_ENABLED_RTG3 (0x40 >> 6)
334#define PPC7D_CPLD_RTS_COM4_TXFUNC_ENABLED_RTG3S (0x40 >> 6)
335
336/* WATCHDOG_TRIG */
337#define PPC7D_CPLD_WDOG_CAUSE_MASK (0x80 >> 0)
338#define PPC7D_CPLD_WDOG_CAUSE_NORMAL_RESET (0 >> 0)
339#define PPC7D_CPLD_WDOG_CAUSE_WATCHDOG (0x80 >> 0)
340#define PPC7D_CPLD_WDOG_ENABLE_MASK (0x80 >> 6)
341#define PPC7D_CPLD_WDOG_ENABLE_OFF (0 >> 6)
342#define PPC7D_CPLD_WDOG_ENABLE_ON (0x80 >> 6)
343#define PPC7D_CPLD_WDOG_RESETSW_MASK (0x80 >> 7)
344#define PPC7D_CPLD_WDOG_RESETSW_OFF (0 >> 7)
345#define PPC7D_CPLD_WDOG_RESETSW_ON (0x80 >> 7)
346
347/* Interrupt mask and status bits */
348#define PPC7D_CPLD_INTR_TEMP_MASK (0x80 >> 0)
349#define PPC7D_CPLD_INTR_HB8_MASK (0x80 >> 1)
350#define PPC7D_CPLD_INTR_PHY1_MASK (0x80 >> 2)
351#define PPC7D_CPLD_INTR_PHY0_MASK (0x80 >> 3)
352#define PPC7D_CPLD_INTR_ISANMI_MASK (0x80 >> 5)
353#define PPC7D_CPLD_INTR_CRITTEMP_MASK (0x80 >> 6)
354
355/* CPLD_INTR */
356#define PPC7D_CPLD_INTR_ENABLE_OFF (0)
357#define PPC7D_CPLD_INTR_ENABLE_ON (!0)
358
359/* CPLD_INTR_STATUS */
360#define PPC7D_CPLD_INTR_STATUS_OFF (0)
361#define PPC7D_CPLD_INTR_STATUS_ON (!0)
362
363/* CPLD_PCI_CONFIG */
364#define PPC7D_CPLD_PCI_CONFIG_PCI0_MASK 0x70
365#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCI33 0x00
366#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCI66 0x10
367#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCIX33 0x40
368#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCIX66 0x50
369#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCIX100 0x60
370#define PPC7D_CPLD_PCI_CONFIG_PCI0_PCIX133 0x70
371#define PPC7D_CPLD_PCI_CONFIG_PCI1_MASK 0x07
372#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCI33 0x00
373#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCI66 0x01
374#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCIX33 0x04
375#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCIX66 0x05
376#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCIX100 0x06
377#define PPC7D_CPLD_PCI_CONFIG_PCI1_PCIX133 0x07
378
379/* CPLD_BOARD_REVISION */
380#define PPC7D_CPLD_BOARD_REVISION_NUMBER_MASK 0xe0
381#define PPC7D_CPLD_BOARD_REVISION_LETTER_MASK 0x1f
382
383/* CPLD_EXTENDED_ID */
384#define PPC7D_CPLD_EXTENDED_ID_PPC7D 0x18
385
386/* CPLD_ID_LINK */
387#define PPC7D_CPLD_ID_LINK_VME64_GAP_MASK (0x80 >> 2)
388#define PPC7D_CPLD_ID_LINK_VME64_GA4_MASK (0x80 >> 3)
389#define PPC7D_CPLD_ID_LINK_E13_MASK (0x80 >> 4)
390#define PPC7D_CPLD_ID_LINK_E12_MASK (0x80 >> 5)
391#define PPC7D_CPLD_ID_LINK_E7_MASK (0x80 >> 6)
392#define PPC7D_CPLD_ID_LINK_E6_MASK (0x80 >> 7)
393
394/* CPLD_MOTHERBOARD_TYPE */
395#define PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK (0x80 >> 0)
396#define PPC7D_CPLD_MB_TYPE_ECC_ENABLED (0x80 >> 0)
397#define PPC7D_CPLD_MB_TYPE_ECC_DISABLED (0 >> 0)
398#define PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK (0x80 >> 3)
399#define PPC7D_CPLD_MB_TYPE_PLL_MASK 0x0c
400#define PPC7D_CPLD_MB_TYPE_PLL_133 0x00
401#define PPC7D_CPLD_MB_TYPE_PLL_100 0x08
402#define PPC7D_CPLD_MB_TYPE_PLL_64 0x04
403#define PPC7D_CPLD_MB_TYPE_HW_ID_MASK 0x03
404
405/* CPLD_FLASH_WRITE_CNTL */
406#define PPD7D_CPLD_FLASH_CNTL_WR_LINK_MASK (0x80 >> 0)
407#define PPD7D_CPLD_FLASH_CNTL_WR_LINK_FITTED (0x80 >> 0)
408#define PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_MASK (0x80 >> 2)
409#define PPD7D_CPLD_FLASH_CNTL_BOOT_LINK_FITTED (0x80 >> 2)
410#define PPD7D_CPLD_FLASH_CNTL_USER_LINK_MASK (0x80 >> 3)
411#define PPD7D_CPLD_FLASH_CNTL_USER_LINK_FITTED (0x80 >> 3)
412#define PPD7D_CPLD_FLASH_CNTL_RECO_WR_MASK (0x80 >> 5)
413#define PPD7D_CPLD_FLASH_CNTL_RECO_WR_ENABLED (0x80 >> 5)
414#define PPD7D_CPLD_FLASH_CNTL_BOOT_WR_MASK (0x80 >> 6)
415#define PPD7D_CPLD_FLASH_CNTL_BOOT_WR_ENABLED (0x80 >> 6)
416#define PPD7D_CPLD_FLASH_CNTL_USER_WR_MASK (0x80 >> 7)
417#define PPD7D_CPLD_FLASH_CNTL_USER_WR_ENABLED (0x80 >> 7)
418
419/* CPLD_SW_FLASH_WRITE_PROTECT */
420#define PPC7D_CPLD_SW_FLASH_WRPROT_ENABLED (!0)
421#define PPC7D_CPLD_SW_FLASH_WRPROT_DISABLED (0)
422#define PPC7D_CPLD_SW_FLASH_WRPROT_SYSBOOT_MASK (0x80 >> 6)
423#define PPC7D_CPLD_SW_FLASH_WRPROT_USER_MASK (0x80 >> 7)
424
425/* CPLD_FLASH_WRITE_CNTL */
426#define PPC7D_CPLD_FLASH_CNTL_NVRAM_PROT_MASK (0x80 >> 0)
427#define PPC7D_CPLD_FLASH_CNTL_NVRAM_DISABLED (0 >> 0)
428#define PPC7D_CPLD_FLASH_CNTL_NVRAM_ENABLED (0x80 >> 0)
429#define PPC7D_CPLD_FLASH_CNTL_ALTBOOT_LINK_MASK (0x80 >> 1)
430#define PPC7D_CPLD_FLASH_CNTL_VMEBOOT_LINK_MASK (0x80 >> 2)
431#define PPC7D_CPLD_FLASH_CNTL_RECBOOT_LINK_MASK (0x80 >> 3)
432
433
434#endif /* __PPC_PLATFORMS_PPC7D_H */
diff --git a/arch/ppc/platforms/residual.c b/arch/ppc/platforms/residual.c
new file mode 100644
index 000000000000..0f84ca603612
--- /dev/null
+++ b/arch/ppc/platforms/residual.c
@@ -0,0 +1,1034 @@
1/*
2 * Code to deal with the PReP residual data.
3 *
4 * Written by: Cort Dougan (cort@cs.nmt.edu)
5 * Improved _greatly_ and rewritten by Gabriel Paubert (paubert@iram.es)
6 *
7 * This file is based on the following documentation:
8 *
9 * IBM Power Personal Systems Architecture
10 * Residual Data
11 * Document Number: PPS-AR-FW0001
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file COPYING in the main directory of this archive
15 * for more details.
16 *
17 */
18
19#include <linux/string.h>
20#include <asm/residual.h>
21#include <asm/pnp.h>
22#include <asm/byteorder.h>
23
24#include <linux/errno.h>
25#include <linux/sched.h>
26#include <linux/kernel.h>
27#include <linux/mm.h>
28#include <linux/stddef.h>
29#include <linux/unistd.h>
30#include <linux/ptrace.h>
31#include <linux/slab.h>
32#include <linux/user.h>
33#include <linux/a.out.h>
34#include <linux/tty.h>
35#include <linux/major.h>
36#include <linux/interrupt.h>
37#include <linux/reboot.h>
38#include <linux/init.h>
39#include <linux/ioport.h>
40#include <linux/pci.h>
41#include <linux/ide.h>
42
43#include <asm/sections.h>
44#include <asm/mmu.h>
45#include <asm/io.h>
46#include <asm/pgtable.h>
47#include <asm/ide.h>
48
49
50unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
51RESIDUAL *res = (RESIDUAL *)&__res;
52
53char * PnP_BASE_TYPES[] __initdata = {
54 "Reserved",
55 "MassStorageDevice",
56 "NetworkInterfaceController",
57 "DisplayController",
58 "MultimediaController",
59 "MemoryController",
60 "BridgeController",
61 "CommunicationsDevice",
62 "SystemPeripheral",
63 "InputDevice",
64 "ServiceProcessor"
65 };
66
67/* Device Sub Type Codes */
68
69unsigned char * PnP_SUB_TYPES[] __initdata = {
70 "\001\000SCSIController",
71 "\001\001IDEController",
72 "\001\002FloppyController",
73 "\001\003IPIController",
74 "\001\200OtherMassStorageController",
75 "\002\000EthernetController",
76 "\002\001TokenRingController",
77 "\002\002FDDIController",
78 "\002\0x80OtherNetworkController",
79 "\003\000VGAController",
80 "\003\001SVGAController",
81 "\003\002XGAController",
82 "\003\200OtherDisplayController",
83 "\004\000VideoController",
84 "\004\001AudioController",
85 "\004\200OtherMultimediaController",
86 "\005\000RAM",
87 "\005\001FLASH",
88 "\005\200OtherMemoryDevice",
89 "\006\000HostProcessorBridge",
90 "\006\001ISABridge",
91 "\006\002EISABridge",
92 "\006\003MicroChannelBridge",
93 "\006\004PCIBridge",
94 "\006\005PCMCIABridge",
95 "\006\006VMEBridge",
96 "\006\200OtherBridgeDevice",
97 "\007\000RS232Device",
98 "\007\001ATCompatibleParallelPort",
99 "\007\200OtherCommunicationsDevice",
100 "\010\000ProgrammableInterruptController",
101 "\010\001DMAController",
102 "\010\002SystemTimer",
103 "\010\003RealTimeClock",
104 "\010\004L2Cache",
105 "\010\005NVRAM",
106 "\010\006PowerManagement",
107 "\010\007CMOS",
108 "\010\010OperatorPanel",
109 "\010\011ServiceProcessorClass1",
110 "\010\012ServiceProcessorClass2",
111 "\010\013ServiceProcessorClass3",
112 "\010\014GraphicAssist",
113 "\010\017SystemPlanar",
114 "\010\200OtherSystemPeripheral",
115 "\011\000KeyboardController",
116 "\011\001Digitizer",
117 "\011\002MouseController",
118 "\011\003TabletController",
119 "\011\0x80OtherInputController",
120 "\012\000GeneralMemoryController",
121 NULL
122};
123
124/* Device Interface Type Codes */
125
126unsigned char * PnP_INTERFACES[] __initdata = {
127 "\000\000\000General",
128 "\001\000\000GeneralSCSI",
129 "\001\001\000GeneralIDE",
130 "\001\001\001ATACompatible",
131
132 "\001\002\000GeneralFloppy",
133 "\001\002\001Compatible765",
134 "\001\002\002NS398_Floppy", /* NS Super I/O wired to use index
135 register at port 398 and data
136 register at port 399 */
137 "\001\002\003NS26E_Floppy", /* Ports 26E and 26F */
138 "\001\002\004NS15C_Floppy", /* Ports 15C and 15D */
139 "\001\002\005NS2E_Floppy", /* Ports 2E and 2F */
140 "\001\002\006CHRP_Floppy", /* CHRP Floppy in PR*P system */
141
142 "\001\003\000GeneralIPI",
143
144 "\002\000\000GeneralEther",
145 "\002\001\000GeneralToken",
146 "\002\002\000GeneralFDDI",
147
148 "\003\000\000GeneralVGA",
149 "\003\001\000GeneralSVGA",
150 "\003\002\000GeneralXGA",
151
152 "\004\000\000GeneralVideo",
153 "\004\001\000GeneralAudio",
154 "\004\001\001CS4232Audio", /* CS 4232 Plug 'n Play Configured */
155
156 "\005\000\000GeneralRAM",
157 /* This one is obviously wrong ! */
158 "\005\000\000PCIMemoryController", /* PCI Config Method */
159 "\005\000\001RS6KMemoryController", /* RS6K Config Method */
160 "\005\001\000GeneralFLASH",
161
162 "\006\000\000GeneralHostBridge",
163 "\006\001\000GeneralISABridge",
164 "\006\002\000GeneralEISABridge",
165 "\006\003\000GeneralMCABridge",
166 /* GeneralPCIBridge = 0, */
167 "\006\004\000PCIBridgeDirect",
168 "\006\004\001PCIBridgeIndirect",
169 "\006\004\002PCIBridgeRS6K",
170 "\006\005\000GeneralPCMCIABridge",
171 "\006\006\000GeneralVMEBridge",
172
173 "\007\000\000GeneralRS232",
174 "\007\000\001COMx",
175 "\007\000\002Compatible16450",
176 "\007\000\003Compatible16550",
177 "\007\000\004NS398SerPort", /* NS Super I/O wired to use index
178 register at port 398 and data
179 register at port 399 */
180 "\007\000\005NS26ESerPort", /* Ports 26E and 26F */
181 "\007\000\006NS15CSerPort", /* Ports 15C and 15D */
182 "\007\000\007NS2ESerPort", /* Ports 2E and 2F */
183
184 "\007\001\000GeneralParPort",
185 "\007\001\001LPTx",
186 "\007\001\002NS398ParPort", /* NS Super I/O wired to use index
187 register at port 398 and data
188 register at port 399 */
189 "\007\001\003NS26EParPort", /* Ports 26E and 26F */
190 "\007\001\004NS15CParPort", /* Ports 15C and 15D */
191 "\007\001\005NS2EParPort", /* Ports 2E and 2F */
192
193 "\010\000\000GeneralPIC",
194 "\010\000\001ISA_PIC",
195 "\010\000\002EISA_PIC",
196 "\010\000\003MPIC",
197 "\010\000\004RS6K_PIC",
198
199 "\010\001\000GeneralDMA",
200 "\010\001\001ISA_DMA",
201 "\010\001\002EISA_DMA",
202
203 "\010\002\000GeneralTimer",
204 "\010\002\001ISA_Timer",
205 "\010\002\002EISA_Timer",
206 "\010\003\000GeneralRTC",
207 "\010\003\001ISA_RTC",
208
209 "\010\004\001StoreThruOnly",
210 "\010\004\002StoreInEnabled",
211 "\010\004\003RS6KL2Cache",
212
213 "\010\005\000IndirectNVRAM", /* Indirectly addressed */
214 "\010\005\001DirectNVRAM", /* Memory Mapped */
215 "\010\005\002IndirectNVRAM24", /* Indirectly addressed - 24 bit */
216
217 "\010\006\000GeneralPowerManagement",
218 "\010\006\001EPOWPowerManagement",
219 "\010\006\002PowerControl", // d1378
220
221 "\010\007\000GeneralCMOS",
222
223 "\010\010\000GeneralOPPanel",
224 "\010\010\001HarddiskLight",
225 "\010\010\002CDROMLight",
226 "\010\010\003PowerLight",
227 "\010\010\004KeyLock",
228 "\010\010\005ANDisplay", /* AlphaNumeric Display */
229 "\010\010\006SystemStatusLED", /* 3 digit 7 segment LED */
230 "\010\010\007CHRP_SystemStatusLED", /* CHRP LEDs in PR*P system */
231
232 "\010\011\000GeneralServiceProcessor",
233 "\010\012\000GeneralServiceProcessor",
234 "\010\013\000GeneralServiceProcessor",
235
236 "\010\014\001TransferData",
237 "\010\014\002IGMC32",
238 "\010\014\003IGMC64",
239
240 "\010\017\000GeneralSystemPlanar", /* 10/5/95 */
241 NULL
242 };
243
244static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType,
245 unsigned char SubType) {
246 unsigned char ** s=PnP_SUB_TYPES;
247 while (*s && !((*s)[0]==BaseType
248 && (*s)[1]==SubType)) s++;
249 if (*s) return *s+2;
250 else return("Unknown !");
251};
252
253static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType,
254 unsigned char SubType,
255 unsigned char Interface) {
256 unsigned char ** s=PnP_INTERFACES;
257 while (*s && !((*s)[0]==BaseType
258 && (*s)[1]==SubType
259 && (*s)[2]==Interface)) s++;
260 if (*s) return *s+3;
261 else return NULL;
262};
263
264static void __init printsmallvendor(PnP_TAG_PACKET *pkt, int size) {
265 int i, c;
266 char decomp[4];
267#define p pkt->S14_Pack.S14_Data.S14_PPCPack
268 switch(p.Type) {
269 case 1:
270 /* Decompress first 3 chars */
271 c = *(unsigned short *)p.PPCData;
272 decomp[0]='A'-1+((c>>10)&0x1F);
273 decomp[1]='A'-1+((c>>5)&0x1F);
274 decomp[2]='A'-1+(c&0x1F);
275 decomp[3]=0;
276 printk(" Chip identification: %s%4.4X\n",
277 decomp, ld_le16((unsigned short *)(p.PPCData+2)));
278 break;
279 default:
280 printk(" Small vendor item type 0x%2.2x, data (hex): ",
281 p.Type);
282 for(i=0; i<size-2; i++) printk("%2.2x ", p.PPCData[i]);
283 printk("\n");
284 break;
285 }
286#undef p
287}
288
289static void __init printsmallpacket(PnP_TAG_PACKET * pkt, int size) {
290 static const unsigned char * intlevel[] = {"high", "low"};
291 static const unsigned char * intsense[] = {"edge", "level"};
292
293 switch (tag_small_item_name(pkt->S1_Pack.Tag)) {
294 case PnPVersion:
295 printk(" PnPversion 0x%x.%x\n",
296 pkt->S1_Pack.Version[0], /* How to interpret version ? */
297 pkt->S1_Pack.Version[1]);
298 break;
299// case Logicaldevice:
300 break;
301// case CompatibleDevice:
302 break;
303 case IRQFormat:
304#define p pkt->S4_Pack
305 printk(" IRQ Mask 0x%4.4x, %s %s sensitive\n",
306 ld_le16((unsigned short *)p.IRQMask),
307 intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0],
308 intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]);
309#undef p
310 break;
311 case DMAFormat:
312#define p pkt->S5_Pack
313 printk(" DMA channel mask 0x%2.2x, info 0x%2.2x\n",
314 p.DMAMask, p.DMAInfo);
315#undef p
316 break;
317 case StartDepFunc:
318 printk("Start dependent function:\n");
319 break;
320 case EndDepFunc:
321 printk("End dependent function\n");
322 break;
323 case IOPort:
324#define p pkt->S8_Pack
325 printk(" Variable (%d decoded bits) I/O port\n"
326 " from 0x%4.4x to 0x%4.4x, alignment %d, %d ports\n",
327 p.IOInfo&ISAAddr16bit?16:10,
328 ld_le16((unsigned short *)p.RangeMin),
329 ld_le16((unsigned short *)p.RangeMax),
330 p.IOAlign, p.IONum);
331#undef p
332 break;
333 case FixedIOPort:
334#define p pkt->S9_Pack
335 printk(" Fixed (10 decoded bits) I/O port from %3.3x to %3.3x\n",
336 (p.Range[1]<<8)|p.Range[0],
337 ((p.Range[1]<<8)|p.Range[0])+p.IONum-1);
338#undef p
339 break;
340 case Res1:
341 case Res2:
342 case Res3:
343 printk(" Undefined packet type %d!\n",
344 tag_small_item_name(pkt->S1_Pack.Tag));
345 break;
346 case SmallVendorItem:
347 printsmallvendor(pkt,size);
348 break;
349 default:
350 printk(" Type 0x2.2x%d, size=%d\n",
351 pkt->S1_Pack.Tag, size);
352 break;
353 }
354}
355
356static void __init printlargevendor(PnP_TAG_PACKET * pkt, int size) {
357 static const unsigned char * addrtype[] = {"I/O", "Memory", "System"};
358 static const unsigned char * inttype[] = {"8259", "MPIC", "RS6k BUID %d"};
359 static const unsigned char * convtype[] = {"Bus Memory", "Bus I/O", "DMA"};
360 static const unsigned char * transtype[] = {"direct", "mapped", "direct-store segment"};
361 static const unsigned char * L2type[] = {"WriteThru", "CopyBack"};
362 static const unsigned char * L2assoc[] = {"DirectMapped", "2-way set"};
363
364 int i;
365 char tmpstr[30], *t;
366#define p pkt->L4_Pack.L4_Data.L4_PPCPack
367 switch(p.Type) {
368 case 2:
369 printk(" %d K %s %s L2 cache, %d/%d bytes line/sector size\n",
370 ld_le32((unsigned int *)p.PPCData),
371 L2type[p.PPCData[10]-1],
372 L2assoc[p.PPCData[4]-1],
373 ld_le16((unsigned short *)p.PPCData+3),
374 ld_le16((unsigned short *)p.PPCData+4));
375 break;
376 case 3:
377 printk(" PCI Bridge parameters\n"
378 " ConfigBaseAddress %0x\n"
379 " ConfigBaseData %0x\n"
380 " Bus number %d\n",
381 ld_le32((unsigned int *)p.PPCData),
382 ld_le32((unsigned int *)(p.PPCData+8)),
383 p.PPCData[16]);
384 for(i=20; i<size-4; i+=12) {
385 int j, first;
386 if(p.PPCData[i]) printk(" PCI Slot %d", p.PPCData[i]);
387 else printk (" Integrated PCI device");
388 for(j=0, first=1, t=tmpstr; j<4; j++) {
389 int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
390 if(line!=0xffff){
391 if(first) first=0; else *t++='/';
392 *t++='A'+j;
393 }
394 }
395 *t='\0';
396 printk(" DevFunc 0x%x interrupt line(s) %s routed to",
397 p.PPCData[i+1],tmpstr);
398 sprintf(tmpstr,
399 inttype[p.PPCData[i+2]-1],
400 p.PPCData[i+3]);
401 printk(" %s line(s) ",
402 tmpstr);
403 for(j=0, first=1, t=tmpstr; j<4; j++) {
404 int line=ld_le16((unsigned short *)(p.PPCData+i+4)+j);
405 if(line!=0xffff){
406 if(first) first=0; else *t++='/';
407 t+=sprintf(t,"%d(%c)",
408 line&0x7fff,
409 line&0x8000?'E':'L');
410 }
411 }
412 printk("%s\n",tmpstr);
413 }
414 break;
415 case 5:
416 printk(" Bridge address translation, %s decoding:\n"
417 " Processor Bus Size Conversion Translation\n"
418 " 0x%8.8x 0x%8.8x 0x%8.8x %s %s\n",
419 p.PPCData[0]&1 ? "positive" : "subtractive",
420 ld_le32((unsigned int *)p.PPCData+1),
421 ld_le32((unsigned int *)p.PPCData+3),
422 ld_le32((unsigned int *)p.PPCData+5),
423 convtype[p.PPCData[2]-1],
424 transtype[p.PPCData[1]-1]);
425 break;
426 case 6:
427 printk(" Bus speed %d Hz, %d slot(s)\n",
428 ld_le32((unsigned int *)p.PPCData),
429 p.PPCData[4]);
430 break;
431 case 7:
432 printk(" SCSI buses: %d, id(s):", p.PPCData[0]);
433 for(i=1; i<=p.PPCData[0]; i++)
434 printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? '\n' : ',');
435 break;
436 case 9:
437 printk(" %s address (%d bits), at 0x%x size 0x%x bytes\n",
438 addrtype[p.PPCData[0]-1],
439 p.PPCData[1],
440 ld_le32((unsigned int *)(p.PPCData+4)),
441 ld_le32((unsigned int *)(p.PPCData+12)));
442 break;
443 case 10:
444 sprintf(tmpstr,
445 inttype[p.PPCData[0]-1],
446 p.PPCData[1]);
447
448 printk(" ISA interrupts routed to %s\n"
449 " lines",
450 tmpstr);
451 for(i=0; i<16; i++) {
452 int line=ld_le16((unsigned short *)p.PPCData+i+1);
453 if (line!=0xffff) printk(" %d(IRQ%d)", line, i);
454 }
455 printk("\n");
456 break;
457 default:
458 printk(" Large vendor item type 0x%2.2x\n Data (hex):",
459 p.Type);
460 for(i=0; i<size-4; i++) printk(" %2.2x", p.PPCData[i]);
461 printk("\n");
462#undef p
463 }
464}
465
466static void __init printlargepacket(PnP_TAG_PACKET * pkt, int size) {
467 switch (tag_large_item_name(pkt->S1_Pack.Tag)) {
468 case LargeVendorItem:
469 printlargevendor(pkt, size);
470 break;
471 default:
472 printk(" Type 0x2.2x%d, size=%d\n",
473 pkt->S1_Pack.Tag, size);
474 break;
475 }
476}
477
478static void __init printpackets(PnP_TAG_PACKET * pkt, const char * cat)
479{
480 if (pkt->S1_Pack.Tag== END_TAG) {
481 printk(" No packets describing %s resources.\n", cat);
482 return;
483 }
484 printk( " Packets describing %s resources:\n",cat);
485 do {
486 int size;
487 if (tag_type(pkt->S1_Pack.Tag)) {
488 size= 3 +
489 pkt->L1_Pack.Count0 +
490 pkt->L1_Pack.Count1*256;
491 printlargepacket(pkt, size);
492 } else {
493 size=tag_small_count(pkt->S1_Pack.Tag)+1;
494 printsmallpacket(pkt, size);
495 }
496 pkt = (PnP_TAG_PACKET *)((unsigned char *) pkt + size);
497 } while (pkt->S1_Pack.Tag != END_TAG);
498}
499
500void __init print_residual_device_info(void)
501{
502 int i;
503 PPC_DEVICE *dev;
504#define did dev->DeviceId
505
506 /* make sure we have residual data first */
507 if (!have_residual_data)
508 return;
509
510 printk("Residual: %ld devices\n", res->ActualNumDevices);
511 for ( i = 0;
512 i < res->ActualNumDevices ;
513 i++)
514 {
515 char decomp[4], sn[20];
516 const char * s;
517 dev = &res->Devices[i];
518 s = PnP_INTERFACE_STR(did.BaseType, did.SubType,
519 did.Interface);
520 if(!s) {
521 sprintf(sn, "interface %d", did.Interface);
522 s=sn;
523 }
524 if ( did.BusId & PCIDEVICE )
525 printk("PCI Device, Bus %d, DevFunc 0x%x:",
526 dev->BusAccess.PCIAccess.BusNumber,
527 dev->BusAccess.PCIAccess.DevFuncNumber);
528 if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
529 if ( did.BusId & ISADEVICE )
530 printk("ISA Device, Slot %d, LogicalDev %d:",
531 dev->BusAccess.ISAAccess.SlotNumber,
532 dev->BusAccess.ISAAccess.LogicalDevNumber);
533 if ( did.BusId & EISADEVICE ) printk("EISA Device:");
534 if ( did.BusId & PROCESSORDEVICE )
535 printk("ProcBus Device, Bus %d, BUID %d: ",
536 dev->BusAccess.ProcBusAccess.BusNumber,
537 dev->BusAccess.ProcBusAccess.BUID);
538 if ( did.BusId & PCMCIADEVICE ) printk("PCMCIA ");
539 if ( did.BusId & VMEDEVICE ) printk("VME ");
540 if ( did.BusId & MCADEVICE ) printk("MCA ");
541 if ( did.BusId & MXDEVICE ) printk("MX ");
542 /* Decompress first 3 chars */
543 decomp[0]='A'-1+((did.DevId>>26)&0x1F);
544 decomp[1]='A'-1+((did.DevId>>21)&0x1F);
545 decomp[2]='A'-1+((did.DevId>>16)&0x1F);
546 decomp[3]=0;
547 printk(" %s%4.4lX, %s, %s, %s\n",
548 decomp, did.DevId&0xffff,
549 PnP_BASE_TYPES[did.BaseType],
550 PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
551 s);
552 if ( dev->AllocatedOffset )
553 printpackets( (union _PnP_TAG_PACKET *)
554 &res->DevicePnPHeap[dev->AllocatedOffset],
555 "allocated");
556 if ( dev->PossibleOffset )
557 printpackets( (union _PnP_TAG_PACKET *)
558 &res->DevicePnPHeap[dev->PossibleOffset],
559 "possible");
560 if ( dev->CompatibleOffset )
561 printpackets( (union _PnP_TAG_PACKET *)
562 &res->DevicePnPHeap[dev->CompatibleOffset],
563 "compatible");
564 }
565}
566
567
568#if 0
569static void __init printVPD(void) {
570#define vpd res->VitalProductData
571 int ps=vpd.PageSize, i, j;
572 static const char* Usage[]={
573 "FirmwareStack", "FirmwareHeap", "FirmwareCode", "BootImage",
574 "Free", "Unpopulated", "ISAAddr", "PCIConfig",
575 "IOMemory", "SystemIO", "SystemRegs", "PCIAddr",
576 "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other"
577 };
578 static const unsigned char *FWMan[]={
579 "IBM", "Motorola", "FirmWorks", "Bull"
580 };
581 static const unsigned char *FWFlags[]={
582 "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
583 "MultiBoot", "LowClient", "Hex41", "FAT",
584 "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
585 };
586 static const unsigned char *ESM[]={
587 "Port92", "PCIConfigA8", "FF001030", "????????"
588 };
589 static const unsigned char *SIOM[]={
590 "Port850", "????????", "PCIConfigA8", "????????"
591 };
592
593 printk("Model: %s\n",vpd.PrintableModel);
594 printk("Serial: %s\n", vpd.Serial);
595 printk("FirmwareSupplier: %s\n", FWMan[vpd.FirmwareSupplier]);
596 printk("FirmwareFlags:");
597 for(j=0; j<12; j++) {
598 if (vpd.FirmwareSupports & (1<<j)) {
599 printk(" %s%c", FWFlags[j],
600 vpd.FirmwareSupports&(-2<<j) ? ',' : '\n');
601 }
602 }
603 printk("NVRamSize: %ld\n", vpd.NvramSize);
604 printk("SIMMslots: %ld\n", vpd.NumSIMMSlots);
605 printk("EndianSwitchMethod: %s\n",
606 ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
607 printk("SpreadIOMethod: %s\n",
608 SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
609 printk("Processor/Bus frequencies (Hz): %ld/%ld\n",
610 vpd.ProcessorHz, vpd.ProcessorBusHz);
611 printk("Time Base Divisor: %ld\n", vpd.TimeBaseDivisor);
612 printk("WordWidth, PageSize: %ld, %d\n", vpd.WordWidth, ps);
613 printk("Cache sector size, Lock granularity: %ld, %ld\n",
614 vpd.CoherenceBlockSize, vpd.GranuleSize);
615 for (i=0; i<res->ActualNumMemSegs; i++) {
616 int mask=res->Segs[i].Usage, first, j;
617 printk("%8.8lx-%8.8lx ",
618 res->Segs[i].BasePage*ps,
619 (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
620 for(j=15, first=1; j>=0; j--) {
621 if (mask&(1<<j)) {
622 if (first) first=0;
623 else printk(", ");
624 printk("%s", Usage[j]);
625 }
626 }
627 printk("\n");
628 }
629}
630
631/*
632 * Spit out some info about residual data
633 */
634void print_residual_device_info(void)
635{
636 int i;
637 union _PnP_TAG_PACKET *pkt;
638 PPC_DEVICE *dev;
639#define did dev->DeviceId
640
641 /* make sure we have residual data first */
642 if (!have_residual_data)
643 return;
644 printk("Residual: %ld devices\n", res->ActualNumDevices);
645 for ( i = 0;
646 i < res->ActualNumDevices ;
647 i++)
648 {
649 dev = &res->Devices[i];
650 /*
651 * pci devices
652 */
653 if ( did.BusId & PCIDEVICE )
654 {
655 printk("PCI Device:");
656 /* unknown vendor */
657 if ( !strncmp( "Unknown", pci_strvendor(did.DevId>>16), 7) )
658 printk(" id %08lx types %d/%d", did.DevId,
659 did.BaseType, did.SubType);
660 /* known vendor */
661 else
662 printk(" %s %s",
663 pci_strvendor(did.DevId>>16),
664 pci_strdev(did.DevId>>16,
665 did.DevId&0xffff)
666 );
667
668 if ( did.BusId & PNPISADEVICE )
669 {
670 printk(" pnp:");
671 /* get pnp info on the device */
672 pkt = (union _PnP_TAG_PACKET *)
673 &res->DevicePnPHeap[dev->AllocatedOffset];
674 for (; pkt->S1_Pack.Tag != DF_END_TAG;
675 pkt++ )
676 {
677 if ( (pkt->S1_Pack.Tag == S4_Packet) ||
678 (pkt->S1_Pack.Tag == S4_Packet_flags) )
679 printk(" irq %02x%02x",
680 pkt->S4_Pack.IRQMask[0],
681 pkt->S4_Pack.IRQMask[1]);
682 }
683 }
684 printk("\n");
685 continue;
686 }
687 /*
688 * isa devices
689 */
690 if ( did.BusId & ISADEVICE )
691 {
692 printk("ISA Device: basetype: %d subtype: %d",
693 did.BaseType, did.SubType);
694 printk("\n");
695 continue;
696 }
697 /*
698 * eisa devices
699 */
700 if ( did.BusId & EISADEVICE )
701 {
702 printk("EISA Device: basetype: %d subtype: %d",
703 did.BaseType, did.SubType);
704 printk("\n");
705 continue;
706 }
707 /*
708 * proc bus devices
709 */
710 if ( did.BusId & PROCESSORDEVICE )
711 {
712 printk("ProcBus Device: basetype: %d subtype: %d",
713 did.BaseType, did.SubType);
714 printk("\n");
715 continue;
716 }
717 /*
718 * pcmcia devices
719 */
720 if ( did.BusId & PCMCIADEVICE )
721 {
722 printk("PCMCIA Device: basetype: %d subtype: %d",
723 did.BaseType, did.SubType);
724 printk("\n");
725 continue;
726 }
727 printk("Unknown bus access device: busid %lx\n",
728 did.BusId);
729 }
730}
731#endif
732
733/* Returns the device index in the residual data,
734 any of the search items may be set as -1 for wildcard,
735 DevID number field (second halfword) is big endian !
736
737 Examples:
738 - search for the Interrupt controller (8259 type), 2 methods:
739 1) i8259 = residual_find_device(~0,
740 NULL,
741 SystemPeripheral,
742 ProgrammableInterruptController,
743 ISA_PIC,
744 0);
745 2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0)
746
747 - search for the first two serial devices, whatever their type)
748 iserial1 = residual_find_device(~0,NULL,
749 CommunicationsDevice,
750 RS232Device,
751 -1, 0)
752 iserial2 = residual_find_device(~0,NULL,
753 CommunicationsDevice,
754 RS232Device,
755 -1, 1)
756 - but search for typical COM1 and COM2 is not easy due to the
757 fact that the interface may be anything and the name "PNP0500" or
758 "PNP0501". Quite bad.
759
760*/
761
762/* devid are easier to uncompress than to compress, so to minimize bloat
763in this rarely used area we unencode and compare */
764
765/* in residual data number is big endian in the device table and
766little endian in the heap, so we use two parameters to avoid writing
767two very similar functions */
768
769static int __init same_DevID(unsigned short vendor,
770 unsigned short Number,
771 char * str)
772{
773 static unsigned const char hexdigit[]="0123456789ABCDEF";
774 if (strlen(str)!=7) return 0;
775 if ( ( ((vendor>>10)&0x1f)+'A'-1 == str[0]) &&
776 ( ((vendor>>5)&0x1f)+'A'-1 == str[1]) &&
777 ( (vendor&0x1f)+'A'-1 == str[2]) &&
778 (hexdigit[(Number>>12)&0x0f] == str[3]) &&
779 (hexdigit[(Number>>8)&0x0f] == str[4]) &&
780 (hexdigit[(Number>>4)&0x0f] == str[5]) &&
781 (hexdigit[Number&0x0f] == str[6]) ) return 1;
782 return 0;
783}
784
785PPC_DEVICE __init *residual_find_device(unsigned long BusMask,
786 unsigned char * DevID,
787 int BaseType,
788 int SubType,
789 int Interface,
790 int n)
791{
792 int i;
793 if (!have_residual_data) return NULL;
794 for (i=0; i<res->ActualNumDevices; i++) {
795#define Dev res->Devices[i].DeviceId
796 if ( (Dev.BusId&BusMask) &&
797 (BaseType==-1 || Dev.BaseType==BaseType) &&
798 (SubType==-1 || Dev.SubType==SubType) &&
799 (Interface==-1 || Dev.Interface==Interface) &&
800 (DevID==NULL || same_DevID((Dev.DevId>>16)&0xffff,
801 Dev.DevId&0xffff, DevID)) &&
802 !(n--) ) return res->Devices+i;
803#undef Dev
804 }
805 return NULL;
806}
807
808PPC_DEVICE __init *residual_find_device_id(unsigned long BusMask,
809 unsigned short DevID,
810 int BaseType,
811 int SubType,
812 int Interface,
813 int n)
814{
815 int i;
816 if (!have_residual_data) return NULL;
817 for (i=0; i<res->ActualNumDevices; i++) {
818#define Dev res->Devices[i].DeviceId
819 if ( (Dev.BusId&BusMask) &&
820 (BaseType==-1 || Dev.BaseType==BaseType) &&
821 (SubType==-1 || Dev.SubType==SubType) &&
822 (Interface==-1 || Dev.Interface==Interface) &&
823 (DevID==0xffff || (Dev.DevId&0xffff) == DevID) &&
824 !(n--) ) return res->Devices+i;
825#undef Dev
826 }
827 return NULL;
828}
829
830static int __init
831residual_scan_pcibridge(PnP_TAG_PACKET * pkt, struct pci_dev *dev)
832{
833 int irq = -1;
834
835#define data pkt->L4_Pack.L4_Data.L4_PPCPack.PPCData
836 if (dev->bus->number == data[16]) {
837 int i, size;
838
839 size = 3 + ld_le16((u_short *) (&pkt->L4_Pack.Count0));
840 for (i = 20; i < size - 4; i += 12) {
841 unsigned char pin;
842 int line_irq;
843
844 if (dev->devfn != data[i + 1])
845 continue;
846
847 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
848 if (pin) {
849 line_irq = ld_le16((unsigned short *)
850 (&data[i + 4 + 2 * (pin - 1)]));
851 irq = (line_irq == 0xffff) ? 0
852 : line_irq & 0x7fff;
853 } else
854 irq = 0;
855
856 break;
857 }
858 }
859#undef data
860
861 return irq;
862}
863
864int __init
865residual_pcidev_irq(struct pci_dev *dev)
866{
867 int i = 0;
868 int irq = -1;
869 PPC_DEVICE *bridge;
870
871 while ((bridge = residual_find_device
872 (-1, NULL, BridgeController, PCIBridge, -1, i++))) {
873
874 PnP_TAG_PACKET *pkt;
875 if (bridge->AllocatedOffset) {
876 pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
877 bridge->AllocatedOffset, 3, 0);
878 if (!pkt)
879 continue;
880
881 irq = residual_scan_pcibridge(pkt, dev);
882 if (irq != -1)
883 break;
884 }
885 }
886
887 return (irq < 0) ? 0 : irq;
888}
889
890void __init residual_irq_mask(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
891{
892 PPC_DEVICE *dev;
893 int i = 0;
894 unsigned short irq_mask = 0x000; /* default to edge */
895
896 while ((dev = residual_find_device(-1, NULL, -1, -1, -1, i++))) {
897 PnP_TAG_PACKET *pkt;
898 unsigned short mask;
899 int size;
900 int offset = dev->AllocatedOffset;
901
902 if (!offset)
903 continue;
904
905 pkt = PnP_find_packet(res->DevicePnPHeap + offset,
906 IRQFormat, 0);
907 if (!pkt)
908 continue;
909
910 size = tag_small_count(pkt->S1_Pack.Tag) + 1;
911 mask = ld_le16((unsigned short *)pkt->S4_Pack.IRQMask);
912 if (size > 3 && (pkt->S4_Pack.IRQInfo & 0x0c))
913 irq_mask |= mask;
914 }
915
916 *irq_edge_mask_lo = irq_mask & 0xff;
917 *irq_edge_mask_hi = irq_mask >> 8;
918}
919
920unsigned int __init residual_isapic_addr(void)
921{
922 PPC_DEVICE *isapic;
923 PnP_TAG_PACKET *pkt;
924 unsigned int addr;
925
926 isapic = residual_find_device(~0, NULL, SystemPeripheral,
927 ProgrammableInterruptController,
928 ISA_PIC, 0);
929 if (!isapic)
930 goto unknown;
931
932 pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
933 isapic->AllocatedOffset, 9, 0);
934 if (!pkt)
935 goto unknown;
936
937#define p pkt->L4_Pack.L4_Data.L4_PPCPack
938 /* Must be 32-bit system address */
939 if (!((p.PPCData[0] == 3) && (p.PPCData[1] == 32)))
940 goto unknown;
941
942 /* It doesn't seem to work where length != 1 (what can I say? :-/ ) */
943 if (ld_le32((unsigned int *)(p.PPCData + 12)) != 1)
944 goto unknown;
945
946 addr = ld_le32((unsigned int *) (p.PPCData + 4));
947#undef p
948 return addr;
949unknown:
950 return 0;
951}
952
953PnP_TAG_PACKET *PnP_find_packet(unsigned char *p,
954 unsigned packet_tag,
955 int n)
956{
957 unsigned mask, masked_tag, size;
958 if(!p) return NULL;
959 if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
960 masked_tag = packet_tag&mask;
961 for(; *p != END_TAG; p+=size) {
962 if ((*p & mask) == masked_tag && !(n--))
963 return (PnP_TAG_PACKET *) p;
964 if (tag_type(*p))
965 size=ld_le16((unsigned short *)(p+1))+3;
966 else
967 size=tag_small_count(*p)+1;
968 }
969 return NULL; /* not found */
970}
971
972PnP_TAG_PACKET __init *PnP_find_small_vendor_packet(unsigned char *p,
973 unsigned packet_type,
974 int n)
975{
976 int next=0;
977 while (p) {
978 p = (unsigned char *) PnP_find_packet(p, 0x70, next);
979 if (p && p[1]==packet_type && !(n--))
980 return (PnP_TAG_PACKET *) p;
981 next = 1;
982 };
983 return NULL; /* not found */
984}
985
986PnP_TAG_PACKET __init *PnP_find_large_vendor_packet(unsigned char *p,
987 unsigned packet_type,
988 int n)
989{
990 int next=0;
991 while (p) {
992 p = (unsigned char *) PnP_find_packet(p, 0x84, next);
993 if (p && p[3]==packet_type && !(n--))
994 return (PnP_TAG_PACKET *) p;
995 next = 1;
996 };
997 return NULL; /* not found */
998}
999
1000#ifdef CONFIG_PROC_PREPRESIDUAL
1001static int proc_prep_residual_read(char * buf, char ** start, off_t off,
1002 int count, int *eof, void *data)
1003{
1004 int n;
1005
1006 n = res->ResidualLength - off;
1007 if (n < 0) {
1008 *eof = 1;
1009 n = 0;
1010 }
1011 else {
1012 if (n > count)
1013 n = count;
1014 else
1015 *eof = 1;
1016
1017 memcpy(buf, (char *)res + off, n);
1018 *start = buf;
1019 }
1020
1021 return n;
1022}
1023
1024int __init
1025proc_prep_residual_init(void)
1026{
1027 if (have_residual_data)
1028 create_proc_read_entry("residual", S_IRUGO, NULL,
1029 proc_prep_residual_read, NULL);
1030 return 0;
1031}
1032
1033__initcall(proc_prep_residual_init);
1034#endif
diff --git a/arch/ppc/platforms/rpx8260.h b/arch/ppc/platforms/rpx8260.h
new file mode 100644
index 000000000000..843494a50ef3
--- /dev/null
+++ b/arch/ppc/platforms/rpx8260.h
@@ -0,0 +1,81 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the Embedded Planet RPX6 (or RPX Super) MPC8260 board.
4 * Copied from the RPX-Classic and SBS8260 stuff.
5 *
6 * Copyright (c) 2001 Dan Malek <dan@embeddededge.com>
7 */
8#ifdef __KERNEL__
9#ifndef __ASM_PLATFORMS_RPX8260_H__
10#define __ASM_PLATFORMS_RPX8260_H__
11
12/* A Board Information structure that is given to a program when
13 * prom starts it up.
14 */
15typedef struct bd_info {
16 unsigned int bi_memstart; /* Memory start address */
17 unsigned int bi_memsize; /* Memory (end) size in bytes */
18 unsigned int bi_nvsize; /* NVRAM size in bytes (can be 0) */
19 unsigned int bi_intfreq; /* Internal Freq, in Hz */
20 unsigned int bi_busfreq; /* Bus Freq, in MHz */
21 unsigned int bi_cpmfreq; /* CPM Freq, in MHz */
22 unsigned int bi_brgfreq; /* BRG Freq, in MHz */
23 unsigned int bi_vco; /* VCO Out from PLL */
24 unsigned int bi_baudrate; /* Default console baud rate */
25 unsigned int bi_immr; /* IMMR when called from boot rom */
26 unsigned char bi_enetaddr[6];
27} bd_t;
28
29extern bd_t m8xx_board_info;
30
31/* Memory map is configured by the PROM startup.
32 * We just map a few things we need. The CSR is actually 4 byte-wide
33 * registers that can be accessed as 8-, 16-, or 32-bit values.
34 */
35#define CPM_MAP_ADDR ((uint)0xf0000000)
36#define RPX_CSR_ADDR ((uint)0xfa000000)
37#define RPX_CSR_SIZE ((uint)(512 * 1024))
38#define RPX_NVRTC_ADDR ((uint)0xfa080000)
39#define RPX_NVRTC_SIZE ((uint)(512 * 1024))
40
41/* The RPX6 has 16, byte wide control/status registers.
42 * Not all are used (yet).
43 */
44extern volatile u_char *rpx6_csr_addr;
45
46/* Things of interest in the CSR.
47*/
48#define BCSR0_ID_MASK ((u_char)0xf0) /* Read only */
49#define BCSR0_SWITCH_MASK ((u_char)0x0f) /* Read only */
50#define BCSR1_XCVR_SMC1 ((u_char)0x80)
51#define BCSR1_XCVR_SMC2 ((u_char)0x40)
52#define BCSR2_FLASH_WENABLE ((u_char)0x20)
53#define BCSR2_NVRAM_ENABLE ((u_char)0x10)
54#define BCSR2_ALT_IRQ2 ((u_char)0x08)
55#define BCSR2_ALT_IRQ3 ((u_char)0x04)
56#define BCSR2_PRST ((u_char)0x02) /* Force reset */
57#define BCSR2_ENPRST ((u_char)0x01) /* Enable POR */
58#define BCSR3_MODCLK_MASK ((u_char)0xe0)
59#define BCSR3_ENCLKHDR ((u_char)0x10)
60#define BCSR3_LED5 ((u_char)0x04) /* 0 == on */
61#define BCSR3_LED6 ((u_char)0x02) /* 0 == on */
62#define BCSR3_LED7 ((u_char)0x01) /* 0 == on */
63#define BCSR4_EN_PHY ((u_char)0x80) /* Enable PHY */
64#define BCSR4_EN_MII ((u_char)0x40) /* Enable PHY */
65#define BCSR4_MII_READ ((u_char)0x04)
66#define BCSR4_MII_MDC ((u_char)0x02)
67#define BCSR4_MII_MDIO ((u_char)0x01)
68#define BCSR13_FETH_IRQMASK ((u_char)0xf0)
69#define BCSR15_FETH_IRQ ((u_char)0x20)
70
71#define PHY_INTERRUPT SIU_INT_IRQ7
72
73/* For our show_cpuinfo hooks. */
74#define CPUINFO_VENDOR "Embedded Planet"
75#define CPUINFO_MACHINE "EP8260 PowerPC"
76
77/* Warm reset vector. */
78#define BOOTROM_RESTART_ADDR ((uint)0xfff00104)
79
80#endif /* __ASM_PLATFORMS_RPX8260_H__ */
81#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/rpxclassic.h b/arch/ppc/platforms/rpxclassic.h
new file mode 100644
index 000000000000..6daa109491c4
--- /dev/null
+++ b/arch/ppc/platforms/rpxclassic.h
@@ -0,0 +1,119 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the RPCG RPX-Classic board. Copied from the RPX-Lite stuff.
4 *
5 * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
6 */
7#ifdef __KERNEL__
8#ifndef __MACH_RPX_DEFS
9#define __MACH_RPX_DEFS
10
11#include <linux/config.h>
12
13#ifndef __ASSEMBLY__
14/* A Board Information structure that is given to a program when
15 * prom starts it up.
16 */
17typedef struct bd_info {
18 unsigned int bi_memstart; /* Memory start address */
19 unsigned int bi_memsize; /* Memory (end) size in bytes */
20 unsigned int bi_intfreq; /* Internal Freq, in Hz */
21 unsigned int bi_busfreq; /* Bus Freq, in Hz */
22 unsigned char bi_enetaddr[6];
23 unsigned int bi_baudrate;
24} bd_t;
25
26extern bd_t m8xx_board_info;
27
28/* Memory map is configured by the PROM startup.
29 * We just map a few things we need. The CSR is actually 4 byte-wide
30 * registers that can be accessed as 8-, 16-, or 32-bit values.
31 */
32#define PCI_ISA_IO_ADDR ((unsigned)0x80000000)
33#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024))
34#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000)
35#define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024))
36#define RPX_CSR_ADDR ((uint)0xfa400000)
37#define RPX_CSR_SIZE ((uint)(4 * 1024))
38#define IMAP_ADDR ((uint)0xfa200000)
39#define IMAP_SIZE ((uint)(64 * 1024))
40#define PCI_CSR_ADDR ((uint)0x80000000)
41#define PCI_CSR_SIZE ((uint)(64 * 1024))
42#define PCMCIA_MEM_ADDR ((uint)0xe0000000)
43#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
44#define PCMCIA_IO_ADDR ((uint)0xe4000000)
45#define PCMCIA_IO_SIZE ((uint)(4 * 1024))
46#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000)
47#define PCMCIA_ATTRB_SIZE ((uint)(4 * 1024))
48
49/* Things of interest in the CSR.
50*/
51#define BCSR0_ETHEN ((uint)0x80000000)
52#define BCSR0_ETHLPBK ((uint)0x40000000)
53#define BCSR0_COLTESTDIS ((uint)0x20000000)
54#define BCSR0_FULLDPLXDIS ((uint)0x10000000)
55#define BCSR0_ENFLSHSEL ((uint)0x04000000)
56#define BCSR0_FLASH_SEL ((uint)0x02000000)
57#define BCSR0_ENMONXCVR ((uint)0x01000000)
58
59#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) /* CLLF */
60#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */
61#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */
62
63#define BCSR1_IPB5SEL ((uint)0x00100000)
64#define BCSR1_PCVCTL4 ((uint)0x00080000)
65#define BCSR1_PCVCTL5 ((uint)0x00040000)
66#define BCSR1_PCVCTL6 ((uint)0x00020000)
67#define BCSR1_PCVCTL7 ((uint)0x00010000)
68
69#define BCSR2_EN232XCVR ((uint)0x00008000)
70#define BCSR2_QSPACESEL ((uint)0x00004000)
71#define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */
72
73#if defined(CONFIG_HTDMSOUND)
74#include <platforms/rpxhiox.h>
75#endif
76
77/* define IO_BASE for pcmcia, CLLF only */
78#if !defined(CONFIG_PCI)
79#define _IO_BASE 0x80000000
80#define _IO_BASE_SIZE 0x1000
81
82/* for pcmcia sandisk */
83#ifdef CONFIG_IDE
84# define MAX_HWIFS 1
85#endif
86#endif
87
88/* Interrupt level assignments.
89*/
90#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */
91
92
93/* CPM Ethernet through SCCx.
94 *
95 * Bits in parallel I/O port registers that have to be set/cleared
96 * to configure the pins for SCC1 use.
97 */
98#define PA_ENET_RXD ((ushort)0x0001)
99#define PA_ENET_TXD ((ushort)0x0002)
100#define PA_ENET_TCLK ((ushort)0x0200)
101#define PA_ENET_RCLK ((ushort)0x0800)
102#define PB_ENET_TENA ((uint)0x00001000)
103#define PC_ENET_CLSN ((ushort)0x0010)
104#define PC_ENET_RENA ((ushort)0x0020)
105
106/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
107 * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
108 */
109#define SICR_ENET_MASK ((uint)0x000000ff)
110#define SICR_ENET_CLKRT ((uint)0x0000003d)
111
112/* We don't use the 8259.
113*/
114
115#define NR_8259_INTS 0
116
117#endif /* !__ASSEMBLY__ */
118#endif /* __MACH_RPX_DEFS */
119#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/rpxhiox.h b/arch/ppc/platforms/rpxhiox.h
new file mode 100644
index 000000000000..c3fa5a653762
--- /dev/null
+++ b/arch/ppc/platforms/rpxhiox.h
@@ -0,0 +1,41 @@
1/*
2 * The Embedded Planet HIOX expansion card definitions.
3 * There were a few different versions of these cards, but only
4 * the one that escaped real production is defined here.
5 *
6 * Copyright (c) 2000 Dan Malek (dmalek@jlc.net)
7 */
8#ifndef __MACH_RPX_HIOX_DEFS
9#define __MACH_RPX_HIOX_DEFS
10
11#define HIOX_CSR_ADDR ((uint)0xfac00000)
12#define HIOX_CSR_SIZE ((uint)(4 * 1024))
13#define HIOX_CSR0_ADDR HIOX_CSR_ADDR
14#define HIOX_CSR4_ADDR ((uint)0xfac00004)
15
16#define HIOX_CSR0_DEFAULT ((uint)0x380f3c00)
17#define HIOX_CSR0_ENSCC2 ((uint)0x80000000)
18#define HIOX_CSR0_ENSMC2 ((uint)0x04000000)
19#define HIOX_CSR0_ENVDOCLK ((uint)0x02000000)
20#define HIOX_CSR0_VDORST_HL ((uint)0x01000000)
21#define HIOX_CSR0_RS232SEL ((uint)0x0000c000)
22#define HIOX_CSR0_SCC3SEL ((uint)0x0000c000)
23#define HIOX_CSR0_SMC1SEL ((uint)0x00008000)
24#define HIOX_CSR0_SCC1SEL ((uint)0x00004000)
25#define HIOX_CSR0_ENTOUCH ((uint)0x00000080)
26#define HIOX_CSR0_PDOWN100 ((uint)0x00000060)
27#define HIOX_CSR0_PDOWN10 ((uint)0x00000040)
28#define HIOX_CSR0_PDOWN1 ((uint)0x00000020)
29#define HIOX_CSR0_TSELSPI ((uint)0x00000010)
30#define HIOX_CSR0_TIRQSTAT ((uint)0x00000008)
31#define HIOX_CSR4_DEFAULT ((uint)0x00000000)
32#define HIOX_CSR4_ENTIRQ2 ((uint)0x20000000)
33#define HIOX_CSR4_ENTIRQ3 ((uint)0x10000000)
34#define HIOX_CSR4_ENAUDIO ((uint)0x00000080)
35#define HIOX_CSR4_RSTAUDIO ((uint)0x00000040) /* 0 == reset */
36#define HIOX_CSR4_AUDCLKHI ((uint)0x00000020)
37#define HIOX_CSR4_AUDSPISEL ((uint)0x00000010)
38#define HIOX_CSR4_AUDIRQSTAT ((uint)0x00000008)
39#define HIOX_CSR4_AUDCLKSEL ((uint)0x00000007)
40
41#endif
diff --git a/arch/ppc/platforms/rpxlite.h b/arch/ppc/platforms/rpxlite.h
new file mode 100644
index 000000000000..deee5bd36aa8
--- /dev/null
+++ b/arch/ppc/platforms/rpxlite.h
@@ -0,0 +1,96 @@
1/*
2 * A collection of structures, addresses, and values associated with
3 * the RPCG RPX-Lite board. Copied from the MBX stuff.
4 *
5 * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
6 */
7#ifdef __KERNEL__
8#ifndef __MACH_RPX_DEFS
9#define __MACH_RPX_DEFS
10
11#include <linux/config.h>
12
13#ifndef __ASSEMBLY__
14/* A Board Information structure that is given to a program when
15 * prom starts it up.
16 */
17typedef struct bd_info {
18 unsigned int bi_memstart; /* Memory start address */
19 unsigned int bi_memsize; /* Memory (end) size in bytes */
20 unsigned int bi_intfreq; /* Internal Freq, in Hz */
21 unsigned int bi_busfreq; /* Bus Freq, in Hz */
22 unsigned char bi_enetaddr[6];
23 unsigned int bi_baudrate;
24} bd_t;
25
26extern bd_t m8xx_board_info;
27
28/* Memory map is configured by the PROM startup.
29 * We just map a few things we need. The CSR is actually 4 byte-wide
30 * registers that can be accessed as 8-, 16-, or 32-bit values.
31 */
32#define RPX_CSR_ADDR ((uint)0xfa400000)
33#define RPX_CSR_SIZE ((uint)(4 * 1024))
34#define IMAP_ADDR ((uint)0xfa200000)
35#define IMAP_SIZE ((uint)(64 * 1024))
36#define PCMCIA_MEM_ADDR ((uint)0x04000000)
37#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
38#define PCMCIA_IO_ADDR ((uint)0x04400000)
39#define PCMCIA_IO_SIZE ((uint)(4 * 1024))
40
41/* Things of interest in the CSR.
42*/
43#define BCSR0_ETHEN ((uint)0x80000000)
44#define BCSR0_ETHLPBK ((uint)0x40000000)
45#define BCSR0_COLTESTDIS ((uint)0x20000000)
46#define BCSR0_FULLDPLXDIS ((uint)0x10000000)
47#define BCSR0_LEDOFF ((uint)0x08000000)
48#define BCSR0_USBDISABLE ((uint)0x04000000)
49#define BCSR0_USBHISPEED ((uint)0x02000000)
50#define BCSR0_USBPWREN ((uint)0x01000000)
51#define BCSR0_PCMCIAVOLT ((uint)0x000f0000)
52#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000)
53#define BCSR0_PCMCIA5VOLT ((uint)0x00060000)
54
55#define BCSR1_IPB5SEL ((uint)0x00100000)
56#define BCSR1_PCVCTL4 ((uint)0x00080000)
57#define BCSR1_PCVCTL5 ((uint)0x00040000)
58#define BCSR1_PCVCTL6 ((uint)0x00020000)
59#define BCSR1_PCVCTL7 ((uint)0x00010000)
60
61#if defined(CONFIG_HTDMSOUND)
62#include <platforms/rpxhiox.h>
63#endif
64
65/* define IO_BASE for pcmcia */
66#define _IO_BASE 0x80000000
67#define _IO_BASE_SIZE 0x1000
68
69#ifdef CONFIG_IDE
70# define MAX_HWIFS 1
71#endif
72
73/* CPM Ethernet through SCCx.
74 *
75 * This ENET stuff is for the MPC850 with ethernet on SCC2. Some of
76 * this may be unique to the RPX-Lite configuration.
77 * Note TENA is on Port B.
78 */
79#define PA_ENET_RXD ((ushort)0x0004)
80#define PA_ENET_TXD ((ushort)0x0008)
81#define PA_ENET_TCLK ((ushort)0x0200)
82#define PA_ENET_RCLK ((ushort)0x0800)
83#define PB_ENET_TENA ((uint)0x00002000)
84#define PC_ENET_CLSN ((ushort)0x0040)
85#define PC_ENET_RENA ((ushort)0x0080)
86
87#define SICR_ENET_MASK ((uint)0x0000ff00)
88#define SICR_ENET_CLKRT ((uint)0x00003d00)
89
90/* We don't use the 8259.
91*/
92#define NR_8259_INTS 0
93
94#endif /* !__ASSEMBLY__ */
95#endif /* __MACH_RPX_DEFS */
96#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
new file mode 100644
index 000000000000..531bfa0e4512
--- /dev/null
+++ b/arch/ppc/platforms/sandpoint.c
@@ -0,0 +1,742 @@
1/*
2 * arch/ppc/platforms/sandpoint_setup.c
3 *
4 * Board setup routines for the Motorola SPS Sandpoint Test Platform.
5 *
6 * Author: Mark A. Greer
7 * mgreer@mvista.com
8 *
9 * 2000-2003 (c) MontaVista Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15/*
16 * This file adds support for the Motorola SPS Sandpoint Test Platform.
17 * These boards have a PPMC slot for the processor so any combination
18 * of cpu and host bridge can be attached. This port is for an 8240 PPMC
19 * module from Motorola SPS and other closely related cpu/host bridge
20 * combinations (e.g., 750/755/7400 with MPC107 host bridge).
21 * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2
22 * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a
23 * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr),
24 * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V
25 * but are really 5V).
26 *
27 * The firmware on the sandpoint is called DINK (not my acronym :). This port
28 * depends on DINK to do some basic initialization (e.g., initialize the memory
29 * ctlr) and to ensure that the processor is using MAP B (CHRP map).
30 *
31 * The switch settings for the Sandpoint board MUST be as follows:
32 * S3: down
33 * S4: up
34 * S5: up
35 * S6: down
36 *
37 * 'down' is in the direction from the PCI slots towards the PPMC slot;
38 * 'up' is in the direction from the PPMC slot towards the PCI slots.
39 * Be careful, the way the sandpoint board is installed in XT chasses will
40 * make the directions reversed.
41 *
42 * Since Motorola listened to our suggestions for improvement, we now have
43 * the Sandpoint X3 board. All of the PCI slots are available, it uses
44 * the serial interrupt interface (just a hardware thing we need to
45 * configure properly).
46 *
47 * Use the default X3 switch settings. The interrupts are then:
48 * EPIC Source
49 * 0 SIOINT (8259, active low)
50 * 1 PCI #1
51 * 2 PCI #2
52 * 3 PCI #3
53 * 4 PCI #4
54 * 7 Winbond INTC (IDE interrupt)
55 * 8 Winbond INTD (IDE interrupt)
56 *
57 *
58 * Motorola has finally released a version of DINK32 that correctly
59 * (seemingly) initalizes the memory controller correctly, regardless
60 * of the amount of memory in the system. Once a method of determining
61 * what version of DINK initializes the system for us, if applicable, is
62 * found, we can hopefully stop hardcoding 32MB of RAM.
63 */
64
65#include <linux/config.h>
66#include <linux/stddef.h>
67#include <linux/kernel.h>
68#include <linux/init.h>
69#include <linux/errno.h>
70#include <linux/reboot.h>
71#include <linux/pci.h>
72#include <linux/kdev_t.h>
73#include <linux/major.h>
74#include <linux/initrd.h>
75#include <linux/console.h>
76#include <linux/delay.h>
77#include <linux/irq.h>
78#include <linux/ide.h>
79#include <linux/seq_file.h>
80#include <linux/root_dev.h>
81#include <linux/serial.h>
82#include <linux/tty.h> /* for linux/serial_core.h */
83#include <linux/serial_core.h>
84
85#include <asm/system.h>
86#include <asm/pgtable.h>
87#include <asm/page.h>
88#include <asm/time.h>
89#include <asm/dma.h>
90#include <asm/io.h>
91#include <asm/machdep.h>
92#include <asm/prom.h>
93#include <asm/smp.h>
94#include <asm/vga.h>
95#include <asm/open_pic.h>
96#include <asm/i8259.h>
97#include <asm/todc.h>
98#include <asm/bootinfo.h>
99#include <asm/mpc10x.h>
100#include <asm/pci-bridge.h>
101#include <asm/kgdb.h>
102
103#include "sandpoint.h"
104
105/* Set non-zero if an X2 Sandpoint detected. */
106static int sandpoint_is_x2;
107
108unsigned char __res[sizeof(bd_t)];
109
110static void sandpoint_halt(void);
111static void sandpoint_probe_type(void);
112
113/*
114 * Define all of the IRQ senses and polarities. Taken from the
115 * Sandpoint X3 User's manual.
116 */
117static u_char sandpoint_openpic_initsenses[] __initdata = {
118 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 0: SIOINT */
119 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 2: PCI Slot 1 */
120 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 3: PCI Slot 2 */
121 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 4: PCI Slot 3 */
122 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 5: PCI Slot 4 */
123 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 8: IDE (INT C) */
124 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE) /* 9: IDE (INT D) */
125};
126
127/*
128 * Motorola SPS Sandpoint interrupt routing.
129 */
130static inline int
131x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
132{
133 static char pci_irq_table[][4] =
134 /*
135 * PCI IDSEL/INTPIN->INTLINE
136 * A B C D
137 */
138 {
139 { 16, 0, 0, 0 }, /* IDSEL 11 - i8259 on Winbond */
140 { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
141 { 18, 21, 20, 19 }, /* IDSEL 13 - PCI slot 1 */
142 { 19, 18, 21, 20 }, /* IDSEL 14 - PCI slot 2 */
143 { 20, 19, 18, 21 }, /* IDSEL 15 - PCI slot 3 */
144 { 21, 20, 19, 18 }, /* IDSEL 16 - PCI slot 4 */
145 };
146
147 const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
148 return PCI_IRQ_TABLE_LOOKUP;
149}
150
151static inline int
152x2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
153{
154 static char pci_irq_table[][4] =
155 /*
156 * PCI IDSEL/INTPIN->INTLINE
157 * A B C D
158 */
159 {
160 { 18, 0, 0, 0 }, /* IDSEL 11 - i8259 on Windbond */
161 { 0, 0, 0, 0 }, /* IDSEL 12 - unused */
162 { 16, 17, 18, 19 }, /* IDSEL 13 - PCI slot 1 */
163 { 17, 18, 19, 16 }, /* IDSEL 14 - PCI slot 2 */
164 { 18, 19, 16, 17 }, /* IDSEL 15 - PCI slot 3 */
165 { 19, 16, 17, 18 }, /* IDSEL 16 - PCI slot 4 */
166 };
167
168 const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
169 return PCI_IRQ_TABLE_LOOKUP;
170}
171
172static void __init
173sandpoint_setup_winbond_83553(struct pci_controller *hose)
174{
175 int devfn;
176
177 /*
178 * Route IDE interrupts directly to the 8259's IRQ 14 & 15.
179 * We can't route the IDE interrupt to PCI INTC# or INTD# because those
180 * woule interfere with the PMC's INTC# and INTD# lines.
181 */
182 /*
183 * Winbond Fcn 0
184 */
185 devfn = PCI_DEVFN(11,0);
186
187 early_write_config_byte(hose,
188 0,
189 devfn,
190 0x43, /* IDE Interrupt Routing Control */
191 0xef);
192 early_write_config_word(hose,
193 0,
194 devfn,
195 0x44, /* PCI Interrupt Routing Control */
196 0x0000);
197
198 /* Want ISA memory cycles to be forwarded to PCI bus */
199 early_write_config_byte(hose,
200 0,
201 devfn,
202 0x48, /* ISA-to-PCI Addr Decoder Control */
203 0xf0);
204
205 /* Enable Port 92. */
206 early_write_config_byte(hose,
207 0,
208 devfn,
209 0x4e, /* AT System Control Register */
210 0x06);
211 /*
212 * Winbond Fcn 1
213 */
214 devfn = PCI_DEVFN(11,1);
215
216 /* Put IDE controller into native mode. */
217 early_write_config_byte(hose,
218 0,
219 devfn,
220 0x09, /* Programming interface Register */
221 0x8f);
222
223 /* Init IRQ routing, enable both ports, disable fast 16 */
224 early_write_config_dword(hose,
225 0,
226 devfn,
227 0x40, /* IDE Control/Status Register */
228 0x00ff0011);
229 return;
230}
231
232/* On the sandpoint X2, we must avoid sending configuration cycles to
233 * device #12 (IDSEL addr = AD12).
234 */
235static int
236x2_exclude_device(u_char bus, u_char devfn)
237{
238 if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL))
239 return PCIBIOS_DEVICE_NOT_FOUND;
240 else
241 return PCIBIOS_SUCCESSFUL;
242}
243
244static void __init
245sandpoint_find_bridges(void)
246{
247 struct pci_controller *hose;
248
249 hose = pcibios_alloc_controller();
250
251 if (!hose)
252 return;
253
254 hose->first_busno = 0;
255 hose->last_busno = 0xff;
256
257 if (mpc10x_bridge_init(hose,
258 MPC10X_MEM_MAP_B,
259 MPC10X_MEM_MAP_B,
260 MPC10X_MAPB_EUMB_BASE) == 0) {
261
262 /* Do early winbond init, then scan PCI bus */
263 sandpoint_setup_winbond_83553(hose);
264 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
265
266 ppc_md.pcibios_fixup = NULL;
267 ppc_md.pcibios_fixup_bus = NULL;
268 ppc_md.pci_swizzle = common_swizzle;
269 if (sandpoint_is_x2) {
270 ppc_md.pci_map_irq = x2_map_irq;
271 ppc_md.pci_exclude_device = x2_exclude_device;
272 } else
273 ppc_md.pci_map_irq = x3_map_irq;
274 }
275 else {
276 if (ppc_md.progress)
277 ppc_md.progress("Bridge init failed", 0x100);
278 printk("Host bridge init failed\n");
279 }
280
281 return;
282}
283
284static void __init
285sandpoint_setup_arch(void)
286{
287 /* Probe for Sandpoint model */
288 sandpoint_probe_type();
289 if (sandpoint_is_x2)
290 epic_serial_mode = 0;
291
292 loops_per_jiffy = 100000000 / HZ;
293
294#ifdef CONFIG_BLK_DEV_INITRD
295 if (initrd_start)
296 ROOT_DEV = Root_RAM0;
297 else
298#endif
299#ifdef CONFIG_ROOT_NFS
300 ROOT_DEV = Root_NFS;
301#else
302 ROOT_DEV = Root_HDA1;
303#endif
304
305 /* Lookup PCI host bridges */
306 sandpoint_find_bridges();
307
308 printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n");
309 printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
310
311 /* DINK32 12.3 and below do not correctly enable any caches.
312 * We will do this now with good known values. Future versions
313 * of DINK32 are supposed to get this correct.
314 */
315 if (cpu_has_feature(CPU_FTR_SPEC7450))
316 /* 745x is different. We only want to pass along enable. */
317 _set_L2CR(L2CR_L2E);
318 else if (cpu_has_feature(CPU_FTR_L2CR))
319 /* All modules have 1MB of L2. We also assume that an
320 * L2 divisor of 3 will work.
321 */
322 _set_L2CR(L2CR_L2E | L2CR_L2SIZ_1MB | L2CR_L2CLK_DIV3
323 | L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
324#if 0
325 /* Untested right now. */
326 if (cpu_has_feature(CPU_FTR_L3CR)) {
327 /* Magic value. */
328 _set_L3CR(0x8f032000);
329 }
330#endif
331}
332
333#define SANDPOINT_87308_CFG_ADDR 0x15c
334#define SANDPOINT_87308_CFG_DATA 0x15d
335
336#define SANDPOINT_87308_CFG_INB(addr, byte) { \
337 outb((addr), SANDPOINT_87308_CFG_ADDR); \
338 (byte) = inb(SANDPOINT_87308_CFG_DATA); \
339}
340
341#define SANDPOINT_87308_CFG_OUTB(addr, byte) { \
342 outb((addr), SANDPOINT_87308_CFG_ADDR); \
343 outb((byte), SANDPOINT_87308_CFG_DATA); \
344}
345
346#define SANDPOINT_87308_SELECT_DEV(dev_num) { \
347 SANDPOINT_87308_CFG_OUTB(0x07, (dev_num)); \
348}
349
350#define SANDPOINT_87308_DEV_ENABLE(dev_num) { \
351 SANDPOINT_87308_SELECT_DEV(dev_num); \
352 SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \
353}
354
355/*
356 * To probe the Sandpoint type, we need to check for a connection between GPIO
357 * pins 6 and 7 on the NS87308 SuperIO.
358 */
359static void __init sandpoint_probe_type(void)
360{
361 u8 x;
362 /* First, ensure that the GPIO pins are enabled. */
363 SANDPOINT_87308_SELECT_DEV(0x07); /* Select GPIO logical device */
364 SANDPOINT_87308_CFG_OUTB(0x60, 0x07); /* Base address 0x700 */
365 SANDPOINT_87308_CFG_OUTB(0x61, 0x00);
366 SANDPOINT_87308_CFG_OUTB(0x30, 0x01); /* Enable */
367
368 /* Now, set pin 7 to output and pin 6 to input. */
369 outb((inb(0x701) | 0x80) & 0xbf, 0x701);
370 /* Set push-pull output */
371 outb(inb(0x702) | 0x80, 0x702);
372 /* Set pull-up on input */
373 outb(inb(0x703) | 0x40, 0x703);
374 /* Set output high and check */
375 x = inb(0x700);
376 outb(x | 0x80, 0x700);
377 x = inb(0x700);
378 sandpoint_is_x2 = ! (x & 0x40);
379 if (ppc_md.progress && sandpoint_is_x2)
380 ppc_md.progress("High output says X2", 0);
381 /* Set output low and check */
382 outb(x & 0x7f, 0x700);
383 sandpoint_is_x2 |= inb(0x700) & 0x40;
384 if (ppc_md.progress && sandpoint_is_x2)
385 ppc_md.progress("Low output says X2", 0);
386 if (ppc_md.progress && ! sandpoint_is_x2)
387 ppc_md.progress("Sandpoint is X3", 0);
388}
389
390/*
391 * Fix IDE interrupts.
392 */
393static int __init
394sandpoint_fix_winbond_83553(void)
395{
396 /* Make some 8259 interrupt level sensitive */
397 outb(0xe0, 0x4d0);
398 outb(0xde, 0x4d1);
399
400 return 0;
401}
402
403arch_initcall(sandpoint_fix_winbond_83553);
404
405/*
406 * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip.
407 */
408static int __init
409sandpoint_setup_natl_87308(void)
410{
411 u_char reg;
412
413 /*
414 * Enable all the devices on the Super I/O chip.
415 */
416 SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */
417 SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */
418 SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */
419 SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */
420 SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */
421 SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */
422 SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */
423 SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */
424 SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
425 SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */
426 SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */
427
428 /* Set up floppy in PS/2 mode */
429 outb(0x09, SIO_CONFIG_RA);
430 reg = inb(SIO_CONFIG_RD);
431 reg = (reg & 0x3F) | 0x40;
432 outb(reg, SIO_CONFIG_RD);
433 outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
434
435 return 0;
436}
437
438arch_initcall(sandpoint_setup_natl_87308);
439
440static int __init
441sandpoint_request_io(void)
442{
443 request_region(0x00,0x20,"dma1");
444 request_region(0x20,0x20,"pic1");
445 request_region(0x40,0x20,"timer");
446 request_region(0x80,0x10,"dma page reg");
447 request_region(0xa0,0x20,"pic2");
448 request_region(0xc0,0x20,"dma2");
449
450 return 0;
451}
452
453arch_initcall(sandpoint_request_io);
454
455/*
456 * Interrupt setup and service. Interrrupts on the Sandpoint come
457 * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
458 * The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4,
459 * IDE is on EPIC 7 and 8.
460 */
461static void __init
462sandpoint_init_IRQ(void)
463{
464 int i;
465
466 OpenPIC_InitSenses = sandpoint_openpic_initsenses;
467 OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses);
468
469 mpc10x_set_openpic();
470 openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade",
471 i8259_irq);
472
473 /*
474 * openpic_init() has set up irq_desc[16-31] to be openpic
475 * interrupts. We need to set irq_desc[0-15] to be i8259
476 * interrupts.
477 */
478 for(i=0; i < NUM_8259_INTERRUPTS; i++)
479 irq_desc[i].handler = &i8259_pic;
480
481 /*
482 * The EPIC allows for a read in the range of 0xFEF00000 ->
483 * 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
484 */
485 i8259_init(0xfef00000);
486}
487
488static u32
489sandpoint_irq_canonicalize(u32 irq)
490{
491 if (irq == 2)
492 return 9;
493 else
494 return irq;
495}
496
497static unsigned long __init
498sandpoint_find_end_of_memory(void)
499{
500 bd_t *bp = (bd_t *)__res;
501
502 if (bp->bi_memsize)
503 return bp->bi_memsize;
504
505 /* DINK32 13.0 correctly initalizes things, so iff you use
506 * this you _should_ be able to change this instead of a
507 * hardcoded value. */
508#if 0
509 return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
510#else
511 return 32*1024*1024;
512#endif
513}
514
515static void __init
516sandpoint_map_io(void)
517{
518 io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO);
519}
520
521static void
522sandpoint_restart(char *cmd)
523{
524 local_irq_disable();
525
526 /* Set exception prefix high - to the firmware */
527 _nmask_and_or_msr(0, MSR_IP);
528
529 /* Reset system via Port 92 */
530 outb(0x00, 0x92);
531 outb(0x01, 0x92);
532 for(;;); /* Spin until reset happens */
533}
534
535static void
536sandpoint_power_off(void)
537{
538 local_irq_disable();
539 for(;;); /* No way to shut power off with software */
540 /* NOTREACHED */
541}
542
543static void
544sandpoint_halt(void)
545{
546 sandpoint_power_off();
547 /* NOTREACHED */
548}
549
550static int
551sandpoint_show_cpuinfo(struct seq_file *m)
552{
553 seq_printf(m, "vendor\t\t: Motorola SPS\n");
554 seq_printf(m, "machine\t\t: Sandpoint\n");
555
556 return 0;
557}
558
559#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
560/*
561 * IDE support.
562 */
563static int sandpoint_ide_ports_known = 0;
564static unsigned long sandpoint_ide_regbase[MAX_HWIFS];
565static unsigned long sandpoint_ide_ctl_regbase[MAX_HWIFS];
566static unsigned long sandpoint_idedma_regbase;
567
568static void
569sandpoint_ide_probe(void)
570{
571 struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_WINBOND,
572 PCI_DEVICE_ID_WINBOND_82C105, NULL);
573
574 if (pdev) {
575 sandpoint_ide_regbase[0]=pdev->resource[0].start;
576 sandpoint_ide_regbase[1]=pdev->resource[2].start;
577 sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
578 sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
579 sandpoint_idedma_regbase=pdev->resource[4].start;
580 pci_dev_put(pdev);
581 }
582
583 sandpoint_ide_ports_known = 1;
584}
585
586static int
587sandpoint_ide_default_irq(unsigned long base)
588{
589 if (sandpoint_ide_ports_known == 0)
590 sandpoint_ide_probe();
591
592 if (base == sandpoint_ide_regbase[0])
593 return SANDPOINT_IDE_INT0;
594 else if (base == sandpoint_ide_regbase[1])
595 return SANDPOINT_IDE_INT1;
596 else
597 return 0;
598}
599
600static unsigned long
601sandpoint_ide_default_io_base(int index)
602{
603 if (sandpoint_ide_ports_known == 0)
604 sandpoint_ide_probe();
605
606 return sandpoint_ide_regbase[index];
607}
608
609static void __init
610sandpoint_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
611 unsigned long ctrl_port, int *irq)
612{
613 unsigned long reg = data_port;
614 uint alt_status_base;
615 int i;
616
617 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
618 hw->io_ports[i] = reg++;
619 }
620
621 if (data_port == sandpoint_ide_regbase[0]) {
622 alt_status_base = sandpoint_ide_ctl_regbase[0] + 2;
623 hw->irq = 14;
624 }
625 else if (data_port == sandpoint_ide_regbase[1]) {
626 alt_status_base = sandpoint_ide_ctl_regbase[1] + 2;
627 hw->irq = 15;
628 }
629 else {
630 alt_status_base = 0;
631 hw->irq = 0;
632 }
633
634 if (ctrl_port) {
635 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
636 } else {
637 hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base;
638 }
639
640 if (irq != NULL) {
641 *irq = hw->irq;
642 }
643}
644#endif
645
646/*
647 * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
648 */
649static __inline__ void
650sandpoint_set_bat(void)
651{
652 unsigned long bat3u, bat3l;
653
654 __asm__ __volatile__(
655 " lis %0,0xf800\n \
656 ori %1,%0,0x002a\n \
657 ori %0,%0,0x0ffe\n \
658 mtspr 0x21e,%0\n \
659 mtspr 0x21f,%1\n \
660 isync\n \
661 sync "
662 : "=r" (bat3u), "=r" (bat3l));
663}
664
665TODC_ALLOC();
666
667void __init
668platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
669 unsigned long r6, unsigned long r7)
670{
671 parse_bootinfo(find_bootinfo());
672
673 /* ASSUMPTION: If both r3 (bd_t pointer) and r6 (cmdline pointer)
674 * are non-zero, then we should use the board info from the bd_t
675 * structure and the cmdline pointed to by r6 instead of the
676 * information from birecs, if any. Otherwise, use the information
677 * from birecs as discovered by the preceeding call to
678 * parse_bootinfo(). This rule should work with both PPCBoot, which
679 * uses a bd_t board info structure, and the kernel boot wrapper,
680 * which uses birecs.
681 */
682 if (r3 && r6) {
683 /* copy board info structure */
684 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
685 /* copy command line */
686 *(char *)(r7+KERNELBASE) = 0;
687 strcpy(cmd_line, (char *)(r6+KERNELBASE));
688 }
689
690#ifdef CONFIG_BLK_DEV_INITRD
691 /* take care of initrd if we have one */
692 if (r4) {
693 initrd_start = r4 + KERNELBASE;
694 initrd_end = r5 + KERNELBASE;
695 }
696#endif /* CONFIG_BLK_DEV_INITRD */
697
698 /* Map in board regs, etc. */
699 sandpoint_set_bat();
700
701 isa_io_base = MPC10X_MAPB_ISA_IO_BASE;
702 isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE;
703 pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET;
704 ISA_DMA_THRESHOLD = 0x00ffffff;
705 DMA_MODE_READ = 0x44;
706 DMA_MODE_WRITE = 0x48;
707
708 ppc_md.setup_arch = sandpoint_setup_arch;
709 ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
710 ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
711 ppc_md.init_IRQ = sandpoint_init_IRQ;
712 ppc_md.get_irq = openpic_get_irq;
713
714 ppc_md.restart = sandpoint_restart;
715 ppc_md.power_off = sandpoint_power_off;
716 ppc_md.halt = sandpoint_halt;
717
718 ppc_md.find_end_of_memory = sandpoint_find_end_of_memory;
719 ppc_md.setup_io_mappings = sandpoint_map_io;
720
721 TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8);
722 ppc_md.time_init = todc_time_init;
723 ppc_md.set_rtc_time = todc_set_rtc_time;
724 ppc_md.get_rtc_time = todc_get_rtc_time;
725 ppc_md.calibrate_decr = todc_calibrate_decr;
726
727 ppc_md.nvram_read_val = todc_mc146818_read_val;
728 ppc_md.nvram_write_val = todc_mc146818_write_val;
729
730#ifdef CONFIG_KGDB
731 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
732#endif
733#ifdef CONFIG_SERIAL_TEXT_DEBUG
734 ppc_md.progress = gen550_progress;
735#endif
736
737#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
738 ppc_ide_md.default_irq = sandpoint_ide_default_irq;
739 ppc_ide_md.default_io_base = sandpoint_ide_default_io_base;
740 ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports;
741#endif
742}
diff --git a/arch/ppc/platforms/sandpoint.h b/arch/ppc/platforms/sandpoint.h
new file mode 100644
index 000000000000..f4e982cb69df
--- /dev/null
+++ b/arch/ppc/platforms/sandpoint.h
@@ -0,0 +1,80 @@
1/*
2 * arch/ppc/platforms/sandpoint.h
3 *
4 * Definitions for Motorola SPS Sandpoint Test Platform
5 *
6 * Author: Mark A. Greer
7 * mgreer@mvista.com
8 *
9 * 2000-2003 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14
15/*
16 * Sandpoint uses the CHRP map (Map B).
17 */
18
19#ifndef __PPC_PLATFORMS_SANDPOINT_H
20#define __PPC_PLATFORMS_SANDPOINT_H
21
22#include <asm/ppcboot.h>
23
24#if 0
25/* The Sandpoint X3 allows the IDE interrupt to be directly connected
26 * from the Windbond (PCI INTC or INTD) to the serial EPIC. Someday
27 * we should try this, but it was easier to use the existing 83c553
28 * initialization than change it to route the different interrupts :-).
29 * -- Dan
30 */
31#define SANDPOINT_IDE_INT0 23 /* EPIC 7 */
32#define SANDPOINT_IDE_INT1 24 /* EPIC 8 */
33#else
34#define SANDPOINT_IDE_INT0 14 /* 8259 Test */
35#define SANDPOINT_IDE_INT1 15 /* 8259 Test */
36#endif
37
38/*
39 * The sandpoint boards have processor modules that either have an 8240 or
40 * an MPC107 host bridge on them. These bridges have an IDSEL line that allows
41 * them to respond to PCI transactions as if they were a normal PCI devices.
42 * However, the processor on the processor side of the bridge can not reach
43 * out onto the PCI bus and then select the bridge or bad things will happen
44 * (documented in the 8240 and 107 manuals).
45 * Because of this, we always skip the bridge PCI device when accessing the
46 * PCI bus. The PCI slot that the bridge occupies is defined by the macro
47 * below.
48 */
49#define SANDPOINT_HOST_BRIDGE_IDSEL 12
50
51/*
52 * Serial defines.
53 */
54#define SANDPOINT_SERIAL_0 0xfe0003f8
55#define SANDPOINT_SERIAL_1 0xfe0002f8
56
57#define RS_TABLE_SIZE 2
58
59/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
60#define BASE_BAUD ( 1843200 / 16 )
61#define UART_CLK 1843200
62
63#ifdef CONFIG_SERIAL_DETECT_IRQ
64#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ)
65#else
66#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF)
67#endif
68
69#define STD_SERIAL_PORT_DFNS \
70 { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, STD_COM_FLAGS, /* ttyS0 */ \
71 iomem_base: (u8 *)SANDPOINT_SERIAL_0, \
72 io_type: SERIAL_IO_MEM }, \
73 { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, STD_COM_FLAGS, /* ttyS1 */ \
74 iomem_base: (u8 *)SANDPOINT_SERIAL_1, \
75 io_type: SERIAL_IO_MEM },
76
77#define SERIAL_PORT_DFNS \
78 STD_SERIAL_PORT_DFNS
79
80#endif /* __PPC_PLATFORMS_SANDPOINT_H */
diff --git a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c
new file mode 100644
index 000000000000..74c9ff72c3dd
--- /dev/null
+++ b/arch/ppc/platforms/sbc82xx.c
@@ -0,0 +1,259 @@
1/*
2 * arch/ppc/platforms/sbc82xx.c
3 *
4 * SBC82XX platform support
5 *
6 * Author: Guy Streeter <streeter@redhat.com>
7 *
8 * Derived from: est8260_setup.c by Allen Curtis, ONZ
9 *
10 * Copyright 2004 Red Hat, Inc.
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
18#include <linux/config.h>
19#include <linux/stddef.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24
25#include <asm/mpc8260.h>
26#include <asm/machdep.h>
27#include <asm/io.h>
28#include <asm/todc.h>
29#include <asm/immap_cpm2.h>
30#include <asm/pci.h>
31
32static void (*callback_init_IRQ)(void);
33
34extern unsigned char __res[sizeof(bd_t)];
35
36extern void (*late_time_init)(void);
37
38#ifdef CONFIG_GEN_RTC
39TODC_ALLOC();
40
41/*
42 * Timer init happens before mem_init but after paging init, so we cannot
43 * directly use ioremap() at that time.
44 * late_time_init() is call after paging init.
45 */
46
47static void sbc82xx_time_init(void)
48{
49 volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
50
51 /* Set up CS11 for RTC chip */
52 mc->memc_br11=0;
53 mc->memc_or11=0xffff0836;
54 mc->memc_br11=SBC82xx_TODC_NVRAM_ADDR | 0x0801;
55
56 TODC_INIT(TODC_TYPE_MK48T59, 0, 0, SBC82xx_TODC_NVRAM_ADDR, 0);
57
58 todc_info->nvram_data =
59 (unsigned int)ioremap(todc_info->nvram_data, 0x2000);
60 BUG_ON(!todc_info->nvram_data);
61 ppc_md.get_rtc_time = todc_get_rtc_time;
62 ppc_md.set_rtc_time = todc_set_rtc_time;
63 ppc_md.nvram_read_val = todc_direct_read_val;
64 ppc_md.nvram_write_val = todc_direct_write_val;
65 todc_time_init();
66}
67#endif /* CONFIG_GEN_RTC */
68
69static volatile char *sbc82xx_i8259_map;
70static char sbc82xx_i8259_mask = 0xff;
71static DEFINE_SPINLOCK(sbc82xx_i8259_lock);
72
73static void sbc82xx_i8259_mask_and_ack_irq(unsigned int irq_nr)
74{
75 unsigned long flags;
76
77 irq_nr -= NR_SIU_INTS;
78
79 spin_lock_irqsave(&sbc82xx_i8259_lock, flags);
80 sbc82xx_i8259_mask |= 1 << irq_nr;
81 (void) sbc82xx_i8259_map[1]; /* Dummy read */
82 sbc82xx_i8259_map[1] = sbc82xx_i8259_mask;
83 sbc82xx_i8259_map[0] = 0x20; /* OCW2: Non-specific EOI */
84 spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags);
85}
86
87static void sbc82xx_i8259_mask_irq(unsigned int irq_nr)
88{
89 unsigned long flags;
90
91 irq_nr -= NR_SIU_INTS;
92
93 spin_lock_irqsave(&sbc82xx_i8259_lock, flags);
94 sbc82xx_i8259_mask |= 1 << irq_nr;
95 sbc82xx_i8259_map[1] = sbc82xx_i8259_mask;
96 spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags);
97}
98
99static void sbc82xx_i8259_unmask_irq(unsigned int irq_nr)
100{
101 unsigned long flags;
102
103 irq_nr -= NR_SIU_INTS;
104
105 spin_lock_irqsave(&sbc82xx_i8259_lock, flags);
106 sbc82xx_i8259_mask &= ~(1 << irq_nr);
107 sbc82xx_i8259_map[1] = sbc82xx_i8259_mask;
108 spin_unlock_irqrestore(&sbc82xx_i8259_lock, flags);
109}
110
111static void sbc82xx_i8259_end_irq(unsigned int irq)
112{
113 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
114 && irq_desc[irq].action)
115 sbc82xx_i8259_unmask_irq(irq);
116}
117
118
119struct hw_interrupt_type sbc82xx_i8259_ic = {
120 .typename = " i8259 ",
121 .enable = sbc82xx_i8259_unmask_irq,
122 .disable = sbc82xx_i8259_mask_irq,
123 .ack = sbc82xx_i8259_mask_and_ack_irq,
124 .end = sbc82xx_i8259_end_irq,
125};
126
127static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *regs)
128{
129 spin_lock(&sbc82xx_i8259_lock);
130
131 sbc82xx_i8259_map[0] = 0x0c; /* OCW3: Read IR register on RD# pulse */
132 irq = sbc82xx_i8259_map[0] & 7; /* Read IRR */
133
134 if (irq == 7) {
135 /* Possible spurious interrupt */
136 int isr;
137 sbc82xx_i8259_map[0] = 0x0b; /* OCW3: Read IS register on RD# pulse */
138 isr = sbc82xx_i8259_map[0]; /* Read ISR */
139
140 if (!(isr & 0x80)) {
141 printk(KERN_INFO "Spurious i8259 interrupt\n");
142 return IRQ_HANDLED;
143 }
144 }
145 __do_IRQ(NR_SIU_INTS + irq, regs);
146 return IRQ_HANDLED;
147}
148
149static struct irqaction sbc82xx_i8259_irqaction = {
150 .handler = sbc82xx_i8259_demux,
151 .flags = SA_INTERRUPT,
152 .mask = CPU_MASK_NONE,
153 .name = "i8259 demux",
154};
155
156void __init sbc82xx_init_IRQ(void)
157{
158 volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
159 volatile intctl_cpm2_t *ic = &cpm2_immr->im_intctl;
160 int i;
161
162 callback_init_IRQ();
163
164 /* u-boot doesn't always set the board up correctly */
165 mc->memc_br5 = 0;
166 mc->memc_or5 = 0xfff00856;
167 mc->memc_br5 = 0x22000801;
168
169 sbc82xx_i8259_map = ioremap(0x22008000, 2);
170 if (!sbc82xx_i8259_map) {
171 printk(KERN_CRIT "Mapping i8259 interrupt controller failed\n");
172 return;
173 }
174
175 /* Set up the interrupt handlers for the i8259 IRQs */
176 for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) {
177 irq_desc[i].handler = &sbc82xx_i8259_ic;
178 irq_desc[i].status |= IRQ_LEVEL;
179 }
180
181 /* make IRQ6 level sensitive */
182 ic->ic_siexr &= ~(1 << (14 - (SIU_INT_IRQ6 - SIU_INT_IRQ1)));
183 irq_desc[SIU_INT_IRQ6].status |= IRQ_LEVEL;
184
185 /* Initialise the i8259 */
186 sbc82xx_i8259_map[0] = 0x1b; /* ICW1: Level, no cascade, ICW4 */
187 sbc82xx_i8259_map[1] = 0x00; /* ICW2: vector base */
188 /* No ICW3 (no cascade) */
189 sbc82xx_i8259_map[1] = 0x01; /* ICW4: 8086 mode, normal EOI */
190
191 sbc82xx_i8259_map[0] = 0x0b; /* OCW3: Read IS register on RD# pulse */
192
193 sbc82xx_i8259_map[1] = sbc82xx_i8259_mask; /* Set interrupt mask */
194
195 /* Request cascade IRQ */
196 if (setup_irq(SIU_INT_IRQ6, &sbc82xx_i8259_irqaction)) {
197 printk("Installation of i8259 IRQ demultiplexer failed.\n");
198 }
199}
200
201static int sbc82xx_pci_map_irq(struct pci_dev *dev, unsigned char idsel,
202 unsigned char pin)
203{
204 static char pci_irq_table[][4] = {
205 /*
206 * PCI IDSEL/INTPIN->INTLINE
207 * A B C D
208 */
209 { SBC82xx_PIRQA, SBC82xx_PIRQB, SBC82xx_PIRQC, SBC82xx_PIRQD }, /* IDSEL 16 - PMC slot */
210 { SBC82xx_PC_IRQA, SBC82xx_PC_IRQB, -1, -1 }, /* IDSEL 17 - CardBus */
211 { SBC82xx_PIRQA, SBC82xx_PIRQB, SBC82xx_PIRQC, SBC82xx_PIRQD }, /* IDSEL 18 - PCI-X bridge */
212 };
213
214 const long min_idsel = 16, max_idsel = 18, irqs_per_slot = 4;
215
216 return PCI_IRQ_TABLE_LOOKUP;
217}
218
219static void __devinit quirk_sbc8260_cardbus(struct pci_dev *pdev)
220{
221 uint32_t ctrl;
222
223 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(17, 0))
224 return;
225
226 printk(KERN_INFO "Setting up CardBus controller\n");
227
228 /* Set P2CCLK bit in System Control Register */
229 pci_read_config_dword(pdev, 0x80, &ctrl);
230 ctrl |= (1<<27);
231 pci_write_config_dword(pdev, 0x80, ctrl);
232
233 /* Set MFUNC up for PCI IRQ routing via INTA and INTB, and LEDs. */
234 pci_write_config_dword(pdev, 0x8c, 0x00c01d22);
235
236}
237DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, quirk_sbc8260_cardbus);
238
239void __init
240m82xx_board_init(void)
241{
242 /* u-boot may be using one of the FCC Ethernet devices.
243 Use the MAC address to the SCC. */
244 __res[offsetof(bd_t, bi_enetaddr[5])] &= ~3;
245
246 /* Anything special for this platform */
247 callback_init_IRQ = ppc_md.init_IRQ;
248
249 ppc_md.init_IRQ = sbc82xx_init_IRQ;
250 ppc_md.pci_map_irq = sbc82xx_pci_map_irq;
251#ifdef CONFIG_GEN_RTC
252 ppc_md.time_init = NULL;
253 ppc_md.get_rtc_time = NULL;
254 ppc_md.set_rtc_time = NULL;
255 ppc_md.nvram_read_val = NULL;
256 ppc_md.nvram_write_val = NULL;
257 late_time_init = sbc82xx_time_init;
258#endif /* CONFIG_GEN_RTC */
259}
diff --git a/arch/ppc/platforms/sbc82xx.h b/arch/ppc/platforms/sbc82xx.h
new file mode 100644
index 000000000000..e4042d4995f6
--- /dev/null
+++ b/arch/ppc/platforms/sbc82xx.h
@@ -0,0 +1,36 @@
1/* Board information for the SBCPowerQUICCII, which should be generic for
2 * all 8260 boards. The IMMR is now given to us so the hard define
3 * will soon be removed. All of the clock values are computed from
4 * the configuration SCMR and the Power-On-Reset word.
5 */
6
7#ifndef __PPC_SBC82xx_H__
8#define __PPC_SBC82xx_H__
9
10#include <asm/ppcboot.h>
11
12#define CPM_MAP_ADDR 0xf0000000
13
14#define SBC82xx_TODC_NVRAM_ADDR 0xd0000000
15
16#define SBC82xx_MACADDR_NVRAM_FCC1 0x220000c9 /* JP6B */
17#define SBC82xx_MACADDR_NVRAM_SCC1 0x220000cf /* JP6A */
18#define SBC82xx_MACADDR_NVRAM_FCC2 0x220000d5 /* JP7A */
19#define SBC82xx_MACADDR_NVRAM_FCC3 0x220000db /* JP7B */
20
21/* For our show_cpuinfo hooks. */
22#define CPUINFO_VENDOR "Wind River"
23#define CPUINFO_MACHINE "SBC PowerQUICC II"
24
25#define BOOTROM_RESTART_ADDR ((uint)0x40000104)
26
27#define SBC82xx_PC_IRQA (NR_SIU_INTS+0)
28#define SBC82xx_PC_IRQB (NR_SIU_INTS+1)
29#define SBC82xx_MPC185_IRQ (NR_SIU_INTS+2)
30#define SBC82xx_ATM_IRQ (NR_SIU_INTS+3)
31#define SBC82xx_PIRQA (NR_SIU_INTS+4)
32#define SBC82xx_PIRQB (NR_SIU_INTS+5)
33#define SBC82xx_PIRQC (NR_SIU_INTS+6)
34#define SBC82xx_PIRQD (NR_SIU_INTS+7)
35
36#endif /* __PPC_SBC82xx_H__ */
diff --git a/arch/ppc/platforms/sbs8260.h b/arch/ppc/platforms/sbs8260.h
new file mode 100644
index 000000000000..d51427a0f0d4
--- /dev/null
+++ b/arch/ppc/platforms/sbs8260.h
@@ -0,0 +1,28 @@
1#ifndef __ASSEMBLY__
2/* Board information for various SBS 8260 cards, which should be generic for
3 * all 8260 boards. The IMMR is now given to us so the hard define
4 * will soon be removed. All of the clock values are computed from
5 * the configuration SCMR and the Power-On-Reset word.
6 */
7
8#define CPM_MAP_ADDR ((uint)0xfe000000)
9
10
11/* A Board Information structure that is given to a program when
12 * prom starts it up.
13 */
14typedef struct bd_info {
15 unsigned int bi_memstart; /* Memory start address */
16 unsigned int bi_memsize; /* Memory (end) size in bytes */
17 unsigned int bi_intfreq; /* Internal Freq, in Hz */
18 unsigned int bi_busfreq; /* Bus Freq, in MHz */
19 unsigned int bi_cpmfreq; /* CPM Freq, in MHz */
20 unsigned int bi_brgfreq; /* BRG Freq, in MHz */
21 unsigned int bi_vco; /* VCO Out from PLL */
22 unsigned int bi_baudrate; /* Default console baud rate */
23 unsigned int bi_immr; /* IMMR when called from boot rom */
24 unsigned char bi_enetaddr[6];
25} bd_t;
26
27extern bd_t m8xx_board_info;
28#endif /* !__ASSEMBLY__ */
diff --git a/arch/ppc/platforms/spd8xx.h b/arch/ppc/platforms/spd8xx.h
new file mode 100644
index 000000000000..ed48d144f415
--- /dev/null
+++ b/arch/ppc/platforms/spd8xx.h
@@ -0,0 +1,92 @@
1/*
2 * Speech Design SPD8xxTS board specific definitions
3 *
4 * Copyright (c) 2000,2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifdef __KERNEL__
8#ifndef __ASM_SPD8XX_H__
9#define __ASM_SPD8XX_H__
10
11#include <linux/config.h>
12
13#include <asm/ppcboot.h>
14
15#ifndef __ASSEMBLY__
16#define SPD_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */
17#define SPD_IMAP_SIZE (64 * 1024) /* size of mapped area */
18
19#define IMAP_ADDR SPD_IMMR_BASE /* physical base address of IMMR area */
20#define IMAP_SIZE SPD_IMAP_SIZE /* mapped size of IMMR area */
21
22#define PCMCIA_MEM_ADDR ((uint)0xFE100000)
23#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
24
25#define IDE0_INTERRUPT 10 /* = IRQ5 */
26#define IDE1_INTERRUPT 12 /* = IRQ6 */
27#define CPM_INTERRUPT 13 /* = SIU_LEVEL6 (was: SIU_LEVEL2) */
28
29/* override the default number of IDE hardware interfaces */
30#define MAX_HWIFS 2
31
32/*
33 * Definitions for IDE0 Interface
34 */
35#define IDE0_BASE_OFFSET 0x0000 /* Offset in PCMCIA memory */
36#define IDE0_DATA_REG_OFFSET 0x0000
37#define IDE0_ERROR_REG_OFFSET 0x0081
38#define IDE0_NSECTOR_REG_OFFSET 0x0082
39#define IDE0_SECTOR_REG_OFFSET 0x0083
40#define IDE0_LCYL_REG_OFFSET 0x0084
41#define IDE0_HCYL_REG_OFFSET 0x0085
42#define IDE0_SELECT_REG_OFFSET 0x0086
43#define IDE0_STATUS_REG_OFFSET 0x0087
44#define IDE0_CONTROL_REG_OFFSET 0x0106
45#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */
46
47/*
48 * Definitions for IDE1 Interface
49 */
50#define IDE1_BASE_OFFSET 0x0C00 /* Offset in PCMCIA memory */
51#define IDE1_DATA_REG_OFFSET 0x0000
52#define IDE1_ERROR_REG_OFFSET 0x0081
53#define IDE1_NSECTOR_REG_OFFSET 0x0082
54#define IDE1_SECTOR_REG_OFFSET 0x0083
55#define IDE1_LCYL_REG_OFFSET 0x0084
56#define IDE1_HCYL_REG_OFFSET 0x0085
57#define IDE1_SELECT_REG_OFFSET 0x0086
58#define IDE1_STATUS_REG_OFFSET 0x0087
59#define IDE1_CONTROL_REG_OFFSET 0x0106
60#define IDE1_IRQ_REG_OFFSET 0x000A /* not used */
61
62/* CPM Ethernet through SCCx.
63 *
64 * Bits in parallel I/O port registers that have to be set/cleared
65 * to configure the pins for SCC2 use.
66 */
67#define PA_ENET_MDC ((ushort)0x0001) /* PA 15 !!! */
68#define PA_ENET_MDIO ((ushort)0x0002) /* PA 14 !!! */
69#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
70#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
71#define PA_ENET_RCLK ((ushort)0x0200) /* PA 6 */
72#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
73
74#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
75
76#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
77#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
78#define PC_ENET_RESET ((ushort)0x0100) /* PC 7 !!! */
79
80/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK2) to
81 * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
82 */
83#define SICR_ENET_MASK ((uint)0x0000ff00)
84#define SICR_ENET_CLKRT ((uint)0x00002E00)
85
86/* We don't use the 8259.
87*/
88#define NR_8259_INTS 0
89
90#endif /* !__ASSEMBLY__ */
91#endif /* __ASM_SPD8XX_H__ */
92#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/spruce.c b/arch/ppc/platforms/spruce.c
new file mode 100644
index 000000000000..5ad70d357cb9
--- /dev/null
+++ b/arch/ppc/platforms/spruce.c
@@ -0,0 +1,325 @@
1/*
2 * arch/ppc/platforms/spruce.c
3 *
4 * Board and PCI setup routines for IBM Spruce
5 *
6 * Author: MontaVista Software <source@mvista.com>
7 *
8 * 2000-2004 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/kdev_t.h>
22#include <linux/types.h>
23#include <linux/major.h>
24#include <linux/initrd.h>
25#include <linux/console.h>
26#include <linux/delay.h>
27#include <linux/seq_file.h>
28#include <linux/ide.h>
29#include <linux/root_dev.h>
30#include <linux/serial.h>
31#include <linux/tty.h>
32#include <linux/serial_core.h>
33
34#include <asm/system.h>
35#include <asm/pgtable.h>
36#include <asm/page.h>
37#include <asm/dma.h>
38#include <asm/io.h>
39#include <asm/machdep.h>
40#include <asm/time.h>
41#include <asm/todc.h>
42#include <asm/bootinfo.h>
43#include <asm/kgdb.h>
44
45#include <syslib/cpc700.h>
46
47#include "spruce.h"
48
49static inline int
50spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
51{
52 static char pci_irq_table[][4] =
53 /*
54 * PCI IDSEL/INTPIN->INTLINE
55 * A B C D
56 */
57 {
58 {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */
59 {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */
60 {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */
61 {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */
62 };
63
64 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
65 return PCI_IRQ_TABLE_LOOKUP;
66}
67
68static void __init
69spruce_setup_hose(void)
70{
71 struct pci_controller *hose;
72
73 /* Setup hose */
74 hose = pcibios_alloc_controller();
75 if (!hose)
76 return;
77
78 hose->first_busno = 0;
79 hose->last_busno = 0xff;
80
81 pci_init_resource(&hose->io_resource,
82 SPRUCE_PCI_LOWER_IO,
83 SPRUCE_PCI_UPPER_IO,
84 IORESOURCE_IO,
85 "PCI host bridge");
86
87 pci_init_resource(&hose->mem_resources[0],
88 SPRUCE_PCI_LOWER_MEM,
89 SPRUCE_PCI_UPPER_MEM,
90 IORESOURCE_MEM,
91 "PCI host bridge");
92
93 hose->io_space.start = SPRUCE_PCI_LOWER_IO;
94 hose->io_space.end = SPRUCE_PCI_UPPER_IO;
95 hose->mem_space.start = SPRUCE_PCI_LOWER_MEM;
96 hose->mem_space.end = SPRUCE_PCI_UPPER_MEM;
97 hose->io_base_virt = (void *)SPRUCE_ISA_IO_BASE;
98
99 setup_indirect_pci(hose,
100 SPRUCE_PCI_CONFIG_ADDR,
101 SPRUCE_PCI_CONFIG_DATA);
102
103 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
104
105 ppc_md.pci_swizzle = common_swizzle;
106 ppc_md.pci_map_irq = spruce_map_irq;
107}
108
109/*
110 * CPC700 PIC interrupt programming table
111 *
112 * First entry is the sensitivity (level/edge), second is the polarity.
113 */
114unsigned int cpc700_irq_assigns[32][2] = {
115 { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */
116 { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */
117 { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */
118 { 0, 1 }, /* IRQ 3: UART 0 - active high */
119 { 0, 1 }, /* IRQ 4: UART 1 - active high */
120 { 0, 1 }, /* IRQ 5: ICC 0 - active high */
121 { 0, 1 }, /* IRQ 6: ICC 1 - active high */
122 { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */
123 { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */
124 { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */
125 { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */
126 { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */
127 { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */
128 { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */
129 { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */
130 { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */
131 { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */
132 { 0, 0 }, /* IRQ 17: Reserved */
133 { 0, 0 }, /* IRQ 18: Reserved */
134 { 0, 0 }, /* IRQ 19: Reserved */
135 { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */
136 { 1, 1 }, /* IRQ 21: Mouse - rising edge */
137 { 1, 1 }, /* IRQ 22: Keyboard - rising edge */
138 { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */
139 { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */
140 { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */
141 { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */
142};
143
144static void __init
145spruce_calibrate_decr(void)
146{
147 int freq, divisor = 4;
148
149 /* determine processor bus speed */
150 freq = SPRUCE_BUS_SPEED;
151 tb_ticks_per_jiffy = freq / HZ / divisor;
152 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
153}
154
155static int
156spruce_show_cpuinfo(struct seq_file *m)
157{
158 seq_printf(m, "vendor\t\t: IBM\n");
159 seq_printf(m, "machine\t\t: Spruce\n");
160
161 return 0;
162}
163
164static void __init
165spruce_early_serial_map(void)
166{
167 u32 uart_clk;
168 struct uart_port serial_req;
169
170 if (SPRUCE_UARTCLK_IS_33M(readb(SPRUCE_FPGA_REG_A)))
171 uart_clk = SPRUCE_BAUD_33M * 16;
172 else
173 uart_clk = SPRUCE_BAUD_30M * 16;
174
175 /* Setup serial port access */
176 memset(&serial_req, 0, sizeof(serial_req));
177 serial_req.uartclk = uart_clk;
178 serial_req.irq = UART0_INT;
179 serial_req.flags = ASYNC_BOOT_AUTOCONF;
180 serial_req.iotype = SERIAL_IO_MEM;
181 serial_req.membase = (u_char *)UART0_IO_BASE;
182 serial_req.regshift = 0;
183
184#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)
185 gen550_init(0, &serial_req);
186#endif
187#ifdef CONFIG_SERIAL_8250
188 if (early_serial_setup(&serial_req) != 0)
189 printk("Early serial init of port 0 failed\n");
190#endif
191
192 /* Assume early_serial_setup() doesn't modify serial_req */
193 serial_req.line = 1;
194 serial_req.irq = UART1_INT;
195 serial_req.membase = (u_char *)UART1_IO_BASE;
196
197#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG)
198 gen550_init(1, &serial_req);
199#endif
200#ifdef CONFIG_SERIAL_8250
201 if (early_serial_setup(&serial_req) != 0)
202 printk("Early serial init of port 1 failed\n");
203#endif
204}
205
206TODC_ALLOC();
207
208static void __init
209spruce_setup_arch(void)
210{
211 /* Setup TODC access */
212 TODC_INIT(TODC_TYPE_DS1643, 0, 0, SPRUCE_RTC_BASE_ADDR, 8);
213
214 /* init to some ~sane value until calibrate_delay() runs */
215 loops_per_jiffy = 50000000 / HZ;
216
217 /* Setup PCI host bridge */
218 spruce_setup_hose();
219
220#ifdef CONFIG_BLK_DEV_INITRD
221 if (initrd_start)
222 ROOT_DEV = Root_RAM0;
223 else
224#endif
225#ifdef CONFIG_ROOT_NFS
226 ROOT_DEV = Root_NFS;
227#else
228 ROOT_DEV = Root_SDA1;
229#endif
230
231 /* Identify the system */
232 printk(KERN_INFO "System Identification: IBM Spruce\n");
233 printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
234}
235
236static void
237spruce_restart(char *cmd)
238{
239 local_irq_disable();
240
241 /* SRR0 has system reset vector, SRR1 has default MSR value */
242 /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */
243 __asm__ __volatile__
244 ("\n\
245 lis 3,0xfff0 \n\
246 ori 3,3,0x0100 \n\
247 mtspr 26,3 \n\
248 li 3,0 \n\
249 mtspr 27,3 \n\
250 rfi \n\
251 ");
252 for(;;);
253}
254
255static void
256spruce_power_off(void)
257{
258 for(;;);
259}
260
261static void
262spruce_halt(void)
263{
264 spruce_restart(NULL);
265}
266
267static void __init
268spruce_map_io(void)
269{
270 io_block_mapping(SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE,
271 0x08000000, _PAGE_IO);
272}
273
274/*
275 * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1.
276 */
277static __inline__ void
278spruce_set_bat(void)
279{
280 mb();
281 mtspr(SPRN_DBAT1U, 0xf8000ffe);
282 mtspr(SPRN_DBAT1L, 0xf800002a);
283 mb();
284}
285
286void __init
287platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
288 unsigned long r6, unsigned long r7)
289{
290 parse_bootinfo(find_bootinfo());
291
292 /* Map in board regs, etc. */
293 spruce_set_bat();
294
295 isa_io_base = SPRUCE_ISA_IO_BASE;
296 pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE;
297
298 ppc_md.setup_arch = spruce_setup_arch;
299 ppc_md.show_cpuinfo = spruce_show_cpuinfo;
300 ppc_md.init_IRQ = cpc700_init_IRQ;
301 ppc_md.get_irq = cpc700_get_irq;
302
303 ppc_md.setup_io_mappings = spruce_map_io;
304
305 ppc_md.restart = spruce_restart;
306 ppc_md.power_off = spruce_power_off;
307 ppc_md.halt = spruce_halt;
308
309 ppc_md.time_init = todc_time_init;
310 ppc_md.set_rtc_time = todc_set_rtc_time;
311 ppc_md.get_rtc_time = todc_get_rtc_time;
312 ppc_md.calibrate_decr = spruce_calibrate_decr;
313
314 ppc_md.nvram_read_val = todc_direct_read_val;
315 ppc_md.nvram_write_val = todc_direct_write_val;
316
317 spruce_early_serial_map();
318
319#ifdef CONFIG_SERIAL_TEXT_DEBUG
320 ppc_md.progress = gen550_progress;
321#endif /* CONFIG_SERIAL_TEXT_DEBUG */
322#ifdef CONFIG_KGDB
323 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
324#endif
325}
diff --git a/arch/ppc/platforms/spruce.h b/arch/ppc/platforms/spruce.h
new file mode 100644
index 000000000000..a31ff7ee698f
--- /dev/null
+++ b/arch/ppc/platforms/spruce.h
@@ -0,0 +1,71 @@
1/*
2 * include/asm-ppc/platforms/spruce.h
3 *
4 * Definitions for IBM Spruce reference board support
5 *
6 * Authors: Matt Porter and Johnnie Peters
7 * mporter@mvista.com
8 * jpeters@mvista.com
9 *
10 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
14 */
15
16#ifdef __KERNEL__
17#ifndef __ASM_SPRUCE_H__
18#define __ASM_SPRUCE_H__
19
20#define SPRUCE_PCI_CONFIG_ADDR 0xfec00000
21#define SPRUCE_PCI_CONFIG_DATA 0xfec00004
22
23#define SPRUCE_PCI_PHY_IO_BASE 0xf8000000
24#define SPRUCE_PCI_IO_BASE SPRUCE_PCI_PHY_IO_BASE
25
26#define SPRUCE_PCI_SYS_MEM_BASE 0x00000000
27
28#define SPRUCE_PCI_LOWER_MEM 0x80000000
29#define SPRUCE_PCI_UPPER_MEM 0x9fffffff
30#define SPRUCE_PCI_LOWER_IO 0x00000000
31#define SPRUCE_PCI_UPPER_IO 0x03ffffff
32
33#define SPRUCE_ISA_IO_BASE SPRUCE_PCI_IO_BASE
34
35#define SPRUCE_MEM_SIZE 0x04000000
36#define SPRUCE_BUS_SPEED 66666667
37
38#define SPRUCE_NVRAM_BASE_ADDR 0xff800000
39#define SPRUCE_RTC_BASE_ADDR SPRUCE_NVRAM_BASE_ADDR
40
41/*
42 * Serial port defines
43 */
44#define SPRUCE_FPGA_REG_A 0xff820000
45#define SPRUCE_UARTCLK_33M 0x02
46#define SPRUCE_UARTCLK_IS_33M(reg) (reg & SPRUCE_UARTCLK_33M)
47
48#define UART0_IO_BASE 0xff600300
49#define UART1_IO_BASE 0xff600400
50
51#define RS_TABLE_SIZE 2
52
53#define SPRUCE_BAUD_33M (33000000/64)
54#define SPRUCE_BAUD_30M (30000000/64)
55#define BASE_BAUD SPRUCE_BAUD_33M
56
57#define UART0_INT 3
58#define UART1_INT 4
59
60#define STD_UART_OP(num) \
61 { 0, BASE_BAUD, 0, UART##num##_INT, \
62 ASYNC_BOOT_AUTOCONF, \
63 iomem_base: (unsigned char *) UART##num##_IO_BASE, \
64 io_type: SERIAL_IO_MEM},
65
66#define SERIAL_PORT_DFNS \
67 STD_UART_OP(0) \
68 STD_UART_OP(1)
69
70#endif /* __ASM_SPRUCE_H__ */
71#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/tqm8260.h b/arch/ppc/platforms/tqm8260.h
new file mode 100644
index 000000000000..c7a78a646c66
--- /dev/null
+++ b/arch/ppc/platforms/tqm8260.h
@@ -0,0 +1,23 @@
1/*
2 * TQM8260 board specific definitions
3 *
4 * Copyright (c) 2001 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifndef __TQM8260_PLATFORM
8#define __TQM8260_PLATFORM
9
10#include <linux/config.h>
11
12#include <asm/ppcboot.h>
13
14#define CPM_MAP_ADDR ((uint)0xFFF00000)
15#define PHY_INTERRUPT 25
16
17/* For our show_cpuinfo hooks. */
18#define CPUINFO_VENDOR "IN2 Systems"
19#define CPUINFO_MACHINE "TQM8260 PowerPC"
20
21#define BOOTROM_RESTART_ADDR ((uint)0x40000104)
22
23#endif /* __TQM8260_PLATFORM */
diff --git a/arch/ppc/platforms/tqm8260_setup.c b/arch/ppc/platforms/tqm8260_setup.c
new file mode 100644
index 000000000000..a8880bfc034b
--- /dev/null
+++ b/arch/ppc/platforms/tqm8260_setup.c
@@ -0,0 +1,44 @@
1/*
2 * arch/ppc/platforms/tqm8260_setup.c
3 *
4 * TQM8260 platform support
5 *
6 * Author: Allen Curtis <acurtis@onz.com>
7 * Derived from: m8260_setup.c by Dan Malek, MVista
8 *
9 * Copyright 2002 Ones and Zeros, 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
17#include <linux/init.h>
18
19#include <asm/immap_cpm2.h>
20#include <asm/mpc8260.h>
21#include <asm/machdep.h>
22
23static int
24tqm8260_set_rtc_time(unsigned long time)
25{
26 ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt = time;
27 ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcntsc = 0x3;
28
29 return(0);
30}
31
32static unsigned long
33tqm8260_get_rtc_time(void)
34{
35 return ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt;
36}
37
38void __init
39m82xx_board_init(void)
40{
41 /* Anything special for this platform */
42 ppc_md.set_rtc_time = tqm8260_set_rtc_time;
43 ppc_md.get_rtc_time = tqm8260_get_rtc_time;
44}
diff --git a/arch/ppc/platforms/tqm8xx.h b/arch/ppc/platforms/tqm8xx.h
new file mode 100644
index 000000000000..2150dc87b18f
--- /dev/null
+++ b/arch/ppc/platforms/tqm8xx.h
@@ -0,0 +1,179 @@
1/*
2 * TQM8xx(L) board specific definitions
3 *
4 * Copyright (c) 1999-2002 Wolfgang Denk (wd@denx.de)
5 */
6
7#ifdef __KERNEL__
8#ifndef __MACH_TQM8xx_H
9#define __MACH_TQM8xx_H
10
11#include <linux/config.h>
12
13#include <asm/ppcboot.h>
14
15#ifndef __ASSEMBLY__
16#define TQM_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */
17#define TQM_IMAP_SIZE (64 * 1024) /* size of mapped area */
18
19#define IMAP_ADDR TQM_IMMR_BASE /* physical base address of IMMR area */
20#define IMAP_SIZE TQM_IMAP_SIZE /* mapped size of IMMR area */
21
22/*-----------------------------------------------------------------------
23 * PCMCIA stuff
24 *-----------------------------------------------------------------------
25 *
26 */
27#define PCMCIA_MEM_SIZE ( 64 << 20 )
28
29#ifndef CONFIG_KUP4K
30# define MAX_HWIFS 1 /* overwrite default in include/asm-ppc/ide.h */
31
32#else /* CONFIG_KUP4K */
33
34# define MAX_HWIFS 2 /* overwrite default in include/asm-ppc/ide.h */
35# ifndef __ASSEMBLY__
36# include <asm/8xx_immap.h>
37static __inline__ void ide_led(int on)
38{
39 volatile immap_t *immap = (immap_t *)IMAP_ADDR;
40
41 if (on) {
42 immap->im_ioport.iop_padat &= ~0x80;
43 } else {
44 immap->im_ioport.iop_padat |= 0x80;
45 }
46}
47# endif /* __ASSEMBLY__ */
48# define IDE_LED(x) ide_led((x))
49#endif /* CONFIG_KUP4K */
50
51/*
52 * Definitions for IDE0 Interface
53 */
54#define IDE0_BASE_OFFSET 0
55#define IDE0_DATA_REG_OFFSET (PCMCIA_MEM_SIZE + 0x320)
56#define IDE0_ERROR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 1)
57#define IDE0_NSECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 2)
58#define IDE0_SECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 3)
59#define IDE0_LCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 4)
60#define IDE0_HCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 5)
61#define IDE0_SELECT_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 6)
62#define IDE0_STATUS_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 7)
63#define IDE0_CONTROL_REG_OFFSET 0x0106
64#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */
65
66/* define IO_BASE for PCMCIA */
67#define _IO_BASE 0x80000000
68#define _IO_BASE_SIZE (64<<10)
69
70#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */
71#define PHY_INTERRUPT 12 /* = IRQ6 */
72#define IDE0_INTERRUPT 13
73
74#ifdef CONFIG_IDE
75#endif
76
77/*-----------------------------------------------------------------------
78 * CPM Ethernet through SCCx.
79 *-----------------------------------------------------------------------
80 *
81 */
82
83/*** TQM823L, TQM850L ***********************************************/
84
85#if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
86/* Bits in parallel I/O port registers that have to be set/cleared
87 * to configure the pins for SCC1 use.
88 */
89#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
90#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
91#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
92#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
93
94#define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
95
96#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
97#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
98
99/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
100 * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
101 */
102#define SICR_ENET_MASK ((uint)0x0000ff00)
103#define SICR_ENET_CLKRT ((uint)0x00002600)
104#endif /* CONFIG_TQM823L, CONFIG_TQM850L */
105
106/*** TQM860L ********************************************************/
107
108#ifdef CONFIG_TQM860L
109/* Bits in parallel I/O port registers that have to be set/cleared
110 * to configure the pins for SCC1 use.
111 */
112#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */
113#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */
114#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
115#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
116
117#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */
118#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */
119#define PC_ENET_RENA ((ushort)0x0020) /* PC 10 */
120
121/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
122 * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
123 */
124#define SICR_ENET_MASK ((uint)0x000000ff)
125#define SICR_ENET_CLKRT ((uint)0x00000026)
126#endif /* CONFIG_TQM860L */
127
128/*** FPS850L *********************************************************/
129
130#ifdef CONFIG_FPS850L
131/* Bits in parallel I/O port registers that have to be set/cleared
132 * to configure the pins for SCC1 use.
133 */
134#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
135#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
136#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
137#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
138
139#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */
140#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
141#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
142
143/* Control bits in the SICR to route TCLK (CLK2) and RCLK (CLK4) to
144 * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
145 */
146#define SICR_ENET_MASK ((uint)0x0000ff00)
147#define SICR_ENET_CLKRT ((uint)0x00002600)
148#endif /* CONFIG_FPS850L */
149
150/*** SM850 *********************************************************/
151
152/* The SM850 Service Module uses SCC2 for IrDA and SCC3 for Ethernet */
153
154#ifdef CONFIG_SM850
155#define PB_ENET_RXD ((uint)0x00000004) /* PB 29 */
156#define PB_ENET_TXD ((uint)0x00000002) /* PB 30 */
157#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
158#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
159
160#define PC_ENET_LBK ((ushort)0x0008) /* PC 12 */
161#define PC_ENET_TENA ((ushort)0x0004) /* PC 13 */
162
163#define PC_ENET_RENA ((ushort)0x0800) /* PC 4 */
164#define PC_ENET_CLSN ((ushort)0x0400) /* PC 5 */
165
166/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
167 * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero.
168 */
169#define SICR_ENET_MASK ((uint)0x00FF0000)
170#define SICR_ENET_CLKRT ((uint)0x00260000)
171#endif /* CONFIG_SM850 */
172
173/* We don't use the 8259.
174*/
175#define NR_8259_INTS 0
176
177#endif /* !__ASSEMBLY__ */
178#endif /* __MACH_TQM8xx_H */
179#endif /* __KERNEL__ */