blob: feeefb92b34bd195a238763a6cfd02d0143680e0 [file] [log] [blame]
/*
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
*
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/**
* @file mali_osk_types.h
* Defines types of the OS abstraction layer for the kernel device driver (OSK)
*/
#ifndef __MALI_OSK_TYPES_H__
#define __MALI_OSK_TYPES_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup uddapi Unified Device Driver (UDD) APIs
*
* @{
*/
/**
* @addtogroup oskapi UDD OS Abstraction for Kernel-side (OSK) APIs
*
* @{
*/
/** @defgroup _mali_osk_miscellaneous OSK Miscellaneous functions, constants and types
* @{ */
/* Define integer types used by OSK. Note: these currently clash with Linux so we only define them if not defined already */
#ifndef __KERNEL__
typedef unsigned char u8;
typedef signed char s8;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned int u32;
typedef signed int s32;
typedef unsigned long long u64;
#define BITS_PER_LONG (sizeof(long)*8)
#else
/* Ensure Linux types u32, etc. are defined */
#include <linux/types.h>
#endif
/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE
*/
typedef unsigned long mali_bool;
#ifndef MALI_TRUE
#define MALI_TRUE ((mali_bool)1)
#endif
#ifndef MALI_FALSE
#define MALI_FALSE ((mali_bool)0)
#endif
#define MALI_HW_CORE_NO_COUNTER ((u32)-1)
/**
* @brief OSK Error codes
*
* Each OS may use its own set of error codes, and may require that the
* User/Kernel interface take certain error code. This means that the common
* error codes need to be sufficiently rich to pass the correct error code
* thorugh from the OSK to U/K layer, across all OSs.
*
* The result is that some error codes will appear redundant on some OSs.
* Under all OSs, the OSK layer must translate native OS error codes to
* _mali_osk_errcode_t codes. Similarly, the U/K layer must translate from
* _mali_osk_errcode_t codes to native OS error codes.
*/
typedef enum {
_MALI_OSK_ERR_OK = 0, /**< Success. */
_MALI_OSK_ERR_FAULT = -1, /**< General non-success */
_MALI_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */
_MALI_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */
_MALI_OSK_ERR_NOMEM = -4, /**< Insufficient memory */
_MALI_OSK_ERR_TIMEOUT = -5, /**< Timeout occurred */
_MALI_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */
_MALI_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */
_MALI_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */
_MALI_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */
} _mali_osk_errcode_t;
/** @} */ /* end group _mali_osk_miscellaneous */
/** @defgroup _mali_osk_wq OSK work queues
* @{ */
/** @brief Private type for work objects */
typedef struct _mali_osk_wq_work_s _mali_osk_wq_work_t;
typedef struct _mali_osk_wq_delayed_work_s _mali_osk_wq_delayed_work_t;
/** @brief Work queue handler function
*
* This function type is called when the work is scheduled by the work queue,
* e.g. as an IRQ bottom-half handler.
*
* Refer to \ref _mali_osk_wq_schedule_work() for more information on the
* work-queue and work handlers.
*
* @param arg resource-specific data
*/
typedef void (*_mali_osk_wq_work_handler_t)(void *arg);
/* @} */ /* end group _mali_osk_wq */
/** @defgroup _mali_osk_irq OSK IRQ handling
* @{ */
/** @brief Private type for IRQ handling objects */
typedef struct _mali_osk_irq_t_struct _mali_osk_irq_t;
/** @brief Optional function to trigger an irq from a resource
*
* This function is implemented by the common layer to allow probing of a resource's IRQ.
* @param arg resource-specific data */
typedef void (*_mali_osk_irq_trigger_t)(void *arg);
/** @brief Optional function to acknowledge an irq from a resource
*
* This function is implemented by the common layer to allow probing of a resource's IRQ.
* @param arg resource-specific data
* @return _MALI_OSK_ERR_OK if the IRQ was successful, or a suitable _mali_osk_errcode_t on failure. */
typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)(void *arg);
/** @brief IRQ 'upper-half' handler callback.
*
* This function is implemented by the common layer to do the initial handling of a
* resource's IRQ. This maps on to the concept of an ISR that does the minimum
* work necessary before handing off to an IST.
*
* The communication of the resource-specific data from the ISR to the IST is
* handled by the OSK implementation.
*
* On most systems, the IRQ upper-half handler executes in IRQ context.
* Therefore, the system may have restrictions about what can be done in this
* context
*
* If an IRQ upper-half handler requires more work to be done than can be
* acheived in an IRQ context, then it may defer the work with
* _mali_osk_wq_schedule_work(). Refer to \ref _mali_osk_wq_create_work() for
* more information.
*
* @param arg resource-specific data
* @return _MALI_OSK_ERR_OK if the IRQ was correctly handled, or a suitable
* _mali_osk_errcode_t otherwise.
*/
typedef _mali_osk_errcode_t (*_mali_osk_irq_uhandler_t)(void *arg);
/** @} */ /* end group _mali_osk_irq */
/** @defgroup _mali_osk_atomic OSK Atomic counters
* @{ */
/** @brief Public type of atomic counters
*
* This is public for allocation on stack. On systems that support it, this is just a single 32-bit value.
* On others, it could be encapsulating an object stored elsewhere.
*
* Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used
* for all accesses to the variable's value, even if atomicity is not required.
* Do not access u.val or u.obj directly.
*/
typedef struct {
union {
u32 val;
void *obj;
} u;
} _mali_osk_atomic_t;
/** @} */ /* end group _mali_osk_atomic */
/** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks
* @{ */
/** @brief OSK Mutual Exclusion Lock ordered list
*
* This lists the various types of locks in the system and is used to check
* that locks are taken in the correct order.
*
* - Holding more than one lock of the same order at the same time is not
* allowed.
* - Taking a lock of a lower order than the highest-order lock currently held
* is not allowed.
*
*/
typedef enum {
/* || Locks || */
/* || must be || */
/* _||_ taken in _||_ */
/* \ / this \ / */
/* \/ order! \/ */
_MALI_OSK_LOCK_ORDER_FIRST = 0,
_MALI_OSK_LOCK_ORDER_SESSIONS,
_MALI_OSK_LOCK_ORDER_MEM_SESSION,
_MALI_OSK_LOCK_ORDER_MEM_INFO,
_MALI_OSK_LOCK_ORDER_MEM_PT_CACHE,
_MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP,
_MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL,
_MALI_OSK_LOCK_ORDER_GROUP,
_MALI_OSK_LOCK_ORDER_TIMELINE_SYSTEM,
_MALI_OSK_LOCK_ORDER_SCHEDULER,
_MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED,
_MALI_OSK_LOCK_ORDER_PM_CORE_STATE,
_MALI_OSK_LOCK_ORDER_L2_COMMAND,
_MALI_OSK_LOCK_ORDER_DMA_COMMAND,
_MALI_OSK_LOCK_ORDER_PROFILING,
_MALI_OSK_LOCK_ORDER_L2_COUNTER,
_MALI_OSK_LOCK_ORDER_UTILIZATION,
_MALI_OSK_LOCK_ORDER_PM_EXECUTE,
_MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS,
_MALI_OSK_LOCK_ORDER_PM_DOMAIN,
_MALI_OSK_LOCK_ORDER_PMU,
_MALI_OSK_LOCK_ORDER_LAST,
} _mali_osk_lock_order_t;
/** @brief OSK Mutual Exclusion Lock flags type
*
* - Any lock can use the order parameter.
*/
typedef enum {
_MALI_OSK_LOCKFLAG_UNORDERED = 0x1, /**< Indicate that the order of this lock should not be checked */
_MALI_OSK_LOCKFLAG_ORDERED = 0x2,
/** @enum _mali_osk_lock_flags_t
*
* Flags from 0x10000--0x80000000 are RESERVED for User-mode */
} _mali_osk_lock_flags_t;
/** @brief Mutual Exclusion Lock Mode Optimization hint
*
* The lock mode is used to implement the read/write locking of locks when we call
* functions _mali_osk_mutex_rw_init/wait/signal/term/. In this case, the RO mode can
* be used to allow multiple concurrent readers, but no writers. The RW mode is used for
* writers, and so will wait for all readers to release the lock (if any present).
* Further readers and writers will wait until the writer releases the lock.
*
* The mode is purely an optimization hint: for example, it is permissible for
* all locks to behave in RW mode, regardless of that supplied.
*
* It is an error to attempt to use locks in anything other that RW mode when
* call functions _mali_osk_mutex_rw_wait/signal().
*
*/
typedef enum {
_MALI_OSK_LOCKMODE_UNDEF = -1, /**< Undefined lock mode. For internal use only */
_MALI_OSK_LOCKMODE_RW = 0x0, /**< Read-write mode, default. All readers and writers are mutually-exclusive */
_MALI_OSK_LOCKMODE_RO, /**< Read-only mode, to support multiple concurrent readers, but mutual exclusion in the presence of writers. */
/** @enum _mali_osk_lock_mode_t
*
* Lock modes 0x40--0x7F are RESERVED for User-mode */
} _mali_osk_lock_mode_t;
/** @brief Private types for Mutual Exclusion lock objects */
typedef struct _mali_osk_lock_debug_s _mali_osk_lock_debug_t;
typedef struct _mali_osk_spinlock_s _mali_osk_spinlock_t;
typedef struct _mali_osk_spinlock_irq_s _mali_osk_spinlock_irq_t;
typedef struct _mali_osk_mutex_s _mali_osk_mutex_t;
typedef struct _mali_osk_mutex_rw_s _mali_osk_mutex_rw_t;
/** @} */ /* end group _mali_osk_lock */
/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations
* @{ */
/**
* @brief Private data type for use in IO accesses to/from devices.
*
* This represents some range that is accessible from the device. Examples
* include:
* - Device Registers, which could be readable and/or writeable.
* - Memory that the device has access to, for storing configuration structures.
*
* Access to this range must be made through the _mali_osk_mem_ioread32() and
* _mali_osk_mem_iowrite32() functions.
*/
typedef struct _mali_io_address *mali_io_address;
/** @defgroup _MALI_OSK_CPU_PAGE CPU Physical page size macros.
*
* The order of the page size is supplied for
* ease of use by algorithms that might require it, since it is easier to know
* it ahead of time rather than calculating it.
*
* The Mali Page Mask macro masks off the lower bits of a physical address to
* give the start address of the page for that physical address.
*
* @note The Mali device driver code is designed for systems with 4KB page size.
* Changing these macros will not make the entire Mali device driver work with
* page sizes other than 4KB.
*
* @note The CPU Physical Page Size has been assumed to be the same as the Mali
* Physical Page Size.
*
* @{
*/
/** CPU Page Order, as log to base 2 of the Page size. @see _MALI_OSK_CPU_PAGE_SIZE */
#define _MALI_OSK_CPU_PAGE_ORDER ((u32)12)
/** CPU Page Size, in bytes. */
#define _MALI_OSK_CPU_PAGE_SIZE (((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER))
/** CPU Page Mask, which masks off the offset within a page */
#define _MALI_OSK_CPU_PAGE_MASK (~((((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) - ((u32)1)))
/** @} */ /* end of group _MALI_OSK_CPU_PAGE */
/** @defgroup _MALI_OSK_MALI_PAGE Mali Physical Page size macros
*
* Mali Physical page size macros. The order of the page size is supplied for
* ease of use by algorithms that might require it, since it is easier to know
* it ahead of time rather than calculating it.
*
* The Mali Page Mask macro masks off the lower bits of a physical address to
* give the start address of the page for that physical address.
*
* @note The Mali device driver code is designed for systems with 4KB page size.
* Changing these macros will not make the entire Mali device driver work with
* page sizes other than 4KB.
*
* @note The Mali Physical Page Size has been assumed to be the same as the CPU
* Physical Page Size.
*
* @{
*/
/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */
#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12)
/** Mali Page Size, in bytes. */
#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER))
/** Mali Page Mask, which masks off the offset within a page */
#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1)))
/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/
/** @brief flags for mapping a user-accessible memory range
*
* Where a function with prefix '_mali_osk_mem_mapregion' accepts flags as one
* of the function parameters, it will use one of these. These allow per-page
* control over mappings. Compare with the mali_memory_allocation_flag type,
* which acts over an entire range
*
* These may be OR'd together with bitwise OR (|), but must be cast back into
* the type after OR'ing.
*/
typedef enum {
_MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR = 0x1, /**< Physical address is OS Allocated */
} _mali_osk_mem_mapregion_flags_t;
/** @} */ /* end group _mali_osk_low_level_memory */
/** @defgroup _mali_osk_notification OSK Notification Queues
* @{ */
/** @brief Private type for notification queue objects */
typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queue_t;
/** @brief Public notification data object type */
typedef struct _mali_osk_notification_t_struct {
u32 notification_type; /**< The notification type */
u32 result_buffer_size; /**< Size of the result buffer to copy to user space */
void *result_buffer; /**< Buffer containing any type specific data */
} _mali_osk_notification_t;
/** @} */ /* end group _mali_osk_notification */
/** @defgroup _mali_osk_timer OSK Timer Callbacks
* @{ */
/** @brief Function to call when a timer expires
*
* When a timer expires, this function is called. Note that on many systems,
* a timer callback will be executed in IRQ context. Therefore, restrictions
* may apply on what can be done inside the timer callback.
*
* If a timer requires more work to be done than can be acheived in an IRQ
* context, then it may defer the work with a work-queue. For example, it may
* use \ref _mali_osk_wq_schedule_work() to make use of a bottom-half handler
* to carry out the remaining work.
*
* Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of
* the callback. Therefore, the callback may not obtain any mutexes also held
* by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur.
*
* @param arg Function-specific data */
typedef void (*_mali_osk_timer_callback_t)(void *arg);
/** @brief Private type for Timer Callback Objects */
typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t;
/** @} */ /* end group _mali_osk_timer */
/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists
* @{ */
/** @brief Public List objects.
*
* To use, add a _mali_osk_list_t member to the structure that may become part
* of a list. When traversing the _mali_osk_list_t objects, use the
* _MALI_OSK_CONTAINER_OF() macro to recover the structure from its
*_mali_osk_list_t member
*
* Each structure may have multiple _mali_osk_list_t members, so that the
* structure is part of multiple lists. When traversing lists, ensure that the
* correct _mali_osk_list_t member is used, because type-checking will be
* lost by the compiler.
*/
typedef struct _mali_osk_list_s {
struct _mali_osk_list_s *next;
struct _mali_osk_list_s *prev;
} _mali_osk_list_t;
/** @} */ /* end group _mali_osk_list */
/** @addtogroup _mali_osk_miscellaneous
* @{ */
/** @brief resource description struct
*
* Platform independent representation of a Mali HW resource
*/
typedef struct _mali_osk_resource {
const char *description; /**< short description of the resource */
u32 base; /**< Physical base address of the resource, as seen by Mali resources. */
u32 irq; /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */
} _mali_osk_resource_t;
/** @} */ /* end group _mali_osk_miscellaneous */
/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality
* @{ */
/** @brief Private type for wait queue objects */
typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t;
/** @} */ /* end group _mali_osk_wait_queue */
/** @} */ /* end group osuapi */
/** @} */ /* end group uddapi */
#ifdef __cplusplus
}
#endif
#endif /* __MALI_OSK_TYPES_H__ */