randr12: remove pointless debug in nv_output and nv_crtc
[nouveau] / src / nouveau_dma.h
1 /*
2  * Copyright 2007 Nouveau Project
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #ifndef __NOUVEAU_DMA_H__
24 #define __NOUVEAU_DMA_H__
25
26 #include <string.h>
27 #include "nouveau_drmif.h"
28 #include "nouveau_local.h"
29
30 #define RING_SKIPS 8
31
32 NOUVEAU_PRIVATE int  nouveau_dma_wait(struct nouveau_channel *chan, int size);
33 NOUVEAU_PRIVATE void nouveau_dma_subc_bind(struct nouveau_grobj *);
34 NOUVEAU_PRIVATE void nouveau_dma_channel_init(struct nouveau_channel *);
35 NOUVEAU_PRIVATE void nouveau_dma_kickoff(struct nouveau_channel *);
36
37 #ifdef NOUVEAU_DMA_DEBUG
38 NOUVEAU_PRIVATE char faulty[1024];
39 #endif
40
41 static inline void
42 nouveau_dma_out(struct nouveau_channel *userchan, uint32_t data)
43 {
44         struct nouveau_channel_priv *chan = nouveau_channel(userchan);
45
46 #ifdef NOUVEAU_DMA_DEBUG
47         if (chan->dma.push_free == 0) {
48                 NOUVEAU_ERR("No space left in packet. Error at %s\n",faulty);
49                 return;
50         }
51         chan->dma.push_free--;
52 #endif
53 #ifdef NOUVEAU_DMA_TRACE
54         {
55                 uint32_t offset = (chan->dma.cur << 2) + chan->dma.base;
56                 NOUVEAU_MSG("\tOUT_RING %d/0x%08x -> 0x%08x\n",
57                             chan->drm.channel, offset, data);
58         }
59 #endif
60         chan->pushbuf[chan->dma.cur++] = data;
61 }
62
63 static inline void
64 nouveau_dma_outp(struct nouveau_channel *userchan, uint32_t *ptr, int size)
65 {
66         struct nouveau_channel_priv *chan = nouveau_channel(userchan);
67         (void)chan;
68
69 #ifdef NOUVEAU_DMA_DEBUG
70         if (chan->dma.push_free < size) {
71                 NOUVEAU_ERR("Packet too small.  Free=%d, Need=%d\n",
72                             chan->dma.push_free, size);
73                 return;
74         }
75 #endif
76 #ifdef NOUVEAU_DMA_TRACE
77         while (size--) {
78                 nouveau_dma_out(userchan, *ptr);
79                 ptr++;
80         }
81 #else
82         memcpy(&chan->pushbuf[chan->dma.cur], ptr, size << 2);
83 #ifdef NOUVEAU_DMA_DEBUG
84         chan->dma.push_free -= size;
85 #endif
86         chan->dma.cur += size;
87 #endif
88 }
89
90 static inline void
91 nouveau_dma_begin(struct nouveau_channel *userchan, struct nouveau_grobj *grobj,
92                   int method, int size, const char* file, int line)
93 {
94         struct nouveau_channel_priv *chan = nouveau_channel(userchan);
95         int push_size = size + 1;
96
97 #ifdef NOUVEAU_DMA_SUBCHAN_LRU
98         if (grobj->bound == NOUVEAU_GROBJ_UNBOUND)
99                 nouveau_dma_subc_bind(grobj);
100         chan->subchannel[grobj->subc].seq = chan->subc_sequence++;
101 #endif
102
103 #ifdef NOUVEAU_DMA_TRACE
104         NOUVEAU_MSG("BEGIN_RING %d/%08x/%d/0x%04x/%d\n", chan->drm.channel,
105                     grobj->handle, grobj->subc, method, size);
106 #endif
107
108 #ifdef NOUVEAU_DMA_DEBUG
109         if (chan->dma.push_free) {
110                 NOUVEAU_ERR("Previous packet incomplete: %d left. Error at %s\n",
111                             chan->dma.push_free,faulty);
112                 return;
113         }
114         sprintf(faulty,"%s:%d",file,line);
115 #endif
116
117         if (chan->dma.free < push_size) {
118                 if (nouveau_dma_wait(userchan, push_size) &&
119                     userchan->hang_notify) {
120                         userchan->hang_notify(userchan);
121                 }
122         }
123         chan->dma.free -= push_size;
124 #ifdef NOUVEAU_DMA_DEBUG
125         chan->dma.push_free = push_size;
126 #endif
127
128         nouveau_dma_out(userchan, (size << 18) | (grobj->subc << 13) | method);
129 }
130
131 static inline void
132 nouveau_dma_bind(struct nouveau_channel *userchan, struct nouveau_grobj *grobj,
133                  int subc)
134 {
135         struct nouveau_channel_priv *chan = nouveau_channel(userchan);
136
137         if (chan->subchannel[subc].grobj == grobj)
138                 return;
139
140         if (chan->subchannel[subc].grobj)
141                 chan->subchannel[subc].grobj->bound = NOUVEAU_GROBJ_UNBOUND;
142         chan->subchannel[subc].grobj = grobj;
143         grobj->subc  = subc;
144         grobj->bound = NOUVEAU_GROBJ_EXPLICIT_BIND;
145
146         nouveau_dma_begin(userchan, grobj, 0x0000, 1, __FUNCTION__, __LINE__);
147         nouveau_dma_out  (userchan, grobj->handle);
148 }
149
150 #define BIND_RING_CH(ch,gr,sc)       nouveau_dma_bind((ch), (gr), (sc))
151 #define BEGIN_RING_CH(ch,gr,m,sz)    nouveau_dma_begin((ch), (gr), (m), (sz), __FUNCTION__, __LINE__ )
152 #define OUT_RING_CH(ch, data)        nouveau_dma_out((ch), (data))
153 #define OUT_RINGp_CH(ch,ptr,dwords)  nouveau_dma_outp((ch), (void*)(ptr),      \
154                                                       (dwords))
155 #define FIRE_RING_CH(ch)             nouveau_dma_kickoff((ch))
156 #define WAIT_RING_CH(ch,sz)          nouveau_dma_wait((ch), (sz))
157                 
158 #endif