nicstarmac.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * this file included by nicstar.c
  3. */
  4. /*
  5. * nicstarmac.c
  6. * Read this ForeRunner's MAC address from eprom/eeprom
  7. */
  8. #include <linux/kernel.h>
  9. typedef void __iomem *virt_addr_t;
  10. #define CYCLE_DELAY 5
  11. /* This was the original definition
  12. #define osp_MicroDelay(microsec) \
  13. do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
  14. */
  15. #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
  16. udelay((useconds));}
  17. /* The following tables represent the timing diagrams found in
  18. * the Data Sheet for the Xicor X25020 EEProm. The #defines below
  19. * represent the bits in the NICStAR's General Purpose register
  20. * that must be toggled for the corresponding actions on the EEProm
  21. * to occur.
  22. */
  23. /* Write Data To EEProm from SI line on rising edge of CLK */
  24. /* Read Data From EEProm on falling edge of CLK */
  25. #define CS_HIGH 0x0002 /* Chip select high */
  26. #define CS_LOW 0x0000 /* Chip select low (active low)*/
  27. #define CLK_HIGH 0x0004 /* Clock high */
  28. #define CLK_LOW 0x0000 /* Clock low */
  29. #define SI_HIGH 0x0001 /* Serial input data high */
  30. #define SI_LOW 0x0000 /* Serial input data low */
  31. /* Read Status Register = 0000 0101b */
  32. #if 0
  33. static u_int32_t rdsrtab[] =
  34. {
  35. CS_HIGH | CLK_HIGH,
  36. CS_LOW | CLK_LOW,
  37. CLK_HIGH, /* 0 */
  38. CLK_LOW,
  39. CLK_HIGH, /* 0 */
  40. CLK_LOW,
  41. CLK_HIGH, /* 0 */
  42. CLK_LOW,
  43. CLK_HIGH, /* 0 */
  44. CLK_LOW,
  45. CLK_HIGH, /* 0 */
  46. CLK_LOW | SI_HIGH,
  47. CLK_HIGH | SI_HIGH, /* 1 */
  48. CLK_LOW | SI_LOW,
  49. CLK_HIGH, /* 0 */
  50. CLK_LOW | SI_HIGH,
  51. CLK_HIGH | SI_HIGH /* 1 */
  52. };
  53. #endif /* 0 */
  54. /* Read from EEPROM = 0000 0011b */
  55. static u_int32_t readtab[] =
  56. {
  57. /*
  58. CS_HIGH | CLK_HIGH,
  59. */
  60. CS_LOW | CLK_LOW,
  61. CLK_HIGH, /* 0 */
  62. CLK_LOW,
  63. CLK_HIGH, /* 0 */
  64. CLK_LOW,
  65. CLK_HIGH, /* 0 */
  66. CLK_LOW,
  67. CLK_HIGH, /* 0 */
  68. CLK_LOW,
  69. CLK_HIGH, /* 0 */
  70. CLK_LOW,
  71. CLK_HIGH, /* 0 */
  72. CLK_LOW | SI_HIGH,
  73. CLK_HIGH | SI_HIGH, /* 1 */
  74. CLK_LOW | SI_HIGH,
  75. CLK_HIGH | SI_HIGH /* 1 */
  76. };
  77. /* Clock to read from/write to the eeprom */
  78. static u_int32_t clocktab[] =
  79. {
  80. CLK_LOW,
  81. CLK_HIGH,
  82. CLK_LOW,
  83. CLK_HIGH,
  84. CLK_LOW,
  85. CLK_HIGH,
  86. CLK_LOW,
  87. CLK_HIGH,
  88. CLK_LOW,
  89. CLK_HIGH,
  90. CLK_LOW,
  91. CLK_HIGH,
  92. CLK_LOW,
  93. CLK_HIGH,
  94. CLK_LOW,
  95. CLK_HIGH,
  96. CLK_LOW
  97. };
  98. #define NICSTAR_REG_WRITE(bs, reg, val) \
  99. while ( readl(bs + STAT) & 0x0200 ) ; \
  100. writel((val),(base)+(reg))
  101. #define NICSTAR_REG_READ(bs, reg) \
  102. readl((base)+(reg))
  103. #define NICSTAR_REG_GENERAL_PURPOSE GP
  104. /*
  105. * This routine will clock the Read_Status_reg function into the X2520
  106. * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
  107. * register.
  108. */
  109. #if 0
  110. u_int32_t
  111. nicstar_read_eprom_status( virt_addr_t base )
  112. {
  113. u_int32_t val;
  114. u_int32_t rbyte;
  115. int32_t i, j;
  116. /* Send read instruction */
  117. val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
  118. for (i=0; i<ARRAY_SIZE(rdsrtab); i++)
  119. {
  120. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  121. (val | rdsrtab[i]) );
  122. osp_MicroDelay( CYCLE_DELAY );
  123. }
  124. /* Done sending instruction - now pull data off of bit 16, MSB first */
  125. /* Data clocked out of eeprom on falling edge of clock */
  126. rbyte = 0;
  127. for (i=7, j=0; i>=0; i--)
  128. {
  129. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  130. (val | clocktab[j++]) );
  131. rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE)
  132. & 0x00010000) >> 16) << i);
  133. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  134. (val | clocktab[j++]) );
  135. osp_MicroDelay( CYCLE_DELAY );
  136. }
  137. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
  138. osp_MicroDelay( CYCLE_DELAY );
  139. return rbyte;
  140. }
  141. #endif /* 0 */
  142. /*
  143. * This routine will clock the Read_data function into the X2520
  144. * eeprom, followed by the address to read from, through the NicSTaR's General
  145. * Purpose register.
  146. */
  147. static u_int8_t
  148. read_eprom_byte(virt_addr_t base, u_int8_t offset)
  149. {
  150. u_int32_t val = 0;
  151. int i,j=0;
  152. u_int8_t tempread = 0;
  153. val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
  154. /* Send READ instruction */
  155. for (i=0; i<ARRAY_SIZE(readtab); i++)
  156. {
  157. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  158. (val | readtab[i]) );
  159. osp_MicroDelay( CYCLE_DELAY );
  160. }
  161. /* Next, we need to send the byte address to read from */
  162. for (i=7; i>=0; i--)
  163. {
  164. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  165. (val | clocktab[j++] | ((offset >> i) & 1) ) );
  166. osp_MicroDelay(CYCLE_DELAY);
  167. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  168. (val | clocktab[j++] | ((offset >> i) & 1) ) );
  169. osp_MicroDelay( CYCLE_DELAY );
  170. }
  171. j = 0;
  172. /* Now, we can read data from the eeprom by clocking it in */
  173. for (i=7; i>=0; i--)
  174. {
  175. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  176. (val | clocktab[j++]) );
  177. osp_MicroDelay( CYCLE_DELAY );
  178. tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE )
  179. & 0x00010000) >> 16) << i);
  180. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
  181. (val | clocktab[j++]) );
  182. osp_MicroDelay( CYCLE_DELAY );
  183. }
  184. NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 );
  185. osp_MicroDelay( CYCLE_DELAY );
  186. return tempread;
  187. }
  188. static void
  189. nicstar_init_eprom( virt_addr_t base )
  190. {
  191. u_int32_t val;
  192. /*
  193. * turn chip select off
  194. */
  195. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  196. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  197. (val | CS_HIGH | CLK_HIGH));
  198. osp_MicroDelay( CYCLE_DELAY );
  199. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  200. (val | CS_HIGH | CLK_LOW));
  201. osp_MicroDelay( CYCLE_DELAY );
  202. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  203. (val | CS_HIGH | CLK_HIGH));
  204. osp_MicroDelay( CYCLE_DELAY );
  205. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  206. (val | CS_HIGH | CLK_LOW));
  207. osp_MicroDelay( CYCLE_DELAY );
  208. }
  209. /*
  210. * This routine will be the interface to the ReadPromByte function
  211. * above.
  212. */
  213. static void
  214. nicstar_read_eprom(
  215. virt_addr_t base,
  216. u_int8_t prom_offset,
  217. u_int8_t *buffer,
  218. u_int32_t nbytes )
  219. {
  220. u_int i;
  221. for (i=0; i<nbytes; i++)
  222. {
  223. buffer[i] = read_eprom_byte( base, prom_offset );
  224. ++prom_offset;
  225. osp_MicroDelay( CYCLE_DELAY );
  226. }
  227. }
  228. /*
  229. void osp_MicroDelay(int x) {
  230. }
  231. */