Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * DMA implementation for Hexagon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/dma-map-ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/genalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static struct gen_pool *coherent_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Allocates from a pool of uncached memory that was reserved at boot time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 		gfp_t flag, unsigned long attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 	void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	 * Our max_low_pfn should have been backed off by 16MB in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	 * mm/init.c to create DMA coherent space.  Use that as the VA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 	 * for the pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 	if (coherent_pool == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 		coherent_pool = gen_pool_create(PAGE_SHIFT, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 		if (coherent_pool == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 			panic("Can't create %s() memory pool!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 			gen_pool_add(coherent_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 				(unsigned long)pfn_to_virt(max_low_pfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 				hexagon_coherent_pool_size, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	ret = (void *) gen_pool_alloc(coherent_pool, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 		memset(ret, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 		*dma_addr = (dma_addr_t) virt_to_phys(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 		*dma_addr = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void arch_dma_free(struct device *dev, size_t size, void *vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 		dma_addr_t dma_addr, unsigned long attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 		enum dma_data_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	void *addr = phys_to_virt(paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 	switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 	case DMA_TO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 		hexagon_clean_dcache_range((unsigned long) addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 		(unsigned long) addr + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 	case DMA_FROM_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 		hexagon_inv_dcache_range((unsigned long) addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 		(unsigned long) addr + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 	case DMA_BIDIRECTIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 		flush_dcache_range((unsigned long) addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 		(unsigned long) addr + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }