aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2014-11-04 01:13:24 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-11-24 01:45:01 -0500
commitf490682a6b21ffed5acd7a0d49d8371e5e625d7a (patch)
tree23fec41907ba1f5fb8cac1a5d2e0f18af6ee8fa7
parent432d9ecb9628bdcb20670b2cf0678f3738bd40a5 (diff)
MIPS: Loongson-3: Add PHYS48_TO_HT40 support
The width of HT-bus is only 40-bit, but Loongson-3 has 48-bit physical address. This implies only node-0's memory is DMAable because high bits (Node ID) will lost. Fortunately, by configuring address windows in firmware, we can extract 2bit Node ID (bit 44~47, only bit 44~45 used now) from Loongson-3's 48-bit address space and embed it into 40-bit (bit 37~38). Every NUMA node can do DMA now (however, maximum memory of each node is reduced to 2^37 = 128GB). Signed-off-by: Huacai Chen <chenhc@lemote.com> Cc: John Crispin <john@phrozen.org> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang <zhangfx@lemote.com> Cc: Zhangjin Wu <wuzhangjin@gmail.com> Patchwork: https://patchwork.linux-mips.org/patch/8321/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/mach-loongson/dma-coherence.h6
-rw-r--r--arch/mips/loongson/Kconfig5
-rw-r--r--arch/mips/loongson/common/dma-swiotlb.c14
3 files changed, 22 insertions, 3 deletions
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
index 6a902751cc7f..a90534161bd2 100644
--- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
23 size_t size) 23 size_t size)
24{ 24{
25#ifdef CONFIG_CPU_LOONGSON3 25#ifdef CONFIG_CPU_LOONGSON3
26 return virt_to_phys(addr); 26 return phys_to_dma(dev, virt_to_phys(addr));
27#else 27#else
28 return virt_to_phys(addr) | 0x80000000; 28 return virt_to_phys(addr) | 0x80000000;
29#endif 29#endif
@@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
33 struct page *page) 33 struct page *page)
34{ 34{
35#ifdef CONFIG_CPU_LOONGSON3 35#ifdef CONFIG_CPU_LOONGSON3
36 return page_to_phys(page); 36 return phys_to_dma(dev, page_to_phys(page));
37#else 37#else
38 return page_to_phys(page) | 0x80000000; 38 return page_to_phys(page) | 0x80000000;
39#endif 39#endif
@@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
43 dma_addr_t dma_addr) 43 dma_addr_t dma_addr)
44{ 44{
45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) 45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
46 return dma_addr; 46 return dma_to_phys(dev, dma_addr);
47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) 47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); 48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
49#else 49#else
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 1b91fc6a921b..72f830ac0782 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -86,6 +86,7 @@ config LOONGSON_MACH3X
86 select LOONGSON_MC146818 86 select LOONGSON_MC146818
87 select ZONE_DMA32 87 select ZONE_DMA32
88 select LEFI_FIRMWARE_INTERFACE 88 select LEFI_FIRMWARE_INTERFACE
89 select PHYS48_TO_HT40
89 help 90 help
90 Generic Loongson 3 family machines utilize the 3A/3B revision 91 Generic Loongson 3 family machines utilize the 3A/3B revision
91 of Loongson processor and RS780/SBX00 chipset. 92 of Loongson processor and RS780/SBX00 chipset.
@@ -131,6 +132,10 @@ config SWIOTLB
131 select NEED_SG_DMA_LENGTH 132 select NEED_SG_DMA_LENGTH
132 select NEED_DMA_MAP_STATE 133 select NEED_DMA_MAP_STATE
133 134
135config PHYS48_TO_HT40
136 bool
137 default y if CPU_LOONGSON3
138
134config LOONGSON_MC146818 139config LOONGSON_MC146818
135 bool 140 bool
136 default n 141 default n
diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c
index c2be01f91575..2c6b989c1bc4 100644
--- a/arch/mips/loongson/common/dma-swiotlb.c
+++ b/arch/mips/loongson/common/dma-swiotlb.c
@@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask)
105 105
106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
107{ 107{
108 long nid;
109#ifdef CONFIG_PHYS48_TO_HT40
110 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
111 * Loongson-3's 48bit address space and embed it into 40bit */
112 nid = (paddr >> 44) & 0x3;
113 paddr = ((nid << 44) ^ paddr) | (nid << 37);
114#endif
108 return paddr; 115 return paddr;
109} 116}
110 117
111phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) 118phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
112{ 119{
120 long nid;
121#ifdef CONFIG_PHYS48_TO_HT40
122 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
123 * Loongson-3's 48bit address space and embed it into 40bit */
124 nid = (daddr >> 37) & 0x3;
125 daddr = ((nid << 37) ^ daddr) | (nid << 44);
126#endif
113 return daddr; 127 return daddr;
114} 128}
115 129