1/*
2 * Created 1998 by David Bateman <dbateman@eng.uts.edu.au>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  The authors makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27/*
28 * The functions in this file are used to read/write the C&T extension register
29 * and supply MMIO replacements of the VGA register access functions in
30 * vgaHW.c for chips that support MMIO access (eg 69000). Unlike the MGA
31 * chips, for instance, the C&T chipsets don't have a direct mapping between
32 * the MMIO mapped vga registers and the PIO versions.
33 *
34 * In General, these are the ONLY supported way of access the video processors
35 * registers. Exception are
36 *
37 * 1) chipsFindIsaDevice, where we don't know the chipset and so we don't know
38 *    if the chipset supports MMIO access to its VGA registers, and we don't
39 *    know the chips MemBase address and so can't map the VGA registers even
40 *    if the chip did support MMIO. This effectively limits the use of non-PCI
41 *    MMIO and multihead to a single card accessing 0x3D6/0x3D7. I.E. You can
42 *    only have a single C&T card in a non-PCI multihead arrangement. Also as
43 *    ISA has no method to disable I/O access to a card ISA multihead will
44 *    never be supported.
45 *
46 * 2) ct_Blitter.h, ct_BlitMM.h and ct_BltHiQV.h, where speed is crucial and
47 *    we know exactly whether we are using MMIO or PIO.
48 *
49 * 3) The 6554x 32bit DRxx in ct_cursor.c where the choice between MMIO and
50 *    PIO is made explicitly
51 */
52
53
54/* All drivers should typically include these */
55#include "xf86.h"
56#include "xf86_OSproc.h"
57
58/* Everything using inb/outb, etc needs "compiler.h" */
59#include "compiler.h"
60
61/* Drivers that need to access the PCI config space directly need this */
62#include "xf86Pci.h"
63
64/* Driver specific headers */
65#include "ct_driver.h"
66
67#define CHIPS_MONO_STAT_1		0x3BA
68#define CHIPS_STAT_0			0x3BA
69#define CHIPS_MSS			0x3CB
70#define CHIPS_IOSS			0x3CD
71#define CHIPS_FR_INDEX			0x3D0
72#define CHIPS_FR_DATA			0x3D1
73#define CHIPS_MR_INDEX			0x3D2
74#define CHIPS_MR_DATA			0x3D3
75#define CHIPS_XR_INDEX			0x3D6
76#define CHIPS_XR_DATA			0x3D7
77#define CHIPS_COLOR_STAT_1		0x3DA
78
79#define CHIPS_MMIO_MONO_CRTC_INDEX	0x768
80#define CHIPS_MMIO_MONO_CRTC_DATA	0x769
81#define CHIPS_MMIO_MONO_STAT_1		0x774
82#define CHIPS_MMIO_ATTR_INDEX		0x780
83#define CHIPS_MMIO_ATTR_DATA_W		0x780
84#define CHIPS_MMIO_ATTR_DATA_R		0x781
85#define CHIPS_MMIO_STAT_0		0x784
86#define CHIPS_MMIO_MISC_OUT_W		0x784
87#define CHIPS_MMIO_SEQ_INDEX		0x788
88#define CHIPS_MMIO_SEQ_DATA		0x789
89#define CHIPS_MMIO_DAC_MASK		0x78C
90#define CHIPS_MMIO_DAC_READ_ADDR	0x78D
91#define CHIPS_MMIO_DAC_WRITE_ADDR	0x790
92#define CHIPS_MMIO_DAC_DATA		0x791
93#define CHIPS_MMIO_FEATURE_R		0x794
94#define CHIPS_MMIO_MSS			0x795
95#define CHIPS_MMIO_MISC_OUT_R		0x798
96#define CHIPS_MMIO_IOSS			0x799
97#define CHIPS_MMIO_GRAPH_INDEX		0x79C
98#define CHIPS_MMIO_GRAPH_DATA		0x79D
99#define CHIPS_MMIO_FR_INDEX		0x7A0
100#define CHIPS_MMIO_FR_DATA		0x7A1
101#define CHIPS_MMIO_MR_INDEX		0x7A4
102#define CHIPS_MMIO_MR_DATA		0x7A5
103#define CHIPS_MMIO_COLOR_CRTC_INDEX	0x7A8
104#define CHIPS_MMIO_COLOR_CRTC_DATA	0x7A9
105#define CHIPS_MMIO_XR_INDEX		0x7AC
106#define CHIPS_MMIO_XR_DATA		0x7AD
107#define CHIPS_MMIO_COLOR_STAT_1		0x7B4
108
109/*
110 * PIO Access to the C&T extension registers
111 */
112static void
113chipsStdWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
114{
115    outb(cPtr->PIOBase + CHIPS_XR_INDEX, index);
116    outb(cPtr->PIOBase + CHIPS_XR_DATA, value);
117}
118
119static CARD8
120chipsStdReadXR(CHIPSPtr cPtr, CARD8 index)
121{
122    outb(cPtr->PIOBase + CHIPS_XR_INDEX, index);
123    return inb(cPtr->PIOBase + CHIPS_XR_DATA);
124}
125
126static void
127chipsStdWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
128{
129    outb(cPtr->PIOBase + CHIPS_FR_INDEX, index);
130    outb(cPtr->PIOBase + CHIPS_FR_DATA, value);
131}
132
133static CARD8
134chipsStdReadFR(CHIPSPtr cPtr, CARD8 index)
135{
136    outb(cPtr->PIOBase + CHIPS_FR_INDEX, index);
137    return inb(cPtr->PIOBase + CHIPS_FR_DATA);
138}
139
140static void
141chipsStdWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
142{
143    outb(cPtr->PIOBase + CHIPS_MR_INDEX, index);
144    outb(cPtr->PIOBase + CHIPS_MR_DATA, value);
145}
146
147static CARD8
148chipsStdReadMR(CHIPSPtr cPtr, CARD8 index)
149{
150    outb(cPtr->PIOBase + CHIPS_MR_INDEX, index);
151    return inb(cPtr->PIOBase + CHIPS_MR_DATA);
152}
153
154static void
155chipsStdWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value)
156{
157    outb(cPtr->PIOBase + CHIPS_MSS, value);
158}
159
160static CARD8
161chipsStdReadMSS(CHIPSPtr cPtr)
162{
163    return inb(cPtr->PIOBase + CHIPS_MSS);
164}
165
166static void
167chipsStdWriteIOSS(CHIPSPtr cPtr, CARD8 value)
168{
169    outb(cPtr->PIOBase + CHIPS_IOSS, value);
170}
171
172static CARD8
173chipsStdReadIOSS(CHIPSPtr cPtr)
174{
175    return inb(cPtr->PIOBase + CHIPS_IOSS);
176}
177
178void
179CHIPSSetStdExtFuncs(CHIPSPtr cPtr)
180{
181    cPtr->writeFR		= chipsStdWriteFR;
182    cPtr->readFR		= chipsStdReadFR;
183    cPtr->writeMR		= chipsStdWriteMR;
184    cPtr->readMR		= chipsStdReadMR;
185    cPtr->writeXR		= chipsStdWriteXR;
186    cPtr->readXR		= chipsStdReadXR;
187    cPtr->writeMSS		= chipsStdWriteMSS;
188    cPtr->readMSS		= chipsStdReadMSS;
189    cPtr->writeIOSS		= chipsStdWriteIOSS;
190    cPtr->readIOSS		= chipsStdReadIOSS;
191}
192
193/*
194 * MMIO Access to the C&T extension registers
195 */
196
197#define chipsminb(p) MMIO_IN8(cPtr->MMIOBaseVGA, (p))
198#define chipsmoutb(p,v) MMIO_OUT8(cPtr->MMIOBaseVGA, (p),(v))
199
200static void
201chipsMmioWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
202{
203    chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
204    chipsmoutb(CHIPS_MMIO_XR_DATA, value);
205}
206
207static CARD8
208chipsMmioReadXR(CHIPSPtr cPtr, CARD8 index)
209{
210    chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
211    return chipsminb(CHIPS_MMIO_XR_DATA);
212}
213
214static void
215chipsMmioWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
216{
217    chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
218    chipsmoutb(CHIPS_MMIO_FR_DATA, value);
219}
220
221static CARD8
222chipsMmioReadFR(CHIPSPtr cPtr, CARD8 index)
223{
224    chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
225    return chipsminb(CHIPS_MMIO_FR_DATA);
226}
227
228static void
229chipsMmioWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
230{
231    chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
232    chipsmoutb(CHIPS_MMIO_MR_DATA, value);
233}
234
235static CARD8
236chipsMmioReadMR(CHIPSPtr cPtr, CARD8 index)
237{
238    chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
239    return chipsminb(CHIPS_MMIO_MR_DATA);
240}
241
242static void
243chipsMmioWriteMSS(CHIPSPtr cPtr, vgaHWPtr hwp, CARD8 value)
244{
245    /* 69030 MMIO Fix.
246     *
247     * <value> determines which MMIOBase to use; either
248     * Pipe A or Pipe B. -GHB
249     */
250    if ((value & MSS_SHADOW) == MSS_PIPE_B)
251	cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeB;
252    else
253	cPtr->MMIOBaseVGA = cPtr->MMIOBasePipeA;
254
255    hwp->MMIOBase = cPtr->MMIOBaseVGA;
256
257    /* Since our Pipe constants don't set bit 3 of MSS, the value
258     * written here has no effect on the hardware's behavior. It
259     * does allow us to use the value returned by readMSS() to key
260     * the above logic, though. -GHB
261     */
262    chipsmoutb(CHIPS_MMIO_MSS, value);
263}
264
265static CARD8
266chipsMmioReadMSS(CHIPSPtr cPtr)
267{
268    return chipsminb(CHIPS_MMIO_MSS);
269}
270
271static void
272chipsMmioWriteIOSS(CHIPSPtr cPtr, CARD8 value)
273{
274    chipsmoutb(CHIPS_MMIO_IOSS, value);
275}
276
277static CARD8
278chipsMmioReadIOSS(CHIPSPtr cPtr)
279{
280    return chipsminb(CHIPS_MMIO_IOSS);
281}
282
283void
284CHIPSSetMmioExtFuncs(CHIPSPtr cPtr)
285{
286    cPtr->writeFR		= chipsMmioWriteFR;
287    cPtr->readFR		= chipsMmioReadFR;
288    cPtr->writeMR		= chipsMmioWriteMR;
289    cPtr->readMR		= chipsMmioReadMR;
290    cPtr->writeXR		= chipsMmioWriteXR;
291    cPtr->readXR		= chipsMmioReadXR;
292    cPtr->writeMSS		= chipsMmioWriteMSS;
293    cPtr->readMSS		= chipsMmioReadMSS;
294    cPtr->writeIOSS		= chipsMmioWriteIOSS;
295    cPtr->readIOSS		= chipsMmioReadIOSS;
296}
297
298/*
299 * MMIO versions of the VGA register access functions.
300 */
301
302#define minb(p) MMIO_IN8(hwp->MMIOBase, (p))
303#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (p),(v))
304
305static void
306chipsMmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
307{
308    if (hwp->IOBase == VGA_IOBASE_MONO) {
309	moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
310    	moutb(CHIPS_MMIO_MONO_CRTC_DATA, value);
311    } else {
312	moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
313    	moutb(CHIPS_MMIO_COLOR_CRTC_DATA, value);
314    }
315}
316
317static CARD8
318chipsMmioReadCrtc(vgaHWPtr hwp, CARD8 index)
319{
320    if (hwp->IOBase == VGA_IOBASE_MONO) {
321	moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
322    	return minb(CHIPS_MMIO_MONO_CRTC_DATA);
323    } else {
324	moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
325    	return minb(CHIPS_MMIO_COLOR_CRTC_DATA);
326    }
327}
328
329static void
330chipsMmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
331{
332    moutb(CHIPS_MMIO_GRAPH_INDEX, index);
333    moutb(CHIPS_MMIO_GRAPH_DATA, value);
334}
335
336static CARD8
337chipsMmioReadGr(vgaHWPtr hwp, CARD8 index)
338{
339    moutb(CHIPS_MMIO_GRAPH_INDEX, index);
340    return minb(CHIPS_MMIO_GRAPH_DATA);
341}
342
343static void
344chipsMmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
345{
346    moutb(CHIPS_MMIO_SEQ_INDEX, index);
347    moutb(CHIPS_MMIO_SEQ_DATA, value);
348}
349
350static CARD8
351chipsMmioReadSeq(vgaHWPtr hwp, CARD8 index)
352{
353    moutb(CHIPS_MMIO_SEQ_INDEX, index);
354    return minb(CHIPS_MMIO_SEQ_DATA);
355}
356
357static void
358chipsMmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
359{
360    if (hwp->paletteEnabled)
361	index &= ~0x20;
362    else
363	index |= 0x20;
364
365    if (hwp->IOBase == VGA_IOBASE_MONO)
366	(void) minb(CHIPS_MMIO_MONO_STAT_1);
367    else
368	(void) minb(CHIPS_MMIO_COLOR_STAT_1);
369    moutb(CHIPS_MMIO_ATTR_INDEX, index);
370    moutb(CHIPS_MMIO_ATTR_DATA_W, value);
371}
372
373static CARD8
374chipsMmioReadAttr(vgaHWPtr hwp, CARD8 index)
375{
376    if (hwp->paletteEnabled)
377	index &= ~0x20;
378    else
379	index |= 0x20;
380
381    if (hwp->IOBase == VGA_IOBASE_MONO)
382	(void) minb(CHIPS_MMIO_MONO_STAT_1);
383    else
384	(void) minb(CHIPS_MMIO_COLOR_STAT_1);
385    moutb(CHIPS_MMIO_ATTR_INDEX, index);
386    return minb(CHIPS_MMIO_ATTR_DATA_R);
387}
388
389static void
390chipsMmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
391{
392    moutb(CHIPS_MMIO_MISC_OUT_W, value);
393}
394
395static CARD8
396chipsMmioReadMiscOut(vgaHWPtr hwp)
397{
398    return minb(CHIPS_MMIO_MISC_OUT_R);
399}
400
401static void
402chipsMmioEnablePalette(vgaHWPtr hwp)
403{
404    if (hwp->IOBase == VGA_IOBASE_MONO)
405	(void) minb(CHIPS_MMIO_MONO_STAT_1);
406    else
407	(void) minb(CHIPS_MMIO_COLOR_STAT_1);
408    moutb(CHIPS_MMIO_ATTR_INDEX, 0x00);
409    hwp->paletteEnabled = TRUE;
410}
411
412static void
413chipsMmioDisablePalette(vgaHWPtr hwp)
414{
415    if (hwp->IOBase == VGA_IOBASE_MONO)
416	(void) minb(CHIPS_MMIO_MONO_STAT_1);
417    else
418	(void) minb(CHIPS_MMIO_COLOR_STAT_1);
419    moutb(CHIPS_MMIO_ATTR_INDEX, 0x20);
420    hwp->paletteEnabled = FALSE;
421}
422
423static void
424chipsMmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
425{
426    moutb(CHIPS_MMIO_DAC_MASK, value);
427}
428
429static CARD8
430chipsMmioReadDacMask(vgaHWPtr hwp)
431{
432    return minb(CHIPS_MMIO_DAC_MASK);
433}
434
435static void
436chipsMmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
437{
438    moutb(CHIPS_MMIO_DAC_READ_ADDR, value);
439}
440
441static void
442chipsMmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
443{
444    moutb(CHIPS_MMIO_DAC_WRITE_ADDR, value);
445}
446
447static void
448chipsMmioWriteDacData(vgaHWPtr hwp, CARD8 value)
449{
450    moutb(CHIPS_MMIO_DAC_DATA, value);
451}
452
453static CARD8
454chipsMmioReadDacData(vgaHWPtr hwp)
455{
456    return minb(CHIPS_MMIO_DAC_DATA);
457}
458
459static CARD8
460chipsMmioReadST00(vgaHWPtr hwp)
461{
462    return minb(CHIPS_MMIO_STAT_0);
463}
464
465static CARD8
466chipsMmioReadST01(vgaHWPtr hwp)
467{
468    if (hwp->IOBase == VGA_IOBASE_MONO)
469	return minb(CHIPS_MMIO_MONO_STAT_1);
470    else
471	return minb(CHIPS_MMIO_COLOR_STAT_1);
472}
473
474static CARD8
475chipsMmioReadFCR(vgaHWPtr hwp)
476{
477    return minb(CHIPS_MMIO_FEATURE_R);
478}
479
480static void
481chipsMmioWriteFCR(vgaHWPtr hwp, CARD8 value)
482{
483    if (hwp->IOBase == VGA_IOBASE_MONO) {
484    	moutb(CHIPS_MMIO_MONO_STAT_1, value);
485    } else {
486    	moutb(CHIPS_MMIO_COLOR_STAT_1, value);
487    }
488}
489
490void
491CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset)
492{
493    vgaHWPtr hwp = VGAHWPTR(pScrn);
494
495    hwp->writeCrtc		= chipsMmioWriteCrtc;
496    hwp->readCrtc		= chipsMmioReadCrtc;
497    hwp->writeGr		= chipsMmioWriteGr;
498    hwp->readGr			= chipsMmioReadGr;
499    hwp->writeAttr		= chipsMmioWriteAttr;
500    hwp->readAttr		= chipsMmioReadAttr;
501    hwp->writeSeq		= chipsMmioWriteSeq;
502    hwp->readSeq		= chipsMmioReadSeq;
503    hwp->writeMiscOut		= chipsMmioWriteMiscOut;
504    hwp->readMiscOut		= chipsMmioReadMiscOut;
505    hwp->enablePalette		= chipsMmioEnablePalette;
506    hwp->disablePalette		= chipsMmioDisablePalette;
507    hwp->writeDacMask		= chipsMmioWriteDacMask;
508    hwp->readDacMask		= chipsMmioReadDacMask;
509    hwp->writeDacWriteAddr	= chipsMmioWriteDacWriteAddr;
510    hwp->writeDacReadAddr	= chipsMmioWriteDacReadAddr;
511    hwp->writeDacData		= chipsMmioWriteDacData;
512    hwp->readDacData		= chipsMmioReadDacData;
513    hwp->readST00               = chipsMmioReadST00;
514    hwp->readST01               = chipsMmioReadST01;
515    hwp->readFCR               = chipsMmioReadFCR;
516    hwp->writeFCR              = chipsMmioWriteFCR;
517    hwp->MMIOBase		= base;
518    hwp->MMIOOffset		= offset;
519}
520
521
522
523
524