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:
@@ -2,7 +2,7 @@
|
|||||||
Copyright 2007-2008 Haiku, Inc. All rights reserved.
|
Copyright 2007-2008 Haiku, Inc. All rights reserved.
|
||||||
Distributed under the terms of the MIT license.
|
Distributed under the terms of the MIT license.
|
||||||
|
|
||||||
Other authors:
|
Authors:
|
||||||
Gerald Zajac 2007-2008
|
Gerald Zajac 2007-2008
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,27 +16,42 @@
|
|||||||
#include <edid.h>
|
#include <edid.h>
|
||||||
|
|
||||||
|
|
||||||
// This is the info that needs to be shared between the kernel driver and
|
// This file contains info that is shared between the kernel driver and the
|
||||||
// the accelerant for the sample driver.
|
// 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 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
|
#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;
|
sem_id sem;
|
||||||
int32 ben;
|
int32 count;
|
||||||
};
|
|
||||||
|
|
||||||
#define INIT_BEN(x) x.sem = create_sem(0, "S3 "#x" benaphore"); x.ben = 0;
|
status_t Init(const char* name)
|
||||||
#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);
|
count = 0;
|
||||||
#define DELETE_BEN(x) delete_sem(x.sem);
|
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
|
#define S3_PRIVATE_DATA_MAGIC 0x4521 // a private driver rev, of sorts
|
||||||
@@ -45,6 +60,7 @@ struct benaphore {
|
|||||||
enum {
|
enum {
|
||||||
S3_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
S3_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
||||||
S3_DEVICE_NAME,
|
S3_DEVICE_NAME,
|
||||||
|
S3_GET_EDID,
|
||||||
S3_GET_PIO,
|
S3_GET_PIO,
|
||||||
S3_SET_PIO,
|
S3_SET_PIO,
|
||||||
S3_RUN_INTERRUPTS,
|
S3_RUN_INTERRUPTS,
|
||||||
@@ -54,7 +70,7 @@ enum {
|
|||||||
// Chip type numbers. These are used to group the chips into related
|
// Chip type numbers. These are used to group the chips into related
|
||||||
// groups. See table S3_ChipTable in driver.c
|
// groups. See table S3_ChipTable in driver.c
|
||||||
|
|
||||||
enum S3_ChipType {
|
enum ChipType {
|
||||||
S3_TRIO64 = 1,
|
S3_TRIO64 = 1,
|
||||||
S3_TRIO64_VP, // Trio64V+ has same ID as Trio64 but different revision number
|
S3_TRIO64_VP, // Trio64V+ has same ID as Trio64 but different revision number
|
||||||
S3_TRIO64_UVP,
|
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 {
|
struct DisplayModeEx : display_mode {
|
||||||
uint32 bpp; // bits/pixel
|
uint32 bpp; // bits/pixel
|
||||||
uint32 bytesPerRow; // number of bytes in one line/row
|
uint32 bytesPerRow; // actual number of bytes in one line/row
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -147,6 +140,9 @@ struct SharedInfo {
|
|||||||
bool bAccelerantInUse; // true = accelerant has been initialized
|
bool bAccelerantInUse; // true = accelerant has been initialized
|
||||||
bool bInterruptAssigned; // card has a useable interrupt assigned to it
|
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
|
sem_id vertBlankSem; // vertical blank semaphore; if < 0, there is no semaphore
|
||||||
|
|
||||||
// Memory mappings.
|
// Memory mappings.
|
||||||
@@ -169,11 +165,8 @@ struct SharedInfo {
|
|||||||
area_id modeArea; // area containing list of display modes the driver supports
|
area_id modeArea; // area containing list of display modes the driver supports
|
||||||
uint32 modeCount; // number of display modes in the list
|
uint32 modeCount; // number of display modes in the list
|
||||||
|
|
||||||
// Cursor info.
|
uint16 cursorHotX; // Cursor hot spot. Top left corner of the cursor
|
||||||
struct {
|
uint16 cursorHotY; // is 0,0
|
||||||
uint16 hot_x; // Cursor hot spot. Top left corner of the cursor
|
|
||||||
uint16 hot_y; // is 0,0
|
|
||||||
} cursor;
|
|
||||||
|
|
||||||
// Current display mode configuration, and other parameters related to
|
// Current display mode configuration, and other parameters related to
|
||||||
// current display mode.
|
// current display mode.
|
||||||
@@ -183,12 +176,7 @@ struct SharedInfo {
|
|||||||
edid1_info edidInfo;
|
edid1_info edidInfo;
|
||||||
bool bHaveEDID; // true = EDID info from device is in edidInfo
|
bool bHaveEDID; // true = EDID info from device is in edidInfo
|
||||||
|
|
||||||
// Acceleration engine.
|
Benaphore engineLock; // for serializing access to the 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;
|
|
||||||
|
|
||||||
int mclk;
|
int mclk;
|
||||||
|
|
||||||
@@ -198,41 +186,39 @@ struct SharedInfo {
|
|||||||
uint16 panelY; // laptop LCD height
|
uint16 panelY; // laptop LCD height
|
||||||
|
|
||||||
// Command Overflow Buffer (COB) parameters for Savage chips.
|
// Command Overflow Buffer (COB) parameters for Savage chips.
|
||||||
bool bDisableCOB; // enable/disable COB for Savage 4 & ProSavage
|
uint32 cobSizeIndex; // size index
|
||||||
uint32 cobIndex; // size index
|
|
||||||
uint32 cobSize; // size in bytes
|
|
||||||
uint32 cobOffset; // offset in video memory
|
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)
|
// Set some boolean condition (like enabling or disabling interrupts)
|
||||||
struct S3SetBoolState {
|
struct S3SetBoolState {
|
||||||
uint32 magic; // magic number to make sure the caller groks us
|
uint32 magic; // magic number
|
||||||
bool bEnable; // state to set
|
bool bEnable; // state to set
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Retrieve the area_id of the kernel/accelerant shared info
|
// Retrieve the area_id of the kernel/accelerant shared info
|
||||||
struct S3GetPrivateData {
|
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
|
area_id sharedInfoArea; // ID of area containing shared information
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct S3GetSetPIO {
|
struct S3GetEDID {
|
||||||
uint32 magic; // magic number to make sure the caller groks us
|
uint32 magic; // magic number
|
||||||
uint32 offset; // offset of PIO register to read/write
|
edid1_raw rawEdid; // raw EDID info to obtain
|
||||||
uint32 size; // number of bytes to transfer
|
|
||||||
uint32 value; // value to write or value that was read
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
struct S3GetSetPIO {
|
||||||
}
|
uint32 magic; // magic number
|
||||||
#endif
|
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
|
#endif // DRIVERINTERFACE_H
|
||||||
|
|||||||
@@ -97,15 +97,15 @@ InitAccelerant(int fileDesc)
|
|||||||
} else {
|
} else {
|
||||||
result = gInfo.ChipInit(); // perform init related to current chip
|
result = gInfo.ChipInit(); // perform init related to current chip
|
||||||
if (result == B_OK) {
|
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);
|
// ensure that this function won't be executed again
|
||||||
si.engine.lastIdle = 0;
|
// (copies should be clones)
|
||||||
si.engine.count = 0;
|
si.bAccelerantInUse = true;
|
||||||
|
}
|
||||||
gInfo.ShowCursor(false);
|
|
||||||
|
|
||||||
// ensure that this function won't be executed again (copies should be clones)
|
|
||||||
si.bAccelerantInUse = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,6 @@
|
|||||||
#include "register_io.h"
|
#include "register_io.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
|
|
||||||
@@ -43,7 +38,7 @@ struct AccelerantInfo {
|
|||||||
display_mode* modeList; // list of standard display modes
|
display_mode* modeList; // list of standard display modes
|
||||||
area_id modeListArea; // mode list area ID
|
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.
|
// Pointers to wait handlers.
|
||||||
void (*WaitQueue)(uint32);
|
void (*WaitQueue)(uint32);
|
||||||
@@ -51,7 +46,7 @@ struct AccelerantInfo {
|
|||||||
|
|
||||||
// Pointers to DPMS functions.
|
// Pointers to DPMS functions.
|
||||||
uint32 (*DPMSCapabilities)(void);
|
uint32 (*DPMSCapabilities)(void);
|
||||||
uint32 (*DPMSMode)(void);
|
uint32 (*GetDPMSMode)(void);
|
||||||
status_t (*SetDPMSMode)(uint32 dpms_flags);
|
status_t (*SetDPMSMode)(uint32 dpms_flags);
|
||||||
|
|
||||||
// Pointers to cursor functions.
|
// Pointers to cursor functions.
|
||||||
@@ -82,6 +77,10 @@ extern AccelerantInfo gInfo;
|
|||||||
// chips will have no prefix.
|
// chips will have no prefix.
|
||||||
//================================================================
|
//================================================================
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
// General
|
// General
|
||||||
status_t InitAccelerant(int fd);
|
status_t InitAccelerant(int fd);
|
||||||
ssize_t AccelerantCloneInfoSize(void);
|
ssize_t AccelerantCloneInfoSize(void);
|
||||||
@@ -109,15 +108,15 @@ status_t GetEdidInfo(void* info, size_t size, uint32* _version);
|
|||||||
|
|
||||||
// DPMS
|
// DPMS
|
||||||
uint32 Savage_DPMSCapabilities(void);
|
uint32 Savage_DPMSCapabilities(void);
|
||||||
uint32 Savage_DPMSMode(void);
|
uint32 Savage_GetDPMSMode(void);
|
||||||
status_t Savage_SetDPMSMode(uint32 dpms_flags);
|
status_t Savage_SetDPMSMode(uint32 dpms_flags);
|
||||||
|
|
||||||
uint32 Trio64_DPMSCapabilities(void);
|
uint32 Trio64_DPMSCapabilities(void);
|
||||||
uint32 Trio64_DPMSMode(void);
|
uint32 Trio64_GetDPMSMode(void);
|
||||||
status_t Trio64_SetDPMSMode(uint32 dpms_flags);
|
status_t Trio64_SetDPMSMode(uint32 dpms_flags);
|
||||||
|
|
||||||
uint32 Virge_DPMSCapabilities(void);
|
uint32 Virge_DPMSCapabilities(void);
|
||||||
uint32 Virge_DPMSMode(void);
|
uint32 Virge_GetDPMSMode(void);
|
||||||
status_t Virge_SetDPMSMode(uint32 dpms_flags);
|
status_t Virge_SetDPMSMode(uint32 dpms_flags);
|
||||||
|
|
||||||
// Cursor
|
// 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_InvertRectangle(engine_token* et, fill_rect_params* list, uint32 count);
|
||||||
void Virge_ScreenToScreenBlit(engine_token* et, blit_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
|
// Prototypes for other functions that are called from source files other than
|
||||||
// where they are defined.
|
// 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[],
|
void InitCrtcTimingValues(const DisplayModeEx& mode, int horzScaleFactor, uint8 crtc[],
|
||||||
uint8& cr3b, uint8& cr3c, uint8& cr5d, uint8& cr5e);
|
uint8& cr3b, uint8& cr3c, uint8& cr5d, uint8& cr5e);
|
||||||
bool IsModeUsable(const display_mode* mode);
|
bool IsModeUsable(const display_mode* mode);
|
||||||
|
|
||||||
// Savage functions.
|
// 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);
|
bool Savage_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask);
|
||||||
void Savage_SetCursorPosition(int x, int y);
|
void Savage_SetCursorPosition(int x, int y);
|
||||||
@@ -185,7 +189,7 @@ void Trio64_SetFunctionPointers(void);
|
|||||||
|
|
||||||
// Virge functions.
|
// 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);
|
bool Virge_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask);
|
||||||
void Virge_SetCursorPosition(int x, int y);
|
void Virge_SetCursorPosition(int x, int y);
|
||||||
@@ -195,8 +199,4 @@ bool Virge_SetDisplayMode(const DisplayModeEx& mode);
|
|||||||
void Virge_SetFunctionPointers(void);
|
void Virge_SetFunctionPointers(void);
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _ACCEL_H
|
#endif // _ACCEL_H
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "accel.h"
|
#include "accel.h"
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
|
SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
|
||||||
uint8* andMask, uint8* xorMask)
|
uint8* andMask, uint8* xorMask)
|
||||||
{
|
{
|
||||||
@@ -23,8 +23,8 @@ SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
|
|||||||
// Update cursor variables appropriately.
|
// Update cursor variables appropriately.
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
si.cursor.hot_x = hot_x;
|
si.cursorHotX = hot_x;
|
||||||
si.cursor.hot_y = hot_y;
|
si.cursorHotY = hot_y;
|
||||||
|
|
||||||
if ( ! gInfo.LoadCursorImage(width, height, andMask, xorMask))
|
if ( ! gInfo.LoadCursorImage(width, height, andMask, xorMask))
|
||||||
return B_ERROR;
|
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)
|
MoveCursor(uint16 xPos, uint16 yPos)
|
||||||
{
|
{
|
||||||
// Move the cursor to the specified position on the desktop. If we're
|
// 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);
|
MoveDisplay(hds, vds);
|
||||||
|
|
||||||
// Put cursor in correct physical position.
|
// Put cursor in correct physical position.
|
||||||
x -= (hds + si.cursor.hot_x);
|
x -= (hds + si.cursorHotX);
|
||||||
y -= (vds + si.cursor.hot_y);
|
y -= (vds + si.cursorHotY);
|
||||||
|
|
||||||
// Position the cursor on the display.
|
// Position the cursor on the display.
|
||||||
gInfo.SetCursorPosition(x, y);
|
gInfo.SetCursorPosition(x, y);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
This file may be used under the terms of the Be Sample Code License.
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
|
||||||
Other authors:
|
Other authors:
|
||||||
Gerald Zajac 2007
|
Gerald Zajac 2007-2008
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "accel.h"
|
#include "accel.h"
|
||||||
@@ -12,22 +12,23 @@
|
|||||||
static engine_token engineToken = { 1, B_2D_ACCELERATION, NULL };
|
static engine_token engineToken = { 1, B_2D_ACCELERATION, NULL };
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
AccelerantEngineCount(void)
|
AccelerantEngineCount(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
AcquireEngine(uint32 capabilities, uint32 max_wait,
|
AcquireEngine(uint32 capabilities, uint32 max_wait,
|
||||||
sync_token* st, engine_token** et)
|
sync_token* st, engine_token** et)
|
||||||
{
|
{
|
||||||
(void)capabilities; // avoid compiler warning for unused arg
|
(void)capabilities; // avoid compiler warning for unused arg
|
||||||
(void)max_wait; // avoid compiler warning for unused arg
|
(void)max_wait; // avoid compiler warning for unused arg
|
||||||
|
|
||||||
// Acquire the shared benaphore.
|
if (gInfo.sharedInfo->engineLock.Acquire() != B_OK)
|
||||||
AQUIRE_BEN(gInfo.sharedInfo->engine.lock)
|
return B_ERROR;
|
||||||
|
|
||||||
// Sync if required.
|
// Sync if required.
|
||||||
if (st)
|
if (st)
|
||||||
SyncToToken(st);
|
SyncToToken(st);
|
||||||
@@ -38,37 +39,35 @@ AcquireEngine(uint32 capabilities, uint32 max_wait,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ReleaseEngine(engine_token* et, sync_token* st)
|
ReleaseEngine(engine_token* et, sync_token* st)
|
||||||
{
|
{
|
||||||
// Update the sync token, if any.
|
// Update the sync token, if any.
|
||||||
if (st)
|
if (st)
|
||||||
GetSyncToken(et, st);
|
GetSyncToken(et, st);
|
||||||
|
|
||||||
// Release the shared benaphore.
|
gInfo.sharedInfo->engineLock.Release();
|
||||||
RELEASE_BEN(gInfo.sharedInfo->engine.lock)
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WaitEngineIdle(void)
|
WaitEngineIdle(void)
|
||||||
{
|
{
|
||||||
gInfo.WaitIdleEmpty(); // wait until engine is completely idle
|
gInfo.WaitIdleEmpty(); // wait until engine is completely idle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
GetSyncToken(engine_token* et, sync_token* st)
|
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->engine_id = et->engine_id;
|
||||||
st->counter = gInfo.sharedInfo->engine.count;
|
st->counter = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
SyncToToken(sync_token* st)
|
SyncToToken(sync_token* st)
|
||||||
{
|
{
|
||||||
(void)st; // avoid compiler warning for unused arg
|
(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
|
(void)data; // avoid compiler warning for unused arg
|
||||||
|
|
||||||
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
// General
|
// General
|
||||||
case B_INIT_ACCELERANT: return (void*)InitAccelerant;
|
case B_INIT_ACCELERANT: return (void*)InitAccelerant;
|
||||||
@@ -42,13 +44,16 @@ get_accelerant_hook(uint32 feature, void* data)
|
|||||||
|
|
||||||
// DPMS
|
// DPMS
|
||||||
case B_DPMS_CAPABILITIES: return (void*)(gInfo.DPMSCapabilities);
|
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);
|
case B_SET_DPMS_MODE: return (void*)(gInfo.SetDPMSMode);
|
||||||
|
|
||||||
// Cursor
|
// Cursor
|
||||||
case B_SET_CURSOR_SHAPE: return (void*)SetCursorShape;
|
case B_SET_CURSOR_SHAPE:
|
||||||
case B_MOVE_CURSOR: return (void*)MoveCursor;
|
return (void*)(si.bDisableHdwCursor ? NULL : SetCursorShape);
|
||||||
case B_SHOW_CURSOR: return (void*)(gInfo.ShowCursor);
|
case B_MOVE_CURSOR:
|
||||||
|
return (void*)(si.bDisableHdwCursor ? NULL : MoveCursor);
|
||||||
|
case B_SHOW_CURSOR:
|
||||||
|
return (void*)(si.bDisableHdwCursor ? NULL : gInfo.ShowCursor);
|
||||||
|
|
||||||
// Engine Management
|
// Engine Management
|
||||||
case B_ACCELERANT_ENGINE_COUNT: return (void*)AccelerantEngineCount;
|
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;
|
case B_SYNC_TO_TOKEN: return (void*)SyncToToken;
|
||||||
|
|
||||||
// 2D acceleration
|
// 2D acceleration
|
||||||
case B_SCREEN_TO_SCREEN_BLIT: return (void*)(gInfo.ScreenToScreenBlit);
|
case B_SCREEN_TO_SCREEN_BLIT:
|
||||||
case B_FILL_RECTANGLE: return (void*)(gInfo.FillRectangle);
|
return (void*)(si.bDisableAccelDraw ? NULL : gInfo.ScreenToScreenBlit);
|
||||||
case B_INVERT_RECTANGLE: return (void*)(gInfo.InvertRectangle);
|
case B_FILL_RECTANGLE:
|
||||||
case B_FILL_SPAN: return (void*)(gInfo.FillSpan);
|
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
|
return NULL; // Return null pointer for any feature not handled above
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
#include "accel.h"
|
#include "accel.h"
|
||||||
|
|
||||||
#include <create_display_modes.h>
|
#include <create_display_modes.h> // common accelerant header file
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -29,7 +30,7 @@ InitCrtcTimingValues(const DisplayModeEx& mode, int horzScaleFactor, uint8 crtc[
|
|||||||
int hDisp_e = (mode.timing.h_display * horzScaleFactor) / 8 - 1;
|
int hDisp_e = (mode.timing.h_display * horzScaleFactor) / 8 - 1;
|
||||||
int hSync_s = (mode.timing.h_sync_start * horzScaleFactor) / 8;
|
int hSync_s = (mode.timing.h_sync_start * horzScaleFactor) / 8;
|
||||||
int hSync_e = (mode.timing.h_sync_end * 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 hBlank_e = hTotal; // end of horizontal blanking
|
||||||
|
|
||||||
int vTotal = mode.timing.v_total - 2;
|
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_s = vDisp_e; // start of vertical blanking
|
||||||
int vBlank_e = vTotal; // end of vertical blanking
|
int vBlank_e = vTotal; // end of vertical blanking
|
||||||
|
|
||||||
TRACE("InitCrtcTimingValues()\n");
|
|
||||||
|
|
||||||
// CRTC Controller values
|
// CRTC Controller values
|
||||||
|
|
||||||
crtc[0x00] = hTotal;
|
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
|
bool
|
||||||
IsModeUsable(const display_mode* mode)
|
IsModeUsable(const display_mode* mode)
|
||||||
{
|
{
|
||||||
@@ -162,10 +183,9 @@ IsModeUsable(const display_mode* mode)
|
|||||||
if ( ! gInfo.GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock))
|
if ( ! gInfo.GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock))
|
||||||
return false;
|
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)
|
if ( ! IsThereEnoughFBMemory(mode, bitsPerPixel))
|
||||||
> si.maxFrameBufferSize)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mode->timing.pixel_clock > maxPixelClock)
|
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)
|
if (mode->timing.h_display == 640 && mode->timing.v_display < 480)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// In most mode lists, there are three entries for 640 x 480 which have a
|
// If the video chip is connected directly to an LCD display (ie, laptop
|
||||||
// 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
|
|
||||||
// computer), restrict the display mode to resolutions where the width and
|
// 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
|
// 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
|
// LCD display.
|
||||||
// get the preferred mode which should be the resolution of the 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)) {
|
|| mode->timing.v_display > si.panelY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __HAIKU__
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
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;
|
display_mode* list;
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
area_id listArea;
|
area_id listArea;
|
||||||
@@ -254,9 +297,9 @@ ProposeDisplayMode(display_mode *target, const display_mode *low,
|
|||||||
(void)low; // avoid compiler warning for unused arg
|
(void)low; // avoid compiler warning for unused arg
|
||||||
(void)high; // 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",
|
TRACE("ProposeDisplayMode() %dx%d, pixel clock: %d kHz, space: 0x%X\n",
|
||||||
target->timing.pixel_clock, target->virtual_width, target->virtual_height,
|
target->timing.h_display, target->timing.v_display,
|
||||||
target->space);
|
target->timing.pixel_clock, target->space);
|
||||||
|
|
||||||
// Search the mode list for the specified mode.
|
// Search the mode list for the specified mode.
|
||||||
|
|
||||||
@@ -275,6 +318,7 @@ ProposeDisplayMode(display_mode *target, const display_mode *low,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
SetDisplayMode(display_mode* pMode)
|
SetDisplayMode(display_mode* pMode)
|
||||||
{
|
{
|
||||||
@@ -290,27 +334,50 @@ SetDisplayMode(display_mode* pMode)
|
|||||||
if ( ! gInfo.GetColorSpaceParams(mode.space, mode.bpp, maxPixelClock))
|
if ( ! gInfo.GetColorSpaceParams(mode.space, mode.bpp, maxPixelClock))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
mode.bytesPerRow = mode.virtual_width * ((mode.bpp + 7) / 8); // use virtual width
|
|
||||||
|
|
||||||
if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK)
|
if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// Test if there is sufficient memory for this mode. Use the virtual width
|
// Note that for some Savage chips, accelerated drawing is badly messed up
|
||||||
// and height for this calculation since one or both might be greater than
|
// when the display width is 1400 because 1400 is not evenly divisible by 32.
|
||||||
// the actual dimensions of the mode.
|
// 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;
|
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);
|
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.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.h_total,
|
||||||
mode.timing.v_display, mode.timing.v_sync_start, mode.timing.v_sync_end,
|
mode.timing.v_display,
|
||||||
mode.timing.v_total, mode.timing.flags);
|
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))
|
if ( ! gInfo.SetDisplayMode(mode))
|
||||||
return B_ERROR;
|
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 = (void*)((addr_t)si.videoMemAddr + si.frameBufferOffset);
|
||||||
pFBC->frame_buffer_dma = (void*)((addr_t)si.videoMemPCI + 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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -418,7 +486,6 @@ GetTimingConstraints(display_timing_constraints *constraints)
|
|||||||
{
|
{
|
||||||
(void)constraints; // avoid compiler warning for unused arg
|
(void)constraints; // avoid compiler warning for unused arg
|
||||||
|
|
||||||
TRACE("GetTimingConstraints() called\n");
|
|
||||||
return B_ERROR;
|
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
|
// 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.
|
// matching width and height, 60 Hz refresh rate, and greatest color depth.
|
||||||
|
|
||||||
TRACE("GetPreferredDisplayMode()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
if (si.displayType == MT_LCD) {
|
if (si.displayType == MT_LCD) {
|
||||||
@@ -452,8 +517,6 @@ GetPreferredDisplayMode(display_mode* preferredMode)
|
|||||||
status_t
|
status_t
|
||||||
GetEdidInfo(void* info, size_t size, uint32* _version)
|
GetEdidInfo(void* info, size_t size, uint32* _version)
|
||||||
{
|
{
|
||||||
TRACE("GetEdidInfo()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
if ( ! si.bHaveEDID)
|
if ( ! si.bHaveEDID)
|
||||||
|
|||||||
@@ -40,17 +40,9 @@
|
|||||||
// Primary Stream 2 Stride.
|
// Primary Stream 2 Stride.
|
||||||
#define PRI_STREAM2_STRIDE 0x81b8
|
#define PRI_STREAM2_STRIDE 0x81b8
|
||||||
|
|
||||||
|
#define S3_GLOBAL_GBD_REG 0x816C // global bitmap descriptor register
|
||||||
|
|
||||||
#define MEMORY_CTRL0_REG 0xCA
|
#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_PS1 0x10 // CRCA_4 :Primary stream 1
|
||||||
#define MEM_PS2 0x20 // CRCA_5 :Primary stream 2
|
#define MEM_PS2 0x20 // CRCA_5 :Primary stream 2
|
||||||
|
|
||||||
@@ -73,7 +65,6 @@
|
|||||||
|
|
||||||
#define TILE_FORMAT_LINEAR 0
|
#define TILE_FORMAT_LINEAR 0
|
||||||
|
|
||||||
// BD - BCI enable.
|
|
||||||
#define BCI_ENABLE 8 // savage4, MX, IX, 3D
|
#define BCI_ENABLE 8 // savage4, MX, IX, 3D
|
||||||
#define BCI_ENABLE_TWISTER 0 // twister, prosavage, DDR, supersavage, 2000
|
#define BCI_ENABLE_TWISTER 0 // twister, prosavage, DDR, supersavage, 2000
|
||||||
|
|
||||||
@@ -81,6 +72,7 @@
|
|||||||
#define S3_LITTLE_ENDIAN 0
|
#define S3_LITTLE_ENDIAN 0
|
||||||
#define S3_BD64 1
|
#define S3_BD64 1
|
||||||
|
|
||||||
|
#define BCI_BD_BW_DISABLE 0x10000000
|
||||||
#define BCI_BUFFER_OFFSET 0x10000
|
#define BCI_BUFFER_OFFSET 0x10000
|
||||||
|
|
||||||
#define BCI_GET_PTR vuint32* bci_ptr = ((uint32*)(gInfo.regs + BCI_BUFFER_OFFSET))
|
#define BCI_GET_PTR vuint32* bci_ptr = ((uint32*)(gInfo.regs + BCI_BUFFER_OFFSET))
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Savage_DPMSCapabilities(void)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
Savage_DPMSMode(void)
|
Savage_GetDPMSMode(void)
|
||||||
{
|
{
|
||||||
// Return the current DPMS mode.
|
// Return the current DPMS mode.
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ Savage_DPMSMode(void)
|
|||||||
mode = ((ReadSeqReg(0x31) & 0x10) ? B_DPMS_ON : B_DPMS_OFF);
|
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;
|
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
|
(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--) {
|
while (count--) {
|
||||||
int x = pList->left;
|
int x = pList->left;
|
||||||
@@ -38,8 +38,8 @@ Savage_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, ui
|
|||||||
gInfo.WaitQueue(7);
|
gInfo.WaitQueue(7);
|
||||||
|
|
||||||
BCI_SEND(cmd);
|
BCI_SEND(cmd);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
|
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
|
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
|
||||||
|
|
||||||
BCI_SEND(color);
|
BCI_SEND(color);
|
||||||
BCI_SEND(BCI_X_Y(x, y));
|
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
|
(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--) {
|
while (count--) {
|
||||||
int y = *pList++;
|
int y = *pList++;
|
||||||
@@ -78,8 +78,8 @@ Savage_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count)
|
|||||||
gInfo.WaitQueue(7);
|
gInfo.WaitQueue(7);
|
||||||
|
|
||||||
BCI_SEND(cmd);
|
BCI_SEND(cmd);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
|
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
|
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
|
||||||
|
|
||||||
BCI_SEND(color);
|
BCI_SEND(color);
|
||||||
BCI_SEND(BCI_X_Y(x, y));
|
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);
|
gInfo.WaitQueue(7);
|
||||||
|
|
||||||
BCI_SEND(cmd);
|
BCI_SEND(cmd);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
|
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
|
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
|
||||||
|
|
||||||
BCI_SEND(BCI_X_Y(x, y));
|
BCI_SEND(BCI_X_Y(x, y));
|
||||||
BCI_SEND(BCI_W_H(w, h));
|
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(cmd);
|
||||||
|
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
|
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
|
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
|
||||||
|
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.LoPart);
|
BCI_SEND(gInfo.sharedInfo->frameBufferOffset);
|
||||||
BCI_SEND(gInfo.sharedInfo->GlobalBD.bd2.HiPart);
|
BCI_SEND(gInfo.sharedInfo->globalBitmapDesc);
|
||||||
|
|
||||||
BCI_SEND(BCI_X_Y(src_x, src_y));
|
BCI_SEND(BCI_X_Y(src_x, src_y));
|
||||||
BCI_SEND(BCI_X_Y(dest_x, dest_y));
|
BCI_SEND(BCI_X_Y(dest_x, dest_y));
|
||||||
BCI_SEND(BCI_W_H(width + 1, height + 1));
|
BCI_SEND(BCI_W_H(width + 1, height + 1));
|
||||||
|
|
||||||
pList ++;
|
pList++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ SetI2CSignals(void* cookie, int _clock, int data)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Savage_GetEdidInfo(void)
|
Savage_GetEdidInfo(edid1_info& edidInfo)
|
||||||
{
|
{
|
||||||
// Get the EDID info and return true if successful.
|
// Get the EDID info and return true if successful.
|
||||||
|
|
||||||
@@ -83,17 +83,8 @@ Savage_GetEdidInfo(void)
|
|||||||
uint8 tmp = ReadCrtcReg(DDCPort);
|
uint8 tmp = ReadCrtcReg(DDCPort);
|
||||||
WriteCrtcReg(DDCPort, tmp | 0x13);
|
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);
|
WriteCrtcReg(DDCPort, tmp);
|
||||||
|
|
||||||
if (si.bHaveEDID) {
|
return bResult;
|
||||||
#ifdef ENABLE_DEBUG_TRACE
|
|
||||||
edid_dump(&(si.edidInfo));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
TRACE("Savage_GetEdidInfo() failed!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return si.bHaveEDID;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
static void
|
||||||
Savage_GetPanelInfo()
|
Savage_GetPanelInfo()
|
||||||
{
|
{
|
||||||
@@ -132,20 +115,12 @@ Savage_GetPanelInfo()
|
|||||||
int panelX = (ReadSeqReg(0x61) + ((ReadSeqReg(0x66) & 0x02) << 7) + 1) * 8;
|
int panelX = (ReadSeqReg(0x61) + ((ReadSeqReg(0x66) & 0x02) << 7) + 1) * 8;
|
||||||
int panelY = ReadSeqReg(0x69) + ((ReadSeqReg(0x6e) & 0x70) << 4) + 1;
|
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
|
if (panelX == 1408)
|
||||||
// a width that is 8 pixels too wide probably because reg SR61 is set
|
panelX = 1400;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* sTechnology;
|
char* sTechnology;
|
||||||
|
|
||||||
@@ -199,7 +174,7 @@ Savage_Init(void)
|
|||||||
static uint8 RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
|
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 RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
|
||||||
static const uint8 RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
|
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
|
uint8 cr36 = ReadCrtcReg(0x36); // get amount of video ram
|
||||||
|
|
||||||
@@ -239,57 +214,37 @@ Savage_Init(void)
|
|||||||
break;
|
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;
|
return B_ERROR;
|
||||||
|
|
||||||
si.videoMemSize = ramSizeMB * 1024 * 1024;
|
si.videoMemSize = usableMB * 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;
|
|
||||||
|
|
||||||
// Compute the Command Overflow Buffer (COB) location.
|
// Compute the Command Overflow Buffer (COB) location.
|
||||||
|
|
||||||
if ((S3_SAVAGE4_SERIES(si.chipType) || S3_SUPERSAVAGE == si.chipType)
|
uint32 cobSize = 0x20000; // use 128kB for the COB
|
||||||
&& si.bDisableCOB) {
|
si.cobSizeIndex = 7;
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that the X.org developers stated that the command overflow buffer
|
// 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
|
// (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
|
// the very end of the video memory.
|
||||||
// of the video memory. It had been tried immediately preceding the COB,
|
|
||||||
// but the Savage MX chip screws up the cursor in that case.
|
|
||||||
|
|
||||||
si.cobOffset = (si.videoMemSize - si.cobSize) & ~0x1ffff; // align cob to 128k
|
si.cobOffset = (si.videoMemSize - cobSize) & ~0x1ffff; // align cob to 128k
|
||||||
si.cursorOffset = 0;
|
si.cursorOffset = (si.cobOffset - CURSOR_BYTES) & ~0xfff; // align to 4k boundary
|
||||||
si.frameBufferOffset = si.cursorOffset + CURSOR_BYTES;
|
si.frameBufferOffset = 0;
|
||||||
si.maxFrameBufferSize = si.cobOffset - si.frameBufferOffset;
|
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);
|
TRACE("cursorOffset: 0x%x frameBufferOffset: 0x%x\n", si.cursorOffset, si.frameBufferOffset);
|
||||||
|
|
||||||
// Reset graphics engine to avoid memory corruption.
|
// Reset graphics engine to avoid memory corruption.
|
||||||
@@ -340,13 +295,12 @@ Savage_Init(void)
|
|||||||
si.colorSpaces[2] = B_RGB32;
|
si.colorSpaces[2] = B_RGB32;
|
||||||
si.colorSpaceCount = 3;
|
si.colorSpaceCount = 3;
|
||||||
|
|
||||||
// Get info about the display capabilities (EDID).
|
si.bDisableHdwCursor = false; // allow use of hardware cursor
|
||||||
|
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
|
||||||
Savage_GetEdidInfo();
|
|
||||||
|
|
||||||
// Setup the mode list.
|
// Setup the mode list.
|
||||||
|
|
||||||
return CreateModeList(IsModeUsable);
|
return CreateModeList(IsModeUsable, Savage_GetEdidInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -379,7 +333,7 @@ Savage_SetFunctionPointers(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gInfo.DPMSCapabilities = Savage_DPMSCapabilities;
|
gInfo.DPMSCapabilities = Savage_DPMSCapabilities;
|
||||||
gInfo.DPMSMode = Savage_DPMSMode;
|
gInfo.GetDPMSMode = Savage_GetDPMSMode;
|
||||||
gInfo.SetDPMSMode = Savage_SetDPMSMode;
|
gInfo.SetDPMSMode = Savage_SetDPMSMode;
|
||||||
|
|
||||||
gInfo.LoadCursorImage = Savage_LoadCursorImage;
|
gInfo.LoadCursorImage = Savage_LoadCursorImage;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
Haiku S3 Savage driver adapted from the X.org Savage driver.
|
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.
|
Copyright 2007-2008 Haiku, Inc. All rights reserved.
|
||||||
Distributed under the terms of the MIT license.
|
Distributed under the terms of the MIT license.
|
||||||
@@ -21,9 +22,9 @@
|
|||||||
struct SavageRegRec {
|
struct SavageRegRec {
|
||||||
uint8 CRTC[25]; // Crtc Controller reg's
|
uint8 CRTC[25]; // Crtc Controller reg's
|
||||||
|
|
||||||
uint8 SR12, SR13, SR15, SR18, SR1B, SR29;
|
uint8 SR12, SR13, SR1B, SR29;
|
||||||
uint8 CR31, CR33, CR34, CR3A, CR3B, CR3C;
|
uint8 CR33, CR34, CR3A, CR3B, CR3C;
|
||||||
uint8 CR40, CR42, CR43, CR45;
|
uint8 CR42, CR43, CR45;
|
||||||
uint8 CR50, CR51, CR53, CR58, CR5D, CR5E;
|
uint8 CR50, CR51, CR53, CR58, CR5D, CR5E;
|
||||||
uint8 CR65, CR66, CR67, CR69;
|
uint8 CR65, CR66, CR67, CR69;
|
||||||
uint8 CR86, CR88;
|
uint8 CR86, CR88;
|
||||||
@@ -32,15 +33,12 @@ struct SavageRegRec {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Savage_SetGBD_Twister(const DisplayModeEx& mode)
|
Savage_SetGBD_Twister(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
int bci_enable;
|
int bci_enable;
|
||||||
|
|
||||||
TRACE("Savage_SetGBD_Twister()\n");
|
|
||||||
|
|
||||||
if (si.chipType == S3_SAVAGE4)
|
if (si.chipType == S3_SAVAGE4)
|
||||||
bci_enable = BCI_ENABLE;
|
bci_enable = BCI_ENABLE;
|
||||||
else
|
else
|
||||||
@@ -68,12 +66,7 @@ Savage_SetGBD_Twister(const DisplayModeEx& mode)
|
|||||||
|
|
||||||
WriteCrtcReg(0x69, 0x80, 0x80);
|
WriteCrtcReg(0x69, 0x80, 0x80);
|
||||||
|
|
||||||
WriteReg32(0x8128, 0xFFFFFFFFL);
|
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
|
||||||
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
|
|
||||||
|
|
||||||
// If MS1NB style linear tiling mode.
|
// If MS1NB style linear tiling mode.
|
||||||
// bit MM850C[15] = 0 select NB linear tile 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
|
uint32 ulTmp = ReadReg32(ADVANCED_FUNC_CTRL) | 0x8000; // use MS-s style tile mode
|
||||||
WriteReg32(ADVANCED_FUNC_CTRL, ulTmp);
|
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.
|
// CR88, bit 4 - Block write enabled/disabled.
|
||||||
//
|
//
|
||||||
// Note: Block write must be disabled when writing to tiled
|
// 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.
|
// write should only be enabled for certain types of SGRAM.
|
||||||
|
|
||||||
WriteCrtcReg(0x88, DISABLE_BLOCK_WRITE_2D, DISABLE_BLOCK_WRITE_2D);
|
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
|
static void
|
||||||
Savage_SetGBD_3D(const DisplayModeEx& mode)
|
Savage_SetGBD_3D(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_SetGBD_3D()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
|
||||||
int bci_enable = BCI_ENABLE;
|
int bci_enable = BCI_ENABLE;
|
||||||
|
|
||||||
// MM81C0 and 81C4 are used to control primary stream.
|
// MM81C0 and 81C4 are used to control primary stream.
|
||||||
@@ -174,12 +112,7 @@ Savage_SetGBD_3D(const DisplayModeEx& mode)
|
|||||||
|
|
||||||
WriteCrtcReg(0x69, 0x80, 0x80);
|
WriteCrtcReg(0x69, 0x80, 0x80);
|
||||||
|
|
||||||
WriteReg32(0x8128, 0xFFFFFFFFL);
|
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
|
||||||
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
|
|
||||||
|
|
||||||
// If MS1NB style linear tiling mode.
|
// If MS1NB style linear tiling mode.
|
||||||
// bit MM850C[15] = 0 select NB linear tile 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
|
uint32 ulTmp = ReadReg32(ADVANCED_FUNC_CTRL) | 0x8000; // use MS-s style tile mode
|
||||||
WriteReg32(ADVANCED_FUNC_CTRL, ulTmp);
|
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.
|
// CR88, bit 4 - Block write enabled/disabled.
|
||||||
//
|
//
|
||||||
// Note: Block write must be disabled when writing to tiled
|
// 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.
|
// write should only be enabled for certain types of SGRAM.
|
||||||
|
|
||||||
WriteCrtcReg(0x88, DISABLE_BLOCK_WRITE_2D, DISABLE_BLOCK_WRITE_2D);
|
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
|
static void
|
||||||
Savage_SetGBD_MX(const DisplayModeEx& mode)
|
Savage_SetGBD_MX(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_SetGBD_MX()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
int bci_enable = BCI_ENABLE;
|
int bci_enable = BCI_ENABLE;
|
||||||
|
|
||||||
@@ -285,12 +174,7 @@ Savage_SetGBD_MX(const DisplayModeEx& mode)
|
|||||||
(((mode.bytesPerRow * 2) << 16) & 0x3FFF0000) |
|
(((mode.bytesPerRow * 2) << 16) & 0x3FFF0000) |
|
||||||
(mode.bytesPerRow & 0x00003fff));
|
(mode.bytesPerRow & 0x00003fff));
|
||||||
|
|
||||||
WriteReg32(0x8128, 0xFFFFFFFFL);
|
WriteReg32(S3_GLOBAL_GBD_REG, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
|
||||||
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
|
|
||||||
|
|
||||||
// CR78, bit 3 - Block write enabled(1)/disabled(0).
|
// CR78, bit 3 - Block write enabled(1)/disabled(0).
|
||||||
// bit 2 - Block write cycle time(0:2 cycles,1: 1 cycle)
|
// 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.
|
// write should only be enabled for certain types of SGRAM.
|
||||||
|
|
||||||
WriteCrtcReg(0x78, 0xfb, 0xfb);
|
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
|
static void
|
||||||
Savage_SetGBD_Super(const DisplayModeEx& mode)
|
Savage_SetGBD_Super(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_SetGBD_Super()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
int bci_enable = BCI_ENABLE_TWISTER;
|
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_ADDR0, (si.frameBufferOffset & 0xfffffffc) | 0x80000000);
|
||||||
WriteReg32(PRI_STREAM2_FBUF_ADDR1, si.frameBufferOffset & 0xfffffffc);
|
WriteReg32(PRI_STREAM2_FBUF_ADDR1, si.frameBufferOffset & 0xfffffffc);
|
||||||
|
|
||||||
WriteReg32(0x8128, 0xFFFFFFFFL);
|
|
||||||
WriteReg32(0x812C, 0xFFFFFFFFL);
|
|
||||||
|
|
||||||
// Bit 28:block write disable.
|
// 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
|
|
||||||
|
|
||||||
// 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
|
static void
|
||||||
Savage_SetGBD_2000(const DisplayModeEx& mode)
|
Savage_SetGBD_2000(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_SetGBD_2000()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
int bci_enable = BCI_ENABLE_TWISTER;
|
int bci_enable = BCI_ENABLE_TWISTER;
|
||||||
|
|
||||||
@@ -463,47 +266,18 @@ Savage_SetGBD_2000(const DisplayModeEx& mode)
|
|||||||
|
|
||||||
WriteCrtcReg(0x67, 0x08, 0x08);
|
WriteCrtcReg(0x67, 0x08, 0x08);
|
||||||
|
|
||||||
WriteReg32(0x8128, 0xFFFFFFFFL);
|
|
||||||
WriteReg32(0x812C, 0xFFFFFFFFL);
|
|
||||||
|
|
||||||
// Bit 28:block write disable.
|
// 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
|
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
|
static void
|
||||||
Savage_SetGBD(const DisplayModeEx& mode)
|
Savage_SetGBD(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_SetGBD()\n");
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
VerticalRetraceWait();
|
VerticalRetraceWait();
|
||||||
|
|
||||||
@@ -531,19 +305,27 @@ Savage_SetGBD(const DisplayModeEx& mode)
|
|||||||
Savage_SetGBD_2000(mode);
|
Savage_SetGBD_2000(mode);
|
||||||
break;
|
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
|
static void
|
||||||
Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_Initialize2DEngine()\n");
|
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
uint32 thresholds;
|
|
||||||
|
|
||||||
WriteCrtcReg(0x40, 0x01);
|
WriteCrtcReg(0x40, 0x01); // enable graphics engine
|
||||||
WriteCrtcReg(0x31, 0x0c);
|
WriteCrtcReg(0x31, 0x0c); // turn on 16-bit register access
|
||||||
|
|
||||||
// Setup plane masks.
|
// Setup plane masks.
|
||||||
WriteReg32(0x8128, ~0); // enable all write planes
|
WriteReg32(0x8128, ~0); // enable all write planes
|
||||||
@@ -555,14 +337,16 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
|||||||
case S3_SAVAGE_3D:
|
case S3_SAVAGE_3D:
|
||||||
case S3_SAVAGE_MX:
|
case S3_SAVAGE_MX:
|
||||||
|
|
||||||
// Disable BCI.
|
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0); // Disable BCI
|
||||||
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0);
|
|
||||||
// Setup BCI command overflow buffer.
|
// Setup BCI command overflow buffer. 0x48c14
|
||||||
WriteReg32(0x48C14, (si.cobOffset >> 11) | (si.cobIndex << 29)); // tim
|
// 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.
|
// Program shadow status update.
|
||||||
thresholds = ((si.bciThresholdLo & 0xffff) << 16) |
|
WriteReg32(0x48C10, 0x78207220);
|
||||||
(si.bciThresholdHi & 0xffff);
|
|
||||||
WriteReg32(0x48C10, thresholds);
|
|
||||||
|
|
||||||
WriteReg32(0x48C0C, 0);
|
WriteReg32(0x48C0C, 0);
|
||||||
// Enable BCI and command overflow buffer.
|
// Enable BCI and command overflow buffer.
|
||||||
@@ -575,23 +359,14 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
|||||||
case S3_PROSAVAGE_DDR:
|
case S3_PROSAVAGE_DDR:
|
||||||
case S3_SUPERSAVAGE:
|
case S3_SUPERSAVAGE:
|
||||||
|
|
||||||
// Disable BCI.
|
// Some Savage4 and ProSavage chips have coherency problems with
|
||||||
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0);
|
// respect to the Command Overflow Buffer (COB); thus, do not
|
||||||
|
// enable the COB.
|
||||||
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);
|
|
||||||
|
|
||||||
|
WriteReg32(0x48C18, ReadReg32(0x48C18) & 0x3FF0); // Disable BCI
|
||||||
|
WriteReg32(0x48C10, 0x00700040);
|
||||||
WriteReg32(0x48C0C, 0);
|
WriteReg32(0x48C0C, 0);
|
||||||
if (si.bDisableCOB)
|
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x08); // enable BCI without COB
|
||||||
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x08); // enable BCI without COB
|
|
||||||
else
|
|
||||||
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x0C); // enable BCI with COB
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -600,23 +375,17 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
|||||||
// Disable BCI.
|
// Disable BCI.
|
||||||
WriteReg32(0x48C18, 0);
|
WriteReg32(0x48C18, 0);
|
||||||
// Setup BCI command overflow buffer.
|
// Setup BCI command overflow buffer.
|
||||||
WriteReg32(0x48C18, (si.cobOffset >> 7) | (si.cobIndex));
|
WriteReg32(0x48C18, (si.cobOffset >> 7) | (si.cobSizeIndex));
|
||||||
// Disable shadow status update.
|
// Disable shadow status update.
|
||||||
WriteReg32(0x48A30, 0);
|
WriteReg32(0x48A30, 0);
|
||||||
// Enable BCI and command overflow buffer.
|
// Enable BCI and command overflow buffer.
|
||||||
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x00280000 );
|
WriteReg32(0x48C18, ReadReg32(0x48C18) | 0x00280000);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use and set global bitmap descriptor.
|
// 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);
|
Savage_SetGBD(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,8 +393,6 @@ Savage_Initialize2DEngine(const DisplayModeEx& mode)
|
|||||||
static void
|
static void
|
||||||
Savage_GEReset(const DisplayModeEx& mode)
|
Savage_GEReset(const DisplayModeEx& mode)
|
||||||
{
|
{
|
||||||
TRACE("Savage_GEReset() begin\n");
|
|
||||||
|
|
||||||
gInfo.WaitIdleEmpty();
|
gInfo.WaitIdleEmpty();
|
||||||
snooze(10000);
|
snooze(10000);
|
||||||
|
|
||||||
@@ -665,7 +432,7 @@ Savage_GEReset(const DisplayModeEx& mode)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
snooze(10000);
|
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.
|
// 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);
|
WriteReg32(MONO_PAT_1, ~0);
|
||||||
|
|
||||||
Savage_SetGBD(mode);
|
Savage_SetGBD(mode);
|
||||||
|
|
||||||
TRACE("Savage_GEReset() end\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -739,7 +504,7 @@ Savage_CalcClock(long freq, int min_m,
|
|||||||
static void
|
static void
|
||||||
Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
||||||
{
|
{
|
||||||
TRACE("Savage_WriteMode() enter\n");
|
TRACE("Savage_WriteMode() begin\n");
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
@@ -756,7 +521,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
if (ReadCrtcReg(0x66) & 0x01) {
|
if (ReadCrtcReg(0x66) & 0x01) {
|
||||||
Savage_GEReset(mode); // reset GE to make sure nothing is going on
|
Savage_GEReset(mode); // reset GE to make sure nothing is going on
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteCrtcReg(0x67, regRec.CR67 & ~0x0e); // no STREAMS yet old and new
|
WriteCrtcReg(0x67, regRec.CR67 & ~0x0e); // no STREAMS yet old and new
|
||||||
|
|
||||||
// Set register SR19 to zero so that the ProSavage chips will start up
|
// 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
|
// not cleared, it will startup only if booting under BeOS using the
|
||||||
// default boot screen or the boot screen resolution matches the resolution
|
// default boot screen or the boot screen resolution matches the resolution
|
||||||
// of the mode currently being set.
|
// of the mode currently being set.
|
||||||
|
|
||||||
if (si.chipType == S3_SAVAGE_MX)
|
if (si.chipType == S3_SAVAGE_MX)
|
||||||
WriteSeqReg(0x30, 0x00, 0x08);
|
WriteSeqReg(0x30, 0x00, 0x08);
|
||||||
|
|
||||||
@@ -777,14 +542,20 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
|
|
||||||
WriteCrtcReg(0x66, regRec.CR66);
|
WriteCrtcReg(0x66, regRec.CR66);
|
||||||
WriteCrtcReg(0x3a, regRec.CR3A);
|
WriteCrtcReg(0x3a, regRec.CR3A);
|
||||||
WriteCrtcReg(0x31, regRec.CR31);
|
|
||||||
WriteCrtcReg(0x58, regRec.CR58);
|
WriteCrtcReg(0x58, regRec.CR58);
|
||||||
WriteCrtcReg(0x53, regRec.CR53 & 0x7f);
|
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);
|
if (S3_SAVAGE_MOBILE_SERIES(si.chipType)) {
|
||||||
WriteSeqReg(0x15, regRec.SR15);
|
WriteSeqReg(0x54, 0x10);
|
||||||
|
WriteSeqReg(0x56, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the standard CRTC vga regs.
|
// Set the standard CRTC vga regs.
|
||||||
|
|
||||||
@@ -818,7 +589,6 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
|
|
||||||
// Other mode timing and extended regs.
|
// Other mode timing and extended regs.
|
||||||
WriteCrtcReg(0x34, regRec.CR34);
|
WriteCrtcReg(0x34, regRec.CR34);
|
||||||
WriteCrtcReg(0x40, regRec.CR40);
|
|
||||||
WriteCrtcReg(0x42, regRec.CR42);
|
WriteCrtcReg(0x42, regRec.CR42);
|
||||||
WriteCrtcReg(0x45, regRec.CR45);
|
WriteCrtcReg(0x45, regRec.CR45);
|
||||||
WriteCrtcReg(0x50, regRec.CR50);
|
WriteCrtcReg(0x50, regRec.CR50);
|
||||||
@@ -837,22 +607,21 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
if (si.chipType == S3_SAVAGE4)
|
if (si.chipType == S3_SAVAGE4)
|
||||||
WriteCrtcReg(0xb0, regRec.CRB0);
|
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);
|
WriteSeqReg(0x1b, regRec.SR1B);
|
||||||
|
|
||||||
// Load new m, n pll values for dclk & mclk.
|
if ( ! (S3_SAVAGE_MOBILE_SERIES(si.chipType) && si.displayType == MT_LCD)) {
|
||||||
temp = ReadSeqReg(0x15) & ~0x21;
|
// Set extended seq regs for dclk.
|
||||||
|
WriteSeqReg(0x12, regRec.SR12);
|
||||||
|
WriteSeqReg(0x13, regRec.SR13);
|
||||||
|
WriteSeqReg(0x29, regRec.SR29);
|
||||||
|
|
||||||
WriteSeqReg(0x15, temp | 0x03);
|
// Load new m, n pll values for dclk & mclk.
|
||||||
WriteSeqReg(0x15, temp | 0x23);
|
temp = ReadSeqReg(0x15) & ~0x20;
|
||||||
WriteSeqReg(0x15, temp | 0x03);
|
WriteSeqReg(0x15, temp);
|
||||||
WriteSeqReg(0x15, regRec.SR15);
|
WriteSeqReg(0x15, temp | 0x20);
|
||||||
snooze( 100 );
|
WriteSeqReg(0x15, temp);
|
||||||
|
snooze(100);
|
||||||
|
}
|
||||||
|
|
||||||
// Now write out cr67 in full, possibly starting STREAMS.
|
// Now write out cr67 in full, possibly starting STREAMS.
|
||||||
VerticalRetraceWait();
|
VerticalRetraceWait();
|
||||||
@@ -874,7 +643,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
|
|
||||||
Savage_SetGBD(mode);
|
Savage_SetGBD(mode);
|
||||||
|
|
||||||
TRACE("Savage_WriteMode() end\n");
|
TRACE("Savage_WriteMode() done\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -883,7 +652,7 @@ Savage_WriteMode(const DisplayModeEx& mode, const SavageRegRec& regRec)
|
|||||||
static bool
|
static bool
|
||||||
Savage_ModeInit(const DisplayModeEx& mode)
|
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);
|
mode.timing.h_display, mode.timing.v_display, mode.timing.pixel_clock);
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
@@ -896,7 +665,7 @@ Savage_ModeInit(const DisplayModeEx& mode)
|
|||||||
|
|
||||||
InitCrtcTimingValues(mode, horizScaleFactor, regRec.CRTC,
|
InitCrtcTimingValues(mode, horizScaleFactor, regRec.CRTC,
|
||||||
regRec.CR3B, regRec.CR3C, regRec.CR5D, regRec.CR5E);
|
regRec.CR3B, regRec.CR3C, regRec.CR5D, regRec.CR5E);
|
||||||
regRec.CRTC[23] = 0xEB;
|
regRec.CRTC[0x17] = 0xEB;
|
||||||
|
|
||||||
int dclk = mode.timing.pixel_clock;
|
int dclk = mode.timing.pixel_clock;
|
||||||
regRec.CR67 = 0x00;
|
regRec.CR67 = 0x00;
|
||||||
@@ -930,25 +699,14 @@ Savage_ModeInit(const DisplayModeEx& mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Use traditional register-crunching to set mode.
|
|
||||||
|
|
||||||
regRec.CR3A = (ReadCrtcReg(0x3a) & 0x7f) | 0x15;
|
regRec.CR3A = (ReadCrtcReg(0x3a) & 0x7f) | 0x15;
|
||||||
regRec.CR53 = 0x00;
|
regRec.CR53 = 0x00;
|
||||||
regRec.CR31 = 0x8c;
|
|
||||||
regRec.CR66 = 0x89;
|
regRec.CR66 = 0x89;
|
||||||
regRec.CR58 = (ReadCrtcReg(0x58) & 0x80) | 0x13;
|
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.SR1B = ReadSeqReg(0x1b) | 0x10; // enable 8-bit Color Lookup Table
|
||||||
|
|
||||||
regRec.CR43 = regRec.CR45 = regRec.CR65 = 0x00;
|
regRec.CR43 = regRec.CR45 = regRec.CR65 = 0x00;
|
||||||
regRec.CR40 = ReadCrtcReg(0x40) & ~0x01;
|
|
||||||
|
|
||||||
unsigned int m, n, r;
|
unsigned int m, n, r;
|
||||||
Savage_CalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &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
|
else
|
||||||
regRec.CR33 = 0x08;
|
regRec.CR33 = 0x08;
|
||||||
|
|
||||||
regRec.CR67 |= 1;
|
|
||||||
regRec.CR69 = 0;
|
regRec.CR69 = 0;
|
||||||
regRec.CR86 = ReadCrtcReg(0x86) | 0x08;
|
regRec.CR86 = ReadCrtcReg(0x86) | 0x08;
|
||||||
regRec.CR88 = ReadCrtcReg(0x88) | DISABLE_BLOCK_WRITE_2D;
|
regRec.CR88 = ReadCrtcReg(0x88) | DISABLE_BLOCK_WRITE_2D;
|
||||||
@@ -1027,6 +784,7 @@ Savage_SetDisplayMode(const DisplayModeEx& mode)
|
|||||||
Savage_AdjustFrame(mode);
|
Savage_AdjustFrame(mode);
|
||||||
|
|
||||||
WriteSeqReg(0x01, 0x00, 0x20); // unblank the screen
|
WriteSeqReg(0x01, 0x00, 0x20); // unblank the screen
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Trio64_DPMSCapabilities(void)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
Trio64_DPMSMode(void)
|
Trio64_GetDPMSMode(void)
|
||||||
{
|
{
|
||||||
// Return the current DPMS mode.
|
// Return the current DPMS mode.
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Trio64_DPMSMode(void)
|
|||||||
TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
|
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;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,9 +136,12 @@ Trio64_Init(void)
|
|||||||
si.colorSpaces[1] = B_RGB16;
|
si.colorSpaces[1] = B_RGB16;
|
||||||
si.colorSpaceCount = 2;
|
si.colorSpaceCount = 2;
|
||||||
|
|
||||||
|
si.bDisableHdwCursor = false; // allow use of hardware cursor
|
||||||
|
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
|
||||||
|
|
||||||
// Setup the mode list.
|
// Setup the mode list.
|
||||||
|
|
||||||
return CreateModeList(Trio64_IsModeUsable);
|
return CreateModeList(Trio64_IsModeUsable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +155,7 @@ Trio64_SetFunctionPointers(void)
|
|||||||
gInfo.WaitIdleEmpty = WaitIdle;
|
gInfo.WaitIdleEmpty = WaitIdle;
|
||||||
|
|
||||||
gInfo.DPMSCapabilities = Trio64_DPMSCapabilities;
|
gInfo.DPMSCapabilities = Trio64_DPMSCapabilities;
|
||||||
gInfo.DPMSMode = Trio64_DPMSMode;
|
gInfo.GetDPMSMode = Trio64_GetDPMSMode;
|
||||||
gInfo.SetDPMSMode = Trio64_SetDPMSMode;
|
gInfo.SetDPMSMode = Trio64_SetDPMSMode;
|
||||||
|
|
||||||
gInfo.LoadCursorImage = Trio64_LoadCursorImage;
|
gInfo.LoadCursorImage = Trio64_LoadCursorImage;
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bEnableAccelFuncs = true;
|
bool bDisableAccelFuncs = false;
|
||||||
|
|
||||||
switch (mode.timing.h_display) {
|
switch (mode.timing.h_display) {
|
||||||
case 640:
|
case 640:
|
||||||
@@ -152,7 +152,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
|
|||||||
cr50 |= 0x81;
|
cr50 |= 0x81;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bEnableAccelFuncs = false; // use app_server default accel functions
|
bDisableAccelFuncs = true; // use app_server default accel functions
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,20 +167,7 @@ Trio64_ModeInit(const DisplayModeEx& mode)
|
|||||||
// only with the display widths defined in the above switch statement. For
|
// 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.
|
// the other widths, the default functions in the app_server will be used.
|
||||||
|
|
||||||
if (bEnableAccelFuncs)
|
si.bDisableAccelDraw = bDisableAccelFuncs;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the standard CRTC vga regs.
|
// Set the standard CRTC vga regs.
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Virge_DPMSCapabilities(void)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
Virge_DPMSMode(void)
|
Virge_GetDPMSMode(void)
|
||||||
{
|
{
|
||||||
// Return the current DPMS mode.
|
// Return the current DPMS mode.
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Virge_DPMSMode(void)
|
|||||||
TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
|
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;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ SetI2CSignals(void* cookie, int _clock, int data)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Virge_GetEdidInfo(void)
|
Virge_GetEdidInfo(edid1_info& edidInfo)
|
||||||
{
|
{
|
||||||
// Get the EDID info and return true if successful.
|
// Get the EDID info and return true if successful.
|
||||||
|
|
||||||
SharedInfo& si = *gInfo.sharedInfo;
|
SharedInfo& si = *gInfo.sharedInfo;
|
||||||
|
|
||||||
si.bHaveEDID = false;
|
bool bResult = false;
|
||||||
|
|
||||||
if (si.chipType == S3_TRIO_3D_2X) {
|
if (si.chipType == S3_TRIO_3D_2X) {
|
||||||
uint32 DDCPort = 0xAA;
|
uint32 DDCPort = 0xAA;
|
||||||
@@ -100,7 +100,7 @@ Virge_GetEdidInfo(void)
|
|||||||
uint8 tmp = ReadCrtcReg(DDCPort);
|
uint8 tmp = ReadCrtcReg(DDCPort);
|
||||||
WriteCrtcReg(DDCPort, tmp | 0x13);
|
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);
|
WriteCrtcReg(DDCPort, tmp);
|
||||||
} else {
|
} else {
|
||||||
@@ -113,18 +113,10 @@ Virge_GetEdidInfo(void)
|
|||||||
uint8 tmp = ReadReg8(DDC_REG);
|
uint8 tmp = ReadReg8(DDC_REG);
|
||||||
WriteReg8(DDC_REG, tmp | 0x13);
|
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);
|
WriteReg8(DDC_REG, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si.bHaveEDID) {
|
return bResult;
|
||||||
#ifdef ENABLE_DEBUG_TRACE
|
|
||||||
edid_dump(&(si.edidInfo));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
TRACE("Virge_GetEdidInfo() failed!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return si.bHaveEDID;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,13 +226,12 @@ Virge_Init(void)
|
|||||||
si.colorSpaces[1] = B_RGB16;
|
si.colorSpaces[1] = B_RGB16;
|
||||||
si.colorSpaceCount = 2;
|
si.colorSpaceCount = 2;
|
||||||
|
|
||||||
// Get info about the display capabilities (EDID).
|
si.bDisableHdwCursor = false; // allow use of hardware cursor
|
||||||
|
si.bDisableAccelDraw = false; // allow use of accelerated drawing functions
|
||||||
Virge_GetEdidInfo();
|
|
||||||
|
|
||||||
// Setup the mode list.
|
// Setup the mode list.
|
||||||
|
|
||||||
return CreateModeList(IsModeUsable);
|
return CreateModeList(IsModeUsable, Virge_GetEdidInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -251,7 +250,7 @@ Virge_SetFunctionPointers(void)
|
|||||||
gInfo.WaitIdleEmpty = VirgeWaitIdleEmpty;
|
gInfo.WaitIdleEmpty = VirgeWaitIdleEmpty;
|
||||||
|
|
||||||
gInfo.DPMSCapabilities = Virge_DPMSCapabilities;
|
gInfo.DPMSCapabilities = Virge_DPMSCapabilities;
|
||||||
gInfo.DPMSMode = Virge_DPMSMode;
|
gInfo.GetDPMSMode = Virge_GetDPMSMode;
|
||||||
gInfo.SetDPMSMode = Virge_SetDPMSMode;
|
gInfo.SetDPMSMode = Virge_SetDPMSMode;
|
||||||
|
|
||||||
gInfo.LoadCursorImage = Virge_LoadCursorImage;
|
gInfo.LoadCursorImage = Virge_LoadCursorImage;
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ Virge_ModeInit(const DisplayModeEx& mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int width = mode.bytesPerRow >> 3;
|
int width = mode.bytesPerRow >> 3;
|
||||||
regRec.CRTC[19] = 0xFF & width;
|
regRec.CRTC[0x13] = 0xFF & width;
|
||||||
regRec.CR51 = (0x300 & width) >> 4; // Extension bits
|
regRec.CR51 = (0x300 & width) >> 4; // Extension bits
|
||||||
|
|
||||||
regRec.CR33 = 0x20;
|
regRec.CR33 = 0x20;
|
||||||
@@ -694,6 +694,13 @@ Virge_ModeInit(const DisplayModeEx& mode)
|
|||||||
|
|
||||||
Virge_WriteMode(mode, regRec); // write mode registers to hardware
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user