Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Tegra host1x Syncpoints
0004  *
0005  * Copyright (c) 2010-2013, NVIDIA Corporation.
0006  */
0007 
0008 #ifndef __HOST1X_SYNCPT_H
0009 #define __HOST1X_SYNCPT_H
0010 
0011 #include <linux/atomic.h>
0012 #include <linux/host1x.h>
0013 #include <linux/kernel.h>
0014 #include <linux/kref.h>
0015 #include <linux/sched.h>
0016 
0017 #include "intr.h"
0018 
0019 struct host1x;
0020 
0021 /* Reserved for replacing an expired wait with a NOP */
0022 #define HOST1X_SYNCPT_RESERVED          0
0023 
0024 struct host1x_syncpt_base {
0025     unsigned int id;
0026     bool requested;
0027 };
0028 
0029 struct host1x_syncpt {
0030     struct kref ref;
0031 
0032     unsigned int id;
0033     atomic_t min_val;
0034     atomic_t max_val;
0035     u32 base_val;
0036     const char *name;
0037     bool client_managed;
0038     struct host1x *host;
0039     struct host1x_syncpt_base *base;
0040 
0041     /* interrupt data */
0042     struct host1x_syncpt_intr intr;
0043 
0044     /*
0045      * If a submission incrementing this syncpoint fails, lock it so that
0046      * further submission cannot be made until application has handled the
0047      * failure.
0048      */
0049     bool locked;
0050 };
0051 
0052 /* Initialize sync point array  */
0053 int host1x_syncpt_init(struct host1x *host);
0054 
0055 /*  Free sync point array */
0056 void host1x_syncpt_deinit(struct host1x *host);
0057 
0058 /* Return number of sync point supported. */
0059 unsigned int host1x_syncpt_nb_pts(struct host1x *host);
0060 
0061 /* Return number of wait bases supported. */
0062 unsigned int host1x_syncpt_nb_bases(struct host1x *host);
0063 
0064 /* Return number of mlocks supported. */
0065 unsigned int host1x_syncpt_nb_mlocks(struct host1x *host);
0066 
0067 /*
0068  * Check sync point sanity. If max is larger than min, there have too many
0069  * sync point increments.
0070  *
0071  * Client managed sync point are not tracked.
0072  * */
0073 static inline bool host1x_syncpt_check_max(struct host1x_syncpt *sp, u32 real)
0074 {
0075     u32 max;
0076     if (sp->client_managed)
0077         return true;
0078     max = host1x_syncpt_read_max(sp);
0079     return (s32)(max - real) >= 0;
0080 }
0081 
0082 /* Return true if sync point is client managed. */
0083 static inline bool host1x_syncpt_client_managed(struct host1x_syncpt *sp)
0084 {
0085     return sp->client_managed;
0086 }
0087 
0088 /*
0089  * Returns true if syncpoint min == max, which means that there are no
0090  * outstanding operations.
0091  */
0092 static inline bool host1x_syncpt_idle(struct host1x_syncpt *sp)
0093 {
0094     int min, max;
0095     smp_rmb();
0096     min = atomic_read(&sp->min_val);
0097     max = atomic_read(&sp->max_val);
0098     return (min == max);
0099 }
0100 
0101 /* Load current value from hardware to the shadow register. */
0102 u32 host1x_syncpt_load(struct host1x_syncpt *sp);
0103 
0104 /* Check if the given syncpoint value has already passed */
0105 bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh);
0106 
0107 /* Save host1x sync point state into shadow registers. */
0108 void host1x_syncpt_save(struct host1x *host);
0109 
0110 /* Reset host1x sync point state from shadow registers. */
0111 void host1x_syncpt_restore(struct host1x *host);
0112 
0113 /* Read current wait base value into shadow register and return it. */
0114 u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp);
0115 
0116 /* Indicate future operations by incrementing the sync point max. */
0117 u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
0118 
0119 /* Check if sync point id is valid. */
0120 static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp)
0121 {
0122     return sp->id < host1x_syncpt_nb_pts(sp->host);
0123 }
0124 
0125 static inline void host1x_syncpt_set_locked(struct host1x_syncpt *sp)
0126 {
0127     sp->locked = true;
0128 }
0129 
0130 #endif