Applied patch by Gerald Zajac:

1) Some video modes which did not work properly with the Savage chips
have been removed from the mode list, and a few wide-screen modes which
work have been added.
2) The code which loads the cursor image has been simplified.  This code
is similar to the code I'm using in the S3 Virge video driver which I
will be submitting to the Haiku project in a few days.  This change also
removes the last piece of code that came from Erdi Chen's BeSavage
driver;  thus,  this diff file also removes his copyright from the file
savage_cursor.c.

I did a minor modification to fix a warning in ProposeDisplayMode.c (it
now includes savage.h). Thanks!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22670 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-22 22:05:16 +00:00
parent 30eca597da
commit 568bb32385
5 changed files with 78 additions and 89 deletions
@@ -142,10 +142,6 @@ INIT_ACCELERANT(int the_fd)
/* count of issued parameters or commands */
si->engine.lastIdle = si->engine.count = 0;
/* set the cursor colors. You may or may not have to do this, depending
on the device. */
SavageSetCursorColors(~0, 0);
/* ensure cursor state */
SHOW_CURSOR(false);
@@ -8,6 +8,8 @@
#include "GlobalData.h"
#include "AccelerantPrototypes.h"
#include "savage.h"
#include <string.h>
@@ -17,8 +19,6 @@
static const display_mode mode_list[] = {
{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */
{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */
{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */
{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */
{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */
{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */
@@ -35,6 +35,7 @@ static const display_mode mode_list[] = {
{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */
{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */
{ { 81642, 1152, 1216, 1336, 1520, 864, 865, 868, 895, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, // 1152x864x60Hz
{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
{ { 97800, 1152, 1216, 1344, 1552, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */
@@ -59,14 +60,13 @@ static const display_mode mode_list[] = {
{ { 218250, 1856, 1952, 2176, 2528, 1392, 1393, 1396, 1439, B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1856X1392) */
{ { 288000, 1856, 1984, 2208, 2560, 1392, 1393, 1396, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1856, 1392, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1856X1392) */
// widescreen resolutions, 16:10
{ { 83500, 1280, 1344, 1480, 1680, 800, 801, 804, 828, T_POSITIVE_SYNC}, B_CMAP8, 1280, 800, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X800) */
{ { 106500, 1440, 1520, 1672, 1904, 900, 901, 904, 932, T_POSITIVE_SYNC}, B_CMAP8, 1440, 900, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1440X900) */
{ { 234000, 1920, 2048, 2256, 2600, 1440, 1441, 1444, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1920X1440) */
{ { 297000, 1920, 2064, 2288, 2640, 1440, 1441, 1444, 1500, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1920X1440) */
{ { 341350, 1920, 2072, 2288, 2656, 1440, 1441, 1444, 1512, B_POSITIVE_VSYNC}, B_CMAP8, 1920, 1440, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1920X1440) */
{ { 266950, 2048, 2200, 2424, 2800, 1536, 1537, 1540, 1589, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(2048x1536) */
{ { 340480, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1603, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(2048x1536) */
{ { 388040, 2048, 2216, 2440, 2832, 1536, 1537, 1540, 1612, B_POSITIVE_VSYNC}, B_CMAP8, 2048, 1536, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(2048x1536) */
// widescreen resolutions, 16:9
{ { 74520, 1280, 1368, 1424, 1656, 720, 724, 730, 750, T_POSITIVE_SYNC}, B_CMAP8, 1280, 720, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@60Hz_(1280X720) */
};
@@ -213,12 +213,13 @@ PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const displa
result = B_BAD_VALUE;
// If the video is connected directly to an LCD display (ie, notebook
// computer), restrict the display mode to the resolution of the LCD
// display.
// computer), restrict the display mode to resolutions where the width and
// height of the mode are less than or equal to the width and height of the
// LCD display.
if (MT_LCD == si->displayType && si->panelX > 0 && si->panelY > 0 &&
(target->timing.h_display != si->panelX
|| target->timing.v_display != si->panelY)) {
(target->timing.h_display > si->panelX
|| target->timing.v_display > si->panelY)) {
return B_ERROR;
}
@@ -399,3 +400,19 @@ create_mode_list(void)
return B_OK;
}
bool
IsDisplaySizeValid(int width, int height)
{
// Search the mode list for a mode which has the width and height passed
// by the caller, and return true if a match is found.
uint32 i;
for (i = 0; i < MODE_COUNT; i++) {
if (mode_list[i].virtual_width == width && mode_list[i].virtual_height == height)
return true;
}
return false; // match not found
}
+2 -1
View File
@@ -245,8 +245,9 @@ typedef struct
bool IsDisplaySizeValid(int width, int height);
bool SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask);
void SavageSetCursorColors(int bg, int fg);
void SavageSetCursorPosition(int x, int y);
void SavageShowCursor(void);
void SavageHideCursor(void);
@@ -1,8 +1,6 @@
/*
Haiku S3 Savage driver adapted from the original BeSavage driver by
Erdi Chen and the X.org Savage driver.
Haiku S3 Savage driver adapted from the X.org Savage driver.
Copyright 1999 Erdi Chen
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Copyright (c) 2003-2006, X.Org Foundation
@@ -101,7 +99,7 @@ SavageSetCursorPosition(int x, int y)
}
void
static void
SavageSetCursorColors(int bg, int fg)
{
/* With the streams engine on HW Cursor seems to be 24bpp ALWAYS */
@@ -127,74 +125,44 @@ SavageSetCursorColors(int bg, int fg)
/* Assume width and height are byte-aligned. */
bool
SavageLoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask)
SavageLoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
{
int i, x, y, bit_shift;
uint8 and_buf[64*64 / 8];
uint8 xor_buf[64*64 / 8];
uint8* and_ptr = and_mask;
uint8* xor_ptr = xor_mask;
uint16* pFB;
int i, colByte, row;
uint8* fbCursor;
uint16* fbCursor16;
//@ TRACE(("SavageLoadCursorImage\n"));
// TRACE(("SavageLoadCursorImage, width: %ld height: %ld\n", width, height));
if ( ! and_mask || ! xor_mask)
if ( ! andMask || ! xorMask)
return false;
bit_shift = width & 7;
width /= 8;
if (width != 64 || height != 64) {
and_ptr = (uint8*)and_buf;
xor_ptr = (uint8*)xor_buf;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
*and_ptr++ = *and_mask++;
*xor_ptr++ = *xor_mask++;
}
if (bit_shift) {
x++;
*and_ptr++ = 0xFF ^ ((*and_mask++) & (~(0xFF >> bit_shift)));
*xor_ptr++ = (*xor_mask++) & (~(0xFF >> bit_shift));
}
for (; x < 8; x++) {
*and_ptr++ = 0xFF;
*xor_ptr++ = 0x00;
}
}
for (; y < 64; y++) {
*(uint32 *)and_ptr = ~0;
and_ptr += 4;
*(uint32 *)and_ptr = ~0;
and_ptr += 4;
*(uint32 *)xor_ptr = 0;
xor_ptr += 4;
*(uint32 *)xor_ptr = 0;
xor_ptr += 4;
}
and_ptr = (uint8 *)and_buf;
xor_ptr = (uint8 *)xor_buf;
// Initialize the hardware cursor as completely transparent.
fbCursor16 = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
for (i = 0; i < 1024 / 4; i++) {
*fbCursor16++ = ~0; // and bits
*fbCursor16++ = 0; // xor bits
}
// Now load the AND & XOR masks for the cursor image into the cursor
// buffer.
fbCursor = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
for (row = 0; row < height; row++) {
for (colByte = 0; colByte < width / 8; colByte++) {
fbCursor[row * 16 + colByte] = *andMask++;
fbCursor[row * 16 + colByte + 2] = *xorMask++;
}
}
SavageSetCursorColors(~0, 0); // set cursor colors to black & white
/* Set cursor location in video memory. */
WriteCrtc(0x4d, (0xff & si->cursorOffset / 1024));
WriteCrtc(0x4c, (0xff00 & si->cursorOffset / 1024) >> 8);
pFB = (void *)((addr_t)si->videoMemAddr + si->cursorOffset);
for (i = 0; i < 64 * 64 / 16; i++) {
*pFB++ = *(uint16*)and_ptr;
*pFB++ = *(uint16*)xor_ptr;
and_ptr += 2;
xor_ptr += 2;
}
if (S3_SAVAGE4_SERIES(si->chipset)) {
/*
* Bug in Savage4 Rev B requires us to do an MMIO read after
@@ -189,7 +189,8 @@ WaitIdleEmpty2K()
}
static void SavageGetPanelInfo()
static void
SavageGetPanelInfo()
{
uint8 cr6b;
int panelX, panelY;
@@ -209,14 +210,20 @@ static void SavageGetPanelInfo()
panelX = (ReadSeq(0x61) + ((ReadSeq(0x66) & 0x02) << 7) + 1) * 8;
panelY = ReadSeq(0x69) + ((ReadSeq(0x6e) & 0x70) << 4) + 1;
/* OK, I admit it. I don't know how to limit the max dot clock
* for LCD panels of various sizes. I thought I copied the formula
* from the BIOS, but many users have informed me of my folly.
*
* Instead, I'll abandon any attempt to automatically limit the
* clock, and add an LCDClock option to XF86Config. Some day,
* I should come back to this.
*/
if ( ! IsDisplaySizeValid(panelX, panelY)) {
// Some chips such as the Savage IX/MV in a Thinkpad T-22 will return
// a width that is 8 pixels too wide probably because reg SR61 is set
// to a value +1 higher than it should be. Subtract 8 from the width,
// and check if that is a valid width.
panelX -= 8;
if ( ! IsDisplaySizeValid(panelX, panelY)) {
TRACE(("%dx%d LCD panel size invalid. No matching video mode\n", panelX + 8, panelY));
si->displayType = MT_CRT;
return;
}
}
if ((ReadSeq(0x39) & 0x03) == 0)
sTechnology = "TFT";
@@ -229,7 +236,7 @@ static void SavageGetPanelInfo()
cr6b & ActiveLCD ? "and active" : "but not active"));
if (cr6b & ActiveLCD) {
TRACE(("Limiting video mode to %dx%d\n", panelX, panelY));
TRACE(("Limiting max video mode to %dx%d\n", panelX, panelY));
si->panelX = panelX;
si->panelY = panelY;