File: /usr/src/linux/drivers/sbus/sbus.c

1     /* $Id: sbus.c,v 1.95 2001/03/15 02:11:10 davem Exp $
2      * sbus.c:  SBus support routines.
3      *
4      * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5      */
6     
7     #include <linux/kernel.h>
8     #include <linux/slab.h>
9     #include <linux/config.h>
10     #include <linux/init.h>
11     #include <linux/pci.h>
12     
13     #include <asm/system.h>
14     #include <asm/sbus.h>
15     #include <asm/dma.h>
16     #include <asm/oplib.h>
17     #include <asm/bpp.h>
18     #include <asm/irq.h>
19     
20     struct sbus_bus *sbus_root = NULL;
21     
22     static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } };
23     
24     /* Perhaps when I figure out more about the iommu we'll put a
25      * device registration routine here that probe_sbus() calls to
26      * setup the iommu for each Sbus.
27      */
28     
29     /* We call this for each SBus device, and fill the structure based
30      * upon the prom device tree.  We return the start of memory after
31      * the things we have allocated.
32      */
33     
34     /* #define DEBUG_FILL */
35     
36     static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
37     {
38     	unsigned long address, base;
39     	int len;
40     
41     	sdev->prom_node = prom_node;
42     	prom_getstring(prom_node, "name",
43     		       sdev->prom_name, sizeof(sdev->prom_name));
44     	address = prom_getint(prom_node, "address");
45     	len = prom_getproperty(prom_node, "reg",
46     			       (char *) sdev->reg_addrs,
47     			       sizeof(sdev->reg_addrs));
48     	if (len == -1) {
49     		sdev->num_registers = 0;
50     		goto no_regs;
51     	}
52     
53     	if (len % sizeof(struct linux_prom_registers)) {
54     		prom_printf("fill_sbus_device: proplen for regs of %s "
55     			    " was %d, need multiple of %d\n",
56     			    sdev->prom_name, len,
57     			    (int) sizeof(struct linux_prom_registers));
58     		prom_halt();
59     	}
60     	if (len > (sizeof(struct linux_prom_registers) * PROMREG_MAX)) {
61     		prom_printf("fill_sbus_device: Too many register properties "
62     			    "for device %s, len=%d\n",
63     			    sdev->prom_name, len);
64     		prom_halt();
65     	}
66     	sdev->num_registers = len / sizeof(struct linux_prom_registers);
67     	sdev->ranges_applied = 0;
68     
69     	base = (unsigned long) sdev->reg_addrs[0].phys_addr;
70     
71     	/* Compute the slot number. */
72     	if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) {
73     		sdev->slot = sbus_dev_slot(base);
74     	} else {
75     		sdev->slot = sdev->reg_addrs[0].which_io;
76     	}
77     
78     no_regs:
79     	len = prom_getproperty(prom_node, "ranges",
80     			       (char *)sdev->device_ranges,
81     			       sizeof(sdev->device_ranges));
82     	if (len == -1) {
83     		sdev->num_device_ranges = 0;
84     		goto no_ranges;
85     	}
86     	if (len % sizeof(struct linux_prom_ranges)) {
87     		prom_printf("fill_sbus_device: proplen for ranges of %s "
88     			    " was %d, need multiple of %d\n",
89     			    sdev->prom_name, len,
90     			    (int) sizeof(struct linux_prom_ranges));
91     		prom_halt();
92     	}
93     	if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) {
94     		prom_printf("fill_sbus_device: Too many range properties "
95     			    "for device %s, len=%d\n",
96     			    sdev->prom_name, len);
97     		prom_halt();
98     	}
99     	sdev->num_device_ranges =
100     		len / sizeof(struct linux_prom_ranges);
101     
102     no_ranges:
103     	/* XXX Unfortunately, IRQ issues are very arch specific.
104     	 * XXX Pull this crud out into an arch specific area
105     	 * XXX at some point. -DaveM
106     	 */
107     #ifdef __sparc_v9__
108     	len = prom_getproperty(prom_node, "interrupts",
109     			       (char *) irqs, sizeof(irqs));
110     	if (len == -1 || len == 0) {
111     		sdev->irqs[0] = 0;
112     		sdev->num_irqs = 0;
113     	} else {
114     		unsigned int pri = irqs[0].pri;
115     
116     		sdev->num_irqs = 1;
117     		if (pri < 0x20)
118     			pri += sdev->slot * 8;
119     
120     		sdev->irqs[0] =	sbus_build_irq(sdev->bus, pri);
121     	}
122     #else
123     	len = prom_getproperty(prom_node, "intr",
124     			       (char *)irqs, sizeof(irqs));
125     	if (len == -1)
126     		len = 0;
127     	sdev->num_irqs = len / 8;
128     	if (sdev->num_irqs == 0) {
129     		sdev->irqs[0] = 0;
130     	} else if (sparc_cpu_model == sun4d) {
131     		extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
132     
133     		for (len = 0; len < sdev->num_irqs; len++)
134     			sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri);
135     	} else {
136     		for (len = 0; len < sdev->num_irqs; len++)
137     			sdev->irqs[len] = irqs[len].pri;
138     	}
139     #endif /* !__sparc_v9__ */
140     }
141     
142     /* This routine gets called from whoever needs the sbus first, to scan
143      * the SBus device tree.  Currently it just prints out the devices
144      * found on the bus and builds trees of SBUS structs and attached
145      * devices.
146      */
147     
148     extern void iommu_init(int iommu_node, struct sbus_bus *sbus);
149     extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus);
150     void sun4_init(void);
151     #ifdef CONFIG_SUN_AUXIO
152     extern void auxio_probe(void);
153     #endif
154     
155     static void __init sbus_do_child_siblings(int start_node,
156     					  struct sbus_dev *child,
157     					  struct sbus_dev *parent,
158     					  struct sbus_bus *sbus)
159     {
160     	struct sbus_dev *this_dev = child;
161     	int this_node = start_node;
162     
163     	/* Child already filled in, just need to traverse siblings. */
164     	child->child = NULL;
165     	child->parent = parent;
166     	while((this_node = prom_getsibling(this_node)) != 0) {
167     		this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
168     		this_dev = this_dev->next;
169     		this_dev->next = 0;
170     		this_dev->parent = parent;
171     
172     		this_dev->bus = sbus;
173     		fill_sbus_device(this_node, this_dev);
174     
175     		if(prom_getchild(this_node)) {
176     			this_dev->child = kmalloc(sizeof(struct sbus_dev),
177     						  GFP_ATOMIC);
178     			this_dev->child->bus = sbus;
179     			this_dev->child->next = 0;
180     			fill_sbus_device(prom_getchild(this_node), this_dev->child);
181     			sbus_do_child_siblings(prom_getchild(this_node),
182     					       this_dev->child, this_dev, sbus);
183     		} else {
184     			this_dev->child = NULL;
185     		}
186     	}
187     }
188     
189     /*
190      * XXX This functions appears to be a distorted version of
191      * prom_sbus_ranges_init(), with all sun4d stuff cut away.
192      * Ask DaveM what is going on here, how is sun4d supposed to work... XXX
193      */
194     static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus)
195     {
196     	int len;
197     
198     	len = prom_getproperty(sbus->prom_node, "ranges",
199     			       (char *) sbus->sbus_ranges,
200     			       sizeof(sbus->sbus_ranges));
201     	if (len == -1 || len == 0) {
202     		sbus->num_sbus_ranges = 0;
203     		return;
204     	}
205     	sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges);
206     }
207     
208     static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
209     					  int num_ranges,
210     					  struct linux_prom_registers *regs,
211     					  int num_regs)
212     {
213     	if (num_ranges) {
214     		int regnum;
215     
216     		for (regnum = 0; regnum < num_regs; regnum++) {
217     			int rngnum;
218     
219     			for (rngnum = 0; rngnum < num_ranges; rngnum++) {
220     				if (regs[regnum].which_io == ranges[rngnum].ot_child_space)
221     					break;
222     			}
223     			if (rngnum == num_ranges) {
224     				/* We used to flag this as an error.  Actually
225     				 * some devices do not report the regs as we expect.
226     				 * For example, see SUNW,pln device.  In that case
227     				 * the reg property is in a format internal to that
228     				 * node, ie. it is not in the SBUS register space
229     				 * per se. -DaveM
230     				 */
231     				return;
232     			}
233     			regs[regnum].which_io = ranges[rngnum].ot_parent_space;
234     			regs[regnum].phys_addr += ranges[rngnum].ot_parent_base;
235     		}
236     	}
237     }
238     
239     static void __init __fixup_regs_sdev(struct sbus_dev *sdev)
240     {
241     	if (sdev->num_registers != 0) {
242     		struct sbus_dev *parent = sdev->parent;
243     		int i;
244     
245     		while (parent != NULL) {
246     			__apply_ranges_to_regs(parent->device_ranges,
247     					       parent->num_device_ranges,
248     					       sdev->reg_addrs,
249     					       sdev->num_registers);
250     
251     			parent = parent->parent;
252     		}
253     
254     		__apply_ranges_to_regs(sdev->bus->sbus_ranges,
255     				       sdev->bus->num_sbus_ranges,
256     				       sdev->reg_addrs,
257     				       sdev->num_registers);
258     
259     		for (i = 0; i < sdev->num_registers; i++) {
260     			struct resource *res = &sdev->resource[i];
261     
262     			res->start = sdev->reg_addrs[i].phys_addr;
263     			res->end = (res->start +
264     				    (unsigned long)sdev->reg_addrs[i].reg_size - 1UL);
265     			res->flags = IORESOURCE_IO |
266     				(sdev->reg_addrs[i].which_io & 0xff);
267     		}
268     	}
269     }
270     
271     static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev)
272     {
273     	struct sbus_dev *sdev;
274     
275     	for (sdev = first_sdev; sdev; sdev = sdev->next) {
276     		if (sdev->child)
277     			sbus_fixup_all_regs(sdev->child);
278     		__fixup_regs_sdev(sdev);
279     	}
280     }
281     
282     extern void register_proc_sparc_ioport(void);
283     extern void firetruck_init(void);
284     extern void rs_init(void);
285     
286     void __init sbus_init(void)
287     {
288     	int nd, this_sbus, sbus_devs, topnd, iommund;
289     	unsigned int sbus_clock;
290     	struct sbus_bus *sbus;
291     	struct sbus_dev *this_dev;
292     	int num_sbus = 0;  /* How many did we find? */
293     
294     #ifndef __sparc_v9__
295     	register_proc_sparc_ioport();
296     #endif
297     
298     #ifdef CONFIG_SUN4
299     	return sun4_dvma_init();
300     #endif
301     
302     	topnd = prom_getchild(prom_root_node);
303     	
304     	/* Finding the first sbus is a special case... */
305     	iommund = 0;
306     	if(sparc_cpu_model == sun4u) {
307     		nd = prom_searchsiblings(topnd, "sbus");
308     		if(nd == 0) {
309     #ifdef CONFIG_PCI
310     			if (!pcibios_present()) {	
311     				prom_printf("Neither SBUS nor PCI found.\n");
312     				prom_halt();
313     			} else {
314     #ifdef __sparc_v9__
315     				firetruck_init();
316     #endif
317     			}
318     			return;
319     #else
320     			prom_printf("YEEE, UltraSparc sbus not found\n");
321     			prom_halt();
322     #endif
323     		}
324     	} else if(sparc_cpu_model == sun4d) {
325     		if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 ||
326     		   (nd = prom_getchild(iommund)) == 0 ||
327     		   (nd = prom_searchsiblings(nd, "sbi")) == 0) {
328     		   	panic("sbi not found");
329     		}
330     	} else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) {
331     		if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 ||
332     		   (nd = prom_getchild(iommund)) == 0 ||
333     		   (nd = prom_searchsiblings(nd, "sbus")) == 0) {
334     #ifdef CONFIG_PCI
335                             if (!pcibios_present()) {       
336                                     prom_printf("Neither SBUS nor PCI found.\n");
337                                     prom_halt();
338                             }
339                             return;
340     #else
341     			/* No reason to run further - the data access trap will occur. */
342     			panic("sbus not found");
343     #endif
344     		}
345     	}
346     
347     	/* Ok, we've found the first one, allocate first SBus struct
348     	 * and place in chain.
349     	 */
350     	sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
351     	sbus->next = NULL;
352     	sbus->prom_node = nd;
353     	this_sbus = nd;
354     
355     	if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d)
356     		iommu_init(iommund, sbus);
357     
358     	/* Loop until we find no more SBUS's */
359     	while(this_sbus) {
360     #ifdef __sparc_v9__						  
361     		/* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */
362     		if(sparc_cpu_model == sun4u) {
363     			extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus);
364     
365     			sbus_iommu_init(this_sbus, sbus);
366     		}
367     #endif
368     #ifndef __sparc_v9__						  
369     		if (sparc_cpu_model == sun4d)
370     			iounit_init(this_sbus, iommund, sbus);
371     #endif						   
372     		printk("sbus%d: ", num_sbus);
373     		sbus_clock = prom_getint(this_sbus, "clock-frequency");
374     		if(sbus_clock == -1)
375     			sbus_clock = (25*1000*1000);
376     		printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
377     		       (int) (((sbus_clock/1000)%1000 != 0) ? 
378     			      (((sbus_clock/1000)%1000) + 1000) : 0));
379     
380     		prom_getstring(this_sbus, "name",
381     			       sbus->prom_name, sizeof(sbus->prom_name));
382     		sbus->clock_freq = sbus_clock;
383     #ifndef __sparc_v9__		
384     		if (sparc_cpu_model == sun4d) {
385     			sbus->devid = prom_getint(iommund, "device-id");
386     			sbus->board = prom_getint(iommund, "board#");
387     		}
388     #endif
389     		
390     		sbus_bus_ranges_init(iommund, sbus);
391     
392     		sbus_devs = prom_getchild(this_sbus);
393     
394     		sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
395     
396     		this_dev = sbus->devices;
397     		this_dev->next = NULL;
398     
399     		this_dev->bus = sbus;
400     		this_dev->parent = NULL;
401     		fill_sbus_device(sbus_devs, this_dev);
402     
403     		/* Should we traverse for children? */
404     		if(prom_getchild(sbus_devs)) {
405     			/* Allocate device node */
406     			this_dev->child = kmalloc(sizeof(struct sbus_dev),
407     						  GFP_ATOMIC);
408     			/* Fill it */
409     			this_dev->child->bus = sbus;
410     			this_dev->child->next = 0;
411     			fill_sbus_device(prom_getchild(sbus_devs),
412     					 this_dev->child);
413     			sbus_do_child_siblings(prom_getchild(sbus_devs),
414     					       this_dev->child,
415     					       this_dev,
416     					       sbus);
417     		} else {
418     			this_dev->child = NULL;
419     		}
420     
421     		while((sbus_devs = prom_getsibling(sbus_devs)) != 0) {
422     			/* Allocate device node */
423     			this_dev->next = kmalloc(sizeof(struct sbus_dev),
424     						 GFP_ATOMIC);
425     			this_dev = this_dev->next;
426     			this_dev->next = NULL;
427     
428     			/* Fill it */
429     			this_dev->bus = sbus;
430     			this_dev->parent = NULL;
431     			fill_sbus_device(sbus_devs, this_dev);
432     
433     			/* Is there a child node hanging off of us? */
434     			if(prom_getchild(sbus_devs)) {
435     				/* Get new device struct */
436     				this_dev->child = kmalloc(sizeof(struct sbus_dev),
437     							  GFP_ATOMIC);
438     				/* Fill it */
439     				this_dev->child->bus = sbus;
440     				this_dev->child->next = 0;
441     				fill_sbus_device(prom_getchild(sbus_devs),
442     						 this_dev->child);
443     				sbus_do_child_siblings(prom_getchild(sbus_devs),
444     						       this_dev->child,
445     						       this_dev,
446     						       sbus);
447     			} else {
448     				this_dev->child = NULL;
449     			}
450     		}
451     
452     		/* Walk all devices and apply parent ranges. */
453     		sbus_fixup_all_regs(sbus->devices);
454     
455     		dvma_init(sbus);
456     
457     		num_sbus++;
458     		if(sparc_cpu_model == sun4u) {
459     			this_sbus = prom_getsibling(this_sbus);
460     			if(!this_sbus)
461     				break;
462     			this_sbus = prom_searchsiblings(this_sbus, "sbus");
463     		} else if(sparc_cpu_model == sun4d) {
464     			iommund = prom_getsibling(iommund);
465     			if(!iommund)
466     				break;
467     			iommund = prom_searchsiblings(iommund, "io-unit");
468     			if(!iommund)
469     				break;
470     			this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi");
471     		} else {
472     			this_sbus = prom_getsibling(this_sbus);
473     			if(!this_sbus)
474     				break;
475     			this_sbus = prom_searchsiblings(this_sbus, "sbus");
476     		}
477     		if(this_sbus) {
478     			sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
479     			sbus = sbus->next;
480     			sbus->next = NULL;
481     			sbus->prom_node = this_sbus;
482     		} else {
483     			break;
484     		}
485     	} /* while(this_sbus) */
486     
487     	if (sparc_cpu_model == sun4d) {
488     		extern void sun4d_init_sbi_irq(void);
489     		sun4d_init_sbi_irq();
490     	}
491     	
492     	rs_init();
493     
494     #ifdef __sparc_v9__
495     	if (sparc_cpu_model == sun4u) {
496     		firetruck_init();
497     	}
498     #endif
499     #ifdef CONFIG_SUN_AUXIO
500     	if (sparc_cpu_model == sun4u)
501     		auxio_probe ();
502     #endif
503     #ifdef __sparc_v9__
504     	if (sparc_cpu_model == sun4u) {
505     		extern void clock_probe(void);
506     
507     		clock_probe();
508     	}
509     #endif
510     }
511