tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / r4p0_rel0 / common / mali_dma.h
1 /*
2  * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
3  * 
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  * 
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 #ifndef __MALI_DMA_H__
12 #define __MALI_DMA_H__
13
14 #include "mali_osk.h"
15 #include "mali_osk_mali.h"
16 #include "mali_hw_core.h"
17
18 #define MALI_DMA_CMD_BUF_SIZE 1024
19
20 typedef struct mali_dma_cmd_buf {
21         u32 *virt_addr;           /**< CPU address of command buffer */
22         u32 phys_addr;            /**< Physical address of command buffer */
23         u32 size;                 /**< Number of prepared words in command buffer */
24 } mali_dma_cmd_buf;
25
26 /** @brief Create a new DMA unit
27  *
28  * This is called from entry point of the driver in order to create and
29  * intialize the DMA resource
30  *
31  * @param resource it will be a pointer to a DMA resource
32  * @return DMA object on success, NULL on failure
33  */
34 struct mali_dma_core *mali_dma_create(_mali_osk_resource_t *resource);
35
36 /** @brief Delete DMA unit
37  *
38  * This is called on entry point of driver if the driver initialization fails
39  * after initialization of the DMA unit. It is also called on the exit of the
40  * driver to delete the DMA resource
41  *
42  * @param dma Pointer to DMA unit object
43  */
44 void mali_dma_delete(struct mali_dma_core *dma);
45
46 /** @brief Retrieves the MALI DMA core object (if there is)
47  *
48  * @return The Mali DMA object otherwise NULL
49  */
50 struct mali_dma_core *mali_dma_get_global_dma_core(void);
51
52 /**
53  * @brief Run a command buffer on the DMA unit
54  *
55  * @param dma Pointer to the DMA unit to use
56  * @param buf Pointer to the command buffer to use
57  * @return _MALI_OSK_ERR_OK if the buffer was started successfully,
58  *         _MALI_OSK_ERR_BUSY if the DMA unit is busy.
59  */
60 _mali_osk_errcode_t mali_dma_start(struct mali_dma_core* dma, mali_dma_cmd_buf *buf);
61
62 /**
63  * @brief Create a DMA command
64  *
65  * @param core Mali core
66  * @param reg offset to register of core
67  * @param n number of registers to write
68  */
69 MALI_STATIC_INLINE u32 mali_dma_command_write(struct mali_hw_core *core, u32 reg, u32 n)
70 {
71         u32 core_offset = core->phys_offset;
72
73         MALI_DEBUG_ASSERT(reg < 0x2000);
74         MALI_DEBUG_ASSERT(n < 0x800);
75         MALI_DEBUG_ASSERT(core_offset < 0x30000);
76         MALI_DEBUG_ASSERT(0 == ((core_offset + reg) & ~0x7FFFF));
77
78         return (n << 20) | (core_offset + reg);
79 }
80
81 /**
82  * @brief Add a array write to DMA command buffer
83  *
84  * @param buf DMA command buffer to fill in
85  * @param core Core to do DMA to
86  * @param reg Register on core to start writing to
87  * @param data Pointer to data to write
88  * @param count Number of 4 byte words to write
89  */
90 MALI_STATIC_INLINE void mali_dma_write_array(mali_dma_cmd_buf *buf, struct mali_hw_core *core,
91         u32 reg, u32 *data, u32 count)
92 {
93         MALI_DEBUG_ASSERT((buf->size + 1 + count ) < MALI_DMA_CMD_BUF_SIZE / 4);
94
95         buf->virt_addr[buf->size++] = mali_dma_command_write(core, reg, count);
96
97         _mali_osk_memcpy(buf->virt_addr + buf->size, data, count * sizeof(*buf->virt_addr));
98
99         buf->size += count;
100 }
101
102 /**
103  * @brief Add a conditional array write to DMA command buffer
104  *
105  * @param buf DMA command buffer to fill in
106  * @param core Core to do DMA to
107  * @param reg Register on core to start writing to
108  * @param data Pointer to data to write
109  * @param count Number of 4 byte words to write
110  * @param ref Pointer to referance data that can be skipped if equal
111  */
112 MALI_STATIC_INLINE void mali_dma_write_array_conditional(mali_dma_cmd_buf *buf, struct mali_hw_core *core,
113         u32 reg, u32 *data, u32 count, const u32 *ref)
114 {
115         /* Do conditional array writes are not yet implemented, fallback to a
116          * normal array write. */
117         mali_dma_write_array(buf, core, reg, data, count);
118 }
119
120 /**
121  * @brief Add a conditional register write to the DMA command buffer
122  *
123  * If the data matches the reference the command will be skipped.
124  *
125  * @param buf DMA command buffer to fill in
126  * @param core Core to do DMA to
127  * @param reg Register on core to start writing to
128  * @param data Pointer to data to write
129  * @param ref Pointer to referance data that can be skipped if equal
130  */
131 MALI_STATIC_INLINE void mali_dma_write_conditional(mali_dma_cmd_buf *buf, struct mali_hw_core *core,
132         u32 reg, u32 data, const u32 ref)
133 {
134         /* Skip write if reference value is equal to data. */
135         if (data == ref) return;
136
137         buf->virt_addr[buf->size++] = mali_dma_command_write(core, reg, 1);
138
139         buf->virt_addr[buf->size++] = data;
140
141         MALI_DEBUG_ASSERT(buf->size < MALI_DMA_CMD_BUF_SIZE / 4);
142 }
143
144 /**
145  * @brief Add a register write to the DMA command buffer
146  *
147  * @param buf DMA command buffer to fill in
148  * @param core Core to do DMA to
149  * @param reg Register on core to start writing to
150  * @param data Pointer to data to write
151  */
152 MALI_STATIC_INLINE void mali_dma_write(mali_dma_cmd_buf *buf, struct mali_hw_core *core,
153                                        u32 reg, u32 data)
154 {
155         buf->virt_addr[buf->size++] = mali_dma_command_write(core, reg, 1);
156
157         buf->virt_addr[buf->size++] = data;
158
159         MALI_DEBUG_ASSERT(buf->size < MALI_DMA_CMD_BUF_SIZE / 4);
160 }
161
162 /**
163  * @brief Prepare DMA command buffer for use
164  *
165  * This function allocates the DMA buffer itself.
166  *
167  * @param buf The mali_dma_cmd_buf to prepare
168  * @return _MALI_OSK_ERR_OK if the \a buf is ready to use
169  */
170 _mali_osk_errcode_t mali_dma_get_cmd_buf(mali_dma_cmd_buf *buf);
171
172 /**
173  * @brief Check if a DMA command buffer is ready for use
174  *
175  * @param buf The mali_dma_cmd_buf to check
176  * @return MALI_TRUE if buffer is usable, MALI_FALSE otherwise
177  */
178 MALI_STATIC_INLINE mali_bool mali_dma_cmd_buf_is_valid(mali_dma_cmd_buf *buf)
179 {
180         return NULL != buf->virt_addr;
181 }
182
183 /**
184  * @brief Return a DMA command buffer
185  *
186  * @param buf Pointer to DMA command buffer to return
187  */
188 void mali_dma_put_cmd_buf(mali_dma_cmd_buf *buf);
189
190 #endif /* __MALI_DMA_H__ */