hns_mdio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) 2014-2015 Hisilicon Limited.
  4. */
  5. #include <linux/acpi.h>
  6. #include <linux/errno.h>
  7. #include <linux/etherdevice.h>
  8. #include <linux/init.h>
  9. #include <linux/kernel.h>
  10. #include <linux/mfd/syscon.h>
  11. #include <linux/module.h>
  12. #include <linux/mutex.h>
  13. #include <linux/netdevice.h>
  14. #include <linux/of_address.h>
  15. #include <linux/of.h>
  16. #include <linux/of_mdio.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/phy.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/regmap.h>
  21. #define MDIO_DRV_NAME "Hi-HNS_MDIO"
  22. #define MDIO_BUS_NAME "Hisilicon MII Bus"
  23. #define MDIO_TIMEOUT 1000000
  24. struct hns_mdio_sc_reg {
  25. u16 mdio_clk_en;
  26. u16 mdio_clk_dis;
  27. u16 mdio_reset_req;
  28. u16 mdio_reset_dreq;
  29. u16 mdio_clk_st;
  30. u16 mdio_reset_st;
  31. };
  32. struct hns_mdio_device {
  33. u8 __iomem *vbase; /* mdio reg base address */
  34. struct regmap *subctrl_vbase;
  35. struct hns_mdio_sc_reg sc_reg;
  36. };
  37. /* mdio reg */
  38. #define MDIO_COMMAND_REG 0x0
  39. #define MDIO_ADDR_REG 0x4
  40. #define MDIO_WDATA_REG 0x8
  41. #define MDIO_RDATA_REG 0xc
  42. #define MDIO_STA_REG 0x10
  43. /* cfg phy bit map */
  44. #define MDIO_CMD_DEVAD_M 0x1f
  45. #define MDIO_CMD_DEVAD_S 0
  46. #define MDIO_CMD_PRTAD_M 0x1f
  47. #define MDIO_CMD_PRTAD_S 5
  48. #define MDIO_CMD_OP_S 10
  49. #define MDIO_CMD_ST_S 12
  50. #define MDIO_CMD_START_B 14
  51. #define MDIO_ADDR_DATA_M 0xffff
  52. #define MDIO_ADDR_DATA_S 0
  53. #define MDIO_WDATA_DATA_M 0xffff
  54. #define MDIO_WDATA_DATA_S 0
  55. #define MDIO_RDATA_DATA_M 0xffff
  56. #define MDIO_RDATA_DATA_S 0
  57. #define MDIO_STATE_STA_B 0
  58. enum mdio_st_clause {
  59. MDIO_ST_CLAUSE_45 = 0,
  60. MDIO_ST_CLAUSE_22
  61. };
  62. enum mdio_c22_op_seq {
  63. MDIO_C22_WRITE = 1,
  64. MDIO_C22_READ = 2
  65. };
  66. enum mdio_c45_op_seq {
  67. MDIO_C45_WRITE_ADDR = 0,
  68. MDIO_C45_WRITE_DATA,
  69. MDIO_C45_READ_INCREMENT,
  70. MDIO_C45_READ
  71. };
  72. /* peri subctrl reg */
  73. #define MDIO_SC_CLK_EN 0x338
  74. #define MDIO_SC_CLK_DIS 0x33C
  75. #define MDIO_SC_RESET_REQ 0xA38
  76. #define MDIO_SC_RESET_DREQ 0xA3C
  77. #define MDIO_SC_CLK_ST 0x531C
  78. #define MDIO_SC_RESET_ST 0x5A1C
  79. static void mdio_write_reg(u8 __iomem *base, u32 reg, u32 value)
  80. {
  81. writel_relaxed(value, base + reg);
  82. }
  83. #define MDIO_WRITE_REG(a, reg, value) \
  84. mdio_write_reg((a)->vbase, (reg), (value))
  85. static u32 mdio_read_reg(u8 __iomem *base, u32 reg)
  86. {
  87. return readl_relaxed(base + reg);
  88. }
  89. #define mdio_set_field(origin, mask, shift, val) \
  90. do { \
  91. (origin) &= (~((mask) << (shift))); \
  92. (origin) |= (((val) & (mask)) << (shift)); \
  93. } while (0)
  94. #define mdio_get_field(origin, mask, shift) (((origin) >> (shift)) & (mask))
  95. static void mdio_set_reg_field(u8 __iomem *base, u32 reg, u32 mask, u32 shift,
  96. u32 val)
  97. {
  98. u32 origin = mdio_read_reg(base, reg);
  99. mdio_set_field(origin, mask, shift, val);
  100. mdio_write_reg(base, reg, origin);
  101. }
  102. #define MDIO_SET_REG_FIELD(dev, reg, mask, shift, val) \
  103. mdio_set_reg_field((dev)->vbase, (reg), (mask), (shift), (val))
  104. static u32 mdio_get_reg_field(u8 __iomem *base, u32 reg, u32 mask, u32 shift)
  105. {
  106. u32 origin;
  107. origin = mdio_read_reg(base, reg);
  108. return mdio_get_field(origin, mask, shift);
  109. }
  110. #define MDIO_GET_REG_FIELD(dev, reg, mask, shift) \
  111. mdio_get_reg_field((dev)->vbase, (reg), (mask), (shift))
  112. #define MDIO_GET_REG_BIT(dev, reg, bit) \
  113. mdio_get_reg_field((dev)->vbase, (reg), 0x1ull, (bit))
  114. #define MDIO_CHECK_SET_ST 1
  115. #define MDIO_CHECK_CLR_ST 0
  116. static int mdio_sc_cfg_reg_write(struct hns_mdio_device *mdio_dev,
  117. u32 cfg_reg, u32 set_val,
  118. u32 st_reg, u32 st_msk, u8 check_st)
  119. {
  120. u32 time_cnt;
  121. u32 reg_value;
  122. int ret;
  123. regmap_write(mdio_dev->subctrl_vbase, cfg_reg, set_val);
  124. for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
  125. ret = regmap_read(mdio_dev->subctrl_vbase, st_reg, &reg_value);
  126. if (ret)
  127. return ret;
  128. reg_value &= st_msk;
  129. if ((!!check_st) == (!!reg_value))
  130. break;
  131. }
  132. if ((!!check_st) != (!!reg_value))
  133. return -EBUSY;
  134. return 0;
  135. }
  136. static int hns_mdio_wait_ready(struct mii_bus *bus)
  137. {
  138. struct hns_mdio_device *mdio_dev = bus->priv;
  139. u32 cmd_reg_value;
  140. int i;
  141. /* waitting for MDIO_COMMAND_REG 's mdio_start==0 */
  142. /* after that can do read or write*/
  143. for (i = 0; i < MDIO_TIMEOUT; i++) {
  144. cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
  145. MDIO_COMMAND_REG,
  146. MDIO_CMD_START_B);
  147. if (!cmd_reg_value)
  148. break;
  149. }
  150. if ((i == MDIO_TIMEOUT) && cmd_reg_value)
  151. return -ETIMEDOUT;
  152. return 0;
  153. }
  154. static void hns_mdio_cmd_write(struct hns_mdio_device *mdio_dev,
  155. u8 is_c45, u8 op, u8 phy_id, u16 cmd)
  156. {
  157. u32 cmd_reg_value;
  158. u8 st = is_c45 ? MDIO_ST_CLAUSE_45 : MDIO_ST_CLAUSE_22;
  159. cmd_reg_value = st << MDIO_CMD_ST_S;
  160. cmd_reg_value |= op << MDIO_CMD_OP_S;
  161. cmd_reg_value |=
  162. (phy_id & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
  163. cmd_reg_value |= (cmd & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
  164. cmd_reg_value |= 1 << MDIO_CMD_START_B;
  165. MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
  166. }
  167. /**
  168. * hns_mdio_write - access phy register
  169. * @bus: mdio bus
  170. * @phy_id: phy id
  171. * @regnum: register num
  172. * @value: register value
  173. *
  174. * Return 0 on success, negative on failure
  175. */
  176. static int hns_mdio_write(struct mii_bus *bus,
  177. int phy_id, int regnum, u16 data)
  178. {
  179. int ret;
  180. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  181. u8 devad = ((regnum >> 16) & 0x1f);
  182. u8 is_c45 = !!(regnum & MII_ADDR_C45);
  183. u16 reg = (u16)(regnum & 0xffff);
  184. u8 op;
  185. u16 cmd_reg_cfg;
  186. dev_dbg(&bus->dev, "mdio write %s,base is %p\n",
  187. bus->id, mdio_dev->vbase);
  188. dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x, write data=%d\n",
  189. phy_id, is_c45, devad, reg, data);
  190. /* wait for ready */
  191. ret = hns_mdio_wait_ready(bus);
  192. if (ret) {
  193. dev_err(&bus->dev, "MDIO bus is busy\n");
  194. return ret;
  195. }
  196. if (!is_c45) {
  197. cmd_reg_cfg = reg;
  198. op = MDIO_C22_WRITE;
  199. } else {
  200. /* config the cmd-reg to write addr*/
  201. MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
  202. MDIO_ADDR_DATA_S, reg);
  203. hns_mdio_cmd_write(mdio_dev, is_c45,
  204. MDIO_C45_WRITE_ADDR, phy_id, devad);
  205. /* check for read or write opt is finished */
  206. ret = hns_mdio_wait_ready(bus);
  207. if (ret) {
  208. dev_err(&bus->dev, "MDIO bus is busy\n");
  209. return ret;
  210. }
  211. /* config the data needed writing */
  212. cmd_reg_cfg = devad;
  213. op = MDIO_C45_WRITE_DATA;
  214. }
  215. MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M,
  216. MDIO_WDATA_DATA_S, data);
  217. hns_mdio_cmd_write(mdio_dev, is_c45, op, phy_id, cmd_reg_cfg);
  218. return 0;
  219. }
  220. /**
  221. * hns_mdio_read - access phy register
  222. * @bus: mdio bus
  223. * @phy_id: phy id
  224. * @regnum: register num
  225. * @value: register value
  226. *
  227. * Return phy register value
  228. */
  229. static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
  230. {
  231. int ret;
  232. u16 reg_val = 0;
  233. u8 devad = ((regnum >> 16) & 0x1f);
  234. u8 is_c45 = !!(regnum & MII_ADDR_C45);
  235. u16 reg = (u16)(regnum & 0xffff);
  236. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  237. dev_dbg(&bus->dev, "mdio read %s,base is %p\n",
  238. bus->id, mdio_dev->vbase);
  239. dev_dbg(&bus->dev, "phy id=%d, is_c45=%d, devad=%d, reg=%#x!\n",
  240. phy_id, is_c45, devad, reg);
  241. /* Step 1: wait for ready */
  242. ret = hns_mdio_wait_ready(bus);
  243. if (ret) {
  244. dev_err(&bus->dev, "MDIO bus is busy\n");
  245. return ret;
  246. }
  247. if (!is_c45) {
  248. hns_mdio_cmd_write(mdio_dev, is_c45,
  249. MDIO_C22_READ, phy_id, reg);
  250. } else {
  251. MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
  252. MDIO_ADDR_DATA_S, reg);
  253. /* Step 2; config the cmd-reg to write addr*/
  254. hns_mdio_cmd_write(mdio_dev, is_c45,
  255. MDIO_C45_WRITE_ADDR, phy_id, devad);
  256. /* Step 3: check for read or write opt is finished */
  257. ret = hns_mdio_wait_ready(bus);
  258. if (ret) {
  259. dev_err(&bus->dev, "MDIO bus is busy\n");
  260. return ret;
  261. }
  262. hns_mdio_cmd_write(mdio_dev, is_c45,
  263. MDIO_C45_READ, phy_id, devad);
  264. }
  265. /* Step 5: waitting for MDIO_COMMAND_REG 's mdio_start==0,*/
  266. /* check for read or write opt is finished */
  267. ret = hns_mdio_wait_ready(bus);
  268. if (ret) {
  269. dev_err(&bus->dev, "MDIO bus is busy\n");
  270. return ret;
  271. }
  272. reg_val = MDIO_GET_REG_BIT(mdio_dev, MDIO_STA_REG, MDIO_STATE_STA_B);
  273. if (reg_val) {
  274. dev_err(&bus->dev, " ERROR! MDIO Read failed!\n");
  275. return -EBUSY;
  276. }
  277. /* Step 6; get out data*/
  278. reg_val = (u16)MDIO_GET_REG_FIELD(mdio_dev, MDIO_RDATA_REG,
  279. MDIO_RDATA_DATA_M, MDIO_RDATA_DATA_S);
  280. return reg_val;
  281. }
  282. /**
  283. * hns_mdio_reset - reset mdio bus
  284. * @bus: mdio bus
  285. *
  286. * Return 0 on success, negative on failure
  287. */
  288. static int hns_mdio_reset(struct mii_bus *bus)
  289. {
  290. struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
  291. const struct hns_mdio_sc_reg *sc_reg;
  292. int ret;
  293. if (dev_of_node(bus->parent)) {
  294. if (!mdio_dev->subctrl_vbase) {
  295. dev_err(&bus->dev, "mdio sys ctl reg has not maped\n");
  296. return -ENODEV;
  297. }
  298. sc_reg = &mdio_dev->sc_reg;
  299. /* 1. reset req, and read reset st check */
  300. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_req,
  301. 0x1, sc_reg->mdio_reset_st, 0x1,
  302. MDIO_CHECK_SET_ST);
  303. if (ret) {
  304. dev_err(&bus->dev, "MDIO reset fail\n");
  305. return ret;
  306. }
  307. /* 2. dis clk, and read clk st check */
  308. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_dis,
  309. 0x1, sc_reg->mdio_clk_st, 0x1,
  310. MDIO_CHECK_CLR_ST);
  311. if (ret) {
  312. dev_err(&bus->dev, "MDIO dis clk fail\n");
  313. return ret;
  314. }
  315. /* 3. reset dreq, and read reset st check */
  316. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_reset_dreq,
  317. 0x1, sc_reg->mdio_reset_st, 0x1,
  318. MDIO_CHECK_CLR_ST);
  319. if (ret) {
  320. dev_err(&bus->dev, "MDIO dis clk fail\n");
  321. return ret;
  322. }
  323. /* 4. en clk, and read clk st check */
  324. ret = mdio_sc_cfg_reg_write(mdio_dev, sc_reg->mdio_clk_en,
  325. 0x1, sc_reg->mdio_clk_st, 0x1,
  326. MDIO_CHECK_SET_ST);
  327. if (ret)
  328. dev_err(&bus->dev, "MDIO en clk fail\n");
  329. } else if (is_acpi_node(bus->parent->fwnode)) {
  330. acpi_status s;
  331. s = acpi_evaluate_object(ACPI_HANDLE(bus->parent),
  332. "_RST", NULL, NULL);
  333. if (ACPI_FAILURE(s)) {
  334. dev_err(&bus->dev, "Reset failed, return:%#x\n", s);
  335. ret = -EBUSY;
  336. } else {
  337. ret = 0;
  338. }
  339. } else {
  340. dev_err(&bus->dev, "Can not get cfg data from DT or ACPI\n");
  341. ret = -ENXIO;
  342. }
  343. return ret;
  344. }
  345. /**
  346. * hns_mdio_probe - probe mdio device
  347. * @pdev: mdio platform device
  348. *
  349. * Return 0 on success, negative on failure
  350. */
  351. static int hns_mdio_probe(struct platform_device *pdev)
  352. {
  353. struct hns_mdio_device *mdio_dev;
  354. struct mii_bus *new_bus;
  355. int ret = -ENODEV;
  356. if (!pdev) {
  357. dev_err(NULL, "pdev is NULL!\r\n");
  358. return -ENODEV;
  359. }
  360. mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL);
  361. if (!mdio_dev)
  362. return -ENOMEM;
  363. new_bus = devm_mdiobus_alloc(&pdev->dev);
  364. if (!new_bus) {
  365. dev_err(&pdev->dev, "mdiobus_alloc fail!\n");
  366. return -ENOMEM;
  367. }
  368. new_bus->name = MDIO_BUS_NAME;
  369. new_bus->read = hns_mdio_read;
  370. new_bus->write = hns_mdio_write;
  371. new_bus->reset = hns_mdio_reset;
  372. new_bus->priv = mdio_dev;
  373. new_bus->parent = &pdev->dev;
  374. mdio_dev->vbase = devm_platform_ioremap_resource(pdev, 0);
  375. if (IS_ERR(mdio_dev->vbase)) {
  376. ret = PTR_ERR(mdio_dev->vbase);
  377. return ret;
  378. }
  379. platform_set_drvdata(pdev, new_bus);
  380. snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%s", "Mii",
  381. dev_name(&pdev->dev));
  382. if (dev_of_node(&pdev->dev)) {
  383. struct of_phandle_args reg_args;
  384. ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
  385. "subctrl-vbase",
  386. 4,
  387. 0,
  388. &reg_args);
  389. if (!ret) {
  390. mdio_dev->subctrl_vbase =
  391. syscon_node_to_regmap(reg_args.np);
  392. if (IS_ERR(mdio_dev->subctrl_vbase)) {
  393. dev_warn(&pdev->dev, "syscon_node_to_regmap error\n");
  394. mdio_dev->subctrl_vbase = NULL;
  395. } else {
  396. if (reg_args.args_count == 4) {
  397. mdio_dev->sc_reg.mdio_clk_en =
  398. (u16)reg_args.args[0];
  399. mdio_dev->sc_reg.mdio_clk_dis =
  400. (u16)reg_args.args[0] + 4;
  401. mdio_dev->sc_reg.mdio_reset_req =
  402. (u16)reg_args.args[1];
  403. mdio_dev->sc_reg.mdio_reset_dreq =
  404. (u16)reg_args.args[1] + 4;
  405. mdio_dev->sc_reg.mdio_clk_st =
  406. (u16)reg_args.args[2];
  407. mdio_dev->sc_reg.mdio_reset_st =
  408. (u16)reg_args.args[3];
  409. } else {
  410. /* for compatible */
  411. mdio_dev->sc_reg.mdio_clk_en =
  412. MDIO_SC_CLK_EN;
  413. mdio_dev->sc_reg.mdio_clk_dis =
  414. MDIO_SC_CLK_DIS;
  415. mdio_dev->sc_reg.mdio_reset_req =
  416. MDIO_SC_RESET_REQ;
  417. mdio_dev->sc_reg.mdio_reset_dreq =
  418. MDIO_SC_RESET_DREQ;
  419. mdio_dev->sc_reg.mdio_clk_st =
  420. MDIO_SC_CLK_ST;
  421. mdio_dev->sc_reg.mdio_reset_st =
  422. MDIO_SC_RESET_ST;
  423. }
  424. }
  425. } else {
  426. dev_warn(&pdev->dev, "find syscon ret = %#x\n", ret);
  427. mdio_dev->subctrl_vbase = NULL;
  428. }
  429. ret = of_mdiobus_register(new_bus, pdev->dev.of_node);
  430. } else if (is_acpi_node(pdev->dev.fwnode)) {
  431. /* Clear all the IRQ properties */
  432. memset(new_bus->irq, PHY_POLL, 4 * PHY_MAX_ADDR);
  433. /* Mask out all PHYs from auto probing. */
  434. new_bus->phy_mask = ~0;
  435. /* Register the MDIO bus */
  436. ret = mdiobus_register(new_bus);
  437. } else {
  438. dev_err(&pdev->dev, "Can not get cfg data from DT or ACPI\n");
  439. ret = -ENXIO;
  440. }
  441. if (ret) {
  442. dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
  443. platform_set_drvdata(pdev, NULL);
  444. return ret;
  445. }
  446. return 0;
  447. }
  448. /**
  449. * hns_mdio_remove - remove mdio device
  450. * @pdev: mdio platform device
  451. *
  452. * Return 0 on success, negative on failure
  453. */
  454. static int hns_mdio_remove(struct platform_device *pdev)
  455. {
  456. struct mii_bus *bus;
  457. bus = platform_get_drvdata(pdev);
  458. mdiobus_unregister(bus);
  459. platform_set_drvdata(pdev, NULL);
  460. return 0;
  461. }
  462. static const struct of_device_id hns_mdio_match[] = {
  463. {.compatible = "hisilicon,mdio"},
  464. {.compatible = "hisilicon,hns-mdio"},
  465. {}
  466. };
  467. MODULE_DEVICE_TABLE(of, hns_mdio_match);
  468. static const struct acpi_device_id hns_mdio_acpi_match[] = {
  469. { "HISI0141", 0 },
  470. { },
  471. };
  472. MODULE_DEVICE_TABLE(acpi, hns_mdio_acpi_match);
  473. static struct platform_driver hns_mdio_driver = {
  474. .probe = hns_mdio_probe,
  475. .remove = hns_mdio_remove,
  476. .driver = {
  477. .name = MDIO_DRV_NAME,
  478. .of_match_table = hns_mdio_match,
  479. .acpi_match_table = ACPI_PTR(hns_mdio_acpi_match),
  480. },
  481. };
  482. module_platform_driver(hns_mdio_driver);
  483. MODULE_LICENSE("GPL");
  484. MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
  485. MODULE_DESCRIPTION("Hisilicon HNS MDIO driver");
  486. MODULE_ALIAS("platform:" MDIO_DRV_NAME);