summaryrefslogtreecommitdiff
path: root/src/tseng_acl.c
blob: 9a62e4ec3a02c2657948a8cd98ab1bbeaba634d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c,v 1.25 2000/12/14 16:33:10 eich Exp $ */





#include "tseng.h"
#include "tseng_acl.h"
#include "compiler.h"

void tseng_terminate_acl(TsengPtr pTseng);

/*
 * conversion from X ROPs to Microsoft ROPs.
 */

int W32OpTable[] =
{
    0x00,			       /* Xclear             0 */
    0x88,			       /* Xand               src AND dst */
    0x44,			       /* XandReverse        src AND NOT dst */
    0xcc,			       /* Xcopy              src */
    0x22,			       /* XandInverted       NOT src AND dst */
    0xaa,			       /* Xnoop              dst */
    0x66,			       /* Xxor               src XOR dst */
    0xee,			       /* Xor                src OR dst */
    0x11,			       /* Xnor               NOT src AND NOT dst */
    0x99,			       /* Xequiv             NOT src XOR dst */
    0x55,			       /* Xinvert            NOT dst */
    0xdd,			       /* XorReverse         src OR NOT dst */
    0x33,			       /* XcopyInverted      NOT src */
    0xbb,			       /* XorInverted        NOT src OR dst */
    0x77,			       /* Xnand              NOT src OR NOT dst */
    0xff			       /* Xset               1 */
};

int W32OpTable_planemask[] =
{
    0x0a,			       /* Xclear             0 */
    0x8a,			       /* Xand               src AND dst */
    0x4a,			       /* XandReverse        src AND NOT dst */
    0xca,			       /* Xcopy              src */
    0x2a,			       /* XandInverted       NOT src AND dst */
    0xaa,			       /* Xnoop              dst */
    0x6a,			       /* Xxor               src XOR dst */
    0xea,			       /* Xor                src OR dst */
    0x1a,			       /* Xnor               NOT src AND NOT dst */
    0x9a,			       /* Xequiv             NOT src XOR dst */
    0x5a,			       /* Xinvert            NOT dst */
    0xda,			       /* XorReverse         src OR NOT dst */
    0x3a,			       /* XcopyInverted      NOT src */
    0xba,			       /* XorInverted        NOT src OR dst */
    0x7a,			       /* Xnand              NOT src OR NOT dst */
    0xfa			       /* Xset               1 */
};

int W32PatternOpTable[] =
{
    0x00,			       /* Xclear             0 */
    0xa0,			       /* Xand               pat AND dst */
    0x50,			       /* XandReverse        pat AND NOT dst */
    0xf0,			       /* Xcopy              pat */
    0x0a,			       /* XandInverted       NOT pat AND dst */
    0xaa,			       /* Xnoop              dst */
    0x5a,			       /* Xxor               pat XOR dst */
    0xfa,			       /* Xor                pat OR dst */
    0x05,			       /* Xnor               NOT pat AND NOT dst */
    0xa5,			       /* Xequiv             NOT pat XOR dst */
    0x55,			       /* Xinvert            NOT dst */
    0xf5,			       /* XorReverse         pat OR NOT dst */
    0x0f,			       /* XcopyInverted      NOT pat */
    0xaf,			       /* XorInverted        NOT pat OR dst */
    0x5f,			       /* Xnand              NOT pat OR NOT dst */
    0xff			       /* Xset               1 */
};



/**********************************************************************/

void 
tseng_terminate_acl(TsengPtr pTseng)
{
    /* only terminate when needed */
/*  if (*(volatile unsigned char *)ACL_ACCELERATOR_STATUS & 0x06) */
    {
	ACL_SUSPEND_TERMINATE(0x00);
	/* suspend any running operation */
	ACL_SUSPEND_TERMINATE(0x01);
	WAIT_ACL;
	ACL_SUSPEND_TERMINATE(0x00);
	/* ... and now terminate it */
	ACL_SUSPEND_TERMINATE(0x10);
	WAIT_ACL;
	ACL_SUSPEND_TERMINATE(0x00);
    }
}

void 
tseng_recover_timeout(TsengPtr pTseng)
{
    if (!Is_ET6K) {
	ErrorF("trying to unlock......................................\n");
	MMIO_OUT32(pTseng->tsengCPU2ACLBase,0,0L); /* try unlocking the bus when CPU-to-accel gets stuck */
    }
    if (Is_W32p) {		       /* flush the accelerator pipeline */
	ACL_SUSPEND_TERMINATE(0x00);
	ACL_SUSPEND_TERMINATE(0x02);
	ACL_SUSPEND_TERMINATE(0x00);
    }
}

