1/*
2 * Copyright 2007 Stephane Marchesin
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "drmP.h"
26#include "drm.h"
27#include "nouveau_drm.h"
28#include "nouveau_drv.h"
29
30static uint32_t nv04_graph_ctx_regs [] = {
31	NV04_PGRAPH_CTX_SWITCH1,
32	NV04_PGRAPH_CTX_SWITCH2,
33	NV04_PGRAPH_CTX_SWITCH3,
34	NV04_PGRAPH_CTX_SWITCH4,
35	NV04_PGRAPH_CTX_CACHE1,
36	NV04_PGRAPH_CTX_CACHE2,
37	NV04_PGRAPH_CTX_CACHE3,
38	NV04_PGRAPH_CTX_CACHE4,
39	0x00400184,
40	0x004001a4,
41	0x004001c4,
42	0x004001e4,
43	0x00400188,
44	0x004001a8,
45	0x004001c8,
46	0x004001e8,
47	0x0040018c,
48	0x004001ac,
49	0x004001cc,
50	0x004001ec,
51	0x00400190,
52	0x004001b0,
53	0x004001d0,
54	0x004001f0,
55	0x00400194,
56	0x004001b4,
57	0x004001d4,
58	0x004001f4,
59	0x00400198,
60	0x004001b8,
61	0x004001d8,
62	0x004001f8,
63	0x0040019c,
64	0x004001bc,
65	0x004001dc,
66	0x004001fc,
67	0x00400174,
68	NV04_PGRAPH_DMA_START_0,
69	NV04_PGRAPH_DMA_START_1,
70	NV04_PGRAPH_DMA_LENGTH,
71	NV04_PGRAPH_DMA_MISC,
72	NV04_PGRAPH_DMA_PITCH,
73	NV04_PGRAPH_BOFFSET0,
74	NV04_PGRAPH_BBASE0,
75	NV04_PGRAPH_BLIMIT0,
76	NV04_PGRAPH_BOFFSET1,
77	NV04_PGRAPH_BBASE1,
78	NV04_PGRAPH_BLIMIT1,
79	NV04_PGRAPH_BOFFSET2,
80	NV04_PGRAPH_BBASE2,
81	NV04_PGRAPH_BLIMIT2,
82	NV04_PGRAPH_BOFFSET3,
83	NV04_PGRAPH_BBASE3,
84	NV04_PGRAPH_BLIMIT3,
85	NV04_PGRAPH_BOFFSET4,
86	NV04_PGRAPH_BBASE4,
87	NV04_PGRAPH_BLIMIT4,
88	NV04_PGRAPH_BOFFSET5,
89	NV04_PGRAPH_BBASE5,
90	NV04_PGRAPH_BLIMIT5,
91	NV04_PGRAPH_BPITCH0,
92	NV04_PGRAPH_BPITCH1,
93	NV04_PGRAPH_BPITCH2,
94	NV04_PGRAPH_BPITCH3,
95	NV04_PGRAPH_BPITCH4,
96	NV04_PGRAPH_SURFACE,
97	NV04_PGRAPH_STATE,
98	NV04_PGRAPH_BSWIZZLE2,
99	NV04_PGRAPH_BSWIZZLE5,
100	NV04_PGRAPH_BPIXEL,
101	NV04_PGRAPH_NOTIFY,
102	NV04_PGRAPH_PATT_COLOR0,
103	NV04_PGRAPH_PATT_COLOR1,
104	NV04_PGRAPH_PATT_COLORRAM+0x00,
105	NV04_PGRAPH_PATT_COLORRAM+0x01,
106	NV04_PGRAPH_PATT_COLORRAM+0x02,
107	NV04_PGRAPH_PATT_COLORRAM+0x03,
108	NV04_PGRAPH_PATT_COLORRAM+0x04,
109	NV04_PGRAPH_PATT_COLORRAM+0x05,
110	NV04_PGRAPH_PATT_COLORRAM+0x06,
111	NV04_PGRAPH_PATT_COLORRAM+0x07,
112	NV04_PGRAPH_PATT_COLORRAM+0x08,
113	NV04_PGRAPH_PATT_COLORRAM+0x09,
114	NV04_PGRAPH_PATT_COLORRAM+0x0A,
115	NV04_PGRAPH_PATT_COLORRAM+0x0B,
116	NV04_PGRAPH_PATT_COLORRAM+0x0C,
117	NV04_PGRAPH_PATT_COLORRAM+0x0D,
118	NV04_PGRAPH_PATT_COLORRAM+0x0E,
119	NV04_PGRAPH_PATT_COLORRAM+0x0F,
120	NV04_PGRAPH_PATT_COLORRAM+0x10,
121	NV04_PGRAPH_PATT_COLORRAM+0x11,
122	NV04_PGRAPH_PATT_COLORRAM+0x12,
123	NV04_PGRAPH_PATT_COLORRAM+0x13,
124	NV04_PGRAPH_PATT_COLORRAM+0x14,
125	NV04_PGRAPH_PATT_COLORRAM+0x15,
126	NV04_PGRAPH_PATT_COLORRAM+0x16,
127	NV04_PGRAPH_PATT_COLORRAM+0x17,
128	NV04_PGRAPH_PATT_COLORRAM+0x18,
129	NV04_PGRAPH_PATT_COLORRAM+0x19,
130	NV04_PGRAPH_PATT_COLORRAM+0x1A,
131	NV04_PGRAPH_PATT_COLORRAM+0x1B,
132	NV04_PGRAPH_PATT_COLORRAM+0x1C,
133	NV04_PGRAPH_PATT_COLORRAM+0x1D,
134	NV04_PGRAPH_PATT_COLORRAM+0x1E,
135	NV04_PGRAPH_PATT_COLORRAM+0x1F,
136	NV04_PGRAPH_PATT_COLORRAM+0x20,
137	NV04_PGRAPH_PATT_COLORRAM+0x21,
138	NV04_PGRAPH_PATT_COLORRAM+0x22,
139	NV04_PGRAPH_PATT_COLORRAM+0x23,
140	NV04_PGRAPH_PATT_COLORRAM+0x24,
141	NV04_PGRAPH_PATT_COLORRAM+0x25,
142	NV04_PGRAPH_PATT_COLORRAM+0x26,
143	NV04_PGRAPH_PATT_COLORRAM+0x27,
144	NV04_PGRAPH_PATT_COLORRAM+0x28,
145	NV04_PGRAPH_PATT_COLORRAM+0x29,
146	NV04_PGRAPH_PATT_COLORRAM+0x2A,
147	NV04_PGRAPH_PATT_COLORRAM+0x2B,
148	NV04_PGRAPH_PATT_COLORRAM+0x2C,
149	NV04_PGRAPH_PATT_COLORRAM+0x2D,
150	NV04_PGRAPH_PATT_COLORRAM+0x2E,
151	NV04_PGRAPH_PATT_COLORRAM+0x2F,
152	NV04_PGRAPH_PATT_COLORRAM+0x30,
153	NV04_PGRAPH_PATT_COLORRAM+0x31,
154	NV04_PGRAPH_PATT_COLORRAM+0x32,
155	NV04_PGRAPH_PATT_COLORRAM+0x33,
156	NV04_PGRAPH_PATT_COLORRAM+0x34,
157	NV04_PGRAPH_PATT_COLORRAM+0x35,
158	NV04_PGRAPH_PATT_COLORRAM+0x36,
159	NV04_PGRAPH_PATT_COLORRAM+0x37,
160	NV04_PGRAPH_PATT_COLORRAM+0x38,
161	NV04_PGRAPH_PATT_COLORRAM+0x39,
162	NV04_PGRAPH_PATT_COLORRAM+0x3A,
163	NV04_PGRAPH_PATT_COLORRAM+0x3B,
164	NV04_PGRAPH_PATT_COLORRAM+0x3C,
165	NV04_PGRAPH_PATT_COLORRAM+0x3D,
166	NV04_PGRAPH_PATT_COLORRAM+0x3E,
167	NV04_PGRAPH_PATT_COLORRAM+0x3F,
168	NV04_PGRAPH_PATTERN,
169	0x0040080c,
170	NV04_PGRAPH_PATTERN_SHAPE,
171	0x00400600,
172	NV04_PGRAPH_ROP3,
173	NV04_PGRAPH_CHROMA,
174	NV04_PGRAPH_BETA_AND,
175	NV04_PGRAPH_BETA_PREMULT,
176	NV04_PGRAPH_CONTROL0,
177	NV04_PGRAPH_CONTROL1,
178	NV04_PGRAPH_CONTROL2,
179	NV04_PGRAPH_BLEND,
180	NV04_PGRAPH_STORED_FMT,
181	NV04_PGRAPH_SOURCE_COLOR,
182	0x00400560,
183	0x00400568,
184	0x00400564,
185	0x0040056c,
186	0x00400400,
187	0x00400480,
188	0x00400404,
189	0x00400484,
190	0x00400408,
191	0x00400488,
192	0x0040040c,
193	0x0040048c,
194	0x00400410,
195	0x00400490,
196	0x00400414,
197	0x00400494,
198	0x00400418,
199	0x00400498,
200	0x0040041c,
201	0x0040049c,
202	0x00400420,
203	0x004004a0,
204	0x00400424,
205	0x004004a4,
206	0x00400428,
207	0x004004a8,
208	0x0040042c,
209	0x004004ac,
210	0x00400430,
211	0x004004b0,
212	0x00400434,
213	0x004004b4,
214	0x00400438,
215	0x004004b8,
216	0x0040043c,
217	0x004004bc,
218	0x00400440,
219	0x004004c0,
220	0x00400444,
221	0x004004c4,
222	0x00400448,
223	0x004004c8,
224	0x0040044c,
225	0x004004cc,
226	0x00400450,
227	0x004004d0,
228	0x00400454,
229	0x004004d4,
230	0x00400458,
231	0x004004d8,
232	0x0040045c,
233	0x004004dc,
234	0x00400460,
235	0x004004e0,
236	0x00400464,
237	0x004004e4,
238	0x00400468,
239	0x004004e8,
240	0x0040046c,
241	0x004004ec,
242	0x00400470,
243	0x004004f0,
244	0x00400474,
245	0x004004f4,
246	0x00400478,
247	0x004004f8,
248	0x0040047c,
249	0x004004fc,
250	0x0040053c,
251	0x00400544,
252	0x00400540,
253	0x00400548,
254	0x00400560,
255	0x00400568,
256	0x00400564,
257	0x0040056c,
258	0x00400534,
259	0x00400538,
260	0x00400514,
261	0x00400518,
262	0x0040051c,
263	0x00400520,
264	0x00400524,
265	0x00400528,
266	0x0040052c,
267	0x00400530,
268	0x00400d00,
269	0x00400d40,
270	0x00400d80,
271	0x00400d04,
272	0x00400d44,
273	0x00400d84,
274	0x00400d08,
275	0x00400d48,
276	0x00400d88,
277	0x00400d0c,
278	0x00400d4c,
279	0x00400d8c,
280	0x00400d10,
281	0x00400d50,
282	0x00400d90,
283	0x00400d14,
284	0x00400d54,
285	0x00400d94,
286	0x00400d18,
287	0x00400d58,
288	0x00400d98,
289	0x00400d1c,
290	0x00400d5c,
291	0x00400d9c,
292	0x00400d20,
293	0x00400d60,
294	0x00400da0,
295	0x00400d24,
296	0x00400d64,
297	0x00400da4,
298	0x00400d28,
299	0x00400d68,
300	0x00400da8,
301	0x00400d2c,
302	0x00400d6c,
303	0x00400dac,
304	0x00400d30,
305	0x00400d70,
306	0x00400db0,
307	0x00400d34,
308	0x00400d74,
309	0x00400db4,
310	0x00400d38,
311	0x00400d78,
312	0x00400db8,
313	0x00400d3c,
314	0x00400d7c,
315	0x00400dbc,
316	0x00400590,
317	0x00400594,
318	0x00400598,
319	0x0040059c,
320	0x004005a8,
321	0x004005ac,
322	0x004005b0,
323	0x004005b4,
324	0x004005c0,
325	0x004005c4,
326	0x004005c8,
327	0x004005cc,
328	0x004005d0,
329	0x004005d4,
330	0x004005d8,
331	0x004005dc,
332	0x004005e0,
333	NV04_PGRAPH_PASSTHRU_0,
334	NV04_PGRAPH_PASSTHRU_1,
335	NV04_PGRAPH_PASSTHRU_2,
336	NV04_PGRAPH_DVD_COLORFMT,
337	NV04_PGRAPH_SCALED_FORMAT,
338	NV04_PGRAPH_MISC24_0,
339	NV04_PGRAPH_MISC24_1,
340	NV04_PGRAPH_MISC24_2,
341	0x00400500,
342	0x00400504,
343	NV04_PGRAPH_VALID1,
344	NV04_PGRAPH_VALID2
345
346
347};
348
349struct graph_state {
350	int nv04[sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0])];
351};
352
353void nouveau_nv04_context_switch(struct drm_device *dev)
354{
355	struct drm_nouveau_private *dev_priv = dev->dev_private;
356	struct nouveau_engine *engine = &dev_priv->Engine;
357	struct nouveau_channel *next, *last;
358	int chid;
359
360	if (!dev) {
361		DRM_DEBUG("Invalid drm_device\n");
362		return;
363	}
364	dev_priv = dev->dev_private;
365	if (!dev_priv) {
366		DRM_DEBUG("Invalid drm_nouveau_private\n");
367		return;
368	}
369	if (!dev_priv->fifos) {
370		DRM_DEBUG("Invalid drm_nouveau_private->fifos\n");
371		return;
372	}
373
374	chid = engine->fifo.channel_id(dev);
375	next = dev_priv->fifos[chid];
376
377	if (!next) {
378		DRM_DEBUG("Invalid next channel\n");
379		return;
380	}
381
382	chid = (NV_READ(NV04_PGRAPH_CTX_USER) >> 24) & (engine->fifo.channels - 1);
383	last = dev_priv->fifos[chid];
384
385	if (!last) {
386		DRM_DEBUG("WARNING: Invalid last channel, switch to %x\n",
387		          next->id);
388	} else {
389		DRM_INFO("NV: PGRAPH context switch interrupt channel %x -> %x\n",
390		         last->id, next->id);
391	}
392
393/*	NV_WRITE(NV03_PFIFO_CACHES, 0x0);
394	NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0);
395	NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x0);*/
396	NV_WRITE(NV04_PGRAPH_FIFO,0x0);
397
398	if (last)
399		nv04_graph_save_context(last);
400
401	nouveau_wait_for_idle(dev);
402
403	NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10000000);
404	NV_WRITE(NV04_PGRAPH_CTX_USER, (NV_READ(NV04_PGRAPH_CTX_USER) & 0xffffff) | (0x0f << 24));
405
406	nouveau_wait_for_idle(dev);
407
408	nv04_graph_load_context(next);
409
410	NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
411	NV_WRITE(NV04_PGRAPH_CTX_USER, next->id << 24);
412	NV_WRITE(NV04_PGRAPH_FFINTFC_ST2, NV_READ(NV04_PGRAPH_FFINTFC_ST2)&0x000FFFFF);
413
414/*	NV_WRITE(NV04_PGRAPH_FIFO,0x0);
415	NV_WRITE(NV04_PFIFO_CACHE0_PULL0, 0x0);
416	NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x1);
417	NV_WRITE(NV03_PFIFO_CACHES, 0x1);*/
418	NV_WRITE(NV04_PGRAPH_FIFO,0x1);
419}
420
421int nv04_graph_create_context(struct nouveau_channel *chan) {
422	struct graph_state* pgraph_ctx;
423	DRM_DEBUG("nv04_graph_context_create %d\n", chan->id);
424
425	chan->pgraph_ctx = pgraph_ctx = drm_calloc(1, sizeof(*pgraph_ctx),
426					      DRM_MEM_DRIVER);
427
428	if (pgraph_ctx == NULL)
429		return -ENOMEM;
430
431	//dev_priv->fifos[channel].pgraph_ctx_user = channel << 24;
432	pgraph_ctx->nv04[0] = 0x0001ffff;
433	/* is it really needed ??? */
434	//dev_priv->fifos[channel].pgraph_ctx[1] = NV_READ(NV_PGRAPH_DEBUG_4);
435	//dev_priv->fifos[channel].pgraph_ctx[2] = NV_READ(0x004006b0);
436
437	return 0;
438}
439
440void nv04_graph_destroy_context(struct nouveau_channel *chan)
441{
442	struct graph_state* pgraph_ctx = chan->pgraph_ctx;
443
444	drm_free(pgraph_ctx, sizeof(*pgraph_ctx), DRM_MEM_DRIVER);
445	chan->pgraph_ctx = NULL;
446}
447
448int nv04_graph_load_context(struct nouveau_channel *chan)
449{
450	struct drm_device *dev = chan->dev;
451	struct drm_nouveau_private *dev_priv = dev->dev_private;
452	struct graph_state* pgraph_ctx = chan->pgraph_ctx;
453	int i;
454
455	for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++)
456		NV_WRITE(nv04_graph_ctx_regs[i], pgraph_ctx->nv04[i]);
457
458	return 0;
459}
460
461int nv04_graph_save_context(struct nouveau_channel *chan)
462{
463	struct drm_device *dev = chan->dev;
464	struct drm_nouveau_private *dev_priv = dev->dev_private;
465	struct graph_state* pgraph_ctx = chan->pgraph_ctx;
466	int i;
467
468	for (i = 0; i < sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++)
469		pgraph_ctx->nv04[i] = NV_READ(nv04_graph_ctx_regs[i]);
470
471	return 0;
472}
473
474int nv04_graph_init(struct drm_device *dev) {
475	struct drm_nouveau_private *dev_priv = dev->dev_private;
476
477	NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
478			~NV_PMC_ENABLE_PGRAPH);
479	NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
480			 NV_PMC_ENABLE_PGRAPH);
481
482	/* Enable PGRAPH interrupts */
483	NV_WRITE(NV03_PGRAPH_INTR, 0xFFFFFFFF);
484	NV_WRITE(NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
485
486	NV_WRITE(NV04_PGRAPH_VALID1, 0);
487	NV_WRITE(NV04_PGRAPH_VALID2, 0);
488	/*NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x000001FF);
489	NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
490	NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x1231c000);
491	/*1231C000 blob, 001 haiku*/
492	//*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
493	NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x72111100);
494	/*0x72111100 blob , 01 haiku*/
495	/*NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
496	NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11d5f071);
497	/*haiku same*/
498
499	/*NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
500	NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
501	/*haiku and blob 10d4*/
502
503	NV_WRITE(NV04_PGRAPH_STATE        , 0xFFFFFFFF);
504	NV_WRITE(NV04_PGRAPH_CTX_CONTROL  , 0x10010100);
505	NV_WRITE(NV04_PGRAPH_FIFO         , 0x00000001);
506
507	/* These don't belong here, they're part of a per-channel context */
508	NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
509	NV_WRITE(NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
510
511	return 0;
512}
513
514void nv04_graph_takedown(struct drm_device *dev)
515{
516}
517