18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Tegra host1x Interrupt Management
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2010-2013, NVIDIA Corporation.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __HOST1X_INTR_H
98c2ecf20Sopenharmony_ci#define __HOST1X_INTR_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
128c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_cistruct host1x_syncpt;
158c2ecf20Sopenharmony_cistruct host1x;
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cienum host1x_intr_action {
188c2ecf20Sopenharmony_ci	/*
198c2ecf20Sopenharmony_ci	 * Perform cleanup after a submit has completed.
208c2ecf20Sopenharmony_ci	 * 'data' points to a channel
218c2ecf20Sopenharmony_ci	 */
228c2ecf20Sopenharmony_ci	HOST1X_INTR_ACTION_SUBMIT_COMPLETE = 0,
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	/*
258c2ecf20Sopenharmony_ci	 * Wake up a  task.
268c2ecf20Sopenharmony_ci	 * 'data' points to a wait_queue_head_t
278c2ecf20Sopenharmony_ci	 */
288c2ecf20Sopenharmony_ci	HOST1X_INTR_ACTION_WAKEUP,
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	/*
318c2ecf20Sopenharmony_ci	 * Wake up a interruptible task.
328c2ecf20Sopenharmony_ci	 * 'data' points to a wait_queue_head_t
338c2ecf20Sopenharmony_ci	 */
348c2ecf20Sopenharmony_ci	HOST1X_INTR_ACTION_WAKEUP_INTERRUPTIBLE,
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	HOST1X_INTR_ACTION_COUNT
378c2ecf20Sopenharmony_ci};
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistruct host1x_syncpt_intr {
408c2ecf20Sopenharmony_ci	spinlock_t lock;
418c2ecf20Sopenharmony_ci	struct list_head wait_head;
428c2ecf20Sopenharmony_ci	char thresh_irq_name[12];
438c2ecf20Sopenharmony_ci	struct work_struct work;
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistruct host1x_waitlist {
478c2ecf20Sopenharmony_ci	struct list_head list;
488c2ecf20Sopenharmony_ci	struct kref refcount;
498c2ecf20Sopenharmony_ci	u32 thresh;
508c2ecf20Sopenharmony_ci	enum host1x_intr_action action;
518c2ecf20Sopenharmony_ci	atomic_t state;
528c2ecf20Sopenharmony_ci	void *data;
538c2ecf20Sopenharmony_ci	int count;
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/*
578c2ecf20Sopenharmony_ci * Schedule an action to be taken when a sync point reaches the given threshold.
588c2ecf20Sopenharmony_ci *
598c2ecf20Sopenharmony_ci * @id the sync point
608c2ecf20Sopenharmony_ci * @thresh the threshold
618c2ecf20Sopenharmony_ci * @action the action to take
628c2ecf20Sopenharmony_ci * @data a pointer to extra data depending on action, see above
638c2ecf20Sopenharmony_ci * @waiter waiter structure - assumes ownership
648c2ecf20Sopenharmony_ci * @ref must be passed if cancellation is possible, else NULL
658c2ecf20Sopenharmony_ci *
668c2ecf20Sopenharmony_ci * This is a non-blocking api.
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_ciint host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt,
698c2ecf20Sopenharmony_ci			   u32 thresh, enum host1x_intr_action action,
708c2ecf20Sopenharmony_ci			   void *data, struct host1x_waitlist *waiter,
718c2ecf20Sopenharmony_ci			   void **ref);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*
748c2ecf20Sopenharmony_ci * Unreference an action submitted to host1x_intr_add_action().
758c2ecf20Sopenharmony_ci * You must call this if you passed non-NULL as ref.
768c2ecf20Sopenharmony_ci * @ref the ref returned from host1x_intr_add_action()
778c2ecf20Sopenharmony_ci */
788c2ecf20Sopenharmony_civoid host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/* Initialize host1x sync point interrupt */
818c2ecf20Sopenharmony_ciint host1x_intr_init(struct host1x *host, unsigned int irq_sync);
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/* Deinitialize host1x sync point interrupt */
848c2ecf20Sopenharmony_civoid host1x_intr_deinit(struct host1x *host);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci/* Enable host1x sync point interrupt */
878c2ecf20Sopenharmony_civoid host1x_intr_start(struct host1x *host);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/* Disable host1x sync point interrupt */
908c2ecf20Sopenharmony_civoid host1x_intr_stop(struct host1x *host);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciirqreturn_t host1x_syncpt_thresh_fn(void *dev_id);
938c2ecf20Sopenharmony_ci#endif
94