at v3.12-rc4 162 lines 4.6 kB view raw
1/* 2 * Tegra host1x Syncpoints 3 * 4 * Copyright (c) 2010-2013, NVIDIA Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19#ifndef __HOST1X_SYNCPT_H 20#define __HOST1X_SYNCPT_H 21 22#include <linux/atomic.h> 23#include <linux/kernel.h> 24#include <linux/sched.h> 25 26#include "intr.h" 27 28struct host1x; 29 30/* Reserved for replacing an expired wait with a NOP */ 31#define HOST1X_SYNCPT_RESERVED 0 32 33struct host1x_syncpt { 34 int id; 35 atomic_t min_val; 36 atomic_t max_val; 37 u32 base_val; 38 const char *name; 39 bool client_managed; 40 struct host1x *host; 41 struct device *dev; 42 43 /* interrupt data */ 44 struct host1x_syncpt_intr intr; 45}; 46 47/* Initialize sync point array */ 48int host1x_syncpt_init(struct host1x *host); 49 50/* Free sync point array */ 51void host1x_syncpt_deinit(struct host1x *host); 52 53/* 54 * Read max. It indicates how many operations there are in queue, either in 55 * channel or in a software thread. 56 * */ 57static inline u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) 58{ 59 smp_rmb(); 60 return (u32)atomic_read(&sp->max_val); 61} 62 63/* 64 * Read min, which is a shadow of the current sync point value in hardware. 65 */ 66static inline u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) 67{ 68 smp_rmb(); 69 return (u32)atomic_read(&sp->min_val); 70} 71 72/* Return number of sync point supported. */ 73int host1x_syncpt_nb_pts(struct host1x *host); 74 75/* Return number of wait bases supported. */ 76int host1x_syncpt_nb_bases(struct host1x *host); 77 78/* Return number of mlocks supported. */ 79int host1x_syncpt_nb_mlocks(struct host1x *host); 80 81/* 82 * Check sync point sanity. If max is larger than min, there have too many 83 * sync point increments. 84 * 85 * Client managed sync point are not tracked. 86 * */ 87static inline bool host1x_syncpt_check_max(struct host1x_syncpt *sp, u32 real) 88{ 89 u32 max; 90 if (sp->client_managed) 91 return true; 92 max = host1x_syncpt_read_max(sp); 93 return (s32)(max - real) >= 0; 94} 95 96/* Return true if sync point is client managed. */ 97static inline bool host1x_syncpt_client_managed(struct host1x_syncpt *sp) 98{ 99 return sp->client_managed; 100} 101 102/* 103 * Returns true if syncpoint min == max, which means that there are no 104 * outstanding operations. 105 */ 106static inline bool host1x_syncpt_idle(struct host1x_syncpt *sp) 107{ 108 int min, max; 109 smp_rmb(); 110 min = atomic_read(&sp->min_val); 111 max = atomic_read(&sp->max_val); 112 return (min == max); 113} 114 115/* Return pointer to struct denoting sync point id. */ 116struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id); 117 118/* Load current value from hardware to the shadow register. */ 119u32 host1x_syncpt_load(struct host1x_syncpt *sp); 120 121/* Check if the given syncpoint value has already passed */ 122bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh); 123 124/* Save host1x sync point state into shadow registers. */ 125void host1x_syncpt_save(struct host1x *host); 126 127/* Reset host1x sync point state from shadow registers. */ 128void host1x_syncpt_restore(struct host1x *host); 129 130/* Read current wait base value into shadow register and return it. */ 131u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp); 132 133/* Request incrementing a sync point. */ 134int host1x_syncpt_incr(struct host1x_syncpt *sp); 135 136/* Indicate future operations by incrementing the sync point max. */ 137u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs); 138 139/* Wait until sync point reaches a threshold value, or a timeout. */ 140int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, 141 long timeout, u32 *value); 142 143/* Check if sync point id is valid. */ 144static inline int host1x_syncpt_is_valid(struct host1x_syncpt *sp) 145{ 146 return sp->id < host1x_syncpt_nb_pts(sp->host); 147} 148 149/* Patch a wait by replacing it with a wait for syncpt 0 value 0 */ 150int host1x_syncpt_patch_wait(struct host1x_syncpt *sp, void *patch_addr); 151 152/* Return id of the sync point */ 153u32 host1x_syncpt_id(struct host1x_syncpt *sp); 154 155/* Allocate a sync point for a device. */ 156struct host1x_syncpt *host1x_syncpt_request(struct device *dev, 157 bool client_managed); 158 159/* Free a sync point. */ 160void host1x_syncpt_free(struct host1x_syncpt *sp); 161 162#endif