xref: /openbmc/linux/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
17e1659ccSBen Skeggs /*
27e1659ccSBen Skeggs  * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
37e1659ccSBen Skeggs  *
47e1659ccSBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
57e1659ccSBen Skeggs  * copy of this software and associated documentation files (the "Software"),
67e1659ccSBen Skeggs  * to deal in the Software without restriction, including without limitation
77e1659ccSBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87e1659ccSBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
97e1659ccSBen Skeggs  * Software is furnished to do so, subject to the following conditions:
107e1659ccSBen Skeggs  *
117e1659ccSBen Skeggs  * The above copyright notice and this permission notice shall be included in
127e1659ccSBen Skeggs  * all copies or substantial portions of the Software.
137e1659ccSBen Skeggs  *
147e1659ccSBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157e1659ccSBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167e1659ccSBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
177e1659ccSBen Skeggs  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
187e1659ccSBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
197e1659ccSBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
207e1659ccSBen Skeggs  * OTHER DEALINGS IN THE SOFTWARE.
217e1659ccSBen Skeggs  *
227e1659ccSBen Skeggs  */
237e1659ccSBen Skeggs #include "qmgr.h"
247e1659ccSBen Skeggs 
25*a15d8f58SBen Skeggs struct nvkm_falcon_qmgr_seq *
nvkm_falcon_qmgr_seq_acquire(struct nvkm_falcon_qmgr * qmgr)26*a15d8f58SBen Skeggs nvkm_falcon_qmgr_seq_acquire(struct nvkm_falcon_qmgr *qmgr)
277e1659ccSBen Skeggs {
28*a15d8f58SBen Skeggs 	const struct nvkm_subdev *subdev = qmgr->falcon->owner;
29*a15d8f58SBen Skeggs 	struct nvkm_falcon_qmgr_seq *seq;
307e1659ccSBen Skeggs 	u32 index;
317e1659ccSBen Skeggs 
32*a15d8f58SBen Skeggs 	mutex_lock(&qmgr->seq.mutex);
33*a15d8f58SBen Skeggs 	index = find_first_zero_bit(qmgr->seq.tbl, NVKM_FALCON_QMGR_SEQ_NUM);
34*a15d8f58SBen Skeggs 	if (index >= NVKM_FALCON_QMGR_SEQ_NUM) {
357e1659ccSBen Skeggs 		nvkm_error(subdev, "no free sequence available\n");
36*a15d8f58SBen Skeggs 		mutex_unlock(&qmgr->seq.mutex);
377e1659ccSBen Skeggs 		return ERR_PTR(-EAGAIN);
387e1659ccSBen Skeggs 	}
397e1659ccSBen Skeggs 
40*a15d8f58SBen Skeggs 	set_bit(index, qmgr->seq.tbl);
41*a15d8f58SBen Skeggs 	mutex_unlock(&qmgr->seq.mutex);
427e1659ccSBen Skeggs 
43*a15d8f58SBen Skeggs 	seq = &qmgr->seq.id[index];
447e1659ccSBen Skeggs 	seq->state = SEQ_STATE_PENDING;
457e1659ccSBen Skeggs 	return seq;
467e1659ccSBen Skeggs }
477e1659ccSBen Skeggs 
487e1659ccSBen Skeggs void
nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr * qmgr,struct nvkm_falcon_qmgr_seq * seq)49*a15d8f58SBen Skeggs nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr *qmgr,
50*a15d8f58SBen Skeggs 			     struct nvkm_falcon_qmgr_seq *seq)
517e1659ccSBen Skeggs {
52*a15d8f58SBen Skeggs 	/* no need to acquire seq.mutex since clear_bit is atomic */
537e1659ccSBen Skeggs 	seq->state = SEQ_STATE_FREE;
547e1659ccSBen Skeggs 	seq->callback = NULL;
558e90a98dSBen Skeggs 	reinit_completion(&seq->done);
56*a15d8f58SBen Skeggs 	clear_bit(seq->id, qmgr->seq.tbl);
577e1659ccSBen Skeggs }
588763955bSBen Skeggs 
598763955bSBen Skeggs void
nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr ** pqmgr)608763955bSBen Skeggs nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **pqmgr)
618763955bSBen Skeggs {
628763955bSBen Skeggs 	struct nvkm_falcon_qmgr *qmgr = *pqmgr;
638763955bSBen Skeggs 	if (qmgr) {
648763955bSBen Skeggs 		kfree(*pqmgr);
658763955bSBen Skeggs 		*pqmgr = NULL;
668763955bSBen Skeggs 	}
678763955bSBen Skeggs }
688763955bSBen Skeggs 
698763955bSBen Skeggs int
nvkm_falcon_qmgr_new(struct nvkm_falcon * falcon,struct nvkm_falcon_qmgr ** pqmgr)708763955bSBen Skeggs nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon,
718763955bSBen Skeggs 		     struct nvkm_falcon_qmgr **pqmgr)
728763955bSBen Skeggs {
738763955bSBen Skeggs 	struct nvkm_falcon_qmgr *qmgr;
740ae59432SBen Skeggs 	int i;
758763955bSBen Skeggs 
768763955bSBen Skeggs 	if (!(qmgr = *pqmgr = kzalloc(sizeof(*qmgr), GFP_KERNEL)))
778763955bSBen Skeggs 		return -ENOMEM;
788763955bSBen Skeggs 
798763955bSBen Skeggs 	qmgr->falcon = falcon;
80*a15d8f58SBen Skeggs 	mutex_init(&qmgr->seq.mutex);
81*a15d8f58SBen Skeggs 	for (i = 0; i < NVKM_FALCON_QMGR_SEQ_NUM; i++) {
82*a15d8f58SBen Skeggs 		qmgr->seq.id[i].id = i;
83*a15d8f58SBen Skeggs 		init_completion(&qmgr->seq.id[i].done);
848e90a98dSBen Skeggs 	}
850ae59432SBen Skeggs 
868763955bSBen Skeggs 	return 0;
878763955bSBen Skeggs }
88