mpc8xx_pcmcia.c 6.6 KB

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