summaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-10-30 19:38:18 -0700
committerIngo Molnar <mingo@elte.hu>2008-10-31 10:12:39 +0100
commit9663f2e6a6cf3f82b06d8fb699b11b80f92553ba (patch)
tree108ce4d443e87c8ddc00c028c995b83a6d01e420 /Documentation
parentfd9409343521eac22b6ed51686128a643c7c976b (diff)
downloadop-kernel-dev-9663f2e6a6cf3f82b06d8fb699b11b80f92553ba.zip
op-kernel-dev-9663f2e6a6cf3f82b06d8fb699b11b80f92553ba.tar.gz
resources: add io-mapping functions to dynamically map large device apertures
Impact: add new generic io_map_*() APIs Graphics devices have large PCI apertures which would consume a significant fraction of a 32-bit address space if mapped during driver initialization. Using ioremap at runtime is impractical as it is too slow. This new set of interfaces uses atomic mappings on 32-bit processors and a large static mapping on 64-bit processors to provide reasonable 32-bit performance and optimal 64-bit performance. The current implementation sits atop the io_map_atomic fixmap-based mechanism for 32-bit processors. This includes some editorial suggestions from Randy Dunlap for Documentation/io-mapping.txt Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/io-mapping.txt76
1 files changed, 76 insertions, 0 deletions
diff --git a/Documentation/io-mapping.txt b/Documentation/io-mapping.txt
new file mode 100644
index 0000000..cd2f726
--- /dev/null
+++ b/Documentation/io-mapping.txt
@@ -0,0 +1,76 @@
+The io_mapping functions in linux/io-mapping.h provide an abstraction for
+efficiently mapping small regions of an I/O device to the CPU. The initial
+usage is to support the large graphics aperture on 32-bit processors where
+ioremap_wc cannot be used to statically map the entire aperture to the CPU
+as it would consume too much of the kernel address space.
+
+A mapping object is created during driver initialization using
+
+ struct io_mapping *io_mapping_create_wc(unsigned long base,
+ unsigned long size)
+
+ 'base' is the bus address of the region to be made
+ mappable, while 'size' indicates how large a mapping region to
+ enable. Both are in bytes.
+
+ This _wc variant provides a mapping which may only be used
+ with the io_mapping_map_atomic_wc or io_mapping_map_wc.
+
+With this mapping object, individual pages can be mapped either atomically
+or not, depending on the necessary scheduling environment. Of course, atomic
+maps are more efficient:
+
+ void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
+ unsigned long offset)
+
+ 'offset' is the offset within the defined mapping region.
+ Accessing addresses beyond the region specified in the
+ creation function yields undefined results. Using an offset
+ which is not page aligned yields an undefined result. The
+ return value points to a single page in CPU address space.
+
+ This _wc variant returns a write-combining map to the
+ page and may only be used with mappings created by
+ io_mapping_create_wc
+
+ Note that the task may not sleep while holding this page
+ mapped.
+
+ void io_mapping_unmap_atomic(void *vaddr)
+
+ 'vaddr' must be the the value returned by the last
+ io_mapping_map_atomic_wc call. This unmaps the specified
+ page and allows the task to sleep once again.
+
+If you need to sleep while holding the lock, you can use the non-atomic
+variant, although they may be significantly slower.
+
+ void *io_mapping_map_wc(struct io_mapping *mapping,
+ unsigned long offset)
+
+ This works like io_mapping_map_atomic_wc except it allows
+ the task to sleep while holding the page mapped.
+
+ void io_mapping_unmap(void *vaddr)
+
+ This works like io_mapping_unmap_atomic, except it is used
+ for pages mapped with io_mapping_map_wc.
+
+At driver close time, the io_mapping object must be freed:
+
+ void io_mapping_free(struct io_mapping *mapping)
+
+Current Implementation:
+
+The initial implementation of these functions uses existing mapping
+mechanisms and so provides only an abstraction layer and no new
+functionality.
+
+On 64-bit processors, io_mapping_create_wc calls ioremap_wc for the whole
+range, creating a permanent kernel-visible mapping to the resource. The
+map_atomic and map functions add the requested offset to the base of the
+virtual address returned by ioremap_wc.
+
+On 32-bit processors, io_mapping_map_atomic_wc uses io_map_atomic_prot_pfn,
+which uses the fixmaps to get us a mapping to a page using an atomic fashion.
+For io_mapping_map_wc, ioremap_wc() is used to get a mapping of the region.
OpenPOWER on IntegriCloud