smsc9303.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * smsc9303.c - routines to initialize SMSC 9303 switch
  3. *
  4. * Copyright (c) 2010 BCT Electronic GmbH
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <config.h>
  10. #include <miiphy.h>
  11. #include <asm/blackfin.h>
  12. #include <asm/gpio.h>
  13. static int smc9303i_write_mii(unsigned char addr, unsigned char reg, unsigned short data)
  14. {
  15. const char *devname = miiphy_get_current_dev();
  16. if (!devname)
  17. return 0;
  18. if (miiphy_write(devname, addr, reg, data) != 0)
  19. return 0;
  20. return 1;
  21. }
  22. static int smc9303i_write_reg(unsigned short reg, unsigned int data)
  23. {
  24. const char *devname = miiphy_get_current_dev();
  25. unsigned char mii_addr = 0x10 | (reg >> 6);
  26. unsigned char mii_reg = (reg & 0x3c) >> 1;
  27. if (!devname)
  28. return 0;
  29. if (miiphy_write(devname, mii_addr, mii_reg|0, data & 0xffff) != 0)
  30. return 0;
  31. if (miiphy_write(devname, mii_addr, mii_reg|1, data >> 16) != 0)
  32. return 0;
  33. return 1;
  34. }
  35. static int smc9303i_read_reg(unsigned short reg, unsigned int *data)
  36. {
  37. const char *devname = miiphy_get_current_dev();
  38. unsigned char mii_addr = 0x10 | (reg >> 6);
  39. unsigned char mii_reg = (reg & 0x3c) >> 1;
  40. unsigned short tmp1, tmp2;
  41. if (!devname)
  42. return 0;
  43. if (miiphy_read(devname, mii_addr, mii_reg|0, &tmp1) != 0)
  44. return 0;
  45. if (miiphy_read(devname, mii_addr, mii_reg|1, &tmp2) != 0)
  46. return 0;
  47. *data = (tmp2 << 16) | tmp1;
  48. return 1;
  49. }
  50. #if 0
  51. static int smc9303i_read_mii(unsigned char addr, unsigned char reg, unsigned short *data)
  52. {
  53. const char *devname = miiphy_get_current_dev();
  54. if (!devname)
  55. return 0;
  56. if (miiphy_read(devname, addr, reg, data) != 0)
  57. return 0;
  58. return 1;
  59. }
  60. #endif
  61. typedef struct {
  62. unsigned short reg;
  63. unsigned int value;
  64. } smsc9303i_config_entry1_t;
  65. static const smsc9303i_config_entry1_t smsc9303i_config_table1[] =
  66. {
  67. {0x1a0, 0x00000006}, /* Port 1 Manual Flow Control Register */
  68. {0x1a4, 0x00000006}, /* Port 2 Manual Flow Control Register */
  69. {0x1a8, 0x00000006}, /* Port 0 Manual Flow Control Register */
  70. };
  71. typedef struct
  72. {
  73. unsigned char addr;
  74. unsigned char reg;
  75. unsigned short value;
  76. } smsc9303i_config_entry2_t;
  77. static const smsc9303i_config_entry2_t smsc9303i_config_table2[] =
  78. {
  79. {0x01, 0x00, 0x0100}, /* Port0 PHY Basic Control Register */
  80. {0x02, 0x00, 0x1100}, /* Port1 PHY Basic Control Register */
  81. {0x03, 0x00, 0x1100}, /* Port2 PHY Basic Control Register */
  82. {0x01, 0x04, 0x0001}, /* Port0 PHY Auto-Negotiation Advertisement Register */
  83. {0x02, 0x04, 0x2de1}, /* Port1 PHY Auto-Negotiation Advertisement Register */
  84. {0x03, 0x04, 0x2de1}, /* Port2 PHY Auto-Negotiation Advertisement Register */
  85. {0x01, 0x11, 0x0000}, /* Port0 PHY Mode Control/Status Register */
  86. {0x02, 0x11, 0x0000}, /* Port1 PHY Mode Control/Status Register */
  87. {0x03, 0x11, 0x0000}, /* Port2 PHY Mode Control/Status Register */
  88. {0x01, 0x12, 0x0021}, /* Port0 PHY Special Modes Register */
  89. {0x02, 0x12, 0x00e2}, /* Port1 PHY Special Modes Register */
  90. {0x03, 0x12, 0x00e3}, /* Port2 PHY Special Modes Register */
  91. {0x01, 0x1b, 0x0000}, /* Port0 PHY Special Control/Status Indication Register */
  92. {0x02, 0x1b, 0x0000}, /* Port1 PHY Special Control/Status Indication Register */
  93. {0x03, 0x1b, 0x0000}, /* Port2 PHY Special Control/Status Indication Register */
  94. {0x01, 0x1e, 0x0000}, /* Port0 PHY Interrupt Source Flags Register */
  95. {0x02, 0x1e, 0x0000}, /* Port1 PHY Interrupt Source Flags Register */
  96. {0x03, 0x1e, 0x0000}, /* Port2 PHY Interrupt Source Flags Register */
  97. };
  98. int init_smsc9303i_mii(void)
  99. {
  100. unsigned int data;
  101. unsigned int i;
  102. printf(" reset SMSC LAN9303i\n");
  103. gpio_request(GPIO_PG10, "smsc9303");
  104. gpio_direction_output(GPIO_PG10, 0);
  105. udelay(10000);
  106. gpio_direction_output(GPIO_PG10, 1);
  107. udelay(10000);
  108. gpio_free(GPIO_PG10);
  109. #if defined(CONFIG_MII_INIT)
  110. mii_init();
  111. #endif
  112. printf(" write SMSC LAN9303i configuration\n");
  113. if (!smc9303i_read_reg(0x50, &data))
  114. return 0;
  115. if ((data >> 16) != 0x9303) {
  116. /* chip id not found */
  117. printf(" error identifying SMSC LAN9303i\n");
  118. return 0;
  119. }
  120. for (i = 0; i < ARRAY_SIZE(smsc9303i_config_table1); i++) {
  121. const smsc9303i_config_entry1_t *entry = &smsc9303i_config_table1[i];
  122. if (!smc9303i_write_reg(entry->reg, entry->value)) {
  123. printf(" error writing SMSC LAN9303i configuration\n");
  124. return 0;
  125. }
  126. }
  127. for (i = 0; i < ARRAY_SIZE(smsc9303i_config_table2); i++) {
  128. const smsc9303i_config_entry2_t *entry = &smsc9303i_config_table2[i];
  129. if (!smc9303i_write_mii(entry->addr, entry->reg, entry->value)) {
  130. printf(" error writing SMSC LAN9303i configuration\n");
  131. return 0;
  132. }
  133. }
  134. return 1;
  135. }