sprd-iommu.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Unisoc IOMMU driver
  4. *
  5. * Copyright (C) 2020 Unisoc, Inc.
  6. * Author: Chunyan Zhang <chunyan.zhang@unisoc.com>
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/device.h>
  10. #include <linux/dma-mapping.h>
  11. #include <linux/errno.h>
  12. #include <linux/iommu.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of_platform.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/regmap.h>
  18. #include <linux/slab.h>
  19. #define SPRD_IOMMU_PAGE_SHIFT 12
  20. #define SPRD_IOMMU_PAGE_SIZE SZ_4K
  21. #define SPRD_EX_CFG 0x0
  22. #define SPRD_IOMMU_VAOR_BYPASS BIT(4)
  23. #define SPRD_IOMMU_GATE_EN BIT(1)
  24. #define SPRD_IOMMU_EN BIT(0)
  25. #define SPRD_EX_UPDATE 0x4
  26. #define SPRD_EX_FIRST_VPN 0x8
  27. #define SPRD_EX_VPN_RANGE 0xc
  28. #define SPRD_EX_FIRST_PPN 0x10
  29. #define SPRD_EX_DEFAULT_PPN 0x14
  30. #define SPRD_IOMMU_VERSION 0x0
  31. #define SPRD_VERSION_MASK GENMASK(15, 8)
  32. #define SPRD_VERSION_SHIFT 0x8
  33. #define SPRD_VAU_CFG 0x4
  34. #define SPRD_VAU_UPDATE 0x8
  35. #define SPRD_VAU_AUTH_CFG 0xc
  36. #define SPRD_VAU_FIRST_PPN 0x10
  37. #define SPRD_VAU_DEFAULT_PPN_RD 0x14
  38. #define SPRD_VAU_DEFAULT_PPN_WR 0x18
  39. #define SPRD_VAU_FIRST_VPN 0x1c
  40. #define SPRD_VAU_VPN_RANGE 0x20
  41. enum sprd_iommu_version {
  42. SPRD_IOMMU_EX,
  43. SPRD_IOMMU_VAU,
  44. };
  45. /*
  46. * struct sprd_iommu_device - high-level sprd IOMMU device representation,
  47. * including hardware information and configuration, also driver data, etc
  48. *
  49. * @ver: sprd IOMMU IP version
  50. * @prot_page_va: protect page base virtual address
  51. * @prot_page_pa: protect page base physical address, data would be
  52. * written to here while translation fault
  53. * @base: mapped base address for accessing registers
  54. * @dev: pointer to basic device structure
  55. * @iommu: IOMMU core representation
  56. * @group: IOMMU group
  57. * @eb: gate clock which controls IOMMU access
  58. */
  59. struct sprd_iommu_device {
  60. struct sprd_iommu_domain *dom;
  61. enum sprd_iommu_version ver;
  62. u32 *prot_page_va;
  63. dma_addr_t prot_page_pa;
  64. void __iomem *base;
  65. struct device *dev;
  66. struct iommu_device iommu;
  67. struct clk *eb;
  68. };
  69. struct sprd_iommu_domain {
  70. spinlock_t pgtlock; /* lock for page table */
  71. struct iommu_domain domain;
  72. u32 *pgt_va; /* page table virtual address base */
  73. dma_addr_t pgt_pa; /* page table physical address base */
  74. struct sprd_iommu_device *sdev;
  75. };
  76. static const struct iommu_ops sprd_iommu_ops;
  77. static struct sprd_iommu_domain *to_sprd_domain(struct iommu_domain *dom)
  78. {
  79. return container_of(dom, struct sprd_iommu_domain, domain);
  80. }
  81. static inline void
  82. sprd_iommu_write(struct sprd_iommu_device *sdev, unsigned int reg, u32 val)
  83. {
  84. writel_relaxed(val, sdev->base + reg);
  85. }
  86. static inline u32
  87. sprd_iommu_read(struct sprd_iommu_device *sdev, unsigned int reg)
  88. {
  89. return readl_relaxed(sdev->base + reg);
  90. }
  91. static inline void
  92. sprd_iommu_update_bits(struct sprd_iommu_device *sdev, unsigned int reg,
  93. u32 mask, u32 shift, u32 val)
  94. {
  95. u32 t = sprd_iommu_read(sdev, reg);
  96. t = (t & (~(mask << shift))) | ((val & mask) << shift);
  97. sprd_iommu_write(sdev, reg, t);
  98. }
  99. static inline int
  100. sprd_iommu_get_version(struct sprd_iommu_device *sdev)
  101. {
  102. int ver = (sprd_iommu_read(sdev, SPRD_IOMMU_VERSION) &
  103. SPRD_VERSION_MASK) >> SPRD_VERSION_SHIFT;
  104. switch (ver) {
  105. case SPRD_IOMMU_EX:
  106. case SPRD_IOMMU_VAU:
  107. return ver;
  108. default:
  109. return -EINVAL;
  110. }
  111. }
  112. static size_t
  113. sprd_iommu_pgt_size(struct iommu_domain *domain)
  114. {
  115. return ((domain->geometry.aperture_end -
  116. domain->geometry.aperture_start + 1) >>
  117. SPRD_IOMMU_PAGE_SHIFT) * sizeof(u32);
  118. }
  119. static struct iommu_domain *sprd_iommu_domain_alloc_paging(struct device *dev)
  120. {
  121. struct sprd_iommu_domain *dom;
  122. dom = kzalloc_obj(*dom);
  123. if (!dom)
  124. return NULL;
  125. spin_lock_init(&dom->pgtlock);
  126. dom->domain.pgsize_bitmap = SPRD_IOMMU_PAGE_SIZE;
  127. dom->domain.geometry.aperture_start = 0;
  128. dom->domain.geometry.aperture_end = SZ_256M - 1;
  129. dom->domain.geometry.force_aperture = true;
  130. return &dom->domain;
  131. }
  132. static void sprd_iommu_first_vpn(struct sprd_iommu_domain *dom)
  133. {
  134. struct sprd_iommu_device *sdev = dom->sdev;
  135. u32 val;
  136. unsigned int reg;
  137. if (sdev->ver == SPRD_IOMMU_EX)
  138. reg = SPRD_EX_FIRST_VPN;
  139. else
  140. reg = SPRD_VAU_FIRST_VPN;
  141. val = dom->domain.geometry.aperture_start >> SPRD_IOMMU_PAGE_SHIFT;
  142. sprd_iommu_write(sdev, reg, val);
  143. }
  144. static void sprd_iommu_vpn_range(struct sprd_iommu_domain *dom)
  145. {
  146. struct sprd_iommu_device *sdev = dom->sdev;
  147. u32 val;
  148. unsigned int reg;
  149. if (sdev->ver == SPRD_IOMMU_EX)
  150. reg = SPRD_EX_VPN_RANGE;
  151. else
  152. reg = SPRD_VAU_VPN_RANGE;
  153. val = (dom->domain.geometry.aperture_end -
  154. dom->domain.geometry.aperture_start) >> SPRD_IOMMU_PAGE_SHIFT;
  155. sprd_iommu_write(sdev, reg, val);
  156. }
  157. static void sprd_iommu_first_ppn(struct sprd_iommu_domain *dom)
  158. {
  159. u32 val = dom->pgt_pa >> SPRD_IOMMU_PAGE_SHIFT;
  160. struct sprd_iommu_device *sdev = dom->sdev;
  161. unsigned int reg;
  162. if (sdev->ver == SPRD_IOMMU_EX)
  163. reg = SPRD_EX_FIRST_PPN;
  164. else
  165. reg = SPRD_VAU_FIRST_PPN;
  166. sprd_iommu_write(sdev, reg, val);
  167. }
  168. static void sprd_iommu_default_ppn(struct sprd_iommu_device *sdev)
  169. {
  170. u32 val = sdev->prot_page_pa >> SPRD_IOMMU_PAGE_SHIFT;
  171. if (sdev->ver == SPRD_IOMMU_EX) {
  172. sprd_iommu_write(sdev, SPRD_EX_DEFAULT_PPN, val);
  173. } else if (sdev->ver == SPRD_IOMMU_VAU) {
  174. sprd_iommu_write(sdev, SPRD_VAU_DEFAULT_PPN_RD, val);
  175. sprd_iommu_write(sdev, SPRD_VAU_DEFAULT_PPN_WR, val);
  176. }
  177. }
  178. static void sprd_iommu_hw_en(struct sprd_iommu_device *sdev, bool en)
  179. {
  180. unsigned int reg_cfg;
  181. u32 mask, val;
  182. if (sdev->ver == SPRD_IOMMU_EX)
  183. reg_cfg = SPRD_EX_CFG;
  184. else
  185. reg_cfg = SPRD_VAU_CFG;
  186. mask = SPRD_IOMMU_EN | SPRD_IOMMU_GATE_EN;
  187. val = en ? mask : 0;
  188. sprd_iommu_update_bits(sdev, reg_cfg, mask, 0, val);
  189. }
  190. static void sprd_iommu_cleanup(struct sprd_iommu_domain *dom)
  191. {
  192. size_t pgt_size;
  193. /* Nothing need to do if the domain hasn't been attached */
  194. if (!dom->sdev)
  195. return;
  196. pgt_size = sprd_iommu_pgt_size(&dom->domain);
  197. dma_free_coherent(dom->sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa);
  198. sprd_iommu_hw_en(dom->sdev, false);
  199. dom->sdev = NULL;
  200. }
  201. static void sprd_iommu_domain_free(struct iommu_domain *domain)
  202. {
  203. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  204. sprd_iommu_cleanup(dom);
  205. kfree(dom);
  206. }
  207. static int sprd_iommu_attach_device(struct iommu_domain *domain,
  208. struct device *dev,
  209. struct iommu_domain *old)
  210. {
  211. struct sprd_iommu_device *sdev = dev_iommu_priv_get(dev);
  212. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  213. size_t pgt_size = sprd_iommu_pgt_size(domain);
  214. /* The device is attached to this domain */
  215. if (sdev->dom == dom)
  216. return 0;
  217. /* The first time that domain is attaching to a device */
  218. if (!dom->pgt_va) {
  219. dom->pgt_va = dma_alloc_coherent(sdev->dev, pgt_size, &dom->pgt_pa, GFP_KERNEL);
  220. if (!dom->pgt_va)
  221. return -ENOMEM;
  222. dom->sdev = sdev;
  223. }
  224. sdev->dom = dom;
  225. /*
  226. * One sprd IOMMU serves one client device only, disabled it before
  227. * configure mapping table to avoid access conflict in case other
  228. * mapping table is stored in.
  229. */
  230. sprd_iommu_hw_en(sdev, false);
  231. sprd_iommu_first_ppn(dom);
  232. sprd_iommu_first_vpn(dom);
  233. sprd_iommu_vpn_range(dom);
  234. sprd_iommu_default_ppn(sdev);
  235. sprd_iommu_hw_en(sdev, true);
  236. return 0;
  237. }
  238. static int sprd_iommu_map(struct iommu_domain *domain, unsigned long iova,
  239. phys_addr_t paddr, size_t pgsize, size_t pgcount,
  240. int prot, gfp_t gfp, size_t *mapped)
  241. {
  242. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  243. size_t size = pgcount * SPRD_IOMMU_PAGE_SIZE;
  244. unsigned long flags;
  245. unsigned int i;
  246. u32 *pgt_base_iova;
  247. u32 pabase = (u32)paddr;
  248. unsigned long start = domain->geometry.aperture_start;
  249. unsigned long end = domain->geometry.aperture_end;
  250. if (!dom->sdev) {
  251. pr_err("No sprd_iommu_device attached to the domain\n");
  252. return -EINVAL;
  253. }
  254. if (iova < start || (iova + size) > (end + 1)) {
  255. dev_err(dom->sdev->dev, "(iova(0x%lx) + size(%zx)) are not in the range!\n",
  256. iova, size);
  257. return -EINVAL;
  258. }
  259. pgt_base_iova = dom->pgt_va + ((iova - start) >> SPRD_IOMMU_PAGE_SHIFT);
  260. spin_lock_irqsave(&dom->pgtlock, flags);
  261. for (i = 0; i < pgcount; i++) {
  262. pgt_base_iova[i] = pabase >> SPRD_IOMMU_PAGE_SHIFT;
  263. pabase += SPRD_IOMMU_PAGE_SIZE;
  264. }
  265. spin_unlock_irqrestore(&dom->pgtlock, flags);
  266. *mapped = size;
  267. return 0;
  268. }
  269. static size_t sprd_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
  270. size_t pgsize, size_t pgcount,
  271. struct iommu_iotlb_gather *iotlb_gather)
  272. {
  273. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  274. unsigned long flags;
  275. u32 *pgt_base_iova;
  276. size_t size = pgcount * SPRD_IOMMU_PAGE_SIZE;
  277. unsigned long start = domain->geometry.aperture_start;
  278. unsigned long end = domain->geometry.aperture_end;
  279. if (iova < start || (iova + size) > (end + 1))
  280. return 0;
  281. pgt_base_iova = dom->pgt_va + ((iova - start) >> SPRD_IOMMU_PAGE_SHIFT);
  282. spin_lock_irqsave(&dom->pgtlock, flags);
  283. memset(pgt_base_iova, 0, pgcount * sizeof(u32));
  284. spin_unlock_irqrestore(&dom->pgtlock, flags);
  285. return size;
  286. }
  287. static int sprd_iommu_sync_map(struct iommu_domain *domain,
  288. unsigned long iova, size_t size)
  289. {
  290. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  291. unsigned int reg;
  292. if (dom->sdev->ver == SPRD_IOMMU_EX)
  293. reg = SPRD_EX_UPDATE;
  294. else
  295. reg = SPRD_VAU_UPDATE;
  296. /* clear IOMMU TLB buffer after page table updated */
  297. sprd_iommu_write(dom->sdev, reg, 0xffffffff);
  298. return 0;
  299. }
  300. static void sprd_iommu_sync(struct iommu_domain *domain,
  301. struct iommu_iotlb_gather *iotlb_gather)
  302. {
  303. sprd_iommu_sync_map(domain, 0, 0);
  304. }
  305. static phys_addr_t sprd_iommu_iova_to_phys(struct iommu_domain *domain,
  306. dma_addr_t iova)
  307. {
  308. struct sprd_iommu_domain *dom = to_sprd_domain(domain);
  309. unsigned long flags;
  310. phys_addr_t pa;
  311. unsigned long start = domain->geometry.aperture_start;
  312. unsigned long end = domain->geometry.aperture_end;
  313. if (WARN_ON(iova < start || iova > end))
  314. return 0;
  315. spin_lock_irqsave(&dom->pgtlock, flags);
  316. pa = *(dom->pgt_va + ((iova - start) >> SPRD_IOMMU_PAGE_SHIFT));
  317. pa = (pa << SPRD_IOMMU_PAGE_SHIFT) + ((iova - start) & (SPRD_IOMMU_PAGE_SIZE - 1));
  318. spin_unlock_irqrestore(&dom->pgtlock, flags);
  319. return pa;
  320. }
  321. static struct iommu_device *sprd_iommu_probe_device(struct device *dev)
  322. {
  323. struct sprd_iommu_device *sdev = dev_iommu_priv_get(dev);
  324. return &sdev->iommu;
  325. }
  326. static int sprd_iommu_of_xlate(struct device *dev,
  327. const struct of_phandle_args *args)
  328. {
  329. struct platform_device *pdev;
  330. if (!dev_iommu_priv_get(dev)) {
  331. pdev = of_find_device_by_node(args->np);
  332. dev_iommu_priv_set(dev, platform_get_drvdata(pdev));
  333. platform_device_put(pdev);
  334. }
  335. return 0;
  336. }
  337. static const struct iommu_ops sprd_iommu_ops = {
  338. .domain_alloc_paging = sprd_iommu_domain_alloc_paging,
  339. .probe_device = sprd_iommu_probe_device,
  340. .device_group = generic_single_device_group,
  341. .of_xlate = sprd_iommu_of_xlate,
  342. .owner = THIS_MODULE,
  343. .default_domain_ops = &(const struct iommu_domain_ops) {
  344. .attach_dev = sprd_iommu_attach_device,
  345. .map_pages = sprd_iommu_map,
  346. .unmap_pages = sprd_iommu_unmap,
  347. .iotlb_sync_map = sprd_iommu_sync_map,
  348. .iotlb_sync = sprd_iommu_sync,
  349. .iova_to_phys = sprd_iommu_iova_to_phys,
  350. .free = sprd_iommu_domain_free,
  351. }
  352. };
  353. static const struct of_device_id sprd_iommu_of_match[] = {
  354. { .compatible = "sprd,iommu-v1" },
  355. { },
  356. };
  357. MODULE_DEVICE_TABLE(of, sprd_iommu_of_match);
  358. /*
  359. * Clock is not required, access to some of IOMMUs is controlled by gate
  360. * clk, enabled clocks for that kind of IOMMUs before accessing.
  361. * Return 0 for success or no clocks found.
  362. */
  363. static int sprd_iommu_clk_enable(struct sprd_iommu_device *sdev)
  364. {
  365. struct clk *eb;
  366. eb = devm_clk_get_optional(sdev->dev, NULL);
  367. if (!eb)
  368. return 0;
  369. if (IS_ERR(eb))
  370. return PTR_ERR(eb);
  371. sdev->eb = eb;
  372. return clk_prepare_enable(eb);
  373. }
  374. static void sprd_iommu_clk_disable(struct sprd_iommu_device *sdev)
  375. {
  376. if (sdev->eb)
  377. clk_disable_unprepare(sdev->eb);
  378. }
  379. static int sprd_iommu_probe(struct platform_device *pdev)
  380. {
  381. struct sprd_iommu_device *sdev;
  382. struct device *dev = &pdev->dev;
  383. void __iomem *base;
  384. int ret;
  385. sdev = devm_kzalloc(dev, sizeof(*sdev), GFP_KERNEL);
  386. if (!sdev)
  387. return -ENOMEM;
  388. base = devm_platform_ioremap_resource(pdev, 0);
  389. if (IS_ERR(base)) {
  390. dev_err(dev, "Failed to get ioremap resource.\n");
  391. return PTR_ERR(base);
  392. }
  393. sdev->base = base;
  394. sdev->prot_page_va = dma_alloc_coherent(dev, SPRD_IOMMU_PAGE_SIZE,
  395. &sdev->prot_page_pa, GFP_KERNEL);
  396. if (!sdev->prot_page_va)
  397. return -ENOMEM;
  398. platform_set_drvdata(pdev, sdev);
  399. sdev->dev = dev;
  400. ret = iommu_device_sysfs_add(&sdev->iommu, dev, NULL, dev_name(dev));
  401. if (ret)
  402. goto free_page;
  403. ret = iommu_device_register(&sdev->iommu, &sprd_iommu_ops, dev);
  404. if (ret)
  405. goto remove_sysfs;
  406. ret = sprd_iommu_clk_enable(sdev);
  407. if (ret)
  408. goto unregister_iommu;
  409. ret = sprd_iommu_get_version(sdev);
  410. if (ret < 0) {
  411. dev_err(dev, "IOMMU version(%d) is invalid.\n", ret);
  412. goto disable_clk;
  413. }
  414. sdev->ver = ret;
  415. return 0;
  416. disable_clk:
  417. sprd_iommu_clk_disable(sdev);
  418. unregister_iommu:
  419. iommu_device_unregister(&sdev->iommu);
  420. remove_sysfs:
  421. iommu_device_sysfs_remove(&sdev->iommu);
  422. free_page:
  423. dma_free_coherent(sdev->dev, SPRD_IOMMU_PAGE_SIZE, sdev->prot_page_va, sdev->prot_page_pa);
  424. return ret;
  425. }
  426. static void sprd_iommu_remove(struct platform_device *pdev)
  427. {
  428. struct sprd_iommu_device *sdev = platform_get_drvdata(pdev);
  429. dma_free_coherent(sdev->dev, SPRD_IOMMU_PAGE_SIZE, sdev->prot_page_va, sdev->prot_page_pa);
  430. platform_set_drvdata(pdev, NULL);
  431. iommu_device_sysfs_remove(&sdev->iommu);
  432. iommu_device_unregister(&sdev->iommu);
  433. }
  434. static struct platform_driver sprd_iommu_driver = {
  435. .driver = {
  436. .name = "sprd-iommu",
  437. .of_match_table = sprd_iommu_of_match,
  438. .suppress_bind_attrs = true,
  439. },
  440. .probe = sprd_iommu_probe,
  441. .remove = sprd_iommu_remove,
  442. };
  443. module_platform_driver(sprd_iommu_driver);
  444. MODULE_DESCRIPTION("IOMMU driver for Unisoc SoCs");
  445. MODULE_ALIAS("platform:sprd-iommu");
  446. MODULE_LICENSE("GPL");