pci_ep-uclass.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * PCI Endpoint uclass
  4. *
  5. * Based on Linux PCI-EP driver written by
  6. * Kishon Vijay Abraham I <kishon@ti.com>
  7. *
  8. * Copyright (c) 2019
  9. * Written by Ramon Fried <ramon.fried@gmail.com>
  10. */
  11. #include <common.h>
  12. #include <dm.h>
  13. #include <errno.h>
  14. #include <linux/log2.h>
  15. #include <pci_ep.h>
  16. DECLARE_GLOBAL_DATA_PTR;
  17. int pci_ep_write_header(struct udevice *dev, uint fn, struct pci_ep_header *hdr)
  18. {
  19. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  20. if (!ops->write_header)
  21. return -ENOSYS;
  22. return ops->write_header(dev, fn, hdr);
  23. }
  24. int pci_ep_read_header(struct udevice *dev, uint fn, struct pci_ep_header *hdr)
  25. {
  26. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  27. if (!ops->read_header)
  28. return -ENOSYS;
  29. return ops->read_header(dev, fn, hdr);
  30. }
  31. int pci_ep_set_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar)
  32. {
  33. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  34. int flags = ep_bar->flags;
  35. /* Some basic bar validity checks */
  36. if (ep_bar->barno > BAR_5 || ep_bar->barno < BAR_0)
  37. return -EINVAL;
  38. if ((ep_bar->barno == BAR_5 &&
  39. (flags & PCI_BASE_ADDRESS_MEM_TYPE_64)) ||
  40. ((flags & PCI_BASE_ADDRESS_SPACE_IO) &&
  41. (flags & PCI_BASE_ADDRESS_IO_MASK)) ||
  42. (upper_32_bits(ep_bar->size) &&
  43. !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)))
  44. return -EINVAL;
  45. if (!ops->set_bar)
  46. return -ENOSYS;
  47. return ops->set_bar(dev, func_no, ep_bar);
  48. }
  49. int pci_ep_read_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar,
  50. enum pci_barno barno)
  51. {
  52. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  53. /* Some basic bar validity checks */
  54. if (barno > BAR_5 || barno < BAR_0)
  55. return -EINVAL;
  56. if (!ops->read_bar)
  57. return -ENOSYS;
  58. return ops->read_bar(dev, func_no, ep_bar, barno);
  59. }
  60. int pci_ep_clear_bar(struct udevice *dev, uint func_num, enum pci_barno bar)
  61. {
  62. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  63. if (!ops->clear_bar)
  64. return -ENOSYS;
  65. return ops->clear_bar(dev, func_num, bar);
  66. }
  67. int pci_ep_map_addr(struct udevice *dev, uint func_no, phys_addr_t addr,
  68. u64 pci_addr, size_t size)
  69. {
  70. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  71. if (!ops->map_addr)
  72. return -ENOSYS;
  73. return ops->map_addr(dev, func_no, addr, pci_addr, size);
  74. }
  75. int pci_ep_unmap_addr(struct udevice *dev, uint func_no, phys_addr_t addr)
  76. {
  77. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  78. if (!ops->unmap_addr)
  79. return -ENOSYS;
  80. return ops->unmap_addr(dev, func_no, addr);
  81. }
  82. int pci_ep_set_msi(struct udevice *dev, uint func_no, uint interrupts)
  83. {
  84. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  85. uint encode_int;
  86. if (interrupts > 32)
  87. return -EINVAL;
  88. if (!ops->set_msi)
  89. return -ENOSYS;
  90. /* MSI spec permits allocation of
  91. * only 1, 2, 4, 8, 16, 32 interrupts
  92. */
  93. encode_int = order_base_2(interrupts);
  94. return ops->set_msi(dev, func_no, encode_int);
  95. }
  96. int pci_ep_get_msi(struct udevice *dev, uint func_no)
  97. {
  98. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  99. int interrupt;
  100. if (!ops->get_msi)
  101. return -ENOSYS;
  102. interrupt = ops->get_msi(dev, func_no);
  103. if (interrupt < 0)
  104. return 0;
  105. /* Translate back from order base 2*/
  106. interrupt = 1 << interrupt;
  107. return interrupt;
  108. }
  109. int pci_ep_set_msix(struct udevice *dev, uint func_no, uint interrupts)
  110. {
  111. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  112. if (interrupts < 1 || interrupts > 2048)
  113. return -EINVAL;
  114. if (!ops->set_msix)
  115. return -ENOSYS;
  116. return ops->set_msix(dev, func_no, interrupts - 1);
  117. }
  118. int pci_ep_get_msix(struct udevice *dev, uint func_no)
  119. {
  120. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  121. int interrupt;
  122. if (!ops->get_msix)
  123. return -ENOSYS;
  124. interrupt = ops->get_msix(dev, func_no);
  125. if (interrupt < 0)
  126. return 0;
  127. return interrupt + 1;
  128. }
  129. int pci_ep_raise_irq(struct udevice *dev, uint func_no,
  130. enum pci_ep_irq_type type, uint interrupt_num)
  131. {
  132. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  133. if (!ops->raise_irq)
  134. return -ENOSYS;
  135. return ops->raise_irq(dev, func_no, type, interrupt_num);
  136. }
  137. int pci_ep_start(struct udevice *dev)
  138. {
  139. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  140. if (!ops->start)
  141. return -ENOSYS;
  142. return ops->start(dev);
  143. }
  144. int pci_ep_stop(struct udevice *dev)
  145. {
  146. struct pci_ep_ops *ops = pci_ep_get_ops(dev);
  147. if (!ops->stop)
  148. return -ENOSYS;
  149. return ops->stop(dev);
  150. }
  151. UCLASS_DRIVER(pci_ep) = {
  152. .id = UCLASS_PCI_EP,
  153. .name = "pci_ep",
  154. .flags = DM_UC_FLAG_SEQ_ALIAS,
  155. };
  156. void pci_ep_init(void)
  157. {
  158. struct udevice *dev;
  159. for (uclass_first_device_check(UCLASS_PCI_EP, &dev);
  160. dev;
  161. uclass_next_device_check(&dev)) {
  162. ;
  163. }
  164. }