1fda9279dSmrg/*
2fda9279dSmrg * Copyright 2007 Nouveau Project
3fda9279dSmrg *
4fda9279dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5fda9279dSmrg * copy of this software and associated documentation files (the "Software"),
6fda9279dSmrg * to deal in the Software without restriction, including without limitation
7fda9279dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fda9279dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9fda9279dSmrg * Software is furnished to do so, subject to the following conditions:
10fda9279dSmrg *
11fda9279dSmrg * The above copyright notice and this permission notice shall be included in
12fda9279dSmrg * all copies or substantial portions of the Software.
13fda9279dSmrg *
14fda9279dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15fda9279dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16fda9279dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17fda9279dSmrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18fda9279dSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19fda9279dSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20fda9279dSmrg * SOFTWARE.
21fda9279dSmrg */
22fda9279dSmrg
23fda9279dSmrg#ifndef __NOUVEAU_LOCAL_H__
24fda9279dSmrg#define __NOUVEAU_LOCAL_H__
25fda9279dSmrg
26fda9279dSmrg#include "compiler.h"
27fda9279dSmrg#include "xf86_OSproc.h"
28fda9279dSmrg
29fda9279dSmrg#include <nouveau.h>
30fda9279dSmrg
31fda9279dSmrg/* Debug output */
32fda9279dSmrg#define NOUVEAU_MSG(fmt,args...) ErrorF(fmt, ##args)
33fda9279dSmrg#define NOUVEAU_ERR(fmt,args...) \
34fda9279dSmrg	ErrorF("%s:%d - "fmt, __func__, __LINE__, ##args)
35fda9279dSmrg#if 0
36fda9279dSmrg#define NOUVEAU_FALLBACK(fmt,args...) do {    \
37fda9279dSmrg	NOUVEAU_ERR("FALLBACK: "fmt, ##args); \
38fda9279dSmrg	return FALSE;                         \
39fda9279dSmrg} while(0)
40fda9279dSmrg#else
41fda9279dSmrg#define NOUVEAU_FALLBACK(fmt,args...) do {    \
42fda9279dSmrg	return FALSE;                         \
43fda9279dSmrg} while(0)
44fda9279dSmrg#endif
45fda9279dSmrg
46fda9279dSmrg#define NOUVEAU_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
47fda9279dSmrg
48fda9279dSmrg#define NV50_TILE_PITCH(m) (64 << ((m) & 0xf))
49fda9279dSmrg#define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4))
50fda9279dSmrg#define NVC0_TILE_PITCH(m) (64 << ((m) & 0xf))
51fda9279dSmrg#define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4))
52fda9279dSmrg
53fda9279dSmrgstatic inline int log2i(int i)
54fda9279dSmrg{
55fda9279dSmrg	int r = 0;
56fda9279dSmrg
57fda9279dSmrg	if (i & 0xffff0000) {
58fda9279dSmrg		i >>= 16;
59fda9279dSmrg		r += 16;
60fda9279dSmrg	}
61fda9279dSmrg	if (i & 0x0000ff00) {
62fda9279dSmrg		i >>= 8;
63fda9279dSmrg		r += 8;
64fda9279dSmrg	}
65fda9279dSmrg	if (i & 0x000000f0) {
66fda9279dSmrg		i >>= 4;
67fda9279dSmrg		r += 4;
68fda9279dSmrg	}
69fda9279dSmrg	if (i & 0x0000000c) {
70fda9279dSmrg		i >>= 2;
71fda9279dSmrg		r += 2;
72fda9279dSmrg	}
73fda9279dSmrg	if (i & 0x00000002) {
74fda9279dSmrg		r += 1;
75fda9279dSmrg	}
76fda9279dSmrg	return r;
77fda9279dSmrg}
78fda9279dSmrg
79fda9279dSmrgstatic inline int round_down_pow2(int x)
80fda9279dSmrg{
81fda9279dSmrg	return 1 << log2i(x);
82fda9279dSmrg}
83fda9279dSmrg
84fda9279dSmrgstatic inline int round_up_pow2(int x)
85fda9279dSmrg{
86fda9279dSmrg   int r = round_down_pow2(x);
87fda9279dSmrg   if (r < x)
88fda9279dSmrg      r <<= 1;
89fda9279dSmrg   return r;
90fda9279dSmrg}
91fda9279dSmrg
92fda9279dSmrg#define SWAP(x, y) do {			\
93fda9279dSmrg		typeof(x) __z = (x);	\
94fda9279dSmrg		(x) = (y);		\
95fda9279dSmrg		(y) = __z;		\
96fda9279dSmrg	} while (0)
97fda9279dSmrg
98fda9279dSmrgstatic inline uint32_t
99fda9279dSmrgPUSH_AVAIL(struct nouveau_pushbuf *push)
100fda9279dSmrg{
101fda9279dSmrg	return push->end - push->cur;
102fda9279dSmrg}
103fda9279dSmrg
104fda9279dSmrgstatic inline Bool
105fda9279dSmrgPUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
106fda9279dSmrg{
107fda9279dSmrg	if (PUSH_AVAIL(push) < size)
108fda9279dSmrg		return nouveau_pushbuf_space(push, size, 0, 0) == 0;
109fda9279dSmrg	return TRUE;
110fda9279dSmrg}
111fda9279dSmrg
112fda9279dSmrgstatic inline void
113fda9279dSmrgPUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
114fda9279dSmrg{
115fda9279dSmrg	*push->cur++ = data;
116fda9279dSmrg}
117fda9279dSmrg
118fda9279dSmrgstatic inline void
119fda9279dSmrgPUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
120fda9279dSmrg{
121fda9279dSmrg	memcpy(push->cur, data, size * 4);
122fda9279dSmrg	push->cur += size;
123fda9279dSmrg}
124fda9279dSmrg
125fda9279dSmrgstatic inline void
126fda9279dSmrgPUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset,
127fda9279dSmrg	   uint32_t flags, uint32_t vor, uint32_t tor)
128fda9279dSmrg{
129fda9279dSmrg	nouveau_pushbuf_reloc(push, bo, offset, flags, vor, tor);
130fda9279dSmrg}
131fda9279dSmrg
132fda9279dSmrgstatic inline void
133fda9279dSmrgPUSH_KICK(struct nouveau_pushbuf *push)
134fda9279dSmrg{
135fda9279dSmrg	nouveau_pushbuf_kick(push, push->channel);
136fda9279dSmrg}
137fda9279dSmrg
138fda9279dSmrgstatic inline struct nouveau_bufctx *
139fda9279dSmrgBUFCTX(struct nouveau_pushbuf *push)
140fda9279dSmrg{
141fda9279dSmrg	return push->user_priv;
142fda9279dSmrg}
143fda9279dSmrg
144fda9279dSmrgstatic inline void
145fda9279dSmrgPUSH_RESET(struct nouveau_pushbuf *push)
146fda9279dSmrg{
147fda9279dSmrg	nouveau_bufctx_reset(BUFCTX(push), 0);
148fda9279dSmrg}
149fda9279dSmrg
150fda9279dSmrgstatic inline void
151fda9279dSmrgPUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t access)
152fda9279dSmrg{
153fda9279dSmrg	nouveau_bufctx_refn(BUFCTX(push), 0, bo, access);
154fda9279dSmrg}
155fda9279dSmrg
156fda9279dSmrgstatic inline void
157fda9279dSmrgPUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd,
158fda9279dSmrg	   struct nouveau_bo *bo, uint32_t offset, uint32_t access)
159fda9279dSmrg{
160fda9279dSmrg	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
161fda9279dSmrg			    bo, offset, access | NOUVEAU_BO_LOW, 0, 0);
162fda9279dSmrg	PUSH_DATA (push, bo->offset + offset);
163fda9279dSmrg}
164fda9279dSmrg
165fda9279dSmrgstatic inline void
166fda9279dSmrgPUSH_MTHDo(struct nouveau_pushbuf *push, int subc, int mthd,
167fda9279dSmrg	   struct nouveau_bo *bo, uint32_t access, uint32_t vor, uint32_t tor)
168fda9279dSmrg{
169fda9279dSmrg	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
170fda9279dSmrg			    bo, 0, access | NOUVEAU_BO_OR, vor, tor);
171fda9279dSmrg	if (bo->flags & NOUVEAU_BO_VRAM)
172fda9279dSmrg		PUSH_DATA (push, vor);
173fda9279dSmrg	else
174fda9279dSmrg		PUSH_DATA (push, tor);
175fda9279dSmrg}
176fda9279dSmrg
177fda9279dSmrgstatic inline void
178fda9279dSmrgPUSH_MTHDs(struct nouveau_pushbuf *push, int subc, int mthd,
179fda9279dSmrg	   struct nouveau_bo *bo, uint32_t data, uint32_t access,
180fda9279dSmrg	   uint32_t vor, uint32_t tor)
181fda9279dSmrg{
182fda9279dSmrg	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
183fda9279dSmrg			    bo, data, access | NOUVEAU_BO_OR, vor, tor);
184fda9279dSmrg	if (bo->flags & NOUVEAU_BO_VRAM)
185fda9279dSmrg		PUSH_DATA (push, data | vor);
186fda9279dSmrg	else
187fda9279dSmrg		PUSH_DATA (push, data | tor);
188fda9279dSmrg}
189fda9279dSmrg
190fda9279dSmrgstatic inline void
191fda9279dSmrgPUSH_MTHD(struct nouveau_pushbuf *push, int subc, int mthd,
192fda9279dSmrg	  struct nouveau_bo *bo, uint32_t data, uint32_t access,
193fda9279dSmrg	  uint32_t vor, uint32_t tor)
194fda9279dSmrg{
195fda9279dSmrg	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
196fda9279dSmrg			    bo, data, access | NOUVEAU_BO_OR, vor, tor);
197fda9279dSmrg	if (access & NOUVEAU_BO_LOW)
198fda9279dSmrg		data += bo->offset;
199fda9279dSmrg	if (access & NOUVEAU_BO_OR) {
200fda9279dSmrg		if (bo->flags & NOUVEAU_BO_VRAM)
201fda9279dSmrg			data |= vor;
202fda9279dSmrg		else
203fda9279dSmrg			data |= tor;
204fda9279dSmrg	}
205fda9279dSmrg	PUSH_DATA (push, data);
206fda9279dSmrg}
207fda9279dSmrg
208fda9279dSmrgstatic inline void
209fda9279dSmrgPUSH_DATAf(struct nouveau_pushbuf *push, float v)
210fda9279dSmrg{
211fda9279dSmrg	union { float f; uint32_t i; } d = { .f = v };
212fda9279dSmrg	PUSH_DATA (push, d.i);
213fda9279dSmrg}
214fda9279dSmrg
215fda9279dSmrgstatic inline void
216fda9279dSmrgBEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
217fda9279dSmrg{
218fda9279dSmrg	PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd);
219fda9279dSmrg}
220fda9279dSmrg
221fda9279dSmrgstatic inline void
222fda9279dSmrgBEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
223fda9279dSmrg{
224fda9279dSmrg	PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd);
225fda9279dSmrg}
226fda9279dSmrg
227fda9279dSmrgstatic inline void
228fda9279dSmrgBEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
229fda9279dSmrg{
230fda9279dSmrg	PUSH_DATA (push, 0x20000000 | (size << 16) | (subc << 13) | (mthd / 4));
231fda9279dSmrg}
232fda9279dSmrg
233fda9279dSmrgstatic inline void
234fda9279dSmrgBEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
235fda9279dSmrg{
236fda9279dSmrg	PUSH_DATA (push, 0x60000000 | (size << 16) | (subc << 13) | (mthd / 4));
237fda9279dSmrg}
238fda9279dSmrg
239fda9279dSmrgstatic inline void
240cd34e0e1SmrgIMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int data)
241fda9279dSmrg{
242fda9279dSmrg	PUSH_DATA (push, 0x80000000 | (data << 16) | (subc << 13) | (mthd / 4));
243fda9279dSmrg}
244fda9279dSmrg
245fda9279dSmrgstatic inline void
246fda9279dSmrgBEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
247fda9279dSmrg{
248fda9279dSmrg	PUSH_DATA (push, 0xa0000000 | (size << 16) | (subc << 13) | (mthd / 4));
249fda9279dSmrg}
250fda9279dSmrg
251fda9279dSmrg#define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd))
252fda9279dSmrg#define NV11_SUBC(subc, mthd) SUBC_##subc((NV11_SUBCHAN_##mthd))
253fda9279dSmrg#define NV84_SUBC(subc, mthd) SUBC_##subc((NV84_SUBCHAN_##mthd))
254fda9279dSmrg
255fda9279dSmrg#define NV04_GRAPH(subc, mthd) SUBC_##subc((NV04_GRAPH_##mthd))
256fda9279dSmrg#define NV50_GRAPH(subc, mthd) SUBC_##subc((NV50_GRAPH_##mthd))
257fda9279dSmrg#define NVC0_GRAPH(subc, mthd) SUBC_##subc((NVC0_GRAPH_##mthd))
258fda9279dSmrg
259fda9279dSmrg#endif
260