Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / arch / mips / loongson64 / common / dma-swiotlb.c
blob7bbcf89475f3a305a0f5ae5be4c084f002285f66
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/mm.h>
3 #include <linux/init.h>
4 #include <linux/dma-mapping.h>
5 #include <linux/scatterlist.h>
6 #include <linux/swiotlb.h>
7 #include <linux/bootmem.h>
9 #include <asm/bootinfo.h>
10 #include <boot_param.h>
11 #include <dma-coherence.h>
13 static void *loongson_dma_alloc_coherent(struct device *dev, size_t size,
14 dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
16 void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
18 mb();
19 return ret;
22 static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page,
23 unsigned long offset, size_t size,
24 enum dma_data_direction dir,
25 unsigned long attrs)
27 dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
28 dir, attrs);
29 mb();
30 return daddr;
33 static int loongson_dma_map_sg(struct device *dev, struct scatterlist *sg,
34 int nents, enum dma_data_direction dir,
35 unsigned long attrs)
37 int r = swiotlb_map_sg_attrs(dev, sg, nents, dir, attrs);
38 mb();
40 return r;
43 static void loongson_dma_sync_single_for_device(struct device *dev,
44 dma_addr_t dma_handle, size_t size,
45 enum dma_data_direction dir)
47 swiotlb_sync_single_for_device(dev, dma_handle, size, dir);
48 mb();
51 static void loongson_dma_sync_sg_for_device(struct device *dev,
52 struct scatterlist *sg, int nents,
53 enum dma_data_direction dir)
55 swiotlb_sync_sg_for_device(dev, sg, nents, dir);
56 mb();
59 static int loongson_dma_supported(struct device *dev, u64 mask)
61 if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits))
62 return 0;
63 return swiotlb_dma_supported(dev, mask);
66 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
68 long nid;
69 #ifdef CONFIG_PHYS48_TO_HT40
70 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
71 * Loongson-3's 48bit address space and embed it into 40bit */
72 nid = (paddr >> 44) & 0x3;
73 paddr = ((nid << 44) ^ paddr) | (nid << 37);
74 #endif
75 return paddr;
78 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
80 long nid;
81 #ifdef CONFIG_PHYS48_TO_HT40
82 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
83 * Loongson-3's 48bit address space and embed it into 40bit */
84 nid = (daddr >> 37) & 0x3;
85 daddr = ((nid << 37) ^ daddr) | (nid << 44);
86 #endif
87 return daddr;
90 static const struct dma_map_ops loongson_dma_map_ops = {
91 .alloc = loongson_dma_alloc_coherent,
92 .free = swiotlb_free,
93 .map_page = loongson_dma_map_page,
94 .unmap_page = swiotlb_unmap_page,
95 .map_sg = loongson_dma_map_sg,
96 .unmap_sg = swiotlb_unmap_sg_attrs,
97 .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
98 .sync_single_for_device = loongson_dma_sync_single_for_device,
99 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
100 .sync_sg_for_device = loongson_dma_sync_sg_for_device,
101 .mapping_error = swiotlb_dma_mapping_error,
102 .dma_supported = loongson_dma_supported,
105 void __init plat_swiotlb_setup(void)
107 swiotlb_init(1);
108 mips_dma_map_ops = &loongson_dma_map_ops;