void 
tseng_init_acl(ScrnInfoPtr pScrn)
{
    TsengPtr pTseng = TsengPTR(pScrn);

    PDEBUG("	tseng_init_acl\n");
    /*
     * prepare some shortcuts for faster access to memory mapped registers
     */

    if (pTseng->UseLinMem) {
	pTseng->scratchMemBase = pTseng->FbBase + pTseng->AccelColorBufferOffset;
	/* 
	 * we won't be using tsengCPU2ACLBase in linear memory mode anyway, since
	 * using the MMU apertures restricts the amount of useable video memory
	 * to only 2MB, supposing we ONLY redirect MMU aperture 2 to the CPU.
	 * (see data book W32p, page 207)
	 */
	pTseng->tsengCPU2ACLBase = pTseng->FbBase + 0x200000;	/* MMU aperture 2 */
    } else {
	/*
	 * MMU 0 is used for the scratchpad (i.e. FG and BG colors).
	 *
	 * MMU 1 is used for the Imagewrite buffers. This code assumes those
	 * buffers are back-to-back, with AccelImageWriteBufferOffsets[0]
	 * being the first, and don't exceed 8kb (aperture size) in total
	 * length.
	 */
	pTseng->scratchMemBase = pTseng->FbBase + 0x18000L;
	MMIO_OUT32(pTseng->MMioBase, 0x00<<0, pTseng->AccelColorBufferOffset);
	MMIO_OUT32(pTseng->MMioBase, 0x04<<0, pTseng->AccelImageWriteBufferOffsets[0]);
	/*
	 * tsengCPU2ACLBase is used for CPUtoSCreen...() operations on < ET6000 devices
	 */
	pTseng->tsengCPU2ACLBase = pTseng->FbBase + 0x1C000L;	/* MMU aperture 2 */
	/*      MMIO_IN32(pTseng->MMioBase, 0x08<<0) = 200000; *//* TEST */
    }
#ifdef DEBUG    
    ErrorF("MMioBase = 0x%x, scratchMemBase = 0x%x\n", pTseng->MMioBase, pTseng->scratchMemBase);
#endif

    /*
     * prepare the accelerator for some real work
     */

    tseng_terminate_acl(pTseng);

    ACL_INTERRUPT_STATUS(0xe);       /* clear interrupts */
    ACL_INTERRUPT_MASK(0x04);	       /* disable interrupts, but enable deadlock exit */
    ACL_INTERRUPT_STATUS(0x0);
    ACL_ACCELERATOR_STATUS_SET(0x0);

    if (Is_ET6K) {
	ACL_STEPPING_INHIBIT(0x0);   /* Undefined at power-on, let all maps (Src, Dst, Mix, Pat) step */
	ACL_6K_CONFIG(0x00);	       /* maximum performance -- what did you think? */
	ACL_POWER_CONTROL(0x01);     /* conserve power when ACL is idle */
	ACL_MIX_CONTROL(0x33);
	ACL_TRANSFER_DISABLE(0x00);  /* Undefined at power-on, enable all transfers */
    } else {			       /* W32i/W32p */
  	ACL_RELOAD_CONTROL(0x0); 
	ACL_SYNC_ENABLE(0x1);	       /* | 0x2 = 0WS ACL read. Yields up to 10% faster operation for small blits */
	ACL_ROUTING_CONTROL(0x00);
    }

    if (Is_W32p || Is_ET6K) {
	/* Enable the W32p startup bit and set use an eight-bit pixel depth */
	ACL_NQ_X_POSITION(0);
	ACL_NQ_Y_POSITION(0);
	ACL_PIXEL_DEPTH((pScrn->bitsPerPixel - 8) << 1);
	/* writing destination address will start ACL */
	ACL_OPERATION_STATE(0x10);
    } else {
	/* X, Y positions set to zero's for w32 and w32i */
	ACL_X_POSITION(0);
	ACL_Y_POSITION(0);
	ACL_OPERATION_STATE(0x0);
	/* if we ever use CPU-to-screen pixmap uploading on W32I or W32,
	 * ACL_VIRTUAL_BUS_SIZE will need to be made dynamic (i.e. moved to
	 * Setup() functions).
	 *
	 * VBS = 1 byte is faster than VBS = 4 bytes, since the ACL can
	 * start processing as soon as the first byte arrives.
	 */
	ACL_VIRTUAL_BUS_SIZE(0x00);
    }
    ACL_DESTINATION_Y_OFFSET(pScrn->displayWidth * pTseng->Bytesperpixel - 1);
    ACL_XY_DIRECTION(0);

    MMU_CONTROL(0x74);

    if (Is_W32p && pTseng->UseLinMem) {
	/*
	 * Since the w32p revs C and D don't have any memory mapped when the
	 * accelerator registers are used it is necessary to use the MMUs to
	 * provide a semblance of linear memory. Fortunately on these chips
	 * the MMU appertures are 1 megabyte each. So as long as we are
	 * willing to only use 3 megs of video memory we can have some
	 * acceleration. If we ever get the CPU-to-screen-color-expansion
	 * stuff working then we will NOT need to sacrifice the extra 1MB
	 * provided by MBP2, because we could do dynamic switching of the APT
	 * bit in the MMU control register.
	 *
	 * On W32p rev c and d MBP2 is hardwired to 0x200000 when linear
	 * memory mode is enabled. (On rev a it is programmable).
	 *
	 * W32p rev a and b have their first 2M mapped in the normal (non-MMU)
	 * way, and MMU0 and MMU1, each 512 kb wide, can be used to access
	 * another 1MB of memory. This totals to 3MB of mem. available in
	 * linear memory when the accelerator is enabled.
	 */
	if (Is_W32p_ab) {
	    MMIO_OUT32(pTseng->MMioBase, 0x00<<0, 0x200000L);
	    MMIO_OUT32(pTseng->MMioBase, 0x04<<0, 0x280000L);
	} else {		       /* rev C & D */
	    MMIO_OUT32(pTseng->MMioBase, 0x00<<0, 0x0L);
	    MMIO_OUT32 (pTseng->MMioBase, 0x04<<0, 0x100000L);
	}
    }
}