size_t size)
{
#ifdef CONFIG_CPU_LOONGSON3
- return virt_to_phys(addr);
+ return phys_to_dma(dev, virt_to_phys(addr));
#else
return virt_to_phys(addr) | 0x80000000;
#endif
struct page *page)
{
#ifdef CONFIG_CPU_LOONGSON3
- return page_to_phys(page);
+ return phys_to_dma(dev, page_to_phys(page));
#else
return page_to_phys(page) | 0x80000000;
#endif
dma_addr_t dma_addr)
{
#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)
return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
#else
select LOONGSON_MC146818
select ZONE_DMA32
select LEFI_FIRMWARE_INTERFACE
+ select PHYS48_TO_HT40
help
Generic Loongson 3 family machines utilize the 3A/3B revision
of Loongson processor and RS780/SBX00 chipset.
select NEED_SG_DMA_LENGTH
select NEED_DMA_MAP_STATE
+config PHYS48_TO_HT40
+ bool
+ default y if CPU_LOONGSON3
+
config LOONGSON_MC146818
bool
default n
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;
}
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;
}