1/*
2	Copyright 1999, Be Incorporated.   All Rights Reserved.
3	This file may be used under the terms of the Be Sample Code License.
4
5	other authors:
6	Mark Watson
7	Rudolf Cornelissen 3/2004-3/2009
8*/
9
10/*
11	note:
12	attempting DMA on NV40 and higher because without it I can't get it going ATM.
13	Later on this can become a nv.settings switch, and maybe later we can even
14	forget about non-DMA completely (depends on 3D acceleration attempts).
15*/
16
17#define MODULE_BIT 0x10000000
18
19#include "acc_std.h"
20
21
22static engine_token nv_engine_token = { 1, B_2D_ACCELERATION, NULL };
23
24uint32 ACCELERANT_ENGINE_COUNT(void)
25{
26	/* we have one acceleration engine */
27	return 1;
28}
29
30status_t ACQUIRE_ENGINE_PIO(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et)
31{
32	/* acquire the shared benaphore */
33	AQUIRE_BEN(si->engine.lock)
34	/* sync if required */
35	if (st) SYNC_TO_TOKEN(st);
36
37	/* make sure all needed engine cmd's are mapped to the FIFO if acceleration isn't blocked */
38	if (!si->settings.block_acc) nv_acc_assert_fifo();
39
40	/* return an engine token */
41	*et = &nv_engine_token;
42	return B_OK;
43}
44
45status_t ACQUIRE_ENGINE_DMA(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et)
46{
47	/* acquire the shared benaphore */
48	AQUIRE_BEN(si->engine.lock)
49	/* sync if required */
50	if (st) SYNC_TO_TOKEN(st);
51
52	/* make sure all needed engine cmd's are mapped to the FIFO if acceleration isn't blocked */
53	if (!si->settings.block_acc) nv_acc_assert_fifo_dma();
54
55	/* return an engine token */
56	*et = &nv_engine_token;
57	return B_OK;
58}
59
60status_t RELEASE_ENGINE(engine_token *et, sync_token *st)
61{
62	/* update the sync token, if any */
63	if (st) GET_SYNC_TOKEN(et,st);
64
65	/* release the shared benaphore */
66	RELEASE_BEN(si->engine.lock)
67	return B_OK;
68}
69
70void WAIT_ENGINE_IDLE(void)
71{
72	/* do nothing if acceleration is te be blocked */
73	if (si->settings.block_acc) return;
74
75	/*wait for the engine to be totally idle*/
76	if (!si->settings.dma_acc)
77		nv_acc_wait_idle();
78	else
79		nv_acc_wait_idle_dma();
80}
81
82status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st)
83{
84	/* engine count will always be zero: we don't support syncing to token (yet) */
85	st->engine_id = et->engine_id;
86	st->counter = si->engine.count;
87	return B_OK;
88}
89
90status_t SYNC_TO_TOKEN(sync_token *st)
91{
92	/* wait until the engine is totally idle: we don't support syncing to token (yet) */
93	/* note:
94	 * AFAIK in order to be able to setup sync_to_token, we'd need a circular fifo
95	 * buffer in (main) memory instead of directly programming the GPU fifo so we
96	 * can tell (via a hardware maintained pointer into this circular fifo) where
97	 * the acc engine is with executing commands! */
98	WAIT_ENGINE_IDLE();
99
100	return B_OK;
101}
102