aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShunqian Zheng <zhengsq@rock-chips.com>2016-06-23 22:13:29 -0400
committerJoerg Roedel <jroedel@suse.de>2016-06-27 08:50:08 -0400
commit4f0aba676735c653b4e739b760c1e66cd520d3e3 (patch)
tree69d0c011f1379b5b60c57fd822fd575f5fc5825d
parent3d08f434bd58656ae630376d0b5afd6ca1ffb013 (diff)
iommu/rockchip: Use DMA API to manage coherency
Use DMA API instead of architecture internal functions like __cpuc_flush_dcache_area() etc. The biggest difficulty here is that dma_map and _sync calls require some struct device, while there is no real 1:1 relation between an IOMMU domain and some device. To overcome this, a simple platform device is registered for each allocated IOMMU domain. With this patch, this driver can be used on both ARM and ARM64 platforms, such as RK3288 and RK3399 respectively. Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com> Signed-off-by: Tomasz Figa <tfiga@chromium.org> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/rockchip-iommu.c162
1 files changed, 123 insertions, 39 deletions
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 8a5bac7ff0b7..712ed7591783 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -4,11 +4,10 @@
4 * published by the Free Software Foundation. 4 * published by the Free Software Foundation.
5 */ 5 */
6 6
7#include <asm/cacheflush.h>
8#include <asm/pgtable.h>
9#include <linux/compiler.h> 7#include <linux/compiler.h>
10#include <linux/delay.h> 8#include <linux/delay.h>
11#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/dma-iommu.h>
12#include <linux/errno.h> 11#include <linux/errno.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
14#include <linux/io.h> 13#include <linux/io.h>
@@ -77,7 +76,9 @@
77 76
78struct rk_iommu_domain { 77struct rk_iommu_domain {
79 struct list_head iommus; 78 struct list_head iommus;
79 struct platform_device *pdev;
80 u32 *dt; /* page directory table */ 80 u32 *dt; /* page directory table */
81 dma_addr_t dt_dma;
81 spinlock_t iommus_lock; /* lock for iommus list */ 82 spinlock_t iommus_lock; /* lock for iommus list */
82 spinlock_t dt_lock; /* lock for modifying page directory table */ 83 spinlock_t dt_lock; /* lock for modifying page directory table */
83 84
@@ -93,14 +94,12 @@ struct rk_iommu {
93 struct iommu_domain *domain; /* domain to which iommu is attached */ 94 struct iommu_domain *domain; /* domain to which iommu is attached */
94}; 95};
95 96
96static inline void rk_table_flush(u32 *va, unsigned int count) 97static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma,
98 unsigned int count)
97{ 99{
98 phys_addr_t pa_start = virt_to_phys(va); 100 size_t size = count * sizeof(u32); /* count of u32 entry */
99 phys_addr_t pa_end = virt_to_phys(va + count);
100 size_t size = pa_end - pa_start;
101 101
102 __cpuc_flush_dcache_area(va, size); 102 dma_sync_single_for_device(&dom->pdev->dev, dma, size, DMA_TO_DEVICE);
103 outer_flush_range(pa_start, pa_end);
104} 103}
105 104
106static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom) 105static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)
@@ -183,10 +182,9 @@ static inline bool rk_dte_is_pt_valid(u32 dte)
183 return dte & RK_DTE_PT_VALID; 182 return dte & RK_DTE_PT_VALID;
184} 183}
185 184
186static u32 rk_mk_dte(u32 *pt) 185static inline u32 rk_mk_dte(dma_addr_t pt_dma)
187{ 186{
188 phys_addr_t pt_phys = virt_to_phys(pt); 187 return (pt_dma & RK_DTE_PT_ADDRESS_MASK) | RK_DTE_PT_VALID;
189 return (pt_phys & RK_DTE_PT_ADDRESS_MASK) | RK_DTE_PT_VALID;
190} 188}
191 189
192/* 190/*
@@ -603,13 +601,16 @@ static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
603static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain, 601static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
604 dma_addr_t iova) 602 dma_addr_t iova)
605{ 603{
604 struct device *dev = &rk_domain->pdev->dev;
606 u32 *page_table, *dte_addr; 605 u32 *page_table, *dte_addr;
607 u32 dte; 606 u32 dte_index, dte;
608 phys_addr_t pt_phys; 607 phys_addr_t pt_phys;
608 dma_addr_t pt_dma;
609 609
610 assert_spin_locked(&rk_domain->dt_lock); 610 assert_spin_locked(&rk_domain->dt_lock);
611 611
612 dte_addr = &rk_domain->dt[rk_iova_dte_index(iova)]; 612 dte_index = rk_iova_dte_index(iova);
613 dte_addr = &rk_domain->dt[dte_index];
613 dte = *dte_addr; 614 dte = *dte_addr;
614 if (rk_dte_is_pt_valid(dte)) 615 if (rk_dte_is_pt_valid(dte))
615 goto done; 616 goto done;
@@ -618,19 +619,27 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
618 if (!page_table) 619 if (!page_table)
619 return ERR_PTR(-ENOMEM); 620 return ERR_PTR(-ENOMEM);
620 621
621 dte = rk_mk_dte(page_table); 622 pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);
622 *dte_addr = dte; 623 if (dma_mapping_error(dev, pt_dma)) {
624 dev_err(dev, "DMA mapping error while allocating page table\n");
625 free_page((unsigned long)page_table);
626 return ERR_PTR(-ENOMEM);
627 }
623 628
624 rk_table_flush(page_table, NUM_PT_ENTRIES); 629 dte = rk_mk_dte(pt_dma);
625 rk_table_flush(dte_addr, 1); 630 *dte_addr = dte;
626 631
632 rk_table_flush(rk_domain, pt_dma, NUM_PT_ENTRIES);
633 rk_table_flush(rk_domain,
634 rk_domain->dt_dma + dte_index * sizeof(u32), 1);
627done: 635done:
628 pt_phys = rk_dte_pt_address(dte); 636 pt_phys = rk_dte_pt_address(dte);
629 return (u32 *)phys_to_virt(pt_phys); 637 return (u32 *)phys_to_virt(pt_phys);
630} 638}
631 639
632static size_t rk_iommu_unmap_iova(struct rk_iommu_domain *rk_domain, 640static size_t rk_iommu_unmap_iova(struct rk_iommu_domain *rk_domain,
633 u32 *pte_addr, dma_addr_t iova, size_t size) 641 u32 *pte_addr, dma_addr_t pte_dma,
642 size_t size)
634{ 643{
635 unsigned int pte_count; 644 unsigned int pte_count;
636 unsigned int pte_total = size / SPAGE_SIZE; 645 unsigned int pte_total = size / SPAGE_SIZE;
@@ -645,14 +654,14 @@ static size_t rk_iommu_unmap_iova(struct rk_iommu_domain *rk_domain,
645 pte_addr[pte_count] = rk_mk_pte_invalid(pte); 654 pte_addr[pte_count] = rk_mk_pte_invalid(pte);
646 } 655 }
647 656
648 rk_table_flush(pte_addr, pte_count); 657 rk_table_flush(rk_domain, pte_dma, pte_count);
649 658
650 return pte_count * SPAGE_SIZE; 659 return pte_count * SPAGE_SIZE;
651} 660}
652 661
653static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr, 662static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
654 dma_addr_t iova, phys_addr_t paddr, size_t size, 663 dma_addr_t pte_dma, dma_addr_t iova,
655 int prot) 664 phys_addr_t paddr, size_t size, int prot)
656{ 665{
657 unsigned int pte_count; 666 unsigned int pte_count;
658 unsigned int pte_total = size / SPAGE_SIZE; 667 unsigned int pte_total = size / SPAGE_SIZE;
@@ -671,7 +680,7 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
671 paddr += SPAGE_SIZE; 680 paddr += SPAGE_SIZE;
672 } 681 }
673 682
674 rk_table_flush(pte_addr, pte_count); 683 rk_table_flush(rk_domain, pte_dma, pte_total);
675 684
676 /* 685 /*
677 * Zap the first and last iova to evict from iotlb any previously 686 * Zap the first and last iova to evict from iotlb any previously
@@ -684,7 +693,8 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
684 return 0; 693 return 0;
685unwind: 694unwind:
686 /* Unmap the range of iovas that we just mapped */ 695 /* Unmap the range of iovas that we just mapped */
687 rk_iommu_unmap_iova(rk_domain, pte_addr, iova, pte_count * SPAGE_SIZE); 696 rk_iommu_unmap_iova(rk_domain, pte_addr, pte_dma,
697 pte_count * SPAGE_SIZE);
688 698
689 iova += pte_count * SPAGE_SIZE; 699 iova += pte_count * SPAGE_SIZE;
690 page_phys = rk_pte_page_address(pte_addr[pte_count]); 700 page_phys = rk_pte_page_address(pte_addr[pte_count]);
@@ -699,8 +709,9 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
699{ 709{
700 struct rk_iommu_domain *rk_domain = to_rk_domain(domain); 710 struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
701 unsigned long flags; 711 unsigned long flags;
702 dma_addr_t iova = (dma_addr_t)_iova; 712 dma_addr_t pte_dma, iova = (dma_addr_t)_iova;
703 u32 *page_table, *pte_addr; 713 u32 *page_table, *pte_addr;
714 u32 dte_index, pte_index;
704 int ret; 715 int ret;
705 716
706 spin_lock_irqsave(&rk_domain->dt_lock, flags); 717 spin_lock_irqsave(&rk_domain->dt_lock, flags);
@@ -718,8 +729,13 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
718 return PTR_ERR(page_table); 729 return PTR_ERR(page_table);
719 } 730 }
720 731
721 pte_addr = &page_table[rk_iova_pte_index(iova)]; 732 dte_index = rk_domain->dt[rk_iova_dte_index(iova)];
722 ret = rk_iommu_map_iova(rk_domain, pte_addr, iova, paddr, size, prot); 733 pte_index = rk_iova_pte_index(iova);
734 pte_addr = &page_table[pte_index];
735 pte_dma = rk_dte_pt_address(dte_index) + pte_index * sizeof(u32);
736 ret = rk_iommu_map_iova(rk_domain, pte_addr, pte_dma, iova,
737 paddr, size, prot);
738
723 spin_unlock_irqrestore(&rk_domain->dt_lock, flags); 739 spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
724 740
725 return ret; 741 return ret;
@@ -730,7 +746,7 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
730{ 746{
731 struct rk_iommu_domain *rk_domain = to_rk_domain(domain); 747 struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
732 unsigned long flags; 748 unsigned long flags;
733 dma_addr_t iova = (dma_addr_t)_iova; 749 dma_addr_t pte_dma, iova = (dma_addr_t)_iova;
734 phys_addr_t pt_phys; 750 phys_addr_t pt_phys;
735 u32 dte; 751 u32 dte;
736 u32 *pte_addr; 752 u32 *pte_addr;
@@ -754,7 +770,8 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
754 770
755 pt_phys = rk_dte_pt_address(dte); 771 pt_phys = rk_dte_pt_address(dte);
756 pte_addr = (u32 *)phys_to_virt(pt_phys) + rk_iova_pte_index(iova); 772 pte_addr = (u32 *)phys_to_virt(pt_phys) + rk_iova_pte_index(iova);
757 unmap_size = rk_iommu_unmap_iova(rk_domain, pte_addr, iova, size); 773 pte_dma = pt_phys + rk_iova_pte_index(iova) * sizeof(u32);
774 unmap_size = rk_iommu_unmap_iova(rk_domain, pte_addr, pte_dma, size);
758 775
759 spin_unlock_irqrestore(&rk_domain->dt_lock, flags); 776 spin_unlock_irqrestore(&rk_domain->dt_lock, flags);
760 777
@@ -787,7 +804,6 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
787 struct rk_iommu_domain *rk_domain = to_rk_domain(domain); 804 struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
788 unsigned long flags; 805 unsigned long flags;
789 int ret, i; 806 int ret, i;
790 phys_addr_t dte_addr;
791 807
792 /* 808 /*
793 * Allow 'virtual devices' (e.g., drm) to attach to domain. 809 * Allow 'virtual devices' (e.g., drm) to attach to domain.
@@ -812,9 +828,9 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
812 if (ret) 828 if (ret)
813 return ret; 829 return ret;
814 830
815 dte_addr = virt_to_phys(rk_domain->dt);
816 for (i = 0; i < iommu->num_mmu; i++) { 831 for (i = 0; i < iommu->num_mmu; i++) {
817 rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dte_addr); 832 rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR,
833 rk_domain->dt_dma);
818 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); 834 rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
819 rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); 835 rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
820 } 836 }
@@ -870,14 +886,30 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
870static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) 886static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
871{ 887{
872 struct rk_iommu_domain *rk_domain; 888 struct rk_iommu_domain *rk_domain;
889 struct platform_device *pdev;
890 struct device *iommu_dev;
873 891
874 if (type != IOMMU_DOMAIN_UNMANAGED) 892 if (type != IOMMU_DOMAIN_UNMANAGED)
875 return NULL; 893 return NULL;
876 894
877 rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL); 895 /* Register a pdev per domain, so DMA API can base on this *dev
878 if (!rk_domain) 896 * even some virtual master doesn't have an iommu slave
897 */
898 pdev = platform_device_register_simple("rk_iommu_domain",
899 PLATFORM_DEVID_AUTO, NULL, 0);
900 if (IS_ERR(pdev))
879 return NULL; 901 return NULL;
880 902
903 rk_domain = devm_kzalloc(&pdev->dev, sizeof(*rk_domain), GFP_KERNEL);
904 if (!rk_domain)
905 goto err_unreg_pdev;
906
907 rk_domain->pdev = pdev;
908
909 /* To init the iovad which is required by iommu_dma_init_domain() */
910 if (iommu_get_dma_cookie(&rk_domain->domain))
911 goto err_unreg_pdev;
912
881 /* 913 /*
882 * rk32xx iommus use a 2 level pagetable. 914 * rk32xx iommus use a 2 level pagetable.
883 * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries. 915 * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries.
@@ -885,9 +917,17 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
885 */ 917 */
886 rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32); 918 rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
887 if (!rk_domain->dt) 919 if (!rk_domain->dt)
888 goto err_dt; 920 goto err_put_cookie;
921
922 iommu_dev = &pdev->dev;
923 rk_domain->dt_dma = dma_map_single(iommu_dev, rk_domain->dt,
924 SPAGE_SIZE, DMA_TO_DEVICE);
925 if (dma_mapping_error(iommu_dev, rk_domain->dt_dma)) {
926 dev_err(iommu_dev, "DMA map error for DT\n");
927 goto err_free_dt;
928 }
889 929
890 rk_table_flush(rk_domain->dt, NUM_DT_ENTRIES); 930 rk_table_flush(rk_domain, rk_domain->dt_dma, NUM_DT_ENTRIES);
891 931
892 spin_lock_init(&rk_domain->iommus_lock); 932 spin_lock_init(&rk_domain->iommus_lock);
893 spin_lock_init(&rk_domain->dt_lock); 933 spin_lock_init(&rk_domain->dt_lock);
@@ -895,8 +935,13 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
895 935
896 return &rk_domain->domain; 936 return &rk_domain->domain;
897 937
898err_dt: 938err_free_dt:
899 kfree(rk_domain); 939 free_page((unsigned long)rk_domain->dt);
940err_put_cookie:
941 iommu_put_dma_cookie(&rk_domain->domain);
942err_unreg_pdev:
943 platform_device_unregister(pdev);
944
900 return NULL; 945 return NULL;
901} 946}
902 947
@@ -912,12 +957,19 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
912 if (rk_dte_is_pt_valid(dte)) { 957 if (rk_dte_is_pt_valid(dte)) {
913 phys_addr_t pt_phys = rk_dte_pt_address(dte); 958 phys_addr_t pt_phys = rk_dte_pt_address(dte);
914 u32 *page_table = phys_to_virt(pt_phys); 959 u32 *page_table = phys_to_virt(pt_phys);
960 dma_unmap_single(&rk_domain->pdev->dev, pt_phys,
961 SPAGE_SIZE, DMA_TO_DEVICE);
915 free_page((unsigned long)page_table); 962 free_page((unsigned long)page_table);
916 } 963 }
917 } 964 }
918 965
966 dma_unmap_single(&rk_domain->pdev->dev, rk_domain->dt_dma,
967 SPAGE_SIZE, DMA_TO_DEVICE);
919 free_page((unsigned long)rk_domain->dt); 968 free_page((unsigned long)rk_domain->dt);
920 kfree(rk_domain); 969
970 iommu_put_dma_cookie(&rk_domain->domain);
971
972 platform_device_unregister(rk_domain->pdev);
921} 973}
922 974
923static bool rk_iommu_is_dev_iommu_master(struct device *dev) 975static bool rk_iommu_is_dev_iommu_master(struct device *dev)
@@ -1029,6 +1081,30 @@ static const struct iommu_ops rk_iommu_ops = {
1029 .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, 1081 .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
1030}; 1082};
1031 1083
1084static int rk_iommu_domain_probe(struct platform_device *pdev)
1085{
1086 struct device *dev = &pdev->dev;
1087
1088 dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL);
1089 if (!dev->dma_parms)
1090 return -ENOMEM;
1091
1092 /* Set dma_ops for dev, otherwise it would be dummy_dma_ops */
1093 arch_setup_dma_ops(dev, 0, DMA_BIT_MASK(32), NULL, false);
1094
1095 dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
1096 dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
1097
1098 return 0;
1099}
1100
1101static struct platform_driver rk_iommu_domain_driver = {
1102 .probe = rk_iommu_domain_probe,
1103 .driver = {
1104 .name = "rk_iommu_domain",
1105 },
1106};
1107
1032static int rk_iommu_probe(struct platform_device *pdev) 1108static int rk_iommu_probe(struct platform_device *pdev)
1033{ 1109{
1034 struct device *dev = &pdev->dev; 1110 struct device *dev = &pdev->dev;
@@ -1106,11 +1182,19 @@ static int __init rk_iommu_init(void)
1106 if (ret) 1182 if (ret)
1107 return ret; 1183 return ret;
1108 1184
1109 return platform_driver_register(&rk_iommu_driver); 1185 ret = platform_driver_register(&rk_iommu_domain_driver);
1186 if (ret)
1187 return ret;
1188
1189 ret = platform_driver_register(&rk_iommu_driver);
1190 if (ret)
1191 platform_driver_unregister(&rk_iommu_domain_driver);
1192 return ret;
1110} 1193}
1111static void __exit rk_iommu_exit(void) 1194static void __exit rk_iommu_exit(void)
1112{ 1195{
1113 platform_driver_unregister(&rk_iommu_driver); 1196 platform_driver_unregister(&rk_iommu_driver);
1197 platform_driver_unregister(&rk_iommu_domain_driver);
1114} 1198}
1115 1199
1116subsys_initcall(rk_iommu_init); 1200subsys_initcall(rk_iommu_init);