diff options
author | Philippe Langlais <philippe.langlais@linaro.org> | 2011-05-05 11:28:37 +0200 |
---|---|---|
committer | Henrik Aberg <henrik.aberg@stericsson.com> | 2011-05-18 09:39:45 +0200 |
commit | a3c458646f20e01c6ce0e1163f6fcd7f7337d6ea (patch) | |
tree | 9c55da32442e3e6f55025c338804faf015453d8e /include/linux | |
parent | d5f86b4ed34d9c3f0bebe3ce0f037dd2a5e17fa9 (diff) |
HWMEM: Update API
Perform queued hwmem API changes. One commit to ease dependency
handling.
Depends-On: I13f249cf5f51f9f138171e8d6f59e1d5d2f72de1, I31030bcfda7cf76d15402c2137576da4f3fb2761, I2dc7e6aa5686492550b5164e50c06ed750ac9e16, Ia12bbb9f378c331cfb9b1376dedb3b7b65f56429, Ibc3404df4876971d8b69272c63120e2fe3bb2787
ST-Ericsson ID: AP 327001
ST-Ericsson FOSS-OUT ID: STETL-FOSS-OUT-10068
Change-Id: I9a45ad54a0cc8a5cdb1e3b9038ad50aeacb3f9c3
Signed-off-by: Johan Mossberg <johan.xx.mossberg@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/17518
Reviewed-by: Robert FEKETE <robert.fekete@stericsson.com>
Conflicts:
drivers/misc/dispdev/dispdev.c
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/hwmem.h | 346 |
1 files changed, 205 insertions, 141 deletions
diff --git a/include/linux/hwmem.h b/include/linux/hwmem.h index bc0a26a30a6..6756085f72a 100644 --- a/include/linux/hwmem.h +++ b/include/linux/hwmem.h @@ -1,7 +1,7 @@ /* - * Copyright (C) ST-Ericsson AB 2010 + * Copyright (C) ST-Ericsson SA 2010 * - * ST-Ericsson HW memory driver + * Hardware memory driver, hwmem * * Author: Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com> * for ST-Ericsson. @@ -27,36 +27,49 @@ */ enum hwmem_alloc_flags { /** - * @brief Buffer will not be cached and not buffered + * @brief Buffered */ - HWMEM_ALLOC_UNCACHED = (0 << 0), + HWMEM_ALLOC_HINT_WRITE_COMBINE = (1 << 0), /** - * @brief Buffer will be buffered, but not cached + * @brief Non-buffered */ - HWMEM_ALLOC_BUFFERED = (1 << 0), + HWMEM_ALLOC_HINT_NO_WRITE_COMBINE = (1 << 1), /** - * @brief Buffer will be cached and buffered, use cache hints to be - * more specific + * @brief Cached */ - HWMEM_ALLOC_CACHED = (3 << 0), + HWMEM_ALLOC_HINT_CACHED = (1 << 2), /** - * @brief Buffer should be cached write-back in both level 1 and 2 cache + * @brief Uncached */ - HWMEM_ALLOC_CACHE_HINT_WB = (1 << 2), + HWMEM_ALLOC_HINT_UNCACHED = (1 << 3), /** - * @brief Buffer should be cached write-through in both level 1 and - * 2 cache + * @brief Write back */ - HWMEM_ALLOC_CACHE_HINT_WT = (2 << 2), + HWMEM_ALLOC_HINT_CACHE_WB = (1 << 4), /** - * @brief Buffer should be cached write-back in level 1 cache + * @brief Write through */ - HWMEM_ALLOC_CACHE_HINT_WB_INNER = (3 << 2), + HWMEM_ALLOC_HINT_CACHE_WT = (1 << 5), /** - * @brief Buffer should be cached write-through in level 1 cache + * @brief No alloc on write */ - HWMEM_ALLOC_CACHE_HINT_WT_INNER = (4 << 2), - HWMEM_ALLOC_CACHE_HINT_MASK = 0x1C, + HWMEM_ALLOC_HINT_CACHE_NAOW = (1 << 6), + /** + * @brief Alloc on write + */ + HWMEM_ALLOC_HINT_CACHE_AOW = (1 << 7), + /** + * @brief Inner and outer cache + */ + HWMEM_ALLOC_HINT_INNER_AND_OUTER_CACHE = (1 << 8), + /** + * @brief Inner cache only + */ + HWMEM_ALLOC_HINT_INNER_CACHE_ONLY = (1 << 9), + /** + * @brief Reserved for use by the cache handler integration + */ + HWMEM_ALLOC_RESERVED_CHI = (1 << 31), }; /** @@ -78,82 +91,32 @@ enum hwmem_access { }; /** - * @brief Flags defining memory type. + * @brief Values defining memory types. */ enum hwmem_mem_type { /** - * @brief Scattered system memory. Currently not supported! + * @brief Scattered system memory. */ - HWMEM_MEM_SCATTERED_SYS = (1 << 0), + HWMEM_MEM_SCATTERED_SYS, /** * @brief Contiguous system memory. */ - HWMEM_MEM_CONTIGUOUS_SYS = (1 << 1), + HWMEM_MEM_CONTIGUOUS_SYS, }; -/** - * @brief Values defining memory domain. - */ -enum hwmem_domain { - /** - * @brief This value specifies the neutral memory domain. Setting this - * domain will syncronize all supported memory domains (currently CPU). - */ - HWMEM_DOMAIN_SYNC = 0, - /** - * @brief This value specifies the CPU memory domain. - */ - HWMEM_DOMAIN_CPU = 1, -}; +/* User space API */ /** - * @brief Structure defining a region of a memory buffer. - * - * A buffer is defined to contain a number of equally sized blocks. Each block - * has a part of it included in the region [<start>-<end>). That is - * <end>-<start> bytes. Each block is <size> bytes long. Total number of bytes - * in the region is (<end> - <start>) * <count>. First byte of the region is - * <offset> + <start> bytes into the buffer. - * - * Here's an example of a region in a graphics buffer (X = buffer, R = region): - * - * XXXXXXXXXXXXXXXXXXXX \ - * XXXXXXXXXXXXXXXXXXXX |-- offset = 60 - * XXXXXXXXXXXXXXXXXXXX / - * XXRRRRRRRRXXXXXXXXXX \ - * XXRRRRRRRRXXXXXXXXXX |-- count = 4 - * XXRRRRRRRRXXXXXXXXXX | - * XXRRRRRRRRXXXXXXXXXX / - * XXXXXXXXXXXXXXXXXXXX - * --| start = 2 - * ----------| end = 10 - * --------------------| size = 20 + * @see struct hwmem_region. */ -struct hwmem_region { - /** - * @brief The first block's offset from beginning of buffer. - */ - uint32_t offset; - /** - * @brief The number of blocks included in this region. - */ - uint32_t count; - /** - * @brief The index of the first byte included in this block. - */ - uint32_t start; - /** - * @brief The index of the last byte included in this block plus one. - */ - uint32_t end; - /** - * @brief The size in bytes of each block. - */ - uint32_t size; +struct hwmem_region_us { + __u32 offset; + __u32 count; + __u32 start; + __u32 end; + __u32 size; }; -/* User space API */ - /** * @brief Alloc request data. */ @@ -162,19 +125,19 @@ struct hwmem_alloc_request { * @brief [in] Size of requested allocation in bytes. Size will be * aligned to PAGE_SIZE bytes. */ - uint32_t size; + __u32 size; /** * @brief [in] Flags describing requested allocation options. */ - uint32_t flags; /* enum hwmem_alloc_flags */ + __u32 flags; /* enum hwmem_alloc_flags */ /** * @brief [in] Default access rights for buffer. */ - uint32_t default_access; /* enum hwmem_access */ + __u32 default_access; /* enum hwmem_access */ /** * @brief [in] Memory type of the buffer. */ - uint32_t mem_type; /* enum hwmem_mem_type */ + __u32 mem_type; /* enum hwmem_mem_type */ }; /** @@ -185,24 +148,20 @@ struct hwmem_set_domain_request { * @brief [in] Identifier of buffer to be prepared. If 0 is specified * the buffer associated with the current file instance will be used. */ - int32_t id; - /** - * @brief [in] Value specifying the new memory domain. - */ - uint32_t domain; /* enum hwmem_domain */ + __s32 id; /** * @brief [in] Flags specifying access mode of the operation. * * One of HWMEM_ACCESS_READ and HWMEM_ACCESS_WRITE is required. * For details, @see enum hwmem_access. */ - uint32_t access; /* enum hwmem_access */ + __u32 access; /* enum hwmem_access */ /** * @brief [in] The region of bytes to be prepared. * * For details, @see struct hwmem_region. */ - struct hwmem_region region; + struct hwmem_region_us region; }; /** @@ -213,18 +172,11 @@ struct hwmem_pin_request { * @brief [in] Identifier of buffer to be pinned. If 0 is specified, * the buffer associated with the current file instance will be used. */ - int32_t id; + __s32 id; /** * @brief [out] Physical address of first word in buffer. */ - uint32_t phys_addr; - /** - * @brief [in] Pointer to buffer for physical addresses of pinned - * scattered buffer. Buffer must be (buffer_size / page_size) * - * sizeof(uint32_t) bytes. - * This field can be NULL for physically contiguos buffers. - */ - uint32_t *scattered_addrs; + __u32 phys_addr; }; /** @@ -232,14 +184,15 @@ struct hwmem_pin_request { */ struct hwmem_set_access_request { /** - * @brief [in] Identifier of buffer to be pinned. If 0 is specified, - * the buffer associated with the current file instance will be used. + * @brief [in] Identifier of buffer to set access rights for. If 0 is + * specified, the buffer associated with the current file instance will + * be used. */ - int32_t id; + __s32 id; /** * @param access Access value indicating what is allowed. */ - uint32_t access; /* enum hwmem_access */ + __u32 access; /* enum hwmem_access */ /** * @param pid Process ID to set rights for. */ @@ -254,19 +207,19 @@ struct hwmem_get_info_request { * @brief [in] Identifier of buffer to get info about. If 0 is specified, * the buffer associated with the current file instance will be used. */ - int32_t id; + __s32 id; /** * @brief [out] Size in bytes of buffer. */ - uint32_t size; + __u32 size; /** * @brief [out] Memory type of buffer. */ - uint32_t mem_type; /* enum hwmem_mem_type */ + __u32 mem_type; /* enum hwmem_mem_type */ /** * @brief [out] Access rights for buffer. */ - uint32_t access; /* enum hwmem_access */ + __u32 access; /* enum hwmem_access */ }; /** @@ -296,7 +249,8 @@ struct hwmem_get_info_request { * @brief Releases buffer. * * Buffers are reference counted and will not be destroyed until the last - * reference is released. Bufferes allocated with ALLOC_FD_IOC not allowed. + * reference is released. Buffers allocated with ALLOC_FD_IOC shall not be + * released with this IOC, @see HWMEM_ALLOC_FD_IOC. * * Input is the buffer identifier. * @@ -305,44 +259,72 @@ struct hwmem_get_info_request { #define HWMEM_RELEASE_IOC _IO('W', 3) /** - * @brief Set the buffer's memory domain and prepares it for access. + * Memory Mapping + * + * To map a hwmem buffer mmap the hwmem fd and supply the buffer identifier as + * the offset. If the buffer is linked to the fd and thus have no buffer + * identifier supply 0 as the offset. Note that the offset feature of mmap is + * disabled in both cases, you can only mmap starting a position 0. + */ + +/** + * @brief Prepares the buffer for CPU access. + * + * Input is a pointer to a hwmem_set_domain_request struct. + * + * @return Zero on success, or a negative error code. + */ +#define HWMEM_SET_CPU_DOMAIN_IOC _IOW('W', 4, struct hwmem_set_domain_request) + +/** + * DEPRECATED: Set sync domain from driver instead! + * + * @brief Prepares the buffer for access by any DMA hardware. * * Input is a pointer to a hwmem_set_domain_request struct. * * @return Zero on success, or a negative error code. */ -#define HWMEM_SET_DOMAIN_IOC _IOR('W', 4, struct hwmem_set_domain_request) +#define HWMEM_SET_SYNC_DOMAIN_IOC _IOW('W', 5, struct hwmem_set_domain_request) /** - * @brief Pins the buffer and returns the physical address of the buffer. + * DEPRECATED: Pin from driver instead! + * + * @brief Pins the buffer. + * + * Input is a pointer to a hwmem_pin_request struct. Only contiguous buffers + * can be pinned from user space. * * @return Zero on success, or a negative error code. */ -#define HWMEM_PIN_IOC _IOWR('W', 5, struct hwmem_pin_request) +#define HWMEM_PIN_IOC _IOWR('W', 6, struct hwmem_pin_request) /** + * DEPRECATED: Unpin from driver instead! + * * @brief Unpins the buffer. * * @return Zero on success, or a negative error code. */ -#define HWMEM_UNPIN_IOC _IO('W', 6) +#define HWMEM_UNPIN_IOC _IO('W', 7) /** * @brief Set access rights for buffer. * + * Input is a pointer to a hwmem_set_access_request struct. + * * @return Zero on success, or a negative error code. */ -#define HWMEM_SET_ACCESS_IOC _IOW('W', 7, struct hwmem_set_access_request) +#define HWMEM_SET_ACCESS_IOC _IOW('W', 8, struct hwmem_set_access_request) /** * @brief Get buffer information. * - * Input is the buffer identifier. If 0 is specified the buffer associated - * with the current file instance will be used. + * Input is a pointer to a hwmem_get_info_request struct. * * @return Zero on success, or a negative error code. */ -#define HWMEM_GET_INFO_IOC _IOWR('W', 8, struct hwmem_get_info_request) +#define HWMEM_GET_INFO_IOC _IOWR('W', 9, struct hwmem_get_info_request) /** * @brief Export the buffer identifier for use in another process. @@ -355,33 +337,101 @@ struct hwmem_get_info_request { * * @return A global buffer name on success, or a negative error code. */ -#define HWMEM_EXPORT_IOC _IO('W', 9) +#define HWMEM_EXPORT_IOC _IO('W', 10) /** * @brief Import a buffer to allow local access to the buffer. * * Input is the buffer's global name. * - * @return The imported buffer's identifier on success, or a negative error code. + * @return The imported buffer's identifier on success, or a negative error + * code. */ -#define HWMEM_IMPORT_IOC _IO('W', 10) +#define HWMEM_IMPORT_IOC _IO('W', 11) /** - * @brief Import a buffer to allow local access to the buffer using fd. + * @brief Import a buffer to allow local access to the buffer using the current + * fd. * * Input is the buffer's global name. * * @return Zero on success, or a negative error code. */ -#define HWMEM_IMPORT_FD_IOC _IO('W', 11) +#define HWMEM_IMPORT_FD_IOC _IO('W', 12) #ifdef __KERNEL__ /* Kernel API */ +/** + * @brief Values defining memory domain. + */ +enum hwmem_domain { + /** + * @brief This value specifies the neutral memory domain. Setting this + * domain will syncronize all supported memory domains. + */ + HWMEM_DOMAIN_SYNC = 0, + /** + * @brief This value specifies the CPU memory domain. + */ + HWMEM_DOMAIN_CPU, +}; + struct hwmem_alloc; /** + * @brief Structure defining a region of a memory buffer. + * + * A buffer is defined to contain a number of equally sized blocks. Each block + * has a part of it included in the region [<start>-<end>). That is + * <end>-<start> bytes. Each block is <size> bytes long. Total number of bytes + * in the region is (<end> - <start>) * <count>. First byte of the region is + * <offset> + <start> bytes into the buffer. + * + * Here's an example of a region in a graphics buffer (X = buffer, R = region): + * + * XXXXXXXXXXXXXXXXXXXX \ + * XXXXXXXXXXXXXXXXXXXX |-- offset = 60 + * XXXXXXXXXXXXXXXXXXXX / + * XXRRRRRRRRXXXXXXXXXX \ + * XXRRRRRRRRXXXXXXXXXX |-- count = 4 + * XXRRRRRRRRXXXXXXXXXX | + * XXRRRRRRRRXXXXXXXXXX / + * XXXXXXXXXXXXXXXXXXXX + * --| start = 2 + * ----------| end = 10 + * --------------------| size = 20 + */ +struct hwmem_region { + /** + * @brief The first block's offset from beginning of buffer. + */ + size_t offset; + /** + * @brief The number of blocks included in this region. + */ + size_t count; + /** + * @brief The index of the first byte included in this block. + */ + size_t start; + /** + * @brief The index of the last byte included in this block plus one. + */ + size_t end; + /** + * @brief The size in bytes of each block. + */ + size_t size; +}; + +struct hwmem_mem_chunk { + phys_addr_t paddr; + size_t size; +}; + +/** * @brief Allocates <size> number of bytes. * * @param size Number of bytes to allocate. All allocations are page aligned. @@ -391,7 +441,7 @@ struct hwmem_alloc; * * @return Pointer to allocation, or a negative error code. */ -struct hwmem_alloc *hwmem_alloc(u32 size, enum hwmem_alloc_flags flags, +struct hwmem_alloc *hwmem_alloc(size_t size, enum hwmem_alloc_flags flags, enum hwmem_access def_access, enum hwmem_mem_type mem_type); /** @@ -419,14 +469,26 @@ int hwmem_set_domain(struct hwmem_alloc *alloc, enum hwmem_access access, /** * @brief Pins the buffer. * + * Notice that the number of mem chunks a buffer consists of can change at any + * time if the buffer is not pinned. Because of this one can not assume that + * pin will succeed if <mem_chunks> has the length specified by a previous call + * to pin as the buffer layout may have changed between the calls. There are + * two ways of handling this situation, keep redoing the pin procedure till it + * succeeds or allocate enough mem chunks for the worst case ("buffer size" / + * "page size" mem chunks). Contiguous buffers always require only one mem + * chunk. + * * @param alloc Buffer to be pinned. - * @param phys_addr Reference to variable to receive physical address. - * @param scattered_phys_addrs Pointer to buffer to receive physical addresses - * of all pages in the scattered buffer. Can be NULL if buffer is contigous. - * Buffer size must be (buffer_size / page_size) * sizeof(uint32_t) bytes. + * @param mem_chunks Pointer to array of mem chunks. + * @param mem_chunks_length Pointer to variable that contains the length of + * <mem_chunks> array. On success the number of written mem chunks will be + * stored in this variable. If the call fails with -ENOSPC the required length + * of <mem_chunks> will be stored in this variable. + * + * @return Zero on success, or a negative error code. */ -int hwmem_pin(struct hwmem_alloc *alloc, uint32_t *phys_addr, - uint32_t *scattered_phys_addrs); +int hwmem_pin(struct hwmem_alloc *alloc, struct hwmem_mem_chunk *mem_chunks, + size_t *mem_chunks_length); /** * @brief Unpins the buffer. @@ -438,7 +500,9 @@ void hwmem_unpin(struct hwmem_alloc *alloc); /** * @brief Map the buffer to user space. * - * @param alloc Buffer to be unpinned. + * @param alloc Buffer to be mapped. + * + * @return Zero on success, or a negative error code. */ int hwmem_mmap(struct hwmem_alloc *alloc, struct vm_area_struct *vma); @@ -476,12 +540,12 @@ int hwmem_set_access(struct hwmem_alloc *alloc, enum hwmem_access access, * @brief Get buffer information. * * @param alloc Buffer to get information about. - * @param size Pointer to size output variable. - * @param size Pointer to memory type output variable. - * @param size Pointer to access rights output variable. + * @param size Pointer to size output variable. Can be NULL. + * @param size Pointer to memory type output variable. Can be NULL. + * @param size Pointer to access rights output variable. Can be NULL. */ -void hwmem_get_info(struct hwmem_alloc *alloc, uint32_t *size, - enum hwmem_mem_type *mem_type, enum hwmem_access *access); +void hwmem_get_info(struct hwmem_alloc *alloc, size_t *size, + enum hwmem_mem_type *mem_type, enum hwmem_access *access); /** * @brief Allocate a global buffer name. @@ -492,7 +556,7 @@ void hwmem_get_info(struct hwmem_alloc *alloc, uint32_t *size, * * @return Positive global name on success, or a negative error code. */ -int hwmem_get_name(struct hwmem_alloc *alloc); +s32 hwmem_get_name(struct hwmem_alloc *alloc); /** * @brief Import the global buffer name to allow local access to the buffer. @@ -508,10 +572,10 @@ struct hwmem_alloc *hwmem_resolve_by_name(s32 name); /* Internal */ struct hwmem_platform_data { - /* Starting physical address of memory region */ - unsigned long start; + /* Physical address of memory region */ + u32 start; /* Size of memory region */ - unsigned long size; + u32 size; }; #endif |