forked from starfive-tech/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RISC-V: Support non-coherent DMA operations
** Do not upstream ** This is hacky fix just for testing. The actual patch would read the RISCV_UNCACHED_OFFSET from the DT for only the non-coherent devices. All other devices on beagleV and all other platform should just set dma_default_coherent to true. [Emil: remove spurious whitespace and fix format string warning] Signed-off-by: Atish Patra <[email protected]> Signed-off-by: Emil Renner Berthing <[email protected]>
- Loading branch information
Showing
4 changed files
with
79 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* DMA mapping implementation inspired from arm/mm/dma-mapping.c | ||
* | ||
* Copyright (c) 2021 Western Digital Corporation or its affiliates. | ||
*/ | ||
|
||
#include <linux/dma-direct.h> | ||
#include <linux/dma-map-ops.h> | ||
#include <linux/init.h> | ||
#include <linux/io.h> | ||
#include <linux/mm.h> | ||
#include <asm/cpu_ops.h> | ||
#include <asm/sbi.h> | ||
#include <asm/smp.h> | ||
|
||
//TODO Do it through SBI | ||
#include <soc/sifive/sifive_l2_cache.h> | ||
|
||
void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir) | ||
{ | ||
sifive_l2_flush64_range(paddr, size); | ||
} | ||
|
||
void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir) | ||
{ | ||
sifive_l2_flush64_range(paddr, size); | ||
} | ||
|
||
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, | ||
const struct iommu_ops *iommu, bool coherent) | ||
{ | ||
dev_info(dev, "coherent device %d dev->dma_coherent %d\n", coherent, dev->dma_coherent); | ||
dev->dma_coherent = coherent; | ||
} | ||
|
||
//TODO: We are supposed to invalidate the cache here | ||
void arch_dma_prep_coherent(struct page *page, size_t size) | ||
{ | ||
void *flush_addr = page_address(page); | ||
|
||
memset(flush_addr, 0, size); | ||
sifive_l2_flush64_range(__pa(flush_addr), size); | ||
} | ||
|
||
void arch_dma_clear_uncached(void *addr, size_t size) | ||
{ | ||
memunmap(addr); | ||
} | ||
|
||
void *arch_dma_set_uncached(void *addr, size_t size) | ||
{ | ||
phys_addr_t phys_addr = __pa(addr) + CONFIG_RISCV_UNCACHED_OFFSET; | ||
void *mem_base = NULL; | ||
|
||
mem_base = memremap(phys_addr, size, MEMREMAP_WT); | ||
if (!mem_base) { | ||
pr_err("%s memremap failed for addr %px\n", __func__, addr); | ||
return ERR_PTR(-EINVAL); | ||
} | ||
|
||
return mem_base; | ||
} |