diff options
Diffstat (limited to 'arch/ppc/syslib')
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 | |||
5 | CFLAGS_prom_init.o += -fPIC | ||
6 | CFLAGS_btext.o += -fPIC | ||
7 | |||
8 | wdt-mpc8xx-$(CONFIG_8xx_WDT) += m8xx_wdt.o | ||
9 | |||
10 | obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o | ||
11 | obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o | ||
12 | obj-$(CONFIG_PPC_OCP) += ocp.o | ||
13 | obj-$(CONFIG_IBM_OCP) += ibm_ocp.o | ||
14 | obj-$(CONFIG_44x) += ibm44x_common.o | ||
15 | obj-$(CONFIG_440EP) += ibm440gx_common.o | ||
16 | obj-$(CONFIG_440GP) += ibm440gp_common.o | ||
17 | obj-$(CONFIG_440GX) += ibm440gx_common.o | ||
18 | obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o | ||
19 | obj-$(CONFIG_440SPE) += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o | ||
20 | ifeq ($(CONFIG_4xx),y) | ||
21 | ifeq ($(CONFIG_XILINX_VIRTEX),y) | ||
22 | obj-$(CONFIG_40x) += xilinx_pic.o | ||
23 | obj-y += virtex_devices.o | ||
24 | else | ||
25 | ifeq ($(CONFIG_403),y) | ||
26 | obj-$(CONFIG_40x) += ppc403_pic.o | ||
27 | else | ||
28 | obj-$(CONFIG_40x) += ppc4xx_pic.o | ||
29 | endif | ||
30 | endif | ||
31 | obj-$(CONFIG_44x) += ppc4xx_pic.o | ||
32 | obj-$(CONFIG_40x) += ppc4xx_setup.o | ||
33 | obj-$(CONFIG_GEN_RTC) += todc_time.o | ||
34 | obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o | ||
35 | obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o | ||
36 | ifeq ($(CONFIG_40x),y) | ||
37 | obj-$(CONFIG_PCI) += pci_auto.o ppc405_pci.o | ||
38 | endif | ||
39 | endif | ||
40 | obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ | ||
41 | ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o | ||
42 | obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o | ||
43 | obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o | ||
44 | obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o | ||
45 | obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o | ||
46 | obj-$(CONFIG_EBONY) += pci_auto.o todc_time.o | ||
47 | obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o | ||
48 | obj-$(CONFIG_EV64360) += todc_time.o | ||
49 | obj-$(CONFIG_CHESTNUT) += mv64360_pic.o pci_auto.o | ||
50 | obj-$(CONFIG_GT64260) += gt64260_pic.o | ||
51 | obj-$(CONFIG_LOPEC) += pci_auto.o todc_time.o | ||
52 | obj-$(CONFIG_HDPU) += pci_auto.o | ||
53 | obj-$(CONFIG_LUAN) += pci_auto.o todc_time.o | ||
54 | obj-$(CONFIG_YUCCA) += pci_auto.o todc_time.o | ||
55 | obj-$(CONFIG_KATANA) += pci_auto.o | ||
56 | obj-$(CONFIG_MV64360) += mv64360_pic.o | ||
57 | obj-$(CONFIG_MV64X60) += mv64x60.o mv64x60_win.o | ||
58 | obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o \ | ||
59 | pci_auto.o hawk_common.o | ||
60 | obj-$(CONFIG_OCOTEA) += pci_auto.o todc_time.o | ||
61 | obj-$(CONFIG_PAL4) += cpc700_pic.o | ||
62 | obj-$(CONFIG_POWERPMC250) += pci_auto.o | ||
63 | obj-$(CONFIG_PPLUS) += hawk_common.o open_pic.o \ | ||
64 | todc_time.o pci_auto.o | ||
65 | obj-$(CONFIG_PRPMC750) += open_pic.o pci_auto.o \ | ||
66 | hawk_common.o | ||
67 | obj-$(CONFIG_HARRIER) += harrier.o | ||
68 | obj-$(CONFIG_PRPMC800) += open_pic.o pci_auto.o | ||
69 | obj-$(CONFIG_RADSTONE_PPC7D) += pci_auto.o | ||
70 | obj-$(CONFIG_SANDPOINT) += pci_auto.o todc_time.o | ||
71 | obj-$(CONFIG_SBC82xx) += todc_time.o | ||
72 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o pci_auto.o \ | ||
73 | todc_time.o | ||
74 | obj-$(CONFIG_TAISHAN) += pci_auto.o | ||
75 | obj-$(CONFIG_8260) += m8260_setup.o pq2_devices.o pq2_sys.o \ | ||
76 | ppc_sys.o | ||
77 | obj-$(CONFIG_PCI_8260) += m82xx_pci.o pci_auto.o | ||
78 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o | ||
79 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o | ||
80 | ifeq ($(CONFIG_PPC_GEN550),y) | ||
81 | obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o | ||
82 | obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o | ||
83 | endif | ||
84 | ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y) | ||
85 | obj-$(CONFIG_SERIAL_TEXT_DEBUG) += mv64x60_dbg.o | ||
86 | endif | ||
87 | obj-$(CONFIG_BOOTX_TEXT) += btext.o | ||
88 | obj-$(CONFIG_MPC10X_BRIDGE) += mpc10x_common.o ppc_sys.o | ||
89 | obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o | ||
90 | obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_setup.o mpc52xx_pic.o \ | ||
91 | mpc52xx_sys.o mpc52xx_devices.o ppc_sys.o | ||
92 | ifeq ($(CONFIG_PPC_MPC52xx),y) | ||
93 | obj-$(CONFIG_PCI) += mpc52xx_pci.o | ||
94 | endif | ||
95 | |||
96 | obj-$(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 | ||
24 | static void scrollscreen(void); | ||
25 | #endif | ||
26 | |||
27 | static void draw_byte(unsigned char c, long locX, long locY); | ||
28 | static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb); | ||
29 | static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb); | ||
30 | static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb); | ||
31 | |||
32 | static int g_loc_X; | ||
33 | static int g_loc_Y; | ||
34 | static int g_max_loc_X; | ||
35 | static int g_max_loc_Y; | ||
36 | |||
37 | unsigned long disp_BAT[2] __initdata = {0, 0}; | ||
38 | |||
39 | #define cmapsz (16*256) | ||
40 | |||
41 | static unsigned char vga_font[cmapsz]; | ||
42 | |||
43 | int boot_text_mapped; | ||
44 | int force_printk_to_btext = 0; | ||
45 | |||
46 | boot_infos_t disp_bi; | ||
47 | |||
48 | extern 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 | */ | ||
65 | void __init | ||
66 | btext_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 | |||
76 | void __init | ||
77 | btext_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 | */ | ||
126 | void __init | ||
127 | btext_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 | */ | ||
158 | void __init | ||
159 | btext_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 | |||
189 | void | ||
190 | map_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) */ | ||
212 | static unsigned char * BTEXT | ||
213 | calc_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 */ | ||
226 | void | ||
227 | btext_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 | |||
257 | void 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 | |||
279 | void 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 | ||
299 | static BTEXT void | ||
300 | scrollscreen(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 | |||
334 | void 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 | |||
382 | void BTEXT | ||
383 | btext_drawstring(const char *c) | ||
384 | { | ||
385 | if (!boot_text_mapped) | ||
386 | return; | ||
387 | while (*c) | ||
388 | btext_drawchar(*c++); | ||
389 | } | ||
390 | |||
391 | void BTEXT | ||
392 | btext_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 | |||
409 | static void BTEXT | ||
410 | draw_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 | |||
432 | static 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 | |||
451 | static unsigned long expand_bits_16[4] BTDATA = { | ||
452 | 0x00000000, | ||
453 | 0x0000ffff, | ||
454 | 0xffff0000, | ||
455 | 0xffffffff | ||
456 | }; | ||
457 | |||
458 | |||
459 | static void BTEXT | ||
460 | draw_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 | |||
481 | static void BTEXT | ||
482 | draw_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 | |||
500 | static void BTEXT | ||
501 | draw_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 | |||
517 | static unsigned char vga_font[cmapsz] BTDATA = { | ||
518 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
519 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, | ||
520 | 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, | ||
521 | 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
522 | 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, | ||
523 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, | ||
524 | 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, | ||
525 | 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
526 | 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, | ||
527 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, | ||
528 | 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | ||
529 | 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
530 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, | ||
531 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, | ||
532 | 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, | ||
533 | 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, | ||
534 | 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, | ||
535 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, | ||
536 | 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, | ||
537 | 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, | ||
538 | 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, | ||
539 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, | ||
540 | 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, | ||
541 | 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, | ||
542 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, | ||
543 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
544 | 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, | ||
545 | 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, | ||
546 | 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, | ||
547 | 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
548 | 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, | ||
549 | 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
550 | 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
551 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
552 | 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
553 | 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
554 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, | ||
555 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, | ||
556 | 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
557 | 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
558 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, | ||
559 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, | ||
560 | 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
561 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
562 | 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, | ||
563 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, | ||
564 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, | ||
565 | 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, | ||
566 | 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, | ||
567 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, | ||
568 | 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, | ||
569 | 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
570 | 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
571 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, | ||
572 | 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, | ||
573 | 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, | ||
574 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, | ||
575 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, | ||
576 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
577 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, | ||
578 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
579 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
580 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
581 | 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, | ||
582 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, | ||
583 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, | ||
584 | 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
585 | 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
586 | 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, | ||
587 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, | ||
588 | 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, | ||
589 | 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
590 | 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
591 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, | ||
592 | 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
593 | 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
594 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, | ||
595 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, | ||
596 | 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
597 | 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, | ||
598 | 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, | ||
599 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, | ||
600 | 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, | ||
601 | 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, | ||
602 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, | ||
603 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, | ||
604 | 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, | ||
605 | 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
606 | 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, | ||
607 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, | ||
608 | 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, | ||
609 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, | ||
610 | 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, | ||
611 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, | ||
612 | 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, | ||
613 | 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, | ||
614 | 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
615 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
616 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, | ||
617 | 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, | ||
618 | 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, | ||
619 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, | ||
620 | 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, | ||
621 | 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, | ||
622 | 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, | ||
623 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
624 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, | ||
625 | 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, | ||
626 | 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, | ||
627 | 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, | ||
628 | 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, | ||
629 | 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
630 | 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
631 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
632 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, | ||
633 | 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
634 | 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, | ||
635 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, | ||
636 | 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, | ||
637 | 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
638 | 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, | ||
639 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, | ||
640 | 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
641 | 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, | ||
642 | 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, | ||
643 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
644 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
645 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, | ||
646 | 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
647 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, | ||
648 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
649 | 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
650 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, | ||
651 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, | ||
652 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
653 | 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
654 | 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, | ||
655 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, | ||
656 | 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
657 | 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, | ||
658 | 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
659 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, | ||
660 | 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, | ||
661 | 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, | ||
662 | 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
663 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, | ||
664 | 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
665 | 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
666 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
667 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, | ||
668 | 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
669 | 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, | ||
670 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, | ||
671 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, | ||
672 | 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, | ||
673 | 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, | ||
674 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
675 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, | ||
676 | 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
677 | 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
678 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, | ||
679 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, | ||
680 | 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
681 | 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
682 | 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, | ||
683 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, | ||
684 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, | ||
685 | 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, | ||
686 | 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
687 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, | ||
688 | 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, | ||
689 | 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, | ||
690 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
691 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, | ||
692 | 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, | ||
693 | 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
694 | 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, | ||
695 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, | ||
696 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, | ||
697 | 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
698 | 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, | ||
699 | 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, | ||
700 | 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, | ||
701 | 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
702 | 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, | ||
703 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, | ||
704 | 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, | ||
705 | 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
706 | 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, | ||
707 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, | ||
708 | 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, | ||
709 | 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
710 | 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, | ||
711 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, | ||
712 | 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, | ||
713 | 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, | ||
714 | 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
715 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, | ||
716 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, | ||
717 | 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, | ||
718 | 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, | ||
719 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, | ||
720 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, | ||
721 | 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, | ||
722 | 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
723 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, | ||
724 | 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, | ||
725 | 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
726 | 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, | ||
727 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, | ||
728 | 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, | ||
729 | 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, | ||
730 | 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
731 | 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, | ||
732 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, | ||
733 | 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, | ||
734 | 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, | ||
735 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, | ||
736 | 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, | ||
737 | 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, | ||
738 | 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, | ||
739 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, | ||
740 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, | ||
741 | 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
742 | 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, | ||
743 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, | ||
744 | 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
745 | 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
746 | 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, | ||
747 | 0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, | ||
748 | 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, | ||
749 | 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, | ||
750 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, | ||
751 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, | ||
752 | 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, | ||
753 | 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, | ||
754 | 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, | ||
755 | 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, | ||
756 | 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, | ||
757 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
758 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, | ||
759 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, | ||
760 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, | ||
761 | 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
762 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, | ||
763 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, | ||
764 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, | ||
765 | 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
766 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
767 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, | ||
768 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
769 | 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
770 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, | ||
771 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, | ||
772 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
773 | 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
774 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, | ||
775 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, | ||
776 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
777 | 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
778 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
779 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, | ||
780 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, | ||
781 | 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
782 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
783 | 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, | ||
784 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
785 | 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
786 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, | ||
787 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, | ||
788 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
789 | 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
790 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, | ||
791 | 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, | ||
792 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, | ||
793 | 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
794 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, | ||
795 | 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, | ||
796 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
797 | 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
798 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, | ||
799 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, | ||
800 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, | ||
801 | 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
802 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, | ||
803 | 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, | ||
804 | 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
805 | 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, | ||
806 | 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, | ||
807 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, | ||
808 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
809 | 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
810 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
811 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, | ||
812 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, | ||
813 | 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, | ||
814 | 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, | ||
815 | 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, | ||
816 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
817 | 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, | ||
818 | 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, | ||
819 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, | ||
820 | 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
821 | 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, | ||
822 | 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, | ||
823 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, | ||
824 | 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
825 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, | ||
826 | 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
827 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, | ||
828 | 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, | ||
829 | 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, | ||
830 | 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, | ||
831 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, | ||
832 | 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
833 | 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
834 | 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, | ||
835 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, | ||
836 | 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, | ||
837 | 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, | ||
838 | 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, | ||
839 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, | ||
840 | 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, | ||
841 | 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, | ||
842 | 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, | ||
843 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, | ||
844 | 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, | ||
845 | 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, | ||
846 | 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, | ||
847 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, | ||
848 | 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, | ||
849 | 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
850 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, | ||
851 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
852 | 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, | ||
853 | 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, | ||
854 | 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
855 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, | ||
856 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
857 | 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
858 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
859 | 0x00, 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 | */ | ||
90 | extern struct hw_interrupt_type cpc700_pic; | ||
91 | extern unsigned int cpc700_irq_assigns[32][2]; | ||
92 | |||
93 | extern void __init cpc700_init_IRQ(void); | ||
94 | extern 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 | |||
27 | static void | ||
28 | cpc700_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 | |||
53 | static void | ||
54 | cpc700_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 | |||
70 | static void | ||
71 | cpc700_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 | |||
90 | static 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 | ||
98 | cpc700_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 | ||
129 | cpc700_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 | */ | ||
160 | int | ||
161 | cpc700_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 | |||
33 | static void cpm2_dpinit(void); | ||
34 | cpm_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 | */ | ||
39 | cpm2_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 | |||
45 | void | ||
46 | cpm2_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 | */ | ||
75 | void | ||
76 | cpm_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 | */ | ||
96 | void | ||
97 | cpm2_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 | */ | ||
117 | static spinlock_t cpm_dpmem_lock; | ||
118 | /* 16 blocks should be enough to satisfy all requests | ||
119 | * until the memory subsystem goes up... */ | ||
120 | static rh_block_t cpm_boot_dpmem_rh_block[16]; | ||
121 | static rh_info_t cpm_dpmem_info; | ||
122 | |||
123 | static 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 | */ | ||
144 | unsigned 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 | } | ||
156 | EXPORT_SYMBOL(cpm_dpalloc); | ||
157 | |||
158 | int 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 | } | ||
169 | EXPORT_SYMBOL(cpm_dpfree); | ||
170 | |||
171 | /* not sure if this is ever needed */ | ||
172 | unsigned 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 | } | ||
184 | EXPORT_SYMBOL(cpm_dpalloc_fixed); | ||
185 | |||
186 | void cpm_dpdump(void) | ||
187 | { | ||
188 | rh_dump(&cpm_dpmem_info); | ||
189 | } | ||
190 | EXPORT_SYMBOL(cpm_dpdump); | ||
191 | |||
192 | void *cpm_dpram_addr(unsigned long offset) | ||
193 | { | ||
194 | return (void *)&cpm2_immr->im_dprambase[offset]; | ||
195 | } | ||
196 | EXPORT_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 | |||
24 | static 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]) */ | ||
37 | static 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 | |||
48 | static 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 | |||
63 | static 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 | |||
78 | static 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 | |||
95 | static 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 | |||
118 | static 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 | |||
126 | int 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 | |||
141 | void 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 | |||
4 | extern int cpm2_get_irq(void); | ||
5 | |||
6 | extern 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 | |||
12 | extern void gen550_progress(char *, unsigned short); | ||
13 | extern void gen550_init(int, struct uart_port *); | ||
14 | extern 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 | |||
34 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | ||
35 | SERIAL_PORT_DFNS /* defined in <asm/serial.h> */ | ||
36 | }; | ||
37 | |||
38 | static void (*serial_outb)(unsigned long, unsigned char); | ||
39 | static unsigned long (*serial_inb)(unsigned long); | ||
40 | |||
41 | static int shift; | ||
42 | |||
43 | unsigned long direct_inb(unsigned long addr) | ||
44 | { | ||
45 | return readb((void __iomem *)addr); | ||
46 | } | ||
47 | |||
48 | void direct_outb(unsigned long addr, unsigned char val) | ||
49 | { | ||
50 | writeb(val, (void __iomem *)addr); | ||
51 | } | ||
52 | |||
53 | unsigned long io_inb(unsigned long port) | ||
54 | { | ||
55 | return inb(port); | ||
56 | } | ||
57 | |||
58 | void io_outb(unsigned long port, unsigned char val) | ||
59 | { | ||
60 | outb(val, port); | ||
61 | } | ||
62 | |||
63 | unsigned 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 | |||
125 | void | ||
126 | serial_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 | |||
133 | unsigned char | ||
134 | serial_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 | |||
141 | int | ||
142 | serial_tstc(unsigned long com_port) | ||
143 | { | ||
144 | return ((serial_inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0); | ||
145 | } | ||
146 | |||
147 | void | ||
148 | serial_close(unsigned long com_port) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | void | ||
153 | gen550_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 | ||
163 | void | ||
164 | gen550_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 | |||
23 | extern unsigned long serial_init(int, void *); | ||
24 | extern unsigned long serial_getc(unsigned long); | ||
25 | extern 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 | |||
39 | static volatile unsigned int kgdb_debugport; | ||
40 | |||
41 | void 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 | |||
49 | int 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 | |||
57 | void kgdb_interruptible(int enable) | ||
58 | { | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | void 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 | */ | ||
76 | void | ||
77 | gen550_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 | |||
53 | static void gt64260_unmask_irq(unsigned int); | ||
54 | static void gt64260_mask_irq(unsigned int); | ||
55 | |||
56 | /* ========================== local declarations =========================== */ | ||
57 | |||
58 | struct 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 | |||
66 | u32 gt64260_irq_base = 0; /* GT64260 handles the next 96 IRQs from here */ | ||
67 | |||
68 | static 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 | */ | ||
78 | void __init | ||
79 | gt64260_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 = >64260_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 | */ | ||
118 | int | ||
119 | gt64260_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 | */ | ||
174 | static void | ||
175 | gt64260_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 | */ | ||
207 | static void | ||
208 | gt64260_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 | |||
227 | static irqreturn_t | ||
228 | gt64260_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 | |||
248 | static irqreturn_t | ||
249 | gt64260_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 | |||
289 | static int __init | ||
290 | gt64260_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 | |||
323 | arch_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 | */ | ||
39 | void __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 | |||
81 | void __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 | |||
94 | void __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 | */ | ||
123 | int __init | ||
124 | harrier_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 | |||
219 | static 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 | */ | ||
245 | unsigned 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 | */ | ||
44 | int __init | ||
45 | hawk_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 | |||
185 | static 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 | |||
196 | static 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 | |||
206 | static 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 | */ | ||
226 | unsigned long __init | ||
227 | hawk_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 | |||
287 | int __init | ||
288 | hawk_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 | |||
15 | static volatile void __iomem *pci_intack; /* RO, gives us the irq vector */ | ||
16 | |||
17 | static unsigned char cached_8259[2] = { 0xff, 0xff }; | ||
18 | #define cached_A1 (cached_8259[0]) | ||
19 | #define cached_21 (cached_8259[1]) | ||
20 | |||
21 | static DEFINE_SPINLOCK(i8259_lock); | ||
22 | |||
23 | static 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 | */ | ||
31 | int 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 | |||
72 | static 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 | |||
93 | static void i8259_set_irq_mask(int irq_nr) | ||
94 | { | ||
95 | outb(cached_A1,0xA1); | ||
96 | outb(cached_21,0x21); | ||
97 | } | ||
98 | |||
99 | static 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 | |||
113 | static 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 | |||
127 | static 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 | |||
135 | static struct resource pic1_iores = { | ||
136 | .name = "8259 (master)", | ||
137 | .start = 0x20, | ||
138 | .end = 0x21, | ||
139 | .flags = IORESOURCE_BUSY, | ||
140 | }; | ||
141 | |||
142 | static struct resource pic2_iores = { | ||
143 | .name = "8259 (slave)", | ||
144 | .start = 0xa0, | ||
145 | .end = 0xa1, | ||
146 | .flags = IORESOURCE_BUSY, | ||
147 | }; | ||
148 | |||
149 | static struct resource pic_edgectrl_iores = { | ||
150 | .name = "8259 edge control", | ||
151 | .start = 0x4d0, | ||
152 | .end = 0x4d1, | ||
153 | .flags = IORESOURCE_BUSY, | ||
154 | }; | ||
155 | |||
156 | static 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 | */ | ||
168 | void __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 | */ | ||
24 | void __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 | */ | ||
27 | void 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 | */ | ||
23 | static inline u32 __fix_zero(u32 v, u32 def){ | ||
24 | return v ? v : def; | ||
25 | } | ||
26 | |||
27 | void __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 { | ||
79 | bypass: | ||
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 */ | ||
114 | static 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 | |||
122 | static 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 */ | ||
147 | void __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 */ | ||
205 | void __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 | |||
231 | void __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 | |||
245 | int __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 | |||
250 | void __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 | |||
255 | void __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 | |||
264 | int 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 | |||
284 | void __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 | */ | ||
28 | void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk, | ||
29 | unsigned int ser_clk) __init; | ||
30 | |||
31 | /* common 440GX platform init */ | ||
32 | void 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 */ | ||
36 | void ibm440gx_l2c_enable(void) __init; | ||
37 | |||
38 | /* Disable L2 cache */ | ||
39 | void ibm440gx_l2c_disable(void) __init; | ||
40 | |||
41 | /* Enable/disable L2 cache for a particular chip revision */ | ||
42 | void ibm440gx_l2c_setup(struct ibm44x_clocks*) __init; | ||
43 | |||
44 | /* Get Ethernet Group */ | ||
45 | int ibm440gx_get_eth_grp(void) __init; | ||
46 | |||
47 | /* Set Ethernet Group */ | ||
48 | void ibm440gx_set_eth_grp(int group) __init; | ||
49 | |||
50 | /* Enable TAH devices */ | ||
51 | void ibm440gx_tah_enable(void) __init; | ||
52 | |||
53 | /* Add L2C info to /proc/cpuinfo */ | ||
54 | int 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 | */ | ||
29 | unsigned 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 | |||
19 | extern 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 */ | ||
34 | bd_t __res; | ||
35 | |||
36 | phys_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 | }; | ||
60 | EXPORT_SYMBOL(fixup_bigphys_addr); | ||
61 | |||
62 | void __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 | |||
78 | extern void abort(void); | ||
79 | |||
80 | static void ibm44x_restart(char *cmd) | ||
81 | { | ||
82 | local_irq_disable(); | ||
83 | abort(); | ||
84 | } | ||
85 | |||
86 | static void ibm44x_power_off(void) | ||
87 | { | ||
88 | local_irq_disable(); | ||
89 | for(;;); | ||
90 | } | ||
91 | |||
92 | static 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 | */ | ||
101 | static 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 | |||
156 | void __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 */ | ||
213 | void 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 | */ | ||
22 | struct 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 */ | ||
37 | void 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 */ | ||
41 | void 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 | |||
5 | struct 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 | |||
10 | EXPORT_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 | |||
29 | static int | ||
30 | indirect_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 | |||
68 | static int | ||
69 | indirect_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 | |||
107 | static struct pci_ops indirect_pci_ops = | ||
108 | { | ||
109 | indirect_read_config, | ||
110 | indirect_write_config | ||
111 | }; | ||
112 | |||
113 | void __init | ||
114 | setup_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 | |||
122 | void __init | ||
123 | setup_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 */ | ||
39 | typedef 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 */ | ||
50 | static 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 | |||
81 | void 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 | */ | ||
125 | static void | ||
126 | idma_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 | */ | ||
177 | static void | ||
178 | idma_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 | */ | ||
223 | static void | ||
224 | idma_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 | } | ||
243 | EXPORT_SYMBOL(idma_pci9_init); | ||
244 | EXPORT_SYMBOL(idma_pci9_read); | ||
245 | EXPORT_SYMBOL(idma_pci9_read_le); | ||
246 | |||
247 | static 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)) | ||
259 | int 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 | |||
271 | int 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 | |||
283 | unsigned 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 | |||
295 | int 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 | |||
304 | int 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 | |||
313 | unsigned 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 | |||
322 | void 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 | |||
329 | void 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 | |||
336 | void 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 | |||
343 | void *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 | |||
354 | EXPORT_SYMBOL(readb); | ||
355 | EXPORT_SYMBOL(readw); | ||
356 | EXPORT_SYMBOL(readl); | ||
357 | EXPORT_SYMBOL(inb); | ||
358 | EXPORT_SYMBOL(inw); | ||
359 | EXPORT_SYMBOL(inl); | ||
360 | EXPORT_SYMBOL(insb); | ||
361 | EXPORT_SYMBOL(insw); | ||
362 | EXPORT_SYMBOL(insl); | ||
363 | EXPORT_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 | |||
379 | static 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 | |||
411 | static 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 | |||
443 | static struct pci_ops indirect_pci_ops = | ||
444 | { | ||
445 | .read = indirect_read_config, | ||
446 | .write = indirect_write_config, | ||
447 | }; | ||
448 | |||
449 | void | ||
450 | setup_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 | |||
32 | unsigned char __res[sizeof(bd_t)]; | ||
33 | |||
34 | extern void pq2_find_bridges(void); | ||
35 | extern void pq2pci_init_irq(void); | ||
36 | extern void idma_pci9_init(void); | ||
37 | |||
38 | /* Place-holder for board-specific init */ | ||
39 | void __attribute__ ((weak)) __init | ||
40 | m82xx_board_setup(void) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | static void __init | ||
45 | m8260_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 | */ | ||
73 | static void __init | ||
74 | m8260_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 | */ | ||
88 | static uint rtc_time; | ||
89 | |||
90 | static int | ||
91 | m8260_set_rtc_time(unsigned long time) | ||
92 | { | ||
93 | rtc_time = time; | ||
94 | |||
95 | return(0); | ||
96 | } | ||
97 | |||
98 | static unsigned long | ||
99 | m8260_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 | |||
111 | static void | ||
112 | m8260_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 | |||
130 | static void | ||
131 | m8260_halt(void) | ||
132 | { | ||
133 | local_irq_disable(); | ||
134 | while (1); | ||
135 | } | ||
136 | |||
137 | static void | ||
138 | m8260_power_off(void) | ||
139 | { | ||
140 | m8260_halt(); | ||
141 | } | ||
142 | |||
143 | static int | ||
144 | m8260_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 | */ | ||
169 | static void __init | ||
170 | m8260_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 | */ | ||
183 | static unsigned long __init | ||
184 | m8260_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 | */ | ||
196 | static void __init | ||
197 | m8260_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 */ | ||
210 | void __attribute__ ((weak)) __init | ||
211 | m82xx_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 | */ | ||
226 | void __init | ||
227 | platform_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 | |||
54 | static inline int | ||
55 | pq2pci_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 | |||
72 | static void | ||
73 | pq2pci_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 | |||
81 | static void | ||
82 | pq2pci_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 | |||
90 | static void | ||
91 | pq2pci_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 | |||
99 | static void | ||
100 | pq2pci_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 | |||
108 | struct 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 | |||
119 | static irqreturn_t | ||
120 | pq2pci_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 | |||
140 | static 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 | |||
148 | void | ||
149 | pq2pci_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 | |||
168 | static int | ||
169 | pq2pci_exclude_device(u_char bus, u_char devfn) | ||
170 | { | ||
171 | return PCIBIOS_SUCCESSFUL; | ||
172 | } | ||
173 | |||
174 | /* PCI bus configuration registers. | ||
175 | */ | ||
176 | static void | ||
177 | pq2ads_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 | |||
270 | void __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 | ||
85 | struct pci_controller; | ||
86 | extern 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 | */ | ||
68 | static 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 | |||
84 | static int m8xx_set_rtc_time(unsigned long time); | ||
85 | static unsigned long m8xx_get_rtc_time(void); | ||
86 | void m8xx_calibrate_decr(void); | ||
87 | |||
88 | unsigned char __res[sizeof(bd_t)]; | ||
89 | |||
90 | extern unsigned long find_available_memory(void); | ||
91 | extern void m8xx_cpm_reset(void); | ||
92 | extern void m8xx_wdt_handler_install(bd_t *bp); | ||
93 | extern void rpxfb_alloc_pages(void); | ||
94 | extern void cpm_interrupt_init(void); | ||
95 | |||
96 | void __attribute__ ((weak)) | ||
97 | board_init(void) | ||
98 | { | ||
99 | } | ||
100 | |||
101 | void __init | ||
102 | m8xx_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 | |||
147 | void | ||
148 | abort(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. */ | ||
160 | irqreturn_t timebase_interrupt(int irq, void * dev) | ||
161 | { | ||
162 | printk ("timebase_interrupt()\n"); | ||
163 | |||
164 | return IRQ_HANDLED; | ||
165 | } | ||
166 | |||
167 | static 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. */ | ||
174 | void __init __attribute__ ((weak)) | ||
175 | init_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 | */ | ||
189 | void __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 | */ | ||
256 | static int | ||
257 | m8xx_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 | |||
265 | static unsigned long | ||
266 | m8xx_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 | |||
272 | static void | ||
273 | m8xx_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 | |||
289 | static void | ||
290 | m8xx_power_off(void) | ||
291 | { | ||
292 | m8xx_restart(NULL); | ||
293 | } | ||
294 | |||
295 | static void | ||
296 | m8xx_halt(void) | ||
297 | { | ||
298 | m8xx_restart(NULL); | ||
299 | } | ||
300 | |||
301 | |||
302 | static int | ||
303 | m8xx_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 | ||
318 | static 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 | */ | ||
331 | static void __init | ||
332 | m8xx_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 | */ | ||
367 | static unsigned long __init | ||
368 | m8xx_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 | */ | ||
384 | static void __init | ||
385 | m8xx_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 | |||
418 | void __init | ||
419 | platform_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 | |||
21 | static int wdt_timeout; | ||
22 | int m8xx_has_internal_rtc = 0; | ||
23 | |||
24 | static irqreturn_t m8xx_wdt_interrupt(int, void *); | ||
25 | static struct irqaction m8xx_wdt_irqaction = { | ||
26 | .handler = m8xx_wdt_interrupt, | ||
27 | .name = "watchdog", | ||
28 | }; | ||
29 | |||
30 | void 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 | |||
38 | static 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 | |||
52 | void __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 | |||
83 | static void m8xx_wdt_timer_func(unsigned long data); | ||
84 | |||
85 | static struct timer_list m8xx_wdt_timer = | ||
86 | TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0); | ||
87 | |||
88 | void m8xx_wdt_stop_timer(void) | ||
89 | { | ||
90 | del_timer(&m8xx_wdt_timer); | ||
91 | } | ||
92 | |||
93 | void m8xx_wdt_install_timer(void) | ||
94 | { | ||
95 | m8xx_wdt_timer.expires = jiffies + (HZ/2); | ||
96 | add_timer(&m8xx_wdt_timer); | ||
97 | } | ||
98 | |||
99 | static void m8xx_wdt_timer_func(unsigned long data) | ||
100 | { | ||
101 | m8xx_wdt_reset(); | ||
102 | m8xx_wdt_install_timer(); | ||
103 | } | ||
104 | |||
105 | void __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 | |||
145 | int 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 | |||
12 | extern int m8xx_has_internal_rtc; | ||
13 | |||
14 | extern void m8xx_wdt_handler_install(bd_t * binfo); | ||
15 | extern int m8xx_wdt_get_timeout(void); | ||
16 | extern void m8xx_wdt_reset(void); | ||
17 | extern void m8xx_wdt_install_timer(void); | ||
18 | extern 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 | |||
55 | static struct fsl_i2c_platform_data mpc10x_i2c_pdata = { | ||
56 | .device_flags = 0, | ||
57 | }; | ||
58 | |||
59 | static 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 | }; | ||
67 | static 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 | |||
76 | struct 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 */ | ||
153 | struct ppc_sys_spec *cur_ppc_sys_spec; | ||
154 | struct 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 | */ | ||
196 | static 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 | |||
204 | static int __init mach_mpc10x_init(void) | ||
205 | { | ||
206 | ppc_sys_device_fixup = mach_mpc10x_fixup; | ||
207 | return 0; | ||
208 | } | ||
209 | postcore_initcall(mach_mpc10x_init); | ||
210 | |||
211 | /* Set resources to match bridge memory map */ | ||
212 | void __init | ||
213 | mpc10x_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 | */ | ||
257 | int __init | ||
258 | mpc10x_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) \ | ||
500 | static void \ | ||
501 | mpc10x_##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 | |||
510 | MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) | ||
511 | MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) | ||
512 | #if 0 /* Not used */ | ||
513 | MPC10X_PCI_OP(write, byte, u8, out_8, 3) | ||
514 | MPC10X_PCI_OP(read, word, u16 *, in_le16, 2) | ||
515 | MPC10X_PCI_OP(write, word, u16, out_le16, 2) | ||
516 | MPC10X_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 | */ | ||
524 | unsigned long __init | ||
525 | mpc10x_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 | |||
596 | int __init | ||
597 | mpc10x_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 | |||
618 | int __init | ||
619 | mpc10x_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 | ||
641 | void __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 | |||
21 | static u64 mpc52xx_dma_mask = 0xffffffffULL; | ||
22 | |||
23 | static 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 | |||
35 | struct 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 | |||
305 | static int __init mach_mpc52xx_fixup(struct platform_device *pdev) | ||
306 | { | ||
307 | ppc_sys_fixup_mem_resource(pdev, MPC52xx_MBAR); | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int __init mach_mpc52xx_init(void) | ||
312 | { | ||
313 | ppc_sys_device_fixup = mach_mpc52xx_fixup; | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | postcore_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 | |||
30 | static int | ||
31 | mpc52xx_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 | |||
83 | static int | ||
84 | mpc52xx_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 | |||
145 | static struct pci_ops mpc52xx_pci_ops = { | ||
146 | .read = mpc52xx_pci_read_config, | ||
147 | .write = mpc52xx_pci_write_config | ||
148 | }; | ||
149 | |||
150 | |||
151 | static void __init | ||
152 | mpc52xx_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 | |||
208 | static void | ||
209 | mpc52xx_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 | |||
234 | void __init | ||
235 | mpc52xx_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 | |||
102 | struct 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 | |||
33 | static struct mpc52xx_intr __iomem *intr; | ||
34 | static struct mpc52xx_sdma __iomem *sdma; | ||
35 | |||
36 | static void | ||
37 | mpc52xx_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 | |||
71 | static void | ||
72 | mpc52xx_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 | |||
106 | static void | ||
107 | mpc52xx_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 | |||
151 | static void | ||
152 | mpc52xx_ic_disable_and_ack(unsigned int irq) | ||
153 | { | ||
154 | mpc52xx_ic_disable(irq); | ||
155 | mpc52xx_ic_ack(irq); | ||
156 | } | ||
157 | |||
158 | static void | ||
159 | mpc52xx_ic_end(unsigned int irq) | ||
160 | { | ||
161 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
162 | mpc52xx_ic_enable(irq); | ||
163 | } | ||
164 | |||
165 | static 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 | |||
173 | void __init | ||
174 | mpc52xx_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 | |||
221 | int | ||
222 | mpc52xx_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 */ | ||
242 | peripheral: | ||
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 | |||
29 | extern bd_t __res; | ||
30 | |||
31 | static 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 | |||
38 | void | ||
39 | mpc52xx_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 | |||
53 | void | ||
54 | mpc52xx_halt(void) | ||
55 | { | ||
56 | local_irq_disable(); | ||
57 | |||
58 | while (1); | ||
59 | } | ||
60 | |||
61 | void | ||
62 | mpc52xx_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 | |||
71 | void __init | ||
72 | mpc52xx_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 | |||
84 | void __init | ||
85 | mpc52xx_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 | |||
100 | static void | ||
101 | mpc52xx_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 | |||
108 | void | ||
109 | mpc52xx_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 | |||
129 | unsigned long __init | ||
130 | mpc52xx_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 | |||
159 | void __init | ||
160 | mpc52xx_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 | |||
222 | void __init | ||
223 | mpc52xx_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 */ | ||
261 | unmap_regs: | ||
262 | if (cdm) iounmap(cdm); | ||
263 | if (xlb) iounmap(xlb); | ||
264 | } | ||
265 | |||
266 | |||
267 | int 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 | |||
280 | int 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 | |||
16 | struct ppc_sys_spec *cur_ppc_sys_spec; | ||
17 | struct 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 | |||
28 | struct 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 | |||
231 | static int __init mach_mpc8xx_fixup(struct platform_device *pdev) | ||
232 | { | ||
233 | ppc_sys_fixup_mem_resource (pdev, IMAP_ADDR); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int __init mach_mpc8xx_init(void) | ||
238 | { | ||
239 | ppc_sys_device_fixup = mach_mpc8xx_fixup; | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | postcore_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 | |||
19 | struct ppc_sys_spec *cur_ppc_sys_spec; | ||
20 | struct 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 | |||
55 | static void mv64360_unmask_irq(unsigned int); | ||
56 | static void mv64360_mask_irq(unsigned int); | ||
57 | static irqreturn_t mv64360_cpu_error_int_handler(int, void *); | ||
58 | static irqreturn_t mv64360_sram_error_int_handler(int, void *); | ||
59 | static irqreturn_t mv64360_pci_error_int_handler(int, void *); | ||
60 | |||
61 | /* ========================== local declarations =========================== */ | ||
62 | |||
63 | struct 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 | |||
76 | static struct mv64x60_handle bh; | ||
77 | |||
78 | u32 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 | */ | ||
97 | void __init | ||
98 | mv64360_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 | */ | ||
139 | int | ||
140 | mv64360_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 | */ | ||
210 | static void | ||
211 | mv64360_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 | */ | ||
252 | static void | ||
253 | mv64360_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 | |||
280 | static irqreturn_t | ||
281 | mv64360_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 | |||
301 | static irqreturn_t | ||
302 | mv64360_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 | |||
322 | static irqreturn_t | ||
323 | mv64360_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 | |||
370 | static int __init | ||
371 | mv64360_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 | |||
423 | arch_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 | |||
33 | u8 mv64x60_pci_exclude_bridge = 1; | ||
34 | DEFINE_SPINLOCK(mv64x60_lock); | ||
35 | |||
36 | static phys_addr_t mv64x60_bridge_pbase; | ||
37 | static void __iomem *mv64x60_bridge_vbase; | ||
38 | static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID; | ||
39 | static u32 mv64x60_bridge_rev; | ||
40 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
41 | static struct pci_controller sysfs_hose_a; | ||
42 | #endif | ||
43 | |||
44 | static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits); | ||
45 | static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits); | ||
46 | static void gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, | ||
47 | u32 window, u32 base); | ||
48 | static void gt64260_set_pci2regs_window(struct mv64x60_handle *bh, | ||
49 | struct pci_controller *hose, u32 bus, u32 base); | ||
50 | static u32 gt64260_is_enabled_32bit(struct mv64x60_handle *bh, u32 window); | ||
51 | static void gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window); | ||
52 | static void gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window); | ||
53 | static void gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window); | ||
54 | static void gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window); | ||
55 | static void gt64260_disable_all_windows(struct mv64x60_handle *bh, | ||
56 | struct mv64x60_setup_info *si); | ||
57 | static void gt64260a_chip_specific_init(struct mv64x60_handle *bh, | ||
58 | struct mv64x60_setup_info *si); | ||
59 | static void gt64260b_chip_specific_init(struct mv64x60_handle *bh, | ||
60 | struct mv64x60_setup_info *si); | ||
61 | |||
62 | static u32 mv64360_translate_size(u32 base, u32 size, u32 num_bits); | ||
63 | static u32 mv64360_untranslate_size(u32 base, u32 size, u32 num_bits); | ||
64 | static void mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, | ||
65 | u32 window, u32 base); | ||
66 | static void mv64360_set_pci2regs_window(struct mv64x60_handle *bh, | ||
67 | struct pci_controller *hose, u32 bus, u32 base); | ||
68 | static u32 mv64360_is_enabled_32bit(struct mv64x60_handle *bh, u32 window); | ||
69 | static void mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window); | ||
70 | static void mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window); | ||
71 | static void mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window); | ||
72 | static void mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window); | ||
73 | static void mv64360_disable_all_windows(struct mv64x60_handle *bh, | ||
74 | struct mv64x60_setup_info *si); | ||
75 | static void mv64360_config_io2mem_windows(struct mv64x60_handle *bh, | ||
76 | struct mv64x60_setup_info *si, | ||
77 | u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]); | ||
78 | static void mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base); | ||
79 | static void mv64360_chip_specific_init(struct mv64x60_handle *bh, | ||
80 | struct mv64x60_setup_info *si); | ||
81 | static 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 | */ | ||
89 | static 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 | |||
105 | static 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 | |||
121 | static 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 | |||
139 | static 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 | ||
165 | static 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 | |||
173 | static 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 | |||
191 | static 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 | |||
201 | static 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 | |||
219 | static 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 | |||
247 | static 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 | |||
257 | static 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 | |||
276 | static 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 | |||
304 | static 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) | ||
316 | static 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 | |||
326 | static 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 | ||
334 | static 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 | |||
343 | static struct mv643xx_eth_platform_data eth0_pd = { | ||
344 | .shared = &mv64x60_eth_shared_device; | ||
345 | .port_number = 0, | ||
346 | }; | ||
347 | |||
348 | static 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 = ð0_pd, | ||
355 | }, | ||
356 | }; | ||
357 | #endif | ||
358 | |||
359 | #ifdef CONFIG_MV643XX_ETH_1 | ||
360 | static 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 | |||
369 | static struct mv643xx_eth_platform_data eth1_pd = { | ||
370 | .shared = &mv64x60_eth_shared_device; | ||
371 | .port_number = 1, | ||
372 | }; | ||
373 | |||
374 | static 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 = ð1_pd, | ||
381 | }, | ||
382 | }; | ||
383 | #endif | ||
384 | |||
385 | #ifdef CONFIG_MV643XX_ETH_2 | ||
386 | static 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 | |||
395 | static struct mv643xx_eth_platform_data eth2_pd = { | ||
396 | .shared = &mv64x60_eth_shared_device; | ||
397 | .port_number = 2, | ||
398 | }; | ||
399 | |||
400 | static 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 = ð2_pd, | ||
407 | }, | ||
408 | }; | ||
409 | #endif | ||
410 | #endif | ||
411 | |||
412 | #ifdef CONFIG_I2C_MV64XXX | ||
413 | static 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 | |||
419 | static 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 | |||
435 | static 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 | ||
447 | static 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 | |||
452 | static 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 | |||
461 | static 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) | ||
473 | static struct mv64xxx_pdata mv64xxx_pdata = { | ||
474 | .hs_reg_valid = 0, | ||
475 | }; | ||
476 | |||
477 | static 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 | |||
486 | static 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 | ð0_device, | ||
497 | #endif | ||
498 | #ifdef CONFIG_MV643XX_ETH_1 | ||
499 | ð1_device, | ||
500 | #endif | ||
501 | #ifdef CONFIG_MV643XX_ETH_2 | ||
502 | ð2_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 | */ | ||
529 | int __init | ||
530 | mv64x60_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 | */ | ||
605 | void __init | ||
606 | mv64x60_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 | */ | ||
669 | void __init | ||
670 | mv64x60_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 | */ | ||
707 | void __init | ||
708 | mv64x60_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 | */ | ||
743 | void __init | ||
744 | mv64x60_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 | */ | ||
786 | void __init | ||
787 | mv64x60_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 | */ | ||
826 | u32 __init | ||
827 | mv64x60_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 | */ | ||
837 | u32 __init | ||
838 | mv64x60_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 | */ | ||
848 | u32 __init | ||
849 | mv64x60_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 | */ | ||
866 | int __init | ||
867 | mv64x60_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 | */ | ||
939 | int __init | ||
940 | mv64x60_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 = >64260a_ci; | ||
948 | break; | ||
949 | |||
950 | case MV64x60_TYPE_GT64260B: | ||
951 | bh->ci = >64260b_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 | */ | ||
978 | void __iomem * | ||
979 | mv64x60_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 | */ | ||
989 | u32 | ||
990 | mv64x60_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 | */ | ||
1000 | u32 | ||
1001 | mv64x60_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 | */ | ||
1020 | u32 __init | ||
1021 | mv64x60_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 | */ | ||
1045 | void __init | ||
1046 | mv64x60_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 | */ | ||
1067 | u32 __init | ||
1068 | mv64x60_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 | */ | ||
1091 | static 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 | |||
1096 | static 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 | |||
1101 | void __init | ||
1102 | mv64x60_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 | */ | ||
1133 | static 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 | |||
1140 | static 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 | |||
1147 | void __init | ||
1148 | mv64x60_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 | */ | ||
1187 | static 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 | |||
1194 | static 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 | |||
1201 | static 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 | |||
1208 | void __init | ||
1209 | mv64x60_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 | */ | ||
1263 | void __init | ||
1264 | mv64x60_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 | */ | ||
1278 | void __init | ||
1279 | mv64x60_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 | */ | ||
1319 | void __init | ||
1320 | mv64x60_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 | */ | ||
1362 | void __init | ||
1363 | mv64x60_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 | */ | ||
1409 | int | ||
1410 | mv64x60_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 | */ | ||
1439 | void __init | ||
1440 | mv64x60_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 | */ | ||
1464 | static int __init | ||
1465 | mv64x60_add_pds(void) | ||
1466 | { | ||
1467 | return platform_add_devices(mv64x60_pd_devs, | ||
1468 | ARRAY_SIZE(mv64x60_pd_devs)); | ||
1469 | } | ||
1470 | arch_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 | */ | ||
1484 | static u32 __init | ||
1485 | gt64260_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 | */ | ||
1495 | static u32 __init | ||
1496 | gt64260_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 | */ | ||
1512 | static u32 gt64260_reg_addrs[2][4] __initdata = { | ||
1513 | { 0x10, 0x14, 0x18, 0x1c }, { 0x90, 0x94, 0x98, 0x9c } | ||
1514 | }; | ||
1515 | |||
1516 | static void __init | ||
1517 | gt64260_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 | */ | ||
1537 | static u32 gt64260_offset[2] __initdata = {0x20, 0xa0}; | ||
1538 | |||
1539 | static void __init | ||
1540 | gt64260_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 | */ | ||
1561 | static u32 __init | ||
1562 | gt64260_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 | */ | ||
1585 | static void __init | ||
1586 | gt64260_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 | */ | ||
1597 | static void __init | ||
1598 | gt64260_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 | */ | ||
1620 | static void __init | ||
1621 | gt64260_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 | */ | ||
1632 | static void __init | ||
1633 | gt64260_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 | */ | ||
1657 | static void __init | ||
1658 | gt64260_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 | */ | ||
1741 | static void __init | ||
1742 | gt64260a_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 | */ | ||
1813 | static void __init | ||
1814 | gt64260b_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 | */ | ||
1900 | static u32 __init | ||
1901 | mv64360_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 | */ | ||
1911 | static u32 __init | ||
1912 | mv64360_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 | */ | ||
1929 | struct { | ||
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 | |||
1940 | static void __init | ||
1941 | mv64360_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 | */ | ||
1966 | static u32 mv64360_offset[2][2] __initdata = {{0x20, 0x24}, {0xa0, 0xa4}}; | ||
1967 | |||
1968 | static void __init | ||
1969 | mv64360_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 | */ | ||
1994 | static u32 __init | ||
1995 | mv64360_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 | */ | ||
2047 | static void __init | ||
2048 | mv64360_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 | */ | ||
2100 | static void __init | ||
2101 | mv64360_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 | */ | ||
2155 | static void __init | ||
2156 | mv64360_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 | */ | ||
2181 | static void __init | ||
2182 | mv64360_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 | */ | ||
2209 | static void __init | ||
2210 | mv64360_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 | */ | ||
2248 | static 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 | |||
2253 | static 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 | |||
2258 | static 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 | |||
2263 | static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] __initdata = | ||
2264 | { 0xe, 0xd, 0xb, 0x7 }; | ||
2265 | |||
2266 | static void __init | ||
2267 | mv64360_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 | */ | ||
2341 | static void __init | ||
2342 | mv64360_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 | */ | ||
2353 | static void __init | ||
2354 | mv64360_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 | */ | ||
2373 | static void __init | ||
2374 | mv64460_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 | |||
2394 | static DEFINE_MUTEX(mv64xxx_hs_lock); | ||
2395 | |||
2396 | static ssize_t | ||
2397 | mv64xxx_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 | |||
2419 | static ssize_t | ||
2420 | mv64xxx_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 | |||
2446 | static 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 */ | ||
2457 | static ssize_t | ||
2458 | mv64xxx_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 | } | ||
2475 | static DEVICE_ATTR(hs_reg_valid, S_IRUGO, mv64xxx_hs_reg_valid_show, NULL); | ||
2476 | |||
2477 | static int __init | ||
2478 | mv64xxx_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 | } | ||
2484 | subsys_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 | |||
32 | static struct mv64x60_handle mv64x60_dbg_bh; | ||
33 | |||
34 | void | ||
35 | mv64x60_progress_init(u32 base) | ||
36 | { | ||
37 | mv64x60_dbg_bh.v_base = base; | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | static void | ||
42 | mv64x60_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 | |||
56 | void | ||
57 | mv64x60_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 | |||
84 | void | ||
85 | putDebugChar(unsigned char c) | ||
86 | { | ||
87 | mv64x60_polled_putc(KGDB_PORT, (char)c); | ||
88 | } | ||
89 | |||
90 | int | ||
91 | getDebugChar(void) | ||
92 | { | ||
93 | unsigned char c; | ||
94 | |||
95 | while (!mv64x60_polled_getc(KGDB_PORT, &c)); | ||
96 | return (int)c; | ||
97 | } | ||
98 | |||
99 | void | ||
100 | putDebugString(char* str) | ||
101 | { | ||
102 | while (*str != '\0') { | ||
103 | putDebugChar(*str); | ||
104 | str++; | ||
105 | } | ||
106 | putDebugChar('\r'); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | void | ||
111 | kgdb_interruptible(int enable) | ||
112 | { | ||
113 | } | ||
114 | |||
115 | void | ||
116 | kgdb_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 | */ | ||
37 | struct 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 | |||
352 | struct 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 | |||
578 | struct 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 | |||
1013 | struct 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 | |||
56 | extern int mem_init_done; | ||
57 | |||
58 | extern struct ocp_def core_ocp[]; /* Static list of devices, provided by | ||
59 | CPU core */ | ||
60 | |||
61 | LIST_HEAD(ocp_devices); /* List of all OCP devices */ | ||
62 | DECLARE_RWSEM(ocp_devices_sem); /* Global semaphores for those lists */ | ||
63 | |||
64 | static int ocp_inited; | ||
65 | |||
66 | /* Sysfs support */ | ||
67 | #define OCP_DEF_ATTR(field, format_string) \ | ||
68 | static ssize_t \ | ||
69 | show_##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 | } \ | ||
75 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | ||
76 | |||
77 | OCP_DEF_ATTR(vendor, "0x%04x\n"); | ||
78 | OCP_DEF_ATTR(function, "0x%04x\n"); | ||
79 | OCP_DEF_ATTR(index, "0x%04x\n"); | ||
80 | #ifdef CONFIG_PTE_64BIT | ||
81 | OCP_DEF_ATTR(paddr, "0x%016Lx\n"); | ||
82 | #else | ||
83 | OCP_DEF_ATTR(paddr, "0x%08lx\n"); | ||
84 | #endif | ||
85 | OCP_DEF_ATTR(irq, "%d\n"); | ||
86 | OCP_DEF_ATTR(pm, "%lu\n"); | ||
87 | |||
88 | void 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 | */ | ||
111 | static int | ||
112 | ocp_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 | |||
132 | static int | ||
133 | ocp_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 | |||
152 | static int | ||
153 | ocp_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 | |||
165 | static int | ||
166 | ocp_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 | |||
176 | static int | ||
177 | ocp_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 | |||
187 | struct 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 | */ | ||
207 | int | ||
208 | ocp_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 | */ | ||
225 | void | ||
226 | ocp_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 */ | ||
236 | static 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 | */ | ||
272 | struct ocp_device * | ||
273 | ocp_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 | */ | ||
294 | struct ocp_def * | ||
295 | ocp_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 | */ | ||
323 | int | ||
324 | ocp_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 | */ | ||
365 | int | ||
366 | ocp_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 | */ | ||
394 | void | ||
395 | ocp_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 | */ | ||
416 | int __init | ||
417 | ocp_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 | */ | ||
437 | static int __init | ||
438 | ocp_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 | |||
477 | postcore_initcall(ocp_driver_init); | ||
478 | |||
479 | EXPORT_SYMBOL(ocp_bus_type); | ||
480 | EXPORT_SYMBOL(ocp_find_device); | ||
481 | EXPORT_SYMBOL(ocp_register_driver); | ||
482 | EXPORT_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 | |||
31 | void __iomem *OpenPIC_Addr; | ||
32 | static 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 | */ | ||
39 | u_int OpenPIC_NumInitSenses __initdata = 0; | ||
40 | u_char *OpenPIC_InitSenses __initdata = NULL; | ||
41 | extern int use_of_interrupt_tree; | ||
42 | |||
43 | static u_int NumProcessors; | ||
44 | static u_int NumSources; | ||
45 | static int open_pic_irq_offset; | ||
46 | static volatile OpenPIC_Source __iomem *ISR[NR_IRQS]; | ||
47 | static int openpic_cascade_irq = -1; | ||
48 | static int (*openpic_cascade_fn)(void); | ||
49 | |||
50 | /* Global Operations */ | ||
51 | static void openpic_disable_8259_pass_through(void); | ||
52 | static void openpic_set_spurious(u_int vector); | ||
53 | |||
54 | #ifdef CONFIG_SMP | ||
55 | /* Interprocessor Interrupts */ | ||
56 | static void openpic_initipi(u_int ipi, u_int pri, u_int vector); | ||
57 | static irqreturn_t openpic_ipi_action(int cpl, void *dev_id); | ||
58 | #endif | ||
59 | |||
60 | /* Timer Interrupts */ | ||
61 | static void openpic_inittimer(u_int timer, u_int pri, u_int vector); | ||
62 | static void openpic_maptimer(u_int timer, cpumask_t cpumask); | ||
63 | |||
64 | /* Interrupt Sources */ | ||
65 | static void openpic_enable_irq(u_int irq); | ||
66 | static void openpic_disable_irq(u_int irq); | ||
67 | static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, | ||
68 | int is_level); | ||
69 | static 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 | ||
76 | static void openpic_enable_8259_pass_through(void); | ||
77 | static u_int openpic_get_spurious(void); | ||
78 | static 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 | */ | ||
84 | static void openpic_end_irq(unsigned int irq_nr); | ||
85 | static void openpic_ack_irq(unsigned int irq_nr); | ||
86 | static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask); | ||
87 | |||
88 | struct 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 | ||
98 | static void openpic_end_ipi(unsigned int irq_nr); | ||
99 | static void openpic_ack_ipi(unsigned int irq_nr); | ||
100 | static void openpic_enable_ipi(unsigned int irq_nr); | ||
101 | static void openpic_disable_ipi(unsigned int irq_nr); | ||
102 | |||
103 | struct 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 | |||
161 | u_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 | |||
173 | static 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 | |||
182 | static 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 | |||
188 | inline 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 | |||
195 | static inline void openpic_clearfield(volatile u_int __iomem *addr, u_int mask) | ||
196 | { | ||
197 | openpic_writefield(addr, mask, 0); | ||
198 | } | ||
199 | |||
200 | static inline void openpic_setfield(volatile u_int __iomem *addr, u_int mask) | ||
201 | { | ||
202 | openpic_writefield(addr, mask, mask); | ||
203 | } | ||
204 | |||
205 | static 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 */ | ||
215 | u_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 */ | ||
227 | inline 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 | |||
233 | static inline void openpic_clearfield_IPI(volatile u_int __iomem *addr, u_int mask) | ||
234 | { | ||
235 | openpic_writefield_IPI(addr, mask, 0); | ||
236 | } | ||
237 | |||
238 | static inline void openpic_setfield_IPI(volatile u_int __iomem *addr, u_int mask) | ||
239 | { | ||
240 | openpic_writefield_IPI(addr, mask, mask); | ||
241 | } | ||
242 | |||
243 | static 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. */ | ||
259 | int epic_serial_mode = 1; | ||
260 | |||
261 | static 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 | |||
267 | static 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) | ||
275 | static 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 | |||
285 | void __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 | */ | ||
306 | void __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 | ||
428 | static 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 | |||
435 | static 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 | */ | ||
444 | u_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 | |||
455 | void 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 | |||
465 | u_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 | |||
474 | void 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 | ||
488 | static u_int openpic_get_spurious(void) | ||
489 | { | ||
490 | return openpic_readfield(&OpenPIC->Global.Spurious_Vector, | ||
491 | OPENPIC_VECTOR_MASK); | ||
492 | } | ||
493 | #endif /* notused */ | ||
494 | |||
495 | static 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 | */ | ||
506 | static 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 | |||
523 | void 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) | ||
529 | static 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 | */ | ||
540 | static 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 | */ | ||
556 | void 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 | |||
566 | void 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 | |||
606 | void __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 | */ | ||
639 | static 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 | */ | ||
652 | static 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 | */ | ||
663 | void __init | ||
664 | openpic_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 | */ | ||
678 | void __init | ||
679 | openpic_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 | |||
695 | static struct irqaction openpic_cascade_irqaction = { | ||
696 | .handler = no_action, | ||
697 | .flags = IRQF_DISABLED, | ||
698 | .mask = CPU_MASK_NONE, | ||
699 | }; | ||
700 | |||
701 | void __init | ||
702 | openpic_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 | */ | ||
718 | static 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 | |||
731 | static 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 | */ | ||
752 | void 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 | |||
760 | void 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 | */ | ||
777 | static void __init | ||
778 | openpic_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 | */ | ||
792 | static 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 | */ | ||
810 | static 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 | */ | ||
822 | static 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 | |||
833 | static 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 | |||
845 | static 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 | ||
851 | static void openpic_ack_ipi(unsigned int irq_nr) | ||
852 | { | ||
853 | openpic_eoi(); | ||
854 | } | ||
855 | |||
856 | static void openpic_end_ipi(unsigned int irq_nr) | ||
857 | { | ||
858 | } | ||
859 | |||
860 | static 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 | |||
868 | int | ||
869 | openpic_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 | ||
892 | void | ||
893 | smp_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 | |||
929 | static u32 save_ipi_vp[OPENPIC_NUM_IPI]; | ||
930 | static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES]; | ||
931 | static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES]; | ||
932 | static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS]; | ||
933 | static int openpic_suspend_count; | ||
934 | |||
935 | static 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 | |||
941 | static 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 | */ | ||
951 | int 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 | */ | ||
992 | int 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 | |||
1045 | static struct sysdev_class openpic_sysclass = { | ||
1046 | .name = "openpic", | ||
1047 | }; | ||
1048 | |||
1049 | static struct sys_device device_openpic = { | ||
1050 | .id = 0, | ||
1051 | .cls = &openpic_sysclass, | ||
1052 | }; | ||
1053 | |||
1054 | static struct sysdev_driver driver_openpic = { | ||
1055 | #ifdef CONFIG_PM | ||
1056 | .suspend = &openpic_suspend, | ||
1057 | .resume = &openpic_resume, | ||
1058 | #endif /* CONFIG_PM */ | ||
1059 | }; | ||
1060 | |||
1061 | static 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 | |||
1086 | subsys_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 | |||
31 | void *OpenPIC2_Addr; | ||
32 | static 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 | */ | ||
38 | extern u_int OpenPIC_NumInitSenses; | ||
39 | extern u_char *OpenPIC_InitSenses; | ||
40 | extern int use_of_interrupt_tree; | ||
41 | |||
42 | static u_int NumProcessors; | ||
43 | static u_int NumSources; | ||
44 | static int open_pic2_irq_offset; | ||
45 | static volatile OpenPIC_Source *ISR[NR_IRQS]; | ||
46 | |||
47 | /* Global Operations */ | ||
48 | static void openpic2_disable_8259_pass_through(void); | ||
49 | static void openpic2_set_priority(u_int pri); | ||
50 | static void openpic2_set_spurious(u_int vector); | ||
51 | |||
52 | /* Timer Interrupts */ | ||
53 | static void openpic2_inittimer(u_int timer, u_int pri, u_int vector); | ||
54 | static void openpic2_maptimer(u_int timer, u_int cpumask); | ||
55 | |||
56 | /* Interrupt Sources */ | ||
57 | static void openpic2_enable_irq(u_int irq); | ||
58 | static void openpic2_disable_irq(u_int irq); | ||
59 | static void openpic2_initirq(u_int irq, u_int pri, u_int vector, int polarity, | ||
60 | int is_level); | ||
61 | static 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 | */ | ||
67 | static void openpic2_reset(void); | ||
68 | #ifdef notused | ||
69 | static void openpic2_enable_8259_pass_through(void); | ||
70 | static u_int openpic2_get_priority(void); | ||
71 | static u_int openpic2_get_spurious(void); | ||
72 | static 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 | */ | ||
78 | static void openpic2_end_irq(unsigned int irq_nr); | ||
79 | static void openpic2_ack_irq(unsigned int irq_nr); | ||
80 | |||
81 | struct 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 | */ | ||
115 | extern 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 | |||
134 | static u_int openpic2_read(volatile u_int *addr) | ||
135 | { | ||
136 | u_int val; | ||
137 | |||
138 | val = in_be32(addr); | ||
139 | return val; | ||
140 | } | ||
141 | |||
142 | static inline void openpic2_write(volatile u_int *addr, u_int val) | ||
143 | { | ||
144 | out_be32(addr, val); | ||
145 | } | ||
146 | |||
147 | static 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 | |||
153 | inline 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 | |||
160 | static inline void openpic2_clearfield(volatile u_int *addr, u_int mask) | ||
161 | { | ||
162 | openpic2_writefield(addr, mask, 0); | ||
163 | } | ||
164 | |||
165 | static inline void openpic2_setfield(volatile u_int *addr, u_int mask) | ||
166 | { | ||
167 | openpic2_writefield(addr, mask, mask); | ||
168 | } | ||
169 | |||
170 | static 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 | |||
178 | static 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 | |||
187 | void __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 | */ | ||
208 | void __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 | ||
305 | static 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 */ | ||
313 | static 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 | */ | ||
322 | u_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 | |||
333 | void 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 | ||
344 | static 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 | |||
354 | static 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 | ||
368 | static 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 */ | ||
376 | static 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 | |||
383 | static 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 | */ | ||
392 | static 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 | */ | ||
405 | static 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 | */ | ||
418 | void __init | ||
419 | openpic2_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 | */ | ||
439 | static 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 | |||
452 | static 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 | */ | ||
477 | static void __init | ||
478 | openpic2_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 | */ | ||
492 | static 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 | */ | ||
507 | static 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 | */ | ||
519 | static void openpic2_ack_irq(unsigned int irq_nr) | ||
520 | { | ||
521 | openpic2_disable_irq(irq_nr); | ||
522 | openpic2_eoi(); | ||
523 | } | ||
524 | |||
525 | static 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 | |||
531 | int | ||
532 | openpic2_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 | |||
553 | static u32 save_ipi_vp[OPENPIC_NUM_IPI]; | ||
554 | static u32 save_irq_src_vp[OPENPIC_MAX_SOURCES]; | ||
555 | static u32 save_irq_src_dest[OPENPIC_MAX_SOURCES]; | ||
556 | static u32 save_cpu_task_pri[OPENPIC_MAX_PROCESSORS]; | ||
557 | static int openpic_suspend_count; | ||
558 | |||
559 | static 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 | |||
565 | static 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 | */ | ||
575 | int 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 | */ | ||
614 | int 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 */ | ||
668 | static struct sysdev_class openpic2_sysclass = { | ||
669 | .name = "openpic2", | ||
670 | }; | ||
671 | |||
672 | static struct sys_device device_openpic2 = { | ||
673 | .id = 0, | ||
674 | .cls = &openpic2_sysclass, | ||
675 | }; | ||
676 | |||
677 | static struct sysdev_driver driver_openpic2 = { | ||
678 | #ifdef CONFIG_PM | ||
679 | .suspend = &openpic2_suspend, | ||
680 | .resume = &openpic2_resume, | ||
681 | #endif /* CONFIG_PM */ | ||
682 | }; | ||
683 | |||
684 | static 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 | |||
709 | subsys_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 | |||
48 | typedef 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 | |||
58 | typedef 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 | |||
91 | typedef 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 | |||
103 | typedef 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 | |||
147 | typedef 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 | |||
157 | struct 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 | |||
38 | static int pciauto_upper_iospc; | ||
39 | static int pciauto_upper_memspc; | ||
40 | |||
41 | void __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 | |||
122 | void __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 | |||
184 | void __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 | |||
261 | void __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 | |||
306 | void __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 | |||
377 | int __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 | |||
33 | static void ppc403_aic_enable(unsigned int irq); | ||
34 | static void ppc403_aic_disable(unsigned int irq); | ||
35 | static void ppc403_aic_disable_and_ack(unsigned int irq); | ||
36 | |||
37 | static 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 | |||
44 | int | ||
45 | ppc403_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 | |||
71 | static void | ||
72 | ppc403_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 | |||
83 | static void | ||
84 | ppc403_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 | |||
95 | static void | ||
96 | ppc403_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 | |||
108 | void __init | ||
109 | ppc4xx_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 | |||
26 | extern void bios_fixup(struct pci_controller *, struct pcil0_regs *); | ||
27 | extern int ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, | ||
28 | unsigned char pin); | ||
29 | |||
30 | void | ||
31 | ppc405_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 | |||
67 | static int | ||
68 | ppc4xx_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 | |||
77 | void | ||
78 | ppc4xx_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 | |||
22 | static int | ||
23 | pcie_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 | |||
54 | static int | ||
55 | pcie_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 | |||
79 | static struct pci_ops pcie_pci_ops = | ||
80 | { | ||
81 | .read = pcie_read_config, | ||
82 | .write = pcie_write_config | ||
83 | }; | ||
84 | |||
85 | enum { | ||
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 | |||
95 | static 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 | */ | ||
154 | int 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 | |||
174 | int 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 | |||
374 | void 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 | |||
145 | int ppc440spe_init_pcie(void); | ||
146 | int ppc440spe_init_pcie_rootport(int port); | ||
147 | void 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 | |||
33 | ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS]; | ||
34 | |||
35 | int | ||
36 | ppc4xx_get_dma_status(void) | ||
37 | { | ||
38 | return (mfdcr(DCRN_DMASR)); | ||
39 | } | ||
40 | |||
41 | void | ||
42 | ppc4xx_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 | |||
56 | void | ||
57 | ppc4xx_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 | |||
71 | void | ||
72 | ppc4xx_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 | |||
142 | void | ||
143 | ppc4xx_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 | */ | ||
182 | int | ||
183 | ppc4xx_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 | */ | ||
203 | void | ||
204 | ppc4xx_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 | */ | ||
249 | int | ||
250 | ppc4xx_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 | */ | ||
270 | void | ||
271 | ppc4xx_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 | */ | ||
318 | void | ||
319 | ppc4xx_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 | */ | ||
376 | int | ||
377 | ppc4xx_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 | */ | ||
404 | int | ||
405 | ppc4xx_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 | */ | ||
433 | int | ||
434 | ppc4xx_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 | */ | ||
502 | int | ||
503 | ppc4xx_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 | */ | ||
556 | int | ||
557 | ppc4xx_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 | */ | ||
592 | unsigned int | ||
593 | ppc4xx_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 | */ | ||
610 | int | ||
611 | ppc4xx_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 | */ | ||
629 | int | ||
630 | ppc4xx_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 | */ | ||
648 | int | ||
649 | ppc4xx_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 | */ | ||
673 | int | ||
674 | ppc4xx_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 | |||
687 | EXPORT_SYMBOL(ppc4xx_enable_burst); | ||
688 | EXPORT_SYMBOL(ppc4xx_disable_burst); | ||
689 | EXPORT_SYMBOL(ppc4xx_set_burst_size); | ||
690 | #endif /* CONFIG_PPC4xx_EDMA */ | ||
691 | |||
692 | EXPORT_SYMBOL(ppc4xx_init_dma_channel); | ||
693 | EXPORT_SYMBOL(ppc4xx_get_channel_config); | ||
694 | EXPORT_SYMBOL(ppc4xx_set_channel_priority); | ||
695 | EXPORT_SYMBOL(ppc4xx_get_peripheral_width); | ||
696 | EXPORT_SYMBOL(dma_channels); | ||
697 | EXPORT_SYMBOL(ppc4xx_set_src_addr); | ||
698 | EXPORT_SYMBOL(ppc4xx_set_dst_addr); | ||
699 | EXPORT_SYMBOL(ppc4xx_set_dma_addr); | ||
700 | EXPORT_SYMBOL(ppc4xx_set_dma_addr2); | ||
701 | EXPORT_SYMBOL(ppc4xx_enable_dma); | ||
702 | EXPORT_SYMBOL(ppc4xx_disable_dma); | ||
703 | EXPORT_SYMBOL(ppc4xx_set_dma_mode); | ||
704 | EXPORT_SYMBOL(ppc4xx_set_dma_count); | ||
705 | EXPORT_SYMBOL(ppc4xx_get_dma_residue); | ||
706 | EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt); | ||
707 | EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt); | ||
708 | EXPORT_SYMBOL(ppc4xx_get_dma_status); | ||
709 | EXPORT_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 | */ | ||
30 | extern struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[NR_UICS] | ||
31 | __attribute__ ((weak)); | ||
32 | extern 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) \ | ||
41 | static 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 | \ | ||
50 | static 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 | \ | ||
57 | static 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 | \ | ||
66 | static 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); | ||
94 | UIC_HANDLERS(0); | ||
95 | UIC_HANDLERS(1); | ||
96 | UIC_HANDLERS(2); | ||
97 | UIC_HANDLERS(3); | ||
98 | |||
99 | static 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 | |||
112 | static 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); | ||
124 | UIC_HANDLERS(0); | ||
125 | UIC_HANDLERS(1); | ||
126 | UIC_HANDLERS(2); | ||
127 | |||
128 | static 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 | |||
141 | static 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); | ||
158 | UIC_HANDLERS(0); | ||
159 | UIC_HANDLERS(1); | ||
160 | |||
161 | static 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 | |||
170 | static 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 | ||
180 | UIC_HANDLERS(0); | ||
181 | |||
182 | static int ppc4xx_pic_get_irq(void) | ||
183 | { | ||
184 | u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0)); | ||
185 | return uic0 ? 32 - ffs(uic0) : -1; | ||
186 | } | ||
187 | |||
188 | static inline void ppc4xx_pic_impl_init(void) | ||
189 | { | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | static 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 | |||
209 | static 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 | |||
215 | void __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 */ | ||
45 | extern void abort(void); | ||
46 | extern void ppc4xx_find_bridges(void); | ||
47 | |||
48 | /* Global Variables */ | ||
49 | bd_t __res; | ||
50 | |||
51 | void __init | ||
52 | ppc4xx_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 | |||
74 | static int | ||
75 | ppc4xx_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 | */ | ||
86 | static int | ||
87 | ppc4xx_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 | */ | ||
105 | static unsigned long __init | ||
106 | ppc4xx_find_end_of_memory(void) | ||
107 | { | ||
108 | return ((unsigned long) __res.bi_memsize); | ||
109 | } | ||
110 | |||
111 | void __init | ||
112 | ppc4xx_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 | |||
126 | void __init | ||
127 | ppc4xx_init_IRQ(void) | ||
128 | { | ||
129 | ppc4xx_pic_init(); | ||
130 | } | ||
131 | |||
132 | static void | ||
133 | ppc4xx_restart(char *cmd) | ||
134 | { | ||
135 | printk("%s\n", cmd); | ||
136 | abort(); | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | ppc4xx_power_off(void) | ||
141 | { | ||
142 | printk("System Halted\n"); | ||
143 | local_irq_disable(); | ||
144 | while (1) ; | ||
145 | } | ||
146 | |||
147 | static void | ||
148 | ppc4xx_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 | */ | ||
161 | static void __init | ||
162 | ppc4xx_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 | |||
191 | TODC_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 | */ | ||
205 | void __init | ||
206 | ppc4xx_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 */ | ||
258 | void 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 | |||
32 | void | ||
33 | ppc4xx_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 | */ | ||
56 | int | ||
57 | ppc4xx_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 | */ | ||
144 | void | ||
145 | ppc4xx_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 | */ | ||
177 | void | ||
178 | ppc4xx_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 | */ | ||
204 | int | ||
205 | ppc4xx_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 | */ | ||
288 | int | ||
289 | ppc4xx_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 | */ | ||
354 | int | ||
355 | ppc4xx_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 | */ | ||
439 | void | ||
440 | ppc4xx_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 | |||
458 | EXPORT_SYMBOL(ppc4xx_alloc_dma_handle); | ||
459 | EXPORT_SYMBOL(ppc4xx_free_dma_handle); | ||
460 | EXPORT_SYMBOL(ppc4xx_add_dma_sgl); | ||
461 | EXPORT_SYMBOL(ppc4xx_delete_dma_sgl_element); | ||
462 | EXPORT_SYMBOL(ppc4xx_enable_dma_sgl); | ||
463 | EXPORT_SYMBOL(ppc4xx_disable_dma_sgl); | ||
464 | EXPORT_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 | |||
13 | extern 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 | |||
24 | static 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 | |||
35 | static 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 | |||
46 | static 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 | |||
61 | static 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 | |||
73 | struct 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 | */ | ||
84 | int | ||
85 | m8xx_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 | */ | ||
119 | void 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 | |||
7 | extern struct hw_interrupt_type ppc8xx_pic; | ||
8 | |||
9 | void m8xx_do_IRQ(struct pt_regs *regs, | ||
10 | int cpu); | ||
11 | int m8xx_get_irq(struct pt_regs *regs); | ||
12 | |||
13 | #ifdef CONFIG_MBX | ||
14 | #include <asm/i8259.h> | ||
15 | #include <asm/io.h> | ||
16 | void 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 | |||
19 | int (*ppc_sys_device_fixup) (struct platform_device * pdev); | ||
20 | |||
21 | static int ppc_sys_inited; | ||
22 | static int ppc_sys_func_inited; | ||
23 | |||
24 | static 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 | |||
33 | void __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 | |||
47 | void __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 | |||
60 | static 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 | |||
68 | static 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 | |||
98 | void __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 */ | ||
106 | void __init | ||
107 | ppc_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 */ | ||
122 | void *__init ppc_sys_get_pdata(enum ppc_sys_devices dev) | ||
123 | { | ||
124 | return ppc_sys_platform_devices[dev].dev.platform_data; | ||
125 | } | ||
126 | |||
127 | void 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 | |||
146 | void 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 | */ | ||
191 | void 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*/ | ||
219 | void 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 | |||
252 | void 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 | |||
265 | void 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 | |||
279 | void 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 | |||
290 | void 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 | |||
302 | static 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 | |||
329 | subsys_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 | |||
21 | struct 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 | |||
379 | static 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 | |||
385 | static 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 | |||
393 | postcore_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 | |||
17 | struct ppc_sys_spec *cur_ppc_sys_spec; | ||
18 | struct 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 | |||
20 | static char nvramData[MAX_PREP_NVRAM]; | ||
21 | static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0]; | ||
22 | |||
23 | unsigned 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 | |||
30 | void 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 | |||
38 | void __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 | |||
82 | char *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 | |||
101 | char *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 | |||
111 | char *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 | |||
96 | static DEFINE_SPINLOCK(pcibios_lock); | ||
97 | |||
98 | int 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 | |||
137 | int 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 | |||
176 | int 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 | |||
210 | int 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 | |||
250 | int 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 | |||
290 | int 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 | |||
322 | int 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 | |||
347 | int 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 | |||
367 | void __init | ||
368 | m8xx_pcibios_fixup(void) | ||
369 | { | ||
370 | /* Lots to do here, all board and configuration specific. */ | ||
371 | } | ||
372 | |||
373 | void __init | ||
374 | m8xx_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) */ | ||
79 | u_char | ||
80 | todc_direct_read_val(int addr) | ||
81 | { | ||
82 | return readb((void __iomem *)(todc_info->nvram_data + addr)); | ||
83 | } | ||
84 | |||
85 | void | ||
86 | todc_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 */ | ||
93 | u_char | ||
94 | todc_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 | |||
101 | void | ||
102 | todc_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 */ | ||
111 | u_char | ||
112 | todc_mc146818_read_val(int addr) | ||
113 | { | ||
114 | outb_p(addr, todc_info->nvram_as0); | ||
115 | return inb_p(todc_info->nvram_data); | ||
116 | } | ||
117 | |||
118 | void | ||
119 | todc_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 | */ | ||
133 | static inline u_char | ||
134 | todc_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 | |||
155 | static inline void | ||
156 | todc_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 | */ | ||
186 | long __init | ||
187 | todc_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 | */ | ||
274 | ulong | ||
275 | todc_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 | |||
359 | int | ||
360 | todc_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 | */ | ||
416 | static 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 | */ | ||
455 | void __init | ||
456 | todc_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 */ | ||
114 | struct 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 | |||
143 | struct 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 */ | ||
210 | static void __init | ||
211 | virtex_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 | |||
228 | void __init | ||
229 | virtex_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 | */ | ||
251 | int __attribute__ ((weak)) | ||
252 | virtex_device_fixup(struct platform_device *dev) | ||
253 | { | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static 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 | |||
276 | subsys_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 | |||
17 | void __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 | */ | ||
26 | int virtex_device_fixup(struct platform_device *dev); | ||
27 | |||
28 | /* SPI Controller IP */ | ||
29 | struct 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 | ||
31 | static 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 | |||
40 | static void | ||
41 | xilinx_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 | |||
48 | static void | ||
49 | xilinx_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 | |||
56 | static void | ||
57 | xilinx_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 | |||
66 | static void | ||
67 | xilinx_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 | |||
80 | static 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 | |||
88 | int | ||
89 | xilinx_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 | |||
108 | void __init | ||
109 | ppc4xx_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 | } | ||