mpc8xx_pcmcia.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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. #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
  45. #define CONFIG_SYS_PCMCIA_TIMING ( PCMCIA_SHT(9) \
  46. | PCMCIA_SST(3) \
  47. | PCMCIA_SL(12))
  48. #else
  49. #define CONFIG_SYS_PCMCIA_TIMING ( PCMCIA_SHT(2) \
  50. | PCMCIA_SST(4) \
  51. | PCMCIA_SL(9))
  52. #endif
  53. /* -------------------------------------------------------------------- */
  54. int pcmcia_on (void)
  55. {
  56. u_long reg, base;
  57. pcmcia_win_t *win;
  58. u_int slotbit;
  59. u_int rc, slot;
  60. int i;
  61. debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
  62. /* intialize the fixed memory windows */
  63. win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
  64. base = CONFIG_SYS_PCMCIA_MEM_ADDR;
  65. if((reg = m8xx_get_graycode(CONFIG_SYS_PCMCIA_MEM_SIZE)) == -1) {
  66. printf ("Cannot set window size to 0x%08x\n",
  67. CONFIG_SYS_PCMCIA_MEM_SIZE);
  68. return (1);
  69. }
  70. slotbit = PCMCIA_SLOT_x;
  71. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  72. win->br = base;
  73. #if (PCMCIA_SOCKETS_NO == 2)
  74. if (i == 4) /* Another slot starting from win 4 */
  75. slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
  76. #endif
  77. switch (i) {
  78. #ifdef CONFIG_IDE_8xx_PCCARD
  79. case 4:
  80. case 0: { /* map attribute memory */
  81. win->or = ( PCMCIA_BSIZE_64M
  82. | PCMCIA_PPS_8
  83. | PCMCIA_PRS_ATTR
  84. | slotbit
  85. | PCMCIA_PV
  86. | CONFIG_SYS_PCMCIA_TIMING );
  87. break;
  88. }
  89. case 5:
  90. case 1: { /* map I/O window for data reg */
  91. win->or = ( PCMCIA_BSIZE_1K
  92. | PCMCIA_PPS_16
  93. | PCMCIA_PRS_IO
  94. | slotbit
  95. | PCMCIA_PV
  96. | CONFIG_SYS_PCMCIA_TIMING );
  97. break;
  98. }
  99. case 6:
  100. case 2: { /* map I/O window for cmd/ctrl reg block */
  101. win->or = ( PCMCIA_BSIZE_1K
  102. | PCMCIA_PPS_8
  103. | PCMCIA_PRS_IO
  104. | slotbit
  105. | PCMCIA_PV
  106. | CONFIG_SYS_PCMCIA_TIMING );
  107. break;
  108. }
  109. #endif /* CONFIG_IDE_8xx_PCCARD */
  110. default: /* set to not valid */
  111. win->or = 0;
  112. break;
  113. }
  114. debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
  115. i, win->br, win->or);
  116. base += CONFIG_SYS_PCMCIA_MEM_SIZE;
  117. ++win;
  118. }
  119. for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
  120. /* turn off voltage */
  121. if ((rc = pcmcia_voltage_set(slot, 0, 0)))
  122. continue;
  123. /* Enable external hardware */
  124. if ((rc = pcmcia_hardware_enable(slot)))
  125. continue;
  126. #ifdef CONFIG_IDE_8xx_PCCARD
  127. if ((rc = check_ide_device(i)))
  128. continue;
  129. #endif
  130. }
  131. return rc;
  132. }
  133. #if defined(CONFIG_CMD_PCMCIA)
  134. int pcmcia_off (void)
  135. {
  136. int i;
  137. pcmcia_win_t *win;
  138. printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
  139. /* clear interrupt state, and disable interrupts */
  140. ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
  141. ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
  142. /* turn off interrupt and disable CxOE */
  143. PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
  144. /* turn off memory windows */
  145. win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
  146. for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
  147. /* disable memory window */
  148. win->or = 0;
  149. ++win;
  150. }
  151. /* turn off voltage */
  152. pcmcia_voltage_set(_slot_, 0, 0);
  153. /* disable external hardware */
  154. printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
  155. pcmcia_hardware_disable(_slot_);
  156. return 0;
  157. }
  158. #endif
  159. static u_int m8xx_get_graycode(u_int size)
  160. {
  161. u_int k;
  162. for (k = 0; k < M8XX_SIZES_NO; k++) {
  163. if(m8xx_size_to_gray[k] == size)
  164. break;
  165. }
  166. if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
  167. k = -1;
  168. return k;
  169. }
  170. #if 0
  171. #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  172. /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
  173. * SYPCR is write once only, therefore must the slowest memory be faster
  174. * than the bus monitor or we will get a machine check due to the bus timeout.
  175. */
  176. #undef PCMCIA_BMT_LIMIT
  177. #define PCMCIA_BMT_LIMIT (6*8)
  178. #endif
  179. static u_int m8xx_get_speed(u_int ns, u_int is_io)
  180. {
  181. u_int reg, clocks, psst, psl, psht;
  182. if(!ns) {
  183. /*
  184. * We get called with IO maps setup to 0ns
  185. * if not specified by the user.
  186. * They should be 255ns.
  187. */
  188. if(is_io)
  189. ns = 255;
  190. else
  191. ns = 100; /* fast memory if 0 */
  192. }
  193. /*
  194. * In PSST, PSL, PSHT fields we tell the controller
  195. * timing parameters in CLKOUT clock cycles.
  196. * CLKOUT is the same as GCLK2_50.
  197. */
  198. /* how we want to adjust the timing - in percent */
  199. #define ADJ 180 /* 80 % longer accesstime - to be sure */
  200. clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
  201. clocks = (clocks * ADJ) / (100*1000);
  202. if(clocks >= PCMCIA_BMT_LIMIT) {
  203. DEBUG(0, "Max access time limit reached\n");
  204. clocks = PCMCIA_BMT_LIMIT-1;
  205. }
  206. psst = clocks / 7; /* setup time */
  207. psht = clocks / 7; /* hold time */
  208. psl = (clocks * 5) / 7; /* strobe length */
  209. psst += clocks - (psst + psht + psl);
  210. reg = psst << 12;
  211. reg |= psl << 7;
  212. reg |= psht << 16;
  213. return reg;
  214. }
  215. #endif /* 0 */
  216. #endif /* CONFIG_PCMCIA */