Update for the S3 driver by Gerald:

* The hardware cursor is now disabled at 640x480 with a Virge VX (before it
  was just invisible).
* EDID info can now be read for all S3 chips.
* For the Savage IX, Savage MX, and SuperSavage chips the display is no 
  longer expanded to fill a laptop LCD display when the mode resolution is 
  less than the size of LCD display.
* Savage IX, Savage MX, and SuperSavage chips will now display mode 
  1400x1050 on a 1400x1050 laptop LCD display.  Previously the display was 
  blank at that resolution. 
* Previously about half the Savage chips would not draw properly at 
  1400x1050.  That is, the image was badly skewed and unusable.  All of 
  them now draw properly at 1400x1050.
* Some code was reorganized to remove unnecessary and redundant code.  


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27863 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-10-04 08:09:40 +00:00
parent da720168c1
commit c1379d357b
21 changed files with 986 additions and 1143 deletions

View File

@ -2,7 +2,7 @@
Copyright 2007-2008 Haiku, Inc. All rights reserved.
Distributed under the terms of the MIT license.
Other authors:
Authors:
Gerald Zajac 2007-2008
*/
@ -16,27 +16,42 @@
#include <edid.h>
// This is the info that needs to be shared between the kernel driver and
// the accelerant for the sample driver.
// This file contains info that is shared between the kernel driver and the
// accelerant, and info that is shared among the source files of the accelerant.
#if defined(__cplusplus)
extern "C" {
#endif
#define ENABLE_DEBUG_TRACE // if defined, turns on debug output to syslog
#define NUM_ELEMENTS(a) ((int)(sizeof(a) / sizeof(a[0]))) // for computing number of elements in an array
struct benaphore {
struct Benaphore {
sem_id sem;
int32 ben;
};
int32 count;
#define INIT_BEN(x) x.sem = create_sem(0, "S3 "#x" benaphore"); x.ben = 0;
#define AQUIRE_BEN(x) if((atomic_add(&(x.ben), 1)) >= 1) acquire_sem(x.sem);
#define RELEASE_BEN(x) if((atomic_add(&(x.ben), -1)) > 1) release_sem(x.sem);
#define DELETE_BEN(x) delete_sem(x.sem);
status_t Init(const char* name)
{
count = 0;
sem = create_sem(0, name);
return sem < 0 ? sem : B_OK;
}
status_t Acquire()
{
if (atomic_add(&count, 1) > 0)
return acquire_sem(sem);
return B_OK;
}
status_t Release()
{
if (atomic_add(&count, -1) > 1)
return release_sem(sem);
return B_OK;
}
void Delete() { delete_sem(sem); }
};
#define S3_PRIVATE_DATA_MAGIC 0x4521 // a private driver rev, of sorts
@ -45,6 +60,7 @@ struct benaphore {
enum {
S3_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
S3_DEVICE_NAME,
S3_GET_EDID,
S3_GET_PIO,
S3_SET_PIO,
S3_RUN_INTERRUPTS,
@ -54,7 +70,7 @@ enum {
// Chip type numbers. These are used to group the chips into related
// groups. See table S3_ChipTable in driver.c
enum S3_ChipType {
enum ChipType {
S3_TRIO64 = 1,
S3_TRIO64_VP, // Trio64V+ has same ID as Trio64 but different revision number
S3_TRIO64_UVP,
@ -106,33 +122,10 @@ enum MonitorType {
};
// Bitmap descriptor structures for BCI (for Savage chips)
struct HIGH {
unsigned short Stride;
unsigned char Bpp;
unsigned char ResBWTile;
};
struct BMPDESC1 {
unsigned long Offset;
HIGH HighPart;
};
struct BMPDESC2 {
unsigned long LoPart;
unsigned long HiPart;
};
union BMPDESC {
BMPDESC1 bd1;
BMPDESC2 bd2;
};
struct DisplayModeEx : display_mode {
uint32 bpp; // bits/pixel
uint32 bytesPerRow; // number of bytes in one line/row
uint32 bpp; // bits/pixel
uint32 bytesPerRow; // actual number of bytes in one line/row
};
@ -147,6 +140,9 @@ struct SharedInfo {
bool bAccelerantInUse; // true = accelerant has been initialized
bool bInterruptAssigned; // card has a useable interrupt assigned to it
bool bDisableHdwCursor; // true = disable hardware cursor & use software cursor
bool bDisableAccelDraw; // true = disable accelerated drawing
sem_id vertBlankSem; // vertical blank semaphore; if < 0, there is no semaphore
// Memory mappings.
@ -169,11 +165,8 @@ struct SharedInfo {
area_id modeArea; // area containing list of display modes the driver supports
uint32 modeCount; // number of display modes in the list
// Cursor info.
struct {
uint16 hot_x; // Cursor hot spot. Top left corner of the cursor
uint16 hot_y; // is 0,0
} cursor;
uint16 cursorHotX; // Cursor hot spot. Top left corner of the cursor
uint16 cursorHotY; // is 0,0
// Current display mode configuration, and other parameters related to
// current display mode.
@ -183,12 +176,7 @@ struct SharedInfo {
edid1_info edidInfo;
bool bHaveEDID; // true = EDID info from device is in edidInfo
// Acceleration engine.
struct {
uint64 count; // last fifo slot used
uint64 lastIdle; // last fifo slot we *know* the engine was idle after
benaphore lock; // for serializing access to the acceleration engine
} engine;
Benaphore engineLock; // for serializing access to the acceleration engine
int mclk;
@ -198,41 +186,39 @@ struct SharedInfo {
uint16 panelY; // laptop LCD height
// Command Overflow Buffer (COB) parameters for Savage chips.
bool bDisableCOB; // enable/disable COB for Savage 4 & ProSavage
uint32 cobIndex; // size index
uint32 cobSize; // size in bytes
uint32 cobSizeIndex; // size index
uint32 cobOffset; // offset in video memory
uint32 bciThresholdLo; // low and high thresholds for
uint32 bciThresholdHi; // shadow status update (32bit words)
BMPDESC GlobalBD; // Bitmap Descriptor for BCI
uint32 globalBitmapDesc; // Global Bitmap Descriptor for BCI
};
// Set some boolean condition (like enabling or disabling interrupts)
struct S3SetBoolState {
uint32 magic; // magic number to make sure the caller groks us
uint32 magic; // magic number
bool bEnable; // state to set
};
// Retrieve the area_id of the kernel/accelerant shared info
struct S3GetPrivateData {
uint32 magic; // magic number to make sure the caller groks us
uint32 magic; // magic number
area_id sharedInfoArea; // ID of area containing shared information
};
struct S3GetSetPIO {
uint32 magic; // magic number to make sure the caller groks us
uint32 offset; // offset of PIO register to read/write
uint32 size; // number of bytes to transfer
uint32 value; // value to write or value that was read
struct S3GetEDID {
uint32 magic; // magic number
edid1_raw rawEdid; // raw EDID info to obtain
};
#if defined(__cplusplus)
}
#endif
struct S3GetSetPIO {
uint32 magic; // magic number
uint32 offset; // offset of PIO register to read/write
uint32 size; // number of bytes to transfer
uint32 value; // value to write or value that was read
};
#endif // DRIVERINTERFACE_H

View File

@ -97,15 +97,15 @@ InitAccelerant(int fileDesc)
} else {
result = gInfo.ChipInit(); // perform init related to current chip
if (result == B_OK) {
result = si.engineLock.Init("ATI engine lock");
if (result == B_OK) {
if (gInfo.ShowCursor != NULL)
gInfo.ShowCursor(false);
INIT_BEN(si.engine.lock);
si.engine.lastIdle = 0;
si.engine.count = 0;
gInfo.ShowCursor(false);
// ensure that this function won't be executed again (copies should be clones)
si.bAccelerantInUse = true;
// ensure that this function won't be executed again
// (copies should be clones)
si.bAccelerantInUse = true;
}
}
}

View File

@ -13,11 +13,6 @@
#include "register_io.h"
#if defined(__cplusplus)
extern "C" {
#endif
#undef TRACE
@ -43,7 +38,7 @@ struct AccelerantInfo {
display_mode* modeList; // list of standard display modes
area_id modeListArea; // mode list area ID
bool bAccelerantIsClone;// true if this is a cloned accelerant
bool bAccelerantIsClone; // true if this is a cloned accelerant
// Pointers to wait handlers.
void (*WaitQueue)(uint32);
@ -51,7 +46,7 @@ struct AccelerantInfo {
// Pointers to DPMS functions.
uint32 (*DPMSCapabilities)(void);
uint32 (*DPMSMode)(void);
uint32 (*GetDPMSMode)(void);
status_t (*SetDPMSMode)(uint32 dpms_flags);
// Pointers to cursor functions.
@ -82,6 +77,10 @@ extern AccelerantInfo gInfo;
// chips will have no prefix.
//================================================================
#if defined(__cplusplus)
extern "C" {
#endif
// General
status_t InitAccelerant(int fd);
ssize_t AccelerantCloneInfoSize(void);
@ -109,15 +108,15 @@ status_t GetEdidInfo(void* info, size_t size, uint32* _version);
// DPMS
uint32 Savage_DPMSCapabilities(void);
uint32 Savage_DPMSMode(void);
uint32 Savage_GetDPMSMode(void);
status_t Savage_SetDPMSMode(uint32 dpms_flags);
uint32 Trio64_DPMSCapabilities(void);
uint32 Trio64_DPMSMode(void);
uint32 Trio64_GetDPMSMode(void);
status_t Trio64_SetDPMSMode(uint32 dpms_flags);
uint32 Virge_DPMSCapabilities(void);
uint32 Virge_DPMSMode(void);
uint32 Virge_GetDPMSMode(void);
status_t Virge_SetDPMSMode(uint32 dpms_flags);
// Cursor
@ -152,20 +151,25 @@ void Virge_FillSpan(engine_token* et, uint32 color, uint16* list, uint32 count)
void Virge_InvertRectangle(engine_token* et, fill_rect_params* list, uint32 count);
void Virge_ScreenToScreenBlit(engine_token* et, blit_params* list, uint32 count);
#if defined(__cplusplus)
}
#endif
// Prototypes for other functions that are called from source files other than
// where they are defined.
//============================================================================
status_t CreateModeList(bool (*checkMode)(const display_mode* mode));
status_t CreateModeList(bool (*checkMode)(const display_mode* mode),
bool (*getEdid)(edid1_info& edidInfo));
void InitCrtcTimingValues(const DisplayModeEx& mode, int horzScaleFactor, uint8 crtc[],
uint8& cr3b, uint8& cr3c, uint8& cr5d, uint8& cr5e);
bool IsModeUsable(const display_mode* mode);
// Savage functions.
bool Savage_GetEdidInfo(void);
bool Savage_GetEdidInfo(edid1_info& edidInfo);
bool Savage_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask);
void Savage_SetCursorPosition(int x, int y);
@ -185,7 +189,7 @@ void Trio64_SetFunctionPointers(void);
// Virge functions.
bool Virge_GetEdidInfo(void);
bool Virge_GetEdidInfo(edid1_info& edidInfo);
bool Virge_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask);
void Virge_SetCursorPosition(int x, int y);
@ -195,8 +199,4 @@ bool Virge_SetDisplayMode(const DisplayModeEx& mode);
void Virge_SetFunctionPointers(void);
#if defined(__cplusplus)
}
#endif
#endif // _ACCEL_H

View File

@ -9,7 +9,7 @@
#include "accel.h"
status_t
status_t
SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
uint8* andMask, uint8* xorMask)
{
@ -23,8 +23,8 @@ SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
// Update cursor variables appropriately.
SharedInfo& si = *gInfo.sharedInfo;
si.cursor.hot_x = hot_x;
si.cursor.hot_y = hot_y;
si.cursorHotX = hot_x;
si.cursorHotY = hot_y;
if ( ! gInfo.LoadCursorImage(width, height, andMask, xorMask))
return B_ERROR;
@ -34,7 +34,7 @@ SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
}
void
void
MoveCursor(uint16 xPos, uint16 yPos)
{
// Move the cursor to the specified position on the desktop. If we're
@ -72,8 +72,8 @@ MoveCursor(uint16 xPos, uint16 yPos)
MoveDisplay(hds, vds);
// Put cursor in correct physical position.
x -= (hds + si.cursor.hot_x);
y -= (vds + si.cursor.hot_y);
x -= (hds + si.cursorHotX);
y -= (vds + si.cursorHotY);
// Position the cursor on the display.
gInfo.SetCursorPosition(x, y);

View File

@ -3,7 +3,7 @@
This file may be used under the terms of the Be Sample Code License.
Other authors:
Gerald Zajac 2007
Gerald Zajac 2007-2008
*/
#include "accel.h"
@ -12,22 +12,23 @@
static engine_token engineToken = { 1, B_2D_ACCELERATION, NULL };
uint32
uint32
AccelerantEngineCount(void)
{
return 1;
}
status_t
status_t
AcquireEngine(uint32 capabilities, uint32 max_wait,
sync_token* st, engine_token** et)
{
(void)capabilities; // avoid compiler warning for unused arg
(void)max_wait; // avoid compiler warning for unused arg
// Acquire the shared benaphore.
AQUIRE_BEN(gInfo.sharedInfo->engine.lock)
if (gInfo.sharedInfo->engineLock.Acquire() != B_OK)
return B_ERROR;
// Sync if required.
if (st)
SyncToToken(st);
@ -38,37 +39,35 @@ AcquireEngine(uint32 capabilities, uint32 max_wait,
}
status_t
status_t
ReleaseEngine(engine_token* et, sync_token* st)
{
// Update the sync token, if any.
if (st)
GetSyncToken(et, st);
// Release the shared benaphore.
RELEASE_BEN(gInfo.sharedInfo->engine.lock)
gInfo.sharedInfo->engineLock.Release();
return B_OK;
}
void
void
WaitEngineIdle(void)
{
gInfo.WaitIdleEmpty(); // wait until engine is completely idle
}
status_t
status_t
GetSyncToken(engine_token* et, sync_token* st)
{
// Engine count will always be zero: we don't support syncing to token (yet).
st->engine_id = et->engine_id;
st->counter = gInfo.sharedInfo->engine.count;
st->counter = 0;
return B_OK;
}
status_t
status_t
SyncToToken(sync_token* st)
{
(void)st; // avoid compiler warning for unused arg

View File

@ -14,6 +14,8 @@ get_accelerant_hook(uint32 feature, void* data)
{
(void)data; // avoid compiler warning for unused arg
SharedInfo& si = *gInfo.sharedInfo;
switch (feature) {
// General
case B_INIT_ACCELERANT: return (void*)InitAccelerant;
@ -42,13 +44,16 @@ get_accelerant_hook(uint32 feature, void* data)
// DPMS
case B_DPMS_CAPABILITIES: return (void*)(gInfo.DPMSCapabilities);
case B_DPMS_MODE: return (void*)(gInfo.DPMSMode);
case B_DPMS_MODE: return (void*)(gInfo.GetDPMSMode);
case B_SET_DPMS_MODE: return (void*)(gInfo.SetDPMSMode);
// Cursor
case B_SET_CURSOR_SHAPE: return (void*)SetCursorShape;
case B_MOVE_CURSOR: return (void*)MoveCursor;
case B_SHOW_CURSOR: return (void*)(gInfo.ShowCursor);
case B_SET_CURSOR_SHAPE:
return (void*)(si.bDisableHdwCursor ? NULL : SetCursorShape);
case B_MOVE_CURSOR:
return (void*)(si.bDisableHdwCursor ? NULL : MoveCursor);
case B_SHOW_CURSOR:
return (void*)(si.bDisableHdwCursor ? NULL : gInfo.ShowCursor);
// Engine Management
case B_ACCELERANT_ENGINE_COUNT: return (void*)AccelerantEngineCount;
@ -59,10 +64,14 @@ get_accelerant_hook(uint32 feature, void* data)
case B_SYNC_TO_TOKEN: return (void*)SyncToToken;
// 2D acceleration
case B_SCREEN_TO_SCREEN_BLIT: return (void*)(gInfo.ScreenToScreenBlit);
case B_FILL_RECTANGLE: return (void*)(gInfo.FillRectangle);
case B_INVERT_RECTANGLE: return (void*)(gInfo.InvertRectangle);
case B_FILL_SPAN: return (void*)(gInfo.FillSpan);
case B_SCREEN_TO_SCREEN_BLIT:
return (void*)(si.bDisableAccelDraw ? NULL : gInfo.ScreenToScreenBlit);
case B_FILL_RECTANGLE:
return (void*)(si.bDisableAccelDraw ? NULL : gInfo.FillRectangle);
case B_INVERT_RECTANGLE:
return (void*)(si.bDisableAccelDraw ? NULL : gInfo.InvertRectangle);
case B_FILL_SPAN:
return (void*)(si.bDisableAccelDraw ? NULL : gInfo.FillSpan);
}
return NULL; // Return null pointer for any feature not handled above

View File

@ -8,8 +8,9 @@
#include "accel.h"
#include <create_display_modes.h>
#include <create_display_modes.h> // common accelerant header file
#include <string.h>
#include <unistd.h>
void
@ -29,7 +30,7 @@ InitCrtcTimingValues(const DisplayModeEx& mode, int horzScaleFactor, uint8 crtc[
int hDisp_e = (mode.timing.h_display * horzScaleFactor) / 8 - 1;
int hSync_s = (mode.timing.h_sync_start * horzScaleFactor) / 8;
int hSync_e = (mode.timing.h_sync_end * horzScaleFactor) / 8;
int hBlank_s = hDisp_e; // start of horizontal blanking
int hBlank_s = hDisp_e + 1; // start of horizontal blanking
int hBlank_e = hTotal; // end of horizontal blanking
int vTotal = mode.timing.v_total - 2;
@ -39,8 +40,6 @@ InitCrtcTimingValues(const DisplayModeEx& mode, int horzScaleFactor, uint8 crtc[
int vBlank_s = vDisp_e; // start of vertical blanking
int vBlank_e = vTotal; // end of vertical blanking
TRACE("InitCrtcTimingValues()\n");
// CRTC Controller values
crtc[0x00] = hTotal;
@ -146,6 +145,28 @@ FindDisplayMode(int width, int height, int refreshRate, uint32 colorDepth)
}
static bool
IsThereEnoughFBMemory(const display_mode* mode, uint32 bitsPerPixel)
{
// Test if there is enough Frame Buffer memory for the mode and color depth
// specified by the caller, and return true if there is sufficient memory.
uint32 maxWidth = mode->virtual_width;
if (mode->timing.h_display > maxWidth)
maxWidth = mode->timing.h_display;
uint32 maxHeight = mode->virtual_height;
if (mode->timing.v_display > maxHeight)
maxHeight = mode->timing.v_display;
uint32 bytesPerPixel = (bitsPerPixel + 7) / 8;
return (maxWidth * maxHeight * bytesPerPixel < gInfo.sharedInfo->maxFrameBufferSize);
}
bool
IsModeUsable(const display_mode* mode)
{
@ -162,10 +183,9 @@ IsModeUsable(const display_mode* mode)
if ( ! gInfo.GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock))
return false;
// Is there enough memory to handle the mode?
// Is there enough frame buffer memory to handle the mode?
if (mode->virtual_width * mode->virtual_height * ((bitsPerPixel + 7) / 8)
> si.maxFrameBufferSize)
if ( ! IsThereEnoughFBMemory(mode, bitsPerPixel))
return false;
if (mode->timing.pixel_clock > maxPixelClock)
@ -190,42 +210,65 @@ IsModeUsable(const display_mode* mode)
if (mode->timing.h_display == 640 && mode->timing.v_display < 480)
return false;
// In most mode lists, there are three entries for 640 x 480 which have a
// refresh rate of 60 Hz. The one with a pixel clock of 25175 works fine
// with the S3 chips; however, the other two with higher clock rates
// cause the display to be offset down and to the right; thus, reject them.
if (mode->timing.h_display == 640 && mode->timing.v_display == 480) {
int modeRefreshRate = int(((mode->timing.pixel_clock * 1000.0 /
mode->timing.h_total) / mode->timing.v_total) + 0.5);
if (modeRefreshRate == 60 && mode->timing.pixel_clock > 26000)
return false;
}
// If the video is connected directly to an LCD display (ie, laptop
// If the video chip is connected directly to an LCD display (ie, laptop
// 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. Note that this code is not needed under Haiku since it can
// get the preferred mode which should be the resolution of the LCD display.
// LCD display.
#ifndef __HAIKU__
if (si.displayType == MT_LCD && si.panelX > 0 && si.panelY > 0 &&
(mode->timing.h_display > si.panelX
if (si.displayType == MT_LCD && si.panelX > 0 && si.panelY > 0
&& (mode->timing.h_display > si.panelX
|| mode->timing.v_display > si.panelY)) {
return false;
}
#endif // __HAIKU__
return true;
}
status_t
CreateModeList(bool (*checkMode)(const display_mode* mode))
CreateModeList( bool (*checkMode)(const display_mode* mode),
bool (*getEdid)(edid1_info& edidInfo))
{
SharedInfo& si = *gInfo.sharedInfo;
// Obtain EDID info which is needed for for building the mode list.
// However, if a laptop's LCD display is active, bypass getting the EDID
// info since it is not needed, and if the external display supports only
// resolutions smaller than the size of the laptop LCD display, it would
// unnecessarily restrict size of the resolutions that could be set for
// laptop LCD display.
si.bHaveEDID = false;
if (si.displayType != MT_LCD) {
if (getEdid != NULL)
si.bHaveEDID = getEdid(si.edidInfo);
if ( ! si.bHaveEDID) {
S3GetEDID ged;
ged.magic = S3_PRIVATE_DATA_MAGIC;
if (ioctl(gInfo.deviceFileDesc, S3_GET_EDID, &ged, sizeof(ged)) == B_OK) {
if (ged.rawEdid.version.version != 1
|| ged.rawEdid.version.revision > 4) {
TRACE("CreateModeList(); EDID version %d.%d out of range\n",
ged.rawEdid.version.version, ged.rawEdid.version.revision);
} else {
edid_decode(&si.edidInfo, &ged.rawEdid); // decode & save EDID info
si.bHaveEDID = true;
}
}
}
if (si.bHaveEDID) {
#ifdef ENABLE_DEBUG_TRACE
edid_dump(&(si.edidInfo));
#endif
} else {
TRACE("CreateModeList(); Unable to get EDID info\n");
}
}
display_mode* list;
uint32 count = 0;
area_id listArea;
@ -254,9 +297,9 @@ ProposeDisplayMode(display_mode *target, const display_mode *low,
(void)low; // avoid compiler warning for unused arg
(void)high; // avoid compiler warning for unused arg
TRACE("ProposeDisplayMode() clock: %d, width: %d, height: %d, space: 0x%X\n",
target->timing.pixel_clock, target->virtual_width, target->virtual_height,
target->space);
TRACE("ProposeDisplayMode() %dx%d, pixel clock: %d kHz, space: 0x%X\n",
target->timing.h_display, target->timing.v_display,
target->timing.pixel_clock, target->space);
// Search the mode list for the specified mode.
@ -275,6 +318,7 @@ ProposeDisplayMode(display_mode *target, const display_mode *low,
}
status_t
SetDisplayMode(display_mode* pMode)
{
@ -290,27 +334,50 @@ SetDisplayMode(display_mode* pMode)
if ( ! gInfo.GetColorSpaceParams(mode.space, mode.bpp, maxPixelClock))
return B_ERROR;
mode.bytesPerRow = mode.virtual_width * ((mode.bpp + 7) / 8); // use virtual width
if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK)
return B_ERROR;
// Test if there is sufficient memory for this mode. Use the virtual width
// and height for this calculation since one or both might be greater than
// the actual dimensions of the mode.
// Note that for some Savage chips, accelerated drawing is badly messed up
// when the display width is 1400 because 1400 is not evenly divisible by 32.
// For those chips, set the width to 1408 so that accelerated drawing will
// draw properly.
if (mode.bytesPerRow * mode.virtual_height > si.maxFrameBufferSize)
if (mode.timing.h_display == 1400 && (si.chipType == S3_PROSAVAGE
|| si.chipType == S3_PROSAVAGE_DDR
|| si.chipType == S3_TWISTER
|| si.chipType == S3_SUPERSAVAGE
|| si.chipType == S3_SAVAGE2000)) {
mode.timing.h_display = 1408;
mode.virtual_width = 1408;
}
int bytesPerPixel = (mode.bpp + 7) / 8;
mode.bytesPerRow = mode.timing.h_display * bytesPerPixel;
// Is there enough frame buffer memory for this mode?
if ( ! IsThereEnoughFBMemory(&mode, mode.bpp))
return B_ERROR;
TRACE("Display Mode: width = %d, height = %d, depth = %d\n",
TRACE("Set display mode: %dx%d virtual size: %dx%d color depth: %d bpp\n",
mode.timing.h_display, mode.timing.v_display,
mode.virtual_width, mode.virtual_height, mode.bpp);
TRACE("Mode Timing = { %d %d %d %d %d %d %d %d %d 0x%x }\n",
TRACE(" mode timing: %d %d %d %d %d %d %d %d %d\n",
mode.timing.pixel_clock,
mode.timing.h_display, mode.timing.h_sync_start, mode.timing.h_sync_end,
mode.timing.h_display,
mode.timing.h_sync_start, mode.timing.h_sync_end,
mode.timing.h_total,
mode.timing.v_display, mode.timing.v_sync_start, mode.timing.v_sync_end,
mode.timing.v_total, mode.timing.flags);
mode.timing.v_display,
mode.timing.v_sync_start, mode.timing.v_sync_end,
mode.timing.v_total);
TRACE(" mode hFreq: %.1f kHz vFreq: %.1f Hz %chSync %cvSync\n",
double(mode.timing.pixel_clock) / mode.timing.h_total,
((double(mode.timing.pixel_clock) / mode.timing.h_total) * 1000.0)
/ mode.timing.v_total,
(mode.timing.flags & B_POSITIVE_HSYNC) ? '+' : '-',
(mode.timing.flags & B_POSITIVE_VSYNC) ? '+' : '-');
if ( ! gInfo.SetDisplayMode(mode))
return B_ERROR;
@ -379,7 +446,8 @@ GetFrameBufferConfig(frame_buffer_config* pFBC)
pFBC->frame_buffer = (void*)((addr_t)si.videoMemAddr + si.frameBufferOffset);
pFBC->frame_buffer_dma = (void*)((addr_t)si.videoMemPCI + si.frameBufferOffset);
pFBC->bytes_per_row = si.displayMode.bytesPerRow;
uint32 bytesPerPixel = (si.displayMode.bpp + 7) / 8;
pFBC->bytes_per_row = si.displayMode.virtual_width * bytesPerPixel;
return B_OK;
}
@ -418,7 +486,6 @@ GetTimingConstraints(display_timing_constraints *constraints)
{
(void)constraints; // avoid compiler warning for unused arg
TRACE("GetTimingConstraints() called\n");
return B_ERROR;
}
@ -429,8 +496,6 @@ GetPreferredDisplayMode(display_mode* preferredMode)
// If the chip is connected to a laptop LCD panel, find the mode with
// matching width and height, 60 Hz refresh rate, and greatest color depth.
TRACE("GetPreferredDisplayMode()\n");
SharedInfo& si = *gInfo.sharedInfo;
if (si.displayType == MT_LCD) {
@ -452,8 +517,6 @@ GetPreferredDisplayMode(display_mode* preferredMode)
status_t
GetEdidInfo(void* info, size_t size, uint32* _version)
{
TRACE("GetEdidInfo()\n");
SharedInfo& si = *gInfo.sharedInfo;
if ( ! si.bHaveEDID)

View File

@ -40,17 +40,9 @@
// Primary Stream 2 Stride.
#define PRI_STREAM2_STRIDE 0x81b8
#define S3_GLOBAL_GBD_REG 0x816C // global bitmap descriptor register
#define MEMORY_CTRL0_REG 0xCA
#define MEMORY_CONFIG_REG 0x31
// Bitmap descriptor register.
#define S3_GLB_BD_LOW 0x8168
#define S3_GLB_BD_HIGH 0x816C
#define S3_PRI_BD_LOW 0x8170
#define S3_PRI_BD_HIGH 0x8174
#define S3_SEC_BD_LOW 0x8178
#define S3_SEC_BD_HIGH 0x817c
#define MEM_PS1 0x10 // CRCA_4 :Primary stream 1
#define MEM_PS2 0x20 // CRCA_5 :Primary stream 2
@ -73,7 +65,6 @@
#define TILE_FORMAT_LINEAR 0
// BD - BCI enable.
#define BCI_ENABLE 8 // savage4, MX, IX, 3D
#define BCI_ENABLE_TWISTER 0 // twister, prosavage, DDR, supersavage, 2000
@ -81,6 +72,7 @@
#define S3_LITTLE_ENDIAN 0
#define S3_BD64 1
#define BCI_BD_BW_DISABLE 0x10000000
#define BCI_BUFFER_OFFSET 0x10000
#define BCI_GET_PTR vuint32* bci_ptr = ((uint32*)(gInfo.regs + BCI_BUFFER_OFFSET))

View File

@ -27,7 +27,7 @@ Savage_DPMSCapabilities(void)
uint32
Savage_DPMSMode(void)
Savage_GetDPMSMode(void)
{
// Return the current DPMS mode.
@ -59,7 +59,7 @@ Savage_DPMSMode(void)
mode = ((ReadSeqReg(0x31) & 0x10) ? B_DPMS_ON : B_DPMS_OFF);
}
TRACE("Savage_DPMSMode() mode: %d\n", mode);
TRACE("Savage_GetDPMSMode() mode: %d\n", mode);
return mode;
}

View File

@ -25,7 +25,7 @@ Savage_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, ui
(void)et; // avoid compiler warning for unused arg
BCI_CMD_SET_ROP(cmd, 0xCC); // use GXcopy for rop
BCI_CMD_SET_ROP(cmd, 0xF0); // use GXcopy for rop
while (count--) {
int x = pList->left;
@ -38,8 +38,8 @@ Savage_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, ui
gInfo.WaitQueue(7);
BCI_SEND(cmd);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
BCI_SEND(color);
BCI_SEND(BCI_X_Y(x, y));
@ -58,7 +58,7 @@ Savage_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
(void)et; // avoid compiler warning for unused arg
BCI_CMD_SET_ROP(cmd, 0xCC); // use GXcopy for rop
BCI_CMD_SET_ROP(cmd, 0xF0); // use GXcopy for rop
while (count--) {
int y = *pList++;
@ -78,8 +78,8 @@ Savage_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
gInfo.WaitQueue(7);
BCI_SEND(cmd);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
BCI_SEND(color);
BCI_SEND(BCI_X_Y(x, y));
@ -109,8 +109,8 @@ Savage_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count)
gInfo.WaitQueue(7);
BCI_SEND(cmd);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
BCI_SEND(BCI_X_Y(x, y));
BCI_SEND(BCI_W_H(w, h));
@ -157,17 +157,17 @@ Savage_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count)
BCI_SEND(cmd);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
BCI_SEND(BCI_X_Y(src_x, src_y));
BCI_SEND(BCI_X_Y(dest_x, dest_y));
BCI_SEND(BCI_W_H(width + 1, height + 1));
pList ++;
pList++;
}
}

View File

@ -50,7 +50,7 @@ SetI2CSignals(void* cookie, int _clock, int data)
bool
Savage_GetEdidInfo(void)
Savage_GetEdidInfo(edid1_info& edidInfo)
{
// Get the EDID info and return true if successful.
@ -83,17 +83,8 @@ Savage_GetEdidInfo(void)
uint8 tmp = ReadCrtcReg(DDCPort);
WriteCrtcReg(DDCPort, tmp | 0x13);
si.bHaveEDID = (ddc2_read_edid1(&bus, &(si.edidInfo), NULL, NULL) == B_OK);
bool bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK);
WriteCrtcReg(DDCPort, tmp);
if (si.bHaveEDID) {
#ifdef ENABLE_DEBUG_TRACE
edid_dump(&(si.edidInfo));
#endif
} else {
TRACE("Savage_GetEdidInfo() failed!\n");
}
return si.bHaveEDID;
return bResult;
}

View File

@ -95,23 +95,6 @@ WaitIdleEmpty2K()
}
static bool
IsLCDWidthValid(int width)
{
// Search the array of valid LCD widths to find a width that matches the
// width by the caller, and return true if a match is found.
const int lcdWidths[] = { 640, 800, 1024, 1152, 1280, 1400, 1440, 1600, 1680 };
for (int i = 0; i < NUM_ELEMENTS(lcdWidths); i++) {
if (lcdWidths[i] == width)
return true;
}
return false; // match not found
}
static void
Savage_GetPanelInfo()
{
@ -132,20 +115,12 @@ Savage_GetPanelInfo()
int panelX = (ReadSeqReg(0x61) + ((ReadSeqReg(0x66) & 0x02) << 7) + 1) * 8;
int panelY = ReadSeqReg(0x69) + ((ReadSeqReg(0x6e) & 0x70) << 4) + 1;
if ( ! IsLCDWidthValid(panelX)) {
// A Savage IX/MV in a Thinkpad T22 or SuperSavage in a Thinkpad T23 with
// a 1400x1050 display will return a width of 1408; thus, in this case,
// set the width to the correct value of 1400.
// 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 ( ! IsLCDWidthValid(panelX)) {
TRACE("%dx%d LCD panel width invalid.\n", panelX + 8, panelY);
si.displayType = MT_CRT;
return;
}
}
if (panelX == 1408)
panelX = 1400;
char* sTechnology;
@ -199,7 +174,7 @@ Savage_Init(void)
static uint8 RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
static const uint8 RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
static const uint8 RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
int ramSizeMB = 0; // memory size in megabytes
uint32 ramSizeMB = 0; // memory size in megabytes
uint8 cr36 = ReadCrtcReg(0x36); // get amount of video ram
@ -239,57 +214,37 @@ Savage_Init(void)
break;
}
TRACE("Savage_Init() memory size: %d MB\n", ramSizeMB);
uint32 usableMB = ramSizeMB;
if (ramSizeMB <= 0)
// If a Savage MX chip has > 8 MB, clamp it at 8 MB since memory for the
// hardware cursor above 8 MB is unusable.
if (si.chipType == S3_SAVAGE_MX && ramSizeMB > 8)
usableMB = 8;
TRACE("Savage_Init() memory size: %d MB, usable memory: %d MB\n", ramSizeMB, usableMB);
if (usableMB <= 0)
return B_ERROR;
si.videoMemSize = ramSizeMB * 1024 * 1024;
// Certain Savage4 and ProSavage chips can have coherency problems
// with respect to the Command Overflow Buffer (COB); thus, to avoid
// problems with these chips, set bDisableCOB to true.
si.bDisableCOB = false;
si.videoMemSize = usableMB * 1024 * 1024;
// Compute the Command Overflow Buffer (COB) location.
if ((S3_SAVAGE4_SERIES(si.chipType) || S3_SUPERSAVAGE == si.chipType)
&& si.bDisableCOB) {
// The Savage4 and ProSavage have COB coherency bugs which render
// the buffer useless.
si.cobIndex = 0;
si.cobSize = 0;
si.bciThresholdHi = 32;
si.bciThresholdLo = 0;
} else {
// We use 128kB for the COB on all other chips.
si.cobSize = 0x20000;
if (S3_SAVAGE_3D_SERIES(si.chipType) || si.chipType == S3_SAVAGE2000)
si.cobIndex = 7; // rev.A savage4 apparently also uses 7
else
si.cobIndex = 2;
// Max command size: 2560 entries.
si.bciThresholdHi = si.cobSize / 4 + 32 - 2560;
si.bciThresholdLo = si.bciThresholdHi - 2560;
}
uint32 cobSize = 0x20000; // use 128kB for the COB
si.cobSizeIndex = 7;
// Note that the X.org developers stated that the command overflow buffer
// (COB) must END at a 4MB boundary which for all practical purposes means
// the very end of the video memory. The cursor must be at the beginning
// of the video memory. It had been tried immediately preceding the COB,
// but the Savage MX chip screws up the cursor in that case.
// the very end of the video memory.
si.cobOffset = (si.videoMemSize - si.cobSize) & ~0x1ffff; // align cob to 128k
si.cursorOffset = 0;
si.frameBufferOffset = si.cursorOffset + CURSOR_BYTES;
si.maxFrameBufferSize = si.cobOffset - si.frameBufferOffset;
si.cobOffset = (si.videoMemSize - cobSize) & ~0x1ffff; // align cob to 128k
si.cursorOffset = (si.cobOffset - CURSOR_BYTES) & ~0xfff; // align to 4k boundary
si.frameBufferOffset = 0;
si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset;
TRACE("cobIndex: %d cobSize: %d cobOffset: 0x%x\n", si.cobIndex, si.cobSize, si.cobOffset);
TRACE("cobSizeIndex: %d cobSize: %d cobOffset: 0x%x\n", si.cobSizeIndex, cobSize, si.cobOffset);
TRACE("cursorOffset: 0x%x frameBufferOffset: 0x%x\n", si.cursorOffset, si.frameBufferOffset);
// Reset graphics engine to avoid memory corruption.
@ -340,13 +295,12 @@ Savage_Init(void)
si.colorSpaces[2] = B_RGB32;
si.colorSpaceCount = 3;
// Get info about the display capabilities (EDID).
Savage_GetEdidInfo();
si.bDisableHdwCursor = false; // allow use of hardware cursor
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
// Setup the mode list.
return CreateModeList(IsModeUsable);
return CreateModeList(IsModeUsable, Savage_GetEdidInfo);
}
@ -379,7 +333,7 @@ Savage_SetFunctionPointers(void)
}
gInfo.DPMSCapabilities = Savage_DPMSCapabilities;
gInfo.DPMSMode = Savage_DPMSMode;
gInfo.GetDPMSMode = Savage_GetDPMSMode;
gInfo.SetDPMSMode = Savage_SetDPMSMode;
gInfo.LoadCursorImage = Savage_LoadCursorImage;

View File

@ -1,7 +1,8 @@
/*
Haiku S3 Savage driver adapted from the X.org Savage driver.
Copyright 1995-1997 The XFree86 Project, Inc.
Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
Copyright (c) 2003-2006, X.Org Foundation
Copyright 2007-2008 Haiku, Inc. All rights reserved.
Distributed under the terms of the MIT license.
@ -21,9 +22,9 @@
struct SavageRegRec {
uint8 CRTC[25]; // Crtc Controller reg's
uint8 SR12, SR13, SR15, SR18, SR1B, SR29;
uint8 CR31, CR33, CR34, CR3A, CR3B, CR3C;
uint8 CR40, CR42, CR43, CR45;
uint8 SR12, SR13, SR1B, SR29;
uint8 CR33, CR34, CR3A, CR3B, CR3C;
uint8 CR42, CR43, CR45;
uint8 CR50, CR51, CR53, CR58, CR5D, CR5E;
uint8 CR65, CR66, CR67, CR69;
uint8 CR86, CR88;
@ -32,15 +33,12 @@ struct SavageRegRec {
static void
Savage_SetGBD_Twister(const DisplayModeEx& mode)
{
SharedInfo& si = *gInfo.sharedInfo;
int bci_enable;
TRACE("Savage_SetGBD_Twister()\n");
if (si.chipType == S3_SAVAGE4)
bci_enable = BCI_ENABLE;
else
@ -68,12 +66,7 @@ Savage_SetGBD_Twister(const DisplayModeEx& mode)
WriteCrtcReg(0x69, 0x80, 0x80);
WriteReg32(0x8128, 0xFFFFFFFFL);
WriteReg32(0x812C, 0xFFFFFFFFL);
WriteReg32(S3_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
// If MS1NB style linear tiling mode.
// bit MM850C[15] = 0 select NB linear tile mode.
@ -82,45 +75,6 @@ Savage_SetGBD_Twister(const DisplayModeEx& mode)
uint32 ulTmp = ReadReg32(ADVANCED_FUNC_CTRL) | 0x8000; // use MS-s style tile mode
WriteReg32(ADVANCED_FUNC_CTRL, ulTmp);
// Set up Tiled Surface Registers
// Bit 25:20 - Surface width in tiles.
// Bit 29 - Y Range Flag.
// Bit 31:30 = 00, 4 bpp.
// = 01, 8 bpp.
// = 10, 16 bpp.
// = 11, 32 bpp.
// Global Bitmap Descriptor Register MM816C - twister/prosavage
// bit 24~25: tile format
// 00: linear
// 01: destination tiling format
// 10: texture tiling format
// 11: reserved
// bit 28: block write disble/enable
// 0: disable
// 1: enable
// Global Bitmap Descriptor Register MM816C - savage4
// bit 24~25: tile format
// 00: linear
// 01: reserved
// 10: 16 bpp tiles
// 11: 32 bpp tiles
// bit 28: block write disable/enable
// 0: enable
// 1: disable
// Do not enable block_write even for non-tiling modes, because
// the driver cannot determine if the memory type is the certain
// type of SGRAM for which block_write can be used.
si.GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR; // linear
si.GlobalBD.bd1.HighPart.ResBWTile |= 0x10; // disable block write
// HW uses width.
si.GlobalBD.bd1.HighPart.Stride = (uint16)(mode.timing.h_display); // number of pixels per line
si.GlobalBD.bd1.HighPart.Bpp = (uint8)(mode.bpp);
si.GlobalBD.bd1.Offset = si.frameBufferOffset;
// CR88, bit 4 - Block write enabled/disabled.
//
// Note: Block write must be disabled when writing to tiled
@ -128,28 +82,12 @@ Savage_SetGBD_Twister(const DisplayModeEx& mode)
// write should only be enabled for certain types of SGRAM.
WriteCrtcReg(0x88, DISABLE_BLOCK_WRITE_2D, DISABLE_BLOCK_WRITE_2D);
// CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
// bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
// at A000:0.
WriteCrtcReg(MEMORY_CONFIG_REG, 0x00, 0x01);
// Program the GBD and SBD's.
WriteReg32(S3_GLB_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_GLB_BD_HIGH, si.GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
WriteReg32(S3_PRI_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_PRI_BD_HIGH, si.GlobalBD.bd2.HiPart);
}
static void
Savage_SetGBD_3D(const DisplayModeEx& mode)
{
TRACE("Savage_SetGBD_3D()\n");
SharedInfo& si = *gInfo.sharedInfo;
int bci_enable = BCI_ENABLE;
// MM81C0 and 81C4 are used to control primary stream.
@ -174,12 +112,7 @@ Savage_SetGBD_3D(const DisplayModeEx& mode)
WriteCrtcReg(0x69, 0x80, 0x80);
WriteReg32(0x8128, 0xFFFFFFFFL);
WriteReg32(0x812C, 0xFFFFFFFFL);
WriteReg32(S3_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
// If MS1NB style linear tiling mode.
// bit MM850C[15] = 0 select NB linear tile mode.
@ -188,36 +121,6 @@ Savage_SetGBD_3D(const DisplayModeEx& mode)
uint32 ulTmp = ReadReg32(ADVANCED_FUNC_CTRL) | 0x8000; // use MS-s style tile mode
WriteReg32(ADVANCED_FUNC_CTRL, ulTmp);
// Tiled Surface 0 Registers MM48C40:
// bit 0~23: tile surface 0 frame buffer offset
// bit 24~29:tile surface 0 width
// bit 30~31:tile surface 0 bits/pixel
// 00: reserved
// 01, 8 bits
// 10, 16 Bits.
// 11, 32 Bits.
// Global Bitmap Descriptor Register MM816C
// bit 24~25: tile format
// 00: linear
// 01: reserved
// 10: 16 bpp tiles
// 11: 32 bpp tiles
// bit 28: block write disable/enable
// 0: enable
// 1: disable
// Do not enable block_write even for non-tiling modes, because
// the driver cannot determine if the memory type is the certain
// type of SGRAM for which block_write can be used.
si.GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR; // linear
si.GlobalBD.bd1.HighPart.ResBWTile |= 0x10; // disable block write
// HW uses width.
si.GlobalBD.bd1.HighPart.Stride = (uint16)(mode.timing.h_display); // number of pixels per line
si.GlobalBD.bd1.HighPart.Bpp = (uint8)(mode.bpp);
si.GlobalBD.bd1.Offset = si.frameBufferOffset;
// CR88, bit 4 - Block write enabled/disabled.
//
// Note: Block write must be disabled when writing to tiled
@ -225,26 +128,12 @@ Savage_SetGBD_3D(const DisplayModeEx& mode)
// write should only be enabled for certain types of SGRAM.
WriteCrtcReg(0x88, DISABLE_BLOCK_WRITE_2D, DISABLE_BLOCK_WRITE_2D);
// CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
// bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
// at A000:0.
WriteCrtcReg(MEMORY_CONFIG_REG, 0x00, 0x01);
// Program the GBD and SBD's.
WriteReg32(S3_GLB_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_GLB_BD_HIGH, si.GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
WriteReg32(S3_PRI_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_PRI_BD_HIGH, si.GlobalBD.bd2.HiPart);
}
static void
Savage_SetGBD_MX(const DisplayModeEx& mode)
{
TRACE("Savage_SetGBD_MX()\n");
SharedInfo& si = *gInfo.sharedInfo;
int bci_enable = BCI_ENABLE;
@ -285,12 +174,7 @@ Savage_SetGBD_MX(const DisplayModeEx& mode)
(((mode.bytesPerRow * 2) << 16) & 0x3FFF0000) |
(mode.bytesPerRow & 0x00003fff));
WriteReg32(0x8128, 0xFFFFFFFFL);
WriteReg32(0x812C, 0xFFFFFFFFL);
WriteReg32(S3_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
// CR78, bit 3 - Block write enabled(1)/disabled(0).
// bit 2 - Block write cycle time(0:2 cycles,1: 1 cycle)
@ -299,60 +183,12 @@ Savage_SetGBD_MX(const DisplayModeEx& mode)
// write should only be enabled for certain types of SGRAM.
WriteCrtcReg(0x78, 0xfb, 0xfb);
// Tiled Surface 0 Registers MM48C40:
// bit 0~23: tile surface 0 frame buffer offset
// bit 24~29:tile surface 0 width
// bit 30~31:tile surface 0 bits/pixel
// 00: reserved
// 01, 8 bits
// 10, 16 Bits.
// 11, 32 Bits.
// Global Bitmap Descriptor Register MM816C
// bit 24~25: tile format
// 00: linear
// 01: reserved
// 10: 16 bit
// 11: 32 bit
// bit 28: block write disble/enable
// 0: enable
// 1: disable
// Do not enable block_write even for non-tiling modes, because
// the driver cannot determine if the memory type is the certain
// type of SGRAM for which block_write can be used.
si.GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR; // linear
si.GlobalBD.bd1.HighPart.ResBWTile |= 0x10; // disable block write
// HW uses width.
si.GlobalBD.bd1.HighPart.Stride = (uint16)(mode.timing.h_display); // number of pixels per line
si.GlobalBD.bd1.HighPart.Bpp = (uint8)(mode.bpp);
si.GlobalBD.bd1.Offset = si.frameBufferOffset;
// CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
// bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
// at A000:0.
WriteCrtcReg(MEMORY_CONFIG_REG, 0x04, 0x05); // CR31
// Program the GBD and SBD's.
WriteReg32(S3_GLB_BD_LOW, si.GlobalBD.bd2.LoPart );
// 8: bci enable.
WriteReg32(S3_GLB_BD_HIGH, (si.GlobalBD.bd2.HiPart
| bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
WriteReg32(S3_PRI_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_PRI_BD_HIGH, si.GlobalBD.bd2.HiPart);
WriteReg32(S3_SEC_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_SEC_BD_HIGH, si.GlobalBD.bd2.HiPart);
}
static void
Savage_SetGBD_Super(const DisplayModeEx& mode)
{
TRACE("Savage_SetGBD_Super()\n");
SharedInfo& si = *gInfo.sharedInfo;
int bci_enable = BCI_ENABLE_TWISTER;
@ -395,47 +231,14 @@ Savage_SetGBD_Super(const DisplayModeEx& mode)
WriteReg32(PRI_STREAM2_FBUF_ADDR0, (si.frameBufferOffset & 0xfffffffc) | 0x80000000);
WriteReg32(PRI_STREAM2_FBUF_ADDR1, si.frameBufferOffset & 0xfffffffc);
WriteReg32(0x8128, 0xFFFFFFFFL);
WriteReg32(0x812C, 0xFFFFFFFFL);
// Bit 28:block write disable.
WriteReg32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
// Do not enable block_write even for non-tiling modes, because
// the driver cannot determine if the memory type is the certain
// type of SGRAM for which block_write can be used.
si.GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR; // linear
si.GlobalBD.bd1.HighPart.ResBWTile |= 0x10; // disable block write
// HW uses width.
si.GlobalBD.bd1.HighPart.Stride = (uint16)(mode.timing.h_display); // number of pixels per line
si.GlobalBD.bd1.HighPart.Bpp = (uint8)(mode.bpp);
si.GlobalBD.bd1.Offset = si.frameBufferOffset;
// CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
// bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
// at A000:0.
WriteCrtcReg(MEMORY_CONFIG_REG, 0x00, 0x01);
// Program the GBD and SBDs.
WriteReg32(S3_GLB_BD_LOW, si.GlobalBD.bd2.LoPart );
WriteReg32(S3_GLB_BD_HIGH, (si.GlobalBD.bd2.HiPart
| bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
WriteReg32(S3_PRI_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_PRI_BD_HIGH, si.GlobalBD.bd2.HiPart);
WriteReg32(S3_SEC_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_SEC_BD_HIGH, si.GlobalBD.bd2.HiPart);
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_BD64 | 0x10000000);
}
static void
Savage_SetGBD_2000(const DisplayModeEx& mode)
{
TRACE("Savage_SetGBD_2000()\n");
SharedInfo& si = *gInfo.sharedInfo;
int bci_enable = BCI_ENABLE_TWISTER;
@ -463,47 +266,18 @@ Savage_SetGBD_2000(const DisplayModeEx& mode)
WriteCrtcReg(0x67, 0x08, 0x08);
WriteReg32(0x8128, 0xFFFFFFFFL);
WriteReg32(0x812C, 0xFFFFFFFFL);
// Bit 28:block write disable.
WriteReg32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_BD64 | 0x10000000);
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
WriteCrtcReg(0x73, 0x00, 0x20); // CR73 bit 5 = 0 block write disable
// Do not enable block_write even for non-tiling modes, because
// the driver cannot determine if the memory type is the certain
// type of SGRAM for which block_write can be used.
si.GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR; // linear
si.GlobalBD.bd1.HighPart.ResBWTile |= 0x10; // disable block write
// HW uses width.
si.GlobalBD.bd1.HighPart.Stride = (uint16)(mode.timing.h_display); // number of pixels per line
si.GlobalBD.bd1.HighPart.Bpp = (uint8)(mode.bpp);
si.GlobalBD.bd1.Offset = si.frameBufferOffset;
// CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
// bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
// at A000:0.
WriteCrtcReg(MEMORY_CONFIG_REG, 0x00, 0x01);
// Program the GBD and SBDs.
WriteReg32(S3_GLB_BD_LOW, si.GlobalBD.bd2.LoPart );
WriteReg32(S3_GLB_BD_HIGH, (si.GlobalBD.bd2.HiPart
| bci_enable | S3_LITTLE_ENDIAN | S3_BD64));
WriteReg32(S3_PRI_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_PRI_BD_HIGH, si.GlobalBD.bd2.HiPart);
WriteReg32(S3_SEC_BD_LOW, si.GlobalBD.bd2.LoPart);
WriteReg32(S3_SEC_BD_HIGH, si.GlobalBD.bd2.HiPart);
}
static void
Savage_SetGBD(const DisplayModeEx& mode)
{
TRACE("Savage_SetGBD()\n");
SharedInfo& si = *gInfo.sharedInfo;
VerticalRetraceWait();
@ -531,19 +305,27 @@ Savage_SetGBD(const DisplayModeEx& mode)
Savage_SetGBD_2000(mode);
break;
}
WriteCrtcReg(0x50, 0xc1, 0xc1); // CR50, bit 7,6,0 = 111, Use GBD
// Set up the Global Bitmap Descriptor used for BCI.
// Do not enable block_write because we can't determine if the memory
// type is a certain type of SGRAM for which block write can be used.
// bit 24~25: tile format, 00 = linear
// bit 28: block write disble/enable, 0 = disable, 1 = enable
si.globalBitmapDesc = mode.timing.h_display | (mode.bpp << 16)
| TILE_FORMAT_LINEAR | BCI_BD_BW_DISABLE | S3_BD64; // disable block write
}
static void
Savage_Initialize2DEngine(const DisplayModeEx& mode)
{
TRACE("Savage_Initialize2DEngine()\n");
SharedInfo& si = *gInfo.sharedInfo;
uint32 thresholds;
WriteCrtcReg(0x40, 0x01);
WriteCrtcReg(0x31, 0x0c);
WriteCrtcReg(0x40, 0x01); // enable graphics engine
WriteCrtcReg(0x31, 0x0c); // turn on 16-bit register access
// Setup plane masks.
WriteReg32(0x8128, ~0); // enable all write planes
@ -555,14 +337,16 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
case S3_SAVAGE_3D:
case S3_SAVAGE_MX:
// Disable BCI.
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0);
// Setup BCI command overflow buffer.
WriteReg32(0x48C14, (si.cobOffset >> 11) | (si.cobIndex << 29)); // tim
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0); // Disable BCI
// Setup BCI command overflow buffer. 0x48c14
// Bits 0-11 = Bits 22-11 of the Command Buffer Offset.
// Bits 12-28 = Total number of entries in the command buffer(Read only).
// Bits 29-31 = COB size index, 111 = 32K entries or 128K bytes
WriteReg32(0x48C14, (si.cobOffset >> 11) | (si.cobSizeIndex << 29));
// Program shadow status update.
thresholds = ((si.bciThresholdLo & 0xffff) << 16) |
(si.bciThresholdHi & 0xffff);
WriteReg32(0x48C10, thresholds);
WriteReg32(0x48C10, 0x78207220);
WriteReg32(0x48C0C, 0);
// Enable BCI and command overflow buffer.
@ -575,23 +359,14 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
case S3_PROSAVAGE_DDR:
case S3_SUPERSAVAGE:
// Disable BCI.
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0);
if ( ! si.bDisableCOB) {
// Setup BCI command overflow buffer.
WriteReg32(0x48C14, (si.cobOffset >> 11) | (si.cobIndex << 29));
}
// Program shadow status update; AGD: what should this be?
thresholds = ((si.bciThresholdLo & 0x1fffe0) << 11)
| ((si.bciThresholdHi & 0x1fffe0) >> 5);
WriteReg32(0x48C10, thresholds);
// Some Savage4 and ProSavage chips have coherency problems with
// respect to the Command Overflow Buffer (COB); thus, do not
// enable the COB.
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0); // Disable BCI
WriteReg32(0x48C10, 0x00700040);
WriteReg32(0x48C0C, 0);
if (si.bDisableCOB)
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x08); // enable BCI without COB
else
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x0C); // enable BCI with COB
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x08); // enable BCI without COB
break;
@ -600,23 +375,17 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
// Disable BCI.
WriteReg32(0x48C18, 0);
// Setup BCI command overflow buffer.
WriteReg32(0x48C18, (si.cobOffset >> 7) | (si.cobIndex));
WriteReg32(0x48C18, (si.cobOffset >> 7) | (si.cobSizeIndex));
// Disable shadow status update.
WriteReg32(0x48A30, 0);
// Enable BCI and command overflow buffer.
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x00280000 );
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x00280000);
break;
}
// Use and set global bitmap descriptor.
// For reasons I do not fully understand yet, on the Savage4, the
// write to the GBD register, MM816C, does not "take" at this time.
// Only the low-order byte is acknowledged, resulting in an incorrect
// stride. Writing the register later, after the mode switch, works
// correctly. This needs to get resolved.
Savage_SetGBD(mode);
}
@ -624,8 +393,6 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
static void
Savage_GEReset(const DisplayModeEx& mode)
{
TRACE("Savage_GEReset() begin\n");
gInfo.WaitIdleEmpty();
snooze(10000);
@ -665,7 +432,7 @@ Savage_GEReset(const DisplayModeEx& mode)
break;
snooze(10000);
TRACE("Restarting S3 graphics engine reset %2d ...\n", r);
TRACE("Savage_GEReset(), restarting S3 graphics engine reset %2d ...\n", r);
}
// At this point, the FIFO is empty and the engine is idle.
@ -678,8 +445,6 @@ Savage_GEReset(const DisplayModeEx& mode)
WriteReg32(MONO_PAT_1, ~0);
Savage_SetGBD(mode);
TRACE("Savage_GEReset() end\n");
}
@ -739,7 +504,7 @@ Savage_CalcClock(long freq, int min_m,
static void
Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
{
TRACE("Savage_WriteMode() enter\n");
TRACE("Savage_WriteMode() begin\n");
SharedInfo& si = *gInfo.sharedInfo;
@ -756,7 +521,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
if (ReadCrtcReg(0x66) & 0x01) {
Savage_GEReset(mode); // reset GE to make sure nothing is going on
}
WriteCrtcReg(0x67, regRec.CR67 & ~0x0e); // no STREAMS yet old and new
// Set register SR19 to zero so that the ProSavage chips will start up
@ -769,7 +534,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
// not cleared, it will startup only if booting under BeOS using the
// default boot screen or the boot screen resolution matches the resolution
// of the mode currently being set.
if (si.chipType == S3_SAVAGE_MX)
WriteSeqReg(0x30, 0x00, 0x08);
@ -777,14 +542,20 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
WriteCrtcReg(0x66, regRec.CR66);
WriteCrtcReg(0x3a, regRec.CR3A);
WriteCrtcReg(0x31, regRec.CR31);
WriteCrtcReg(0x58, regRec.CR58);
WriteCrtcReg(0x53, regRec.CR53 & 0x7f);
// Set DCLK registers.
// If Savage IX/MX or SuperSavage, set SR54 & SR56 to 0x10 so that when
// resolutions are set where the width and/or height is less than the
// native resolution of the attached LCD display, the chip will not expand
// the display to fill the screen. That is, if a resolution is set to
// 640x480, it will use only 640x480 pixels for the display. When the chip
// expands the display, text is much less readable.
WriteSeqReg(0x29, regRec.SR29);
WriteSeqReg(0x15, regRec.SR15);
if (S3_SAVAGE_MOBILE_SERIES(si.chipType)) {
WriteSeqReg(0x54, 0x10);
WriteSeqReg(0x56, 0x10);
}
// Set the standard CRTC vga regs.
@ -818,7 +589,6 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
// Other mode timing and extended regs.
WriteCrtcReg(0x34, regRec.CR34);
WriteCrtcReg(0x40, regRec.CR40);
WriteCrtcReg(0x42, regRec.CR42);
WriteCrtcReg(0x45, regRec.CR45);
WriteCrtcReg(0x50, regRec.CR50);
@ -837,22 +607,21 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
if (si.chipType == S3_SAVAGE4)
WriteCrtcReg(0xb0, regRec.CRB0);
// Set extended seq regs for dclk.
WriteSeqReg(0x12, regRec.SR12);
WriteSeqReg(0x13, regRec.SR13);
WriteSeqReg(0x29, regRec.SR29);
WriteSeqReg(0x18, regRec.SR18);
WriteSeqReg(0x1b, regRec.SR1B);
// Load new m, n pll values for dclk & mclk.
temp = ReadSeqReg(0x15) & ~0x21;
if ( ! (S3_SAVAGE_MOBILE_SERIES(si.chipType) && si.displayType == MT_LCD)) {
// Set extended seq regs for dclk.
WriteSeqReg(0x12, regRec.SR12);
WriteSeqReg(0x13, regRec.SR13);
WriteSeqReg(0x29, regRec.SR29);
WriteSeqReg(0x15, temp | 0x03);
WriteSeqReg(0x15, temp | 0x23);
WriteSeqReg(0x15, temp | 0x03);
WriteSeqReg(0x15, regRec.SR15);
snooze( 100 );
// Load new m, n pll values for dclk & mclk.
temp = ReadSeqReg(0x15) & ~0x20;
WriteSeqReg(0x15, temp);
WriteSeqReg(0x15, temp | 0x20);
WriteSeqReg(0x15, temp);
snooze(100);
}
// Now write out cr67 in full, possibly starting STREAMS.
VerticalRetraceWait();
@ -874,7 +643,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
Savage_SetGBD(mode);
TRACE("Savage_WriteMode() end\n");
TRACE("Savage_WriteMode() done\n");
return;
}
@ -883,7 +652,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
static bool
Savage_ModeInit(const DisplayModeEx& mode)
{
TRACE("Savage_ModeInit(%dx%d, %dHz)\n",
TRACE("Savage_ModeInit(%dx%d, %d kHz)\n",
mode.timing.h_display, mode.timing.v_display, mode.timing.pixel_clock);
SharedInfo& si = *gInfo.sharedInfo;
@ -896,7 +665,7 @@ Savage_ModeInit(const DisplayModeEx& mode)
InitCrtcTimingValues(mode, horizScaleFactor, regRec.CRTC,
regRec.CR3B, regRec.CR3C, regRec.CR5D, regRec.CR5E);
regRec.CRTC[23] = 0xEB;
regRec.CRTC[0x17] = 0xEB;
int dclk = mode.timing.pixel_clock;
regRec.CR67 = 0x00;
@ -930,25 +699,14 @@ Savage_ModeInit(const DisplayModeEx& mode)
break;
}
// Use traditional register-crunching to set mode.
regRec.CR3A = (ReadCrtcReg(0x3a) & 0x7f) | 0x15;
regRec.CR53 = 0x00;
regRec.CR31 = 0x8c;
regRec.CR66 = 0x89;
regRec.CR58 = (ReadCrtcReg(0x58) & 0x80) | 0x13;
if (si.chipType == S3_SAVAGE2000)
regRec.SR15 = 0x02;
else
regRec.SR15 = 0x83;
regRec.SR18 = 0x00;
regRec.SR1B = ReadSeqReg(0x1b) | 0x10; // enable 8-bit Color Lookup Table
regRec.CR43 = regRec.CR45 = regRec.CR65 = 0x00;
regRec.CR40 = ReadCrtcReg(0x40) & ~0x01;
unsigned int m, n, r;
Savage_CalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r);
@ -997,7 +755,6 @@ Savage_ModeInit(const DisplayModeEx& mode)
else
regRec.CR33 = 0x08;
regRec.CR67 |= 1;
regRec.CR69 = 0;
regRec.CR86 = ReadCrtcReg(0x86) | 0x08;
regRec.CR88 = ReadCrtcReg(0x88) | DISABLE_BLOCK_WRITE_2D;
@ -1027,6 +784,7 @@ Savage_SetDisplayMode(const DisplayModeEx& mode)
Savage_AdjustFrame(mode);
WriteSeqReg(0x01, 0x00, 0x20); // unblank the screen
return true;
}

View File

@ -26,7 +26,7 @@ Trio64_DPMSCapabilities(void)
uint32
Trio64_DPMSMode(void)
Trio64_GetDPMSMode(void)
{
// Return the current DPMS mode.
@ -53,7 +53,7 @@ Trio64_DPMSMode(void)
TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
}
TRACE("Trio64_DPMSMode() mode: %d\n", mode);
TRACE("Trio64_GetDPMSMode() mode: %d\n", mode);
return mode;
}

View File

@ -136,9 +136,12 @@ Trio64_Init(void)
si.colorSpaces[1] = B_RGB16;
si.colorSpaceCount = 2;
si.bDisableHdwCursor = false; // allow use of hardware cursor
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
// Setup the mode list.
return CreateModeList(Trio64_IsModeUsable);
return CreateModeList(Trio64_IsModeUsable, NULL);
}
@ -152,7 +155,7 @@ Trio64_SetFunctionPointers(void)
gInfo.WaitIdleEmpty = WaitIdle;
gInfo.DPMSCapabilities = Trio64_DPMSCapabilities;
gInfo.DPMSMode = Trio64_DPMSMode;
gInfo.GetDPMSMode = Trio64_GetDPMSMode;
gInfo.SetDPMSMode = Trio64_SetDPMSMode;
gInfo.LoadCursorImage = Trio64_LoadCursorImage;

View File

@ -130,7 +130,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
break;
}
bool bEnableAccelFuncs = true;
bool bDisableAccelFuncs = false;
switch (mode.timing.h_display) {
case 640:
@ -152,7 +152,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
cr50 |= 0x81;
break;
default:
bEnableAccelFuncs = false; // use app_server default accel functions
bDisableAccelFuncs = true; // use app_server default accel functions
break;
}
@ -167,20 +167,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
// only with the display widths defined in the above switch statement. For
// the other widths, the default functions in the app_server will be used.
if (bEnableAccelFuncs)
{
gInfo.FillRectangle = Trio64_FillRectangle;
gInfo.FillSpan = Trio64_FillSpan;
gInfo.InvertRectangle = Trio64_InvertRectangle;
gInfo.ScreenToScreenBlit = Trio64_ScreenToScreenBlit;
}
else
{
gInfo.FillRectangle = NULL;
gInfo.FillSpan = NULL;
gInfo.InvertRectangle = NULL;
gInfo.ScreenToScreenBlit = NULL;
}
si.bDisableAccelDraw = bDisableAccelFuncs;
// Set the standard CRTC vga regs.

View File

@ -26,7 +26,7 @@ Virge_DPMSCapabilities(void)
uint32
Virge_DPMSMode(void)
Virge_GetDPMSMode(void)
{
// Return the current DPMS mode.
@ -53,7 +53,7 @@ Virge_DPMSMode(void)
TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
}
TRACE("Virge_DPMSMode() mode: %d\n", mode);
TRACE("Virge_GetDPMSMode() mode: %d\n", mode);
return mode;
}

View File

@ -80,13 +80,13 @@ SetI2CSignals(void* cookie, int _clock, int data)
bool
Virge_GetEdidInfo(void)
Virge_GetEdidInfo(edid1_info& edidInfo)
{
// Get the EDID info and return true if successful.
SharedInfo& si = *gInfo.sharedInfo;
si.bHaveEDID = false;
bool bResult = false;
if (si.chipType == S3_TRIO_3D_2X) {
uint32 DDCPort = 0xAA;
@ -100,7 +100,7 @@ Virge_GetEdidInfo(void)
uint8 tmp = ReadCrtcReg(DDCPort);
WriteCrtcReg(DDCPort, tmp | 0x13);
si.bHaveEDID = (ddc2_read_edid1(&bus, &(si.edidInfo), NULL, NULL) == B_OK);
bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK);
WriteCrtcReg(DDCPort, tmp);
} else {
@ -113,18 +113,10 @@ Virge_GetEdidInfo(void)
uint8 tmp = ReadReg8(DDC_REG);
WriteReg8(DDC_REG, tmp | 0x13);
si.bHaveEDID = (ddc2_read_edid1(&bus, &(si.edidInfo), NULL, NULL) == B_OK);
bResult = (ddc2_read_edid1(&bus, &edidInfo, NULL, NULL) == B_OK);
WriteReg8(DDC_REG, tmp);
}
if (si.bHaveEDID) {
#ifdef ENABLE_DEBUG_TRACE
edid_dump(&(si.edidInfo));
#endif
} else {
TRACE("Virge_GetEdidInfo() failed!\n");
}
return si.bHaveEDID;
return bResult;
}

View File

@ -226,13 +226,12 @@ Virge_Init(void)
si.colorSpaces[1] = B_RGB16;
si.colorSpaceCount = 2;
// Get info about the display capabilities (EDID).
Virge_GetEdidInfo();
si.bDisableHdwCursor = false; // allow use of hardware cursor
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
// Setup the mode list.
return CreateModeList(IsModeUsable);
return CreateModeList(IsModeUsable, Virge_GetEdidInfo);
}
@ -251,7 +250,7 @@ Virge_SetFunctionPointers(void)
gInfo.WaitIdleEmpty = VirgeWaitIdleEmpty;
gInfo.DPMSCapabilities = Virge_DPMSCapabilities;
gInfo.DPMSMode = Virge_DPMSMode;
gInfo.GetDPMSMode = Virge_GetDPMSMode;
gInfo.SetDPMSMode = Virge_SetDPMSMode;
gInfo.LoadCursorImage = Virge_LoadCursorImage;

View File

@ -623,7 +623,7 @@ Virge_ModeInit(const DisplayModeEx& mode)
}
int width = mode.bytesPerRow >> 3;
regRec.CRTC[19] = 0xFF & width;
regRec.CRTC[0x13] = 0xFF & width;
regRec.CR51 = (0x300 & width) >> 4; // Extension bits
regRec.CR33 = 0x20;
@ -694,6 +694,13 @@ Virge_ModeInit(const DisplayModeEx& mode)
Virge_WriteMode(mode, regRec); // write mode registers to hardware
// Note that the Virge VX chip does not display the hardware cursor when the
// mode is set to 640x480; thus, in this case the hardware cursor functions
// will be disabled so that a software cursor will be used.
si.bDisableHdwCursor = (si.chipType == S3_VIRGE_VX
&& mode.timing.h_display == 640 && mode.timing.v_display == 480);
return true;
}

File diff suppressed because it is too large Load Diff