diff options
Diffstat (limited to 'hw/kdrive/sis530/sis.c')
-rw-r--r-- | hw/kdrive/sis530/sis.c | 953 |
1 files changed, 953 insertions, 0 deletions
diff --git a/hw/kdrive/sis530/sis.c b/hw/kdrive/sis530/sis.c new file mode 100644 index 000000000..e79ce1a4a --- /dev/null +++ b/hw/kdrive/sis530/sis.c @@ -0,0 +1,953 @@ +/* + * $Id$ + * + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* $XFree86: $ */ + +#include "sis.h" + +#define MAX_FB_SIZE (4096 * 1024) + +#define MMIO_SIZE (64 * 1024) + +#define SIS_TIMING_BAIL 2 + +SisTiming sisTimings[] = { + /* FP BP BLANK */ + { 640, 480, 85, + 56, 80, 192, /* horizontal 43.265 KHz */ + 1, 25, 29, /* vertical 85.000 Hz */ + /* pixel 35.996 MHz */ + }, + + { 640, 480, 75, + 16, 120, 200, /* horizontal 37.500 KHz */ + 1, 16, 20, /* vertical 75.000 Hz */ + /* pixel 31.500 MHz */ + }, + + { 640, 480, 60, + 16, 48, 160, /* horizontal 31.321 KHz */ + 10, 33, 45, /* vertical 59.568 Hz */ + /* pixel 25.057 MHz */ + }, + + { 800, 600, 85, + 32, 152, 248, /* horizontal 53.673 KHz */ + 1, 27, 31, /* vertical 85.060 Hz */ + /* pixel 56.249 MHz */ + }, + { 800, 600, 75, + 16, 160, 256, /* horizontal 46.891 KHz */ + 1, 21, 25, /* vertical 75.025 Hz */ + /* pixel 49.516 MHz */ + }, + { 800, 600, 72, + 56, 64, 240, /* horizontal 48.186 KHz */ + 37, 23, 66, /* vertical 72.351 Hz */ + /* pixel 50.113 MHz */ + }, + + { 1024, 768, 85, + 48, 208, 352, /* horizontal 68.676 KHz */ + 1, 36, 40, /* vertical 84.996 Hz */ + /* pixel 94.499 MHz */ + }, + { 1024, 768, 75, + 16, 176, 288, /* horizontal 60.022 KHz */ + 1, 28, 32, /* vertical 75.028 Hz */ + /* pixel 78.749 MHz */ + }, + { 1024, 768, 70, + 24, 144, 304, /* horizontal 56.604 KHz */ + 3, 29, 38, /* vertical 70.227 Hz */ + /* pixel 75.170 MHz */ + }, + { 1024, 768, 66, + 24, 144, 304, /* horizontal 53.234 KHz */ + 3, 29, 38, /* vertical 66.047 Hz */ + /* pixel 70.695 MHz */ + }, + + { 1152, 900, 85, + 48, 208, 384, /* horizontal 79.900 KHz */ + 1, 32, 38, /* vertical 85.181 Hz */ + /* pixel 122.726 MHz */ + }, + { 1152, 900, 75, + 32, 208, 384, /* horizontal 70.495 Khz */ + 1, 32, 38, /* vertical 75.154 Hz */ + /* pixel 108.280 MHz */ + }, + { 1152, 900, 70, + 32, 208, 384, /* horizontal 65.251 KHz */ + 2, 32, 38, /* vertical 69.564 Hz */ + /* pixel 100.226 MHz */ + }, + { 1152, 900, 66, + 32, 208, 384, /* horizontal 61.817 KHz */ + 1, 32, 38, /* vertical 65.903 Hz */ + /* pixel 94.951 MHz */ + }, + { 1280, 1024, 85, + 16, 248, 416, /* horizontal 90.561 KHz */ + 1, 40, 45, /* vertical 84.717 Hz */ + /* pixel 153.593 MHz */ + }, + { 1280, 1024, 75, + 16, 248, 408, /* horizontal 80.255 KHz */ + 1, 38, 42, /* vertical 75.285 Hz */ + /* pixel 134.828 MHz */ + }, + { 1280, 1024, 70, + 32, 248, 400, /* horizontal 74.573 KHz */ + 0, 36, 39, /* vertical 70.153 Hz */ + /* pixel 125.283 MHz */ + }, + { 1280, 1024, 66, + 32, 248, 400, /* horizontal 70.007 KHz */ + 0, 36, 39, /* vertical 65.858 Hz */ + /* pixel 117.612 MHz */ + }, + + { 1600, 1200, 85, + 64, 304, 560, /* horizontal 106.059 KHz */ + 1, 46, 50, /* vertical 84.847 Hz */ + /* pixel 229.088 MHz */ + }, + { 1600, 1200, 75, + 64, 304, 560, /* horizontal 93.748 KHz */ + 1, 46, 50, /* vertical 74.999 Hz */ + /* pixel 202.497 MHz */ + }, + { 1600, 1200, 70, + 56, 304, 588, /* horizontal 87.524 KHz */ + 1, 46, 50, /* vertical 70.019 Hz */ + /* pixel 191.503 MHz */ + }, + { 1600, 1200, 65, + 56, 308, 524, /* horizontal 80.050 KHz */ + 1, 38, 42, /* vertical 64.453 Hz */ + /* pixel 170.026 MHz */ + }, +}; + +#define NUM_SIS_TIMINGS (sizeof (sisTimings) / sizeof (sisTimings[0])) + +Bool +sisCardInit (KdCardInfo *card) +{ + SisCardInfo *sisc; + SisPtr sis; + int size; + CARD8 *registers; + CARD8 *temp_buffer; + + sisc = (SisCardInfo *) xalloc (sizeof (SisCardInfo)); + if (!sisc) + goto bail0; + + temp_buffer = KdMapDevice (card->attr.address[0], MAX_FB_SIZE); + if (!temp_buffer) + goto bail1; + + sisc->memory = KdFrameBufferSize (temp_buffer, MAX_FB_SIZE); + + KdUnmapDevice (temp_buffer, MAX_FB_SIZE); + + if (!sisc->memory) + { + ErrorF ("Can't detect SiS530 frame buffer\n"); + goto bail1; + } + + /* + * Map frame buffer and MMIO registers + */ + sisc->frameBuffer = KdMapDevice (card->attr.address[0], sisc->memory); + if (!sisc->frameBuffer) + goto bail1; + + sisc->registers = KdMapDevice (card->attr.address[1], MMIO_SIZE); + if (!sisc->registers) + goto bail2; + + /* + * Offset from base of MMIO to registers + */ + sisc->sis = (SisPtr) (sisc->registers + SIS_MMIO_OFFSET); + sisc->cpu_bitblt = (VOL32 *) sisc->registers; + sisc->io_base = card->attr.io; + + /* + * enable access to SiS ports (no MMIO available) + */ + ioperm (sisc->io_base, 0x80, 1); + card->driver = sisc; + + return TRUE; +bail2: + KdUnmapDevice (sisc->frameBuffer, sisc->memory); +bail1: + xfree (sisc); +bail0: + return FALSE; +} + +SisTiming * +sisGetTiming (int width, int height, int rate) +{ + int i; + SisTiming *t; + + for (i = 0; i < NUM_SIS_TIMINGS; i++) + { + t = &sisTimings[i]; + if (t->horizontal >= width && + t->vertical >= height && + (!rate || t->rate <= rate)) + return t; + } + return &sisTimings[SIS_TIMING_BAIL]; +} + +Bool +sisScreenInit (KdScreenInfo *screen) +{ + KdCardInfo *card = screen->card; + SisCardInfo *sisc = (SisCardInfo *) card->driver; + SisScreenInfo *siss; + int i; + SisTiming *t; + CARD32 memory; + int byte_width, pixel_width, screen_size; + + siss = (SisScreenInfo *) xalloc (sizeof (SisScreenInfo)); + if (!siss) + return FALSE; + + memset (siss, '\0', sizeof (SisScreenInfo)); + + if (!screen->width || !screen->height) + { + screen->width = 800; + screen->height = 600; + screen->rate = 72; + } + if (!screen->depth) + screen->depth = 8; + + for (;;) + { + if (screen->depth >= 24) + { + screen->depth = 24; + screen->bitsPerPixel = 24; + } + else if (screen->depth >= 16) + { + screen->depth = 16; + screen->bitsPerPixel = 16; + } + else if (screen->depth >= 15) + { + screen->depth = 15; + screen->bitsPerPixel = 16; + } + else + { + screen->depth = 8; + screen->bitsPerPixel = 8; + } + + /* Normalize width to supported values */ + + if (screen->width >= 1600) + screen->width = 1600; + else if (screen->width >= 1280) + screen->width = 1280; + else if (screen->width >= 1152) + screen->width = 1152; + else if (screen->width >= 1024) + screen->width = 1024; + else if (screen->width >= 800) + screen->width = 800; + else + screen->width = 640; + + byte_width = screen->width * (screen->bitsPerPixel >> 3); + pixel_width = screen->width; + screen->pixelStride = pixel_width; + screen->byteStride = byte_width; + + screen_size = byte_width * screen->height; + + if (screen_size <= sisc->memory) + break; + + /* + * Fix requested depth and geometry until it works + */ + if (screen->depth > 16) + screen->depth = 16; + else if (screen->depth > 8) + screen->depth = 8; + else if (screen->width > 1152) + { + screen->width = 1152; + screen->height = 900; + } + else if (screen->width > 1024) + { + screen->width = 1024; + screen->height = 768; + } + else if (screen->width > 800) + { + screen->width = 800; + screen->height = 600; + } + else if (screen->width > 640) + { + screen->width = 640; + screen->height = 480; + } + else + { + xfree (siss); + return FALSE; + } + } + + t = sisGetTiming (screen->width, screen->height, screen->rate); + screen->rate = t->rate; + screen->width = t->horizontal; + screen->height = t->vertical; + + /* + * Take requested geometry and adjust to fit possible geometries + */ + switch (screen->depth) { + case 4: + screen->bitsPerPixel = 4; + break; + case 8: + screen->bitsPerPixel = 8; + break; + case 15: + case 16: + screen->bitsPerPixel = 16; + break; + case 24: + case 32: + screen->bitsPerPixel = 24; + screen->dumb = TRUE; + break; + } + + screen->byteStride = screen->width * (screen->bitsPerPixel >> 3); + screen->pixelStride = screen->width; + + memory = sisc->memory - screen_size; + + screen->frameBuffer = sisc->frameBuffer; + + /* + * Cursor lives in the last 16k of memory + */ + if (memory >= 16384 && !screen->softCursor) + { + siss->cursor_base = sisc->frameBuffer + (sisc->memory - 16384); + siss->cursor_off = siss->cursor_base - sisc->frameBuffer; + memory -= 16384; + } + else + { + screen->softCursor = TRUE; + siss->cursor_base = 0; + siss->cursor_off = 0; + } + + if (memory > 8192) + { + siss->expand = screen->frameBuffer + screen_size; + siss->expand_off = siss->expand - sisc->frameBuffer; + siss->expand_len = memory; + memory = 0; + } + else + { + siss->expand = 0; + siss->expand_len = 0; + } + + switch (screen->depth) { + case 8: + screen->visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + screen->blueMask = 0x00; + screen->greenMask = 0x00; + screen->redMask = 0x00; + break; + case 15: + screen->visuals = (1 << TrueColor); + screen->blueMask = 0x001f; + screen->greenMask = 0x03e0; + screen->redMask = 0x7c00; + break; + case 16: + screen->visuals = (1 << TrueColor); + screen->blueMask = 0x001f; + screen->greenMask = 0x07e0; + screen->redMask = 0xf800; + break; + case 24: + screen->visuals = (1 << TrueColor); + screen->blueMask = 0x0000ff; + screen->greenMask = 0x00ff00; + screen->redMask = 0xff0000; + break; + } + + screen->driver = siss; + + return TRUE; +} + +static void +_sisGetCrtc (SisCardInfo *sisc, SisCrtc *crtc) +{ + crtc->misc_output = _sisInb(sisc->io_base+0x4c); + crtc->h_total_0_7 = GetCrtc (sisc, 0x00); + crtc->h_display_end_0_7 = GetCrtc (sisc, 0x01); + crtc->h_blank_start_0_7 = GetCrtc (sisc, 0x02); + crtc->_h_blank_end = GetCrtc (sisc, 0x03); + crtc->h_sync_start_0_7 = GetCrtc (sisc, 0x04); + crtc->_h_sync_end = GetCrtc (sisc, 0x05); + crtc->v_total_0_7 = GetCrtc (sisc, 0x06); + crtc->crtc_overflow = GetCrtc (sisc, 0x07); + crtc->preset_row_scan = GetCrtc (sisc, 0x08); + crtc->_max_scan_line = GetCrtc (sisc, 0x09); + + crtc->start_address_8_15 = GetCrtc (sisc, 0x0c); + crtc->start_address_0_7 = GetCrtc (sisc, 0x0d); + + crtc->v_retrace_start_0_7 = GetCrtc (sisc, 0x10); + crtc->_v_retrace_end = GetCrtc (sisc, 0x11); + crtc->v_display_end_0_7 = GetCrtc (sisc, 0x12); + crtc->screen_off_0_7 = GetCrtc (sisc, 0x13); + crtc->_underline_location = GetCrtc (sisc, 0x14); + crtc->v_blank_start_0_7 = GetCrtc (sisc, 0x15); + crtc->v_blank_end_0_7 = GetCrtc (sisc, 0x16); + crtc->crtc_mode = GetCrtc (sisc, 0x17); + + crtc->line_compare_0_7 = GetCrtc (sisc, 0x18); + + crtc->mode_control = GetArtc (sisc, 0x10); + crtc->screen_border_color = GetArtc (sisc, 0x11); + crtc->enable_color_plane = GetArtc (sisc, 0x12); + crtc->horizontal_pixel_pan = GetArtc (sisc, 0x13); + + crtc->mode_register = GetGrtc (sisc, 0x5); + + crtc->clock_mode = GetSrtc (sisc, 0x1); + + crtc->graphics_mode = GetSrtc (sisc, 0x6); + crtc->misc_control_0 = GetSrtc (sisc, 0x7); + crtc->crt_cpu_threshold_control_0 = GetSrtc (sisc, 0x8); + crtc->crt_cpu_threshold_control_1 = GetSrtc (sisc, 0x9); + crtc->extended_crt_overflow = GetSrtc (sisc, 0xa); + crtc->misc_control_1 = GetSrtc (sisc, 0xb); + crtc->misc_control_2 = GetSrtc (sisc, 0xc); + + crtc->ddc_and_power_control = GetSrtc (sisc, 0x11); + crtc->extended_horizontal_overflow = GetSrtc (sisc, 0x12); + crtc->extended_clock_generator = GetSrtc (sisc, 0x13); + crtc->cursor_0_red = GetSrtc (sisc, 0x14); + crtc->cursor_0_green = GetSrtc (sisc, 0x15); + crtc->cursor_0_blue = GetSrtc (sisc, 0x16); + crtc->cursor_1_red = GetSrtc (sisc, 0x17); + crtc->cursor_1_green = GetSrtc (sisc, 0x18); + crtc->cursor_1_blue = GetSrtc (sisc, 0x19); + crtc->cursor_h_start_0_7 = GetSrtc (sisc, 0x1a); + crtc->cursor_h_start_1 = GetSrtc (sisc, 0x1b); + crtc->cursor_h_preset_0_5 = GetSrtc (sisc, 0x1c); + crtc->cursor_v_start_0_7 = GetSrtc (sisc, 0x1d); + crtc->cursor_v_start_1 = GetSrtc (sisc, 0x1e); + crtc->cursor_v_preset_0_5 = GetSrtc (sisc, 0x1f); + crtc->linear_base_19_26 = GetSrtc (sisc, 0x20); + crtc->linear_base_1 = GetSrtc (sisc, 0x21); + + crtc->graphics_engine_0 = GetSrtc (sisc, 0x26); + crtc->graphics_engine_1 = GetSrtc (sisc, 0x27); + crtc->internal_mclk_0 = GetSrtc (sisc, 0x28); + crtc->internal_mclk_1 = GetSrtc (sisc, 0x29); + crtc->internal_vclk_0 = GetSrtc (sisc, 0x2A); + crtc->internal_vclk_1 = GetSrtc (sisc, 0x2B); + + crtc->misc_control_7 = GetSrtc (sisc, 0x38); + + crtc->misc_control_11 = GetSrtc (sisc, 0x3E); + crtc->misc_control_12 = GetSrtc (sisc, 0x3F); +} + +static void +_sisSetBlank (SisCardInfo *sisc, Bool blank) +{ + CARD8 clock; + + clock = GetSrtc (sisc, 0x01); + if (blank) + clock |= 0x20; + else + clock &= ~0x20; + PutSrtc (sisc, 0x01, clock); +} + +static void +_sisSetCrtc (SisCardInfo *sisc, SisCrtc *crtc) +{ + _sisOutb(crtc->misc_output, sisc->io_base+0x4c); + _sisSetBlank (sisc, TRUE); + PutCrtc (sisc, 0x00, crtc->h_total_0_7); + PutCrtc (sisc, 0x01, crtc->h_display_end_0_7); + PutCrtc (sisc, 0x02, crtc->h_blank_start_0_7); + PutCrtc (sisc, 0x03, crtc->_h_blank_end); + PutCrtc (sisc, 0x04, crtc->h_sync_start_0_7); + PutCrtc (sisc, 0x05, crtc->_h_sync_end); + PutCrtc (sisc, 0x06, crtc->v_total_0_7); + PutCrtc (sisc, 0x07, crtc->crtc_overflow); + PutCrtc (sisc, 0x08, crtc->preset_row_scan); + PutCrtc (sisc, 0x09, crtc->_max_scan_line); + + PutCrtc (sisc, 0x0c, crtc->start_address_8_15); + PutCrtc (sisc, 0x0d, crtc->start_address_0_7); + + PutCrtc (sisc, 0x10, crtc->v_retrace_start_0_7); + PutCrtc (sisc, 0x11, crtc->_v_retrace_end); + PutCrtc (sisc, 0x12, crtc->v_display_end_0_7); + PutCrtc (sisc, 0x13, crtc->screen_off_0_7); + PutCrtc (sisc, 0x14, crtc->_underline_location); + PutCrtc (sisc, 0x15, crtc->v_blank_start_0_7); + PutCrtc (sisc, 0x16, crtc->v_blank_end_0_7); + PutCrtc (sisc, 0x17, crtc->crtc_mode); + PutCrtc (sisc, 0x18, crtc->line_compare_0_7); + + PutArtc (sisc, 0x10, crtc->mode_control); + PutArtc (sisc, 0x11, crtc->screen_border_color); + PutArtc (sisc, 0x12, crtc->enable_color_plane); + PutArtc (sisc, 0x13, crtc->horizontal_pixel_pan); + + PutGrtc (sisc, 0x5, crtc->mode_register); + + PutSrtc (sisc, 0x1, crtc->clock_mode | 0x20); + + PutSrtc (sisc, 0x6, crtc->graphics_mode); + PutSrtc (sisc, 0x7, crtc->misc_control_0); + PutSrtc (sisc, 0x8, crtc->crt_cpu_threshold_control_0); + PutSrtc (sisc, 0x9, crtc->crt_cpu_threshold_control_1); + PutSrtc (sisc, 0xa, crtc->extended_crt_overflow); + PutSrtc (sisc, 0xb, crtc->misc_control_1); + PutSrtc (sisc, 0xc, crtc->misc_control_2); + + PutSrtc (sisc, 0x11, crtc->ddc_and_power_control); + PutSrtc (sisc, 0x12, crtc->extended_horizontal_overflow); + PutSrtc (sisc, 0x13, crtc->extended_clock_generator); + PutSrtc (sisc, 0x14, crtc->cursor_0_red); + PutSrtc (sisc, 0x15, crtc->cursor_0_green); + PutSrtc (sisc, 0x16, crtc->cursor_0_blue); + PutSrtc (sisc, 0x17, crtc->cursor_1_red); + PutSrtc (sisc, 0x18, crtc->cursor_1_green); + PutSrtc (sisc, 0x19, crtc->cursor_1_blue); + PutSrtc (sisc, 0x1a, crtc->cursor_h_start_0_7); + PutSrtc (sisc, 0x1b, crtc->cursor_h_start_1); + PutSrtc (sisc, 0x1c, crtc->cursor_h_preset_0_5); + PutSrtc (sisc, 0x1d, crtc->cursor_v_start_0_7); + PutSrtc (sisc, 0x1e, crtc->cursor_v_start_1); + PutSrtc (sisc, 0x1f, crtc->cursor_v_preset_0_5); + PutSrtc (sisc, 0x20, crtc->linear_base_19_26); + PutSrtc (sisc, 0x21, crtc->linear_base_1); + + PutSrtc (sisc, 0x26, crtc->graphics_engine_0); + PutSrtc (sisc, 0x27, crtc->graphics_engine_1); + PutSrtc (sisc, 0x28, crtc->internal_mclk_0); + PutSrtc (sisc, 0x29, crtc->internal_mclk_1); + PutSrtc (sisc, 0x2A, crtc->internal_vclk_0); + PutSrtc (sisc, 0x2B, crtc->internal_vclk_1); + + PutSrtc (sisc, 0x38, crtc->misc_control_7); + + PutSrtc (sisc, 0x3E, crtc->misc_control_11); + PutSrtc (sisc, 0x3F, crtc->misc_control_12); + + _sisSetBlank (sisc, FALSE); +} + +CARD8 +_sisReadIndexRegister (CARD32 base, CARD8 index) +{ + CARD8 ret; + + _sisOutb (index, base); + ret = _sisInb (base+1); + return ret; +} + +void +_sisWriteIndexRegister (CARD32 base, CARD8 index, CARD8 value) +{ + _sisOutb (index, base); + _sisOutb (value, base+1); +} + +void +sisPreserve (KdCardInfo *card) +{ + SisCardInfo *sisc = card->driver; + CARD8 *r = sisc->registers; + int a, i, l; + CARD8 line[16]; + CARD8 prev[16]; + BOOL gotone; + + sisc->save.sr5 = GetSrtc(sisc,0x5); + if (sisc->save.sr5 != 0x21) + sisc->save.sr5 = 0x86; + /* unlock extension registers */ + PutSrtc(sisc,0x5,0x86); + + /* enable MMIO access to registers */ + sisc->save.srb = GetSrtc(sisc,0xb); + PutSrtc(sisc, 0xb, sisc->save.srb | 0x60); + _sisGetCrtc (sisc, &sisc->save.crtc); +} + +void +sisEnable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + SisCardInfo *sisc = card->driver; + SisScreenInfo *siss = screen->driver; + SisTiming *t; + SisCrtc crtc; + unsigned long pixel; + + int hactive; + int hblank; + int hfp; + int hbp; + + int vactive; + int vblank; + int vfp; + int vbp; + + int h_total; + int h_display_end; + int h_blank_start; + int h_blank_end; + int h_sync_start; + int h_sync_end; + int h_screen_off; + + int h_adjust; + + int v_total; + int v_retrace_start; + int v_retrace_end; + int v_display_end; + int v_blank_start; + int v_blank_end; + + crtc = sisc->save.crtc; + + t = sisGetTiming (screen->width, screen->height, screen->rate); + + /* CR11 */ + crtc.disable_v_retrace_int = 1; + + /* 3CC/3C2 */ + crtc.io_address_select = 1; + crtc.display_ram_enable = 1; + crtc.clock_select = 3; + + /* SR6 */ + crtc.graphics_mode = 0; + crtc.graphics_mode_linear = 1; + crtc.enhanced_graphics_mode = 1; + + /* SRB */ + crtc.cpu_bitblt_enable = 1; + crtc.memory_mapped_mode = 3; + + /* SRC */ + crtc.graphics_mode_32bit_enable = 1; + crtc.text_mode_16bit_enable = 0; + crtc.read_ahead_enable = 1; + + /* SR11 */ + crtc.acpi_enable = 0; + crtc.kbd_cursor_activate = 0; + crtc.video_memory_activate = 0; + crtc.vga_standby = 0; + crtc.vga_suspend = 0; + + /* AR10 */ + crtc.mode_control = 0; + crtc.graphics_mode_enable = 1; + /* AR11 */ + crtc.screen_border_color = 0; + /* AR12 */ + crtc.enable_color_plane = 0xf; + /* AR13 */ + crtc.horizontal_pixel_pan = 0; + + /* SR27 */ + crtc.logical_screen_width = 3; + crtc.graphics_prog_enable = 1; + + /* SR38 */ + crtc.extended_clock_select = 0; + + if (siss->cursor_base) + { + crtc_set_cursor_start_addr (&crtc, siss->cursor_off); + crtc.graphics_mode_hw_cursor = 0; + } + + hactive = t->horizontal; + hblank = t->hblank; + hbp = t->hbp; + hfp = t->hfp; + + vactive = t->vertical; + vblank = t->vblank; + vbp = t->vbp; + vfp = t->vfp; + + pixel = (hactive + hblank) * (vactive + vblank) * t->rate; + + switch (screen->bitsPerPixel) { + case 8: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + crtc.color_mode_256 = 1; + h_screen_off = hactive; + h_adjust = 1; + + break; + case 16: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 2; + h_adjust = 1; + + crtc.color_mode_256 = 0; + + if (screen->depth == 15) + crtc.graphics_mode_32k = 1; + else + crtc.graphics_mode_64k = 1; + break; + case 24: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 3; + h_adjust = 1; + + crtc.color_mode_256 = 0; + + /* SR6 */ + crtc.graphics_mode_true = 1; + /* SR7 */ + crtc.direct_color_24bit = 0; + /* SR9 */ + crtc.true_color_32bpp = 0; + /* SRB */ + crtc.true_color_order = 1; + break; + case 32: + hactive /= 8; + hblank /= 8; + hfp /= 8; + hbp /= 8; + + h_screen_off = hactive * 4; + h_adjust = 1; + + crtc.color_mode_256 = 0; + + /* SR6 */ + crtc.graphics_mode_true = 1; + /* SR7 */ + crtc.direct_color_24bit = 0; + /* SR9 */ + crtc.true_color_32bpp = 1; + /* SRB */ + crtc.true_color_order = 1; + break; + } + + sisGetClock (pixel, &crtc); + + crtc.high_speed_dac_0 = crtc.high_speed_dac_1 = pixel > 135000000; + + sisEngThresh (&crtc, pixel, screen->bitsPerPixel); + + /* + * Compute horizontal register values from timings + */ + h_total = hactive + hblank - 5; + h_display_end = hactive - 1; + h_blank_start = h_display_end; + h_blank_end = h_blank_start + hblank; + + h_sync_start = hactive + hfp + h_adjust; + h_sync_end = h_sync_start + hblank - hbp - hfp; + + crtc_set_h_total(&crtc, h_total); + crtc_set_h_display_end (&crtc, h_display_end); + crtc_set_h_blank_start (&crtc, h_blank_start); + crtc_set_h_blank_end (&crtc, h_blank_end); + crtc_set_h_sync_start (&crtc, h_sync_start); + crtc_set_h_sync_end (&crtc, h_sync_end); + crtc_set_screen_off (&crtc, h_screen_off); + + v_total = vactive + vblank - 2; + v_retrace_start = vactive + vfp - 1; + v_retrace_end = v_retrace_start + vblank - vbp - vfp; + v_display_end = vactive - 1; + v_blank_start = vactive - 1; + v_blank_end = v_blank_start + vblank /* - 1 */; + + crtc_set_v_total(&crtc, v_total); + crtc_set_v_retrace_start (&crtc, v_retrace_start); + crtc.v_retrace_end_0_3 = v_retrace_end; + crtc_set_v_display_end (&crtc, v_display_end); + crtc_set_v_blank_start (&crtc, v_blank_start); + crtc.v_blank_end_0_7 = v_blank_end; + + _sisSetCrtc (sisc, &crtc); +} + +Bool +sisDPMS (ScreenPtr pScreen, int mode) +{ + KdScreenPriv(pScreen); + sisCardInfo(pScreenPriv); + union ddc_and_power_control_u _ddc_and_power_control_u; + + ddc_and_power_control = sisc->save.crtc.ddc_and_power_control; + + kbd_cursor_activate = 0; + video_memory_activate = 0; + vga_standby = 0; + vga_suspend = 0; + acpi_enable = 0; + switch (mode) { + case KD_DPMS_NORMAL: + break; + case KD_DPMS_STANDBY: + vga_standby = 1; + break; + case KD_DPMS_SUSPEND: + vga_suspend = 1; + break; + case KD_DPMS_POWERDOWN: + acpi_enable = 1; + break; + } + PutSrtc (sisc, 0x11, ddc_and_power_control); + return TRUE; +} + +void +sisDisable (ScreenPtr pScreen) +{ +} + +void +sisRestore (KdCardInfo *card) +{ + SisCardInfo *sisc = (SisCardInfo *) card->driver; + + _sisSetCrtc (sisc, &sisc->save.crtc); + PutSrtc (sisc, 0xb, sisc->save.srb); + PutSrtc (sisc, 0x5, sisc->save.sr5); +} + +void +sisScreenFini (KdScreenInfo *screen) +{ + SisScreenInfo *siss = (SisScreenInfo *) screen->driver; + + xfree (siss); + screen->driver = 0; +} + +void +sisCardFini (KdCardInfo *card) +{ + SisCardInfo *sisc = (SisCardInfo *) card->driver; + + KdUnmapDevice (sisc->frameBuffer, sisc->memory); + KdUnmapDevice (sisc->registers, sizeof (SisRec)); + ioperm (sisc->io_base, 0x80, 0); +} + +KdCardFuncs sisFuncs = { + sisCardInit, + sisScreenInit, + sisPreserve, + sisEnable, + sisDPMS, + sisDisable, + sisRestore, + sisScreenFini, + sisCardFini, + sisCursorInit, + sisCursorEnable, + sisCursorDisable, + sisCursorFini, + 0, + sisDrawInit, + sisDrawEnable, + sisDrawDisable, + sisDrawFini, + sisGetColors, + sisPutColors, +}; |