tc.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * tc-init: We assume the TURBOchannel to be up and running so
  3. * just probe for Modules and fill in the global data structure
  4. * tc_bus.
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. *
  10. * Copyright (c) Harald Koerfgen, 1998
  11. * Copyright (c) 2001, 2003 Maciej W. Rozycki
  12. */
  13. #include <linux/string.h>
  14. #include <linux/init.h>
  15. #include <linux/ioport.h>
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <asm/addrspace.h>
  19. #include <asm/errno.h>
  20. #include <asm/dec/machtype.h>
  21. #include <asm/dec/prom.h>
  22. #include <asm/dec/tcinfo.h>
  23. #include <asm/dec/tcmodule.h>
  24. #include <asm/dec/interrupts.h>
  25. #include <asm/paccess.h>
  26. #include <asm/ptrace.h>
  27. #define TC_DEBUG
  28. MODULE_LICENSE("GPL");
  29. slot_info tc_bus[MAX_SLOT];
  30. static int num_tcslots;
  31. static tcinfo *info;
  32. unsigned long system_base;
  33. /*
  34. * Interface to the world. Read comment in include/asm-mips/tc.h.
  35. */
  36. int search_tc_card(const char *name)
  37. {
  38. int slot;
  39. slot_info *sip;
  40. for (slot = 0; slot < num_tcslots; slot++) {
  41. sip = &tc_bus[slot];
  42. if ((sip->flags & FREE) &&
  43. (strncmp(sip->name, name, strlen(name)) == 0)) {
  44. return slot;
  45. }
  46. }
  47. return -ENODEV;
  48. }
  49. void claim_tc_card(int slot)
  50. {
  51. if (tc_bus[slot].flags & IN_USE) {
  52. printk("claim_tc_card: attempting to claim a card already in use\n");
  53. return;
  54. }
  55. tc_bus[slot].flags &= ~FREE;
  56. tc_bus[slot].flags |= IN_USE;
  57. }
  58. void release_tc_card(int slot)
  59. {
  60. if (tc_bus[slot].flags & FREE) {
  61. printk("release_tc_card: "
  62. "attempting to release a card already free\n");
  63. return;
  64. }
  65. tc_bus[slot].flags &= ~IN_USE;
  66. tc_bus[slot].flags |= FREE;
  67. }
  68. unsigned long get_tc_base_addr(int slot)
  69. {
  70. return tc_bus[slot].base_addr;
  71. }
  72. unsigned long get_tc_irq_nr(int slot)
  73. {
  74. return tc_bus[slot].interrupt;
  75. }
  76. unsigned long get_tc_speed(void)
  77. {
  78. return 100000 * (10000 / (unsigned long)info->clk_period);
  79. }
  80. /*
  81. * Probing for TURBOchannel modules
  82. */
  83. static void __init tc_probe(unsigned long startaddr, unsigned long size,
  84. int slots)
  85. {
  86. int i, slot, err;
  87. long offset;
  88. unsigned char pattern[4];
  89. unsigned char *module;
  90. for (slot = 0; slot < slots; slot++) {
  91. module = (char *)(startaddr + slot * size);
  92. offset = OLDCARD;
  93. err = 0;
  94. err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
  95. err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
  96. err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
  97. err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
  98. if (err)
  99. continue;
  100. if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
  101. pattern[2] != 0xaa || pattern[3] != 0xff) {
  102. offset = NEWCARD;
  103. err = 0;
  104. err |= get_dbe(pattern[0], module + TC_PATTERN0);
  105. err |= get_dbe(pattern[1], module + TC_PATTERN1);
  106. err |= get_dbe(pattern[2], module + TC_PATTERN2);
  107. err |= get_dbe(pattern[3], module + TC_PATTERN3);
  108. if (err)
  109. continue;
  110. }
  111. if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
  112. pattern[2] != 0xaa || pattern[3] != 0xff)
  113. continue;
  114. tc_bus[slot].base_addr = (unsigned long)module;
  115. for(i = 0; i < 8; i++) {
  116. tc_bus[slot].firmware[i] =
  117. module[TC_FIRM_VER + offset + 4 * i];
  118. tc_bus[slot].vendor[i] =
  119. module[TC_VENDOR + offset + 4 * i];
  120. tc_bus[slot].name[i] =
  121. module[TC_MODULE + offset + 4 * i];
  122. }
  123. tc_bus[slot].firmware[8] = 0;
  124. tc_bus[slot].vendor[8] = 0;
  125. tc_bus[slot].name[8] = 0;
  126. /*
  127. * Looks unneccesary, but we may change
  128. * TC? in the future
  129. */
  130. switch (slot) {
  131. case 0:
  132. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
  133. break;
  134. case 1:
  135. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
  136. break;
  137. case 2:
  138. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
  139. break;
  140. /*
  141. * Yuck! DS5000/200 onboard devices
  142. */
  143. case 5:
  144. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
  145. break;
  146. case 6:
  147. tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
  148. break;
  149. default:
  150. tc_bus[slot].interrupt = -1;
  151. break;
  152. }
  153. }
  154. }
  155. /*
  156. * the main entry
  157. */
  158. void __init tc_init(void)
  159. {
  160. int tc_clock;
  161. int i;
  162. unsigned long slot0addr;
  163. unsigned long slot_size;
  164. if (!TURBOCHANNEL)
  165. return;
  166. for (i = 0; i < MAX_SLOT; i++) {
  167. tc_bus[i].base_addr = 0;
  168. tc_bus[i].name[0] = 0;
  169. tc_bus[i].vendor[0] = 0;
  170. tc_bus[i].firmware[0] = 0;
  171. tc_bus[i].interrupt = -1;
  172. tc_bus[i].flags = FREE;
  173. }
  174. info = (tcinfo *) rex_gettcinfo();
  175. slot0addr = (unsigned long)KSEG1ADDR(rex_slot_address(0));
  176. switch (mips_machtype) {
  177. case MACH_DS5000_200:
  178. num_tcslots = 7;
  179. break;
  180. case MACH_DS5000_1XX:
  181. case MACH_DS5000_2X0:
  182. case MACH_DS5900:
  183. num_tcslots = 3;
  184. break;
  185. case MACH_DS5000_XX:
  186. default:
  187. num_tcslots = 2;
  188. break;
  189. }
  190. tc_clock = 10000 / info->clk_period;
  191. if (TURBOCHANNEL && info->slot_size && slot0addr) {
  192. printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
  193. tc_clock / 10, tc_clock % 10);
  194. printk("(with%s parity)\n", info->parity ? "" : "out");
  195. slot_size = info->slot_size << 20;
  196. tc_probe(slot0addr, slot_size, num_tcslots);
  197. /*
  198. * All TURBOchannel DECstations have the onboard devices
  199. * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
  200. * would be.
  201. */
  202. if(mips_machtype == MACH_DS5000_XX)
  203. i = 1;
  204. else
  205. i = 0;
  206. system_base = slot0addr + slot_size * (num_tcslots + i);
  207. #ifdef TC_DEBUG
  208. for (i = 0; i < num_tcslots; i++)
  209. if (tc_bus[i].base_addr) {
  210. printk(" slot %d: ", i);
  211. printk("%s %s %s\n", tc_bus[i].vendor,
  212. tc_bus[i].name, tc_bus[i].firmware);
  213. }
  214. #endif
  215. ioport_resource.end = KSEG2 - 1;
  216. }
  217. }
  218. subsys_initcall(tc_init);
  219. EXPORT_SYMBOL(search_tc_card);
  220. EXPORT_SYMBOL(claim_tc_card);
  221. EXPORT_SYMBOL(release_tc_card);
  222. EXPORT_SYMBOL(get_tc_base_addr);
  223. EXPORT_SYMBOL(get_tc_irq_nr);
  224. EXPORT_SYMBOL(get_tc_speed);
  225. EXPORT_SYMBOL(system_base);