sart.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // SPDX-License-Identifier: GPL-2.0-only OR MIT
  2. /*
  3. * Apple SART device driver
  4. * Copyright (C) The Asahi Linux Contributors
  5. *
  6. * Apple SART is a simple address filter for some DMA transactions.
  7. * Regions of physical memory must be added to the SART's allow
  8. * list before any DMA can target these. Unlike a proper
  9. * IOMMU no remapping can be done and special support in the
  10. * consumer driver is required since not all DMA transactions of
  11. * a single device are subject to SART filtering.
  12. */
  13. #include <linux/soc/apple/sart.h>
  14. #include <linux/atomic.h>
  15. #include <linux/bits.h>
  16. #include <linux/bitfield.h>
  17. #include <linux/device.h>
  18. #include <linux/io.h>
  19. #include <linux/module.h>
  20. #include <linux/of.h>
  21. #include <linux/of_platform.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/types.h>
  24. #define APPLE_SART_MAX_ENTRIES 16
  25. /* SARTv0 registers */
  26. #define APPLE_SART0_CONFIG(idx) (0x00 + 4 * (idx))
  27. #define APPLE_SART0_CONFIG_FLAGS GENMASK(28, 24)
  28. #define APPLE_SART0_CONFIG_SIZE GENMASK(18, 0)
  29. #define APPLE_SART0_CONFIG_SIZE_SHIFT 12
  30. #define APPLE_SART0_CONFIG_SIZE_MAX GENMASK(18, 0)
  31. #define APPLE_SART0_PADDR(idx) (0x40 + 4 * (idx))
  32. #define APPLE_SART0_PADDR_SHIFT 12
  33. #define APPLE_SART0_FLAGS_ALLOW 0xf
  34. /* SARTv2 registers */
  35. #define APPLE_SART2_CONFIG(idx) (0x00 + 4 * (idx))
  36. #define APPLE_SART2_CONFIG_FLAGS GENMASK(31, 24)
  37. #define APPLE_SART2_CONFIG_SIZE GENMASK(23, 0)
  38. #define APPLE_SART2_CONFIG_SIZE_SHIFT 12
  39. #define APPLE_SART2_CONFIG_SIZE_MAX GENMASK(23, 0)
  40. #define APPLE_SART2_PADDR(idx) (0x40 + 4 * (idx))
  41. #define APPLE_SART2_PADDR_SHIFT 12
  42. #define APPLE_SART2_FLAGS_ALLOW 0xff
  43. /* SARTv3 registers */
  44. #define APPLE_SART3_CONFIG(idx) (0x00 + 4 * (idx))
  45. #define APPLE_SART3_PADDR(idx) (0x40 + 4 * (idx))
  46. #define APPLE_SART3_PADDR_SHIFT 12
  47. #define APPLE_SART3_SIZE(idx) (0x80 + 4 * (idx))
  48. #define APPLE_SART3_SIZE_SHIFT 12
  49. #define APPLE_SART3_SIZE_MAX GENMASK(29, 0)
  50. #define APPLE_SART3_FLAGS_ALLOW 0xff
  51. struct apple_sart_ops {
  52. void (*get_entry)(struct apple_sart *sart, int index, u8 *flags,
  53. phys_addr_t *paddr, size_t *size);
  54. void (*set_entry)(struct apple_sart *sart, int index, u8 flags,
  55. phys_addr_t paddr_shifted, size_t size_shifted);
  56. /* This is probably a bitfield but the exact meaning of each bit is unknown. */
  57. unsigned int flags_allow;
  58. unsigned int size_shift;
  59. unsigned int paddr_shift;
  60. size_t size_max;
  61. };
  62. struct apple_sart {
  63. struct device *dev;
  64. void __iomem *regs;
  65. const struct apple_sart_ops *ops;
  66. unsigned long protected_entries;
  67. unsigned long used_entries;
  68. };
  69. static void sart0_get_entry(struct apple_sart *sart, int index, u8 *flags,
  70. phys_addr_t *paddr, size_t *size)
  71. {
  72. u32 cfg = readl(sart->regs + APPLE_SART0_CONFIG(index));
  73. phys_addr_t paddr_ = readl(sart->regs + APPLE_SART0_PADDR(index));
  74. size_t size_ = FIELD_GET(APPLE_SART0_CONFIG_SIZE, cfg);
  75. *flags = FIELD_GET(APPLE_SART0_CONFIG_FLAGS, cfg);
  76. *size = size_ << APPLE_SART0_CONFIG_SIZE_SHIFT;
  77. *paddr = paddr_ << APPLE_SART0_PADDR_SHIFT;
  78. }
  79. static void sart0_set_entry(struct apple_sart *sart, int index, u8 flags,
  80. phys_addr_t paddr_shifted, size_t size_shifted)
  81. {
  82. u32 cfg;
  83. cfg = FIELD_PREP(APPLE_SART0_CONFIG_FLAGS, flags);
  84. cfg |= FIELD_PREP(APPLE_SART0_CONFIG_SIZE, size_shifted);
  85. writel(paddr_shifted, sart->regs + APPLE_SART0_PADDR(index));
  86. writel(cfg, sart->regs + APPLE_SART0_CONFIG(index));
  87. }
  88. static struct apple_sart_ops sart_ops_v0 = {
  89. .get_entry = sart0_get_entry,
  90. .set_entry = sart0_set_entry,
  91. .flags_allow = APPLE_SART0_FLAGS_ALLOW,
  92. .size_shift = APPLE_SART0_CONFIG_SIZE_SHIFT,
  93. .paddr_shift = APPLE_SART0_PADDR_SHIFT,
  94. .size_max = APPLE_SART0_CONFIG_SIZE_MAX,
  95. };
  96. static void sart2_get_entry(struct apple_sart *sart, int index, u8 *flags,
  97. phys_addr_t *paddr, size_t *size)
  98. {
  99. u32 cfg = readl(sart->regs + APPLE_SART2_CONFIG(index));
  100. phys_addr_t paddr_ = readl(sart->regs + APPLE_SART2_PADDR(index));
  101. size_t size_ = FIELD_GET(APPLE_SART2_CONFIG_SIZE, cfg);
  102. *flags = FIELD_GET(APPLE_SART2_CONFIG_FLAGS, cfg);
  103. *size = size_ << APPLE_SART2_CONFIG_SIZE_SHIFT;
  104. *paddr = paddr_ << APPLE_SART2_PADDR_SHIFT;
  105. }
  106. static void sart2_set_entry(struct apple_sart *sart, int index, u8 flags,
  107. phys_addr_t paddr_shifted, size_t size_shifted)
  108. {
  109. u32 cfg;
  110. cfg = FIELD_PREP(APPLE_SART2_CONFIG_FLAGS, flags);
  111. cfg |= FIELD_PREP(APPLE_SART2_CONFIG_SIZE, size_shifted);
  112. writel(paddr_shifted, sart->regs + APPLE_SART2_PADDR(index));
  113. writel(cfg, sart->regs + APPLE_SART2_CONFIG(index));
  114. }
  115. static struct apple_sart_ops sart_ops_v2 = {
  116. .get_entry = sart2_get_entry,
  117. .set_entry = sart2_set_entry,
  118. .flags_allow = APPLE_SART2_FLAGS_ALLOW,
  119. .size_shift = APPLE_SART2_CONFIG_SIZE_SHIFT,
  120. .paddr_shift = APPLE_SART2_PADDR_SHIFT,
  121. .size_max = APPLE_SART2_CONFIG_SIZE_MAX,
  122. };
  123. static void sart3_get_entry(struct apple_sart *sart, int index, u8 *flags,
  124. phys_addr_t *paddr, size_t *size)
  125. {
  126. phys_addr_t paddr_ = readl(sart->regs + APPLE_SART3_PADDR(index));
  127. size_t size_ = readl(sart->regs + APPLE_SART3_SIZE(index));
  128. *flags = readl(sart->regs + APPLE_SART3_CONFIG(index));
  129. *size = size_ << APPLE_SART3_SIZE_SHIFT;
  130. *paddr = paddr_ << APPLE_SART3_PADDR_SHIFT;
  131. }
  132. static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags,
  133. phys_addr_t paddr_shifted, size_t size_shifted)
  134. {
  135. writel(paddr_shifted, sart->regs + APPLE_SART3_PADDR(index));
  136. writel(size_shifted, sart->regs + APPLE_SART3_SIZE(index));
  137. writel(flags, sart->regs + APPLE_SART3_CONFIG(index));
  138. }
  139. static struct apple_sart_ops sart_ops_v3 = {
  140. .get_entry = sart3_get_entry,
  141. .set_entry = sart3_set_entry,
  142. .flags_allow = APPLE_SART3_FLAGS_ALLOW,
  143. .size_shift = APPLE_SART3_SIZE_SHIFT,
  144. .paddr_shift = APPLE_SART3_PADDR_SHIFT,
  145. .size_max = APPLE_SART3_SIZE_MAX,
  146. };
  147. static int apple_sart_probe(struct platform_device *pdev)
  148. {
  149. int i;
  150. struct apple_sart *sart;
  151. struct device *dev = &pdev->dev;
  152. sart = devm_kzalloc(dev, sizeof(*sart), GFP_KERNEL);
  153. if (!sart)
  154. return -ENOMEM;
  155. sart->dev = dev;
  156. sart->ops = of_device_get_match_data(dev);
  157. sart->regs = devm_platform_ioremap_resource(pdev, 0);
  158. if (IS_ERR(sart->regs))
  159. return PTR_ERR(sart->regs);
  160. for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) {
  161. u8 flags;
  162. size_t size;
  163. phys_addr_t paddr;
  164. sart->ops->get_entry(sart, i, &flags, &paddr, &size);
  165. if (!flags)
  166. continue;
  167. dev_dbg(sart->dev,
  168. "SART bootloader entry: index %02d; flags: 0x%02x; paddr: %pa; size: 0x%zx\n",
  169. i, flags, &paddr, size);
  170. set_bit(i, &sart->protected_entries);
  171. }
  172. platform_set_drvdata(pdev, sart);
  173. return 0;
  174. }
  175. struct apple_sart *devm_apple_sart_get(struct device *dev)
  176. {
  177. struct device_node *sart_node;
  178. struct platform_device *sart_pdev;
  179. struct apple_sart *sart;
  180. sart_node = of_parse_phandle(dev->of_node, "apple,sart", 0);
  181. if (!sart_node)
  182. return ERR_PTR(-ENODEV);
  183. sart_pdev = of_find_device_by_node(sart_node);
  184. of_node_put(sart_node);
  185. if (!sart_pdev)
  186. return ERR_PTR(-ENODEV);
  187. sart = dev_get_drvdata(&sart_pdev->dev);
  188. if (!sart) {
  189. put_device(&sart_pdev->dev);
  190. return ERR_PTR(-EPROBE_DEFER);
  191. }
  192. device_link_add(dev, &sart_pdev->dev,
  193. DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
  194. put_device(&sart_pdev->dev);
  195. return sart;
  196. }
  197. EXPORT_SYMBOL_GPL(devm_apple_sart_get);
  198. static int sart_set_entry(struct apple_sart *sart, int index, u8 flags,
  199. phys_addr_t paddr, size_t size)
  200. {
  201. if (size & ((1 << sart->ops->size_shift) - 1))
  202. return -EINVAL;
  203. if (paddr & ((1 << sart->ops->paddr_shift) - 1))
  204. return -EINVAL;
  205. paddr >>= sart->ops->size_shift;
  206. size >>= sart->ops->paddr_shift;
  207. if (size > sart->ops->size_max)
  208. return -EINVAL;
  209. sart->ops->set_entry(sart, index, flags, paddr, size);
  210. return 0;
  211. }
  212. int apple_sart_add_allowed_region(struct apple_sart *sart, phys_addr_t paddr,
  213. size_t size)
  214. {
  215. int i, ret;
  216. for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) {
  217. if (test_bit(i, &sart->protected_entries))
  218. continue;
  219. if (test_and_set_bit(i, &sart->used_entries))
  220. continue;
  221. ret = sart_set_entry(sart, i, sart->ops->flags_allow, paddr,
  222. size);
  223. if (ret) {
  224. dev_dbg(sart->dev,
  225. "unable to set entry %d to [%pa, 0x%zx]\n",
  226. i, &paddr, size);
  227. clear_bit(i, &sart->used_entries);
  228. return ret;
  229. }
  230. dev_dbg(sart->dev, "wrote [%pa, 0x%zx] to %d\n", &paddr, size,
  231. i);
  232. return 0;
  233. }
  234. dev_warn(sart->dev,
  235. "no free entries left to add [paddr: 0x%pa, size: 0x%zx]\n",
  236. &paddr, size);
  237. return -EBUSY;
  238. }
  239. EXPORT_SYMBOL_GPL(apple_sart_add_allowed_region);
  240. int apple_sart_remove_allowed_region(struct apple_sart *sart, phys_addr_t paddr,
  241. size_t size)
  242. {
  243. int i;
  244. dev_dbg(sart->dev,
  245. "will remove [paddr: %pa, size: 0x%zx] from allowed regions\n",
  246. &paddr, size);
  247. for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) {
  248. u8 eflags;
  249. size_t esize;
  250. phys_addr_t epaddr;
  251. if (test_bit(i, &sart->protected_entries))
  252. continue;
  253. sart->ops->get_entry(sart, i, &eflags, &epaddr, &esize);
  254. if (epaddr != paddr || esize != size)
  255. continue;
  256. sart->ops->set_entry(sart, i, 0, 0, 0);
  257. clear_bit(i, &sart->used_entries);
  258. dev_dbg(sart->dev, "cleared entry %d\n", i);
  259. return 0;
  260. }
  261. dev_warn(sart->dev, "entry [paddr: 0x%pa, size: 0x%zx] not found\n",
  262. &paddr, size);
  263. return -EINVAL;
  264. }
  265. EXPORT_SYMBOL_GPL(apple_sart_remove_allowed_region);
  266. static void apple_sart_shutdown(struct platform_device *pdev)
  267. {
  268. struct apple_sart *sart = dev_get_drvdata(&pdev->dev);
  269. int i;
  270. for (i = 0; i < APPLE_SART_MAX_ENTRIES; ++i) {
  271. if (test_bit(i, &sart->protected_entries))
  272. continue;
  273. sart->ops->set_entry(sart, i, 0, 0, 0);
  274. }
  275. }
  276. static const struct of_device_id apple_sart_of_match[] = {
  277. {
  278. .compatible = "apple,t6000-sart",
  279. .data = &sart_ops_v3,
  280. },
  281. {
  282. .compatible = "apple,t8103-sart",
  283. .data = &sart_ops_v2,
  284. },
  285. {
  286. .compatible = "apple,t8015-sart",
  287. .data = &sart_ops_v0,
  288. },
  289. {}
  290. };
  291. MODULE_DEVICE_TABLE(of, apple_sart_of_match);
  292. static struct platform_driver apple_sart_driver = {
  293. .driver = {
  294. .name = "apple-sart",
  295. .of_match_table = apple_sart_of_match,
  296. },
  297. .probe = apple_sart_probe,
  298. .shutdown = apple_sart_shutdown,
  299. };
  300. module_platform_driver(apple_sart_driver);
  301. MODULE_LICENSE("Dual MIT/GPL");
  302. MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
  303. MODULE_DESCRIPTION("Apple SART driver");