2019-05-28 20:10:04 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2013-03-22 18:34:01 +04:00
/*
* Tegra host1x Syncpoints
*
* Copyright ( c ) 2010 - 2013 , NVIDIA Corporation .
*/
# ifndef __HOST1X_SYNCPT_H
# define __HOST1X_SYNCPT_H
# include <linux/atomic.h>
2013-09-24 18:30:32 +04:00
# include <linux/host1x.h>
2013-03-22 18:34:01 +04:00
# include <linux/kernel.h>
# include <linux/sched.h>
2013-03-22 18:34:02 +04:00
# include "intr.h"
2013-03-22 18:34:01 +04:00
struct host1x ;
2013-03-22 18:34:03 +04:00
/* Reserved for replacing an expired wait with a NOP */
# define HOST1X_SYNCPT_RESERVED 0
2013-10-14 16:21:53 +04:00
struct host1x_syncpt_base {
unsigned int id ;
bool requested ;
} ;
2013-03-22 18:34:01 +04:00
struct host1x_syncpt {
2016-06-23 12:19:00 +03:00
unsigned int id ;
2013-03-22 18:34:01 +04:00
atomic_t min_val ;
atomic_t max_val ;
u32 base_val ;
const char * name ;
2013-05-29 14:26:07 +04:00
bool client_managed ;
2013-03-22 18:34:01 +04:00
struct host1x * host ;
2017-08-30 13:48:31 +03:00
struct host1x_client * client ;
2013-10-14 16:21:53 +04:00
struct host1x_syncpt_base * base ;
2013-03-22 18:34:02 +04:00
/* interrupt data */
struct host1x_syncpt_intr intr ;
2013-03-22 18:34:01 +04:00
} ;
/* Initialize sync point array */
int host1x_syncpt_init ( struct host1x * host ) ;
/* Free sync point array */
void host1x_syncpt_deinit ( struct host1x * host ) ;
/* Return number of sync point supported. */
2016-06-22 17:44:07 +03:00
unsigned int host1x_syncpt_nb_pts ( struct host1x * host ) ;
2013-03-22 18:34:01 +04:00
/* Return number of wait bases supported. */
2016-06-22 17:44:07 +03:00
unsigned int host1x_syncpt_nb_bases ( struct host1x * host ) ;
2013-03-22 18:34:01 +04:00
/* Return number of mlocks supported. */
2016-06-22 17:44:07 +03:00
unsigned int host1x_syncpt_nb_mlocks ( struct host1x * host ) ;
2013-03-22 18:34:01 +04:00
/*
* Check sync point sanity . If max is larger than min , there have too many
* sync point increments .
*
* Client managed sync point are not tracked .
* */
static inline bool host1x_syncpt_check_max ( struct host1x_syncpt * sp , u32 real )
{
u32 max ;
if ( sp - > client_managed )
return true ;
max = host1x_syncpt_read_max ( sp ) ;
return ( s32 ) ( max - real ) > = 0 ;
}
/* Return true if sync point is client managed. */
2013-05-29 14:26:07 +04:00
static inline bool host1x_syncpt_client_managed ( struct host1x_syncpt * sp )
2013-03-22 18:34:01 +04:00
{
return sp - > client_managed ;
}
/*
* Returns true if syncpoint min = = max , which means that there are no
* outstanding operations .
*/
static inline bool host1x_syncpt_idle ( struct host1x_syncpt * sp )
{
int min , max ;
smp_rmb ( ) ;
min = atomic_read ( & sp - > min_val ) ;
max = atomic_read ( & sp - > max_val ) ;
return ( min = = max ) ;
}
/* Load current value from hardware to the shadow register. */
u32 host1x_syncpt_load ( struct host1x_syncpt * sp ) ;
2013-03-22 18:34:02 +04:00
/* Check if the given syncpoint value has already passed */
bool host1x_syncpt_is_expired ( struct host1x_syncpt * sp , u32 thresh ) ;
2013-03-22 18:34:01 +04:00
/* Save host1x sync point state into shadow registers. */
void host1x_syncpt_save ( struct host1x * host ) ;
/* Reset host1x sync point state from shadow registers. */
void host1x_syncpt_restore ( struct host1x * host ) ;
/* Read current wait base value into shadow register and return it. */
u32 host1x_syncpt_load_wait_base ( struct host1x_syncpt * sp ) ;
/* Indicate future operations by incrementing the sync point max. */
u32 host1x_syncpt_incr_max ( struct host1x_syncpt * sp , u32 incrs ) ;
/* Check if sync point id is valid. */
static inline int host1x_syncpt_is_valid ( struct host1x_syncpt * sp )
{
return sp - > id < host1x_syncpt_nb_pts ( sp - > host ) ;
}
# endif