pci_ep-uclass.c 4.5 KB

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