mpc8xx_pcmcia.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. #include <common.h>
  2. #if defined(CONFIG_8xx)
  3. #include <mpc8xx.h>
  4. #endif
  5. #include <pcmcia.h>
  6. #undef CONFIG_PCMCIA
  7. #if defined(CONFIG_CMD_PCMCIA)
  8. #define CONFIG_PCMCIA
  9. #endif
  10. #if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
  11. #define CONFIG_PCMCIA
  12. #endif
  13. #if defined(CONFIG_8xx) && defined(CONFIG_PCMCIA)
  14. #if defined(CONFIG_IDE_8xx_PCCARD)
  15. extern int check_ide_device (int slot);
  16. #endif
  17. extern int pcmcia_hardware_enable (int slot);
  18. extern int pcmcia_voltage_set(int slot, int vcc, int vpp);
  19. #if defined(CONFIG_CMD_PCMCIA)
  20. extern int pcmcia_hardware_disable(int slot);
  21. #endif
  22. static u_int m8xx_get_graycode(u_int size);
  23. #if 0 /* Disabled */
  24. static u_int m8xx_get_speed(u_int ns, u_int is_io);
  25. #endif
  26. /* look up table for pgcrx registers */
  27. u_int *pcmcia_pgcrx[2] = {
  28. &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
  29. &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
  30. };
  31. /*
  32. * Search this table to see if the windowsize is
  33. * supported...
  34. */
  35. #define M8XX_SIZES_NO 32
  36. static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
  37. { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
  38. 0x00000080, 0x00000040, 0x00000010, 0x00000020,
  39. 0x00008000, 0x00004000, 0x00001000, 0x00002000,
  40. 0x00000100, 0x00000200, 0x00000800, 0x00000400,
  41. 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  42. 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
  43. 0x00010000, 0x00020000, 0x00080000, 0x00040000,
  44. 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
  45. /* -------------------------------------------------------------------- */
  46. #ifdef CONFIG_HMI10
  47. #define HMI10_FRAM_TIMING ( PCMCIA_SHT(2) \
  48. | PCMCIA_SST(2) \
  49. | PCMCIA_SL(4))
  50. #endif
  51. #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
  52. #define CFG_PCMCIA_TIMING ( PCMCIA_SHT(9) \
  53. | PCMCIA_SST(3) \
  54. | PCMCIA_SL(12))
  55. #else
  56. #define CFG_PCMCIA_TIMING ( PCMCIA_SHT(2) \
  57. | PCMCIA_SST(4) \
  58. | PCMCIA_SL(9))
  59. #endif
  60. /* -------------------------------------------------------------------- */
  61. int pcmcia_on (void)
  62. {
  63. u_long reg, base;
  64. pcmcia_win_t *win;
  65. u_int slotbit;
  66. u_int rc, slot;
  67. int i;
  68. debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
  69. /* intialize the fixed memory windows */
  70. win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
  71. base = CFG_PCMCIA_MEM_ADDR;
  72. if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
  73. printf ("Cannot set window size to 0x%08x\n",
  74. CFG_PCMCIA_MEM_SIZE);
  75. return (1);
  76. }
  77. slotbit = PCMCIA_SLOT_x;
  78. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  79. win->br = base;
  80. #if (PCMCIA_SOCKETS_NO == 2)
  81. if (i == 4) /* Another slot starting from win 4 */
  82. slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
  83. #endif
  84. switch (i) {
  85. #ifdef CONFIG_IDE_8xx_PCCARD
  86. case 4:
  87. #ifdef CONFIG_HMI10
  88. { /* map FRAM area */
  89. win->or = ( PCMCIA_BSIZE_256K
  90. | PCMCIA_PPS_8
  91. | PCMCIA_PRS_ATTR
  92. | slotbit
  93. | PCMCIA_PV
  94. | HMI10_FRAM_TIMING );
  95. break;
  96. }
  97. #endif
  98. case 0: { /* map attribute memory */
  99. win->or = ( PCMCIA_BSIZE_64M
  100. | PCMCIA_PPS_8
  101. | PCMCIA_PRS_ATTR
  102. | slotbit
  103. | PCMCIA_PV
  104. | CFG_PCMCIA_TIMING );
  105. break;
  106. }
  107. case 5:
  108. case 1: { /* map I/O window for data reg */
  109. win->or = ( PCMCIA_BSIZE_1K
  110. | PCMCIA_PPS_16
  111. | PCMCIA_PRS_IO
  112. | slotbit
  113. | PCMCIA_PV
  114. | CFG_PCMCIA_TIMING );
  115. break;
  116. }
  117. case 6:
  118. case 2: { /* map I/O window for cmd/ctrl reg block */
  119. win->or = ( PCMCIA_BSIZE_1K
  120. | PCMCIA_PPS_8
  121. | PCMCIA_PRS_IO
  122. | slotbit
  123. | PCMCIA_PV
  124. | CFG_PCMCIA_TIMING );
  125. break;
  126. }
  127. #endif /* CONFIG_IDE_8xx_PCCARD */
  128. #ifdef CONFIG_HMI10
  129. case 3: { /* map I/O window for 4xUART data/ctrl */
  130. win->br += 0x40000;
  131. win->or = ( PCMCIA_BSIZE_256K
  132. | PCMCIA_PPS_8
  133. | PCMCIA_PRS_IO
  134. | slotbit
  135. | PCMCIA_PV
  136. | CFG_PCMCIA_TIMING );
  137. break;
  138. }
  139. #endif /* CONFIG_HMI10 */
  140. default: /* set to not valid */
  141. win->or = 0;
  142. break;
  143. }
  144. debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
  145. i, win->br, win->or);
  146. base += CFG_PCMCIA_MEM_SIZE;
  147. ++win;
  148. }
  149. for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
  150. /* turn off voltage */
  151. if ((rc = pcmcia_voltage_set(slot, 0, 0)))
  152. continue;
  153. /* Enable external hardware */
  154. if ((rc = pcmcia_hardware_enable(slot)))
  155. continue;
  156. #ifdef CONFIG_IDE_8xx_PCCARD
  157. if ((rc = check_ide_device(i)))
  158. continue;
  159. #endif
  160. }
  161. return rc;
  162. }
  163. #if defined(CONFIG_CMD_PCMCIA)
  164. int pcmcia_off (void)
  165. {
  166. int i;
  167. pcmcia_win_t *win;
  168. printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
  169. /* clear interrupt state, and disable interrupts */
  170. ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
  171. ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
  172. /* turn off interrupt and disable CxOE */
  173. PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
  174. /* turn off memory windows */
  175. win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
  176. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  177. /* disable memory window */
  178. win->or = 0;
  179. ++win;
  180. }
  181. /* turn off voltage */
  182. pcmcia_voltage_set(_slot_, 0, 0);
  183. /* disable external hardware */
  184. printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
  185. pcmcia_hardware_disable(_slot_);
  186. return 0;
  187. }
  188. #endif
  189. static u_int m8xx_get_graycode(u_int size)
  190. {
  191. u_int k;
  192. for (k = 0; k < M8XX_SIZES_NO; k++) {
  193. if(m8xx_size_to_gray[k] == size)
  194. break;
  195. }
  196. if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
  197. k = -1;
  198. return k;
  199. }
  200. #if 0
  201. #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  202. /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
  203. * SYPCR is write once only, therefore must the slowest memory be faster
  204. * than the bus monitor or we will get a machine check due to the bus timeout.
  205. */
  206. #undef PCMCIA_BMT_LIMIT
  207. #define PCMCIA_BMT_LIMIT (6*8)
  208. #endif
  209. static u_int m8xx_get_speed(u_int ns, u_int is_io)
  210. {
  211. u_int reg, clocks, psst, psl, psht;
  212. if(!ns) {
  213. /*
  214. * We get called with IO maps setup to 0ns
  215. * if not specified by the user.
  216. * They should be 255ns.
  217. */
  218. if(is_io)
  219. ns = 255;
  220. else
  221. ns = 100; /* fast memory if 0 */
  222. }
  223. /*
  224. * In PSST, PSL, PSHT fields we tell the controller
  225. * timing parameters in CLKOUT clock cycles.
  226. * CLKOUT is the same as GCLK2_50.
  227. */
  228. /* how we want to adjust the timing - in percent */
  229. #define ADJ 180 /* 80 % longer accesstime - to be sure */
  230. clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
  231. clocks = (clocks * ADJ) / (100*1000);
  232. if(clocks >= PCMCIA_BMT_LIMIT) {
  233. DEBUG(0, "Max access time limit reached\n");
  234. clocks = PCMCIA_BMT_LIMIT-1;
  235. }
  236. psst = clocks / 7; /* setup time */
  237. psht = clocks / 7; /* hold time */
  238. psl = (clocks * 5) / 7; /* strobe length */
  239. psst += clocks - (psst + psht + psl);
  240. reg = psst << 12;
  241. reg |= psl << 7;
  242. reg |= psht << 16;
  243. return reg;
  244. }
  245. #endif /* 0 */
  246. #endif /* CONFIG_8xx && CONFIG_PCMCIA */