mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
1299b0e05e
Loongson doesn't support DMA address above 4GB traditionally. If memory is more than 4GB, CONFIG_SWIOTLB and ZONE_DMA32 should be selected. In this way, DMA pages are allocated below 4GB preferably. However, if low memory is not enough, high pages are allocated and swiotlb is used for bouncing. Moreover, we provide a platform-specific dma_map_ops::set_dma_mask() to set a device's dma_mask and coherent_dma_mask. We use these masks to distinguishes an allocated page can be used for DMA directly, or need swiotlb to bounce. Recently, we found that 32-bit DMA isn't a hardware bug, but a hardware configuration issue. So, latest firmware has enable the DMA support as high as 40-bit. To support all-memory DMA for all devices (besides the Loongson platform limit, there are still some devices have their own DMA32 limit), and also to be compatible with old firmware, we keep use swiotlb. Signed-off-by: Huacai Chen <chenhc@lemote.com> Signed-off-by: Hongliang Tao <taohl@lemote.com> Signed-off-by: Hua Yan <yanh@lemote.com> Tested-by: Alex Smith <alex.smith@imgtec.com> Reviewed-by: Alex Smith <alex.smith@imgtec.com> Cc: John Crispin <john@phrozen.org> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: Aurelien Jarno <aurelien@aurel32.net> 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/6636 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
82 lines
2.0 KiB
C
82 lines
2.0 KiB
C
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (C) 2006, 07 Ralf Baechle <ralf@linux-mips.org>
|
|
* Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
|
|
* Author: Fuxin Zhang, zhangfx@lemote.com
|
|
*
|
|
*/
|
|
#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H
|
|
#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H
|
|
|
|
#ifdef CONFIG_SWIOTLB
|
|
#include <linux/swiotlb.h>
|
|
#endif
|
|
|
|
struct device;
|
|
|
|
extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
|
|
extern phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
|
|
static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
|
|
size_t size)
|
|
{
|
|
#ifdef CONFIG_CPU_LOONGSON3
|
|
return virt_to_phys(addr);
|
|
#else
|
|
return virt_to_phys(addr) | 0x80000000;
|
|
#endif
|
|
}
|
|
|
|
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
|
|
struct page *page)
|
|
{
|
|
#ifdef CONFIG_CPU_LOONGSON3
|
|
return page_to_phys(page);
|
|
#else
|
|
return page_to_phys(page) | 0x80000000;
|
|
#endif
|
|
}
|
|
|
|
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
|
|
dma_addr_t dma_addr)
|
|
{
|
|
#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
|
|
return dma_addr;
|
|
#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
|
|
return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
|
|
#else
|
|
return dma_addr & 0x7fffffff;
|
|
#endif
|
|
}
|
|
|
|
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
|
|
size_t size, enum dma_data_direction direction)
|
|
{
|
|
}
|
|
|
|
static inline int plat_dma_supported(struct device *dev, u64 mask)
|
|
{
|
|
/*
|
|
* we fall back to GFP_DMA when the mask isn't all 1s,
|
|
* so we can't guarantee allocations that must be
|
|
* within a tighter range than GFP_DMA..
|
|
*/
|
|
if (mask < DMA_BIT_MASK(24))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int plat_device_is_coherent(struct device *dev)
|
|
{
|
|
#ifdef CONFIG_DMA_NONCOHERENT
|
|
return 0;
|
|
#else
|
|
return 1;
|
|
#endif /* CONFIG_DMA_NONCOHERENT */
|
|
}
|
|
|
|
#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
|