pci-layerscape-ep.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * PCIe controller EP driver for Freescale Layerscape SoCs
  4. *
  5. * Copyright (C) 2018 NXP Semiconductor.
  6. *
  7. * Author: Xiaowei Bao <[email protected]>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/init.h>
  11. #include <linux/of_pci.h>
  12. #include <linux/of_platform.h>
  13. #include <linux/of_address.h>
  14. #include <linux/pci.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/resource.h>
  17. #include "pcie-designware.h"
  18. #define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
  19. struct ls_pcie_ep_drvdata {
  20. u32 func_offset;
  21. const struct dw_pcie_ep_ops *ops;
  22. const struct dw_pcie_ops *dw_pcie_ops;
  23. };
  24. struct ls_pcie_ep {
  25. struct dw_pcie *pci;
  26. struct pci_epc_features *ls_epc;
  27. const struct ls_pcie_ep_drvdata *drvdata;
  28. };
  29. static const struct pci_epc_features*
  30. ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
  31. {
  32. struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
  33. struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
  34. return pcie->ls_epc;
  35. }
  36. static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
  37. {
  38. struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
  39. struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
  40. struct dw_pcie_ep_func *ep_func;
  41. enum pci_barno bar;
  42. ep_func = dw_pcie_ep_get_func_from_ep(ep, 0);
  43. if (!ep_func)
  44. return;
  45. for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
  46. dw_pcie_ep_reset_bar(pci, bar);
  47. pcie->ls_epc->msi_capable = ep_func->msi_cap ? true : false;
  48. pcie->ls_epc->msix_capable = ep_func->msix_cap ? true : false;
  49. }
  50. static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
  51. enum pci_epc_irq_type type, u16 interrupt_num)
  52. {
  53. struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
  54. switch (type) {
  55. case PCI_EPC_IRQ_LEGACY:
  56. return dw_pcie_ep_raise_legacy_irq(ep, func_no);
  57. case PCI_EPC_IRQ_MSI:
  58. return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
  59. case PCI_EPC_IRQ_MSIX:
  60. return dw_pcie_ep_raise_msix_irq_doorbell(ep, func_no,
  61. interrupt_num);
  62. default:
  63. dev_err(pci->dev, "UNKNOWN IRQ type\n");
  64. return -EINVAL;
  65. }
  66. }
  67. static unsigned int ls_pcie_ep_func_conf_select(struct dw_pcie_ep *ep,
  68. u8 func_no)
  69. {
  70. struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
  71. struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
  72. WARN_ON(func_no && !pcie->drvdata->func_offset);
  73. return pcie->drvdata->func_offset * func_no;
  74. }
  75. static const struct dw_pcie_ep_ops ls_pcie_ep_ops = {
  76. .ep_init = ls_pcie_ep_init,
  77. .raise_irq = ls_pcie_ep_raise_irq,
  78. .get_features = ls_pcie_ep_get_features,
  79. .func_conf_select = ls_pcie_ep_func_conf_select,
  80. };
  81. static const struct ls_pcie_ep_drvdata ls1_ep_drvdata = {
  82. .ops = &ls_pcie_ep_ops,
  83. };
  84. static const struct ls_pcie_ep_drvdata ls2_ep_drvdata = {
  85. .func_offset = 0x20000,
  86. .ops = &ls_pcie_ep_ops,
  87. };
  88. static const struct ls_pcie_ep_drvdata lx2_ep_drvdata = {
  89. .func_offset = 0x8000,
  90. .ops = &ls_pcie_ep_ops,
  91. };
  92. static const struct of_device_id ls_pcie_ep_of_match[] = {
  93. { .compatible = "fsl,ls1046a-pcie-ep", .data = &ls1_ep_drvdata },
  94. { .compatible = "fsl,ls1088a-pcie-ep", .data = &ls2_ep_drvdata },
  95. { .compatible = "fsl,ls2088a-pcie-ep", .data = &ls2_ep_drvdata },
  96. { .compatible = "fsl,lx2160ar2-pcie-ep", .data = &lx2_ep_drvdata },
  97. { },
  98. };
  99. static int __init ls_pcie_ep_probe(struct platform_device *pdev)
  100. {
  101. struct device *dev = &pdev->dev;
  102. struct dw_pcie *pci;
  103. struct ls_pcie_ep *pcie;
  104. struct pci_epc_features *ls_epc;
  105. struct resource *dbi_base;
  106. pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
  107. if (!pcie)
  108. return -ENOMEM;
  109. pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
  110. if (!pci)
  111. return -ENOMEM;
  112. ls_epc = devm_kzalloc(dev, sizeof(*ls_epc), GFP_KERNEL);
  113. if (!ls_epc)
  114. return -ENOMEM;
  115. pcie->drvdata = of_device_get_match_data(dev);
  116. pci->dev = dev;
  117. pci->ops = pcie->drvdata->dw_pcie_ops;
  118. ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
  119. pcie->pci = pci;
  120. pcie->ls_epc = ls_epc;
  121. dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
  122. pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
  123. if (IS_ERR(pci->dbi_base))
  124. return PTR_ERR(pci->dbi_base);
  125. pci->ep.ops = &ls_pcie_ep_ops;
  126. platform_set_drvdata(pdev, pcie);
  127. return dw_pcie_ep_init(&pci->ep);
  128. }
  129. static struct platform_driver ls_pcie_ep_driver = {
  130. .driver = {
  131. .name = "layerscape-pcie-ep",
  132. .of_match_table = ls_pcie_ep_of_match,
  133. .suppress_bind_attrs = true,
  134. },
  135. };
  136. builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe);