mpc8xx_pcmcia.c 5.6 KB

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