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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user