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>
This commit is contained in:
parent
432d9ecb96
commit
f490682a6b
|
@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CPU_LOONGSON3
|
#ifdef CONFIG_CPU_LOONGSON3
|
||||||
return virt_to_phys(addr);
|
return phys_to_dma(dev, virt_to_phys(addr));
|
||||||
#else
|
#else
|
||||||
return virt_to_phys(addr) | 0x80000000;
|
return virt_to_phys(addr) | 0x80000000;
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
|
||||||
struct page *page)
|
struct page *page)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CPU_LOONGSON3
|
#ifdef CONFIG_CPU_LOONGSON3
|
||||||
return page_to_phys(page);
|
return phys_to_dma(dev, page_to_phys(page));
|
||||||
#else
|
#else
|
||||||
return page_to_phys(page) | 0x80000000;
|
return page_to_phys(page) | 0x80000000;
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
|
||||||
dma_addr_t dma_addr)
|
dma_addr_t dma_addr)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
|
#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
|
||||||
return dma_addr;
|
return dma_to_phys(dev, dma_addr);
|
||||||
#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
|
#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
|
||||||
return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
|
return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -86,6 +86,7 @@ config LOONGSON_MACH3X
|
||||||
select LOONGSON_MC146818
|
select LOONGSON_MC146818
|
||||||
select ZONE_DMA32
|
select ZONE_DMA32
|
||||||
select LEFI_FIRMWARE_INTERFACE
|
select LEFI_FIRMWARE_INTERFACE
|
||||||
|
select PHYS48_TO_HT40
|
||||||
help
|
help
|
||||||
Generic Loongson 3 family machines utilize the 3A/3B revision
|
Generic Loongson 3 family machines utilize the 3A/3B revision
|
||||||
of Loongson processor and RS780/SBX00 chipset.
|
of Loongson processor and RS780/SBX00 chipset.
|
||||||
|
@ -131,6 +132,10 @@ config SWIOTLB
|
||||||
select NEED_SG_DMA_LENGTH
|
select NEED_SG_DMA_LENGTH
|
||||||
select NEED_DMA_MAP_STATE
|
select NEED_DMA_MAP_STATE
|
||||||
|
|
||||||
|
config PHYS48_TO_HT40
|
||||||
|
bool
|
||||||
|
default y if CPU_LOONGSON3
|
||||||
|
|
||||||
config LOONGSON_MC146818
|
config LOONGSON_MC146818
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask)
|
||||||
|
|
||||||
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
|
dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
|
||||||
{
|
{
|
||||||
|
long nid;
|
||||||
|
#ifdef CONFIG_PHYS48_TO_HT40
|
||||||
|
/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
|
||||||
|
* Loongson-3's 48bit address space and embed it into 40bit */
|
||||||
|
nid = (paddr >> 44) & 0x3;
|
||||||
|
paddr = ((nid << 44) ^ paddr) | (nid << 37);
|
||||||
|
#endif
|
||||||
return paddr;
|
return paddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
|
||||||
{
|
{
|
||||||
|
long nid;
|
||||||
|
#ifdef CONFIG_PHYS48_TO_HT40
|
||||||
|
/* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
|
||||||
|
* Loongson-3's 48bit address space and embed it into 40bit */
|
||||||
|
nid = (daddr >> 37) & 0x3;
|
||||||
|
daddr = ((nid << 37) ^ daddr) | (nid << 44);
|
||||||
|
#endif
|
||||||
return daddr;
|
return daddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue