2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright 2011-2016 Freescale Semiconductor Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of the above-listed copyright holders nor the
18 * names of any contributors may be used to endorse or promote products
19 * derived from this software without specific prior written permission.
23 * ALTERNATIVELY, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") as published by the Free Software
25 * Foundation, either version 2 of that License or (at your option) any
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
43 #include <sys/ioctl.h>
49 /* As higher-level drivers will be built on top of this (dma_mem, qbman, ...),
50 * it's preferable that the process driver itself not provide any exported API.
51 * As such, combined with the fact that none of these operations are
52 * performance critical, it is justified to use lazy initialisation, so that's
53 * what the lock is for.
56 static pthread_mutex_t fd_init_lock = PTHREAD_MUTEX_INITIALIZER;
58 static int check_fd(void)
64 ret = pthread_mutex_lock(&fd_init_lock);
66 /* check again with the lock held */
68 fd = open(PROCESS_PATH, O_RDWR);
69 ret = pthread_mutex_unlock(&fd_init_lock);
71 return (fd >= 0) ? 0 : -ENODEV;
74 #define DPAA_IOCTL_MAGIC 'u'
75 struct dpaa_ioctl_id_alloc {
76 uint32_t base; /* Return value, the start of the allocated range */
77 enum dpaa_id_type id_type; /* what kind of resource(s) to allocate */
78 uint32_t num; /* how many IDs to allocate (and return value) */
79 uint32_t align; /* must be a power of 2, 0 is treated like 1 */
80 int partial; /* whether to allow less than 'num' */
83 struct dpaa_ioctl_id_release {
85 enum dpaa_id_type id_type;
90 struct dpaa_ioctl_id_reserve {
91 enum dpaa_id_type id_type;
96 #define DPAA_IOCTL_ID_ALLOC \
97 _IOWR(DPAA_IOCTL_MAGIC, 0x01, struct dpaa_ioctl_id_alloc)
98 #define DPAA_IOCTL_ID_RELEASE \
99 _IOW(DPAA_IOCTL_MAGIC, 0x02, struct dpaa_ioctl_id_release)
100 #define DPAA_IOCTL_ID_RESERVE \
101 _IOW(DPAA_IOCTL_MAGIC, 0x0A, struct dpaa_ioctl_id_reserve)
103 int process_alloc(enum dpaa_id_type id_type, uint32_t *base, uint32_t num,
104 uint32_t align, int partial)
106 struct dpaa_ioctl_id_alloc id = {
112 int ret = check_fd();
116 ret = ioctl(fd, DPAA_IOCTL_ID_ALLOC, &id);
119 for (ret = 0; ret < (int)id.num; ret++)
120 base[ret] = id.base + ret;
124 void process_release(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
126 struct dpaa_ioctl_id_release id = {
131 int ret = check_fd();
134 fprintf(stderr, "Process FD failure\n");
137 ret = ioctl(fd, DPAA_IOCTL_ID_RELEASE, &id);
139 fprintf(stderr, "Process FD ioctl failure type %d base 0x%x num %d\n",
143 int process_reserve(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
145 struct dpaa_ioctl_id_reserve id = {
150 int ret = check_fd();
154 return ioctl(fd, DPAA_IOCTL_ID_RESERVE, &id);
157 /***************************************/
158 /* Mapping and using QMan/BMan portals */
159 /***************************************/
161 #define DPAA_IOCTL_PORTAL_MAP \
162 _IOWR(DPAA_IOCTL_MAGIC, 0x07, struct dpaa_ioctl_portal_map)
163 #define DPAA_IOCTL_PORTAL_UNMAP \
164 _IOW(DPAA_IOCTL_MAGIC, 0x08, struct dpaa_portal_map)
166 int process_portal_map(struct dpaa_ioctl_portal_map *params)
168 int ret = check_fd();
173 ret = ioctl(fd, DPAA_IOCTL_PORTAL_MAP, params);
175 perror("ioctl(DPAA_IOCTL_PORTAL_MAP)");
181 int process_portal_unmap(struct dpaa_portal_map *map)
183 int ret = check_fd();
188 ret = ioctl(fd, DPAA_IOCTL_PORTAL_UNMAP, map);
190 perror("ioctl(DPAA_IOCTL_PORTAL_UNMAP)");
196 #define DPAA_IOCTL_PORTAL_IRQ_MAP \
197 _IOW(DPAA_IOCTL_MAGIC, 0x09, struct dpaa_ioctl_irq_map)
199 int process_portal_irq_map(int ifd, struct dpaa_ioctl_irq_map *map)
202 return ioctl(ifd, DPAA_IOCTL_PORTAL_IRQ_MAP, map);
205 int process_portal_irq_unmap(int ifd)
210 struct dpaa_ioctl_raw_portal {
212 enum dpaa_portal_type type; /* Type of portal to allocate */
214 uint8_t enable_stash; /* set to non zero to turn on stashing */
215 /* Stashing attributes for the portal */
219 /* Specifies the stash request queue this portal should use */
222 /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
223 * for don't care. The portal index will be populated by the
224 * driver when the ioctl() successfully completes.
233 #define DPAA_IOCTL_ALLOC_RAW_PORTAL \
234 _IOWR(DPAA_IOCTL_MAGIC, 0x0C, struct dpaa_ioctl_raw_portal)
236 #define DPAA_IOCTL_FREE_RAW_PORTAL \
237 _IOR(DPAA_IOCTL_MAGIC, 0x0D, struct dpaa_ioctl_raw_portal)
239 static int process_portal_allocate(struct dpaa_ioctl_raw_portal *portal)
241 int ret = check_fd();
246 ret = ioctl(fd, DPAA_IOCTL_ALLOC_RAW_PORTAL, portal);
248 perror("ioctl(DPAA_IOCTL_ALLOC_RAW_PORTAL)");
254 static int process_portal_free(struct dpaa_ioctl_raw_portal *portal)
256 int ret = check_fd();
261 ret = ioctl(fd, DPAA_IOCTL_FREE_RAW_PORTAL, portal);
263 perror("ioctl(DPAA_IOCTL_FREE_RAW_PORTAL)");
269 int qman_allocate_raw_portal(struct dpaa_raw_portal *portal)
271 struct dpaa_ioctl_raw_portal input;
274 input.type = dpaa_portal_qman;
275 input.index = portal->index;
276 input.enable_stash = portal->enable_stash;
277 input.cpu = portal->cpu;
278 input.cache = portal->cache;
279 input.window = portal->window;
280 input.sdest = portal->sdest;
282 ret = process_portal_allocate(&input);
285 portal->index = input.index;
286 portal->cinh = input.cinh;
287 portal->cena = input.cena;
291 int qman_free_raw_portal(struct dpaa_raw_portal *portal)
293 struct dpaa_ioctl_raw_portal input;
295 input.type = dpaa_portal_qman;
296 input.index = portal->index;
297 input.cinh = portal->cinh;
298 input.cena = portal->cena;
300 return process_portal_free(&input);
303 int bman_allocate_raw_portal(struct dpaa_raw_portal *portal)
305 struct dpaa_ioctl_raw_portal input;
308 input.type = dpaa_portal_bman;
309 input.index = portal->index;
310 input.enable_stash = 0;
312 ret = process_portal_allocate(&input);
315 portal->index = input.index;
316 portal->cinh = input.cinh;
317 portal->cena = input.cena;
321 int bman_free_raw_portal(struct dpaa_raw_portal *portal)
323 struct dpaa_ioctl_raw_portal input;
325 input.type = dpaa_portal_bman;
326 input.index = portal->index;
327 input.cinh = portal->cinh;
328 input.cena = portal->cena;
330 return process_portal_free(&input);