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:
parent
da720168c1
commit
c1379d357b
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user