Add samsung specific changes

This commit is contained in:
2025-08-11 14:29:00 +02:00
parent c66122e619
commit 4d134a1294
2688 changed files with 1127995 additions and 11475 deletions

View File

@@ -120,6 +120,18 @@ config DMA_RESTRICTED_POOL
and <kernel/dma/swiotlb.c>.
If unsure, say "n".
config SWIOTLB_NONLINEAR
bool "Allow swiotlb to use non-linear memory as bounce buffers"
depends on SWIOTLB
help
This allows swiotlb driver to work with memory regions where
physical to virtual address translations can't be done using APIs
such as phys_to_virt. These could be reserved memory regions that
are not mapped by default or could be seen as "device" memory
accessed via ioremap().
If unsure, say "n".
#
# Should be selected if we can mmap non-coherent mappings to userspace.
# The only thing that is really required is a way to set an uncached bit

View File

@@ -96,6 +96,16 @@ static struct io_tlb_mem io_tlb_default_mem;
#endif /* CONFIG_SWIOTLB_DYNAMIC */
#ifdef CONFIG_SWIOTLB_NONLINEAR
phys_addr_t io_tlb_start, io_tlb_end;
static unsigned long io_tlb_nslabs;
static char *io_tlb_vstart;
static inline unsigned char *swiotlb_phys_to_virt(phys_addr_t tlb_addr);
#else
#define swiotlb_phys_to_virt phys_to_virt
#endif
static unsigned long default_nslabs = IO_TLB_DEFAULT_SIZE >> IO_TLB_SHIFT;
static unsigned long default_nareas;
@@ -266,7 +276,7 @@ void __init swiotlb_update_mem_attributes(void)
static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
unsigned long nslabs, bool late_alloc, unsigned int nareas)
{
void *vaddr = phys_to_virt(start);
void *vaddr = swiotlb_phys_to_virt(start);
unsigned long bytes = nslabs << IO_TLB_SHIFT, i;
mem->nslabs = nslabs;
@@ -518,6 +528,63 @@ error_area:
return -ENOMEM;
}
#ifdef CONFIG_SWIOTLB_NONLINEAR
static int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
{
struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
unsigned long bytes = nslabs << IO_TLB_SHIFT;
unsigned int area_order;
/* protect against double initialization */
if (WARN_ON_ONCE(mem->nslabs))
return -ENOMEM;
if (!default_nareas)
swiotlb_adjust_nareas(num_possible_cpus());
area_order = get_order(array_size(sizeof(*mem->areas),
default_nareas));
mem->areas = (struct io_tlb_area *)
__get_free_pages(GFP_KERNEL | __GFP_ZERO, area_order);
if (!mem->areas)
return -ENOMEM;
mem->slots = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(array_size(sizeof(*mem->slots), nslabs)));
if (!mem->slots)
goto error_slots;
set_memory_decrypted((unsigned long)tlb, bytes >> PAGE_SHIFT);
swiotlb_init_io_tlb_pool(mem, io_tlb_start, nslabs, true, default_nareas);
add_mem_pool(&io_tlb_default_mem, mem);
swiotlb_print_info();
return 0;
error_slots:
free_pages((unsigned long)mem->areas, area_order);
return -ENOMEM;
}
int swiotlb_late_init_with_tblpaddr(char *tlb,
phys_addr_t tlb_paddr, unsigned long nslabs)
{
unsigned long bytes;
if (io_tlb_start)
return -EBUSY;
bytes = nslabs << IO_TLB_SHIFT;
io_tlb_nslabs = nslabs;
io_tlb_start = tlb_paddr;
io_tlb_vstart = tlb;
io_tlb_end = io_tlb_start + bytes;
return swiotlb_late_init_with_tbl(tlb, nslabs);
}
EXPORT_SYMBOL_GPL(swiotlb_late_init_with_tblpaddr);
#endif /* CONFIG_SWIOTLB_NONLINEAR */
void __init swiotlb_exit(void)
{
struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
@@ -829,6 +896,13 @@ static unsigned int swiotlb_align_offset(struct device *dev, u64 addr)
return addr & dma_get_min_align_mask(dev) & (IO_TLB_SIZE - 1);
}
#ifdef CONFIG_SWIOTLB_NONLINEAR
static inline unsigned char *swiotlb_phys_to_virt(phys_addr_t tlb_addr)
{
return (unsigned char *)(io_tlb_vstart + (tlb_addr - io_tlb_start));
}
#endif
/*
* Bounce: copy the swiotlb buffer from or back to the original dma location
*/
@@ -1431,6 +1505,10 @@ void swiotlb_tbl_unmap_single(struct device *dev, phys_addr_t tlb_addr,
swiotlb_release_slots(dev, tlb_addr);
}
#ifdef CONFIG_SWIOTLB_NONLINEAR
EXPORT_SYMBOL_GPL(swiotlb_tbl_unmap_single);
#endif
void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
size_t size, enum dma_data_direction dir)
{
@@ -1481,6 +1559,15 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size,
arch_sync_dma_for_device(swiotlb_addr, size, dir);
return dma_addr;
}
#ifdef CONFIG_SWIOTLB_NONLINEAR
EXPORT_SYMBOL_GPL(swiotlb_map);
size_t swiotlb_max_mapping_size(struct device *dev)
{
return 4096;
}
#else
size_t swiotlb_max_mapping_size(struct device *dev)
{
@@ -1497,6 +1584,7 @@ size_t swiotlb_max_mapping_size(struct device *dev)
return ((size_t)IO_TLB_SIZE) * IO_TLB_SEGSIZE - min_align;
}
#endif
/**
* is_swiotlb_allocated() - check if the default software IO TLB is initialized