thunder_xcv.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2016 Cavium, Inc.
  4. */
  5. #include <linux/acpi.h>
  6. #include <linux/module.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/pci.h>
  9. #include <linux/netdevice.h>
  10. #include <linux/etherdevice.h>
  11. #include <linux/phy.h>
  12. #include <linux/of.h>
  13. #include <linux/of_mdio.h>
  14. #include <linux/of_net.h>
  15. #include "nic.h"
  16. #include "thunder_bgx.h"
  17. #define DRV_NAME "thunder_xcv"
  18. #define DRV_VERSION "1.0"
  19. /* Register offsets */
  20. #define XCV_RESET 0x00
  21. #define PORT_EN BIT_ULL(63)
  22. #define CLK_RESET BIT_ULL(15)
  23. #define DLL_RESET BIT_ULL(11)
  24. #define COMP_EN BIT_ULL(7)
  25. #define TX_PKT_RESET BIT_ULL(3)
  26. #define TX_DATA_RESET BIT_ULL(2)
  27. #define RX_PKT_RESET BIT_ULL(1)
  28. #define RX_DATA_RESET BIT_ULL(0)
  29. #define XCV_DLL_CTL 0x10
  30. #define CLKRX_BYP BIT_ULL(23)
  31. #define CLKTX_BYP BIT_ULL(15)
  32. #define XCV_COMP_CTL 0x20
  33. #define DRV_BYP BIT_ULL(63)
  34. #define XCV_CTL 0x30
  35. #define XCV_INT 0x40
  36. #define XCV_INT_W1S 0x48
  37. #define XCV_INT_ENA_W1C 0x50
  38. #define XCV_INT_ENA_W1S 0x58
  39. #define XCV_INBND_STATUS 0x80
  40. #define XCV_BATCH_CRD_RET 0x100
  41. struct xcv {
  42. void __iomem *reg_base;
  43. struct pci_dev *pdev;
  44. };
  45. static struct xcv *xcv;
  46. /* Supported devices */
  47. static const struct pci_device_id xcv_id_table[] = {
  48. { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xA056) },
  49. { 0, } /* end of table */
  50. };
  51. MODULE_AUTHOR("Cavium Inc");
  52. MODULE_DESCRIPTION("Cavium Thunder RGX/XCV Driver");
  53. MODULE_LICENSE("GPL v2");
  54. MODULE_VERSION(DRV_VERSION);
  55. MODULE_DEVICE_TABLE(pci, xcv_id_table);
  56. void xcv_init_hw(void)
  57. {
  58. u64 cfg;
  59. /* Take DLL out of reset */
  60. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  61. cfg &= ~DLL_RESET;
  62. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  63. /* Take clock tree out of reset */
  64. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  65. cfg &= ~CLK_RESET;
  66. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  67. /* Wait for DLL to lock */
  68. msleep(1);
  69. /* Configure DLL - enable or bypass
  70. * TX no bypass, RX bypass
  71. */
  72. cfg = readq_relaxed(xcv->reg_base + XCV_DLL_CTL);
  73. cfg &= ~0xFF03;
  74. cfg |= CLKRX_BYP;
  75. writeq_relaxed(cfg, xcv->reg_base + XCV_DLL_CTL);
  76. /* Enable compensation controller and force the
  77. * write to be visible to HW by readig back.
  78. */
  79. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  80. cfg |= COMP_EN;
  81. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  82. readq_relaxed(xcv->reg_base + XCV_RESET);
  83. /* Wait for compensation state machine to lock */
  84. msleep(10);
  85. /* enable the XCV block */
  86. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  87. cfg |= PORT_EN;
  88. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  89. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  90. cfg |= CLK_RESET;
  91. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  92. }
  93. EXPORT_SYMBOL(xcv_init_hw);
  94. void xcv_setup_link(bool link_up, int link_speed)
  95. {
  96. u64 cfg;
  97. int speed = 2;
  98. if (!xcv) {
  99. pr_err("XCV init not done, probe may have failed\n");
  100. return;
  101. }
  102. if (link_speed == 100)
  103. speed = 1;
  104. else if (link_speed == 10)
  105. speed = 0;
  106. if (link_up) {
  107. /* set operating speed */
  108. cfg = readq_relaxed(xcv->reg_base + XCV_CTL);
  109. cfg &= ~0x03;
  110. cfg |= speed;
  111. writeq_relaxed(cfg, xcv->reg_base + XCV_CTL);
  112. /* Reset datapaths */
  113. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  114. cfg |= TX_DATA_RESET | RX_DATA_RESET;
  115. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  116. /* Enable the packet flow */
  117. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  118. cfg |= TX_PKT_RESET | RX_PKT_RESET;
  119. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  120. /* Return credits to RGX */
  121. writeq_relaxed(0x01, xcv->reg_base + XCV_BATCH_CRD_RET);
  122. } else {
  123. /* Disable packet flow */
  124. cfg = readq_relaxed(xcv->reg_base + XCV_RESET);
  125. cfg &= ~(TX_PKT_RESET | RX_PKT_RESET);
  126. writeq_relaxed(cfg, xcv->reg_base + XCV_RESET);
  127. readq_relaxed(xcv->reg_base + XCV_RESET);
  128. }
  129. }
  130. EXPORT_SYMBOL(xcv_setup_link);
  131. static int xcv_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  132. {
  133. int err;
  134. struct device *dev = &pdev->dev;
  135. xcv = devm_kzalloc(dev, sizeof(struct xcv), GFP_KERNEL);
  136. if (!xcv)
  137. return -ENOMEM;
  138. xcv->pdev = pdev;
  139. pci_set_drvdata(pdev, xcv);
  140. err = pci_enable_device(pdev);
  141. if (err) {
  142. dev_err(dev, "Failed to enable PCI device\n");
  143. goto err_kfree;
  144. }
  145. err = pci_request_regions(pdev, DRV_NAME);
  146. if (err) {
  147. dev_err(dev, "PCI request regions failed 0x%x\n", err);
  148. goto err_disable_device;
  149. }
  150. /* MAP configuration registers */
  151. xcv->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
  152. if (!xcv->reg_base) {
  153. dev_err(dev, "XCV: Cannot map CSR memory space, aborting\n");
  154. err = -ENOMEM;
  155. goto err_release_regions;
  156. }
  157. return 0;
  158. err_release_regions:
  159. pci_release_regions(pdev);
  160. err_disable_device:
  161. pci_disable_device(pdev);
  162. err_kfree:
  163. devm_kfree(dev, xcv);
  164. xcv = NULL;
  165. return err;
  166. }
  167. static void xcv_remove(struct pci_dev *pdev)
  168. {
  169. struct device *dev = &pdev->dev;
  170. if (xcv) {
  171. devm_kfree(dev, xcv);
  172. xcv = NULL;
  173. }
  174. pci_release_regions(pdev);
  175. pci_disable_device(pdev);
  176. }
  177. static struct pci_driver xcv_driver = {
  178. .name = DRV_NAME,
  179. .id_table = xcv_id_table,
  180. .probe = xcv_probe,
  181. .remove = xcv_remove,
  182. };
  183. static int __init xcv_init_module(void)
  184. {
  185. pr_info("%s, ver %s\n", DRV_NAME, DRV_VERSION);
  186. return pci_register_driver(&xcv_driver);
  187. }
  188. static void __exit xcv_cleanup_module(void)
  189. {
  190. pci_unregister_driver(&xcv_driver);
  191. }
  192. module_init(xcv_init_module);
  193. module_exit(xcv_cleanup_module);