multiverse.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * multiverse.c
  3. *
  4. * VME driver for Multiverse
  5. *
  6. * Author : Sangmoon Kim
  7. * dogoil@etinsys.com
  8. *
  9. * Copyright 2005 ETIN SYSTEMS Co.,Ltd.
  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 <common.h>
  17. #include <asm/io.h>
  18. #include <pci.h>
  19. #include <linux/compiler.h>
  20. #include "multiverse.h"
  21. static unsigned long vme_asi_addr;
  22. static unsigned long vme_iack_addr;
  23. static unsigned long pci_reg_addr;
  24. static unsigned long vme_reg_addr;
  25. int multiv_reset(unsigned long base)
  26. {
  27. writeb(0x09, base + VME_SLAVE32_AM);
  28. writeb(0x39, base + VME_SLAVE24_AM);
  29. writeb(0x29, base + VME_SLAVE16_AM);
  30. writeb(0x2f, base + VME_SLAVE_REG_AM);
  31. writeb((VME_A32_SLV_BUS >> 24) & 0xff, base + VME_SLAVE32_A);
  32. writeb((VME_A24_SLV_BUS >> 16) & 0xff, base + VME_SLAVE24_A);
  33. writeb((VME_A16_SLV_BUS >> 8 ) & 0xff, base + VME_SLAVE16_A);
  34. #ifdef A32_SLV_WINDOW
  35. if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
  36. writeb(((~(VME_A32_SLV_SIZE-1)) >> 24) & 0xff,
  37. base + VME_SLAVE32_MASK);
  38. writeb(0x01, base + VME_SLAVE32_EN);
  39. } else {
  40. writeb(0xff, base + VME_SLAVE32_MASK);
  41. writeb(0x00, base + VME_SLAVE32_EN);
  42. }
  43. #else
  44. writeb(0xff, base + VME_SLAVE32_MASK);
  45. writeb(0x00, base + VME_SLAVE32_EN);
  46. #endif
  47. #ifdef A24_SLV_WINDOW
  48. if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
  49. writeb(((~(VME_A24_SLV_SIZE-1)) >> 16) & 0xff,
  50. base + VME_SLAVE24_MASK);
  51. writeb(0x01, base + VME_SLAVE24_EN);
  52. } else {
  53. writeb(0xff, base + VME_SLAVE24_MASK);
  54. writeb(0x00, base + VME_SLAVE24_EN);
  55. }
  56. #else
  57. writeb(0xff, base + VME_SLAVE24_MASK);
  58. writeb(0x00, base + VME_SLAVE24_EN);
  59. #endif
  60. #ifdef A16_SLV_WINDOW
  61. if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
  62. writeb(((~(VME_A16_SLV_SIZE-1)) >> 8) & 0xff,
  63. base + VME_SLAVE16_MASK);
  64. writeb(0x01, base + VME_SLAVE16_EN);
  65. } else {
  66. writeb(0xff, base + VME_SLAVE16_MASK);
  67. writeb(0x00, base + VME_SLAVE16_EN);
  68. }
  69. #else
  70. writeb(0xff, base + VME_SLAVE16_MASK);
  71. writeb(0x00, base + VME_SLAVE16_EN);
  72. #endif
  73. #ifdef REG_SLV_WINDOW
  74. if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
  75. writeb(((~(VME_REG_SLV_SIZE-1)) >> 16) & 0xff,
  76. base + VME_SLAVE_REG_MASK);
  77. writeb(0x01, base + VME_SLAVE_REG_EN);
  78. } else {
  79. writeb(0xf8, base + VME_SLAVE_REG_MASK);
  80. }
  81. #else
  82. writeb(0xf8, base + VME_SLAVE_REG_MASK);
  83. #endif
  84. writeb(0x09, base + VME_MASTER32_AM);
  85. writeb(0x39, base + VME_MASTER24_AM);
  86. writeb(0x29, base + VME_MASTER16_AM);
  87. writeb(0x2f, base + VME_MASTER_REG_AM);
  88. writel(0x00000000, base + VME_RMW_ADRS);
  89. writeb(0x00, base + VME_IRQ);
  90. writeb(0x00, base + VME_INT_EN);
  91. writel(0x00000000, base + VME_IRQ1_REG);
  92. writel(0x00000000, base + VME_IRQ2_REG);
  93. writel(0x00000000, base + VME_IRQ3_REG);
  94. writel(0x00000000, base + VME_IRQ4_REG);
  95. writel(0x00000000, base + VME_IRQ5_REG);
  96. writel(0x00000000, base + VME_IRQ6_REG);
  97. writel(0x00000000, base + VME_IRQ7_REG);
  98. return 0;
  99. }
  100. void multiv_auto_slot_id(unsigned long base)
  101. {
  102. __maybe_unused unsigned int vector;
  103. int slot_id = 1;
  104. if (readb(base + VME_CTRL) & VME_CTRL_SYSFAIL) {
  105. *(volatile unsigned int*)(base + VME_IRQ2_REG) = 0xfe;
  106. writeb(readb(base + VME_IRQ) | 0x04, base + VME_IRQ);
  107. writeb(readb(base + VME_CTRL) & ~VME_CTRL_SYSFAIL,
  108. base + VME_CTRL);
  109. while (readb(base + VME_STATUS) & VME_STATUS_SYSFAIL);
  110. if (readb(base + VME_STATUS) & VME_STATUS_SYSCON) {
  111. while (readb(base + VME_INT) & 0x04) {
  112. vector = *(volatile unsigned int*)
  113. (vme_iack_addr + VME_IACK2);
  114. *(unsigned char*)(vme_asi_addr + 0x7ffff)
  115. = (slot_id << 3) & 0xff;
  116. slot_id ++;
  117. if (slot_id > 31)
  118. break;
  119. }
  120. }
  121. }
  122. }
  123. int multiverse_init(void)
  124. {
  125. int i;
  126. pci_dev_t pdev;
  127. unsigned int bar[6];
  128. pdev = pci_find_device(0x1895, 0x0001, 0);
  129. if (pdev == 0)
  130. return -1;
  131. for (i = 0; i < 6; i++)
  132. pci_read_config_dword (pdev,
  133. PCI_BASE_ADDRESS_0 + i * 4, &bar[i]);
  134. pci_reg_addr = bar[0];
  135. vme_reg_addr = bar[1] + 0x00F00000;
  136. vme_iack_addr = bar[1] + 0x00200000;
  137. vme_asi_addr = bar[3];
  138. pci_write_config_dword (pdev, PCI_COMMAND,
  139. PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
  140. writel(0xFF000000, pci_reg_addr + P_TA1);
  141. writel(0x04, pci_reg_addr + P_IMG_CTRL1);
  142. writel(0xf0000000, pci_reg_addr + P_TA2);
  143. writel(0x04, pci_reg_addr + P_IMG_CTRL2);
  144. writel(0xF1000000, pci_reg_addr + P_TA3);
  145. writel(0x04, pci_reg_addr + P_IMG_CTRL3);
  146. writel(VME_A32_MSTR_BUS, pci_reg_addr + P_TA5);
  147. writel(~(VME_A32_MSTR_SIZE-1), pci_reg_addr + P_AM5);
  148. writel(0x04, pci_reg_addr + P_IMG_CTRL5);
  149. writel(VME_A32_SLV_BUS, pci_reg_addr + W_BA1);
  150. writel(~(VME_A32_SLV_SIZE-1), pci_reg_addr + W_AM1);
  151. writel(VME_A32_SLV_LOCAL, pci_reg_addr + W_TA1);
  152. writel(0x04, pci_reg_addr + W_IMG_CTRL1);
  153. writel(0xF0000000, pci_reg_addr + W_BA2);
  154. writel(0xFF000000, pci_reg_addr + W_AM2);
  155. writel(VME_A24_SLV_LOCAL, pci_reg_addr + W_TA2);
  156. writel(0x04, pci_reg_addr + W_IMG_CTRL2);
  157. writel(0xFF000000, pci_reg_addr + W_BA3);
  158. writel(0xFF000000, pci_reg_addr + W_AM3);
  159. writel(VME_A16_SLV_LOCAL, pci_reg_addr + W_TA3);
  160. writel(0x04, pci_reg_addr + W_IMG_CTRL3);
  161. writel(0x00000001, pci_reg_addr + W_ERR_CS);
  162. writel(0x00000001, pci_reg_addr + P_ERR_CS);
  163. multiv_reset(vme_reg_addr);
  164. writeb(readb(vme_reg_addr + VME_CTRL) | VME_CTRL_SHORT_D,
  165. vme_reg_addr + VME_CTRL);
  166. multiv_auto_slot_id(vme_reg_addr);
  167. return 0;
  168. }