nicstarmac.c 6.5 KB

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