eth_phy_cvitek.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdio.h>
  17. #include <assert.h>
  18. #include <string.h>
  19. #include <stdbool.h>
  20. #include "cvi_eth_phy.h"
  21. #include "mii.h"
  22. // #define CVI_ETH_PHY_LOOPBACK
  23. #define LOOPBACK_XMII2MAC 0x8000
  24. #define LOOPBACK_PCS2MAC 0x2000
  25. #define LOOPBACK_PMA2MAC 0x1000
  26. #define LOOPBACK_RMII2PHY 0x0080
  27. #define EPHY_EFUSE_VALID_BIT_BASE 0x03050120
  28. #define EPHY_EFUSE_TXECHORC_FLAG 0x00000100 // bit 8
  29. #define EPHY_EFUSE_TXITUNE_FLAG 0x00000200 // bit 9
  30. #define EPHY_EFUSE_TXRXTERM_FLAG 0x00000800 // bit 11
  31. static inline bool phy_if_mode_is_rgmii(phy_if_mode_t interface)
  32. {
  33. return interface >= PHY_IF_MODE_RGMII && interface <= PHY_IF_MODE_RGMII_TXID;
  34. }
  35. #if defined(CVI_ETH_PHY_LOOPBACK)
  36. static int cv181x_set_phy_loopback(eth_phy_handle_t handle, phy_loopback_mode_t mode)
  37. {
  38. return 0;
  39. }
  40. #endif
  41. /**
  42. \brief Configure the cv181x before make it start up.
  43. \param[in] handle phy handle
  44. \return error code
  45. */
  46. /* CVITEK cv181x */
  47. int32_t cv181x_config(eth_phy_handle_t handle)
  48. {
  49. assert(handle);
  50. eth_phy_dev_t *dev = (eth_phy_dev_t *)handle;
  51. uint32_t val = 0;
  52. // eth_phy_reset(dev);
  53. // set rg_ephy_apb_rw_sel 0x0804@[0]=1/APB by using APB interface
  54. mmio_write_32(0x03009804, 0x0001);
  55. // Release 0x0800[0]=0/shutdown
  56. // mmio_write_32(0x03009800, 0x0900);
  57. // Release 0x0800[2]=1/dig_rst_n, Let mii_reg can be accessabile
  58. // mmio_write_32(0x03009800, 0x0904);
  59. //mdelay(10);
  60. // ANA INIT (PD/EN), switch to MII-page5
  61. mmio_write_32(0x0300907c, 0x0500);
  62. // Release ANA_PD p5.0x10@[13:8] = 6'b001100
  63. mmio_write_32(0x03009040, 0x0c00);
  64. // Release ANA_EN p5.0x10@[7:0] = 8'b01111110
  65. mmio_write_32(0x03009040, 0x0c7e);
  66. // Wait PLL_Lock, Lock_Status p5.0x12@[15] = 1
  67. //mdelay(1);
  68. // Release 0x0800[1] = 1/ana_rst_n
  69. mmio_write_32(0x03009800, 0x0906);
  70. // ANA INIT
  71. // @Switch to MII-page5
  72. mmio_write_32(0x0300907c, 0x0500);
  73. // Efuse register
  74. // Set Double Bias Current
  75. //Set rg_eth_txitune1 0x03009064 [15:8]
  76. //Set rg_eth_txitune0 0x03009064 [7:0]
  77. if ((mmio_read_32(EPHY_EFUSE_VALID_BIT_BASE) & EPHY_EFUSE_TXITUNE_FLAG) ==
  78. EPHY_EFUSE_TXITUNE_FLAG) {
  79. val = ((mmio_read_32(0x03051024) >> 24) & 0xFF) |
  80. (((mmio_read_32(0x03051024) >> 16) & 0xFF) << 8);
  81. mmio_clrsetbits_32(0x03009064, 0xFFFF, val);
  82. } else
  83. mmio_write_32(0x03009064, 0x5a5a);
  84. // Set Echo_I
  85. // Set rg_eth_txechoiadj 0x03009054 [15:8]
  86. if ((mmio_read_32(EPHY_EFUSE_VALID_BIT_BASE) & EPHY_EFUSE_TXECHORC_FLAG) ==
  87. EPHY_EFUSE_TXECHORC_FLAG) {
  88. mmio_clrsetbits_32(0x03009054, 0xFF00, ((mmio_read_32(0x03051024) >> 8) & 0xFF) << 8);
  89. } else
  90. mmio_write_32(0x03009054, 0x0000);
  91. //Set TX_Rterm & Echo_RC_Delay
  92. // Set rg_eth_txrterm_p1 0x03009058 [11:8]
  93. // Set rg_eth_txrterm 0x03009058 [7:4]
  94. // Set rg_eth_txechorcadj 0x03009058 [3:0]
  95. if ((mmio_read_32(EPHY_EFUSE_VALID_BIT_BASE) & EPHY_EFUSE_TXRXTERM_FLAG) ==
  96. EPHY_EFUSE_TXRXTERM_FLAG) {
  97. val = (((mmio_read_32(0x03051020) >> 28) & 0xF) << 4) |
  98. (((mmio_read_32(0x03051020) >> 24) & 0xF) << 8);
  99. mmio_clrsetbits_32(0x03009058, 0xFF0, val);
  100. } else
  101. mmio_write_32(0x03009058, 0x0bb0);
  102. // ETH_100BaseT
  103. // Set Rise update
  104. mmio_write_32(0x0300905c, 0x0c10);
  105. // Set Falling phase
  106. mmio_write_32(0x03009068, 0x0003);
  107. // Set Double TX Bias Current
  108. mmio_write_32(0x03009054, 0x0000);
  109. // Switch to MII-page16
  110. mmio_write_32(0x0300907c, 0x1000);
  111. // Set MLT3 Positive phase code, Set MLT3 +0
  112. mmio_write_32(0x03009068, 0x1000);
  113. mmio_write_32(0x0300906c, 0x3020);
  114. mmio_write_32(0x03009070, 0x5040);
  115. mmio_write_32(0x03009074, 0x7060);
  116. // Set MLT3 +I
  117. mmio_write_32(0x03009058, 0x1708);
  118. mmio_write_32(0x0300905c, 0x3827);
  119. mmio_write_32(0x03009060, 0x5748);
  120. mmio_write_32(0x03009064, 0x7867);
  121. // Switch to MII-page17
  122. mmio_write_32(0x0300907c, 0x1100);
  123. // Set MLT3 Negative phase code, Set MLT3 -0
  124. mmio_write_32(0x03009040, 0x9080);
  125. mmio_write_32(0x03009044, 0xb0a0);
  126. mmio_write_32(0x03009048, 0xd0c0);
  127. mmio_write_32(0x0300904c, 0xf0e0);
  128. // Set MLT3 -I
  129. mmio_write_32(0x03009050, 0x9788);
  130. mmio_write_32(0x03009054, 0xb8a7);
  131. mmio_write_32(0x03009058, 0xd7c8);
  132. mmio_write_32(0x0300905c, 0xf8e7);
  133. // @Switch to MII-page5
  134. mmio_write_32(0x0300907c, 0x0500);
  135. // En TX_Rterm
  136. mmio_write_32(0x03009040, (0x0001 | mmio_read_32(0x03009040)));
  137. // Link Pulse
  138. // Switch to MII-page10
  139. mmio_write_32(0x0300907c, 0x0a00);
  140. // Set Link Pulse
  141. mmio_write_32(0x03009040, 0x2000);
  142. mmio_write_32(0x03009044, 0x3832);
  143. mmio_write_32(0x03009048, 0x3132);
  144. mmio_write_32(0x0300904c, 0x2d2f);
  145. mmio_write_32(0x03009050, 0x2c2d);
  146. mmio_write_32(0x03009054, 0x1b2b);
  147. mmio_write_32(0x03009058, 0x94a0);
  148. mmio_write_32(0x0300905c, 0x8990);
  149. mmio_write_32(0x03009060, 0x8788);
  150. mmio_write_32(0x03009064, 0x8485);
  151. mmio_write_32(0x03009068, 0x8283);
  152. mmio_write_32(0x0300906c, 0x8182);
  153. mmio_write_32(0x03009070, 0x0081);
  154. // TP_IDLE
  155. // Switch to MII-page11
  156. mmio_write_32(0x0300907c, 0x0b00);
  157. // Set TP_IDLE
  158. mmio_write_32(0x03009040, 0x5252);
  159. mmio_write_32(0x03009044, 0x5252);
  160. mmio_write_32(0x03009048, 0x4B52);
  161. mmio_write_32(0x0300904c, 0x3D47);
  162. mmio_write_32(0x03009050, 0xAA99);
  163. mmio_write_32(0x03009054, 0x989E);
  164. mmio_write_32(0x03009058, 0x9395);
  165. mmio_write_32(0x0300905C, 0x9091);
  166. mmio_write_32(0x03009060, 0x8E8F);
  167. mmio_write_32(0x03009064, 0x8D8E);
  168. mmio_write_32(0x03009068, 0x8C8C);
  169. mmio_write_32(0x0300906C, 0x8B8B);
  170. mmio_write_32(0x03009070, 0x008A);
  171. // ETH 10BaseT Data
  172. // Switch to MII-page13
  173. mmio_write_32(0x0300907c, 0x0d00);
  174. mmio_write_32(0x03009040, 0x1E0A);
  175. mmio_write_32(0x03009044, 0x3862);
  176. mmio_write_32(0x03009048, 0x1E62);
  177. mmio_write_32(0x0300904c, 0x2A08);
  178. mmio_write_32(0x03009050, 0x244C);
  179. mmio_write_32(0x03009054, 0x1A44);
  180. mmio_write_32(0x03009058, 0x061C);
  181. // Switch to MII-page14
  182. mmio_write_32(0x0300907c, 0x0e00);
  183. mmio_write_32(0x03009040, 0x2D30);
  184. mmio_write_32(0x03009044, 0x3470);
  185. mmio_write_32(0x03009048, 0x0648);
  186. mmio_write_32(0x0300904c, 0x261C);
  187. mmio_write_32(0x03009050, 0x3160);
  188. mmio_write_32(0x03009054, 0x2D5E);
  189. // Switch to MII-page15
  190. mmio_write_32(0x0300907c, 0x0f00);
  191. mmio_write_32(0x03009040, 0x2922);
  192. mmio_write_32(0x03009044, 0x366E);
  193. mmio_write_32(0x03009048, 0x0752);
  194. mmio_write_32(0x0300904c, 0x2556);
  195. mmio_write_32(0x03009050, 0x2348);
  196. mmio_write_32(0x03009054, 0x0C30);
  197. // Switch to MII-page16
  198. mmio_write_32(0x0300907c, 0x1000);
  199. mmio_write_32(0x03009040, 0x1E08);
  200. mmio_write_32(0x03009044, 0x3868);
  201. mmio_write_32(0x03009048, 0x1462);
  202. mmio_write_32(0x0300904c, 0x1A0E);
  203. mmio_write_32(0x03009050, 0x305E);
  204. mmio_write_32(0x03009054, 0x2F62);
  205. // LED PAD MUX
  206. mmio_write_32(0x030010e0, 0x05);
  207. mmio_write_32(0x030010e4, 0x05);
  208. //(SD1_CLK selphy)
  209. mmio_write_32(0x050270b0, 0x11111111);
  210. //(SD1_CMD selphy)
  211. mmio_write_32(0x050270b4, 0x11111111);
  212. // LED
  213. // Switch to MII-page1
  214. mmio_write_32(0x0300907c, 0x0100);
  215. // select LED_LNK/SPD/DPX out to LED_PAD
  216. mmio_write_32(0x03009068, (mmio_read_32(0x03009068) & ~0x0f00));
  217. // @Switch to MII-page0
  218. mmio_write_32(0x0300907c, 0x0000);
  219. // PHY_ID
  220. mmio_write_32(0x03009008, 0x0043);
  221. mmio_write_32(0x0300900c, 0x5649);
  222. // Switch to MII-page19
  223. mmio_write_32(0x0300907c, 0x1300);
  224. mmio_write_32(0x03009058, 0x0012);
  225. // set agc max/min swing
  226. mmio_write_32(0x0300905C, 0x6848);
  227. // Switch to MII-page18
  228. mmio_write_32(0x0300907c, 0x1200);
  229. // p18.0x12, lpf
  230. mmio_write_32(0x03009048, 0x0808);
  231. mmio_write_32(0x0300904C, 0x0808);
  232. // hpf
  233. //sean
  234. mmio_write_32(0x03009050, 0x32f8);
  235. mmio_write_32(0x03009054, 0xf8dc);
  236. // Switch to MII-page0
  237. mmio_write_32(0x0300907c, 0x0000);
  238. // EPHY start auto-neg procedure
  239. mmio_write_32(0x03009800, 0x090e);
  240. // switch to MDIO control by ETH_MAC
  241. mmio_write_32(0x03009804, 0x0000);
  242. genphy_config(dev);
  243. #if defined(CVI_ETH_PHY_LOOPBACK)
  244. cv181x_set_phy_loopback(handle, LOOPBACK_PCS2MAC);
  245. #endif
  246. return 0;
  247. }
  248. /**
  249. \brief Parse 88E1xxx's speed and duplex from status register.
  250. \param[in] dev phy device pointer
  251. \return error code
  252. */
  253. static int32_t cv181x_parse_status(eth_phy_dev_t *dev)
  254. {
  255. assert(dev);
  256. assert(dev->priv);
  257. eth_phy_priv_t *priv = dev->priv;
  258. uint8_t phy_addr = dev->phy_addr;
  259. uint16_t mii_reg;
  260. int32_t ret;
  261. ret = eth_phy_read(priv, phy_addr, CVI_MII_BMSR, &mii_reg);
  262. if (ret != 0) {
  263. return ret;
  264. }
  265. if (mii_reg & (CVI_BMSR_100FULL | CVI_BMSR_100HALF))
  266. priv->link_info.speed = CSI_ETH_SPEED_100M;
  267. else
  268. priv->link_info.speed = CSI_ETH_SPEED_10M;
  269. if (mii_reg & (CVI_BMSR_10FULL | CVI_BMSR_100FULL))
  270. priv->link_info.duplex = CSI_ETH_DUPLEX_FULL;
  271. else
  272. priv->link_info.duplex = CSI_ETH_DUPLEX_HALF;
  273. return 0;
  274. }
  275. /**
  276. \brief Start up the 88E1111.
  277. \param[in] handle phy handle
  278. \return error code
  279. */
  280. int32_t cv181x_start(eth_phy_handle_t handle)
  281. {
  282. assert(handle);
  283. eth_phy_dev_t *dev = (eth_phy_dev_t *)handle;
  284. /* Read the Status (2x to make sure link is right) */
  285. genphy_update_link(dev);
  286. return cv181x_parse_status(dev);
  287. }
  288. /**
  289. \brief Halt the cv181x.
  290. \param[in] handle phy handle
  291. \return error code
  292. */
  293. int32_t cv181x_stop(eth_phy_handle_t handle)
  294. {
  295. return 0;
  296. }
  297. /**
  298. \brief Update the cv181x's link state.
  299. \param[in] handle phy handle
  300. \return error code
  301. */
  302. int32_t cv181x_update_link(eth_phy_handle_t handle)
  303. {
  304. assert(handle);
  305. eth_phy_dev_t *dev = (eth_phy_dev_t *)handle;
  306. return cv181x_parse_status(dev);;
  307. }
  308. /* Support for cv181x PHYs */
  309. eth_phy_dev_t cv181x_device = {
  310. .name = "CVITEK,CV181X",
  311. .phy_id = 0x00435649,
  312. .mask = 0xffffffff,
  313. .features = CVI_PHY_BASIC_FEATURES,
  314. .config = &cv181x_config,
  315. .start = &cv181x_start,
  316. .stop = &cv181x_stop,
  317. //.loopback = &cv181x_loopback,
  318. //.update_link = &cv181x_update_link,
  319. };