pcibr_reg.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
  7. */
  8. #include <linux/interrupt.h>
  9. #include <linux/types.h>
  10. #include <asm/sn/pcibr_provider.h>
  11. #include <asm/sn/pcibus_provider_defs.h>
  12. #include <asm/sn/pcidev.h>
  13. #include <asm/sn/pic.h>
  14. #include <asm/sn/tiocp.h>
  15. union br_ptr {
  16. struct tiocp tio;
  17. struct pic pic;
  18. };
  19. /*
  20. * Control Register Access -- Read/Write 0000_0020
  21. */
  22. void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
  23. {
  24. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  25. if (pcibus_info) {
  26. switch (pcibus_info->pbi_bridge_type) {
  27. case PCIBR_BRIDGETYPE_TIOCP:
  28. ptr->tio.cp_control &= ~bits;
  29. break;
  30. case PCIBR_BRIDGETYPE_PIC:
  31. ptr->pic.p_wid_control &= ~bits;
  32. break;
  33. default:
  34. panic
  35. ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
  36. (void *)ptr);
  37. }
  38. }
  39. }
  40. void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
  41. {
  42. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  43. if (pcibus_info) {
  44. switch (pcibus_info->pbi_bridge_type) {
  45. case PCIBR_BRIDGETYPE_TIOCP:
  46. ptr->tio.cp_control |= bits;
  47. break;
  48. case PCIBR_BRIDGETYPE_PIC:
  49. ptr->pic.p_wid_control |= bits;
  50. break;
  51. default:
  52. panic
  53. ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
  54. (void *)ptr);
  55. }
  56. }
  57. }
  58. /*
  59. * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050
  60. */
  61. uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info)
  62. {
  63. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  64. uint64_t ret = 0;
  65. if (pcibus_info) {
  66. switch (pcibus_info->pbi_bridge_type) {
  67. case PCIBR_BRIDGETYPE_TIOCP:
  68. ret = ptr->tio.cp_tflush;
  69. break;
  70. case PCIBR_BRIDGETYPE_PIC:
  71. ret = ptr->pic.p_wid_tflush;
  72. break;
  73. default:
  74. panic
  75. ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
  76. (void *)ptr);
  77. }
  78. }
  79. /* Read of the Target Flush should always return zero */
  80. if (ret != 0)
  81. panic("pcireg_tflush_get:Target Flush failed\n");
  82. return ret;
  83. }
  84. /*
  85. * Interrupt Status Register Access -- Read Only 0000_0100
  86. */
  87. uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info)
  88. {
  89. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  90. uint64_t ret = 0;
  91. if (pcibus_info) {
  92. switch (pcibus_info->pbi_bridge_type) {
  93. case PCIBR_BRIDGETYPE_TIOCP:
  94. ret = ptr->tio.cp_int_status;
  95. break;
  96. case PCIBR_BRIDGETYPE_PIC:
  97. ret = ptr->pic.p_int_status;
  98. break;
  99. default:
  100. panic
  101. ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
  102. (void *)ptr);
  103. }
  104. }
  105. return ret;
  106. }
  107. /*
  108. * Interrupt Enable Register Access -- Read/Write 0000_0108
  109. */
  110. void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
  111. {
  112. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  113. if (pcibus_info) {
  114. switch (pcibus_info->pbi_bridge_type) {
  115. case PCIBR_BRIDGETYPE_TIOCP:
  116. ptr->tio.cp_int_enable &= ~bits;
  117. break;
  118. case PCIBR_BRIDGETYPE_PIC:
  119. ptr->pic.p_int_enable &= ~bits;
  120. break;
  121. default:
  122. panic
  123. ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
  124. (void *)ptr);
  125. }
  126. }
  127. }
  128. void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
  129. {
  130. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  131. if (pcibus_info) {
  132. switch (pcibus_info->pbi_bridge_type) {
  133. case PCIBR_BRIDGETYPE_TIOCP:
  134. ptr->tio.cp_int_enable |= bits;
  135. break;
  136. case PCIBR_BRIDGETYPE_PIC:
  137. ptr->pic.p_int_enable |= bits;
  138. break;
  139. default:
  140. panic
  141. ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
  142. (void *)ptr);
  143. }
  144. }
  145. }
  146. /*
  147. * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168
  148. */
  149. void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
  150. uint64_t addr)
  151. {
  152. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  153. if (pcibus_info) {
  154. switch (pcibus_info->pbi_bridge_type) {
  155. case PCIBR_BRIDGETYPE_TIOCP:
  156. ptr->tio.cp_int_addr[int_n] &= ~TIOCP_HOST_INTR_ADDR;
  157. ptr->tio.cp_int_addr[int_n] |=
  158. (addr & TIOCP_HOST_INTR_ADDR);
  159. break;
  160. case PCIBR_BRIDGETYPE_PIC:
  161. ptr->pic.p_int_addr[int_n] &= ~PIC_HOST_INTR_ADDR;
  162. ptr->pic.p_int_addr[int_n] |=
  163. (addr & PIC_HOST_INTR_ADDR);
  164. break;
  165. default:
  166. panic
  167. ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
  168. (void *)ptr);
  169. }
  170. }
  171. }
  172. /*
  173. * Force Interrupt Register Access -- Write Only 0000_01C0 - 0000_01F8
  174. */
  175. void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
  176. {
  177. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  178. if (pcibus_info) {
  179. switch (pcibus_info->pbi_bridge_type) {
  180. case PCIBR_BRIDGETYPE_TIOCP:
  181. ptr->tio.cp_force_pin[int_n] = 1;
  182. break;
  183. case PCIBR_BRIDGETYPE_PIC:
  184. ptr->pic.p_force_pin[int_n] = 1;
  185. break;
  186. default:
  187. panic
  188. ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
  189. (void *)ptr);
  190. }
  191. }
  192. }
  193. /*
  194. * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258
  195. */
  196. uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
  197. {
  198. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  199. uint64_t ret = 0;
  200. if (pcibus_info) {
  201. switch (pcibus_info->pbi_bridge_type) {
  202. case PCIBR_BRIDGETYPE_TIOCP:
  203. ret = ptr->tio.cp_wr_req_buf[device];
  204. break;
  205. case PCIBR_BRIDGETYPE_PIC:
  206. ret = ptr->pic.p_wr_req_buf[device];
  207. break;
  208. default:
  209. panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr);
  210. }
  211. }
  212. /* Read of the Write Buffer Flush should always return zero */
  213. return ret;
  214. }
  215. void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
  216. uint64_t val)
  217. {
  218. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  219. if (pcibus_info) {
  220. switch (pcibus_info->pbi_bridge_type) {
  221. case PCIBR_BRIDGETYPE_TIOCP:
  222. ptr->tio.cp_int_ate_ram[ate_index] = (uint64_t) val;
  223. break;
  224. case PCIBR_BRIDGETYPE_PIC:
  225. ptr->pic.p_int_ate_ram[ate_index] = (uint64_t) val;
  226. break;
  227. default:
  228. panic
  229. ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
  230. (void *)ptr);
  231. }
  232. }
  233. }
  234. uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
  235. {
  236. union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
  237. uint64_t *ret = (uint64_t *) 0;
  238. if (pcibus_info) {
  239. switch (pcibus_info->pbi_bridge_type) {
  240. case PCIBR_BRIDGETYPE_TIOCP:
  241. ret =
  242. (uint64_t *) & (ptr->tio.cp_int_ate_ram[ate_index]);
  243. break;
  244. case PCIBR_BRIDGETYPE_PIC:
  245. ret =
  246. (uint64_t *) & (ptr->pic.p_int_ate_ram[ate_index]);
  247. break;
  248. default:
  249. panic
  250. ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
  251. (void *)ptr);
  252. }
  253. }
  254. return ret;
  255. }