nicstarmac.c 5.8 KB

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