nicstarmac.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * this file included by nicstar.c
  4. */
  5. /*
  6. * nicstarmac.c
  7. * Read this ForeRunner's MAC address from eprom/eeprom
  8. */
  9. #include <linux/kernel.h>
  10. typedef void __iomem *virt_addr_t;
  11. #define CYCLE_DELAY 5
  12. /*
  13. This was the original definition
  14. #define osp_MicroDelay(microsec) \
  15. do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
  16. */
  17. #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
  18. udelay((useconds));}
  19. /*
  20. * The following tables represent the timing diagrams found in
  21. * the Data Sheet for the Xicor X25020 EEProm. The #defines below
  22. * represent the bits in the NICStAR's General Purpose register
  23. * that must be toggled for the corresponding actions on the EEProm
  24. * to occur.
  25. */
  26. /* Write Data To EEProm from SI line on rising edge of CLK */
  27. /* Read Data From EEProm on falling edge of CLK */
  28. #define CS_HIGH 0x0002 /* Chip select high */
  29. #define CS_LOW 0x0000 /* Chip select low (active low) */
  30. #define CLK_HIGH 0x0004 /* Clock high */
  31. #define CLK_LOW 0x0000 /* Clock low */
  32. #define SI_HIGH 0x0001 /* Serial input data high */
  33. #define SI_LOW 0x0000 /* Serial input data low */
  34. /* Read Status Register = 0000 0101b */
  35. #if 0
  36. static u_int32_t rdsrtab[] = {
  37. CS_HIGH | CLK_HIGH,
  38. CS_LOW | 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,
  47. CLK_HIGH, /* 0 */
  48. CLK_LOW | SI_HIGH,
  49. CLK_HIGH | SI_HIGH, /* 1 */
  50. CLK_LOW | SI_LOW,
  51. CLK_HIGH, /* 0 */
  52. CLK_LOW | SI_HIGH,
  53. CLK_HIGH | SI_HIGH /* 1 */
  54. };
  55. #endif /* 0 */
  56. /* Read from EEPROM = 0000 0011b */
  57. static u_int32_t readtab[] = {
  58. /*
  59. CS_HIGH | CLK_HIGH,
  60. */
  61. CS_LOW | 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,
  72. CLK_HIGH, /* 0 */
  73. CLK_LOW | SI_HIGH,
  74. CLK_HIGH | SI_HIGH, /* 1 */
  75. CLK_LOW | SI_HIGH,
  76. CLK_HIGH | SI_HIGH /* 1 */
  77. };
  78. /* Clock to read from/write to the eeprom */
  79. static u_int32_t clocktab[] = {
  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 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 < ARRAY_SIZE(rdsrtab); i++) {
  118. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  119. (val | rdsrtab[i]));
  120. osp_MicroDelay(CYCLE_DELAY);
  121. }
  122. /* Done sending instruction - now pull data off of bit 16, MSB first */
  123. /* Data clocked out of eeprom on falling edge of clock */
  124. rbyte = 0;
  125. for (i = 7, j = 0; i >= 0; i--) {
  126. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  127. (val | clocktab[j++]));
  128. rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  129. & 0x00010000) >> 16) << i);
  130. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  131. (val | clocktab[j++]));
  132. osp_MicroDelay(CYCLE_DELAY);
  133. }
  134. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  135. osp_MicroDelay(CYCLE_DELAY);
  136. return rbyte;
  137. }
  138. #endif /* 0 */
  139. /*
  140. * This routine will clock the Read_data function into the X2520
  141. * eeprom, followed by the address to read from, through the NicSTaR's General
  142. * Purpose register.
  143. */
  144. static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
  145. {
  146. u_int32_t val = 0;
  147. int i, j = 0;
  148. u_int8_t tempread = 0;
  149. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  150. /* Send READ instruction */
  151. for (i = 0; i < ARRAY_SIZE(readtab); i++) {
  152. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  153. (val | readtab[i]));
  154. osp_MicroDelay(CYCLE_DELAY);
  155. }
  156. /* Next, we need to send the byte address to read from */
  157. for (i = 7; i >= 0; i--) {
  158. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  159. (val | clocktab[j++] | ((offset >> i) & 1)));
  160. osp_MicroDelay(CYCLE_DELAY);
  161. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  162. (val | clocktab[j++] | ((offset >> i) & 1)));
  163. osp_MicroDelay(CYCLE_DELAY);
  164. }
  165. j = 0;
  166. /* Now, we can read data from the eeprom by clocking it in */
  167. for (i = 7; i >= 0; i--) {
  168. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  169. (val | clocktab[j++]));
  170. osp_MicroDelay(CYCLE_DELAY);
  171. tempread |=
  172. (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
  173. & 0x00010000) >> 16) << i);
  174. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  175. (val | clocktab[j++]));
  176. osp_MicroDelay(CYCLE_DELAY);
  177. }
  178. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
  179. osp_MicroDelay(CYCLE_DELAY);
  180. return tempread;
  181. }
  182. static void nicstar_init_eprom(virt_addr_t base)
  183. {
  184. u_int32_t val;
  185. /*
  186. * turn chip select off
  187. */
  188. val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
  189. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  190. (val | CS_HIGH | CLK_HIGH));
  191. osp_MicroDelay(CYCLE_DELAY);
  192. NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
  193. (val | CS_HIGH | CLK_LOW));
  194. osp_MicroDelay(CYCLE_DELAY);
  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. }
  202. /*
  203. * This routine will be the interface to the ReadPromByte function
  204. * above.
  205. */
  206. static void
  207. nicstar_read_eprom(virt_addr_t base,
  208. u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
  209. {
  210. u_int i;
  211. for (i = 0; i < nbytes; i++) {
  212. buffer[i] = read_eprom_byte(base, prom_offset);
  213. ++prom_offset;
  214. osp_MicroDelay(CYCLE_DELAY);
  215. }
  216. }