87b6a14d60e34b142da9bd814370597e07e6de80
[linux-2.6.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-2011, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #ifndef __NVHOST_CDMA_H
24 #define __NVHOST_CDMA_H
25
26 #include <linux/sched.h>
27 #include <linux/semaphore.h>
28
29 #include <linux/nvhost.h>
30 #include <mach/nvmap.h>
31 #include <linux/kfifo.h>
32
33 #include "nvhost_acm.h"
34
35 struct nvhost_syncpt;
36 struct nvhost_userctx_timeout;
37 struct nvhost_job;
38
39 /*
40  * cdma
41  *
42  * This is in charge of a host command DMA channel.
43  * Sends ops to a push buffer, and takes responsibility for unpinning
44  * (& possibly freeing) of memory after those ops have completed.
45  * Producer:
46  *      begin
47  *              push - send ops to the push buffer
48  *      end - start command DMA and enqueue handles to be unpinned
49  * Consumer:
50  *      update - call to update sync queue and push buffer, unpin memory
51  */
52
53 struct nvmap_client_handle {
54         struct nvmap_client *client;
55         struct nvmap_handle *handle;
56 };
57
58 struct push_buffer {
59         struct nvmap_handle_ref *mem;   /* handle to pushbuffer memory */
60         u32 *mapped;                    /* mapped pushbuffer memory */
61         u32 phys;                       /* physical address of pushbuffer */
62         u32 fence;                      /* index we've written */
63         u32 cur;                        /* index to write to */
64         struct nvmap_client_handle *nvmap;
65                                         /* nvmap handle for each opcode pair */
66 };
67
68 struct syncpt_buffer {
69         struct nvmap_handle_ref *mem; /* handle to pushbuffer memory */
70         u32 *mapped;            /* mapped gather buffer (at channel offset */
71         u32 phys;               /* physical address (at channel offset) */
72         u32 incr_per_buffer;    /* max # of incrs per GATHER */
73         u32 words_per_incr;     /* # of DWORDS in buffer to incr a syncpt */
74 };
75
76 struct buffer_timeout {
77         struct delayed_work wq;         /* work queue */
78         bool initialized;               /* timer one-time setup flag */
79         u32 syncpt_id;                  /* buffer completion syncpt id */
80         u32 syncpt_val;                 /* syncpt value when completed */
81         ktime_t start_ktime;            /* starting time */
82         /* context timeout information */
83         struct nvhost_hwctx *ctx;
84         int clientid;
85 };
86
87 enum cdma_event {
88         CDMA_EVENT_NONE,                /* not waiting for any event */
89         CDMA_EVENT_SYNC_QUEUE_EMPTY,    /* wait for empty sync queue */
90         CDMA_EVENT_SYNC_QUEUE_SPACE,    /* wait for space in sync queue */
91         CDMA_EVENT_PUSH_BUFFER_SPACE    /* wait for space in push buffer */
92 };
93
94 struct nvhost_cdma {
95         struct mutex lock;              /* controls access to shared state */
96         struct semaphore sem;           /* signalled when event occurs */
97         enum cdma_event event;          /* event that sem is waiting for */
98         unsigned int slots_used;        /* pb slots used in current submit */
99         unsigned int slots_free;        /* pb slots free in current submit */
100         unsigned int first_get;         /* DMAGET value, where submit begins */
101         unsigned int last_put;          /* last value written to DMAPUT */
102         struct push_buffer push_buffer; /* channel's push buffer */
103         struct syncpt_buffer syncpt_buffer; /* syncpt incr buffer */
104         DECLARE_KFIFO_PTR(sync_queue, struct nvhost_job *); /* job queue */
105         struct buffer_timeout timeout;  /* channel's timeout state/wq */
106         bool running;
107         bool torndown;
108 };
109
110 #define cdma_to_channel(cdma) container_of(cdma, struct nvhost_channel, cdma)
111 #define cdma_to_dev(cdma) ((cdma_to_channel(cdma))->dev)
112 #define cdma_op(cdma) (cdma_to_dev(cdma)->op.cdma)
113 #define cdma_to_nvmap(cdma) ((cdma_to_dev(cdma))->nvmap)
114 #define pb_to_cdma(pb) container_of(pb, struct nvhost_cdma, push_buffer)
115 #define cdma_pb_op(cdma) (cdma_to_dev(cdma)->op.push_buffer)
116
117 int     nvhost_cdma_init(struct nvhost_cdma *cdma);
118 void    nvhost_cdma_deinit(struct nvhost_cdma *cdma);
119 void    nvhost_cdma_stop(struct nvhost_cdma *cdma);
120 int     nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job);
121 void    nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
122 #define NVHOST_CDMA_PUSH_GATHER_CTXSAVE 0xffffffff
123 void    nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
124                 struct nvmap_client *client,
125                 struct nvmap_handle *handle, u32 op1, u32 op2);
126 void    nvhost_cdma_end(struct nvhost_cdma *cdma,
127                 struct nvhost_job *job);
128 void    nvhost_cdma_update(struct nvhost_cdma *cdma);
129 int     nvhost_cdma_flush(struct nvhost_cdma *cdma, int timeout);
130 void    nvhost_cdma_peek(struct nvhost_cdma *cdma,
131                 u32 dmaget, int slot, u32 *out);
132 unsigned int nvhost_cdma_wait_locked(struct nvhost_cdma *cdma,
133                 enum cdma_event event);
134 void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
135                 struct nvhost_syncpt *syncpt, struct device *dev);
136 #endif