video: tegra: host: Support multi-syncpt jobs
[linux-3.10.git] / drivers / video / tegra / host / nvhost_cdma.h
1 /*
2  * drivers/video/tegra/host/nvhost_cdma.h
3  *
4  * Tegra Graphics Host Command DMA
5  *
6  * Copyright (c) 2010-2013, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifndef __NVHOST_CDMA_H
22 #define __NVHOST_CDMA_H
23
24 #include <linux/sched.h>
25 #include <linux/semaphore.h>
26
27 #include <linux/nvhost.h>
28 #include <linux/list.h>
29
30 struct nvhost_syncpt;
31 struct nvhost_userctx_timeout;
32 struct nvhost_job;
33 struct mem_mgr;
34 struct mem_handle;
35
36 /*
37  * cdma
38  *
39  * This is in charge of a host command DMA channel.
40  * Sends ops to a push buffer, and takes responsibility for unpinning
41  * (& possibly freeing) of memory after those ops have completed.
42  * Producer:
43  *      begin
44  *              push - send ops to the push buffer
45  *      end - start command DMA and enqueue handles to be unpinned
46  * Consumer:
47  *      update - call to update sync queue and push buffer, unpin memory
48  */
49
50 struct mem_mgr_handle {
51         struct mem_mgr *client;
52         struct mem_handle *handle;
53 };
54
55 struct push_buffer {
56         struct mem_handle *mem;         /* handle to pushbuffer memory */
57         u32 *mapped;                    /* mapped pushbuffer memory */
58         struct sg_table *sgt;
59         dma_addr_t phys;                /* physical address of pushbuffer */
60         u32 fence;                      /* index we've written */
61         u32 cur;                        /* index to write to */
62         struct mem_mgr_handle *client_handle; /* handle for each opcode pair */
63 };
64
65 struct buffer_timeout {
66         struct delayed_work wq;         /* work queue */
67         bool initialized;               /* timer one-time setup flag */
68         struct nvhost_job_syncpt *sp;   /* buffer syncpoint information */
69         ktime_t start_ktime;            /* starting time */
70         /* context timeout information */
71         struct nvhost_hwctx *ctx;
72         int clientid;
73         bool timeout_debug_dump;
74         int num_syncpts;
75 };
76
77 enum cdma_event {
78         CDMA_EVENT_NONE,                /* not waiting for any event */
79         CDMA_EVENT_SYNC_QUEUE_EMPTY,    /* wait for empty sync queue */
80         CDMA_EVENT_PUSH_BUFFER_SPACE    /* wait for space in push buffer */
81 };
82
83 struct nvhost_cdma {
84         struct mutex lock;              /* controls access to shared state */
85         struct semaphore sem;           /* signalled when event occurs */
86         enum cdma_event event;          /* event that sem is waiting for */
87         unsigned int slots_used;        /* pb slots used in current submit */
88         unsigned int slots_free;        /* pb slots free in current submit */
89         unsigned int first_get;         /* DMAGET value, where submit begins */
90         unsigned int last_put;          /* last value written to DMAPUT */
91         struct push_buffer push_buffer; /* channel's push buffer */
92         struct list_head sync_queue;    /* job queue */
93         struct buffer_timeout timeout;  /* channel's timeout state/wq */
94         bool running;
95         bool torndown;
96         int high_prio_count;
97         int med_prio_count;
98         int low_prio_count;
99 };
100
101 #define cdma_to_channel(cdma) container_of(cdma, struct nvhost_channel, cdma)
102 #define cdma_to_dev(cdma) nvhost_get_host(cdma_to_channel(cdma)->dev)
103 #define cdma_to_memmgr(cdma) ((cdma_to_dev(cdma))->memmgr)
104 #define pb_to_cdma(pb) container_of(pb, struct nvhost_cdma, push_buffer)
105
106 int     nvhost_cdma_init(struct nvhost_cdma *cdma);
107 void    nvhost_cdma_deinit(struct nvhost_cdma *cdma);
108 void    nvhost_cdma_stop(struct nvhost_cdma *cdma);
109 int     nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job);
110 void    nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
111 void    nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
112                 struct mem_mgr *client,
113                 struct mem_handle *handle, u32 offset, u32 op1, u32 op2);
114 void    nvhost_cdma_end(struct nvhost_cdma *cdma,
115                 struct nvhost_job *job);
116 void    nvhost_cdma_update(struct nvhost_cdma *cdma);
117 int     nvhost_cdma_flush(struct nvhost_cdma *cdma, int timeout);
118 void    nvhost_cdma_peek(struct nvhost_cdma *cdma,
119                 u32 dmaget, int slot, u32 *out);
120 unsigned int nvhost_cdma_wait_locked(struct nvhost_cdma *cdma,
121                 enum cdma_event event);
122 void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
123                 struct nvhost_syncpt *syncpt, struct platform_device *dev);
124 #endif