sta2x11-fixup.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * DMA translation between STA2x11 AMBA memory mapping and the x86 memory mapping
  4. *
  5. * ST Microelectronics ConneXt (STA2X11/STA2X10)
  6. *
  7. * Copyright (c) 2010-2011 Wind River Systems, Inc.
  8. */
  9. #include <linux/pci.h>
  10. #include <linux/pci_ids.h>
  11. #include <linux/export.h>
  12. #include <linux/list.h>
  13. #include <linux/dma-map-ops.h>
  14. #include <linux/swiotlb.h>
  15. #include <asm/iommu.h>
  16. #define STA2X11_SWIOTLB_SIZE (4*1024*1024)
  17. /*
  18. * We build a list of bus numbers that are under the ConneXt. The
  19. * main bridge hosts 4 busses, which are the 4 endpoints, in order.
  20. */
  21. #define STA2X11_NR_EP 4 /* 0..3 included */
  22. #define STA2X11_NR_FUNCS 8 /* 0..7 included */
  23. #define STA2X11_AMBA_SIZE (512 << 20)
  24. struct sta2x11_ahb_regs { /* saved during suspend */
  25. u32 base, pexlbase, pexhbase, crw;
  26. };
  27. struct sta2x11_mapping {
  28. int is_suspended;
  29. struct sta2x11_ahb_regs regs[STA2X11_NR_FUNCS];
  30. };
  31. struct sta2x11_instance {
  32. struct list_head list;
  33. int bus0;
  34. struct sta2x11_mapping map[STA2X11_NR_EP];
  35. };
  36. static LIST_HEAD(sta2x11_instance_list);
  37. /* At probe time, record new instances of this bridge (likely one only) */
  38. static void sta2x11_new_instance(struct pci_dev *pdev)
  39. {
  40. struct sta2x11_instance *instance;
  41. instance = kzalloc(sizeof(*instance), GFP_ATOMIC);
  42. if (!instance)
  43. return;
  44. /* This has a subordinate bridge, with 4 more-subordinate ones */
  45. instance->bus0 = pdev->subordinate->number + 1;
  46. if (list_empty(&sta2x11_instance_list)) {
  47. int size = STA2X11_SWIOTLB_SIZE;
  48. /* First instance: register your own swiotlb area */
  49. dev_info(&pdev->dev, "Using SWIOTLB (size %i)\n", size);
  50. if (swiotlb_init_late(size, GFP_DMA, NULL))
  51. dev_emerg(&pdev->dev, "init swiotlb failed\n");
  52. }
  53. list_add(&instance->list, &sta2x11_instance_list);
  54. }
  55. DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, 0xcc17, sta2x11_new_instance);
  56. /*
  57. * Utility functions used in this file from below
  58. */
  59. static struct sta2x11_instance *sta2x11_pdev_to_instance(struct pci_dev *pdev)
  60. {
  61. struct sta2x11_instance *instance;
  62. int ep;
  63. list_for_each_entry(instance, &sta2x11_instance_list, list) {
  64. ep = pdev->bus->number - instance->bus0;
  65. if (ep >= 0 && ep < STA2X11_NR_EP)
  66. return instance;
  67. }
  68. return NULL;
  69. }
  70. static int sta2x11_pdev_to_ep(struct pci_dev *pdev)
  71. {
  72. struct sta2x11_instance *instance;
  73. instance = sta2x11_pdev_to_instance(pdev);
  74. if (!instance)
  75. return -1;
  76. return pdev->bus->number - instance->bus0;
  77. }
  78. /* This is exported, as some devices need to access the MFD registers */
  79. struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev)
  80. {
  81. return sta2x11_pdev_to_instance(pdev);
  82. }
  83. EXPORT_SYMBOL(sta2x11_get_instance);
  84. /* At setup time, we use our own ops if the device is a ConneXt one */
  85. static void sta2x11_setup_pdev(struct pci_dev *pdev)
  86. {
  87. struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
  88. if (!instance) /* either a sta2x11 bridge or another ST device */
  89. return;
  90. /* We must enable all devices as master, for audio DMA to work */
  91. pci_set_master(pdev);
  92. }
  93. DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_setup_pdev);
  94. /*
  95. * At boot we must set up the mappings for the pcie-to-amba bridge.
  96. * It involves device access, and the same happens at suspend/resume time
  97. */
  98. #define AHB_MAPB 0xCA4
  99. #define AHB_CRW(i) (AHB_MAPB + 0 + (i) * 0x10)
  100. #define AHB_CRW_SZMASK 0xfffffc00UL
  101. #define AHB_CRW_ENABLE (1 << 0)
  102. #define AHB_CRW_WTYPE_MEM (2 << 1)
  103. #define AHB_CRW_ROE (1UL << 3) /* Relax Order Ena */
  104. #define AHB_CRW_NSE (1UL << 4) /* No Snoop Enable */
  105. #define AHB_BASE(i) (AHB_MAPB + 4 + (i) * 0x10)
  106. #define AHB_PEXLBASE(i) (AHB_MAPB + 8 + (i) * 0x10)
  107. #define AHB_PEXHBASE(i) (AHB_MAPB + 12 + (i) * 0x10)
  108. /* At probe time, enable mapping for each endpoint, using the pdev */
  109. static void sta2x11_map_ep(struct pci_dev *pdev)
  110. {
  111. struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
  112. struct device *dev = &pdev->dev;
  113. u32 amba_base, max_amba_addr;
  114. int i, ret;
  115. if (!instance)
  116. return;
  117. pci_read_config_dword(pdev, AHB_BASE(0), &amba_base);
  118. max_amba_addr = amba_base + STA2X11_AMBA_SIZE - 1;
  119. ret = dma_direct_set_offset(dev, 0, amba_base, STA2X11_AMBA_SIZE);
  120. if (ret)
  121. dev_err(dev, "sta2x11: could not set DMA offset\n");
  122. dev->bus_dma_limit = max_amba_addr;
  123. dma_set_mask_and_coherent(&pdev->dev, max_amba_addr);
  124. /* Configure AHB mapping */
  125. pci_write_config_dword(pdev, AHB_PEXLBASE(0), 0);
  126. pci_write_config_dword(pdev, AHB_PEXHBASE(0), 0);
  127. pci_write_config_dword(pdev, AHB_CRW(0), STA2X11_AMBA_SIZE |
  128. AHB_CRW_WTYPE_MEM | AHB_CRW_ENABLE);
  129. /* Disable all the other windows */
  130. for (i = 1; i < STA2X11_NR_FUNCS; i++)
  131. pci_write_config_dword(pdev, AHB_CRW(i), 0);
  132. dev_info(&pdev->dev,
  133. "sta2x11: Map EP %i: AMBA address %#8x-%#8x\n",
  134. sta2x11_pdev_to_ep(pdev), amba_base, max_amba_addr);
  135. }
  136. DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_map_ep);
  137. #ifdef CONFIG_PM /* Some register values must be saved and restored */
  138. static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev)
  139. {
  140. struct sta2x11_instance *instance;
  141. int ep;
  142. instance = sta2x11_pdev_to_instance(pdev);
  143. if (!instance)
  144. return NULL;
  145. ep = sta2x11_pdev_to_ep(pdev);
  146. return instance->map + ep;
  147. }
  148. static void suspend_mapping(struct pci_dev *pdev)
  149. {
  150. struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
  151. int i;
  152. if (!map)
  153. return;
  154. if (map->is_suspended)
  155. return;
  156. map->is_suspended = 1;
  157. /* Save all window configs */
  158. for (i = 0; i < STA2X11_NR_FUNCS; i++) {
  159. struct sta2x11_ahb_regs *regs = map->regs + i;
  160. pci_read_config_dword(pdev, AHB_BASE(i), &regs->base);
  161. pci_read_config_dword(pdev, AHB_PEXLBASE(i), &regs->pexlbase);
  162. pci_read_config_dword(pdev, AHB_PEXHBASE(i), &regs->pexhbase);
  163. pci_read_config_dword(pdev, AHB_CRW(i), &regs->crw);
  164. }
  165. }
  166. DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, suspend_mapping);
  167. static void resume_mapping(struct pci_dev *pdev)
  168. {
  169. struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
  170. int i;
  171. if (!map)
  172. return;
  173. if (!map->is_suspended)
  174. goto out;
  175. map->is_suspended = 0;
  176. /* Restore all window configs */
  177. for (i = 0; i < STA2X11_NR_FUNCS; i++) {
  178. struct sta2x11_ahb_regs *regs = map->regs + i;
  179. pci_write_config_dword(pdev, AHB_BASE(i), regs->base);
  180. pci_write_config_dword(pdev, AHB_PEXLBASE(i), regs->pexlbase);
  181. pci_write_config_dword(pdev, AHB_PEXHBASE(i), regs->pexhbase);
  182. pci_write_config_dword(pdev, AHB_CRW(i), regs->crw);
  183. }
  184. out:
  185. pci_set_master(pdev); /* Like at boot, enable master on all devices */
  186. }
  187. DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, resume_mapping);
  188. #endif /* CONFIG_PM */