Module Name: src Committed By: riastradh Date: Sun Dec 19 12:03:30 UTC 2021
Modified Files: src/sys/external/bsd/drm2/include/linux: io-mapping.h Log Message: drm: Allow >page-sized io_mapping_map_wc. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 \ src/sys/external/bsd/drm2/include/linux/io-mapping.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/include/linux/io-mapping.h diff -u src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.9 src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.10 --- src/sys/external/bsd/drm2/include/linux/io-mapping.h:1.9 Sun Dec 19 11:57:43 2021 +++ src/sys/external/bsd/drm2/include/linux/io-mapping.h Sun Dec 19 12:03:30 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: io-mapping.h,v 1.9 2021/12/19 11:57:43 riastradh Exp $ */ +/* $NetBSD: io-mapping.h,v 1.10 2021/12/19 12:03:30 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -45,7 +45,8 @@ struct io_mapping { bus_addr_t base; /* Linux API */ bus_size_t size; /* Linux API */ vaddr_t diom_va; - bool diom_mapped; + bus_size_t diom_mapsize; + bool diom_atomic; }; static inline bool @@ -77,7 +78,8 @@ bus_space_io_mapping_init_wc(bus_space_t mapping->diom_bst = bst; mapping->base = addr; mapping->size = size; - mapping->diom_mapped = false; + mapping->diom_mapsize = 0; + mapping->diom_atomic = false; /* Allocate kva for one page. */ mapping->diom_va = uvm_km_alloc(kernel_map, PAGE_SIZE, PAGE_SIZE, @@ -91,7 +93,8 @@ static inline void io_mapping_fini(struct io_mapping *mapping) { - KASSERT(!mapping->diom_mapped); + KASSERT(mapping->diom_mapsize == 0); + KASSERT(!mapping->diom_atomic); uvm_km_free(kernel_map, mapping->diom_va, PAGE_SIZE, UVM_KMF_VAONLY); mapping->diom_va = 0; /* paranoia */ @@ -124,53 +127,93 @@ static inline void * io_mapping_map_wc(struct io_mapping *mapping, bus_addr_t offset, bus_size_t size) { + bus_size_t pg, npgs = size >> PAGE_SHIFT; + vaddr_t va; paddr_t cookie; - KASSERT(size == PAGE_SIZE); KASSERT(0 == (offset & (PAGE_SIZE - 1))); KASSERT(PAGE_SIZE <= mapping->size); KASSERT(offset <= (mapping->size - PAGE_SIZE)); KASSERT(__type_fit(off_t, offset)); - KASSERT(!mapping->diom_mapped); + KASSERT(mapping->diom_mapsize == 0); + KASSERT(!mapping->diom_atomic); - cookie = bus_space_mmap(mapping->diom_bst, mapping->base, offset, - PROT_READ|PROT_WRITE, - BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE); - KASSERT(cookie != (paddr_t)-1); + va = uvm_km_alloc(kernel_map, size, PAGE_SIZE, + UVM_KMF_VAONLY|UVM_KMF_WAITVA); + for (pg = 0; pg < npgs; pg++) { + cookie = bus_space_mmap(mapping->diom_bst, mapping->base, + offset + pg*PAGE_SIZE, + PROT_READ|PROT_WRITE, + BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE); + KASSERT(cookie != (paddr_t)-1); - pmap_kenter_pa(mapping->diom_va, pmap_phys_address(cookie), - PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie)); + pmap_kenter_pa(va, pmap_phys_address(cookie), + PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie)); + } pmap_update(pmap_kernel()); - mapping->diom_mapped = true; - return (void *)mapping->diom_va; + mapping->diom_mapsize = size; + mapping->diom_atomic = false; + return (void *)va; } static inline void io_mapping_unmap(struct io_mapping *mapping, void *ptr __diagused) { + vaddr_t va = (vaddr_t)ptr; - KASSERT(mapping->diom_mapped); - KASSERT(mapping->diom_va == (vaddr_t)ptr); + KASSERT(mapping->diom_mapsize); + KASSERT(!mapping->diom_atomic); + KASSERT(mapping->diom_va != va); - pmap_kremove(mapping->diom_va, PAGE_SIZE); + pmap_kremove(va, PAGE_SIZE); pmap_update(pmap_kernel()); - mapping->diom_mapped = false; + uvm_km_free(kernel_map, va, mapping->diom_mapsize, UVM_KMF_VAONLY); + + mapping->diom_mapsize = 0; + mapping->diom_atomic = false; } static inline void * -io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) +io_mapping_map_atomic_wc(struct io_mapping *mapping, bus_addr_t offset) { + paddr_t cookie; + + KASSERT(0 == (offset & (PAGE_SIZE - 1))); + KASSERT(PAGE_SIZE <= mapping->size); + KASSERT(offset <= (mapping->size - PAGE_SIZE)); + KASSERT(__type_fit(off_t, offset)); + KASSERT(mapping->diom_mapsize == 0); + KASSERT(!mapping->diom_atomic); + + cookie = bus_space_mmap(mapping->diom_bst, mapping->base, offset, + PROT_READ|PROT_WRITE, + BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE); + KASSERT(cookie != (paddr_t)-1); + + pmap_kenter_pa(mapping->diom_va, pmap_phys_address(cookie), + PROT_READ|PROT_WRITE, pmap_mmap_flags(cookie)); + pmap_update(pmap_kernel()); - return io_mapping_map_wc(mapping, offset, PAGE_SIZE); + mapping->diom_mapsize = PAGE_SIZE; + mapping->diom_atomic = true; + return (void *)mapping->diom_va; } static inline void -io_mapping_unmap_atomic(struct io_mapping *mapping, void *ptr) +io_mapping_unmap_atomic(struct io_mapping *mapping, void *ptr __diagused) { - io_mapping_unmap(mapping, ptr); + KASSERT(mapping->diom_mapsize); + KASSERT(mapping->diom_atomic); + KASSERT(mapping->diom_va == (vaddr_t)ptr); + + pmap_kremove(mapping->diom_va, PAGE_SIZE); + pmap_update(pmap_kernel()); + + mapping->diom_mapsize = 0; + mapping->diom_atomic = false; } #endif /* _LINUX_IO_MAPPING_H_ */