xref: /dpdk/drivers/bus/dpaa/base/qbman/process.c (revision d81734caccade4dc17d24d2ffd8b71244d35a69f)
1*d81734caSHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
223df3960SShreyansh Jain  *
323df3960SShreyansh Jain  * Copyright 2011-2016 Freescale Semiconductor Inc.
4*d81734caSHemant Agrawal  * Copyright 2017 NXP
523df3960SShreyansh Jain  *
623df3960SShreyansh Jain  */
723df3960SShreyansh Jain #include <assert.h>
823df3960SShreyansh Jain #include <fcntl.h>
923df3960SShreyansh Jain #include <unistd.h>
1023df3960SShreyansh Jain #include <sys/ioctl.h>
1123df3960SShreyansh Jain 
1223df3960SShreyansh Jain #include "process.h"
1323df3960SShreyansh Jain 
1423df3960SShreyansh Jain #include <fsl_usd.h>
1523df3960SShreyansh Jain 
1623df3960SShreyansh Jain /* As higher-level drivers will be built on top of this (dma_mem, qbman, ...),
1723df3960SShreyansh Jain  * it's preferable that the process driver itself not provide any exported API.
1823df3960SShreyansh Jain  * As such, combined with the fact that none of these operations are
1923df3960SShreyansh Jain  * performance critical, it is justified to use lazy initialisation, so that's
2023df3960SShreyansh Jain  * what the lock is for.
2123df3960SShreyansh Jain  */
2223df3960SShreyansh Jain static int fd = -1;
2323df3960SShreyansh Jain static pthread_mutex_t fd_init_lock = PTHREAD_MUTEX_INITIALIZER;
2423df3960SShreyansh Jain 
2523df3960SShreyansh Jain static int check_fd(void)
2623df3960SShreyansh Jain {
2723df3960SShreyansh Jain 	int ret;
2823df3960SShreyansh Jain 
2923df3960SShreyansh Jain 	if (fd >= 0)
3023df3960SShreyansh Jain 		return 0;
3123df3960SShreyansh Jain 	ret = pthread_mutex_lock(&fd_init_lock);
3223df3960SShreyansh Jain 	assert(!ret);
3323df3960SShreyansh Jain 	/* check again with the lock held */
3423df3960SShreyansh Jain 	if (fd < 0)
3523df3960SShreyansh Jain 		fd = open(PROCESS_PATH, O_RDWR);
3623df3960SShreyansh Jain 	ret = pthread_mutex_unlock(&fd_init_lock);
3723df3960SShreyansh Jain 	assert(!ret);
3823df3960SShreyansh Jain 	return (fd >= 0) ? 0 : -ENODEV;
3923df3960SShreyansh Jain }
4023df3960SShreyansh Jain 
4123df3960SShreyansh Jain #define DPAA_IOCTL_MAGIC 'u'
4223df3960SShreyansh Jain struct dpaa_ioctl_id_alloc {
4323df3960SShreyansh Jain 	uint32_t base; /* Return value, the start of the allocated range */
4423df3960SShreyansh Jain 	enum dpaa_id_type id_type; /* what kind of resource(s) to allocate */
4523df3960SShreyansh Jain 	uint32_t num; /* how many IDs to allocate (and return value) */
4623df3960SShreyansh Jain 	uint32_t align; /* must be a power of 2, 0 is treated like 1 */
4723df3960SShreyansh Jain 	int partial; /* whether to allow less than 'num' */
4823df3960SShreyansh Jain };
4923df3960SShreyansh Jain 
5023df3960SShreyansh Jain struct dpaa_ioctl_id_release {
5123df3960SShreyansh Jain 	/* Input; */
5223df3960SShreyansh Jain 	enum dpaa_id_type id_type;
5323df3960SShreyansh Jain 	uint32_t base;
5423df3960SShreyansh Jain 	uint32_t num;
5523df3960SShreyansh Jain };
5623df3960SShreyansh Jain 
5723df3960SShreyansh Jain struct dpaa_ioctl_id_reserve {
5823df3960SShreyansh Jain 	enum dpaa_id_type id_type;
5923df3960SShreyansh Jain 	uint32_t base;
6023df3960SShreyansh Jain 	uint32_t num;
6123df3960SShreyansh Jain };
6223df3960SShreyansh Jain 
6323df3960SShreyansh Jain #define DPAA_IOCTL_ID_ALLOC \
6423df3960SShreyansh Jain 	_IOWR(DPAA_IOCTL_MAGIC, 0x01, struct dpaa_ioctl_id_alloc)
6523df3960SShreyansh Jain #define DPAA_IOCTL_ID_RELEASE \
6623df3960SShreyansh Jain 	_IOW(DPAA_IOCTL_MAGIC, 0x02, struct dpaa_ioctl_id_release)
6723df3960SShreyansh Jain #define DPAA_IOCTL_ID_RESERVE \
6823df3960SShreyansh Jain 	_IOW(DPAA_IOCTL_MAGIC, 0x0A, struct dpaa_ioctl_id_reserve)
6923df3960SShreyansh Jain 
7023df3960SShreyansh Jain int process_alloc(enum dpaa_id_type id_type, uint32_t *base, uint32_t num,
7123df3960SShreyansh Jain 		  uint32_t align, int partial)
7223df3960SShreyansh Jain {
7323df3960SShreyansh Jain 	struct dpaa_ioctl_id_alloc id = {
7423df3960SShreyansh Jain 		.id_type = id_type,
7523df3960SShreyansh Jain 		.num = num,
7623df3960SShreyansh Jain 		.align = align,
7723df3960SShreyansh Jain 		.partial = partial
7823df3960SShreyansh Jain 	};
7923df3960SShreyansh Jain 	int ret = check_fd();
8023df3960SShreyansh Jain 
8123df3960SShreyansh Jain 	if (ret)
8223df3960SShreyansh Jain 		return ret;
8323df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_ID_ALLOC, &id);
8423df3960SShreyansh Jain 	if (ret)
8523df3960SShreyansh Jain 		return ret;
8623df3960SShreyansh Jain 	for (ret = 0; ret < (int)id.num; ret++)
8723df3960SShreyansh Jain 		base[ret] = id.base + ret;
8823df3960SShreyansh Jain 	return id.num;
8923df3960SShreyansh Jain }
9023df3960SShreyansh Jain 
9123df3960SShreyansh Jain void process_release(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
9223df3960SShreyansh Jain {
9323df3960SShreyansh Jain 	struct dpaa_ioctl_id_release id = {
9423df3960SShreyansh Jain 		.id_type = id_type,
9523df3960SShreyansh Jain 		.base = base,
9623df3960SShreyansh Jain 		.num = num
9723df3960SShreyansh Jain 	};
9823df3960SShreyansh Jain 	int ret = check_fd();
9923df3960SShreyansh Jain 
10023df3960SShreyansh Jain 	if (ret) {
10123df3960SShreyansh Jain 		fprintf(stderr, "Process FD failure\n");
10223df3960SShreyansh Jain 		return;
10323df3960SShreyansh Jain 	}
10423df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_ID_RELEASE, &id);
10523df3960SShreyansh Jain 	if (ret)
10623df3960SShreyansh Jain 		fprintf(stderr, "Process FD ioctl failure type %d base 0x%x num %d\n",
10723df3960SShreyansh Jain 			id_type, base, num);
10823df3960SShreyansh Jain }
10923df3960SShreyansh Jain 
11023df3960SShreyansh Jain int process_reserve(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
11123df3960SShreyansh Jain {
11223df3960SShreyansh Jain 	struct dpaa_ioctl_id_reserve id = {
11323df3960SShreyansh Jain 		.id_type = id_type,
11423df3960SShreyansh Jain 		.base = base,
11523df3960SShreyansh Jain 		.num = num
11623df3960SShreyansh Jain 	};
11723df3960SShreyansh Jain 	int ret = check_fd();
11823df3960SShreyansh Jain 
11923df3960SShreyansh Jain 	if (ret)
12023df3960SShreyansh Jain 		return ret;
12123df3960SShreyansh Jain 	return ioctl(fd, DPAA_IOCTL_ID_RESERVE, &id);
12223df3960SShreyansh Jain }
12323df3960SShreyansh Jain 
12423df3960SShreyansh Jain /***************************************/
12523df3960SShreyansh Jain /* Mapping and using QMan/BMan portals */
12623df3960SShreyansh Jain /***************************************/
12723df3960SShreyansh Jain 
12823df3960SShreyansh Jain #define DPAA_IOCTL_PORTAL_MAP \
12923df3960SShreyansh Jain 	_IOWR(DPAA_IOCTL_MAGIC, 0x07, struct dpaa_ioctl_portal_map)
13023df3960SShreyansh Jain #define DPAA_IOCTL_PORTAL_UNMAP \
13123df3960SShreyansh Jain 	_IOW(DPAA_IOCTL_MAGIC, 0x08, struct dpaa_portal_map)
13223df3960SShreyansh Jain 
13323df3960SShreyansh Jain int process_portal_map(struct dpaa_ioctl_portal_map *params)
13423df3960SShreyansh Jain {
13523df3960SShreyansh Jain 	int ret = check_fd();
13623df3960SShreyansh Jain 
13723df3960SShreyansh Jain 	if (ret)
13823df3960SShreyansh Jain 		return ret;
13923df3960SShreyansh Jain 
14023df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_PORTAL_MAP, params);
14123df3960SShreyansh Jain 	if (ret) {
14223df3960SShreyansh Jain 		perror("ioctl(DPAA_IOCTL_PORTAL_MAP)");
14323df3960SShreyansh Jain 		return ret;
14423df3960SShreyansh Jain 	}
14523df3960SShreyansh Jain 	return 0;
14623df3960SShreyansh Jain }
14723df3960SShreyansh Jain 
14823df3960SShreyansh Jain int process_portal_unmap(struct dpaa_portal_map *map)
14923df3960SShreyansh Jain {
15023df3960SShreyansh Jain 	int ret = check_fd();
15123df3960SShreyansh Jain 
15223df3960SShreyansh Jain 	if (ret)
15323df3960SShreyansh Jain 		return ret;
15423df3960SShreyansh Jain 
15523df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_PORTAL_UNMAP, map);
15623df3960SShreyansh Jain 	if (ret) {
15723df3960SShreyansh Jain 		perror("ioctl(DPAA_IOCTL_PORTAL_UNMAP)");
15823df3960SShreyansh Jain 		return ret;
15923df3960SShreyansh Jain 	}
16023df3960SShreyansh Jain 	return 0;
16123df3960SShreyansh Jain }
16223df3960SShreyansh Jain 
16323df3960SShreyansh Jain #define DPAA_IOCTL_PORTAL_IRQ_MAP \
16423df3960SShreyansh Jain 	_IOW(DPAA_IOCTL_MAGIC, 0x09, struct dpaa_ioctl_irq_map)
16523df3960SShreyansh Jain 
16623df3960SShreyansh Jain int process_portal_irq_map(int ifd, struct dpaa_ioctl_irq_map *map)
16723df3960SShreyansh Jain {
16823df3960SShreyansh Jain 	map->fd = fd;
16923df3960SShreyansh Jain 	return ioctl(ifd, DPAA_IOCTL_PORTAL_IRQ_MAP, map);
17023df3960SShreyansh Jain }
17123df3960SShreyansh Jain 
17223df3960SShreyansh Jain int process_portal_irq_unmap(int ifd)
17323df3960SShreyansh Jain {
17423df3960SShreyansh Jain 	return close(ifd);
17523df3960SShreyansh Jain }
17623df3960SShreyansh Jain 
17723df3960SShreyansh Jain struct dpaa_ioctl_raw_portal {
17823df3960SShreyansh Jain 	/* inputs */
17923df3960SShreyansh Jain 	enum dpaa_portal_type type; /* Type of portal to allocate */
18023df3960SShreyansh Jain 
18123df3960SShreyansh Jain 	uint8_t enable_stash; /* set to non zero to turn on stashing */
18223df3960SShreyansh Jain 	/* Stashing attributes for the portal */
18323df3960SShreyansh Jain 	uint32_t cpu;
18423df3960SShreyansh Jain 	uint32_t cache;
18523df3960SShreyansh Jain 	uint32_t window;
18623df3960SShreyansh Jain 	/* Specifies the stash request queue this portal should use */
18723df3960SShreyansh Jain 	uint8_t sdest;
18823df3960SShreyansh Jain 
18923df3960SShreyansh Jain 	/* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
19023df3960SShreyansh Jain 	 * for don't care.  The portal index will be populated by the
19123df3960SShreyansh Jain 	 * driver when the ioctl() successfully completes.
19223df3960SShreyansh Jain 	 */
19323df3960SShreyansh Jain 	uint32_t index;
19423df3960SShreyansh Jain 
19523df3960SShreyansh Jain 	/* outputs */
19623df3960SShreyansh Jain 	uint64_t cinh;
19723df3960SShreyansh Jain 	uint64_t cena;
19823df3960SShreyansh Jain };
19923df3960SShreyansh Jain 
20023df3960SShreyansh Jain #define DPAA_IOCTL_ALLOC_RAW_PORTAL \
20123df3960SShreyansh Jain 	_IOWR(DPAA_IOCTL_MAGIC, 0x0C, struct dpaa_ioctl_raw_portal)
20223df3960SShreyansh Jain 
20323df3960SShreyansh Jain #define DPAA_IOCTL_FREE_RAW_PORTAL \
20423df3960SShreyansh Jain 	_IOR(DPAA_IOCTL_MAGIC, 0x0D, struct dpaa_ioctl_raw_portal)
20523df3960SShreyansh Jain 
20623df3960SShreyansh Jain static int process_portal_allocate(struct dpaa_ioctl_raw_portal *portal)
20723df3960SShreyansh Jain {
20823df3960SShreyansh Jain 	int ret = check_fd();
20923df3960SShreyansh Jain 
21023df3960SShreyansh Jain 	if (ret)
21123df3960SShreyansh Jain 		return ret;
21223df3960SShreyansh Jain 
21323df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_ALLOC_RAW_PORTAL, portal);
21423df3960SShreyansh Jain 	if (ret) {
21523df3960SShreyansh Jain 		perror("ioctl(DPAA_IOCTL_ALLOC_RAW_PORTAL)");
21623df3960SShreyansh Jain 		return ret;
21723df3960SShreyansh Jain 	}
21823df3960SShreyansh Jain 	return 0;
21923df3960SShreyansh Jain }
22023df3960SShreyansh Jain 
22123df3960SShreyansh Jain static int process_portal_free(struct dpaa_ioctl_raw_portal *portal)
22223df3960SShreyansh Jain {
22323df3960SShreyansh Jain 	int ret = check_fd();
22423df3960SShreyansh Jain 
22523df3960SShreyansh Jain 	if (ret)
22623df3960SShreyansh Jain 		return ret;
22723df3960SShreyansh Jain 
22823df3960SShreyansh Jain 	ret = ioctl(fd, DPAA_IOCTL_FREE_RAW_PORTAL, portal);
22923df3960SShreyansh Jain 	if (ret) {
23023df3960SShreyansh Jain 		perror("ioctl(DPAA_IOCTL_FREE_RAW_PORTAL)");
23123df3960SShreyansh Jain 		return ret;
23223df3960SShreyansh Jain 	}
23323df3960SShreyansh Jain 	return 0;
23423df3960SShreyansh Jain }
23523df3960SShreyansh Jain 
23623df3960SShreyansh Jain int qman_allocate_raw_portal(struct dpaa_raw_portal *portal)
23723df3960SShreyansh Jain {
23823df3960SShreyansh Jain 	struct dpaa_ioctl_raw_portal input;
23923df3960SShreyansh Jain 	int ret;
24023df3960SShreyansh Jain 
24123df3960SShreyansh Jain 	input.type = dpaa_portal_qman;
24223df3960SShreyansh Jain 	input.index = portal->index;
24323df3960SShreyansh Jain 	input.enable_stash = portal->enable_stash;
24423df3960SShreyansh Jain 	input.cpu = portal->cpu;
24523df3960SShreyansh Jain 	input.cache = portal->cache;
24623df3960SShreyansh Jain 	input.window = portal->window;
24723df3960SShreyansh Jain 	input.sdest = portal->sdest;
24823df3960SShreyansh Jain 
24923df3960SShreyansh Jain 	ret =  process_portal_allocate(&input);
25023df3960SShreyansh Jain 	if (ret)
25123df3960SShreyansh Jain 		return ret;
25223df3960SShreyansh Jain 	portal->index = input.index;
25323df3960SShreyansh Jain 	portal->cinh = input.cinh;
25423df3960SShreyansh Jain 	portal->cena  = input.cena;
25523df3960SShreyansh Jain 	return 0;
25623df3960SShreyansh Jain }
25723df3960SShreyansh Jain 
25823df3960SShreyansh Jain int qman_free_raw_portal(struct dpaa_raw_portal *portal)
25923df3960SShreyansh Jain {
26023df3960SShreyansh Jain 	struct dpaa_ioctl_raw_portal input;
26123df3960SShreyansh Jain 
26223df3960SShreyansh Jain 	input.type = dpaa_portal_qman;
26323df3960SShreyansh Jain 	input.index = portal->index;
26423df3960SShreyansh Jain 	input.cinh = portal->cinh;
26523df3960SShreyansh Jain 	input.cena = portal->cena;
26623df3960SShreyansh Jain 
26723df3960SShreyansh Jain 	return process_portal_free(&input);
26823df3960SShreyansh Jain }
26923df3960SShreyansh Jain 
27023df3960SShreyansh Jain int bman_allocate_raw_portal(struct dpaa_raw_portal *portal)
27123df3960SShreyansh Jain {
27223df3960SShreyansh Jain 	struct dpaa_ioctl_raw_portal input;
27323df3960SShreyansh Jain 	int ret;
27423df3960SShreyansh Jain 
27523df3960SShreyansh Jain 	input.type = dpaa_portal_bman;
27623df3960SShreyansh Jain 	input.index = portal->index;
27723df3960SShreyansh Jain 	input.enable_stash = 0;
27823df3960SShreyansh Jain 
27923df3960SShreyansh Jain 	ret =  process_portal_allocate(&input);
28023df3960SShreyansh Jain 	if (ret)
28123df3960SShreyansh Jain 		return ret;
28223df3960SShreyansh Jain 	portal->index = input.index;
28323df3960SShreyansh Jain 	portal->cinh = input.cinh;
28423df3960SShreyansh Jain 	portal->cena  = input.cena;
28523df3960SShreyansh Jain 	return 0;
28623df3960SShreyansh Jain }
28723df3960SShreyansh Jain 
28823df3960SShreyansh Jain int bman_free_raw_portal(struct dpaa_raw_portal *portal)
28923df3960SShreyansh Jain {
29023df3960SShreyansh Jain 	struct dpaa_ioctl_raw_portal input;
29123df3960SShreyansh Jain 
29223df3960SShreyansh Jain 	input.type = dpaa_portal_bman;
29323df3960SShreyansh Jain 	input.index = portal->index;
29423df3960SShreyansh Jain 	input.cinh = portal->cinh;
29523df3960SShreyansh Jain 	input.cena = portal->cena;
29623df3960SShreyansh Jain 
29723df3960SShreyansh Jain 	return process_portal_free(&input);
29823df3960SShreyansh Jain }
299