2
* $RCSId: xc/programs/Xserver/hw/kdrive/igs/igs.c,v 1.2 2000/05/24 23:52:47 keithp Exp $
4
* Copyright ļæ½ 1999 SuSE, Inc.
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of SuSE not be used in advertising or
11
* publicity pertaining to distribution of the software without specific,
12
* written prior permission. SuSE makes no representations about the
13
* suitability of this software for any purpose. It is provided "as is"
14
* without express or implied warranty.
16
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
18
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: Keith Packard, SuSE, Inc.
27
#include <kdrive-config.h>
32
igsCardInit (KdCardInfo *card)
38
igsc = (IgsCardInfo *) xalloc (sizeof (IgsCardInfo));
42
memset (igsc, '\0', sizeof (IgsCardInfo));
44
igsc->frameBuffer = (CARD8 *) KdMapDevice (card->attr.address[0] +
48
igsc->vga = (VOL8 *) KdMapDevice (card->attr.address[0] +
52
igsc->cop = (Cop5xxx *) KdMapDevice (card->attr.address[0] +
56
igsc->copData = (VOL32 *) KdMapDevice (card->attr.address[0] +
60
igsRegInit (&igsc->igsvga, igsc->vga);
68
igsModeSupported (KdScreenInfo *screen,
69
const KdMonitorTiming *t)
71
/* make sure the clock isn't too fast */
72
if (t->clock > IGS_MAX_CLOCK)
74
/* width must be a multiple of 16 */
75
if (t->horizontal & 0xf)
81
igsModeUsable (KdScreenInfo *screen)
83
KdCardInfo *card = screen->card;
90
if (screen->fb[fb].depth >= 24)
92
screen->fb[fb].depth = 24;
93
if (screen->fb[fb].bitsPerPixel != 24)
94
screen->fb[fb].bitsPerPixel = 32;
96
else if (screen->fb[fb].depth >= 16)
98
screen->fb[fb].depth = 16;
99
screen->fb[fb].bitsPerPixel = 16;
101
else if (screen->fb[fb].depth >= 15)
103
screen->fb[fb].depth = 15;
104
screen->fb[fb].bitsPerPixel = 16;
106
else if (screen->fb[fb].depth >= 12)
108
screen->fb[fb].depth = 12;
109
screen->fb[fb].bitsPerPixel = 16;
113
screen->fb[fb].depth = 8;
114
screen->fb[fb].bitsPerPixel = 8;
117
byte_width = screen->width * (screen->fb[fb].bitsPerPixel >> 3);
118
pixel_width = screen->width;
119
screen->fb[fb].pixelStride = pixel_width;
120
screen->fb[fb].byteStride = byte_width;
121
screen_size += byte_width * screen->height;
127
igsScreenInit (KdScreenInfo *screen)
129
IgsCardInfo *igsc = screen->card->driver;
132
int screen_size, memory;
136
int poffset, boffset;
137
const KdMonitorTiming *t;
139
if (!screen->width || !screen->height)
142
screen->height = 600;
145
if (!screen->fb[0].depth)
146
screen->fb[0].depth = 8;
148
t = KdFindMode (screen, igsModeSupported);
150
screen->rate = t->rate;
151
screen->width = t->horizontal;
152
screen->height = t->vertical;
154
if (!KdTuneMode (screen, igsModeUsable, igsModeSupported))
159
igss = (IgsScreenInfo *) xalloc (sizeof (IgsScreenInfo));
163
memset (igss, '\0', sizeof (IgsScreenInfo));
165
screen_size = screen->fb[fb].byteStride * screen->height;
167
memory -= screen_size;
170
igss->cursor_offset = memory - 1024;
171
#if BITMAP_BIT_ORDER == MSBFirst
172
igss->cursor_base = (CARD8 *) KdMapDevice (card->attr.address[0] +
176
igss->cursor_base = igsc->frameBuffer + igss->cursor_offset;
181
igss->cursor_base = 0;
183
tile_size = IgsTileSize(screen->fb[fb].bitsPerPixel) * IGS_NUM_PATTERN;
184
stipple_size = IgsStippleSize(screen->fb[fb].bitsPerPixel) * IGS_NUM_PATTERN;
185
pattern_size = tile_size + stipple_size;
186
if (memory >= pattern_size)
188
boffset = screen_size;
189
poffset = boffset * 8 / screen->fb[fb].bitsPerPixel;
190
igss->tile.offset = poffset;
191
igss->tile.base = igsc->frameBuffer + boffset;
193
boffset = screen_size + tile_size;
194
poffset = boffset * 8 / screen->fb[fb].bitsPerPixel;
195
igss->stipple.offset = poffset;
196
igss->stipple.base = igsc->frameBuffer + boffset;
198
memory -= pattern_size;
203
igss->stipple.base = 0;
206
switch (screen->fb[fb].depth) {
208
screen->fb[fb].visuals = ((1 << StaticGray) |
214
screen->fb[fb].blueMask = 0x00;
215
screen->fb[fb].greenMask = 0x00;
216
screen->fb[fb].redMask = 0x00;
219
screen->fb[fb].visuals = (1 << TrueColor);
220
screen->fb[fb].blueMask = 0x001f;
221
screen->fb[fb].greenMask = 0x03e0;
222
screen->fb[fb].redMask = 0x7c00;
225
screen->fb[fb].visuals = (1 << TrueColor);
226
screen->fb[fb].blueMask = 0x001f;
227
screen->fb[fb].greenMask = 0x07e0;
228
screen->fb[fb].redMask = 0xf800;
231
screen->fb[fb].visuals = (1 << TrueColor);
232
screen->fb[fb].blueMask = 0x0000ff;
233
screen->fb[fb].greenMask = 0x00ff00;
234
screen->fb[fb].redMask = 0xff0000;
238
screen->fb[fb].pixelStride = screen->width;
239
screen->fb[fb].byteStride = screen->width * (screen->fb[fb].bitsPerPixel >> 3);
240
screen->fb[fb].frameBuffer = igsc->frameBuffer;
243
screen->driver = igss;
248
igsInitScreen(ScreenPtr pScreen)
254
igsPreserve (KdCardInfo *card)
256
IgsCardInfo *igsc = card->driver;
257
IgsVga *igsvga = &igsc->igsvga;
263
igsSetBlank (IgsVga *igsvga, Bool blank)
265
igsSetImm(igsvga, igs_screen_off, blank ? 1 : 0);
269
igsSetSync (IgsCardInfo *igsc, int hsync, int vsync)
271
IgsVga *igsvga = &igsc->igsvga;
273
igsSet (igsvga, igs_mexhsyn, hsync);
274
igsSet (igsvga, igs_mexvsyn, vsync);
275
VgaFlush (&igsvga->card);
282
* scale = p ? (2 * p) : 1
283
* f_out = f_ref * ((M + 1) / ((N + 1) * scale))
287
* 1. 115MHz <= f_ref * ((M + 1) / (N + 1)) <= 260 MHz
290
* Vertical refresh rate = clock / ((hsize + hblank) * (vsize + vblank))
291
* Horizontal refresh rate = clock / (hsize + hblank)
297
igsGetClock (int target, int *Mp, int *Np, int *Pp, int maxM, int maxN, int maxP, int minVco)
299
int M, N, P, bestM, bestN;
301
int err, abserr, besterr;
304
* Compute correct P value to keep VCO in range
306
for (P = 0; P <= maxP; P++)
308
f_vco = target * IGS_SCALE(P);
313
/* M = f_out / f_ref * ((N + 1) * IGS_SCALE(P)); */
315
for (N = 1; N <= maxN; N++)
317
M = ((target * (N + 1) * IGS_SCALE(P) + (IGS_CLOCK_REF/2)) + IGS_CLOCK_REF/2) / IGS_CLOCK_REF - 1;
318
if (0 <= M && M <= maxM)
320
f_out = IGS_CLOCK(M,N,P);
321
err = target - f_out;
338
igsEnable (ScreenPtr pScreen)
340
KdScreenPriv(pScreen);
341
KdCardInfo *card = pScreenPriv->card;
342
KdScreenInfo *screen = pScreenPriv->screen;
343
IgsCardInfo *igsc = card->driver;
344
IgsVga *igsvga = &igsc->igsvga;
345
const KdMonitorTiming *t;
346
int hactive, hblank, hfp, hbp;
347
int vactive, vblank, vfp, vbp;
369
igsSetBlank (igsvga, TRUE);
371
t = KdFindMode (screen, igsModeSupported);
373
igsGetClock (t->clock, &m, &n, &r, 2047, 255, 7, IGS_MIN_VCO);
376
* Set the chip so that 0x400000 is a big-endian frame buffer
377
* with the correct byte swapping enabled
379
igsSet (igsvga, igs_biga22force, 0);
380
igsSet (igsvga, igs_biga22en, 1);
381
igsSet (igsvga, igs_biga24en, 1);
385
igsSet (igsvga, igs_rampwdn, 0);
386
igsSet (igsvga, igs_dac6_8, 1);
387
igsSet (igsvga, igs_dacpwdn, 0);
389
* Set overscan to black
391
igsSet (igsvga, igs_overscan_red, 0x00);
392
igsSet (igsvga, igs_overscan_green, 0x00);
393
igsSet (igsvga, igs_overscan_blue, 0x00);
397
igsSet (igsvga, igs_iow_retry, 1);
398
igsSet (igsvga, igs_mw_retry, 1);
399
igsSet (igsvga, igs_mr_retry, 1);
400
igsSet (igsvga, igs_pci_burst_write, 1);
401
igsSet (igsvga, igs_pci_burst_read, 1);
405
igsSet (igsvga, igs_memgopg, 1);
406
igsSet (igsvga, igs_memr2wpg, 0);
407
igsSet (igsvga, igs_crtff16, 0);
408
igsSet (igsvga, igs_fifomust, 0xff);
409
igsSet (igsvga, igs_fifogen, 0xff);
411
* Enable CRT reg access
413
igsSetImm (igsvga, igs_ena_vr_access, 1);
414
igsSetImm (igsvga, igs_crt_protect, 0);
419
hactive = t->horizontal;
420
offset = screen->fb[0].byteStride;
425
vactive = t->vertical;
428
* Compute character lengths for horizontal timing values
430
hactive = screen->width / 8;
436
switch (screen->fb[fb].bitsPerPixel) {
438
igsSet (igsvga, igs_overscan_red, pScreen->blackPixel);
439
igsSet (igsvga, igs_overscan_green, pScreen->blackPixel);
440
igsSet (igsvga, igs_overscan_blue, pScreen->blackPixel);
441
igsSet (igsvga, igs_bigswap, IGS_BIGSWAP_8);
442
igsSet (igsvga, igs_mode_sel, IGS_MODE_8);
443
igsSet (igsvga, igs_ramdacbypass, 0);
446
igsSet (igsvga, igs_bigswap, IGS_BIGSWAP_16);
447
igsSet (igsvga, igs_ramdacbypass, 1);
448
switch (screen->fb[fb].depth) {
450
igsSet (igsvga, igs_mode_sel, IGS_MODE_4444);
453
igsSet (igsvga, igs_mode_sel, IGS_MODE_5551);
456
igsSet (igsvga, igs_mode_sel, IGS_MODE_565);
461
igsSet (igsvga, igs_ramdacbypass, 1);
462
igsSet (igsvga, igs_bigswap, IGS_BIGSWAP_8);
463
igsSet (igsvga, igs_mode_sel, IGS_MODE_888);
466
igsSet (igsvga, igs_ramdacbypass, 1);
467
igsSet (igsvga, igs_bigswap, IGS_BIGSWAP_32);
468
igsSet (igsvga, igs_mode_sel, IGS_MODE_8888);
473
* Compute horizontal register values from timings
475
h_total = hactive + hblank - 5;
476
h_display_end = hactive - 1;
478
h_sync_start = hactive + hfp;
479
h_sync_end = hactive + hblank - hbp;
481
* pad the blank values narrow a bit and use the border_select to
482
* eliminate the remaining border; don't know why, but it doesn't
483
* work in the documented fashion
485
h_blank_start = hactive - 1;
486
h_blank_end = hactive + hblank - 1 - 1;
488
num_fetch = (t->horizontal * screen->fb[fb].bitsPerPixel / 64) + 1;
490
v_total = vactive + vblank - 2;
491
v_display_end = vactive - 1;
493
v_blank_start = vactive - 1;
494
v_blank_end = v_blank_start + vblank - 1;
496
v_retrace_start = vactive + vfp;
497
v_retrace_end = vactive + vblank - vbp;
500
#define chk(a,b,c) fprintf (stderr, "%20.20s: BIOS %6d X %6d\n", a, igsGet(igsvga, b), c);
502
chk("h_total", igs_h_total, h_total);
503
chk("h_display_end", igs_h_de_end, h_display_end);
504
chk("h_sync_start", igs_h_rstart, h_sync_start);
505
chk("h_sync_end", igs_h_rend, h_sync_end&0x1f);
506
chk("h_blank_start", igs_h_bstart, h_blank_start);
507
chk("h_blank_end", igs_h_bend, h_blank_end&0x3f);
508
chk("offset", igs_offset, offset);
509
chk("num_fetch", igs_num_fetch, num_fetch);
511
chk("v_total", igs_v_total, v_total);
512
chk("v_display_end", igs_v_de_end, v_display_end);
513
chk("v_blank_start", igs_v_bstart, v_blank_start);
514
chk("v_blank_end", igs_v_bend, v_blank_end&0xf);
515
chk("v_retrace_start", igs_v_rstart, v_retrace_start);
516
chk("v_retrace_end", igs_v_rend, v_retrace_end&0xf);
517
chk("vclk_m", igs_vclk_m, m);
518
chk("vclk_n", igs_vclk_n, n);
519
chk("vclk_p", igs_vclk_p, r);
521
fprintf (stderr, "%20.20s: BIOS %6d X %6d\n", "vclk",
522
IGS_CLOCK(igsGet(igsvga,igs_vclk_m),
523
igsGet(igsvga,igs_vclk_n),
524
igsGet(igsvga,igs_vclk_p)),
527
igsSet (igsvga, igs_h_total, h_total);
528
igsSet (igsvga, igs_h_de_end, h_display_end);
529
igsSet (igsvga, igs_h_rstart, h_sync_start);
530
igsSet (igsvga, igs_h_rend, h_sync_end);
531
igsSet (igsvga, igs_h_bstart, h_blank_start);
532
igsSet (igsvga, igs_h_bend, h_blank_end);
533
igsSet (igsvga, igs_offset, offset);
534
igsSet (igsvga, igs_num_fetch, num_fetch);
536
igsSet (igsvga, igs_v_total, v_total);
537
igsSet (igsvga, igs_v_de_end, v_display_end);
538
igsSet (igsvga, igs_v_bstart, v_blank_start);
539
igsSet (igsvga, igs_v_bend, v_blank_end&0xf);
540
igsSet (igsvga, igs_v_rstart, v_retrace_start);
541
igsSet (igsvga, igs_v_rend, v_retrace_end&0xf);
543
igsSet (igsvga, igs_vclk_m, m);
544
igsSet (igsvga, igs_vclk_n, n);
545
igsSet (igsvga, igs_vclk_p, r);
546
igsSet (igsvga, igs_vfsel, IGS_CLOCK(m, n, 0) >= 180000);
547
VgaFlush (&igsvga->card);
549
igsSetImm (igsvga, igs_frqlat, 0);
550
igsSetImm (igsvga, igs_frqlat, 1);
551
igsSetImm (igsvga, igs_frqlat, 0);
553
igsSetBlank (igsvga, FALSE);
555
#define dbg(a,b) fprintf(stderr, "%20.20s = 0x%x\n", a, igsGet(igsvga,b))
563
for (reg = 0; reg < IGS_NREG; reg++)
564
fprintf(stderr, "%20.20s = 0x%02x\n", igsRegName(buf, reg),
565
VgaFetch (&igsvga->card, reg));
572
igsDPMS (ScreenPtr pScreen, int mode)
574
KdScreenPriv(pScreen);
575
IgsCardInfo *igsc = pScreenPriv->card->driver;
576
IgsVga *igsvga = &igsc->igsvga;
580
igsSetSync (igsc, 0, 0);
581
igsSetBlank (igsvga, FALSE);
583
case KD_DPMS_STANDBY:
584
igsSetBlank (igsvga, TRUE);
585
igsSetSync (igsc, 1, 0);
587
case KD_DPMS_SUSPEND:
588
igsSetBlank (igsvga, TRUE);
589
igsSetSync (igsc, 0, 1);
591
case KD_DPMS_POWERDOWN:
592
igsSetBlank (igsvga, TRUE);
593
igsSetSync (igsc, 1, 1);
600
igsDisable (ScreenPtr pScreen)
605
igsRestore (KdCardInfo *card)
607
IgsCardInfo *igsc = card->driver;
608
IgsVga *igsvga = &igsc->igsvga;
614
igsScreenFini (KdScreenInfo *screen)
616
IgsScreenInfo *igss = (IgsScreenInfo *) screen->driver;
618
#if BITMAP_BIT_ORDER == MSBFirst
619
if (igss->cursor_base)
620
KdUnmapDevice ((void *) igss->cursor_base, 1024);
627
igsCardFini (KdCardInfo *card)
629
IgsCardInfo *igsc = card->driver;
632
KdUnmapDevice ((void *) igsc->copData, IGS_COP_DATA_LEN);
634
KdUnmapDevice ((void *) igsc->cop, sizeof (Cop5xxx));
636
KdUnmapDevice ((void *) igsc->vga, 64 * 1024);
637
if (igsc->frameBuffer)
638
KdUnmapDevice (igsc->frameBuffer, IGS_MEM);
643
KdCardFuncs igsFuncs = {
644
igsCardInit, /* cardinit */
645
igsScreenInit, /* scrinit */
647
igsPreserve, /* preserve */
648
igsEnable, /* enable */
650
igsDisable, /* disable */
651
igsRestore, /* restore */
652
igsScreenFini, /* scrfini */
653
igsCardFini, /* cardfini */
655
igsCursorInit, /* initCursor */
656
igsCursorEnable, /* enableCursor */
657
igsCursorDisable, /* disableCursor */
658
igsCursorFini, /* finiCursor */
659
0, /* recolorCursor */
661
igsDrawInit, /* initAccel */
662
igsDrawEnable, /* enableAccel */
663
igsDrawSync, /* drawSync */
664
igsDrawDisable, /* disableAccel */
665
igsDrawFini, /* finiAccel */
667
igsGetColors, /* getColors */
668
igsPutColors, /* putColors */