sbus.c 15 KB

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