aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/syslib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/syslib')
-rw-r--r--arch/ppc/syslib/Makefile96
-rw-r--r--arch/ppc/syslib/btext.c860
-rw-r--r--arch/ppc/syslib/cpc700.h96
-rw-r--r--arch/ppc/syslib/cpc700_pic.c181
-rw-r--r--arch/ppc/syslib/cpm2_common.c196
-rw-r--r--arch/ppc/syslib/cpm2_pic.c177
-rw-r--r--arch/ppc/syslib/cpm2_pic.h8
-rw-r--r--arch/ppc/syslib/gen550.h14
-rw-r--r--arch/ppc/syslib/gen550_dbg.c179
-rw-r--r--arch/ppc/syslib/gen550_kgdb.c83
-rw-r--r--arch/ppc/syslib/gt64260_pic.c323
-rw-r--r--arch/ppc/syslib/harrier.c300
-rw-r--r--arch/ppc/syslib/hawk_common.c317
-rw-r--r--arch/ppc/syslib/i8259.c213
-rw-r--r--arch/ppc/syslib/ibm440gp_common.c73
-rw-r--r--arch/ppc/syslib/ibm440gp_common.h32
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c294
-rw-r--r--arch/ppc/syslib/ibm440gx_common.h58
-rw-r--r--arch/ppc/syslib/ibm440sp_common.c68
-rw-r--r--arch/ppc/syslib/ibm440sp_common.h23
-rw-r--r--arch/ppc/syslib/ibm44x_common.c235
-rw-r--r--arch/ppc/syslib/ibm44x_common.h45
-rw-r--r--arch/ppc/syslib/ibm_ocp.c10
-rw-r--r--arch/ppc/syslib/indirect_pci.c134
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c455
-rw-r--r--arch/ppc/syslib/m8260_setup.c266
-rw-r--r--arch/ppc/syslib/m82xx_pci.c346
-rw-r--r--arch/ppc/syslib/m82xx_pci.h92
-rw-r--r--arch/ppc/syslib/m8xx_setup.c465
-rw-r--r--arch/ppc/syslib/m8xx_wdt.c148
-rw-r--r--arch/ppc/syslib/m8xx_wdt.h20
-rw-r--r--arch/ppc/syslib/mpc10x_common.c654
-rw-r--r--arch/ppc/syslib/mpc52xx_devices.c317
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c289
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.h137
-rw-r--r--arch/ppc/syslib/mpc52xx_pic.c254
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c313
-rw-r--r--arch/ppc/syslib/mpc52xx_sys.c36
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c243
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c61
-rw-r--r--arch/ppc/syslib/mv64360_pic.c423
-rw-r--r--arch/ppc/syslib/mv64x60.c2485
-rw-r--r--arch/ppc/syslib/mv64x60_dbg.c121
-rw-r--r--arch/ppc/syslib/mv64x60_win.c1165
-rw-r--r--arch/ppc/syslib/ocp.c482
-rw-r--r--arch/ppc/syslib/open_pic.c1087
-rw-r--r--arch/ppc/syslib/open_pic2.c710
-rw-r--r--arch/ppc/syslib/open_pic_defs.h287
-rw-r--r--arch/ppc/syslib/pci_auto.c515
-rw-r--r--arch/ppc/syslib/ppc403_pic.c125
-rw-r--r--arch/ppc/syslib/ppc405_pci.c170
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.c441
-rw-r--r--arch/ppc/syslib/ppc440spe_pcie.h149
-rw-r--r--arch/ppc/syslib/ppc4xx_dma.c710
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c284
-rw-r--r--arch/ppc/syslib/ppc4xx_setup.c271
-rw-r--r--arch/ppc/syslib/ppc4xx_sgdma.c464
-rw-r--r--arch/ppc/syslib/ppc8xx_pic.c126
-rw-r--r--arch/ppc/syslib/ppc8xx_pic.h19
-rw-r--r--arch/ppc/syslib/ppc_sys.c329
-rw-r--r--arch/ppc/syslib/pq2_devices.c393
-rw-r--r--arch/ppc/syslib/pq2_sys.c203
-rw-r--r--arch/ppc/syslib/prep_nvram.c135
-rw-r--r--arch/ppc/syslib/qspan_pci.c380
-rw-r--r--arch/ppc/syslib/todc_time.c511
-rw-r--r--arch/ppc/syslib/virtex_devices.c276
-rw-r--r--arch/ppc/syslib/virtex_devices.h35
-rw-r--r--arch/ppc/syslib/xilinx_pic.c153
68 files changed, 0 insertions, 20560 deletions
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
deleted file mode 100644
index 52ddebe6c6d1..000000000000
--- a/arch/ppc/syslib/Makefile
+++ /dev/null
@@ -1,96 +0,0 @@
1#
2# Makefile for the linux kernel.
3#
4
5CFLAGS_prom_init.o += -fPIC
6CFLAGS_btext.o += -fPIC
7
8wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o
9
10obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
11obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o
12obj-$(CONFIG_PPC_OCP) += ocp.o
13obj-$(CONFIG_IBM_OCP) += ibm_ocp.o
14obj-$(CONFIG_44x) += ibm44x_common.o
15obj-$(CONFIG_440EP) += ibm440gx_common.o
16obj-$(CONFIG_440GP) += ibm440gp_common.o
17obj-$(CONFIG_440GX) += ibm440gx_common.o
18obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o
19obj-$(CONFIG_440SPE) += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
20ifeq ($(CONFIG_4xx),y)
21ifeq ($(CONFIG_XILINX_VIRTEX),y)
22obj-$(CONFIG_40x) += xilinx_pic.o
23obj-y += virtex_devices.o
24else
25ifeq ($(CONFIG_403),y)
26obj-$(CONFIG_40x) += ppc403_pic.o
27else
28obj-$(CONFIG_40x) += ppc4xx_pic.o
29endif
30endif
31obj-$(CONFIG_44x) += ppc4xx_pic.o
32obj-$(CONFIG_40x) += ppc4xx_setup.o
33obj-$(CONFIG_GEN_RTC) += todc_time.o
34obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
35obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
36ifeq ($(CONFIG_40x),y)
37obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o
38endif
39endif
40obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
41 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
42obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
43obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
44obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
45obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
46obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o
47obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o
48obj-$(CONFIG_EV64360) += todc_time.o
49obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o
50obj-$(CONFIG_GT64260) += gt64260_pic.o
51obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o
52obj-$(CONFIG_HDPU) += pci_auto.o
53obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o
54obj-$(CONFIG_YUCCA) += pci_auto.o todc_time.o
55obj-$(CONFIG_KATANA) += pci_auto.o
56obj-$(CONFIG_MV64360) += mv64360_pic.o
57obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o
58obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \
59 pci_auto.o hawk_common.o
60obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o
61obj-$(CONFIG_PAL4) += cpc700_pic.o
62obj-$(CONFIG_POWERPMC250) += pci_auto.o
63obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \
64 todc_time.o pci_auto.o
65obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \
66 hawk_common.o
67obj-$(CONFIG_HARRIER) += harrier.o
68obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o
69obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o
70obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o
71obj-$(CONFIG_SBC82xx) += todc_time.o
72obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \
73 todc_time.o
74obj-$(CONFIG_TAISHAN) += pci_auto.o
75obj-$(CONFIG_8260) += m8260_setup.o pq2_devices.o pq2_sys.o \
76 ppc_sys.o
77obj-$(CONFIG_PCI_8260) += m82xx_pci.o pci_auto.o
78obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
79obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
80ifeq ($(CONFIG_PPC_GEN550),y)
81obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o
82obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o
83endif
84ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
85obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o
86endif
87obj-$(CONFIG_BOOTX_TEXT) += btext.o
88obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o
89obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o
90obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \
91 mpc52xx_sys.o mpc52xx_devices.o ppc_sys.o
92ifeq ($(CONFIG_PPC_MPC52xx),y)
93obj-$(CONFIG_PCI) += mpc52xx_pci.o
94endif
95
96obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/ppc/syslib/btext.c b/arch/ppc/syslib/btext.c
deleted file mode 100644
index d11667046f21..000000000000
--- a/arch/ppc/syslib/btext.c
+++ /dev/null
@@ -1,860 +0,0 @@
1/*
2 * Procedures for drawing on the screen early on in the boot process.
3 *
4 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 */
6#include <linux/kernel.h>
7#include <linux/string.h>
8#include <linux/init.h>
9#include <linux/utsrelease.h>
10
11#include <asm/sections.h>
12#include <asm/bootx.h>
13#include <asm/btext.h>
14#include <asm/prom.h>
15#include <asm/page.h>
16#include <asm/mmu.h>
17#include <asm/pgtable.h>
18#include <asm/io.h>
19#include <asm/reg.h>
20
21#define NO_SCROLL
22
23#ifndef NO_SCROLL
24static void scrollscreen(void);
25#endif
26
27static void draw_byte(unsigned char c, long locX, long locY);
28static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
29static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
30static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
31
32static int g_loc_X;
33static int g_loc_Y;
34static int g_max_loc_X;
35static int g_max_loc_Y;
36
37unsigned long disp_BAT[2] __initdata = {0, 0};
38
39#define cmapsz (16*256)
40
41static unsigned char vga_font[cmapsz];
42
43int boot_text_mapped;
44int force_printk_to_btext = 0;
45
46boot_infos_t disp_bi;
47
48extern char *klimit;
49
50/*
51 * Powermac can use btext_* after boot for xmon,
52 * chrp only uses it during early boot.
53 */
54#ifdef CONFIG_XMON
55#define BTEXT
56#define BTDATA
57#else
58#define BTEXT __init
59#define BTDATA __initdata
60#endif /* CONFIG_XMON */
61
62/*
63 * This is called only when we are booted via BootX.
64 */
65void __init
66btext_init(boot_infos_t *bi)
67{
68 g_loc_X = 0;
69 g_loc_Y = 0;
70 g_max_loc_X = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
71 g_max_loc_Y = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
72 disp_bi = *bi;
73 boot_text_mapped = 1;
74}
75
76void __init
77btext_welcome(void)
78{
79 unsigned long flags;
80 unsigned long pvr;
81 boot_infos_t* bi = &disp_bi;
82
83 btext_drawstring("Welcome to Linux, kernel " UTS_RELEASE "\n");
84 btext_drawstring("\nlinked at : 0x");
85 btext_drawhex(KERNELBASE);
86 btext_drawstring("\nframe buffer at : 0x");
87 btext_drawhex((unsigned long)bi->dispDeviceBase);
88 btext_drawstring(" (phys), 0x");
89 btext_drawhex((unsigned long)bi->logicalDisplayBase);
90 btext_drawstring(" (log)");
91 btext_drawstring("\nklimit : 0x");
92 btext_drawhex((unsigned long)klimit);
93 btext_drawstring("\nMSR : 0x");
94 __asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
95 btext_drawhex(flags);
96 __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
97 pvr >>= 16;
98 if (pvr > 1) {
99 btext_drawstring("\nHID0 : 0x");
100 __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
101 btext_drawhex(flags);
102 }
103 if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
104 btext_drawstring("\nICTC : 0x");
105 __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
106 btext_drawhex(flags);
107 }
108 btext_drawstring("\n\n");
109}
110
111/* Calc BAT values for mapping the display and store them
112 * in disp_BAT. Those values are then used from head.S to map
113 * the display during identify_machine() and MMU_Init()
114 *
115 * The display is mapped to virtual address 0xD0000000, rather
116 * than 1:1, because some some CHRP machines put the frame buffer
117 * in the region starting at 0xC0000000 (KERNELBASE).
118 * This mapping is temporary and will disappear as soon as the
119 * setup done by MMU_Init() is applied.
120 *
121 * For now, we align the BAT and then map 8Mb on 601 and 16Mb
122 * on other PPCs. This may cause trouble if the framebuffer
123 * is really badly aligned, but I didn't encounter this case
124 * yet.
125 */
126void __init
127btext_prepare_BAT(void)
128{
129 boot_infos_t* bi = &disp_bi;
130 unsigned long vaddr = KERNELBASE + 0x10000000;
131 unsigned long addr;
132 unsigned long lowbits;
133
134 addr = (unsigned long)bi->dispDeviceBase;
135 if (!addr) {
136 boot_text_mapped = 0;
137 return;
138 }
139 if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
140 /* 603, 604, G3, G4, ... */
141 lowbits = addr & ~0xFF000000UL;
142 addr &= 0xFF000000UL;
143 disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
144 disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
145 } else {
146 /* 601 */
147 lowbits = addr & ~0xFF800000UL;
148 addr &= 0xFF800000UL;
149 disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
150 disp_BAT[1] = addr | BL_8M | 0x40;
151 }
152 bi->logicalDisplayBase = (void *) (vaddr + lowbits);
153}
154
155/* This function will enable the early boot text when doing OF booting. This
156 * way, xmon output should work too
157 */
158void __init
159btext_setup_display(int width, int height, int depth, int pitch,
160 unsigned long address)
161{
162 boot_infos_t* bi = &disp_bi;
163
164 g_loc_X = 0;
165 g_loc_Y = 0;
166 g_max_loc_X = width / 8;
167 g_max_loc_Y = height / 16;
168 bi->logicalDisplayBase = (unsigned char *)address;
169 bi->dispDeviceBase = (unsigned char *)address;
170 bi->dispDeviceRowBytes = pitch;
171 bi->dispDeviceDepth = depth;
172 bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
173 bi->dispDeviceRect[2] = width;
174 bi->dispDeviceRect[3] = height;
175 boot_text_mapped = 1;
176}
177
178/* Here's a small text engine to use during early boot
179 * or for debugging purposes
180 *
181 * todo:
182 *
183 * - build some kind of vgacon with it to enable early printk
184 * - move to a separate file
185 * - add a few video driver hooks to keep in sync with display
186 * changes.
187 */
188
189void
190map_boot_text(void)
191{
192 unsigned long base, offset, size;
193 boot_infos_t *bi = &disp_bi;
194 unsigned char *vbase;
195
196 /* By default, we are no longer mapped */
197 boot_text_mapped = 0;
198 if (bi->dispDeviceBase == 0)
199 return;
200 base = ((unsigned long) bi->dispDeviceBase) & 0xFFFFF000UL;
201 offset = ((unsigned long) bi->dispDeviceBase) - base;
202 size = bi->dispDeviceRowBytes * bi->dispDeviceRect[3] + offset
203 + bi->dispDeviceRect[0];
204 vbase = ioremap(base, size);
205 if (vbase == 0)
206 return;
207 bi->logicalDisplayBase = vbase + offset;
208 boot_text_mapped = 1;
209}
210
211/* Calc the base address of a given point (x,y) */
212static unsigned char * BTEXT
213calc_base(boot_infos_t *bi, int x, int y)
214{
215 unsigned char *base;
216
217 base = bi->logicalDisplayBase;
218 if (base == 0)
219 base = bi->dispDeviceBase;
220 base += (x + bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3);
221 base += (y + bi->dispDeviceRect[1]) * bi->dispDeviceRowBytes;
222 return base;
223}
224
225/* Adjust the display to a new resolution */
226void
227btext_update_display(unsigned long phys, int width, int height,
228 int depth, int pitch)
229{
230 boot_infos_t *bi = &disp_bi;
231
232 if (bi->dispDeviceBase == 0)
233 return;
234
235 /* check it's the same frame buffer (within 256MB) */
236 if ((phys ^ (unsigned long)bi->dispDeviceBase) & 0xf0000000)
237 return;
238
239 bi->dispDeviceBase = (__u8 *) phys;
240 bi->dispDeviceRect[0] = 0;
241 bi->dispDeviceRect[1] = 0;
242 bi->dispDeviceRect[2] = width;
243 bi->dispDeviceRect[3] = height;
244 bi->dispDeviceDepth = depth;
245 bi->dispDeviceRowBytes = pitch;
246 if (boot_text_mapped) {
247 iounmap(bi->logicalDisplayBase);
248 boot_text_mapped = 0;
249 }
250 map_boot_text();
251 g_loc_X = 0;
252 g_loc_Y = 0;
253 g_max_loc_X = width / 8;
254 g_max_loc_Y = height / 16;
255}
256
257void BTEXT btext_clearscreen(void)
258{
259 boot_infos_t* bi = &disp_bi;
260 unsigned long *base = (unsigned long *)calc_base(bi, 0, 0);
261 unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
262 (bi->dispDeviceDepth >> 3)) >> 2;
263 int i,j;
264
265 for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
266 {
267 unsigned long *ptr = base;
268 for(j=width; j; --j)
269 *(ptr++) = 0;
270 base += (bi->dispDeviceRowBytes >> 2);
271 }
272}
273
274__inline__ void dcbst(const void* addr)
275{
276 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (addr));
277}
278
279void BTEXT btext_flushscreen(void)
280{
281 boot_infos_t* bi = &disp_bi;
282 unsigned long *base = (unsigned long *)calc_base(bi, 0, 0);
283 unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
284 (bi->dispDeviceDepth >> 3)) >> 2;
285 int i,j;
286
287 for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
288 {
289 unsigned long *ptr = base;
290 for(j=width; j>0; j-=8) {
291 dcbst(ptr);
292 ptr += 8;
293 }
294 base += (bi->dispDeviceRowBytes >> 2);
295 }
296}
297
298#ifndef NO_SCROLL
299static BTEXT void
300scrollscreen(void)
301{
302 boot_infos_t* bi = &disp_bi;
303 unsigned long *src = (unsigned long *)calc_base(bi,0,16);
304 unsigned long *dst = (unsigned long *)calc_base(bi,0,0);
305 unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
306 (bi->dispDeviceDepth >> 3)) >> 2;
307 int i,j;
308
309#ifdef CONFIG_ADB_PMU
310 pmu_suspend(); /* PMU will not shut us down ! */
311#endif
312 for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
313 {
314 unsigned long *src_ptr = src;
315 unsigned long *dst_ptr = dst;
316 for(j=width; j; --j)
317 *(dst_ptr++) = *(src_ptr++);
318 src += (bi->dispDeviceRowBytes >> 2);
319 dst += (bi->dispDeviceRowBytes >> 2);
320 }
321 for (i=0; i<16; i++)
322 {
323 unsigned long *dst_ptr = dst;
324 for(j=width; j; --j)
325 *(dst_ptr++) = 0;
326 dst += (bi->dispDeviceRowBytes >> 2);
327 }
328#ifdef CONFIG_ADB_PMU
329 pmu_resume(); /* PMU will not shut us down ! */
330#endif
331}
332#endif /* ndef NO_SCROLL */
333
334void BTEXT btext_drawchar(char c)
335{
336 int cline = 0, x;
337
338 if (!boot_text_mapped)
339 return;
340
341 switch (c) {
342 case '\b':
343 if (g_loc_X > 0)
344 --g_loc_X;
345 break;
346 case '\t':
347 g_loc_X = (g_loc_X & -8) + 8;
348 break;
349 case '\r':
350 g_loc_X = 0;
351 break;
352 case '\n':
353 g_loc_X = 0;
354 g_loc_Y++;
355 cline = 1;
356 break;
357 default:
358 draw_byte(c, g_loc_X++, g_loc_Y);
359 }
360 if (g_loc_X >= g_max_loc_X) {
361 g_loc_X = 0;
362 g_loc_Y++;
363 cline = 1;
364 }
365#ifndef NO_SCROLL
366 while (g_loc_Y >= g_max_loc_Y) {
367 scrollscreen();
368 g_loc_Y--;
369 }
370#else
371 /* wrap around from bottom to top of screen so we don't
372 waste time scrolling each line. -- paulus. */
373 if (g_loc_Y >= g_max_loc_Y)
374 g_loc_Y = 0;
375 if (cline) {
376 for (x = 0; x < g_max_loc_X; ++x)
377 draw_byte(' ', x, g_loc_Y);
378 }
379#endif
380}
381
382void BTEXT
383btext_drawstring(const char *c)
384{
385 if (!boot_text_mapped)
386 return;
387 while (*c)
388 btext_drawchar(*c++);
389}
390
391void BTEXT
392btext_drawhex(unsigned long v)
393{
394 static char hex_table[] = "0123456789abcdef";
395
396 if (!boot_text_mapped)
397 return;
398 btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
399 btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
400 btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
401 btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
402 btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
403 btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]);
404 btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]);
405 btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]);
406 btext_drawchar(' ');
407}
408
409static void BTEXT
410draw_byte(unsigned char c, long locX, long locY)
411{
412 boot_infos_t* bi = &disp_bi;
413 unsigned char *base = calc_base(bi, locX << 3, locY << 4);
414 unsigned char *font = &vga_font[((unsigned long)c) * 16];
415 int rb = bi->dispDeviceRowBytes;
416
417 switch(bi->dispDeviceDepth) {
418 case 24:
419 case 32:
420 draw_byte_32(font, (unsigned long *)base, rb);
421 break;
422 case 15:
423 case 16:
424 draw_byte_16(font, (unsigned long *)base, rb);
425 break;
426 case 8:
427 draw_byte_8(font, (unsigned long *)base, rb);
428 break;
429 }
430}
431
432static unsigned long expand_bits_8[16] BTDATA = {
433 0x00000000,
434 0x000000ff,
435 0x0000ff00,
436 0x0000ffff,
437 0x00ff0000,
438 0x00ff00ff,
439 0x00ffff00,
440 0x00ffffff,
441 0xff000000,
442 0xff0000ff,
443 0xff00ff00,
444 0xff00ffff,
445 0xffff0000,
446 0xffff00ff,
447 0xffffff00,
448 0xffffffff
449};
450
451static unsigned long expand_bits_16[4] BTDATA = {
452 0x00000000,
453 0x0000ffff,
454 0xffff0000,
455 0xffffffff
456};
457
458
459static void BTEXT
460draw_byte_32(unsigned char *font, unsigned long *base, int rb)
461{
462 int l, bits;
463 int fg = 0xFFFFFFFFUL;
464 int bg = 0x00000000UL;
465
466 for (l = 0; l < 16; ++l)
467 {
468 bits = *font++;
469 base[0] = (-(bits >> 7) & fg) ^ bg;
470 base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
471 base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
472 base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
473 base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
474 base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
475 base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
476 base[7] = (-(bits & 1) & fg) ^ bg;
477 base = (unsigned long *) ((char *)base + rb);
478 }
479}
480
481static void BTEXT
482draw_byte_16(unsigned char *font, unsigned long *base, int rb)
483{
484 int l, bits;
485 int fg = 0xFFFFFFFFUL;
486 int bg = 0x00000000UL;
487 unsigned long *eb = expand_bits_16;
488
489 for (l = 0; l < 16; ++l)
490 {
491 bits = *font++;
492 base[0] = (eb[bits >> 6] & fg) ^ bg;
493 base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
494 base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
495 base[3] = (eb[bits & 3] & fg) ^ bg;
496 base = (unsigned long *) ((char *)base + rb);
497 }
498}
499
500static void BTEXT
501draw_byte_8(unsigned char *font, unsigned long *base, int rb)
502{
503 int l, bits;
504 int fg = 0x0F0F0F0FUL;
505 int bg = 0x00000000UL;
506 unsigned long *eb = expand_bits_8;
507
508 for (l = 0; l < 16; ++l)
509 {
510 bits = *font++;
511 base[0] = (eb[bits >> 4] & fg) ^ bg;
512 base[1] = (eb[bits & 0xf] & fg) ^ bg;
513 base = (unsigned long *) ((char *)base + rb);
514 }
515}
516
517static unsigned char vga_font[cmapsz] BTDATA = {
5180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
5200x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
5210xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
5240x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
5250x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5280x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
5290xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
5300x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
5310x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
5320xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
5330x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
5360x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
5370x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
5380x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
5400xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
5410x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
5440x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
5450xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
5470x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5480xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
5490x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
5520x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
5560xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5570x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
5590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
5600x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5620x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
5630x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
5640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
5650x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
5660x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
5670x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
5680x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
5690x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
5700x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
5720x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
5730x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5740x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
5750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
5760x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5770x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
5780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
5790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5800x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5810x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
5820x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
5830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
5840x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5850x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
5860x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
5870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
5880x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
5890xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5900x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
5910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
5920x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
5930xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
5940x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
5950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
5960x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5970x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
5980x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
5990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
6000x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
6010x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
6020x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
6030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
6040xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
6050x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
6060x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
6070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
6080xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
6090x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
6100x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
6110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
6120x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6130xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
6140x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
6160x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
6170x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
6180x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
6190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
6200x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
6210xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
6220x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
6230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6240xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
6250x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
6260x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
6270x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
6280x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
6290xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6300x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
6320xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6330xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
6340x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
6350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
6360x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
6370xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
6380x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
6390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
6400x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
6410xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
6420x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
6430x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
6440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
6460x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
6480xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
6490x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
6500x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
6510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
6520xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6530x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
6540x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
6550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
6560xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
6570x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
6580x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
6600x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
6610x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
6620x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
6630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
6640xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6650x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
6660x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
6670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
6680x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
6690x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
6700x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
6710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
6720x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
6730x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
6740x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
6760xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6770x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
6780x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
6790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
6800xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
6810x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
6820x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
6830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
6840x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
6850x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
6860x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
6880xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
6890xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
6900x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
6910x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
6920xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
6930x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6940x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
6950x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
6960xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
6970x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
6980x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
6990x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
7000xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7010x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7020x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
7030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
7040x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
7050x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7060x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
7070x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
7080xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
7090x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
7100x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
7110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
7120x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
7130xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
7140x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
7160xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
7170x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
7180x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
7190x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
7200xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
7210x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
7220x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7230x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
7240xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
7250xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
7260x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
7270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
7280xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
7290x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
7300x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
7310xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
7320xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
7330x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
7340x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
7350x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
7360xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
7370x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
7380x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
7390x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
7400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
7410x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7420x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
7430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
7440xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7450x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
7460x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
7470x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
7480x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
7490x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
7500x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
7510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
7520x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
7530x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
7540x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
7550x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
7560xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
7570x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7580x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
7590x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
7600x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
7610x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
7630x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
7640x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
7650x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7660x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7670x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
7680x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7690x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7700x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
7710x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
7720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7730x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7740x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
7750x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
7760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7770x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7780x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7790x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
7800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
7810x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7820x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
7830x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
7840x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7850x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7860x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7870x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
7880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7890x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7900x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
7910x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
7920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
7930x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
7940x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
7950x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
7960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7970x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
7980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
7990x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
8000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
8010x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8020x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
8030x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
8040x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8050x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
8060x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
8070x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
8080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8090x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
8110xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
8120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
8130xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
8140x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
8150x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
8160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8170x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
8180x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
8190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
8200xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8210xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
8220x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
8230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
8240xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8250x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
8260x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
8280x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
8290x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
8300x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
8310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
8320x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8330x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8340x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
8350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
8360x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
8370xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
8380x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
8390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
8400x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
8410x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
8420x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
8430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
8440x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
8450x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
8460x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
8470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
8480x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
8490x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
8510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8520x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
8530x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
8540x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
8550x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
8560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8570x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
8580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8590x00, 0x00, 0x00, 0x00,
860};
diff --git a/arch/ppc/syslib/cpc700.h b/arch/ppc/syslib/cpc700.h
deleted file mode 100644
index 987e9aa0dd45..000000000000
--- a/arch/ppc/syslib/cpc700.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * Header file for IBM CPC700 Host Bridge, et. al.
3 *
4 * Author: Mark A. Greer
5 * mgreer@mvista.com
6 *
7 * 2000-2002 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12
13/*
14 * This file contains the defines and macros for the IBM CPC700 host bridge,
15 * memory controller, PIC, UARTs, IIC, and Timers.
16 */
17
18#ifndef __PPC_SYSLIB_CPC700_H__
19#define __PPC_SYSLIB_CPC700_H__
20
21#include <linux/stddef.h>
22#include <linux/types.h>
23#include <linux/init.h>
24
25/* XXX no barriers? not even any volatiles? -- paulus */
26#define CPC700_OUT_32(a,d) (*(u_int *)a = d)
27#define CPC700_IN_32(a) (*(u_int *)a)
28
29/*
30 * PCI Section
31 */
32#define CPC700_PCI_CONFIG_ADDR 0xfec00000
33#define CPC700_PCI_CONFIG_DATA 0xfec00004
34
35/* CPU -> PCI memory window 0 */
36#define CPC700_PMM0_LOCAL 0xff400000 /* CPU physical addr */
37#define CPC700_PMM0_MASK_ATTR 0xff400004 /* size and attrs */
38#define CPC700_PMM0_PCI_LOW 0xff400008 /* PCI addr, low word */
39#define CPC700_PMM0_PCI_HIGH 0xff40000c /* PCI addr, high wd */
40/* CPU -> PCI memory window 1 */
41#define CPC700_PMM1_LOCAL 0xff400010
42#define CPC700_PMM1_MASK_ATTR 0xff400014
43#define CPC700_PMM1_PCI_LOW 0xff400018
44#define CPC700_PMM1_PCI_HIGH 0xff40001c
45/* CPU -> PCI memory window 2 */
46#define CPC700_PMM2_LOCAL 0xff400020
47#define CPC700_PMM2_MASK_ATTR 0xff400024
48#define CPC700_PMM2_PCI_LOW 0xff400028
49#define CPC700_PMM2_PCI_HIGH 0xff40002c
50/* PCI memory -> CPU window 1 */
51#define CPC700_PTM1_MEMSIZE 0xff400030 /* window size */
52#define CPC700_PTM1_LOCAL 0xff400034 /* CPU phys addr */
53/* PCI memory -> CPU window 2 */
54#define CPC700_PTM2_MEMSIZE 0xff400038 /* size and enable */
55#define CPC700_PTM2_LOCAL 0xff40003c
56
57/*
58 * PIC Section
59 *
60 * IBM calls the CPC700's programmable interrupt controller the Universal
61 * Interrupt Controller or UIC.
62 */
63
64/*
65 * UIC Register Addresses.
66 */
67#define CPC700_UIC_UICSR 0xff500880 /* Status Reg (Rd/Clr)*/
68#define CPC700_UIC_UICSRS 0xff500884 /* Status Reg (Set) */
69#define CPC700_UIC_UICER 0xff500888 /* Enable Reg */
70#define CPC700_UIC_UICCR 0xff50088c /* Critical Reg */
71#define CPC700_UIC_UICPR 0xff500890 /* Polarity Reg */
72#define CPC700_UIC_UICTR 0xff500894 /* Trigger Reg */
73#define CPC700_UIC_UICMSR 0xff500898 /* Masked Status Reg */
74#define CPC700_UIC_UICVR 0xff50089c /* Vector Reg */
75#define CPC700_UIC_UICVCR 0xff5008a0 /* Vector Config Reg */
76
77#define CPC700_UIC_UICER_ENABLE 0x00000001 /* Enable an IRQ */
78
79#define CPC700_UIC_UICVCR_31_HI 0x00000000 /* IRQ 31 hi priority */
80#define CPC700_UIC_UICVCR_0_HI 0x00000001 /* IRQ 0 hi priority */
81#define CPC700_UIC_UICVCR_BASE_MASK 0xfffffffc
82#define CPC700_UIC_UICVCR_ORDER_MASK 0x00000001
83
84/* Specify value of a bit for an IRQ. */
85#define CPC700_UIC_IRQ_BIT(i) ((0x00000001) << (31 - (i)))
86
87/*
88 * UIC Exports...
89 */
90extern struct hw_interrupt_type cpc700_pic;
91extern unsigned int cpc700_irq_assigns[32][2];
92
93extern void __init cpc700_init_IRQ(void);
94extern int cpc700_get_irq(void);
95
96#endif /* __PPC_SYSLIB_CPC700_H__ */
diff --git a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c
deleted file mode 100644
index d48e8f45c050..000000000000
--- a/arch/ppc/syslib/cpc700_pic.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/*
2 * Interrupt controller support for IBM Spruce
3 *
4 * Authors: Mark Greer, Matt Porter, and Johnnie Peters
5 * mgreer@mvista.com
6 * mporter@mvista.com
7 * jpeters@mvista.com
8 *
9 * 2001-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#include <linux/stddef.h>
16#include <linux/init.h>
17#include <linux/sched.h>
18#include <linux/signal.h>
19#include <linux/irq.h>
20
21#include <asm/io.h>
22#include <asm/system.h>
23#include <asm/irq.h>
24
25#include "cpc700.h"
26
27static void
28cpc700_unmask_irq(unsigned int irq)
29{
30 unsigned int tr_bits;
31
32 /*
33 * IRQ 31 is largest IRQ supported.
34 * IRQs 17-19 are reserved.
35 */
36 if ((irq <= 31) && ((irq < 17) || (irq > 19))) {
37 tr_bits = CPC700_IN_32(CPC700_UIC_UICTR);
38
39 if ((tr_bits & (1 << (31 - irq))) == 0) {
40 /* level trigger interrupt, clear bit in status
41 * register */
42 CPC700_OUT_32(CPC700_UIC_UICSR, 1 << (31 - irq));
43 }
44
45 /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */
46 ppc_cached_irq_mask[0] |= CPC700_UIC_IRQ_BIT(irq);
47
48 CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]);
49 }
50 return;
51}
52
53static void
54cpc700_mask_irq(unsigned int irq)
55{
56 /*
57 * IRQ 31 is largest IRQ supported.
58 * IRQs 17-19 are reserved.
59 */
60 if ((irq <= 31) && ((irq < 17) || (irq > 19))) {
61 /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */
62 ppc_cached_irq_mask[0] &=
63 ~CPC700_UIC_IRQ_BIT(irq);
64
65 CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]);
66 }
67 return;
68}
69
70static void
71cpc700_mask_and_ack_irq(unsigned int irq)
72{
73 u_int bit;
74
75 /*
76 * IRQ 31 is largest IRQ supported.
77 * IRQs 17-19 are reserved.
78 */
79 if ((irq <= 31) && ((irq < 17) || (irq > 19))) {
80 /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */
81 bit = CPC700_UIC_IRQ_BIT(irq);
82
83 ppc_cached_irq_mask[0] &= ~bit;
84 CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]);
85 CPC700_OUT_32(CPC700_UIC_UICSR, bit); /* Write 1 clears IRQ */
86 }
87 return;
88}
89
90static struct hw_interrupt_type cpc700_pic = {
91 .typename = "CPC700 PIC",
92 .enable = cpc700_unmask_irq,
93 .disable = cpc700_mask_irq,
94 .ack = cpc700_mask_and_ack_irq,
95};
96
97__init static void
98cpc700_pic_init_irq(unsigned int irq)
99{
100 unsigned int tmp;
101
102 /* Set interrupt sense */
103 tmp = CPC700_IN_32(CPC700_UIC_UICTR);
104 if (cpc700_irq_assigns[irq][0] == 0) {
105 tmp &= ~CPC700_UIC_IRQ_BIT(irq);
106 } else {
107 tmp |= CPC700_UIC_IRQ_BIT(irq);
108 }
109 CPC700_OUT_32(CPC700_UIC_UICTR, tmp);
110
111 /* Set interrupt polarity */
112 tmp = CPC700_IN_32(CPC700_UIC_UICPR);
113 if (cpc700_irq_assigns[irq][1]) {
114 tmp |= CPC700_UIC_IRQ_BIT(irq);
115 } else {
116 tmp &= ~CPC700_UIC_IRQ_BIT(irq);
117 }
118 CPC700_OUT_32(CPC700_UIC_UICPR, tmp);
119
120 /* Set interrupt critical */
121 tmp = CPC700_IN_32(CPC700_UIC_UICCR);
122 tmp |= CPC700_UIC_IRQ_BIT(irq);
123 CPC700_OUT_32(CPC700_UIC_UICCR, tmp);
124
125 return;
126}
127
128__init void
129cpc700_init_IRQ(void)
130{
131 int i;
132
133 ppc_cached_irq_mask[0] = 0;
134 CPC700_OUT_32(CPC700_UIC_UICER, 0x00000000); /* Disable all irq's */
135 CPC700_OUT_32(CPC700_UIC_UICSR, 0xffffffff); /* Clear cur intrs */
136 CPC700_OUT_32(CPC700_UIC_UICCR, 0xffffffff); /* Gen INT not MCP */
137 CPC700_OUT_32(CPC700_UIC_UICPR, 0x00000000); /* Active low */
138 CPC700_OUT_32(CPC700_UIC_UICTR, 0x00000000); /* Level Sensitive */
139 CPC700_OUT_32(CPC700_UIC_UICVR, CPC700_UIC_UICVCR_0_HI);
140 /* IRQ 0 is highest */
141
142 for (i = 0; i < 17; i++) {
143 irq_desc[i].chip = &cpc700_pic;
144 cpc700_pic_init_irq(i);
145 }
146
147 for (i = 20; i < 32; i++) {
148 irq_desc[i].chip = &cpc700_pic;
149 cpc700_pic_init_irq(i);
150 }
151
152 return;
153}
154
155
156
157/*
158 * Find the highest IRQ that generating an interrupt, if any.
159 */
160int
161cpc700_get_irq(void)
162{
163 int irq = 0;
164 u_int irq_status, irq_test = 1;
165
166 irq_status = CPC700_IN_32(CPC700_UIC_UICMSR);
167
168 do
169 {
170 if (irq_status & irq_test)
171 break;
172 irq++;
173 irq_test <<= 1;
174 } while (irq < NR_IRQS);
175
176
177 if (irq == NR_IRQS)
178 irq = 33;
179
180 return (31 - irq);
181}
diff --git a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c
deleted file mode 100644
index 6cd859d7721f..000000000000
--- a/arch/ppc/syslib/cpm2_common.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/*
2 * General Purpose functions for the global management of the
3 * 8260 Communication Processor Module.
4 * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
5 * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
6 * 2.3.99 Updates
7 *
8 * In addition to the individual control of the communication
9 * channels, there are a few functions that globally affect the
10 * communication processor.
11 *
12 * Buffer descriptors must be allocated from the dual ported memory
13 * space. The allocator for that is here. When the communication
14 * process is reset, we reclaim the memory available. There is
15 * currently no deallocator for this memory.
16 */
17#include <linux/errno.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/param.h>
21#include <linux/string.h>
22#include <linux/mm.h>
23#include <linux/interrupt.h>
24#include <linux/module.h>
25#include <asm/io.h>
26#include <asm/irq.h>
27#include <asm/mpc8260.h>
28#include <asm/page.h>
29#include <asm/pgtable.h>
30#include <asm/cpm2.h>
31#include <asm/rheap.h>
32
33static void cpm2_dpinit(void);
34cpm_cpm2_t *cpmp; /* Pointer to comm processor space */
35
36/* We allocate this here because it is used almost exclusively for
37 * the communication processor devices.
38 */
39cpm2_map_t *cpm2_immr;
40
41#define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount
42 of space for CPM as it is larger
43 than on PQ2 */
44
45void
46cpm2_reset(void)
47{
48 cpm2_immr = (cpm2_map_t *)ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
49
50 /* Reclaim the DP memory for our use.
51 */
52 cpm2_dpinit();
53
54 /* Tell everyone where the comm processor resides.
55 */
56 cpmp = &cpm2_immr->im_cpm;
57}
58
59/* Set a baud rate generator. This needs lots of work. There are
60 * eight BRGs, which can be connected to the CPM channels or output
61 * as clocks. The BRGs are in two different block of internal
62 * memory mapped space.
63 * The baud rate clock is the system clock divided by something.
64 * It was set up long ago during the initial boot phase and is
65 * is given to us.
66 * Baud rate clocks are zero-based in the driver code (as that maps
67 * to port numbers). Documentation uses 1-based numbering.
68 */
69#define BRG_INT_CLK (((bd_t *)__res)->bi_brgfreq)
70#define BRG_UART_CLK (BRG_INT_CLK/16)
71
72/* This function is used by UARTS, or anything else that uses a 16x
73 * oversampled clock.
74 */
75void
76cpm_setbrg(uint brg, uint rate)
77{
78 volatile uint *bp;
79
80 /* This is good enough to get SMCs running.....
81 */
82 if (brg < 4) {
83 bp = (uint *)&cpm2_immr->im_brgc1;
84 }
85 else {
86 bp = (uint *)&cpm2_immr->im_brgc5;
87 brg -= 4;
88 }
89 bp += brg;
90 *bp = ((BRG_UART_CLK / rate) << 1) | CPM_BRG_EN;
91}
92
93/* This function is used to set high speed synchronous baud rate
94 * clocks.
95 */
96void
97cpm2_fastbrg(uint brg, uint rate, int div16)
98{
99 volatile uint *bp;
100
101 if (brg < 4) {
102 bp = (uint *)&cpm2_immr->im_brgc1;
103 }
104 else {
105 bp = (uint *)&cpm2_immr->im_brgc5;
106 brg -= 4;
107 }
108 bp += brg;
109 *bp = ((BRG_INT_CLK / rate) << 1) | CPM_BRG_EN;
110 if (div16)
111 *bp |= CPM_BRG_DIV16;
112}
113
114/*
115 * dpalloc / dpfree bits.
116 */
117static spinlock_t cpm_dpmem_lock;
118/* 16 blocks should be enough to satisfy all requests
119 * until the memory subsystem goes up... */
120static rh_block_t cpm_boot_dpmem_rh_block[16];
121static rh_info_t cpm_dpmem_info;
122
123static void cpm2_dpinit(void)
124{
125 spin_lock_init(&cpm_dpmem_lock);
126
127 /* initialize the info header */
128 rh_init(&cpm_dpmem_info, 1,
129 sizeof(cpm_boot_dpmem_rh_block) /
130 sizeof(cpm_boot_dpmem_rh_block[0]),
131 cpm_boot_dpmem_rh_block);
132
133 /* Attach the usable dpmem area */
134 /* XXX: This is actually crap. CPM_DATAONLY_BASE and
135 * CPM_DATAONLY_SIZE is only a subset of the available dpram. It
136 * varies with the processor and the microcode patches activated.
137 * But the following should be at least safe.
138 */
139 rh_attach_region(&cpm_dpmem_info, CPM_DATAONLY_BASE, CPM_DATAONLY_SIZE);
140}
141
142/* This function returns an index into the DPRAM area.
143 */
144unsigned long cpm_dpalloc(uint size, uint align)
145{
146 unsigned long start;
147 unsigned long flags;
148
149 spin_lock_irqsave(&cpm_dpmem_lock, flags);
150 cpm_dpmem_info.alignment = align;
151 start = rh_alloc(&cpm_dpmem_info, size, "commproc");
152 spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
153
154 return start;
155}
156EXPORT_SYMBOL(cpm_dpalloc);
157
158int cpm_dpfree(unsigned long offset)
159{
160 int ret;
161 unsigned long flags;
162
163 spin_lock_irqsave(&cpm_dpmem_lock, flags);
164 ret = rh_free(&cpm_dpmem_info, offset);
165 spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
166
167 return ret;
168}
169EXPORT_SYMBOL(cpm_dpfree);
170
171/* not sure if this is ever needed */
172unsigned long cpm_dpalloc_fixed(unsigned long offset, uint size, uint align)
173{
174 unsigned long start;
175 unsigned long flags;
176
177 spin_lock_irqsave(&cpm_dpmem_lock, flags);
178 cpm_dpmem_info.alignment = align;
179 start = rh_alloc_fixed(&cpm_dpmem_info, offset, size, "commproc");
180 spin_unlock_irqrestore(&cpm_dpmem_lock, flags);
181
182 return start;
183}
184EXPORT_SYMBOL(cpm_dpalloc_fixed);
185
186void cpm_dpdump(void)
187{
188 rh_dump(&cpm_dpmem_info);
189}
190EXPORT_SYMBOL(cpm_dpdump);
191
192void *cpm_dpram_addr(unsigned long offset)
193{
194 return (void *)&cpm2_immr->im_dprambase[offset];
195}
196EXPORT_SYMBOL(cpm_dpram_addr);
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c
deleted file mode 100644
index fb2d5842641a..000000000000
--- a/arch/ppc/syslib/cpm2_pic.c
+++ /dev/null
@@ -1,177 +0,0 @@
1/* The CPM2 internal interrupt controller. It is usually
2 * the only interrupt controller.
3 * There are two 32-bit registers (high/low) for up to 64
4 * possible interrupts.
5 *
6 * Now, the fun starts.....Interrupt Numbers DO NOT MAP
7 * in a simple arithmetic fashion to mask or pending registers.
8 * That is, interrupt 4 does not map to bit position 4.
9 * We create two tables, indexed by vector number, to indicate
10 * which register to use and which bit in the register to use.
11 */
12
13#include <linux/stddef.h>
14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/signal.h>
17#include <linux/irq.h>
18
19#include <asm/immap_cpm2.h>
20#include <asm/mpc8260.h>
21
22#include "cpm2_pic.h"
23
24static u_char irq_to_siureg[] = {
25 1, 1, 1, 1, 1, 1, 1, 1,
26 1, 1, 1, 1, 1, 1, 1, 1,
27 0, 0, 0, 0, 0, 0, 0, 0,
28 0, 0, 0, 0, 0, 0, 0, 0,
29 1, 1, 1, 1, 1, 1, 1, 1,
30 1, 1, 1, 1, 1, 1, 1, 1,
31 0, 0, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0
33};
34
35/* bit numbers do not match the docs, these are precomputed so the bit for
36 * a given irq is (1 << irq_to_siubit[irq]) */
37static u_char irq_to_siubit[] = {
38 0, 15, 14, 13, 12, 11, 10, 9,
39 8, 7, 6, 5, 4, 3, 2, 1,
40 2, 1, 0, 14, 13, 12, 11, 10,
41 9, 8, 7, 6, 5, 4, 3, 0,
42 31, 30, 29, 28, 27, 26, 25, 24,
43 23, 22, 21, 20, 19, 18, 17, 16,
44 16, 17, 18, 19, 20, 21, 22, 23,
45 24, 25, 26, 27, 28, 29, 30, 31,
46};
47
48static void cpm2_mask_irq(unsigned int irq_nr)
49{
50 int bit, word;
51 volatile uint *simr;
52
53 irq_nr -= CPM_IRQ_OFFSET;
54
55 bit = irq_to_siubit[irq_nr];
56 word = irq_to_siureg[irq_nr];
57
58 simr = &(cpm2_immr->im_intctl.ic_simrh);
59 ppc_cached_irq_mask[word] &= ~(1 << bit);
60 simr[word] = ppc_cached_irq_mask[word];
61}
62
63static void cpm2_unmask_irq(unsigned int irq_nr)
64{
65 int bit, word;
66 volatile uint *simr;
67
68 irq_nr -= CPM_IRQ_OFFSET;
69
70 bit = irq_to_siubit[irq_nr];
71 word = irq_to_siureg[irq_nr];
72
73 simr = &(cpm2_immr->im_intctl.ic_simrh);
74 ppc_cached_irq_mask[word] |= 1 << bit;
75 simr[word] = ppc_cached_irq_mask[word];
76}
77
78static void cpm2_mask_and_ack(unsigned int irq_nr)
79{
80 int bit, word;
81 volatile uint *simr, *sipnr;
82
83 irq_nr -= CPM_IRQ_OFFSET;
84
85 bit = irq_to_siubit[irq_nr];
86 word = irq_to_siureg[irq_nr];
87
88 simr = &(cpm2_immr->im_intctl.ic_simrh);
89 sipnr = &(cpm2_immr->im_intctl.ic_sipnrh);
90 ppc_cached_irq_mask[word] &= ~(1 << bit);
91 simr[word] = ppc_cached_irq_mask[word];
92 sipnr[word] = 1 << bit;
93}
94
95static void cpm2_end_irq(unsigned int irq_nr)
96{
97 int bit, word;
98 volatile uint *simr;
99
100 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
101 && irq_desc[irq_nr].action) {
102
103 irq_nr -= CPM_IRQ_OFFSET;
104 bit = irq_to_siubit[irq_nr];
105 word = irq_to_siureg[irq_nr];
106
107 simr = &(cpm2_immr->im_intctl.ic_simrh);
108 ppc_cached_irq_mask[word] |= 1 << bit;
109 simr[word] = ppc_cached_irq_mask[word];
110 /*
111 * Work around large numbers of spurious IRQs on PowerPC 82xx
112 * systems.
113 */
114 mb();
115 }
116}
117
118static struct hw_interrupt_type cpm2_pic = {
119 .typename = " CPM2 SIU ",
120 .enable = cpm2_unmask_irq,
121 .disable = cpm2_mask_irq,
122 .ack = cpm2_mask_and_ack,
123 .end = cpm2_end_irq,
124};
125
126int cpm2_get_irq(void)
127{
128 int irq;
129 unsigned long bits;
130
131 /* For CPM2, read the SIVEC register and shift the bits down
132 * to get the irq number. */
133 bits = cpm2_immr->im_intctl.ic_sivec;
134 irq = bits >> 26;
135
136 if (irq == 0)
137 return(-1);
138 return irq+CPM_IRQ_OFFSET;
139}
140
141void cpm2_init_IRQ(void)
142{
143 int i;
144
145 /* Clear the CPM IRQ controller, in case it has any bits set
146 * from the bootloader
147 */
148
149 /* Mask out everything */
150 cpm2_immr->im_intctl.ic_simrh = 0x00000000;
151 cpm2_immr->im_intctl.ic_simrl = 0x00000000;
152 wmb();
153
154 /* Ack everything */
155 cpm2_immr->im_intctl.ic_sipnrh = 0xffffffff;
156 cpm2_immr->im_intctl.ic_sipnrl = 0xffffffff;
157 wmb();
158
159 /* Dummy read of the vector */
160 i = cpm2_immr->im_intctl.ic_sivec;
161 rmb();
162
163 /* Initialize the default interrupt mapping priorities,
164 * in case the boot rom changed something on us.
165 */
166 cpm2_immr->im_intctl.ic_sicr = 0;
167 cpm2_immr->im_intctl.ic_scprrh = 0x05309770;
168 cpm2_immr->im_intctl.ic_scprrl = 0x05309770;
169
170
171 /* Enable chaining to OpenPIC, and make everything level
172 */
173 for (i = 0; i < NR_CPM_INTS; i++) {
174 irq_desc[i+CPM_IRQ_OFFSET].chip = &cpm2_pic;
175 irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL;
176 }
177}
diff --git a/arch/ppc/syslib/cpm2_pic.h b/arch/ppc/syslib/cpm2_pic.h
deleted file mode 100644
index 467339337a78..000000000000
--- a/arch/ppc/syslib/cpm2_pic.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef _PPC_KERNEL_CPM2_H
2#define _PPC_KERNEL_CPM2_H
3
4extern int cpm2_get_irq(void);
5
6extern void cpm2_init_IRQ(void);
7
8#endif /* _PPC_KERNEL_CPM2_H */
diff --git a/arch/ppc/syslib/gen550.h b/arch/ppc/syslib/gen550.h
deleted file mode 100644
index 5254d3cdbca6..000000000000
--- a/arch/ppc/syslib/gen550.h
+++ /dev/null
@@ -1,14 +0,0 @@
1/*
2 * gen550 prototypes
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 *
6 * 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
12extern void gen550_progress(char *, unsigned short);
13extern void gen550_init(int, struct uart_port *);
14extern void gen550_kgdb_map_scc(void);
diff --git a/arch/ppc/syslib/gen550_dbg.c b/arch/ppc/syslib/gen550_dbg.c
deleted file mode 100644
index 9293f5c59099..000000000000
--- a/arch/ppc/syslib/gen550_dbg.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/*
2 * A library of polled 16550 serial routines. These are intended to
3 * be used to support progress messages, xmon, kgdb, etc. on a
4 * variety of platforms.
5 *
6 * Adapted from lots of code ripped from the arch/ppc/boot/ polled
7 * 16550 support.
8 *
9 * Author: Matt Porter <mporter@mvista.com>
10 *
11 * 2002-2003 (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#include <linux/types.h>
18#include <linux/serial.h>
19#include <linux/tty.h> /* For linux/serial_core.h */
20#include <linux/serial_core.h>
21#include <linux/serialP.h>
22#include <linux/serial_reg.h>
23#include <asm/machdep.h>
24#include <asm/serial.h>
25#include <asm/io.h>
26
27#define SERIAL_BAUD 9600
28
29/* SERIAL_PORT_DFNS is defined in <asm/serial.h> */
30#ifndef SERIAL_PORT_DFNS
31#define SERIAL_PORT_DFNS
32#endif
33
34static struct serial_state rs_table[RS_TABLE_SIZE] = {
35 SERIAL_PORT_DFNS /* defined in <asm/serial.h> */
36};
37
38static void (*serial_outb)(unsigned long, unsigned char);
39static unsigned long (*serial_inb)(unsigned long);
40
41static int shift;
42
43unsigned long direct_inb(unsigned long addr)
44{
45 return readb((void __iomem *)addr);
46}
47
48void direct_outb(unsigned long addr, unsigned char val)
49{
50 writeb(val, (void __iomem *)addr);
51}
52
53unsigned long io_inb(unsigned long port)
54{
55 return inb(port);
56}
57
58void io_outb(unsigned long port, unsigned char val)
59{
60 outb(val, port);
61}
62
63unsigned long serial_init(int chan, void *ignored)
64{
65 unsigned long com_port;
66 unsigned char lcr, dlm;
67
68 /* We need to find out which type io we're expecting. If it's
69 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
70 * If it's 'SERIAL_IO_MEM', we can the exact location. -- Tom */
71 switch (rs_table[chan].io_type) {
72 case SERIAL_IO_PORT:
73 com_port = rs_table[chan].port;
74 serial_outb = io_outb;
75 serial_inb = io_inb;
76 break;
77 case SERIAL_IO_MEM:
78 com_port = (unsigned long)rs_table[chan].iomem_base;
79 serial_outb = direct_outb;
80 serial_inb = direct_inb;
81 break;
82 default:
83 /* We can't deal with it. */
84 return -1;
85 }
86
87 /* How far apart the registers are. */
88 shift = rs_table[chan].iomem_reg_shift;
89
90 /* save the LCR */
91 lcr = serial_inb(com_port + (UART_LCR << shift));
92
93 /* Access baud rate */
94 serial_outb(com_port + (UART_LCR << shift), UART_LCR_DLAB);
95 dlm = serial_inb(com_port + (UART_DLM << shift));
96
97 /*
98 * Test if serial port is unconfigured
99 * We assume that no-one uses less than 110 baud or
100 * less than 7 bits per character these days.
101 * -- paulus.
102 */
103 if ((dlm <= 4) && (lcr & 2)) {
104 /* port is configured, put the old LCR back */
105 serial_outb(com_port + (UART_LCR << shift), lcr);
106 }
107 else {
108 /* Input clock. */
109 serial_outb(com_port + (UART_DLL << shift),
110 (rs_table[chan].baud_base / SERIAL_BAUD) & 0xFF);
111 serial_outb(com_port + (UART_DLM << shift),
112 (rs_table[chan].baud_base / SERIAL_BAUD) >> 8);
113 /* 8 data, 1 stop, no parity */
114 serial_outb(com_port + (UART_LCR << shift), 0x03);
115 /* RTS/DTR */
116 serial_outb(com_port + (UART_MCR << shift), 0x03);
117
118 /* Clear & enable FIFOs */
119 serial_outb(com_port + (UART_FCR << shift), 0x07);
120 }
121
122 return (com_port);
123}
124
125void
126serial_putc(unsigned long com_port, unsigned char c)
127{
128 while ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
129 ;
130 serial_outb(com_port, c);
131}
132
133unsigned char
134serial_getc(unsigned long com_port)
135{
136 while ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
137 ;
138 return serial_inb(com_port);
139}
140
141int
142serial_tstc(unsigned long com_port)
143{
144 return ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
145}
146
147void
148serial_close(unsigned long com_port)
149{
150}
151
152void
153gen550_init(int i, struct uart_port *serial_req)
154{
155 rs_table[i].io_type = serial_req->iotype;
156 rs_table[i].port = serial_req->iobase;
157 rs_table[i].iomem_base = serial_req->membase;
158 rs_table[i].iomem_reg_shift = serial_req->regshift;
159 rs_table[i].baud_base = serial_req->uartclk ? serial_req->uartclk / 16 : BASE_BAUD;
160}
161
162#ifdef CONFIG_SERIAL_TEXT_DEBUG
163void
164gen550_progress(char *s, unsigned short hex)
165{
166 volatile unsigned int progress_debugport;
167 volatile char c;
168
169 progress_debugport = serial_init(0, NULL);
170
171 serial_putc(progress_debugport, '\r');
172
173 while ((c = *s++) != 0)
174 serial_putc(progress_debugport, c);
175
176 serial_putc(progress_debugport, '\n');
177 serial_putc(progress_debugport, '\r');
178}
179#endif /* CONFIG_SERIAL_TEXT_DEBUG */
diff --git a/arch/ppc/syslib/gen550_kgdb.c b/arch/ppc/syslib/gen550_kgdb.c
deleted file mode 100644
index 987cc0414e6e..000000000000
--- a/arch/ppc/syslib/gen550_kgdb.c
+++ /dev/null
@@ -1,83 +0,0 @@
1/*
2 * Generic 16550 kgdb support intended to be useful on a variety
3 * of platforms. To enable this support, it is necessary to set
4 * the CONFIG_GEN550 option. Any virtual mapping of the serial
5 * port(s) to be used can be accomplished by setting
6 * ppc_md.early_serial_map to a platform-specific mapping function.
7 *
8 * Adapted from ppc4xx_kgdb.c.
9 *
10 * Author: Matt Porter <mporter@kernel.crashing.org>
11 *
12 * 2002-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/types.h>
19#include <linux/kernel.h>
20
21#include <asm/machdep.h>
22
23extern unsigned long serial_init(int, void *);
24extern unsigned long serial_getc(unsigned long);
25extern unsigned long serial_putc(unsigned long, unsigned char);
26
27#if defined(CONFIG_KGDB_TTYS0)
28#define KGDB_PORT 0
29#elif defined(CONFIG_KGDB_TTYS1)
30#define KGDB_PORT 1
31#elif defined(CONFIG_KGDB_TTYS2)
32#define KGDB_PORT 2
33#elif defined(CONFIG_KGDB_TTYS3)
34#define KGDB_PORT 3
35#else
36#error "invalid kgdb_tty port"
37#endif
38
39static volatile unsigned int kgdb_debugport;
40
41void putDebugChar(unsigned char c)
42{
43 if (kgdb_debugport == 0)
44 kgdb_debugport = serial_init(KGDB_PORT, NULL);
45
46 serial_putc(kgdb_debugport, c);
47}
48
49int getDebugChar(void)
50{
51 if (kgdb_debugport == 0)
52 kgdb_debugport = serial_init(KGDB_PORT, NULL);
53
54 return(serial_getc(kgdb_debugport));
55}
56
57void kgdb_interruptible(int enable)
58{
59 return;
60}
61
62void putDebugString(char* str)
63{
64 while (*str != '\0') {
65 putDebugChar(*str);
66 str++;
67 }
68 putDebugChar('\r');
69 return;
70}
71
72/*
73 * Note: gen550_init() must be called already on the port we are going
74 * to use.
75 */
76void
77gen550_kgdb_map_scc(void)
78{
79 printk(KERN_DEBUG "kgdb init\n");
80 if (ppc_md.early_serial_map)
81 ppc_md.early_serial_map();
82 kgdb_debugport = serial_init(KGDB_PORT, NULL);
83}
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
deleted file mode 100644
index 3b4fcca5d1e1..000000000000
--- a/arch/ppc/syslib/gt64260_pic.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/*
2 * Interrupt controller support for Galileo's GT64260.
3 *
4 * Author: Chris Zankel <source@mvista.com>
5 * Modified by: Mark A. Greer <mgreer@mvista.com>
6 *
7 * Based on sources from Rabeeh Khoury / Galileo Technology
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/*
16 * This file contains the specific functions to support the GT64260
17 * interrupt controller.
18 *
19 * The GT64260 has two main interrupt registers (high and low) that
20 * summarizes the interrupts generated by the units of the GT64260.
21 * Each bit is assigned to an interrupt number, where the low register
22 * are assigned from IRQ0 to IRQ31 and the high cause register
23 * from IRQ32 to IRQ63
24 * The GPP (General Purpose Port) interrupts are assigned from IRQ64 (GPP0)
25 * to IRQ95 (GPP31).
26 * get_irq() returns the lowest interrupt number that is currently asserted.
27 *
28 * Note:
29 * - This driver does not initialize the GPP when used as an interrupt
30 * input.
31 */
32
33#include <linux/stddef.h>
34#include <linux/init.h>
35#include <linux/interrupt.h>
36#include <linux/sched.h>
37#include <linux/signal.h>
38#include <linux/delay.h>
39#include <linux/irq.h>
40
41#include <asm/io.h>
42#include <asm/system.h>
43#include <asm/irq.h>
44#include <asm/mv64x60.h>
45#include <asm/machdep.h>
46
47#define CPU_INTR_STR "gt64260 cpu interface error"
48#define PCI0_INTR_STR "gt64260 pci 0 error"
49#define PCI1_INTR_STR "gt64260 pci 1 error"
50
51/* ========================== forward declaration ========================== */
52
53static void gt64260_unmask_irq(unsigned int);
54static void gt64260_mask_irq(unsigned int);
55
56/* ========================== local declarations =========================== */
57
58struct hw_interrupt_type gt64260_pic = {
59 .typename = " gt64260_pic ",
60 .enable = gt64260_unmask_irq,
61 .disable = gt64260_mask_irq,
62 .ack = gt64260_mask_irq,
63 .end = gt64260_unmask_irq,
64};
65
66u32 gt64260_irq_base = 0; /* GT64260 handles the next 96 IRQs from here */
67
68static struct mv64x60_handle bh;
69
70/* gt64260_init_irq()
71 *
72 * This function initializes the interrupt controller. It assigns
73 * all interrupts from IRQ0 to IRQ95 to the gt64260 interrupt controller.
74 *
75 * Note:
76 * We register all GPP inputs as interrupt source, but disable them.
77 */
78void __init
79gt64260_init_irq(void)
80{
81 int i;
82
83 if (ppc_md.progress)
84 ppc_md.progress("gt64260_init_irq: enter", 0x0);
85
86 bh.v_base = mv64x60_get_bridge_vbase();
87
88 ppc_cached_irq_mask[0] = 0;
89 ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
90 ppc_cached_irq_mask[2] = 0;
91
92 /* disable all interrupts and clear current interrupts */
93 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
94 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
95 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]);
96 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]);
97
98 /* use the gt64260 for all (possible) interrupt sources */
99 for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++)
100 irq_desc[i].chip = &gt64260_pic;
101
102 if (ppc_md.progress)
103 ppc_md.progress("gt64260_init_irq: exit", 0x0);
104}
105
106/*
107 * gt64260_get_irq()
108 *
109 * This function returns the lowest interrupt number of all interrupts that
110 * are currently asserted.
111 *
112 * Output Variable(s):
113 * None.
114 *
115 * Returns:
116 * int <interrupt number> or -2 (bogus interrupt)
117 */
118int
119gt64260_get_irq(void)
120{
121 int irq;
122 int irq_gpp;
123
124 irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_LO);
125 irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
126
127 if (irq == -1) {
128 irq = mv64x60_read(&bh, GT64260_IC_MAIN_CAUSE_HI);
129 irq = __ilog2((irq & 0x0f000db7) & ppc_cached_irq_mask[1]);
130
131 if (irq == -1)
132 irq = -2; /* bogus interrupt, should never happen */
133 else {
134 if (irq >= 24) {
135 irq_gpp = mv64x60_read(&bh,
136 MV64x60_GPP_INTR_CAUSE);
137 irq_gpp = __ilog2(irq_gpp &
138 ppc_cached_irq_mask[2]);
139
140 if (irq_gpp == -1)
141 irq = -2;
142 else {
143 irq = irq_gpp + 64;
144 mv64x60_write(&bh,
145 MV64x60_GPP_INTR_CAUSE,
146 ~(1 << (irq - 64)));
147 }
148 } else
149 irq += 32;
150 }
151 }
152
153 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
154
155 if (irq < 0)
156 return (irq);
157 else
158 return (gt64260_irq_base + irq);
159}
160
161/* gt64260_unmask_irq()
162 *
163 * This function enables an interrupt.
164 *
165 * Input Variable(s):
166 * unsigned int interrupt number (IRQ0...IRQ95).
167 *
168 * Output Variable(s):
169 * None.
170 *
171 * Returns:
172 * void
173 */
174static void
175gt64260_unmask_irq(unsigned int irq)
176{
177 irq -= gt64260_irq_base;
178
179 if (irq > 31)
180 if (irq > 63) /* unmask GPP irq */
181 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
182 ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
183 else /* mask high interrupt register */
184 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
185 ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
186 else /* mask low interrupt register */
187 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
188 ppc_cached_irq_mask[0] |= (1 << irq));
189
190 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
191 return;
192}
193
194/* gt64260_mask_irq()
195 *
196 * This function disables the requested interrupt.
197 *
198 * Input Variable(s):
199 * unsigned int interrupt number (IRQ0...IRQ95).
200 *
201 * Output Variable(s):
202 * None.
203 *
204 * Returns:
205 * void
206 */
207static void
208gt64260_mask_irq(unsigned int irq)
209{
210 irq -= gt64260_irq_base;
211
212 if (irq > 31)
213 if (irq > 63) /* mask GPP irq */
214 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
215 ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
216 else /* mask high interrupt register */
217 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_HI,
218 ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
219 else /* mask low interrupt register */
220 mv64x60_write(&bh, GT64260_IC_CPU_INTR_MASK_LO,
221 ppc_cached_irq_mask[0] &= ~(1 << irq));
222
223 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
224 return;
225}
226
227static irqreturn_t
228gt64260_cpu_error_int_handler(int irq, void *dev_id)
229{
230 printk(KERN_ERR "gt64260_cpu_error_int_handler: %s 0x%08x\n",
231 "Error on CPU interface - Cause regiser",
232 mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
233 printk(KERN_ERR "\tCPU error register dump:\n");
234 printk(KERN_ERR "\tAddress low 0x%08x\n",
235 mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
236 printk(KERN_ERR "\tAddress high 0x%08x\n",
237 mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
238 printk(KERN_ERR "\tData low 0x%08x\n",
239 mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
240 printk(KERN_ERR "\tData high 0x%08x\n",
241 mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
242 printk(KERN_ERR "\tParity 0x%08x\n",
243 mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
244 mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
245 return IRQ_HANDLED;
246}
247
248static irqreturn_t
249gt64260_pci_error_int_handler(int irq, void *dev_id)
250{
251 u32 val;
252 unsigned int pci_bus = (unsigned int)dev_id;
253
254 if (pci_bus == 0) { /* Error on PCI 0 */
255 val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
256 printk(KERN_ERR "%s: Error in PCI %d Interface\n",
257 "gt64260_pci_error_int_handler", pci_bus);
258 printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
259 printk(KERN_ERR "\tCause register 0x%08x\n", val);
260 printk(KERN_ERR "\tAddress Low 0x%08x\n",
261 mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
262 printk(KERN_ERR "\tAddress High 0x%08x\n",
263 mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
264 printk(KERN_ERR "\tAttribute 0x%08x\n",
265 mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
266 printk(KERN_ERR "\tCommand 0x%08x\n",
267 mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
268 mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
269 }
270 if (pci_bus == 1) { /* Error on PCI 1 */
271 val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
272 printk(KERN_ERR "%s: Error in PCI %d Interface\n",
273 "gt64260_pci_error_int_handler", pci_bus);
274 printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
275 printk(KERN_ERR "\tCause register 0x%08x\n", val);
276 printk(KERN_ERR "\tAddress Low 0x%08x\n",
277 mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
278 printk(KERN_ERR "\tAddress High 0x%08x\n",
279 mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
280 printk(KERN_ERR "\tAttribute 0x%08x\n",
281 mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
282 printk(KERN_ERR "\tCommand 0x%08x\n",
283 mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
284 mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
285 }
286 return IRQ_HANDLED;
287}
288
289static int __init
290gt64260_register_hdlrs(void)
291{
292 int rc;
293
294 /* Register CPU interface error interrupt handler */
295 if ((rc = request_irq(MV64x60_IRQ_CPU_ERR,
296 gt64260_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, 0)))
297 printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
298
299 mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
300 mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000fe);
301
302 /* Register PCI 0 error interrupt handler */
303 if ((rc = request_irq(MV64360_IRQ_PCI0, gt64260_pci_error_int_handler,
304 IRQF_DISABLED, PCI0_INTR_STR, (void *)0)))
305 printk(KERN_WARNING "Can't register pci 0 error handler: %d",
306 rc);
307
308 mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
309 mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0x003c0c24);
310
311 /* Register PCI 1 error interrupt handler */
312 if ((rc = request_irq(MV64360_IRQ_PCI1, gt64260_pci_error_int_handler,
313 IRQF_DISABLED, PCI1_INTR_STR, (void *)1)))
314 printk(KERN_WARNING "Can't register pci 1 error handler: %d",
315 rc);
316
317 mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
318 mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0x003c0c24);
319
320 return 0;
321}
322
323arch_initcall(gt64260_register_hdlrs);
diff --git a/arch/ppc/syslib/harrier.c b/arch/ppc/syslib/harrier.c
deleted file mode 100644
index 45b797b3a336..000000000000
--- a/arch/ppc/syslib/harrier.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/*
2 * Motorola MCG Harrier northbridge/memory controller support
3 *
4 * Author: Dale Farnsworth
5 * dale.farnsworth@mvista.com
6 *
7 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <linux/harrier_defs.h>
16
17#include <asm/byteorder.h>
18#include <asm/io.h>
19#include <asm/irq.h>
20#include <asm/pci.h>
21#include <asm/pci-bridge.h>
22#include <asm/open_pic.h>
23#include <asm/harrier.h>
24
25/* define defaults for inbound windows */
26#define HARRIER_ITAT_DEFAULT (HARRIER_ITAT_ENA | \
27 HARRIER_ITAT_MEM | \
28 HARRIER_ITAT_WPE | \
29 HARRIER_ITAT_GBL)
30
31#define HARRIER_MPAT_DEFAULT (HARRIER_ITAT_ENA | \
32 HARRIER_ITAT_MEM | \
33 HARRIER_ITAT_WPE | \
34 HARRIER_ITAT_GBL)
35
36/*
37 * Initialize the inbound window size on a non-monarch harrier.
38 */
39void __init harrier_setup_nonmonarch(uint ppc_reg_base, uint in0_size)
40{
41 u16 temps;
42 u32 temp;
43
44 if (in0_size > HARRIER_ITSZ_2GB) {
45 printk
46 ("harrier_setup_nonmonarch: Invalid window size code %d\n",
47 in0_size);
48 return;
49 }
50
51 /* Clear the PCI memory enable bit. If we don't, then when the
52 * inbound windows are enabled below, the corresponding BARs will be
53 * "live" and start answering to PCI memory reads from their default
54 * addresses (0x0), which overlap with system RAM.
55 */
56 temps = in_le16((u16 *) (ppc_reg_base +
57 HARRIER_XCSR_CONFIG(PCI_COMMAND)));
58 temps &= ~(PCI_COMMAND_MEMORY);
59 out_le16((u16 *) (ppc_reg_base + HARRIER_XCSR_CONFIG(PCI_COMMAND)),
60 temps);
61
62 /* Setup a non-prefetchable inbound window */
63 out_le32((u32 *) (ppc_reg_base +
64 HARRIER_XCSR_CONFIG(HARRIER_ITSZ0_OFF)), in0_size);
65
66 temp = in_le32((u32 *) (ppc_reg_base +
67 HARRIER_XCSR_CONFIG(HARRIER_ITAT0_OFF)));
68 temp &= ~HARRIER_ITAT_PRE;
69 temp |= HARRIER_ITAT_DEFAULT;
70 out_le32((u32 *) (ppc_reg_base +
71 HARRIER_XCSR_CONFIG(HARRIER_ITAT0_OFF)), temp);
72
73 /* Enable the message passing block */
74 temp = in_le32((u32 *) (ppc_reg_base +
75 HARRIER_XCSR_CONFIG(HARRIER_MPAT_OFF)));
76 temp |= HARRIER_MPAT_DEFAULT;
77 out_le32((u32 *) (ppc_reg_base +
78 HARRIER_XCSR_CONFIG(HARRIER_MPAT_OFF)), temp);
79}
80
81void __init harrier_release_eready(uint ppc_reg_base)
82{
83 ulong temp;
84
85 /*
86 * Set EREADY to allow the line to be pulled up after everyone is
87 * ready.
88 */
89 temp = in_be32((uint *) (ppc_reg_base + HARRIER_MISC_CSR_OFF));
90 temp |= HARRIER_EREADY;
91 out_be32((uint *) (ppc_reg_base + HARRIER_MISC_CSR_OFF), temp);
92}
93
94void __init harrier_wait_eready(uint ppc_reg_base)
95{
96 ulong temp;
97
98 /*
99 * Poll the ERDYS line until it goes high to indicate that all
100 * non-monarch PrPMCs are ready for bus enumeration (or that there are
101 * no PrPMCs present).
102 */
103
104 /* FIXME: Add a timeout of some kind to prevent endless waits. */
105 do {
106
107 temp = in_be32((uint *) (ppc_reg_base + HARRIER_MISC_CSR_OFF));
108
109 } while (!(temp & HARRIER_ERDYS));
110}
111
112/*
113 * Initialize the Motorola MCG Harrier host bridge.
114 *
115 * This means setting up the PPC bus to PCI memory and I/O space mappings,
116 * setting the PCI memory space address of the MPIC (mapped straight
117 * through), and ioremap'ing the mpic registers.
118 * 'OpenPIC_Addr' will be set correctly by this routine.
119 * This routine will not change the PCI_CONFIG_ADDR or PCI_CONFIG_DATA
120 * addresses and assumes that the mapping of PCI memory space back to system
121 * memory is set up correctly by PPCBug.
122 */
123int __init
124harrier_init(struct pci_controller *hose,
125 uint ppc_reg_base,
126 ulong processor_pci_mem_start,
127 ulong processor_pci_mem_end,
128 ulong processor_pci_io_start,
129 ulong processor_pci_io_end, ulong processor_mpic_base)
130{
131 uint addr, offset;
132
133 /*
134 * Some sanity checks...
135 */
136 if (((processor_pci_mem_start & 0xffff0000) != processor_pci_mem_start)
137 || ((processor_pci_io_start & 0xffff0000) !=
138 processor_pci_io_start)) {
139 printk("harrier_init: %s\n",
140 "PPC to PCI mappings must start on 64 KB boundaries");
141 return -1;
142 }
143
144 if (((processor_pci_mem_end & 0x0000ffff) != 0x0000ffff) ||
145 ((processor_pci_io_end & 0x0000ffff) != 0x0000ffff)) {
146 printk("harrier_init: PPC to PCI mappings %s\n",
147 "must end just before a 64 KB boundaries");
148 return -1;
149 }
150
151 if (((processor_pci_mem_end - processor_pci_mem_start) !=
152 (hose->mem_space.end - hose->mem_space.start)) ||
153 ((processor_pci_io_end - processor_pci_io_start) !=
154 (hose->io_space.end - hose->io_space.start))) {
155 printk("harrier_init: %s\n",
156 "PPC and PCI memory or I/O space sizes don't match");
157 return -1;
158 }
159
160 if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) {
161 printk("harrier_init: %s\n",
162 "MPIC address must start on 256 KB boundary");
163 return -1;
164 }
165
166 if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) {
167 printk("harrier_init: %s\n",
168 "pci_dram_offset must be multiple of 64 KB");
169 return -1;
170 }
171
172 /*
173 * Program the OTAD/OTOF registers to set up the PCI Mem & I/O
174 * space mappings. These are the mappings going from the processor to
175 * the PCI bus.
176 *
177 * Note: Don't need to 'AND' start/end addresses with 0xffff0000
178 * because sanity check above ensures that they are properly
179 * aligned.
180 */
181
182 /* Set up PPC->PCI Mem mapping */
183 addr = processor_pci_mem_start | (processor_pci_mem_end >> 16);
184#ifdef CONFIG_HARRIER_STORE_GATHERING
185 offset = (hose->mem_space.start - processor_pci_mem_start) | 0x9a;
186#else
187 offset = (hose->mem_space.start - processor_pci_mem_start) | 0x92;
188#endif
189 out_be32((uint *) (ppc_reg_base + HARRIER_OTAD0_OFF), addr);
190 out_be32((uint *) (ppc_reg_base + HARRIER_OTOF0_OFF), offset);
191
192 /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */
193 addr = processor_pci_io_start | (processor_pci_io_end >> 16);
194 offset = (hose->io_space.start - processor_pci_io_start) | 0x80;
195 out_be32((uint *) (ppc_reg_base + HARRIER_OTAD1_OFF), addr);
196 out_be32((uint *) (ppc_reg_base + HARRIER_OTOF1_OFF), offset);
197
198 /* Enable MPIC */
199 OpenPIC_Addr = (void *)processor_mpic_base;
200 addr = (processor_mpic_base >> 16) | 1;
201 out_be16((ushort *) (ppc_reg_base + HARRIER_MBAR_OFF), addr);
202 out_8((u_char *) (ppc_reg_base + HARRIER_MPIC_CSR_OFF),
203 HARRIER_MPIC_OPI_ENABLE);
204
205 return 0;
206}
207
208/*
209 * Find the amount of RAM present.
210 * This assumes that PPCBug has initialized the memory controller (SMC)
211 * on the Harrier correctly (i.e., it does no sanity checking).
212 * It also assumes that the memory base registers are set to configure the
213 * memory as contiguous starting with "RAM A BASE", "RAM B BASE", etc.
214 * however, RAM base registers can be skipped (e.g. A, B, C are set,
215 * D is skipped but E is set is okay).
216 */
217#define MB (1024*1024UL)
218
219static uint harrier_size_table[] __initdata = {
220 0 * MB, /* 0 ==> 0 MB */
221 32 * MB, /* 1 ==> 32 MB */
222 64 * MB, /* 2 ==> 64 MB */
223 64 * MB, /* 3 ==> 64 MB */
224 128 * MB, /* 4 ==> 128 MB */
225 128 * MB, /* 5 ==> 128 MB */
226 128 * MB, /* 6 ==> 128 MB */
227 256 * MB, /* 7 ==> 256 MB */
228 256 * MB, /* 8 ==> 256 MB */
229 256 * MB, /* 9 ==> 256 MB */
230 512 * MB, /* a ==> 512 MB */
231 512 * MB, /* b ==> 512 MB */
232 512 * MB, /* c ==> 512 MB */
233 1024 * MB, /* d ==> 1024 MB */
234 1024 * MB, /* e ==> 1024 MB */
235 2048 * MB, /* f ==> 2048 MB */
236};
237
238/*
239 * *** WARNING: You MUST have a BAT set up to map in the XCSR regs ***
240 *
241 * Read the memory controller's registers to determine the amount of system
242 * memory. Assumes that the memory controller registers are already mapped
243 * into virtual memory--too early to use ioremap().
244 */
245unsigned long __init harrier_get_mem_size(uint xcsr_base)
246{
247 ulong last_addr;
248 int i;
249 uint vend_dev_id;
250 uint *size_table;
251 uint val;
252 uint *csrp;
253 uint size;
254 int size_table_entries;
255
256 vend_dev_id = in_be32((uint *) xcsr_base + PCI_VENDOR_ID);
257
258 if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) {
259 printk("harrier_get_mem_size: %s (0x%x)\n",
260 "Not a Motorola Memory Controller", vend_dev_id);
261 return 0;
262 }
263
264 vend_dev_id &= 0x0000ffff;
265
266 if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HARRIER) {
267 size_table = harrier_size_table;
268 size_table_entries = sizeof(harrier_size_table) /
269 sizeof(harrier_size_table[0]);
270 } else {
271 printk("harrier_get_mem_size: %s (0x%x)\n",
272 "Not a Harrier", vend_dev_id);
273 return 0;
274 }
275
276 last_addr = 0;
277
278 csrp = (uint *) (xcsr_base + HARRIER_SDBA_OFF);
279 for (i = 0; i < 8; i++) {
280 val = in_be32(csrp++);
281
282 if (val & 0x100) { /* If enabled */
283 size = val >> HARRIER_SDB_SIZE_SHIFT;
284 size &= HARRIER_SDB_SIZE_MASK;
285 if (size >= size_table_entries) {
286 break; /* Register not set correctly */
287 }
288 size = size_table[size];
289
290 val &= ~(size - 1);
291 val += size;
292
293 if (val > last_addr) {
294 last_addr = val;
295 }
296 }
297 }
298
299 return last_addr;
300}
diff --git a/arch/ppc/syslib/hawk_common.c b/arch/ppc/syslib/hawk_common.c
deleted file mode 100644
index 86821d8753ed..000000000000
--- a/arch/ppc/syslib/hawk_common.c
+++ /dev/null
@@ -1,317 +0,0 @@
1/*
2 * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK.
3 *
4 * Author: Mark A. Greer
5 * mgreer@mvista.com
6 *
7 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15
16#include <asm/byteorder.h>
17#include <asm/io.h>
18#include <asm/irq.h>
19#include <asm/pci.h>
20#include <asm/pci-bridge.h>
21#include <asm/open_pic.h>
22#include <asm/hawk.h>
23
24/*
25 * The Falcon/Raven and HAWK has 4 sets of registers:
26 * 1) PPC Registers which define the mappings from PPC bus to PCI bus,
27 * etc.
28 * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the
29 * MPIC base address.
30 * 3) MPIC registers.
31 * 4) System Memory Controller (SMC) registers.
32 */
33
34/*
35 * Initialize the Motorola MCG Raven or HAWK host bridge.
36 *
37 * This means setting up the PPC bus to PCI memory and I/O space mappings,
38 * setting the PCI memory space address of the MPIC (mapped straight
39 * through), and ioremap'ing the mpic registers.
40 * This routine will set the PCI_CONFIG_ADDR or PCI_CONFIG_DATA
41 * addresses based on the PCI I/O address that is passed in.
42 * 'OpenPIC_Addr' will be set correctly by this routine.
43 */
44int __init
45hawk_init(struct pci_controller *hose,
46 uint ppc_reg_base,
47 ulong processor_pci_mem_start,
48 ulong processor_pci_mem_end,
49 ulong processor_pci_io_start,
50 ulong processor_pci_io_end,
51 ulong processor_mpic_base)
52{
53 uint addr, offset;
54
55 /*
56 * Some sanity checks...
57 */
58 if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) ||
59 ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) {
60 printk("hawk_init: %s\n",
61 "PPC to PCI mappings must start on 64 KB boundaries");
62 return -1;
63 }
64
65 if (((processor_pci_mem_end &0x0000ffff) != 0x0000ffff) ||
66 ((processor_pci_io_end &0x0000ffff) != 0x0000ffff)) {
67 printk("hawk_init: PPC to PCI mappings %s\n",
68 "must end just before a 64 KB boundaries");
69 return -1;
70 }
71
72 if (((processor_pci_mem_end - processor_pci_mem_start) !=
73 (hose->mem_space.end - hose->mem_space.start)) ||
74 ((processor_pci_io_end - processor_pci_io_start) !=
75 (hose->io_space.end - hose->io_space.start))) {
76 printk("hawk_init: %s\n",
77 "PPC and PCI memory or I/O space sizes don't match");
78 return -1;
79 }
80
81 if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) {
82 printk("hawk_init: %s\n",
83 "MPIC address must start on 256 MB boundary");
84 return -1;
85 }
86
87 if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) {
88 printk("hawk_init: %s\n",
89 "pci_dram_offset must be multiple of 64 KB");
90 return -1;
91 }
92
93 /*
94 * Disable previous PPC->PCI mappings.
95 */
96 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF0_OFF), 0x00000000);
97 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF1_OFF), 0x00000000);
98 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF2_OFF), 0x00000000);
99 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF3_OFF), 0x00000000);
100
101 /*
102 * Program the XSADD/XSOFF registers to set up the PCI Mem & I/O
103 * space mappings. These are the mappings going from the processor to
104 * the PCI bus.
105 *
106 * Note: Don't need to 'AND' start/end addresses with 0xffff0000
107 * because sanity check above ensures that they are properly
108 * aligned.
109 */
110
111 /* Set up PPC->PCI Mem mapping */
112 addr = processor_pci_mem_start | (processor_pci_mem_end >> 16);
113 offset = (hose->mem_space.start - processor_pci_mem_start) | 0xd2;
114 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSADD0_OFF), addr);
115 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF0_OFF), offset);
116
117 /* Set up PPC->MPIC mapping on the bridge */
118 addr = processor_mpic_base |
119 (((processor_mpic_base + HAWK_MPIC_SIZE) >> 16) - 1);
120 /* No write posting for this PCI Mem space */
121 offset = (hose->mem_space.start - processor_pci_mem_start) | 0xc2;
122
123 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSADD1_OFF), addr);
124 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF1_OFF), offset);
125
126 /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */
127 addr = processor_pci_io_start | (processor_pci_io_end >> 16);
128 offset = (hose->io_space.start - processor_pci_io_start) | 0xc0;
129 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSADD3_OFF), addr);
130 out_be32((uint *)(ppc_reg_base + HAWK_PPC_XSOFF3_OFF), offset);
131
132 hose->io_base_virt = (void *)ioremap(processor_pci_io_start,
133 (processor_pci_io_end - processor_pci_io_start + 1));
134
135 /*
136 * Set up the indirect method of accessing PCI config space.
137 * The PCI config addr/data pair based on start addr of PCI I/O space.
138 */
139 setup_indirect_pci(hose,
140 processor_pci_io_start + HAWK_PCI_CONFIG_ADDR_OFF,
141 processor_pci_io_start + HAWK_PCI_CONFIG_DATA_OFF);
142
143 /*
144 * Disable previous PCI->PPC mappings.
145 */
146
147 /* XXXX Put in mappings from PCI bus to processor bus XXXX */
148
149 /*
150 * Disable MPIC response to PCI I/O space (BAR 0).
151 * Make MPIC respond to PCI Mem space at specified address.
152 * (BAR 1).
153 */
154 early_write_config_dword(hose,
155 0,
156 PCI_DEVFN(0,0),
157 PCI_BASE_ADDRESS_0,
158 0x00000000 | 0x1);
159
160 early_write_config_dword(hose,
161 0,
162 PCI_DEVFN(0,0),
163 PCI_BASE_ADDRESS_1,
164 (processor_mpic_base -
165 processor_pci_mem_start +
166 hose->mem_space.start) | 0x0);
167
168 /* Map MPIC into virtual memory */
169 OpenPIC_Addr = ioremap(processor_mpic_base, HAWK_MPIC_SIZE);
170
171 return 0;
172}
173
174/*
175 * Find the amount of RAM present.
176 * This assumes that PPCBug has initialized the memory controller (SMC)
177 * on the Falcon/HAWK correctly (i.e., it does no sanity checking).
178 * It also assumes that the memory base registers are set to configure the
179 * memory as contiguous starting with "RAM A BASE", "RAM B BASE", etc.
180 * however, RAM base registers can be skipped (e.g. A, B, C are set,
181 * D is skipped but E is set is okay).
182 */
183#define MB (1024*1024)
184
185static uint reg_offset_table[] __initdata = {
186 HAWK_SMC_RAM_A_SIZE_REG_OFF,
187 HAWK_SMC_RAM_B_SIZE_REG_OFF,
188 HAWK_SMC_RAM_C_SIZE_REG_OFF,
189 HAWK_SMC_RAM_D_SIZE_REG_OFF,
190 HAWK_SMC_RAM_E_SIZE_REG_OFF,
191 HAWK_SMC_RAM_F_SIZE_REG_OFF,
192 HAWK_SMC_RAM_G_SIZE_REG_OFF,
193 HAWK_SMC_RAM_H_SIZE_REG_OFF
194};
195
196static uint falcon_size_table[] __initdata = {
197 0 * MB, /* 0 ==> 0 MB */
198 16 * MB, /* 1 ==> 16 MB */
199 32 * MB, /* 2 ==> 32 MB */
200 64 * MB, /* 3 ==> 64 MB */
201 128 * MB, /* 4 ==> 128 MB */
202 256 * MB, /* 5 ==> 256 MB */
203 1024 * MB, /* 6 ==> 1024 MB (1 GB) */
204};
205
206static uint hawk_size_table[] __initdata = {
207 0 * MB, /* 0 ==> 0 MB */
208 32 * MB, /* 1 ==> 32 MB */
209 64 * MB, /* 2 ==> 64 MB */
210 64 * MB, /* 3 ==> 64 MB */
211 128 * MB, /* 4 ==> 128 MB */
212 128 * MB, /* 5 ==> 128 MB */
213 128 * MB, /* 6 ==> 128 MB */
214 256 * MB, /* 7 ==> 256 MB */
215 256 * MB, /* 8 ==> 256 MB */
216 512 * MB, /* 9 ==> 512 MB */
217};
218
219/*
220 * *** WARNING: You MUST have a BAT set up to map in the SMC regs ***
221 *
222 * Read the memory controller's registers to determine the amount of system
223 * memory. Assumes that the memory controller registers are already mapped
224 * into virtual memory--too early to use ioremap().
225 */
226unsigned long __init
227hawk_get_mem_size(uint smc_base)
228{
229 unsigned long total;
230 int i, size_table_entries, reg_limit;
231 uint vend_dev_id;
232 uint *size_table;
233 u_char val;
234
235
236 vend_dev_id = in_be32((uint *)smc_base + PCI_VENDOR_ID);
237
238 if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) {
239 printk("hawk_get_mem_size: %s (0x%x)\n",
240 "Not a Motorola Memory Controller", vend_dev_id);
241 return 0;
242 }
243
244 vend_dev_id &= 0x0000ffff;
245
246 if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_FALCON) {
247 size_table = falcon_size_table;
248 size_table_entries = sizeof(falcon_size_table) /
249 sizeof(falcon_size_table[0]);
250
251 reg_limit = FALCON_SMC_REG_COUNT;
252 }
253 else if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HAWK) {
254 size_table = hawk_size_table;
255 size_table_entries = sizeof(hawk_size_table) /
256 sizeof(hawk_size_table[0]);
257 reg_limit = HAWK_SMC_REG_COUNT;
258 }
259 else {
260 printk("hawk_get_mem_size: %s (0x%x)\n",
261 "Not a Falcon or HAWK", vend_dev_id);
262 return 0;
263 }
264
265 total = 0;
266
267 /* Check every reg because PPCBug may skip some */
268 for (i=0; i<reg_limit; i++) {
269 val = in_8((u_char *)(smc_base + reg_offset_table[i]));
270
271 if (val & 0x80) { /* If enabled */
272 val &= 0x0f;
273
274 /* Don't go past end of size_table */
275 if (val < size_table_entries) {
276 total += size_table[val];
277 }
278 else { /* Register not set correctly */
279 break;
280 }
281 }
282 }
283
284 return total;
285}
286
287int __init
288hawk_mpic_init(unsigned int pci_mem_offset)
289{
290 unsigned short devid;
291 unsigned int pci_membase;
292
293 /* Check the first PCI device to see if it is a Raven or Hawk. */
294 early_read_config_word(0, 0, 0, PCI_DEVICE_ID, &devid);
295
296 switch (devid) {
297 case PCI_DEVICE_ID_MOTOROLA_RAVEN:
298 case PCI_DEVICE_ID_MOTOROLA_HAWK:
299 break;
300 default:
301 OpenPIC_Addr = NULL;
302 return 1;
303 }
304
305 /* Read the memory base register. */
306 early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
307
308 if (pci_membase == 0) {
309 OpenPIC_Addr = NULL;
310 return 1;
311 }
312
313 /* Map the MPIC registers to virtual memory. */
314 OpenPIC_Addr = ioremap(pci_membase + pci_mem_offset, 0x22000);
315
316 return 0;
317}
diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
deleted file mode 100644
index 559f27c6aefe..000000000000
--- a/arch/ppc/syslib/i8259.c
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 * i8259 interrupt controller driver.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/init.h>
10#include <linux/ioport.h>
11#include <linux/interrupt.h>
12#include <asm/io.h>
13#include <asm/i8259.h>
14
15static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */
16
17static unsigned char cached_8259[2] = { 0xff, 0xff };
18#define cached_A1 (cached_8259[0])
19#define cached_21 (cached_8259[1])
20
21static DEFINE_SPINLOCK(i8259_lock);
22
23static int i8259_pic_irq_offset;
24
25/*
26 * Acknowledge the IRQ using either the PCI host bridge's interrupt
27 * acknowledge feature or poll. How i8259_init() is called determines
28 * which is called. It should be noted that polling is broken on some
29 * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
30 */
31int i8259_irq(void)
32{
33 int irq;
34
35 spin_lock(&i8259_lock);
36
37 /* Either int-ack or poll for the IRQ */
38 if (pci_intack)
39 irq = readb(pci_intack);
40 else {
41 /* Perform an interrupt acknowledge cycle on controller 1. */
42 outb(0x0C, 0x20); /* prepare for poll */
43 irq = inb(0x20) & 7;
44 if (irq == 2 ) {
45 /*
46 * Interrupt is cascaded so perform interrupt
47 * acknowledge on controller 2.
48 */
49 outb(0x0C, 0xA0); /* prepare for poll */
50 irq = (inb(0xA0) & 7) + 8;
51 }
52 }
53
54 if (irq == 7) {
55 /*
56 * This may be a spurious interrupt.
57 *
58 * Read the interrupt status register (ISR). If the most
59 * significant bit is not set then there is no valid
60 * interrupt.
61 */
62 if (!pci_intack)
63 outb(0x0B, 0x20); /* ISR register */
64 if(~inb(0x20) & 0x80)
65 irq = -1;
66 }
67
68 spin_unlock(&i8259_lock);
69 return irq + i8259_pic_irq_offset;
70}
71
72static void i8259_mask_and_ack_irq(unsigned int irq_nr)
73{
74 unsigned long flags;
75
76 spin_lock_irqsave(&i8259_lock, flags);
77 irq_nr -= i8259_pic_irq_offset;
78 if (irq_nr > 7) {
79 cached_A1 |= 1 << (irq_nr-8);
80 inb(0xA1); /* DUMMY */
81 outb(cached_A1, 0xA1);
82 outb(0x20, 0xA0); /* Non-specific EOI */
83 outb(0x20, 0x20); /* Non-specific EOI to cascade */
84 } else {
85 cached_21 |= 1 << irq_nr;
86 inb(0x21); /* DUMMY */
87 outb(cached_21, 0x21);
88 outb(0x20, 0x20); /* Non-specific EOI */
89 }
90 spin_unlock_irqrestore(&i8259_lock, flags);
91}
92
93static void i8259_set_irq_mask(int irq_nr)
94{
95 outb(cached_A1,0xA1);
96 outb(cached_21,0x21);
97}
98
99static void i8259_mask_irq(unsigned int irq_nr)
100{
101 unsigned long flags;
102
103 spin_lock_irqsave(&i8259_lock, flags);
104 irq_nr -= i8259_pic_irq_offset;
105 if (irq_nr < 8)
106 cached_21 |= 1 << irq_nr;
107 else
108 cached_A1 |= 1 << (irq_nr-8);
109 i8259_set_irq_mask(irq_nr);
110 spin_unlock_irqrestore(&i8259_lock, flags);
111}
112
113static void i8259_unmask_irq(unsigned int irq_nr)
114{
115 unsigned long flags;
116
117 spin_lock_irqsave(&i8259_lock, flags);
118 irq_nr -= i8259_pic_irq_offset;
119 if (irq_nr < 8)
120 cached_21 &= ~(1 << irq_nr);
121 else
122 cached_A1 &= ~(1 << (irq_nr-8));
123 i8259_set_irq_mask(irq_nr);
124 spin_unlock_irqrestore(&i8259_lock, flags);
125}
126
127static struct irq_chip i8259_pic = {
128 .typename = " i8259 ",
129 .mask = i8259_mask_irq,
130 .disable = i8259_mask_irq,
131 .unmask = i8259_unmask_irq,
132 .mask_ack = i8259_mask_and_ack_irq,
133};
134
135static struct resource pic1_iores = {
136 .name = "8259 (master)",
137 .start = 0x20,
138 .end = 0x21,
139 .flags = IORESOURCE_BUSY,
140};
141
142static struct resource pic2_iores = {
143 .name = "8259 (slave)",
144 .start = 0xa0,
145 .end = 0xa1,
146 .flags = IORESOURCE_BUSY,
147};
148
149static struct resource pic_edgectrl_iores = {
150 .name = "8259 edge control",
151 .start = 0x4d0,
152 .end = 0x4d1,
153 .flags = IORESOURCE_BUSY,
154};
155
156static struct irqaction i8259_irqaction = {
157 .handler = no_action,
158 .flags = IRQF_DISABLED,
159 .mask = CPU_MASK_NONE,
160 .name = "82c59 secondary cascade",
161};
162
163/*
164 * i8259_init()
165 * intack_addr - PCI interrupt acknowledge (real) address which will return
166 * the active irq from the 8259
167 */
168void __init i8259_init(unsigned long intack_addr, int offset)
169{
170 unsigned long flags;
171 int i;
172
173 spin_lock_irqsave(&i8259_lock, flags);
174 i8259_pic_irq_offset = offset;
175
176 /* init master interrupt controller */
177 outb(0x11, 0x20); /* Start init sequence */
178 outb(0x00, 0x21); /* Vector base */
179 outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
180 outb(0x01, 0x21); /* Select 8086 mode */
181
182 /* init slave interrupt controller */
183 outb(0x11, 0xA0); /* Start init sequence */
184 outb(0x08, 0xA1); /* Vector base */
185 outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
186 outb(0x01, 0xA1); /* Select 8086 mode */
187
188 /* always read ISR */
189 outb(0x0B, 0x20);
190 outb(0x0B, 0xA0);
191
192 /* Mask all interrupts */
193 outb(cached_A1, 0xA1);
194 outb(cached_21, 0x21);
195
196 spin_unlock_irqrestore(&i8259_lock, flags);
197
198 for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) {
199 set_irq_chip_and_handler(offset + i, &i8259_pic,
200 handle_level_irq);
201 irq_desc[offset + i].status |= IRQ_LEVEL;
202 }
203
204 /* reserve our resources */
205 setup_irq(offset + 2, &i8259_irqaction);
206 request_resource(&ioport_resource, &pic1_iores);
207 request_resource(&ioport_resource, &pic2_iores);
208 request_resource(&ioport_resource, &pic_edgectrl_iores);
209
210 if (intack_addr != 0)
211 pci_intack = ioremap(intack_addr, 1);
212
213}
diff --git a/arch/ppc/syslib/ibm440gp_common.c b/arch/ppc/syslib/ibm440gp_common.c
deleted file mode 100644
index a3927ec9b5d7..000000000000
--- a/arch/ppc/syslib/ibm440gp_common.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * PPC440GP system library
3 *
4 * Matt Porter <mporter@mvista.com>
5 * Copyright 2002-2003 MontaVista Software Inc.
6 *
7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
8 * Copyright (c) 2003 Zultys Technologies
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/types.h>
17#include <asm/reg.h>
18#include <asm/ibm44x.h>
19#include <asm/mmu.h>
20
21/*
22 * Calculate 440GP clocks
23 */
24void __init ibm440gp_get_clocks(struct ibm44x_clocks* p,
25 unsigned int sys_clk,
26 unsigned int ser_clk)
27{
28 u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0);
29 u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0);
30 u32 opdv = ((cpc0_sys0 >> 10) & 0x3) + 1;
31 u32 epdv = ((cpc0_sys0 >> 8) & 0x3) + 1;
32
33 if (cpc0_sys0 & 0x2){
34 /* Bypass system PLL */
35 p->cpu = p->plb = sys_clk;
36 }
37 else {
38 u32 fbdv, fwdva, fwdvb, m, vco;
39
40 fbdv = (cpc0_sys0 >> 18) & 0x0f;
41 if (!fbdv)
42 fbdv = 16;
43
44 fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7);
45 fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7);
46
47 /* Feedback path */
48 if (cpc0_sys0 & 0x00000080){
49 /* PerClk */
50 m = fwdvb * opdv * epdv;
51 }
52 else {
53 /* CPU clock */
54 m = fbdv * fwdva;
55 }
56 vco = sys_clk * m;
57 p->cpu = vco / fwdva;
58 p->plb = vco / fwdvb;
59 }
60
61 p->opb = p->plb / opdv;
62 p->ebc = p->opb / epdv;
63
64 if (cpc0_cr0 & 0x00400000){
65 /* External UART clock */
66 p->uart0 = p->uart1 = ser_clk;
67 }
68 else {
69 /* Internal UART clock */
70 u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1;
71 p->uart0 = p->uart1 = p->plb / uart_div;
72 }
73}
diff --git a/arch/ppc/syslib/ibm440gp_common.h b/arch/ppc/syslib/ibm440gp_common.h
deleted file mode 100644
index 94d7835038ad..000000000000
--- a/arch/ppc/syslib/ibm440gp_common.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * PPC440GP system library
3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2003 Zultys Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifdef __KERNEL__
14#ifndef __PPC_SYSLIB_IBM440GP_COMMON_H
15#define __PPC_SYSLIB_IBM440GP_COMMON_H
16
17#ifndef __ASSEMBLY__
18
19#include <linux/init.h>
20#include <syslib/ibm44x_common.h>
21
22/*
23 * Please, refer to the Figure 13.1 in 440GP user manual
24 *
25 * if internal UART clock is used, ser_clk is ignored
26 */
27void ibm440gp_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
28 unsigned int ser_clk) __init;
29
30#endif /* __ASSEMBLY__ */
31#endif /* __PPC_SYSLIB_IBM440GP_COMMON_H */
32#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
deleted file mode 100644
index 6ad52f4a26e1..000000000000
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ /dev/null
@@ -1,294 +0,0 @@
1/*
2 * PPC440GX system library
3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2003 - 2006 Zultys Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <asm/ibm44x.h>
16#include <asm/mmu.h>
17#include <asm/processor.h>
18#include <syslib/ibm440gx_common.h>
19
20/*
21 * Calculate 440GX clocks
22 */
23static inline u32 __fix_zero(u32 v, u32 def){
24 return v ? v : def;
25}
26
27void __init ibm440gx_get_clocks(struct ibm44x_clocks* p, unsigned int sys_clk,
28 unsigned int ser_clk)
29{
30 u32 pllc = CPR_READ(DCRN_CPR_PLLC);
31 u32 plld = CPR_READ(DCRN_CPR_PLLD);
32 u32 uart0 = SDR_READ(DCRN_SDR_UART0);
33 u32 uart1 = SDR_READ(DCRN_SDR_UART1);
34#ifdef CONFIG_440EP
35 u32 uart2 = SDR_READ(DCRN_SDR_UART2);
36 u32 uart3 = SDR_READ(DCRN_SDR_UART3);
37#endif
38
39 /* Dividers */
40 u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32);
41 u32 fwdva = __fix_zero((plld >> 16) & 0xf, 16);
42 u32 fwdvb = __fix_zero((plld >> 8) & 7, 8);
43 u32 lfbdv = __fix_zero(plld & 0x3f, 64);
44 u32 pradv0 = __fix_zero((CPR_READ(DCRN_CPR_PRIMAD) >> 24) & 7, 8);
45 u32 prbdv0 = __fix_zero((CPR_READ(DCRN_CPR_PRIMBD) >> 24) & 7, 8);
46 u32 opbdv0 = __fix_zero((CPR_READ(DCRN_CPR_OPBD) >> 24) & 3, 4);
47 u32 perdv0 = __fix_zero((CPR_READ(DCRN_CPR_PERD) >> 24) & 3, 4);
48
49 /* Input clocks for primary dividers */
50 u32 clk_a, clk_b;
51
52 if (pllc & 0x40000000){
53 u32 m;
54
55 /* Feedback path */
56 switch ((pllc >> 24) & 7){
57 case 0:
58 /* PLLOUTx */
59 m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv;
60 break;
61 case 1:
62 /* CPU */
63 m = fwdva * pradv0;
64 break;
65 case 5:
66 /* PERClk */
67 m = fwdvb * prbdv0 * opbdv0 * perdv0;
68 break;
69 default:
70 printk(KERN_EMERG "invalid PLL feedback source\n");
71 goto bypass;
72 }
73 m *= fbdv;
74 p->vco = sys_clk * m;
75 clk_a = p->vco / fwdva;
76 clk_b = p->vco / fwdvb;
77 }
78 else {
79bypass:
80 /* Bypass system PLL */
81 p->vco = 0;
82 clk_a = clk_b = sys_clk;
83 }
84
85 p->cpu = clk_a / pradv0;
86 p->plb = clk_b / prbdv0;
87 p->opb = p->plb / opbdv0;
88 p->ebc = p->opb / perdv0;
89
90 /* UARTs clock */
91 if (uart0 & 0x00800000)
92 p->uart0 = ser_clk;
93 else
94 p->uart0 = p->plb / __fix_zero(uart0 & 0xff, 256);
95
96 if (uart1 & 0x00800000)
97 p->uart1 = ser_clk;
98 else
99 p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256);
100#ifdef CONFIG_440EP
101 if (uart2 & 0x00800000)
102 p->uart2 = ser_clk;
103 else
104 p->uart2 = p->plb / __fix_zero(uart2 & 0xff, 256);
105
106 if (uart3 & 0x00800000)
107 p->uart3 = ser_clk;
108 else
109 p->uart3 = p->plb / __fix_zero(uart3 & 0xff, 256);
110#endif
111}
112
113/* Issue L2C diagnostic command */
114static inline u32 l2c_diag(u32 addr)
115{
116 mtdcr(DCRN_L2C0_ADDR, addr);
117 mtdcr(DCRN_L2C0_CMD, L2C_CMD_DIAG);
118 while (!(mfdcr(DCRN_L2C0_SR) & L2C_SR_CC)) ;
119 return mfdcr(DCRN_L2C0_DATA);
120}
121
122static irqreturn_t l2c_error_handler(int irq, void* dev)
123{
124 u32 sr = mfdcr(DCRN_L2C0_SR);
125 if (sr & L2C_SR_CPE){
126 /* Read cache trapped address */
127 u32 addr = l2c_diag(0x42000000);
128 printk(KERN_EMERG "L2C: Cache Parity Error, addr[16:26] = 0x%08x\n", addr);
129 }
130 if (sr & L2C_SR_TPE){
131 /* Read tag trapped address */
132 u32 addr = l2c_diag(0x82000000) >> 16;
133 printk(KERN_EMERG "L2C: Tag Parity Error, addr[16:26] = 0x%08x\n", addr);
134 }
135
136 /* Clear parity errors */
137 if (sr & (L2C_SR_CPE | L2C_SR_TPE)){
138 mtdcr(DCRN_L2C0_ADDR, 0);
139 mtdcr(DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);
140 } else
141 printk(KERN_EMERG "L2C: LRU error\n");
142
143 return IRQ_HANDLED;
144}
145
146/* Enable L2 cache */
147void __init ibm440gx_l2c_enable(void){
148 u32 r;
149 unsigned long flags;
150
151 /* Install error handler */
152 if (request_irq(87, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0){
153 printk(KERN_ERR "Cannot install L2C error handler, cache is not enabled\n");
154 return;
155 }
156
157 local_irq_save(flags);
158 asm volatile ("sync" ::: "memory");
159
160 /* Disable SRAM */
161 mtdcr(DCRN_SRAM0_DPC, mfdcr(DCRN_SRAM0_DPC) & ~SRAM_DPC_ENABLE);
162 mtdcr(DCRN_SRAM0_SB0CR, mfdcr(DCRN_SRAM0_SB0CR) & ~SRAM_SBCR_BU_MASK);
163 mtdcr(DCRN_SRAM0_SB1CR, mfdcr(DCRN_SRAM0_SB1CR) & ~SRAM_SBCR_BU_MASK);
164 mtdcr(DCRN_SRAM0_SB2CR, mfdcr(DCRN_SRAM0_SB2CR) & ~SRAM_SBCR_BU_MASK);
165 mtdcr(DCRN_SRAM0_SB3CR, mfdcr(DCRN_SRAM0_SB3CR) & ~SRAM_SBCR_BU_MASK);
166
167 /* Enable L2_MODE without ICU/DCU */
168 r = mfdcr(DCRN_L2C0_CFG) & ~(L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_SS_MASK);
169 r |= L2C_CFG_L2M | L2C_CFG_SS_256;
170 mtdcr(DCRN_L2C0_CFG, r);
171
172 mtdcr(DCRN_L2C0_ADDR, 0);
173
174 /* Hardware Clear Command */
175 mtdcr(DCRN_L2C0_CMD, L2C_CMD_HCC);
176 while (!(mfdcr(DCRN_L2C0_SR) & L2C_SR_CC)) ;
177
178 /* Clear Cache Parity and Tag Errors */
179 mtdcr(DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);
180
181 /* Enable 64G snoop region starting at 0 */
182 r = mfdcr(DCRN_L2C0_SNP0) & ~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK);
183 r |= L2C_SNP_SSR_32G | L2C_SNP_ESR;
184 mtdcr(DCRN_L2C0_SNP0, r);
185
186 r = mfdcr(DCRN_L2C0_SNP1) & ~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK);
187 r |= 0x80000000 | L2C_SNP_SSR_32G | L2C_SNP_ESR;
188 mtdcr(DCRN_L2C0_SNP1, r);
189
190 asm volatile ("sync" ::: "memory");
191
192 /* Enable ICU/DCU ports */
193 r = mfdcr(DCRN_L2C0_CFG);
194 r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM | L2C_CFG_TPEI
195 | L2C_CFG_CPEI | L2C_CFG_NAM | L2C_CFG_NBRM);
196 r |= L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_TPC | L2C_CFG_CPC | L2C_CFG_FRAN
197 | L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;
198 mtdcr(DCRN_L2C0_CFG, r);
199
200 asm volatile ("sync; isync" ::: "memory");
201 local_irq_restore(flags);
202}
203
204/* Disable L2 cache */
205void __init ibm440gx_l2c_disable(void){
206 u32 r;
207 unsigned long flags;
208
209 local_irq_save(flags);
210 asm volatile ("sync" ::: "memory");
211
212 /* Disable L2C mode */
213 r = mfdcr(DCRN_L2C0_CFG) & ~(L2C_CFG_L2M | L2C_CFG_ICU | L2C_CFG_DCU);
214 mtdcr(DCRN_L2C0_CFG, r);
215
216 /* Enable SRAM */
217 mtdcr(DCRN_SRAM0_DPC, mfdcr(DCRN_SRAM0_DPC) | SRAM_DPC_ENABLE);
218 mtdcr(DCRN_SRAM0_SB0CR,
219 SRAM_SBCR_BAS0 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW);
220 mtdcr(DCRN_SRAM0_SB1CR,
221 SRAM_SBCR_BAS1 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW);
222 mtdcr(DCRN_SRAM0_SB2CR,
223 SRAM_SBCR_BAS2 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW);
224 mtdcr(DCRN_SRAM0_SB3CR,
225 SRAM_SBCR_BAS3 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW);
226
227 asm volatile ("sync; isync" ::: "memory");
228 local_irq_restore(flags);
229}
230
231void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
232{
233 /* Disable L2C on rev.A, rev.B and 800MHz version of rev.C,
234 enable it on all other revisions
235 */
236 if (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. A") == 0 ||
237 strcmp(cur_cpu_spec->cpu_name, "440GX Rev. B") == 0
238 || (strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C")
239 == 0 && p->cpu > 667000000))
240 ibm440gx_l2c_disable();
241 else
242 ibm440gx_l2c_enable();
243}
244
245int __init ibm440gx_get_eth_grp(void)
246{
247 return (SDR_READ(DCRN_SDR_PFC1) & DCRN_SDR_PFC1_EPS) >> DCRN_SDR_PFC1_EPS_SHIFT;
248}
249
250void __init ibm440gx_set_eth_grp(int group)
251{
252 SDR_WRITE(DCRN_SDR_PFC1, (SDR_READ(DCRN_SDR_PFC1) & ~DCRN_SDR_PFC1_EPS) | (group << DCRN_SDR_PFC1_EPS_SHIFT));
253}
254
255void __init ibm440gx_tah_enable(void)
256{
257 /* Enable TAH0 and TAH1 */
258 SDR_WRITE(DCRN_SDR_MFR,SDR_READ(DCRN_SDR_MFR) &
259 ~DCRN_SDR_MFR_TAH0);
260 SDR_WRITE(DCRN_SDR_MFR,SDR_READ(DCRN_SDR_MFR) &
261 ~DCRN_SDR_MFR_TAH1);
262}
263
264int ibm440gx_show_cpuinfo(struct seq_file *m){
265
266 u32 l2c_cfg = mfdcr(DCRN_L2C0_CFG);
267 const char* s;
268 if (l2c_cfg & L2C_CFG_L2M){
269 switch (l2c_cfg & (L2C_CFG_ICU | L2C_CFG_DCU)){
270 case L2C_CFG_ICU: s = "I-Cache only"; break;
271 case L2C_CFG_DCU: s = "D-Cache only"; break;
272 default: s = "I-Cache/D-Cache"; break;
273 }
274 }
275 else
276 s = "disabled";
277
278 seq_printf(m, "L2-Cache\t: %s (0x%08x 0x%08x)\n", s,
279 l2c_cfg, mfdcr(DCRN_L2C0_SR));
280
281 return 0;
282}
283
284void __init ibm440gx_platform_init(unsigned long r3, unsigned long r4,
285 unsigned long r5, unsigned long r6,
286 unsigned long r7)
287{
288 /* Erratum 440_43 workaround, disable L1 cache parity checking */
289 if (!strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C") ||
290 !strcmp(cur_cpu_spec->cpu_name, "440GX Rev. F"))
291 mtspr(SPRN_CCR1, mfspr(SPRN_CCR1) | CCR1_DPC);
292
293 ibm44x_platform_init(r3, r4, r5, r6, r7);
294}
diff --git a/arch/ppc/syslib/ibm440gx_common.h b/arch/ppc/syslib/ibm440gx_common.h
deleted file mode 100644
index 8d6f203e7a1d..000000000000
--- a/arch/ppc/syslib/ibm440gx_common.h
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 * PPC440GX system library
3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2003, 2004 Zultys Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifdef __KERNEL__
14#ifndef __PPC_SYSLIB_IBM440GX_COMMON_H
15#define __PPC_SYSLIB_IBM440GX_COMMON_H
16
17#ifndef __ASSEMBLY__
18
19#include <linux/init.h>
20#include <linux/seq_file.h>
21#include <syslib/ibm44x_common.h>
22
23/*
24 * Please, refer to the Figure 14.1 in 440GX user manual
25 *
26 * if internal UART clock is used, ser_clk is ignored
27 */
28void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
29 unsigned int ser_clk) __init;
30
31/* common 440GX platform init */
32void ibm440gx_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
33 unsigned long r6, unsigned long r7) __init;
34
35/* Enable L2 cache */
36void ibm440gx_l2c_enable(void) __init;
37
38/* Disable L2 cache */
39void ibm440gx_l2c_disable(void) __init;
40
41/* Enable/disable L2 cache for a particular chip revision */
42void ibm440gx_l2c_setup(struct ibm44x_clocks*) __init;
43
44/* Get Ethernet Group */
45int ibm440gx_get_eth_grp(void) __init;
46
47/* Set Ethernet Group */
48void ibm440gx_set_eth_grp(int group) __init;
49
50/* Enable TAH devices */
51void ibm440gx_tah_enable(void) __init;
52
53/* Add L2C info to /proc/cpuinfo */
54int ibm440gx_show_cpuinfo(struct seq_file*);
55
56#endif /* __ASSEMBLY__ */
57#endif /* __PPC_SYSLIB_IBM440GX_COMMON_H */
58#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
deleted file mode 100644
index 571f8bcf78e6..000000000000
--- a/arch/ppc/syslib/ibm440sp_common.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * PPC440SP/PPC440SPe system library
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 * Copyright 2002-2005 MontaVista Software Inc.
6 *
7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
8 * Copyright (c) 2003, 2004 Zultys Technologies
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/types.h>
17#include <linux/serial.h>
18
19#include <asm/param.h>
20#include <asm/ibm44x.h>
21#include <asm/mmu.h>
22#include <asm/machdep.h>
23#include <asm/time.h>
24#include <asm/ppc4xx_pic.h>
25
26/*
27 * Read the 440SP memory controller to get size of system memory.
28 */
29unsigned long __init ibm440sp_find_end_of_memory(void)
30{
31 u32 i;
32 u32 mem_size = 0;
33
34 /* Read two bank sizes and sum */
35 for (i=0; i< MQ0_NUM_BANKS; i++)
36 switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
37 case MQ0_CONFIG_SIZE_8M:
38 mem_size += PPC44x_MEM_SIZE_8M;
39 break;
40 case MQ0_CONFIG_SIZE_16M:
41 mem_size += PPC44x_MEM_SIZE_16M;
42 break;
43 case MQ0_CONFIG_SIZE_32M:
44 mem_size += PPC44x_MEM_SIZE_32M;
45 break;
46 case MQ0_CONFIG_SIZE_64M:
47 mem_size += PPC44x_MEM_SIZE_64M;
48 break;
49 case MQ0_CONFIG_SIZE_128M:
50 mem_size += PPC44x_MEM_SIZE_128M;
51 break;
52 case MQ0_CONFIG_SIZE_256M:
53 mem_size += PPC44x_MEM_SIZE_256M;
54 break;
55 case MQ0_CONFIG_SIZE_512M:
56 mem_size += PPC44x_MEM_SIZE_512M;
57 break;
58 case MQ0_CONFIG_SIZE_1G:
59 mem_size += PPC44x_MEM_SIZE_1G;
60 break;
61 case MQ0_CONFIG_SIZE_2G:
62 mem_size += PPC44x_MEM_SIZE_2G;
63 break;
64 default:
65 break;
66 }
67 return mem_size;
68}
diff --git a/arch/ppc/syslib/ibm440sp_common.h b/arch/ppc/syslib/ibm440sp_common.h
deleted file mode 100644
index 8077bf8ed118..000000000000
--- a/arch/ppc/syslib/ibm440sp_common.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * PPC440SP system library
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 * Copyright 2004-2005 MontaVista Software, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifdef __KERNEL__
14#ifndef __PPC_SYSLIB_IBM440SP_COMMON_H
15#define __PPC_SYSLIB_IBM440SP_COMMON_H
16
17#ifndef __ASSEMBLY__
18
19extern unsigned long __init ibm440sp_find_end_of_memory(void);
20
21#endif /* __ASSEMBLY__ */
22#endif /* __PPC_SYSLIB_IBM440SP_COMMON_H */
23#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
deleted file mode 100644
index 01f99b4a6649..000000000000
--- a/arch/ppc/syslib/ibm44x_common.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/*
2 * PPC44x system library
3 *
4 * Matt Porter <mporter@kernel.crashing.org>
5 * Copyright 2002-2005 MontaVista Software Inc.
6 *
7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
8 * Copyright (c) 2003, 2004 Zultys Technologies
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/time.h>
17#include <linux/types.h>
18#include <linux/serial.h>
19#include <linux/module.h>
20#include <linux/initrd.h>
21
22#include <asm/ibm44x.h>
23#include <asm/mmu.h>
24#include <asm/machdep.h>
25#include <asm/time.h>
26#include <asm/ppc4xx_pic.h>
27#include <asm/param.h>
28#include <asm/bootinfo.h>
29#include <asm/ppcboot.h>
30
31#include <syslib/gen550.h>
32
33/* Global Variables */
34bd_t __res;
35
36phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
37{
38 phys_addr_t page_4gb = 0;
39
40 /*
41 * Trap the least significant 32-bit portions of an
42 * address in the 440's 36-bit address space. Fix
43 * them up with the appropriate ERPN
44 */
45 if ((addr >= PPC44x_IO_LO) && (addr <= PPC44x_IO_HI))
46 page_4gb = PPC44x_IO_PAGE;
47 else if ((addr >= PPC44x_PCI0CFG_LO) && (addr <= PPC44x_PCI0CFG_HI))
48 page_4gb = PPC44x_PCICFG_PAGE;
49#ifdef CONFIG_440SP
50 else if ((addr >= PPC44x_PCI1CFG_LO) && (addr <= PPC44x_PCI1CFG_HI))
51 page_4gb = PPC44x_PCICFG_PAGE;
52 else if ((addr >= PPC44x_PCI2CFG_LO) && (addr <= PPC44x_PCI2CFG_HI))
53 page_4gb = PPC44x_PCICFG_PAGE;
54#endif
55 else if ((addr >= PPC44x_PCIMEM_LO) && (addr <= PPC44x_PCIMEM_HI))
56 page_4gb = PPC44x_PCIMEM_PAGE;
57
58 return (page_4gb | addr);
59};
60EXPORT_SYMBOL(fixup_bigphys_addr);
61
62void __init ibm44x_calibrate_decr(unsigned int freq)
63{
64 tb_ticks_per_jiffy = freq / HZ;
65 tb_to_us = mulhwu_scale_factor(freq, 1000000);
66
67 /* Set the time base to zero */
68 mtspr(SPRN_TBWL, 0);
69 mtspr(SPRN_TBWU, 0);
70
71 /* Clear any pending timer interrupts */
72 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
73
74 /* Enable decrementer interrupt */
75 mtspr(SPRN_TCR, TCR_DIE);
76}
77
78extern void abort(void);
79
80static void ibm44x_restart(char *cmd)
81{
82 local_irq_disable();
83 abort();
84}
85
86static void ibm44x_power_off(void)
87{
88 local_irq_disable();
89 for(;;);
90}
91
92static void ibm44x_halt(void)
93{
94 local_irq_disable();
95 for(;;);
96}
97
98/*
99 * Read the 44x memory controller to get size of system memory.
100 */
101static unsigned long __init ibm44x_find_end_of_memory(void)
102{
103 u32 i, bank_config;
104 u32 mem_size = 0;
105
106 for (i=0; i<4; i++)
107 {
108 switch (i)
109 {
110 case 0:
111 mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR);
112 break;
113 case 1:
114 mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR);
115 break;
116 case 2:
117 mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR);
118 break;
119 case 3:
120 mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR);
121 break;
122 }
123
124 bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
125
126 if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE))
127 continue;
128 switch (SDRAM_CONFIG_BANK_SIZE(bank_config))
129 {
130 case SDRAM_CONFIG_SIZE_8M:
131 mem_size += PPC44x_MEM_SIZE_8M;
132 break;
133 case SDRAM_CONFIG_SIZE_16M:
134 mem_size += PPC44x_MEM_SIZE_16M;
135 break;
136 case SDRAM_CONFIG_SIZE_32M:
137 mem_size += PPC44x_MEM_SIZE_32M;
138 break;
139 case SDRAM_CONFIG_SIZE_64M:
140 mem_size += PPC44x_MEM_SIZE_64M;
141 break;
142 case SDRAM_CONFIG_SIZE_128M:
143 mem_size += PPC44x_MEM_SIZE_128M;
144 break;
145 case SDRAM_CONFIG_SIZE_256M:
146 mem_size += PPC44x_MEM_SIZE_256M;
147 break;
148 case SDRAM_CONFIG_SIZE_512M:
149 mem_size += PPC44x_MEM_SIZE_512M;
150 break;
151 }
152 }
153 return mem_size;
154}
155
156void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
157 unsigned long r6, unsigned long r7)
158{
159 parse_bootinfo(find_bootinfo());
160
161 /*
162 * If we were passed in a board information, copy it into the
163 * residual data area.
164 */
165 if (r3)
166 __res = *(bd_t *)(r3 + KERNELBASE);
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 ppc_md.init_IRQ = ppc4xx_pic_init;
187 ppc_md.find_end_of_memory = ibm44x_find_end_of_memory;
188 ppc_md.restart = ibm44x_restart;
189 ppc_md.power_off = ibm44x_power_off;
190 ppc_md.halt = ibm44x_halt;
191
192#ifdef CONFIG_SERIAL_TEXT_DEBUG
193 ppc_md.progress = gen550_progress;
194#endif /* CONFIG_SERIAL_TEXT_DEBUG */
195#ifdef CONFIG_KGDB
196 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
197#endif
198
199 /*
200 * The Abatron BDI JTAG debugger does not tolerate others
201 * mucking with the debug registers.
202 */
203#if !defined(CONFIG_BDI_SWITCH)
204 /* Enable internal debug mode */
205 mtspr(SPRN_DBCR0, (DBCR0_IDM));
206
207 /* Clear any residual debug events */
208 mtspr(SPRN_DBSR, 0xffffffff);
209#endif
210}
211
212/* Called from machine_check_exception */
213void platform_machine_check(struct pt_regs *regs)
214{
215#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
216 printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
217 mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
218 mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESRH),
219 mfdcr(DCRN_PLB0_BESRL));
220 printk("PLB1: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x%08x\n",
221 mfdcr(DCRN_PLB1_BEARH), mfdcr(DCRN_PLB1_BEARL),
222 mfdcr(DCRN_PLB1_ACR), mfdcr(DCRN_PLB1_BESRH),
223 mfdcr(DCRN_PLB1_BESRL));
224#else
225 printk("PLB0: BEAR=0x%08x%08x ACR= 0x%08x BESR= 0x%08x\n",
226 mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
227 mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR));
228#endif
229 printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
230 mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
231 mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
232 printk("OPB0: BEAR=0x%08x%08x BSTAT=0x%08x\n",
233 mfdcr(DCRN_OPB0_BEARH), mfdcr(DCRN_OPB0_BEARL),
234 mfdcr(DCRN_OPB0_BSTAT));
235}
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
deleted file mode 100644
index f179db8634e0..000000000000
--- a/arch/ppc/syslib/ibm44x_common.h
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * PPC44x system library
3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2003, 2004 Zultys Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifdef __KERNEL__
14#ifndef __PPC_SYSLIB_IBM44x_COMMON_H
15#define __PPC_SYSLIB_IBM44x_COMMON_H
16
17#ifndef __ASSEMBLY__
18
19/*
20 * All clocks are in Hz
21 */
22struct ibm44x_clocks {
23 unsigned int vco; /* VCO, 0 if system PLL is bypassed */
24 unsigned int cpu; /* CPUCoreClk */
25 unsigned int plb; /* PLBClk */
26 unsigned int opb; /* OPBClk */
27 unsigned int ebc; /* PerClk */
28 unsigned int uart0;
29 unsigned int uart1;
30#ifdef CONFIG_440EP
31 unsigned int uart2;
32 unsigned int uart3;
33#endif
34};
35
36/* common 44x platform init */
37void ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
38 unsigned long r6, unsigned long r7) __init;
39
40/* initialize decrementer and tick-related variables */
41void ibm44x_calibrate_decr(unsigned int freq) __init;
42
43#endif /* __ASSEMBLY__ */
44#endif /* __PPC_SYSLIB_IBM44x_COMMON_H */
45#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/ibm_ocp.c b/arch/ppc/syslib/ibm_ocp.c
deleted file mode 100644
index 2ee176610e7c..000000000000
--- a/arch/ppc/syslib/ibm_ocp.c
+++ /dev/null
@@ -1,10 +0,0 @@
1#include <linux/module.h>
2#include <asm/ibm4xx.h>
3#include <asm/ocp.h>
4
5struct ocp_sys_info_data ocp_sys_info = {
6 .opb_bus_freq = 50000000, /* OPB Bus Frequency (Hz) */
7 .ebc_bus_freq = 33333333, /* EBC Bus Frequency (Hz) */
8};
9
10EXPORT_SYMBOL(ocp_sys_info);
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
deleted file mode 100644
index 83b323a7d029..000000000000
--- a/arch/ppc/syslib/indirect_pci.c
+++ /dev/null
@@ -1,134 +0,0 @@
1/*
2 * Support for indirect PCI bridges.
3 *
4 * Copyright (C) 1998 Gabriel Paubert.
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#include <linux/kernel.h>
13#include <linux/pci.h>
14#include <linux/delay.h>
15#include <linux/string.h>
16#include <linux/init.h>
17
18#include <asm/io.h>
19#include <asm/prom.h>
20#include <asm/pci-bridge.h>
21#include <asm/machdep.h>
22
23#ifdef CONFIG_PPC_INDIRECT_PCI_BE
24#define PCI_CFG_OUT out_be32
25#else
26#define PCI_CFG_OUT out_le32
27#endif
28
29static int
30indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
31 int len, u32 *val)
32{
33 struct pci_controller *hose = bus->sysdata;
34 volatile void __iomem *cfg_data;
35 u8 cfg_type = 0;
36
37 if (ppc_md.pci_exclude_device)
38 if (ppc_md.pci_exclude_device(bus->number, devfn))
39 return PCIBIOS_DEVICE_NOT_FOUND;
40
41 if (hose->set_cfg_type)
42 if (bus->number != hose->first_busno)
43 cfg_type = 1;
44
45 PCI_CFG_OUT(hose->cfg_addr,
46 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
47 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
48
49 /*
50 * Note: the caller has already checked that offset is
51 * suitably aligned and that len is 1, 2 or 4.
52 */
53 cfg_data = hose->cfg_data + (offset & 3);
54 switch (len) {
55 case 1:
56 *val = in_8(cfg_data);
57 break;
58 case 2:
59 *val = in_le16(cfg_data);
60 break;
61 default:
62 *val = in_le32(cfg_data);
63 break;
64 }
65 return PCIBIOS_SUCCESSFUL;
66}
67
68static int
69indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
70 int len, u32 val)
71{
72 struct pci_controller *hose = bus->sysdata;
73 volatile void __iomem *cfg_data;
74 u8 cfg_type = 0;
75
76 if (ppc_md.pci_exclude_device)
77 if (ppc_md.pci_exclude_device(bus->number, devfn))
78 return PCIBIOS_DEVICE_NOT_FOUND;
79
80 if (hose->set_cfg_type)
81 if (bus->number != hose->first_busno)
82 cfg_type = 1;
83
84 PCI_CFG_OUT(hose->cfg_addr,
85 (0x80000000 | ((bus->number - hose->bus_offset) << 16)
86 | (devfn << 8) | ((offset & 0xfc) | cfg_type)));
87
88 /*
89 * Note: the caller has already checked that offset is
90 * suitably aligned and that len is 1, 2 or 4.
91 */
92 cfg_data = hose->cfg_data + (offset & 3);
93 switch (len) {
94 case 1:
95 out_8(cfg_data, val);
96 break;
97 case 2:
98 out_le16(cfg_data, val);
99 break;
100 default:
101 out_le32(cfg_data, val);
102 break;
103 }
104 return PCIBIOS_SUCCESSFUL;
105}
106
107static struct pci_ops indirect_pci_ops =
108{
109 indirect_read_config,
110 indirect_write_config
111};
112
113void __init
114setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
115 void __iomem * cfg_data)
116{
117 hose->cfg_addr = cfg_addr;
118 hose->cfg_data = cfg_data;
119 hose->ops = &indirect_pci_ops;
120}
121
122void __init
123setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
124{
125 unsigned long base = cfg_addr & PAGE_MASK;
126 void __iomem *mbase, *addr, *data;
127
128 mbase = ioremap(base, PAGE_SIZE);
129 addr = mbase + (cfg_addr & ~PAGE_MASK);
130 if ((cfg_data & PAGE_MASK) != base)
131 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
132 data = mbase + (cfg_data & ~PAGE_MASK);
133 setup_indirect_pci_nomap(hose, addr, data);
134}
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
deleted file mode 100644
index ebb8c8f8f30c..000000000000
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ /dev/null
@@ -1,455 +0,0 @@
1/*
2 * Workaround for device erratum PCI 9.
3 * See Motorola's "XPC826xA Family Device Errata Reference."
4 * The erratum applies to all 8260 family Hip4 processors. It is scheduled
5 * to be fixed in HiP4 Rev C. Erratum PCI 9 states that a simultaneous PCI
6 * inbound write transaction and PCI outbound read transaction can result in a
7 * bus deadlock. The suggested workaround is to use the IDMA controller to
8 * perform all reads from PCI configuration, memory, and I/O space.
9 *
10 * Author: andy_lowe@mvista.com
11 *
12 * 2003 (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#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/pci.h>
20#include <linux/types.h>
21#include <linux/string.h>
22
23#include <asm/io.h>
24#include <asm/pci-bridge.h>
25#include <asm/machdep.h>
26#include <asm/byteorder.h>
27#include <asm/mpc8260.h>
28#include <asm/immap_cpm2.h>
29#include <asm/cpm2.h>
30
31#include "m82xx_pci.h"
32
33#ifdef CONFIG_8260_PCI9
34/*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
35
36#define IDMA_XFER_BUF_SIZE 64 /* size of the IDMA transfer buffer */
37
38/* define a structure for the IDMA dpram usage */
39typedef struct idma_dpram_s {
40 idma_t pram; /* IDMA parameter RAM */
41 u_char xfer_buf[IDMA_XFER_BUF_SIZE]; /* IDMA transfer buffer */
42 idma_bd_t bd; /* buffer descriptor */
43} idma_dpram_t;
44
45/* define offsets relative to start of IDMA dpram */
46#define IDMA_XFER_BUF_OFFSET (sizeof(idma_t))
47#define IDMA_BD_OFFSET (sizeof(idma_t) + IDMA_XFER_BUF_SIZE)
48
49/* define globals */
50static volatile idma_dpram_t *idma_dpram;
51
52/* Exactly one of CONFIG_8260_PCI9_IDMAn must be defined,
53 * where n is 1, 2, 3, or 4. This selects the IDMA channel used for
54 * the PCI9 workaround.
55 */
56#ifdef CONFIG_8260_PCI9_IDMA1
57#define IDMA_CHAN 0
58#define PROFF_IDMA PROFF_IDMA1_BASE
59#define IDMA_PAGE CPM_CR_IDMA1_PAGE
60#define IDMA_SBLOCK CPM_CR_IDMA1_SBLOCK
61#endif
62#ifdef CONFIG_8260_PCI9_IDMA2
63#define IDMA_CHAN 1
64#define PROFF_IDMA PROFF_IDMA2_BASE
65#define IDMA_PAGE CPM_CR_IDMA2_PAGE
66#define IDMA_SBLOCK CPM_CR_IDMA2_SBLOCK
67#endif
68#ifdef CONFIG_8260_PCI9_IDMA3
69#define IDMA_CHAN 2
70#define PROFF_IDMA PROFF_IDMA3_BASE
71#define IDMA_PAGE CPM_CR_IDMA3_PAGE
72#define IDMA_SBLOCK CPM_CR_IDMA3_SBLOCK
73#endif
74#ifdef CONFIG_8260_PCI9_IDMA4
75#define IDMA_CHAN 3
76#define PROFF_IDMA PROFF_IDMA4_BASE
77#define IDMA_PAGE CPM_CR_IDMA4_PAGE
78#define IDMA_SBLOCK CPM_CR_IDMA4_SBLOCK
79#endif
80
81void idma_pci9_init(void)
82{
83 uint dpram_offset;
84 volatile idma_t *pram;
85 volatile im_idma_t *idma_reg;
86 volatile cpm2_map_t *immap = cpm2_immr;
87
88 /* allocate IDMA dpram */
89 dpram_offset = cpm_dpalloc(sizeof(idma_dpram_t), 64);
90 idma_dpram = cpm_dpram_addr(dpram_offset);
91
92 /* initialize the IDMA parameter RAM */
93 memset((void *)idma_dpram, 0, sizeof(idma_dpram_t));
94 pram = &idma_dpram->pram;
95 pram->ibase = dpram_offset + IDMA_BD_OFFSET;
96 pram->dpr_buf = dpram_offset + IDMA_XFER_BUF_OFFSET;
97 pram->ss_max = 32;
98 pram->dts = 32;
99
100 /* initialize the IDMA_BASE pointer to the IDMA parameter RAM */
101 *((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset;
102
103 /* initialize the IDMA registers */
104 idma_reg = (volatile im_idma_t *) &immap->im_sdma.sdma_idsr1;
105 idma_reg[IDMA_CHAN].idmr = 0; /* mask all IDMA interrupts */
106 idma_reg[IDMA_CHAN].idsr = 0xff; /* clear all event flags */
107
108 printk(KERN_WARNING
109 "Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
110 IDMA_CHAN + 1);
111
112 return;
113}
114
115/* Use the IDMA controller to transfer data from I/O memory to local RAM.
116 * The src address must be a physical address suitable for use by the DMA
117 * controller with no translation. The dst address must be a kernel virtual
118 * address. The dst address is translated to a physical address via
119 * virt_to_phys().
120 * The sinc argument specifies whether or not the source address is incremented
121 * by the DMA controller. The source address is incremented if and only if sinc
122 * is non-zero. The destination address is always incremented since the
123 * destination is always host RAM.
124 */
125static void
126idma_pci9_read(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
127{
128 unsigned long flags;
129 volatile idma_t *pram = &idma_dpram->pram;
130 volatile idma_bd_t *bd = &idma_dpram->bd;
131 volatile cpm2_map_t *immap = cpm2_immr;
132
133 local_irq_save(flags);
134
135 /* initialize IDMA parameter RAM for this transfer */
136 if (sinc)
137 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
138 | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
139 else
140 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_DINC
141 | IDMA_DCM_SD_MEM2MEM;
142 pram->ibdptr = pram->ibase;
143 pram->sts = unit_size;
144 pram->istate = 0;
145
146 /* initialize the buffer descriptor */
147 bd->dst = virt_to_phys(dst);
148 bd->src = (uint) src;
149 bd->len = bytes;
150 bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
151 | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;
152
153 /* issue the START_IDMA command to the CP */
154 while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
155 immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
156 CPM_CR_START_IDMA) | CPM_CR_FLG;
157 while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
158
159 /* wait for transfer to complete */
160 while(bd->flags & IDMA_BD_V);
161
162 local_irq_restore(flags);
163
164 return;
165}
166
167/* Use the IDMA controller to transfer data from I/O memory to local RAM.
168 * The dst address must be a physical address suitable for use by the DMA
169 * controller with no translation. The src address must be a kernel virtual
170 * address. The src address is translated to a physical address via
171 * virt_to_phys().
172 * The dinc argument specifies whether or not the dest address is incremented
173 * by the DMA controller. The source address is incremented if and only if sinc
174 * is non-zero. The source address is always incremented since the
175 * source is always host RAM.
176 */
177static void
178idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc)
179{
180 unsigned long flags;
181 volatile idma_t *pram = &idma_dpram->pram;
182 volatile idma_bd_t *bd = &idma_dpram->bd;
183 volatile cpm2_map_t *immap = cpm2_immr;
184
185 local_irq_save(flags);
186
187 /* initialize IDMA parameter RAM for this transfer */
188 if (dinc)
189 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
190 | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
191 else
192 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
193 | IDMA_DCM_SD_MEM2MEM;
194 pram->ibdptr = pram->ibase;
195 pram->sts = unit_size;
196 pram->istate = 0;
197
198 /* initialize the buffer descriptor */
199 bd->dst = (uint) dst;
200 bd->src = virt_to_phys(src);
201 bd->len = bytes;
202 bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
203 | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;
204
205 /* issue the START_IDMA command to the CP */
206 while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
207 immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
208 CPM_CR_START_IDMA) | CPM_CR_FLG;
209 while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
210
211 /* wait for transfer to complete */
212 while(bd->flags & IDMA_BD_V);
213
214 local_irq_restore(flags);
215
216 return;
217}
218
219/* Same as idma_pci9_read, but 16-bit little-endian byte swapping is performed
220 * if the unit_size is 2, and 32-bit little-endian byte swapping is performed if
221 * the unit_size is 4.
222 */
223static void
224idma_pci9_read_le(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
225{
226 int i;
227 u8 *p;
228
229 idma_pci9_read(dst, src, bytes, unit_size, sinc);
230 switch(unit_size) {
231 case 2:
232 for (i = 0, p = dst; i < bytes; i += 2, p += 2)
233 swab16s((u16 *) p);
234 break;
235 case 4:
236 for (i = 0, p = dst; i < bytes; i += 4, p += 4)
237 swab32s((u32 *) p);
238 break;
239 default:
240 break;
241 }
242}
243EXPORT_SYMBOL(idma_pci9_init);
244EXPORT_SYMBOL(idma_pci9_read);
245EXPORT_SYMBOL(idma_pci9_read_le);
246
247static inline int is_pci_mem(unsigned long addr)
248{
249 if (addr >= M82xx_PCI_LOWER_MMIO &&
250 addr <= M82xx_PCI_UPPER_MMIO)
251 return 1;
252 if (addr >= M82xx_PCI_LOWER_MEM &&
253 addr <= M82xx_PCI_UPPER_MEM)
254 return 1;
255 return 0;
256}
257
258#define is_pci_mem(pa) ( (pa > 0x80000000) && (pa < 0xc0000000))
259int readb(volatile unsigned char *addr)
260{
261 u8 val;
262 unsigned long pa = iopa((unsigned long) addr);
263
264 if (!is_pci_mem(pa))
265 return in_8(addr);
266
267 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
268 return val;
269}
270
271int readw(volatile unsigned short *addr)
272{
273 u16 val;
274 unsigned long pa = iopa((unsigned long) addr);
275
276 if (!is_pci_mem(pa))
277 return in_le16(addr);
278
279 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
280 return swab16(val);
281}
282
283unsigned readl(volatile unsigned *addr)
284{
285 u32 val;
286 unsigned long pa = iopa((unsigned long) addr);
287
288 if (!is_pci_mem(pa))
289 return in_le32(addr);
290
291 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
292 return swab32(val);
293}
294
295int inb(unsigned port)
296{
297 u8 val;
298 u8 *addr = (u8 *)(port + _IO_BASE);
299
300 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
301 return val;
302}
303
304int inw(unsigned port)
305{
306 u16 val;
307 u8 *addr = (u8 *)(port + _IO_BASE);
308
309 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
310 return swab16(val);
311}
312
313unsigned inl(unsigned port)
314{
315 u32 val;
316 u8 *addr = (u8 *)(port + _IO_BASE);
317
318 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
319 return swab32(val);
320}
321
322void insb(unsigned port, void *buf, int ns)
323{
324 u8 *addr = (u8 *)(port + _IO_BASE);
325
326 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u8), sizeof(u8), 0);
327}
328
329void insw(unsigned port, void *buf, int ns)
330{
331 u8 *addr = (u8 *)(port + _IO_BASE);
332
333 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
334}
335
336void insl(unsigned port, void *buf, int nl)
337{
338 u8 *addr = (u8 *)(port + _IO_BASE);
339
340 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
341}
342
343void *memcpy_fromio(void *dest, unsigned long src, size_t count)
344{
345 unsigned long pa = iopa((unsigned long) src);
346
347 if (is_pci_mem(pa))
348 idma_pci9_read((u8 *)dest, (u8 *)pa, count, 32, 1);
349 else
350 memcpy(dest, (void *)src, count);
351 return dest;
352}
353
354EXPORT_SYMBOL(readb);
355EXPORT_SYMBOL(readw);
356EXPORT_SYMBOL(readl);
357EXPORT_SYMBOL(inb);
358EXPORT_SYMBOL(inw);
359EXPORT_SYMBOL(inl);
360EXPORT_SYMBOL(insb);
361EXPORT_SYMBOL(insw);
362EXPORT_SYMBOL(insl);
363EXPORT_SYMBOL(memcpy_fromio);
364
365#endif /* ifdef CONFIG_8260_PCI9 */
366
367/* Indirect PCI routines adapted from arch/ppc/kernel/indirect_pci.c.
368 * Copyright (C) 1998 Gabriel Paubert.
369 */
370#ifndef CONFIG_8260_PCI9
371#define cfg_read(val, addr, type, op) *val = op((type)(addr))
372#else
373#define cfg_read(val, addr, type, op) \
374 idma_pci9_read_le((u8*)(val),(u8*)(addr),sizeof(*(val)),sizeof(*(val)),0)
375#endif
376
377#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
378
379static int indirect_write_config(struct pci_bus *pbus, unsigned int devfn, int where,
380 int size, u32 value)
381{
382 struct pci_controller *hose = pbus->sysdata;
383 u8 cfg_type = 0;
384 if (ppc_md.pci_exclude_device)
385 if (ppc_md.pci_exclude_device(pbus->number, devfn))
386 return PCIBIOS_DEVICE_NOT_FOUND;
387
388 if (hose->set_cfg_type)
389 if (pbus->number != hose->first_busno)
390 cfg_type = 1;
391
392 out_be32(hose->cfg_addr,
393 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
394 | ((pbus->number - hose->bus_offset) << 8) | 0x80);
395
396 switch (size)
397 {
398 case 1:
399 cfg_write(value, hose->cfg_data + (where & 3), u8, out_8);
400 break;
401 case 2:
402 cfg_write(value, hose->cfg_data + (where & 2), u16, out_le16);
403 break;
404 case 4:
405 cfg_write(value, hose->cfg_data + (where & 0), u32, out_le32);
406 break;
407 }
408 return PCIBIOS_SUCCESSFUL;
409}
410
411static int indirect_read_config(struct pci_bus *pbus, unsigned int devfn, int where,
412 int size, u32 *value)
413{
414 struct pci_controller *hose = pbus->sysdata;
415 u8 cfg_type = 0;
416 if (ppc_md.pci_exclude_device)
417 if (ppc_md.pci_exclude_device(pbus->number, devfn))
418 return PCIBIOS_DEVICE_NOT_FOUND;
419
420 if (hose->set_cfg_type)
421 if (pbus->number != hose->first_busno)
422 cfg_type = 1;
423
424 out_be32(hose->cfg_addr,
425 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
426 | ((pbus->number - hose->bus_offset) << 8) | 0x80);
427
428 switch (size)
429 {
430 case 1:
431 cfg_read(value, hose->cfg_data + (where & 3), u8 *, in_8);
432 break;
433 case 2:
434 cfg_read(value, hose->cfg_data + (where & 2), u16 *, in_le16);
435 break;
436 case 4:
437 cfg_read(value, hose->cfg_data + (where & 0), u32 *, in_le32);
438 break;
439 }
440 return PCIBIOS_SUCCESSFUL;
441}
442
443static struct pci_ops indirect_pci_ops =
444{
445 .read = indirect_read_config,
446 .write = indirect_write_config,
447};
448
449void
450setup_m8260_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
451{
452 hose->ops = &indirect_pci_ops;
453 hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4);
454 hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4);
455}
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
deleted file mode 100644
index b40583724de3..000000000000
--- a/arch/ppc/syslib/m8260_setup.c
+++ /dev/null
@@ -1,266 +0,0 @@
1/*
2 * Copyright (C) 1995 Linus Torvalds
3 * Adapted from 'alpha' version by Gary Thomas
4 * Modified by Cort Dougan (cort@cs.nmt.edu)
5 * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net)
6 * Further modified for generic 8xx and 8260 by Dan.
7 */
8
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/mm.h>
12#include <linux/stddef.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/initrd.h>
16#include <linux/root_dev.h>
17#include <linux/seq_file.h>
18#include <linux/irq.h>
19
20#include <asm/mmu.h>
21#include <asm/io.h>
22#include <asm/pgtable.h>
23#include <asm/mpc8260.h>
24#include <asm/cpm2.h>
25#include <asm/machdep.h>
26#include <asm/bootinfo.h>
27#include <asm/time.h>
28#include <asm/ppc_sys.h>
29
30#include "cpm2_pic.h"
31
32unsigned char __res[sizeof(bd_t)];
33
34extern void pq2_find_bridges(void);
35extern void pq2pci_init_irq(void);
36extern void idma_pci9_init(void);
37
38/* Place-holder for board-specific init */
39void __attribute__ ((weak)) __init
40m82xx_board_setup(void)
41{
42}
43
44static void __init
45m8260_setup_arch(void)
46{
47 /* Print out Vendor and Machine info. */
48 printk(KERN_INFO "%s %s port\n", CPUINFO_VENDOR, CPUINFO_MACHINE);
49
50 /* Reset the Communication Processor Module. */
51 cpm2_reset();
52#ifdef CONFIG_8260_PCI9
53 /* Initialise IDMA for PCI erratum workaround */
54 idma_pci9_init();
55#endif
56#ifdef CONFIG_PCI_8260
57 pq2_find_bridges();
58#endif
59#ifdef CONFIG_BLK_DEV_INITRD
60 if (initrd_start)
61 ROOT_DEV = Root_RAM0;
62#endif
63
64 identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
65 in_be32((void *)CPM_MAP_ADDR + CPM_IMMR_OFFSET));
66
67 m82xx_board_setup();
68}
69
70/* The decrementer counts at the system (internal) clock frequency
71 * divided by four.
72 */
73static void __init
74m8260_calibrate_decr(void)
75{
76 bd_t *binfo = (bd_t *)__res;
77 int freq, divisor;
78
79 freq = binfo->bi_busfreq;
80 divisor = 4;
81 tb_ticks_per_jiffy = freq / HZ / divisor;
82 tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
83}
84
85/* The 8260 has an internal 1-second timer update register that
86 * we should use for this purpose.
87 */
88static uint rtc_time;
89
90static int
91m8260_set_rtc_time(unsigned long time)
92{
93 rtc_time = time;
94
95 return(0);
96}
97
98static unsigned long
99m8260_get_rtc_time(void)
100{
101 /* Get time from the RTC.
102 */
103 return((unsigned long)rtc_time);
104}
105
106#ifndef BOOTROM_RESTART_ADDR
107#warning "Using default BOOTROM_RESTART_ADDR!"
108#define BOOTROM_RESTART_ADDR 0xff000104
109#endif
110
111static void
112m8260_restart(char *cmd)
113{
114 extern void m8260_gorom(bd_t *bi, uint addr);
115 uint startaddr;
116
117 /* Most boot roms have a warmstart as the second instruction
118 * of the reset vector. If that doesn't work for you, change this
119 * or the reboot program to send a proper address.
120 */
121 startaddr = BOOTROM_RESTART_ADDR;
122 if (cmd != NULL) {
123 if (!strncmp(cmd, "startaddr=", 10))
124 startaddr = simple_strtoul(&cmd[10], NULL, 0);
125 }
126
127 m8260_gorom((void*)__pa(__res), startaddr);
128}
129
130static void
131m8260_halt(void)
132{
133 local_irq_disable();
134 while (1);
135}
136
137static void
138m8260_power_off(void)
139{
140 m8260_halt();
141}
142
143static int
144m8260_show_cpuinfo(struct seq_file *m)
145{
146 bd_t *bp = (bd_t *)__res;
147
148 seq_printf(m, "vendor\t\t: %s\n"
149 "machine\t\t: %s\n"
150 "\n"
151 "mem size\t\t: 0x%08lx\n"
152 "console baud\t\t: %ld\n"
153 "\n"
154 "core clock\t: %lu MHz\n"
155 "CPM clock\t: %lu MHz\n"
156 "bus clock\t: %lu MHz\n",
157 CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
158 bp->bi_baudrate, bp->bi_intfreq / 1000000,
159 bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
160 return 0;
161}
162
163/* Initialize the internal interrupt controller. The number of
164 * interrupts supported can vary with the processor type, and the
165 * 8260 family can have up to 64.
166 * External interrupts can be either edge or level triggered, and
167 * need to be initialized by the appropriate driver.
168 */
169static void __init
170m8260_init_IRQ(void)
171{
172 cpm2_init_IRQ();
173
174 /* Initialize the default interrupt mapping priorities,
175 * in case the boot rom changed something on us.
176 */
177 cpm2_immr->im_intctl.ic_siprr = 0x05309770;
178}
179
180/*
181 * Same hack as 8xx
182 */
183static unsigned long __init
184m8260_find_end_of_memory(void)
185{
186 bd_t *binfo = (bd_t *)__res;
187
188 return binfo->bi_memsize;
189}
190
191/* Map the IMMR, plus anything else we can cover
192 * in that upper space according to the memory controller
193 * chip select mapping. Grab another bunch of space
194 * below that for stuff we can't cover in the upper.
195 */
196static void __init
197m8260_map_io(void)
198{
199 uint addr;
200
201 /* Map IMMR region to a 256MB BAT */
202 addr = (cpm2_immr != NULL) ? (uint)cpm2_immr : CPM_MAP_ADDR;
203 io_block_mapping(addr, addr, 0x10000000, _PAGE_IO);
204
205 /* Map I/O region to a 256MB BAT */
206 io_block_mapping(IO_VIRT_ADDR, IO_PHYS_ADDR, 0x10000000, _PAGE_IO);
207}
208
209/* Place-holder for board-specific ppc_md hooking */
210void __attribute__ ((weak)) __init
211m82xx_board_init(void)
212{
213}
214
215/* Inputs:
216 * r3 - Optional pointer to a board information structure.
217 * r4 - Optional pointer to the physical starting address of the init RAM
218 * disk.
219 * r5 - Optional pointer to the physical ending address of the init RAM
220 * disk.
221 * r6 - Optional pointer to the physical starting address of any kernel
222 * command-line parameters.
223 * r7 - Optional pointer to the physical ending address of any kernel
224 * command-line parameters.
225 */
226void __init
227platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
228 unsigned long r6, unsigned long r7)
229{
230 parse_bootinfo(find_bootinfo());
231
232 if ( r3 )
233 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
234
235#ifdef CONFIG_BLK_DEV_INITRD
236 /* take care of initrd if we have one */
237 if ( r4 ) {
238 initrd_start = r4 + KERNELBASE;
239 initrd_end = r5 + KERNELBASE;
240 }
241#endif /* CONFIG_BLK_DEV_INITRD */
242 /* take care of cmd line */
243 if ( r6 ) {
244 *(char *)(r7+KERNELBASE) = 0;
245 strcpy(cmd_line, (char *)(r6+KERNELBASE));
246 }
247
248 ppc_md.setup_arch = m8260_setup_arch;
249 ppc_md.show_cpuinfo = m8260_show_cpuinfo;
250 ppc_md.init_IRQ = m8260_init_IRQ;
251 ppc_md.get_irq = cpm2_get_irq;
252
253 ppc_md.restart = m8260_restart;
254 ppc_md.power_off = m8260_power_off;
255 ppc_md.halt = m8260_halt;
256
257 ppc_md.set_rtc_time = m8260_set_rtc_time;
258 ppc_md.get_rtc_time = m8260_get_rtc_time;
259 ppc_md.calibrate_decr = m8260_calibrate_decr;
260
261 ppc_md.find_end_of_memory = m8260_find_end_of_memory;
262 ppc_md.setup_io_mappings = m8260_map_io;
263
264 /* Call back for board-specific settings and overrides. */
265 m82xx_board_init();
266}
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
deleted file mode 100644
index 657a1c25a2ab..000000000000
--- a/arch/ppc/syslib/m82xx_pci.c
+++ /dev/null
@@ -1,346 +0,0 @@
1/*
2 *
3 * (C) Copyright 2003
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 *
6 * (C) Copyright 2004 Red Hat, Inc.
7 *
8 * 2005 (c) MontaVista Software, Inc.
9 * Vitaly Bordug <vbordug@ru.mvista.com>
10 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/slab.h>
34#include <linux/delay.h>
35#include <linux/irq.h>
36#include <linux/interrupt.h>
37
38#include <asm/byteorder.h>
39#include <asm/io.h>
40#include <asm/irq.h>
41#include <asm/uaccess.h>
42#include <asm/machdep.h>
43#include <asm/pci-bridge.h>
44#include <asm/immap_cpm2.h>
45#include <asm/mpc8260.h>
46#include <asm/cpm2.h>
47
48#include "m82xx_pci.h"
49
50/*
51 * Interrupt routing
52 */
53
54static inline int
55pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
56{
57 static char pci_irq_table[][4] =
58 /*
59 * PCI IDSEL/INTPIN->INTLINE
60 * A B C D
61 */
62 {
63 { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */
64 { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */
65 { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */
66 };
67
68 const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
69 return PCI_IRQ_TABLE_LOOKUP;
70}
71
72static void
73pq2pci_mask_irq(unsigned int irq)
74{
75 int bit = irq - NR_CPM_INTS;
76
77 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
78 return;
79}
80
81static void
82pq2pci_unmask_irq(unsigned int irq)
83{
84 int bit = irq - NR_CPM_INTS;
85
86 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
87 return;
88}
89
90static void
91pq2pci_mask_and_ack(unsigned int irq)
92{
93 int bit = irq - NR_CPM_INTS;
94
95 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
96 return;
97}
98
99static void
100pq2pci_end_irq(unsigned int irq)
101{
102 int bit = irq - NR_CPM_INTS;
103
104 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
105 return;
106}
107
108struct hw_interrupt_type pq2pci_ic = {
109 "PQ2 PCI",
110 NULL,
111 NULL,
112 pq2pci_unmask_irq,
113 pq2pci_mask_irq,
114 pq2pci_mask_and_ack,
115 pq2pci_end_irq,
116 0
117};
118
119static irqreturn_t
120pq2pci_irq_demux(int irq, void *dev_id)
121{
122 unsigned long stat, mask, pend;
123 int bit;
124
125 for(;;) {
126 stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
127 mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
128 pend = stat & ~mask & 0xf0000000;
129 if (!pend)
130 break;
131 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
132 if (pend & 0x80000000)
133 __do_IRQ(NR_CPM_INTS + bit);
134 }
135 }
136
137 return IRQ_HANDLED;
138}
139
140static struct irqaction pq2pci_irqaction = {
141 .handler = pq2pci_irq_demux,
142 .flags = IRQF_DISABLED,
143 .mask = CPU_MASK_NONE,
144 .name = "PQ2 PCI cascade",
145};
146
147
148void
149pq2pci_init_irq(void)
150{
151 int irq;
152 volatile cpm2_map_t *immap = cpm2_immr;
153 for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
154 irq_desc[irq].chip = &pq2pci_ic;
155
156 /* make PCI IRQ level sensitive */
157 immap->im_intctl.ic_siexr &=
158 ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
159
160 /* mask all PCI interrupts */
161 *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
162
163 /* install the demultiplexer for the PCI cascade interrupt */
164 setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
165 return;
166}
167
168static int
169pq2pci_exclude_device(u_char bus, u_char devfn)
170{
171 return PCIBIOS_SUCCESSFUL;
172}
173
174/* PCI bus configuration registers.
175 */
176static void
177pq2ads_setup_pci(struct pci_controller *hose)
178{
179 __u32 val;
180 volatile cpm2_map_t *immap = cpm2_immr;
181 bd_t* binfo = (bd_t*) __res;
182 u32 sccr = immap->im_clkrst.car_sccr;
183 uint pci_div,freq,time;
184 /* PCI int lowest prio */
185 /* Each 4 bits is a device bus request and the MS 4bits
186 is highest priority */
187 /* Bus 4bit value
188 --- ----------
189 CPM high 0b0000
190 CPM middle 0b0001
191 CPM low 0b0010
192 PCI request 0b0011
193 Reserved 0b0100
194 Reserved 0b0101
195 Internal Core 0b0110
196 External Master 1 0b0111
197 External Master 2 0b1000
198 External Master 3 0b1001
199 The rest are reserved
200 */
201 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
202 /* park bus on core */
203 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
204 /*
205 * Set up master windows that allow the CPU to access PCI space. These
206 * windows are set up using the two SIU PCIBR registers.
207 */
208
209 immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
210 immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
211
212#ifdef M82xx_PCI_SEC_WND_SIZE
213 immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
214 immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
215#endif
216
217 /* Enable PCI */
218 immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
219
220 pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
221 ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
222 freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
223 time = (int)66666666/freq;
224
225 /* due to PCI Local Bus spec, some devices needs to wait such a long
226 time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
227 printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
228 (time==1) ? "0.5 seconds":"1 second" );
229
230 {
231 int i;
232 for(i=0;i<(500*time);i++)
233 udelay(1000);
234 }
235
236 /* setup ATU registers */
237 immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
238 ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
239 immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
240 immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
241
242 /* Set-up non-prefetchable window */
243 immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
244 immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
245 immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
246
247 /* Set-up prefetchable window */
248 immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
249 (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
250 immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
251 immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
252
253 /* Inbound transactions from PCI memory space */
254 immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
255 ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
256 immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT);
257 immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
258
259 /* park bus on PCI */
260 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
261
262 /* Enable bus mastering and inbound memory transactions */
263 early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
264 val &= 0xffff0000;
265 val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
266 early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
267
268}
269
270void __init pq2_find_bridges(void)
271{
272 extern int pci_assign_all_buses;
273 struct pci_controller * hose;
274 int host_bridge;
275
276 pci_assign_all_buses = 1;
277
278 hose = pcibios_alloc_controller();
279
280 if (!hose)
281 return;
282
283 ppc_md.pci_swizzle = common_swizzle;
284
285 hose->first_busno = 0;
286 hose->bus_offset = 0;
287 hose->last_busno = 0xff;
288
289 setup_m8260_indirect_pci(hose,
290 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
291 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
292
293 /* Make sure it is a supported bridge */
294 early_read_config_dword(hose,
295 0,
296 PCI_DEVFN(0,0),
297 PCI_VENDOR_ID,
298 &host_bridge);
299 switch (host_bridge) {
300 case PCI_DEVICE_ID_MPC8265:
301 break;
302 case PCI_DEVICE_ID_MPC8272:
303 break;
304 default:
305 printk("Attempting to use unrecognized host bridge ID"
306 " 0x%08x.\n", host_bridge);
307 break;
308 }
309
310 pq2ads_setup_pci(hose);
311
312 hose->io_space.start = M82xx_PCI_LOWER_IO;
313 hose->io_space.end = M82xx_PCI_UPPER_IO;
314 hose->mem_space.start = M82xx_PCI_LOWER_MEM;
315 hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
316 hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
317
318 isa_io_base =
319 (unsigned long) ioremap(M82xx_PCI_IO_BASE,
320 M82xx_PCI_IO_SIZE);
321 hose->io_base_virt = (void *) isa_io_base;
322
323 /* setup resources */
324 pci_init_resource(&hose->mem_resources[0],
325 M82xx_PCI_LOWER_MEM,
326 M82xx_PCI_UPPER_MEM,
327 IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
328
329 pci_init_resource(&hose->mem_resources[1],
330 M82xx_PCI_LOWER_MMIO,
331 M82xx_PCI_UPPER_MMIO,
332 IORESOURCE_MEM, "PCI memory");
333
334 pci_init_resource(&hose->io_resource,
335 M82xx_PCI_LOWER_IO,
336 M82xx_PCI_UPPER_IO,
337 IORESOURCE_IO | 1, "PCI I/O");
338
339 ppc_md.pci_exclude_device = pq2pci_exclude_device;
340 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
341
342 ppc_md.pci_map_irq = pq2pci_map_irq;
343 ppc_md.pcibios_fixup = NULL;
344 ppc_md.pcibios_fixup_bus = NULL;
345
346}
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h
deleted file mode 100644
index 924f73f8e595..000000000000
--- a/arch/ppc/syslib/m82xx_pci.h
+++ /dev/null
@@ -1,92 +0,0 @@
1
2#ifndef _PPC_KERNEL_M82XX_PCI_H
3#define _PPC_KERNEL_M82XX_PCI_H
4
5#include <asm/m8260_pci.h>
6/*
7 * Local->PCI map (from CPU) controlled by
8 * MPC826x master window
9 *
10 * 0xF6000000 - 0xF7FFFFFF IO space
11 * 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0
12 *
13 * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1)
14 * 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2)
15 * 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3)
16 *
17 * PCI->Local map (from PCI)
18 * MPC826x slave window controlled by
19 *
20 * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1)
21 */
22
23/*
24 * Slave window that allows PCI masters to access MPC826x local memory.
25 * This window is set up using the first set of Inbound ATU registers
26 */
27
28#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
29#define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart)
30#define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart)
31#define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize)
32#endif
33
34/*
35 * This is the window that allows the CPU to access PCI address space.
36 * It will be setup with the SIU PCIBR0 register. All three PCI master
37 * windows, which allow the CPU to access PCI prefetch, non prefetch,
38 * and IO space (see below), must all fit within this window.
39 */
40
41#ifndef M82xx_PCI_LOWER_MEM
42#define M82xx_PCI_LOWER_MEM 0x80000000
43#define M82xx_PCI_UPPER_MEM 0x9fffffff
44#define M82xx_PCI_MEM_OFFSET 0x00000000
45#define M82xx_PCI_MEM_SIZE 0x20000000
46#endif
47
48#ifndef M82xx_PCI_LOWER_MMIO
49#define M82xx_PCI_LOWER_MMIO 0xa0000000
50#define M82xx_PCI_UPPER_MMIO 0xafffffff
51#define M82xx_PCI_MMIO_OFFSET 0x00000000
52#define M82xx_PCI_MMIO_SIZE 0x20000000
53#endif
54
55#ifndef M82xx_PCI_LOWER_IO
56#define M82xx_PCI_LOWER_IO 0x00000000
57#define M82xx_PCI_UPPER_IO 0x01ffffff
58#define M82xx_PCI_IO_BASE 0xf6000000
59#define M82xx_PCI_IO_SIZE 0x02000000
60#endif
61
62#ifndef M82xx_PCI_PRIM_WND_SIZE
63#define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U)
64#define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE)
65#endif
66
67#ifndef M82xx_PCI_SEC_WND_SIZE
68#define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
69#define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM)
70#endif
71
72#ifndef POTA_ADDR_SHIFT
73#define POTA_ADDR_SHIFT 12
74#endif
75
76#ifndef PITA_ADDR_SHIFT
77#define PITA_ADDR_SHIFT 12
78#endif
79
80#ifndef _IO_BASE
81#define _IO_BASE isa_io_base
82#endif
83
84#ifdef CONFIG_8260_PCI9
85struct pci_controller;
86extern void setup_m8260_indirect_pci(struct pci_controller* hose,
87 u32 cfg_addr, u32 cfg_data);
88#else
89#define setup_m8260_indirect_pci setup_indirect_pci
90#endif
91
92#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
deleted file mode 100644
index 18da720fc1b0..000000000000
--- a/arch/ppc/syslib/m8xx_setup.c
+++ /dev/null
@@ -1,465 +0,0 @@
1/*
2 * Copyright (C) 1995 Linus Torvalds
3 * Adapted from 'alpha' version by Gary Thomas
4 * Modified by Cort Dougan (cort@cs.nmt.edu)
5 * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net)
6 * Further modified for generic 8xx by Dan.
7 */
8
9/*
10 * bootup setup stuff..
11 */
12
13#include <linux/errno.h>
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/mm.h>
17#include <linux/stddef.h>
18#include <linux/unistd.h>
19#include <linux/ptrace.h>
20#include <linux/slab.h>
21#include <linux/user.h>
22#include <linux/a.out.h>
23#include <linux/tty.h>
24#include <linux/major.h>
25#include <linux/interrupt.h>
26#include <linux/reboot.h>
27#include <linux/init.h>
28#include <linux/initrd.h>
29#include <linux/ioport.h>
30#include <linux/bootmem.h>
31#include <linux/seq_file.h>
32#include <linux/root_dev.h>
33
34#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
35#include <linux/mtd/partitions.h>
36#include <linux/mtd/physmap.h>
37#include <linux/mtd/mtd.h>
38#include <linux/mtd/map.h>
39#endif
40
41#include <asm/mmu.h>
42#include <asm/reg.h>
43#include <asm/residual.h>
44#include <asm/io.h>
45#include <asm/pgtable.h>
46#include <asm/mpc8xx.h>
47#include <asm/8xx_immap.h>
48#include <asm/machdep.h>
49#include <asm/bootinfo.h>
50#include <asm/time.h>
51#include <asm/xmon.h>
52#include <asm/ppc_sys.h>
53
54#include "ppc8xx_pic.h"
55
56#ifdef CONFIG_MTD_PHYSMAP
57#define MPC8xxADS_BANK_WIDTH 4
58#endif
59
60#define MPC8xxADS_U_BOOT_SIZE 0x80000
61#define MPC8xxADS_FREE_AREA_OFFSET MPC8xxADS_U_BOOT_SIZE
62
63#if defined(CONFIG_MTD_PARTITIONS)
64 /*
65 NOTE: bank width and interleave relative to the installed flash
66 should have been chosen within MTD_CFI_GEOMETRY options.
67 */
68static struct mtd_partition mpc8xxads_partitions[] = {
69 {
70 .name = "bootloader",
71 .size = MPC8xxADS_U_BOOT_SIZE,
72 .offset = 0,
73 .mask_flags = MTD_WRITEABLE, /* force read-only */
74 }, {
75 .name = "User FS",
76 .offset = MPC8xxADS_FREE_AREA_OFFSET
77 }
78};
79
80#define mpc8xxads_part_num ARRAY_SIZE(mpc8xxads_partitions)
81
82#endif
83
84static int m8xx_set_rtc_time(unsigned long time);
85static unsigned long m8xx_get_rtc_time(void);
86void m8xx_calibrate_decr(void);
87
88unsigned char __res[sizeof(bd_t)];
89
90extern unsigned long find_available_memory(void);
91extern void m8xx_cpm_reset(void);
92extern void m8xx_wdt_handler_install(bd_t *bp);
93extern void rpxfb_alloc_pages(void);
94extern void cpm_interrupt_init(void);
95
96void __attribute__ ((weak))
97board_init(void)
98{
99}
100
101void __init
102m8xx_setup_arch(void)
103{
104#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
105 bd_t *binfo = (bd_t *)__res;
106#endif
107
108 /* Reset the Communication Processor Module.
109 */
110 m8xx_cpm_reset();
111
112#ifdef CONFIG_FB_RPX
113 rpxfb_alloc_pages();
114#endif
115
116#ifdef notdef
117 ROOT_DEV = Root_HDA1; /* hda1 */
118#endif
119
120#ifdef CONFIG_BLK_DEV_INITRD
121#if 0
122 ROOT_DEV = Root_FD0; /* floppy */
123 rd_prompt = 1;
124 rd_doload = 1;
125 rd_image_start = 0;
126#endif
127#if 0 /* XXX this may need to be updated for the new bootmem stuff,
128 or possibly just deleted (see set_phys_avail() in init.c).
129 - paulus. */
130 /* initrd_start and size are setup by boot/head.S and kernel/head.S */
131 if ( initrd_start )
132 {
133 if (initrd_end > *memory_end_p)
134 {
135 printk("initrd extends beyond end of memory "
136 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
137 initrd_end,*memory_end_p);
138 initrd_start = 0;
139 }
140 }
141#endif
142#endif
143
144 board_init();
145}
146
147void
148abort(void)
149{
150#ifdef CONFIG_XMON
151 xmon(0);
152#endif
153 machine_restart(NULL);
154
155 /* not reached */
156 for (;;);
157}
158
159/* A place holder for time base interrupts, if they are ever enabled. */
160irqreturn_t timebase_interrupt(int irq, void * dev)
161{
162 printk ("timebase_interrupt()\n");
163
164 return IRQ_HANDLED;
165}
166
167static struct irqaction tbint_irqaction = {
168 .handler = timebase_interrupt,
169 .mask = CPU_MASK_NONE,
170 .name = "tbint",
171};
172
173/* per-board overridable init_internal_rtc() function. */
174void __init __attribute__ ((weak))
175init_internal_rtc(void)
176{
177 /* Disable the RTC one second and alarm interrupts. */
178 clrbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
179
180 /* Enable the RTC */
181 setbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
182
183}
184
185/* The decrementer counts at the system (internal) clock frequency divided by
186 * sixteen, or external oscillator divided by four. We force the processor
187 * to use system clock divided by sixteen.
188 */
189void __init m8xx_calibrate_decr(void)
190{
191 bd_t *binfo = (bd_t *)__res;
192 int freq, fp, divisor;
193
194 /* Unlock the SCCR. */
195 out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
196 out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
197
198 /* Force all 8xx processors to use divide by 16 processor clock. */
199 setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr, 0x02000000);
200 /* Processor frequency is MHz.
201 * The value 'fp' is the number of decrementer ticks per second.
202 */
203 fp = binfo->bi_intfreq / 16;
204 freq = fp*60; /* try to make freq/1e6 an integer */
205 divisor = 60;
206 printk("Decrementer Frequency = %d/%d\n", freq, divisor);
207 tb_ticks_per_jiffy = freq / HZ / divisor;
208 tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
209
210 /* Perform some more timer/timebase initialization. This used
211 * to be done elsewhere, but other changes caused it to get
212 * called more than once....that is a bad thing.
213 *
214 * First, unlock all of the registers we are going to modify.
215 * To protect them from corruption during power down, registers
216 * that are maintained by keep alive power are "locked". To
217 * modify these registers we have to write the key value to
218 * the key location associated with the register.
219 * Some boards power up with these unlocked, while others
220 * are locked. Writing anything (including the unlock code?)
221 * to the unlocked registers will lock them again. So, here
222 * we guarantee the registers are locked, then we unlock them
223 * for our use.
224 */
225 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
226 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
227 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, ~KAPWR_KEY);
228 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk, KAPWR_KEY);
229 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
230 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
231
232 init_internal_rtc();
233
234 /* Enabling the decrementer also enables the timebase interrupts
235 * (or from the other point of view, to get decrementer interrupts
236 * we have to enable the timebase). The decrementer interrupt
237 * is wired into the vector table, nothing to do here for that.
238 */
239 out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr, (mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE));
240
241 if (setup_irq(DEC_INTERRUPT, &tbint_irqaction))
242 panic("Could not allocate timer IRQ!");
243
244#ifdef CONFIG_8xx_WDT
245 /* Install watchdog timer handler early because it might be
246 * already enabled by the bootloader
247 */
248 m8xx_wdt_handler_install(binfo);
249#endif
250}
251
252/* The RTC on the MPC8xx is an internal register.
253 * We want to protect this during power down, so we need to unlock,
254 * modify, and re-lock.
255 */
256static int
257m8xx_set_rtc_time(unsigned long time)
258{
259 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, KAPWR_KEY);
260 out_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc, time);
261 out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck, ~KAPWR_KEY);
262 return(0);
263}
264
265static unsigned long
266m8xx_get_rtc_time(void)
267{
268 /* Get time from the RTC. */
269 return (unsigned long) in_be32(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtc);
270}
271
272static void
273m8xx_restart(char *cmd)
274{
275 __volatile__ unsigned char dummy;
276
277 local_irq_disable();
278
279 setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, 0x00000080);
280 /* Clear the ME bit in MSR to cause checkstop on machine check
281 */
282 mtmsr(mfmsr() & ~0x1000);
283
284 dummy = in_8(&((immap_t *)IMAP_ADDR)->im_clkrst.res[0]);
285 printk("Restart failed\n");
286 while(1);
287}
288
289static void
290m8xx_power_off(void)
291{
292 m8xx_restart(NULL);
293}
294
295static void
296m8xx_halt(void)
297{
298 m8xx_restart(NULL);
299}
300
301
302static int
303m8xx_show_percpuinfo(struct seq_file *m, int i)
304{
305 bd_t *bp;
306
307 bp = (bd_t *)__res;
308
309 seq_printf(m, "clock\t\t: %uMHz\n"
310 "bus clock\t: %uMHz\n",
311 bp->bi_intfreq / 1000000,
312 bp->bi_busfreq / 1000000);
313
314 return 0;
315}
316
317#ifdef CONFIG_PCI
318static struct irqaction mbx_i8259_irqaction = {
319 .handler = mbx_i8259_action,
320 .mask = CPU_MASK_NONE,
321 .name = "i8259 cascade",
322};
323#endif
324
325/* Initialize the internal interrupt controller. The number of
326 * interrupts supported can vary with the processor type, and the
327 * 82xx family can have up to 64.
328 * External interrupts can be either edge or level triggered, and
329 * need to be initialized by the appropriate driver.
330 */
331static void __init
332m8xx_init_IRQ(void)
333{
334 int i;
335
336 for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++)
337 irq_desc[i].chip = &ppc8xx_pic;
338
339 cpm_interrupt_init();
340
341#if defined(CONFIG_PCI)
342 for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++)
343 irq_desc[i].chip = &i8259_pic;
344
345 i8259_pic_irq_offset = I8259_IRQ_OFFSET;
346 i8259_init(0);
347
348 /* The i8259 cascade interrupt must be level sensitive. */
349
350 clrbits32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, (0x80000000 >> ISA_BRIDGE_INT));
351 if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
352 enable_irq(ISA_BRIDGE_INT);
353#endif /* CONFIG_PCI */
354}
355
356/* -------------------------------------------------------------------- */
357
358/*
359 * This is a big hack right now, but it may turn into something real
360 * someday.
361 *
362 * For the 8xx boards (at this time anyway), there is nothing to initialize
363 * associated the PROM. Rather than include all of the prom.c
364 * functions in the image just to get prom_init, all we really need right
365 * now is the initialization of the physical memory region.
366 */
367static unsigned long __init
368m8xx_find_end_of_memory(void)
369{
370 bd_t *binfo;
371 extern unsigned char __res[];
372
373 binfo = (bd_t *)__res;
374
375 return binfo->bi_memsize;
376}
377
378/*
379 * Now map in some of the I/O space that is generically needed
380 * or shared with multiple devices.
381 * All of this fits into the same 4Mbyte region, so it only
382 * requires one page table page. (or at least it used to -- paulus)
383 */
384static void __init
385m8xx_map_io(void)
386{
387 io_block_mapping(IMAP_ADDR, IMAP_ADDR, IMAP_SIZE, _PAGE_IO);
388#ifdef CONFIG_MBX
389 io_block_mapping(NVRAM_ADDR, NVRAM_ADDR, NVRAM_SIZE, _PAGE_IO);
390 io_block_mapping(MBX_CSR_ADDR, MBX_CSR_ADDR, MBX_CSR_SIZE, _PAGE_IO);
391 io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
392
393 /* Map some of the PCI/ISA I/O space to get the IDE interface.
394 */
395 io_block_mapping(PCI_ISA_IO_ADDR, PCI_ISA_IO_ADDR, 0x4000, _PAGE_IO);
396 io_block_mapping(PCI_IDE_ADDR, PCI_IDE_ADDR, 0x4000, _PAGE_IO);
397#endif
398#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
399 io_block_mapping(RPX_CSR_ADDR, RPX_CSR_ADDR, RPX_CSR_SIZE, _PAGE_IO);
400#if !defined(CONFIG_PCI)
401 io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
402#endif
403#endif
404#if defined(CONFIG_RPXTOUCH) || defined(CONFIG_FB_RPX)
405 io_block_mapping(HIOX_CSR_ADDR, HIOX_CSR_ADDR, HIOX_CSR_SIZE, _PAGE_IO);
406#endif
407#ifdef CONFIG_FADS
408 io_block_mapping(BCSR_ADDR, BCSR_ADDR, BCSR_SIZE, _PAGE_IO);
409#endif
410#ifdef CONFIG_PCI
411 io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
412#endif
413#if defined(CONFIG_NETTA)
414 io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
415#endif
416}
417
418void __init
419platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
420 unsigned long r6, unsigned long r7)
421{
422 parse_bootinfo(find_bootinfo());
423
424 if ( r3 )
425 memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
426
427#ifdef CONFIG_PCI
428 m8xx_setup_pci_ptrs();
429#endif
430
431#ifdef CONFIG_BLK_DEV_INITRD
432 /* take care of initrd if we have one */
433 if ( r4 )
434 {
435 initrd_start = r4 + KERNELBASE;
436 initrd_end = r5 + KERNELBASE;
437 }
438#endif /* CONFIG_BLK_DEV_INITRD */
439 /* take care of cmd line */
440 if ( r6 )
441 {
442 *(char *)(r7+KERNELBASE) = 0;
443 strcpy(cmd_line, (char *)(r6+KERNELBASE));
444 }
445
446 identify_ppc_sys_by_name(BOARD_CHIP_NAME);
447
448 ppc_md.setup_arch = m8xx_setup_arch;
449 ppc_md.show_percpuinfo = m8xx_show_percpuinfo;
450 ppc_md.init_IRQ = m8xx_init_IRQ;
451 ppc_md.get_irq = m8xx_get_irq;
452 ppc_md.init = NULL;
453
454 ppc_md.restart = m8xx_restart;
455 ppc_md.power_off = m8xx_power_off;
456 ppc_md.halt = m8xx_halt;
457
458 ppc_md.time_init = NULL;
459 ppc_md.set_rtc_time = m8xx_set_rtc_time;
460 ppc_md.get_rtc_time = m8xx_get_rtc_time;
461 ppc_md.calibrate_decr = m8xx_calibrate_decr;
462
463 ppc_md.find_end_of_memory = m8xx_find_end_of_memory;
464 ppc_md.setup_io_mappings = m8xx_map_io;
465}
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
deleted file mode 100644
index fffac8cbeb51..000000000000
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ /dev/null
@@ -1,148 +0,0 @@
1/*
2 * m8xx_wdt.c - MPC8xx watchdog driver
3 *
4 * Author: Florian Schirmer <jolt@tuxbox.org>
5 *
6 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> 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 <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <asm/io.h>
18#include <asm/8xx_immap.h>
19#include <syslib/m8xx_wdt.h>
20
21static int wdt_timeout;
22int m8xx_has_internal_rtc = 0;
23
24static irqreturn_t m8xx_wdt_interrupt(int, void *);
25static struct irqaction m8xx_wdt_irqaction = {
26 .handler = m8xx_wdt_interrupt,
27 .name = "watchdog",
28};
29
30void m8xx_wdt_reset(void)
31{
32 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
33
34 out_be16(&imap->im_siu_conf.sc_swsr, 0x556c); /* write magic1 */
35 out_be16(&imap->im_siu_conf.sc_swsr, 0xaa39); /* write magic2 */
36}
37
38static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev)
39{
40 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
41
42 m8xx_wdt_reset();
43
44 setbits16(&imap->im_sit.sit_piscr, PISCR_PS);
45 return IRQ_HANDLED;
46}
47
48#define SYPCR_SWP 0x1
49#define SYPCR_SWE 0x4
50
51
52void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo)
53{
54 u32 pitc;
55 u32 pitrtclk;
56
57 /*
58 * Fire trigger if half of the wdt ticked down
59 */
60
61 if (imap->im_sit.sit_rtcsc & RTCSC_38K)
62 pitrtclk = 9600;
63 else
64 pitrtclk = 8192;
65
66 if ((wdt_timeout) > (UINT_MAX / pitrtclk))
67 pitc = wdt_timeout / binfo->bi_intfreq * pitrtclk / 2;
68 else
69 pitc = pitrtclk * wdt_timeout / binfo->bi_intfreq / 2;
70
71 out_be32(&imap->im_sit.sit_pitc, pitc << 16);
72
73 out_be16(&imap->im_sit.sit_piscr, (mk_int_int_mask(PIT_INTERRUPT) << 8) | PISCR_PIE | PISCR_PTE);
74
75 if (setup_irq(PIT_INTERRUPT, &m8xx_wdt_irqaction))
76 panic("m8xx_wdt: error setting up the watchdog irq!");
77
78 printk(KERN_NOTICE
79 "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc);
80
81}
82
83static void m8xx_wdt_timer_func(unsigned long data);
84
85static struct timer_list m8xx_wdt_timer =
86 TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0);
87
88void m8xx_wdt_stop_timer(void)
89{
90 del_timer(&m8xx_wdt_timer);
91}
92
93void m8xx_wdt_install_timer(void)
94{
95 m8xx_wdt_timer.expires = jiffies + (HZ/2);
96 add_timer(&m8xx_wdt_timer);
97}
98
99static void m8xx_wdt_timer_func(unsigned long data)
100{
101 m8xx_wdt_reset();
102 m8xx_wdt_install_timer();
103}
104
105void __init m8xx_wdt_handler_install(bd_t * binfo)
106{
107 volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
108 u32 sypcr;
109
110 sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
111
112 if (!(sypcr & SYPCR_SWE)) {
113 printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
114 sypcr);
115 return;
116 }
117
118 m8xx_wdt_reset();
119
120 printk(KERN_NOTICE
121 "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
122 (sypcr >> 16), sypcr & SYPCR_SWP);
123
124 wdt_timeout = (sypcr >> 16) & 0xFFFF;
125
126 if (!wdt_timeout)
127 wdt_timeout = 0xFFFF;
128
129 if (sypcr & SYPCR_SWP)
130 wdt_timeout *= 2048;
131
132 m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE;
133
134 /* if the internal RTC is off use a kernel timer */
135 if (!m8xx_has_internal_rtc) {
136 if (wdt_timeout < (binfo->bi_intfreq/HZ))
137 printk(KERN_ERR "m8xx_wdt: timeout too short for ktimer!\n");
138 m8xx_wdt_install_timer();
139 } else
140 m8xx_wdt_install_irq(imap, binfo);
141
142 wdt_timeout /= binfo->bi_intfreq;
143}
144
145int m8xx_wdt_get_timeout(void)
146{
147 return wdt_timeout;
148}
diff --git a/arch/ppc/syslib/m8xx_wdt.h b/arch/ppc/syslib/m8xx_wdt.h
deleted file mode 100644
index e75835f0012b..000000000000
--- a/arch/ppc/syslib/m8xx_wdt.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * Author: Florian Schirmer <jolt@tuxbox.org>
3 *
4 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
5 * the terms of the GNU General Public License version 2. This program
6 * is licensed "as is" without any warranty of any kind, whether express
7 * or implied.
8 */
9#ifndef _PPC_SYSLIB_M8XX_WDT_H
10#define _PPC_SYSLIB_M8XX_WDT_H
11
12extern int m8xx_has_internal_rtc;
13
14extern void m8xx_wdt_handler_install(bd_t * binfo);
15extern int m8xx_wdt_get_timeout(void);
16extern void m8xx_wdt_reset(void);
17extern void m8xx_wdt_install_timer(void);
18extern void m8xx_wdt_stop_timer(void);
19
20#endif /* _PPC_SYSLIB_M8XX_WDT_H */
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
deleted file mode 100644
index 437a294527a9..000000000000
--- a/arch/ppc/syslib/mpc10x_common.c
+++ /dev/null
@@ -1,654 +0,0 @@
1/*
2 * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
3 * Mem ctlr, EPIC, etc.
4 *
5 * Author: Mark A. Greer
6 * mgreer@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/*
15 * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/pci.h>
21#include <linux/slab.h>
22#include <linux/serial_8250.h>
23#include <linux/fsl_devices.h>
24#include <linux/device.h>
25
26#include <asm/byteorder.h>
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/uaccess.h>
30#include <asm/machdep.h>
31#include <asm/pci-bridge.h>
32#include <asm/open_pic.h>
33#include <asm/mpc10x.h>
34#include <asm/ppc_sys.h>
35
36#ifdef CONFIG_MPC10X_OPENPIC
37#ifdef CONFIG_EPIC_SERIAL_MODE
38#define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5)
39#else
40#define EPIC_IRQ_BASE 5
41#endif
42#define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS)
43#define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS)
44#define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS)
45#define MPC10X_UART0_IRQ (EPIC_IRQ_BASE + 4 + NUM_8259_INTERRUPTS)
46#define MPC10X_UART1_IRQ (EPIC_IRQ_BASE + 5 + NUM_8259_INTERRUPTS)
47#else
48#define MPC10X_I2C_IRQ -1
49#define MPC10X_DMA0_IRQ -1
50#define MPC10X_DMA1_IRQ -1
51#define MPC10X_UART0_IRQ -1
52#define MPC10X_UART1_IRQ -1
53#endif
54
55static struct fsl_i2c_platform_data mpc10x_i2c_pdata = {
56 .device_flags = 0,
57};
58
59static struct plat_serial8250_port serial_plat_uart0[] = {
60 [0] = {
61 .mapbase = 0x4500,
62 .iotype = UPIO_MEM,
63 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
64 },
65 { },
66};
67static struct plat_serial8250_port serial_plat_uart1[] = {
68 [0] = {
69 .mapbase = 0x4600,
70 .iotype = UPIO_MEM,
71 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
72 },
73 { },
74};
75
76struct platform_device ppc_sys_platform_devices[] = {
77 [MPC10X_IIC1] = {
78 .name = "fsl-i2c",
79 .id = 1,
80 .dev.platform_data = &mpc10x_i2c_pdata,
81 .num_resources = 2,
82 .resource = (struct resource[]) {
83 {
84 .start = MPC10X_EUMB_I2C_OFFSET,
85 .end = MPC10X_EUMB_I2C_OFFSET +
86 MPC10X_EUMB_I2C_SIZE - 1,
87 .flags = IORESOURCE_MEM,
88 },
89 {
90 .flags = IORESOURCE_IRQ
91 },
92 },
93 },
94 [MPC10X_DMA0] = {
95 .name = "fsl-dma",
96 .id = 0,
97 .num_resources = 2,
98 .resource = (struct resource[]) {
99 {
100 .start = MPC10X_EUMB_DMA_OFFSET + 0x10,
101 .end = MPC10X_EUMB_DMA_OFFSET + 0x1f,
102 .flags = IORESOURCE_MEM,
103 },
104 {
105 .flags = IORESOURCE_IRQ,
106 },
107 },
108 },
109 [MPC10X_DMA1] = {
110 .name = "fsl-dma",
111 .id = 1,
112 .num_resources = 2,
113 .resource = (struct resource[]) {
114 {
115 .start = MPC10X_EUMB_DMA_OFFSET + 0x20,
116 .end = MPC10X_EUMB_DMA_OFFSET + 0x2f,
117 .flags = IORESOURCE_MEM,
118 },
119 {
120 .flags = IORESOURCE_IRQ,
121 },
122 },
123 },
124 [MPC10X_DMA1] = {
125 .name = "fsl-dma",
126 .id = 1,
127 .num_resources = 2,
128 .resource = (struct resource[]) {
129 {
130 .start = MPC10X_EUMB_DMA_OFFSET + 0x20,
131 .end = MPC10X_EUMB_DMA_OFFSET + 0x2f,
132 .flags = IORESOURCE_MEM,
133 },
134 {
135 .flags = IORESOURCE_IRQ,
136 },
137 },
138 },
139 [MPC10X_UART0] = {
140 .name = "serial8250",
141 .id = PLAT8250_DEV_PLATFORM,
142 .dev.platform_data = serial_plat_uart0,
143 },
144 [MPC10X_UART1] = {
145 .name = "serial8250",
146 .id = PLAT8250_DEV_PLATFORM1,
147 .dev.platform_data = serial_plat_uart1,
148 },
149
150};
151
152/* We use the PCI ID to match on */
153struct ppc_sys_spec *cur_ppc_sys_spec;
154struct ppc_sys_spec ppc_sys_specs[] = {
155 {
156 .ppc_sys_name = "8245",
157 .mask = 0xFFFFFFFF,
158 .value = MPC10X_BRIDGE_8245,
159 .num_devices = 5,
160 .device_list = (enum ppc_sys_devices[])
161 {
162 MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, MPC10X_UART0, MPC10X_UART1,
163 },
164 },
165 {
166 .ppc_sys_name = "8240",
167 .mask = 0xFFFFFFFF,
168 .value = MPC10X_BRIDGE_8240,
169 .num_devices = 3,
170 .device_list = (enum ppc_sys_devices[])
171 {
172 MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
173 },
174 },
175 {
176 .ppc_sys_name = "107",
177 .mask = 0xFFFFFFFF,
178 .value = MPC10X_BRIDGE_107,
179 .num_devices = 3,
180 .device_list = (enum ppc_sys_devices[])
181 {
182 MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
183 },
184 },
185 { /* default match */
186 .ppc_sys_name = "",
187 .mask = 0x00000000,
188 .value = 0x00000000,
189 },
190};
191
192/*
193 * mach_mpc10x_fixup: This function enables DUART mode if it detects
194 * if it detects two UARTS in the platform device entries.
195 */
196static int __init mach_mpc10x_fixup(struct platform_device *pdev)
197{
198 if (strncmp (pdev->name, "serial8250", 10) == 0 && pdev->id == 1)
199 writeb(readb(serial_plat_uart1[0].membase + 0x11) | 0x1,
200 serial_plat_uart1[0].membase + 0x11);
201 return 0;
202}
203
204static int __init mach_mpc10x_init(void)
205{
206 ppc_sys_device_fixup = mach_mpc10x_fixup;
207 return 0;
208}
209postcore_initcall(mach_mpc10x_init);
210
211/* Set resources to match bridge memory map */
212void __init
213mpc10x_bridge_set_resources(int map, struct pci_controller *hose)
214{
215
216 switch (map) {
217 case MPC10X_MEM_MAP_A:
218 pci_init_resource(&hose->io_resource,
219 0x00000000,
220 0x3f7fffff,
221 IORESOURCE_IO,
222 "PCI host bridge");
223
224 pci_init_resource (&hose->mem_resources[0],
225 0xc0000000,
226 0xfeffffff,
227 IORESOURCE_MEM,
228 "PCI host bridge");
229 break;
230 case MPC10X_MEM_MAP_B:
231 pci_init_resource(&hose->io_resource,
232 0x00000000,
233 0x00bfffff,
234 IORESOURCE_IO,
235 "PCI host bridge");
236
237 pci_init_resource (&hose->mem_resources[0],
238 0x80000000,
239 0xfcffffff,
240 IORESOURCE_MEM,
241 "PCI host bridge");
242 break;
243 default:
244 printk("mpc10x_bridge_set_resources: "
245 "Invalid map specified\n");
246 if (ppc_md.progress)
247 ppc_md.progress("mpc10x:exit1", 0x100);
248 }
249}
250
251/*
252 * Do some initialization and put the EUMB registers at the specified address
253 * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set).
254 *
255 * The EPIC is not on the 106, only the 8240 and 107.
256 */
257int __init
258mpc10x_bridge_init(struct pci_controller *hose,
259 uint current_map,
260 uint new_map,
261 uint phys_eumb_base)
262{
263 int host_bridge, picr1, picr1_bit, i;
264 ulong pci_config_addr, pci_config_data;
265 u_char pir, byte;
266
267 if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100);
268
269 /* Set up for current map so we can get at config regs */
270 switch (current_map) {
271 case MPC10X_MEM_MAP_A:
272 setup_indirect_pci(hose,
273 MPC10X_MAPA_CNFG_ADDR,
274 MPC10X_MAPA_CNFG_DATA);
275 break;
276 case MPC10X_MEM_MAP_B:
277 setup_indirect_pci(hose,
278 MPC10X_MAPB_CNFG_ADDR,
279 MPC10X_MAPB_CNFG_DATA);
280 break;
281 default:
282 printk("mpc10x_bridge_init: %s\n",
283 "Invalid current map specified");
284 if (ppc_md.progress)
285 ppc_md.progress("mpc10x:exit1", 0x100);
286 return -1;
287 }
288
289 /* Make sure it's a supported bridge */
290 early_read_config_dword(hose,
291 0,
292 PCI_DEVFN(0,0),
293 PCI_VENDOR_ID,
294 &host_bridge);
295
296 switch (host_bridge) {
297 case MPC10X_BRIDGE_106:
298 case MPC10X_BRIDGE_8240:
299 case MPC10X_BRIDGE_107:
300 case MPC10X_BRIDGE_8245:
301 break;
302 default:
303 if (ppc_md.progress)
304 ppc_md.progress("mpc10x:exit2", 0x100);
305 return -1;
306 }
307
308 switch (new_map) {
309 case MPC10X_MEM_MAP_A:
310 MPC10X_SETUP_HOSE(hose, A);
311 pci_config_addr = MPC10X_MAPA_CNFG_ADDR;
312 pci_config_data = MPC10X_MAPA_CNFG_DATA;
313 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A;
314 break;
315 case MPC10X_MEM_MAP_B:
316 MPC10X_SETUP_HOSE(hose, B);
317 pci_config_addr = MPC10X_MAPB_CNFG_ADDR;
318 pci_config_data = MPC10X_MAPB_CNFG_DATA;
319 picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B;
320 break;
321 default:
322 printk("mpc10x_bridge_init: %s\n",
323 "Invalid new map specified");
324 if (ppc_md.progress)
325 ppc_md.progress("mpc10x:exit3", 0x100);
326 return -1;
327 }
328
329 /* Make bridge use the 'new_map', if not already usng it */
330 if (current_map != new_map) {
331 early_read_config_dword(hose,
332 0,
333 PCI_DEVFN(0,0),
334 MPC10X_CFG_PICR1_REG,
335 &picr1);
336
337 picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) |
338 picr1_bit;
339
340 early_write_config_dword(hose,
341 0,
342 PCI_DEVFN(0,0),
343 MPC10X_CFG_PICR1_REG,
344 picr1);
345
346 asm volatile("sync");
347
348 /* Undo old mappings & map in new cfg data/addr regs */
349 iounmap((void *)hose->cfg_addr);
350 iounmap((void *)hose->cfg_data);
351
352 setup_indirect_pci(hose,
353 pci_config_addr,
354 pci_config_data);
355 }
356
357 /* Setup resources to match map */
358 mpc10x_bridge_set_resources(new_map, hose);
359
360 /*
361 * Want processor accesses of 0xFDxxxxxx to be mapped
362 * to PCI memory space at 0x00000000. Do not want
363 * host bridge to respond to PCI memory accesses of
364 * 0xFDxxxxxx. Do not want host bridge to respond
365 * to PCI memory addresses 0xFD000000-0xFDFFFFFF;
366 * want processor accesses from 0x000A0000-0x000BFFFF
367 * to be forwarded to system memory.
368 *
369 * Only valid if not in agent mode and using MAP B.
370 */
371 if (new_map == MPC10X_MEM_MAP_B) {
372 early_read_config_byte(hose,
373 0,
374 PCI_DEVFN(0,0),
375 MPC10X_CFG_MAPB_OPTIONS_REG,
376 &byte);
377
378 byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE |
379 MPC10X_CFG_MAPB_OPTIONS_PCICH |
380 MPC10X_CFG_MAPB_OPTIONS_PROCCH);
381
382 if (host_bridge != MPC10X_BRIDGE_106) {
383 byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE;
384 }
385
386 early_write_config_byte(hose,
387 0,
388 PCI_DEVFN(0,0),
389 MPC10X_CFG_MAPB_OPTIONS_REG,
390 byte);
391 }
392
393 if (host_bridge != MPC10X_BRIDGE_106) {
394 early_read_config_byte(hose,
395 0,
396 PCI_DEVFN(0,0),
397 MPC10X_CFG_PIR_REG,
398 &pir);
399
400 if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) {
401 printk("Host bridge in Agent mode\n");
402 /* Read or Set LMBAR & PCSRBAR? */
403 }
404
405 /* Set base addr of the 8240/107 EUMB. */
406 early_write_config_dword(hose,
407 0,
408 PCI_DEVFN(0,0),
409 MPC10X_CFG_EUMBBAR,
410 phys_eumb_base);
411#ifdef CONFIG_MPC10X_OPENPIC
412 /* Map EPIC register part of EUMB into vitual memory - PCORE
413 uses an i8259 instead of EPIC. */
414 OpenPIC_Addr =
415 ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
416 MPC10X_EUMB_EPIC_SIZE);
417#endif
418 }
419
420#ifdef CONFIG_MPC10X_STORE_GATHERING
421 mpc10x_enable_store_gathering(hose);
422#else
423 mpc10x_disable_store_gathering(hose);
424#endif
425
426 /* setup platform devices for MPC10x bridges */
427 identify_ppc_sys_by_id (host_bridge);
428
429 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
430 unsigned int dev_id = cur_ppc_sys_spec->device_list[i];
431 ppc_sys_fixup_mem_resource(&ppc_sys_platform_devices[dev_id],
432 phys_eumb_base);
433 }
434
435 /* IRQs are determined at runtime */
436 ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ;
437 ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ;
438 ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ;
439 ppc_sys_platform_devices[MPC10X_DMA0].resource[1].end = MPC10X_DMA0_IRQ;
440 ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ;
441 ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ;
442
443 serial_plat_uart0[0].mapbase += phys_eumb_base;
444 serial_plat_uart0[0].irq = MPC10X_UART0_IRQ;
445 serial_plat_uart0[0].membase = ioremap(serial_plat_uart0[0].mapbase, 0x100);
446
447 serial_plat_uart1[0].mapbase += phys_eumb_base;
448 serial_plat_uart1[0].irq = MPC10X_UART1_IRQ;
449 serial_plat_uart1[0].membase = ioremap(serial_plat_uart1[0].mapbase, 0x100);
450
451 /*
452 * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative
453 * PCI reads may return stale data so turn off.
454 */
455 if ((host_bridge == MPC10X_BRIDGE_8240)
456 || (host_bridge == MPC10X_BRIDGE_8245)
457 || (host_bridge == MPC10X_BRIDGE_107)) {
458
459 early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
460 MPC10X_CFG_PICR1_REG, &picr1);
461
462 picr1 &= ~MPC10X_CFG_PICR1_SPEC_PCI_RD;
463
464 early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
465 MPC10X_CFG_PICR1_REG, picr1);
466 }
467
468 /*
469 * 8241/8245 erratum 28: PCI reads from local memory may return
470 * stale data. Workaround by setting PICR2[0] to disable copyback
471 * optimization. Oddly, the latest available user manual for the
472 * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd.
473 */
474 if (host_bridge == MPC10X_BRIDGE_8245) {
475 u32 picr2;
476
477 early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
478 MPC10X_CFG_PICR2_REG, &picr2);
479
480 picr2 |= MPC10X_CFG_PICR2_COPYBACK_OPT;
481
482 early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
483 MPC10X_CFG_PICR2_REG, picr2);
484 }
485
486 if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100);
487 return 0;
488}
489
490/*
491 * Need to make our own PCI config space access macros because
492 * mpc10x_get_mem_size() is called before the data structures are set up for
493 * the 'early_xxx' and 'indirect_xxx' routines to work.
494 * Assumes bus 0.
495 */
496#define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr))
497#define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val))
498
499#define MPC10X_PCI_OP(rw, size, type, op, mask) \
500static void \
501mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \
502{ \
503 out_be32(cfg_addr, \
504 ((offset & 0xfc) << 24) | (devfn << 16) \
505 | (0 << 8) | 0x80); \
506 MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \
507 return; \
508}
509
510MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
511MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
512#if 0 /* Not used */
513MPC10X_PCI_OP(write, byte, u8, out_8, 3)
514MPC10X_PCI_OP(read, word, u16 *, in_le16, 2)
515MPC10X_PCI_OP(write, word, u16, out_le16, 2)
516MPC10X_PCI_OP(write, dword, u32, out_le32, 0)
517#endif
518
519/*
520 * Read the memory controller registers to determine the amount of memory in
521 * the system. This assumes that the firmware has correctly set up the memory
522 * controller registers.
523 */
524unsigned long __init
525mpc10x_get_mem_size(uint mem_map)
526{
527 uint *config_addr, *config_data, val;
528 ulong start, end, total, offset;
529 int i;
530 u_char bank_enables;
531
532 switch (mem_map) {
533 case MPC10X_MEM_MAP_A:
534 config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR;
535 config_data = (uint *)MPC10X_MAPA_CNFG_DATA;
536 break;
537 case MPC10X_MEM_MAP_B:
538 config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR;
539 config_data = (uint *)MPC10X_MAPB_CNFG_DATA;
540 break;
541 default:
542 return 0;
543 }
544
545 mpc10x_read_config_byte(config_addr,
546 config_data,
547 PCI_DEVFN(0,0),
548 MPC10X_MCTLR_MEM_BANK_ENABLES,
549 &bank_enables);
550
551 total = 0;
552
553 for (i=0; i<8; i++) {
554 if (bank_enables & (1 << i)) {
555 offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
556 mpc10x_read_config_dword(config_addr,
557 config_data,
558 PCI_DEVFN(0,0),
559 offset,
560 &val);
561 start = (val >> ((i & 3) << 3)) & 0xff;
562
563 offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
564 mpc10x_read_config_dword(config_addr,
565 config_data,
566 PCI_DEVFN(0,0),
567 offset,
568 &val);
569 val = (val >> ((i & 3) << 3)) & 0x03;
570 start = (val << 28) | (start << 20);
571
572 offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
573 mpc10x_read_config_dword(config_addr,
574 config_data,
575 PCI_DEVFN(0,0),
576 offset,
577 &val);
578 end = (val >> ((i & 3) << 3)) & 0xff;
579
580 offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
581 mpc10x_read_config_dword(config_addr,
582 config_data,
583 PCI_DEVFN(0,0),
584 offset,
585 &val);
586 val = (val >> ((i & 3) << 3)) & 0x03;
587 end = (val << 28) | (end << 20) | 0xfffff;
588
589 total += (end - start + 1);
590 }
591 }
592
593 return total;
594}
595
596int __init
597mpc10x_enable_store_gathering(struct pci_controller *hose)
598{
599 uint picr1;
600
601 early_read_config_dword(hose,
602 0,
603 PCI_DEVFN(0,0),
604 MPC10X_CFG_PICR1_REG,
605 &picr1);
606
607 picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN;
608
609 early_write_config_dword(hose,
610 0,
611 PCI_DEVFN(0,0),
612 MPC10X_CFG_PICR1_REG,
613 picr1);
614
615 return 0;
616}
617
618int __init
619mpc10x_disable_store_gathering(struct pci_controller *hose)
620{
621 uint picr1;
622
623 early_read_config_dword(hose,
624 0,
625 PCI_DEVFN(0,0),
626 MPC10X_CFG_PICR1_REG,
627 &picr1);
628
629 picr1 &= ~MPC10X_CFG_PICR1_ST_GATH_EN;
630
631 early_write_config_dword(hose,
632 0,
633 PCI_DEVFN(0,0),
634 MPC10X_CFG_PICR1_REG,
635 picr1);
636
637 return 0;
638}
639
640#ifdef CONFIG_MPC10X_OPENPIC
641void __init mpc10x_set_openpic(void)
642{
643 /* Map external IRQs */
644 openpic_set_sources(0, EPIC_IRQ_BASE, OpenPIC_Addr + 0x10200);
645 /* Skip reserved space and map i2c and DMA Ch[01] */
646 openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020);
647 /* Skip reserved space and map Message Unit Interrupt (I2O) */
648 openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0);
649 /* Skip reserved space and map Serial Interrupts */
650 openpic_set_sources(EPIC_IRQ_BASE + 4, 2, OpenPIC_Addr + 0x11120);
651
652 openpic_init(NUM_8259_INTERRUPTS);
653}
654#endif
diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
deleted file mode 100644
index 7487539a4e92..000000000000
--- a/arch/ppc/syslib/mpc52xx_devices.c
+++ /dev/null
@@ -1,317 +0,0 @@
1/*
2 * Freescale MPC52xx device descriptions
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#include <linux/fsl_devices.h>
15#include <linux/resource.h>
16#include <linux/platform_device.h>
17#include <asm/mpc52xx.h>
18#include <asm/ppc_sys.h>
19
20
21static u64 mpc52xx_dma_mask = 0xffffffffULL;
22
23static struct fsl_i2c_platform_data mpc52xx_fsl_i2c_pdata = {
24 .device_flags = FSL_I2C_DEV_CLOCK_5200,
25};
26
27
28/* We use relative offsets for IORESOURCE_MEM to be independent from the
29 * MBAR location at compile time
30 */
31
32/* TODO Add the BestComm initiator channel to the device definitions,
33 possibly using IORESOURCE_DMA. But that's when BestComm is ready ... */
34
35struct platform_device ppc_sys_platform_devices[] = {
36 [MPC52xx_MSCAN1] = {
37 .name = "mpc52xx-mscan",
38 .id = 0,
39 .num_resources = 2,
40 .resource = (struct resource[]) {
41 {
42 .start = 0x0900,
43 .end = 0x097f,
44 .flags = IORESOURCE_MEM,
45 },
46 {
47 .start = MPC52xx_MSCAN1_IRQ,
48 .end = MPC52xx_MSCAN1_IRQ,
49 .flags = IORESOURCE_IRQ,
50 },
51 },
52 },
53 [MPC52xx_MSCAN2] = {
54 .name = "mpc52xx-mscan",
55 .id = 1,
56 .num_resources = 2,
57 .resource = (struct resource[]) {
58 {
59 .start = 0x0980,
60 .end = 0x09ff,
61 .flags = IORESOURCE_MEM,
62 },
63 {
64 .start = MPC52xx_MSCAN2_IRQ,
65 .end = MPC52xx_MSCAN2_IRQ,
66 .flags = IORESOURCE_IRQ,
67 },
68 },
69 },
70 [MPC52xx_SPI] = {
71 .name = "mpc52xx-spi",
72 .id = -1,
73 .num_resources = 3,
74 .resource = (struct resource[]) {
75 {
76 .start = 0x0f00,
77 .end = 0x0f1f,
78 .flags = IORESOURCE_MEM,
79 },
80 {
81 .name = "modf",
82 .start = MPC52xx_SPI_MODF_IRQ,
83 .end = MPC52xx_SPI_MODF_IRQ,
84 .flags = IORESOURCE_IRQ,
85 },
86 {
87 .name = "spif",
88 .start = MPC52xx_SPI_SPIF_IRQ,
89 .end = MPC52xx_SPI_SPIF_IRQ,
90 .flags = IORESOURCE_IRQ,
91 },
92 },
93 },
94 [MPC52xx_USB] = {
95 .name = "ppc-soc-ohci",
96 .id = -1,
97 .num_resources = 2,
98 .dev.dma_mask = &mpc52xx_dma_mask,
99 .dev.coherent_dma_mask = 0xffffffffULL,
100 .resource = (struct resource[]) {
101 {
102 .start = 0x1000,
103 .end = 0x10ff,
104 .flags = IORESOURCE_MEM,
105 },
106 {
107 .start = MPC52xx_USB_IRQ,
108 .end = MPC52xx_USB_IRQ,
109 .flags = IORESOURCE_IRQ,
110 },
111 },
112 },
113 [MPC52xx_BDLC] = {
114 .name = "mpc52xx-bdlc",
115 .id = -1,
116 .num_resources = 2,
117 .resource = (struct resource[]) {
118 {
119 .start = 0x1300,
120 .end = 0x130f,
121 .flags = IORESOURCE_MEM,
122 },
123 {
124 .start = MPC52xx_BDLC_IRQ,
125 .end = MPC52xx_BDLC_IRQ,
126 .flags = IORESOURCE_IRQ,
127 },
128 },
129 },
130 [MPC52xx_PSC1] = {
131 .name = "mpc52xx-psc",
132 .id = 0,
133 .num_resources = 2,
134 .resource = (struct resource[]) {
135 {
136 .start = 0x2000,
137 .end = 0x209f,
138 .flags = IORESOURCE_MEM,
139 },
140 {
141 .start = MPC52xx_PSC1_IRQ,
142 .end = MPC52xx_PSC1_IRQ,
143 .flags = IORESOURCE_IRQ,
144 },
145 },
146 },
147 [MPC52xx_PSC2] = {
148 .name = "mpc52xx-psc",
149 .id = 1,
150 .num_resources = 2,
151 .resource = (struct resource[]) {
152 {
153 .start = 0x2200,
154 .end = 0x229f,
155 .flags = IORESOURCE_MEM,
156 },
157 {
158 .start = MPC52xx_PSC2_IRQ,
159 .end = MPC52xx_PSC2_IRQ,
160 .flags = IORESOURCE_IRQ,
161 },
162 },
163 },
164 [MPC52xx_PSC3] = {
165 .name = "mpc52xx-psc",
166 .id = 2,
167 .num_resources = 2,
168 .resource = (struct resource[]) {
169 {
170 .start = 0x2400,
171 .end = 0x249f,
172 .flags = IORESOURCE_MEM,
173 },
174 {
175 .start = MPC52xx_PSC3_IRQ,
176 .end = MPC52xx_PSC3_IRQ,
177 .flags = IORESOURCE_IRQ,
178 },
179 },
180 },
181 [MPC52xx_PSC4] = {
182 .name = "mpc52xx-psc",
183 .id = 3,
184 .num_resources = 2,
185 .resource = (struct resource[]) {
186 {
187 .start = 0x2600,
188 .end = 0x269f,
189 .flags = IORESOURCE_MEM,
190 },
191 {
192 .start = MPC52xx_PSC4_IRQ,
193 .end = MPC52xx_PSC4_IRQ,
194 .flags = IORESOURCE_IRQ,
195 },
196 },
197 },
198 [MPC52xx_PSC5] = {
199 .name = "mpc52xx-psc",
200 .id = 4,
201 .num_resources = 2,
202 .resource = (struct resource[]) {
203 {
204 .start = 0x2800,
205 .end = 0x289f,
206 .flags = IORESOURCE_MEM,
207 },
208 {
209 .start = MPC52xx_PSC5_IRQ,
210 .end = MPC52xx_PSC5_IRQ,
211 .flags = IORESOURCE_IRQ,
212 },
213 },
214 },
215 [MPC52xx_PSC6] = {
216 .name = "mpc52xx-psc",
217 .id = 5,
218 .num_resources = 2,
219 .resource = (struct resource[]) {
220 {
221 .start = 0x2c00,
222 .end = 0x2c9f,
223 .flags = IORESOURCE_MEM,
224 },
225 {
226 .start = MPC52xx_PSC6_IRQ,
227 .end = MPC52xx_PSC6_IRQ,
228 .flags = IORESOURCE_IRQ,
229 },
230 },
231 },
232 [MPC52xx_FEC] = {
233 .name = "mpc52xx-fec",
234 .id = -1,
235 .num_resources = 2,
236 .resource = (struct resource[]) {
237 {
238 .start = 0x3000,
239 .end = 0x33ff,
240 .flags = IORESOURCE_MEM,
241 },
242 {
243 .start = MPC52xx_FEC_IRQ,
244 .end = MPC52xx_FEC_IRQ,
245 .flags = IORESOURCE_IRQ,
246 },
247 },
248 },
249 [MPC52xx_ATA] = {
250 .name = "mpc52xx-ata",
251 .id = -1,
252 .num_resources = 2,
253 .resource = (struct resource[]) {
254 {
255 .start = 0x3a00,
256 .end = 0x3aff,
257 .flags = IORESOURCE_MEM,
258 },
259 {
260 .start = MPC52xx_ATA_IRQ,
261 .end = MPC52xx_ATA_IRQ,
262 .flags = IORESOURCE_IRQ,
263 },
264 },
265 },
266 [MPC52xx_I2C1] = {
267 .name = "fsl-i2c",
268 .id = 0,
269 .dev.platform_data = &mpc52xx_fsl_i2c_pdata,
270 .num_resources = 2,
271 .resource = (struct resource[]) {
272 {
273 .start = 0x3d00,
274 .end = 0x3d1f,
275 .flags = IORESOURCE_MEM,
276 },
277 {
278 .start = MPC52xx_I2C1_IRQ,
279 .end = MPC52xx_I2C1_IRQ,
280 .flags = IORESOURCE_IRQ,
281 },
282 },
283 },
284 [MPC52xx_I2C2] = {
285 .name = "fsl-i2c",
286 .id = 1,
287 .dev.platform_data = &mpc52xx_fsl_i2c_pdata,
288 .num_resources = 2,
289 .resource = (struct resource[]) {
290 {
291 .start = 0x3d40,
292 .end = 0x3d5f,
293 .flags = IORESOURCE_MEM,
294 },
295 {
296 .start = MPC52xx_I2C2_IRQ,
297 .end = MPC52xx_I2C2_IRQ,
298 .flags = IORESOURCE_IRQ,
299 },
300 },
301 },
302};
303
304
305static int __init mach_mpc52xx_fixup(struct platform_device *pdev)
306{
307 ppc_sys_fixup_mem_resource(pdev, MPC52xx_MBAR);
308 return 0;
309}
310
311static int __init mach_mpc52xx_init(void)
312{
313 ppc_sys_device_fixup = mach_mpc52xx_fixup;
314 return 0;
315}
316
317postcore_initcall(mach_mpc52xx_init);
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
deleted file mode 100644
index 20a0eac0dc3a..000000000000
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ /dev/null
@@ -1,289 +0,0 @@
1/*
2 * PCI code for the Freescale MPC52xx embedded CPU.
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14
15#include <asm/pci.h>
16
17#include <asm/mpc52xx.h>
18#include "mpc52xx_pci.h"
19
20#include <asm/delay.h>
21#include <asm/machdep.h>
22
23
24/* This macro is defined to activate the workaround for the bug
25 435 of the MPC5200 (L25R). With it activated, we don't do any
26 32 bits configuration access during type-1 cycles */
27#define MPC5200_BUG_435_WORKAROUND
28
29
30static int
31mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
32 int offset, int len, u32 *val)
33{
34 struct pci_controller *hose = bus->sysdata;
35 u32 value;
36
37 if (ppc_md.pci_exclude_device)
38 if (ppc_md.pci_exclude_device(bus->number, devfn))
39 return PCIBIOS_DEVICE_NOT_FOUND;
40
41 out_be32(hose->cfg_addr,
42 (1 << 31) |
43 ((bus->number - hose->bus_offset) << 16) |
44 (devfn << 8) |
45 (offset & 0xfc));
46 mb();
47
48#ifdef MPC5200_BUG_435_WORKAROUND
49 if (bus->number != hose->bus_offset) {
50 switch (len) {
51 case 1:
52 value = in_8(((u8 __iomem *)hose->cfg_data) + (offset & 3));
53 break;
54 case 2:
55 value = in_le16(((u16 __iomem *)hose->cfg_data) + ((offset>>1) & 1));
56 break;
57
58 default:
59 value = in_le16((u16 __iomem *)hose->cfg_data) |
60 (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
61 break;
62 }
63 }
64 else
65#endif
66 {
67 value = in_le32(hose->cfg_data);
68
69 if (len != 4) {
70 value >>= ((offset & 0x3) << 3);
71 value &= 0xffffffff >> (32 - (len << 3));
72 }
73 }
74
75 *val = value;
76
77 out_be32(hose->cfg_addr, 0);
78 mb();
79
80 return PCIBIOS_SUCCESSFUL;
81}
82
83static int
84mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
85 int offset, int len, u32 val)
86{
87 struct pci_controller *hose = bus->sysdata;
88 u32 value, mask;
89
90 if (ppc_md.pci_exclude_device)
91 if (ppc_md.pci_exclude_device(bus->number, devfn))
92 return PCIBIOS_DEVICE_NOT_FOUND;
93
94 out_be32(hose->cfg_addr,
95 (1 << 31) |
96 ((bus->number - hose->bus_offset) << 16) |
97 (devfn << 8) |
98 (offset & 0xfc));
99 mb();
100
101#ifdef MPC5200_BUG_435_WORKAROUND
102 if (bus->number != hose->bus_offset) {
103 switch (len) {
104 case 1:
105 out_8(((u8 __iomem *)hose->cfg_data) +
106 (offset & 3), val);
107 break;
108 case 2:
109 out_le16(((u16 __iomem *)hose->cfg_data) +
110 ((offset>>1) & 1), val);
111 break;
112
113 default:
114 out_le16((u16 __iomem *)hose->cfg_data,
115 (u16)val);
116 out_le16(((u16 __iomem *)hose->cfg_data) + 1,
117 (u16)(val>>16));
118 break;
119 }
120 }
121 else
122#endif
123 {
124 if (len != 4) {
125 value = in_le32(hose->cfg_data);
126
127 offset = (offset & 0x3) << 3;
128 mask = (0xffffffff >> (32 - (len << 3)));
129 mask <<= offset;
130
131 value &= ~mask;
132 val = value | ((val << offset) & mask);
133 }
134
135 out_le32(hose->cfg_data, val);
136 }
137 mb();
138
139 out_be32(hose->cfg_addr, 0);
140 mb();
141
142 return PCIBIOS_SUCCESSFUL;
143}
144
145static struct pci_ops mpc52xx_pci_ops = {
146 .read = mpc52xx_pci_read_config,
147 .write = mpc52xx_pci_write_config
148};
149
150
151static void __init
152mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
153{
154 u32 tmp;
155
156 /* Setup control regs */
157 tmp = in_be32(&pci_regs->scr);
158 tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
159 out_be32(&pci_regs->scr, tmp);
160
161 /* Setup windows */
162 out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
163 MPC52xx_PCI_MEM_START + MPC52xx_PCI_MEM_OFFSET,
164 MPC52xx_PCI_MEM_START,
165 MPC52xx_PCI_MEM_SIZE ));
166
167 out_be32(&pci_regs->iw1btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
168 MPC52xx_PCI_MMIO_START + MPC52xx_PCI_MEM_OFFSET,
169 MPC52xx_PCI_MMIO_START,
170 MPC52xx_PCI_MMIO_SIZE ));
171
172 out_be32(&pci_regs->iw2btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
173 MPC52xx_PCI_IO_BASE,
174 MPC52xx_PCI_IO_START,
175 MPC52xx_PCI_IO_SIZE ));
176
177 out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(
178 ( MPC52xx_PCI_IWCR_ENABLE | /* iw0btar */
179 MPC52xx_PCI_IWCR_READ_MULTI |
180 MPC52xx_PCI_IWCR_MEM ),
181 ( MPC52xx_PCI_IWCR_ENABLE | /* iw1btar */
182 MPC52xx_PCI_IWCR_READ |
183 MPC52xx_PCI_IWCR_MEM ),
184 ( MPC52xx_PCI_IWCR_ENABLE | /* iw2btar */
185 MPC52xx_PCI_IWCR_IO )
186 ));
187
188
189 out_be32(&pci_regs->tbatr0,
190 MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
191 out_be32(&pci_regs->tbatr1,
192 MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
193
194 out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
195
196 /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
197 /* Not necessary and can be a bad thing if for example the bootloader
198 is displaying a splash screen or ... Just left here for
199 documentation purpose if anyone need it */
200 tmp = in_be32(&pci_regs->gscr);
201#if 0
202 out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
203 udelay(50);
204#endif
205 out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
206}
207
208static void
209mpc52xx_pci_fixup_resources(struct pci_dev *dev)
210{
211 int i;
212
213 /* We don't rely on boot loader for PCI and resets all
214 devices */
215 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
216 struct resource *res = &dev->resource[i];
217 if (res->end > res->start) { /* Only valid resources */
218 res->end -= res->start;
219 res->start = 0;
220 res->flags |= IORESOURCE_UNSET;
221 }
222 }
223
224 /* The PCI Host bridge of MPC52xx has a prefetch memory resource
225 fixed to 1Gb. Doesn't fit in the resource system so we remove it */
226 if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
227 ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
228 || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
229 struct resource *res = &dev->resource[1];
230 res->start = res->end = res->flags = 0;
231 }
232}
233
234void __init
235mpc52xx_find_bridges(void)
236{
237 struct mpc52xx_pci __iomem *pci_regs;
238 struct pci_controller *hose;
239
240 pci_assign_all_buses = 1;
241
242 pci_regs = ioremap(MPC52xx_PA(MPC52xx_PCI_OFFSET), MPC52xx_PCI_SIZE);
243 if (!pci_regs)
244 return;
245
246 hose = pcibios_alloc_controller();
247 if (!hose) {
248 iounmap(pci_regs);
249 return;
250 }
251
252 ppc_md.pci_swizzle = common_swizzle;
253 ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
254
255 hose->first_busno = 0;
256 hose->last_busno = 0xff;
257 hose->bus_offset = 0;
258 hose->ops = &mpc52xx_pci_ops;
259
260 mpc52xx_pci_setup(pci_regs);
261
262 hose->pci_mem_offset = MPC52xx_PCI_MEM_OFFSET;
263
264 hose->io_base_virt = ioremap(MPC52xx_PCI_IO_BASE, MPC52xx_PCI_IO_SIZE);
265 isa_io_base = (unsigned long) hose->io_base_virt;
266
267 hose->cfg_addr = &pci_regs->car;
268 hose->cfg_data = hose->io_base_virt;
269
270 /* Setup resources */
271 pci_init_resource(&hose->mem_resources[0],
272 MPC52xx_PCI_MEM_START,
273 MPC52xx_PCI_MEM_STOP,
274 IORESOURCE_MEM|IORESOURCE_PREFETCH,
275 "PCI prefetchable memory");
276
277 pci_init_resource(&hose->mem_resources[1],
278 MPC52xx_PCI_MMIO_START,
279 MPC52xx_PCI_MMIO_STOP,
280 IORESOURCE_MEM,
281 "PCI memory");
282
283 pci_init_resource(&hose->io_resource,
284 MPC52xx_PCI_IO_START,
285 MPC52xx_PCI_IO_STOP,
286 IORESOURCE_IO,
287 "PCI I/O");
288
289}
diff --git a/arch/ppc/syslib/mpc52xx_pci.h b/arch/ppc/syslib/mpc52xx_pci.h
deleted file mode 100644
index 77d47dbba85e..000000000000
--- a/arch/ppc/syslib/mpc52xx_pci.h
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * PCI Include file the Freescale MPC52xx embedded cpu chips
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Inspired from code written by Dale Farnsworth <dfarnsworth@mvista.com>
8 * for the 2.4 kernel.
9 *
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 MontaVista, Software, Inc.
12 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 */
17
18#ifndef __SYSLIB_MPC52xx_PCI_H__
19#define __SYSLIB_MPC52xx_PCI_H__
20
21/* ======================================================================== */
22/* PCI windows config */
23/* ======================================================================== */
24
25/*
26 * Master windows : MPC52xx -> PCI
27 *
28 * 0x80000000 -> 0x9FFFFFFF PCI Mem prefetchable IW0BTAR
29 * 0xA0000000 -> 0xAFFFFFFF PCI Mem IW1BTAR
30 * 0xB0000000 -> 0xB0FFFFFF PCI IO IW2BTAR
31 *
32 * Slave windows : PCI -> MPC52xx
33 *
34 * 0xF0000000 -> 0xF003FFFF MPC52xx MBAR TBATR0
35 * 0x00000000 -> 0x3FFFFFFF MPC52xx local memory TBATR1
36 */
37
38#define MPC52xx_PCI_MEM_OFFSET 0x00000000 /* Offset for MEM MMIO */
39
40#define MPC52xx_PCI_MEM_START 0x80000000
41#define MPC52xx_PCI_MEM_SIZE 0x20000000
42#define MPC52xx_PCI_MEM_STOP (MPC52xx_PCI_MEM_START+MPC52xx_PCI_MEM_SIZE-1)
43
44#define MPC52xx_PCI_MMIO_START 0xa0000000
45#define MPC52xx_PCI_MMIO_SIZE 0x10000000
46#define MPC52xx_PCI_MMIO_STOP (MPC52xx_PCI_MMIO_START+MPC52xx_PCI_MMIO_SIZE-1)
47
48#define MPC52xx_PCI_IO_BASE 0xb0000000
49
50#define MPC52xx_PCI_IO_START 0x00000000
51#define MPC52xx_PCI_IO_SIZE 0x01000000
52#define MPC52xx_PCI_IO_STOP (MPC52xx_PCI_IO_START+MPC52xx_PCI_IO_SIZE-1)
53
54
55#define MPC52xx_PCI_TARGET_IO MPC52xx_MBAR
56#define MPC52xx_PCI_TARGET_MEM 0x00000000
57
58
59/* ======================================================================== */
60/* Structures mapping & Defines for PCI Unit */
61/* ======================================================================== */
62
63#define MPC52xx_PCI_GSCR_BM 0x40000000
64#define MPC52xx_PCI_GSCR_PE 0x20000000
65#define MPC52xx_PCI_GSCR_SE 0x10000000
66#define MPC52xx_PCI_GSCR_XLB2PCI_MASK 0x07000000
67#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
68#define MPC52xx_PCI_GSCR_IPG2PCI_MASK 0x00070000
69#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
70#define MPC52xx_PCI_GSCR_BME 0x00004000
71#define MPC52xx_PCI_GSCR_PEE 0x00002000
72#define MPC52xx_PCI_GSCR_SEE 0x00001000
73#define MPC52xx_PCI_GSCR_PR 0x00000001
74
75
76#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size) \
77 ( ( (proc_ad) & 0xff000000 ) | \
78 ( (((size) - 1) >> 8) & 0x00ff0000 ) | \
79 ( ((pci_ad) >> 16) & 0x0000ff00 ) )
80
81#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2) (((win0) << 24) | \
82 ((win1) << 16) | \
83 ((win2) << 8))
84
85#define MPC52xx_PCI_IWCR_DISABLE 0x0
86#define MPC52xx_PCI_IWCR_ENABLE 0x1
87#define MPC52xx_PCI_IWCR_READ 0x0
88#define MPC52xx_PCI_IWCR_READ_LINE 0x2
89#define MPC52xx_PCI_IWCR_READ_MULTI 0x4
90#define MPC52xx_PCI_IWCR_MEM 0x0
91#define MPC52xx_PCI_IWCR_IO 0x8
92
93#define MPC52xx_PCI_TCR_P 0x01000000
94#define MPC52xx_PCI_TCR_LD 0x00010000
95
96#define MPC52xx_PCI_TBATR_DISABLE 0x0
97#define MPC52xx_PCI_TBATR_ENABLE 0x1
98
99
100#ifndef __ASSEMBLY__
101
102struct mpc52xx_pci {
103 u32 idr; /* PCI + 0x00 */
104 u32 scr; /* PCI + 0x04 */
105 u32 ccrir; /* PCI + 0x08 */
106 u32 cr1; /* PCI + 0x0C */
107 u32 bar0; /* PCI + 0x10 */
108 u32 bar1; /* PCI + 0x14 */
109 u8 reserved1[16]; /* PCI + 0x18 */
110 u32 ccpr; /* PCI + 0x28 */
111 u32 sid; /* PCI + 0x2C */
112 u32 erbar; /* PCI + 0x30 */
113 u32 cpr; /* PCI + 0x34 */
114 u8 reserved2[4]; /* PCI + 0x38 */
115 u32 cr2; /* PCI + 0x3C */
116 u8 reserved3[32]; /* PCI + 0x40 */
117 u32 gscr; /* PCI + 0x60 */
118 u32 tbatr0; /* PCI + 0x64 */
119 u32 tbatr1; /* PCI + 0x68 */
120 u32 tcr; /* PCI + 0x6C */
121 u32 iw0btar; /* PCI + 0x70 */
122 u32 iw1btar; /* PCI + 0x74 */
123 u32 iw2btar; /* PCI + 0x78 */
124 u8 reserved4[4]; /* PCI + 0x7C */
125 u32 iwcr; /* PCI + 0x80 */
126 u32 icr; /* PCI + 0x84 */
127 u32 isr; /* PCI + 0x88 */
128 u32 arb; /* PCI + 0x8C */
129 u8 reserved5[104]; /* PCI + 0x90 */
130 u32 car; /* PCI + 0xF8 */
131 u8 reserved6[4]; /* PCI + 0xFC */
132};
133
134#endif /* __ASSEMBLY__ */
135
136
137#endif /* __SYSLIB_MPC52xx_PCI_H__ */
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
deleted file mode 100644
index f58149c03b0f..000000000000
--- a/arch/ppc/syslib/mpc52xx_pic.c
+++ /dev/null
@@ -1,254 +0,0 @@
1/*
2 * Programmable Interrupt Controller functions for the Freescale MPC52xx
3 * embedded CPU.
4 *
5 *
6 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
7 *
8 * Based on (well, mostly copied from) the code from the 2.4 kernel by
9 * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
10 *
11 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
12 * Copyright (C) 2003 Montavista Software, Inc
13 *
14 * This file is licensed under the terms of the GNU General Public License
15 * version 2. This program is licensed "as is" without any warranty of any
16 * kind, whether express or implied.
17 */
18
19#include <linux/stddef.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/signal.h>
23#include <linux/delay.h>
24#include <linux/irq.h>
25
26#include <asm/io.h>
27#include <asm/processor.h>
28#include <asm/system.h>
29#include <asm/irq.h>
30#include <asm/mpc52xx.h>
31
32
33static struct mpc52xx_intr __iomem *intr;
34static struct mpc52xx_sdma __iomem *sdma;
35
36static void
37mpc52xx_ic_disable(unsigned int irq)
38{
39 u32 val;
40
41 if (irq == MPC52xx_IRQ0) {
42 val = in_be32(&intr->ctrl);
43 val &= ~(1 << 11);
44 out_be32(&intr->ctrl, val);
45 }
46 else if (irq < MPC52xx_IRQ1) {
47 BUG();
48 }
49 else if (irq <= MPC52xx_IRQ3) {
50 val = in_be32(&intr->ctrl);
51 val &= ~(1 << (10 - (irq - MPC52xx_IRQ1)));
52 out_be32(&intr->ctrl, val);
53 }
54 else if (irq < MPC52xx_SDMA_IRQ_BASE) {
55 val = in_be32(&intr->main_mask);
56 val |= 1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE));
57 out_be32(&intr->main_mask, val);
58 }
59 else if (irq < MPC52xx_PERP_IRQ_BASE) {
60 val = in_be32(&sdma->IntMask);
61 val |= 1 << (irq - MPC52xx_SDMA_IRQ_BASE);
62 out_be32(&sdma->IntMask, val);
63 }
64 else {
65 val = in_be32(&intr->per_mask);
66 val |= 1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE));
67 out_be32(&intr->per_mask, val);
68 }
69}
70
71static void
72mpc52xx_ic_enable(unsigned int irq)
73{
74 u32 val;
75
76 if (irq == MPC52xx_IRQ0) {
77 val = in_be32(&intr->ctrl);
78 val |= 1 << 11;
79 out_be32(&intr->ctrl, val);
80 }
81 else if (irq < MPC52xx_IRQ1) {
82 BUG();
83 }
84 else if (irq <= MPC52xx_IRQ3) {
85 val = in_be32(&intr->ctrl);
86 val |= 1 << (10 - (irq - MPC52xx_IRQ1));
87 out_be32(&intr->ctrl, val);
88 }
89 else if (irq < MPC52xx_SDMA_IRQ_BASE) {
90 val = in_be32(&intr->main_mask);
91 val &= ~(1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE)));
92 out_be32(&intr->main_mask, val);
93 }
94 else if (irq < MPC52xx_PERP_IRQ_BASE) {
95 val = in_be32(&sdma->IntMask);
96 val &= ~(1 << (irq - MPC52xx_SDMA_IRQ_BASE));
97 out_be32(&sdma->IntMask, val);
98 }
99 else {
100 val = in_be32(&intr->per_mask);
101 val &= ~(1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE)));
102 out_be32(&intr->per_mask, val);
103 }
104}
105
106static void
107mpc52xx_ic_ack(unsigned int irq)
108{
109 u32 val;
110
111 /*
112 * Only some irqs are reset here, others in interrupting hardware.
113 */
114
115 switch (irq) {
116 case MPC52xx_IRQ0:
117 val = in_be32(&intr->ctrl);
118 val |= 0x08000000;
119 out_be32(&intr->ctrl, val);
120 break;
121 case MPC52xx_CCS_IRQ:
122 val = in_be32(&intr->enc_status);
123 val |= 0x00000400;
124 out_be32(&intr->enc_status, val);
125 break;
126 case MPC52xx_IRQ1:
127 val = in_be32(&intr->ctrl);
128 val |= 0x04000000;
129 out_be32(&intr->ctrl, val);
130 break;
131 case MPC52xx_IRQ2:
132 val = in_be32(&intr->ctrl);
133 val |= 0x02000000;
134 out_be32(&intr->ctrl, val);
135 break;
136 case MPC52xx_IRQ3:
137 val = in_be32(&intr->ctrl);
138 val |= 0x01000000;
139 out_be32(&intr->ctrl, val);
140 break;
141 default:
142 if (irq >= MPC52xx_SDMA_IRQ_BASE
143 && irq < (MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)) {
144 out_be32(&sdma->IntPend,
145 1 << (irq - MPC52xx_SDMA_IRQ_BASE));
146 }
147 break;
148 }
149}
150
151static void
152mpc52xx_ic_disable_and_ack(unsigned int irq)
153{
154 mpc52xx_ic_disable(irq);
155 mpc52xx_ic_ack(irq);
156}
157
158static void
159mpc52xx_ic_end(unsigned int irq)
160{
161 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
162 mpc52xx_ic_enable(irq);
163}
164
165static struct hw_interrupt_type mpc52xx_ic = {
166 .typename = " MPC52xx ",
167 .enable = mpc52xx_ic_enable,
168 .disable = mpc52xx_ic_disable,
169 .ack = mpc52xx_ic_disable_and_ack,
170 .end = mpc52xx_ic_end,
171};
172
173void __init
174mpc52xx_init_irq(void)
175{
176 int i;
177 u32 intr_ctrl;
178
179 /* Remap the necessary zones */
180 intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
181 sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);
182
183 if ((intr==NULL) || (sdma==NULL))
184 panic("Can't ioremap PIC/SDMA register for init_irq !");
185
186 /* Disable all interrupt sources. */
187 out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
188 out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
189 out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
190 out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
191 intr_ctrl = in_be32(&intr->ctrl);
192 intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
193 intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
194 0x00001000 | /* MEE master external enable */
195 0x00000000 | /* 0 means disable IRQ 0-3 */
196 0x00000001; /* CEb route critical normally */
197 out_be32(&intr->ctrl, intr_ctrl);
198
199 /* Zero a bunch of the priority settings. */
200 out_be32(&intr->per_pri1, 0);
201 out_be32(&intr->per_pri2, 0);
202 out_be32(&intr->per_pri3, 0);
203 out_be32(&intr->main_pri1, 0);
204 out_be32(&intr->main_pri2, 0);
205
206 /* Initialize irq_desc[i].chip's with mpc52xx_ic. */
207 for (i = 0; i < NR_IRQS; i++) {
208 irq_desc[i].chip = &mpc52xx_ic;
209 irq_desc[i].status = IRQ_LEVEL;
210 }
211
212 #define IRQn_MODE(intr_ctrl,irq) (((intr_ctrl) >> (22-(i<<1))) & 0x03)
213 for (i=0 ; i<4 ; i++) {
214 int mode;
215 mode = IRQn_MODE(intr_ctrl,i);
216 if ((mode == 0x1) || (mode == 0x2))
217 irq_desc[i?MPC52xx_IRQ1+i-1:MPC52xx_IRQ0].status = 0;
218 }
219}
220
221int
222mpc52xx_get_irq(void)
223{
224 u32 status;
225 int irq = -1;
226
227 status = in_be32(&intr->enc_status);
228
229 if (status & 0x00000400) { /* critical */
230 irq = (status >> 8) & 0x3;
231 if (irq == 2) /* high priority peripheral */
232 goto peripheral;
233 irq += MPC52xx_CRIT_IRQ_BASE;
234 }
235 else if (status & 0x00200000) { /* main */
236 irq = (status >> 16) & 0x1f;
237 if (irq == 4) /* low priority peripheral */
238 goto peripheral;
239 irq += MPC52xx_MAIN_IRQ_BASE;
240 }
241 else if (status & 0x20000000) { /* peripheral */
242peripheral:
243 irq = (status >> 24) & 0x1f;
244 if (irq == 0) { /* bestcomm */
245 status = in_be32(&sdma->IntPend);
246 irq = ffs(status) + MPC52xx_SDMA_IRQ_BASE-1;
247 }
248 else
249 irq += MPC52xx_PERP_IRQ_BASE;
250 }
251
252 return irq;
253}
254
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
deleted file mode 100644
index ab0cf4ced9e5..000000000000
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ /dev/null
@@ -1,313 +0,0 @@
1/*
2 * Common code for the boards based on Freescale MPC52xx embedded CPU.
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Support for other bootloaders than UBoot by Dale Farnsworth
8 * <dfarnsworth@mvista.com>
9 *
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 Montavista Software, Inc
12 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 */
17
18
19#include <linux/spinlock.h>
20#include <asm/io.h>
21#include <asm/time.h>
22#include <asm/mpc52xx.h>
23#include <asm/mpc52xx_psc.h>
24#include <asm/pgtable.h>
25#include <asm/ppcboot.h>
26
27#include <syslib/mpc52xx_pci.h>
28
29extern bd_t __res;
30
31static int core_mult[] = { /* CPU Frequency multiplier, taken */
32 0, 0, 0, 10, 20, 20, 25, 45, /* from the datasheet used to compute */
33 30, 55, 40, 50, 0, 60, 35, 0, /* CPU frequency from XLB freq and */
34 30, 25, 65, 10, 70, 20, 75, 45, /* external jumper config */
35 0, 55, 40, 50, 80, 60, 35, 0
36};
37
38void
39mpc52xx_restart(char *cmd)
40{
41 struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
42
43 local_irq_disable();
44
45 /* Turn on the watchdog and wait for it to expire. It effectively
46 does a reset */
47 out_be32(&gpt0->count, 0x000000ff);
48 out_be32(&gpt0->mode, 0x00009004);
49
50 while (1);
51}
52
53void
54mpc52xx_halt(void)
55{
56 local_irq_disable();
57
58 while (1);
59}
60
61void
62mpc52xx_power_off(void)
63{
64 /* By default we don't have any way of shut down.
65 If a specific board wants to, it can set the power down
66 code to any hardware implementation dependent code */
67 mpc52xx_halt();
68}
69
70
71void __init
72mpc52xx_set_bat(void)
73{
74 /* Set BAT 2 to map the 0xf0000000 area */
75 /* This mapping is used during mpc52xx_progress,
76 * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug
77 */
78 mb();
79 mtspr(SPRN_DBAT2U, 0xf0001ffe);
80 mtspr(SPRN_DBAT2L, 0xf000002a);
81 mb();
82}
83
84void __init
85mpc52xx_map_io(void)
86{
87 /* Here we map the MBAR and the whole upper zone. MBAR is only
88 64k but we can't map only 64k with BATs. Map the whole
89 0xf0000000 range is ok and helps eventual lpb devices placed there */
90 io_block_mapping(
91 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
92}
93
94
95#ifdef CONFIG_SERIAL_TEXT_DEBUG
96#ifndef MPC52xx_PF_CONSOLE_PORT
97#error "mpc52xx PSC for console not selected"
98#endif
99
100static void
101mpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c)
102{
103 while (!(in_be16(&psc->mpc52xx_psc_status) &
104 MPC52xx_PSC_SR_TXRDY));
105 out_8(&psc->mpc52xx_psc_buffer_8, c);
106}
107
108void
109mpc52xx_progress(char *s, unsigned short hex)
110{
111 char c;
112 struct mpc52xx_psc __iomem *psc;
113
114 psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
115
116 while ((c = *s++) != 0) {
117 if (c == '\n')
118 mpc52xx_psc_putc(psc, '\r');
119 mpc52xx_psc_putc(psc, c);
120 }
121
122 mpc52xx_psc_putc(psc, '\r');
123 mpc52xx_psc_putc(psc, '\n');
124}
125
126#endif /* CONFIG_SERIAL_TEXT_DEBUG */
127
128
129unsigned long __init
130mpc52xx_find_end_of_memory(void)
131{
132 u32 ramsize = __res.bi_memsize;
133
134 /*
135 * if bootloader passed a memsize, just use it
136 * else get size from sdram config registers
137 */
138 if (ramsize == 0) {
139 struct mpc52xx_mmap_ctl __iomem *mmap_ctl;
140 u32 sdram_config_0, sdram_config_1;
141
142 /* Temp BAT2 mapping active when this is called ! */
143 mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
144
145 sdram_config_0 = in_be32(&mmap_ctl->sdram0);
146 sdram_config_1 = in_be32(&mmap_ctl->sdram1);
147
148 if ((sdram_config_0 & 0x1f) >= 0x13)
149 ramsize = 1 << ((sdram_config_0 & 0xf) + 17);
150
151 if (((sdram_config_1 & 0x1f) >= 0x13) &&
152 ((sdram_config_1 & 0xfff00000) == ramsize))
153 ramsize += 1 << ((sdram_config_1 & 0xf) + 17);
154 }
155
156 return ramsize;
157}
158
159void __init
160mpc52xx_calibrate_decr(void)
161{
162 int current_time, previous_time;
163 int tbl_start, tbl_end;
164 unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;
165
166 xlbfreq = __res.bi_busfreq;
167 /* if bootloader didn't pass bus frequencies, calculate them */
168 if (xlbfreq == 0) {
169 /* Get RTC & Clock manager modules */
170 struct mpc52xx_rtc __iomem *rtc;
171 struct mpc52xx_cdm __iomem *cdm;
172
173 rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
174 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
175
176 if ((rtc==NULL) || (cdm==NULL))
177 panic("Can't ioremap RTC/CDM while computing bus freq");
178
179 /* Count bus clock during 1/64 sec */
180 out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */
181 previous_time = in_be32(&rtc->time);
182 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
183 tbl_start = get_tbl();
184 previous_time = current_time;
185 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
186 tbl_end = get_tbl();
187 out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */
188
189 /* Compute all frequency from that & CDM settings */
190 xlbfreq = (tbl_end - tbl_start) << 8;
191 cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10;
192 ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ?
193 xlbfreq / 2 : xlbfreq;
194 switch (in_8(&cdm->pci_clk_sel) & 3) {
195 case 0:
196 pcifreq = ipbfreq;
197 break;
198 case 1:
199 pcifreq = ipbfreq / 2;
200 break;
201 default:
202 pcifreq = xlbfreq / 4;
203 break;
204 }
205 __res.bi_busfreq = xlbfreq;
206 __res.bi_intfreq = cpufreq;
207 __res.bi_ipbfreq = ipbfreq;
208 __res.bi_pcifreq = pcifreq;
209
210 /* Release mapping */
211 iounmap(rtc);
212 iounmap(cdm);
213 }
214
215 divisor = 4;
216
217 tb_ticks_per_jiffy = xlbfreq / HZ / divisor;
218 tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
219}
220
221
222void __init
223mpc52xx_setup_cpu(void)
224{
225 struct mpc52xx_cdm __iomem *cdm;
226 struct mpc52xx_xlb __iomem *xlb;
227
228 /* Map zones */
229 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
230 xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
231
232 if (!cdm || !xlb) {
233 printk(KERN_ERR __FILE__ ": "
234 "Error while mapping CDM/XLB during "
235 "mpc52xx_setup_cpu\n");
236 goto unmap_regs;
237 }
238
239 /* Use internal 48 Mhz */
240 out_8(&cdm->ext_48mhz_en, 0x00);
241 out_8(&cdm->fd_enable, 0x01);
242 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
243 out_be16(&cdm->fd_counters, 0x0001);
244 else
245 out_be16(&cdm->fd_counters, 0x5555);
246
247 /* Configure the XLB Arbiter priorities */
248 out_be32(&xlb->master_pri_enable, 0xff);
249 out_be32(&xlb->master_priority, 0x11111111);
250
251 /* Enable ram snooping for 1GB window */
252 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
253 out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
254
255 /* Disable XLB pipelining */
256 /* (cfr errata 292. We could do this only just before ATA PIO
257 transaction and re-enable it after ...) */
258 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
259
260 /* Unmap reg zone */
261unmap_regs:
262 if (cdm) iounmap(cdm);
263 if (xlb) iounmap(xlb);
264}
265
266
267int mpc52xx_match_psc_function(int psc_idx, const char *func)
268{
269 struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
270
271 while ((cf->id != -1) && (cf->func != NULL)) {
272 if ((cf->id == psc_idx) && !strcmp(cf->func,func))
273 return 1;
274 cf++;
275 }
276
277 return 0;
278}
279
280int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
281{
282 static DEFINE_SPINLOCK(lock);
283 struct mpc52xx_cdm __iomem *cdm;
284 unsigned long flags;
285 u16 mclken_div;
286 u16 __iomem *reg;
287 u32 mask;
288
289 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
290 if (!cdm) {
291 printk(KERN_ERR __FILE__ ": Error mapping CDM\n");
292 return -ENODEV;
293 }
294
295 mclken_div = 0x8000 | (clkdiv & 0x1FF);
296 switch (psc_id) {
297 case 1: reg = &cdm->mclken_div_psc1; mask = 0x20; break;
298 case 2: reg = &cdm->mclken_div_psc2; mask = 0x40; break;
299 case 3: reg = &cdm->mclken_div_psc3; mask = 0x80; break;
300 case 6: reg = &cdm->mclken_div_psc6; mask = 0x10; break;
301 default:
302 return -ENODEV;
303 }
304
305 /* Set the rate and enable the clock */
306 spin_lock_irqsave(&lock, flags);
307 out_be16(reg, mclken_div);
308 out_be32(&cdm->clk_enables, in_be32(&cdm->clk_enables) | mask);
309 spin_unlock_irqrestore(&lock, flags);
310
311 iounmap(cdm);
312 return 0;
313}
diff --git a/arch/ppc/syslib/mpc52xx_sys.c b/arch/ppc/syslib/mpc52xx_sys.c
deleted file mode 100644
index b4e6f978f057..000000000000
--- a/arch/ppc/syslib/mpc52xx_sys.c
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Freescale MPC52xx system descriptions
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#include <asm/ppc_sys.h>
15
16struct ppc_sys_spec *cur_ppc_sys_spec;
17struct ppc_sys_spec ppc_sys_specs[] = {
18 {
19 .ppc_sys_name = "5200",
20 .mask = 0xffff0000,
21 .value = 0x80110000,
22 .num_devices = 15,
23 .device_list = (enum ppc_sys_devices[])
24 {
25 MPC52xx_MSCAN1, MPC52xx_MSCAN2, MPC52xx_SPI,
26 MPC52xx_USB, MPC52xx_BDLC, MPC52xx_PSC1, MPC52xx_PSC2,
27 MPC52xx_PSC3, MPC52xx_PSC4, MPC52xx_PSC5, MPC52xx_PSC6,
28 MPC52xx_FEC, MPC52xx_ATA, MPC52xx_I2C1, MPC52xx_I2C2,
29 },
30 },
31 { /* default match */
32 .ppc_sys_name = "",
33 .mask = 0x00000000,
34 .value = 0x00000000,
35 },
36};
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
deleted file mode 100644
index 80804eee5795..000000000000
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ /dev/null
@@ -1,243 +0,0 @@
1/*
2 * MPC8xx Device descriptions
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.com>
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#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/serial_8250.h>
18#include <linux/mii.h>
19#include <asm/cpm1.h>
20#include <asm/mpc8xx.h>
21#include <asm/irq.h>
22#include <asm/ppc_sys.h>
23
24/* We use offsets for IORESOURCE_MEM to do not set dependencies at compile time.
25 * They will get fixed up by mach_mpc8xx_fixup
26 */
27
28struct platform_device ppc_sys_platform_devices[] = {
29 [MPC8xx_CPM_FEC1] = {
30 .name = "fsl-cpm-fec",
31 .id = 1,
32 .num_resources = 2,
33 .resource = (struct resource[]) {
34 {
35 .name = "regs",
36 .start = 0xe00,
37 .end = 0xe88,
38 .flags = IORESOURCE_MEM,
39 },
40 {
41 .name = "interrupt",
42 .start = MPC8xx_INT_FEC1,
43 .end = MPC8xx_INT_FEC1,
44 .flags = IORESOURCE_IRQ,
45 },
46 },
47 },
48 [MPC8xx_CPM_FEC2] = {
49 .name = "fsl-cpm-fec",
50 .id = 2,
51 .num_resources = 2,
52 .resource = (struct resource[]) {
53 {
54 .name = "regs",
55 .start = 0x1e00,
56 .end = 0x1e88,
57 .flags = IORESOURCE_MEM,
58 },
59 {
60 .name = "interrupt",
61 .start = MPC8xx_INT_FEC2,
62 .end = MPC8xx_INT_FEC2,
63 .flags = IORESOURCE_IRQ,
64 },
65 },
66 },
67 [MPC8xx_CPM_SCC1] = {
68 .name = "fsl-cpm-scc",
69 .id = 1,
70 .num_resources = 3,
71 .resource = (struct resource[]) {
72 {
73 .name = "regs",
74 .start = 0xa00,
75 .end = 0xa18,
76 .flags = IORESOURCE_MEM,
77 },
78 {
79 .name = "pram",
80 .start = 0x3c00,
81 .end = 0x3c7f,
82 .flags = IORESOURCE_MEM,
83 },
84 {
85 .name = "interrupt",
86 .start = MPC8xx_INT_SCC1,
87 .end = MPC8xx_INT_SCC1,
88 .flags = IORESOURCE_IRQ,
89 },
90 },
91 },
92 [MPC8xx_CPM_SCC2] = {
93 .name = "fsl-cpm-scc",
94 .id = 2,
95 .num_resources = 3,
96 .resource = (struct resource[]) {
97 {
98 .name = "regs",
99 .start = 0xa20,
100 .end = 0xa38,
101 .flags = IORESOURCE_MEM,
102 },
103 {
104 .name = "pram",
105 .start = 0x3d00,
106 .end = 0x3d7f,
107 .flags = IORESOURCE_MEM,
108 },
109
110 {
111 .name = "interrupt",
112 .start = MPC8xx_INT_SCC2,
113 .end = MPC8xx_INT_SCC2,
114 .flags = IORESOURCE_IRQ,
115 },
116 },
117 },
118 [MPC8xx_CPM_SCC3] = {
119 .name = "fsl-cpm-scc",
120 .id = 3,
121 .num_resources = 3,
122 .resource = (struct resource[]) {
123 {
124 .name = "regs",
125 .start = 0xa40,
126 .end = 0xa58,
127 .flags = IORESOURCE_MEM,
128 },
129 {
130 .name = "pram",
131 .start = 0x3e00,
132 .end = 0x3e7f,
133 .flags = IORESOURCE_MEM,
134 },
135
136 {
137 .name = "interrupt",
138 .start = MPC8xx_INT_SCC3,
139 .end = MPC8xx_INT_SCC3,
140 .flags = IORESOURCE_IRQ,
141 },
142 },
143 },
144 [MPC8xx_CPM_SCC4] = {
145 .name = "fsl-cpm-scc",
146 .id = 4,
147 .num_resources = 3,
148 .resource = (struct resource[]) {
149 {
150 .name = "regs",
151 .start = 0xa60,
152 .end = 0xa78,
153 .flags = IORESOURCE_MEM,
154 },
155 {
156 .name = "pram",
157 .start = 0x3f00,
158 .end = 0x3f7f,
159 .flags = IORESOURCE_MEM,
160 },
161
162 {
163 .name = "interrupt",
164 .start = MPC8xx_INT_SCC4,
165 .end = MPC8xx_INT_SCC4,
166 .flags = IORESOURCE_IRQ,
167 },
168 },
169 },
170 [MPC8xx_CPM_SMC1] = {
171 .name = "fsl-cpm-smc",
172 .id = 1,
173 .num_resources = 3,
174 .resource = (struct resource[]) {
175 {
176 .name = "regs",
177 .start = 0xa80,
178 .end = 0xa8f,
179 .flags = IORESOURCE_MEM,
180 },
181 {
182 .name = "pram",
183 .start = 0x3e80,
184 .end = 0x3ebf,
185 .flags = IORESOURCE_MEM,
186 },
187 {
188 .name = "interrupt",
189 .start = MPC8xx_INT_SMC1,
190 .end = MPC8xx_INT_SMC1,
191 .flags = IORESOURCE_IRQ,
192 },
193 },
194 },
195 [MPC8xx_CPM_SMC2] = {
196 .name = "fsl-cpm-smc",
197 .id = 2,
198 .num_resources = 3,
199 .resource = (struct resource[]) {
200 {
201 .name = "regs",
202 .start = 0xa90,
203 .end = 0xa9f,
204 .flags = IORESOURCE_MEM,
205 },
206 {
207 .name = "pram",
208 .start = 0x3f80,
209 .end = 0x3fbf,
210 .flags = IORESOURCE_MEM,
211
212 },
213 {
214 .name = "interrupt",
215 .start = MPC8xx_INT_SMC2,
216 .end = MPC8xx_INT_SMC2,
217 .flags = IORESOURCE_IRQ,
218 },
219 },
220 },
221
222 [MPC8xx_MDIO_FEC] = {
223 .name = "fsl-cpm-fec-mdio",
224 .id = 0,
225 .num_resources = 0,
226
227 },
228
229};
230
231static int __init mach_mpc8xx_fixup(struct platform_device *pdev)
232{
233 ppc_sys_fixup_mem_resource (pdev, IMAP_ADDR);
234 return 0;
235}
236
237static int __init mach_mpc8xx_init(void)
238{
239 ppc_sys_device_fixup = mach_mpc8xx_fixup;
240 return 0;
241}
242
243postcore_initcall(mach_mpc8xx_init);
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
deleted file mode 100644
index 18ba1d7ff9f1..000000000000
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 * MPC8xx System descriptions
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
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#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <asm/ppc_sys.h>
18
19struct ppc_sys_spec *cur_ppc_sys_spec;
20struct ppc_sys_spec ppc_sys_specs[] = {
21 {
22 .ppc_sys_name = "MPC86X",
23 .mask = 0xFFFFFFFF,
24 .value = 0x00000000,
25 .num_devices = 8,
26 .device_list = (enum ppc_sys_devices[])
27 {
28 MPC8xx_CPM_FEC1,
29 MPC8xx_CPM_SCC1,
30 MPC8xx_CPM_SCC2,
31 MPC8xx_CPM_SCC3,
32 MPC8xx_CPM_SCC4,
33 MPC8xx_CPM_SMC1,
34 MPC8xx_CPM_SMC2,
35 MPC8xx_MDIO_FEC,
36 },
37 },
38 {
39 .ppc_sys_name = "MPC885",
40 .mask = 0xFFFFFFFF,
41 .value = 0x00000000,
42 .num_devices = 9,
43 .device_list = (enum ppc_sys_devices[])
44 {
45 MPC8xx_CPM_FEC1,
46 MPC8xx_CPM_FEC2,
47 MPC8xx_CPM_SCC1,
48 MPC8xx_CPM_SCC2,
49 MPC8xx_CPM_SCC3,
50 MPC8xx_CPM_SCC4,
51 MPC8xx_CPM_SMC1,
52 MPC8xx_CPM_SMC2,
53 MPC8xx_MDIO_FEC,
54 },
55 },
56 { /* default match */
57 .ppc_sys_name = "",
58 .mask = 0x00000000,
59 .value = 0x00000000,
60 },
61};
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
deleted file mode 100644
index 2dd2dc5cd404..000000000000
--- a/arch/ppc/syslib/mv64360_pic.c
+++ /dev/null
@@ -1,423 +0,0 @@
1/*
2 * Interrupt controller support for Marvell's MV64360.
3 *
4 * Author: Rabeeh Khoury <rabeeh@galileo.co.il>
5 * Based on MV64360 PIC written by
6 * Chris Zankel <chris@mvista.com>
7 * Mark A. Greer <mgreer@mvista.com>
8 *
9 * Copyright 2004 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 * This file contains the specific functions to support the MV64360
19 * interrupt controller.
20 *
21 * The MV64360 has two main interrupt registers (high and low) that
22 * summarizes the interrupts generated by the units of the MV64360.
23 * Each bit is assigned to an interrupt number, where the low register
24 * are assigned from IRQ0 to IRQ31 and the high cause register
25 * from IRQ32 to IRQ63
26 * The GPP (General Purpose Pins) interrupts are assigned from IRQ64 (GPP0)
27 * to IRQ95 (GPP31).
28 * get_irq() returns the lowest interrupt number that is currently asserted.
29 *
30 * Note:
31 * - This driver does not initialize the GPP when used as an interrupt
32 * input.
33 */
34
35#include <linux/stddef.h>
36#include <linux/init.h>
37#include <linux/sched.h>
38#include <linux/signal.h>
39#include <linux/delay.h>
40#include <linux/irq.h>
41#include <linux/interrupt.h>
42
43#include <asm/io.h>
44#include <asm/processor.h>
45#include <asm/system.h>
46#include <asm/irq.h>
47#include <asm/mv64x60.h>
48#include <asm/machdep.h>
49
50#ifdef CONFIG_IRQ_ALL_CPUS
51#error "The mv64360 does not support distribution of IRQs on all CPUs"
52#endif
53/* ========================== forward declaration ========================== */
54
55static void mv64360_unmask_irq(unsigned int);
56static void mv64360_mask_irq(unsigned int);
57static irqreturn_t mv64360_cpu_error_int_handler(int, void *);
58static irqreturn_t mv64360_sram_error_int_handler(int, void *);
59static irqreturn_t mv64360_pci_error_int_handler(int, void *);
60
61/* ========================== local declarations =========================== */
62
63struct hw_interrupt_type mv64360_pic = {
64 .typename = " mv64360 ",
65 .enable = mv64360_unmask_irq,
66 .disable = mv64360_mask_irq,
67 .ack = mv64360_mask_irq,
68 .end = mv64360_unmask_irq,
69};
70
71#define CPU_INTR_STR "mv64360 cpu interface error"
72#define SRAM_INTR_STR "mv64360 internal sram error"
73#define PCI0_INTR_STR "mv64360 pci 0 error"
74#define PCI1_INTR_STR "mv64360 pci 1 error"
75
76static struct mv64x60_handle bh;
77
78u32 mv64360_irq_base = 0; /* MV64360 handles the next 96 IRQs from here */
79
80/* mv64360_init_irq()
81 *
82 * This function initializes the interrupt controller. It assigns
83 * all interrupts from IRQ0 to IRQ95 to the mv64360 interrupt controller.
84 *
85 * Input Variable(s):
86 * None.
87 *
88 * Outpu. Variable(s):
89 * None.
90 *
91 * Returns:
92 * void
93 *
94 * Note:
95 * We register all GPP inputs as interrupt source, but disable them.
96 */
97void __init
98mv64360_init_irq(void)
99{
100 int i;
101
102 if (ppc_md.progress)
103 ppc_md.progress("mv64360_init_irq: enter", 0x0);
104
105 bh.v_base = mv64x60_get_bridge_vbase();
106
107 ppc_cached_irq_mask[0] = 0;
108 ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */
109 ppc_cached_irq_mask[2] = 0;
110
111 /* disable all interrupts and clear current interrupts */
112 mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, 0);
113 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK, ppc_cached_irq_mask[2]);
114 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,ppc_cached_irq_mask[0]);
115 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,ppc_cached_irq_mask[1]);
116
117 /* All interrupts are level interrupts */
118 for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) {
119 irq_desc[i].status |= IRQ_LEVEL;
120 irq_desc[i].chip = &mv64360_pic;
121 }
122
123 if (ppc_md.progress)
124 ppc_md.progress("mv64360_init_irq: exit", 0x0);
125}
126
127/* mv64360_get_irq()
128 *
129 * This function returns the lowest interrupt number of all interrupts that
130 * are currently asserted.
131 *
132 * Output Variable(s):
133 * None.
134 *
135 * Returns:
136 * int <interrupt number> or -2 (bogus interrupt)
137 *
138 */
139int
140mv64360_get_irq(void)
141{
142 int irq;
143 int irq_gpp;
144
145#ifdef CONFIG_SMP
146 /*
147 * Second CPU gets only doorbell (message) interrupts.
148 * The doorbell interrupt is BIT28 in the main interrupt low cause reg.
149 */
150 int cpu_nr = smp_processor_id();
151 if (cpu_nr == 1) {
152 if (!(mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO) &
153 (1 << MV64x60_IRQ_DOORBELL)))
154 return -1;
155 return mv64360_irq_base + MV64x60_IRQ_DOORBELL;
156 }
157#endif
158
159 irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_LO);
160 irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]);
161
162 if (irq == -1) {
163 irq = mv64x60_read(&bh, MV64360_IC_MAIN_CAUSE_HI);
164 irq = __ilog2((irq & 0x1f0003f7) & ppc_cached_irq_mask[1]);
165
166 if (irq == -1)
167 irq = -2; /* bogus interrupt, should never happen */
168 else {
169 if ((irq >= 24) && (irq < MV64x60_IRQ_DOORBELL)) {
170 irq_gpp = mv64x60_read(&bh,
171 MV64x60_GPP_INTR_CAUSE);
172 irq_gpp = __ilog2(irq_gpp &
173 ppc_cached_irq_mask[2]);
174
175 if (irq_gpp == -1)
176 irq = -2;
177 else {
178 irq = irq_gpp + 64;
179 mv64x60_write(&bh,
180 MV64x60_GPP_INTR_CAUSE,
181 ~(1 << (irq - 64)));
182 }
183 }
184 else
185 irq += 32;
186 }
187 }
188
189 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
190
191 if (irq < 0)
192 return (irq);
193 else
194 return (mv64360_irq_base + irq);
195}
196
197/* mv64360_unmask_irq()
198 *
199 * This function enables an interrupt.
200 *
201 * Input Variable(s):
202 * unsigned int interrupt number (IRQ0...IRQ95).
203 *
204 * Output Variable(s):
205 * None.
206 *
207 * Returns:
208 * void
209 */
210static void
211mv64360_unmask_irq(unsigned int irq)
212{
213#ifdef CONFIG_SMP
214 /* second CPU gets only doorbell interrupts */
215 if ((irq - mv64360_irq_base) == MV64x60_IRQ_DOORBELL) {
216 mv64x60_set_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO,
217 (1 << MV64x60_IRQ_DOORBELL));
218 return;
219 }
220#endif
221 irq -= mv64360_irq_base;
222
223 if (irq > 31) {
224 if (irq > 63) /* unmask GPP irq */
225 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
226 ppc_cached_irq_mask[2] |= (1 << (irq - 64)));
227 else /* mask high interrupt register */
228 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
229 ppc_cached_irq_mask[1] |= (1 << (irq - 32)));
230 }
231 else /* mask low interrupt register */
232 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
233 ppc_cached_irq_mask[0] |= (1 << irq));
234
235 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
236 return;
237}
238
239/* mv64360_mask_irq()
240 *
241 * This function disables the requested interrupt.
242 *
243 * Input Variable(s):
244 * unsigned int interrupt number (IRQ0...IRQ95).
245 *
246 * Output Variable(s):
247 * None.
248 *
249 * Returns:
250 * void
251 */
252static void
253mv64360_mask_irq(unsigned int irq)
254{
255#ifdef CONFIG_SMP
256 if ((irq - mv64360_irq_base) == MV64x60_IRQ_DOORBELL) {
257 mv64x60_clr_bits(&bh, MV64360_IC_CPU1_INTR_MASK_LO,
258 (1 << MV64x60_IRQ_DOORBELL));
259 return;
260 }
261#endif
262 irq -= mv64360_irq_base;
263
264 if (irq > 31) {
265 if (irq > 63) /* mask GPP irq */
266 mv64x60_write(&bh, MV64x60_GPP_INTR_MASK,
267 ppc_cached_irq_mask[2] &= ~(1 << (irq - 64)));
268 else /* mask high interrupt register */
269 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_HI,
270 ppc_cached_irq_mask[1] &= ~(1 << (irq - 32)));
271 }
272 else /* mask low interrupt register */
273 mv64x60_write(&bh, MV64360_IC_CPU0_INTR_MASK_LO,
274 ppc_cached_irq_mask[0] &= ~(1 << irq));
275
276 (void)mv64x60_read(&bh, MV64x60_GPP_INTR_MASK);
277 return;
278}
279
280static irqreturn_t
281mv64360_cpu_error_int_handler(int irq, void *dev_id)
282{
283 printk(KERN_ERR "mv64360_cpu_error_int_handler: %s 0x%08x\n",
284 "Error on CPU interface - Cause regiser",
285 mv64x60_read(&bh, MV64x60_CPU_ERR_CAUSE));
286 printk(KERN_ERR "\tCPU error register dump:\n");
287 printk(KERN_ERR "\tAddress low 0x%08x\n",
288 mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_LO));
289 printk(KERN_ERR "\tAddress high 0x%08x\n",
290 mv64x60_read(&bh, MV64x60_CPU_ERR_ADDR_HI));
291 printk(KERN_ERR "\tData low 0x%08x\n",
292 mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_LO));
293 printk(KERN_ERR "\tData high 0x%08x\n",
294 mv64x60_read(&bh, MV64x60_CPU_ERR_DATA_HI));
295 printk(KERN_ERR "\tParity 0x%08x\n",
296 mv64x60_read(&bh, MV64x60_CPU_ERR_PARITY));
297 mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
298 return IRQ_HANDLED;
299}
300
301static irqreturn_t
302mv64360_sram_error_int_handler(int irq, void *dev_id)
303{
304 printk(KERN_ERR "mv64360_sram_error_int_handler: %s 0x%08x\n",
305 "Error in internal SRAM - Cause register",
306 mv64x60_read(&bh, MV64360_SRAM_ERR_CAUSE));
307 printk(KERN_ERR "\tSRAM error register dump:\n");
308 printk(KERN_ERR "\tAddress Low 0x%08x\n",
309 mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_LO));
310 printk(KERN_ERR "\tAddress High 0x%08x\n",
311 mv64x60_read(&bh, MV64360_SRAM_ERR_ADDR_HI));
312 printk(KERN_ERR "\tData Low 0x%08x\n",
313 mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_LO));
314 printk(KERN_ERR "\tData High 0x%08x\n",
315 mv64x60_read(&bh, MV64360_SRAM_ERR_DATA_HI));
316 printk(KERN_ERR "\tParity 0x%08x\n",
317 mv64x60_read(&bh, MV64360_SRAM_ERR_PARITY));
318 mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
319 return IRQ_HANDLED;
320}
321
322static irqreturn_t
323mv64360_pci_error_int_handler(int irq, void *dev_id)
324{
325 u32 val;
326 unsigned int pci_bus = (unsigned int)dev_id;
327
328 if (pci_bus == 0) { /* Error on PCI 0 */
329 val = mv64x60_read(&bh, MV64x60_PCI0_ERR_CAUSE);
330 printk(KERN_ERR "%s: Error in PCI %d Interface\n",
331 "mv64360_pci_error_int_handler", pci_bus);
332 printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
333 printk(KERN_ERR "\tCause register 0x%08x\n", val);
334 printk(KERN_ERR "\tAddress Low 0x%08x\n",
335 mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_LO));
336 printk(KERN_ERR "\tAddress High 0x%08x\n",
337 mv64x60_read(&bh, MV64x60_PCI0_ERR_ADDR_HI));
338 printk(KERN_ERR "\tAttribute 0x%08x\n",
339 mv64x60_read(&bh, MV64x60_PCI0_ERR_DATA_LO));
340 printk(KERN_ERR "\tCommand 0x%08x\n",
341 mv64x60_read(&bh, MV64x60_PCI0_ERR_CMD));
342 mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, ~val);
343 }
344 if (pci_bus == 1) { /* Error on PCI 1 */
345 val = mv64x60_read(&bh, MV64x60_PCI1_ERR_CAUSE);
346 printk(KERN_ERR "%s: Error in PCI %d Interface\n",
347 "mv64360_pci_error_int_handler", pci_bus);
348 printk(KERN_ERR "\tPCI %d error register dump:\n", pci_bus);
349 printk(KERN_ERR "\tCause register 0x%08x\n", val);
350 printk(KERN_ERR "\tAddress Low 0x%08x\n",
351 mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_LO));
352 printk(KERN_ERR "\tAddress High 0x%08x\n",
353 mv64x60_read(&bh, MV64x60_PCI1_ERR_ADDR_HI));
354 printk(KERN_ERR "\tAttribute 0x%08x\n",
355 mv64x60_read(&bh, MV64x60_PCI1_ERR_DATA_LO));
356 printk(KERN_ERR "\tCommand 0x%08x\n",
357 mv64x60_read(&bh, MV64x60_PCI1_ERR_CMD));
358 mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, ~val);
359 }
360 return IRQ_HANDLED;
361}
362
363/*
364 * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
365 * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
366 * well. IOW, don't set bit 0.
367 */
368#define MV64360_PCI0_ERR_MASK_VAL 0x00a50c24
369
370static int __init
371mv64360_register_hdlrs(void)
372{
373 int rc;
374
375 /* Clear old errors and register CPU interface error intr handler */
376 mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
377 if ((rc = request_irq(MV64x60_IRQ_CPU_ERR + mv64360_irq_base,
378 mv64360_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, NULL)))
379 printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
380
381 mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
382 mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0x000000ff);
383
384 /* Clear old errors and register internal SRAM error intr handler */
385 mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
386 if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR + mv64360_irq_base,
387 mv64360_sram_error_int_handler,IRQF_DISABLED,SRAM_INTR_STR, NULL)))
388 printk(KERN_WARNING "Can't register SRAM error handler: %d",rc);
389
390 /* Clear old errors and register PCI 0 error intr handler */
391 mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, 0);
392 if ((rc = request_irq(MV64360_IRQ_PCI0 + mv64360_irq_base,
393 mv64360_pci_error_int_handler,
394 IRQF_DISABLED, PCI0_INTR_STR, (void *)0)))
395 printk(KERN_WARNING "Can't register pci 0 error handler: %d",
396 rc);
397
398 mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0);
399 mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL);
400
401 /* Erratum FEr PCI-#16 says to clear bit 0 of PCI SERRn Mask reg. */
402 mv64x60_write(&bh, MV64x60_PCI0_ERR_SERR_MASK,
403 mv64x60_read(&bh, MV64x60_PCI0_ERR_SERR_MASK) & ~0x1UL);
404
405 /* Clear old errors and register PCI 1 error intr handler */
406 mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, 0);
407 if ((rc = request_irq(MV64360_IRQ_PCI1 + mv64360_irq_base,
408 mv64360_pci_error_int_handler,
409 IRQF_DISABLED, PCI1_INTR_STR, (void *)1)))
410 printk(KERN_WARNING "Can't register pci 1 error handler: %d",
411 rc);
412
413 mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0);
414 mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL);
415
416 /* Erratum FEr PCI-#16 says to clear bit 0 of PCI Intr Mask reg. */
417 mv64x60_write(&bh, MV64x60_PCI1_ERR_SERR_MASK,
418 mv64x60_read(&bh, MV64x60_PCI1_ERR_SERR_MASK) & ~0x1UL);
419
420 return 0;
421}
422
423arch_initcall(mv64360_register_hdlrs);
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
deleted file mode 100644
index 418f3053de52..000000000000
--- a/arch/ppc/syslib/mv64x60.c
+++ /dev/null
@@ -1,2485 +0,0 @@
1/*
2 * Common routines for the Marvell/Galileo Discovery line of host bridges
3 * (gt64260, mv64360, mv64460, ...).
4 *
5 * Author: Mark A. Greer <mgreer@mvista.com>
6 *
7 * 2004 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <linux/slab.h>
16#include <linux/module.h>
17#include <linux/mutex.h>
18#include <linux/string.h>
19#include <linux/spinlock.h>
20#include <linux/mv643xx.h>
21#include <linux/platform_device.h>
22
23#include <asm/byteorder.h>
24#include <asm/io.h>
25#include <asm/irq.h>
26#include <asm/uaccess.h>
27#include <asm/machdep.h>
28#include <asm/pci-bridge.h>
29#include <asm/delay.h>
30#include <asm/mv64x60.h>
31
32
33u8 mv64x60_pci_exclude_bridge = 1;
34DEFINE_SPINLOCK(mv64x60_lock);
35
36static phys_addr_t mv64x60_bridge_pbase;
37static void __iomem *mv64x60_bridge_vbase;
38static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID;
39static u32 mv64x60_bridge_rev;
40#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
41static struct pci_controller sysfs_hose_a;
42#endif
43
44static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits);
45static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits);
46static void gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus,
47 u32 window, u32 base);
48static void gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
49 struct pci_controller *hose, u32 bus, u32 base);
50static u32 gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
51static void gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
52static void gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
53static void gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
54static void gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
55static void gt64260_disable_all_windows(struct mv64x60_handle *bh,
56 struct mv64x60_setup_info *si);
57static void gt64260a_chip_specific_init(struct mv64x60_handle *bh,
58 struct mv64x60_setup_info *si);
59static void gt64260b_chip_specific_init(struct mv64x60_handle *bh,
60 struct mv64x60_setup_info *si);
61
62static u32 mv64360_translate_size(u32 base, u32 size, u32 num_bits);
63static u32 mv64360_untranslate_size(u32 base, u32 size, u32 num_bits);
64static void mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus,
65 u32 window, u32 base);
66static void mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
67 struct pci_controller *hose, u32 bus, u32 base);
68static u32 mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window);
69static void mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window);
70static void mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window);
71static void mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window);
72static void mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window);
73static void mv64360_disable_all_windows(struct mv64x60_handle *bh,
74 struct mv64x60_setup_info *si);
75static void mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
76 struct mv64x60_setup_info *si,
77 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]);
78static void mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base);
79static void mv64360_chip_specific_init(struct mv64x60_handle *bh,
80 struct mv64x60_setup_info *si);
81static void mv64460_chip_specific_init(struct mv64x60_handle *bh,
82 struct mv64x60_setup_info *si);
83
84
85/*
86 * Define tables that have the chip-specific info for each type of
87 * Marvell bridge chip.
88 */
89static struct mv64x60_chip_info gt64260a_ci __initdata = { /* GT64260A */
90 .translate_size = gt64260_translate_size,
91 .untranslate_size = gt64260_untranslate_size,
92 .set_pci2mem_window = gt64260_set_pci2mem_window,
93 .set_pci2regs_window = gt64260_set_pci2regs_window,
94 .is_enabled_32bit = gt64260_is_enabled_32bit,
95 .enable_window_32bit = gt64260_enable_window_32bit,
96 .disable_window_32bit = gt64260_disable_window_32bit,
97 .enable_window_64bit = gt64260_enable_window_64bit,
98 .disable_window_64bit = gt64260_disable_window_64bit,
99 .disable_all_windows = gt64260_disable_all_windows,
100 .chip_specific_init = gt64260a_chip_specific_init,
101 .window_tab_32bit = gt64260_32bit_windows,
102 .window_tab_64bit = gt64260_64bit_windows,
103};
104
105static struct mv64x60_chip_info gt64260b_ci __initdata = { /* GT64260B */
106 .translate_size = gt64260_translate_size,
107 .untranslate_size = gt64260_untranslate_size,
108 .set_pci2mem_window = gt64260_set_pci2mem_window,
109 .set_pci2regs_window = gt64260_set_pci2regs_window,
110 .is_enabled_32bit = gt64260_is_enabled_32bit,
111 .enable_window_32bit = gt64260_enable_window_32bit,
112 .disable_window_32bit = gt64260_disable_window_32bit,
113 .enable_window_64bit = gt64260_enable_window_64bit,
114 .disable_window_64bit = gt64260_disable_window_64bit,
115 .disable_all_windows = gt64260_disable_all_windows,
116 .chip_specific_init = gt64260b_chip_specific_init,
117 .window_tab_32bit = gt64260_32bit_windows,
118 .window_tab_64bit = gt64260_64bit_windows,
119};
120
121static struct mv64x60_chip_info mv64360_ci __initdata = { /* MV64360 */
122 .translate_size = mv64360_translate_size,
123 .untranslate_size = mv64360_untranslate_size,
124 .set_pci2mem_window = mv64360_set_pci2mem_window,
125 .set_pci2regs_window = mv64360_set_pci2regs_window,
126 .is_enabled_32bit = mv64360_is_enabled_32bit,
127 .enable_window_32bit = mv64360_enable_window_32bit,
128 .disable_window_32bit = mv64360_disable_window_32bit,
129 .enable_window_64bit = mv64360_enable_window_64bit,
130 .disable_window_64bit = mv64360_disable_window_64bit,
131 .disable_all_windows = mv64360_disable_all_windows,
132 .config_io2mem_windows = mv64360_config_io2mem_windows,
133 .set_mpsc2regs_window = mv64360_set_mpsc2regs_window,
134 .chip_specific_init = mv64360_chip_specific_init,
135 .window_tab_32bit = mv64360_32bit_windows,
136 .window_tab_64bit = mv64360_64bit_windows,
137};
138
139static struct mv64x60_chip_info mv64460_ci __initdata = { /* MV64460 */
140 .translate_size = mv64360_translate_size,
141 .untranslate_size = mv64360_untranslate_size,
142 .set_pci2mem_window = mv64360_set_pci2mem_window,
143 .set_pci2regs_window = mv64360_set_pci2regs_window,
144 .is_enabled_32bit = mv64360_is_enabled_32bit,
145 .enable_window_32bit = mv64360_enable_window_32bit,
146 .disable_window_32bit = mv64360_disable_window_32bit,
147 .enable_window_64bit = mv64360_enable_window_64bit,
148 .disable_window_64bit = mv64360_disable_window_64bit,
149 .disable_all_windows = mv64360_disable_all_windows,
150 .config_io2mem_windows = mv64360_config_io2mem_windows,
151 .set_mpsc2regs_window = mv64360_set_mpsc2regs_window,
152 .chip_specific_init = mv64460_chip_specific_init,
153 .window_tab_32bit = mv64360_32bit_windows,
154 .window_tab_64bit = mv64360_64bit_windows,
155};
156
157/*
158 *****************************************************************************
159 *
160 * Platform Device Definitions
161 *
162 *****************************************************************************
163 */
164#ifdef CONFIG_SERIAL_MPSC
165static struct mpsc_shared_pdata mv64x60_mpsc_shared_pdata = {
166 .mrr_val = 0x3ffffe38,
167 .rcrr_val = 0,
168 .tcrr_val = 0,
169 .intr_cause_val = 0,
170 .intr_mask_val = 0,
171};
172
173static struct resource mv64x60_mpsc_shared_resources[] = {
174 /* Do not change the order of the IORESOURCE_MEM resources */
175 [0] = {
176 .name = "mpsc routing base",
177 .start = MV64x60_MPSC_ROUTING_OFFSET,
178 .end = MV64x60_MPSC_ROUTING_OFFSET +
179 MPSC_ROUTING_REG_BLOCK_SIZE - 1,
180 .flags = IORESOURCE_MEM,
181 },
182 [1] = {
183 .name = "sdma intr base",
184 .start = MV64x60_SDMA_INTR_OFFSET,
185 .end = MV64x60_SDMA_INTR_OFFSET +
186 MPSC_SDMA_INTR_REG_BLOCK_SIZE - 1,
187 .flags = IORESOURCE_MEM,
188 },
189};
190
191static struct platform_device mpsc_shared_device = { /* Shared device */
192 .name = MPSC_SHARED_NAME,
193 .id = 0,
194 .num_resources = ARRAY_SIZE(mv64x60_mpsc_shared_resources),
195 .resource = mv64x60_mpsc_shared_resources,
196 .dev = {
197 .platform_data = &mv64x60_mpsc_shared_pdata,
198 },
199};
200
201static struct mpsc_pdata mv64x60_mpsc0_pdata = {
202 .mirror_regs = 0,
203 .cache_mgmt = 0,
204 .max_idle = 0,
205 .default_baud = 9600,
206 .default_bits = 8,
207 .default_parity = 'n',
208 .default_flow = 'n',
209 .chr_1_val = 0x00000000,
210 .chr_2_val = 0x00000000,
211 .chr_10_val = 0x00000003,
212 .mpcr_val = 0,
213 .bcr_val = 0,
214 .brg_can_tune = 0,
215 .brg_clk_src = 8, /* Default to TCLK */
216 .brg_clk_freq = 100000000, /* Default to 100 MHz */
217};
218
219static struct resource mv64x60_mpsc0_resources[] = {
220 /* Do not change the order of the IORESOURCE_MEM resources */
221 [0] = {
222 .name = "mpsc 0 base",
223 .start = MV64x60_MPSC_0_OFFSET,
224 .end = MV64x60_MPSC_0_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
225 .flags = IORESOURCE_MEM,
226 },
227 [1] = {
228 .name = "sdma 0 base",
229 .start = MV64x60_SDMA_0_OFFSET,
230 .end = MV64x60_SDMA_0_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
231 .flags = IORESOURCE_MEM,
232 },
233 [2] = {
234 .name = "brg 0 base",
235 .start = MV64x60_BRG_0_OFFSET,
236 .end = MV64x60_BRG_0_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
237 .flags = IORESOURCE_MEM,
238 },
239 [3] = {
240 .name = "sdma 0 irq",
241 .start = MV64x60_IRQ_SDMA_0,
242 .end = MV64x60_IRQ_SDMA_0,
243 .flags = IORESOURCE_IRQ,
244 },
245};
246
247static struct platform_device mpsc0_device = {
248 .name = MPSC_CTLR_NAME,
249 .id = 0,
250 .num_resources = ARRAY_SIZE(mv64x60_mpsc0_resources),
251 .resource = mv64x60_mpsc0_resources,
252 .dev = {
253 .platform_data = &mv64x60_mpsc0_pdata,
254 },
255};
256
257static struct mpsc_pdata mv64x60_mpsc1_pdata = {
258 .mirror_regs = 0,
259 .cache_mgmt = 0,
260 .max_idle = 0,
261 .default_baud = 9600,
262 .default_bits = 8,
263 .default_parity = 'n',
264 .default_flow = 'n',
265 .chr_1_val = 0x00000000,
266 .chr_1_val = 0x00000000,
267 .chr_2_val = 0x00000000,
268 .chr_10_val = 0x00000003,
269 .mpcr_val = 0,
270 .bcr_val = 0,
271 .brg_can_tune = 0,
272 .brg_clk_src = 8, /* Default to TCLK */
273 .brg_clk_freq = 100000000, /* Default to 100 MHz */
274};
275
276static struct resource mv64x60_mpsc1_resources[] = {
277 /* Do not change the order of the IORESOURCE_MEM resources */
278 [0] = {
279 .name = "mpsc 1 base",
280 .start = MV64x60_MPSC_1_OFFSET,
281 .end = MV64x60_MPSC_1_OFFSET + MPSC_REG_BLOCK_SIZE - 1,
282 .flags = IORESOURCE_MEM,
283 },
284 [1] = {
285 .name = "sdma 1 base",
286 .start = MV64x60_SDMA_1_OFFSET,
287 .end = MV64x60_SDMA_1_OFFSET + MPSC_SDMA_REG_BLOCK_SIZE - 1,
288 .flags = IORESOURCE_MEM,
289 },
290 [2] = {
291 .name = "brg 1 base",
292 .start = MV64x60_BRG_1_OFFSET,
293 .end = MV64x60_BRG_1_OFFSET + MPSC_BRG_REG_BLOCK_SIZE - 1,
294 .flags = IORESOURCE_MEM,
295 },
296 [3] = {
297 .name = "sdma 1 irq",
298 .start = MV64360_IRQ_SDMA_1,
299 .end = MV64360_IRQ_SDMA_1,
300 .flags = IORESOURCE_IRQ,
301 },
302};
303
304static struct platform_device mpsc1_device = {
305 .name = MPSC_CTLR_NAME,
306 .id = 1,
307 .num_resources = ARRAY_SIZE(mv64x60_mpsc1_resources),
308 .resource = mv64x60_mpsc1_resources,
309 .dev = {
310 .platform_data = &mv64x60_mpsc1_pdata,
311 },
312};
313#endif
314
315#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
316static struct resource mv64x60_eth_shared_resources[] = {
317 [0] = {
318 .name = "ethernet shared base",
319 .start = MV643XX_ETH_SHARED_REGS,
320 .end = MV643XX_ETH_SHARED_REGS +
321 MV643XX_ETH_SHARED_REGS_SIZE - 1,
322 .flags = IORESOURCE_MEM,
323 },
324};
325
326static struct platform_device mv64x60_eth_shared_device = {
327 .name = MV643XX_ETH_SHARED_NAME,
328 .id = 0,
329 .num_resources = ARRAY_SIZE(mv64x60_eth_shared_resources),
330 .resource = mv64x60_eth_shared_resources,
331};
332
333#ifdef CONFIG_MV643XX_ETH_0
334static struct resource mv64x60_eth0_resources[] = {
335 [0] = {
336 .name = "eth0 irq",
337 .start = MV64x60_IRQ_ETH_0,
338 .end = MV64x60_IRQ_ETH_0,
339 .flags = IORESOURCE_IRQ,
340 },
341};
342
343static struct mv643xx_eth_platform_data eth0_pd = {
344 .shared = &mv64x60_eth_shared_device;
345 .port_number = 0,
346};
347
348static struct platform_device eth0_device = {
349 .name = MV643XX_ETH_NAME,
350 .id = 0,
351 .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
352 .resource = mv64x60_eth0_resources,
353 .dev = {
354 .platform_data = &eth0_pd,
355 },
356};
357#endif
358
359#ifdef CONFIG_MV643XX_ETH_1
360static struct resource mv64x60_eth1_resources[] = {
361 [0] = {
362 .name = "eth1 irq",
363 .start = MV64x60_IRQ_ETH_1,
364 .end = MV64x60_IRQ_ETH_1,
365 .flags = IORESOURCE_IRQ,
366 },
367};
368
369static struct mv643xx_eth_platform_data eth1_pd = {
370 .shared = &mv64x60_eth_shared_device;
371 .port_number = 1,
372};
373
374static struct platform_device eth1_device = {
375 .name = MV643XX_ETH_NAME,
376 .id = 1,
377 .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
378 .resource = mv64x60_eth1_resources,
379 .dev = {
380 .platform_data = &eth1_pd,
381 },
382};
383#endif
384
385#ifdef CONFIG_MV643XX_ETH_2
386static struct resource mv64x60_eth2_resources[] = {
387 [0] = {
388 .name = "eth2 irq",
389 .start = MV64x60_IRQ_ETH_2,
390 .end = MV64x60_IRQ_ETH_2,
391 .flags = IORESOURCE_IRQ,
392 },
393};
394
395static struct mv643xx_eth_platform_data eth2_pd = {
396 .shared = &mv64x60_eth_shared_device;
397 .port_number = 2,
398};
399
400static struct platform_device eth2_device = {
401 .name = MV643XX_ETH_NAME,
402 .id = 2,
403 .num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
404 .resource = mv64x60_eth2_resources,
405 .dev = {
406 .platform_data = &eth2_pd,
407 },
408};
409#endif
410#endif
411
412#ifdef CONFIG_I2C_MV64XXX
413static struct mv64xxx_i2c_pdata mv64xxx_i2c_pdata = {
414 .freq_m = 8,
415 .freq_n = 3,
416 .timeout = 1000, /* Default timeout of 1 second */
417};
418
419static struct resource mv64xxx_i2c_resources[] = {
420 /* Do not change the order of the IORESOURCE_MEM resources */
421 [0] = {
422 .name = "mv64xxx i2c base",
423 .start = MV64XXX_I2C_OFFSET,
424 .end = MV64XXX_I2C_OFFSET + MV64XXX_I2C_REG_BLOCK_SIZE - 1,
425 .flags = IORESOURCE_MEM,
426 },
427 [1] = {
428 .name = "mv64xxx i2c irq",
429 .start = MV64x60_IRQ_I2C,
430 .end = MV64x60_IRQ_I2C,
431 .flags = IORESOURCE_IRQ,
432 },
433};
434
435static struct platform_device i2c_device = {
436 .name = MV64XXX_I2C_CTLR_NAME,
437 .id = 0,
438 .num_resources = ARRAY_SIZE(mv64xxx_i2c_resources),
439 .resource = mv64xxx_i2c_resources,
440 .dev = {
441 .platform_data = &mv64xxx_i2c_pdata,
442 },
443};
444#endif
445
446#ifdef CONFIG_WATCHDOG
447static struct mv64x60_wdt_pdata mv64x60_wdt_pdata = {
448 .timeout = 10, /* default watchdog expiry in seconds */
449 .bus_clk = 133, /* default bus clock in MHz */
450};
451
452static struct resource mv64x60_wdt_resources[] = {
453 [0] = {
454 .name = "mv64x60 wdt base",
455 .start = MV64x60_WDT_WDC,
456 .end = MV64x60_WDT_WDC + 8 - 1, /* two 32-bit registers */
457 .flags = IORESOURCE_MEM,
458 },
459};
460
461static struct platform_device wdt_device = {
462 .name = MV64x60_WDT_NAME,
463 .id = 0,
464 .num_resources = ARRAY_SIZE(mv64x60_wdt_resources),
465 .resource = mv64x60_wdt_resources,
466 .dev = {
467 .platform_data = &mv64x60_wdt_pdata,
468 },
469};
470#endif
471
472#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
473static struct mv64xxx_pdata mv64xxx_pdata = {
474 .hs_reg_valid = 0,
475};
476
477static struct platform_device mv64xxx_device = { /* general mv64x60 stuff */
478 .name = MV64XXX_DEV_NAME,
479 .id = 0,
480 .dev = {
481 .platform_data = &mv64xxx_pdata,
482 },
483};
484#endif
485
486static struct platform_device *mv64x60_pd_devs[] __initdata = {
487#ifdef CONFIG_SERIAL_MPSC
488 &mpsc_shared_device,
489 &mpsc0_device,
490 &mpsc1_device,
491#endif
492#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
493 &mv64x60_eth_shared_device,
494#endif
495#ifdef CONFIG_MV643XX_ETH_0
496 &eth0_device,
497#endif
498#ifdef CONFIG_MV643XX_ETH_1
499 &eth1_device,
500#endif
501#ifdef CONFIG_MV643XX_ETH_2
502 &eth2_device,
503#endif
504#ifdef CONFIG_I2C_MV64XXX
505 &i2c_device,
506#endif
507#ifdef CONFIG_MV64X60_WDT
508 &wdt_device,
509#endif
510#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
511 &mv64xxx_device,
512#endif
513};
514
515/*
516 *****************************************************************************
517 *
518 * Bridge Initialization Routines
519 *
520 *****************************************************************************
521 */
522/*
523 * mv64x60_init()
524 *
525 * Initialize the bridge based on setting passed in via 'si'. The bridge
526 * handle, 'bh', will be set so that it can be used to make subsequent
527 * calls to routines in this file.
528 */
529int __init
530mv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
531{
532 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
533
534 if (ppc_md.progress)
535 ppc_md.progress("mv64x60 initialization", 0x0);
536
537 spin_lock_init(&mv64x60_lock);
538 mv64x60_early_init(bh, si);
539
540 if (mv64x60_get_type(bh) || mv64x60_setup_for_chip(bh)) {
541 iounmap(bh->v_base);
542 bh->v_base = 0;
543 if (ppc_md.progress)
544 ppc_md.progress("mv64x60_init: Can't determine chip",0);
545 return -1;
546 }
547
548 bh->ci->disable_all_windows(bh, si);
549 mv64x60_get_mem_windows(bh, mem_windows);
550 mv64x60_config_cpu2mem_windows(bh, si, mem_windows);
551
552 if (bh->ci->config_io2mem_windows)
553 bh->ci->config_io2mem_windows(bh, si, mem_windows);
554 if (bh->ci->set_mpsc2regs_window)
555 bh->ci->set_mpsc2regs_window(bh, si->phys_reg_base);
556
557 if (si->pci_1.enable_bus) {
558 bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base,
559 si->pci_1.pci_io.size);
560 isa_io_base = bh->io_base_b;
561 }
562
563 if (si->pci_0.enable_bus) {
564 bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base,
565 si->pci_0.pci_io.size);
566 isa_io_base = bh->io_base_a;
567
568 mv64x60_alloc_hose(bh, MV64x60_PCI0_CONFIG_ADDR,
569 MV64x60_PCI0_CONFIG_DATA, &bh->hose_a);
570 mv64x60_config_resources(bh->hose_a, &si->pci_0, bh->io_base_a);
571 mv64x60_config_pci_params(bh->hose_a, &si->pci_0);
572
573 mv64x60_config_cpu2pci_windows(bh, &si->pci_0, 0);
574 mv64x60_config_pci2mem_windows(bh, bh->hose_a, &si->pci_0, 0,
575 mem_windows);
576 bh->ci->set_pci2regs_window(bh, bh->hose_a, 0,
577 si->phys_reg_base);
578 }
579
580 if (si->pci_1.enable_bus) {
581 mv64x60_alloc_hose(bh, MV64x60_PCI1_CONFIG_ADDR,
582 MV64x60_PCI1_CONFIG_DATA, &bh->hose_b);
583 mv64x60_config_resources(bh->hose_b, &si->pci_1, bh->io_base_b);
584 mv64x60_config_pci_params(bh->hose_b, &si->pci_1);
585
586 mv64x60_config_cpu2pci_windows(bh, &si->pci_1, 1);
587 mv64x60_config_pci2mem_windows(bh, bh->hose_b, &si->pci_1, 1,
588 mem_windows);
589 bh->ci->set_pci2regs_window(bh, bh->hose_b, 1,
590 si->phys_reg_base);
591 }
592
593 bh->ci->chip_specific_init(bh, si);
594 mv64x60_pd_fixup(bh, mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs));
595
596 return 0;
597}
598
599/*
600 * mv64x60_early_init()
601 *
602 * Do some bridge work that must take place before we start messing with
603 * the bridge for real.
604 */
605void __init
606mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si)
607{
608 struct pci_controller hose_a, hose_b;
609
610 memset(bh, 0, sizeof(*bh));
611
612 bh->p_base = si->phys_reg_base;
613 bh->v_base = ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE);
614
615 mv64x60_bridge_pbase = bh->p_base;
616 mv64x60_bridge_vbase = bh->v_base;
617
618 /* Assuming pci mode [reserved] bits 4:5 on 64260 are 0 */
619 bh->pci_mode_a = mv64x60_read(bh, MV64x60_PCI0_MODE) &
620 MV64x60_PCIMODE_MASK;
621 bh->pci_mode_b = mv64x60_read(bh, MV64x60_PCI1_MODE) &
622 MV64x60_PCIMODE_MASK;
623
624 /* Need temporary hose structs to call mv64x60_set_bus() */
625 memset(&hose_a, 0, sizeof(hose_a));
626 memset(&hose_b, 0, sizeof(hose_b));
627 setup_indirect_pci_nomap(&hose_a, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
628 bh->v_base + MV64x60_PCI0_CONFIG_DATA);
629 setup_indirect_pci_nomap(&hose_b, bh->v_base + MV64x60_PCI1_CONFIG_ADDR,
630 bh->v_base + MV64x60_PCI1_CONFIG_DATA);
631 bh->hose_a = &hose_a;
632 bh->hose_b = &hose_b;
633
634#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
635 /* Save a copy of hose_a for sysfs functions -- hack */
636 memcpy(&sysfs_hose_a, &hose_a, sizeof(hose_a));
637#endif
638
639 mv64x60_set_bus(bh, 0, 0);
640 mv64x60_set_bus(bh, 1, 0);
641
642 bh->hose_a = NULL;
643 bh->hose_b = NULL;
644
645 /* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */
646 mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001);
647 mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001);
648
649 /* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */
650 mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12));
651 mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27));
652
653 mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff);
654 mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff);
655}
656
657/*
658 *****************************************************************************
659 *
660 * Window Config Routines
661 *
662 *****************************************************************************
663 */
664/*
665 * mv64x60_get_32bit_window()
666 *
667 * Determine the base address and size of a 32-bit window on the bridge.
668 */
669void __init
670mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,
671 u32 *base, u32 *size)
672{
673 u32 val, base_reg, size_reg, base_bits, size_bits;
674 u32 (*get_from_field)(u32 val, u32 num_bits);
675
676 base_reg = bh->ci->window_tab_32bit[window].base_reg;
677
678 if (base_reg != 0) {
679 size_reg = bh->ci->window_tab_32bit[window].size_reg;
680 base_bits = bh->ci->window_tab_32bit[window].base_bits;
681 size_bits = bh->ci->window_tab_32bit[window].size_bits;
682 get_from_field= bh->ci->window_tab_32bit[window].get_from_field;
683
684 val = mv64x60_read(bh, base_reg);
685 *base = get_from_field(val, base_bits);
686
687 if (size_reg != 0) {
688 val = mv64x60_read(bh, size_reg);
689 val = get_from_field(val, size_bits);
690 *size = bh->ci->untranslate_size(*base, val, size_bits);
691 } else
692 *size = 0;
693 } else {
694 *base = 0;
695 *size = 0;
696 }
697
698 pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n",
699 window, *base, *size);
700}
701
702/*
703 * mv64x60_set_32bit_window()
704 *
705 * Set the base address and size of a 32-bit window on the bridge.
706 */
707void __init
708mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window,
709 u32 base, u32 size, u32 other_bits)
710{
711 u32 val, base_reg, size_reg, base_bits, size_bits;
712 u32 (*map_to_field)(u32 val, u32 num_bits);
713
714 pr_debug("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n",
715 window, base, size, other_bits);
716
717 base_reg = bh->ci->window_tab_32bit[window].base_reg;
718
719 if (base_reg != 0) {
720 size_reg = bh->ci->window_tab_32bit[window].size_reg;
721 base_bits = bh->ci->window_tab_32bit[window].base_bits;
722 size_bits = bh->ci->window_tab_32bit[window].size_bits;
723 map_to_field = bh->ci->window_tab_32bit[window].map_to_field;
724
725 val = map_to_field(base, base_bits) | other_bits;
726 mv64x60_write(bh, base_reg, val);
727
728 if (size_reg != 0) {
729 val = bh->ci->translate_size(base, size, size_bits);
730 val = map_to_field(val, size_bits);
731 mv64x60_write(bh, size_reg, val);
732 }
733
734 (void)mv64x60_read(bh, base_reg); /* Flush FIFO */
735 }
736}
737
738/*
739 * mv64x60_get_64bit_window()
740 *
741 * Determine the base address and size of a 64-bit window on the bridge.
742 */
743void __init
744mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,
745 u32 *base_hi, u32 *base_lo, u32 *size)
746{
747 u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits;
748 u32 (*get_from_field)(u32 val, u32 num_bits);
749
750 base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
751
752 if (base_lo_reg != 0) {
753 size_reg = bh->ci->window_tab_64bit[window].size_reg;
754 base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
755 size_bits = bh->ci->window_tab_64bit[window].size_bits;
756 get_from_field= bh->ci->window_tab_64bit[window].get_from_field;
757
758 *base_hi = mv64x60_read(bh,
759 bh->ci->window_tab_64bit[window].base_hi_reg);
760
761 val = mv64x60_read(bh, base_lo_reg);
762 *base_lo = get_from_field(val, base_lo_bits);
763
764 if (size_reg != 0) {
765 val = mv64x60_read(bh, size_reg);
766 val = get_from_field(val, size_bits);
767 *size = bh->ci->untranslate_size(*base_lo, val,
768 size_bits);
769 } else
770 *size = 0;
771 } else {
772 *base_hi = 0;
773 *base_lo = 0;
774 *size = 0;
775 }
776
777 pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
778 "size: 0x%x\n", window, *base_hi, *base_lo, *size);
779}
780
781/*
782 * mv64x60_set_64bit_window()
783 *
784 * Set the base address and size of a 64-bit window on the bridge.
785 */
786void __init
787mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,
788 u32 base_hi, u32 base_lo, u32 size, u32 other_bits)
789{
790 u32 val, base_lo_reg, size_reg, base_lo_bits, size_bits;
791 u32 (*map_to_field)(u32 val, u32 num_bits);
792
793 pr_debug("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "
794 "size: 0x%x, other: 0x%x\n",
795 window, base_hi, base_lo, size, other_bits);
796
797 base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;
798
799 if (base_lo_reg != 0) {
800 size_reg = bh->ci->window_tab_64bit[window].size_reg;
801 base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;
802 size_bits = bh->ci->window_tab_64bit[window].size_bits;
803 map_to_field = bh->ci->window_tab_64bit[window].map_to_field;
804
805 mv64x60_write(bh, bh->ci->window_tab_64bit[window].base_hi_reg,
806 base_hi);
807
808 val = map_to_field(base_lo, base_lo_bits) | other_bits;
809 mv64x60_write(bh, base_lo_reg, val);
810
811 if (size_reg != 0) {
812 val = bh->ci->translate_size(base_lo, size, size_bits);
813 val = map_to_field(val, size_bits);
814 mv64x60_write(bh, size_reg, val);
815 }
816
817 (void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */
818 }
819}
820
821/*
822 * mv64x60_mask()
823 *
824 * Take the high-order 'num_bits' of 'val' & mask off low bits.
825 */
826u32 __init
827mv64x60_mask(u32 val, u32 num_bits)
828{
829 return val & (0xffffffff << (32 - num_bits));
830}
831
832/*
833 * mv64x60_shift_left()
834 *
835 * Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB).
836 */
837u32 __init
838mv64x60_shift_left(u32 val, u32 num_bits)
839{
840 return val << (32 - num_bits);
841}
842
843/*
844 * mv64x60_shift_right()
845 *
846 * Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB).
847 */
848u32 __init
849mv64x60_shift_right(u32 val, u32 num_bits)
850{
851 return val >> (32 - num_bits);
852}
853
854/*
855 *****************************************************************************
856 *
857 * Chip Identification Routines
858 *
859 *****************************************************************************
860 */
861/*
862 * mv64x60_get_type()
863 *
864 * Determine the type of bridge chip we have.
865 */
866int __init
867mv64x60_get_type(struct mv64x60_handle *bh)
868{
869 struct pci_controller hose;
870 u16 val;
871 u8 save_exclude;
872
873 memset(&hose, 0, sizeof(hose));
874 setup_indirect_pci_nomap(&hose, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,
875 bh->v_base + MV64x60_PCI0_CONFIG_DATA);
876
877 save_exclude = mv64x60_pci_exclude_bridge;
878 mv64x60_pci_exclude_bridge = 0;
879 /* Sanity check of bridge's Vendor ID */
880 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val);
881
882 if (val != PCI_VENDOR_ID_MARVELL) {
883 mv64x60_pci_exclude_bridge = save_exclude;
884 return -1;
885 }
886
887 /* Get the revision of the chip */
888 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_CLASS_REVISION,
889 &val);
890 bh->rev = (u32)(val & 0xff);
891
892 /* Figure out the type of Marvell bridge it is */
893 early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_DEVICE_ID, &val);
894 mv64x60_pci_exclude_bridge = save_exclude;
895
896 switch (val) {
897 case PCI_DEVICE_ID_MARVELL_GT64260:
898 switch (bh->rev) {
899 case GT64260_REV_A:
900 bh->type = MV64x60_TYPE_GT64260A;
901 break;
902
903 default:
904 printk(KERN_WARNING "Unsupported GT64260 rev %04x\n",
905 bh->rev);
906 /* Assume its similar to a 'B' rev and fallthru */
907 case GT64260_REV_B:
908 bh->type = MV64x60_TYPE_GT64260B;
909 break;
910 }
911 break;
912
913 case PCI_DEVICE_ID_MARVELL_MV64360:
914 /* Marvell won't tell me how to distinguish a 64361 & 64362 */
915 bh->type = MV64x60_TYPE_MV64360;
916 break;
917
918 case PCI_DEVICE_ID_MARVELL_MV64460:
919 bh->type = MV64x60_TYPE_MV64460;
920 break;
921
922 default:
923 printk(KERN_ERR "Unknown Marvell bridge type %04x\n", val);
924 return -1;
925 }
926
927 /* Hang onto bridge type & rev for PIC code */
928 mv64x60_bridge_type = bh->type;
929 mv64x60_bridge_rev = bh->rev;
930
931 return 0;
932}
933
934/*
935 * mv64x60_setup_for_chip()
936 *
937 * Set 'bh' to use the proper set of routine for the bridge chip that we have.
938 */
939int __init
940mv64x60_setup_for_chip(struct mv64x60_handle *bh)
941{
942 int rc = 0;
943
944 /* Set up chip-specific info based on the chip/bridge type */
945 switch(bh->type) {
946 case MV64x60_TYPE_GT64260A:
947 bh->ci = &gt64260a_ci;
948 break;
949
950 case MV64x60_TYPE_GT64260B:
951 bh->ci = &gt64260b_ci;
952 break;
953
954 case MV64x60_TYPE_MV64360:
955 bh->ci = &mv64360_ci;
956 break;
957
958 case MV64x60_TYPE_MV64460:
959 bh->ci = &mv64460_ci;
960 break;
961
962 case MV64x60_TYPE_INVALID:
963 default:
964 if (ppc_md.progress)
965 ppc_md.progress("mv64x60: Unsupported bridge", 0x0);
966 printk(KERN_ERR "mv64x60: Unsupported bridge\n");
967 rc = -1;
968 }
969
970 return rc;
971}
972
973/*
974 * mv64x60_get_bridge_vbase()
975 *
976 * Return the virtual address of the bridge's registers.
977 */
978void __iomem *
979mv64x60_get_bridge_vbase(void)
980{
981 return mv64x60_bridge_vbase;
982}
983
984/*
985 * mv64x60_get_bridge_type()
986 *
987 * Return the type of bridge on the platform.
988 */
989u32
990mv64x60_get_bridge_type(void)
991{
992 return mv64x60_bridge_type;
993}
994
995/*
996 * mv64x60_get_bridge_rev()
997 *
998 * Return the revision of the bridge on the platform.
999 */
1000u32
1001mv64x60_get_bridge_rev(void)
1002{
1003 return mv64x60_bridge_rev;
1004}
1005
1006/*
1007 *****************************************************************************
1008 *
1009 * System Memory Window Related Routines
1010 *
1011 *****************************************************************************
1012 */
1013/*
1014 * mv64x60_get_mem_size()
1015 *
1016 * Calculate the amount of memory that the memory controller is set up for.
1017 * This should only be used by board-specific code if there is no other
1018 * way to determine the amount of memory in the system.
1019 */
1020u32 __init
1021mv64x60_get_mem_size(u32 bridge_base, u32 chip_type)
1022{
1023 struct mv64x60_handle bh;
1024 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2];
1025 u32 rc = 0;
1026
1027 memset(&bh, 0, sizeof(bh));
1028
1029 bh.type = chip_type;
1030 bh.v_base = (void *)bridge_base;
1031
1032 if (!mv64x60_setup_for_chip(&bh)) {
1033 mv64x60_get_mem_windows(&bh, mem_windows);
1034 rc = mv64x60_calc_mem_size(&bh, mem_windows);
1035 }
1036
1037 return rc;
1038}
1039
1040/*
1041 * mv64x60_get_mem_windows()
1042 *
1043 * Get the values in the memory controller & return in the 'mem_windows' array.
1044 */
1045void __init
1046mv64x60_get_mem_windows(struct mv64x60_handle *bh,
1047 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1048{
1049 u32 i, win;
1050
1051 for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
1052 if (bh->ci->is_enabled_32bit(bh, win))
1053 mv64x60_get_32bit_window(bh, win,
1054 &mem_windows[i][0], &mem_windows[i][1]);
1055 else {
1056 mem_windows[i][0] = 0;
1057 mem_windows[i][1] = 0;
1058 }
1059}
1060
1061/*
1062 * mv64x60_calc_mem_size()
1063 *
1064 * Using the memory controller register values in 'mem_windows', determine
1065 * how much memory it is set up for.
1066 */
1067u32 __init
1068mv64x60_calc_mem_size(struct mv64x60_handle *bh,
1069 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1070{
1071 u32 i, total = 0;
1072
1073 for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
1074 total += mem_windows[i][1];
1075
1076 return total;
1077}
1078
1079/*
1080 *****************************************************************************
1081 *
1082 * CPU->System MEM, PCI Config Routines
1083 *
1084 *****************************************************************************
1085 */
1086/*
1087 * mv64x60_config_cpu2mem_windows()
1088 *
1089 * Configure CPU->Memory windows on the bridge.
1090 */
1091static u32 prot_tab[] __initdata = {
1092 MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN,
1093 MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN
1094};
1095
1096static u32 cpu_snoop_tab[] __initdata = {
1097 MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN,
1098 MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN
1099};
1100
1101void __init
1102mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,
1103 struct mv64x60_setup_info *si,
1104 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1105{
1106 u32 i, win;
1107
1108 /* Set CPU protection & snoop windows */
1109 for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
1110 if (bh->ci->is_enabled_32bit(bh, win)) {
1111 mv64x60_set_32bit_window(bh, prot_tab[i],
1112 mem_windows[i][0], mem_windows[i][1],
1113 si->cpu_prot_options[i]);
1114 bh->ci->enable_window_32bit(bh, prot_tab[i]);
1115
1116 if (bh->ci->window_tab_32bit[cpu_snoop_tab[i]].
1117 base_reg != 0) {
1118 mv64x60_set_32bit_window(bh, cpu_snoop_tab[i],
1119 mem_windows[i][0], mem_windows[i][1],
1120 si->cpu_snoop_options[i]);
1121 bh->ci->enable_window_32bit(bh,
1122 cpu_snoop_tab[i]);
1123 }
1124
1125 }
1126}
1127
1128/*
1129 * mv64x60_config_cpu2pci_windows()
1130 *
1131 * Configure the CPU->PCI windows for one of the PCI buses.
1132 */
1133static u32 win_tab[2][4] __initdata = {
1134 { MV64x60_CPU2PCI0_IO_WIN, MV64x60_CPU2PCI0_MEM_0_WIN,
1135 MV64x60_CPU2PCI0_MEM_1_WIN, MV64x60_CPU2PCI0_MEM_2_WIN },
1136 { MV64x60_CPU2PCI1_IO_WIN, MV64x60_CPU2PCI1_MEM_0_WIN,
1137 MV64x60_CPU2PCI1_MEM_1_WIN, MV64x60_CPU2PCI1_MEM_2_WIN },
1138};
1139
1140static u32 remap_tab[2][4] __initdata = {
1141 { MV64x60_CPU2PCI0_IO_REMAP_WIN, MV64x60_CPU2PCI0_MEM_0_REMAP_WIN,
1142 MV64x60_CPU2PCI0_MEM_1_REMAP_WIN, MV64x60_CPU2PCI0_MEM_2_REMAP_WIN },
1143 { MV64x60_CPU2PCI1_IO_REMAP_WIN, MV64x60_CPU2PCI1_MEM_0_REMAP_WIN,
1144 MV64x60_CPU2PCI1_MEM_1_REMAP_WIN, MV64x60_CPU2PCI1_MEM_2_REMAP_WIN }
1145};
1146
1147void __init
1148mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,
1149 struct mv64x60_pci_info *pi, u32 bus)
1150{
1151 int i;
1152
1153 if (pi->pci_io.size > 0) {
1154 mv64x60_set_32bit_window(bh, win_tab[bus][0],
1155 pi->pci_io.cpu_base, pi->pci_io.size, pi->pci_io.swap);
1156 mv64x60_set_32bit_window(bh, remap_tab[bus][0],
1157 pi->pci_io.pci_base_lo, 0, 0);
1158 bh->ci->enable_window_32bit(bh, win_tab[bus][0]);
1159 } else /* Actually, the window should already be disabled */
1160 bh->ci->disable_window_32bit(bh, win_tab[bus][0]);
1161
1162 for (i=0; i<3; i++)
1163 if (pi->pci_mem[i].size > 0) {
1164 mv64x60_set_32bit_window(bh, win_tab[bus][i+1],
1165 pi->pci_mem[i].cpu_base, pi->pci_mem[i].size,
1166 pi->pci_mem[i].swap);
1167 mv64x60_set_64bit_window(bh, remap_tab[bus][i+1],
1168 pi->pci_mem[i].pci_base_hi,
1169 pi->pci_mem[i].pci_base_lo, 0, 0);
1170 bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]);
1171 } else /* Actually, the window should already be disabled */
1172 bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]);
1173}
1174
1175/*
1176 *****************************************************************************
1177 *
1178 * PCI->System MEM Config Routines
1179 *
1180 *****************************************************************************
1181 */
1182/*
1183 * mv64x60_config_pci2mem_windows()
1184 *
1185 * Configure the PCI->Memory windows on the bridge.
1186 */
1187static u32 pci_acc_tab[2][4] __initdata = {
1188 { MV64x60_PCI02MEM_ACC_CNTL_0_WIN, MV64x60_PCI02MEM_ACC_CNTL_1_WIN,
1189 MV64x60_PCI02MEM_ACC_CNTL_2_WIN, MV64x60_PCI02MEM_ACC_CNTL_3_WIN },
1190 { MV64x60_PCI12MEM_ACC_CNTL_0_WIN, MV64x60_PCI12MEM_ACC_CNTL_1_WIN,
1191 MV64x60_PCI12MEM_ACC_CNTL_2_WIN, MV64x60_PCI12MEM_ACC_CNTL_3_WIN }
1192};
1193
1194static u32 pci_snoop_tab[2][4] __initdata = {
1195 { MV64x60_PCI02MEM_SNOOP_0_WIN, MV64x60_PCI02MEM_SNOOP_1_WIN,
1196 MV64x60_PCI02MEM_SNOOP_2_WIN, MV64x60_PCI02MEM_SNOOP_3_WIN },
1197 { MV64x60_PCI12MEM_SNOOP_0_WIN, MV64x60_PCI12MEM_SNOOP_1_WIN,
1198 MV64x60_PCI12MEM_SNOOP_2_WIN, MV64x60_PCI12MEM_SNOOP_3_WIN }
1199};
1200
1201static u32 pci_size_tab[2][4] __initdata = {
1202 { MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE,
1203 MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE },
1204 { MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE,
1205 MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE }
1206};
1207
1208void __init
1209mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,
1210 struct pci_controller *hose, struct mv64x60_pci_info *pi,
1211 u32 bus, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
1212{
1213 u32 i, win;
1214
1215 /*
1216 * Set the access control, snoop, BAR size, and window base addresses.
1217 * PCI->MEM windows base addresses will match exactly what the
1218 * CPU->MEM windows are.
1219 */
1220 for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
1221 if (bh->ci->is_enabled_32bit(bh, win)) {
1222 mv64x60_set_64bit_window(bh,
1223 pci_acc_tab[bus][i], 0,
1224 mem_windows[i][0], mem_windows[i][1],
1225 pi->acc_cntl_options[i]);
1226 bh->ci->enable_window_64bit(bh, pci_acc_tab[bus][i]);
1227
1228 if (bh->ci->window_tab_64bit[
1229 pci_snoop_tab[bus][i]].base_lo_reg != 0) {
1230
1231 mv64x60_set_64bit_window(bh,
1232 pci_snoop_tab[bus][i], 0,
1233 mem_windows[i][0], mem_windows[i][1],
1234 pi->snoop_options[i]);
1235 bh->ci->enable_window_64bit(bh,
1236 pci_snoop_tab[bus][i]);
1237 }
1238
1239 bh->ci->set_pci2mem_window(hose, bus, i,
1240 mem_windows[i][0]);
1241 mv64x60_write(bh, pci_size_tab[bus][i],
1242 mv64x60_mask(mem_windows[i][1] - 1, 20));
1243
1244 /* Enable the window */
1245 mv64x60_clr_bits(bh, ((bus == 0) ?
1246 MV64x60_PCI0_BAR_ENABLE :
1247 MV64x60_PCI1_BAR_ENABLE), (1 << i));
1248 }
1249}
1250
1251/*
1252 *****************************************************************************
1253 *
1254 * Hose & Resource Alloc/Init Routines
1255 *
1256 *****************************************************************************
1257 */
1258/*
1259 * mv64x60_alloc_hoses()
1260 *
1261 * Allocate the PCI hose structures for the bridge's PCI buses.
1262 */
1263void __init
1264mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data,
1265 struct pci_controller **hose)
1266{
1267 *hose = pcibios_alloc_controller();
1268 setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr,
1269 bh->v_base + cfg_data);
1270}
1271
1272/*
1273 * mv64x60_config_resources()
1274 *
1275 * Calculate the offsets, etc. for the hose structures to reflect all of
1276 * the address remapping that happens as you go from CPU->PCI and PCI->MEM.
1277 */
1278void __init
1279mv64x60_config_resources(struct pci_controller *hose,
1280 struct mv64x60_pci_info *pi, u32 io_base)
1281{
1282 int i;
1283 /* 2 hoses; 4 resources/hose; string <= 64 bytes */
1284 static char s[2][4][64];
1285
1286 if (pi->pci_io.size != 0) {
1287 sprintf(s[hose->index][0], "PCI hose %d I/O Space",
1288 hose->index);
1289 pci_init_resource(&hose->io_resource, io_base - isa_io_base,
1290 io_base - isa_io_base + pi->pci_io.size - 1,
1291 IORESOURCE_IO, s[hose->index][0]);
1292 hose->io_space.start = pi->pci_io.pci_base_lo;
1293 hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1;
1294 hose->io_base_phys = pi->pci_io.cpu_base;
1295 hose->io_base_virt = (void *)isa_io_base;
1296 }
1297
1298 for (i=0; i<3; i++)
1299 if (pi->pci_mem[i].size != 0) {
1300 sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d",
1301 hose->index, i);
1302 pci_init_resource(&hose->mem_resources[i],
1303 pi->pci_mem[i].cpu_base,
1304 pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1,
1305 IORESOURCE_MEM, s[hose->index][i+1]);
1306 }
1307
1308 hose->mem_space.end = pi->pci_mem[0].pci_base_lo +
1309 pi->pci_mem[0].size - 1;
1310 hose->pci_mem_offset = pi->pci_mem[0].cpu_base -
1311 pi->pci_mem[0].pci_base_lo;
1312}
1313
1314/*
1315 * mv64x60_config_pci_params()
1316 *
1317 * Configure a hose's PCI config space parameters.
1318 */
1319void __init
1320mv64x60_config_pci_params(struct pci_controller *hose,
1321 struct mv64x60_pci_info *pi)
1322{
1323 u32 devfn;
1324 u16 u16_val;
1325 u8 save_exclude;
1326
1327 devfn = PCI_DEVFN(0,0);
1328
1329 save_exclude = mv64x60_pci_exclude_bridge;
1330 mv64x60_pci_exclude_bridge = 0;
1331
1332 /* Set class code to indicate host bridge */
1333 u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */
1334 early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val);
1335
1336 /* Enable bridge to be PCI master & respond to PCI MEM cycles */
1337 early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val);
1338 u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE |
1339 PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
1340 u16_val |= pi->pci_cmd_bits | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1341 early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);
1342
1343 /* Set latency timer, cache line size, clear BIST */
1344 u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2);
1345 early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);
1346
1347 mv64x60_pci_exclude_bridge = save_exclude;
1348}
1349
1350/*
1351 *****************************************************************************
1352 *
1353 * PCI Related Routine
1354 *
1355 *****************************************************************************
1356 */
1357/*
1358 * mv64x60_set_bus()
1359 *
1360 * Set the bus number for the hose directly under the bridge.
1361 */
1362void __init
1363mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus)
1364{
1365 struct pci_controller *hose;
1366 u32 pci_mode, p2p_cfg, pci_cfg_offset, val;
1367 u8 save_exclude;
1368
1369 if (bus == 0) {
1370 pci_mode = bh->pci_mode_a;
1371 p2p_cfg = MV64x60_PCI0_P2P_CONFIG;
1372 pci_cfg_offset = 0x64;
1373 hose = bh->hose_a;
1374 } else {
1375 pci_mode = bh->pci_mode_b;
1376 p2p_cfg = MV64x60_PCI1_P2P_CONFIG;
1377 pci_cfg_offset = 0xe4;
1378 hose = bh->hose_b;
1379 }
1380
1381 child_bus &= 0xff;
1382 val = mv64x60_read(bh, p2p_cfg);
1383
1384 if (pci_mode == MV64x60_PCIMODE_CONVENTIONAL) {
1385 val &= 0xe0000000; /* Force dev num to 0, turn off P2P bridge */
1386 val |= (child_bus << 16) | 0xff;
1387 mv64x60_write(bh, p2p_cfg, val);
1388 (void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */
1389 } else { /* PCI-X */
1390 /*
1391 * Need to use the current bus/dev number (that's in the
1392 * P2P CONFIG reg) to access the bridge's pci config space.
1393 */
1394 save_exclude = mv64x60_pci_exclude_bridge;
1395 mv64x60_pci_exclude_bridge = 0;
1396 early_write_config_dword(hose, (val & 0x00ff0000) >> 16,
1397 PCI_DEVFN(((val & 0x1f000000) >> 24), 0),
1398 pci_cfg_offset, child_bus << 8);
1399 mv64x60_pci_exclude_bridge = save_exclude;
1400 }
1401}
1402
1403/*
1404 * mv64x60_pci_exclude_device()
1405 *
1406 * This routine is used to make the bridge not appear when the
1407 * PCI subsystem is accessing PCI devices (in PCI config space).
1408 */
1409int
1410mv64x60_pci_exclude_device(u8 bus, u8 devfn)
1411{
1412 struct pci_controller *hose;
1413
1414 hose = pci_bus_to_hose(bus);
1415
1416 /* Skip slot 0 on both hoses */
1417 if ((mv64x60_pci_exclude_bridge == 1) && (PCI_SLOT(devfn) == 0) &&
1418 (hose->first_busno == bus))
1419
1420 return PCIBIOS_DEVICE_NOT_FOUND;
1421 else
1422 return PCIBIOS_SUCCESSFUL;
1423} /* mv64x60_pci_exclude_device() */
1424
1425/*
1426 *****************************************************************************
1427 *
1428 * Platform Device Routines
1429 *
1430 *****************************************************************************
1431 */
1432
1433/*
1434 * mv64x60_pd_fixup()
1435 *
1436 * Need to add the base addr of where the bridge's regs are mapped in the
1437 * physical addr space so drivers can ioremap() them.
1438 */
1439void __init
1440mv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[],
1441 u32 entries)
1442{
1443 struct resource *r;
1444 u32 i, j;
1445
1446 for (i=0; i<entries; i++) {
1447 j = 0;
1448
1449 while ((r = platform_get_resource(pd_devs[i],IORESOURCE_MEM,j))
1450 != NULL) {
1451
1452 r->start += bh->p_base;
1453 r->end += bh->p_base;
1454 j++;
1455 }
1456 }
1457}
1458
1459/*
1460 * mv64x60_add_pds()
1461 *
1462 * Add the mv64x60 platform devices to the list of platform devices.
1463 */
1464static int __init
1465mv64x60_add_pds(void)
1466{
1467 return platform_add_devices(mv64x60_pd_devs,
1468 ARRAY_SIZE(mv64x60_pd_devs));
1469}
1470arch_initcall(mv64x60_add_pds);
1471
1472/*
1473 *****************************************************************************
1474 *
1475 * GT64260-Specific Routines
1476 *
1477 *****************************************************************************
1478 */
1479/*
1480 * gt64260_translate_size()
1481 *
1482 * On the GT64260, the size register is really the "top" address of the window.
1483 */
1484static u32 __init
1485gt64260_translate_size(u32 base, u32 size, u32 num_bits)
1486{
1487 return base + mv64x60_mask(size - 1, num_bits);
1488}
1489
1490/*
1491 * gt64260_untranslate_size()
1492 *
1493 * Translate the top address of a window into a window size.
1494 */
1495static u32 __init
1496gt64260_untranslate_size(u32 base, u32 size, u32 num_bits)
1497{
1498 if (size >= base)
1499 size = size - base + (1 << (32 - num_bits));
1500 else
1501 size = 0;
1502
1503 return size;
1504}
1505
1506/*
1507 * gt64260_set_pci2mem_window()
1508 *
1509 * The PCI->MEM window registers are actually in PCI config space so need
1510 * to set them by setting the correct config space BARs.
1511 */
1512static u32 gt64260_reg_addrs[2][4] __initdata = {
1513 { 0x10, 0x14, 0x18, 0x1c }, { 0x90, 0x94, 0x98, 0x9c }
1514};
1515
1516static void __init
1517gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
1518 u32 base)
1519{
1520 u8 save_exclude;
1521
1522 pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
1523 hose->index, base);
1524
1525 save_exclude = mv64x60_pci_exclude_bridge;
1526 mv64x60_pci_exclude_bridge = 0;
1527 early_write_config_dword(hose, 0, PCI_DEVFN(0, 0),
1528 gt64260_reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8);
1529 mv64x60_pci_exclude_bridge = save_exclude;
1530}
1531
1532/*
1533 * gt64260_set_pci2regs_window()
1534 *
1535 * Set where the bridge's registers appear in PCI MEM space.
1536 */
1537static u32 gt64260_offset[2] __initdata = {0x20, 0xa0};
1538
1539static void __init
1540gt64260_set_pci2regs_window(struct mv64x60_handle *bh,
1541 struct pci_controller *hose, u32 bus, u32 base)
1542{
1543 u8 save_exclude;
1544
1545 pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
1546 base);
1547
1548 save_exclude = mv64x60_pci_exclude_bridge;
1549 mv64x60_pci_exclude_bridge = 0;
1550 early_write_config_dword(hose, 0, PCI_DEVFN(0,0), gt64260_offset[bus],
1551 (base << 16));
1552 mv64x60_pci_exclude_bridge = save_exclude;
1553}
1554
1555/*
1556 * gt64260_is_enabled_32bit()
1557 *
1558 * On a GT64260, a window is enabled iff its top address is >= to its base
1559 * address.
1560 */
1561static u32 __init
1562gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
1563{
1564 u32 rc = 0;
1565
1566 if ((gt64260_32bit_windows[window].base_reg != 0) &&
1567 (gt64260_32bit_windows[window].size_reg != 0) &&
1568 ((mv64x60_read(bh, gt64260_32bit_windows[window].size_reg) &
1569 ((1 << gt64260_32bit_windows[window].size_bits) - 1)) >=
1570 (mv64x60_read(bh, gt64260_32bit_windows[window].base_reg) &
1571 ((1 << gt64260_32bit_windows[window].base_bits) - 1))))
1572
1573 rc = 1;
1574
1575 return rc;
1576}
1577
1578/*
1579 * gt64260_enable_window_32bit()
1580 *
1581 * On the GT64260, a window is enabled iff the top address is >= to the base
1582 * address of the window. Since the window has already been configured by
1583 * the time this routine is called, we have nothing to do here.
1584 */
1585static void __init
1586gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
1587{
1588 pr_debug("enable 32bit window: %d\n", window);
1589}
1590
1591/*
1592 * gt64260_disable_window_32bit()
1593 *
1594 * On a GT64260, you disable a window by setting its top address to be less
1595 * than its base address.
1596 */
1597static void __init
1598gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
1599{
1600 pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
1601 window, gt64260_32bit_windows[window].base_reg,
1602 gt64260_32bit_windows[window].size_reg);
1603
1604 if ((gt64260_32bit_windows[window].base_reg != 0) &&
1605 (gt64260_32bit_windows[window].size_reg != 0)) {
1606
1607 /* To disable, make bottom reg higher than top reg */
1608 mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff);
1609 mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0);
1610 }
1611}
1612
1613/*
1614 * gt64260_enable_window_64bit()
1615 *
1616 * On the GT64260, a window is enabled iff the top address is >= to the base
1617 * address of the window. Since the window has already been configured by
1618 * the time this routine is called, we have nothing to do here.
1619 */
1620static void __init
1621gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
1622{
1623 pr_debug("enable 64bit window: %d\n", window);
1624}
1625
1626/*
1627 * gt64260_disable_window_64bit()
1628 *
1629 * On a GT64260, you disable a window by setting its top address to be less
1630 * than its base address.
1631 */
1632static void __init
1633gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
1634{
1635 pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
1636 window, gt64260_64bit_windows[window].base_lo_reg,
1637 gt64260_64bit_windows[window].size_reg);
1638
1639 if ((gt64260_64bit_windows[window].base_lo_reg != 0) &&
1640 (gt64260_64bit_windows[window].size_reg != 0)) {
1641
1642 /* To disable, make bottom reg higher than top reg */
1643 mv64x60_write(bh, gt64260_64bit_windows[window].base_lo_reg,
1644 0xfff);
1645 mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0);
1646 mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0);
1647 }
1648}
1649
1650/*
1651 * gt64260_disable_all_windows()
1652 *
1653 * The GT64260 has several windows that aren't represented in the table of
1654 * windows at the top of this file. This routine turns all of them off
1655 * except for the memory controller windows, of course.
1656 */
1657static void __init
1658gt64260_disable_all_windows(struct mv64x60_handle *bh,
1659 struct mv64x60_setup_info *si)
1660{
1661 u32 i, preserve;
1662
1663 /* Disable 32bit windows (don't disable cpu->mem windows) */
1664 for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
1665 if (i < 32)
1666 preserve = si->window_preserve_mask_32_lo & (1 << i);
1667 else
1668 preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
1669
1670 if (!preserve)
1671 gt64260_disable_window_32bit(bh, i);
1672 }
1673
1674 /* Disable 64bit windows */
1675 for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
1676 if (!(si->window_preserve_mask_64 & (1<<i)))
1677 gt64260_disable_window_64bit(bh, i);
1678
1679 /* Turn off cpu protection windows not in gt64260_32bit_windows[] */
1680 mv64x60_write(bh, GT64260_CPU_PROT_BASE_4, 0xfff);
1681 mv64x60_write(bh, GT64260_CPU_PROT_SIZE_4, 0);
1682 mv64x60_write(bh, GT64260_CPU_PROT_BASE_5, 0xfff);
1683 mv64x60_write(bh, GT64260_CPU_PROT_SIZE_5, 0);
1684 mv64x60_write(bh, GT64260_CPU_PROT_BASE_6, 0xfff);
1685 mv64x60_write(bh, GT64260_CPU_PROT_SIZE_6, 0);
1686 mv64x60_write(bh, GT64260_CPU_PROT_BASE_7, 0xfff);
1687 mv64x60_write(bh, GT64260_CPU_PROT_SIZE_7, 0);
1688
1689 /* Turn off PCI->MEM access cntl wins not in gt64260_64bit_windows[] */
1690 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0xfff);
1691 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_HI, 0);
1692 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_4_SIZE, 0);
1693 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0xfff);
1694 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_HI, 0);
1695 mv64x60_write(bh, MV64x60_PCI0_ACC_CNTL_5_SIZE, 0);
1696 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_LO, 0xfff);
1697 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_BASE_HI, 0);
1698 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_6_SIZE, 0);
1699 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_LO, 0xfff);
1700 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_BASE_HI, 0);
1701 mv64x60_write(bh, GT64260_PCI0_ACC_CNTL_7_SIZE, 0);
1702
1703 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0xfff);
1704 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_HI, 0);
1705 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_4_SIZE, 0);
1706 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0xfff);
1707 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_HI, 0);
1708 mv64x60_write(bh, MV64x60_PCI1_ACC_CNTL_5_SIZE, 0);
1709 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_LO, 0xfff);
1710 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_BASE_HI, 0);
1711 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_6_SIZE, 0);
1712 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_LO, 0xfff);
1713 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_BASE_HI, 0);
1714 mv64x60_write(bh, GT64260_PCI1_ACC_CNTL_7_SIZE, 0);
1715
1716 /* Disable all PCI-><whatever> windows */
1717 mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x07fffdff);
1718 mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x07fffdff);
1719
1720 /*
1721 * Some firmwares enable a bunch of intr sources
1722 * for the PCI INT output pins.
1723 */
1724 mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_LO, 0);
1725 mv64x60_write(bh, GT64260_IC_CPU_INTR_MASK_HI, 0);
1726 mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_LO, 0);
1727 mv64x60_write(bh, GT64260_IC_PCI0_INTR_MASK_HI, 0);
1728 mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_LO, 0);
1729 mv64x60_write(bh, GT64260_IC_PCI1_INTR_MASK_HI, 0);
1730 mv64x60_write(bh, GT64260_IC_CPU_INT_0_MASK, 0);
1731 mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0);
1732 mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0);
1733 mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0);
1734}
1735
1736/*
1737 * gt64260a_chip_specific_init()
1738 *
1739 * Implement errata workarounds for the GT64260A.
1740 */
1741static void __init
1742gt64260a_chip_specific_init(struct mv64x60_handle *bh,
1743 struct mv64x60_setup_info *si)
1744{
1745#ifdef CONFIG_SERIAL_MPSC
1746 struct resource *r;
1747#endif
1748#if !defined(CONFIG_NOT_COHERENT_CACHE)
1749 u32 val;
1750 u8 save_exclude;
1751#endif
1752
1753 if (si->pci_0.enable_bus)
1754 mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
1755 ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
1756
1757 if (si->pci_1.enable_bus)
1758 mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
1759 ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
1760
1761 /*
1762 * Dave Wilhardt found that bit 4 in the PCI Command registers must
1763 * be set if you are using cache coherency.
1764 */
1765#if !defined(CONFIG_NOT_COHERENT_CACHE)
1766 /* Res #MEM-4 -- cpu read buffer to buffer 1 */
1767 if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
1768 mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
1769
1770 save_exclude = mv64x60_pci_exclude_bridge;
1771 mv64x60_pci_exclude_bridge = 0;
1772 if (si->pci_0.enable_bus) {
1773 early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
1774 PCI_COMMAND, &val);
1775 val |= PCI_COMMAND_INVALIDATE;
1776 early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
1777 PCI_COMMAND, val);
1778 }
1779
1780 if (si->pci_1.enable_bus) {
1781 early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
1782 PCI_COMMAND, &val);
1783 val |= PCI_COMMAND_INVALIDATE;
1784 early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
1785 PCI_COMMAND, val);
1786 }
1787 mv64x60_pci_exclude_bridge = save_exclude;
1788#endif
1789
1790 /* Disable buffer/descriptor snooping */
1791 mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
1792 mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
1793
1794#ifdef CONFIG_SERIAL_MPSC
1795 mv64x60_mpsc0_pdata.mirror_regs = 1;
1796 mv64x60_mpsc0_pdata.cache_mgmt = 1;
1797 mv64x60_mpsc1_pdata.mirror_regs = 1;
1798 mv64x60_mpsc1_pdata.cache_mgmt = 1;
1799
1800 if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
1801 != NULL) {
1802 r->start = MV64x60_IRQ_SDMA_0;
1803 r->end = MV64x60_IRQ_SDMA_0;
1804 }
1805#endif
1806}
1807
1808/*
1809 * gt64260b_chip_specific_init()
1810 *
1811 * Implement errata workarounds for the GT64260B.
1812 */
1813static void __init
1814gt64260b_chip_specific_init(struct mv64x60_handle *bh,
1815 struct mv64x60_setup_info *si)
1816{
1817#ifdef CONFIG_SERIAL_MPSC
1818 struct resource *r;
1819#endif
1820#if !defined(CONFIG_NOT_COHERENT_CACHE)
1821 u32 val;
1822 u8 save_exclude;
1823#endif
1824
1825 if (si->pci_0.enable_bus)
1826 mv64x60_set_bits(bh, MV64x60_PCI0_CMD,
1827 ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
1828
1829 if (si->pci_1.enable_bus)
1830 mv64x60_set_bits(bh, MV64x60_PCI1_CMD,
1831 ((1<<4) | (1<<5) | (1<<9) | (1<<13)));
1832
1833 /*
1834 * Dave Wilhardt found that bit 4 in the PCI Command registers must
1835 * be set if you are using cache coherency.
1836 */
1837#if !defined(CONFIG_NOT_COHERENT_CACHE)
1838 mv64x60_set_bits(bh, GT64260_CPU_WB_PRIORITY_BUFFER_DEPTH, 0xf);
1839
1840 /* Res #MEM-4 -- cpu read buffer to buffer 1 */
1841 if ((mv64x60_read(bh, MV64x60_CPU_MODE) & 0xf0) == 0x40)
1842 mv64x60_set_bits(bh, GT64260_SDRAM_CONFIG, (1<<26));
1843
1844 save_exclude = mv64x60_pci_exclude_bridge;
1845 mv64x60_pci_exclude_bridge = 0;
1846 if (si->pci_0.enable_bus) {
1847 early_read_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
1848 PCI_COMMAND, &val);
1849 val |= PCI_COMMAND_INVALIDATE;
1850 early_write_config_dword(bh->hose_a, 0, PCI_DEVFN(0,0),
1851 PCI_COMMAND, val);
1852 }
1853
1854 if (si->pci_1.enable_bus) {
1855 early_read_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
1856 PCI_COMMAND, &val);
1857 val |= PCI_COMMAND_INVALIDATE;
1858 early_write_config_dword(bh->hose_b, 0, PCI_DEVFN(0,0),
1859 PCI_COMMAND, val);
1860 }
1861 mv64x60_pci_exclude_bridge = save_exclude;
1862#endif
1863
1864 /* Disable buffer/descriptor snooping */
1865 mv64x60_clr_bits(bh, 0xf280, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
1866 mv64x60_clr_bits(bh, 0xf2c0, (1<< 6) | (1<<14) | (1<<22) | (1<<30));
1867
1868#ifdef CONFIG_SERIAL_MPSC
1869 /*
1870 * The 64260B is not supposed to have the bug where the MPSC & ENET
1871 * can't access cache coherent regions. However, testing has shown
1872 * that the MPSC, at least, still has this bug.
1873 */
1874 mv64x60_mpsc0_pdata.cache_mgmt = 1;
1875 mv64x60_mpsc1_pdata.cache_mgmt = 1;
1876
1877 if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0))
1878 != NULL) {
1879 r->start = MV64x60_IRQ_SDMA_0;
1880 r->end = MV64x60_IRQ_SDMA_0;
1881 }
1882#endif
1883}
1884
1885/*
1886 *****************************************************************************
1887 *
1888 * MV64360-Specific Routines
1889 *
1890 *****************************************************************************
1891 */
1892/*
1893 * mv64360_translate_size()
1894 *
1895 * On the MV64360, the size register is set similar to the size you get
1896 * from a pci config space BAR register. That is, programmed from LSB to MSB
1897 * as a sequence of 1's followed by a sequence of 0's. IOW, "size -1" with the
1898 * assumption that the size is a power of 2.
1899 */
1900static u32 __init
1901mv64360_translate_size(u32 base_addr, u32 size, u32 num_bits)
1902{
1903 return mv64x60_mask(size - 1, num_bits);
1904}
1905
1906/*
1907 * mv64360_untranslate_size()
1908 *
1909 * Translate the size register value of a window into a window size.
1910 */
1911static u32 __init
1912mv64360_untranslate_size(u32 base_addr, u32 size, u32 num_bits)
1913{
1914 if (size > 0) {
1915 size >>= (32 - num_bits);
1916 size++;
1917 size <<= (32 - num_bits);
1918 }
1919
1920 return size;
1921}
1922
1923/*
1924 * mv64360_set_pci2mem_window()
1925 *
1926 * The PCI->MEM window registers are actually in PCI config space so need
1927 * to set them by setting the correct config space BARs.
1928 */
1929struct {
1930 u32 fcn;
1931 u32 base_hi_bar;
1932 u32 base_lo_bar;
1933} static mv64360_reg_addrs[2][4] __initdata = {
1934 {{ 0, 0x14, 0x10 }, { 0, 0x1c, 0x18 },
1935 { 1, 0x14, 0x10 }, { 1, 0x1c, 0x18 }},
1936 {{ 0, 0x94, 0x90 }, { 0, 0x9c, 0x98 },
1937 { 1, 0x94, 0x90 }, { 1, 0x9c, 0x98 }}
1938};
1939
1940static void __init
1941mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window,
1942 u32 base)
1943{
1944 u8 save_exclude;
1945
1946 pr_debug("set pci->mem window: %d, hose: %d, base: 0x%x\n", window,
1947 hose->index, base);
1948
1949 save_exclude = mv64x60_pci_exclude_bridge;
1950 mv64x60_pci_exclude_bridge = 0;
1951 early_write_config_dword(hose, 0,
1952 PCI_DEVFN(0, mv64360_reg_addrs[bus][window].fcn),
1953 mv64360_reg_addrs[bus][window].base_hi_bar, 0);
1954 early_write_config_dword(hose, 0,
1955 PCI_DEVFN(0, mv64360_reg_addrs[bus][window].fcn),
1956 mv64360_reg_addrs[bus][window].base_lo_bar,
1957 mv64x60_mask(base,20) | 0xc);
1958 mv64x60_pci_exclude_bridge = save_exclude;
1959}
1960
1961/*
1962 * mv64360_set_pci2regs_window()
1963 *
1964 * Set where the bridge's registers appear in PCI MEM space.
1965 */
1966static u32 mv64360_offset[2][2] __initdata = {{0x20, 0x24}, {0xa0, 0xa4}};
1967
1968static void __init
1969mv64360_set_pci2regs_window(struct mv64x60_handle *bh,
1970 struct pci_controller *hose, u32 bus, u32 base)
1971{
1972 u8 save_exclude;
1973
1974 pr_debug("set pci->internal regs hose: %d, base: 0x%x\n", hose->index,
1975 base);
1976
1977 save_exclude = mv64x60_pci_exclude_bridge;
1978 mv64x60_pci_exclude_bridge = 0;
1979 early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
1980 mv64360_offset[bus][0], (base << 16));
1981 early_write_config_dword(hose, 0, PCI_DEVFN(0,0),
1982 mv64360_offset[bus][1], 0);
1983 mv64x60_pci_exclude_bridge = save_exclude;
1984}
1985
1986/*
1987 * mv64360_is_enabled_32bit()
1988 *
1989 * On a MV64360, a window is enabled by either clearing a bit in the
1990 * CPU BAR Enable reg or setting a bit in the window's base reg.
1991 * Note that this doesn't work for windows on the PCI slave side but we don't
1992 * check those so its okay.
1993 */
1994static u32 __init
1995mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window)
1996{
1997 u32 extra, rc = 0;
1998
1999 if (((mv64360_32bit_windows[window].base_reg != 0) &&
2000 (mv64360_32bit_windows[window].size_reg != 0)) ||
2001 (window == MV64x60_CPU2SRAM_WIN)) {
2002
2003 extra = mv64360_32bit_windows[window].extra;
2004
2005 switch (extra & MV64x60_EXTRA_MASK) {
2006 case MV64x60_EXTRA_CPUWIN_ENAB:
2007 rc = (mv64x60_read(bh, MV64360_CPU_BAR_ENABLE) &
2008 (1 << (extra & 0x1f))) == 0;
2009 break;
2010
2011 case MV64x60_EXTRA_CPUPROT_ENAB:
2012 rc = (mv64x60_read(bh,
2013 mv64360_32bit_windows[window].base_reg) &
2014 (1 << (extra & 0x1f))) != 0;
2015 break;
2016
2017 case MV64x60_EXTRA_ENET_ENAB:
2018 rc = (mv64x60_read(bh, MV64360_ENET2MEM_BAR_ENABLE) &
2019 (1 << (extra & 0x7))) == 0;
2020 break;
2021
2022 case MV64x60_EXTRA_MPSC_ENAB:
2023 rc = (mv64x60_read(bh, MV64360_MPSC2MEM_BAR_ENABLE) &
2024 (1 << (extra & 0x3))) == 0;
2025 break;
2026
2027 case MV64x60_EXTRA_IDMA_ENAB:
2028 rc = (mv64x60_read(bh, MV64360_IDMA2MEM_BAR_ENABLE) &
2029 (1 << (extra & 0x7))) == 0;
2030 break;
2031
2032 default:
2033 printk(KERN_ERR "mv64360_is_enabled: %s\n",
2034 "32bit table corrupted");
2035 }
2036 }
2037
2038 return rc;
2039}
2040
2041/*
2042 * mv64360_enable_window_32bit()
2043 *
2044 * On a MV64360, a window is enabled by either clearing a bit in the
2045 * CPU BAR Enable reg or setting a bit in the window's base reg.
2046 */
2047static void __init
2048mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window)
2049{
2050 u32 extra;
2051
2052 pr_debug("enable 32bit window: %d\n", window);
2053
2054 if (((mv64360_32bit_windows[window].base_reg != 0) &&
2055 (mv64360_32bit_windows[window].size_reg != 0)) ||
2056 (window == MV64x60_CPU2SRAM_WIN)) {
2057
2058 extra = mv64360_32bit_windows[window].extra;
2059
2060 switch (extra & MV64x60_EXTRA_MASK) {
2061 case MV64x60_EXTRA_CPUWIN_ENAB:
2062 mv64x60_clr_bits(bh, MV64360_CPU_BAR_ENABLE,
2063 (1 << (extra & 0x1f)));
2064 break;
2065
2066 case MV64x60_EXTRA_CPUPROT_ENAB:
2067 mv64x60_set_bits(bh,
2068 mv64360_32bit_windows[window].base_reg,
2069 (1 << (extra & 0x1f)));
2070 break;
2071
2072 case MV64x60_EXTRA_ENET_ENAB:
2073 mv64x60_clr_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
2074 (1 << (extra & 0x7)));
2075 break;
2076
2077 case MV64x60_EXTRA_MPSC_ENAB:
2078 mv64x60_clr_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
2079 (1 << (extra & 0x3)));
2080 break;
2081
2082 case MV64x60_EXTRA_IDMA_ENAB:
2083 mv64x60_clr_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
2084 (1 << (extra & 0x7)));
2085 break;
2086
2087 default:
2088 printk(KERN_ERR "mv64360_enable: %s\n",
2089 "32bit table corrupted");
2090 }
2091 }
2092}
2093
2094/*
2095 * mv64360_disable_window_32bit()
2096 *
2097 * On a MV64360, a window is disabled by either setting a bit in the
2098 * CPU BAR Enable reg or clearing a bit in the window's base reg.
2099 */
2100static void __init
2101mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window)
2102{
2103 u32 extra;
2104
2105 pr_debug("disable 32bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2106 window, mv64360_32bit_windows[window].base_reg,
2107 mv64360_32bit_windows[window].size_reg);
2108
2109 if (((mv64360_32bit_windows[window].base_reg != 0) &&
2110 (mv64360_32bit_windows[window].size_reg != 0)) ||
2111 (window == MV64x60_CPU2SRAM_WIN)) {
2112
2113 extra = mv64360_32bit_windows[window].extra;
2114
2115 switch (extra & MV64x60_EXTRA_MASK) {
2116 case MV64x60_EXTRA_CPUWIN_ENAB:
2117 mv64x60_set_bits(bh, MV64360_CPU_BAR_ENABLE,
2118 (1 << (extra & 0x1f)));
2119 break;
2120
2121 case MV64x60_EXTRA_CPUPROT_ENAB:
2122 mv64x60_clr_bits(bh,
2123 mv64360_32bit_windows[window].base_reg,
2124 (1 << (extra & 0x1f)));
2125 break;
2126
2127 case MV64x60_EXTRA_ENET_ENAB:
2128 mv64x60_set_bits(bh, MV64360_ENET2MEM_BAR_ENABLE,
2129 (1 << (extra & 0x7)));
2130 break;
2131
2132 case MV64x60_EXTRA_MPSC_ENAB:
2133 mv64x60_set_bits(bh, MV64360_MPSC2MEM_BAR_ENABLE,
2134 (1 << (extra & 0x3)));
2135 break;
2136
2137 case MV64x60_EXTRA_IDMA_ENAB:
2138 mv64x60_set_bits(bh, MV64360_IDMA2MEM_BAR_ENABLE,
2139 (1 << (extra & 0x7)));
2140 break;
2141
2142 default:
2143 printk(KERN_ERR "mv64360_disable: %s\n",
2144 "32bit table corrupted");
2145 }
2146 }
2147}
2148
2149/*
2150 * mv64360_enable_window_64bit()
2151 *
2152 * On the MV64360, a 64-bit window is enabled by setting a bit in the window's
2153 * base reg.
2154 */
2155static void __init
2156mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window)
2157{
2158 pr_debug("enable 64bit window: %d\n", window);
2159
2160 if ((mv64360_64bit_windows[window].base_lo_reg!= 0) &&
2161 (mv64360_64bit_windows[window].size_reg != 0)) {
2162
2163 if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
2164 == MV64x60_EXTRA_PCIACC_ENAB)
2165 mv64x60_set_bits(bh,
2166 mv64360_64bit_windows[window].base_lo_reg,
2167 (1 << (mv64360_64bit_windows[window].extra &
2168 0x1f)));
2169 else
2170 printk(KERN_ERR "mv64360_enable: %s\n",
2171 "64bit table corrupted");
2172 }
2173}
2174
2175/*
2176 * mv64360_disable_window_64bit()
2177 *
2178 * On a MV64360, a 64-bit window is disabled by clearing a bit in the window's
2179 * base reg.
2180 */
2181static void __init
2182mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window)
2183{
2184 pr_debug("disable 64bit window: %d, base_reg: 0x%x, size_reg: 0x%x\n",
2185 window, mv64360_64bit_windows[window].base_lo_reg,
2186 mv64360_64bit_windows[window].size_reg);
2187
2188 if ((mv64360_64bit_windows[window].base_lo_reg != 0) &&
2189 (mv64360_64bit_windows[window].size_reg != 0)) {
2190 if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK)
2191 == MV64x60_EXTRA_PCIACC_ENAB)
2192 mv64x60_clr_bits(bh,
2193 mv64360_64bit_windows[window].base_lo_reg,
2194 (1 << (mv64360_64bit_windows[window].extra &
2195 0x1f)));
2196 else
2197 printk(KERN_ERR "mv64360_disable: %s\n",
2198 "64bit table corrupted");
2199 }
2200}
2201
2202/*
2203 * mv64360_disable_all_windows()
2204 *
2205 * The MV64360 has a few windows that aren't represented in the table of
2206 * windows at the top of this file. This routine turns all of them off
2207 * except for the memory controller windows, of course.
2208 */
2209static void __init
2210mv64360_disable_all_windows(struct mv64x60_handle *bh,
2211 struct mv64x60_setup_info *si)
2212{
2213 u32 preserve, i;
2214
2215 /* Disable 32bit windows (don't disable cpu->mem windows) */
2216 for (i=MV64x60_CPU2DEV_0_WIN; i<MV64x60_32BIT_WIN_COUNT; i++) {
2217 if (i < 32)
2218 preserve = si->window_preserve_mask_32_lo & (1 << i);
2219 else
2220 preserve = si->window_preserve_mask_32_hi & (1<<(i-32));
2221
2222 if (!preserve)
2223 mv64360_disable_window_32bit(bh, i);
2224 }
2225
2226 /* Disable 64bit windows */
2227 for (i=0; i<MV64x60_64BIT_WIN_COUNT; i++)
2228 if (!(si->window_preserve_mask_64 & (1<<i)))
2229 mv64360_disable_window_64bit(bh, i);
2230
2231 /* Turn off PCI->MEM access cntl wins not in mv64360_64bit_windows[] */
2232 mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_4_BASE_LO, 0);
2233 mv64x60_clr_bits(bh, MV64x60_PCI0_ACC_CNTL_5_BASE_LO, 0);
2234 mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_4_BASE_LO, 0);
2235 mv64x60_clr_bits(bh, MV64x60_PCI1_ACC_CNTL_5_BASE_LO, 0);
2236
2237 /* Disable all PCI-><whatever> windows */
2238 mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff);
2239 mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff);
2240}
2241
2242/*
2243 * mv64360_config_io2mem_windows()
2244 *
2245 * ENET, MPSC, and IDMA ctlrs on the MV64[34]60 have separate windows that
2246 * must be set up so that the respective ctlr can access system memory.
2247 */
2248static u32 enet_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
2249 MV64x60_ENET2MEM_0_WIN, MV64x60_ENET2MEM_1_WIN,
2250 MV64x60_ENET2MEM_2_WIN, MV64x60_ENET2MEM_3_WIN,
2251};
2252
2253static u32 mpsc_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
2254 MV64x60_MPSC2MEM_0_WIN, MV64x60_MPSC2MEM_1_WIN,
2255 MV64x60_MPSC2MEM_2_WIN, MV64x60_MPSC2MEM_3_WIN,
2256};
2257
2258static u32 idma_tab[MV64x60_CPU2MEM_WINDOWS] __initdata = {
2259 MV64x60_IDMA2MEM_0_WIN, MV64x60_IDMA2MEM_1_WIN,
2260 MV64x60_IDMA2MEM_2_WIN, MV64x60_IDMA2MEM_3_WIN,
2261};
2262
2263static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] __initdata =
2264 { 0xe, 0xd, 0xb, 0x7 };
2265
2266static void __init
2267mv64360_config_io2mem_windows(struct mv64x60_handle *bh,
2268 struct mv64x60_setup_info *si,
2269 u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2])
2270{
2271 u32 i, win;
2272
2273 pr_debug("config_io2regs_windows: enet, mpsc, idma -> bridge regs\n");
2274
2275 mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_0, 0);
2276 mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_1, 0);
2277 mv64x60_write(bh, MV64360_ENET2MEM_ACC_PROT_2, 0);
2278
2279 mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_0, 0);
2280 mv64x60_write(bh, MV64360_MPSC2MEM_ACC_PROT_1, 0);
2281
2282 mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_0, 0);
2283 mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_1, 0);
2284 mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_2, 0);
2285 mv64x60_write(bh, MV64360_IDMA2MEM_ACC_PROT_3, 0);
2286
2287 /* Assume that mem ctlr has no more windows than embedded I/O ctlr */
2288 for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)
2289 if (bh->ci->is_enabled_32bit(bh, win)) {
2290 mv64x60_set_32bit_window(bh, enet_tab[i],
2291 mem_windows[i][0], mem_windows[i][1],
2292 (dram_selects[i] << 8) |
2293 (si->enet_options[i] & 0x3000));
2294 bh->ci->enable_window_32bit(bh, enet_tab[i]);
2295
2296 /* Give enet r/w access to memory region */
2297 mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_0,
2298 (0x3 << (i << 1)));
2299 mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_1,
2300 (0x3 << (i << 1)));
2301 mv64x60_set_bits(bh, MV64360_ENET2MEM_ACC_PROT_2,
2302 (0x3 << (i << 1)));
2303
2304 mv64x60_set_32bit_window(bh, mpsc_tab[i],
2305 mem_windows[i][0], mem_windows[i][1],
2306 (dram_selects[i] << 8) |
2307 (si->mpsc_options[i] & 0x3000));
2308 bh->ci->enable_window_32bit(bh, mpsc_tab[i]);
2309
2310 /* Give mpsc r/w access to memory region */
2311 mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_0,
2312 (0x3 << (i << 1)));
2313 mv64x60_set_bits(bh, MV64360_MPSC2MEM_ACC_PROT_1,
2314 (0x3 << (i << 1)));
2315
2316 mv64x60_set_32bit_window(bh, idma_tab[i],
2317 mem_windows[i][0], mem_windows[i][1],
2318 (dram_selects[i] << 8) |
2319 (si->idma_options[i] & 0x3000));
2320 bh->ci->enable_window_32bit(bh, idma_tab[i]);
2321
2322 /* Give idma r/w access to memory region */
2323 mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_0,
2324 (0x3 << (i << 1)));
2325 mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_1,
2326 (0x3 << (i << 1)));
2327 mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_2,
2328 (0x3 << (i << 1)));
2329 mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3,
2330 (0x3 << (i << 1)));
2331 }
2332}
2333
2334/*
2335 * mv64360_set_mpsc2regs_window()
2336 *
2337 * MPSC has a window to the bridge's internal registers. Call this routine
2338 * to change that window so it doesn't conflict with the windows mapping the
2339 * mpsc to system memory.
2340 */
2341static void __init
2342mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base)
2343{
2344 pr_debug("set mpsc->internal regs, base: 0x%x\n", base);
2345 mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000);
2346}
2347
2348/*
2349 * mv64360_chip_specific_init()
2350 *
2351 * Implement errata workarounds for the MV64360.
2352 */
2353static void __init
2354mv64360_chip_specific_init(struct mv64x60_handle *bh,
2355 struct mv64x60_setup_info *si)
2356{
2357#if !defined(CONFIG_NOT_COHERENT_CACHE)
2358 mv64x60_set_bits(bh, MV64360_D_UNIT_CONTROL_HIGH, (1<<24));
2359#endif
2360#ifdef CONFIG_SERIAL_MPSC
2361 mv64x60_mpsc0_pdata.brg_can_tune = 1;
2362 mv64x60_mpsc0_pdata.cache_mgmt = 1;
2363 mv64x60_mpsc1_pdata.brg_can_tune = 1;
2364 mv64x60_mpsc1_pdata.cache_mgmt = 1;
2365#endif
2366}
2367
2368/*
2369 * mv64460_chip_specific_init()
2370 *
2371 * Implement errata workarounds for the MV64460.
2372 */
2373static void __init
2374mv64460_chip_specific_init(struct mv64x60_handle *bh,
2375 struct mv64x60_setup_info *si)
2376{
2377#if !defined(CONFIG_NOT_COHERENT_CACHE)
2378 mv64x60_set_bits(bh, MV64360_D_UNIT_CONTROL_HIGH, (1<<24) | (1<<25));
2379 mv64x60_set_bits(bh, MV64460_D_UNIT_MMASK, (1<<1) | (1<<4));
2380#endif
2381#ifdef CONFIG_SERIAL_MPSC
2382 mv64x60_mpsc0_pdata.brg_can_tune = 1;
2383 mv64x60_mpsc0_pdata.cache_mgmt = 1;
2384 mv64x60_mpsc1_pdata.brg_can_tune = 1;
2385 mv64x60_mpsc1_pdata.cache_mgmt = 1;
2386#endif
2387}
2388
2389
2390#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)
2391/* Export the hotswap register via sysfs for enum event monitoring */
2392#define VAL_LEN_MAX 11 /* 32-bit hex or dec stringified number + '\n' */
2393
2394static DEFINE_MUTEX(mv64xxx_hs_lock);
2395
2396static ssize_t
2397mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
2398{
2399 u32 v;
2400 u8 save_exclude;
2401
2402 if (off > 0)
2403 return 0;
2404 if (count < VAL_LEN_MAX)
2405 return -EINVAL;
2406
2407 if (mutex_lock_interruptible(&mv64xxx_hs_lock))
2408 return -ERESTARTSYS;
2409 save_exclude = mv64x60_pci_exclude_bridge;
2410 mv64x60_pci_exclude_bridge = 0;
2411 early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0),
2412 MV64360_PCICFG_CPCI_HOTSWAP, &v);
2413 mv64x60_pci_exclude_bridge = save_exclude;
2414 mutex_unlock(&mv64xxx_hs_lock);
2415
2416 return sprintf(buf, "0x%08x\n", v);
2417}
2418
2419static ssize_t
2420mv64xxx_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
2421{
2422 u32 v;
2423 u8 save_exclude;
2424
2425 if (off > 0)
2426 return 0;
2427 if (count <= 0)
2428 return -EINVAL;
2429
2430 if (sscanf(buf, "%i", &v) == 1) {
2431 if (mutex_lock_interruptible(&mv64xxx_hs_lock))
2432 return -ERESTARTSYS;
2433 save_exclude = mv64x60_pci_exclude_bridge;
2434 mv64x60_pci_exclude_bridge = 0;
2435 early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0),
2436 MV64360_PCICFG_CPCI_HOTSWAP, v);
2437 mv64x60_pci_exclude_bridge = save_exclude;
2438 mutex_unlock(&mv64xxx_hs_lock);
2439 }
2440 else
2441 count = -EINVAL;
2442
2443 return count;
2444}
2445
2446static struct bin_attribute mv64xxx_hs_reg_attr = { /* Hotswap register */
2447 .attr = {
2448 .name = "hs_reg",
2449 .mode = S_IRUGO | S_IWUSR,
2450 },
2451 .size = VAL_LEN_MAX,
2452 .read = mv64xxx_hs_reg_read,
2453 .write = mv64xxx_hs_reg_write,
2454};
2455
2456/* Provide sysfs file indicating if this platform supports the hs_reg */
2457static ssize_t
2458mv64xxx_hs_reg_valid_show(struct device *dev, struct device_attribute *attr,
2459 char *buf)
2460{
2461 struct platform_device *pdev;
2462 struct mv64xxx_pdata *pdp;
2463 u32 v;
2464
2465 pdev = container_of(dev, struct platform_device, dev);
2466 pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data;
2467
2468 if (mutex_lock_interruptible(&mv64xxx_hs_lock))
2469 return -ERESTARTSYS;
2470 v = pdp->hs_reg_valid;
2471 mutex_unlock(&mv64xxx_hs_lock);
2472
2473 return sprintf(buf, "%i\n", v);
2474}
2475static DEVICE_ATTR(hs_reg_valid, S_IRUGO, mv64xxx_hs_reg_valid_show, NULL);
2476
2477static int __init
2478mv64xxx_sysfs_init(void)
2479{
2480 sysfs_create_bin_file(&mv64xxx_device.dev.kobj, &mv64xxx_hs_reg_attr);
2481 sysfs_create_file(&mv64xxx_device.dev.kobj,&dev_attr_hs_reg_valid.attr);
2482 return 0;
2483}
2484subsys_initcall(mv64xxx_sysfs_init);
2485#endif
diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
deleted file mode 100644
index e1876261e5dc..000000000000
--- a/arch/ppc/syslib/mv64x60_dbg.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * KGDB and progress routines for the Marvell/Galileo MV64x60 (Discovery).
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * 2003 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12/*
13 *****************************************************************************
14 *
15 * Low-level MPSC/UART I/O routines
16 *
17 *****************************************************************************
18 */
19
20
21#include <linux/irq.h>
22#include <asm/delay.h>
23#include <asm/mv64x60.h>
24#include <asm/machdep.h>
25
26
27#if defined(CONFIG_SERIAL_TEXT_DEBUG)
28
29#define MPSC_CHR_1 0x000c
30#define MPSC_CHR_2 0x0010
31
32static struct mv64x60_handle mv64x60_dbg_bh;
33
34void
35mv64x60_progress_init(u32 base)
36{
37 mv64x60_dbg_bh.v_base = base;
38 return;
39}
40
41static void
42mv64x60_polled_putc(int chan, char c)
43{
44 u32 offset;
45
46 if (chan == 0)
47 offset = 0x8000;
48 else
49 offset = 0x9000;
50
51 mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_1, (u32)c);
52 mv64x60_write(&mv64x60_dbg_bh, offset + MPSC_CHR_2, 0x200);
53 udelay(2000);
54}
55
56void
57mv64x60_mpsc_progress(char *s, unsigned short hex)
58{
59 volatile char c;
60
61 mv64x60_polled_putc(0, '\r');
62
63 while ((c = *s++) != 0)
64 mv64x60_polled_putc(0, c);
65
66 mv64x60_polled_putc(0, '\n');
67 mv64x60_polled_putc(0, '\r');
68
69 return;
70}
71#endif /* CONFIG_SERIAL_TEXT_DEBUG */
72
73
74#if defined(CONFIG_KGDB)
75
76#if defined(CONFIG_KGDB_TTYS0)
77#define KGDB_PORT 0
78#elif defined(CONFIG_KGDB_TTYS1)
79#define KGDB_PORT 1
80#else
81#error "Invalid kgdb_tty port"
82#endif
83
84void
85putDebugChar(unsigned char c)
86{
87 mv64x60_polled_putc(KGDB_PORT, (char)c);
88}
89
90int
91getDebugChar(void)
92{
93 unsigned char c;
94
95 while (!mv64x60_polled_getc(KGDB_PORT, &c));
96 return (int)c;
97}
98
99void
100putDebugString(char* str)
101{
102 while (*str != '\0') {
103 putDebugChar(*str);
104 str++;
105 }
106 putDebugChar('\r');
107 return;
108}
109
110void
111kgdb_interruptible(int enable)
112{
113}
114
115void
116kgdb_map_scc(void)
117{
118 if (ppc_md.early_serial_map)
119 ppc_md.early_serial_map();
120}
121#endif /* CONFIG_KGDB */
diff --git a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c
deleted file mode 100644
index 4bf1ad17bf1a..000000000000
--- a/arch/ppc/syslib/mv64x60_win.c
+++ /dev/null
@@ -1,1165 +0,0 @@
1/*
2 * Tables with info on how to manipulate the 32 & 64 bit windows on the
3 * various types of Marvell bridge chips.
4 *
5 * Author: Mark A. Greer <mgreer@mvista.com>
6 *
7 * 2004 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <linux/slab.h>
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/mv643xx.h>
19
20#include <asm/byteorder.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23#include <asm/uaccess.h>
24#include <asm/machdep.h>
25#include <asm/pci-bridge.h>
26#include <asm/delay.h>
27#include <asm/mv64x60.h>
28
29
30/*
31 *****************************************************************************
32 *
33 * Tables describing how to set up windows on each type of bridge
34 *
35 *****************************************************************************
36 */
37struct mv64x60_32bit_window
38 gt64260_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
39 /* CPU->MEM Windows */
40 [MV64x60_CPU2MEM_0_WIN] = {
41 .base_reg = MV64x60_CPU2MEM_0_BASE,
42 .size_reg = MV64x60_CPU2MEM_0_SIZE,
43 .base_bits = 12,
44 .size_bits = 12,
45 .get_from_field = mv64x60_shift_left,
46 .map_to_field = mv64x60_shift_right,
47 .extra = 0 },
48 [MV64x60_CPU2MEM_1_WIN] = {
49 .base_reg = MV64x60_CPU2MEM_1_BASE,
50 .size_reg = MV64x60_CPU2MEM_1_SIZE,
51 .base_bits = 12,
52 .size_bits = 12,
53 .get_from_field = mv64x60_shift_left,
54 .map_to_field = mv64x60_shift_right,
55 .extra = 0 },
56 [MV64x60_CPU2MEM_2_WIN] = {
57 .base_reg = MV64x60_CPU2MEM_2_BASE,
58 .size_reg = MV64x60_CPU2MEM_2_SIZE,
59 .base_bits = 12,
60 .size_bits = 12,
61 .get_from_field = mv64x60_shift_left,
62 .map_to_field = mv64x60_shift_right,
63 .extra = 0 },
64 [MV64x60_CPU2MEM_3_WIN] = {
65 .base_reg = MV64x60_CPU2MEM_3_BASE,
66 .size_reg = MV64x60_CPU2MEM_3_SIZE,
67 .base_bits = 12,
68 .size_bits = 12,
69 .get_from_field = mv64x60_shift_left,
70 .map_to_field = mv64x60_shift_right,
71 .extra = 0 },
72 /* CPU->Device Windows */
73 [MV64x60_CPU2DEV_0_WIN] = {
74 .base_reg = MV64x60_CPU2DEV_0_BASE,
75 .size_reg = MV64x60_CPU2DEV_0_SIZE,
76 .base_bits = 12,
77 .size_bits = 12,
78 .get_from_field = mv64x60_shift_left,
79 .map_to_field = mv64x60_shift_right,
80 .extra = 0 },
81 [MV64x60_CPU2DEV_1_WIN] = {
82 .base_reg = MV64x60_CPU2DEV_1_BASE,
83 .size_reg = MV64x60_CPU2DEV_1_SIZE,
84 .base_bits = 12,
85 .size_bits = 12,
86 .get_from_field = mv64x60_shift_left,
87 .map_to_field = mv64x60_shift_right,
88 .extra = 0 },
89 [MV64x60_CPU2DEV_2_WIN] = {
90 .base_reg = MV64x60_CPU2DEV_2_BASE,
91 .size_reg = MV64x60_CPU2DEV_2_SIZE,
92 .base_bits = 12,
93 .size_bits = 12,
94 .get_from_field = mv64x60_shift_left,
95 .map_to_field = mv64x60_shift_right,
96 .extra = 0 },
97 [MV64x60_CPU2DEV_3_WIN] = {
98 .base_reg = MV64x60_CPU2DEV_3_BASE,
99 .size_reg = MV64x60_CPU2DEV_3_SIZE,
100 .base_bits = 12,
101 .size_bits = 12,
102 .get_from_field = mv64x60_shift_left,
103 .map_to_field = mv64x60_shift_right,
104 .extra = 0 },
105 /* CPU->Boot Window */
106 [MV64x60_CPU2BOOT_WIN] = {
107 .base_reg = MV64x60_CPU2BOOT_0_BASE,
108 .size_reg = MV64x60_CPU2BOOT_0_SIZE,
109 .base_bits = 12,
110 .size_bits = 12,
111 .get_from_field = mv64x60_shift_left,
112 .map_to_field = mv64x60_shift_right,
113 .extra = 0 },
114 /* CPU->PCI 0 Windows */
115 [MV64x60_CPU2PCI0_IO_WIN] = {
116 .base_reg = MV64x60_CPU2PCI0_IO_BASE,
117 .size_reg = MV64x60_CPU2PCI0_IO_SIZE,
118 .base_bits = 12,
119 .size_bits = 12,
120 .get_from_field = mv64x60_shift_left,
121 .map_to_field = mv64x60_shift_right,
122 .extra = 0 },
123 [MV64x60_CPU2PCI0_MEM_0_WIN] = {
124 .base_reg = MV64x60_CPU2PCI0_MEM_0_BASE,
125 .size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE,
126 .base_bits = 12,
127 .size_bits = 12,
128 .get_from_field = mv64x60_shift_left,
129 .map_to_field = mv64x60_shift_right,
130 .extra = 0 },
131 [MV64x60_CPU2PCI0_MEM_1_WIN] = {
132 .base_reg = MV64x60_CPU2PCI0_MEM_1_BASE,
133 .size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE,
134 .base_bits = 12,
135 .size_bits = 12,
136 .get_from_field = mv64x60_shift_left,
137 .map_to_field = mv64x60_shift_right,
138 .extra = 0 },
139 [MV64x60_CPU2PCI0_MEM_2_WIN] = {
140 .base_reg = MV64x60_CPU2PCI0_MEM_2_BASE,
141 .size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE,
142 .base_bits = 12,
143 .size_bits = 12,
144 .get_from_field = mv64x60_shift_left,
145 .map_to_field = mv64x60_shift_right,
146 .extra = 0 },
147 [MV64x60_CPU2PCI0_MEM_3_WIN] = {
148 .base_reg = MV64x60_CPU2PCI0_MEM_3_BASE,
149 .size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE,
150 .base_bits = 12,
151 .size_bits = 12,
152 .get_from_field = mv64x60_shift_left,
153 .map_to_field = mv64x60_shift_right,
154 .extra = 0 },
155 /* CPU->PCI 1 Windows */
156 [MV64x60_CPU2PCI1_IO_WIN] = {
157 .base_reg = MV64x60_CPU2PCI1_IO_BASE,
158 .size_reg = MV64x60_CPU2PCI1_IO_SIZE,
159 .base_bits = 12,
160 .size_bits = 12,
161 .get_from_field = mv64x60_shift_left,
162 .map_to_field = mv64x60_shift_right,
163 .extra = 0 },
164 [MV64x60_CPU2PCI1_MEM_0_WIN] = {
165 .base_reg = MV64x60_CPU2PCI1_MEM_0_BASE,
166 .size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE,
167 .base_bits = 12,
168 .size_bits = 12,
169 .get_from_field = mv64x60_shift_left,
170 .map_to_field = mv64x60_shift_right,
171 .extra = 0 },
172 [MV64x60_CPU2PCI1_MEM_1_WIN] = {
173 .base_reg = MV64x60_CPU2PCI1_MEM_1_BASE,
174 .size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE,
175 .base_bits = 12,
176 .size_bits = 12,
177 .get_from_field = mv64x60_shift_left,
178 .map_to_field = mv64x60_shift_right,
179 .extra = 0 },
180 [MV64x60_CPU2PCI1_MEM_2_WIN] = {
181 .base_reg = MV64x60_CPU2PCI1_MEM_2_BASE,
182 .size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE,
183 .base_bits = 12,
184 .size_bits = 12,
185 .get_from_field = mv64x60_shift_left,
186 .map_to_field = mv64x60_shift_right,
187 .extra = 0 },
188 [MV64x60_CPU2PCI1_MEM_3_WIN] = {
189 .base_reg = MV64x60_CPU2PCI1_MEM_3_BASE,
190 .size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE,
191 .base_bits = 12,
192 .size_bits = 12,
193 .get_from_field = mv64x60_shift_left,
194 .map_to_field = mv64x60_shift_right,
195 .extra = 0 },
196 /* CPU->SRAM Window (64260 has no integrated SRAM) */
197 /* CPU->PCI 0 Remap I/O Window */
198 [MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
199 .base_reg = MV64x60_CPU2PCI0_IO_REMAP,
200 .size_reg = 0,
201 .base_bits = 12,
202 .size_bits = 0,
203 .get_from_field = mv64x60_shift_left,
204 .map_to_field = mv64x60_shift_right,
205 .extra = 0 },
206 /* CPU->PCI 1 Remap I/O Window */
207 [MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
208 .base_reg = MV64x60_CPU2PCI1_IO_REMAP,
209 .size_reg = 0,
210 .base_bits = 12,
211 .size_bits = 0,
212 .get_from_field = mv64x60_shift_left,
213 .map_to_field = mv64x60_shift_right,
214 .extra = 0 },
215 /* CPU Memory Protection Windows */
216 [MV64x60_CPU_PROT_0_WIN] = {
217 .base_reg = MV64x60_CPU_PROT_BASE_0,
218 .size_reg = MV64x60_CPU_PROT_SIZE_0,
219 .base_bits = 12,
220 .size_bits = 12,
221 .get_from_field = mv64x60_shift_left,
222 .map_to_field = mv64x60_shift_right,
223 .extra = 0 },
224 [MV64x60_CPU_PROT_1_WIN] = {
225 .base_reg = MV64x60_CPU_PROT_BASE_1,
226 .size_reg = MV64x60_CPU_PROT_SIZE_1,
227 .base_bits = 12,
228 .size_bits = 12,
229 .get_from_field = mv64x60_shift_left,
230 .map_to_field = mv64x60_shift_right,
231 .extra = 0 },
232 [MV64x60_CPU_PROT_2_WIN] = {
233 .base_reg = MV64x60_CPU_PROT_BASE_2,
234 .size_reg = MV64x60_CPU_PROT_SIZE_2,
235 .base_bits = 12,
236 .size_bits = 12,
237 .get_from_field = mv64x60_shift_left,
238 .map_to_field = mv64x60_shift_right,
239 .extra = 0 },
240 [MV64x60_CPU_PROT_3_WIN] = {
241 .base_reg = MV64x60_CPU_PROT_BASE_3,
242 .size_reg = MV64x60_CPU_PROT_SIZE_3,
243 .base_bits = 12,
244 .size_bits = 12,
245 .get_from_field = mv64x60_shift_left,
246 .map_to_field = mv64x60_shift_right,
247 .extra = 0 },
248 /* CPU Snoop Windows */
249 [MV64x60_CPU_SNOOP_0_WIN] = {
250 .base_reg = GT64260_CPU_SNOOP_BASE_0,
251 .size_reg = GT64260_CPU_SNOOP_SIZE_0,
252 .base_bits = 12,
253 .size_bits = 12,
254 .get_from_field = mv64x60_shift_left,
255 .map_to_field = mv64x60_shift_right,
256 .extra = 0 },
257 [MV64x60_CPU_SNOOP_1_WIN] = {
258 .base_reg = GT64260_CPU_SNOOP_BASE_1,
259 .size_reg = GT64260_CPU_SNOOP_SIZE_1,
260 .base_bits = 12,
261 .size_bits = 12,
262 .get_from_field = mv64x60_shift_left,
263 .map_to_field = mv64x60_shift_right,
264 .extra = 0 },
265 [MV64x60_CPU_SNOOP_2_WIN] = {
266 .base_reg = GT64260_CPU_SNOOP_BASE_2,
267 .size_reg = GT64260_CPU_SNOOP_SIZE_2,
268 .base_bits = 12,
269 .size_bits = 12,
270 .get_from_field = mv64x60_shift_left,
271 .map_to_field = mv64x60_shift_right,
272 .extra = 0 },
273 [MV64x60_CPU_SNOOP_3_WIN] = {
274 .base_reg = GT64260_CPU_SNOOP_BASE_3,
275 .size_reg = GT64260_CPU_SNOOP_SIZE_3,
276 .base_bits = 12,
277 .size_bits = 12,
278 .get_from_field = mv64x60_shift_left,
279 .map_to_field = mv64x60_shift_right,
280 .extra = 0 },
281 /* PCI 0->System Memory Remap Windows */
282 [MV64x60_PCI02MEM_REMAP_0_WIN] = {
283 .base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
284 .size_reg = 0,
285 .base_bits = 20,
286 .size_bits = 0,
287 .get_from_field = mv64x60_mask,
288 .map_to_field = mv64x60_mask,
289 .extra = 0 },
290 [MV64x60_PCI02MEM_REMAP_1_WIN] = {
291 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
292 .size_reg = 0,
293 .base_bits = 20,
294 .size_bits = 0,
295 .get_from_field = mv64x60_mask,
296 .map_to_field = mv64x60_mask,
297 .extra = 0 },
298 [MV64x60_PCI02MEM_REMAP_2_WIN] = {
299 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
300 .size_reg = 0,
301 .base_bits = 20,
302 .size_bits = 0,
303 .get_from_field = mv64x60_mask,
304 .map_to_field = mv64x60_mask,
305 .extra = 0 },
306 [MV64x60_PCI02MEM_REMAP_3_WIN] = {
307 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
308 .size_reg = 0,
309 .base_bits = 20,
310 .size_bits = 0,
311 .get_from_field = mv64x60_mask,
312 .map_to_field = mv64x60_mask,
313 .extra = 0 },
314 /* PCI 1->System Memory Remap Windows */
315 [MV64x60_PCI12MEM_REMAP_0_WIN] = {
316 .base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
317 .size_reg = 0,
318 .base_bits = 20,
319 .size_bits = 0,
320 .get_from_field = mv64x60_mask,
321 .map_to_field = mv64x60_mask,
322 .extra = 0 },
323 [MV64x60_PCI12MEM_REMAP_1_WIN] = {
324 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
325 .size_reg = 0,
326 .base_bits = 20,
327 .size_bits = 0,
328 .get_from_field = mv64x60_mask,
329 .map_to_field = mv64x60_mask,
330 .extra = 0 },
331 [MV64x60_PCI12MEM_REMAP_2_WIN] = {
332 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
333 .size_reg = 0,
334 .base_bits = 20,
335 .size_bits = 0,
336 .get_from_field = mv64x60_mask,
337 .map_to_field = mv64x60_mask,
338 .extra = 0 },
339 [MV64x60_PCI12MEM_REMAP_3_WIN] = {
340 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
341 .size_reg = 0,
342 .base_bits = 20,
343 .size_bits = 0,
344 .get_from_field = mv64x60_mask,
345 .map_to_field = mv64x60_mask,
346 .extra = 0 },
347 /* ENET->SRAM Window (64260 doesn't have separate windows) */
348 /* MPSC->SRAM Window (64260 doesn't have separate windows) */
349 /* IDMA->SRAM Window (64260 doesn't have separate windows) */
350};
351
352struct mv64x60_64bit_window
353 gt64260_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
354 /* CPU->PCI 0 MEM Remap Windows */
355 [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
356 .base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
357 .base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
358 .size_reg = 0,
359 .base_lo_bits = 12,
360 .size_bits = 0,
361 .get_from_field = mv64x60_shift_left,
362 .map_to_field = mv64x60_shift_right,
363 .extra = 0 },
364 [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
365 .base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
366 .base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
367 .size_reg = 0,
368 .base_lo_bits = 12,
369 .size_bits = 0,
370 .get_from_field = mv64x60_shift_left,
371 .map_to_field = mv64x60_shift_right,
372 .extra = 0 },
373 [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
374 .base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
375 .base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
376 .size_reg = 0,
377 .base_lo_bits = 12,
378 .size_bits = 0,
379 .get_from_field = mv64x60_shift_left,
380 .map_to_field = mv64x60_shift_right,
381 .extra = 0 },
382 [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
383 .base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
384 .base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
385 .size_reg = 0,
386 .base_lo_bits = 12,
387 .size_bits = 0,
388 .get_from_field = mv64x60_shift_left,
389 .map_to_field = mv64x60_shift_right,
390 .extra = 0 },
391 /* CPU->PCI 1 MEM Remap Windows */
392 [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
393 .base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
394 .base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
395 .size_reg = 0,
396 .base_lo_bits = 12,
397 .size_bits = 0,
398 .get_from_field = mv64x60_shift_left,
399 .map_to_field = mv64x60_shift_right,
400 .extra = 0 },
401 [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
402 .base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
403 .base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
404 .size_reg = 0,
405 .base_lo_bits = 12,
406 .size_bits = 0,
407 .get_from_field = mv64x60_shift_left,
408 .map_to_field = mv64x60_shift_right,
409 .extra = 0 },
410 [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
411 .base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
412 .base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
413 .size_reg = 0,
414 .base_lo_bits = 12,
415 .size_bits = 0,
416 .get_from_field = mv64x60_shift_left,
417 .map_to_field = mv64x60_shift_right,
418 .extra = 0 },
419 [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
420 .base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
421 .base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
422 .size_reg = 0,
423 .base_lo_bits = 12,
424 .size_bits = 0,
425 .get_from_field = mv64x60_shift_left,
426 .map_to_field = mv64x60_shift_right,
427 .extra = 0 },
428 /* PCI 0->MEM Access Control Windows */
429 [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
430 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
431 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
432 .size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE,
433 .base_lo_bits = 12,
434 .size_bits = 12,
435 .get_from_field = mv64x60_shift_left,
436 .map_to_field = mv64x60_shift_right,
437 .extra = 0 },
438 [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
439 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
440 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
441 .size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE,
442 .base_lo_bits = 12,
443 .size_bits = 12,
444 .get_from_field = mv64x60_shift_left,
445 .map_to_field = mv64x60_shift_right,
446 .extra = 0 },
447 [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
448 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
449 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
450 .size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE,
451 .base_lo_bits = 12,
452 .size_bits = 12,
453 .get_from_field = mv64x60_shift_left,
454 .map_to_field = mv64x60_shift_right,
455 .extra = 0 },
456 [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
457 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
458 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
459 .size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE,
460 .base_lo_bits = 12,
461 .size_bits = 12,
462 .get_from_field = mv64x60_shift_left,
463 .map_to_field = mv64x60_shift_right,
464 .extra = 0 },
465 /* PCI 1->MEM Access Control Windows */
466 [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
467 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
468 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
469 .size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE,
470 .base_lo_bits = 12,
471 .size_bits = 12,
472 .get_from_field = mv64x60_shift_left,
473 .map_to_field = mv64x60_shift_right,
474 .extra = 0 },
475 [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
476 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
477 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
478 .size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE,
479 .base_lo_bits = 12,
480 .size_bits = 12,
481 .get_from_field = mv64x60_shift_left,
482 .map_to_field = mv64x60_shift_right,
483 .extra = 0 },
484 [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
485 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
486 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
487 .size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE,
488 .base_lo_bits = 12,
489 .size_bits = 12,
490 .get_from_field = mv64x60_shift_left,
491 .map_to_field = mv64x60_shift_right,
492 .extra = 0 },
493 [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
494 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
495 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
496 .size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE,
497 .base_lo_bits = 12,
498 .size_bits = 12,
499 .get_from_field = mv64x60_shift_left,
500 .map_to_field = mv64x60_shift_right,
501 .extra = 0 },
502 /* PCI 0->MEM Snoop Windows */
503 [MV64x60_PCI02MEM_SNOOP_0_WIN] = {
504 .base_hi_reg = GT64260_PCI0_SNOOP_0_BASE_HI,
505 .base_lo_reg = GT64260_PCI0_SNOOP_0_BASE_LO,
506 .size_reg = GT64260_PCI0_SNOOP_0_SIZE,
507 .base_lo_bits = 12,
508 .size_bits = 12,
509 .get_from_field = mv64x60_shift_left,
510 .map_to_field = mv64x60_shift_right,
511 .extra = 0 },
512 [MV64x60_PCI02MEM_SNOOP_1_WIN] = {
513 .base_hi_reg = GT64260_PCI0_SNOOP_1_BASE_HI,
514 .base_lo_reg = GT64260_PCI0_SNOOP_1_BASE_LO,
515 .size_reg = GT64260_PCI0_SNOOP_1_SIZE,
516 .base_lo_bits = 12,
517 .size_bits = 12,
518 .get_from_field = mv64x60_shift_left,
519 .map_to_field = mv64x60_shift_right,
520 .extra = 0 },
521 [MV64x60_PCI02MEM_SNOOP_2_WIN] = {
522 .base_hi_reg = GT64260_PCI0_SNOOP_2_BASE_HI,
523 .base_lo_reg = GT64260_PCI0_SNOOP_2_BASE_LO,
524 .size_reg = GT64260_PCI0_SNOOP_2_SIZE,
525 .base_lo_bits = 12,
526 .size_bits = 12,
527 .get_from_field = mv64x60_shift_left,
528 .map_to_field = mv64x60_shift_right,
529 .extra = 0 },
530 [MV64x60_PCI02MEM_SNOOP_3_WIN] = {
531 .base_hi_reg = GT64260_PCI0_SNOOP_3_BASE_HI,
532 .base_lo_reg = GT64260_PCI0_SNOOP_3_BASE_LO,
533 .size_reg = GT64260_PCI0_SNOOP_3_SIZE,
534 .base_lo_bits = 12,
535 .size_bits = 12,
536 .get_from_field = mv64x60_shift_left,
537 .map_to_field = mv64x60_shift_right,
538 .extra = 0 },
539 /* PCI 1->MEM Snoop Windows */
540 [MV64x60_PCI12MEM_SNOOP_0_WIN] = {
541 .base_hi_reg = GT64260_PCI1_SNOOP_0_BASE_HI,
542 .base_lo_reg = GT64260_PCI1_SNOOP_0_BASE_LO,
543 .size_reg = GT64260_PCI1_SNOOP_0_SIZE,
544 .base_lo_bits = 12,
545 .size_bits = 12,
546 .get_from_field = mv64x60_shift_left,
547 .map_to_field = mv64x60_shift_right,
548 .extra = 0 },
549 [MV64x60_PCI12MEM_SNOOP_1_WIN] = {
550 .base_hi_reg = GT64260_PCI1_SNOOP_1_BASE_HI,
551 .base_lo_reg = GT64260_PCI1_SNOOP_1_BASE_LO,
552 .size_reg = GT64260_PCI1_SNOOP_1_SIZE,
553 .base_lo_bits = 12,
554 .size_bits = 12,
555 .get_from_field = mv64x60_shift_left,
556 .map_to_field = mv64x60_shift_right,
557 .extra = 0 },
558 [MV64x60_PCI12MEM_SNOOP_2_WIN] = {
559 .base_hi_reg = GT64260_PCI1_SNOOP_2_BASE_HI,
560 .base_lo_reg = GT64260_PCI1_SNOOP_2_BASE_LO,
561 .size_reg = GT64260_PCI1_SNOOP_2_SIZE,
562 .base_lo_bits = 12,
563 .size_bits = 12,
564 .get_from_field = mv64x60_shift_left,
565 .map_to_field = mv64x60_shift_right,
566 .extra = 0 },
567 [MV64x60_PCI12MEM_SNOOP_3_WIN] = {
568 .base_hi_reg = GT64260_PCI1_SNOOP_3_BASE_HI,
569 .base_lo_reg = GT64260_PCI1_SNOOP_3_BASE_LO,
570 .size_reg = GT64260_PCI1_SNOOP_3_SIZE,
571 .base_lo_bits = 12,
572 .size_bits = 12,
573 .get_from_field = mv64x60_shift_left,
574 .map_to_field = mv64x60_shift_right,
575 .extra = 0 },
576};
577
578struct mv64x60_32bit_window
579 mv64360_32bit_windows[MV64x60_32BIT_WIN_COUNT] __initdata = {
580 /* CPU->MEM Windows */
581 [MV64x60_CPU2MEM_0_WIN] = {
582 .base_reg = MV64x60_CPU2MEM_0_BASE,
583 .size_reg = MV64x60_CPU2MEM_0_SIZE,
584 .base_bits = 16,
585 .size_bits = 16,
586 .get_from_field = mv64x60_shift_left,
587 .map_to_field = mv64x60_shift_right,
588 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 0 },
589 [MV64x60_CPU2MEM_1_WIN] = {
590 .base_reg = MV64x60_CPU2MEM_1_BASE,
591 .size_reg = MV64x60_CPU2MEM_1_SIZE,
592 .base_bits = 16,
593 .size_bits = 16,
594 .get_from_field = mv64x60_shift_left,
595 .map_to_field = mv64x60_shift_right,
596 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 1 },
597 [MV64x60_CPU2MEM_2_WIN] = {
598 .base_reg = MV64x60_CPU2MEM_2_BASE,
599 .size_reg = MV64x60_CPU2MEM_2_SIZE,
600 .base_bits = 16,
601 .size_bits = 16,
602 .get_from_field = mv64x60_shift_left,
603 .map_to_field = mv64x60_shift_right,
604 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 2 },
605 [MV64x60_CPU2MEM_3_WIN] = {
606 .base_reg = MV64x60_CPU2MEM_3_BASE,
607 .size_reg = MV64x60_CPU2MEM_3_SIZE,
608 .base_bits = 16,
609 .size_bits = 16,
610 .get_from_field = mv64x60_shift_left,
611 .map_to_field = mv64x60_shift_right,
612 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 3 },
613 /* CPU->Device Windows */
614 [MV64x60_CPU2DEV_0_WIN] = {
615 .base_reg = MV64x60_CPU2DEV_0_BASE,
616 .size_reg = MV64x60_CPU2DEV_0_SIZE,
617 .base_bits = 16,
618 .size_bits = 16,
619 .get_from_field = mv64x60_shift_left,
620 .map_to_field = mv64x60_shift_right,
621 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 4 },
622 [MV64x60_CPU2DEV_1_WIN] = {
623 .base_reg = MV64x60_CPU2DEV_1_BASE,
624 .size_reg = MV64x60_CPU2DEV_1_SIZE,
625 .base_bits = 16,
626 .size_bits = 16,
627 .get_from_field = mv64x60_shift_left,
628 .map_to_field = mv64x60_shift_right,
629 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 5 },
630 [MV64x60_CPU2DEV_2_WIN] = {
631 .base_reg = MV64x60_CPU2DEV_2_BASE,
632 .size_reg = MV64x60_CPU2DEV_2_SIZE,
633 .base_bits = 16,
634 .size_bits = 16,
635 .get_from_field = mv64x60_shift_left,
636 .map_to_field = mv64x60_shift_right,
637 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 6 },
638 [MV64x60_CPU2DEV_3_WIN] = {
639 .base_reg = MV64x60_CPU2DEV_3_BASE,
640 .size_reg = MV64x60_CPU2DEV_3_SIZE,
641 .base_bits = 16,
642 .size_bits = 16,
643 .get_from_field = mv64x60_shift_left,
644 .map_to_field = mv64x60_shift_right,
645 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 7 },
646 /* CPU->Boot Window */
647 [MV64x60_CPU2BOOT_WIN] = {
648 .base_reg = MV64x60_CPU2BOOT_0_BASE,
649 .size_reg = MV64x60_CPU2BOOT_0_SIZE,
650 .base_bits = 16,
651 .size_bits = 16,
652 .get_from_field = mv64x60_shift_left,
653 .map_to_field = mv64x60_shift_right,
654 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 8 },
655 /* CPU->PCI 0 Windows */
656 [MV64x60_CPU2PCI0_IO_WIN] = {
657 .base_reg = MV64x60_CPU2PCI0_IO_BASE,
658 .size_reg = MV64x60_CPU2PCI0_IO_SIZE,
659 .base_bits = 16,
660 .size_bits = 16,
661 .get_from_field = mv64x60_shift_left,
662 .map_to_field = mv64x60_shift_right,
663 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 9 },
664 [MV64x60_CPU2PCI0_MEM_0_WIN] = {
665 .base_reg = MV64x60_CPU2PCI0_MEM_0_BASE,
666 .size_reg = MV64x60_CPU2PCI0_MEM_0_SIZE,
667 .base_bits = 16,
668 .size_bits = 16,
669 .get_from_field = mv64x60_shift_left,
670 .map_to_field = mv64x60_shift_right,
671 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 10 },
672 [MV64x60_CPU2PCI0_MEM_1_WIN] = {
673 .base_reg = MV64x60_CPU2PCI0_MEM_1_BASE,
674 .size_reg = MV64x60_CPU2PCI0_MEM_1_SIZE,
675 .base_bits = 16,
676 .size_bits = 16,
677 .get_from_field = mv64x60_shift_left,
678 .map_to_field = mv64x60_shift_right,
679 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 11 },
680 [MV64x60_CPU2PCI0_MEM_2_WIN] = {
681 .base_reg = MV64x60_CPU2PCI0_MEM_2_BASE,
682 .size_reg = MV64x60_CPU2PCI0_MEM_2_SIZE,
683 .base_bits = 16,
684 .size_bits = 16,
685 .get_from_field = mv64x60_shift_left,
686 .map_to_field = mv64x60_shift_right,
687 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 12 },
688 [MV64x60_CPU2PCI0_MEM_3_WIN] = {
689 .base_reg = MV64x60_CPU2PCI0_MEM_3_BASE,
690 .size_reg = MV64x60_CPU2PCI0_MEM_3_SIZE,
691 .base_bits = 16,
692 .size_bits = 16,
693 .get_from_field = mv64x60_shift_left,
694 .map_to_field = mv64x60_shift_right,
695 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 13 },
696 /* CPU->PCI 1 Windows */
697 [MV64x60_CPU2PCI1_IO_WIN] = {
698 .base_reg = MV64x60_CPU2PCI1_IO_BASE,
699 .size_reg = MV64x60_CPU2PCI1_IO_SIZE,
700 .base_bits = 16,
701 .size_bits = 16,
702 .get_from_field = mv64x60_shift_left,
703 .map_to_field = mv64x60_shift_right,
704 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 14 },
705 [MV64x60_CPU2PCI1_MEM_0_WIN] = {
706 .base_reg = MV64x60_CPU2PCI1_MEM_0_BASE,
707 .size_reg = MV64x60_CPU2PCI1_MEM_0_SIZE,
708 .base_bits = 16,
709 .size_bits = 16,
710 .get_from_field = mv64x60_shift_left,
711 .map_to_field = mv64x60_shift_right,
712 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 15 },
713 [MV64x60_CPU2PCI1_MEM_1_WIN] = {
714 .base_reg = MV64x60_CPU2PCI1_MEM_1_BASE,
715 .size_reg = MV64x60_CPU2PCI1_MEM_1_SIZE,
716 .base_bits = 16,
717 .size_bits = 16,
718 .get_from_field = mv64x60_shift_left,
719 .map_to_field = mv64x60_shift_right,
720 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 16 },
721 [MV64x60_CPU2PCI1_MEM_2_WIN] = {
722 .base_reg = MV64x60_CPU2PCI1_MEM_2_BASE,
723 .size_reg = MV64x60_CPU2PCI1_MEM_2_SIZE,
724 .base_bits = 16,
725 .size_bits = 16,
726 .get_from_field = mv64x60_shift_left,
727 .map_to_field = mv64x60_shift_right,
728 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 17 },
729 [MV64x60_CPU2PCI1_MEM_3_WIN] = {
730 .base_reg = MV64x60_CPU2PCI1_MEM_3_BASE,
731 .size_reg = MV64x60_CPU2PCI1_MEM_3_SIZE,
732 .base_bits = 16,
733 .size_bits = 16,
734 .get_from_field = mv64x60_shift_left,
735 .map_to_field = mv64x60_shift_right,
736 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 18 },
737 /* CPU->SRAM Window */
738 [MV64x60_CPU2SRAM_WIN] = {
739 .base_reg = MV64360_CPU2SRAM_BASE,
740 .size_reg = 0,
741 .base_bits = 16,
742 .size_bits = 0,
743 .get_from_field = mv64x60_shift_left,
744 .map_to_field = mv64x60_shift_right,
745 .extra = MV64x60_EXTRA_CPUWIN_ENAB | 19 },
746 /* CPU->PCI 0 Remap I/O Window */
747 [MV64x60_CPU2PCI0_IO_REMAP_WIN] = {
748 .base_reg = MV64x60_CPU2PCI0_IO_REMAP,
749 .size_reg = 0,
750 .base_bits = 16,
751 .size_bits = 0,
752 .get_from_field = mv64x60_shift_left,
753 .map_to_field = mv64x60_shift_right,
754 .extra = 0 },
755 /* CPU->PCI 1 Remap I/O Window */
756 [MV64x60_CPU2PCI1_IO_REMAP_WIN] = {
757 .base_reg = MV64x60_CPU2PCI1_IO_REMAP,
758 .size_reg = 0,
759 .base_bits = 16,
760 .size_bits = 0,
761 .get_from_field = mv64x60_shift_left,
762 .map_to_field = mv64x60_shift_right,
763 .extra = 0 },
764 /* CPU Memory Protection Windows */
765 [MV64x60_CPU_PROT_0_WIN] = {
766 .base_reg = MV64x60_CPU_PROT_BASE_0,
767 .size_reg = MV64x60_CPU_PROT_SIZE_0,
768 .base_bits = 16,
769 .size_bits = 16,
770 .get_from_field = mv64x60_shift_left,
771 .map_to_field = mv64x60_shift_right,
772 .extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
773 [MV64x60_CPU_PROT_1_WIN] = {
774 .base_reg = MV64x60_CPU_PROT_BASE_1,
775 .size_reg = MV64x60_CPU_PROT_SIZE_1,
776 .base_bits = 16,
777 .size_bits = 16,
778 .get_from_field = mv64x60_shift_left,
779 .map_to_field = mv64x60_shift_right,
780 .extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
781 [MV64x60_CPU_PROT_2_WIN] = {
782 .base_reg = MV64x60_CPU_PROT_BASE_2,
783 .size_reg = MV64x60_CPU_PROT_SIZE_2,
784 .base_bits = 16,
785 .size_bits = 16,
786 .get_from_field = mv64x60_shift_left,
787 .map_to_field = mv64x60_shift_right,
788 .extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
789 [MV64x60_CPU_PROT_3_WIN] = {
790 .base_reg = MV64x60_CPU_PROT_BASE_3,
791 .size_reg = MV64x60_CPU_PROT_SIZE_3,
792 .base_bits = 16,
793 .size_bits = 16,
794 .get_from_field = mv64x60_shift_left,
795 .map_to_field = mv64x60_shift_right,
796 .extra = MV64x60_EXTRA_CPUPROT_ENAB | 31 },
797 /* CPU Snoop Windows -- don't exist on 64360 */
798 /* PCI 0->System Memory Remap Windows */
799 [MV64x60_PCI02MEM_REMAP_0_WIN] = {
800 .base_reg = MV64x60_PCI0_SLAVE_MEM_0_REMAP,
801 .size_reg = 0,
802 .base_bits = 20,
803 .size_bits = 0,
804 .get_from_field = mv64x60_mask,
805 .map_to_field = mv64x60_mask,
806 .extra = 0 },
807 [MV64x60_PCI02MEM_REMAP_1_WIN] = {
808 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
809 .size_reg = 0,
810 .base_bits = 20,
811 .size_bits = 0,
812 .get_from_field = mv64x60_mask,
813 .map_to_field = mv64x60_mask,
814 .extra = 0 },
815 [MV64x60_PCI02MEM_REMAP_2_WIN] = {
816 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
817 .size_reg = 0,
818 .base_bits = 20,
819 .size_bits = 0,
820 .get_from_field = mv64x60_mask,
821 .map_to_field = mv64x60_mask,
822 .extra = 0 },
823 [MV64x60_PCI02MEM_REMAP_3_WIN] = {
824 .base_reg = MV64x60_PCI0_SLAVE_MEM_1_REMAP,
825 .size_reg = 0,
826 .base_bits = 20,
827 .size_bits = 0,
828 .get_from_field = mv64x60_mask,
829 .map_to_field = mv64x60_mask,
830 .extra = 0 },
831 /* PCI 1->System Memory Remap Windows */
832 [MV64x60_PCI12MEM_REMAP_0_WIN] = {
833 .base_reg = MV64x60_PCI1_SLAVE_MEM_0_REMAP,
834 .size_reg = 0,
835 .base_bits = 20,
836 .size_bits = 0,
837 .get_from_field = mv64x60_mask,
838 .map_to_field = mv64x60_mask,
839 .extra = 0 },
840 [MV64x60_PCI12MEM_REMAP_1_WIN] = {
841 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
842 .size_reg = 0,
843 .base_bits = 20,
844 .size_bits = 0,
845 .get_from_field = mv64x60_mask,
846 .map_to_field = mv64x60_mask,
847 .extra = 0 },
848 [MV64x60_PCI12MEM_REMAP_2_WIN] = {
849 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
850 .size_reg = 0,
851 .base_bits = 20,
852 .size_bits = 0,
853 .get_from_field = mv64x60_mask,
854 .map_to_field = mv64x60_mask,
855 .extra = 0 },
856 [MV64x60_PCI12MEM_REMAP_3_WIN] = {
857 .base_reg = MV64x60_PCI1_SLAVE_MEM_1_REMAP,
858 .size_reg = 0,
859 .base_bits = 20,
860 .size_bits = 0,
861 .get_from_field = mv64x60_mask,
862 .map_to_field = mv64x60_mask,
863 .extra = 0 },
864 /* ENET->System Memory Windows */
865 [MV64x60_ENET2MEM_0_WIN] = {
866 .base_reg = MV64360_ENET2MEM_0_BASE,
867 .size_reg = MV64360_ENET2MEM_0_SIZE,
868 .base_bits = 16,
869 .size_bits = 16,
870 .get_from_field = mv64x60_mask,
871 .map_to_field = mv64x60_mask,
872 .extra = MV64x60_EXTRA_ENET_ENAB | 0 },
873 [MV64x60_ENET2MEM_1_WIN] = {
874 .base_reg = MV64360_ENET2MEM_1_BASE,
875 .size_reg = MV64360_ENET2MEM_1_SIZE,
876 .base_bits = 16,
877 .size_bits = 16,
878 .get_from_field = mv64x60_mask,
879 .map_to_field = mv64x60_mask,
880 .extra = MV64x60_EXTRA_ENET_ENAB | 1 },
881 [MV64x60_ENET2MEM_2_WIN] = {
882 .base_reg = MV64360_ENET2MEM_2_BASE,
883 .size_reg = MV64360_ENET2MEM_2_SIZE,
884 .base_bits = 16,
885 .size_bits = 16,
886 .get_from_field = mv64x60_mask,
887 .map_to_field = mv64x60_mask,
888 .extra = MV64x60_EXTRA_ENET_ENAB | 2 },
889 [MV64x60_ENET2MEM_3_WIN] = {
890 .base_reg = MV64360_ENET2MEM_3_BASE,
891 .size_reg = MV64360_ENET2MEM_3_SIZE,
892 .base_bits = 16,
893 .size_bits = 16,
894 .get_from_field = mv64x60_mask,
895 .map_to_field = mv64x60_mask,
896 .extra = MV64x60_EXTRA_ENET_ENAB | 3 },
897 [MV64x60_ENET2MEM_4_WIN] = {
898 .base_reg = MV64360_ENET2MEM_4_BASE,
899 .size_reg = MV64360_ENET2MEM_4_SIZE,
900 .base_bits = 16,
901 .size_bits = 16,
902 .get_from_field = mv64x60_mask,
903 .map_to_field = mv64x60_mask,
904 .extra = MV64x60_EXTRA_ENET_ENAB | 4 },
905 [MV64x60_ENET2MEM_5_WIN] = {
906 .base_reg = MV64360_ENET2MEM_5_BASE,
907 .size_reg = MV64360_ENET2MEM_5_SIZE,
908 .base_bits = 16,
909 .size_bits = 16,
910 .get_from_field = mv64x60_mask,
911 .map_to_field = mv64x60_mask,
912 .extra = MV64x60_EXTRA_ENET_ENAB | 5 },
913 /* MPSC->System Memory Windows */
914 [MV64x60_MPSC2MEM_0_WIN] = {
915 .base_reg = MV64360_MPSC2MEM_0_BASE,
916 .size_reg = MV64360_MPSC2MEM_0_SIZE,
917 .base_bits = 16,
918 .size_bits = 16,
919 .get_from_field = mv64x60_mask,
920 .map_to_field = mv64x60_mask,
921 .extra = MV64x60_EXTRA_MPSC_ENAB | 0 },
922 [MV64x60_MPSC2MEM_1_WIN] = {
923 .base_reg = MV64360_MPSC2MEM_1_BASE,
924 .size_reg = MV64360_MPSC2MEM_1_SIZE,
925 .base_bits = 16,
926 .size_bits = 16,
927 .get_from_field = mv64x60_mask,
928 .map_to_field = mv64x60_mask,
929 .extra = MV64x60_EXTRA_MPSC_ENAB | 1 },
930 [MV64x60_MPSC2MEM_2_WIN] = {
931 .base_reg = MV64360_MPSC2MEM_2_BASE,
932 .size_reg = MV64360_MPSC2MEM_2_SIZE,
933 .base_bits = 16,
934 .size_bits = 16,
935 .get_from_field = mv64x60_mask,
936 .map_to_field = mv64x60_mask,
937 .extra = MV64x60_EXTRA_MPSC_ENAB | 2 },
938 [MV64x60_MPSC2MEM_3_WIN] = {
939 .base_reg = MV64360_MPSC2MEM_3_BASE,
940 .size_reg = MV64360_MPSC2MEM_3_SIZE,
941 .base_bits = 16,
942 .size_bits = 16,
943 .get_from_field = mv64x60_mask,
944 .map_to_field = mv64x60_mask,
945 .extra = MV64x60_EXTRA_MPSC_ENAB | 3 },
946 /* IDMA->System Memory Windows */
947 [MV64x60_IDMA2MEM_0_WIN] = {
948 .base_reg = MV64360_IDMA2MEM_0_BASE,
949 .size_reg = MV64360_IDMA2MEM_0_SIZE,
950 .base_bits = 16,
951 .size_bits = 16,
952 .get_from_field = mv64x60_mask,
953 .map_to_field = mv64x60_mask,
954 .extra = MV64x60_EXTRA_IDMA_ENAB | 0 },
955 [MV64x60_IDMA2MEM_1_WIN] = {
956 .base_reg = MV64360_IDMA2MEM_1_BASE,
957 .size_reg = MV64360_IDMA2MEM_1_SIZE,
958 .base_bits = 16,
959 .size_bits = 16,
960 .get_from_field = mv64x60_mask,
961 .map_to_field = mv64x60_mask,
962 .extra = MV64x60_EXTRA_IDMA_ENAB | 1 },
963 [MV64x60_IDMA2MEM_2_WIN] = {
964 .base_reg = MV64360_IDMA2MEM_2_BASE,
965 .size_reg = MV64360_IDMA2MEM_2_SIZE,
966 .base_bits = 16,
967 .size_bits = 16,
968 .get_from_field = mv64x60_mask,
969 .map_to_field = mv64x60_mask,
970 .extra = MV64x60_EXTRA_IDMA_ENAB | 2 },
971 [MV64x60_IDMA2MEM_3_WIN] = {
972 .base_reg = MV64360_IDMA2MEM_3_BASE,
973 .size_reg = MV64360_IDMA2MEM_3_SIZE,
974 .base_bits = 16,
975 .size_bits = 16,
976 .get_from_field = mv64x60_mask,
977 .map_to_field = mv64x60_mask,
978 .extra = MV64x60_EXTRA_IDMA_ENAB | 3 },
979 [MV64x60_IDMA2MEM_4_WIN] = {
980 .base_reg = MV64360_IDMA2MEM_4_BASE,
981 .size_reg = MV64360_IDMA2MEM_4_SIZE,
982 .base_bits = 16,
983 .size_bits = 16,
984 .get_from_field = mv64x60_mask,
985 .map_to_field = mv64x60_mask,
986 .extra = MV64x60_EXTRA_IDMA_ENAB | 4 },
987 [MV64x60_IDMA2MEM_5_WIN] = {
988 .base_reg = MV64360_IDMA2MEM_5_BASE,
989 .size_reg = MV64360_IDMA2MEM_5_SIZE,
990 .base_bits = 16,
991 .size_bits = 16,
992 .get_from_field = mv64x60_mask,
993 .map_to_field = mv64x60_mask,
994 .extra = MV64x60_EXTRA_IDMA_ENAB | 5 },
995 [MV64x60_IDMA2MEM_6_WIN] = {
996 .base_reg = MV64360_IDMA2MEM_6_BASE,
997 .size_reg = MV64360_IDMA2MEM_6_SIZE,
998 .base_bits = 16,
999 .size_bits = 16,
1000 .get_from_field = mv64x60_mask,
1001 .map_to_field = mv64x60_mask,
1002 .extra = MV64x60_EXTRA_IDMA_ENAB | 6 },
1003 [MV64x60_IDMA2MEM_7_WIN] = {
1004 .base_reg = MV64360_IDMA2MEM_7_BASE,
1005 .size_reg = MV64360_IDMA2MEM_7_SIZE,
1006 .base_bits = 16,
1007 .size_bits = 16,
1008 .get_from_field = mv64x60_mask,
1009 .map_to_field = mv64x60_mask,
1010 .extra = MV64x60_EXTRA_IDMA_ENAB | 7 },
1011};
1012
1013struct mv64x60_64bit_window
1014 mv64360_64bit_windows[MV64x60_64BIT_WIN_COUNT] __initdata = {
1015 /* CPU->PCI 0 MEM Remap Windows */
1016 [MV64x60_CPU2PCI0_MEM_0_REMAP_WIN] = {
1017 .base_hi_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
1018 .base_lo_reg = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
1019 .size_reg = 0,
1020 .base_lo_bits = 16,
1021 .size_bits = 0,
1022 .get_from_field = mv64x60_shift_left,
1023 .map_to_field = mv64x60_shift_right,
1024 .extra = 0 },
1025 [MV64x60_CPU2PCI0_MEM_1_REMAP_WIN] = {
1026 .base_hi_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_HI,
1027 .base_lo_reg = MV64x60_CPU2PCI0_MEM_1_REMAP_LO,
1028 .size_reg = 0,
1029 .base_lo_bits = 16,
1030 .size_bits = 0,
1031 .get_from_field = mv64x60_shift_left,
1032 .map_to_field = mv64x60_shift_right,
1033 .extra = 0 },
1034 [MV64x60_CPU2PCI0_MEM_2_REMAP_WIN] = {
1035 .base_hi_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_HI,
1036 .base_lo_reg = MV64x60_CPU2PCI0_MEM_2_REMAP_LO,
1037 .size_reg = 0,
1038 .base_lo_bits = 16,
1039 .size_bits = 0,
1040 .get_from_field = mv64x60_shift_left,
1041 .map_to_field = mv64x60_shift_right,
1042 .extra = 0 },
1043 [MV64x60_CPU2PCI0_MEM_3_REMAP_WIN] = {
1044 .base_hi_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_HI,
1045 .base_lo_reg = MV64x60_CPU2PCI0_MEM_3_REMAP_LO,
1046 .size_reg = 0,
1047 .base_lo_bits = 16,
1048 .size_bits = 0,
1049 .get_from_field = mv64x60_shift_left,
1050 .map_to_field = mv64x60_shift_right,
1051 .extra = 0 },
1052 /* CPU->PCI 1 MEM Remap Windows */
1053 [MV64x60_CPU2PCI1_MEM_0_REMAP_WIN] = {
1054 .base_hi_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
1055 .base_lo_reg = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
1056 .size_reg = 0,
1057 .base_lo_bits = 16,
1058 .size_bits = 0,
1059 .get_from_field = mv64x60_shift_left,
1060 .map_to_field = mv64x60_shift_right,
1061 .extra = 0 },
1062 [MV64x60_CPU2PCI1_MEM_1_REMAP_WIN] = {
1063 .base_hi_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_HI,
1064 .base_lo_reg = MV64x60_CPU2PCI1_MEM_1_REMAP_LO,
1065 .size_reg = 0,
1066 .base_lo_bits = 16,
1067 .size_bits = 0,
1068 .get_from_field = mv64x60_shift_left,
1069 .map_to_field = mv64x60_shift_right,
1070 .extra = 0 },
1071 [MV64x60_CPU2PCI1_MEM_2_REMAP_WIN] = {
1072 .base_hi_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_HI,
1073 .base_lo_reg = MV64x60_CPU2PCI1_MEM_2_REMAP_LO,
1074 .size_reg = 0,
1075 .base_lo_bits = 16,
1076 .size_bits = 0,
1077 .get_from_field = mv64x60_shift_left,
1078 .map_to_field = mv64x60_shift_right,
1079 .extra = 0 },
1080 [MV64x60_CPU2PCI1_MEM_3_REMAP_WIN] = {
1081 .base_hi_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_HI,
1082 .base_lo_reg = MV64x60_CPU2PCI1_MEM_3_REMAP_LO,
1083 .size_reg = 0,
1084 .base_lo_bits = 16,
1085 .size_bits = 0,
1086 .get_from_field = mv64x60_shift_left,
1087 .map_to_field = mv64x60_shift_right,
1088 .extra = 0 },
1089 /* PCI 0->MEM Access Control Windows */
1090 [MV64x60_PCI02MEM_ACC_CNTL_0_WIN] = {
1091 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
1092 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
1093 .size_reg = MV64x60_PCI0_ACC_CNTL_0_SIZE,
1094 .base_lo_bits = 20,
1095 .size_bits = 20,
1096 .get_from_field = mv64x60_mask,
1097 .map_to_field = mv64x60_mask,
1098 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1099 [MV64x60_PCI02MEM_ACC_CNTL_1_WIN] = {
1100 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
1101 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
1102 .size_reg = MV64x60_PCI0_ACC_CNTL_1_SIZE,
1103 .base_lo_bits = 20,
1104 .size_bits = 20,
1105 .get_from_field = mv64x60_mask,
1106 .map_to_field = mv64x60_mask,
1107 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1108 [MV64x60_PCI02MEM_ACC_CNTL_2_WIN] = {
1109 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
1110 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
1111 .size_reg = MV64x60_PCI0_ACC_CNTL_2_SIZE,
1112 .base_lo_bits = 20,
1113 .size_bits = 20,
1114 .get_from_field = mv64x60_mask,
1115 .map_to_field = mv64x60_mask,
1116 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1117 [MV64x60_PCI02MEM_ACC_CNTL_3_WIN] = {
1118 .base_hi_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
1119 .base_lo_reg = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
1120 .size_reg = MV64x60_PCI0_ACC_CNTL_3_SIZE,
1121 .base_lo_bits = 20,
1122 .size_bits = 20,
1123 .get_from_field = mv64x60_mask,
1124 .map_to_field = mv64x60_mask,
1125 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1126 /* PCI 1->MEM Access Control Windows */
1127 [MV64x60_PCI12MEM_ACC_CNTL_0_WIN] = {
1128 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
1129 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
1130 .size_reg = MV64x60_PCI1_ACC_CNTL_0_SIZE,
1131 .base_lo_bits = 20,
1132 .size_bits = 20,
1133 .get_from_field = mv64x60_mask,
1134 .map_to_field = mv64x60_mask,
1135 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1136 [MV64x60_PCI12MEM_ACC_CNTL_1_WIN] = {
1137 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
1138 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
1139 .size_reg = MV64x60_PCI1_ACC_CNTL_1_SIZE,
1140 .base_lo_bits = 20,
1141 .size_bits = 20,
1142 .get_from_field = mv64x60_mask,
1143 .map_to_field = mv64x60_mask,
1144 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1145 [MV64x60_PCI12MEM_ACC_CNTL_2_WIN] = {
1146 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
1147 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
1148 .size_reg = MV64x60_PCI1_ACC_CNTL_2_SIZE,
1149 .base_lo_bits = 20,
1150 .size_bits = 20,
1151 .get_from_field = mv64x60_mask,
1152 .map_to_field = mv64x60_mask,
1153 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1154 [MV64x60_PCI12MEM_ACC_CNTL_3_WIN] = {
1155 .base_hi_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
1156 .base_lo_reg = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
1157 .size_reg = MV64x60_PCI1_ACC_CNTL_3_SIZE,
1158 .base_lo_bits = 20,
1159 .size_bits = 20,
1160 .get_from_field = mv64x60_mask,
1161 .map_to_field = mv64x60_mask,
1162 .extra = MV64x60_EXTRA_PCIACC_ENAB | 0 },
1163 /* PCI 0->MEM Snoop Windows -- don't exist on 64360 */
1164 /* PCI 1->MEM Snoop Windows -- don't exist on 64360 */
1165};
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
deleted file mode 100644
index a6fb7dcfa738..000000000000
--- a/arch/ppc/syslib/ocp.c
+++ /dev/null
@@ -1,482 +0,0 @@
1/*
2 * ocp.c
3 *
4 * (c) Benjamin Herrenschmidt (benh@kernel.crashing.org)
5 * Mipsys - France
6 *
7 * Derived from work (c) Armin Kuster akuster@pacbell.net
8 *
9 * Additional support and port to 2.6 LDM/sysfs by
10 * Matt Porter <mporter@kernel.crashing.org>
11 * Copyright 2004 MontaVista Software, Inc.
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 * OCP (On Chip Peripheral) is a software emulated "bus" with a
19 * pseudo discovery method for dumb peripherals. Usually these type
20 * of peripherals are found on embedded SoC (System On a Chip)
21 * processors or highly integrated system controllers that have
22 * a host bridge and many peripherals. Common examples where
23 * this is already used include the PPC4xx, MPC52xx,
24 * and MV64xxx parts.
25 *
26 * This subsystem creates a standard OCP bus type within the
27 * device model. The devices on the OCP bus are seeded by an
28 * an initial OCP device array created by the arch-specific
29 * Device entries can be added/removed/modified through OCP
30 * helper functions to accommodate system and board-specific
31 * parameters commonly found in embedded systems. OCP also
32 * provides a standard method for devices to describe extended
33 * attributes about themselves to the system. A standard access
34 * method allows OCP drivers to obtain the information, both
35 * SoC-specific and system/board-specific, needed for operation.
36 */
37
38#include <linux/module.h>
39#include <linux/list.h>
40#include <linux/miscdevice.h>
41#include <linux/slab.h>
42#include <linux/types.h>
43#include <linux/init.h>
44#include <linux/pm.h>
45#include <linux/bootmem.h>
46#include <linux/device.h>
47#include <linux/rwsem.h>
48
49#include <asm/io.h>
50#include <asm/ocp.h>
51#include <asm/errno.h>
52
53//#define DBG(x) printk x
54#define DBG(x)
55
56extern int mem_init_done;
57
58extern struct ocp_def core_ocp[]; /* Static list of devices, provided by
59 CPU core */
60
61LIST_HEAD(ocp_devices); /* List of all OCP devices */
62DECLARE_RWSEM(ocp_devices_sem); /* Global semaphores for those lists */
63
64static int ocp_inited;
65
66/* Sysfs support */
67#define OCP_DEF_ATTR(field, format_string) \
68static ssize_t \
69show_##field(struct device *dev, struct device_attribute *attr, char *buf) \
70{ \
71 struct ocp_device *odev = to_ocp_dev(dev); \
72 \
73 return sprintf(buf, format_string, odev->def->field); \
74} \
75static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
76
77OCP_DEF_ATTR(vendor, "0x%04x\n");
78OCP_DEF_ATTR(function, "0x%04x\n");
79OCP_DEF_ATTR(index, "0x%04x\n");
80#ifdef CONFIG_PTE_64BIT
81OCP_DEF_ATTR(paddr, "0x%016Lx\n");
82#else
83OCP_DEF_ATTR(paddr, "0x%08lx\n");
84#endif
85OCP_DEF_ATTR(irq, "%d\n");
86OCP_DEF_ATTR(pm, "%lu\n");
87
88void ocp_create_sysfs_dev_files(struct ocp_device *odev)
89{
90 struct device *dev = &odev->dev;
91
92 /* Current OCP device def attributes */
93 device_create_file(dev, &dev_attr_vendor);
94 device_create_file(dev, &dev_attr_function);
95 device_create_file(dev, &dev_attr_index);
96 device_create_file(dev, &dev_attr_paddr);
97 device_create_file(dev, &dev_attr_irq);
98 device_create_file(dev, &dev_attr_pm);
99 /* Current OCP device additions attributes */
100 if (odev->def->additions && odev->def->show)
101 odev->def->show(dev);
102}
103
104/**
105 * ocp_device_match - Match one driver to one device
106 * @drv: driver to match
107 * @dev: device to match
108 *
109 * This function returns 0 if the driver and device don't match
110 */
111static int
112ocp_device_match(struct device *dev, struct device_driver *drv)
113{
114 struct ocp_device *ocp_dev = to_ocp_dev(dev);
115 struct ocp_driver *ocp_drv = to_ocp_drv(drv);
116 const struct ocp_device_id *ids = ocp_drv->id_table;
117
118 if (!ids)
119 return 0;
120
121 while (ids->vendor || ids->function) {
122 if ((ids->vendor == OCP_ANY_ID
123 || ids->vendor == ocp_dev->def->vendor)
124 && (ids->function == OCP_ANY_ID
125 || ids->function == ocp_dev->def->function))
126 return 1;
127 ids++;
128 }
129 return 0;
130}
131
132static int
133ocp_device_probe(struct device *dev)
134{
135 int error = 0;
136 struct ocp_driver *drv;
137 struct ocp_device *ocp_dev;
138
139 drv = to_ocp_drv(dev->driver);
140 ocp_dev = to_ocp_dev(dev);
141
142 if (drv->probe) {
143 error = drv->probe(ocp_dev);
144 if (error >= 0) {
145 ocp_dev->driver = drv;
146 error = 0;
147 }
148 }
149 return error;
150}
151
152static int
153ocp_device_remove(struct device *dev)
154{
155 struct ocp_device *ocp_dev = to_ocp_dev(dev);
156
157 if (ocp_dev->driver) {
158 if (ocp_dev->driver->remove)
159 ocp_dev->driver->remove(ocp_dev);
160 ocp_dev->driver = NULL;
161 }
162 return 0;
163}
164
165static int
166ocp_device_suspend(struct device *dev, pm_message_t state)
167{
168 struct ocp_device *ocp_dev = to_ocp_dev(dev);
169 struct ocp_driver *ocp_drv = to_ocp_drv(dev->driver);
170
171 if (dev->driver && ocp_drv->suspend)
172 return ocp_drv->suspend(ocp_dev, state);
173 return 0;
174}
175
176static int
177ocp_device_resume(struct device *dev)
178{
179 struct ocp_device *ocp_dev = to_ocp_dev(dev);
180 struct ocp_driver *ocp_drv = to_ocp_drv(dev->driver);
181
182 if (dev->driver && ocp_drv->resume)
183 return ocp_drv->resume(ocp_dev);
184 return 0;
185}
186
187struct bus_type ocp_bus_type = {
188 .name = "ocp",
189 .match = ocp_device_match,
190 .probe = ocp_device_probe,
191 .remove = ocp_device_remove,
192 .suspend = ocp_device_suspend,
193 .resume = ocp_device_resume,
194};
195
196/**
197 * ocp_register_driver - Register an OCP driver
198 * @drv: pointer to statically defined ocp_driver structure
199 *
200 * The driver's probe() callback is called either recursively
201 * by this function or upon later call of ocp_driver_init
202 *
203 * NOTE: Detection of devices is a 2 pass step on this implementation,
204 * hotswap isn't supported. First, all OCP devices are put in the device
205 * list, _then_ all drivers are probed on each match.
206 */
207int
208ocp_register_driver(struct ocp_driver *drv)
209{
210 /* initialize common driver fields */
211 drv->driver.name = drv->name;
212 drv->driver.bus = &ocp_bus_type;
213
214 /* register with core */
215 return driver_register(&drv->driver);
216}
217
218/**
219 * ocp_unregister_driver - Unregister an OCP driver
220 * @drv: pointer to statically defined ocp_driver structure
221 *
222 * The driver's remove() callback is called recursively
223 * by this function for any device already registered
224 */
225void
226ocp_unregister_driver(struct ocp_driver *drv)
227{
228 DBG(("ocp: ocp_unregister_driver(%s)...\n", drv->name));
229
230 driver_unregister(&drv->driver);
231
232 DBG(("ocp: ocp_unregister_driver(%s)... done.\n", drv->name));
233}
234
235/* Core of ocp_find_device(). Caller must hold ocp_devices_sem */
236static struct ocp_device *
237__ocp_find_device(unsigned int vendor, unsigned int function, int index)
238{
239 struct list_head *entry;
240 struct ocp_device *dev, *found = NULL;
241
242 DBG(("ocp: __ocp_find_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));
243
244 list_for_each(entry, &ocp_devices) {
245 dev = list_entry(entry, struct ocp_device, link);
246 if (vendor != OCP_ANY_ID && vendor != dev->def->vendor)
247 continue;
248 if (function != OCP_ANY_ID && function != dev->def->function)
249 continue;
250 if (index != OCP_ANY_INDEX && index != dev->def->index)
251 continue;
252 found = dev;
253 break;
254 }
255
256 DBG(("ocp: __ocp_find_device(vendor: %x, function: %x, index: %d)... done\n", vendor, function, index));
257
258 return found;
259}
260
261/**
262 * ocp_find_device - Find a device by function & index
263 * @vendor: vendor ID of the device (or OCP_ANY_ID)
264 * @function: function code of the device (or OCP_ANY_ID)
265 * @idx: index of the device (or OCP_ANY_INDEX)
266 *
267 * This function allows a lookup of a given function by it's
268 * index, it's typically used to find the MAL or ZMII associated
269 * with an EMAC or similar horrors.
270 * You can pass vendor, though you usually want OCP_ANY_ID there...
271 */
272struct ocp_device *
273ocp_find_device(unsigned int vendor, unsigned int function, int index)
274{
275 struct ocp_device *dev;
276
277 down_read(&ocp_devices_sem);
278 dev = __ocp_find_device(vendor, function, index);
279 up_read(&ocp_devices_sem);
280
281 return dev;
282}
283
284/**
285 * ocp_get_one_device - Find a def by function & index
286 * @vendor: vendor ID of the device (or OCP_ANY_ID)
287 * @function: function code of the device (or OCP_ANY_ID)
288 * @idx: index of the device (or OCP_ANY_INDEX)
289 *
290 * This function allows a lookup of a given ocp_def by it's
291 * vendor, function, and index. The main purpose for is to
292 * allow modification of the def before binding to the driver
293 */
294struct ocp_def *
295ocp_get_one_device(unsigned int vendor, unsigned int function, int index)
296{
297 struct ocp_device *dev;
298 struct ocp_def *found = NULL;
299
300 DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)...\n",
301 vendor, function, index));
302
303 dev = ocp_find_device(vendor, function, index);
304
305 if (dev)
306 found = dev->def;
307
308 DBG(("ocp: ocp_get_one_device(vendor: %x, function: %x, index: %d)... done.\n",
309 vendor, function, index));
310
311 return found;
312}
313
314/**
315 * ocp_add_one_device - Add a device
316 * @def: static device definition structure
317 *
318 * This function adds a device definition to the
319 * device list. It may only be called before
320 * ocp_driver_init() and will return an error
321 * otherwise.
322 */
323int
324ocp_add_one_device(struct ocp_def *def)
325{
326 struct ocp_device *dev;
327
328 DBG(("ocp: ocp_add_one_device()...\n"));
329
330 /* Can't be called after ocp driver init */
331 if (ocp_inited)
332 return 1;
333
334 if (mem_init_done)
335 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
336 else
337 dev = alloc_bootmem(sizeof(*dev));
338
339 if (dev == NULL)
340 return 1;
341 memset(dev, 0, sizeof(*dev));
342 dev->def = def;
343 dev->current_state = 4;
344 sprintf(dev->name, "OCP device %04x:%04x:%04x",
345 dev->def->vendor, dev->def->function, dev->def->index);
346 down_write(&ocp_devices_sem);
347 list_add_tail(&dev->link, &ocp_devices);
348 up_write(&ocp_devices_sem);
349
350 DBG(("ocp: ocp_add_one_device()...done\n"));
351
352 return 0;
353}
354
355/**
356 * ocp_remove_one_device - Remove a device by function & index
357 * @vendor: vendor ID of the device (or OCP_ANY_ID)
358 * @function: function code of the device (or OCP_ANY_ID)
359 * @idx: index of the device (or OCP_ANY_INDEX)
360 *
361 * This function allows removal of a given function by its
362 * index. It may only be called before ocp_driver_init()
363 * and will return an error otherwise.
364 */
365int
366ocp_remove_one_device(unsigned int vendor, unsigned int function, int index)
367{
368 struct ocp_device *dev;
369
370 DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)...\n", vendor, function, index));
371
372 /* Can't be called after ocp driver init */
373 if (ocp_inited)
374 return 1;
375
376 down_write(&ocp_devices_sem);
377 dev = __ocp_find_device(vendor, function, index);
378 list_del(&dev->link);
379 up_write(&ocp_devices_sem);
380
381 DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index));
382
383 return 0;
384}
385
386/**
387 * ocp_for_each_device - Iterate over OCP devices
388 * @callback: routine to execute for each ocp device.
389 * @arg: user data to be passed to callback routine.
390 *
391 * This routine holds the ocp_device semaphore, so the
392 * callback routine cannot modify the ocp_device list.
393 */
394void
395ocp_for_each_device(void(*callback)(struct ocp_device *, void *arg), void *arg)
396{
397 struct list_head *entry;
398
399 if (callback) {
400 down_read(&ocp_devices_sem);
401 list_for_each(entry, &ocp_devices)
402 callback(list_entry(entry, struct ocp_device, link),
403 arg);
404 up_read(&ocp_devices_sem);
405 }
406}
407
408/**
409 * ocp_early_init - Init OCP device management
410 *
411 * This function builds the list of devices before setup_arch.
412 * This allows platform code to modify the device lists before
413 * they are bound to drivers (changes to paddr, removing devices
414 * etc)
415 */
416int __init
417ocp_early_init(void)
418{
419 struct ocp_def *def;
420
421 DBG(("ocp: ocp_early_init()...\n"));
422
423 /* Fill the devices list */
424 for (def = core_ocp; def->vendor != OCP_VENDOR_INVALID; def++)
425 ocp_add_one_device(def);
426
427 DBG(("ocp: ocp_early_init()... done.\n"));
428
429 return 0;
430}
431
432/**
433 * ocp_driver_init - Init OCP device management
434 *
435 * This function is meant to be called via OCP bus registration.
436 */
437static int __init
438ocp_driver_init(void)
439{
440 int ret = 0, index = 0;
441 struct device *ocp_bus;
442 struct list_head *entry;
443 struct ocp_device *dev;
444
445 if (ocp_inited)
446 return ret;
447 ocp_inited = 1;
448
449 DBG(("ocp: ocp_driver_init()...\n"));
450
451 /* Allocate/register primary OCP bus */
452 ocp_bus = kzalloc(sizeof(struct device), GFP_KERNEL);
453 if (ocp_bus == NULL)
454 return 1;
455 strcpy(ocp_bus->bus_id, "ocp");
456
457 bus_register(&ocp_bus_type);
458
459 device_register(ocp_bus);
460
461 /* Put each OCP device into global device list */
462 list_for_each(entry, &ocp_devices) {
463 dev = list_entry(entry, struct ocp_device, link);
464 sprintf(dev->dev.bus_id, "%2.2x", index);
465 dev->dev.parent = ocp_bus;
466 dev->dev.bus = &ocp_bus_type;
467 device_register(&dev->dev);
468 ocp_create_sysfs_dev_files(dev);
469 index++;
470 }
471
472 DBG(("ocp: ocp_driver_init()... done.\n"));
473
474 return 0;
475}
476
477postcore_initcall(ocp_driver_init);
478
479EXPORT_SYMBOL(ocp_bus_type);
480EXPORT_SYMBOL(ocp_find_device);
481EXPORT_SYMBOL(ocp_register_driver);
482EXPORT_SYMBOL(ocp_unregister_driver);
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
deleted file mode 100644
index 67dffe27b5c3..000000000000
--- a/arch/ppc/syslib/open_pic.c
+++ /dev/null
@@ -1,1087 +0,0 @@
1/*
2 * Copyright (C) 1997 Geert Uytterhoeven
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive
6 * for more details.
7 */
8
9#include <linux/types.h>
10#include <linux/kernel.h>
11#include <linux/sched.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/sysdev.h>
15#include <linux/errno.h>
16#include <asm/ptrace.h>
17#include <asm/signal.h>
18#include <asm/io.h>
19#include <asm/irq.h>
20#include <asm/sections.h>
21#include <asm/open_pic.h>
22#include <asm/i8259.h>
23#include <asm/machdep.h>
24
25#include "open_pic_defs.h"
26
27#if defined(CONFIG_PRPMC800)
28#define OPENPIC_BIG_ENDIAN
29#endif
30
31void __iomem *OpenPIC_Addr;
32static volatile struct OpenPIC __iomem *OpenPIC = NULL;
33
34/*
35 * We define OpenPIC_InitSenses table thusly:
36 * bit 0x1: sense, 0 for edge and 1 for level.
37 * bit 0x2: polarity, 0 for negative, 1 for positive.
38 */
39u_int OpenPIC_NumInitSenses __initdata = 0;
40u_char *OpenPIC_InitSenses __initdata = NULL;
41extern int use_of_interrupt_tree;
42
43static u_int NumProcessors;
44static u_int NumSources;
45static int open_pic_irq_offset;
46static volatile OpenPIC_Source __iomem *ISR[NR_IRQS];
47static int openpic_cascade_irq = -1;
48static int (*openpic_cascade_fn)(void);
49
50/* Global Operations */
51static void openpic_disable_8259_pass_through(void);
52static void openpic_set_spurious(u_int vector);
53
54#ifdef CONFIG_SMP
55/* Interprocessor Interrupts */
56static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
57static irqreturn_t openpic_ipi_action(int cpl, void *dev_id);
58#endif
59
60/* Timer Interrupts */
61static void openpic_inittimer(u_int timer, u_int pri, u_int vector);
62static void openpic_maptimer(u_int timer, cpumask_t cpumask);
63
64/* Interrupt Sources */
65static void openpic_enable_irq(u_int irq);
66static void openpic_disable_irq(u_int irq);
67static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
68 int is_level);
69static void openpic_mapirq(u_int irq, cpumask_t cpumask, cpumask_t keepmask);
70
71/*
72 * These functions are not used but the code is kept here
73 * for completeness and future reference.
74 */
75#ifdef notused
76static void openpic_enable_8259_pass_through(void);
77static u_int openpic_get_spurious(void);
78static void openpic_set_sense(u_int irq, int sense);
79#endif /* notused */
80
81/*
82 * Description of the openpic for the higher-level irq code
83 */
84static void openpic_end_irq(unsigned int irq_nr);
85static void openpic_ack_irq(unsigned int irq_nr);
86static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask);
87
88struct hw_interrupt_type open_pic = {
89 .typename = " OpenPIC ",
90 .enable = openpic_enable_irq,
91 .disable = openpic_disable_irq,
92 .ack = openpic_ack_irq,
93 .end = openpic_end_irq,
94 .set_affinity = openpic_set_affinity,
95};
96
97#ifdef CONFIG_SMP
98static void openpic_end_ipi(unsigned int irq_nr);
99static void openpic_ack_ipi(unsigned int irq_nr);
100static void openpic_enable_ipi(unsigned int irq_nr);
101static void openpic_disable_ipi(unsigned int irq_nr);
102
103struct hw_interrupt_type open_pic_ipi = {
104 .typename = " OpenPIC ",
105 .enable = openpic_enable_ipi,
106 .disable = openpic_disable_ipi,
107 .ack = openpic_ack_ipi,
108 .end = openpic_end_ipi,
109};
110#endif /* CONFIG_SMP */
111
112/*
113 * Accesses to the current processor's openpic registers
114 */
115#ifdef CONFIG_SMP
116#define THIS_CPU Processor[cpu]
117#define DECL_THIS_CPU int cpu = smp_hw_index[smp_processor_id()]
118#define CHECK_THIS_CPU check_arg_cpu(cpu)
119#else
120#define THIS_CPU Processor[0]
121#define DECL_THIS_CPU
122#define CHECK_THIS_CPU
123#endif /* CONFIG_SMP */
124
125#if 1
126#define check_arg_ipi(ipi) \
127 if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \
128 printk("open_pic.c:%d: invalid ipi %d\n", __LINE__, ipi);
129#define check_arg_timer(timer) \
130 if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \
131 printk("open_pic.c:%d: invalid timer %d\n", __LINE__, timer);
132#define check_arg_vec(vec) \
133 if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \
134 printk("open_pic.c:%d: invalid vector %d\n", __LINE__, vec);
135#define check_arg_pri(pri) \
136 if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
137 printk("open_pic.c:%d: invalid priority %d\n", __LINE__, pri);
138/*
139 * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's
140 * data has probably been corrupted and we're going to panic or deadlock later
141 * anyway --Troy
142 */
143#define check_arg_irq(irq) \
144 if (irq < open_pic_irq_offset || irq >= NumSources+open_pic_irq_offset \
145 || ISR[irq - open_pic_irq_offset] == 0) { \
146 printk("open_pic.c:%d: invalid irq %d\n", __LINE__, irq); \
147 dump_stack(); }
148#define check_arg_cpu(cpu) \
149 if (cpu < 0 || cpu >= NumProcessors){ \
150 printk("open_pic.c:%d: invalid cpu %d\n", __LINE__, cpu); \
151 dump_stack(); }
152#else
153#define check_arg_ipi(ipi) do {} while (0)
154#define check_arg_timer(timer) do {} while (0)
155#define check_arg_vec(vec) do {} while (0)
156#define check_arg_pri(pri) do {} while (0)
157#define check_arg_irq(irq) do {} while (0)
158#define check_arg_cpu(cpu) do {} while (0)
159#endif
160
161u_int openpic_read(volatile u_int __iomem *addr)
162{
163 u_int val;
164
165#ifdef OPENPIC_BIG_ENDIAN
166 val = in_be32(addr);
167#else
168 val = in_le32(addr);
169#endif
170 return val;
171}
172
173static inline void openpic_write(volatile u_int __iomem *addr, u_int val)
174{
175#ifdef OPENPIC_BIG_ENDIAN
176 out_be32(addr, val);
177#else
178 out_le32(addr, val);
179#endif
180}
181
182static inline u_int openpic_readfield(volatile u_int __iomem *addr, u_int mask)
183{
184 u_int val = openpic_read(addr);
185 return val & mask;
186}
187
188inline void openpic_writefield(volatile u_int __iomem *addr, u_int mask,
189 u_int field)
190{
191 u_int val = openpic_read(addr);
192 openpic_write(addr, (val & ~mask) | (field & mask));
193}
194
195static inline void openpic_clearfield(volatile u_int __iomem *addr, u_int mask)
196{
197 openpic_writefield(addr, mask, 0);
198}
199
200static inline void openpic_setfield(volatile u_int __iomem *addr, u_int mask)
201{
202 openpic_writefield(addr, mask, mask);
203}
204
205static void openpic_safe_writefield(volatile u_int __iomem *addr, u_int mask,
206 u_int field)
207{
208 openpic_setfield(addr, OPENPIC_MASK);
209 while (openpic_read(addr) & OPENPIC_ACTIVITY);
210 openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
211}
212
213#ifdef CONFIG_SMP
214/* yes this is right ... bug, feature, you decide! -- tgall */
215u_int openpic_read_IPI(volatile u_int __iomem * addr)
216{
217 u_int val = 0;
218#if defined(OPENPIC_BIG_ENDIAN)
219 val = in_be32(addr);
220#else
221 val = in_le32(addr);
222#endif
223 return val;
224}
225
226/* because of the power3 be / le above, this is needed */
227inline void openpic_writefield_IPI(volatile u_int __iomem * addr, u_int mask, u_int field)
228{
229 u_int val = openpic_read_IPI(addr);
230 openpic_write(addr, (val & ~mask) | (field & mask));
231}
232
233static inline void openpic_clearfield_IPI(volatile u_int __iomem *addr, u_int mask)
234{
235 openpic_writefield_IPI(addr, mask, 0);
236}
237
238static inline void openpic_setfield_IPI(volatile u_int __iomem *addr, u_int mask)
239{
240 openpic_writefield_IPI(addr, mask, mask);
241}
242
243static void openpic_safe_writefield_IPI(volatile u_int __iomem *addr, u_int mask, u_int field)
244{
245 openpic_setfield_IPI(addr, OPENPIC_MASK);
246
247 /* wait until it's not in use */
248 /* BenH: Is this code really enough ? I would rather check the result
249 * and eventually retry ...
250 */
251 while(openpic_read_IPI(addr) & OPENPIC_ACTIVITY);
252
253 openpic_writefield_IPI(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
254}
255#endif /* CONFIG_SMP */
256
257#ifdef CONFIG_EPIC_SERIAL_MODE
258/* On platforms that may use EPIC serial mode, the default is enabled. */
259int epic_serial_mode = 1;
260
261static void __init openpic_eicr_set_clk(u_int clkval)
262{
263 openpic_writefield(&OpenPIC->Global.Global_Configuration1,
264 OPENPIC_EICR_S_CLK_MASK, (clkval << 28));
265}
266
267static void __init openpic_enable_sie(void)
268{
269 openpic_setfield(&OpenPIC->Global.Global_Configuration1,
270 OPENPIC_EICR_SIE);
271}
272#endif
273
274#if defined(CONFIG_EPIC_SERIAL_MODE)
275static void openpic_reset(void)
276{
277 openpic_setfield(&OpenPIC->Global.Global_Configuration0,
278 OPENPIC_CONFIG_RESET);
279 while (openpic_readfield(&OpenPIC->Global.Global_Configuration0,
280 OPENPIC_CONFIG_RESET))
281 mb();
282}
283#endif
284
285void __init openpic_set_sources(int first_irq, int num_irqs, void __iomem *first_ISR)
286{
287 volatile OpenPIC_Source __iomem *src = first_ISR;
288 int i, last_irq;
289
290 last_irq = first_irq + num_irqs;
291 if (last_irq > NumSources)
292 NumSources = last_irq;
293 if (src == 0)
294 src = &((struct OpenPIC __iomem *)OpenPIC_Addr)->Source[first_irq];
295 for (i = first_irq; i < last_irq; ++i, ++src)
296 ISR[i] = src;
297}
298
299/*
300 * The `offset' parameter defines where the interrupts handled by the
301 * OpenPIC start in the space of interrupt numbers that the kernel knows
302 * about. In other words, the OpenPIC's IRQ0 is numbered `offset' in the
303 * kernel's interrupt numbering scheme.
304 * We assume there is only one OpenPIC.
305 */
306void __init openpic_init(int offset)
307{
308 u_int t, i;
309 u_int timerfreq;
310 const char *version;
311
312 if (!OpenPIC_Addr) {
313 printk("No OpenPIC found !\n");
314 return;
315 }
316 OpenPIC = (volatile struct OpenPIC __iomem *)OpenPIC_Addr;
317
318#ifdef CONFIG_EPIC_SERIAL_MODE
319 /* Have to start from ground zero.
320 */
321 openpic_reset();
322#endif
323
324 if (ppc_md.progress) ppc_md.progress("openpic: enter", 0x122);
325
326 t = openpic_read(&OpenPIC->Global.Feature_Reporting0);
327 switch (t & OPENPIC_FEATURE_VERSION_MASK) {
328 case 1:
329 version = "1.0";
330 break;
331 case 2:
332 version = "1.2";
333 break;
334 case 3:
335 version = "1.3";
336 break;
337 default:
338 version = "?";
339 break;
340 }
341 NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
342 OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
343 if (NumSources == 0)
344 openpic_set_sources(0,
345 ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
346 OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
347 NULL);
348 printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n",
349 version, NumProcessors, NumSources, OpenPIC);
350 timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
351 if (timerfreq)
352 printk("OpenPIC timer frequency is %d.%06d MHz\n",
353 timerfreq / 1000000, timerfreq % 1000000);
354
355 open_pic_irq_offset = offset;
356
357 /* Initialize timer interrupts */
358 if ( ppc_md.progress ) ppc_md.progress("openpic: timer",0x3ba);
359 for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
360 /* Disabled, Priority 0 */
361 openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset);
362 /* No processor */
363 openpic_maptimer(i, CPU_MASK_NONE);
364 }
365
366#ifdef CONFIG_SMP
367 /* Initialize IPI interrupts */
368 if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
369 for (i = 0; i < OPENPIC_NUM_IPI; i++) {
370 /* Disabled, increased priorities 10..13 */
371 openpic_initipi(i, OPENPIC_PRIORITY_IPI_BASE+i,
372 OPENPIC_VEC_IPI+i+offset);
373 /* IPIs are per-CPU */
374 irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
375 irq_desc[OPENPIC_VEC_IPI+i+offset].chip = &open_pic_ipi;
376 }
377#endif
378
379 /* Initialize external interrupts */
380 if (ppc_md.progress) ppc_md.progress("openpic: external",0x3bc);
381
382 openpic_set_priority(0xf);
383
384 /* Init all external sources, including possibly the cascade. */
385 for (i = 0; i < NumSources; i++) {
386 int sense;
387
388 if (ISR[i] == 0)
389 continue;
390
391 /* the bootloader may have left it enabled (bad !) */
392 openpic_disable_irq(i+offset);
393
394 sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: \
395 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE);
396
397 if (sense & IRQ_SENSE_MASK)
398 irq_desc[i+offset].status = IRQ_LEVEL;
399
400 /* Enabled, Default priority */
401 openpic_initirq(i, OPENPIC_PRIORITY_DEFAULT, i+offset,
402 (sense & IRQ_POLARITY_MASK),
403 (sense & IRQ_SENSE_MASK));
404 /* Processor 0 */
405 openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE);
406 }
407
408 /* Init descriptors */
409 for (i = offset; i < NumSources + offset; i++)
410 irq_desc[i].chip = &open_pic;
411
412 /* Initialize the spurious interrupt */
413 if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
414 openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
415 openpic_disable_8259_pass_through();
416#ifdef CONFIG_EPIC_SERIAL_MODE
417 if (epic_serial_mode) {
418 openpic_eicr_set_clk(7); /* Slowest value until we know better */
419 openpic_enable_sie();
420 }
421#endif
422 openpic_set_priority(0);
423
424 if (ppc_md.progress) ppc_md.progress("openpic: exit",0x222);
425}
426
427#ifdef notused
428static void openpic_enable_8259_pass_through(void)
429{
430 openpic_clearfield(&OpenPIC->Global.Global_Configuration0,
431 OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
432}
433#endif /* notused */
434
435static void openpic_disable_8259_pass_through(void)
436{
437 openpic_setfield(&OpenPIC->Global.Global_Configuration0,
438 OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
439}
440
441/*
442 * Find out the current interrupt
443 */
444u_int openpic_irq(void)
445{
446 u_int vec;
447 DECL_THIS_CPU;
448
449 CHECK_THIS_CPU;
450 vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge,
451 OPENPIC_VECTOR_MASK);
452 return vec;
453}
454
455void openpic_eoi(void)
456{
457 DECL_THIS_CPU;
458
459 CHECK_THIS_CPU;
460 openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
461 /* Handle PCI write posting */
462 (void)openpic_read(&OpenPIC->THIS_CPU.EOI);
463}
464
465u_int openpic_get_priority(void)
466{
467 DECL_THIS_CPU;
468
469 CHECK_THIS_CPU;
470 return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority,
471 OPENPIC_CURRENT_TASK_PRIORITY_MASK);
472}
473
474void openpic_set_priority(u_int pri)
475{
476 DECL_THIS_CPU;
477
478 CHECK_THIS_CPU;
479 check_arg_pri(pri);
480 openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority,
481 OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri);
482}
483
484/*
485 * Get/set the spurious vector
486 */
487#ifdef notused
488static u_int openpic_get_spurious(void)
489{
490 return openpic_readfield(&OpenPIC->Global.Spurious_Vector,
491 OPENPIC_VECTOR_MASK);
492}
493#endif /* notused */
494
495static void openpic_set_spurious(u_int vec)
496{
497 check_arg_vec(vec);
498 openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,
499 vec);
500}
501
502#ifdef CONFIG_SMP
503/*
504 * Convert a cpu mask from logical to physical cpu numbers.
505 */
506static inline cpumask_t physmask(cpumask_t cpumask)
507{
508 int i;
509 cpumask_t mask = CPU_MASK_NONE;
510
511 cpus_and(cpumask, cpu_online_map, cpumask);
512
513 for (i = 0; i < NR_CPUS; i++)
514 if (cpu_isset(i, cpumask))
515 cpu_set(smp_hw_index[i], mask);
516
517 return mask;
518}
519#else
520#define physmask(cpumask) (cpumask)
521#endif
522
523void openpic_reset_processor_phys(u_int mask)
524{
525 openpic_write(&OpenPIC->Global.Processor_Initialization, mask);
526}
527
528#if defined(CONFIG_SMP) || defined(CONFIG_PM)
529static DEFINE_SPINLOCK(openpic_setup_lock);
530#endif
531
532#ifdef CONFIG_SMP
533/*
534 * Initialize an interprocessor interrupt (and disable it)
535 *
536 * ipi: OpenPIC interprocessor interrupt number
537 * pri: interrupt source priority
538 * vec: the vector it will produce
539 */
540static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
541{
542 check_arg_ipi(ipi);
543 check_arg_pri(pri);
544 check_arg_vec(vec);
545 openpic_safe_writefield_IPI(&OpenPIC->Global.IPI_Vector_Priority(ipi),
546 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
547 (pri << OPENPIC_PRIORITY_SHIFT) | vec);
548}
549
550/*
551 * Send an IPI to one or more CPUs
552 *
553 * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI)
554 * and not a system-wide interrupt number
555 */
556void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
557{
558 DECL_THIS_CPU;
559
560 CHECK_THIS_CPU;
561 check_arg_ipi(ipi);
562 openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
563 cpus_addr(physmask(cpumask))[0]);
564}
565
566void openpic_request_IPIs(void)
567{
568 int i;
569
570 /*
571 * Make sure this matches what is defined in smp.c for
572 * smp_message_{pass|recv}() or what shows up in
573 * /proc/interrupts will be wrong!!! --Troy */
574
575 if (OpenPIC == NULL)
576 return;
577
578 /*
579 * IPIs are marked IRQF_DISABLED as they must run with irqs
580 * disabled
581 */
582 request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset,
583 openpic_ipi_action, IRQF_DISABLED,
584 "IPI0 (call function)", NULL);
585 request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1,
586 openpic_ipi_action, IRQF_DISABLED,
587 "IPI1 (reschedule)", NULL);
588 request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2,
589 openpic_ipi_action, IRQF_DISABLED,
590 "IPI2 (invalidate tlb)", NULL);
591 request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3,
592 openpic_ipi_action, IRQF_DISABLED,
593 "IPI3 (xmon break)", NULL);
594
595 for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
596 openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i);
597}
598
599/*
600 * Do per-cpu setup for SMP systems.
601 *
602 * Get IPI's working and start taking interrupts.
603 * -- Cort
604 */
605
606void __devinit do_openpic_setup_cpu(void)
607{
608#ifdef CONFIG_IRQ_ALL_CPUS
609 int i;
610 cpumask_t msk = CPU_MASK_NONE;
611#endif
612 spin_lock(&openpic_setup_lock);
613
614#ifdef CONFIG_IRQ_ALL_CPUS
615 cpu_set(smp_hw_index[smp_processor_id()], msk);
616
617 /* let the openpic know we want intrs. default affinity
618 * is 0xffffffff until changed via /proc
619 * That's how it's done on x86. If we want it differently, then
620 * we should make sure we also change the default values of
621 * irq_desc[].affinity in irq.c.
622 */
623 for (i = 0; i < NumSources; i++)
624 openpic_mapirq(i, msk, CPU_MASK_ALL);
625#endif /* CONFIG_IRQ_ALL_CPUS */
626 openpic_set_priority(0);
627
628 spin_unlock(&openpic_setup_lock);
629}
630#endif /* CONFIG_SMP */
631
632/*
633 * Initialize a timer interrupt (and disable it)
634 *
635 * timer: OpenPIC timer number
636 * pri: interrupt source priority
637 * vec: the vector it will produce
638 */
639static void __init openpic_inittimer(u_int timer, u_int pri, u_int vec)
640{
641 check_arg_timer(timer);
642 check_arg_pri(pri);
643 check_arg_vec(vec);
644 openpic_safe_writefield(&OpenPIC->Global.Timer[timer].Vector_Priority,
645 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
646 (pri << OPENPIC_PRIORITY_SHIFT) | vec);
647}
648
649/*
650 * Map a timer interrupt to one or more CPUs
651 */
652static void __init openpic_maptimer(u_int timer, cpumask_t cpumask)
653{
654 cpumask_t phys = physmask(cpumask);
655 check_arg_timer(timer);
656 openpic_write(&OpenPIC->Global.Timer[timer].Destination,
657 cpus_addr(phys)[0]);
658}
659
660/*
661 * Change the priority of an interrupt
662 */
663void __init
664openpic_set_irq_priority(u_int irq, u_int pri)
665{
666 check_arg_irq(irq);
667 openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
668 OPENPIC_PRIORITY_MASK,
669 pri << OPENPIC_PRIORITY_SHIFT);
670}
671
672/*
673 * Initalize the interrupt source which will generate an NMI.
674 * This raises the interrupt's priority from 8 to 9.
675 *
676 * irq: The logical IRQ which generates an NMI.
677 */
678void __init
679openpic_init_nmi_irq(u_int irq)
680{
681 check_arg_irq(irq);
682 openpic_set_irq_priority(irq, OPENPIC_PRIORITY_NMI);
683}
684
685/*
686 *
687 * All functions below take an offset'ed irq argument
688 *
689 */
690
691/*
692 * Hookup a cascade to the OpenPIC.
693 */
694
695static struct irqaction openpic_cascade_irqaction = {
696 .handler = no_action,
697 .flags = IRQF_DISABLED,
698 .mask = CPU_MASK_NONE,
699};
700
701void __init
702openpic_hookup_cascade(u_int irq, char *name,
703 int (*cascade_fn)(void))
704{
705 openpic_cascade_irq = irq;
706 openpic_cascade_fn = cascade_fn;
707
708 if (setup_irq(irq, &openpic_cascade_irqaction))
709 printk("Unable to get OpenPIC IRQ %d for cascade\n",
710 irq - open_pic_irq_offset);
711}
712
713/*
714 * Enable/disable an external interrupt source
715 *
716 * Externally called, irq is an offseted system-wide interrupt number
717 */
718static void openpic_enable_irq(u_int irq)
719{
720 volatile u_int __iomem *vpp;
721
722 check_arg_irq(irq);
723 vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
724 openpic_clearfield(vpp, OPENPIC_MASK);
725 /* make sure mask gets to controller before we return to user */
726 do {
727 mb(); /* sync is probably useless here */
728 } while (openpic_readfield(vpp, OPENPIC_MASK));
729}
730
731static void openpic_disable_irq(u_int irq)
732{
733 volatile u_int __iomem *vpp;
734 u32 vp;
735
736 check_arg_irq(irq);
737 vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
738 openpic_setfield(vpp, OPENPIC_MASK);
739 /* make sure mask gets to controller before we return to user */
740 do {
741 mb(); /* sync is probably useless here */
742 vp = openpic_readfield(vpp, OPENPIC_MASK | OPENPIC_ACTIVITY);
743 } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
744}
745
746#ifdef CONFIG_SMP
747/*
748 * Enable/disable an IPI interrupt source
749 *
750 * Externally called, irq is an offseted system-wide interrupt number
751 */
752void openpic_enable_ipi(u_int irq)
753{
754 irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset);
755 check_arg_ipi(irq);
756 openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
757
758}
759
760void openpic_disable_ipi(u_int irq)
761{
762 irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset);
763 check_arg_ipi(irq);
764 openpic_setfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK);
765}
766#endif
767
768/*
769 * Initialize an interrupt source (and disable it!)
770 *
771 * irq: OpenPIC interrupt number
772 * pri: interrupt source priority
773 * vec: the vector it will produce
774 * pol: polarity (1 for positive, 0 for negative)
775 * sense: 1 for level, 0 for edge
776 */
777static void __init
778openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
779{
780 openpic_safe_writefield(&ISR[irq]->Vector_Priority,
781 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
782 OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
783 (pri << OPENPIC_PRIORITY_SHIFT) | vec |
784 (pol ? OPENPIC_POLARITY_POSITIVE :
785 OPENPIC_POLARITY_NEGATIVE) |
786 (sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
787}
788
789/*
790 * Map an interrupt source to one or more CPUs
791 */
792static void openpic_mapirq(u_int irq, cpumask_t physmask, cpumask_t keepmask)
793{
794 if (ISR[irq] == 0)
795 return;
796 if (!cpus_empty(keepmask)) {
797 cpumask_t irqdest = { .bits[0] = openpic_read(&ISR[irq]->Destination) };
798 cpus_and(irqdest, irqdest, keepmask);
799 cpus_or(physmask, physmask, irqdest);
800 }
801 openpic_write(&ISR[irq]->Destination, cpus_addr(physmask)[0]);
802}
803
804#ifdef notused
805/*
806 * Set the sense for an interrupt source (and disable it!)
807 *
808 * sense: 1 for level, 0 for edge
809 */
810static void openpic_set_sense(u_int irq, int sense)
811{
812 if (ISR[irq] != 0)
813 openpic_safe_writefield(&ISR[irq]->Vector_Priority,
814 OPENPIC_SENSE_LEVEL,
815 (sense ? OPENPIC_SENSE_LEVEL : 0));
816}
817#endif /* notused */
818
819/* No spinlocks, should not be necessary with the OpenPIC
820 * (1 register = 1 interrupt and we have the desc lock).
821 */
822static void openpic_ack_irq(unsigned int irq_nr)
823{
824#ifdef __SLOW_VERSION__
825 openpic_disable_irq(irq_nr);
826 openpic_eoi();
827#else
828 if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
829 openpic_eoi();
830#endif
831}
832
833static void openpic_end_irq(unsigned int irq_nr)
834{
835#ifdef __SLOW_VERSION__
836 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
837 && irq_desc[irq_nr].action)
838 openpic_enable_irq(irq_nr);
839#else
840 if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
841 openpic_eoi();
842#endif
843}
844
845static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask)
846{
847 openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask), CPU_MASK_NONE);
848}
849
850#ifdef CONFIG_SMP
851static void openpic_ack_ipi(unsigned int irq_nr)
852{
853 openpic_eoi();
854}
855
856static void openpic_end_ipi(unsigned int irq_nr)
857{
858}
859
860static irqreturn_t openpic_ipi_action(int cpl, void *dev_id)
861{
862 smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset);
863 return IRQ_HANDLED;
864}
865
866#endif /* CONFIG_SMP */
867
868int
869openpic_get_irq(void)
870{
871 int irq = openpic_irq();
872
873 /*
874 * Check for the cascade interrupt and call the cascaded
875 * interrupt controller function (usually i8259_irq) if so.
876 * This should move to irq.c eventually. -- paulus
877 */
878 if (irq == openpic_cascade_irq && openpic_cascade_fn != NULL) {
879 int cirq = openpic_cascade_fn();
880
881 /* Allow for the cascade being shared with other devices */
882 if (cirq != -1) {
883 irq = cirq;
884 openpic_eoi();
885 }
886 } else if (irq == OPENPIC_VEC_SPURIOUS)
887 irq = -1;
888 return irq;
889}
890
891#ifdef CONFIG_SMP
892void
893smp_openpic_message_pass(int target, int msg)
894{
895 cpumask_t mask = CPU_MASK_ALL;
896 /* make sure we're sending something that translates to an IPI */
897 if (msg > 0x3) {
898 printk("SMP %d: smp_message_pass: unknown msg %d\n",
899 smp_processor_id(), msg);
900 return;
901 }
902 switch (target) {
903 case MSG_ALL:
904 openpic_cause_IPI(msg, mask);
905 break;
906 case MSG_ALL_BUT_SELF:
907 cpu_clear(smp_processor_id(), mask);
908 openpic_cause_IPI(msg, mask);
909 break;
910 default:
911 openpic_cause_IPI(msg, cpumask_of_cpu(target));
912 break;
913 }
914}
915#endif /* CONFIG_SMP */
916
917#ifdef CONFIG_PM
918
919/*
920 * We implement the IRQ controller as a sysdev and put it
921 * to sleep at powerdown stage (the callback is named suspend,
922 * but it's old semantics, for the Device Model, it's really
923 * powerdown). The possible problem is that another sysdev that
924 * happens to be suspend after this one will have interrupts off,
925 * that may be an issue... For now, this isn't an issue on pmac
926 * though...
927 */
928
929static u32 save_ipi_vp[OPENPIC_NUM_IPI];
930static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES];
931static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES];
932static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS];
933static int openpic_suspend_count;
934
935static void openpic_cached_enable_irq(u_int irq)
936{
937 check_arg_irq(irq);
938 save_irq_src_vp[irq - open_pic_irq_offset] &= ~OPENPIC_MASK;
939}
940
941static void openpic_cached_disable_irq(u_int irq)
942{
943 check_arg_irq(irq);
944 save_irq_src_vp[irq - open_pic_irq_offset] |= OPENPIC_MASK;
945}
946
947/* WARNING: Can be called directly by the cpufreq code with NULL parameter,
948 * we need something better to deal with that... Maybe switch to S1 for
949 * cpufreq changes
950 */
951int openpic_suspend(struct sys_device *sysdev, pm_message_t state)
952{
953 int i;
954 unsigned long flags;
955
956 spin_lock_irqsave(&openpic_setup_lock, flags);
957
958 if (openpic_suspend_count++ > 0) {
959 spin_unlock_irqrestore(&openpic_setup_lock, flags);
960 return 0;
961 }
962
963 openpic_set_priority(0xf);
964
965 open_pic.enable = openpic_cached_enable_irq;
966 open_pic.disable = openpic_cached_disable_irq;
967
968 for (i=0; i<NumProcessors; i++) {
969 save_cpu_task_pri[i] = openpic_read(&OpenPIC->Processor[i].Current_Task_Priority);
970 openpic_writefield(&OpenPIC->Processor[i].Current_Task_Priority,
971 OPENPIC_CURRENT_TASK_PRIORITY_MASK, 0xf);
972 }
973
974 for (i=0; i<OPENPIC_NUM_IPI; i++)
975 save_ipi_vp[i] = openpic_read(&OpenPIC->Global.IPI_Vector_Priority(i));
976 for (i=0; i<NumSources; i++) {
977 if (ISR[i] == 0)
978 continue;
979 save_irq_src_vp[i] = openpic_read(&ISR[i]->Vector_Priority) & ~OPENPIC_ACTIVITY;
980 save_irq_src_dest[i] = openpic_read(&ISR[i]->Destination);
981 }
982
983 spin_unlock_irqrestore(&openpic_setup_lock, flags);
984
985 return 0;
986}
987
988/* WARNING: Can be called directly by the cpufreq code with NULL parameter,
989 * we need something better to deal with that... Maybe switch to S1 for
990 * cpufreq changes
991 */
992int openpic_resume(struct sys_device *sysdev)
993{
994 int i;
995 unsigned long flags;
996 u32 vppmask = OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
997 OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK |
998 OPENPIC_MASK;
999
1000 spin_lock_irqsave(&openpic_setup_lock, flags);
1001
1002 if ((--openpic_suspend_count) > 0) {
1003 spin_unlock_irqrestore(&openpic_setup_lock, flags);
1004 return 0;
1005 }
1006
1007 /* OpenPIC sometimes seem to need some time to be fully back up... */
1008 do {
1009 openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
1010 } while(openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK)
1011 != OPENPIC_VEC_SPURIOUS);
1012
1013 openpic_disable_8259_pass_through();
1014
1015 for (i=0; i<OPENPIC_NUM_IPI; i++)
1016 openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i),
1017 save_ipi_vp[i]);
1018 for (i=0; i<NumSources; i++) {
1019 if (ISR[i] == 0)
1020 continue;
1021 openpic_write(&ISR[i]->Destination, save_irq_src_dest[i]);
1022 openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);
1023 /* make sure mask gets to controller before we return to user */
1024 do {
1025 openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);
1026 } while (openpic_readfield(&ISR[i]->Vector_Priority, vppmask)
1027 != (save_irq_src_vp[i] & vppmask));
1028 }
1029 for (i=0; i<NumProcessors; i++)
1030 openpic_write(&OpenPIC->Processor[i].Current_Task_Priority,
1031 save_cpu_task_pri[i]);
1032
1033 open_pic.enable = openpic_enable_irq;
1034 open_pic.disable = openpic_disable_irq;
1035
1036 openpic_set_priority(0);
1037
1038 spin_unlock_irqrestore(&openpic_setup_lock, flags);
1039
1040 return 0;
1041}
1042
1043#endif /* CONFIG_PM */
1044
1045static struct sysdev_class openpic_sysclass = {
1046 .name = "openpic",
1047};
1048
1049static struct sys_device device_openpic = {
1050 .id = 0,
1051 .cls = &openpic_sysclass,
1052};
1053
1054static struct sysdev_driver driver_openpic = {
1055#ifdef CONFIG_PM
1056 .suspend = &openpic_suspend,
1057 .resume = &openpic_resume,
1058#endif /* CONFIG_PM */
1059};
1060
1061static int __init init_openpic_sysfs(void)
1062{
1063 int rc;
1064
1065 if (!OpenPIC_Addr)
1066 return -ENODEV;
1067 printk(KERN_DEBUG "Registering openpic with sysfs...\n");
1068 rc = sysdev_class_register(&openpic_sysclass);
1069 if (rc) {
1070 printk(KERN_ERR "Failed registering openpic sys class\n");
1071 return -ENODEV;
1072 }
1073 rc = sysdev_register(&device_openpic);
1074 if (rc) {
1075 printk(KERN_ERR "Failed registering openpic sys device\n");
1076 return -ENODEV;
1077 }
1078 rc = sysdev_driver_register(&openpic_sysclass, &driver_openpic);
1079 if (rc) {
1080 printk(KERN_ERR "Failed registering openpic sys driver\n");
1081 return -ENODEV;
1082 }
1083 return 0;
1084}
1085
1086subsys_initcall(init_openpic_sysfs);
1087
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
deleted file mode 100644
index 449075a04798..000000000000
--- a/arch/ppc/syslib/open_pic2.c
+++ /dev/null
@@ -1,710 +0,0 @@
1/*
2 * Copyright (C) 1997 Geert Uytterhoeven
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file COPYING in the main directory of this archive
6 * for more details.
7 *
8 * This is a duplicate of open_pic.c that deals with U3s MPIC on
9 * G5 PowerMacs. It's the same file except it's using big endian
10 * register accesses
11 */
12
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/sysdev.h>
19#include <linux/errno.h>
20#include <asm/ptrace.h>
21#include <asm/signal.h>
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/sections.h>
25#include <asm/open_pic.h>
26#include <asm/i8259.h>
27#include <asm/machdep.h>
28
29#include "open_pic_defs.h"
30
31void *OpenPIC2_Addr;
32static volatile struct OpenPIC *OpenPIC2 = NULL;
33/*
34 * We define OpenPIC_InitSenses table thusly:
35 * bit 0x1: sense, 0 for edge and 1 for level.
36 * bit 0x2: polarity, 0 for negative, 1 for positive.
37 */
38extern u_int OpenPIC_NumInitSenses;
39extern u_char *OpenPIC_InitSenses;
40extern int use_of_interrupt_tree;
41
42static u_int NumProcessors;
43static u_int NumSources;
44static int open_pic2_irq_offset;
45static volatile OpenPIC_Source *ISR[NR_IRQS];
46
47/* Global Operations */
48static void openpic2_disable_8259_pass_through(void);
49static void openpic2_set_priority(u_int pri);
50static void openpic2_set_spurious(u_int vector);
51
52/* Timer Interrupts */
53static void openpic2_inittimer(u_int timer, u_int pri, u_int vector);
54static void openpic2_maptimer(u_int timer, u_int cpumask);
55
56/* Interrupt Sources */
57static void openpic2_enable_irq(u_int irq);
58static void openpic2_disable_irq(u_int irq);
59static void openpic2_initirq(u_int irq, u_int pri, u_int vector, int polarity,
60 int is_level);
61static void openpic2_mapirq(u_int irq, u_int cpumask, u_int keepmask);
62
63/*
64 * These functions are not used but the code is kept here
65 * for completeness and future reference.
66 */
67static void openpic2_reset(void);
68#ifdef notused
69static void openpic2_enable_8259_pass_through(void);
70static u_int openpic2_get_priority(void);
71static u_int openpic2_get_spurious(void);
72static void openpic2_set_sense(u_int irq, int sense);
73#endif /* notused */
74
75/*
76 * Description of the openpic for the higher-level irq code
77 */
78static void openpic2_end_irq(unsigned int irq_nr);
79static void openpic2_ack_irq(unsigned int irq_nr);
80
81struct hw_interrupt_type open_pic2 = {
82 .typename = " OpenPIC2 ",
83 .enable = openpic2_enable_irq,
84 .disable = openpic2_disable_irq,
85 .ack = openpic2_ack_irq,
86 .end = openpic2_end_irq,
87};
88
89/*
90 * Accesses to the current processor's openpic registers
91 * On cascaded controller, this is only CPU 0
92 */
93#define THIS_CPU Processor[0]
94#define DECL_THIS_CPU
95#define CHECK_THIS_CPU
96
97#if 1
98#define check_arg_ipi(ipi) \
99 if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \
100 printk("open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi);
101#define check_arg_timer(timer) \
102 if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \
103 printk("open_pic.c:%d: illegal timer %d\n", __LINE__, timer);
104#define check_arg_vec(vec) \
105 if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \
106 printk("open_pic.c:%d: illegal vector %d\n", __LINE__, vec);
107#define check_arg_pri(pri) \
108 if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
109 printk("open_pic.c:%d: illegal priority %d\n", __LINE__, pri);
110/*
111 * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's
112 * data has probably been corrupted and we're going to panic or deadlock later
113 * anyway --Troy
114 */
115extern unsigned long* _get_SP(void);
116#define check_arg_irq(irq) \
117 if (irq < open_pic2_irq_offset || irq >= NumSources+open_pic2_irq_offset \
118 || ISR[irq - open_pic2_irq_offset] == 0) { \
119 printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
120 /*print_backtrace(_get_SP());*/ }
121#define check_arg_cpu(cpu) \
122 if (cpu < 0 || cpu >= NumProcessors){ \
123 printk("open_pic2.c:%d: illegal cpu %d\n", __LINE__, cpu); \
124 /*print_backtrace(_get_SP());*/ }
125#else
126#define check_arg_ipi(ipi) do {} while (0)
127#define check_arg_timer(timer) do {} while (0)
128#define check_arg_vec(vec) do {} while (0)
129#define check_arg_pri(pri) do {} while (0)
130#define check_arg_irq(irq) do {} while (0)
131#define check_arg_cpu(cpu) do {} while (0)
132#endif
133
134static u_int openpic2_read(volatile u_int *addr)
135{
136 u_int val;
137
138 val = in_be32(addr);
139 return val;
140}
141
142static inline void openpic2_write(volatile u_int *addr, u_int val)
143{
144 out_be32(addr, val);
145}
146
147static inline u_int openpic2_readfield(volatile u_int *addr, u_int mask)
148{
149 u_int val = openpic2_read(addr);
150 return val & mask;
151}
152
153inline void openpic2_writefield(volatile u_int *addr, u_int mask,
154 u_int field)
155{
156 u_int val = openpic2_read(addr);
157 openpic2_write(addr, (val & ~mask) | (field & mask));
158}
159
160static inline void openpic2_clearfield(volatile u_int *addr, u_int mask)
161{
162 openpic2_writefield(addr, mask, 0);
163}
164
165static inline void openpic2_setfield(volatile u_int *addr, u_int mask)
166{
167 openpic2_writefield(addr, mask, mask);
168}
169
170static void openpic2_safe_writefield(volatile u_int *addr, u_int mask,
171 u_int field)
172{
173 openpic2_setfield(addr, OPENPIC_MASK);
174 while (openpic2_read(addr) & OPENPIC_ACTIVITY);
175 openpic2_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
176}
177
178static void openpic2_reset(void)
179{
180 openpic2_setfield(&OpenPIC2->Global.Global_Configuration0,
181 OPENPIC_CONFIG_RESET);
182 while (openpic2_readfield(&OpenPIC2->Global.Global_Configuration0,
183 OPENPIC_CONFIG_RESET))
184 mb();
185}
186
187void __init openpic2_set_sources(int first_irq, int num_irqs, void *first_ISR)
188{
189 volatile OpenPIC_Source *src = first_ISR;
190 int i, last_irq;
191
192 last_irq = first_irq + num_irqs;
193 if (last_irq > NumSources)
194 NumSources = last_irq;
195 if (src == 0)
196 src = &((struct OpenPIC *)OpenPIC2_Addr)->Source[first_irq];
197 for (i = first_irq; i < last_irq; ++i, ++src)
198 ISR[i] = src;
199}
200
201/*
202 * The `offset' parameter defines where the interrupts handled by the
203 * OpenPIC start in the space of interrupt numbers that the kernel knows
204 * about. In other words, the OpenPIC's IRQ0 is numbered `offset' in the
205 * kernel's interrupt numbering scheme.
206 * We assume there is only one OpenPIC.
207 */
208void __init openpic2_init(int offset)
209{
210 u_int t, i;
211 u_int timerfreq;
212 const char *version;
213
214 if (!OpenPIC2_Addr) {
215 printk("No OpenPIC2 found !\n");
216 return;
217 }
218 OpenPIC2 = (volatile struct OpenPIC *)OpenPIC2_Addr;
219
220 if (ppc_md.progress) ppc_md.progress("openpic: enter", 0x122);
221
222 t = openpic2_read(&OpenPIC2->Global.Feature_Reporting0);
223 switch (t & OPENPIC_FEATURE_VERSION_MASK) {
224 case 1:
225 version = "1.0";
226 break;
227 case 2:
228 version = "1.2";
229 break;
230 case 3:
231 version = "1.3";
232 break;
233 default:
234 version = "?";
235 break;
236 }
237 NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
238 OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
239 if (NumSources == 0)
240 openpic2_set_sources(0,
241 ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
242 OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
243 NULL);
244 printk("OpenPIC (2) Version %s (%d CPUs and %d IRQ sources) at %p\n",
245 version, NumProcessors, NumSources, OpenPIC2);
246 timerfreq = openpic2_read(&OpenPIC2->Global.Timer_Frequency);
247 if (timerfreq)
248 printk("OpenPIC timer frequency is %d.%06d MHz\n",
249 timerfreq / 1000000, timerfreq % 1000000);
250
251 open_pic2_irq_offset = offset;
252
253 /* Initialize timer interrupts */
254 if ( ppc_md.progress ) ppc_md.progress("openpic2: timer",0x3ba);
255 for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
256 /* Disabled, Priority 0 */
257 openpic2_inittimer(i, 0, OPENPIC2_VEC_TIMER+i+offset);
258 /* No processor */
259 openpic2_maptimer(i, 0);
260 }
261
262 /* Initialize external interrupts */
263 if (ppc_md.progress) ppc_md.progress("openpic2: external",0x3bc);
264
265 openpic2_set_priority(0xf);
266
267 /* Init all external sources, including possibly the cascade. */
268 for (i = 0; i < NumSources; i++) {
269 int sense;
270
271 if (ISR[i] == 0)
272 continue;
273
274 /* the bootloader may have left it enabled (bad !) */
275 openpic2_disable_irq(i+offset);
276
277 sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: \
278 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE);
279
280 if (sense & IRQ_SENSE_MASK)
281 irq_desc[i+offset].status = IRQ_LEVEL;
282
283 /* Enabled, Priority 8 */
284 openpic2_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK),
285 (sense & IRQ_SENSE_MASK));
286 /* Processor 0 */
287 openpic2_mapirq(i, 1<<0, 0);
288 }
289
290 /* Init descriptors */
291 for (i = offset; i < NumSources + offset; i++)
292 irq_desc[i].chip = &open_pic2;
293
294 /* Initialize the spurious interrupt */
295 if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd);
296 openpic2_set_spurious(OPENPIC2_VEC_SPURIOUS+offset);
297
298 openpic2_disable_8259_pass_through();
299 openpic2_set_priority(0);
300
301 if (ppc_md.progress) ppc_md.progress("openpic2: exit",0x222);
302}
303
304#ifdef notused
305static void openpic2_enable_8259_pass_through(void)
306{
307 openpic2_clearfield(&OpenPIC2->Global.Global_Configuration0,
308 OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
309}
310#endif /* notused */
311
312/* This can't be __init, it is used in openpic_sleep_restore_intrs */
313static void openpic2_disable_8259_pass_through(void)
314{
315 openpic2_setfield(&OpenPIC2->Global.Global_Configuration0,
316 OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE);
317}
318
319/*
320 * Find out the current interrupt
321 */
322u_int openpic2_irq(void)
323{
324 u_int vec;
325 DECL_THIS_CPU;
326
327 CHECK_THIS_CPU;
328 vec = openpic2_readfield(&OpenPIC2->THIS_CPU.Interrupt_Acknowledge,
329 OPENPIC_VECTOR_MASK);
330 return vec;
331}
332
333void openpic2_eoi(void)
334{
335 DECL_THIS_CPU;
336
337 CHECK_THIS_CPU;
338 openpic2_write(&OpenPIC2->THIS_CPU.EOI, 0);
339 /* Handle PCI write posting */
340 (void)openpic2_read(&OpenPIC2->THIS_CPU.EOI);
341}
342
343#ifdef notused
344static u_int openpic2_get_priority(void)
345{
346 DECL_THIS_CPU;
347
348 CHECK_THIS_CPU;
349 return openpic2_readfield(&OpenPIC2->THIS_CPU.Current_Task_Priority,
350 OPENPIC_CURRENT_TASK_PRIORITY_MASK);
351}
352#endif /* notused */
353
354static void __init openpic2_set_priority(u_int pri)
355{
356 DECL_THIS_CPU;
357
358 CHECK_THIS_CPU;
359 check_arg_pri(pri);
360 openpic2_writefield(&OpenPIC2->THIS_CPU.Current_Task_Priority,
361 OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri);
362}
363
364/*
365 * Get/set the spurious vector
366 */
367#ifdef notused
368static u_int openpic2_get_spurious(void)
369{
370 return openpic2_readfield(&OpenPIC2->Global.Spurious_Vector,
371 OPENPIC_VECTOR_MASK);
372}
373#endif /* notused */
374
375/* This can't be __init, it is used in openpic_sleep_restore_intrs */
376static void openpic2_set_spurious(u_int vec)
377{
378 check_arg_vec(vec);
379 openpic2_writefield(&OpenPIC2->Global.Spurious_Vector, OPENPIC_VECTOR_MASK,
380 vec);
381}
382
383static DEFINE_SPINLOCK(openpic2_setup_lock);
384
385/*
386 * Initialize a timer interrupt (and disable it)
387 *
388 * timer: OpenPIC timer number
389 * pri: interrupt source priority
390 * vec: the vector it will produce
391 */
392static void __init openpic2_inittimer(u_int timer, u_int pri, u_int vec)
393{
394 check_arg_timer(timer);
395 check_arg_pri(pri);
396 check_arg_vec(vec);
397 openpic2_safe_writefield(&OpenPIC2->Global.Timer[timer].Vector_Priority,
398 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK,
399 (pri << OPENPIC_PRIORITY_SHIFT) | vec);
400}
401
402/*
403 * Map a timer interrupt to one or more CPUs
404 */
405static void __init openpic2_maptimer(u_int timer, u_int cpumask)
406{
407 check_arg_timer(timer);
408 openpic2_write(&OpenPIC2->Global.Timer[timer].Destination,
409 cpumask);
410}
411
412/*
413 * Initalize the interrupt source which will generate an NMI.
414 * This raises the interrupt's priority from 8 to 9.
415 *
416 * irq: The logical IRQ which generates an NMI.
417 */
418void __init
419openpic2_init_nmi_irq(u_int irq)
420{
421 check_arg_irq(irq);
422 openpic2_safe_writefield(&ISR[irq - open_pic2_irq_offset]->Vector_Priority,
423 OPENPIC_PRIORITY_MASK,
424 9 << OPENPIC_PRIORITY_SHIFT);
425}
426
427/*
428 *
429 * All functions below take an offset'ed irq argument
430 *
431 */
432
433
434/*
435 * Enable/disable an external interrupt source
436 *
437 * Externally called, irq is an offseted system-wide interrupt number
438 */
439static void openpic2_enable_irq(u_int irq)
440{
441 volatile u_int *vpp;
442
443 check_arg_irq(irq);
444 vpp = &ISR[irq - open_pic2_irq_offset]->Vector_Priority;
445 openpic2_clearfield(vpp, OPENPIC_MASK);
446 /* make sure mask gets to controller before we return to user */
447 do {
448 mb(); /* sync is probably useless here */
449 } while (openpic2_readfield(vpp, OPENPIC_MASK));
450}
451
452static void openpic2_disable_irq(u_int irq)
453{
454 volatile u_int *vpp;
455 u32 vp;
456
457 check_arg_irq(irq);
458 vpp = &ISR[irq - open_pic2_irq_offset]->Vector_Priority;
459 openpic2_setfield(vpp, OPENPIC_MASK);
460 /* make sure mask gets to controller before we return to user */
461 do {
462 mb(); /* sync is probably useless here */
463 vp = openpic2_readfield(vpp, OPENPIC_MASK | OPENPIC_ACTIVITY);
464 } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
465}
466
467
468/*
469 * Initialize an interrupt source (and disable it!)
470 *
471 * irq: OpenPIC interrupt number
472 * pri: interrupt source priority
473 * vec: the vector it will produce
474 * pol: polarity (1 for positive, 0 for negative)
475 * sense: 1 for level, 0 for edge
476 */
477static void __init
478openpic2_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
479{
480 openpic2_safe_writefield(&ISR[irq]->Vector_Priority,
481 OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
482 OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
483 (pri << OPENPIC_PRIORITY_SHIFT) | vec |
484 (pol ? OPENPIC_POLARITY_POSITIVE :
485 OPENPIC_POLARITY_NEGATIVE) |
486 (sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
487}
488
489/*
490 * Map an interrupt source to one or more CPUs
491 */
492static void openpic2_mapirq(u_int irq, u_int physmask, u_int keepmask)
493{
494 if (ISR[irq] == 0)
495 return;
496 if (keepmask != 0)
497 physmask |= openpic2_read(&ISR[irq]->Destination) & keepmask;
498 openpic2_write(&ISR[irq]->Destination, physmask);
499}
500
501#ifdef notused
502/*
503 * Set the sense for an interrupt source (and disable it!)
504 *
505 * sense: 1 for level, 0 for edge
506 */
507static void openpic2_set_sense(u_int irq, int sense)
508{
509 if (ISR[irq] != 0)
510 openpic2_safe_writefield(&ISR[irq]->Vector_Priority,
511 OPENPIC_SENSE_LEVEL,
512 (sense ? OPENPIC_SENSE_LEVEL : 0));
513}
514#endif /* notused */
515
516/* No spinlocks, should not be necessary with the OpenPIC
517 * (1 register = 1 interrupt and we have the desc lock).
518 */
519static void openpic2_ack_irq(unsigned int irq_nr)
520{
521 openpic2_disable_irq(irq_nr);
522 openpic2_eoi();
523}
524
525static void openpic2_end_irq(unsigned int irq_nr)
526{
527 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
528 openpic2_enable_irq(irq_nr);
529}
530
531int
532openpic2_get_irq(void)
533{
534 int irq = openpic2_irq();
535
536 if (irq == (OPENPIC2_VEC_SPURIOUS + open_pic2_irq_offset))
537 irq = -1;
538 return irq;
539}
540
541#ifdef CONFIG_PM
542
543/*
544 * We implement the IRQ controller as a sysdev and put it
545 * to sleep at powerdown stage (the callback is named suspend,
546 * but it's old semantics, for the Device Model, it's really
547 * powerdown). The possible problem is that another sysdev that
548 * happens to be suspend after this one will have interrupts off,
549 * that may be an issue... For now, this isn't an issue on pmac
550 * though...
551 */
552
553static u32 save_ipi_vp[OPENPIC_NUM_IPI];
554static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES];
555static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES];
556static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS];
557static int openpic_suspend_count;
558
559static void openpic2_cached_enable_irq(u_int irq)
560{
561 check_arg_irq(irq);
562 save_irq_src_vp[irq - open_pic2_irq_offset] &= ~OPENPIC_MASK;
563}
564
565static void openpic2_cached_disable_irq(u_int irq)
566{
567 check_arg_irq(irq);
568 save_irq_src_vp[irq - open_pic2_irq_offset] |= OPENPIC_MASK;
569}
570
571/* WARNING: Can be called directly by the cpufreq code with NULL parameter,
572 * we need something better to deal with that... Maybe switch to S1 for
573 * cpufreq changes
574 */
575int openpic2_suspend(struct sys_device *sysdev, pm_message_t state)
576{
577 int i;
578 unsigned long flags;
579
580 spin_lock_irqsave(&openpic2_setup_lock, flags);
581
582 if (openpic_suspend_count++ > 0) {
583 spin_unlock_irqrestore(&openpic2_setup_lock, flags);
584 return 0;
585 }
586
587 open_pic2.enable = openpic2_cached_enable_irq;
588 open_pic2.disable = openpic2_cached_disable_irq;
589
590 for (i=0; i<NumProcessors; i++) {
591 save_cpu_task_pri[i] = openpic2_read(&OpenPIC2->Processor[i].Current_Task_Priority);
592 openpic2_writefield(&OpenPIC2->Processor[i].Current_Task_Priority,
593 OPENPIC_CURRENT_TASK_PRIORITY_MASK, 0xf);
594 }
595
596 for (i=0; i<OPENPIC_NUM_IPI; i++)
597 save_ipi_vp[i] = openpic2_read(&OpenPIC2->Global.IPI_Vector_Priority(i));
598 for (i=0; i<NumSources; i++) {
599 if (ISR[i] == 0)
600 continue;
601 save_irq_src_vp[i] = openpic2_read(&ISR[i]->Vector_Priority) & ~OPENPIC_ACTIVITY;
602 save_irq_src_dest[i] = openpic2_read(&ISR[i]->Destination);
603 }
604
605 spin_unlock_irqrestore(&openpic2_setup_lock, flags);
606
607 return 0;
608}
609
610/* WARNING: Can be called directly by the cpufreq code with NULL parameter,
611 * we need something better to deal with that... Maybe switch to S1 for
612 * cpufreq changes
613 */
614int openpic2_resume(struct sys_device *sysdev)
615{
616 int i;
617 unsigned long flags;
618 u32 vppmask = OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
619 OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK |
620 OPENPIC_MASK;
621
622 spin_lock_irqsave(&openpic2_setup_lock, flags);
623
624 if ((--openpic_suspend_count) > 0) {
625 spin_unlock_irqrestore(&openpic2_setup_lock, flags);
626 return 0;
627 }
628
629 openpic2_reset();
630
631 /* OpenPIC sometimes seem to need some time to be fully back up... */
632 do {
633 openpic2_set_spurious(OPENPIC2_VEC_SPURIOUS+open_pic2_irq_offset);
634 } while(openpic2_readfield(&OpenPIC2->Global.Spurious_Vector, OPENPIC_VECTOR_MASK)
635 != (OPENPIC2_VEC_SPURIOUS + open_pic2_irq_offset));
636
637 openpic2_disable_8259_pass_through();
638
639 for (i=0; i<OPENPIC_NUM_IPI; i++)
640 openpic2_write(&OpenPIC2->Global.IPI_Vector_Priority(i),
641 save_ipi_vp[i]);
642 for (i=0; i<NumSources; i++) {
643 if (ISR[i] == 0)
644 continue;
645 openpic2_write(&ISR[i]->Destination, save_irq_src_dest[i]);
646 openpic2_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);
647 /* make sure mask gets to controller before we return to user */
648 do {
649 openpic2_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);
650 } while (openpic2_readfield(&ISR[i]->Vector_Priority, vppmask)
651 != (save_irq_src_vp[i] & vppmask));
652 }
653 for (i=0; i<NumProcessors; i++)
654 openpic2_write(&OpenPIC2->Processor[i].Current_Task_Priority,
655 save_cpu_task_pri[i]);
656
657 open_pic2.enable = openpic2_enable_irq;
658 open_pic2.disable = openpic2_disable_irq;
659
660 spin_unlock_irqrestore(&openpic2_setup_lock, flags);
661
662 return 0;
663}
664
665#endif /* CONFIG_PM */
666
667/* HACK ALERT */
668static struct sysdev_class openpic2_sysclass = {
669 .name = "openpic2",
670};
671
672static struct sys_device device_openpic2 = {
673 .id = 0,
674 .cls = &openpic2_sysclass,
675};
676
677static struct sysdev_driver driver_openpic2 = {
678#ifdef CONFIG_PM
679 .suspend = &openpic2_suspend,
680 .resume = &openpic2_resume,
681#endif /* CONFIG_PM */
682};
683
684static int __init init_openpic2_sysfs(void)
685{
686 int rc;
687
688 if (!OpenPIC2_Addr)
689 return -ENODEV;
690 printk(KERN_DEBUG "Registering openpic2 with sysfs...\n");
691 rc = sysdev_class_register(&openpic2_sysclass);
692 if (rc) {
693 printk(KERN_ERR "Failed registering openpic sys class\n");
694 return -ENODEV;
695 }
696 rc = sysdev_register(&device_openpic2);
697 if (rc) {
698 printk(KERN_ERR "Failed registering openpic sys device\n");
699 return -ENODEV;
700 }
701 rc = sysdev_driver_register(&openpic2_sysclass, &driver_openpic2);
702 if (rc) {
703 printk(KERN_ERR "Failed registering openpic sys driver\n");
704 return -ENODEV;
705 }
706 return 0;
707}
708
709subsys_initcall(init_openpic2_sysfs);
710
diff --git a/arch/ppc/syslib/open_pic_defs.h b/arch/ppc/syslib/open_pic_defs.h
deleted file mode 100644
index 3a25de7cb572..000000000000
--- a/arch/ppc/syslib/open_pic_defs.h
+++ /dev/null
@@ -1,287 +0,0 @@
1/*
2 * Copyright (C) 1997 Geert Uytterhoeven
3 *
4 * This file is based on the following documentation:
5 *
6 * The Open Programmable Interrupt Controller (PIC)
7 * Register Interface Specification Revision 1.2
8 *
9 * Issue Date: October 1995
10 *
11 * Issued jointly by Advanced Micro Devices and Cyrix Corporation
12 *
13 * AMD is a registered trademark of Advanced Micro Devices, Inc.
14 * Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc.
15 * All Rights Reserved.
16 *
17 * To receive a copy of this documentation, send an email to openpic@amd.com.
18 *
19 * This file is subject to the terms and conditions of the GNU General Public
20 * License. See the file COPYING in the main directory of this archive
21 * for more details.
22 */
23
24#ifndef _LINUX_OPENPIC_H
25#define _LINUX_OPENPIC_H
26
27#ifdef __KERNEL__
28
29 /*
30 * OpenPIC supports up to 2048 interrupt sources and up to 32 processors
31 */
32
33#define OPENPIC_MAX_SOURCES 2048
34#define OPENPIC_MAX_PROCESSORS 32
35#define OPENPIC_MAX_ISU 16
36
37#define OPENPIC_NUM_TIMERS 4
38#define OPENPIC_NUM_IPI 4
39#define OPENPIC_NUM_PRI 16
40#define OPENPIC_NUM_VECTORS 256
41
42
43
44 /*
45 * OpenPIC Registers are 32 bits and aligned on 128 bit boundaries
46 */
47
48typedef struct _OpenPIC_Reg {
49 u_int Reg; /* Little endian! */
50 char Pad[0xc];
51} OpenPIC_Reg;
52
53
54 /*
55 * Per Processor Registers
56 */
57
58typedef struct _OpenPIC_Processor {
59 /*
60 * Private Shadow Registers (for SLiC backwards compatibility)
61 */
62 u_int IPI0_Dispatch_Shadow; /* Write Only */
63 char Pad1[0x4];
64 u_int IPI0_Vector_Priority_Shadow; /* Read/Write */
65 char Pad2[0x34];
66 /*
67 * Interprocessor Interrupt Command Ports
68 */
69 OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI]; /* Write Only */
70 /*
71 * Current Task Priority Register
72 */
73 OpenPIC_Reg _Current_Task_Priority; /* Read/Write */
74 char Pad3[0x10];
75 /*
76 * Interrupt Acknowledge Register
77 */
78 OpenPIC_Reg _Interrupt_Acknowledge; /* Read Only */
79 /*
80 * End of Interrupt (EOI) Register
81 */
82 OpenPIC_Reg _EOI; /* Read/Write */
83 char Pad5[0xf40];
84} OpenPIC_Processor;
85
86
87 /*
88 * Timer Registers
89 */
90
91typedef struct _OpenPIC_Timer {
92 OpenPIC_Reg _Current_Count; /* Read Only */
93 OpenPIC_Reg _Base_Count; /* Read/Write */
94 OpenPIC_Reg _Vector_Priority; /* Read/Write */
95 OpenPIC_Reg _Destination; /* Read/Write */
96} OpenPIC_Timer;
97
98
99 /*
100 * Global Registers
101 */
102
103typedef struct _OpenPIC_Global {
104 /*
105 * Feature Reporting Registers
106 */
107 OpenPIC_Reg _Feature_Reporting0; /* Read Only */
108 OpenPIC_Reg _Feature_Reporting1; /* Future Expansion */
109 /*
110 * Global Configuration Registers
111 */
112 OpenPIC_Reg _Global_Configuration0; /* Read/Write */
113 OpenPIC_Reg _Global_Configuration1; /* Future Expansion */
114 /*
115 * Vendor Specific Registers
116 */
117 OpenPIC_Reg _Vendor_Specific[4];
118 /*
119 * Vendor Identification Register
120 */
121 OpenPIC_Reg _Vendor_Identification; /* Read Only */
122 /*
123 * Processor Initialization Register
124 */
125 OpenPIC_Reg _Processor_Initialization; /* Read/Write */
126 /*
127 * IPI Vector/Priority Registers
128 */
129 OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */
130 /*
131 * Spurious Vector Register
132 */
133 OpenPIC_Reg _Spurious_Vector; /* Read/Write */
134 /*
135 * Global Timer Registers
136 */
137 OpenPIC_Reg _Timer_Frequency; /* Read/Write */
138 OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS];
139 char Pad1[0xee00];
140} OpenPIC_Global;
141
142
143 /*
144 * Interrupt Source Registers
145 */
146
147typedef struct _OpenPIC_Source {
148 OpenPIC_Reg _Vector_Priority; /* Read/Write */
149 OpenPIC_Reg _Destination; /* Read/Write */
150} OpenPIC_Source, *OpenPIC_SourcePtr;
151
152
153 /*
154 * OpenPIC Register Map
155 */
156
157struct OpenPIC {
158 char Pad1[0x1000];
159 /*
160 * Global Registers
161 */
162 OpenPIC_Global Global;
163 /*
164 * Interrupt Source Configuration Registers
165 */
166 OpenPIC_Source Source[OPENPIC_MAX_SOURCES];
167 /*
168 * Per Processor Registers
169 */
170 OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS];
171};
172
173 /*
174 * Current Task Priority Register
175 */
176
177#define OPENPIC_CURRENT_TASK_PRIORITY_MASK 0x0000000f
178
179 /*
180 * Who Am I Register
181 */
182
183#define OPENPIC_WHO_AM_I_ID_MASK 0x0000001f
184
185 /*
186 * Feature Reporting Register 0
187 */
188
189#define OPENPIC_FEATURE_LAST_SOURCE_MASK 0x07ff0000
190#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT 16
191#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK 0x00001f00
192#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT 8
193#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff
194
195 /*
196 * Global Configuration Register 0
197 */
198
199#define OPENPIC_CONFIG_RESET 0x80000000
200#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE 0x20000000
201#define OPENPIC_CONFIG_BASE_MASK 0x000fffff
202
203 /*
204 * Global Configuration Register 1
205 * This is the EICR on EPICs.
206 */
207
208#define OPENPIC_EICR_S_CLK_MASK 0x70000000
209#define OPENPIC_EICR_SIE 0x08000000
210
211 /*
212 * Vendor Identification Register
213 */
214
215#define OPENPIC_VENDOR_ID_STEPPING_MASK 0x00ff0000
216#define OPENPIC_VENDOR_ID_STEPPING_SHIFT 16
217#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00
218#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT 8
219#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK 0x000000ff
220
221 /*
222 * Vector/Priority Registers
223 */
224
225#define OPENPIC_MASK 0x80000000
226#define OPENPIC_ACTIVITY 0x40000000 /* Read Only */
227#define OPENPIC_PRIORITY_MASK 0x000f0000
228#define OPENPIC_PRIORITY_SHIFT 16
229#define OPENPIC_VECTOR_MASK 0x000000ff
230
231
232 /*
233 * Interrupt Source Registers
234 */
235
236#define OPENPIC_POLARITY_POSITIVE 0x00800000
237#define OPENPIC_POLARITY_NEGATIVE 0x00000000
238#define OPENPIC_POLARITY_MASK 0x00800000
239#define OPENPIC_SENSE_LEVEL 0x00400000
240#define OPENPIC_SENSE_EDGE 0x00000000
241#define OPENPIC_SENSE_MASK 0x00400000
242
243
244 /*
245 * Timer Registers
246 */
247
248#define OPENPIC_COUNT_MASK 0x7fffffff
249#define OPENPIC_TIMER_TOGGLE 0x80000000
250#define OPENPIC_TIMER_COUNT_INHIBIT 0x80000000
251
252
253 /*
254 * Aliases to make life simpler
255 */
256
257/* Per Processor Registers */
258#define IPI_Dispatch(i) _IPI_Dispatch[i].Reg
259#define Current_Task_Priority _Current_Task_Priority.Reg
260#define Interrupt_Acknowledge _Interrupt_Acknowledge.Reg
261#define EOI _EOI.Reg
262
263/* Global Registers */
264#define Feature_Reporting0 _Feature_Reporting0.Reg
265#define Feature_Reporting1 _Feature_Reporting1.Reg
266#define Global_Configuration0 _Global_Configuration0.Reg
267#define Global_Configuration1 _Global_Configuration1.Reg
268#define Vendor_Specific(i) _Vendor_Specific[i].Reg
269#define Vendor_Identification _Vendor_Identification.Reg
270#define Processor_Initialization _Processor_Initialization.Reg
271#define IPI_Vector_Priority(i) _IPI_Vector_Priority[i].Reg
272#define Spurious_Vector _Spurious_Vector.Reg
273#define Timer_Frequency _Timer_Frequency.Reg
274
275/* Timer Registers */
276#define Current_Count _Current_Count.Reg
277#define Base_Count _Base_Count.Reg
278#define Vector_Priority _Vector_Priority.Reg
279#define Destination _Destination.Reg
280
281/* Interrupt Source Registers */
282#define Vector_Priority _Vector_Priority.Reg
283#define Destination _Destination.Reg
284
285#endif /* __KERNEL__ */
286
287#endif /* _LINUX_OPENPIC_H */
diff --git a/arch/ppc/syslib/pci_auto.c b/arch/ppc/syslib/pci_auto.c
deleted file mode 100644
index ee20a86fcc4b..000000000000
--- a/arch/ppc/syslib/pci_auto.c
+++ /dev/null
@@ -1,515 +0,0 @@
1/*
2 * PCI autoconfiguration library
3 *
4 * Author: Matt Porter <mporter@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/*
13 * The CardBus support is very preliminary. Preallocating space is
14 * the way to go but will require some change in card services to
15 * make it useful. Eventually this will ensure that we can put
16 * multiple CB bridges behind multiple P2P bridges. For now, at
17 * least it ensures that we place the CB bridge BAR and assigned
18 * initial bus numbers. I definitely need to do something about
19 * the lack of 16-bit I/O support. -MDP
20 */
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25
26#include <asm/pci-bridge.h>
27
28#define PCIAUTO_IDE_MODE_MASK 0x05
29
30#undef DEBUG
31
32#ifdef DEBUG
33#define DBG(x...) printk(x)
34#else
35#define DBG(x...)
36#endif /* DEBUG */
37
38static int pciauto_upper_iospc;
39static int pciauto_upper_memspc;
40
41void __init pciauto_setup_bars(struct pci_controller *hose,
42 int current_bus,
43 int pci_devfn,
44 int bar_limit)
45{
46 int bar_response, bar_size, bar_value;
47 int bar, addr_mask;
48 int * upper_limit;
49 int found_mem64 = 0;
50
51 DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
52 current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
53
54 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
55 /* Tickle the BAR and get the response */
56 early_write_config_dword(hose,
57 current_bus,
58 pci_devfn,
59 bar,
60 0xffffffff);
61 early_read_config_dword(hose,
62 current_bus,
63 pci_devfn,
64 bar,
65 &bar_response);
66
67 /* If BAR is not implemented go to the next BAR */
68 if (!bar_response)
69 continue;
70
71 /* Check the BAR type and set our address mask */
72 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
73 addr_mask = PCI_BASE_ADDRESS_IO_MASK;
74 upper_limit = &pciauto_upper_iospc;
75 DBG("PCI Autoconfig: BAR 0x%x, I/O, ", bar);
76 } else {
77 if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
78 PCI_BASE_ADDRESS_MEM_TYPE_64)
79 found_mem64 = 1;
80
81 addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
82 upper_limit = &pciauto_upper_memspc;
83 DBG("PCI Autoconfig: BAR 0x%x, Mem ", bar);
84 }
85
86 /* Calculate requested size */
87 bar_size = ~(bar_response & addr_mask) + 1;
88
89 /* Allocate a base address */
90 bar_value = (*upper_limit - bar_size) & ~(bar_size - 1);
91
92 /* Write it out and update our limit */
93 early_write_config_dword(hose,
94 current_bus,
95 pci_devfn,
96 bar,
97 bar_value);
98
99 *upper_limit = bar_value;
100
101 /*
102 * If we are a 64-bit decoder then increment to the
103 * upper 32 bits of the bar and force it to locate
104 * in the lower 4GB of memory.
105 */
106 if (found_mem64) {
107 bar += 4;
108 early_write_config_dword(hose,
109 current_bus,
110 pci_devfn,
111 bar,
112 0x00000000);
113 found_mem64 = 0;
114 }
115
116 DBG("size=0x%x, address=0x%x\n",
117 bar_size, bar_value);
118 }
119
120}
121
122void __init pciauto_prescan_setup_bridge(struct pci_controller *hose,
123 int current_bus,
124 int pci_devfn,
125 int sub_bus,
126 int *iosave,
127 int *memsave)
128{
129 /* Configure bus number registers */
130 early_write_config_byte(hose,
131 current_bus,
132 pci_devfn,
133 PCI_PRIMARY_BUS,
134 current_bus);
135 early_write_config_byte(hose,
136 current_bus,
137 pci_devfn,
138 PCI_SECONDARY_BUS,
139 sub_bus + 1);
140 early_write_config_byte(hose,
141 current_bus,
142 pci_devfn,
143 PCI_SUBORDINATE_BUS,
144 0xff);
145
146 /* Round memory allocator to 1MB boundary */
147 pciauto_upper_memspc &= ~(0x100000 - 1);
148 *memsave = pciauto_upper_memspc;
149
150 /* Round I/O allocator to 4KB boundary */
151 pciauto_upper_iospc &= ~(0x1000 - 1);
152 *iosave = pciauto_upper_iospc;
153
154 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
155 early_write_config_word(hose,
156 current_bus,
157 pci_devfn,
158 PCI_MEMORY_LIMIT,
159 ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
160 early_write_config_byte(hose,
161 current_bus,
162 pci_devfn,
163 PCI_IO_LIMIT,
164 ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
165 early_write_config_word(hose,
166 current_bus,
167 pci_devfn,
168 PCI_IO_LIMIT_UPPER16,
169 ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
170
171 /* Zero upper 32 bits of prefetchable base/limit */
172 early_write_config_dword(hose,
173 current_bus,
174 pci_devfn,
175 PCI_PREF_BASE_UPPER32,
176 0);
177 early_write_config_dword(hose,
178 current_bus,
179 pci_devfn,
180 PCI_PREF_LIMIT_UPPER32,
181 0);
182}
183
184void __init pciauto_postscan_setup_bridge(struct pci_controller *hose,
185 int current_bus,
186 int pci_devfn,
187 int sub_bus,
188 int *iosave,
189 int *memsave)
190{
191 int cmdstat;
192
193 /* Configure bus number registers */
194 early_write_config_byte(hose,
195 current_bus,
196 pci_devfn,
197 PCI_SUBORDINATE_BUS,
198 sub_bus);
199
200 /*
201 * Round memory allocator to 1MB boundary.
202 * If no space used, allocate minimum.
203 */
204 pciauto_upper_memspc &= ~(0x100000 - 1);
205 if (*memsave == pciauto_upper_memspc)
206 pciauto_upper_memspc -= 0x00100000;
207
208 early_write_config_word(hose,
209 current_bus,
210 pci_devfn,
211 PCI_MEMORY_BASE,
212 pciauto_upper_memspc >> 16);
213
214 /* Allocate 1MB for pre-fretch */
215 early_write_config_word(hose,
216 current_bus,
217 pci_devfn,
218 PCI_PREF_MEMORY_LIMIT,
219 ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
220
221 pciauto_upper_memspc -= 0x100000;
222
223 early_write_config_word(hose,
224 current_bus,
225 pci_devfn,
226 PCI_PREF_MEMORY_BASE,
227 pciauto_upper_memspc >> 16);
228
229 /* Round I/O allocator to 4KB boundary */
230 pciauto_upper_iospc &= ~(0x1000 - 1);
231 if (*iosave == pciauto_upper_iospc)
232 pciauto_upper_iospc -= 0x1000;
233
234 early_write_config_byte(hose,
235 current_bus,
236 pci_devfn,
237 PCI_IO_BASE,
238 (pciauto_upper_iospc & 0x0000f000) >> 8);
239 early_write_config_word(hose,
240 current_bus,
241 pci_devfn,
242 PCI_IO_BASE_UPPER16,
243 pciauto_upper_iospc >> 16);
244
245 /* Enable memory and I/O accesses, enable bus master */
246 early_read_config_dword(hose,
247 current_bus,
248 pci_devfn,
249 PCI_COMMAND,
250 &cmdstat);
251 early_write_config_dword(hose,
252 current_bus,
253 pci_devfn,
254 PCI_COMMAND,
255 cmdstat |
256 PCI_COMMAND_IO |
257 PCI_COMMAND_MEMORY |
258 PCI_COMMAND_MASTER);
259}
260
261void __init pciauto_prescan_setup_cardbus_bridge(struct pci_controller *hose,
262 int current_bus,
263 int pci_devfn,
264 int sub_bus,
265 int *iosave,
266 int *memsave)
267{
268 /* Configure bus number registers */
269 early_write_config_byte(hose,
270 current_bus,
271 pci_devfn,
272 PCI_PRIMARY_BUS,
273 current_bus);
274 early_write_config_byte(hose,
275 current_bus,
276 pci_devfn,
277 PCI_SECONDARY_BUS,
278 sub_bus + 1);
279 early_write_config_byte(hose,
280 current_bus,
281 pci_devfn,
282 PCI_SUBORDINATE_BUS,
283 0xff);
284
285 /* Round memory allocator to 4KB boundary */
286 pciauto_upper_memspc &= ~(0x1000 - 1);
287 *memsave = pciauto_upper_memspc;
288
289 /* Round I/O allocator to 4 byte boundary */
290 pciauto_upper_iospc &= ~(0x4 - 1);
291 *iosave = pciauto_upper_iospc;
292
293 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
294 early_write_config_dword(hose,
295 current_bus,
296 pci_devfn,
297 0x20,
298 pciauto_upper_memspc - 1);
299 early_write_config_dword(hose,
300 current_bus,
301 pci_devfn,
302 0x30,
303 pciauto_upper_iospc - 1);
304}
305
306void __init pciauto_postscan_setup_cardbus_bridge(struct pci_controller *hose,
307 int current_bus,
308 int pci_devfn,
309 int sub_bus,
310 int *iosave,
311 int *memsave)
312{
313 int cmdstat;
314
315 /*
316 * Configure subordinate bus number. The PCI subsystem
317 * bus scan will renumber buses (reserving three additional
318 * for this PCI<->CardBus bridge for the case where a CardBus
319 * adapter contains a P2P or CB2CB bridge.
320 */
321 early_write_config_byte(hose,
322 current_bus,
323 pci_devfn,
324 PCI_SUBORDINATE_BUS,
325 sub_bus);
326
327 /*
328 * Reserve an additional 4MB for mem space and 16KB for
329 * I/O space. This should cover any additional space
330 * requirement of unusual CardBus devices with
331 * additional bridges that can consume more address space.
332 *
333 * Although pcmcia-cs currently will reprogram bridge
334 * windows, the goal is to add an option to leave them
335 * alone and use the bridge window ranges as the regions
336 * that are searched for free resources upon hot-insertion
337 * of a device. This will allow a PCI<->CardBus bridge
338 * configured by this routine to happily live behind a
339 * P2P bridge in a system.
340 */
341 pciauto_upper_memspc -= 0x00400000;
342 pciauto_upper_iospc -= 0x00004000;
343
344 /* Round memory allocator to 4KB boundary */
345 pciauto_upper_memspc &= ~(0x1000 - 1);
346
347 early_write_config_dword(hose,
348 current_bus,
349 pci_devfn,
350 0x1c,
351 pciauto_upper_memspc);
352
353 /* Round I/O allocator to 4 byte boundary */
354 pciauto_upper_iospc &= ~(0x4 - 1);
355 early_write_config_dword(hose,
356 current_bus,
357 pci_devfn,
358 0x2c,
359 pciauto_upper_iospc);
360
361 /* Enable memory and I/O accesses, enable bus master */
362 early_read_config_dword(hose,
363 current_bus,
364 pci_devfn,
365 PCI_COMMAND,
366 &cmdstat);
367 early_write_config_dword(hose,
368 current_bus,
369 pci_devfn,
370 PCI_COMMAND,
371 cmdstat |
372 PCI_COMMAND_IO |
373 PCI_COMMAND_MEMORY |
374 PCI_COMMAND_MASTER);
375}
376
377int __init pciauto_bus_scan(struct pci_controller *hose, int current_bus)
378{
379 int sub_bus, pci_devfn, pci_class, cmdstat, found_multi = 0;
380 unsigned short vid;
381 unsigned char header_type;
382
383 /*
384 * Fetch our I/O and memory space upper boundaries used
385 * to allocated base addresses on this hose.
386 */
387 if (current_bus == hose->first_busno) {
388 pciauto_upper_iospc = hose->io_space.end + 1;
389 pciauto_upper_memspc = hose->mem_space.end + 1;
390 }
391
392 sub_bus = current_bus;
393
394 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
395 /* Skip our host bridge */
396 if ( (current_bus == hose->first_busno) && (pci_devfn == 0) )
397 continue;
398
399 if (PCI_FUNC(pci_devfn) && !found_multi)
400 continue;
401
402 /* If config space read fails from this device, move on */
403 if (early_read_config_byte(hose,
404 current_bus,
405 pci_devfn,
406 PCI_HEADER_TYPE,
407 &header_type))
408 continue;
409
410 if (!PCI_FUNC(pci_devfn))
411 found_multi = header_type & 0x80;
412
413 early_read_config_word(hose,
414 current_bus,
415 pci_devfn,
416 PCI_VENDOR_ID,
417 &vid);
418
419 if (vid != 0xffff) {
420 early_read_config_dword(hose,
421 current_bus,
422 pci_devfn,
423 PCI_CLASS_REVISION, &pci_class);
424 if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) {
425 int iosave, memsave;
426
427 DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn));
428 /* Allocate PCI I/O and/or memory space */
429 pciauto_setup_bars(hose,
430 current_bus,
431 pci_devfn,
432 PCI_BASE_ADDRESS_1);
433
434 pciauto_prescan_setup_bridge(hose,
435 current_bus,
436 pci_devfn,
437 sub_bus,
438 &iosave,
439 &memsave);
440 sub_bus = pciauto_bus_scan(hose, sub_bus+1);
441 pciauto_postscan_setup_bridge(hose,
442 current_bus,
443 pci_devfn,
444 sub_bus,
445 &iosave,
446 &memsave);
447 } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) {
448 int iosave, memsave;
449
450 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
451 /* Place CardBus Socket/ExCA registers */
452 pciauto_setup_bars(hose,
453 current_bus,
454 pci_devfn,
455 PCI_BASE_ADDRESS_0);
456
457 pciauto_prescan_setup_cardbus_bridge(hose,
458 current_bus,
459 pci_devfn,
460 sub_bus,
461 &iosave,
462 &memsave);
463 sub_bus = pciauto_bus_scan(hose, sub_bus+1);
464 pciauto_postscan_setup_cardbus_bridge(hose,
465 current_bus,
466 pci_devfn,
467 sub_bus,
468 &iosave,
469 &memsave);
470 } else {
471 if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
472 unsigned char prg_iface;
473
474 early_read_config_byte(hose,
475 current_bus,
476 pci_devfn,
477 PCI_CLASS_PROG,
478 &prg_iface);
479 if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
480 DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n");
481 continue;
482 }
483 }
484 /* Allocate PCI I/O and/or memory space */
485 pciauto_setup_bars(hose,
486 current_bus,
487 pci_devfn,
488 PCI_BASE_ADDRESS_5);
489
490 /*
491 * Enable some standard settings
492 */
493 early_read_config_dword(hose,
494 current_bus,
495 pci_devfn,
496 PCI_COMMAND,
497 &cmdstat);
498 early_write_config_dword(hose,
499 current_bus,
500 pci_devfn,
501 PCI_COMMAND,
502 cmdstat |
503 PCI_COMMAND_IO |
504 PCI_COMMAND_MEMORY |
505 PCI_COMMAND_MASTER);
506 early_write_config_byte(hose,
507 current_bus,
508 pci_devfn,
509 PCI_LATENCY_TIMER,
510 0x80);
511 }
512 }
513 }
514 return sub_bus;
515}
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
deleted file mode 100644
index c3b7b8bfbcfe..000000000000
--- a/arch/ppc/syslib/ppc403_pic.c
+++ /dev/null
@@ -1,125 +0,0 @@
1/*
2 *
3 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Module name: ppc403_pic.c
6 *
7 * Description:
8 * Interrupt controller driver for PowerPC 403-based processors.
9 */
10
11/*
12 * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
13 * 32 possible interrupts, a majority of which are not implemented on
14 * all cores. There are six configurable, external interrupt pins and
15 * there are eight internal interrupts for the on-chip serial port
16 * (SPU), DMA controller, and JTAG controller.
17 *
18 */
19
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/signal.h>
23#include <linux/stddef.h>
24
25#include <asm/processor.h>
26#include <asm/system.h>
27#include <asm/irq.h>
28#include <asm/ppc4xx_pic.h>
29#include <asm/machdep.h>
30
31/* Function Prototypes */
32
33static void ppc403_aic_enable(unsigned int irq);
34static void ppc403_aic_disable(unsigned int irq);
35static void ppc403_aic_disable_and_ack(unsigned int irq);
36
37static struct hw_interrupt_type ppc403_aic = {
38 .typename = "403GC AIC",
39 .enable = ppc403_aic_enable,
40 .disable = ppc403_aic_disable,
41 .ack = ppc403_aic_disable_and_ack,
42};
43
44int
45ppc403_pic_get_irq(void)
46{
47 int irq;
48 unsigned long bits;
49
50 /*
51 * Only report the status of those interrupts that are actually
52 * enabled.
53 */
54
55 bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
56
57 /*
58 * Walk through the interrupts from highest priority to lowest, and
59 * report the first pending interrupt found.
60 * We want PPC, not C bit numbering, so just subtract the ffs()
61 * result from 32.
62 */
63 irq = 32 - ffs(bits);
64
65 if (irq == NR_AIC_IRQS)
66 irq = -1;
67
68 return (irq);
69}
70
71static void
72ppc403_aic_enable(unsigned int irq)
73{
74 int bit, word;
75
76 bit = irq & 0x1f;
77 word = irq >> 5;
78
79 ppc_cached_irq_mask[word] |= (1 << (31 - bit));
80 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
81}
82
83static void
84ppc403_aic_disable(unsigned int irq)
85{
86 int bit, word;
87
88 bit = irq & 0x1f;
89 word = irq >> 5;
90
91 ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
92 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
93}
94
95static void
96ppc403_aic_disable_and_ack(unsigned int irq)
97{
98 int bit, word;
99
100 bit = irq & 0x1f;
101 word = irq >> 5;
102
103 ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
104 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
105 mtdcr(DCRN_EXISR, (1 << (31 - bit)));
106}
107
108void __init
109ppc4xx_pic_init(void)
110{
111 int i;
112
113 /*
114 * Disable all external interrupts until they are
115 * explicitly requested.
116 */
117 ppc_cached_irq_mask[0] = 0;
118
119 mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
120
121 ppc_md.get_irq = ppc403_pic_get_irq;
122
123 for (i = 0; i < NR_IRQS; i++)
124 irq_desc[i].chip = &ppc403_aic;
125}
diff --git a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
deleted file mode 100644
index 9e9035693bfa..000000000000
--- a/arch/ppc/syslib/ppc405_pci.c
+++ /dev/null
@@ -1,170 +0,0 @@
1/*
2 * Authors: Frank Rowand <frank_rowand@mvista.com>,
3 * Debbie Chu <debbie_chu@mvista.com>, or source@mvista.com
4 * Further modifications by Armin Kuster <akuster@mvista.com>
5 *
6 * 2000 (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 * Based on arch/ppc/kernel/indirect.c, Copyright (C) 1998 Gabriel Paubert.
12 */
13
14#include <linux/pci.h>
15#include <asm/io.h>
16#include <asm/system.h>
17#include <asm/machdep.h>
18#include <linux/init.h>
19#include <linux/errno.h>
20#include <asm/ocp.h>
21#include <asm/ibm4xx.h>
22#include <asm/pci-bridge.h>
23#include <asm/ibm_ocp_pci.h>
24
25
26extern void bios_fixup(struct pci_controller *, struct pcil0_regs *);
27extern int ppc405_map_irq(struct pci_dev *dev, unsigned char idsel,
28 unsigned char pin);
29
30void
31ppc405_pcibios_fixup_resources(struct pci_dev *dev)
32{
33 int i;
34 unsigned long max_host_addr;
35 unsigned long min_host_addr;
36 struct resource *res;
37
38 /*
39 * openbios puts some graphics cards in the same range as the host
40 * controller uses to map to SDRAM. Fix it.
41 */
42
43 min_host_addr = 0;
44 max_host_addr = PPC405_PCI_MEM_BASE - 1;
45
46 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
47 res = dev->resource + i;
48 if (!res->start)
49 continue;
50 if ((res->flags & IORESOURCE_MEM) &&
51 (((res->start >= min_host_addr)
52 && (res->start <= max_host_addr))
53 || ((res->end >= min_host_addr)
54 && (res->end <= max_host_addr))
55 || ((res->start < min_host_addr)
56 && (res->end > max_host_addr))
57 )
58 ) {
59
60 /* force pcibios_assign_resources() to assign a new address */
61 res->end -= res->start;
62 res->start = 0;
63 }
64 }
65}
66
67static int
68ppc4xx_exclude_device(unsigned char bus, unsigned char devfn)
69{
70 /* We prevent us from seeing ourselves to avoid having
71 * the kernel try to remap our BAR #1 and fuck up bus
72 * master from external PCI devices
73 */
74 return (bus == 0 && devfn == 0);
75}
76
77void
78ppc4xx_find_bridges(void)
79{
80 struct pci_controller *hose_a;
81 struct pcil0_regs *pcip;
82 unsigned int tmp_addr;
83 unsigned int tmp_size;
84 unsigned int reg_index;
85 unsigned int new_pmm_max = 0;
86 unsigned int new_pmm_min = 0;
87
88 isa_io_base = 0;
89 isa_mem_base = 0;
90 pci_dram_offset = 0;
91
92 /* Setup PCI32 hose */
93 hose_a = pcibios_alloc_controller();
94 if (!hose_a)
95 return;
96 setup_indirect_pci(hose_a, PPC405_PCI_CONFIG_ADDR,
97 PPC405_PCI_CONFIG_DATA);
98
99 pcip = ioremap(PPC4xx_PCI_LCFG_PADDR, PAGE_SIZE);
100 if (pcip != NULL) {
101
102#if defined(CONFIG_BIOS_FIXUP)
103 bios_fixup(hose_a, pcip);
104#endif
105 new_pmm_min = 0xffffffff;
106 for (reg_index = 0; reg_index < 3; reg_index++) {
107 tmp_size = in_le32(&pcip->pmm[reg_index].ma); // mask & attrs
108 /* test the enable bit */
109 if ((tmp_size & 0x1) == 0)
110 continue;
111 tmp_addr = in_le32(&pcip->pmm[reg_index].pcila); // PCI addr
112 if (tmp_addr < PPC405_PCI_PHY_MEM_BASE) {
113 printk(KERN_DEBUG
114 "Disabling mapping to PCI mem addr 0x%8.8x\n",
115 tmp_addr);
116 out_le32(&pcip->pmm[reg_index].ma, tmp_size & ~1); // *_PMMOMA
117 continue;
118 }
119 tmp_addr = in_le32(&pcip->pmm[reg_index].la); // *_PMMOLA
120 if (tmp_addr < new_pmm_min)
121 new_pmm_min = tmp_addr;
122 tmp_addr = tmp_addr +
123 (0xffffffff - (tmp_size & 0xffffc000));
124 if (tmp_addr > PPC405_PCI_UPPER_MEM) {
125 new_pmm_max = tmp_addr; // PPC405_PCI_UPPER_MEM
126 } else {
127 new_pmm_max = PPC405_PCI_UPPER_MEM;
128 }
129
130 } // for
131
132 iounmap(pcip);
133 }
134
135 hose_a->first_busno = 0;
136 hose_a->last_busno = 0xff;
137 hose_a->pci_mem_offset = 0;
138
139 /* Setup bridge memory/IO ranges & resources
140 * TODO: Handle firmware setting up a legacy ISA mem base
141 */
142 hose_a->io_space.start = PPC405_PCI_LOWER_IO;
143 hose_a->io_space.end = PPC405_PCI_UPPER_IO;
144 hose_a->mem_space.start = new_pmm_min;
145 hose_a->mem_space.end = new_pmm_max;
146 hose_a->io_base_phys = PPC405_PCI_PHY_IO_BASE;
147 hose_a->io_base_virt = ioremap(hose_a->io_base_phys, 0x10000);
148 hose_a->io_resource.start = 0;
149 hose_a->io_resource.end = PPC405_PCI_UPPER_IO - PPC405_PCI_LOWER_IO;
150 hose_a->io_resource.flags = IORESOURCE_IO;
151 hose_a->io_resource.name = "PCI I/O";
152 hose_a->mem_resources[0].start = new_pmm_min;
153 hose_a->mem_resources[0].end = new_pmm_max;
154 hose_a->mem_resources[0].flags = IORESOURCE_MEM;
155 hose_a->mem_resources[0].name = "PCI Memory";
156 isa_io_base = (int) hose_a->io_base_virt;
157 isa_mem_base = 0; /* ISA not implemented */
158 ISA_DMA_THRESHOLD = 0x00ffffff; /* ??? ISA not implemented */
159
160 /* Scan busses & initial setup by pci_auto */
161 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
162 hose_a->last_busno = 0;
163
164 /* Setup ppc_md */
165 ppc_md.pcibios_fixup = NULL;
166 ppc_md.pci_exclude_device = ppc4xx_exclude_device;
167 ppc_md.pcibios_fixup_resources = ppc405_pcibios_fixup_resources;
168 ppc_md.pci_swizzle = common_swizzle;
169 ppc_md.pci_map_irq = ppc405_map_irq;
170}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
deleted file mode 100644
index dd5d4b958c31..000000000000
--- a/arch/ppc/syslib/ppc440spe_pcie.c
+++ /dev/null
@@ -1,441 +0,0 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * Roland Dreier <rolandd@cisco.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/pci.h>
14#include <linux/init.h>
15
16#include <asm/reg.h>
17#include <asm/io.h>
18#include <asm/ibm44x.h>
19
20#include "ppc440spe_pcie.h"
21
22static int
23pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
24 int len, u32 *val)
25{
26 struct pci_controller *hose = bus->sysdata;
27
28 if (PCI_SLOT(devfn) != 1)
29 return PCIBIOS_DEVICE_NOT_FOUND;
30
31 offset += devfn << 12;
32
33 /*
34 * Note: the caller has already checked that offset is
35 * suitably aligned and that len is 1, 2 or 4.
36 */
37 switch (len) {
38 case 1:
39 *val = in_8(hose->cfg_data + offset);
40 break;
41 case 2:
42 *val = in_le16(hose->cfg_data + offset);
43 break;
44 default:
45 *val = in_le32(hose->cfg_data + offset);
46 break;
47 }
48
49 if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
50
51 return PCIBIOS_SUCCESSFUL;
52}
53
54static int
55pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
56 int len, u32 val)
57{
58 struct pci_controller *hose = bus->sysdata;
59
60 if (PCI_SLOT(devfn) != 1)
61 return PCIBIOS_DEVICE_NOT_FOUND;
62
63 offset += devfn << 12;
64
65 switch (len) {
66 case 1:
67 out_8(hose->cfg_data + offset, val);
68 break;
69 case 2:
70 out_le16(hose->cfg_data + offset, val);
71 break;
72 default:
73 out_le32(hose->cfg_data + offset, val);
74 break;
75 }
76 return PCIBIOS_SUCCESSFUL;
77}
78
79static struct pci_ops pcie_pci_ops =
80{
81 .read = pcie_read_config,
82 .write = pcie_write_config
83};
84
85enum {
86 PTYPE_ENDPOINT = 0x0,
87 PTYPE_LEGACY_ENDPOINT = 0x1,
88 PTYPE_ROOT_PORT = 0x4,
89
90 LNKW_X1 = 0x1,
91 LNKW_X4 = 0x4,
92 LNKW_X8 = 0x8
93};
94
95static void check_error(void)
96{
97 u32 valPE0, valPE1, valPE2;
98
99 /* SDR0_PEGPLLLCT1 reset */
100 if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
101 printk(KERN_INFO "PCIE: SDR0_PEGPLLLCT1 reset error 0x%8x\n", valPE0);
102 }
103
104 valPE0 = SDR_READ(PESDR0_RCSSET);
105 valPE1 = SDR_READ(PESDR1_RCSSET);
106 valPE2 = SDR_READ(PESDR2_RCSSET);
107
108 /* SDR0_PExRCSSET rstgu */
109 if ( !(valPE0 & 0x01000000) ||
110 !(valPE1 & 0x01000000) ||
111 !(valPE2 & 0x01000000)) {
112 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
113 }
114
115 /* SDR0_PExRCSSET rstdl */
116 if ( !(valPE0 & 0x00010000) ||
117 !(valPE1 & 0x00010000) ||
118 !(valPE2 & 0x00010000)) {
119 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
120 }
121
122 /* SDR0_PExRCSSET rstpyn */
123 if ( (valPE0 & 0x00001000) ||
124 (valPE1 & 0x00001000) ||
125 (valPE2 & 0x00001000)) {
126 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n");
127 }
128
129 /* SDR0_PExRCSSET hldplb */
130 if ( (valPE0 & 0x10000000) ||
131 (valPE1 & 0x10000000) ||
132 (valPE2 & 0x10000000)) {
133 printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
134 }
135
136 /* SDR0_PExRCSSET rdy */
137 if ( (valPE0 & 0x00100000) ||
138 (valPE1 & 0x00100000) ||
139 (valPE2 & 0x00100000)) {
140 printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
141 }
142
143 /* SDR0_PExRCSSET shutdown */
144 if ( (valPE0 & 0x00000100) ||
145 (valPE1 & 0x00000100) ||
146 (valPE2 & 0x00000100)) {
147 printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
148 }
149}
150
151/*
152 * Initialize PCI Express core as described in User Manual section 27.12.1
153 */
154int ppc440spe_init_pcie(void)
155{
156 /* Set PLL clock receiver to LVPECL */
157 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
158
159 check_error();
160
161 printk(KERN_INFO "PCIE initialization OK\n");
162
163 if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
164 printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
165 SDR_READ(PESDR0_PLLLCT2));
166
167 /* De-assert reset of PCIe PLL, wait for lock */
168 SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
169 udelay(3);
170
171 return 0;
172}
173
174int ppc440spe_init_pcie_rootport(int port)
175{
176 static int core_init;
177 void __iomem *utl_base;
178 u32 val = 0;
179 int i;
180
181 if (!core_init) {
182 ++core_init;
183 i = ppc440spe_init_pcie();
184 if (i)
185 return i;
186 }
187
188 /*
189 * Initialize various parts of the PCI Express core for our port:
190 *
191 * - Set as a root port and enable max width
192 * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
193 * - Set up UTL configuration.
194 * - Increase SERDES drive strength to levels suggested by AMCC.
195 * - De-assert RSTPYN, RSTDL and RSTGU.
196 */
197 switch (port) {
198 case 0:
199 SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
200
201 SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
202 SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
203
204 SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
205 SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
206 SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
207 SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
208 SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
209 SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
210 SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
211 SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
212
213 SDR_WRITE(PESDR0_RCSSET,
214 (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
215 break;
216
217 case 1:
218 SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
219
220 SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
221 SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
222
223 SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
224 SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
225 SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
226 SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
227
228 SDR_WRITE(PESDR1_RCSSET,
229 (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
230 break;
231
232 case 2:
233 SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
234
235 SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
236 SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
237
238 SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
239 SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
240 SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
241 SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
242
243 SDR_WRITE(PESDR2_RCSSET,
244 (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
245 break;
246 }
247
248 mdelay(1000);
249
250 switch (port) {
251 case 0: val = SDR_READ(PESDR0_RCSSTS); break;
252 case 1: val = SDR_READ(PESDR1_RCSSTS); break;
253 case 2: val = SDR_READ(PESDR2_RCSSTS); break;
254 }
255
256 if (!(val & (1 << 20)))
257 printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
258 else
259 printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
260
261 switch (port) {
262 case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
263 case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
264 case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
265 }
266
267 /*
268 * Map UTL registers at 0xc_1000_0n00
269 */
270 switch (port) {
271 case 0:
272 mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
273 mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000);
274 mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
275 mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
276 break;
277
278 case 1:
279 mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
280 mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000);
281 mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
282 mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
283 break;
284
285 case 2:
286 mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
287 mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000);
288 mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
289 mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
290 }
291
292 utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100);
293
294 /*
295 * Set buffer allocations and then assert VRB and TXE.
296 */
297 out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
298 out_be32(utl_base + PEUTL_INTR, 0x02000000);
299 out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
300 out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
301 out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
302 out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
303 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
304 out_be32(utl_base + PEUTL_PCTL, 0x80800066);
305
306 iounmap(utl_base);
307
308 /*
309 * We map PCI Express configuration access into the 512MB regions
310 * PCIE0: 0xc_4000_0000
311 * PCIE1: 0xc_8000_0000
312 * PCIE2: 0xc_c000_0000
313 */
314 switch (port) {
315 case 0:
316 mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
317 mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
318 mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
319 break;
320
321 case 1:
322 mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
323 mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
324 mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
325 break;
326
327 case 2:
328 mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
329 mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
330 mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
331 break;
332 }
333
334 /*
335 * Check for VC0 active and assert RDY.
336 */
337 switch (port) {
338 case 0:
339 if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
340 printk(KERN_WARNING "PCIE0: VC0 not active\n");
341 SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
342 break;
343 case 1:
344 if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
345 printk(KERN_WARNING "PCIE0: VC0 not active\n");
346 SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
347 break;
348 case 2:
349 if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
350 printk(KERN_WARNING "PCIE0: VC0 not active\n");
351 SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
352 break;
353 }
354
355#if 0
356 /* Dump all config regs */
357 for (i = 0x300; i <= 0x320; ++i)
358 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
359 for (i = 0x340; i <= 0x353; ++i)
360 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
361 for (i = 0x370; i <= 0x383; ++i)
362 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
363 for (i = 0x3a0; i <= 0x3a2; ++i)
364 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
365 for (i = 0x3c0; i <= 0x3c3; ++i)
366 printk("[%04x] 0x%08x\n", i, SDR_READ(i));
367#endif
368
369 mdelay(100);
370
371 return 0;
372}
373
374void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
375{
376 void __iomem *mbase;
377
378 /*
379 * Map 16MB, which is enough for 4 bits of bus #
380 */
381 hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000,
382 1 << 24);
383 hose->ops = &pcie_pci_ops;
384
385 /*
386 * Set bus numbers on our root port
387 */
388 mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096);
389 out_8(mbase + PCI_PRIMARY_BUS, 0);
390 out_8(mbase + PCI_SECONDARY_BUS, 0);
391
392 /*
393 * Set up outbound translation to hose->mem_space from PLB
394 * addresses at an offset of 0xd_0000_0000. We set the low
395 * bits of the mask to 11 to turn off splitting into 8
396 * subregions and to enable the outbound translation.
397 */
398 out_le32(mbase + PECFG_POM0LAH, 0);
399 out_le32(mbase + PECFG_POM0LAL, hose->mem_space.start);
400
401 switch (port) {
402 case 0:
403 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
404 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), hose->mem_space.start);
405 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
406 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
407 ~(hose->mem_space.end - hose->mem_space.start) | 3);
408 break;
409 case 1:
410 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
411 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), hose->mem_space.start);
412 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
413 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
414 ~(hose->mem_space.end - hose->mem_space.start) | 3);
415
416 break;
417 case 2:
418 mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
419 mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), hose->mem_space.start);
420 mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
421 mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
422 ~(hose->mem_space.end - hose->mem_space.start) | 3);
423 break;
424 }
425
426 /* Set up 16GB inbound memory window at 0 */
427 out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
428 out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
429 out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
430 out_le32(mbase + PECFG_BAR0LMPA, 0);
431 out_le32(mbase + PECFG_PIM0LAL, 0);
432 out_le32(mbase + PECFG_PIM0LAH, 0);
433 out_le32(mbase + PECFG_PIMEN, 0x1);
434
435 /* Enable I/O, Mem, and Busmaster cycles */
436 out_le16(mbase + PCI_COMMAND,
437 in_le16(mbase + PCI_COMMAND) |
438 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
439
440 iounmap(mbase);
441}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
deleted file mode 100644
index 55b765ad3272..000000000000
--- a/arch/ppc/syslib/ppc440spe_pcie.h
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * Roland Dreier <rolandd@cisco.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __PPC_SYSLIB_PPC440SPE_PCIE_H
12#define __PPC_SYSLIB_PPC440SPE_PCIE_H
13
14#define DCRN_SDR0_CFGADDR 0x00e
15#define DCRN_SDR0_CFGDATA 0x00f
16
17#define DCRN_PCIE0_BASE 0x100
18#define DCRN_PCIE1_BASE 0x120
19#define DCRN_PCIE2_BASE 0x140
20#define PCIE0 DCRN_PCIE0_BASE
21#define PCIE1 DCRN_PCIE1_BASE
22#define PCIE2 DCRN_PCIE2_BASE
23
24#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
25#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
26#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
27#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
28#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
29#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
30#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
31#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
32#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
33#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
34#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
35#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
36#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
37#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
38
39/*
40 * System DCRs (SDRs)
41 */
42#define PESDR0_PLLLCT1 0x03a0
43#define PESDR0_PLLLCT2 0x03a1
44#define PESDR0_PLLLCT3 0x03a2
45
46#define PESDR0_UTLSET1 0x0300
47#define PESDR0_UTLSET2 0x0301
48#define PESDR0_DLPSET 0x0302
49#define PESDR0_LOOP 0x0303
50#define PESDR0_RCSSET 0x0304
51#define PESDR0_RCSSTS 0x0305
52#define PESDR0_HSSL0SET1 0x0306
53#define PESDR0_HSSL0SET2 0x0307
54#define PESDR0_HSSL0STS 0x0308
55#define PESDR0_HSSL1SET1 0x0309
56#define PESDR0_HSSL1SET2 0x030a
57#define PESDR0_HSSL1STS 0x030b
58#define PESDR0_HSSL2SET1 0x030c
59#define PESDR0_HSSL2SET2 0x030d
60#define PESDR0_HSSL2STS 0x030e
61#define PESDR0_HSSL3SET1 0x030f
62#define PESDR0_HSSL3SET2 0x0310
63#define PESDR0_HSSL3STS 0x0311
64#define PESDR0_HSSL4SET1 0x0312
65#define PESDR0_HSSL4SET2 0x0313
66#define PESDR0_HSSL4STS 0x0314
67#define PESDR0_HSSL5SET1 0x0315
68#define PESDR0_HSSL5SET2 0x0316
69#define PESDR0_HSSL5STS 0x0317
70#define PESDR0_HSSL6SET1 0x0318
71#define PESDR0_HSSL6SET2 0x0319
72#define PESDR0_HSSL6STS 0x031a
73#define PESDR0_HSSL7SET1 0x031b
74#define PESDR0_HSSL7SET2 0x031c
75#define PESDR0_HSSL7STS 0x031d
76#define PESDR0_HSSCTLSET 0x031e
77#define PESDR0_LANE_ABCD 0x031f
78#define PESDR0_LANE_EFGH 0x0320
79
80#define PESDR1_UTLSET1 0x0340
81#define PESDR1_UTLSET2 0x0341
82#define PESDR1_DLPSET 0x0342
83#define PESDR1_LOOP 0x0343
84#define PESDR1_RCSSET 0x0344
85#define PESDR1_RCSSTS 0x0345
86#define PESDR1_HSSL0SET1 0x0346
87#define PESDR1_HSSL0SET2 0x0347
88#define PESDR1_HSSL0STS 0x0348
89#define PESDR1_HSSL1SET1 0x0349
90#define PESDR1_HSSL1SET2 0x034a
91#define PESDR1_HSSL1STS 0x034b
92#define PESDR1_HSSL2SET1 0x034c
93#define PESDR1_HSSL2SET2 0x034d
94#define PESDR1_HSSL2STS 0x034e
95#define PESDR1_HSSL3SET1 0x034f
96#define PESDR1_HSSL3SET2 0x0350
97#define PESDR1_HSSL3STS 0x0351
98#define PESDR1_HSSCTLSET 0x0352
99#define PESDR1_LANE_ABCD 0x0353
100
101#define PESDR2_UTLSET1 0x0370
102#define PESDR2_UTLSET2 0x0371
103#define PESDR2_DLPSET 0x0372
104#define PESDR2_LOOP 0x0373
105#define PESDR2_RCSSET 0x0374
106#define PESDR2_RCSSTS 0x0375
107#define PESDR2_HSSL0SET1 0x0376
108#define PESDR2_HSSL0SET2 0x0377
109#define PESDR2_HSSL0STS 0x0378
110#define PESDR2_HSSL1SET1 0x0379
111#define PESDR2_HSSL1SET2 0x037a
112#define PESDR2_HSSL1STS 0x037b
113#define PESDR2_HSSL2SET1 0x037c
114#define PESDR2_HSSL2SET2 0x037d
115#define PESDR2_HSSL2STS 0x037e
116#define PESDR2_HSSL3SET1 0x037f
117#define PESDR2_HSSL3SET2 0x0380
118#define PESDR2_HSSL3STS 0x0381
119#define PESDR2_HSSCTLSET 0x0382
120#define PESDR2_LANE_ABCD 0x0383
121
122/*
123 * UTL register offsets
124 */
125#define PEUTL_PBBSZ 0x20
126#define PEUTL_OPDBSZ 0x68
127#define PEUTL_IPHBSZ 0x70
128#define PEUTL_IPDBSZ 0x78
129#define PEUTL_OUTTR 0x90
130#define PEUTL_INTR 0x98
131#define PEUTL_PCTL 0xa0
132#define PEUTL_RCIRQEN 0xb8
133
134/*
135 * Config space register offsets
136 */
137#define PECFG_BAR0LMPA 0x210
138#define PECFG_BAR0HMPA 0x214
139#define PECFG_PIMEN 0x33c
140#define PECFG_PIM0LAL 0x340
141#define PECFG_PIM0LAH 0x344
142#define PECFG_POM0LAL 0x380
143#define PECFG_POM0LAH 0x384
144
145int ppc440spe_init_pcie(void);
146int ppc440spe_init_pcie_rootport(int port);
147void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
148
149#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
deleted file mode 100644
index bd301868996b..000000000000
--- a/arch/ppc/syslib/ppc4xx_dma.c
+++ /dev/null
@@ -1,710 +0,0 @@
1/*
2 * IBM PPC4xx DMA engine core library
3 *
4 * Copyright 2000-2004 MontaVista Software Inc.
5 *
6 * Cleaned up and converted to new DCR access
7 * Matt Porter <mporter@kernel.crashing.org>
8 *
9 * Original code by Armin Kuster <akuster@mvista.com>
10 * and Pete Popov <ppopov@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 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/miscdevice.h>
25#include <linux/init.h>
26#include <linux/module.h>
27
28#include <asm/system.h>
29#include <asm/io.h>
30#include <asm/dma.h>
31#include <asm/ppc4xx_dma.h>
32
33ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS];
34
35int
36ppc4xx_get_dma_status(void)
37{
38 return (mfdcr(DCRN_DMASR));
39}
40
41void
42ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr)
43{
44 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
45 printk("set_src_addr: bad channel: %d\n", dmanr);
46 return;
47 }
48
49#ifdef PPC4xx_DMA_64BIT
50 mtdcr(DCRN_DMASAH0 + dmanr*2, (u32)(src_addr >> 32));
51#else
52 mtdcr(DCRN_DMASA0 + dmanr*2, (u32)src_addr);
53#endif
54}
55
56void
57ppc4xx_set_dst_addr(int dmanr, phys_addr_t dst_addr)
58{
59 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
60 printk("set_dst_addr: bad channel: %d\n", dmanr);
61 return;
62 }
63
64#ifdef PPC4xx_DMA_64BIT
65 mtdcr(DCRN_DMADAH0 + dmanr*2, (u32)(dst_addr >> 32));
66#else
67 mtdcr(DCRN_DMADA0 + dmanr*2, (u32)dst_addr);
68#endif
69}
70
71void
72ppc4xx_enable_dma(unsigned int dmanr)
73{
74 unsigned int control;
75 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
76 unsigned int status_bits[] = { DMA_CS0 | DMA_TS0 | DMA_CH0_ERR,
77 DMA_CS1 | DMA_TS1 | DMA_CH1_ERR,
78 DMA_CS2 | DMA_TS2 | DMA_CH2_ERR,
79 DMA_CS3 | DMA_TS3 | DMA_CH3_ERR};
80
81 if (p_dma_ch->in_use) {
82 printk("enable_dma: channel %d in use\n", dmanr);
83 return;
84 }
85
86 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
87 printk("enable_dma: bad channel: %d\n", dmanr);
88 return;
89 }
90
91 if (p_dma_ch->mode == DMA_MODE_READ) {
92 /* peripheral to memory */
93 ppc4xx_set_src_addr(dmanr, 0);
94 ppc4xx_set_dst_addr(dmanr, p_dma_ch->addr);
95 } else if (p_dma_ch->mode == DMA_MODE_WRITE) {
96 /* memory to peripheral */
97 ppc4xx_set_src_addr(dmanr, p_dma_ch->addr);
98 ppc4xx_set_dst_addr(dmanr, 0);
99 }
100
101 /* for other xfer modes, the addresses are already set */
102 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
103
104 control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */
105 if (p_dma_ch->mode == DMA_MODE_MM) {
106 /* software initiated memory to memory */
107 control |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
108 }
109
110 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
111
112 /*
113 * Clear the CS, TS, RI bits for the channel from DMASR. This
114 * has been observed to happen correctly only after the mode and
115 * ETD/DCE bits in DMACRx are set above. Must do this before
116 * enabling the channel.
117 */
118
119 mtdcr(DCRN_DMASR, status_bits[dmanr]);
120
121 /*
122 * For device-paced transfers, Terminal Count Enable apparently
123 * must be on, and this must be turned on after the mode, etc.
124 * bits are cleared above (at least on Redwood-6).
125 */
126
127 if ((p_dma_ch->mode == DMA_MODE_MM_DEVATDST) ||
128 (p_dma_ch->mode == DMA_MODE_MM_DEVATSRC))
129 control |= DMA_TCE_ENABLE;
130
131 /*
132 * Now enable the channel.
133 */
134
135 control |= (p_dma_ch->mode | DMA_CE_ENABLE);
136
137 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
138
139 p_dma_ch->in_use = 1;
140}
141
142void
143ppc4xx_disable_dma(unsigned int dmanr)
144{
145 unsigned int control;
146 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
147
148 if (!p_dma_ch->in_use) {
149 printk("disable_dma: channel %d not in use\n", dmanr);
150 return;
151 }
152
153 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
154 printk("disable_dma: bad channel: %d\n", dmanr);
155 return;
156 }
157
158 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
159 control &= ~DMA_CE_ENABLE;
160 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
161
162 p_dma_ch->in_use = 0;
163}
164
165/*
166 * Sets the dma mode for single DMA transfers only.
167 * For scatter/gather transfers, the mode is passed to the
168 * alloc_dma_handle() function as one of the parameters.
169 *
170 * The mode is simply saved and used later. This allows
171 * the driver to call set_dma_mode() and set_dma_addr() in
172 * any order.
173 *
174 * Valid mode values are:
175 *
176 * DMA_MODE_READ peripheral to memory
177 * DMA_MODE_WRITE memory to peripheral
178 * DMA_MODE_MM memory to memory
179 * DMA_MODE_MM_DEVATSRC device-paced memory to memory, device at src
180 * DMA_MODE_MM_DEVATDST device-paced memory to memory, device at dst
181 */
182int
183ppc4xx_set_dma_mode(unsigned int dmanr, unsigned int mode)
184{
185 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
186
187 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
188 printk("set_dma_mode: bad channel 0x%x\n", dmanr);
189 return DMA_STATUS_BAD_CHANNEL;
190 }
191
192 p_dma_ch->mode = mode;
193
194 return DMA_STATUS_GOOD;
195}
196
197/*
198 * Sets the DMA Count register. Note that 'count' is in bytes.
199 * However, the DMA Count register counts the number of "transfers",
200 * where each transfer is equal to the bus width. Thus, count
201 * MUST be a multiple of the bus width.
202 */
203void
204ppc4xx_set_dma_count(unsigned int dmanr, unsigned int count)
205{
206 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
207
208#ifdef DEBUG_4xxDMA
209 {
210 int error = 0;
211 switch (p_dma_ch->pwidth) {
212 case PW_8:
213 break;
214 case PW_16:
215 if (count & 0x1)
216 error = 1;
217 break;
218 case PW_32:
219 if (count & 0x3)
220 error = 1;
221 break;
222 case PW_64:
223 if (count & 0x7)
224 error = 1;
225 break;
226 default:
227 printk("set_dma_count: invalid bus width: 0x%x\n",
228 p_dma_ch->pwidth);
229 return;
230 }
231 if (error)
232 printk
233 ("Warning: set_dma_count count 0x%x bus width %d\n",
234 count, p_dma_ch->pwidth);
235 }
236#endif
237
238 count = count >> p_dma_ch->shift;
239
240 mtdcr(DCRN_DMACT0 + (dmanr * 0x8), count);
241}
242
243/*
244 * Returns the number of bytes left to be transferred.
245 * After a DMA transfer, this should return zero.
246 * Reading this while a DMA transfer is still in progress will return
247 * unpredictable results.
248 */
249int
250ppc4xx_get_dma_residue(unsigned int dmanr)
251{
252 unsigned int count;
253 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
254
255 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
256 printk("ppc4xx_get_dma_residue: bad channel 0x%x\n", dmanr);
257 return DMA_STATUS_BAD_CHANNEL;
258 }
259
260 count = mfdcr(DCRN_DMACT0 + (dmanr * 0x8));
261
262 return (count << p_dma_ch->shift);
263}
264
265/*
266 * Sets the DMA address for a memory to peripheral or peripheral
267 * to memory transfer. The address is just saved in the channel
268 * structure for now and used later in enable_dma().
269 */
270void
271ppc4xx_set_dma_addr(unsigned int dmanr, phys_addr_t addr)
272{
273 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
274
275 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
276 printk("ppc4xx_set_dma_addr: bad channel: %d\n", dmanr);
277 return;
278 }
279
280#ifdef DEBUG_4xxDMA
281 {
282 int error = 0;
283 switch (p_dma_ch->pwidth) {
284 case PW_8:
285 break;
286 case PW_16:
287 if ((unsigned) addr & 0x1)
288 error = 1;
289 break;
290 case PW_32:
291 if ((unsigned) addr & 0x3)
292 error = 1;
293 break;
294 case PW_64:
295 if ((unsigned) addr & 0x7)
296 error = 1;
297 break;
298 default:
299 printk("ppc4xx_set_dma_addr: invalid bus width: 0x%x\n",
300 p_dma_ch->pwidth);
301 return;
302 }
303 if (error)
304 printk("Warning: ppc4xx_set_dma_addr addr 0x%x bus width %d\n",
305 addr, p_dma_ch->pwidth);
306 }
307#endif
308
309 /* save dma address and program it later after we know the xfer mode */
310 p_dma_ch->addr = addr;
311}
312
313/*
314 * Sets both DMA addresses for a memory to memory transfer.
315 * For memory to peripheral or peripheral to memory transfers
316 * the function set_dma_addr() should be used instead.
317 */
318void
319ppc4xx_set_dma_addr2(unsigned int dmanr, phys_addr_t src_dma_addr,
320 phys_addr_t dst_dma_addr)
321{
322 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
323 printk("ppc4xx_set_dma_addr2: bad channel: %d\n", dmanr);
324 return;
325 }
326
327#ifdef DEBUG_4xxDMA
328 {
329 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
330 int error = 0;
331 switch (p_dma_ch->pwidth) {
332 case PW_8:
333 break;
334 case PW_16:
335 if (((unsigned) src_dma_addr & 0x1) ||
336 ((unsigned) dst_dma_addr & 0x1)
337 )
338 error = 1;
339 break;
340 case PW_32:
341 if (((unsigned) src_dma_addr & 0x3) ||
342 ((unsigned) dst_dma_addr & 0x3)
343 )
344 error = 1;
345 break;
346 case PW_64:
347 if (((unsigned) src_dma_addr & 0x7) ||
348 ((unsigned) dst_dma_addr & 0x7)
349 )
350 error = 1;
351 break;
352 default:
353 printk("ppc4xx_set_dma_addr2: invalid bus width: 0x%x\n",
354 p_dma_ch->pwidth);
355 return;
356 }
357 if (error)
358 printk
359 ("Warning: ppc4xx_set_dma_addr2 src 0x%x dst 0x%x bus width %d\n",
360 src_dma_addr, dst_dma_addr, p_dma_ch->pwidth);
361 }
362#endif
363
364 ppc4xx_set_src_addr(dmanr, src_dma_addr);
365 ppc4xx_set_dst_addr(dmanr, dst_dma_addr);
366}
367
368/*
369 * Enables the channel interrupt.
370 *
371 * If performing a scatter/gatter transfer, this function
372 * MUST be called before calling alloc_dma_handle() and building
373 * the sgl list. Otherwise, interrupts will not be enabled, if
374 * they were previously disabled.
375 */
376int
377ppc4xx_enable_dma_interrupt(unsigned int dmanr)
378{
379 unsigned int control;
380 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
381
382 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
383 printk("ppc4xx_enable_dma_interrupt: bad channel: %d\n", dmanr);
384 return DMA_STATUS_BAD_CHANNEL;
385 }
386
387 p_dma_ch->int_enable = 1;
388
389 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
390 control |= DMA_CIE_ENABLE; /* Channel Interrupt Enable */
391 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
392
393 return DMA_STATUS_GOOD;
394}
395
396/*
397 * Disables the channel interrupt.
398 *
399 * If performing a scatter/gatter transfer, this function
400 * MUST be called before calling alloc_dma_handle() and building
401 * the sgl list. Otherwise, interrupts will not be disabled, if
402 * they were previously enabled.
403 */
404int
405ppc4xx_disable_dma_interrupt(unsigned int dmanr)
406{
407 unsigned int control;
408 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
409
410 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
411 printk("ppc4xx_disable_dma_interrupt: bad channel: %d\n", dmanr);
412 return DMA_STATUS_BAD_CHANNEL;
413 }
414
415 p_dma_ch->int_enable = 0;
416
417 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
418 control &= ~DMA_CIE_ENABLE; /* Channel Interrupt Enable */
419 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
420
421 return DMA_STATUS_GOOD;
422}
423
424/*
425 * Configures a DMA channel, including the peripheral bus width, if a
426 * peripheral is attached to the channel, the polarity of the DMAReq and
427 * DMAAck signals, etc. This information should really be setup by the boot
428 * code, since most likely the configuration won't change dynamically.
429 * If the kernel has to call this function, it's recommended that it's
430 * called from platform specific init code. The driver should not need to
431 * call this function.
432 */
433int
434ppc4xx_init_dma_channel(unsigned int dmanr, ppc_dma_ch_t * p_init)
435{
436 unsigned int polarity;
437 uint32_t control = 0;
438 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
439
440 DMA_MODE_READ = (unsigned long) DMA_TD; /* Peripheral to Memory */
441 DMA_MODE_WRITE = 0; /* Memory to Peripheral */
442
443 if (!p_init) {
444 printk("ppc4xx_init_dma_channel: NULL p_init\n");
445 return DMA_STATUS_NULL_POINTER;
446 }
447
448 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
449 printk("ppc4xx_init_dma_channel: bad channel %d\n", dmanr);
450 return DMA_STATUS_BAD_CHANNEL;
451 }
452
453#if DCRN_POL > 0
454 polarity = mfdcr(DCRN_POL);
455#else
456 polarity = 0;
457#endif
458
459 /* Setup the control register based on the values passed to
460 * us in p_init. Then, over-write the control register with this
461 * new value.
462 */
463 control |= SET_DMA_CONTROL;
464
465 /* clear all polarity signals and then "or" in new signal levels */
466 polarity &= ~GET_DMA_POLARITY(dmanr);
467 polarity |= p_init->polarity;
468#if DCRN_POL > 0
469 mtdcr(DCRN_POL, polarity);
470#endif
471 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
472
473 /* save these values in our dma channel structure */
474 memcpy(p_dma_ch, p_init, sizeof (ppc_dma_ch_t));
475
476 /*
477 * The peripheral width values written in the control register are:
478 * PW_8 0
479 * PW_16 1
480 * PW_32 2
481 * PW_64 3
482 *
483 * Since the DMA count register takes the number of "transfers",
484 * we need to divide the count sent to us in certain
485 * functions by the appropriate number. It so happens that our
486 * right shift value is equal to the peripheral width value.
487 */
488 p_dma_ch->shift = p_init->pwidth;
489
490 /*
491 * Save the control word for easy access.
492 */
493 p_dma_ch->control = control;
494
495 mtdcr(DCRN_DMASR, 0xffffffff); /* clear status register */
496 return DMA_STATUS_GOOD;
497}
498
499/*
500 * This function returns the channel configuration.
501 */
502int
503ppc4xx_get_channel_config(unsigned int dmanr, ppc_dma_ch_t * p_dma_ch)
504{
505 unsigned int polarity;
506 unsigned int control;
507
508 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
509 printk("ppc4xx_get_channel_config: bad channel %d\n", dmanr);
510 return DMA_STATUS_BAD_CHANNEL;
511 }
512
513 memcpy(p_dma_ch, &dma_channels[dmanr], sizeof (ppc_dma_ch_t));
514
515#if DCRN_POL > 0
516 polarity = mfdcr(DCRN_POL);
517#else
518 polarity = 0;
519#endif
520
521 p_dma_ch->polarity = polarity & GET_DMA_POLARITY(dmanr);
522 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
523
524 p_dma_ch->cp = GET_DMA_PRIORITY(control);
525 p_dma_ch->pwidth = GET_DMA_PW(control);
526 p_dma_ch->psc = GET_DMA_PSC(control);
527 p_dma_ch->pwc = GET_DMA_PWC(control);
528 p_dma_ch->phc = GET_DMA_PHC(control);
529 p_dma_ch->ce = GET_DMA_CE_ENABLE(control);
530 p_dma_ch->int_enable = GET_DMA_CIE_ENABLE(control);
531 p_dma_ch->shift = GET_DMA_PW(control);
532
533#ifdef CONFIG_PPC4xx_EDMA
534 p_dma_ch->pf = GET_DMA_PREFETCH(control);
535#else
536 p_dma_ch->ch_enable = GET_DMA_CH(control);
537 p_dma_ch->ece_enable = GET_DMA_ECE(control);
538 p_dma_ch->tcd_disable = GET_DMA_TCD(control);
539#endif
540 return DMA_STATUS_GOOD;
541}
542
543/*
544 * Sets the priority for the DMA channel dmanr.
545 * Since this is setup by the hardware init function, this function
546 * can be used to dynamically change the priority of a channel.
547 *
548 * Acceptable priorities:
549 *
550 * PRIORITY_LOW
551 * PRIORITY_MID_LOW
552 * PRIORITY_MID_HIGH
553 * PRIORITY_HIGH
554 *
555 */
556int
557ppc4xx_set_channel_priority(unsigned int dmanr, unsigned int priority)
558{
559 unsigned int control;
560
561 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
562 printk("ppc4xx_set_channel_priority: bad channel %d\n", dmanr);
563 return DMA_STATUS_BAD_CHANNEL;
564 }
565
566 if ((priority != PRIORITY_LOW) &&
567 (priority != PRIORITY_MID_LOW) &&
568 (priority != PRIORITY_MID_HIGH) && (priority != PRIORITY_HIGH)) {
569 printk("ppc4xx_set_channel_priority: bad priority: 0x%x\n", priority);
570 }
571
572 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
573 control |= SET_DMA_PRIORITY(priority);
574 mtdcr(DCRN_DMACR0 + (dmanr * 0x8), control);
575
576 return DMA_STATUS_GOOD;
577}
578
579/*
580 * Returns the width of the peripheral attached to this channel. This assumes
581 * that someone who knows the hardware configuration, boot code or some other
582 * init code, already set the width.
583 *
584 * The return value is one of:
585 * PW_8
586 * PW_16
587 * PW_32
588 * PW_64
589 *
590 * The function returns 0 on error.
591 */
592unsigned int
593ppc4xx_get_peripheral_width(unsigned int dmanr)
594{
595 unsigned int control;
596
597 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
598 printk("ppc4xx_get_peripheral_width: bad channel %d\n", dmanr);
599 return DMA_STATUS_BAD_CHANNEL;
600 }
601
602 control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8));
603
604 return (GET_DMA_PW(control));
605}
606
607/*
608 * Clears the channel status bits
609 */
610int
611ppc4xx_clr_dma_status(unsigned int dmanr)
612{
613 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
614 printk(KERN_ERR "ppc4xx_clr_dma_status: bad channel: %d\n", dmanr);
615 return DMA_STATUS_BAD_CHANNEL;
616 }
617 mtdcr(DCRN_DMASR, ((u32)DMA_CH0_ERR | (u32)DMA_CS0 | (u32)DMA_TS0) >> dmanr);
618 return DMA_STATUS_GOOD;
619}
620
621#ifdef CONFIG_PPC4xx_EDMA
622/*
623 * Enables the burst on the channel (BTEN bit in the control/count register)
624 * Note:
625 * For scatter/gather dma, this function MUST be called before the
626 * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
627 * sgl list and used as each sgl element is added.
628 */
629int
630ppc4xx_enable_burst(unsigned int dmanr)
631{
632 unsigned int ctc;
633 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
634 printk(KERN_ERR "ppc4xx_enable_burst: bad channel: %d\n", dmanr);
635 return DMA_STATUS_BAD_CHANNEL;
636 }
637 ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) | DMA_CTC_BTEN;
638 mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
639 return DMA_STATUS_GOOD;
640}
641/*
642 * Disables the burst on the channel (BTEN bit in the control/count register)
643 * Note:
644 * For scatter/gather dma, this function MUST be called before the
645 * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
646 * sgl list and used as each sgl element is added.
647 */
648int
649ppc4xx_disable_burst(unsigned int dmanr)
650{
651 unsigned int ctc;
652 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
653 printk(KERN_ERR "ppc4xx_disable_burst: bad channel: %d\n", dmanr);
654 return DMA_STATUS_BAD_CHANNEL;
655 }
656 ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BTEN;
657 mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
658 return DMA_STATUS_GOOD;
659}
660/*
661 * Sets the burst size (number of peripheral widths) for the channel
662 * (BSIZ bits in the control/count register))
663 * must be one of:
664 * DMA_CTC_BSIZ_2
665 * DMA_CTC_BSIZ_4
666 * DMA_CTC_BSIZ_8
667 * DMA_CTC_BSIZ_16
668 * Note:
669 * For scatter/gather dma, this function MUST be called before the
670 * ppc4xx_alloc_dma_handle() func as the chan count register is copied into the
671 * sgl list and used as each sgl element is added.
672 */
673int
674ppc4xx_set_burst_size(unsigned int dmanr, unsigned int bsize)
675{
676 unsigned int ctc;
677 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
678 printk(KERN_ERR "ppc4xx_set_burst_size: bad channel: %d\n", dmanr);
679 return DMA_STATUS_BAD_CHANNEL;
680 }
681 ctc = mfdcr(DCRN_DMACT0 + (dmanr * 0x8)) &~ DMA_CTC_BSIZ_MSK;
682 ctc |= (bsize & DMA_CTC_BSIZ_MSK);
683 mtdcr(DCRN_DMACT0 + (dmanr * 0x8), ctc);
684 return DMA_STATUS_GOOD;
685}
686
687EXPORT_SYMBOL(ppc4xx_enable_burst);
688EXPORT_SYMBOL(ppc4xx_disable_burst);
689EXPORT_SYMBOL(ppc4xx_set_burst_size);
690#endif /* CONFIG_PPC4xx_EDMA */
691
692EXPORT_SYMBOL(ppc4xx_init_dma_channel);
693EXPORT_SYMBOL(ppc4xx_get_channel_config);
694EXPORT_SYMBOL(ppc4xx_set_channel_priority);
695EXPORT_SYMBOL(ppc4xx_get_peripheral_width);
696EXPORT_SYMBOL(dma_channels);
697EXPORT_SYMBOL(ppc4xx_set_src_addr);
698EXPORT_SYMBOL(ppc4xx_set_dst_addr);
699EXPORT_SYMBOL(ppc4xx_set_dma_addr);
700EXPORT_SYMBOL(ppc4xx_set_dma_addr2);
701EXPORT_SYMBOL(ppc4xx_enable_dma);
702EXPORT_SYMBOL(ppc4xx_disable_dma);
703EXPORT_SYMBOL(ppc4xx_set_dma_mode);
704EXPORT_SYMBOL(ppc4xx_set_dma_count);
705EXPORT_SYMBOL(ppc4xx_get_dma_residue);
706EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt);
707EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt);
708EXPORT_SYMBOL(ppc4xx_get_dma_status);
709EXPORT_SYMBOL(ppc4xx_clr_dma_status);
710
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
deleted file mode 100644
index ee0da4b4b993..000000000000
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ /dev/null
@@ -1,284 +0,0 @@
1/*
2 * Interrupt controller driver for PowerPC 4xx-based processors.
3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2004, 2005 Zultys Technologies
6 *
7 * Based on original code by
8 * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
9 * Armin Custer <akuster@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#include <linux/init.h>
17#include <linux/sched.h>
18#include <linux/signal.h>
19#include <linux/stddef.h>
20
21#include <asm/processor.h>
22#include <asm/system.h>
23#include <asm/irq.h>
24#include <asm/ppc4xx_pic.h>
25#include <asm/machdep.h>
26
27/* See comment in include/arch-ppc/ppc4xx_pic.h
28 * for more info about these two variables
29 */
30extern struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[NR_UICS]
31 __attribute__ ((weak));
32extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));
33
34#define IRQ_MASK_UIC0(irq) (1 << (31 - (irq)))
35#define IRQ_MASK_UICx(irq) (1 << (31 - ((irq) & 0x1f)))
36#define IRQ_MASK_UIC1(irq) IRQ_MASK_UICx(irq)
37#define IRQ_MASK_UIC2(irq) IRQ_MASK_UICx(irq)
38#define IRQ_MASK_UIC3(irq) IRQ_MASK_UICx(irq)
39
40#define UIC_HANDLERS(n) \
41static void ppc4xx_uic##n##_enable(unsigned int irq) \
42{ \
43 u32 mask = IRQ_MASK_UIC##n(irq); \
44 if (irq_desc[irq].status & IRQ_LEVEL) \
45 mtdcr(DCRN_UIC_SR(UIC##n), mask); \
46 ppc_cached_irq_mask[n] |= mask; \
47 mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]); \
48} \
49 \
50static void ppc4xx_uic##n##_disable(unsigned int irq) \
51{ \
52 ppc_cached_irq_mask[n] &= ~IRQ_MASK_UIC##n(irq); \
53 mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]); \
54 ACK_UIC##n##_PARENT \
55} \
56 \
57static void ppc4xx_uic##n##_ack(unsigned int irq) \
58{ \
59 u32 mask = IRQ_MASK_UIC##n(irq); \
60 ppc_cached_irq_mask[n] &= ~mask; \
61 mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]); \
62 mtdcr(DCRN_UIC_SR(UIC##n), mask); \
63 ACK_UIC##n##_PARENT \
64} \
65 \
66static void ppc4xx_uic##n##_end(unsigned int irq) \
67{ \
68 unsigned int status = irq_desc[irq].status; \
69 u32 mask = IRQ_MASK_UIC##n(irq); \
70 if (status & IRQ_LEVEL) { \
71 mtdcr(DCRN_UIC_SR(UIC##n), mask); \
72 ACK_UIC##n##_PARENT \
73 } \
74 if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { \
75 ppc_cached_irq_mask[n] |= mask; \
76 mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]); \
77 } \
78}
79
80#define DECLARE_UIC(n) \
81{ \
82 .typename = "UIC"#n, \
83 .enable = ppc4xx_uic##n##_enable, \
84 .disable = ppc4xx_uic##n##_disable, \
85 .ack = ppc4xx_uic##n##_ack, \
86 .end = ppc4xx_uic##n##_end, \
87} \
88
89#if NR_UICS == 4
90#define ACK_UIC0_PARENT
91#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
92#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
93#define ACK_UIC3_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
94UIC_HANDLERS(0);
95UIC_HANDLERS(1);
96UIC_HANDLERS(2);
97UIC_HANDLERS(3);
98
99static int ppc4xx_pic_get_irq(void)
100{
101 u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
102 if (uic0 & UIC0_UIC1NC)
103 return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
104 else if (uic0 & UIC0_UIC2NC)
105 return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
106 else if (uic0 & UIC0_UIC3NC)
107 return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
108 else
109 return uic0 ? 32 - ffs(uic0) : -1;
110}
111
112static void __init ppc4xx_pic_impl_init(void)
113{
114 /* Enable cascade interrupts in UIC0 */
115 ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
116 mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
117 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
118}
119
120#elif NR_UICS == 3
121#define ACK_UIC0_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
122#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
123#define ACK_UIC2_PARENT mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
124UIC_HANDLERS(0);
125UIC_HANDLERS(1);
126UIC_HANDLERS(2);
127
128static int ppc4xx_pic_get_irq(void)
129{
130 u32 uicb = mfdcr(DCRN_UIC_MSR(UICB));
131 if (uicb & UICB_UIC0NC)
132 return 32 - ffs(mfdcr(DCRN_UIC_MSR(UIC0)));
133 else if (uicb & UICB_UIC1NC)
134 return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
135 else if (uicb & UICB_UIC2NC)
136 return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
137 else
138 return -1;
139}
140
141static void __init ppc4xx_pic_impl_init(void)
142{
143#if defined(CONFIG_440GX)
144 /* Disable 440GP compatibility mode if it was enabled in firmware */
145 SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM);
146#endif
147 /* Configure Base UIC */
148 mtdcr(DCRN_UIC_CR(UICB), 0);
149 mtdcr(DCRN_UIC_TR(UICB), 0);
150 mtdcr(DCRN_UIC_PR(UICB), 0xffffffff);
151 mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
152 mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
153}
154
155#elif NR_UICS == 2
156#define ACK_UIC0_PARENT
157#define ACK_UIC1_PARENT mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
158UIC_HANDLERS(0);
159UIC_HANDLERS(1);
160
161static int ppc4xx_pic_get_irq(void)
162{
163 u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
164 if (uic0 & UIC0_UIC1NC)
165 return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
166 else
167 return uic0 ? 32 - ffs(uic0) : -1;
168}
169
170static void __init ppc4xx_pic_impl_init(void)
171{
172 /* Enable cascade interrupt in UIC0 */
173 ppc_cached_irq_mask[0] |= UIC0_UIC1NC;
174 mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
175 mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
176}
177
178#elif NR_UICS == 1
179#define ACK_UIC0_PARENT
180UIC_HANDLERS(0);
181
182static int ppc4xx_pic_get_irq(void)
183{
184 u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
185 return uic0 ? 32 - ffs(uic0) : -1;
186}
187
188static inline void ppc4xx_pic_impl_init(void)
189{
190}
191#endif
192
193static struct ppc4xx_uic_impl {
194 struct hw_interrupt_type decl;
195 int base; /* Base DCR number */
196} __uic[] = {
197 { .decl = DECLARE_UIC(0), .base = UIC0 },
198#if NR_UICS > 1
199 { .decl = DECLARE_UIC(1), .base = UIC1 },
200#if NR_UICS > 2
201 { .decl = DECLARE_UIC(2), .base = UIC2 },
202#if NR_UICS > 3
203 { .decl = DECLARE_UIC(3), .base = UIC3 },
204#endif
205#endif
206#endif
207};
208
209static inline int is_level_sensitive(int irq)
210{
211 u32 tr = mfdcr(DCRN_UIC_TR(__uic[irq >> 5].base));
212 return (tr & IRQ_MASK_UICx(irq)) == 0;
213}
214
215void __init ppc4xx_pic_init(void)
216{
217 int i;
218 unsigned char *eirqs = ppc4xx_uic_ext_irq_cfg;
219
220 for (i = 0; i < NR_UICS; ++i) {
221 int base = __uic[i].base;
222
223 /* Disable everything by default */
224 ppc_cached_irq_mask[i] = 0;
225 mtdcr(DCRN_UIC_ER(base), 0);
226
227 /* We don't use critical interrupts */
228 mtdcr(DCRN_UIC_CR(base), 0);
229
230 /* Configure polarity and triggering */
231 if (ppc4xx_core_uic_cfg) {
232 struct ppc4xx_uic_settings *p = ppc4xx_core_uic_cfg + i;
233 u32 mask = p->ext_irq_mask;
234 u32 pr = mfdcr(DCRN_UIC_PR(base)) & mask;
235 u32 tr = mfdcr(DCRN_UIC_TR(base)) & mask;
236
237 /* "Fixed" interrupts (on-chip devices) */
238 pr |= p->polarity & ~mask;
239 tr |= p->triggering & ~mask;
240
241 /* Merge external IRQs settings if board port
242 * provided them
243 */
244 if (eirqs && mask) {
245 pr &= ~mask;
246 tr &= ~mask;
247 while (mask) {
248 /* Extract current external IRQ mask */
249 u32 eirq_mask = 1 << __ilog2(mask);
250
251 if (!(*eirqs & IRQ_SENSE_LEVEL))
252 tr |= eirq_mask;
253
254 if (*eirqs & IRQ_POLARITY_POSITIVE)
255 pr |= eirq_mask;
256
257 mask &= ~eirq_mask;
258 ++eirqs;
259 }
260 }
261 mtdcr(DCRN_UIC_PR(base), pr);
262 mtdcr(DCRN_UIC_TR(base), tr);
263 }
264
265 /* ACK any pending interrupts to prevent false
266 * triggering after first enable
267 */
268 mtdcr(DCRN_UIC_SR(base), 0xffffffff);
269 }
270
271 /* Perform optional implementation specific setup
272 * (e.g. enable cascade interrupts for multi-UIC configurations)
273 */
274 ppc4xx_pic_impl_init();
275
276 /* Attach low-level handlers */
277 for (i = 0; i < (NR_UICS << 5); ++i) {
278 irq_desc[i].chip = &__uic[i >> 5].decl;
279 if (is_level_sensitive(i))
280 irq_desc[i].status |= IRQ_LEVEL;
281 }
282
283 ppc_md.get_irq = ppc4xx_pic_get_irq;
284}
diff --git a/arch/ppc/syslib/ppc4xx_setup.c b/arch/ppc/syslib/ppc4xx_setup.c
deleted file mode 100644
index 353d746b47e1..000000000000
--- a/arch/ppc/syslib/ppc4xx_setup.c
+++ /dev/null
@@ -1,271 +0,0 @@
1/*
2 *
3 * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Copyright 2000-2001 MontaVista Software Inc.
6 * Completed implementation.
7 * Author: MontaVista Software, Inc. <source@mvista.com>
8 * Frank Rowand <frank_rowand@mvista.com>
9 * Debbie Chu <debbie_chu@mvista.com>
10 * Further modifications by Armin Kuster
11 *
12 * Module name: ppc4xx_setup.c
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/smp.h>
18#include <linux/threads.h>
19#include <linux/spinlock.h>
20#include <linux/reboot.h>
21#include <linux/param.h>
22#include <linux/string.h>
23#include <linux/initrd.h>
24#include <linux/pci.h>
25#include <linux/rtc.h>
26#include <linux/console.h>
27#include <linux/serial_reg.h>
28#include <linux/seq_file.h>
29
30#include <asm/system.h>
31#include <asm/processor.h>
32#include <asm/machdep.h>
33#include <asm/page.h>
34#include <asm/kgdb.h>
35#include <asm/ibm4xx.h>
36#include <asm/time.h>
37#include <asm/todc.h>
38#include <asm/ppc4xx_pic.h>
39#include <asm/pci-bridge.h>
40#include <asm/bootinfo.h>
41
42#include <syslib/gen550.h>
43
44/* Function Prototypes */
45extern void abort(void);
46extern void ppc4xx_find_bridges(void);
47
48/* Global Variables */
49bd_t __res;
50
51void __init
52ppc4xx_setup_arch(void)
53{
54#if !defined(CONFIG_BDI_SWITCH)
55 /*
56 * The Abatron BDI JTAG debugger does not tolerate others
57 * mucking with the debug registers.
58 */
59 mtspr(SPRN_DBCR0, (DBCR0_IDM));
60 mtspr(SPRN_DBSR, 0xffffffff);
61#endif
62
63 /* Setup PCI host bridges */
64#ifdef CONFIG_PCI
65 ppc4xx_find_bridges();
66#endif
67}
68
69/*
70 * This routine pretty-prints the platform's internal CPU clock
71 * frequencies into the buffer for usage in /proc/cpuinfo.
72 */
73
74static int
75ppc4xx_show_percpuinfo(struct seq_file *m, int i)
76{
77 seq_printf(m, "clock\t\t: %ldMHz\n", (long)__res.bi_intfreq / 1000000);
78
79 return 0;
80}
81
82/*
83 * This routine pretty-prints the platform's internal bus clock
84 * frequencies into the buffer for usage in /proc/cpuinfo.
85 */
86static int
87ppc4xx_show_cpuinfo(struct seq_file *m)
88{
89 bd_t *bip = &__res;
90
91 seq_printf(m, "machine\t\t: %s\n", PPC4xx_MACHINE_NAME);
92 seq_printf(m, "plb bus clock\t: %ldMHz\n",
93 (long) bip->bi_busfreq / 1000000);
94#ifdef CONFIG_PCI
95 seq_printf(m, "pci bus clock\t: %dMHz\n",
96 bip->bi_pci_busfreq / 1000000);
97#endif
98
99 return 0;
100}
101
102/*
103 * Return the virtual address representing the top of physical RAM.
104 */
105static unsigned long __init
106ppc4xx_find_end_of_memory(void)
107{
108 return ((unsigned long) __res.bi_memsize);
109}
110
111void __init
112ppc4xx_map_io(void)
113{
114 io_block_mapping(PPC4xx_ONB_IO_VADDR,
115 PPC4xx_ONB_IO_PADDR, PPC4xx_ONB_IO_SIZE, _PAGE_IO);
116#ifdef CONFIG_PCI
117 io_block_mapping(PPC4xx_PCI_IO_VADDR,
118 PPC4xx_PCI_IO_PADDR, PPC4xx_PCI_IO_SIZE, _PAGE_IO);
119 io_block_mapping(PPC4xx_PCI_CFG_VADDR,
120 PPC4xx_PCI_CFG_PADDR, PPC4xx_PCI_CFG_SIZE, _PAGE_IO);
121 io_block_mapping(PPC4xx_PCI_LCFG_VADDR,
122 PPC4xx_PCI_LCFG_PADDR, PPC4xx_PCI_LCFG_SIZE, _PAGE_IO);
123#endif
124}
125
126void __init
127ppc4xx_init_IRQ(void)
128{
129 ppc4xx_pic_init();
130}
131
132static void
133ppc4xx_restart(char *cmd)
134{
135 printk("%s\n", cmd);
136 abort();
137}
138
139static void
140ppc4xx_power_off(void)
141{
142 printk("System Halted\n");
143 local_irq_disable();
144 while (1) ;
145}
146
147static void
148ppc4xx_halt(void)
149{
150 printk("System Halted\n");
151 local_irq_disable();
152 while (1) ;
153}
154
155/*
156 * This routine retrieves the internal processor frequency from the board
157 * information structure, sets up the kernel timer decrementer based on
158 * that value, enables the 4xx programmable interval timer (PIT) and sets
159 * it up for auto-reload.
160 */
161static void __init
162ppc4xx_calibrate_decr(void)
163{
164 unsigned int freq;
165 bd_t *bip = &__res;
166
167#if defined(CONFIG_WALNUT) || defined(CONFIG_SYCAMORE)
168 /* Walnut boot rom sets DCR CHCR1 (aka CPC0_CR1) bit CETE to 1 */
169 mtdcr(DCRN_CHCR1, mfdcr(DCRN_CHCR1) & ~CHR1_CETE);
170#endif
171 freq = bip->bi_tbfreq;
172 tb_ticks_per_jiffy = freq / HZ;
173 tb_to_us = mulhwu_scale_factor(freq, 1000000);
174
175 /* Set the time base to zero.
176 ** At 200 Mhz, time base will rollover in ~2925 years.
177 */
178
179 mtspr(SPRN_TBWL, 0);
180 mtspr(SPRN_TBWU, 0);
181
182 /* Clear any pending timer interrupts */
183
184 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
185 mtspr(SPRN_TCR, TCR_PIE | TCR_ARE);
186
187 /* Set the PIT reload value and just let it run. */
188 mtspr(SPRN_PIT, tb_ticks_per_jiffy);
189}
190
191TODC_ALLOC();
192
193/*
194 * Input(s):
195 * r3 - Optional pointer to a board information structure.
196 * r4 - Optional pointer to the physical starting address of the init RAM
197 * disk.
198 * r5 - Optional pointer to the physical ending address of the init RAM
199 * disk.
200 * r6 - Optional pointer to the physical starting address of any kernel
201 * command-line parameters.
202 * r7 - Optional pointer to the physical ending address of any kernel
203 * command-line parameters.
204 */
205void __init
206ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
207 unsigned long r6, unsigned long r7)
208{
209 parse_bootinfo(find_bootinfo());
210
211 /*
212 * If we were passed in a board information, copy it into the
213 * residual data area.
214 */
215 if (r3)
216 __res = *(bd_t *)(r3 + KERNELBASE);
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
231 if (r6) {
232 *(char *) (r7 + KERNELBASE) = 0;
233 strcpy(cmd_line, (char *) (r6 + KERNELBASE));
234 }
235
236 /* Initialize machine-dependent vectors */
237
238 ppc_md.setup_arch = ppc4xx_setup_arch;
239 ppc_md.show_percpuinfo = ppc4xx_show_percpuinfo;
240 ppc_md.show_cpuinfo = ppc4xx_show_cpuinfo;
241 ppc_md.init_IRQ = ppc4xx_init_IRQ;
242
243 ppc_md.restart = ppc4xx_restart;
244 ppc_md.power_off = ppc4xx_power_off;
245 ppc_md.halt = ppc4xx_halt;
246
247 ppc_md.calibrate_decr = ppc4xx_calibrate_decr;
248
249 ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory;
250 ppc_md.setup_io_mappings = ppc4xx_map_io;
251
252#ifdef CONFIG_SERIAL_TEXT_DEBUG
253 ppc_md.progress = gen550_progress;
254#endif
255}
256
257/* Called from machine_check_exception */
258void platform_machine_check(struct pt_regs *regs)
259{
260#if defined(DCRN_PLB0_BEAR)
261 printk("PLB0: BEAR= 0x%08x ACR= 0x%08x BESR= 0x%08x\n",
262 mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR),
263 mfdcr(DCRN_PLB0_BESR));
264#endif
265#if defined(DCRN_POB0_BEAR)
266 printk("PLB0 to OPB: BEAR= 0x%08x BESR0= 0x%08x BESR1= 0x%08x\n",
267 mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0),
268 mfdcr(DCRN_POB0_BESR1));
269#endif
270
271}
diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c
deleted file mode 100644
index c4b369b50f9c..000000000000
--- a/arch/ppc/syslib/ppc4xx_sgdma.c
+++ /dev/null
@@ -1,464 +0,0 @@
1/*
2 * IBM PPC4xx DMA engine scatter/gather library
3 *
4 * Copyright 2002-2003 MontaVista Software Inc.
5 *
6 * Cleaned up and converted to new DCR access
7 * Matt Porter <mporter@kernel.crashing.org>
8 *
9 * Original code by Armin Kuster <akuster@mvista.com>
10 * and Pete Popov <ppopov@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 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/dma-mapping.h>
27
28#include <asm/system.h>
29#include <asm/io.h>
30#include <asm/ppc4xx_dma.h>
31
32void
33ppc4xx_set_sg_addr(int dmanr, phys_addr_t sg_addr)
34{
35 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
36 printk("ppc4xx_set_sg_addr: bad channel: %d\n", dmanr);
37 return;
38 }
39
40#ifdef PPC4xx_DMA_64BIT
41 mtdcr(DCRN_ASGH0 + (dmanr * 0x8), (u32)(sg_addr >> 32));
42#endif
43 mtdcr(DCRN_ASG0 + (dmanr * 0x8), (u32)sg_addr);
44}
45
46/*
47 * Add a new sgl descriptor to the end of a scatter/gather list
48 * which was created by alloc_dma_handle().
49 *
50 * For a memory to memory transfer, both dma addresses must be
51 * valid. For a peripheral to memory transfer, one of the addresses
52 * must be set to NULL, depending on the direction of the transfer:
53 * memory to peripheral: set dst_addr to NULL,
54 * peripheral to memory: set src_addr to NULL.
55 */
56int
57ppc4xx_add_dma_sgl(sgl_handle_t handle, phys_addr_t src_addr, phys_addr_t dst_addr,
58 unsigned int count)
59{
60 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
61 ppc_dma_ch_t *p_dma_ch;
62
63 if (!handle) {
64 printk("ppc4xx_add_dma_sgl: null handle\n");
65 return DMA_STATUS_BAD_HANDLE;
66 }
67
68 if (psgl->dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
69 printk("ppc4xx_add_dma_sgl: bad channel: %d\n", psgl->dmanr);
70 return DMA_STATUS_BAD_CHANNEL;
71 }
72
73 p_dma_ch = &dma_channels[psgl->dmanr];
74
75#ifdef DEBUG_4xxDMA
76 {
77 int error = 0;
78 unsigned int aligned =
79 (unsigned) src_addr | (unsigned) dst_addr | count;
80 switch (p_dma_ch->pwidth) {
81 case PW_8:
82 break;
83 case PW_16:
84 if (aligned & 0x1)
85 error = 1;
86 break;
87 case PW_32:
88 if (aligned & 0x3)
89 error = 1;
90 break;
91 case PW_64:
92 if (aligned & 0x7)
93 error = 1;
94 break;
95 default:
96 printk("ppc4xx_add_dma_sgl: invalid bus width: 0x%x\n",
97 p_dma_ch->pwidth);
98 return DMA_STATUS_GENERAL_ERROR;
99 }
100 if (error)
101 printk
102 ("Alignment warning: ppc4xx_add_dma_sgl src 0x%x dst 0x%x count 0x%x bus width var %d\n",
103 src_addr, dst_addr, count, p_dma_ch->pwidth);
104
105 }
106#endif
107
108 if ((unsigned) (psgl->ptail + 1) >= ((unsigned) psgl + SGL_LIST_SIZE)) {
109 printk("sgl handle out of memory \n");
110 return DMA_STATUS_OUT_OF_MEMORY;
111 }
112
113 if (!psgl->ptail) {
114 psgl->phead = (ppc_sgl_t *)
115 ((unsigned) psgl + sizeof (sgl_list_info_t));
116 psgl->phead_dma = psgl->dma_addr + sizeof(sgl_list_info_t);
117 psgl->ptail = psgl->phead;
118 psgl->ptail_dma = psgl->phead_dma;
119 } else {
120 if(p_dma_ch->int_on_final_sg) {
121 /* mask out all dma interrupts, except error, on tail
122 before adding new tail. */
123 psgl->ptail->control_count &=
124 ~(SG_TCI_ENABLE | SG_ETI_ENABLE);
125 }
126 psgl->ptail->next = psgl->ptail_dma + sizeof(ppc_sgl_t);
127 psgl->ptail++;
128 psgl->ptail_dma += sizeof(ppc_sgl_t);
129 }
130
131 psgl->ptail->control = psgl->control;
132 psgl->ptail->src_addr = src_addr;
133 psgl->ptail->dst_addr = dst_addr;
134 psgl->ptail->control_count = (count >> p_dma_ch->shift) |
135 psgl->sgl_control;
136 psgl->ptail->next = (uint32_t) NULL;
137
138 return DMA_STATUS_GOOD;
139}
140
141/*
142 * Enable (start) the DMA described by the sgl handle.
143 */
144void
145ppc4xx_enable_dma_sgl(sgl_handle_t handle)
146{
147 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
148 ppc_dma_ch_t *p_dma_ch;
149 uint32_t sg_command;
150
151 if (!handle) {
152 printk("ppc4xx_enable_dma_sgl: null handle\n");
153 return;
154 } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
155 printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
156 psgl->dmanr);
157 return;
158 } else if (!psgl->phead) {
159 printk("ppc4xx_enable_dma_sgl: sg list empty\n");
160 return;
161 }
162
163 p_dma_ch = &dma_channels[psgl->dmanr];
164 psgl->ptail->control_count &= ~SG_LINK; /* make this the last dscrptr */
165 sg_command = mfdcr(DCRN_ASGC);
166
167 ppc4xx_set_sg_addr(psgl->dmanr, psgl->phead_dma);
168
169 sg_command |= SSG_ENABLE(psgl->dmanr);
170
171 mtdcr(DCRN_ASGC, sg_command); /* start transfer */
172}
173
174/*
175 * Halt an active scatter/gather DMA operation.
176 */
177void
178ppc4xx_disable_dma_sgl(sgl_handle_t handle)
179{
180 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
181 uint32_t sg_command;
182
183 if (!handle) {
184 printk("ppc4xx_enable_dma_sgl: null handle\n");
185 return;
186 } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
187 printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
188 psgl->dmanr);
189 return;
190 }
191
192 sg_command = mfdcr(DCRN_ASGC);
193 sg_command &= ~SSG_ENABLE(psgl->dmanr);
194 mtdcr(DCRN_ASGC, sg_command); /* stop transfer */
195}
196
197/*
198 * Returns number of bytes left to be transferred from the entire sgl list.
199 * *src_addr and *dst_addr get set to the source/destination address of
200 * the sgl descriptor where the DMA stopped.
201 *
202 * An sgl transfer must NOT be active when this function is called.
203 */
204int
205ppc4xx_get_dma_sgl_residue(sgl_handle_t handle, phys_addr_t * src_addr,
206 phys_addr_t * dst_addr)
207{
208 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
209 ppc_dma_ch_t *p_dma_ch;
210 ppc_sgl_t *pnext, *sgl_addr;
211 uint32_t count_left;
212
213 if (!handle) {
214 printk("ppc4xx_get_dma_sgl_residue: null handle\n");
215 return DMA_STATUS_BAD_HANDLE;
216 } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
217 printk("ppc4xx_get_dma_sgl_residue: bad channel in handle %d\n",
218 psgl->dmanr);
219 return DMA_STATUS_BAD_CHANNEL;
220 }
221
222 sgl_addr = (ppc_sgl_t *) __va(mfdcr(DCRN_ASG0 + (psgl->dmanr * 0x8)));
223 count_left = mfdcr(DCRN_DMACT0 + (psgl->dmanr * 0x8)) & SG_COUNT_MASK;
224
225 if (!sgl_addr) {
226 printk("ppc4xx_get_dma_sgl_residue: sgl addr register is null\n");
227 goto error;
228 }
229
230 pnext = psgl->phead;
231 while (pnext &&
232 ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE) &&
233 (pnext != sgl_addr))
234 ) {
235 pnext++;
236 }
237
238 if (pnext == sgl_addr) { /* found the sgl descriptor */
239
240 *src_addr = pnext->src_addr;
241 *dst_addr = pnext->dst_addr;
242
243 /*
244 * Now search the remaining descriptors and add their count.
245 * We already have the remaining count from this descriptor in
246 * count_left.
247 */
248 pnext++;
249
250 while ((pnext != psgl->ptail) &&
251 ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE))
252 ) {
253 count_left += pnext->control_count & SG_COUNT_MASK;
254 }
255
256 if (pnext != psgl->ptail) { /* should never happen */
257 printk
258 ("ppc4xx_get_dma_sgl_residue error (1) psgl->ptail 0x%x handle 0x%x\n",
259 (unsigned int) psgl->ptail, (unsigned int) handle);
260 goto error;
261 }
262
263 /* success */
264 p_dma_ch = &dma_channels[psgl->dmanr];
265 return (count_left << p_dma_ch->shift); /* count in bytes */
266
267 } else {
268 /* this shouldn't happen */
269 printk
270 ("get_dma_sgl_residue, unable to match current address 0x%x, handle 0x%x\n",
271 (unsigned int) sgl_addr, (unsigned int) handle);
272
273 }
274
275 error:
276 *src_addr = (phys_addr_t) NULL;
277 *dst_addr = (phys_addr_t) NULL;
278 return 0;
279}
280
281/*
282 * Returns the address(es) of the buffer(s) contained in the head element of
283 * the scatter/gather list. The element is removed from the scatter/gather
284 * list and the next element becomes the head.
285 *
286 * This function should only be called when the DMA is not active.
287 */
288int
289ppc4xx_delete_dma_sgl_element(sgl_handle_t handle, phys_addr_t * src_dma_addr,
290 phys_addr_t * dst_dma_addr)
291{
292 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
293
294 if (!handle) {
295 printk("ppc4xx_delete_sgl_element: null handle\n");
296 return DMA_STATUS_BAD_HANDLE;
297 } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
298 printk("ppc4xx_delete_sgl_element: bad channel in handle %d\n",
299 psgl->dmanr);
300 return DMA_STATUS_BAD_CHANNEL;
301 }
302
303 if (!psgl->phead) {
304 printk("ppc4xx_delete_sgl_element: sgl list empty\n");
305 *src_dma_addr = (phys_addr_t) NULL;
306 *dst_dma_addr = (phys_addr_t) NULL;
307 return DMA_STATUS_SGL_LIST_EMPTY;
308 }
309
310 *src_dma_addr = (phys_addr_t) psgl->phead->src_addr;
311 *dst_dma_addr = (phys_addr_t) psgl->phead->dst_addr;
312
313 if (psgl->phead == psgl->ptail) {
314 /* last descriptor on the list */
315 psgl->phead = NULL;
316 psgl->ptail = NULL;
317 } else {
318 psgl->phead++;
319 psgl->phead_dma += sizeof(ppc_sgl_t);
320 }
321
322 return DMA_STATUS_GOOD;
323}
324
325
326/*
327 * Create a scatter/gather list handle. This is simply a structure which
328 * describes a scatter/gather list.
329 *
330 * A handle is returned in "handle" which the driver should save in order to
331 * be able to access this list later. A chunk of memory will be allocated
332 * to be used by the API for internal management purposes, including managing
333 * the sg list and allocating memory for the sgl descriptors. One page should
334 * be more than enough for that purpose. Perhaps it's a bit wasteful to use
335 * a whole page for a single sg list, but most likely there will be only one
336 * sg list per channel.
337 *
338 * Interrupt notes:
339 * Each sgl descriptor has a copy of the DMA control word which the DMA engine
340 * loads in the control register. The control word has a "global" interrupt
341 * enable bit for that channel. Interrupts are further qualified by a few bits
342 * in the sgl descriptor count register. In order to setup an sgl, we have to
343 * know ahead of time whether or not interrupts will be enabled at the completion
344 * of the transfers. Thus, enable_dma_interrupt()/disable_dma_interrupt() MUST
345 * be called before calling alloc_dma_handle(). If the interrupt mode will never
346 * change after powerup, then enable_dma_interrupt()/disable_dma_interrupt()
347 * do not have to be called -- interrupts will be enabled or disabled based
348 * on how the channel was configured after powerup by the hw_init_dma_channel()
349 * function. Each sgl descriptor will be setup to interrupt if an error occurs;
350 * however, only the last descriptor will be setup to interrupt. Thus, an
351 * interrupt will occur (if interrupts are enabled) only after the complete
352 * sgl transfer is done.
353 */
354int
355ppc4xx_alloc_dma_handle(sgl_handle_t * phandle, unsigned int mode, unsigned int dmanr)
356{
357 sgl_list_info_t *psgl=NULL;
358 dma_addr_t dma_addr;
359 ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
360 uint32_t sg_command;
361 uint32_t ctc_settings;
362 void *ret;
363
364 if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
365 printk("ppc4xx_alloc_dma_handle: invalid channel 0x%x\n", dmanr);
366 return DMA_STATUS_BAD_CHANNEL;
367 }
368
369 if (!phandle) {
370 printk("ppc4xx_alloc_dma_handle: null handle pointer\n");
371 return DMA_STATUS_NULL_POINTER;
372 }
373
374 /* Get a page of memory, which is zeroed out by consistent_alloc() */
375 ret = dma_alloc_coherent(NULL, DMA_PPC4xx_SIZE, &dma_addr, GFP_KERNEL);
376 if (ret != NULL) {
377 memset(ret, 0, DMA_PPC4xx_SIZE);
378 psgl = (sgl_list_info_t *) ret;
379 }
380
381 if (psgl == NULL) {
382 *phandle = (sgl_handle_t) NULL;
383 return DMA_STATUS_OUT_OF_MEMORY;
384 }
385
386 psgl->dma_addr = dma_addr;
387 psgl->dmanr = dmanr;
388
389 /*
390 * Modify and save the control word. These words will be
391 * written to each sgl descriptor. The DMA engine then
392 * loads this control word into the control register
393 * every time it reads a new descriptor.
394 */
395 psgl->control = p_dma_ch->control;
396 /* Clear all mode bits */
397 psgl->control &= ~(DMA_TM_MASK | DMA_TD);
398 /* Save control word and mode */
399 psgl->control |= (mode | DMA_CE_ENABLE);
400
401 /* In MM mode, we must set ETD/TCE */
402 if (mode == DMA_MODE_MM)
403 psgl->control |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
404
405 if (p_dma_ch->int_enable) {
406 /* Enable channel interrupt */
407 psgl->control |= DMA_CIE_ENABLE;
408 } else {
409 psgl->control &= ~DMA_CIE_ENABLE;
410 }
411
412 sg_command = mfdcr(DCRN_ASGC);
413 sg_command |= SSG_MASK_ENABLE(dmanr);
414
415 /* Enable SGL control access */
416 mtdcr(DCRN_ASGC, sg_command);
417 psgl->sgl_control = SG_ERI_ENABLE | SG_LINK;
418
419 /* keep control count register settings */
420 ctc_settings = mfdcr(DCRN_DMACT0 + (dmanr * 0x8))
421 & (DMA_CTC_BSIZ_MSK | DMA_CTC_BTEN); /*burst mode settings*/
422 psgl->sgl_control |= ctc_settings;
423
424 if (p_dma_ch->int_enable) {
425 if (p_dma_ch->tce_enable)
426 psgl->sgl_control |= SG_TCI_ENABLE;
427 else
428 psgl->sgl_control |= SG_ETI_ENABLE;
429 }
430
431 *phandle = (sgl_handle_t) psgl;
432 return DMA_STATUS_GOOD;
433}
434
435/*
436 * Destroy a scatter/gather list handle that was created by alloc_dma_handle().
437 * The list must be empty (contain no elements).
438 */
439void
440ppc4xx_free_dma_handle(sgl_handle_t handle)
441{
442 sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
443
444 if (!handle) {
445 printk("ppc4xx_free_dma_handle: got NULL\n");
446 return;
447 } else if (psgl->phead) {
448 printk("ppc4xx_free_dma_handle: list not empty\n");
449 return;
450 } else if (!psgl->dma_addr) { /* should never happen */
451 printk("ppc4xx_free_dma_handle: no dma address\n");
452 return;
453 }
454
455 dma_free_coherent(NULL, DMA_PPC4xx_SIZE, (void *) psgl, 0);
456}
457
458EXPORT_SYMBOL(ppc4xx_alloc_dma_handle);
459EXPORT_SYMBOL(ppc4xx_free_dma_handle);
460EXPORT_SYMBOL(ppc4xx_add_dma_sgl);
461EXPORT_SYMBOL(ppc4xx_delete_dma_sgl_element);
462EXPORT_SYMBOL(ppc4xx_enable_dma_sgl);
463EXPORT_SYMBOL(ppc4xx_disable_dma_sgl);
464EXPORT_SYMBOL(ppc4xx_get_dma_sgl_residue);
diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c
deleted file mode 100644
index bce9a75c80e3..000000000000
--- a/arch/ppc/syslib/ppc8xx_pic.c
+++ /dev/null
@@ -1,126 +0,0 @@
1#include <linux/module.h>
2#include <linux/stddef.h>
3#include <linux/init.h>
4#include <linux/sched.h>
5#include <linux/signal.h>
6#include <linux/interrupt.h>
7#include <asm/irq.h>
8#include <asm/io.h>
9#include <asm/8xx_immap.h>
10#include <asm/mpc8xx.h>
11#include "ppc8xx_pic.h"
12
13extern int cpm_get_irq(void);
14
15/* The 8xx internal interrupt controller. It is usually
16 * the only interrupt controller. Some boards, like the MBX and
17 * Sandpoint have the 8259 as a secondary controller. Depending
18 * upon the processor type, the internal controller can have as
19 * few as 16 interrupts or as many as 64. We could use the
20 * "clear_bit()" and "set_bit()" functions like other platforms,
21 * but they are overkill for us.
22 */
23
24static void m8xx_mask_irq(unsigned int irq_nr)
25{
26 int bit, word;
27
28 bit = irq_nr & 0x1f;
29 word = irq_nr >> 5;
30
31 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
32 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
33}
34
35static void m8xx_unmask_irq(unsigned int irq_nr)
36{
37 int bit, word;
38
39 bit = irq_nr & 0x1f;
40 word = irq_nr >> 5;
41
42 ppc_cached_irq_mask[word] |= (1 << (31-bit));
43 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
44}
45
46static void m8xx_end_irq(unsigned int irq_nr)
47{
48 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
49 && irq_desc[irq_nr].action) {
50 int bit, word;
51
52 bit = irq_nr & 0x1f;
53 word = irq_nr >> 5;
54
55 ppc_cached_irq_mask[word] |= (1 << (31-bit));
56 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
57 }
58}
59
60
61static void m8xx_mask_and_ack(unsigned int irq_nr)
62{
63 int bit, word;
64
65 bit = irq_nr & 0x1f;
66 word = irq_nr >> 5;
67
68 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
69 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
70 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit));
71}
72
73struct hw_interrupt_type ppc8xx_pic = {
74 .typename = " 8xx SIU ",
75 .enable = m8xx_unmask_irq,
76 .disable = m8xx_mask_irq,
77 .ack = m8xx_mask_and_ack,
78 .end = m8xx_end_irq,
79};
80
81/*
82 * We either return a valid interrupt or -1 if there is nothing pending
83 */
84int
85m8xx_get_irq(struct pt_regs *regs)
86{
87 int irq;
88
89 /* For MPC8xx, read the SIVEC register and shift the bits down
90 * to get the irq number.
91 */
92 irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26;
93
94 /*
95 * When we read the sivec without an interrupt to process, we will
96 * get back SIU_LEVEL7. In this case, return -1
97 */
98 if (irq == CPM_INTERRUPT)
99 irq = CPM_IRQ_OFFSET + cpm_get_irq();
100#if defined(CONFIG_PCI)
101 else if (irq == ISA_BRIDGE_INT) {
102 int isa_irq;
103
104 if ((isa_irq = i8259_poll(regs)) >= 0)
105 irq = I8259_IRQ_OFFSET + isa_irq;
106 }
107#endif /* CONFIG_PCI */
108 else if (irq == SIU_LEVEL7)
109 irq = -1;
110
111 return irq;
112}
113
114#if defined(CONFIG_MBX) && defined(CONFIG_PCI)
115/* Only the MBX uses the external 8259. This allows us to catch standard
116 * drivers that may mess up the internal interrupt controllers, and also
117 * allow them to run without modification on the MBX.
118 */
119void mbx_i8259_action(int irq, void *dev_id, struct pt_regs *regs)
120{
121 /* This interrupt handler never actually gets called. It is
122 * installed only to unmask the 8259 cascade interrupt in the SIU
123 * and to make the 8259 cascade interrupt visible in /proc/interrupts.
124 */
125}
126#endif /* CONFIG_PCI */
diff --git a/arch/ppc/syslib/ppc8xx_pic.h b/arch/ppc/syslib/ppc8xx_pic.h
deleted file mode 100644
index 53bcd97ef7f5..000000000000
--- a/arch/ppc/syslib/ppc8xx_pic.h
+++ /dev/null
@@ -1,19 +0,0 @@
1#ifndef _PPC_KERNEL_PPC8xx_H
2#define _PPC_KERNEL_PPC8xx_H
3
4#include <linux/irq.h>
5#include <linux/interrupt.h>
6
7extern struct hw_interrupt_type ppc8xx_pic;
8
9void m8xx_do_IRQ(struct pt_regs *regs,
10 int cpu);
11int m8xx_get_irq(struct pt_regs *regs);
12
13#ifdef CONFIG_MBX
14#include <asm/i8259.h>
15#include <asm/io.h>
16void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs);
17#endif
18
19#endif /* _PPC_KERNEL_PPC8xx_H */
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
deleted file mode 100644
index 837183c24dfc..000000000000
--- a/arch/ppc/syslib/ppc_sys.c
+++ /dev/null
@@ -1,329 +0,0 @@
1/*
2 * PPC System library functions
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * Copyright 2005 Freescale Semiconductor Inc.
7 * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
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/string.h>
16#include <linux/bootmem.h>
17#include <asm/ppc_sys.h>
18
19int (*ppc_sys_device_fixup) (struct platform_device * pdev);
20
21static int ppc_sys_inited;
22static int ppc_sys_func_inited;
23
24static const char *ppc_sys_func_names[] = {
25 [PPC_SYS_FUNC_DUMMY] = "dummy",
26 [PPC_SYS_FUNC_ETH] = "eth",
27 [PPC_SYS_FUNC_UART] = "uart",
28 [PPC_SYS_FUNC_HLDC] = "hldc",
29 [PPC_SYS_FUNC_USB] = "usb",
30 [PPC_SYS_FUNC_IRDA] = "irda",
31};
32
33void __init identify_ppc_sys_by_id(u32 id)
34{
35 unsigned int i = 0;
36 while (1) {
37 if ((ppc_sys_specs[i].mask & id) == ppc_sys_specs[i].value)
38 break;
39 i++;
40 }
41
42 cur_ppc_sys_spec = &ppc_sys_specs[i];
43
44 return;
45}
46
47void __init identify_ppc_sys_by_name(char *name)
48{
49 unsigned int i = 0;
50 while (ppc_sys_specs[i].ppc_sys_name[0]) {
51 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
52 break;
53 i++;
54 }
55 cur_ppc_sys_spec = &ppc_sys_specs[i];
56
57 return;
58}
59
60static int __init count_sys_specs(void)
61{
62 int i = 0;
63 while (ppc_sys_specs[i].ppc_sys_name[0])
64 i++;
65 return i;
66}
67
68static int __init find_chip_by_name_and_id(char *name, u32 id)
69{
70 int ret = -1;
71 unsigned int i = 0;
72 unsigned int j = 0;
73 unsigned int dups = 0;
74
75 unsigned char matched[count_sys_specs()];
76
77 while (ppc_sys_specs[i].ppc_sys_name[0]) {
78 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
79 matched[j++] = i;
80 i++;
81 }
82
83 ret = i;
84
85 if (j != 0) {
86 for (i = 0; i < j; i++) {
87 if ((ppc_sys_specs[matched[i]].mask & id) ==
88 ppc_sys_specs[matched[i]].value) {
89 ret = matched[i];
90 dups++;
91 }
92 }
93 ret = (dups == 1) ? ret : (-1 * dups);
94 }
95 return ret;
96}
97
98void __init identify_ppc_sys_by_name_and_id(char *name, u32 id)
99{
100 int i = find_chip_by_name_and_id(name, id);
101 BUG_ON(i < 0);
102 cur_ppc_sys_spec = &ppc_sys_specs[i];
103}
104
105/* Update all memory resources by paddr, call before platform_device_register */
106void __init
107ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
108{
109 int i;
110 for (i = 0; i < pdev->num_resources; i++) {
111 struct resource *r = &pdev->resource[i];
112 if (((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) &&
113 ((r->flags & PPC_SYS_IORESOURCE_FIXUPPED) != PPC_SYS_IORESOURCE_FIXUPPED)) {
114 r->start += paddr;
115 r->end += paddr;
116 r->flags |= PPC_SYS_IORESOURCE_FIXUPPED;
117 }
118 }
119}
120
121/* Get platform_data pointer out of platform device, call before platform_device_register */
122void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev)
123{
124 return ppc_sys_platform_devices[dev].dev.platform_data;
125}
126
127void ppc_sys_device_remove(enum ppc_sys_devices dev)
128{
129 unsigned int i;
130
131 if (ppc_sys_inited) {
132 platform_device_unregister(&ppc_sys_platform_devices[dev]);
133 } else {
134 if (cur_ppc_sys_spec == NULL)
135 return;
136 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++)
137 if (cur_ppc_sys_spec->device_list[i] == dev)
138 cur_ppc_sys_spec->device_list[i] = -1;
139 }
140}
141
142/* Platform-notify mapping
143 * Helper function for BSP code to assign board-specific platfom-divice bits
144 */
145
146void platform_notify_map(const struct platform_notify_dev_map *map,
147 struct device *dev)
148{
149 struct platform_device *pdev;
150 int len, idx;
151 const char *s;
152
153 /* do nothing if no device or no bus_id */
154 if (!dev || !dev->bus_id)
155 return;
156
157 /* call per device map */
158 while (map->bus_id != NULL) {
159 idx = -1;
160 s = strrchr(dev->bus_id, '.');
161 if (s != NULL) {
162 idx = (int)simple_strtol(s + 1, NULL, 10);
163 len = s - dev->bus_id;
164 } else {
165 s = dev->bus_id;
166 len = strlen(dev->bus_id);
167 }
168
169 if (!strncmp(dev->bus_id, map->bus_id, len)) {
170 pdev = container_of(dev, struct platform_device, dev);
171 map->rtn(pdev, idx);
172 }
173 map++;
174 }
175}
176
177/*
178 Function assignment stuff.
179 Intended to work as follows:
180 the device name defined in foo_devices.c will be concatenated with :"func",
181 where func is string map of respective function from platfom_device_func enum
182
183 The PPC_SYS_FUNC_DUMMY function is intended to remove all assignments, making the device to appear
184 in platform bus with unmodified name.
185 */
186
187/*
188 Here we'll replace .name pointers with fixed-length strings
189 Hereby, this should be called *before* any func stuff triggeded.
190 */
191void ppc_sys_device_initfunc(void)
192{
193 int i;
194 const char *name;
195 static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
196 enum ppc_sys_devices cur_dev;
197
198 /* If inited yet, do nothing */
199 if (ppc_sys_func_inited)
200 return;
201
202 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
203 if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
204 continue;
205
206 if (ppc_sys_platform_devices[cur_dev].name) {
207 /*backup name */
208 name = ppc_sys_platform_devices[cur_dev].name;
209 strlcpy(new_names[i], name, BUS_ID_SIZE);
210 ppc_sys_platform_devices[cur_dev].name = new_names[i];
211 }
212 }
213
214 ppc_sys_func_inited = 1;
215}
216
217/*The "engine" of the func stuff. Here we either concat specified function string description
218 to the name, or remove it if PPC_SYS_FUNC_DUMMY parameter is passed here*/
219void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
220 enum platform_device_func func)
221{
222 char *s;
223 char *name = (char *)ppc_sys_platform_devices[dev].name;
224 char tmp[BUS_ID_SIZE];
225
226 if (!ppc_sys_func_inited) {
227 printk(KERN_ERR "Unable to alter function - not inited!\n");
228 return;
229 }
230
231 if (ppc_sys_inited) {
232 platform_device_unregister(&ppc_sys_platform_devices[dev]);
233 }
234
235 if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
236 /* Either change the name after ':' or remove func modifications */
237 if (func != PPC_SYS_FUNC_DUMMY)
238 strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
239 else
240 *s = 0;
241 } else if (func != PPC_SYS_FUNC_DUMMY) {
242 /* do assignment if it is not just "clear" request */
243 sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
244 strlcpy(name, tmp, BUS_ID_SIZE);
245 }
246
247 if (ppc_sys_inited) {
248 platform_device_register(&ppc_sys_platform_devices[dev]);
249 }
250}
251
252void ppc_sys_device_disable(enum ppc_sys_devices dev)
253{
254 BUG_ON(cur_ppc_sys_spec == NULL);
255
256 /*Check if it is enabled*/
257 if(!(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED)) {
258 if (ppc_sys_inited) {
259 platform_device_unregister(&ppc_sys_platform_devices[dev]);
260 }
261 cur_ppc_sys_spec->config[dev] |= PPC_SYS_CONFIG_DISABLED;
262 }
263}
264
265void ppc_sys_device_enable(enum ppc_sys_devices dev)
266{
267 BUG_ON(cur_ppc_sys_spec == NULL);
268
269 /*Check if it is disabled*/
270 if(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED) {
271 if (ppc_sys_inited) {
272 platform_device_register(&ppc_sys_platform_devices[dev]);
273 }
274 cur_ppc_sys_spec->config[dev] &= ~PPC_SYS_CONFIG_DISABLED;
275 }
276
277}
278
279void ppc_sys_device_enable_all(void)
280{
281 enum ppc_sys_devices cur_dev;
282 int i;
283
284 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
285 cur_dev = cur_ppc_sys_spec->device_list[i];
286 ppc_sys_device_enable(cur_dev);
287 }
288}
289
290void ppc_sys_device_disable_all(void)
291{
292 enum ppc_sys_devices cur_dev;
293 int i;
294
295 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
296 cur_dev = cur_ppc_sys_spec->device_list[i];
297 ppc_sys_device_disable(cur_dev);
298 }
299}
300
301
302static int __init ppc_sys_init(void)
303{
304 unsigned int i, dev_id, ret = 0;
305
306 BUG_ON(cur_ppc_sys_spec == NULL);
307
308 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
309 dev_id = cur_ppc_sys_spec->device_list[i];
310 if ((dev_id != -1) &&
311 !(cur_ppc_sys_spec->config[dev_id] & PPC_SYS_CONFIG_DISABLED)) {
312 if (ppc_sys_device_fixup != NULL)
313 ppc_sys_device_fixup(&ppc_sys_platform_devices
314 [dev_id]);
315 if (platform_device_register
316 (&ppc_sys_platform_devices[dev_id])) {
317 ret = 1;
318 printk(KERN_ERR
319 "unable to register device %d\n",
320 dev_id);
321 }
322 }
323 }
324
325 ppc_sys_inited = 1;
326 return ret;
327}
328
329subsys_initcall(ppc_sys_init);
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
deleted file mode 100644
index fefbc217a56d..000000000000
--- a/arch/ppc/syslib/pq2_devices.c
+++ /dev/null
@@ -1,393 +0,0 @@
1/*
2 * PQ2 Device descriptions
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/ioport.h>
16#include <asm/cpm2.h>
17#include <asm/irq.h>
18#include <asm/ppc_sys.h>
19#include <asm/machdep.h>
20
21struct platform_device ppc_sys_platform_devices[] = {
22 [MPC82xx_CPM_FCC1] = {
23 .name = "fsl-cpm-fcc",
24 .id = 1,
25 .num_resources = 3,
26 .resource = (struct resource[]) {
27 {
28 .name = "fcc_regs",
29 .start = 0x11300,
30 .end = 0x1131f,
31 .flags = IORESOURCE_MEM,
32 },
33 {
34 .name = "fcc_pram",
35 .start = 0x8400,
36 .end = 0x84ff,
37 .flags = IORESOURCE_MEM,
38 },
39 {
40 .start = SIU_INT_FCC1,
41 .end = SIU_INT_FCC1,
42 .flags = IORESOURCE_IRQ,
43 },
44 },
45 },
46 [MPC82xx_CPM_FCC2] = {
47 .name = "fsl-cpm-fcc",
48 .id = 2,
49 .num_resources = 3,
50 .resource = (struct resource[]) {
51 {
52 .name = "fcc_regs",
53 .start = 0x11320,
54 .end = 0x1133f,
55 .flags = IORESOURCE_MEM,
56 },
57 {
58 .name = "fcc_pram",
59 .start = 0x8500,
60 .end = 0x85ff,
61 .flags = IORESOURCE_MEM,
62 },
63 {
64 .start = SIU_INT_FCC2,
65 .end = SIU_INT_FCC2,
66 .flags = IORESOURCE_IRQ,
67 },
68 },
69 },
70 [MPC82xx_CPM_FCC3] = {
71 .name = "fsl-cpm-fcc",
72 .id = 3,
73 .num_resources = 3,
74 .resource = (struct resource[]) {
75 {
76 .name = "fcc_regs",
77 .start = 0x11340,
78 .end = 0x1135f,
79 .flags = IORESOURCE_MEM,
80 },
81 {
82 .name = "fcc_pram",
83 .start = 0x8600,
84 .end = 0x86ff,
85 .flags = IORESOURCE_MEM,
86 },
87 {
88 .start = SIU_INT_FCC3,
89 .end = SIU_INT_FCC3,
90 .flags = IORESOURCE_IRQ,
91 },
92 },
93 },
94 [MPC82xx_CPM_I2C] = {
95 .name = "fsl-cpm-i2c",
96 .id = 1,
97 .num_resources = 3,
98 .resource = (struct resource[]) {
99 {
100 .name = "i2c_mem",
101 .start = 0x11860,
102 .end = 0x118BF,
103 .flags = IORESOURCE_MEM,
104 },
105 {
106 .name = "i2c_pram",
107 .start = 0x8afc,
108 .end = 0x8afd,
109 .flags = IORESOURCE_MEM,
110 },
111 {
112 .start = SIU_INT_I2C,
113 .end = SIU_INT_I2C,
114 .flags = IORESOURCE_IRQ,
115 },
116 },
117 },
118 [MPC82xx_CPM_SCC1] = {
119 .name = "fsl-cpm-scc",
120 .id = 1,
121 .num_resources = 3,
122 .resource = (struct resource[]) {
123 {
124 .name = "regs",
125 .start = 0x11A00,
126 .end = 0x11A1F,
127 .flags = IORESOURCE_MEM,
128 },
129 {
130 .name = "pram",
131 .start = 0x8000,
132 .end = 0x80ff,
133 .flags = IORESOURCE_MEM,
134 },
135 {
136 .start = SIU_INT_SCC1,
137 .end = SIU_INT_SCC1,
138 .flags = IORESOURCE_IRQ,
139 },
140 },
141 },
142 [MPC82xx_CPM_SCC2] = {
143 .name = "fsl-cpm-scc",
144 .id = 2,
145 .num_resources = 3,
146 .resource = (struct resource[]) {
147 {
148 .name = "regs",
149 .start = 0x11A20,
150 .end = 0x11A3F,
151 .flags = IORESOURCE_MEM,
152 },
153 {
154 .name = "pram",
155 .start = 0x8100,
156 .end = 0x81ff,
157 .flags = IORESOURCE_MEM,
158 },
159 {
160 .start = SIU_INT_SCC2,
161 .end = SIU_INT_SCC2,
162 .flags = IORESOURCE_IRQ,
163 },
164 },
165 },
166 [MPC82xx_CPM_SCC3] = {
167 .name = "fsl-cpm-scc",
168 .id = 3,
169 .num_resources = 3,
170 .resource = (struct resource[]) {
171 {
172 .name = "regs",
173 .start = 0x11A40,
174 .end = 0x11A5F,
175 .flags = IORESOURCE_MEM,
176 },
177 {
178 .name = "pram",
179 .start = 0x8200,
180 .end = 0x82ff,
181 .flags = IORESOURCE_MEM,
182 },
183 {
184 .start = SIU_INT_SCC3,
185 .end = SIU_INT_SCC3,
186 .flags = IORESOURCE_IRQ,
187 },
188 },
189 },
190 [MPC82xx_CPM_SCC4] = {
191 .name = "fsl-cpm-scc",
192 .id = 4,
193 .num_resources = 3,
194 .resource = (struct resource[]) {
195 {
196 .name = "regs",
197 .start = 0x11A60,
198 .end = 0x11A7F,
199 .flags = IORESOURCE_MEM,
200 },
201 {
202 .name = "pram",
203 .start = 0x8300,
204 .end = 0x83ff,
205 .flags = IORESOURCE_MEM,
206 },
207 {
208 .start = SIU_INT_SCC4,
209 .end = SIU_INT_SCC4,
210 .flags = IORESOURCE_IRQ,
211 },
212 },
213 },
214 [MPC82xx_CPM_SPI] = {
215 .name = "fsl-cpm-spi",
216 .id = 1,
217 .num_resources = 3,
218 .resource = (struct resource[]) {
219 {
220 .name = "spi_mem",
221 .start = 0x11AA0,
222 .end = 0x11AFF,
223 .flags = IORESOURCE_MEM,
224 },
225 {
226 .name = "spi_pram",
227 .start = 0x89fc,
228 .end = 0x89fd,
229 .flags = IORESOURCE_MEM,
230 },
231 {
232 .start = SIU_INT_SPI,
233 .end = SIU_INT_SPI,
234 .flags = IORESOURCE_IRQ,
235 },
236 },
237 },
238 [MPC82xx_CPM_MCC1] = {
239 .name = "fsl-cpm-mcc",
240 .id = 1,
241 .num_resources = 3,
242 .resource = (struct resource[]) {
243 {
244 .name = "mcc_mem",
245 .start = 0x11B30,
246 .end = 0x11B3F,
247 .flags = IORESOURCE_MEM,
248 },
249 {
250 .name = "mcc_pram",
251 .start = 0x8700,
252 .end = 0x877f,
253 .flags = IORESOURCE_MEM,
254 },
255 {
256 .start = SIU_INT_MCC1,
257 .end = SIU_INT_MCC1,
258 .flags = IORESOURCE_IRQ,
259 },
260 },
261 },
262 [MPC82xx_CPM_MCC2] = {
263 .name = "fsl-cpm-mcc",
264 .id = 2,
265 .num_resources = 3,
266 .resource = (struct resource[]) {
267 {
268 .name = "mcc_mem",
269 .start = 0x11B50,
270 .end = 0x11B5F,
271 .flags = IORESOURCE_MEM,
272 },
273 {
274 .name = "mcc_pram",
275 .start = 0x8800,
276 .end = 0x887f,
277 .flags = IORESOURCE_MEM,
278 },
279 {
280 .start = SIU_INT_MCC2,
281 .end = SIU_INT_MCC2,
282 .flags = IORESOURCE_IRQ,
283 },
284 },
285 },
286 [MPC82xx_CPM_SMC1] = {
287 .name = "fsl-cpm-smc",
288 .id = 1,
289 .num_resources = 3,
290 .resource = (struct resource[]) {
291 {
292 .name = "smc_mem",
293 .start = 0x11A80,
294 .end = 0x11A8F,
295 .flags = IORESOURCE_MEM,
296 },
297 {
298 .name = "smc_pram",
299 .start = 0x87fc,
300 .end = 0x87fd,
301 .flags = IORESOURCE_MEM,
302 },
303 {
304 .start = SIU_INT_SMC1,
305 .end = SIU_INT_SMC1,
306 .flags = IORESOURCE_IRQ,
307 },
308 },
309 },
310 [MPC82xx_CPM_SMC2] = {
311 .name = "fsl-cpm-smc",
312 .id = 2,
313 .num_resources = 3,
314 .resource = (struct resource[]) {
315 {
316 .name = "smc_mem",
317 .start = 0x11A90,
318 .end = 0x11A9F,
319 .flags = IORESOURCE_MEM,
320 },
321 {
322 .name = "smc_pram",
323 .start = 0x88fc,
324 .end = 0x88fd,
325 .flags = IORESOURCE_MEM,
326 },
327 {
328 .start = SIU_INT_SMC2,
329 .end = SIU_INT_SMC2,
330 .flags = IORESOURCE_IRQ,
331 },
332 },
333 },
334 [MPC82xx_CPM_USB] = {
335 .name = "fsl-cpm-usb",
336 .id = 1,
337 .num_resources = 3,
338 .resource = (struct resource[]) {
339 {
340 .name = "usb_mem",
341 .start = 0x11b60,
342 .end = 0x11b78,
343 .flags = IORESOURCE_MEM,
344 },
345 {
346 .name = "usb_pram",
347 .start = 0x8b00,
348 .end = 0x8bff,
349 .flags = IORESOURCE_MEM,
350 },
351 {
352 .start = SIU_INT_USB,
353 .end = SIU_INT_USB,
354 .flags = IORESOURCE_IRQ,
355 },
356
357 },
358 },
359 [MPC82xx_SEC1] = {
360 .name = "fsl-sec",
361 .id = 1,
362 .num_resources = 1,
363 .resource = (struct resource[]) {
364 {
365 .name = "sec_mem",
366 .start = 0x40000,
367 .end = 0x52fff,
368 .flags = IORESOURCE_MEM,
369 },
370 },
371 },
372 [MPC82xx_MDIO_BB] = {
373 .name = "fsl-bb-mdio",
374 .id = 0,
375 .num_resources = 0,
376 },
377};
378
379static int __init mach_mpc82xx_fixup(struct platform_device *pdev)
380{
381 ppc_sys_fixup_mem_resource(pdev, CPM_MAP_ADDR);
382 return 0;
383}
384
385static int __init mach_mpc82xx_init(void)
386{
387 if (ppc_md.progress)
388 ppc_md.progress("mach_mpc82xx_init:enter", 0);
389 ppc_sys_device_fixup = mach_mpc82xx_fixup;
390 return 0;
391}
392
393postcore_initcall(mach_mpc82xx_init);
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
deleted file mode 100644
index 9c85300846c7..000000000000
--- a/arch/ppc/syslib/pq2_sys.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * PQ2 System descriptions
3 *
4 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/device.h>
14
15#include <asm/ppc_sys.h>
16
17struct ppc_sys_spec *cur_ppc_sys_spec;
18struct ppc_sys_spec ppc_sys_specs[] = {
19 /* below is a list of the 8260 family of processors */
20 {
21 .ppc_sys_name = "8250",
22 .mask = 0x0000ff00,
23 .value = 0x00000000,
24 .num_devices = 12,
25 .device_list = (enum ppc_sys_devices[])
26 {
27 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
28 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
29 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC2, MPC82xx_CPM_SMC1,
30 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
31 }
32 },
33 {
34 .ppc_sys_name = "8255",
35 .mask = 0x0000ff00,
36 .value = 0x00000000,
37 .num_devices = 11,
38 .device_list = (enum ppc_sys_devices[])
39 {
40 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
41 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
42 MPC82xx_CPM_MCC2, MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2,
43 MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
44 }
45 },
46 {
47 .ppc_sys_name = "8260",
48 .mask = 0x0000ff00,
49 .value = 0x00000000,
50 .num_devices = 13,
51 .device_list = (enum ppc_sys_devices[])
52 {
53 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
54 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
55 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC1, MPC82xx_CPM_MCC2,
56 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
57 MPC82xx_CPM_I2C,
58 }
59 },
60 {
61 .ppc_sys_name = "8264",
62 .mask = 0x0000ff00,
63 .value = 0x00000000,
64 .num_devices = 13,
65 .device_list = (enum ppc_sys_devices[])
66 {
67 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
68 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
69 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC1, MPC82xx_CPM_MCC2,
70 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
71 MPC82xx_CPM_I2C,
72 }
73 },
74 {
75 .ppc_sys_name = "8265",
76 .mask = 0x0000ff00,
77 .value = 0x00000000,
78 .num_devices = 13,
79 .device_list = (enum ppc_sys_devices[])
80 {
81 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
82 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
83 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC1, MPC82xx_CPM_MCC2,
84 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
85 MPC82xx_CPM_I2C,
86 }
87 },
88 {
89 .ppc_sys_name = "8266",
90 .mask = 0x0000ff00,
91 .value = 0x00000000,
92 .num_devices = 13,
93 .device_list = (enum ppc_sys_devices[])
94 {
95 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
96 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
97 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC1, MPC82xx_CPM_MCC2,
98 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
99 MPC82xx_CPM_I2C,
100 }
101 },
102 /* below is a list of the 8272 family of processors */
103 {
104 .ppc_sys_name = "8247",
105 .mask = 0x0000ff00,
106 .value = 0x00000d00,
107 .num_devices = 10,
108 .device_list = (enum ppc_sys_devices[])
109 {
110 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
111 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1,
112 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
113 MPC82xx_CPM_USB,
114 },
115 },
116 {
117 .ppc_sys_name = "8248",
118 .mask = 0x0000ff00,
119 .value = 0x00000c00,
120 .num_devices = 12,
121 .device_list = (enum ppc_sys_devices[])
122 {
123 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
124 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
125 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
126 MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
127 },
128 },
129 {
130 .ppc_sys_name = "8271",
131 .mask = 0x0000ff00,
132 .value = 0x00000d00,
133 .num_devices = 10,
134 .device_list = (enum ppc_sys_devices[])
135 {
136 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
137 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1,
138 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
139 MPC82xx_CPM_USB,
140 },
141 },
142 {
143 .ppc_sys_name = "8272",
144 .mask = 0x0000ff00,
145 .value = 0x00000c00,
146 .num_devices = 13,
147 .device_list = (enum ppc_sys_devices[])
148 {
149 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
150 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
151 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
152 MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
153 MPC82xx_MDIO_BB,
154 },
155 },
156 /* below is a list of the 8280 family of processors */
157 {
158 .ppc_sys_name = "8270",
159 .mask = 0x0000ff00,
160 .value = 0x00000a00,
161 .num_devices = 12,
162 .device_list = (enum ppc_sys_devices[])
163 {
164 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
165 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
166 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC2, MPC82xx_CPM_SMC1,
167 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
168 },
169 },
170 {
171 .ppc_sys_name = "8275",
172 .mask = 0x0000ff00,
173 .value = 0x00000a00,
174 .num_devices = 12,
175 .device_list = (enum ppc_sys_devices[])
176 {
177 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
178 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
179 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC2, MPC82xx_CPM_SMC1,
180 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
181 },
182 },
183 {
184 .ppc_sys_name = "8280",
185 .mask = 0x0000ff00,
186 .value = 0x00000a00,
187 .num_devices = 13,
188 .device_list = (enum ppc_sys_devices[])
189 {
190 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_FCC3,
191 MPC82xx_CPM_SCC1, MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3,
192 MPC82xx_CPM_SCC4, MPC82xx_CPM_MCC1, MPC82xx_CPM_MCC2,
193 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
194 MPC82xx_CPM_I2C,
195 },
196 },
197 {
198 /* default match */
199 .ppc_sys_name = "",
200 .mask = 0x00000000,
201 .value = 0x00000000,
202 },
203};
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
deleted file mode 100644
index 474dccbc4a8a..000000000000
--- a/arch/ppc/syslib/prep_nvram.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * Copyright (C) 1998 Corey Minyard
3 *
4 * This reads the NvRAM on PReP compliant machines (generally from IBM or
5 * Motorola). Motorola kept the format of NvRAM in their ROM, PPCBUG, the
6 * same, long after they had stopped producing PReP compliant machines. So
7 * this code is useful in those cases as well.
8 *
9 */
10#include <linux/init.h>
11#include <linux/delay.h>
12#include <linux/slab.h>
13#include <linux/ioport.h>
14
15#include <asm/sections.h>
16#include <asm/io.h>
17#include <asm/machdep.h>
18#include <asm/prep_nvram.h>
19
20static char nvramData[MAX_PREP_NVRAM];
21static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
22
23unsigned char prep_nvram_read_val(int addr)
24{
25 outb(addr, PREP_NVRAM_AS0);
26 outb(addr>>8, PREP_NVRAM_AS1);
27 return inb(PREP_NVRAM_DATA);
28}
29
30void prep_nvram_write_val(int addr,
31 unsigned char val)
32{
33 outb(addr, PREP_NVRAM_AS0);
34 outb(addr>>8, PREP_NVRAM_AS1);
35 outb(val, PREP_NVRAM_DATA);
36}
37
38void __init init_prep_nvram(void)
39{
40 unsigned char *nvp;
41 int i;
42 int nvramSize;
43
44 /*
45 * The following could fail if the NvRAM were corrupt but
46 * we expect the boot firmware to have checked its checksum
47 * before boot
48 */
49 nvp = (char *) &nvram->Header;
50 for (i=0; i<sizeof(HEADER); i++)
51 {
52 *nvp = ppc_md.nvram_read_val(i);
53 nvp++;
54 }
55
56 /*
57 * The PReP NvRAM may be any size so read in the header to
58 * determine how much we must read in order to get the complete
59 * GE area
60 */
61 nvramSize=(int)nvram->Header.GEAddress+nvram->Header.GELength;
62 if(nvramSize>MAX_PREP_NVRAM)
63 {
64 /*
65 * NvRAM is too large
66 */
67 nvram->Header.GELength=0;
68 return;
69 }
70
71 /*
72 * Read the remainder of the PReP NvRAM
73 */
74 nvp = (char *) &nvram->GEArea[0];
75 for (i=sizeof(HEADER); i<nvramSize; i++)
76 {
77 *nvp = ppc_md.nvram_read_val(i);
78 nvp++;
79 }
80}
81
82char *prep_nvram_get_var(const char *name)
83{
84 char *cp;
85 int namelen;
86
87 namelen = strlen(name);
88 cp = prep_nvram_first_var();
89 while (cp != NULL) {
90 if ((strncmp(name, cp, namelen) == 0)
91 && (cp[namelen] == '='))
92 {
93 return cp+namelen+1;
94 }
95 cp = prep_nvram_next_var(cp);
96 }
97
98 return NULL;
99}
100
101char *prep_nvram_first_var(void)
102{
103 if (nvram->Header.GELength == 0) {
104 return NULL;
105 } else {
106 return (((char *)nvram)
107 + ((unsigned int) nvram->Header.GEAddress));
108 }
109}
110
111char *prep_nvram_next_var(char *name)
112{
113 char *cp;
114
115
116 cp = name;
117 while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
118 && (*cp != '\0'))
119 {
120 cp++;
121 }
122
123 /* Skip over any null characters. */
124 while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
125 && (*cp == '\0'))
126 {
127 cp++;
128 }
129
130 if ((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength) {
131 return cp;
132 } else {
133 return NULL;
134 }
135}
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c
deleted file mode 100644
index 7a97c7440b30..000000000000
--- a/arch/ppc/syslib/qspan_pci.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/*
2 * QSpan pci routines.
3 * Most 8xx boards use the QSpan PCI bridge. The config address register
4 * is located 0x500 from the base of the bridge control/status registers.
5 * The data register is located at 0x504.
6 * This is a two step operation. First, the address register is written,
7 * then the data register is read/written as required.
8 * I don't know what to do about interrupts (yet).
9 *
10 * The RPX Classic implementation shares a chip select for normal
11 * PCI access and QSpan control register addresses. The selection is
12 * further selected by a bit setting in a board control register.
13 * Although it should happen, we disable interrupts during this operation
14 * to make sure some driver doesn't accidentally access the PCI while
15 * we have switched the chip select.
16 */
17
18#include <linux/kernel.h>
19#include <linux/pci.h>
20#include <linux/delay.h>
21#include <linux/string.h>
22#include <linux/init.h>
23
24#include <asm/io.h>
25#include <asm/mpc8xx.h>
26#include <asm/system.h>
27#include <asm/machdep.h>
28#include <asm/pci-bridge.h>
29
30
31/*
32 * This blows......
33 * When reading the configuration space, if something does not respond
34 * the bus times out and we get a machine check interrupt. So, the
35 * good ol' exception tables come to mind to trap it and return some
36 * value.
37 *
38 * On an error we just return a -1, since that is what the caller wants
39 * returned if nothing is present. I copied this from __get_user_asm,
40 * with the only difference of returning -1 instead of EFAULT.
41 * There is an associated hack in the machine check trap code.
42 *
43 * The QSPAN is also a big endian device, that is it makes the PCI
44 * look big endian to us. This presents a problem for the Linux PCI
45 * functions, which assume little endian. For example, we see the
46 * first 32-bit word like this:
47 * ------------------------
48 * | Device ID | Vendor ID |
49 * ------------------------
50 * If we read/write as a double word, that's OK. But in our world,
51 * when read as a word, device ID is at location 0, not location 2 as
52 * the little endian PCI would believe. We have to switch bits in
53 * the PCI addresses given to us to get the data to/from the correct
54 * byte lanes.
55 *
56 * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
57 * It always forces the MS bit to zero. Therefore, dev_fn values
58 * greater than 128 are returned as "no device found" errors.
59 *
60 * The QSPAN can only perform long word (32-bit) configuration cycles.
61 * The "offset" must have the two LS bits set to zero. Read operations
62 * require we read the entire word and then sort out what should be
63 * returned. Write operations other than long word require that we
64 * read the long word, update the proper word or byte, then write the
65 * entire long word back.
66 *
67 * PCI Bridge hack. We assume (correctly) that bus 0 is the primary
68 * PCI bus from the QSPAN. If we are called with a bus number other
69 * than zero, we create a Type 1 configuration access that a downstream
70 * PCI bridge will interpret.
71 */
72
73#define __get_qspan_pci_config(x, addr, op) \
74 __asm__ __volatile__( \
75 "1: "op" %0,0(%1)\n" \
76 " eieio\n" \
77 "2:\n" \
78 ".section .fixup,\"ax\"\n" \
79 "3: li %0,-1\n" \
80 " b 2b\n" \
81 ".section __ex_table,\"a\"\n" \
82 " .align 2\n" \
83 " .long 1b,3b\n" \
84 ".text" \
85 : "=r"(x) : "r"(addr) : " %0")
86
87#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500))
88#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504))
89
90#define mk_config_addr(bus, dev, offset) \
91 (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
92
93#define mk_config_type1(bus, dev, offset) \
94 mk_config_addr(bus, dev, offset) | 1;
95
96static DEFINE_SPINLOCK(pcibios_lock);
97
98int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
99 unsigned char offset, unsigned char *val)
100{
101 uint temp;
102 u_char *cp;
103#ifdef CONFIG_RPXCLASSIC
104 unsigned long flags;
105#endif
106
107 if ((bus > 7) || (dev_fn > 127)) {
108 *val = 0xff;
109 return PCIBIOS_DEVICE_NOT_FOUND;
110 }
111
112#ifdef CONFIG_RPXCLASSIC
113 /* disable interrupts */
114 spin_lock_irqsave(&pcibios_lock, flags);
115 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
116 eieio();
117#endif
118
119 if (bus == 0)
120 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
121 else
122 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
123 __get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
124
125#ifdef CONFIG_RPXCLASSIC
126 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
127 eieio();
128 spin_unlock_irqrestore(&pcibios_lock, flags);
129#endif
130
131 offset ^= 0x03;
132 cp = ((u_char *)&temp) + (offset & 0x03);
133 *val = *cp;
134 return PCIBIOS_SUCCESSFUL;
135}
136
137int qspan_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
138 unsigned char offset, unsigned short *val)
139{
140 uint temp;
141 ushort *sp;
142#ifdef CONFIG_RPXCLASSIC
143 unsigned long flags;
144#endif
145
146 if ((bus > 7) || (dev_fn > 127)) {
147 *val = 0xffff;
148 return PCIBIOS_DEVICE_NOT_FOUND;
149 }
150
151#ifdef CONFIG_RPXCLASSIC
152 /* disable interrupts */
153 spin_lock_irqsave(&pcibios_lock, flags);
154 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
155 eieio();
156#endif
157
158 if (bus == 0)
159 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
160 else
161 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
162 __get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
163 offset ^= 0x02;
164
165#ifdef CONFIG_RPXCLASSIC
166 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
167 eieio();
168 spin_unlock_irqrestore(&pcibios_lock, flags);
169#endif
170
171 sp = ((ushort *)&temp) + ((offset >> 1) & 1);
172 *val = *sp;
173 return PCIBIOS_SUCCESSFUL;
174}
175
176int qspan_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
177 unsigned char offset, unsigned int *val)
178{
179#ifdef CONFIG_RPXCLASSIC
180 unsigned long flags;
181#endif
182
183 if ((bus > 7) || (dev_fn > 127)) {
184 *val = 0xffffffff;
185 return PCIBIOS_DEVICE_NOT_FOUND;
186 }
187
188#ifdef CONFIG_RPXCLASSIC
189 /* disable interrupts */
190 spin_lock_irqsave(&pcibios_lock, flags);
191 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
192 eieio();
193#endif
194
195 if (bus == 0)
196 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
197 else
198 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
199 __get_qspan_pci_config(*val, QS_CONFIG_DATA, "lwz");
200
201#ifdef CONFIG_RPXCLASSIC
202 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
203 eieio();
204 spin_unlock_irqrestore(&pcibios_lock, flags);
205#endif
206
207 return PCIBIOS_SUCCESSFUL;
208}
209
210int qspan_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
211 unsigned char offset, unsigned char val)
212{
213 uint temp;
214 u_char *cp;
215#ifdef CONFIG_RPXCLASSIC
216 unsigned long flags;
217#endif
218
219 if ((bus > 7) || (dev_fn > 127))
220 return PCIBIOS_DEVICE_NOT_FOUND;
221
222 qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
223
224 offset ^= 0x03;
225 cp = ((u_char *)&temp) + (offset & 0x03);
226 *cp = val;
227
228#ifdef CONFIG_RPXCLASSIC
229 /* disable interrupts */
230 spin_lock_irqsave(&pcibios_lock, flags);
231 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
232 eieio();
233#endif
234
235 if (bus == 0)
236 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
237 else
238 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
239 *QS_CONFIG_DATA = temp;
240
241#ifdef CONFIG_RPXCLASSIC
242 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
243 eieio();
244 spin_unlock_irqrestore(&pcibios_lock, flags);
245#endif
246
247 return PCIBIOS_SUCCESSFUL;
248}
249
250int qspan_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
251 unsigned char offset, unsigned short val)
252{
253 uint temp;
254 ushort *sp;
255#ifdef CONFIG_RPXCLASSIC
256 unsigned long flags;
257#endif
258
259 if ((bus > 7) || (dev_fn > 127))
260 return PCIBIOS_DEVICE_NOT_FOUND;
261
262 qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
263
264 offset ^= 0x02;
265 sp = ((ushort *)&temp) + ((offset >> 1) & 1);
266 *sp = val;
267
268#ifdef CONFIG_RPXCLASSIC
269 /* disable interrupts */
270 spin_lock_irqsave(&pcibios_lock, flags);
271 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
272 eieio();
273#endif
274
275 if (bus == 0)
276 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
277 else
278 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
279 *QS_CONFIG_DATA = temp;
280
281#ifdef CONFIG_RPXCLASSIC
282 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
283 eieio();
284 spin_unlock_irqrestore(&pcibios_lock, flags);
285#endif
286
287 return PCIBIOS_SUCCESSFUL;
288}
289
290int qspan_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
291 unsigned char offset, unsigned int val)
292{
293#ifdef CONFIG_RPXCLASSIC
294 unsigned long flags;
295#endif
296
297 if ((bus > 7) || (dev_fn > 127))
298 return PCIBIOS_DEVICE_NOT_FOUND;
299
300#ifdef CONFIG_RPXCLASSIC
301 /* disable interrupts */
302 spin_lock_irqsave(&pcibios_lock, flags);
303 *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
304 eieio();
305#endif
306
307 if (bus == 0)
308 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
309 else
310 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
311 *(unsigned int *)QS_CONFIG_DATA = val;
312
313#ifdef CONFIG_RPXCLASSIC
314 *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
315 eieio();
316 spin_unlock_irqrestore(&pcibios_lock, flags);
317#endif
318
319 return PCIBIOS_SUCCESSFUL;
320}
321
322int qspan_pcibios_find_device(unsigned short vendor, unsigned short dev_id,
323 unsigned short index, unsigned char *bus_ptr,
324 unsigned char *dev_fn_ptr)
325{
326 int num, devfn;
327 unsigned int x, vendev;
328
329 if (vendor == 0xffff)
330 return PCIBIOS_BAD_VENDOR_ID;
331 vendev = (dev_id << 16) + vendor;
332 num = 0;
333 for (devfn = 0; devfn < 32; devfn++) {
334 qspan_pcibios_read_config_dword(0, devfn<<3, PCI_VENDOR_ID, &x);
335 if (x == vendev) {
336 if (index == num) {
337 *bus_ptr = 0;
338 *dev_fn_ptr = devfn<<3;
339 return PCIBIOS_SUCCESSFUL;
340 }
341 ++num;
342 }
343 }
344 return PCIBIOS_DEVICE_NOT_FOUND;
345}
346
347int qspan_pcibios_find_class(unsigned int class_code, unsigned short index,
348 unsigned char *bus_ptr, unsigned char *dev_fn_ptr)
349{
350 int devnr, x, num;
351
352 num = 0;
353 for (devnr = 0; devnr < 32; devnr++) {
354 qspan_pcibios_read_config_dword(0, devnr<<3, PCI_CLASS_REVISION, &x);
355 if ((x>>8) == class_code) {
356 if (index == num) {
357 *bus_ptr = 0;
358 *dev_fn_ptr = devnr<<3;
359 return PCIBIOS_SUCCESSFUL;
360 }
361 ++num;
362 }
363 }
364 return PCIBIOS_DEVICE_NOT_FOUND;
365}
366
367void __init
368m8xx_pcibios_fixup(void)
369{
370 /* Lots to do here, all board and configuration specific. */
371}
372
373void __init
374m8xx_setup_pci_ptrs(void)
375{
376 set_config_access_method(qspan);
377
378 ppc_md.pcibios_fixup = m8xx_pcibios_fixup;
379}
380
diff --git a/arch/ppc/syslib/todc_time.c b/arch/ppc/syslib/todc_time.c
deleted file mode 100644
index a8168b8e5683..000000000000
--- a/arch/ppc/syslib/todc_time.c
+++ /dev/null
@@ -1,511 +0,0 @@
1/*
2 * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
3 * Real Time Clocks/Timekeepers.
4 *
5 * Author: Mark A. Greer
6 * mgreer@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#include <linux/errno.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/time.h>
17#include <linux/timex.h>
18#include <linux/bcd.h>
19#include <linux/mc146818rtc.h>
20
21#include <asm/machdep.h>
22#include <asm/io.h>
23#include <asm/time.h>
24#include <asm/todc.h>
25
26/*
27 * Depending on the hardware on your board and your board design, the
28 * RTC/NVRAM may be accessed either directly (like normal memory) or via
29 * address/data registers. If your board uses the direct method, set
30 * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and
31 * 'nvram_as1' NULL. If your board uses address/data regs to access nvram,
32 * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the
33 * address of the upper byte (leave NULL if using mc146818), and set
34 * 'nvram_data' to the address of the 8-bit data register.
35 *
36 * In order to break the assumption that the RTC and NVRAM are accessed by
37 * the same mechanism, you need to explicitly set 'ppc_md.rtc_read_val' and
38 * 'ppc_md.rtc_write_val', otherwise the values of 'ppc_md.rtc_read_val'
39 * and 'ppc_md.rtc_write_val' will be used.
40 *
41 * Note: Even though the documentation for the various RTC chips say that it
42 * take up to a second before it starts updating once the 'R' bit is
43 * cleared, they always seem to update even though we bang on it many
44 * times a second. This is true, except for the Dallas Semi 1746/1747
45 * (possibly others). Those chips seem to have a real problem whenever
46 * we set the 'R' bit before reading them, they basically stop counting.
47 * --MAG
48 */
49
50/*
51 * 'todc_info' should be initialized in your *_setup.c file to
52 * point to a fully initialized 'todc_info_t' structure.
53 * This structure holds all the register offsets for your particular
54 * TODC/RTC chip.
55 * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you.
56 */
57
58#ifdef RTC_FREQ_SELECT
59#undef RTC_FREQ_SELECT
60#define RTC_FREQ_SELECT control_b /* Register A */
61#endif
62
63#ifdef RTC_CONTROL
64#undef RTC_CONTROL
65#define RTC_CONTROL control_a /* Register B */
66#endif
67
68#ifdef RTC_INTR_FLAGS
69#undef RTC_INTR_FLAGS
70#define RTC_INTR_FLAGS watchdog /* Register C */
71#endif
72
73#ifdef RTC_VALID
74#undef RTC_VALID
75#define RTC_VALID interrupts /* Register D */
76#endif
77
78/* Access routines when RTC accessed directly (like normal memory) */
79u_char
80todc_direct_read_val(int addr)
81{
82 return readb((void __iomem *)(todc_info->nvram_data + addr));
83}
84
85void
86todc_direct_write_val(int addr, unsigned char val)
87{
88 writeb(val, (void __iomem *)(todc_info->nvram_data + addr));
89 return;
90}
91
92/* Access routines for accessing m48txx type chips via addr/data regs */
93u_char
94todc_m48txx_read_val(int addr)
95{
96 outb(addr, todc_info->nvram_as0);
97 outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
98 return inb(todc_info->nvram_data);
99}
100
101void
102todc_m48txx_write_val(int addr, unsigned char val)
103{
104 outb(addr, todc_info->nvram_as0);
105 outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
106 outb(val, todc_info->nvram_data);
107 return;
108}
109
110/* Access routines for accessing mc146818 type chips via addr/data regs */
111u_char
112todc_mc146818_read_val(int addr)
113{
114 outb_p(addr, todc_info->nvram_as0);
115 return inb_p(todc_info->nvram_data);
116}
117
118void
119todc_mc146818_write_val(int addr, unsigned char val)
120{
121 outb_p(addr, todc_info->nvram_as0);
122 outb_p(val, todc_info->nvram_data);
123}
124
125
126/*
127 * Routines to make RTC chips with NVRAM buried behind an addr/data pair
128 * have the NVRAM and clock regs appear at the same level.
129 * The NVRAM will appear to start at addr 0 and the clock regs will appear
130 * to start immediately after the NVRAM (actually, start at offset
131 * todc_info->nvram_size).
132 */
133static inline u_char
134todc_read_val(int addr)
135{
136 u_char val;
137
138 if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
139 if (addr < todc_info->nvram_size) { /* NVRAM */
140 ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
141 val = ppc_md.rtc_read_val(todc_info->nvram_data_reg);
142 }
143 else { /* Clock Reg */
144 addr -= todc_info->nvram_size;
145 val = ppc_md.rtc_read_val(addr);
146 }
147 }
148 else {
149 val = ppc_md.rtc_read_val(addr);
150 }
151
152 return val;
153}
154
155static inline void
156todc_write_val(int addr, u_char val)
157{
158 if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
159 if (addr < todc_info->nvram_size) { /* NVRAM */
160 ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
161 ppc_md.rtc_write_val(todc_info->nvram_data_reg, val);
162 }
163 else { /* Clock Reg */
164 addr -= todc_info->nvram_size;
165 ppc_md.rtc_write_val(addr, val);
166 }
167 }
168 else {
169 ppc_md.rtc_write_val(addr, val);
170 }
171}
172
173/*
174 * TODC routines
175 *
176 * There is some ugly stuff in that there are assumptions for the mc146818.
177 *
178 * Assumptions:
179 * - todc_info->control_a has the offset as mc146818 Register B reg
180 * - todc_info->control_b has the offset as mc146818 Register A reg
181 * - m48txx control reg's write enable or 'W' bit is same as
182 * mc146818 Register B 'SET' bit (i.e., 0x80)
183 *
184 * These assumptions were made to make the code simpler.
185 */
186long __init
187todc_time_init(void)
188{
189 u_char cntl_b;
190
191 if (!ppc_md.rtc_read_val)
192 ppc_md.rtc_read_val = ppc_md.nvram_read_val;
193 if (!ppc_md.rtc_write_val)
194 ppc_md.rtc_write_val = ppc_md.nvram_write_val;
195
196 cntl_b = todc_read_val(todc_info->control_b);
197
198 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
199 if ((cntl_b & 0x70) != 0x20) {
200 printk(KERN_INFO "TODC %s %s\n",
201 "real-time-clock was stopped.",
202 "Now starting...");
203 cntl_b &= ~0x70;
204 cntl_b |= 0x20;
205 }
206
207 todc_write_val(todc_info->control_b, cntl_b);
208 } else if (todc_info->rtc_type == TODC_TYPE_DS17285) {
209 u_char mode;
210
211 mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A);
212 /* Make sure countdown clear is not set */
213 mode &= ~0x40;
214 /* Enable oscillator, extended register set */
215 mode |= 0x30;
216 todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode);
217
218 } else if (todc_info->rtc_type == TODC_TYPE_DS1501) {
219 u_char month;
220
221 todc_info->enable_read = TODC_DS1501_CNTL_B_TE;
222 todc_info->enable_write = TODC_DS1501_CNTL_B_TE;
223
224 month = todc_read_val(todc_info->month);
225
226 if ((month & 0x80) == 0x80) {
227 printk(KERN_INFO "TODC %s %s\n",
228 "real-time-clock was stopped.",
229 "Now starting...");
230 month &= ~0x80;
231 todc_write_val(todc_info->month, month);
232 }
233
234 cntl_b &= ~TODC_DS1501_CNTL_B_TE;
235 todc_write_val(todc_info->control_b, cntl_b);
236 } else { /* must be a m48txx type */
237 u_char cntl_a;
238
239 todc_info->enable_read = TODC_MK48TXX_CNTL_A_R;
240 todc_info->enable_write = TODC_MK48TXX_CNTL_A_W;
241
242 cntl_a = todc_read_val(todc_info->control_a);
243
244 /* Check & clear STOP bit in control B register */
245 if (cntl_b & TODC_MK48TXX_DAY_CB) {
246 printk(KERN_INFO "TODC %s %s\n",
247 "real-time-clock was stopped.",
248 "Now starting...");
249
250 cntl_a |= todc_info->enable_write;
251 cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */
252
253 todc_write_val(todc_info->control_a, cntl_a);
254 todc_write_val(todc_info->control_b, cntl_b);
255 }
256
257 /* Make sure READ & WRITE bits are cleared. */
258 cntl_a &= ~(todc_info->enable_write |
259 todc_info->enable_read);
260 todc_write_val(todc_info->control_a, cntl_a);
261 }
262
263 return 0;
264}
265
266/*
267 * There is some ugly stuff in that there are assumptions that for a mc146818,
268 * the todc_info->control_a has the offset of the mc146818 Register B reg and
269 * that the register'ss 'SET' bit is the same as the m48txx's write enable
270 * bit in the control register of the m48txx (i.e., 0x80).
271 *
272 * It was done to make the code look simpler.
273 */
274ulong
275todc_get_rtc_time(void)
276{
277 uint year = 0, mon = 0, day = 0, hour = 0, min = 0, sec = 0;
278 uint limit, i;
279 u_char save_control, uip = 0;
280
281 spin_lock(&rtc_lock);
282 save_control = todc_read_val(todc_info->control_a);
283
284 if (todc_info->rtc_type != TODC_TYPE_MC146818) {
285 limit = 1;
286
287 switch (todc_info->rtc_type) {
288 case TODC_TYPE_DS1553:
289 case TODC_TYPE_DS1557:
290 case TODC_TYPE_DS1743:
291 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
292 case TODC_TYPE_DS1747:
293 case TODC_TYPE_DS17285:
294 break;
295 default:
296 todc_write_val(todc_info->control_a,
297 (save_control | todc_info->enable_read));
298 }
299 }
300 else {
301 limit = 100000000;
302 }
303
304 for (i=0; i<limit; i++) {
305 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
306 uip = todc_read_val(todc_info->RTC_FREQ_SELECT);
307 }
308
309 sec = todc_read_val(todc_info->seconds) & 0x7f;
310 min = todc_read_val(todc_info->minutes) & 0x7f;
311 hour = todc_read_val(todc_info->hours) & 0x3f;
312 day = todc_read_val(todc_info->day_of_month) & 0x3f;
313 mon = todc_read_val(todc_info->month) & 0x1f;
314 year = todc_read_val(todc_info->year) & 0xff;
315
316 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
317 uip |= todc_read_val(todc_info->RTC_FREQ_SELECT);
318 if ((uip & RTC_UIP) == 0) break;
319 }
320 }
321
322 if (todc_info->rtc_type != TODC_TYPE_MC146818) {
323 switch (todc_info->rtc_type) {
324 case TODC_TYPE_DS1553:
325 case TODC_TYPE_DS1557:
326 case TODC_TYPE_DS1743:
327 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
328 case TODC_TYPE_DS1747:
329 case TODC_TYPE_DS17285:
330 break;
331 default:
332 save_control &= ~(todc_info->enable_read);
333 todc_write_val(todc_info->control_a,
334 save_control);
335 }
336 }
337 spin_unlock(&rtc_lock);
338
339 if ((todc_info->rtc_type != TODC_TYPE_MC146818) ||
340 ((save_control & RTC_DM_BINARY) == 0) ||
341 RTC_ALWAYS_BCD) {
342
343 BCD_TO_BIN(sec);
344 BCD_TO_BIN(min);
345 BCD_TO_BIN(hour);
346 BCD_TO_BIN(day);
347 BCD_TO_BIN(mon);
348 BCD_TO_BIN(year);
349 }
350
351 year = year + 1900;
352 if (year < 1970) {
353 year += 100;
354 }
355
356 return mktime(year, mon, day, hour, min, sec);
357}
358
359int
360todc_set_rtc_time(unsigned long nowtime)
361{
362 struct rtc_time tm;
363 u_char save_control, save_freq_select = 0;
364
365 spin_lock(&rtc_lock);
366 to_tm(nowtime, &tm);
367
368 save_control = todc_read_val(todc_info->control_a);
369
370 /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
371 todc_write_val(todc_info->control_a,
372 (save_control | todc_info->enable_write));
373 save_control &= ~(todc_info->enable_write); /* in case it was set */
374
375 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
376 save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT);
377 todc_write_val(todc_info->RTC_FREQ_SELECT,
378 save_freq_select | RTC_DIV_RESET2);
379 }
380
381
382 tm.tm_year = (tm.tm_year - 1900) % 100;
383
384 if ((todc_info->rtc_type != TODC_TYPE_MC146818) ||
385 ((save_control & RTC_DM_BINARY) == 0) ||
386 RTC_ALWAYS_BCD) {
387
388 BIN_TO_BCD(tm.tm_sec);
389 BIN_TO_BCD(tm.tm_min);
390 BIN_TO_BCD(tm.tm_hour);
391 BIN_TO_BCD(tm.tm_mon);
392 BIN_TO_BCD(tm.tm_mday);
393 BIN_TO_BCD(tm.tm_year);
394 }
395
396 todc_write_val(todc_info->seconds, tm.tm_sec);
397 todc_write_val(todc_info->minutes, tm.tm_min);
398 todc_write_val(todc_info->hours, tm.tm_hour);
399 todc_write_val(todc_info->month, tm.tm_mon);
400 todc_write_val(todc_info->day_of_month, tm.tm_mday);
401 todc_write_val(todc_info->year, tm.tm_year);
402
403 todc_write_val(todc_info->control_a, save_control);
404
405 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
406 todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select);
407 }
408 spin_unlock(&rtc_lock);
409
410 return 0;
411}
412
413/*
414 * Manipulates read bit to reliably read seconds at a high rate.
415 */
416static unsigned char __init todc_read_timereg(int addr)
417{
418 unsigned char save_control = 0, val;
419
420 switch (todc_info->rtc_type) {
421 case TODC_TYPE_DS1553:
422 case TODC_TYPE_DS1557:
423 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
424 case TODC_TYPE_DS1747:
425 case TODC_TYPE_DS17285:
426 case TODC_TYPE_MC146818:
427 break;
428 default:
429 save_control = todc_read_val(todc_info->control_a);
430 todc_write_val(todc_info->control_a,
431 (save_control | todc_info->enable_read));
432 }
433 val = todc_read_val(addr);
434
435 switch (todc_info->rtc_type) {
436 case TODC_TYPE_DS1553:
437 case TODC_TYPE_DS1557:
438 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
439 case TODC_TYPE_DS1747:
440 case TODC_TYPE_DS17285:
441 case TODC_TYPE_MC146818:
442 break;
443 default:
444 save_control &= ~(todc_info->enable_read);
445 todc_write_val(todc_info->control_a, save_control);
446 }
447
448 return val;
449}
450
451/*
452 * This was taken from prep_setup.c
453 * Use the NVRAM RTC to time a second to calibrate the decrementer.
454 */
455void __init
456todc_calibrate_decr(void)
457{
458 ulong freq;
459 ulong tbl, tbu;
460 long i, loop_count;
461 u_char sec;
462
463 todc_time_init();
464
465 /*
466 * Actually this is bad for precision, we should have a loop in
467 * which we only read the seconds counter. todc_read_val writes
468 * the address bytes on every call and this takes a lot of time.
469 * Perhaps an nvram_wait_change method returning a time
470 * stamp with a loop count as parameter would be the solution.
471 */
472 /*
473 * Need to make sure the tbl doesn't roll over so if tbu increments
474 * during this test, we need to do it again.
475 */
476 loop_count = 0;
477
478 sec = todc_read_timereg(todc_info->seconds) & 0x7f;
479
480 do {
481 tbu = get_tbu();
482
483 for (i = 0 ; i < 10000000 ; i++) {/* may take up to 1 second */
484 tbl = get_tbl();
485
486 if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) {
487 break;
488 }
489 }
490
491 sec = todc_read_timereg(todc_info->seconds) & 0x7f;
492
493 for (i = 0 ; i < 10000000 ; i++) { /* Should take 1 second */
494 freq = get_tbl();
495
496 if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) {
497 break;
498 }
499 }
500
501 freq -= tbl;
502 } while ((get_tbu() != tbu) && (++loop_count < 2));
503
504 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
505 freq/1000000, freq%1000000);
506
507 tb_ticks_per_jiffy = freq / HZ;
508 tb_to_us = mulhwu_scale_factor(freq, 1000000);
509
510 return;
511}
diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
deleted file mode 100644
index 7322781be1c6..000000000000
--- a/arch/ppc/syslib/virtex_devices.c
+++ /dev/null
@@ -1,276 +0,0 @@
1/*
2 * Virtex hard ppc405 core common device listing
3 *
4 * Copyright 2005-2007 Secret Lab Technologies Ltd.
5 * Copyright 2005 Freescale Semiconductor Inc.
6 * Copyright 2002-2004 MontaVista Software, 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#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/serial_8250.h>
18#include <syslib/virtex_devices.h>
19#include <platforms/4xx/xparameters/xparameters.h>
20#include <asm/io.h>
21
22/*
23 * UARTLITE: shortcut macro for single instance
24 */
25#define XPAR_UARTLITE(num) { \
26 .name = "uartlite", \
27 .id = num, \
28 .num_resources = 2, \
29 .resource = (struct resource[]) { \
30 { \
31 .start = XPAR_UARTLITE_##num##_BASEADDR + 3, \
32 .end = XPAR_UARTLITE_##num##_HIGHADDR, \
33 .flags = IORESOURCE_MEM, \
34 }, \
35 { \
36 .start = XPAR_INTC_0_UARTLITE_##num##_VEC_ID, \
37 .flags = IORESOURCE_IRQ, \
38 }, \
39 }, \
40}
41
42/*
43 * Full UART: shortcut macro for single instance + platform data structure
44 */
45#define XPAR_UART(num) { \
46 .mapbase = XPAR_UARTNS550_##num##_BASEADDR + 3, \
47 .irq = XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \
48 .iotype = UPIO_MEM, \
49 .uartclk = XPAR_UARTNS550_##num##_CLOCK_FREQ_HZ, \
50 .flags = UPF_BOOT_AUTOCONF, \
51 .regshift = 2, \
52}
53
54/*
55 * SystemACE: shortcut macro for single instance
56 */
57#define XPAR_SYSACE(num) { \
58 .name = "xsysace", \
59 .id = XPAR_SYSACE_##num##_DEVICE_ID, \
60 .num_resources = 2, \
61 .resource = (struct resource[]) { \
62 { \
63 .start = XPAR_SYSACE_##num##_BASEADDR, \
64 .end = XPAR_SYSACE_##num##_HIGHADDR, \
65 .flags = IORESOURCE_MEM, \
66 }, \
67 { \
68 .start = XPAR_INTC_0_SYSACE_##num##_VEC_ID, \
69 .flags = IORESOURCE_IRQ, \
70 }, \
71 }, \
72}
73
74/*
75 * ML300/ML403 Video Device: shortcut macro for single instance
76 */
77#define XPAR_TFT(num) { \
78 .name = "xilinxfb", \
79 .id = num, \
80 .num_resources = 1, \
81 .resource = (struct resource[]) { \
82 { \
83 .start = XPAR_TFT_##num##_BASEADDR, \
84 .end = XPAR_TFT_##num##_BASEADDR+7, \
85 .flags = IORESOURCE_IO, \
86 }, \
87 }, \
88}
89
90#define XPAR_AC97_CONTROLLER_REFERENCE(num) { \
91 .name = "ml403_ac97cr", \
92 .id = num, \
93 .num_resources = 3, \
94 .resource = (struct resource[]) { \
95 { \
96 .start = XPAR_OPB_AC97_CONTROLLER_REF_##num##_BASEADDR, \
97 .end = XPAR_OPB_AC97_CONTROLLER_REF_##num##_HIGHADDR, \
98 .flags = IORESOURCE_MEM, \
99 }, \
100 { \
101 .start = XPAR_INTC_0_AC97_CONTROLLER_REF_##num##_PLAYBACK_VEC_ID, \
102 .end = XPAR_INTC_0_AC97_CONTROLLER_REF_##num##_PLAYBACK_VEC_ID, \
103 .flags = IORESOURCE_IRQ, \
104 }, \
105 { \
106 .start = XPAR_INTC_0_AC97_CONTROLLER_REF_##num##_RECORD_VEC_ID, \
107 .end = XPAR_INTC_0_AC97_CONTROLLER_REF_##num##_RECORD_VEC_ID, \
108 .flags = IORESOURCE_IRQ, \
109 }, \
110 }, \
111}
112
113/* UART 8250 driver platform data table */
114struct plat_serial8250_port virtex_serial_platform_data[] = {
115#if defined(XPAR_UARTNS550_0_BASEADDR)
116 XPAR_UART(0),
117#endif
118#if defined(XPAR_UARTNS550_1_BASEADDR)
119 XPAR_UART(1),
120#endif
121#if defined(XPAR_UARTNS550_2_BASEADDR)
122 XPAR_UART(2),
123#endif
124#if defined(XPAR_UARTNS550_3_BASEADDR)
125 XPAR_UART(3),
126#endif
127#if defined(XPAR_UARTNS550_4_BASEADDR)
128 XPAR_UART(4),
129#endif
130#if defined(XPAR_UARTNS550_5_BASEADDR)
131 XPAR_UART(5),
132#endif
133#if defined(XPAR_UARTNS550_6_BASEADDR)
134 XPAR_UART(6),
135#endif
136#if defined(XPAR_UARTNS550_7_BASEADDR)
137 XPAR_UART(7),
138#endif
139 { }, /* terminated by empty record */
140};
141
142
143struct platform_device virtex_platform_devices[] = {
144 /* UARTLITE instances */
145#if defined(XPAR_UARTLITE_0_BASEADDR)
146 XPAR_UARTLITE(0),
147#endif
148#if defined(XPAR_UARTLITE_1_BASEADDR)
149 XPAR_UARTLITE(1),
150#endif
151#if defined(XPAR_UARTLITE_2_BASEADDR)
152 XPAR_UARTLITE(2),
153#endif
154#if defined(XPAR_UARTLITE_3_BASEADDR)
155 XPAR_UARTLITE(3),
156#endif
157#if defined(XPAR_UARTLITE_4_BASEADDR)
158 XPAR_UARTLITE(4),
159#endif
160#if defined(XPAR_UARTLITE_5_BASEADDR)
161 XPAR_UARTLITE(5),
162#endif
163#if defined(XPAR_UARTLITE_6_BASEADDR)
164 XPAR_UARTLITE(6),
165#endif
166#if defined(XPAR_UARTLITE_7_BASEADDR)
167 XPAR_UARTLITE(7),
168#endif
169
170 /* Full UART instances */
171#if defined(XPAR_UARTNS550_0_BASEADDR)
172 {
173 .name = "serial8250",
174 .id = 0,
175 .dev.platform_data = virtex_serial_platform_data,
176 },
177#endif
178
179 /* SystemACE instances */
180#if defined(XPAR_SYSACE_0_BASEADDR)
181 XPAR_SYSACE(0),
182#endif
183#if defined(XPAR_SYSACE_1_BASEADDR)
184 XPAR_SYSACE(1),
185#endif
186
187#if defined(XPAR_TFT_0_BASEADDR)
188 XPAR_TFT(0),
189#endif
190#if defined(XPAR_TFT_1_BASEADDR)
191 XPAR_TFT(1),
192#endif
193#if defined(XPAR_TFT_2_BASEADDR)
194 XPAR_TFT(2),
195#endif
196#if defined(XPAR_TFT_3_BASEADDR)
197 XPAR_TFT(3),
198#endif
199
200 /* AC97 Controller Reference instances */
201#if defined(XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR)
202 XPAR_AC97_CONTROLLER_REFERENCE(0),
203#endif
204#if defined(XPAR_OPB_AC97_CONTROLLER_REF_1_BASEADDR)
205 XPAR_AC97_CONTROLLER_REFERENCE(1),
206#endif
207};
208
209/* Early serial support functions */
210static void __init
211virtex_early_serial_init(int num, struct plat_serial8250_port *pdata)
212{
213#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
214 struct uart_port serial_req;
215
216 memset(&serial_req, 0, sizeof(serial_req));
217 serial_req.mapbase = pdata->mapbase;
218 serial_req.membase = pdata->membase;
219 serial_req.irq = pdata->irq;
220 serial_req.uartclk = pdata->uartclk;
221 serial_req.regshift = pdata->regshift;
222 serial_req.iotype = pdata->iotype;
223 serial_req.flags = pdata->flags;
224 gen550_init(num, &serial_req);
225#endif
226}
227
228void __init
229virtex_early_serial_map(void)
230{
231#ifdef CONFIG_SERIAL_8250
232 struct plat_serial8250_port *pdata;
233 int i = 0;
234
235 pdata = virtex_serial_platform_data;
236 while(pdata && pdata->flags) {
237 pdata->membase = ioremap(pdata->mapbase, 0x100);
238 virtex_early_serial_init(i, pdata);
239 pdata++;
240 i++;
241 }
242#endif /* CONFIG_SERIAL_8250 */
243}
244
245/*
246 * default fixup routine; do nothing and return success.
247 *
248 * Reimplement this routine in your custom board support file to
249 * override the default behaviour
250 */
251int __attribute__ ((weak))
252virtex_device_fixup(struct platform_device *dev)
253{
254 return 0;
255}
256
257static int __init virtex_init(void)
258{
259 struct platform_device *index = virtex_platform_devices;
260 unsigned int ret = 0;
261 int i;
262
263 for (i = 0; i < ARRAY_SIZE(virtex_platform_devices); i++, index++) {
264 if (virtex_device_fixup(index) != 0)
265 continue;
266
267 if (platform_device_register(index)) {
268 ret = 1;
269 printk(KERN_ERR "cannot register dev %s:%d\n",
270 index->name, index->id);
271 }
272 }
273 return ret;
274}
275
276subsys_initcall(virtex_init);
diff --git a/arch/ppc/syslib/virtex_devices.h b/arch/ppc/syslib/virtex_devices.h
deleted file mode 100644
index 6ebd9b4b8f1c..000000000000
--- a/arch/ppc/syslib/virtex_devices.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Common support header for virtex ppc405 platforms
3 *
4 * Copyright 2007 Secret Lab Technologies Ltd.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#ifndef __ASM_VIRTEX_DEVICES_H__
12#define __ASM_VIRTEX_DEVICES_H__
13
14#include <linux/platform_device.h>
15#include <linux/xilinxfb.h>
16
17void __init virtex_early_serial_map(void);
18
19/* Prototype for device fixup routine. Implement this routine in the
20 * board specific fixup code and the generic setup code will call it for
21 * each device is the platform device list.
22 *
23 * If the hook returns a non-zero value, then the device will not get
24 * registered with the platform bus
25 */
26int virtex_device_fixup(struct platform_device *dev);
27
28/* SPI Controller IP */
29struct xspi_platform_data {
30 s16 bus_num;
31 u16 num_chipselect;
32 u32 speed_hz;
33};
34
35#endif /* __ASM_VIRTEX_DEVICES_H__ */
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
deleted file mode 100644
index 3b82333e96d8..000000000000
--- a/arch/ppc/syslib/xilinx_pic.c
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Interrupt controller driver for Xilinx Virtex-II Pro.
3 *
4 * Author: MontaVista Software, Inc.
5 * source@mvista.com
6 *
7 * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <asm/io.h>
16#include <platforms/4xx/xparameters/xparameters.h>
17#include <asm/ibm4xx.h>
18#include <asm/machdep.h>
19
20/* No one else should require these constants, so define them locally here. */
21#define ISR 0 /* Interrupt Status Register */
22#define IPR 1 /* Interrupt Pending Register */
23#define IER 2 /* Interrupt Enable Register */
24#define IAR 3 /* Interrupt Acknowledge Register */
25#define SIE 4 /* Set Interrupt Enable bits */
26#define CIE 5 /* Clear Interrupt Enable bits */
27#define IVR 6 /* Interrupt Vector Register */
28#define MER 7 /* Master Enable Register */
29
30#if XPAR_XINTC_USE_DCR == 0
31static volatile u32 *intc;
32#define intc_out_be32(addr, mask) out_be32((addr), (mask))
33#define intc_in_be32(addr) in_be32((addr))
34#else
35#define intc XPAR_INTC_0_BASEADDR
36#define intc_out_be32(addr, mask) mtdcr((addr), (mask))
37#define intc_in_be32(addr) mfdcr((addr))
38#endif
39
40static void
41xilinx_intc_enable(unsigned int irq)
42{
43 unsigned long mask = (0x00000001 << (irq & 31));
44 pr_debug("enable: %d\n", irq);
45 intc_out_be32(intc + SIE, mask);
46}
47
48static void
49xilinx_intc_disable(unsigned int irq)
50{
51 unsigned long mask = (0x00000001 << (irq & 31));
52 pr_debug("disable: %d\n", irq);
53 intc_out_be32(intc + CIE, mask);
54}
55
56static void
57xilinx_intc_disable_and_ack(unsigned int irq)
58{
59 unsigned long mask = (0x00000001 << (irq & 31));
60 pr_debug("disable_and_ack: %d\n", irq);
61 intc_out_be32(intc + CIE, mask);
62 if (!(irq_desc[irq].status & IRQ_LEVEL))
63 intc_out_be32(intc + IAR, mask); /* ack edge triggered intr */
64}
65
66static void
67xilinx_intc_end(unsigned int irq)
68{
69 unsigned long mask = (0x00000001 << (irq & 31));
70
71 pr_debug("end: %d\n", irq);
72 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
73 intc_out_be32(intc + SIE, mask);
74 /* ack level sensitive intr */
75 if (irq_desc[irq].status & IRQ_LEVEL)
76 intc_out_be32(intc + IAR, mask);
77 }
78}
79
80static struct hw_interrupt_type xilinx_intc = {
81 .typename = "Xilinx Interrupt Controller",
82 .enable = xilinx_intc_enable,
83 .disable = xilinx_intc_disable,
84 .ack = xilinx_intc_disable_and_ack,
85 .end = xilinx_intc_end,
86};
87
88int
89xilinx_pic_get_irq(void)
90{
91 int irq;
92
93 /*
94 * NOTE: This function is the one that needs to be improved in
95 * order to handle multiple interrupt controllers. It currently
96 * is hardcoded to check for interrupts only on the first INTC.
97 */
98
99 irq = intc_in_be32(intc + IVR);
100 if (irq != -1)
101 irq = irq;
102
103 pr_debug("get_irq: %d\n", irq);
104
105 return (irq);
106}
107
108void __init
109ppc4xx_pic_init(void)
110{
111 int i;
112
113 /*
114 * NOTE: The assumption here is that NR_IRQS is 32 or less
115 * (NR_IRQS is 32 for PowerPC 405 cores by default).
116 */
117#if (NR_IRQS > 32)
118#error NR_IRQS > 32 not supported
119#endif
120
121#if XPAR_XINTC_USE_DCR == 0
122 intc = ioremap(XPAR_INTC_0_BASEADDR, 32);
123
124 printk(KERN_INFO "Xilinx INTC #0 at 0x%08lX mapped to 0x%08lX\n",
125 (unsigned long) XPAR_INTC_0_BASEADDR, (unsigned long) intc);
126#else
127 printk(KERN_INFO "Xilinx INTC #0 at 0x%08lX (DCR)\n",
128 (unsigned long) XPAR_INTC_0_BASEADDR);
129#endif
130
131 /*
132 * Disable all external interrupts until they are
133 * explicitly requested.
134 */
135 intc_out_be32(intc + IER, 0);
136
137 /* Acknowledge any pending interrupts just in case. */
138 intc_out_be32(intc + IAR, ~(u32) 0);
139
140 /* Turn on the Master Enable. */
141 intc_out_be32(intc + MER, 0x3UL);
142
143 ppc_md.get_irq = xilinx_pic_get_irq;
144
145 for (i = 0; i < NR_IRQS; ++i) {
146 irq_desc[i].chip = &xilinx_intc;
147
148 if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i))
149 irq_desc[i].status &= ~IRQ_LEVEL;
150 else
151 irq_desc[i].status |= IRQ_LEVEL;
152 }
153}