From 80829ec813241c9a702a45e39929286f13c55093 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 5 Jun 2009 02:50:25 +0000 Subject: [PATCH] Imported Gerald Zajac's ATI Mach64 / Rage driver and removed the old GPL-only mach64 driver that wasn't even part of the image anyways. Thanks! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30962 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/jam/HaikuImage | 2 + src/add-ons/accelerants/Jamfile | 3 +- src/add-ons/accelerants/ati/Jamfile | 28 + src/add-ons/accelerants/ati/accelerant.cpp | 222 +++ src/add-ons/accelerants/ati/accelerant.h | 208 ++ src/add-ons/accelerants/ati/cursor.cpp | 81 + src/add-ons/accelerants/ati/engine.cpp | 78 + src/add-ons/accelerants/ati/hooks.cpp | 67 + src/add-ons/accelerants/ati/mach64.h | 476 +++++ src/add-ons/accelerants/ati/mach64_cursor.cpp | 102 + src/add-ons/accelerants/ati/mach64_dpms.cpp | 114 ++ src/add-ons/accelerants/ati/mach64_draw.cpp | 236 +++ src/add-ons/accelerants/ati/mach64_init.cpp | 281 +++ src/add-ons/accelerants/ati/mach64_mode.cpp | 410 ++++ src/add-ons/accelerants/ati/mach64_util.cpp | 88 + src/add-ons/accelerants/ati/mode.cpp | 450 +++++ src/add-ons/accelerants/ati/rage128.h | 271 +++ .../accelerants/ati/rage128_cursor.cpp | 99 + src/add-ons/accelerants/ati/rage128_dpms.cpp | 144 ++ src/add-ons/accelerants/ati/rage128_draw.cpp | 258 +++ src/add-ons/accelerants/ati/rage128_init.cpp | 221 +++ src/add-ons/accelerants/ati/rage128_mode.cpp | 448 +++++ .../accelerants/atimach64/Acceleration.c | 434 ---- src/add-ons/accelerants/atimach64/Cursor.c | 210 -- .../accelerants/atimach64/EngineManagment.c | 83 - .../accelerants/atimach64/GetAccelerantHook.c | 86 - .../accelerants/atimach64/GetModeInfo.c | 73 - .../accelerants/atimach64/GlobalData.c | 10 - .../accelerants/atimach64/GlobalData.h | 16 - .../accelerants/atimach64/InitAccelerant.c | 373 ---- src/add-ons/accelerants/atimach64/Jamfile | 21 - src/add-ons/accelerants/atimach64/Mach64.c | 447 ----- src/add-ons/accelerants/atimach64/Mach64.h | 5 - .../accelerants/atimach64/Mach64fifo.c | 1738 ----------------- .../accelerants/atimach64/Mach64fifo.h | 72 - .../atimach64/ProposeDisplayMode.c | 399 ---- .../accelerants/atimach64/SetDisplayMode.c | 285 --- src/add-ons/accelerants/atimach64/generic.h | 46 - src/add-ons/kernel/drivers/graphics/Jamfile | 3 +- .../kernel/drivers/graphics/ati/Jamfile | 9 + .../kernel/drivers/graphics/ati/driver.cpp | 1151 +++++++++++ .../kernel/drivers/graphics/atimach64/COPYING | 339 ---- .../kernel/drivers/graphics/atimach64/Jamfile | 11 - .../drivers/graphics/atimach64/driver.c | 976 --------- .../drivers/graphics/atimach64/m64info.c | 256 --- 45 files changed, 5446 insertions(+), 5884 deletions(-) create mode 100644 src/add-ons/accelerants/ati/Jamfile create mode 100644 src/add-ons/accelerants/ati/accelerant.cpp create mode 100644 src/add-ons/accelerants/ati/accelerant.h create mode 100644 src/add-ons/accelerants/ati/cursor.cpp create mode 100644 src/add-ons/accelerants/ati/engine.cpp create mode 100644 src/add-ons/accelerants/ati/hooks.cpp create mode 100644 src/add-ons/accelerants/ati/mach64.h create mode 100644 src/add-ons/accelerants/ati/mach64_cursor.cpp create mode 100644 src/add-ons/accelerants/ati/mach64_dpms.cpp create mode 100644 src/add-ons/accelerants/ati/mach64_draw.cpp create mode 100644 src/add-ons/accelerants/ati/mach64_init.cpp create mode 100644 src/add-ons/accelerants/ati/mach64_mode.cpp create mode 100644 src/add-ons/accelerants/ati/mach64_util.cpp create mode 100644 src/add-ons/accelerants/ati/mode.cpp create mode 100644 src/add-ons/accelerants/ati/rage128.h create mode 100644 src/add-ons/accelerants/ati/rage128_cursor.cpp create mode 100644 src/add-ons/accelerants/ati/rage128_dpms.cpp create mode 100644 src/add-ons/accelerants/ati/rage128_draw.cpp create mode 100644 src/add-ons/accelerants/ati/rage128_init.cpp create mode 100644 src/add-ons/accelerants/ati/rage128_mode.cpp delete mode 100644 src/add-ons/accelerants/atimach64/Acceleration.c delete mode 100644 src/add-ons/accelerants/atimach64/Cursor.c delete mode 100644 src/add-ons/accelerants/atimach64/EngineManagment.c delete mode 100644 src/add-ons/accelerants/atimach64/GetAccelerantHook.c delete mode 100644 src/add-ons/accelerants/atimach64/GetModeInfo.c delete mode 100644 src/add-ons/accelerants/atimach64/GlobalData.c delete mode 100644 src/add-ons/accelerants/atimach64/GlobalData.h delete mode 100644 src/add-ons/accelerants/atimach64/InitAccelerant.c delete mode 100644 src/add-ons/accelerants/atimach64/Jamfile delete mode 100644 src/add-ons/accelerants/atimach64/Mach64.c delete mode 100644 src/add-ons/accelerants/atimach64/Mach64.h delete mode 100644 src/add-ons/accelerants/atimach64/Mach64fifo.c delete mode 100644 src/add-ons/accelerants/atimach64/Mach64fifo.h delete mode 100644 src/add-ons/accelerants/atimach64/ProposeDisplayMode.c delete mode 100644 src/add-ons/accelerants/atimach64/SetDisplayMode.c delete mode 100644 src/add-ons/accelerants/atimach64/generic.h create mode 100644 src/add-ons/kernel/drivers/graphics/ati/Jamfile create mode 100644 src/add-ons/kernel/drivers/graphics/ati/driver.cpp delete mode 100644 src/add-ons/kernel/drivers/graphics/atimach64/COPYING delete mode 100644 src/add-ons/kernel/drivers/graphics/atimach64/Jamfile delete mode 100644 src/add-ons/kernel/drivers/graphics/atimach64/driver.c delete mode 100644 src/add-ons/kernel/drivers/graphics/atimach64/m64info.c diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 7361b82a3c..18eff40674 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -100,6 +100,7 @@ SYSTEM_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant $(X86_ONLY)nvidia.accelerant $(X86_ONLY)matrox.accelerant $(X86_ONLY)neomagic.accelerant $(X86_ONLY)intel_extreme.accelerant $(X86_ONLY)s3.accelerant $(X86_ONLY)vesa.accelerant + $(X86_ONLY)ati.accelerant #$(X86_ONLY)via.accelerant #$(X86_ONLY)vmware.accelerant ; @@ -142,6 +143,7 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia sis7018 usb_audio ; SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia $(X86_ONLY)neomagic $(X86_ONLY)matrox $(X86_ONLY)intel_extreme $(X86_ONLY)s3 $(X86_ONLY)vesa #$(X86_ONLY)via #$(X86_ONLY)vmware + $(X86_ONLY)ati ; SYSTEM_ADD_ONS_DRIVERS_MIDI = emuxki ; SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)broadcom440x diff --git a/src/add-ons/accelerants/Jamfile b/src/add-ons/accelerants/Jamfile index 2f3433cd72..6281ab3c28 100644 --- a/src/add-ons/accelerants/Jamfile +++ b/src/add-ons/accelerants/Jamfile @@ -1,5 +1,6 @@ SubDir HAIKU_TOP src add-ons accelerants ; +SubInclude HAIKU_TOP src add-ons accelerants ati ; SubInclude HAIKU_TOP src add-ons accelerants common ; SubInclude HAIKU_TOP src add-ons accelerants et6x00 ; SubInclude HAIKU_TOP src add-ons accelerants intel_extreme ; @@ -13,5 +14,3 @@ SubInclude HAIKU_TOP src add-ons accelerants tdfx ; SubInclude HAIKU_TOP src add-ons accelerants vesa ; SubInclude HAIKU_TOP src add-ons accelerants via ; SubInclude HAIKU_TOP src add-ons accelerants vmware ; - -SubIncludeGPL HAIKU_TOP src add-ons accelerants atimach64 ; diff --git a/src/add-ons/accelerants/ati/Jamfile b/src/add-ons/accelerants/ati/Jamfile new file mode 100644 index 0000000000..f265135879 --- /dev/null +++ b/src/add-ons/accelerants/ati/Jamfile @@ -0,0 +1,28 @@ +SubDir HAIKU_TOP src add-ons accelerants ati ; + +UsePrivateHeaders graphics ; +UsePrivateHeaders [ FDirName graphics ati ] ; +UsePrivateHeaders [ FDirName graphics common ] ; + +Addon ati.accelerant : + accelerant.cpp + cursor.cpp + engine.cpp + hooks.cpp + mode.cpp + + mach64_cursor.cpp + mach64_dpms.cpp + mach64_draw.cpp + mach64_init.cpp + mach64_mode.cpp + mach64_util.cpp + + rage128_cursor.cpp + rage128_dpms.cpp + rage128_draw.cpp + rage128_init.cpp + rage128_mode.cpp + + : be libaccelerantscommon.a +; diff --git a/src/add-ons/accelerants/ati/accelerant.cpp b/src/add-ons/accelerants/ati/accelerant.cpp new file mode 100644 index 0000000000..0497134612 --- /dev/null +++ b/src/add-ons/accelerants/ati/accelerant.cpp @@ -0,0 +1,222 @@ +/* + Copyright 2007-2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2007-2009 +*/ + +#include "accelerant.h" + +#include +#include +#include + + + +AccelerantInfo gInfo; // global data used by various source files of accelerant. + + + +static status_t +InitCommon(int fileDesc) +{ + // Initialization function used by primary and cloned accelerants. + + gInfo.deviceFileDesc = fileDesc; + + // Get area ID of shared data from driver. + + area_id sharedArea; + status_t result = ioctl(gInfo.deviceFileDesc, ATI_GET_SHARED_DATA, + &sharedArea, sizeof(sharedArea)); + if (result != B_OK) + return result; + + gInfo.sharedInfoArea = clone_area("ATI shared info", (void**)&(gInfo.sharedInfo), + B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, sharedArea); + if (gInfo.sharedInfoArea < 0) + return gInfo.sharedInfoArea; // sharedInfoArea has error code + + gInfo.regsArea = clone_area("ATI regs area", (void**)&(gInfo.regs), + B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea); + if (gInfo.regsArea < 0) { + delete_area(gInfo.sharedInfoArea); + return gInfo.regsArea; // regsArea has error code + } + + // Set pointers to various device specific functions. + + if (RAGE128_FAMILY(gInfo.sharedInfo->chipType)) + Rage128_SetFunctionPointers(); + else if (MACH64_FAMILY(gInfo.sharedInfo->chipType)) + Mach64_SetFunctionPointers(); + else + return B_ERROR; // undefined chip type code + + return B_OK; +} + + +static void +UninitCommon(void) +{ + // This function is used by both primary and cloned accelerants. + + delete_area(gInfo.regsArea); + gInfo.regs = 0; + + delete_area(gInfo.sharedInfoArea); + gInfo.sharedInfo = 0; +} + + +status_t +InitAccelerant(int fileDesc) +{ + // Initialize the accelerant. fileDesc is the file handle of the device + // (in /dev/graphics) that has been opened by the app_server. + + TRACE("Enter InitAccelerant()\n"); + + gInfo.bAccelerantIsClone = false; // indicate this is primary accelerant + + status_t result = InitCommon(fileDesc); + if (result == B_OK) { + SharedInfo& si = *gInfo.sharedInfo; + + TRACE("Vendor ID: 0x%X, Device ID: 0x%X\n", si.vendorID, si.deviceID); + + // Ensure that InitAccelerant is executed just once (copies should be clones) + + if (si.bAccelerantInUse) { + result = B_NOT_ALLOWED; + } else { + result = gInfo.ChipInit(); // perform init related to current chip + if (result == B_OK) { + result = si.engineLock.Init("ATI engine lock"); + if (result == B_OK) { + if (gInfo.ShowCursor != NULL) + gInfo.ShowCursor(false); + + // ensure that this function won't be executed again + // (copies should be clones) + si.bAccelerantInUse = true; + } + } + } + + if (result != B_OK) + UninitCommon(); + } + + TRACE("Leave InitAccelerant(), result: 0x%X\n", result); + return result; +} + + +ssize_t +AccelerantCloneInfoSize(void) +{ + // Return the number of bytes required to hold the information required + // to clone the device. The information is merely the name of the device; + // thus, return the size of the name buffer. + + return B_OS_NAME_LENGTH; +} + + +void +GetAccelerantCloneInfo(void* data) +{ + // Return the info required to clone the device. Argument data points to + // a buffer which is the size returned by AccelerantCloneInfoSize(). + + ioctl(gInfo.deviceFileDesc, ATI_DEVICE_NAME, data, B_OS_NAME_LENGTH); +} + + +status_t +CloneAccelerant(void* data) +{ + // Initialize a copy of the accelerant as a clone. Argument data points to + // a copy of the data which was returned by GetAccelerantCloneInfo(). + + TRACE("Enter CloneAccelerant()\n"); + + char path[MAXPATHLEN] = "/dev/"; + strcat(path, (const char*)data); + + gInfo.deviceFileDesc = open(path, B_READ_WRITE); // open the device + if (gInfo.deviceFileDesc < 0) + return errno; + + gInfo.bAccelerantIsClone = true; + + status_t result = InitCommon(gInfo.deviceFileDesc); + if (result != B_OK) { + close(gInfo.deviceFileDesc); + return result; + } + + result = gInfo.modeListArea = clone_area("ATI cloned display_modes", + (void**) &gInfo.modeList, B_ANY_ADDRESS, B_READ_AREA, + gInfo.sharedInfo->modeArea); + if (result < 0) { + UninitCommon(); + close(gInfo.deviceFileDesc); + return result; + } + + TRACE("Leave CloneAccelerant()\n"); + return B_OK; +} + + +void +UninitAccelerant(void) +{ + delete_area(gInfo.modeListArea); + gInfo.modeList = NULL; + + UninitCommon(); + + if (gInfo.bAccelerantIsClone) + close(gInfo.deviceFileDesc); +} + + +sem_id +AccelerantRetraceSemaphore(void) +{ + // Return the semaphore id that will be used to signal that a vertical + // retrace occured. + + return B_ERROR; +} + + +status_t +GetAccelerantDeviceInfo(accelerant_device_info* adi) +{ + // Get info about the device. + + SharedInfo& si = *gInfo.sharedInfo; + + adi->version = 1; + strcpy(adi->name, "ATI chipset"); + strcpy(adi->serial_no, "unknown"); + adi->memory = si.maxFrameBufferSize; + adi->dac_speed = 270; + + // If laptop LCD display or flat panel display (ie, DVI interface), set chip + // set name to "VESA" so that Screen Preferences will not show a refresh rate + // since we will be using VESA code to set the video mode. + + if (si.displayType == MT_VGA) + strcpy(adi->chipset, si.chipName); + else + strcpy(adi->chipset, "VESA"); + + return B_OK; +} diff --git a/src/add-ons/accelerants/ati/accelerant.h b/src/add-ons/accelerants/ati/accelerant.h new file mode 100644 index 0000000000..5291b90c54 --- /dev/null +++ b/src/add-ons/accelerants/ati/accelerant.h @@ -0,0 +1,208 @@ +/* + Copyright 2007-2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2007-2009 +*/ + +#ifndef _ACCELERANT_H +#define _ACCELERANT_H + +#include "DriverInterface.h" + + + +#undef TRACE + +#ifdef ENABLE_DEBUG_TRACE +extern "C" void _sPrintf(const char* format, ...); +# define TRACE(x...) _sPrintf("ati: " x) +#else +# define TRACE(x...) ; +#endif + + +// Global data used by various source files of the accelerant. + +struct AccelerantInfo { + int deviceFileDesc; // file descriptor of kernel driver + + SharedInfo* sharedInfo; // address of info shared between accelerants & driver + area_id sharedInfoArea; // shared info area ID + + uint8* regs; // base address of MMIO register area + area_id regsArea; // MMIO register area ID + + display_mode* modeList; // list of standard display modes + area_id modeListArea; // mode list area ID + + bool bAccelerantIsClone; // true if this is a cloned accelerant + + // Pointers to various global accelerant functions. + //------------------------------------------------- + + // Pointers to wait handlers. + void (*WaitForFifo)(uint32); + void (*WaitForIdle)(); + + // Pointers to DPMS functions. + uint32 (*DPMSCapabilities)(void); + uint32 (*GetDPMSMode)(void); + status_t (*SetDPMSMode)(uint32 dpms_flags); + + // Pointers to cursor functions. + bool (*LoadCursorImage)(int width, int height, uint8* and_mask, uint8* xor_mask); + void (*SetCursorPosition)(int x, int y); + void (*ShowCursor)(bool bShow); + + // Pointers to 2D acceleration functions. + void (*FillRectangle)(engine_token*, uint32 color, fill_rect_params*, uint32 count); + void (*FillSpan)(engine_token*, uint32 color, uint16* list, uint32 count); + void (*InvertRectangle)(engine_token*, fill_rect_params*, uint32 count); + void (*ScreenToScreenBlit)(engine_token*, blit_params*, uint32 count); + + // Pointers to other functions. + void (*AdjustFrame)(const DisplayModeEx& mode); + status_t (*ChipInit)(void); + bool (*GetColorSpaceParams)(int colorSpace, uint8& bpp, uint32& maxPixelClk); + status_t (*SetDisplayMode)(const DisplayModeEx& mode); + void (*SetIndexedColors)(uint count, uint8 first, uint8* color_data, uint32 flags); +}; + +extern AccelerantInfo gInfo; + + +// Prototypes of the interface functions called by the app_server. Note that +// the functions that are unique to a particular chip family, will be prefixed +// with the name of the family, and the functions that are applicable to all +// chips will have no prefix. +//================================================================ + +#if defined(__cplusplus) +extern "C" { +#endif + +// General +status_t InitAccelerant(int fd); +ssize_t AccelerantCloneInfoSize(void); +void GetAccelerantCloneInfo(void* data); +status_t CloneAccelerant(void* data); +void UninitAccelerant(void); +status_t GetAccelerantDeviceInfo(accelerant_device_info* adi); +sem_id AccelerantRetraceSemaphore(void); + +// Mode Configuration +uint32 AccelerantModeCount(void); +status_t GetModeList(display_mode* dm); +status_t ProposeDisplayMode(display_mode* target, const display_mode* low, const display_mode* high); +status_t SetDisplayMode(display_mode* mode_to_set); +status_t GetDisplayMode(display_mode* current_mode); +status_t GetFrameBufferConfig(frame_buffer_config* a_frame_buffer); +status_t GetPixelClockLimits(display_mode* dm, uint32* low, uint32* high); +status_t MoveDisplay(uint16 h_display_start, uint16 v_display_start); +status_t GetTimingConstraints(display_timing_constraints* dtc); +void Mach64_SetIndexedColors(uint count, uint8 first, uint8* color_data, uint32 flags); +void Rage128_SetIndexedColors(uint count, uint8 first, uint8* color_data, uint32 flags); +status_t GetPreferredDisplayMode(display_mode* preferredMode); +status_t GetEdidInfo(void* info, size_t size, uint32* _version); + +// DPMS +uint32 Mach64_DPMSCapabilities(void); +uint32 Mach64_GetDPMSMode(void); +status_t Mach64_SetDPMSMode(uint32 dpms_flags); + +uint32 Rage128_DPMSCapabilities(void); +uint32 Rage128_GetDPMSMode(void); +status_t Rage128_SetDPMSMode(uint32 dpms_flags); + +// Cursor +status_t SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, + uint8* andMask, uint8* xorMask); +void MoveCursor(uint16 x, uint16 y); + +// Engine Management +uint32 AccelerantEngineCount(void); +status_t AcquireEngine(uint32 capabilities, uint32 max_wait, sync_token* st, engine_token** et); +status_t ReleaseEngine(engine_token* et, sync_token* st); +void WaitEngineIdle(void); +status_t GetSyncToken(engine_token* et, sync_token* st); +status_t SyncToToken(sync_token* st); + +// 2D acceleration +void Mach64_FillRectangle(engine_token* et, uint32 color, fill_rect_params* list, uint32 count); +void Mach64_FillSpan(engine_token* et, uint32 color, uint16* list, uint32 count); +void Mach64_InvertRectangle(engine_token* et, fill_rect_params* list, uint32 count); +void Mach64_ScreenToScreenBlit(engine_token* et, blit_params* list, uint32 count); + +void Rage128_FillRectangle(engine_token* et, uint32 color, fill_rect_params* list, uint32 count); +void Rage128_FillSpan(engine_token* et, uint32 color, uint16* list, uint32 count); +void Rage128_InvertRectangle(engine_token* et, fill_rect_params* list, uint32 count); +void Rage128_ScreenToScreenBlit(engine_token* et, blit_params* list, uint32 count); + +#if defined(__cplusplus) +} +#endif + + + +// Prototypes for other functions that are called from source files other than +// where they are defined. +//============================================================================ + +status_t CreateModeList(bool (*checkMode)(const display_mode* mode)); +uint16 GetVesaModeNumber(const display_mode& mode, uint8 bitsPerPixel); +bool IsModeUsable(const display_mode* mode); + +// Mach64 functions. + +void Mach64_EngineReset(void); +void Mach64_EngineInit(const DisplayModeEx& mode); + +bool Mach64_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask); +void Mach64_SetCursorPosition(int x, int y); +void Mach64_ShowCursor(bool bShow); + +void Mach64_AdjustFrame(const DisplayModeEx& mode); +status_t Mach64_SetDisplayMode(const DisplayModeEx& mode); +void Mach64_SetFunctionPointers(void); + +int Mach64_Divide(int numerator, int denom, int shift, const int roundingKind); +void Mach64_ReduceRatio(int *numerator, int *denominator); + + +// Rage128 functions. + +void Rage128_EngineFlush(void); +void Rage128_EngineReset(void); +void Rage128_EngineInit(const DisplayModeEx& mode); + +bool Rage128_GetEdidInfo(void); + +bool Rage128_LoadCursorImage(int width, int height, uint8* and_mask, uint8* xor_mask); +void Rage128_SetCursorPosition(int x, int y); +void Rage128_ShowCursor(bool bShow); + +void Rage128_AdjustFrame(const DisplayModeEx& mode); +status_t Rage128_SetDisplayMode(const DisplayModeEx& mode); +void Rage128_SetFunctionPointers(void); + + +// Macros for memory mapped I/O for both Mach64 and Rage128 chips. +//================================================================ + +#define INREG8(addr) *((vuint8*)(gInfo.regs + addr)) +#define INREG16(addr) *((vuint16*)(gInfo.regs + addr)) +#define INREG(addr) *((vuint32*)(gInfo.regs + addr)) + +#define OUTREG8(addr, val) *((vuint8*)(gInfo.regs + addr)) = val +#define OUTREG16(addr, val) *((vuint16*)(gInfo.regs + addr)) = val +#define OUTREG(addr, val) *((vuint32*)(gInfo.regs + addr)) = val + +// Write a value to an 32-bit reg using a mask. The mask selects the +// bits to be modified. +#define OUTREGM(addr, value, mask) \ + (OUTREG(addr, (INREG(addr) & ~mask) | (value & mask))) + + +#endif // _ACCELERANT_H diff --git a/src/add-ons/accelerants/ati/cursor.cpp b/src/add-ons/accelerants/ati/cursor.cpp new file mode 100644 index 0000000000..4b22d08dde --- /dev/null +++ b/src/add-ons/accelerants/ati/cursor.cpp @@ -0,0 +1,81 @@ +/* + Copyright 1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. + + Other authors: + Gerald Zajac 2007-2008 +*/ + +#include "accelerant.h" + + +status_t +SetCursorShape(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, + uint8* andMask, uint8* xorMask) +{ + // NOTE: Currently, for BeOS, cursor width and height must be equal to 16. + + if ((width != 16) || (height != 16)) { + return B_ERROR; + } else if ((hot_x >= width) || (hot_y >= height)) { + return B_ERROR; + } else { + // Update cursor variables appropriately. + + SharedInfo& si = *gInfo.sharedInfo; + si.cursorHotX = hot_x; + si.cursorHotY = hot_y; + + if ( ! gInfo.LoadCursorImage(width, height, andMask, xorMask)) + return B_ERROR; + } + + return B_OK; +} + + +void +MoveCursor(uint16 xPos, uint16 yPos) +{ + // Move the cursor to the specified position on the desktop. If we're + // using some kind of virtual desktop, adjust the display start position + // accordingly and position the cursor in the proper "virtual" location. + + int x = xPos; // use signed int's since chip specific functions + int y = yPos; // need signed int to determine if cursor off screen + + SharedInfo& si = *gInfo.sharedInfo; + DisplayModeEx& dm = si.displayMode; + + uint16 hds = dm.h_display_start; // current horizontal starting pixel + uint16 vds = dm.v_display_start; // current vertical starting line + + // Clamp cursor to virtual display. + if (x >= dm.virtual_width) + x = dm.virtual_width - 1; + if (y >= dm.virtual_height) + y = dm.virtual_height - 1; + + // Adjust h/v display start to move cursor onto screen. + if (x >= (dm.timing.h_display + hds)) + hds = x - dm.timing.h_display + 1; + else if (x < hds) + hds = x; + + if (y >= (dm.timing.v_display + vds)) + vds = y - dm.timing.v_display + 1; + else if (y < vds) + vds = y; + + // Reposition the desktop on the display if required. + if (hds != dm.h_display_start || vds != dm.v_display_start) + MoveDisplay(hds, vds); + + // Put cursor in correct physical position. + x -= (hds + si.cursorHotX); + y -= (vds + si.cursorHotY); + + // Position the cursor on the display. + gInfo.SetCursorPosition(x, y); +} + diff --git a/src/add-ons/accelerants/ati/engine.cpp b/src/add-ons/accelerants/ati/engine.cpp new file mode 100644 index 0000000000..15ff0f1476 --- /dev/null +++ b/src/add-ons/accelerants/ati/engine.cpp @@ -0,0 +1,78 @@ +/* + Copyright 1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. + + Other authors: + Gerald Zajac 2007-2008 +*/ + +#include "accelerant.h" + + +static engine_token engineToken = { 1, B_2D_ACCELERATION, NULL }; + + +uint32 +AccelerantEngineCount(void) +{ + return 1; +} + + +status_t +AcquireEngine(uint32 capabilities, uint32 max_wait, + sync_token* st, engine_token** et) +{ + (void)capabilities; // avoid compiler warning for unused arg + (void)max_wait; // avoid compiler warning for unused arg + + if (gInfo.sharedInfo->engineLock.Acquire() != B_OK) + return B_ERROR; + + // Sync if required. + if (st) + SyncToToken(st); + + // Return an engine token. + *et = &engineToken; + return B_OK; +} + + +status_t +ReleaseEngine(engine_token* et, sync_token* st) +{ + // Update the sync token, if any. + if (st) + GetSyncToken(et, st); + + gInfo.sharedInfo->engineLock.Release(); + return B_OK; +} + + +void +WaitEngineIdle(void) +{ + gInfo.WaitForIdle(); // wait until engine is completely idle +} + + +status_t +GetSyncToken(engine_token* et, sync_token* st) +{ + st->engine_id = et->engine_id; + st->counter = 0; + return B_OK; +} + + +status_t +SyncToToken(sync_token* st) +{ + (void)st; // avoid compiler warning for unused arg + + WaitEngineIdle(); + return B_OK; +} + diff --git a/src/add-ons/accelerants/ati/hooks.cpp b/src/add-ons/accelerants/ati/hooks.cpp new file mode 100644 index 0000000000..320c4996c0 --- /dev/null +++ b/src/add-ons/accelerants/ati/hooks.cpp @@ -0,0 +1,67 @@ +/* + Copyright 2008 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2008 +*/ + +#include "accelerant.h" + + +extern "C" void* +get_accelerant_hook(uint32 feature, void* data) +{ + (void)data; // avoid compiler warning for unused arg + + switch (feature) { + // General + case B_INIT_ACCELERANT: return (void*)InitAccelerant; + case B_UNINIT_ACCELERANT: return (void*)UninitAccelerant; + case B_CLONE_ACCELERANT: return (void*)CloneAccelerant; + case B_ACCELERANT_CLONE_INFO_SIZE: return (void*)AccelerantCloneInfoSize; + case B_GET_ACCELERANT_CLONE_INFO: return (void*)GetAccelerantCloneInfo; + case B_GET_ACCELERANT_DEVICE_INFO: return (void*)GetAccelerantDeviceInfo; + case B_ACCELERANT_RETRACE_SEMAPHORE: return (void*)AccelerantRetraceSemaphore; + + // Mode Configuration + case B_ACCELERANT_MODE_COUNT: return (void*)AccelerantModeCount; + case B_GET_MODE_LIST: return (void*)GetModeList; + case B_PROPOSE_DISPLAY_MODE: return (void*)ProposeDisplayMode; + case B_SET_DISPLAY_MODE: return (void*)SetDisplayMode; + case B_GET_DISPLAY_MODE: return (void*)GetDisplayMode; + case B_GET_PREFERRED_DISPLAY_MODE: return (void*)GetPreferredDisplayMode; + case B_GET_EDID_INFO: return (void*)GetEdidInfo; + case B_GET_FRAME_BUFFER_CONFIG: return (void*)GetFrameBufferConfig; + case B_GET_PIXEL_CLOCK_LIMITS: return (void*)GetPixelClockLimits; + case B_MOVE_DISPLAY: return (void*)MoveDisplay; + case B_SET_INDEXED_COLORS: return (void*)(gInfo.SetIndexedColors); + case B_GET_TIMING_CONSTRAINTS: return (void*)GetTimingConstraints; + + // DPMS + case B_DPMS_CAPABILITIES: return (void*)(gInfo.DPMSCapabilities); + case B_DPMS_MODE: return (void*)(gInfo.GetDPMSMode); + case B_SET_DPMS_MODE: return (void*)(gInfo.SetDPMSMode); + + // Cursor + case B_SET_CURSOR_SHAPE: return (void*)SetCursorShape; + case B_MOVE_CURSOR: return (void*)MoveCursor; + case B_SHOW_CURSOR: return (void*)(gInfo.ShowCursor); + + // Engine Management + case B_ACCELERANT_ENGINE_COUNT: return (void*)AccelerantEngineCount; + case B_ACQUIRE_ENGINE: return (void*)AcquireEngine; + case B_RELEASE_ENGINE: return (void*)ReleaseEngine; + case B_WAIT_ENGINE_IDLE: return (void*)WaitEngineIdle; + case B_GET_SYNC_TOKEN: return (void*)GetSyncToken; + case B_SYNC_TO_TOKEN: return (void*)SyncToToken; + + // 2D acceleration + case B_SCREEN_TO_SCREEN_BLIT: return (void*)(gInfo.ScreenToScreenBlit); + case B_FILL_RECTANGLE: return (void*)(gInfo.FillRectangle); + case B_INVERT_RECTANGLE: return (void*)(gInfo.InvertRectangle); + case B_FILL_SPAN: return (void*)(gInfo.FillSpan); + } + + return NULL; // Return null pointer for any feature not handled above +} diff --git a/src/add-ons/accelerants/ati/mach64.h b/src/add-ons/accelerants/ati/mach64.h new file mode 100644 index 0000000000..7d410c206e --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64.h @@ -0,0 +1,476 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + +#ifndef __MACH64_H__ +#define __MACH64_H__ + + +#define CURSOR_BYTES 1024 // bytes used for cursor image in video memory + +// Memory types for Mach64 chips. + +enum Mach64_MemoryType +{ + MEM_NONE, + MEM_DRAM, + MEM_EDO, + MEM_PSEUDO_EDO, + MEM_SDRAM, + MEM_SGRAM, + MEM_SGRAM32, + MEM_TYPE_7 +}; + + +// Macros to get/set a contiguous bit field. Arguments should not be +// self-modifying. + +#define UnitOf(___Value) (((((___Value) ^ ((___Value) - 1)) + 1) >> 1) \ + | ((((___Value) ^ ((___Value) - 1)) >> 1) + 1)) + +#define GetBits(__Value, _Mask) (((__Value) & (_Mask)) / UnitOf(_Mask)) +#define SetBits(__Value, _Mask) (((__Value) * UnitOf(_Mask)) & (_Mask)) + + +// Register MMIO addresses - expressed in BYTE offsets. +//----------------------------------------------------- + +#define CRTC_H_TOTAL_DISP (0x0c00 + 0x0000) // Dword offset 00 +#define CRTC_H_SYNC_STRT_WID (0x0c00 + 0x0004) // Dword offset 01 +#define CRTC_V_TOTAL_DISP (0x0c00 + 0x0008) // Dword offset 02 +#define CRTC_V_SYNC_STRT_WID (0x0c00 + 0x000C) // Dword offset 03 +#define CRTC_VLINE_CRNT_VLINE (0x0c00 + 0x0010) // Dword offset 04 +#define CRTC_OFF_PITCH (0x0c00 + 0x0014) // Dword offset 05 +#define CRTC_INT_CNTL (0x0c00 + 0x0018) // Dword offset 06 +#define CRTC_GEN_CNTL (0x0c00 + 0x001C) // Dword offset 07 + +#define DSP_CONFIG (0x0c00 + 0x0020) // Dword offset 08 +#define DSP_ON_OFF (0x0c00 + 0x0024) // Dword offset 09 + +#define SHARED_CNTL (0x0c00 + 0x0038) // Dword offset 0E + +#define OVR_CLR (0x0c00 + 0x0040) // Dword offset 10 +#define OVR_WID_LEFT_RIGHT (0x0c00 + 0x0044) // Dword offset 11 +#define OVR_WID_TOP_BOTTOM (0x0c00 + 0x0048) // Dword offset 12 + +#define CUR_CLR0 (0x0c00 + 0x0060) // Dword offset 18 +#define CUR_CLR1 (0x0c00 + 0x0064) // Dword offset 19 +#define CUR_OFFSET (0x0c00 + 0x0068) // Dword offset 1A +#define CUR_HORZ_VERT_POSN (0x0c00 + 0x006C) // Dword offset 1B +#define CUR_HORZ_VERT_OFF (0x0c00 + 0x0070) // Dword offset 1C + +#define HW_DEBUG (0x0c00 + 0x007C) // Dword offset 1F + +#define SCRATCH_REG0 (0x0c00 + 0x0080) // Dword offset 20 +#define SCRATCH_REG1 (0x0c00 + 0x0084) // Dword offset 21 + +#define CLOCK_CNTL (0x0c00 + 0x0090) // Dword offset 24 + +#define BUS_CNTL (0x0c00 + 0x00A0) // Dword offset 28 + +#define LCD_INDEX (0x0c00 + 0x00A4) // Dword offset 29 +#define LCD_DATA (0x0c00 + 0x00A8) // Dword offset 2A + +#define MEM_CNTL (0x0c00 + 0x00B0) // Dword offset 2C + +#define MEM_VGA_WP_SEL (0x0c00 + 0x00B4) // Dword offset 2D +#define MEM_VGA_RP_SEL (0x0c00 + 0x00B8) // Dword offset 2E + +#define DAC_REGS (0x0c00 + 0x00C0) // Dword offset 30 +#define DAC_W_INDEX (DAC_REGS + 0) +#define DAC_DATA (DAC_REGS + 1) +#define DAC_MASK (DAC_REGS + 2) +#define DAC_R_INDEX (DAC_REGS + 3) +#define DAC_CNTL (0x0c00 + 0x00C4) // Dword offset 31 + +#define GEN_TEST_CNTL (0x0c00 + 0x00D0) // Dword offset 34 + +#define CONFIG_CNTL (0x0c00 + 0x00DC // Dword offset 37 (CT, ET, VT) +#define CONFIG_CHIP_ID (0x0c00 + 0x00E0) // Dword offset 38 +#define CONFIG_STAT0 (0x0c00 + 0x00E4) // Dword offset 39 +#define CONFIG_STAT1 (0x0c00 + 0x00E8) // Dword offset 3A + +#define DST_OFF_PITCH (0x0c00 + 0x0100) // Dword offset 40 +#define DST_X (0x0c00 + 0x0104) // Dword offset 41 +#define DST_Y (0x0c00 + 0x0108) // Dword offset 42 +#define DST_Y_X (0x0c00 + 0x010C) // Dword offset 43 +#define DST_WIDTH (0x0c00 + 0x0110) // Dword offset 44 +#define DST_HEIGHT (0x0c00 + 0x0114) // Dword offset 45 +#define DST_HEIGHT_WIDTH (0x0c00 + 0x0118) // Dword offset 46 +#define DST_X_WIDTH (0x0c00 + 0x011C) // Dword offset 47 +#define DST_BRES_LNTH (0x0c00 + 0x0120) // Dword offset 48 +#define DST_BRES_ERR (0x0c00 + 0x0124) // Dword offset 49 +#define DST_BRES_INC (0x0c00 + 0x0128) // Dword offset 4A +#define DST_BRES_DEC (0x0c00 + 0x012C) // Dword offset 4B +#define DST_CNTL (0x0c00 + 0x0130) // Dword offset 4C + +#define SRC_OFF_PITCH (0x0c00 + 0x0180) // Dword offset 60 +#define SRC_X (0x0c00 + 0x0184) // Dword offset 61 +#define SRC_Y (0x0c00 + 0x0188) // Dword offset 62 +#define SRC_Y_X (0x0c00 + 0x018C) // Dword offset 63 +#define SRC_WIDTH1 (0x0c00 + 0x0190) // Dword offset 64 +#define SRC_HEIGHT1 (0x0c00 + 0x0194) // Dword offset 65 +#define SRC_HEIGHT1_WIDTH1 (0x0c00 + 0x0198) // Dword offset 66 +#define SRC_X_START (0x0c00 + 0x019C) // Dword offset 67 +#define SRC_Y_START (0x0c00 + 0x01A0) // Dword offset 68 +#define SRC_Y_X_START (0x0c00 + 0x01A4) // Dword offset 69 +#define SRC_WIDTH2 (0x0c00 + 0x01A8) // Dword offset 6A +#define SRC_HEIGHT2 (0x0c00 + 0x01AC) // Dword offset 6B +#define SRC_HEIGHT2_WIDTH2 (0x0c00 + 0x01B0) // Dword offset 6C +#define SRC_CNTL (0x0c00 + 0x01B4) // Dword offset 6D + +#define HOST_DATA0 (0x0c00 + 0x0200) // Dword offset 80 +#define HOST_DATA1 (0x0c00 + 0x0204) // Dword offset 81 +#define HOST_DATA2 (0x0c00 + 0x0208) // Dword offset 82 +#define HOST_DATA3 (0x0c00 + 0x020C) // Dword offset 83 +#define HOST_DATA4 (0x0c00 + 0x0210) // Dword offset 84 +#define HOST_DATA5 (0x0c00 + 0x0214) // Dword offset 85 +#define HOST_DATA6 (0x0c00 + 0x0218) // Dword offset 86 +#define HOST_DATA7 (0x0c00 + 0x021C) // Dword offset 87 +#define HOST_DATA8 (0x0c00 + 0x0220) // Dword offset 88 +#define HOST_DATA9 (0x0c00 + 0x0224) // Dword offset 89 +#define HOST_DATAA (0x0c00 + 0x0228) // Dword offset 8A +#define HOST_DATAB (0x0c00 + 0x022C) // Dword offset 8B +#define HOST_DATAC (0x0c00 + 0x0230) // Dword offset 8C +#define HOST_DATAD (0x0c00 + 0x0234) // Dword offset 8D +#define HOST_DATAE (0x0c00 + 0x0238) // Dword offset 8E +#define HOST_DATAF (0x0c00 + 0x023C) // Dword offset 8F +#define HOST_CNTL (0x0c00 + 0x0240) // Dword offset 90 + +#define PAT_REG0 (0x0c00 + 0x0280) // Dword offset A0 +#define PAT_REG1 (0x0c00 + 0x0284) // Dword offset A1 +#define PAT_CNTL (0x0c00 + 0x0288) // Dword offset A2 + +#define SC_LEFT (0x0c00 + 0x02A0) // Dword offset A8 +#define SC_RIGHT (0x0c00 + 0x02A4) // Dword offset A9 +#define SC_LEFT_RIGHT (0x0c00 + 0x02A8) // Dword offset AA +#define SC_TOP (0x0c00 + 0x02AC) // Dword offset AB +#define SC_BOTTOM (0x0c00 + 0x02B0) // Dword offset AC +#define SC_TOP_BOTTOM (0x0c00 + 0x02B4) // Dword offset AD + +#define DP_BKGD_CLR (0x0c00 + 0x02C0) // Dword offset B0 +#define DP_FRGD_CLR (0x0c00 + 0x02C4) // Dword offset B1 +#define DP_WRITE_MASK (0x0c00 + 0x02C8) // Dword offset B2 +#define DP_CHAIN_MASK (0x0c00 + 0x02CC) // Dword offset B3 +#define DP_PIX_WIDTH (0x0c00 + 0x02D0) // Dword offset B4 +#define DP_MIX (0x0c00 + 0x02D4) // Dword offset B5 +#define DP_SRC (0x0c00 + 0x02D8) // Dword offset B6 + +#define CLR_CMP_CLR (0x0c00 + 0x0300) // Dword offset C0 +#define CLR_CMP_MASK (0x0c00 + 0x0304) // Dword offset C1 +#define CLR_CMP_CNTL (0x0c00 + 0x0308) // Dword offset C2 + +#define FIFO_STAT (0x0c00 + 0x0310) // Dword offset C4 + +#define CONTEXT_MASK (0x0c00 + 0x0320) // Dword offset C8 +#define CONTEXT_LOAD_CNTL (0x0c00 + 0x032C) // Dword offset CB + +#define GUI_TRAJ_CNTL (0x0c00 + 0x0330) // Dword offset CC +#define GUI_STAT (0x0c00 + 0x0338) // Dword offset CE + + +// CRTC control values. + +#define CRTC_H_SYNC_NEG 0x00200000 +#define CRTC_V_SYNC_NEG 0x00200000 + +#define CRTC_DBL_SCAN_EN 0x00000001 +#define CRTC_INTERLACE_EN 0x00000002 +#define CRTC_HSYNC_DIS 0x00000004 +#define CRTC_VSYNC_DIS 0x00000008 +#define CRTC_CSYNC_EN 0x00000010 +#define CRTC_PIX_BY_2_EN 0x00000020 +#define CRTC_DISPLAY_DIS 0x00000040 +#define CRTC_VGA_XOVERSCAN 0x00000080 + +#define CRTC_PIX_WIDTH 0x00000700 +#define CRTC_PIX_WIDTH_4BPP 0x00000100 +#define CRTC_PIX_WIDTH_8BPP 0x00000200 +#define CRTC_PIX_WIDTH_15BPP 0x00000300 +#define CRTC_PIX_WIDTH_16BPP 0x00000400 +#define CRTC_PIX_WIDTH_24BPP 0x00000500 +#define CRTC_PIX_WIDTH_32BPP 0x00000600 + +#define CRTC_BYTE_PIX_ORDER 0x00000800 +#define CRTC_PIX_ORDER_MSN_LSN 0x00000000 +#define CRTC_PIX_ORDER_LSN_MSN 0x00000800 + +#define CRTC_FIFO_LWM 0x000f0000 +#define CRTC2_PIX_WIDTH 0x000e0000 +#define CRTC_VGA_128KAP_PAGING 0x00100000 +#define CRTC_VFC_SYNC_TRISTATE 0x00200000 +#define CRTC2_EN 0x00200000 +#define CRTC_LOCK_REGS 0x00400000 +#define CRTC_SYNC_TRISTATE 0x00800000 +#define CRTC_EXT_DISP_EN 0x01000000 +#define CRTC_EN 0x02000000 +#define CRTC_DISP_REQ_EN 0x04000000 +#define CRTC_VGA_LINEAR 0x08000000 +#define CRTC_VGA_TEXT_132 0x20000000 +#define CRTC_CNT_EN 0x40000000 +#define CRTC_CUR_B_TEST 0x80000000 + +#define CRTC_CRNT_VLINE 0x07f00000 +#define CRTC_VBLANK 0x00000001 + +#define CRTC_PITCH 0xffc00000 + +// DAC control values. + +#define DAC_8BIT_EN 0x00000100 + +// Mix control values. + +#define MIX_NOT_DST 0x0000 +#define MIX_0 0x0001 +#define MIX_1 0x0002 +#define MIX_DST 0x0003 +#define MIX_NOT_SRC 0x0004 +#define MIX_XOR 0x0005 +#define MIX_XNOR 0x0006 +#define MIX_SRC 0x0007 +#define MIX_NAND 0x0008 +#define MIX_NOT_SRC_OR_DST 0x0009 +#define MIX_SRC_OR_NOT_DST 0x000a +#define MIX_OR 0x000b +#define MIX_AND 0x000c +#define MIX_SRC_AND_NOT_DST 0x000d +#define MIX_NOT_SRC_AND_DST 0x000e +#define MIX_NOR 0x000f + +// BUS_CNTL register constants. +#define BUS_FIFO_ERR_ACK 0x00200000 +#define BUS_HOST_ERR_ACK 0x00800000 +#define BUS_APER_REG_DIS 0x00000010 + +// GEN_TEST_CNTL register constants. +#define GEN_OVR_OUTPUT_EN 0x20 +#define HWCURSOR_ENABLE 0x80 +#define GUI_ENGINE_ENABLE 0x100 + +// DSP_CONFIG register constants. +#define DSP_XCLKS_PER_QW 0x00003fff +#define DSP_LOOP_LATENCY 0x000f0000 +#define DSP_PRECISION 0x00700000 + +// DSP_ON_OFF register constants. +#define DSP_OFF 0x000007ff +#define DSP_ON 0x07ff0000 + +// CLOCK_CNTL register constants. +#define CLOCK_SEL 0x0f +#define CLOCK_DIV 0x30 +#define CLOCK_DIV1 0x00 +#define CLOCK_DIV2 0x10 +#define CLOCK_DIV4 0x20 +#define CLOCK_STROBE 0x40 +#define PLL_WR_EN 0x02 +#define PLL_ADDR 0xfc + +// PLL registers. +#define PLL_MACRO_CNTL 0x01 +#define PLL_REF_DIV 0x02 +#define PLL_GEN_CNTL 0x03 +#define PLL_MCLK_FB_DIV 0x04 +#define PLL_VCLK_CNTL 0x05 +#define PLL_VCLK_POST_DIV 0x06 +#define PLL_VCLK0_FB_DIV 0x07 +#define PLL_VCLK1_FB_DIV 0x08 +#define PLL_VCLK2_FB_DIV 0x09 +#define PLL_VCLK3_FB_DIV 0x0A +#define PLL_XCLK_CNTL 0x0B +#define PLL_TEST_CTRL 0x0E +#define PLL_TEST_COUNT 0x0F + +// Fields in PLL registers. +#define PLL_PC_GAIN 0x07 +#define PLL_VC_GAIN 0x18 +#define PLL_DUTY_CYC 0xE0 +#define PLL_MFB_TIMES_4_2B 0x08 +#define PLL_VCLK0_XDIV 0x10 +#define PLL_OVERRIDE 0x01 +#define PLL_MCLK_RST 0x02 +#define OSC_EN 0x04 +#define EXT_CLK_EN 0x08 +#define MCLK_SRC_SEL 0x70 +#define EXT_CLK_CNTL 0x80 +#define PLL_VCLK_SRC_SEL 0x03 +#define PLL_VCLK_RESET 0x04 +#define VCLK_INVERT 0x08 +#define VCLK0_POST 0x03 +#define VCLK1_POST 0x0C +#define VCLK2_POST 0x30 +#define VCLK3_POST 0xC0 + +// MEM_CNTL register constants. +#define CTL_MEM_TRP 0x00000300 +#define CTL_MEM_TRCD 0x00000C00 +#define CTL_MEM_TCRD 0x00001000 +#define CTL_MEM_TRAS 0x00070000 + +// DST_CNTL register constants. +#define DST_X_LEFT_TO_RIGHT 1 +#define DST_Y_TOP_TO_BOTTOM 2 +#define DST_LAST_PEL 0x20 + +// SRC_CNTL register constants. +#define SRC_LINE_X_LEFT_TO_RIGHT 0x10 + +// HOST_CNTL register constants. +#define HOST_BYTE_ALIGN 1 + +// DP_CHAIN_MASK register constants. +#define DP_CHAIN_4BPP 0x8888 +#define DP_CHAIN_7BPP 0xD2D2 +#define DP_CHAIN_8BPP 0x8080 +#define DP_CHAIN_8BPP_RGB 0x9292 +#define DP_CHAIN_15BPP 0x4210 +#define DP_CHAIN_16BPP 0x8410 +#define DP_CHAIN_24BPP 0x8080 +#define DP_CHAIN_32BPP 0x8080 + +// DP_PIX_WIDTH register constants. +#define DST_1BPP 0 +#define DST_4BPP 1 +#define DST_8BPP 2 +#define DST_15BPP 3 +#define DST_16BPP 4 +#define DST_32BPP 6 +#define SRC_1BPP 0 +#define SRC_4BPP 0x100 +#define SRC_8BPP 0x200 +#define SRC_15BPP 0x300 +#define SRC_16BPP 0x400 +#define SRC_32BPP 0x600 +#define HOST_1BPP 0 +#define HOST_4BPP 0x10000 +#define HOST_8BPP 0x20000 +#define HOST_15BPP 0x30000 +#define HOST_16BPP 0x40000 +#define HOST_32BPP 0x60000 +#define BYTE_ORDER_MSB_TO_LSB 0 +#define BYTE_ORDER_LSB_TO_MSB 0x1000000 + +// DP_SRC register constants. +#define BKGD_SRC_BKGD_CLR 0 +#define FRGD_SRC_FRGD_CLR 0x100 +#define FRGD_SRC_BLIT 0x300 +#define MONO_SRC_ONE 0 + +// GUI_STAT register constants. +#define ENGINE_BUSY 1 + +// LCD Index register constants. +#define LCD_REG_INDEX 0x0000003F +#define LCD_DISPLAY_DIS 0x00000100 +#define LCD_SRC_SEL 0x00000200 +#define CRTC2_DISPLAY_DIS 0x00000400 + +// LCD register indices. +#define LCD_CONFIG_PANEL 0x00 +#define LCD_GEN_CNTL 0x01 +#define LCD_DSTN_CONTROL 0x02 +#define LCD_HFB_PITCH_ADDR 0x03 +#define LCD_HORZ_STRETCHING 0x04 +#define LCD_VERT_STRETCHING 0x05 +#define LCD_EXT_VERT_STRETCH 0x06 +#define LCD_LT_GIO 0x07 +#define LCD_POWER_MANAGEMENT 0x08 + +// LCD_CONFIG_PANEL register constants. +#define DONT_SHADOW_HEND 0x00004000 + +// LCD_GEN_CNTL register constants. +#define CRT_ON 0x00000001 +#define LCD_ON 0x00000002 +#define HORZ_DIVBY2_EN 0x00000004 +#define LOCK_8DOT 0x00000010 +#define DONT_SHADOW_VPAR 0x00000040 +#define DIS_HOR_CRT_DIVBY2 0x00000400 +#define MCLK_PM_EN 0x00010000 +#define VCLK_DAC_PM_EN 0x00020000 +#define CRTC_RW_SELECT 0x08000000 +#define USE_SHADOWED_VEND 0x10000000 +#define USE_SHADOWED_ROWCUR 0x20000000 +#define SHADOW_EN 0x40000000 +#define SHADOW_RW_EN 0x80000000 + +// LCD_HORZ_STRETCHING register constants. +#define HORZ_STRETCH_BLEND 0x00000fff +#define HORZ_STRETCH_RATIO 0x0000ffff +#define HORZ_STRETCH_LOOP 0x00070000 +#define HORZ_PANEL_SIZE 0x0ff00000 +#define AUTO_HORZ_RATIO 0x20000000 +#define HORZ_STRETCH_MODE 0x40000000 +#define HORZ_STRETCH_EN 0x80000000 + +// LCD_VERT_STRETCHING register constants. +#define VERT_STRETCH_RATIO0 0x000003ff +#define VERT_STRETCH_RATIO1 0x000ffc00 +#define VERT_STRETCH_RATIO2 0x3ff00000 +#define VERT_STRETCH_USE0 0x40000000 +#define VERT_STRETCH_EN 0x80000000 + +// LCD_EXT_VERT_STRETCH register constants. +#define VERT_STRETCH_RATIO3 0x000003ff +#define FORCE_DAC_DATA 0x000000ff +#define FORCE_DAC_DATA_SEL 0x00000300 +#define VERT_STRETCH_MODE 0x00000400 +#define VERT_PANEL_SIZE 0x003ff800 +#define AUTO_VERT_RATIO 0x00400000 +#define USE_AUTO_FP_POS 0x00800000 +#define USE_AUTO_LCD_VSYNC 0x01000000 + +// LCD_POWER_MANAGEMENT register constants. +#define AUTO_POWER_UP 0x00000008 +#define POWER_BLON 0x02000000 +#define STANDBY_NOW 0x10000000 +#define SUSPEND_NOW 0x20000000 + + + +// Functions to get/set PLL registers. +//======================================= + +static inline uint8 +Mach64_GetPLLReg(uint8 index) +{ + OUTREG8(CLOCK_CNTL + 1, (index << 2) & PLL_ADDR); + return INREG8(CLOCK_CNTL + 2); +} + + +static inline void +Mach64_SetPLLReg(uint8 index, uint8 value) +{ + OUTREG8(CLOCK_CNTL + 1, ((index << 2) & PLL_ADDR) | PLL_WR_EN); + OUTREG8(CLOCK_CNTL + 2, value); +} + + +static inline uint32 +Mach64_GetLCDReg(int index) +{ + OUTREG8(LCD_INDEX, index & LCD_REG_INDEX); + return INREG(LCD_DATA); +} + + +static inline void +Mach64_PutLCDReg(int index, uint32 value) +{ + OUTREG8(LCD_INDEX, index & LCD_REG_INDEX); + OUTREG(LCD_DATA, value); +} + + +#endif // __MACH64_H__ diff --git a/src/add-ons/accelerants/ati/mach64_cursor.cpp b/src/add-ons/accelerants/ati/mach64_cursor.cpp new file mode 100644 index 0000000000..c397e34210 --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_cursor.cpp @@ -0,0 +1,102 @@ +/* + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "mach64.h" + +#include + + + +void +Mach64_ShowCursor(bool bShow) +{ + // Turn cursor on/off. + + OUTREGM(GEN_TEST_CNTL, bShow ? HWCURSOR_ENABLE : 0, HWCURSOR_ENABLE); +} + + +void +Mach64_SetCursorPosition(int x, int y) +{ + SharedInfo& si = *gInfo.sharedInfo; + + // xOffset & yOffset are used for displaying partial cursors on screen edges. + + uint8 xOffset = 0; + uint8 yOffset = 0; + + if (x < 0) { + xOffset = -x; + x = 0; + } + + if (y < 0) { + yOffset = -y; + y = 0; + } + + OUTREG(CUR_OFFSET, (si.cursorOffset >> 3) + (yOffset << 1)); + OUTREG(CUR_HORZ_VERT_OFF, (yOffset << 16) | xOffset); + OUTREG(CUR_HORZ_VERT_POSN, (y << 16) | x); +} + + +bool +Mach64_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask) +{ + SharedInfo& si = *gInfo.sharedInfo; + + if (andMask == NULL || xorMask == NULL) + return false; + + uint16* fbCursor = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset); + + // Initialize the hardware cursor as completely transparent. + + memset(fbCursor, 0xaa, CURSOR_BYTES); + + // Now load the AND & XOR masks for the cursor image into the cursor + // buffer. Note that a particular bit in these masks will have the + // following effect upon the corresponding cursor pixel: + // AND XOR Result + // 0 0 White pixel + // 0 1 Black pixel + // 1 0 Screen color (for transparency) + // 1 1 Reverse screen color to black or white + + for (int row = 0; row < height; row++) { + for (int colByte = 0; colByte < width / 8; colByte++) { + // Convert the 8 bit AND and XOR masks into a 16 bit mask containing + // pairs of the bits from the AND and XOR maks. + + uint8 andBits = *andMask++; + uint8 xorBits = *xorMask++; + uint16 cursorBits = 0; + + for (int j = 0; j < 8; j++) { + cursorBits <<= 2; + cursorBits |= ((andBits & 0x01) << 1); + cursorBits |= (xorBits & 0x01); + andBits >>= 1; + xorBits >>= 1; + } + + fbCursor[row * 8 + colByte] = cursorBits; + } + } + + // Set the cursor colors which are white background and black foreground. + + OUTREG(CUR_CLR0, ~0); + OUTREG(CUR_CLR1, 0); + + return true; +} diff --git a/src/add-ons/accelerants/ati/mach64_dpms.cpp b/src/add-ons/accelerants/ati/mach64_dpms.cpp new file mode 100644 index 0000000000..6fc8b74105 --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_dpms.cpp @@ -0,0 +1,114 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina. + Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "mach64.h" + + + +uint32 +Mach64_DPMSCapabilities(void) +{ + // Return DPMS modes supported by this device. + + return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF; +} + + +uint32 +Mach64_GetDPMSMode(void) +{ + // Return the current DPMS mode. + + uint32 tmp = INREG(CRTC_GEN_CNTL); + uint32 mode; + + if( (tmp & CRTC_DISPLAY_DIS) == 0 ) + mode = B_DPMS_ON; + else if( (tmp & CRTC_VSYNC_DIS) == 0 ) + mode = B_DPMS_STAND_BY; + else if( (tmp & CRTC_HSYNC_DIS) == 0 ) + mode = B_DPMS_SUSPEND; + else + mode = B_DPMS_OFF; + + TRACE("Mach64_DPMSMode() mode: %d\n", mode); + return mode; +} + + +status_t +Mach64_SetDPMSMode(uint32 dpmsMode) +{ + // Set the display into one of the Display Power Management modes, + // and return B_OK if successful, else return B_ERROR. + + TRACE("Mach64_SetDPMSMode() mode: %d, display type: %d\n", dpmsMode, gInfo.sharedInfo->displayType); + + int mask = (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); + + switch (dpmsMode) { + case B_DPMS_ON: + // Screen: On; HSync: On, VSync: On. + OUTREGM(CRTC_GEN_CNTL, 0, mask); + break; + + case B_DPMS_STAND_BY: + // Screen: Off; HSync: Off, VSync: On. + OUTREGM(CRTC_GEN_CNTL, CRTC_HSYNC_DIS, mask); + break; + + case B_DPMS_SUSPEND: + // Screen: Off; HSync: On, VSync: Off. + OUTREGM(CRTC_GEN_CNTL, CRTC_VSYNC_DIS, mask); + break; + + case B_DPMS_OFF: + // Screen: Off; HSync: Off, VSync: Off. + OUTREGM(CRTC_GEN_CNTL, mask, mask); + break; + + default: + TRACE("Invalid DPMS mode %d\n", dpmsMode); + return B_ERROR; + } + + if (gInfo.sharedInfo->displayType == MT_LAPTOP) { + uint32 powerMgmt = (Mach64_GetLCDReg(LCD_POWER_MANAGEMENT) + & ~(STANDBY_NOW | SUSPEND_NOW | POWER_BLON | AUTO_POWER_UP)); + + switch (dpmsMode) { + case B_DPMS_ON: + powerMgmt |= (POWER_BLON | AUTO_POWER_UP); + break; + + case B_DPMS_STAND_BY: + powerMgmt |= STANDBY_NOW; + break; + + case B_DPMS_SUSPEND: + powerMgmt |= SUSPEND_NOW; + break; + + case B_DPMS_OFF: + powerMgmt |= STANDBY_NOW | SUSPEND_NOW; + break; + } + + Mach64_PutLCDReg(LCD_POWER_MANAGEMENT, powerMgmt); + } + + return B_OK; +} + diff --git a/src/add-ons/accelerants/ati/mach64_draw.cpp b/src/add-ons/accelerants/ati/mach64_draw.cpp new file mode 100644 index 0000000000..394f30f41f --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_draw.cpp @@ -0,0 +1,236 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina. + Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "mach64.h" + + + +void +Mach64_EngineReset() +{ + // Reset engine and then enable it. + + uint32 genTestCntl = INREG(GEN_TEST_CNTL) & ~GUI_ENGINE_ENABLE; + OUTREG(GEN_TEST_CNTL, genTestCntl); + OUTREG(GEN_TEST_CNTL, genTestCntl | GUI_ENGINE_ENABLE); + + // Ensure engine is not locked up by clearing any FIFO errors. + + OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK); +} + + +void +Mach64_EngineInit(const DisplayModeEx& mode) +{ + // Initialize the drawing environment and clear the display. + + Mach64_EngineReset(); + + gInfo.WaitForIdle(); + + OUTREG(MEM_VGA_WP_SEL, 0x00010000); + OUTREG(MEM_VGA_RP_SEL, 0x00010000); + + uint32 dpPixWidth = 0; + uint32 dpChainMask = 0; + + switch (mode.bitsPerPixel) { + case 8: + dpPixWidth = HOST_8BPP | SRC_8BPP | DST_8BPP; + dpChainMask = DP_CHAIN_8BPP; + break; + case 15: + dpPixWidth = HOST_15BPP | SRC_15BPP | DST_15BPP; + dpChainMask = DP_CHAIN_15BPP; + break; + case 16: + dpPixWidth = HOST_16BPP | SRC_16BPP | DST_16BPP; + dpChainMask = DP_CHAIN_16BPP; + break; + case 32: + dpPixWidth = HOST_32BPP | SRC_32BPP | DST_32BPP; + dpChainMask = DP_CHAIN_32BPP; + break; + } + + dpPixWidth |= BYTE_ORDER_LSB_TO_MSB; // set for little-endian byte order + + gInfo.WaitForFifo(3); + OUTREG(DP_PIX_WIDTH, dpPixWidth); + OUTREG(DP_CHAIN_MASK, dpChainMask); + + OUTREG(CONTEXT_MASK, 0xffffffff); + + gInfo.WaitForFifo(7); + OUTREG(DST_OFF_PITCH, (mode.timing.h_display / 8) << 22); + OUTREG(DST_Y_X, 0); + OUTREG(DST_HEIGHT, 0); + OUTREG(DST_BRES_ERR, 0); + OUTREG(DST_BRES_INC, 0); + OUTREG(DST_BRES_DEC, 0); + OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL); + + gInfo.WaitForFifo(6); + OUTREG(SRC_OFF_PITCH, (mode.timing.h_display / 8) << 22); + OUTREG(SRC_Y_X, 0); + OUTREG(SRC_HEIGHT1_WIDTH1, 0x10001); + OUTREG(SRC_Y_X_START, 0); + OUTREG(SRC_HEIGHT2_WIDTH2, 0x10001); + OUTREG(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT); + + gInfo.WaitForFifo(7); + OUTREGM(HOST_CNTL, 0, HOST_BYTE_ALIGN); + OUTREG(PAT_REG0, 0); + OUTREG(PAT_REG1, 0); + OUTREG(PAT_CNTL, 0); + + OUTREG(SC_LEFT_RIGHT, ((mode.timing.h_display << 16) | 0 )); + OUTREG(SC_TOP_BOTTOM, ((mode.timing.v_display << 16) | 0 )); + + gInfo.WaitForFifo(9); + OUTREG(DP_BKGD_CLR, 0); + OUTREG(DP_FRGD_CLR, 0xffffffff); + OUTREG(DP_WRITE_MASK, 0xffffffff); + OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST); + OUTREG(DP_SRC, FRGD_SRC_FRGD_CLR); + + OUTREG(CLR_CMP_CLR, 0); + OUTREG(CLR_CMP_MASK, 0xffffffff); + OUTREG(CLR_CMP_CNTL, 0); + + gInfo.WaitForIdle(); +} + + +void +Mach64_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(4); + OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE); + OUTREG(DP_FRGD_CLR, color); + OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST); + OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL); + + while (count--) { + int x = pList->left; + int y = pList->top; + int w = pList->right - x + 1; + int h = pList->bottom - y + 1; + + gInfo.WaitForFifo(2); + OUTREG(DST_Y_X, (x << 16) | y); + OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h); + + pList++; + } +} + + +void +Mach64_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(4); + OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE); + OUTREG(DP_FRGD_CLR, color); + OUTREG(DP_MIX, (MIX_SRC << 16) | MIX_DST); + OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL); + + while (count--) { + int y = *pList++; + int x = *pList++; + int w = *pList++ - x + 1; + + if (w <= 0) + continue; // discard span with zero or negative width + + gInfo.WaitForFifo(2); + OUTREG(DST_Y_X, (x << 16) | y); + OUTREG(DST_HEIGHT_WIDTH, (w << 16) | 1); + } +} + + +void +Mach64_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(3); + OUTREG(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE); + OUTREG(DP_MIX, MIX_NOT_DST << 16); + OUTREG(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM | DST_LAST_PEL); + + while (count--) { + int x = pList->left; + int y = pList->top; + int w = pList->right - x + 1; + int h = pList->bottom - y + 1; + + gInfo.WaitForFifo(2); + OUTREG(DST_Y_X, (x << 16) | y); + OUTREG(DST_HEIGHT_WIDTH, (w << 16) | h); + + pList++; + } +} + + +void +Mach64_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(2); + OUTREG(DP_SRC, FRGD_SRC_BLIT); + OUTREG(DP_MIX, MIX_SRC << 16); + + while (count--) { + int cmd = DST_LAST_PEL; + int src_x = pList->src_left; + int src_y = pList->src_top; + int dest_x = pList->dest_left; + int dest_y = pList->dest_top; + int width = pList->width; + int height = pList->height; + + if (dest_x <= src_x) { + cmd |= DST_X_LEFT_TO_RIGHT; + } else { + src_x += width; + dest_x += width; + } + + if (dest_y <= src_y) { + cmd |= DST_Y_TOP_TO_BOTTOM; + } else { + src_y += height; + dest_y += height; + } + + gInfo.WaitForFifo(5); + OUTREG(DST_CNTL, cmd); + OUTREG(SRC_Y_X, (src_x << 16) | src_y); + OUTREG(SRC_HEIGHT1_WIDTH1, ((width + 1) << 16) | (height + 1)); + OUTREG(DST_Y_X, (dest_x << 16) | dest_y); + OUTREG(DST_HEIGHT_WIDTH, ((width + 1) << 16) | (height + 1)); + + pList ++; + } +} diff --git a/src/add-ons/accelerants/ati/mach64_init.cpp b/src/add-ons/accelerants/ati/mach64_init.cpp new file mode 100644 index 0000000000..509855ff33 --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_init.cpp @@ -0,0 +1,281 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina. + Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "mach64.h" + + + +static bool +Mach64_InitDSPParams() +{ + // Initialize global variables used to set DSP registers on a VT-B or later. + + SharedInfo& si = *gInfo.sharedInfo; + M64_Params& params = si.m64Params; + + // Retrieve XCLK settings. + + uint8 ioValue = Mach64_GetPLLReg(PLL_XCLK_CNTL); + params.xClkPostDivider = ioValue & 0x7; + + switch (params.xClkPostDivider) { + case 0: + case 1: + case 2: + case 3: + params.xClkRefDivider = 1; + break; + + case 4: + params.xClkRefDivider = 3; + params.xClkPostDivider = 0; + break; + + default: + TRACE("Unsupported XCLK source: %d.\n", params.xClkPostDivider); + return false; + } + + if (ioValue & PLL_MFB_TIMES_4_2B) + params.xClkPostDivider--; + + // Compute maximum RAS delay and related params. + + uint32 memCntl = INREG(MEM_CNTL); + int trp = GetBits(memCntl, CTL_MEM_TRP); + params.xClkPageFaultDelay = GetBits(memCntl, CTL_MEM_TRCD) + + GetBits(memCntl, CTL_MEM_TCRD) + trp + 2; + params.xClkMaxRASDelay = GetBits(memCntl, CTL_MEM_TRAS) + trp + 2; + + params.displayFIFODepth = 32; + + if (si.chipType < MACH64_264VT4) { + params.xClkPageFaultDelay += 2; + params.xClkMaxRASDelay += 3; + params.displayFIFODepth = 24; + } + + // Determine type of memory used with the chip. + + int memType = INREG(CONFIG_STAT0) & 0x7; + TRACE("Memory type: %d\n", memType); + + switch (memType) { + case MEM_DRAM: + if (si.videoMemSize <= 1024 * 1024) { + params.displayLoopLatency = 10; + } else { + params.displayLoopLatency = 8; + params.xClkPageFaultDelay += 2; + } + break; + + case MEM_EDO: + case MEM_PSEUDO_EDO: + if (si.videoMemSize <= 1024 * 1024) { + params.displayLoopLatency = 9; + } else { + params.displayLoopLatency = 8; + params.xClkPageFaultDelay++; + } + break; + + case MEM_SDRAM: + if (si.videoMemSize <= 1024 * 1024) { + params.displayLoopLatency = 11; + } else { + params.displayLoopLatency = 10; + params.xClkPageFaultDelay++; + } + break; + + case MEM_SGRAM: + params.displayLoopLatency = 8; + params.xClkPageFaultDelay += 3; + break; + + default: /* Set maximums */ + params.displayLoopLatency = 11; + params.xClkPageFaultDelay += 3; + break; + } + + if (params.xClkMaxRASDelay <= params.xClkPageFaultDelay) + params.xClkMaxRASDelay = params.xClkPageFaultDelay + 1; + + uint32 dspConfig = INREG(DSP_CONFIG); + if (dspConfig) + params.displayLoopLatency = GetBits(dspConfig, DSP_LOOP_LATENCY); + + return true; +} + + +static bool +Mach64_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock) +{ + // Get parameters for a color space which is supported by the Mach64 chips. + // Argument maxPixelClock is in KHz. + // Return true if the color space is supported; else return false. + + SharedInfo& si = *gInfo.sharedInfo; + + switch (colorSpace) { + case B_RGB32: + bitsPerPixel = 32; + break; + case B_RGB16: + bitsPerPixel = 16; + break; + case B_RGB15: + bitsPerPixel = 15; + break; + case B_CMAP8: + bitsPerPixel = 8; + break; + default: + TRACE("Unsupported color space: 0x%X\n", colorSpace); + return false; + } + + if (si.chipType >= MACH64_264VTB) { + if ((si.chipType >= MACH64_264VT4) && (si.chipType != MACH64_264LTPRO)) + maxPixelClock = 230000; + else if (si.chipType >= MACH64_264VT3) + maxPixelClock = 200000; + else + maxPixelClock = 170000; + } else { + if (bitsPerPixel == 8) + maxPixelClock = 135000; + else + maxPixelClock = 80000; + } + + return true; +} + + + +status_t +Mach64_Init(void) +{ + TRACE("Mach64_Init()\n"); + + SharedInfo& si = *gInfo.sharedInfo; + + static const int videoRamSizes[] = + { 512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024 }; + + uint32 memCntl = INREG(MEM_CNTL); + if (si.chipType < MACH64_264VTB) { + si.videoMemSize = videoRamSizes[memCntl & 0x7] * 1024; + } else { + uint32 ioValue = (memCntl & 0xf); + if (ioValue < 8) + si.videoMemSize = (ioValue + 1) * 512 * 1024; + else if (ioValue < 12) + si.videoMemSize = (ioValue - 3) * 1024 * 1024; + else + si.videoMemSize = (ioValue - 7) * 2048 * 1024; + } + + si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff; // align to 4k boundary + si.frameBufferOffset = 0; + si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset; + + TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n", + si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset); + + // 264VT-B's and later have DSP registers. + + if ((si.chipType >= MACH64_264VTB) && !Mach64_InitDSPParams()) + return B_ERROR; + + // Determine if the LCD display of a laptop computer is active. + + si.displayType = MT_VGA; + + if (si.chipType == MACH64_MOBILITY && si.panelX > 0 && si.panelY > 0) { + if (Mach64_GetLCDReg(LCD_GEN_CNTL) & LCD_ON) + si.displayType = MT_LAPTOP; + } + + // Set up the array of color spaces supported by the Mach64 chips. + + si.colorSpaces[0] = B_CMAP8; + si.colorSpaces[1] = B_RGB15; + si.colorSpaces[2] = B_RGB16; + si.colorSpaces[3] = B_RGB32; + si.colorSpaceCount = 4; + + // Setup the mode list. + + return CreateModeList(IsModeUsable); +} + + +static void +Mach64_WaitForFifo(uint32 entries) +{ + // The FIFO has 16 slots. This routines waits until at least `entries' + // of these slots are empty. + + while ((INREG(FIFO_STAT) & 0xffff) > (0x8000ul >> entries)) ; +} + + +static void +Mach64_WaitForIdle() +{ + // Wait for the graphics engine to be completely idle. That is, the FIFO + // has drained, the Pixel Cache is flushed, and the engine is idle. This + // is a standard "sync" function that will make the hardware "quiescent". + + Mach64_WaitForFifo(16); + + while (INREG(GUI_STAT) & ENGINE_BUSY) ; +} + + +void +Mach64_SetFunctionPointers(void) +{ + // Setting the function pointers must be done prior to first ModeInit call + // or any accel activity. + + gInfo.WaitForFifo = Mach64_WaitForFifo; + gInfo.WaitForIdle = Mach64_WaitForIdle; + + gInfo.DPMSCapabilities = Mach64_DPMSCapabilities; + gInfo.GetDPMSMode = Mach64_GetDPMSMode; + gInfo.SetDPMSMode = Mach64_SetDPMSMode; + + gInfo.LoadCursorImage = Mach64_LoadCursorImage; + gInfo.SetCursorPosition = Mach64_SetCursorPosition; + gInfo.ShowCursor = Mach64_ShowCursor; + + gInfo.FillRectangle = Mach64_FillRectangle; + gInfo.FillSpan = Mach64_FillSpan; + gInfo.InvertRectangle = Mach64_InvertRectangle; + gInfo.ScreenToScreenBlit = Mach64_ScreenToScreenBlit; + + gInfo.AdjustFrame = Mach64_AdjustFrame; + gInfo.ChipInit = Mach64_Init; + gInfo.GetColorSpaceParams = Mach64_GetColorSpaceParams; + gInfo.SetDisplayMode = Mach64_SetDisplayMode; + gInfo.SetIndexedColors = Mach64_SetIndexedColors; +} + diff --git a/src/add-ons/accelerants/ati/mach64_mode.cpp b/src/add-ons/accelerants/ati/mach64_mode.cpp new file mode 100644 index 0000000000..57036d3010 --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_mode.cpp @@ -0,0 +1,410 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1992,1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Carolina. + Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "mach64.h" + +#include + + + + +static void SetClockRegisters(const DisplayModeEx& mode) +{ + SharedInfo& si = *gInfo.sharedInfo; + M64_Params& params = si.m64Params; + + int p; + int postDiv; + bool extendedDiv = false; + uint32 pixelClock = mode.timing.pixel_clock; + + if (pixelClock > params.maxPixelClock) + pixelClock = params.maxPixelClock; + + double q = ((pixelClock / 10.0) * params.refDivider) / (2.0 * params.refFreq); + + if (si.chipType >= MACH64_264VTB) { + if (q > 255) { + TRACE("SetClockRegisters(): Warning: q > 255\n"); + q = 255; + p = 0; + postDiv = 1; + } else if (q > 127.5) { + p = 0; + postDiv = 1; + } else if (q > 85) { + p = 1; + postDiv = 2; + } else if (q > 63.75) { + p = 0; + postDiv = 3; + extendedDiv = true; + } else if (q > 42.5) { + p = 2; + postDiv = 4; + } else if (q > 31.875) { + p = 2; + postDiv = 6; + extendedDiv = true; + } else if (q > 21.25) { + p = 3; + postDiv = 8; + } else if (q >= 10.6666666667) { + p = 3; + postDiv = 12; + extendedDiv = true; + } else { + TRACE("SetClockRegisters(): Warning: q < 10.66666667\n"); + p = 3; + postDiv = 12; + extendedDiv = true; + } + } else { + if (q > 255) { + TRACE("SetClockRegisters(): Warning: q > 255\n"); + q = 255; + p = 0; + } else if (q > 127.5) + p = 0; + else if (q > 63.75) + p = 1; + else if (q > 31.875) + p = 2; + else if (q >= 16) + p = 3; + else { + TRACE("SetClockRegisters(): Warning: q < 16\n"); + p = 3; + } + postDiv = 1 << p; + } + + uint8 fbDiv = uint8(q * postDiv); + + // With some chips such as those with ID's 4750 & 475A, the display has + // ripples when using resolution 1440x900 at 60 Hz refresh rate. + // Decrementing fbDiv by 1 seems to fix this problem. + + if (mode.timing.h_display == 1440 && pixelClock < 108000) + fbDiv--; + + int clkNum = params.clockNumberToProgram; + + OUTREG8(CLOCK_CNTL, clkNum | CLOCK_STROBE); + + // Temporarily switch to accelerator mode. + uint32 crtc_gen_cntl = INREG(CRTC_GEN_CNTL); + if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) + OUTREG(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_EXT_DISP_EN); + + // Reset VCLK generator. + uint8 vclkCntl = Mach64_GetPLLReg(PLL_VCLK_CNTL); + Mach64_SetPLLReg(PLL_VCLK_CNTL, vclkCntl | PLL_VCLK_RESET); + + // Set post-divider. + uint8 tmp = Mach64_GetPLLReg(PLL_VCLK_POST_DIV); + Mach64_SetPLLReg(PLL_VCLK_POST_DIV, + (tmp & ~(0x03 << (2 * clkNum))) | (p << (2 * clkNum))); + + // Set feedback divider. + Mach64_SetPLLReg(PLL_VCLK0_FB_DIV + clkNum, fbDiv); + + // Set extended post-divider. + if (si.chipType >= MACH64_264VTB) { + tmp = Mach64_GetPLLReg(PLL_XCLK_CNTL); + if (extendedDiv) + Mach64_SetPLLReg(PLL_XCLK_CNTL, tmp | (0x10 << clkNum)); + else + Mach64_SetPLLReg(PLL_XCLK_CNTL, tmp & ~(0x10 << clkNum)); + } + + // End VCLK generator reset. + Mach64_SetPLLReg(PLL_VCLK_CNTL, vclkCntl & ~PLL_VCLK_RESET); + + snooze(5000); + INREG8(DAC_W_INDEX); // Clear DAC counter + + if (!(crtc_gen_cntl & CRTC_EXT_DISP_EN)) + OUTREG(CRTC_GEN_CNTL, crtc_gen_cntl); // Restore register + + // Save parameters that will be used for computing the DSP parameters. + + params.vClkPostDivider = postDiv; + params.vClkFeedbackDivider = fbDiv; + + return; +} + + +static void +SetDSPRegisters(const DisplayModeEx& mode) +{ + // Set up DSP register values for a VTB or later. + + SharedInfo& si = *gInfo.sharedInfo; + M64_Params& params = si.m64Params; + +#define Maximum_DSP_PRECISION 7 + + uint8 mClkFeedbackDivider = Mach64_GetPLLReg(PLL_MCLK_FB_DIV); + + /* Compute a memory-to-screen bandwidth ratio */ + uint32 multiplier = uint32(mClkFeedbackDivider) * params.vClkPostDivider; + uint32 divider = uint32(params.vClkFeedbackDivider) * params.xClkRefDivider; + divider *= ((mode.bitsPerPixel + 1) / 4); + + // Start by assuming a display FIFO width of 64 bits. + + int vshift = (6 - 2) - params.xClkPostDivider; + + int RASMultiplier = params.xClkMaxRASDelay; + int RASDivider = 1; + + // Determine dsp_precision first. + + int tmp = Mach64_Divide(multiplier * params.displayFIFODepth, divider, vshift, -1); + int dsp_precision; + + for (dsp_precision = -5; tmp; dsp_precision++) + tmp >>= 1; + if (dsp_precision < 0) + dsp_precision = 0; + else if (dsp_precision > Maximum_DSP_PRECISION) + dsp_precision = Maximum_DSP_PRECISION; + + int xshift = 6 - dsp_precision; + vshift += xshift; + + int dsp_off = Mach64_Divide(multiplier * (params.displayFIFODepth - 1), + divider, vshift, -1) - Mach64_Divide(1, 1, vshift - xshift, 1); + + int dsp_on = Mach64_Divide(multiplier, divider, vshift, 1); + tmp = Mach64_Divide(RASMultiplier, RASDivider, xshift, 1); + if (dsp_on < tmp) + dsp_on = tmp; + dsp_on += (tmp * 2) + + Mach64_Divide(params.xClkPageFaultDelay, 1, xshift, 1); + + /* Calculate rounding factor and apply it to dsp_on */ + tmp = ((1 << (Maximum_DSP_PRECISION - dsp_precision)) - 1) >> 1; + dsp_on = ((dsp_on + tmp) / (tmp + 1)) * (tmp + 1); + + if (dsp_on >= ((dsp_off / (tmp + 1)) * (tmp + 1))) { + dsp_on = dsp_off - Mach64_Divide(multiplier, divider, vshift, -1); + dsp_on = (dsp_on / (tmp + 1)) * (tmp + 1); + } + + int dsp_xclks = Mach64_Divide(multiplier, divider, vshift + 5, 1); + + // Build DSP register contents. + + uint32 dsp_on_off = SetBits(dsp_on, DSP_ON) + | SetBits(dsp_off, DSP_OFF); + uint32 dsp_config = SetBits(dsp_precision, DSP_PRECISION) + | SetBits(dsp_xclks, DSP_XCLKS_PER_QW) + | SetBits(params.displayLoopLatency, DSP_LOOP_LATENCY); + + OUTREG(DSP_ON_OFF, dsp_on_off); + OUTREG(DSP_CONFIG, dsp_config); +} + + +static void +SetCrtcRegisters(const DisplayModeEx& mode) +{ + // Calculate the CRTC register values for requested video mode, and then set + // set the registers to the calculated values. + + SharedInfo& si = *gInfo.sharedInfo; + + uint32 crtc_h_total_disp = ((mode.timing.h_total / 8) - 1) + | (((mode.timing.h_display / 8) - 1) << 16); + + int hSyncWidth = (mode.timing.h_sync_end - mode.timing.h_sync_start) / 8; + if (hSyncWidth > 0x3f) + hSyncWidth = 0x3f; + + int hSyncStart = mode.timing.h_sync_start / 8 - 1; + + uint32 crtc_h_sync_strt_wid = (hSyncWidth << 16) + | (hSyncStart & 0xff) | ((hSyncStart & 0x100) << 4) + | ((mode.timing.flags & B_POSITIVE_HSYNC) ? 0 : CRTC_H_SYNC_NEG); + + uint32 crtc_v_total_disp = ((mode.timing.v_total - 1) + | ((mode.timing.v_display - 1) << 16)); + + int vSyncWidth = mode.timing.v_sync_end - mode.timing.v_sync_start; + if (vSyncWidth > 0x1f) + vSyncWidth = 0x1f; + + uint32 crtc_v_sync_strt_wid = (mode.timing.v_sync_start - 1) + | (vSyncWidth << 16) + | ((mode.timing.flags & B_POSITIVE_VSYNC) ? 0 : CRTC_V_SYNC_NEG); + + uint32 crtc_off_pitch = SetBits(mode.timing.h_display >> 3, CRTC_PITCH); + + uint32 crtc_gen_cntl = INREG(CRTC_GEN_CNTL) & + ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN | + CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN | + CRTC_PIX_BY_2_EN | CRTC_VGA_XOVERSCAN | + CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER | + CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE | + CRTC_LOCK_REGS | // already off, but ... + CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN | + CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST); + + crtc_gen_cntl |= CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN; + + switch (mode.bitsPerPixel) { + case 8: + crtc_gen_cntl |= CRTC_PIX_WIDTH_8BPP; + break; + case 15: + crtc_gen_cntl |= CRTC_PIX_WIDTH_15BPP; + break; + case 16: + crtc_gen_cntl |= CRTC_PIX_WIDTH_16BPP; + break; + case 32: + crtc_gen_cntl |= CRTC_PIX_WIDTH_32BPP; + break; + default: + TRACE("Undefined color depth, bitsPerPixel: %d\n", mode.bitsPerPixel); + break; + } + + // For now, set display FIFO low water mark as high as possible. + if (si.chipType < MACH64_264VTB) + crtc_gen_cntl |= CRTC_FIFO_LWM; + + + // Write the CRTC registers. + //-------------------------- + + // Stop CRTC. + OUTREG(CRTC_GEN_CNTL, crtc_gen_cntl & ~(CRTC_EXT_DISP_EN | CRTC_EN)); + + OUTREG(CRTC_H_TOTAL_DISP, crtc_h_total_disp); + OUTREG(CRTC_H_SYNC_STRT_WID, crtc_h_sync_strt_wid); + OUTREG(CRTC_V_TOTAL_DISP, crtc_v_total_disp); + OUTREG(CRTC_V_SYNC_STRT_WID, crtc_v_sync_strt_wid); + + OUTREG(CRTC_OFF_PITCH, crtc_off_pitch); + + // Clear overscan registers. + OUTREG(OVR_CLR, 0); + OUTREG(OVR_WID_LEFT_RIGHT, 0); + OUTREG(OVR_WID_TOP_BOTTOM, 0); + + // Finalise CRTC setup and turn on the screen. + OUTREG(CRTC_GEN_CNTL, crtc_gen_cntl); + + return; +} + + + +status_t +Mach64_SetDisplayMode(const DisplayModeEx& mode) +{ + // The code to actually configure the display. + // All the error checking must be done in ProposeDisplayMode(), + // and assume that the mode values we get here are acceptable. + + SharedInfo& si = *gInfo.sharedInfo; + + if (si.displayType == MT_VGA) { + // Chip is connected to a monitor via a VGA connector. + + SetCrtcRegisters(mode); + SetClockRegisters(mode); + + if (si.chipType >= MACH64_264VTB) + SetDSPRegisters(mode); + + } else { + // Chip is connected to a laptop LCD monitor; or via a DVI interface. + + uint16 vesaMode = GetVesaModeNumber(display_mode(mode), mode.bitsPerPixel); + if (vesaMode == 0) + return B_BAD_VALUE; + + status_t status = ioctl(gInfo.deviceFileDesc, ATI_SET_VESA_DISPLAY_MODE, + &vesaMode, sizeof(vesaMode)); + if (status != B_OK) + return status; + } + + Mach64_AdjustFrame(mode); + + // Initialize the palette so that the various color depths will display + // the correct colors. + + OUTREGM(DAC_CNTL, DAC_8BIT_EN, DAC_8BIT_EN); + OUTREG8(DAC_MASK, 0xff); + OUTREG8(DAC_W_INDEX, 0); // initial color index + + for (int i = 0; i < 256; i++) { + OUTREG8(DAC_DATA, i); + OUTREG8(DAC_DATA, i); + OUTREG8(DAC_DATA, i); + } + + Mach64_EngineInit(mode); + + return B_OK; +} + + + +void +Mach64_AdjustFrame(const DisplayModeEx& mode) +{ + // Adjust start address in frame buffer. + + SharedInfo& si = *gInfo.sharedInfo; + + int address = (mode.v_display_start * mode.virtual_width + + mode.h_display_start) * ((mode.bitsPerPixel + 1) / 8); + + address &= ~0x07; + address += si.frameBufferOffset; + + OUTREGM(CRTC_OFF_PITCH, address, 0xfffff); + return; +} + + +void +Mach64_SetIndexedColors(uint count, uint8 first, uint8* colorData, uint32 flags) +{ + // Set the indexed color palette for 8-bit color depth mode. + + (void)flags; // avoid compiler warning for unused arg + + if (gInfo.sharedInfo->displayMode.space != B_CMAP8) + return ; + + OUTREG8(DAC_MASK, 0xff); + OUTREG8(DAC_W_INDEX, first); // initial color index + + while (count--) { + OUTREG8(DAC_DATA, colorData[0]); // red + OUTREG8(DAC_DATA, colorData[1]); // green + OUTREG8(DAC_DATA, colorData[2]); // blue + + colorData += 3; + } +} diff --git a/src/add-ons/accelerants/ati/mach64_util.cpp b/src/add-ons/accelerants/ati/mach64_util.cpp new file mode 100644 index 0000000000..d7ac5f359d --- /dev/null +++ b/src/add-ons/accelerants/ati/mach64_util.cpp @@ -0,0 +1,88 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + +#include "accelerant.h" +#include "mach64.h" + + +#define MAX_INT ((int)((unsigned int)(-1) >> 2)) + + + +void +Mach64_ReduceRatio(int *numerator, int *denominator) +{ + // Reduce a fraction by factoring out the largest common divider of the + // fraction's numerator and denominator. + + int multiplier = *numerator; + int divider = *denominator; + int remainder; + + while ((remainder = multiplier % divider)) { + multiplier = divider; + divider = remainder; + } + + *numerator /= divider; + *denominator /= divider; +} + + + +int +Mach64_Divide(int numerator, int denominator, int shift, const int roundingKind) +{ + // Using integer arithmetic and avoiding overflows, this function finds the + // rounded integer that best approximates + // + // numerator shift + // ----------- * 2 + // denominator + // + // using the specified rounding (floor (<0), nearest (=0) or ceiling (>0)). + + Mach64_ReduceRatio(&numerator, &denominator); + + // Deal with left shifts but try to keep the denominator even. + if (denominator & 1) { + if (denominator <= MAX_INT) { + denominator <<= 1; + shift++; + } + } else { + while ((shift > 0) && !(denominator & 3)) { + denominator >>= 1; + shift--; + } + } + + // Deal with right shifts. + while (shift < 0) { + if ((numerator & 1) && (denominator <= MAX_INT)) + denominator <<= 1; + else + numerator >>= 1; + + shift++; + } + + int rounding = 0; // Default to floor + + if (!roundingKind) // nearest + rounding = denominator >> 1; + else if (roundingKind > 0) // ceiling + rounding = denominator - 1; + + return ((numerator / denominator) << shift) + + ((((numerator % denominator) << shift) + rounding) / denominator); +} diff --git a/src/add-ons/accelerants/ati/mode.cpp b/src/add-ons/accelerants/ati/mode.cpp new file mode 100644 index 0000000000..b813f1a1c9 --- /dev/null +++ b/src/add-ons/accelerants/ati/mode.cpp @@ -0,0 +1,450 @@ +/* + Copyright 2007-2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2007-2009 +*/ + +#include "accelerant.h" + +#include // common accelerant header file +#include + + + +static display_mode* +FindDisplayMode(int width, int height, int refreshRate, uint32 colorDepth) +{ + // Search the mode list for the mode with specified width, height, + // refresh rate, and color depth. If argument colorDepth is zero, this + // function will search for a mode satisfying the other 3 arguments, and + // if more than one matching mode is found, the one with the greatest color + // depth will be selected. + // + // If successful, return a pointer to the selected display_mode object; + // else return NULL. + + display_mode* selectedMode = NULL; + uint32 modeCount = gInfo.sharedInfo->modeCount; + + for (uint32 j = 0; j < modeCount; j++) { + display_mode& mode = gInfo.modeList[j]; + + if (mode.timing.h_display == width && mode.timing.v_display == height) { + int modeRefreshRate = int(((mode.timing.pixel_clock * 1000.0 / + mode.timing.h_total) / mode.timing.v_total) + 0.5); + if (modeRefreshRate == refreshRate) { + if (colorDepth == 0) { + if (selectedMode == NULL || mode.space > selectedMode->space) + selectedMode = &mode; + } else { + if (mode.space == colorDepth) + return &mode; + } + } + } + } + + return selectedMode; +} + + + +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); +} + + + +uint16 +GetVesaModeNumber(const display_mode& mode, uint8 bitsPerPixel) +{ + // Search VESA mode table for a matching mode, and return the VESA mode + // number if a match is found; else return 0 if no match is found. + + SharedInfo& si = *gInfo.sharedInfo; + + VesaMode* vesaModeTable = (VesaMode*)((uint8*)&si + si.vesaModeTableOffset); + + for (uint32 j = 0; j < si.vesaModeCount; j++) { + VesaMode& vesaMode = vesaModeTable[j]; + + if (vesaMode.width == mode.timing.h_display + && vesaMode.height == mode.timing.v_display + && vesaMode.bitsPerPixel == bitsPerPixel) + return vesaMode.mode; + } + + return 0; // matching VESA mode not found +} + + + +bool +IsModeUsable(const display_mode* mode) +{ + // Test if the display mode is usable by the current video chip. That is, + // does the chip have enough memory for the mode and is the pixel clock + // within the chips allowable range, etc. + // + // Return true if the mode is usable. + + SharedInfo& si = *gInfo.sharedInfo; + uint8 bitsPerPixel; + uint32 maxPixelClock; + + if (!gInfo.GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock)) + return false; + + // Is there enough frame buffer memory to handle the mode? + + if (!IsThereEnoughFBMemory(mode, bitsPerPixel)) + return false; + + if (si.displayType == MT_VGA) { + // Test if mode is usable for a chip that is connected to a monitor + // via an analog VGA connector. + + if (mode->timing.pixel_clock > maxPixelClock) + return false; + + // Is the color space supported? + + bool colorSpaceSupported = false; + for (uint32 j = 0; j < si.colorSpaceCount; j++) { + if (mode->space == uint32(si.colorSpaces[j])) { + colorSpaceSupported = true; + break; + } + } + + if (!colorSpaceSupported) + return false; + + // Reject modes with a width of 640 and a height < 480 since they do not + // work properly with the ATI chipsets. + + if (mode->timing.h_display == 640 && mode->timing.v_display < 480) + return false; + } else { + // Test if mode is usable for a chip that is connected to a laptop LCD + // display or a monitor via a DVI interface. + + // If chip is a Mach64 Mobility chip exclude 640x350 resolution since + // that resolution can not be set without a failure in the VESA set mode + // function. + + if (si.chipType == MACH64_MOBILITY && mode->timing.h_display == 640 + && mode->timing.v_display == 350) + return false; + + // Search VESA mode table for matching mode. + + if (GetVesaModeNumber(*mode, bitsPerPixel) == 0) + return false; + } + + return true; +} + + +status_t +CreateModeList(bool (*checkMode)(const display_mode* mode)) +{ + 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_VGA && !si.bHaveEDID) { + edid1_raw rawEdid; // raw EDID info to obtain + + if (ioctl(gInfo.deviceFileDesc, ATI_GET_EDID, &rawEdid, + sizeof(rawEdid)) == B_OK) { + if (rawEdid.version.version != 1 || rawEdid.version.revision > 4) { + TRACE("CreateModeList(); EDID version %d.%d out of range\n", + rawEdid.version.version, rawEdid.version.revision); + } else { + edid_decode(&si.edidInfo, &rawEdid); // decode & save EDID info + si.bHaveEDID = true; + } + } + + if (si.bHaveEDID) { +#ifdef ENABLE_DEBUG_TRACE + edid_dump(&(si.edidInfo)); +#endif + } else { + TRACE("CreateModeList(); Unable to get EDID info\n"); + } + } + + display_mode* list; + uint32 count = 0; + area_id listArea; + + listArea = create_display_modes("ATI modes", + si.bHaveEDID ? &si.edidInfo : NULL, + NULL, 0, si.colorSpaces, si.colorSpaceCount, + (check_display_mode_hook)checkMode, &list, &count); + + if (listArea < 0) + return listArea; // listArea has error code + + si.modeArea = gInfo.modeListArea = listArea; + si.modeCount = count; + gInfo.modeList = list; + + return B_OK; +} + + + +status_t +ProposeDisplayMode(display_mode *target, const display_mode *low, + const display_mode *high) +{ + (void)low; // avoid compiler warning for unused arg + (void)high; // avoid compiler warning for unused arg + + TRACE("ProposeDisplayMode() %dx%d, pixel clock: %d kHz, space: 0x%X\n", + target->timing.h_display, target->timing.v_display, + target->timing.pixel_clock, target->space); + + // Search the mode list for the specified mode. + + uint32 modeCount = gInfo.sharedInfo->modeCount; + + for (uint32 j = 0; j < modeCount; j++) { + display_mode& mode = gInfo.modeList[j]; + + if (target->timing.h_display == mode.timing.h_display + && target->timing.v_display == mode.timing.v_display + && target->space == mode.space) + return B_OK; // mode found in list + } + + return B_BAD_VALUE; // mode not found in list +} + + +status_t +SetDisplayMode(display_mode* pMode) +{ + // First validate the mode, then call a function to set the registers. + + TRACE("SetDisplayMode() begin\n"); + + SharedInfo& si = *gInfo.sharedInfo; + DisplayModeEx mode; + (display_mode&)mode = *pMode; + + uint32 maxPixelClock; + if ( ! gInfo.GetColorSpaceParams(mode.space, mode.bitsPerPixel, maxPixelClock)) + return B_BAD_VALUE; + + if (ProposeDisplayMode(&mode, pMode, pMode) != B_OK) + return B_BAD_VALUE; + + int bytesPerPixel = (mode.bitsPerPixel + 7) / 8; + mode.bytesPerRow = mode.timing.h_display * bytesPerPixel; + + // Is there enough frame buffer memory for this mode? + + if ( ! IsThereEnoughFBMemory(&mode, mode.bitsPerPixel)) + return B_NO_MEMORY; + + TRACE("Set display mode: %dx%d virtual size: %dx%d color depth: %d bits/pixel\n", + mode.timing.h_display, mode.timing.v_display, + mode.virtual_width, mode.virtual_height, mode.bitsPerPixel); + + if (si.displayType == MT_VGA) { + TRACE(" mode timing: %d %d %d %d %d %d %d %d %d\n", + mode.timing.pixel_clock, + mode.timing.h_display, + mode.timing.h_sync_start, mode.timing.h_sync_end, + mode.timing.h_total, + mode.timing.v_display, + mode.timing.v_sync_start, mode.timing.v_sync_end, + mode.timing.v_total); + + TRACE(" mode hFreq: %.1f kHz vFreq: %.1f Hz %chSync %cvSync\n", + double(mode.timing.pixel_clock) / mode.timing.h_total, + ((double(mode.timing.pixel_clock) / mode.timing.h_total) * 1000.0) + / mode.timing.v_total, + (mode.timing.flags & B_POSITIVE_HSYNC) ? '+' : '-', + (mode.timing.flags & B_POSITIVE_VSYNC) ? '+' : '-'); + } + + status_t status = gInfo.SetDisplayMode(mode); + if (status != B_OK) { + TRACE("SetDisplayMode() failed; status 0x%x\n", status); + return status; + } + + si.displayMode = mode; + + TRACE("SetDisplayMode() done\n"); + return B_OK; +} + + + +status_t +MoveDisplay(uint16 horizontalStart, uint16 verticalStart) +{ + // Set which pixel of the virtual frame buffer will show up in the + // top left corner of the display device. Used for page-flipping + // games and virtual desktops. + + DisplayModeEx& mode = gInfo.sharedInfo->displayMode; + + if (mode.timing.h_display + horizontalStart > mode.virtual_width + || mode.timing.v_display + verticalStart > mode.virtual_height) + return B_ERROR; + + mode.h_display_start = horizontalStart; + mode.v_display_start = verticalStart; + + gInfo.AdjustFrame(mode); + return B_OK; +} + + +uint32 +AccelerantModeCount(void) +{ + // Return the number of display modes in the mode list. + + return gInfo.sharedInfo->modeCount; +} + + +status_t +GetModeList(display_mode* dmList) +{ + // Copy the list of supported video modes to the location pointed at + // by dmList. + + memcpy(dmList, gInfo.modeList, gInfo.sharedInfo->modeCount * sizeof(display_mode)); + return B_OK; +} + + +status_t +GetDisplayMode(display_mode* current_mode) +{ + *current_mode = gInfo.sharedInfo->displayMode; // return current display mode + return B_OK; +} + + +status_t +GetFrameBufferConfig(frame_buffer_config* pFBC) +{ + SharedInfo& si = *gInfo.sharedInfo; + + pFBC->frame_buffer = (void*)((addr_t)si.videoMemAddr + si.frameBufferOffset); + pFBC->frame_buffer_dma = (void*)((addr_t)si.videoMemPCI + si.frameBufferOffset); + uint32 bytesPerPixel = (si.displayMode.bitsPerPixel + 7) / 8; + pFBC->bytes_per_row = si.displayMode.virtual_width * bytesPerPixel; + + return B_OK; +} + + +status_t +GetPixelClockLimits(display_mode* mode, uint32* low, uint32* high) +{ + // Return the maximum and minium pixel clock limits for the specified mode. + + uint8 bitsPerPixel; + uint32 maxPixelClock; + + if ( ! gInfo.GetColorSpaceParams(mode->space, bitsPerPixel, maxPixelClock)) + return B_ERROR; + + if (low != NULL) { + // lower limit of about 48Hz vertical refresh + uint32 totalClocks = (uint32)mode->timing.h_total * (uint32)mode->timing.v_total; + uint32 lowClock = (totalClocks * 48L) / 1000L; + if (lowClock > maxPixelClock) + return B_ERROR; + + *low = lowClock; + } + + if (high != NULL) + *high = maxPixelClock; + + return B_OK; +} + + +status_t +GetTimingConstraints(display_timing_constraints *constraints) +{ + (void)constraints; // avoid compiler warning for unused arg + + return B_ERROR; +} + + +status_t +GetPreferredDisplayMode(display_mode* preferredMode) +{ + // If the chip is connected to a laptop LCD panel, find the mode with + // matching width and height, 60 Hz refresh rate, and greatest color depth. + + SharedInfo& si = *gInfo.sharedInfo; + + if (si.displayType == MT_LAPTOP) { + display_mode* mode = FindDisplayMode(si.panelX, si.panelY, 60, 0); + + if (mode != NULL) { + *preferredMode = *mode; + return B_OK; + } + } + + return B_ERROR; +} + + +status_t +GetEdidInfo(void* info, size_t size, uint32* _version) +{ + SharedInfo& si = *gInfo.sharedInfo; + + if ( ! si.bHaveEDID) + return B_ERROR; + + if (size < sizeof(struct edid1_info)) + return B_BUFFER_OVERFLOW; + + memcpy(info, &si.edidInfo, sizeof(struct edid1_info)); + *_version = EDID_VERSION_1; + return B_OK; +} diff --git a/src/add-ons/accelerants/ati/rage128.h b/src/add-ons/accelerants/ati/rage128.h new file mode 100644 index 0000000000..53f2a5ec88 --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128.h @@ -0,0 +1,271 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#ifndef __RAGE128_H__ +#define __RAGE128_H__ + + +#define CURSOR_BYTES 1024 // bytes used for cursor image in video memory + +#define R128_TIMEOUT 2000000 // Fall out of wait loops after this count + + +// Register MMIO addresses. +//------------------------- + +#define R128_AUX_SC_CNTL 0x1660 + +#define R128_BUS_CNTL 0x0030 +# define R128_BUS_MASTER_DIS (1 << 6) +# define R128_BUS_RD_DISCARD_EN (1 << 24) +# define R128_BUS_RD_ABORT_EN (1 << 25) +# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define R128_BUS_WRT_BURST (1 << 29) +# define R128_BUS_READ_BURST (1 << 30) + +#define R128_CAP0_TRIG_CNTL 0x0950 // ? +#define R128_CAP1_TRIG_CNTL 0x09c0 // ? +#define R128_CLOCK_CNTL_DATA 0x000c +#define R128_CLOCK_CNTL_INDEX 0x0008 +# define R128_PLL_WR_EN (1 << 7) +# define R128_PLL_DIV_SEL (3 << 8) +#define R128_CONFIG_MEMSIZE 0x00f8 +#define R128_CRTC_EXT_CNTL 0x0054 +# define R128_CRTC_VGA_XOVERSCAN (1 << 0) +# define R128_VGA_ATI_LINEAR (1 << 3) +# define R128_XCRT_CNT_EN (1 << 6) +# define R128_CRTC_HSYNC_DIS (1 << 8) +# define R128_CRTC_VSYNC_DIS (1 << 9) +# define R128_CRTC_DISPLAY_DIS (1 << 10) +# define R128_CRTC_CRT_ON (1 << 15) +# define R128_FP_OUT_EN (1 << 22) +# define R128_FP_ACTIVE (1 << 23) +#define R128_CRTC_GEN_CNTL 0x0050 +# define R128_CRTC_CUR_EN (1 << 16) +# define R128_CRTC_EXT_DISP_EN (1 << 24) +# define R128_CRTC_EN (1 << 25) +#define R128_CRTC_H_SYNC_STRT_WID 0x0204 +# define R128_CRTC_H_SYNC_POL (1 << 23) +#define R128_CRTC_H_TOTAL_DISP 0x0200 +#define R128_CRTC_OFFSET 0x0224 +#define R128_CRTC_OFFSET_CNTL 0x0228 +#define R128_CRTC_PITCH 0x022c +#define R128_CRTC_V_SYNC_STRT_WID 0x020c +# define R128_CRTC_V_SYNC_POL (1 << 23) +#define R128_CRTC_V_TOTAL_DISP 0x0208 +#define R128_CUR_CLR0 0x026c +#define R128_CUR_CLR1 0x0270 +#define R128_CUR_HORZ_VERT_OFF 0x0268 +#define R128_CUR_HORZ_VERT_POSN 0x0264 +#define R128_CUR_OFFSET 0x0260 +# define R128_CUR_LOCK (1 << 31) + +#define R128_DAC_CNTL 0x0058 +# define R128_DAC_RANGE_CNTL (3 << 0) +# define R128_DAC_BLANKING (1 << 2) +# define R128_DAC_CRT_SEL_CRTC2 (1 << 4) +# define R128_DAC_PALETTE_ACC_CTL (1 << 5) +# define R128_DAC_8BIT_EN (1 << 8) +# define R128_DAC_VGA_ADR_EN (1 << 13) +# define R128_DAC_MASK_ALL (0xff << 24) +#define R128_DDA_CONFIG 0x02e0 +#define R128_DDA_ON_OFF 0x02e4 +#define R128_DEFAULT_OFFSET 0x16e0 +#define R128_DEFAULT_PITCH 0x16e4 +#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define R128_DP_BRUSH_BKGD_CLR 0x1478 +#define R128_DP_BRUSH_FRGD_CLR 0x147c +#define R128_DP_CNTL 0x16c0 +# define R128_DST_X_LEFT_TO_RIGHT (1 << 0) +# define R128_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define R128_DP_DATATYPE 0x16c4 +# define R128_HOST_BIG_ENDIAN_EN (1 << 29) +#define R128_DP_GUI_MASTER_CNTL 0x146c +# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) +# define R128_GMC_AUX_CLIP_DIS (1 << 29) +# define R128_GMC_BRUSH_NONE (15 << 4) +# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define R128_GMC_DST_DATATYPE_SHIFT 8 +# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define R128_ROP3_Dn 0x00550000 +# define R128_ROP3_P 0x00f00000 +# define R128_ROP3_S 0x00cc0000 +#define R128_DP_SRC_BKGD_CLR 0x15dc +#define R128_DP_SRC_FRGD_CLR 0x15d8 +#define R128_DP_WRITE_MASK 0x16cc +#define R128_DST_BRES_DEC 0x1630 +#define R128_DST_BRES_ERR 0x1628 +#define R128_DST_BRES_INC 0x162c +#define R128_DST_HEIGHT_WIDTH 0x143c +#define R128_DST_WIDTH_HEIGHT 0x1598 +#define R128_DST_Y_X 0x1438 + +#define R128_FP_CRTC_H_TOTAL_DISP 0x0250 +#define R128_FP_CRTC_V_TOTAL_DISP 0x0254 +#define R128_FP_GEN_CNTL 0x0284 +# define R128_FP_FPON (1 << 0) +# define R128_FP_BLANK_DIS (1 << 1) +# define R128_FP_TDMS_EN (1 << 2) +# define R128_FP_DETECT_SENSE (1 << 8) +# define R128_FP_SEL_CRTC2 (1 << 13) +# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define R128_FP_CRTC_DONT_SHADOW_HEND (1 << 17) +# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define R128_FP_CRTC_USE_SHADOW_ROWCUR (1 << 19) +# define R128_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define R128_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define R128_FP_CRT_SYNC_SEL (1 << 23) +# define R128_FP_USE_SHADOW_EN (1 << 24) +#define R128_FP_H_SYNC_STRT_WID 0x02c4 +#define R128_FP_HORZ_STRETCH 0x028c +# define R128_HORZ_STRETCH_RATIO_MASK 0xfff +# define R128_HORZ_STRETCH_RATIO_SHIFT 0 +# define R128_HORZ_STRETCH_RATIO_MAX 4096 +# define R128_HORZ_PANEL_SIZE (0xff << 16) +# define R128_HORZ_PANEL_SHIFT 16 +# define R128_AUTO_HORZ_RATIO (0 << 24) +# define R128_HORZ_STRETCH_PIXREP (0 << 25) +# define R128_HORZ_STRETCH_BLEND (1 << 25) +# define R128_HORZ_STRETCH_ENABLE (1 << 26) +# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define R128_HORZ_STRETCH_RESERVED (1 << 30) +# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define R128_FP_PANEL_CNTL 0x0288 +# define R128_FP_DIGON (1 << 0) +# define R128_FP_BLON (1 << 1) +#define R128_FP_V_SYNC_STRT_WID 0x02c8 +#define R128_FP_VERT_STRETCH 0x0290 +# define R128_VERT_PANEL_SIZE (0x7ff << 0) +# define R128_VERT_PANEL_SHIFT 0 +# define R128_VERT_STRETCH_RATIO_MASK 0x3ff +# define R128_VERT_STRETCH_RATIO_SHIFT 11 +# define R128_VERT_STRETCH_RATIO_MAX 1024 +# define R128_VERT_STRETCH_ENABLE (1 << 24) +# define R128_VERT_STRETCH_LINEREP (0 << 25) +# define R128_VERT_STRETCH_BLEND (1 << 25) +# define R128_VERT_AUTO_RATIO_EN (1 << 26) +# define R128_VERT_STRETCH_RESERVED 0xf8e00000 + +#define R128_GEN_INT_CNTL 0x0040 +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) +#define R128_GPIO_MONID 0x0068 +# define R128_GPIO_MONID_A_0 (1 << 0) +# define R128_GPIO_MONID_A_3 (1 << 3) +# define R128_GPIO_MONID_Y_0 (1 << 8) +# define R128_GPIO_MONID_Y_3 (1 << 11) +# define R128_GPIO_MONID_EN_0 (1 << 16) +# define R128_GPIO_MONID_EN_3 (1 << 19) +# define R128_GPIO_MONID_MASK_0 (1 << 24) +# define R128_GPIO_MONID_MASK_3 (1 << 27) +#define R128_GUI_PROBE 0x16bc +#define R128_GUI_STAT 0x1740 +# define R128_GUI_FIFOCNT_MASK 0x0fff +# define R128_GUI_ACTIVE (1 << 31) + +#define R128_HTOTAL_CNTL 0x0009 // PLL + +#define R128_I2C_CNTL_1 0x0094 // ? + +#define R128_LVDS_GEN_CNTL 0x02d0 +# define R128_LVDS_ON (1 << 0) +# define R128_LVDS_DISPLAY_DIS (1 << 1) +# define R128_LVDS_EN (1 << 7) +# define R128_LVDS_DIGON (1 << 18) +# define R128_LVDS_BLON (1 << 19) +# define R128_LVDS_SEL_CRTC2 (1 << 23) +# define R128_HSYNC_DELAY_SHIFT 28 +# define R128_HSYNC_DELAY_MASK (0xf << 28) + +#define R128_MCLK_CNTL 0x000f /* PLL */ +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CP (1 << 17) +#define R128_MEM_CNTL 0x0140 +#define R128_MPP_TB_CONFIG 0x01c0 // ? +#define R128_MPP_GP_CONFIG 0x01c8 // ? + +#define R128_OVR_CLR 0x0230 +#define R128_OVR_WID_LEFT_RIGHT 0x0234 +#define R128_OVR_WID_TOP_BOTTOM 0x0238 +#define R128_OV0_SCALE_CNTL 0x0420 + +#define R128_PALETTE_DATA 0x00b4 +#define R128_PALETTE_INDEX 0x00b0 +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) +#define R128_PPLL_CNTL 0x0002 // PLL +# define R128_PPLL_RESET (1 << 0) +# define R128_PPLL_SLEEP (1 << 1) +# define R128_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define R128_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +#define R128_PPLL_DIV_3 0x0007 // PLL +# define R128_PPLL_FB3_DIV_MASK 0x07ff +# define R128_PPLL_POST3_DIV_MASK 0x00070000 +#define R128_PPLL_REF_DIV 0x0003 // PLL +# define R128_PPLL_REF_DIV_MASK 0x03ff +# define R128_PPLL_ATOMIC_UPDATE_R (1 << 15) // same as _W +# define R128_PPLL_ATOMIC_UPDATE_W (1 << 15) // same as _R + +#define R128_SC_BOTTOM_RIGHT 0x16f0 +#define R128_SC_TOP_LEFT 0x16ec +#define R128_SCALE_3D_CNTL 0x1a00 +#define R128_SRC_Y_X 0x1434 +#define R128_SUBPIC_CNTL 0x0540 // ? + +#define R128_TMDS_CRC 0x02a0 + +#define R128_VCLK_ECP_CNTL 0x0008 // PLL +# define R128_VCLK_SRC_SEL_MASK 0x03 +# define R128_VCLK_SRC_SEL_CPUCLK 0x00 +# define R128_VCLK_SRC_SEL_PPLLCLK 0x03 +#define R128_VIPH_CONTROL 0x01D0 // ? + + + +// Functions to get/set PLL registers. +//======================================= + +static inline uint32 +GetPLLReg(uint8 index) +{ + OUTREG8(R128_CLOCK_CNTL_INDEX, index & 0x3f); + return INREG(R128_CLOCK_CNTL_DATA); +} + + +static inline void +SetPLLReg(uint8 index, uint32 value) +{ + OUTREG8(R128_CLOCK_CNTL_INDEX, ((index) & 0x3f) | R128_PLL_WR_EN); + OUTREG(R128_CLOCK_CNTL_DATA, value); +} + + +static inline void +SetPLLReg(uint8 index, uint32 value, uint32 mask) +{ + // Write a value to a PLL reg using a mask. The mask selects the + // bits to be modified. + + SetPLLReg(index, (GetPLLReg(index) & ~mask) | (value & mask)); +} + + +#endif // __RAGE128_H__ diff --git a/src/add-ons/accelerants/ati/rage128_cursor.cpp b/src/add-ons/accelerants/ati/rage128_cursor.cpp new file mode 100644 index 0000000000..d7d6b9ecf5 --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128_cursor.cpp @@ -0,0 +1,99 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "rage128.h" + + + +void +Rage128_ShowCursor(bool bShow) +{ + // Turn cursor on/off. + + OUTREGM(R128_CRTC_GEN_CNTL, bShow ? R128_CRTC_CUR_EN : 0, R128_CRTC_CUR_EN); +} + + +void +Rage128_SetCursorPosition(int x, int y) +{ + SharedInfo& si = *gInfo.sharedInfo; + + // xOffset & yOffset are used for displaying partial cursors on screen edges. + + uint8 xOffset = 0; + uint8 yOffset = 0; + + if (x < 0) { + xOffset = (( -x) & 0xFE); + x = 0; + } + + if (y < 0) { + yOffset = (( -y) & 0xFE); + y = 0; + } + + OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xOffset << 16) | yOffset); + OUTREG(R128_CUR_HORZ_VERT_POSN, R128_CUR_LOCK | (x << 16) | y); + OUTREG(R128_CUR_OFFSET, si.cursorOffset + yOffset * 16); +} + + +bool +Rage128_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask) +{ + SharedInfo& si = *gInfo.sharedInfo; + + if (andMask == NULL || xorMask == NULL) + return false; + + // Initialize the hardware cursor as completely transparent. + + uint32* fbCursor32 = (uint32*)((addr_t)si.videoMemAddr + si.cursorOffset); + + for (int i = 0; i < CURSOR_BYTES; i += 16) { + *fbCursor32++ = ~0; // and bits + *fbCursor32++ = ~0; + *fbCursor32++ = 0; // xor bits + *fbCursor32++ = 0; + } + + // Now load the AND & XOR masks for the cursor image into the cursor + // buffer. Note that a particular bit in these masks will have the + // following effect upon the corresponding cursor pixel: + // AND XOR Result + // 0 0 White pixel + // 0 1 Black pixel + // 1 0 Screen color (for transparency) + // 1 1 Reverse screen color to black or white + + uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset); + + for (int row = 0; row < height; row++) { + for (int colByte = 0; colByte < width / 8; colByte++) { + fbCursor[row * 16 + colByte] = *andMask++; + fbCursor[row * 16 + colByte + 8] = *xorMask++; + } + } + + // Set the cursor colors which are white background and black foreground. + + OUTREG(R128_CUR_CLR0, ~0); + OUTREG(R128_CUR_CLR1, 0); + + return true; +} diff --git a/src/add-ons/accelerants/ati/rage128_dpms.cpp b/src/add-ons/accelerants/ati/rage128_dpms.cpp new file mode 100644 index 0000000000..41edd9b970 --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128_dpms.cpp @@ -0,0 +1,144 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "rage128.h" + + + +uint32 +Rage128_DPMSCapabilities(void) +{ + // Return DPMS modes supported by this device. + + return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF; +} + + +uint32 +Rage128_GetDPMSMode(void) +{ + // Return the current DPMS mode. + + uint32 tmp = INREG(R128_CRTC_EXT_CNTL); + uint32 mode; + + if( (tmp & R128_CRTC_DISPLAY_DIS) == 0 ) + mode = B_DPMS_ON; + else if( (tmp & R128_CRTC_VSYNC_DIS) == 0 ) + mode = B_DPMS_STAND_BY; + else if( (tmp & R128_CRTC_HSYNC_DIS) == 0 ) + mode = B_DPMS_SUSPEND; + else + mode = B_DPMS_OFF; + + TRACE("Rage128_DPMSMode() mode: %d\n", mode); + return mode; +} + + +status_t +Rage128_SetDPMSMode(uint32 dpmsMode) +{ + // Set the display into one of the Display Power Management modes, + // and return B_OK if successful, else return B_ERROR. + + SharedInfo& si = *gInfo.sharedInfo; + + TRACE("Rage128_SetDPMSMode() mode: %d, display type: %d\n", dpmsMode, si.displayType); + + int mask = (R128_CRTC_DISPLAY_DIS + | R128_CRTC_HSYNC_DIS + | R128_CRTC_VSYNC_DIS); + + switch (dpmsMode) { + case B_DPMS_ON: + // Screen: On; HSync: On, VSync: On. + OUTREGM(R128_CRTC_EXT_CNTL, 0, mask); + break; + + case B_DPMS_STAND_BY: + // Screen: Off; HSync: Off, VSync: On. + OUTREGM(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, mask); + break; + + case B_DPMS_SUSPEND: + // Screen: Off; HSync: On, VSync: Off. + OUTREGM(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, mask); + break; + + case B_DPMS_OFF: + // Screen: Off; HSync: Off, VSync: Off. + OUTREGM(R128_CRTC_EXT_CNTL, mask, mask); + break; + + default: + TRACE("Invalid DPMS mode %d\n", dpmsMode); + return B_ERROR; + } + + if (si.displayType == MT_LAPTOP) { + uint32 genCtrl; + + switch (dpmsMode) { + case B_DPMS_ON: + genCtrl = INREG(R128_LVDS_GEN_CNTL); + genCtrl |= R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON | R128_LVDS_DIGON; + genCtrl &= ~R128_LVDS_DISPLAY_DIS; + OUTREG(R128_LVDS_GEN_CNTL, genCtrl); + break; + + case B_DPMS_STAND_BY: + case B_DPMS_SUSPEND: + case B_DPMS_OFF: + genCtrl = INREG(R128_LVDS_GEN_CNTL); + genCtrl |= R128_LVDS_DISPLAY_DIS; + OUTREG(R128_LVDS_GEN_CNTL, genCtrl); + snooze(10); + genCtrl &= ~(R128_LVDS_ON | R128_LVDS_EN | R128_LVDS_BLON | R128_LVDS_DIGON); + OUTREG(R128_LVDS_GEN_CNTL, genCtrl); + break; + + default: + TRACE("Invalid DPMS mode %d\n", dpmsMode); + return B_ERROR; + } + } + + if (gInfo.sharedInfo->displayType == MT_DVI) { + switch (dpmsMode) { + case B_DPMS_ON: + OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) + | (R128_FP_FPON | R128_FP_TDMS_EN)); + break; + + case B_DPMS_STAND_BY: + case B_DPMS_SUSPEND: + case B_DPMS_OFF: + OUTREG(R128_FP_GEN_CNTL, INREG(R128_FP_GEN_CNTL) + & ~(R128_FP_FPON | R128_FP_TDMS_EN)); + break; + + default: + TRACE("Invalid DPMS mode %d\n", dpmsMode); + return B_ERROR; + } + } + + return B_OK; +} + diff --git a/src/add-ons/accelerants/ati/rage128_draw.cpp b/src/add-ons/accelerants/ati/rage128_draw.cpp new file mode 100644 index 0000000000..710e5d233c --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128_draw.cpp @@ -0,0 +1,258 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "rage128.h" + + + + +void +Rage128_EngineFlush() +{ + // Flush all dirty data in the Pixel Cache to memory. + + OUTREGM(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, R128_PC_FLUSH_ALL); + + for (int i = 0; i < R128_TIMEOUT; i++) { + if ( ! (INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) + break; + } +} + + +void +Rage128_EngineReset() +{ + // Reset graphics card to known state. + + Rage128_EngineFlush(); + + uint32 clockCntlIndex = INREG(R128_CLOCK_CNTL_INDEX); + uint32 mclkCntl = GetPLLReg(R128_MCLK_CNTL); + + SetPLLReg(R128_MCLK_CNTL, mclkCntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); + + uint32 genResetCntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, genResetCntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, genResetCntl & ~R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + + SetPLLReg(R128_MCLK_CNTL, mclkCntl); + OUTREG(R128_CLOCK_CNTL_INDEX, clockCntlIndex); + OUTREG(R128_GEN_RESET_CNTL, genResetCntl); +} + + +void +Rage128_EngineInit(const DisplayModeEx& mode) +{ + // Initialize the acceleration hardware. + + SharedInfo& si = *gInfo.sharedInfo; + + TRACE("Rage128_EngineInit() bits/pixel: %d\n", mode.bitsPerPixel); + + OUTREG(R128_SCALE_3D_CNTL, 0); + Rage128_EngineReset(); + + uint32 dataType = 0; + + switch (mode.bitsPerPixel) { + case 8: + dataType = 2; + break; + case 15: + dataType = 3; + break; + case 16: + dataType = 4; + break; + case 32: + dataType = 6; + break; + default: + TRACE("Unsupported color depth: %d bits/pixel\n", mode.bitsPerPixel); + } + + gInfo.WaitForFifo(2); + OUTREG(R128_DEFAULT_OFFSET, gInfo.sharedInfo->frameBufferOffset); + OUTREG(R128_DEFAULT_PITCH, mode.timing.h_display / 8); + + gInfo.WaitForFifo(4); + OUTREG(R128_AUX_SC_CNTL, 0); + OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + OUTREG(R128_SC_TOP_LEFT, 0); + OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + + si.r128_dpGuiMasterCntl = ((dataType << R128_GMC_DST_DATATYPE_SHIFT) + | R128_GMC_CLR_CMP_CNTL_DIS + | R128_GMC_AUX_CLIP_DIS); + gInfo.WaitForFifo(1); + OUTREG(R128_DP_GUI_MASTER_CNTL, (si.r128_dpGuiMasterCntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR)); + + gInfo.WaitForFifo(8); + OUTREG(R128_DST_BRES_ERR, 0); + OUTREG(R128_DST_BRES_INC, 0); + OUTREG(R128_DST_BRES_DEC, 0); + OUTREG(R128_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_WRITE_MASK, 0xffffffff); + + gInfo.WaitForFifo(1); + OUTREGM(R128_DP_DATATYPE, 0, R128_HOST_BIG_ENDIAN_EN); + + gInfo.WaitForIdle(); +} + + +void +Rage128_FillRectangle(engine_token *et, uint32 color, fill_rect_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP3_P)); // use GXcopy for rop + + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM); + + while (count--) { + int x = pList->left; + int y = pList->top; + int w = pList->right - x + 1; + int h = pList->bottom - y + 1; + + gInfo.WaitForFifo(2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); + + pList++; + } +} + + +void +Rage128_FillSpan(engine_token *et, uint32 color, uint16 *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP3_P)); // use GXcopy for rop + + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + + while (count--) { + int y = *pList++; + int x = *pList++; + int w = *pList++ - x + 1; + + if (w <= 0) + continue; // discard span with zero or negative width + + gInfo.WaitForFifo(2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | 1); + } +} + + +void +Rage128_InvertRectangle(engine_token *et, fill_rect_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl + | R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_DP_SRC_SOURCE_MEMORY + | R128_ROP3_Dn)); // use GXinvert for rop + + OUTREG(R128_DP_CNTL, R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM); + + while (count--) { + int x = pList->left; + int y = pList->top; + int w = pList->right - x + 1; + int h = pList->bottom - y + 1; + + gInfo.WaitForFifo(2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); + + pList++; + } +} + + +void +Rage128_ScreenToScreenBlit(engine_token *et, blit_params *pList, uint32 count) +{ + (void)et; // avoid compiler warning for unused arg + + gInfo.WaitForFifo(1); + OUTREG(R128_DP_GUI_MASTER_CNTL, (gInfo.sharedInfo->r128_dpGuiMasterCntl + | R128_GMC_BRUSH_NONE + | R128_GMC_SRC_DATATYPE_COLOR + | R128_DP_SRC_SOURCE_MEMORY + | R128_ROP3_S)); // use GXcopy for rop + + while (count--) { + int cmd = 0; + int src_x = pList->src_left; + int src_y = pList->src_top; + int dest_x = pList->dest_left; + int dest_y = pList->dest_top; + int width = pList->width; + int height = pList->height; + + if (dest_x <= src_x) { + cmd |= R128_DST_X_LEFT_TO_RIGHT; + } else { + src_x += width; + dest_x += width; + } + + if (dest_y <= src_y) { + cmd |= R128_DST_Y_TOP_TO_BOTTOM; + } else { + src_y += height; + dest_y += height; + } + + gInfo.WaitForFifo(4); + OUTREG(R128_DP_CNTL, cmd); + OUTREG(R128_SRC_Y_X, (src_y << 16) | src_x); + OUTREG(R128_DST_Y_X, (dest_y << 16) | dest_x); + OUTREG(R128_DST_HEIGHT_WIDTH, ((height + 1) << 16) | (width + 1)); + + pList ++; + } +} diff --git a/src/add-ons/accelerants/ati/rage128_init.cpp b/src/add-ons/accelerants/ati/rage128_init.cpp new file mode 100644 index 0000000000..bdb74e28ac --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128_init.cpp @@ -0,0 +1,221 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "rage128.h" + + + +// Memory Specifications from RAGE 128 Software Development Manual +// (Technical Reference Manual P/N SDK-G04000 Rev 0.01), page 3-21. +static R128_RAMSpec sRAMSpecs[] = { + { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, + { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, +}; + + + +static bool +Rage128_GetColorSpaceParams(int colorSpace, uint8& bitsPerPixel, uint32& maxPixelClock) +{ + // Get parameters for a color space which is supported by the Rage128 chips. + // Argument maxPixelClock is in KHz. + // Return true if the color space is supported; else return false. + + switch (colorSpace) { + case B_RGB32: + bitsPerPixel = 32; + break; + case B_RGB16: + bitsPerPixel = 16; + break; + case B_RGB15: + bitsPerPixel = 15; + break; + case B_CMAP8: + bitsPerPixel = 8; + break; + default: + TRACE("Unsupported color space: 0x%X\n", colorSpace); + return false; + } + + maxPixelClock = gInfo.sharedInfo->r128PLLParams.max_pll_freq * 10; + return true; +} + + +static void +WaitForFifo(uint32 entries) +{ + // The FIFO has 64 slots. This routines waits until at least `entries' + // of these slots are empty. + + while (true) { + for (int i = 0; i < R128_TIMEOUT; i++) { + uint32 slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (slots >= entries) + return; + } + + TRACE("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE)); + TRACE("FIFO timed out, resetting engine...\n"); + + Rage128_EngineReset(); + } +} + + +static void +WaitForIdle() +{ + // Wait for the graphics engine to be completely idle. That is, the FIFO + // has drained, the Pixel Cache is flushed, and the engine is idle. This + // is a standard "sync" function that will make the hardware "quiescent". + + WaitForFifo(64); + + while (true) { + for (uint32 i = 0; i < R128_TIMEOUT; i++) { + if ( ! (INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + Rage128_EngineFlush(); + return ; + } + } + + TRACE("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE)); + TRACE("Idle timed out, resetting engine...\n"); + + Rage128_EngineReset(); + } +} + + +status_t +Rage128_Init(void) +{ + TRACE("Rage128_Init()\n"); + + SharedInfo& si = *gInfo.sharedInfo; + + si.videoMemSize = INREG(R128_CONFIG_MEMSIZE); + + si.cursorOffset = (si.videoMemSize - CURSOR_BYTES) & ~0xfff; // align to 4k boundary + si.frameBufferOffset = 0; + si.maxFrameBufferSize = si.cursorOffset - si.frameBufferOffset; + + TRACE("Video Memory size: %d MB frameBufferOffset: 0x%x cursorOffset: 0x%x\n", + si.videoMemSize / 1024 / 1024, si.frameBufferOffset, si.cursorOffset); + + // Get the specifications of the memory used by the chip. + + uint32 offset; + + switch (INREG(R128_MEM_CNTL) & 0x3) { + case 0: // SDR SGRAM 1:1 + switch (si.deviceID) { + case 0x4C45: // RAGE128 LE: + case 0x4C46: // RAGE128 LF: + case 0x4D46: // RAGE128 MF: + case 0x4D4C: // RAGE128 ML: + case 0x5245: // RAGE128 RE: + case 0x5246: // RAGE128 RF: + case 0x5247: // RAGE128 RG: + case 0x5446: // RAGE128 TF: + case 0x544C: // RAGE128 TL: + case 0x5452: // RAGE128 TR: + offset = 0; // 128-bit SDR SGRAM 1:1 + break; + default: + offset = 1; // 64-bit SDR SGRAM 1:1 + break; + } + break; + case 1: + offset = 2; // 64-bit SDR SGRAM 2:1 + break; + case 2: + offset = 3; // 64-bit DDR SGRAM + break; + default: + offset = 1; // 64-bit SDR SGRAM 1:1 + break; + } + si.r128MemSpec = sRAMSpecs[offset]; + TRACE("RAM type: %s\n", si.r128MemSpec.name); + + // Determine the type of display. + + si.displayType = MT_VGA; + + if (INREG(R128_FP_PANEL_CNTL) & R128_FP_DIGON) // don't know if this is correct + si.displayType = MT_DVI; + + if (si.chipType == RAGE128_MOBILITY && si.panelX > 0 && si.panelY > 0) { + if (INREG(R128_LVDS_GEN_CNTL) & R128_LVDS_ON) + si.displayType = MT_LAPTOP; // laptop LCD display is on + } + + // Set up the array of color spaces supported by the Rage128 chips. + + si.colorSpaces[0] = B_CMAP8; + si.colorSpaces[1] = B_RGB15; + si.colorSpaces[2] = B_RGB16; + si.colorSpaces[3] = B_RGB32; + si.colorSpaceCount = 4; + + // Setup the mode list. + + return CreateModeList(IsModeUsable); +} + + +void +Rage128_SetFunctionPointers(void) +{ + // Setting the function pointers must be done prior to first ModeInit call + // or any accel activity. + + gInfo.WaitForFifo = WaitForFifo; + gInfo.WaitForIdle = WaitForIdle; + + gInfo.DPMSCapabilities = Rage128_DPMSCapabilities; + gInfo.GetDPMSMode = Rage128_GetDPMSMode; + gInfo.SetDPMSMode = Rage128_SetDPMSMode; + + gInfo.LoadCursorImage = Rage128_LoadCursorImage; + gInfo.SetCursorPosition = Rage128_SetCursorPosition; + gInfo.ShowCursor = Rage128_ShowCursor; + + gInfo.FillRectangle = Rage128_FillRectangle; + gInfo.FillSpan = Rage128_FillSpan; + gInfo.InvertRectangle = Rage128_InvertRectangle; + gInfo.ScreenToScreenBlit = Rage128_ScreenToScreenBlit; + + gInfo.AdjustFrame = Rage128_AdjustFrame; + gInfo.ChipInit = Rage128_Init; + gInfo.GetColorSpaceParams = Rage128_GetColorSpaceParams; + gInfo.SetDisplayMode = Rage128_SetDisplayMode; + gInfo.SetIndexedColors = Rage128_SetIndexedColors; +} + diff --git a/src/add-ons/accelerants/ati/rage128_mode.cpp b/src/add-ons/accelerants/ati/rage128_mode.cpp new file mode 100644 index 0000000000..31a316dda6 --- /dev/null +++ b/src/add-ons/accelerants/ati/rage128_mode.cpp @@ -0,0 +1,448 @@ +/* + Haiku ATI video driver adapted from the X.org ATI driver. + + Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + Precision Insight, Inc., Cedar Park, Texas, and + VA Linux Systems Inc., Fremont, California. + + Copyright 2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2009 +*/ + + +#include "accelerant.h" +#include "rage128.h" + +#include + + + + +struct DisplayParams { + // CRTC registers + uint32 crtc_gen_cntl; + uint32 crtc_h_total_disp; + uint32 crtc_h_sync_strt_wid; + uint32 crtc_v_total_disp; + uint32 crtc_v_sync_strt_wid; + uint32 crtc_pitch; + + // DDA register + uint32 dda_config; + uint32 dda_on_off; + + // Computed PLL values + int feedback_div; + int post_div; + + // PLL registers + uint32 ppll_ref_div; + uint32 ppll_div_3; +}; + + + +static inline int +DivideWithRounding(int n, int d) +{ + return (n + (d / 2)) / d; // compute n/d with rounding +} + + +static int +MinimumBits(uint32 value) +{ + // Compute minimum number of bits required to contain a value (ie, log + // base 2 of value). + + if (value == 0) + return 1; + + int numBits = 0; + + while (value != 0) { + value >>= 1; + numBits++; + } + + return numBits; +} + + +static bool +CalculateCrtcRegisters(const DisplayModeEx& mode, DisplayParams& params) +{ + // Define CRTC registers for requested video mode. + // Return true if successful. + + const uint8 hSyncFudge[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; + + uint32 format; + + switch (mode.bitsPerPixel) { + case 8: + format = 2; + break; + case 15: + format = 3; // 555 + break; + case 16: + format = 4; // 565 + break; + case 32: + format = 6; // xRGB + break; + default: + TRACE("Unsupported color depth: %d bits/pixel\n", mode.bitsPerPixel); + return false; + } + + params.crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN + | R128_CRTC_EN + | (format << 8)); + + params.crtc_h_total_disp = (((mode.timing.h_total / 8) - 1) & 0xffff) + | (((mode.timing.h_display / 8) - 1) << 16); + + int hSyncWidth = (mode.timing.h_sync_end - mode.timing.h_sync_start) / 8; + if (hSyncWidth <= 0) + hSyncWidth = 1; + if (hSyncWidth > 0x3f) + hSyncWidth = 0x3f; + + int hSyncStart = mode.timing.h_sync_start - 8 + hSyncFudge[format - 1]; + + params.crtc_h_sync_strt_wid = (hSyncStart & 0xfff) | (hSyncWidth << 16) + | ((mode.timing.flags & B_POSITIVE_HSYNC) ? 0 : R128_CRTC_H_SYNC_POL); + + params.crtc_v_total_disp = (((mode.timing.v_total - 1) & 0xffff) + | ((mode.timing.v_display - 1) << 16)); + + int vSyncWidth = mode.timing.v_sync_end - mode.timing.v_sync_start; + if (vSyncWidth <= 0) + vSyncWidth = 1; + if (vSyncWidth > 0x1f) + vSyncWidth = 0x1f; + + params.crtc_v_sync_strt_wid = ((mode.timing.v_sync_start - 1) & 0xfff) + | (vSyncWidth << 16) + | ((mode.timing.flags & B_POSITIVE_VSYNC) ? 0 : R128_CRTC_V_SYNC_POL); + + params.crtc_pitch = mode.timing.h_display / 8; + + return true; +} + + +static bool +CalculateDDARegisters(const DisplayModeEx& mode, DisplayParams& params) +{ + // Compute and write DDA registers for requested video mode. + // Return true if successful. + + SharedInfo& si = *gInfo.sharedInfo; + R128_RAMSpec& memSpec = si.r128MemSpec; + R128_PLLParams& pll = si.r128PLLParams; + + int displayFifoWidth = 128; + int displayFifoDepth = 32; + int xClkFreq = pll.xclk; + + int vClkFreq = DivideWithRounding(pll.reference_freq * params.feedback_div, + pll.reference_div * params.post_div); + + int bytesPerPixel = (mode.bitsPerPixel + 7) / 8; + + int xClksPerTransfer = DivideWithRounding(xClkFreq * displayFifoWidth, + vClkFreq * bytesPerPixel * 8); + + int useablePrecision = MinimumBits(xClksPerTransfer) + 1; + + int xClksPerTransferPrecise = DivideWithRounding( + (xClkFreq * displayFifoWidth) << (11 - useablePrecision), + vClkFreq * bytesPerPixel * 8); + + int rOff = xClksPerTransferPrecise * (displayFifoDepth - 4); + + int rOn = (4 * memSpec.memBurstLen + + 3 * MAX(memSpec.rasToCasDelay - 2, 0) + + 2 * memSpec.rasPercentage + + memSpec.writeRecovery + + memSpec.casLatency + + memSpec.readToWriteDelay + + xClksPerTransfer) << (11 - useablePrecision); + + if (rOn + memSpec.loopLatency >= rOff) { + TRACE("Error: (rOn = %d) + (loopLatency = %d) >= (rOff = %d)\n", + rOn, memSpec.loopLatency, rOff); + return false; + } + + params.dda_config = xClksPerTransferPrecise | (useablePrecision << 16) + | (memSpec.loopLatency << 20); + params.dda_on_off = (rOn << 16) | rOff; + + return true; +} + + +static bool +CalculatePLLRegisters(const DisplayModeEx& mode, DisplayParams& params) +{ + // Define PLL registers for requested video mode. + + struct Divider { + int divider; + int bitValue; + }; + + // The following data is from RAGE 128 VR/RAGE 128 GL Register Reference + // Manual (Technical Reference Manual P/N RRG-G04100-C Rev. 0.04), page + // 3-17 (PLL_DIV_[3:0]). + + const Divider postDividers[] = { + { 1, 0 }, // VCLK_SRC + { 2, 1 }, // VCLK_SRC/2 + { 4, 2 }, // VCLK_SRC/4 + { 8, 3 }, // VCLK_SRC/8 + { 3, 4 }, // VCLK_SRC/3 + // bitValue = 5 is reserved + { 6, 6 }, // VCLK_SRC/6 + { 12, 7 } // VCLK_SRC/12 + }; + + R128_PLLParams& pll = gInfo.sharedInfo->r128PLLParams; + uint32 freq = mode.timing.pixel_clock / 10; + + if (freq > pll.max_pll_freq) + freq = pll.max_pll_freq; + if (freq * 12 < pll.min_pll_freq) + freq = pll.min_pll_freq / 12; + + int bitValue = -1; + uint32 output_freq; + + for (int j = 0; j < ARRAY_SIZE(postDividers); j++) { + output_freq = postDividers[j].divider * freq; + if (output_freq >= pll.min_pll_freq && output_freq <= pll.max_pll_freq) { + params.feedback_div = DivideWithRounding(pll.reference_div * output_freq, + pll.reference_freq); + params.post_div = postDividers[j].divider; + bitValue = postDividers[j].bitValue; + break; + } + } + + if (bitValue < 0) { + TRACE("CalculatePLLRegisters(), acceptable divider not found\n"); + return false; + } + + params.ppll_ref_div = pll.reference_div; + params.ppll_div_3 = (params.feedback_div | (bitValue << 16)); + + return true; +} + + +static void +PLLWaitForReadUpdateComplete() +{ + while (GetPLLReg(R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R) + ; +} + +static void +PLLWriteUpdate() +{ + PLLWaitForReadUpdateComplete(); + + SetPLLReg(R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, R128_PPLL_ATOMIC_UPDATE_W); +} + + +static void +SetRegisters(DisplayParams& params) +{ + // Write the common registers (most will be set to zero). + //------------------------------------------------------- + + OUTREGM(R128_FP_GEN_CNTL, R128_FP_BLANK_DIS, R128_FP_BLANK_DIS); + + OUTREG(R128_OVR_CLR, 0); + OUTREG(R128_OVR_WID_LEFT_RIGHT, 0); + OUTREG(R128_OVR_WID_TOP_BOTTOM, 0); + OUTREG(R128_OV0_SCALE_CNTL, 0); + OUTREG(R128_MPP_TB_CONFIG, 0); + OUTREG(R128_MPP_GP_CONFIG, 0); + OUTREG(R128_SUBPIC_CNTL, 0); + OUTREG(R128_VIPH_CONTROL, 0); + OUTREG(R128_I2C_CNTL_1, 0); + OUTREG(R128_GEN_INT_CNTL, 0); + OUTREG(R128_CAP0_TRIG_CNTL, 0); + OUTREG(R128_CAP1_TRIG_CNTL, 0); + + // If bursts are enabled, turn on discards and aborts. + + uint32 busCntl = INREG(R128_BUS_CNTL); + if (busCntl & (R128_BUS_WRT_BURST | R128_BUS_READ_BURST)) { + busCntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; + OUTREG(R128_BUS_CNTL, busCntl); + } + + // Write the DDA registers. + //------------------------- + + OUTREG(R128_DDA_CONFIG, params.dda_config); + OUTREG(R128_DDA_ON_OFF, params.dda_on_off); + + // Write the CRTC registers. + //-------------------------- + + OUTREG(R128_CRTC_GEN_CNTL, params.crtc_gen_cntl); + + OUTREGM(R128_DAC_CNTL, R128_DAC_MASK_ALL | R128_DAC_8BIT_EN, + ~(R128_DAC_RANGE_CNTL | R128_DAC_BLANKING)); + + OUTREG(R128_CRTC_H_TOTAL_DISP, params.crtc_h_total_disp); + OUTREG(R128_CRTC_H_SYNC_STRT_WID, params.crtc_h_sync_strt_wid); + OUTREG(R128_CRTC_V_TOTAL_DISP, params.crtc_v_total_disp); + OUTREG(R128_CRTC_V_SYNC_STRT_WID, params.crtc_v_sync_strt_wid); + OUTREG(R128_CRTC_OFFSET, 0); + OUTREG(R128_CRTC_OFFSET_CNTL, 0); + OUTREG(R128_CRTC_PITCH, params.crtc_pitch); + + // Write the PLL registers. + //------------------------- + + OUTREGM(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, R128_PLL_DIV_SEL); + + SetPLLReg(R128_VCLK_ECP_CNTL, R128_VCLK_SRC_SEL_CPUCLK, R128_VCLK_SRC_SEL_MASK); + + SetPLLReg(R128_PPLL_CNTL, 0xffffffff, + R128_PPLL_RESET | R128_PPLL_ATOMIC_UPDATE_EN | R128_PPLL_VGA_ATOMIC_UPDATE_EN); + + PLLWaitForReadUpdateComplete(); + SetPLLReg(R128_PPLL_REF_DIV, params.ppll_ref_div, R128_PPLL_REF_DIV_MASK); + PLLWriteUpdate(); + + PLLWaitForReadUpdateComplete(); + SetPLLReg(R128_PPLL_DIV_3, params.ppll_div_3, + R128_PPLL_FB3_DIV_MASK | R128_PPLL_POST3_DIV_MASK); + PLLWriteUpdate(); + + PLLWaitForReadUpdateComplete(); + SetPLLReg(R128_HTOTAL_CNTL, 0); + PLLWriteUpdate(); + + SetPLLReg(R128_PPLL_CNTL, 0, R128_PPLL_RESET + | R128_PPLL_SLEEP + | R128_PPLL_ATOMIC_UPDATE_EN + | R128_PPLL_VGA_ATOMIC_UPDATE_EN); + + snooze(5000); + + SetPLLReg(R128_VCLK_ECP_CNTL, R128_VCLK_SRC_SEL_PPLLCLK, + R128_VCLK_SRC_SEL_MASK); +} + + + +status_t +Rage128_SetDisplayMode(const DisplayModeEx& mode) +{ + // The code to actually configure the display. + // All the error checking must be done in ProposeDisplayMode(), + // and assume that the mode values we get here are acceptable. + + DisplayParams params; // where computed parameters are saved + + if (gInfo.sharedInfo->displayType == MT_VGA) { + // Chip is connected to a monitor via a VGA connector. + + if ( ! CalculateCrtcRegisters(mode, params)) + return B_BAD_VALUE; + + if ( ! CalculatePLLRegisters(mode, params)) + return B_BAD_VALUE; + + if ( ! CalculateDDARegisters(mode, params)) + return B_BAD_VALUE; + + SetRegisters(params); + + } else { + // Chip is connected to a laptop LCD monitor; or via a DVI interface. + + uint16 vesaMode = GetVesaModeNumber(display_mode(mode), mode.bitsPerPixel); + if (vesaMode == 0) + return B_BAD_VALUE; + + if (ioctl(gInfo.deviceFileDesc, ATI_SET_VESA_DISPLAY_MODE, + &vesaMode, sizeof(vesaMode)) != B_OK) + return B_ERROR; + } + + Rage128_AdjustFrame(mode); + + // Initialize the palette so that color depths > 8 bits/pixel will display + // the correct colors. + + // Select primary monitor and enable 8-bit color. + OUTREGM(R128_DAC_CNTL, R128_DAC_8BIT_EN, + R128_DAC_PALETTE_ACC_CTL | R128_DAC_8BIT_EN); + OUTREG8(R128_PALETTE_INDEX, 0); // set first color index + + for (int i = 0; i < 256; i++) + OUTREG(R128_PALETTE_DATA, (i << 16) | (i << 8) | i ); + + Rage128_EngineInit(mode); + + return B_OK; +} + + + +void +Rage128_AdjustFrame(const DisplayModeEx& mode) +{ + // Adjust start address in frame buffer. + + SharedInfo& si = *gInfo.sharedInfo; + + int address = (mode.v_display_start * mode.virtual_width + + mode.h_display_start) * ((mode.bitsPerPixel + 1) / 8); + + address &= ~0x07; + address += si.frameBufferOffset; + + OUTREG(R128_CRTC_OFFSET, address); + return; +} + + +void +Rage128_SetIndexedColors(uint count, uint8 first, uint8* colorData, uint32 flags) +{ + // Set the indexed color palette for 8-bit color depth mode. + + (void)flags; // avoid compiler warning for unused arg + + if (gInfo.sharedInfo->displayMode.space != B_CMAP8) + return ; + + // Select primary monitor and enable 8-bit color. + OUTREGM(R128_DAC_CNTL, R128_DAC_8BIT_EN, + R128_DAC_PALETTE_ACC_CTL | R128_DAC_8BIT_EN); + OUTREG8(R128_PALETTE_INDEX, first); // set first color index + + while (count--) { + OUTREG(R128_PALETTE_DATA, ((colorData[0] << 16) // red + | (colorData[1] << 8) // green + | colorData[2])); // blue + colorData += 3; + } +} diff --git a/src/add-ons/accelerants/atimach64/Acceleration.c b/src/add-ons/accelerants/atimach64/Acceleration.c deleted file mode 100644 index 0ecb54368b..0000000000 --- a/src/add-ons/accelerants/atimach64/Acceleration.c +++ /dev/null @@ -1,434 +0,0 @@ -#include - -#include "GlobalData.h" -#include "generic.h" - -#define STICKY_REGS 1 - -#define WRITE_REG(x, y) outw(x, y) - -#define wait_for_slots(num) WaitQueue(num) - -/*#define wait_for_slots(numSlots) \ - { \ - uint32 FifoReg; \ - \ - do \ - { \ - READ_REG(FIFO_STAT, FifoReg); \ - } \ - while ((FifoReg & 0xFFFF) >> (16 - numSlots)); \ - } -*/ -void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count) { - - uint32 Offset, Pitch; - uint32 BppEncoding; - uint32 XDir; - uint32 YDir; - - uint32 src_top, src_left; - uint32 dest_top, dest_left; - uint32 width, height; - - uint32 scissor_x = (si->dm.virtual_width - 1) << 16; - uint32 scissor_y = (si->dm.virtual_height - 1) << 16; - - // Perform required calculations and do the blit. - // start of frame buffer - Offset = 1024; - Offset = Offset >> 3; // qword offset of the frame buffer in card memory; had - // better be qword-aligned. - - Pitch = si->dm.virtual_width; - Pitch = (Pitch + 7) >> 3; // frame buffer stride in pixels*8 - - // encode pixel format - switch (si->dm.space & ~0x3000) - { - case B_CMAP8: - BppEncoding = 0x2; - break; - case B_RGB15_BIG: - case B_RGBA15_BIG: - case B_RGB15_LITTLE: - case B_RGBA15_LITTLE: - BppEncoding = 0x3; - break; - case B_RGB16_BIG: - case B_RGB16_LITTLE: - BppEncoding = 0x4; - break; - case B_RGB32_BIG: - case B_RGBA32_BIG: - case B_RGB32_LITTLE: - case B_RGBA32_LITTLE: - default: - BppEncoding = 0x6; - } - - BppEncoding = (BppEncoding << 28) | (BppEncoding << 16) | (BppEncoding << 8) - | (BppEncoding << 4) | BppEncoding; - -#if STICKY_REGS > 0 - wait_for_slots(10); - - WRITE_REG(SC_LEFT_RIGHT, scissor_x); - WRITE_REG(SC_TOP_BOTTOM, scissor_y); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, 0x00070007); // ROP = SRC - WRITE_REG(DP_SRC, 0x00000300); - WRITE_REG(CLR_CMP_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(SRC_OFF_PITCH, (Pitch << 22) | Offset); - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - WRITE_REG(SRC_CNTL, 0x0); - /* update fifo count */ - si->engine.count += 10; -#endif - - /* program the blit */ - while (count--) { - src_left = list->src_left; - src_top = list->src_top; - dest_left = list->dest_left; - dest_top = list->dest_top; - width = list->width + 1; /* + 1 because it seems to be non-inclusive */ - height = list->height + 1; - - // Adjust direction of blitting to allow for overlapping source and destination. - if (src_left < dest_left) - { - XDir = 0; // right to left - src_left += (width - 1); - dest_left += (width - 1); - } - else - XDir = 1; // left to right - - if (src_top < dest_top) - { - YDir = 0; // bottom to top - src_top += (height - 1); - dest_top += (height - 1); - } - else - YDir = 1; // top to bottom - - - // Set up the rectangle blit - - // Critital section - accessing card registers. - //lock_card(); - - -#if STICKY_REGS > 0 - wait_for_slots(5); -#else - wait_for_slots(15); - - WRITE_REG(SC_LEFT_RIGHT, scissor_x); - WRITE_REG(SC_TOP_BOTTOM, scissor_y); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, 0x00070007); // ROP = SRC - WRITE_REG(DP_SRC, 0x00000300); - WRITE_REG(CLR_CMP_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(SRC_OFF_PITCH, (Pitch << 22) | Offset); - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - WRITE_REG(SRC_CNTL, 0x0); -#endif - - WRITE_REG(SRC_WIDTH1, width); - WRITE_REG(SRC_Y_X, ((uint32)src_left << 16) | src_top); - - // Pitch and offset had better not be out of range. - WRITE_REG(DST_CNTL, (YDir << 1) | XDir); - WRITE_REG(DST_Y_X, ((uint32)dest_left << 16) | dest_top); - WRITE_REG(DST_HEIGHT_WIDTH, ((uint32)width << 16) | height); // This triggers drawing. - -#if STICKY_REGS - /* update fifo count */ - si->engine.count += 5; -#else - /* update fifo count */ - si->engine.count += 15; -#endif - /* next one */ - list++; - } -} - -void hardware_rectangle(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count, uint32 ROP) { - - uint32 Offset; - uint32 Pitch; - uint32 Y; - uint32 X; - uint32 Width; - uint32 Height; - uint32 Colour; - uint32 BppEncoding; - -#if STICKY_REGS > 0 - uint32 scissor_x = (si->dm.virtual_width - 1) << 16; - uint32 scissor_y = (si->dm.virtual_height - 1) << 16; -#endif - - // Perform required calculations and do the blit. - // start of frame buffer - Offset = 1024; - Offset = Offset >> 3; // qword offset of the frame buffer in card memory; had - // better be qword-aligned. - - Pitch = si->dm.virtual_width; - Pitch = (Pitch + 7) >> 3; // frame buffer stride in pixels*8 - - // Don't need this - rectangle is in frame buffer co-ordinates. -// X += (uint32) (CardInfo.Display.DisplayXPos); -// Y += (uint32) (CardInfo.Display.DisplayYPos); - - // Fill colour dword with specified colour, though only ls should be necessary. - switch (si->dm.space & ~0x3000) - { - case B_CMAP8: - BppEncoding = 0x2; - colorIndex &= 0xFF; - Colour = colorIndex | (colorIndex << 8) | (colorIndex << 16) | (colorIndex << 24); - break; - case B_RGB15_BIG: - case B_RGBA15_BIG: - case B_RGB15_LITTLE: - case B_RGBA15_LITTLE: - BppEncoding = 0x3; - colorIndex &= 0xFFFF; - Colour = colorIndex | (colorIndex << 16); - break; - case B_RGB16_BIG: - case B_RGB16_LITTLE: - BppEncoding = 0x4; - colorIndex &= 0xFFFF; - Colour = colorIndex | (colorIndex << 16); - break; - case B_RGB32_BIG: - case B_RGBA32_BIG: - case B_RGB32_LITTLE: - case B_RGBA32_LITTLE: - default: - BppEncoding = 0x6; - Colour = colorIndex; - } - - BppEncoding = (BppEncoding << 28) | (BppEncoding << 16) | (BppEncoding << 8) | (BppEncoding << 4) | BppEncoding; - -#if STICKY_REGS > 0 - wait_for_slots(11); - // This seems to be needed even though we aren't using a source trajectory. - WRITE_REG(SRC_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - - WRITE_REG(DP_FRGD_CLR, Colour); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, ROP); - WRITE_REG(DP_SRC, 0x00000100); - - WRITE_REG(CLR_CMP_CNTL, 0x0); - WRITE_REG(GUI_TRAJ_CNTL, 0x3); - WRITE_REG(SC_LEFT_RIGHT, scissor_x); - WRITE_REG(SC_TOP_BOTTOM, scissor_y); - /* update fifo count */ - si->engine.count += 11; -#endif - - while (count--) { - - X = list->left; - Y = list->top; - Width = list->right; - Width = Width - X + 1; - Height = list->bottom; - Height = Height - Y + 1; - -#if STICKY_REGS > 0 - wait_for_slots(2); -#else - wait_for_slots(13); - // This seems to be needed even though we aren't using a source trajectory. - WRITE_REG(SRC_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - - WRITE_REG(DP_FRGD_CLR, Colour); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, ROP); - WRITE_REG(DP_SRC, 0x00000100); - - WRITE_REG(CLR_CMP_CNTL, 0x0); - WRITE_REG(GUI_TRAJ_CNTL, 0x3); - - WRITE_REG(SC_LEFT_RIGHT, ((X + Width - 1) << 16) | X); - WRITE_REG(SC_TOP_BOTTOM, ((Y + Height - 1) << 16) | Y); -#endif - - // X and Y should have been clipped to frame buffer, and so should be in range. - WRITE_REG(DST_Y_X, (X << 16) | Y); - WRITE_REG(DST_HEIGHT_WIDTH, (Width << 16) | Height); // This triggers drawing. - -#if STICKY_REGS - /* update fifo count */ - si->engine.count += 2; -#else - /* update fifo count */ - si->engine.count += 13; -#endif - - /* next rect */ - list++; - } - -} - -void FILL_RECTANGLE(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count) { - hardware_rectangle(et, colorIndex, list, count, 0x00070007); // ROP = SRC -} - -void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count) { - hardware_rectangle(et, 0xFFFFFFFF, list, count, 0x00000000); // ROP = !DST -} - -void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count) { - uint32 Offset; - uint32 Pitch; - uint32 Y; - uint32 X; - uint32 Width; - uint32 Height; - uint32 Colour; - uint32 BppEncoding; - - -#if STICKY_REGS > 0 - uint32 scissor_x = (si->dm.virtual_width - 1) << 16; - uint32 scissor_y = (si->dm.virtual_height - 1) << 16; -#endif - - // Perform required calculations and do the blit. - // start of frame buffer - Offset = 1024; - Offset = Offset >> 3; // qword offset of the frame buffer in card memory; had - // better be qword-aligned. - - Pitch = si->dm.virtual_width; - Pitch = (Pitch + 7) >> 3; // frame buffer stride in pixels*8 - - // Fill colour dword with specified colour, though only ls should be necessary. - switch (si->dm.space & ~0x3000) - { - case B_CMAP8: - BppEncoding = 0x2; - colorIndex &= 0xFF; - Colour = colorIndex | (colorIndex << 8) | (colorIndex << 16) | (colorIndex << 24); - break; - case B_RGB15_BIG: - case B_RGBA15_BIG: - case B_RGB15_LITTLE: - case B_RGBA15_LITTLE: - BppEncoding = 0x3; - colorIndex &= 0xFFFF; - Colour = colorIndex | (colorIndex << 16); - break; - case B_RGB16_BIG: - case B_RGB16_LITTLE: - BppEncoding = 0x4; - colorIndex &= 0xFFFF; - Colour = colorIndex | (colorIndex << 16); - break; - case B_RGB32_BIG: - case B_RGBA32_BIG: - case B_RGB32_LITTLE: - case B_RGBA32_LITTLE: - default: - BppEncoding = 0x6; - Colour = colorIndex; - } - - BppEncoding = (BppEncoding << 28) | (BppEncoding << 16) | (BppEncoding << 8) | (BppEncoding << 4) | BppEncoding; - - -#if STICKY_REGS > 0 - wait_for_slots(11); - // This seems to be needed even though we aren't using a source trajectory. - WRITE_REG(SRC_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - - WRITE_REG(DP_FRGD_CLR, Colour); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, 0x00070007); // ROP = SRC - WRITE_REG(DP_SRC, 0x00000100); - - WRITE_REG(CLR_CMP_CNTL, 0x0); - WRITE_REG(GUI_TRAJ_CNTL, 0x3); - WRITE_REG(SC_LEFT_RIGHT, scissor_x); - WRITE_REG(SC_TOP_BOTTOM, scissor_y); - /* update fifo count */ - si->engine.count += 11; -#endif - /* span lines are always one pixel tall */ - Height = 1; - while (count--) { - - Y = (uint32)*list++; - X = (uint32)*list++; - Width = (uint32)*list++; - Width = Width - X + 1; - -#if STICKY_REGS > 0 - wait_for_slots(2); -#else - wait_for_slots(13); - // This seems to be needed even though we aren't using a source trajectory. - WRITE_REG(SRC_CNTL, 0x0); - - // Pitch and offset had better not be out of range. - WRITE_REG(DST_OFF_PITCH, (Pitch << 22) | Offset); - - WRITE_REG(DP_FRGD_CLR, Colour); - WRITE_REG(DP_WRITE_MASK, 0xFFFFFFFF); - WRITE_REG(DP_PIX_WIDTH, BppEncoding); - WRITE_REG(DP_MIX, 0x00070007); // ROP = SRC - WRITE_REG(DP_SRC, 0x00000100); - - WRITE_REG(CLR_CMP_CNTL, 0x0); - WRITE_REG(GUI_TRAJ_CNTL, 0x3); - - WRITE_REG(SC_LEFT_RIGHT, ((X + Width - 1) << 16) | X); - WRITE_REG(SC_TOP_BOTTOM, ((Y + Height - 1) << 16) | Y); -#endif - - // X and Y should have been clipped to frame buffer, and so should be in range. - WRITE_REG(DST_Y_X, (X << 16) | Y); - WRITE_REG(DST_HEIGHT_WIDTH, (Width << 16) | Height); // This triggers drawing. - -#if STICKY_REGS - /* update fifo count */ - si->engine.count += 2; -#else - /* update fifo count */ - si->engine.count += 13; -#endif - - } - -} diff --git a/src/add-ons/accelerants/atimach64/Cursor.c b/src/add-ons/accelerants/atimach64/Cursor.c deleted file mode 100644 index 506b40ec7a..0000000000 --- a/src/add-ons/accelerants/atimach64/Cursor.c +++ /dev/null @@ -1,210 +0,0 @@ -#include "GlobalData.h" -#include "generic.h" - -void set_cursor_colors(void); -uint8 bit_mirror(uint8 bits); -uint16 bit_merger(uint8 andbits, uint8 xorbits); - -void set_cursor_colors(void) { - /* a place-holder for a routine to set the cursor colors */ - /* In our sample driver, it's only called by the INIT_ACCELERANT() */ - - /* Cursor color 0 is black */ - - outw(CUR_CLR0, 0x00000000); - - /* Cursor color 1 is white */ - - outw(CUR_CLR1, 0xffffffff); - -} - -uint8 -bit_mirror(uint8 bits) -{ - int i; - uint8 res = 0; - - for(i=0; i<8; i++) { - res |= (1 & (bits>>i)) <<(7-i); - - } - - return res; -} - -uint16 -bit_merger(uint8 andbits, uint8 xorbits) -{ - int i; - uint16 res = 0; - uint8 bits = 0; - - for(i=0; i<8; i++) { - bits = (((xorbits & (1<>i)<<1) | ((andbits & (1<>i); - switch (bits){ - case 0: /* Transparent is 10 */ - res |= (2 << (i*2)); - break; - case 2: /* Inversion is 11 */ - res |= (3 << (i*2)); - break; - case 1: /* White is color 1 */ - res |= (1 << (i*2)); - break; - case 3: /* Black is color 0 */ - break; - } - } - - return res; - -} - -status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask) { - - int i, j, k; - uint8 andM, xorM; - uint16 *cdata = (uint16 *)si->cursor.data; - - /* NOTE: Currently, for BeOS, cursor width and height must be equal to 16. */ - - if ((width != 16) || (height != 16)) - { - return B_ERROR; - } - else if ((hot_x >= width) || (hot_y >= height)) - { - return B_ERROR; - } - else - { - - /* Turn off cursor */ - SHOW_CURSOR(false); - - - /* Fill up data */ - k = 0; - for(i = 0; i < height; i++) { - for(j = 0; j < (width / 8); j++) { - andM = bit_mirror(~*(andMask++)); - xorM = bit_mirror(*(xorMask++)); - - /* convert 8 bits to 16 bits of mask */ - cdata[j + (i*8)] = - bit_merger(andM, xorM); - - } - - } - /* Update cursor variables appropriately. */ - si->cursor.width = width; - si->cursor.height = height; - si->cursor.hot_x = hot_x; - si->cursor.hot_y = hot_y; - - /* Turn on cursor */ - SHOW_CURSOR(true); - } - - return B_OK; -} - -/* -Move the cursor to the specified position on the desktop. If we're -using some kind of virtual desktop, adjust the display start position -accordingly and position the cursor in the proper "virtual" location. -*/ -void -MOVE_CURSOR(uint16 x, uint16 y) { - - bool move_screen = false; - uint16 hds = si->dm.h_display_start; /* the current horizontal starting pixel */ - uint16 vds = si->dm.v_display_start; /* the current vertical starting line */ - int xoff, yoff; /* offsets of cursor if it goes out of the screen */ - /* - Most cards can't set the starting horizontal pixel to anything but a multiple - of eight. If your card can, then you can change the adjustment factor here. - Oftentimes the restriction is mode dependant, so you could be fancier and - perhaps get smoother horizontal scrolling with more work. It's a sample driver, - so we're going to be lazy here. - */ - uint16 h_adjust = 7; /* a mask to make horizontal values a multiple of 8 */ - - /* clamp cursor to virtual display */ - if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1; - if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1; - - /* adjust h/v_display_start to move cursor onto screen */ - if (x >= (si->dm.timing.h_display + hds)) { - hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust; - move_screen = true; - } else if (x < hds) { - hds = x & ~h_adjust; - move_screen = true; - } - if (y >= (si->dm.timing.v_display + vds)) { - vds = y - si->dm.timing.v_display + 1; - move_screen = true; - } else if (y < vds) { - vds = y; - move_screen = true; - } - /* reposition the desktop on the display if required */ - if (move_screen) MOVE_DISPLAY(hds,vds); - - /* put cursor in correct physical position */ - x -= hds; - y -= vds; - - /* Take care of hot_x hot_y */ - xoff = x - si->cursor.hot_x; - yoff = y - si->cursor.hot_y; - - /* Do we have to fake the cursor going out of the screen ? */ - if (xoff < 0) { - xoff = -xoff; - } else { - xoff = 0; - x -= si->cursor.hot_x; - } - - if (yoff < 0) { - yoff = -yoff; - } else { - yoff = 0; - y -= si->cursor.hot_y; - } - - /* Position the offset of the cursor */ - outw(CUR_HORZ_VERT_OFF, (yoff << 16) | xoff); - - - /* position the cursor on the display */ - /* this will be card dependant */ - - /* printf(" Place %08x %d %d \n", si->regs + CUR_HORZ_VERT_POSN, x, y);*/ - - outw(CUR_HORZ_VERT_POSN, (y << 16) | x); - -} - -void SHOW_CURSOR(bool is_visible) { - - if (is_visible) { - /* add cursor showing code here */ - WaitQueue(4); - while (!(inw(CRTC_VLINE_CRNT_VLINE) & CRTC_CRNT_VLINE)); - outb(GEN_TEST_CNTL, inb(GEN_TEST_CNTL) | HWCURSOR_ENABLE); - } else { - /* add cursor hiding code here */ - WaitQueue(4); - outb(GEN_TEST_CNTL, inb(GEN_TEST_CNTL) & (~HWCURSOR_ENABLE)); - } - - WaitIdleEmpty(); - - /* record for our info */ - si->cursor.is_visible = is_visible; -} diff --git a/src/add-ons/accelerants/atimach64/EngineManagment.c b/src/add-ons/accelerants/atimach64/EngineManagment.c deleted file mode 100644 index e3a4506b69..0000000000 --- a/src/add-ons/accelerants/atimach64/EngineManagment.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "GlobalData.h" -#include "generic.h" - - -static engine_token ati_engine_token = { 1, B_2D_ACCELERATION, NULL }; - -uint32 ACCELERANT_ENGINE_COUNT(void) { - return 1; -} - -status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et) { - /* acquire the shared benaphore */ - AQUIRE_BEN(si->engine.lock) - /* sync if required */ - if (st) SYNC_TO_TOKEN(st); - - /* return an engine token */ - *et = &ati_engine_token; - return B_OK; -} - -status_t RELEASE_ENGINE(engine_token *et, sync_token *st) { - /* update the sync token, if any */ - if (st) { - st->engine_id = et->engine_id; - st->counter = si->engine.count; - } - - /* release the shared benaphore */ - RELEASE_BEN(si->engine.lock) - return B_OK; -} - -void WAIT_ENGINE_IDLE(void) { - - // Wait until engine finishes - WaitIdleEmpty(); - // note our current possition - si->engine.last_idle = si->engine.count; -} - -status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st) { - st->engine_id = et->engine_id; - st->counter = si->engine.count; - return B_OK; -} - -status_t SYNC_TO_TOKEN(sync_token *st) { - - uint64 fifo_diff; - uint64 fifo_limit; - - /* a quick out */ - if (st->counter < si->engine.last_idle) return B_OK; - - /* the full monty */ - fifo_limit = si->engine.fifo_limit; - /* fifo_mask = si->fifo_mask;*/ - do { - /* calculate the age of the sync token */ - fifo_diff = (vuint64)(si->engine.count) - st->counter; - /* add in the number of free slots in the fifo */ - fifo_diff += (uint64)((inw(GUI_STAT) >> 16) & 0x003f); - /* - The astute observer will notice that the free slot counter - doesn't have enough bits to represent the full FIFO depth. - This means that for "recent" operations, we end up waiting - on engine idle :-( - */ -#if 1 - /* add one if the engine is idle (for when st->counter == si->engine.count) */ - if (!(inw(GUI_STAT) & 0x01)) fifo_diff++; -#endif - /* anything more than fifo_limit fifo slots ago is guaranteed done */ - /* if the engine is idle, bail out */ - } while ((fifo_diff <= fifo_limit) && (inw(GUI_STAT) & 0x01)); - - /* WAIT_ENGINE_IDLE(); */ - - si->engine.last_idle = st->counter; - return B_OK; -} - diff --git a/src/add-ons/accelerants/atimach64/GetAccelerantHook.c b/src/add-ons/accelerants/atimach64/GetAccelerantHook.c deleted file mode 100644 index d3aff93dd0..0000000000 --- a/src/add-ons/accelerants/atimach64/GetAccelerantHook.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "generic.h" - -/* - -The standard entry point. Given a uint32 feature identifier, this routine -returns a pointer to the function that implements the feature. Some features -require more information than just the identifier to select the proper -function. The extra information (which is specific to the feature) is -pointed at by the void *data parameter. By default, no extra information -is available. Any extra information available to choose the function will be -noted on a case by case below. - -*/ -void * get_accelerant_hook(uint32 feature, void *data) { - switch (feature) { -/* -These definitions are out of pure lazyness. -*/ -#define HOOK(x) case B_##x: return (void *)x -#define ZERO(x) case B_##x: return (void *)0 - -/* -One of either B_INIT_ACCELERANT or B_CLONE_ACCELERANT will be requested and -subsequently called before any other hook is requested. All other feature -hook selections can be predicated on variables assigned during the accelerant -initialization process. -*/ - /* initialization */ - HOOK(INIT_ACCELERANT); - HOOK(CLONE_ACCELERANT); - - HOOK(ACCELERANT_CLONE_INFO_SIZE); - HOOK(GET_ACCELERANT_CLONE_INFO); - HOOK(UNINIT_ACCELERANT); - //HOOK(GET_ACCELERANT_DEVICE_INFO); - HOOK(ACCELERANT_RETRACE_SEMAPHORE); - - /* mode configuration */ - HOOK(ACCELERANT_MODE_COUNT); - HOOK(GET_MODE_LIST); - HOOK(PROPOSE_DISPLAY_MODE); - HOOK(SET_DISPLAY_MODE); - HOOK(GET_DISPLAY_MODE); - HOOK(GET_FRAME_BUFFER_CONFIG); - HOOK(GET_PIXEL_CLOCK_LIMITS); - HOOK(MOVE_DISPLAY); - HOOK(SET_INDEXED_COLORS); - //HOOK(GET_TIMING_CONSTRAINTS); - - HOOK(DPMS_CAPABILITIES); - HOOK(DPMS_MODE); - HOOK(SET_DPMS_MODE); - - /* cursor managment */ - HOOK(SET_CURSOR_SHAPE); - HOOK(MOVE_CURSOR); - HOOK(SHOW_CURSOR); - - /* synchronization */ - HOOK(ACCELERANT_ENGINE_COUNT); - HOOK(ACQUIRE_ENGINE); - HOOK(RELEASE_ENGINE); - HOOK(WAIT_ENGINE_IDLE); - HOOK(GET_SYNC_TOKEN); - HOOK(SYNC_TO_TOKEN); - -/* -When requesting an acceleration hook, the calling application provides a -pointer to the display_mode for which the acceleration function will be used. -Depending on the engine architecture, you may choose to provide a different -function to be used with each bit-depth. In the sample driver we return -the same function all the time. -*/ - /* 2D acceleration */ - HOOK(SCREEN_TO_SCREEN_BLIT); - HOOK(FILL_RECTANGLE); - HOOK(INVERT_RECTANGLE); - HOOK(FILL_SPAN); -#undef HOOK -#undef ZERO - } -/* -Return a null pointer for any feature we don't understand. -*/ - return 0; -} diff --git a/src/add-ons/accelerants/atimach64/GetModeInfo.c b/src/add-ons/accelerants/atimach64/GetModeInfo.c deleted file mode 100644 index 9d26cd9232..0000000000 --- a/src/add-ons/accelerants/atimach64/GetModeInfo.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "GlobalData.h" -#include "generic.h" - -extern uint32 calcBitsPerPixel(uint32 cs); - -/* - Return the current display mode. The only time you might return an - error is if a mode hasn't been set. -*/ -status_t GET_DISPLAY_MODE(display_mode *current_mode) { - /* easy for us, we return the last mode we set */ - *current_mode = si->dm; - return B_OK; -} - -/* - Return the frame buffer configuration information. -*/ -status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb) { - /* easy again, as the last mode set stored the info in a convienient form */ - *afb = si->fbc; - return B_OK; -} - -/* - Return the maximum and minium pixel clock limits for the specified mode. -*/ -status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high) { -/* - Note that we're not making any guarantees about the ability of the attached - display to handle pixel clocks within the limits we return. A future monitor - capablilities database will post-process this information. -*/ - uint32 total_pix = (uint32)dm->timing.h_total * (uint32)dm->timing.v_total; - uint32 clock_limit; - float i; - - /* max pixel clock is pixel depth dependant */ - switch (calcBitsPerPixel(dm->space)) { - case 32: clock_limit = si->pix_clk_max32; break; - case 15: - case 16: clock_limit = si->pix_clk_max16; break; - case 8: clock_limit = si->pix_clk_max8; break; - default: - clock_limit = 0; - } - /* printf("low %d, high %d %d \n", *low, clock_limit, si->pix_clk_max8);*/ - /* lower limit of about 48Hz vertical refresh */ - *low = (total_pix * 48L) / 1000L; - i = (total_pix * 48L) / 1000L; - - /* printf("low %d, high %d %08X \n", *low, clock_limit, dm->space);*/ - - if (*low > clock_limit) return B_ERROR; - *high = clock_limit; - return B_OK; -} - -/* - Return the semaphore id that will be used to signal a vertical retrace - occured. -*/ -sem_id ACCELERANT_RETRACE_SEMAPHORE(void) { - /* - NOTE: - The kernel driver created this for us. We don't know if the system is - using real interrupts, or if we're faking it, and we don't care. - If we choose not to support this at all, we'd just return B_ERROR here, - and the user wouldn't get any kind of vertical retrace support. - */ - /* return si->vblank;*/ - return B_ERROR; -} diff --git a/src/add-ons/accelerants/atimach64/GlobalData.c b/src/add-ons/accelerants/atimach64/GlobalData.c deleted file mode 100644 index ffd692e626..0000000000 --- a/src/add-ons/accelerants/atimach64/GlobalData.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "GlobalData.h" - -int fd; -shared_info *si; -area_id shared_info_area; -vuint32 *regs; -area_id regs_area; -display_mode *atimach64_mode_list; -area_id atimach64_mode_list_area; -int accelerantIsClone; diff --git a/src/add-ons/accelerants/atimach64/GlobalData.h b/src/add-ons/accelerants/atimach64/GlobalData.h deleted file mode 100644 index 1237769ebf..0000000000 --- a/src/add-ons/accelerants/atimach64/GlobalData.h +++ /dev/null @@ -1,16 +0,0 @@ -#if !defined(GLOBALDATA_H) -#define GLOBALDATA_H - -#include "DriverInterface.h" -#include "regmach64.h" - -extern int fd; -extern shared_info *si; -extern area_id shared_info_area; -extern vuint32 *regs; -extern area_id regs_area; -extern display_mode *atimach64_mode_list; -extern area_id atimach64_mode_list_area; -extern int accelerantIsClone; - -#endif diff --git a/src/add-ons/accelerants/atimach64/InitAccelerant.c b/src/add-ons/accelerants/atimach64/InitAccelerant.c deleted file mode 100644 index f94cccbe5d..0000000000 --- a/src/add-ons/accelerants/atimach64/InitAccelerant.c +++ /dev/null @@ -1,373 +0,0 @@ -#include "GlobalData.h" -#include "generic.h" -#include "Mach64.h" - -#include "string.h" -#include "unistd.h" -#include "sys/types.h" -#include "sys/stat.h" -#include "fcntl.h" -#include -#include -#include "stdio.h" - -/* defined in ProposeDisplayMode.c */ -extern status_t create_mode_list(void); -/* defined in Cursor.c */ -extern void set_cursor_colors(void); - -// Determines the amount of card memory available by seeing how far up the frame buffer -// data can be written and read back reliably. Does a paranoia check to make sure that -// It isn't just wrapping, either. -unsigned long Get_Card_Mem_Size() -{ - // Allowed sizes actually go up to 16 megs, but clip at the register window for now. - const unsigned long AllowedSizes[] = - { 0x00080000, 0x00100000, 0x00180000, 0x00200000, - 0x00280000, 0x00300000, 0x00380000, 0x00400000, - 0x00500000, 0x00600000, 0x00700000, 0x007FF800, - 0x0 }; - - unsigned long MaxMem; - unsigned long RWIndex; - int iMaxIndex, iTestIndex, iX; - unsigned long LTemp; - int IsOk; - uint32 *VramBase; - - VramBase = (uint32 *)si->framebuffer; - MaxMem = 0; // Default. - IsOk = 1; - // Step through ever-larger memory sizes, recording size if passes test and - // ignoring otherwise. - for (iMaxIndex = 0; (AllowedSizes[iMaxIndex] != 0) && IsOk; iMaxIndex++) - { - // Write test values to the linear aperature. - // Only need to do this for the farthest location, as previous locations - // already have been written to in previous passes. - RWIndex = AllowedSizes[iMaxIndex]; - RWIndex = (RWIndex - 16384) >> 2; - for (iX = 0; iX < 4096; iX++) - { - LTemp = RWIndex; - // Hash LTemp. As the parameters for the hash are prime, it should - // be extremely unlikely to get these values through a glitch, and - // the pattern only repeats at prime intervals, so aliasing shouldn't - // fool the test either. - LTemp = (263 * (LTemp % 65521) + 29) % 65521; - // Extend this to 32 bits. - LTemp |= (LTemp ^ 0x0000FFFFul) << 16; - VramBase[RWIndex] = LTemp; - RWIndex++; - } - - // Verify that all test patterns are still intact. If values written past the - // end of memory drop off the face of the frame buffer, the farthest pattern(s) - // will not be what they should be. If values written past the end of memory - // wrap, then previous patterns will be overwritten (or partly overwritten, - // as the test location at 8 megs is actually at 8 megs - 2k). - // As soon as an invalid value is detected, IsOk is set to 0, which should - // quickly terminate the test loops. - for (iTestIndex = 0; (iTestIndex <= iMaxIndex) && IsOk; iTestIndex++) - { - RWIndex = AllowedSizes[iTestIndex]; - RWIndex = (RWIndex - 16384) >> 2; - for (iX = 0; (iX < 4096) && IsOk; iX++) - { - LTemp = RWIndex; - // Hash LTemp. As the parameters for the hash are prime, it should - // be extremely unlikely to get these values through a glitch, and - // the pattern only repeats at prime intervals, so aliasing shouldn't - // fool the test either. - LTemp = (263 * (LTemp % 65521) + 29) % 65521; - // Extend this to 32 bits. - LTemp |= (LTemp ^ 0x0000FFFFul) << 16; - // Test against the value read from the frame buffer. - if (VramBase[RWIndex] != LTemp) - IsOk = 0; - RWIndex++; - } - } - - // If the test patterns check out, update MaxMem accordingly. - if (IsOk) - MaxMem = AllowedSizes[iMaxIndex]; - } - return MaxMem; -} - - - -static status_t init_common(int the_fd); - -/* Initialization code shared between primary and cloned accelerants */ -static status_t init_common(int the_fd) { - status_t result; - atimach64_get_private_data gpd; - - /* memorize the file descriptor */ - fd = the_fd; - /* set the magic number so the driver knows we're for real */ - gpd.magic = ATIMACH64_PRIVATE_DATA_MAGIC; - /* contact driver and get a pointer to the registers and shared data */ - result = ioctl(fd, ATIMACH64_GET_PRIVATE_DATA, &gpd, sizeof(gpd)); - - if (result != B_OK) goto error0; - - /* clone the shared area for our use */ - shared_info_area = clone_area("ATIMACH64 shared info", (void **)&si, B_ANY_ADDRESS, - B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area); - if (shared_info_area < 0) { - result = shared_info_area; - goto error0; - } - - /* all done */ - goto error0; - -error0: - return result; -} - -/* Clean up code shared between primary and cloned accelrants */ -static void uninit_common(void) { - /* release the memory mapped registers */ - /* delete_area(regs_area); */ - /* a little cheap paranoia */ - regs = 0; - /* release our copy of the shared info from the kernel driver */ - delete_area(shared_info_area); - /* more cheap paranoia */ - si = 0; -} - -/* -Initialize the accelerant. the_fd is the file handle of the device (in -/dev/graphics) that has been opened by the app_server (or some test harness). -We need to determine if the kernel driver and the accelerant are compatible. -If they are, get the accelerant ready to handle other hook functions and -report success or failure. -*/ -status_t INIT_ACCELERANT(int the_fd) { - status_t result; - - /* note that we're the primary accelerant (accelerantIsClone is global) */ - accelerantIsClone = 0; - - /* do the initialization common to both the primary and the clones */ - result = init_common(the_fd); - - /* bail out if the common initialization failed */ - if (result != B_OK) goto error0; - - /* - If there is a possiblity that the kernel driver will recognize a card that - the accelerant can't support, you should check for that here. Perhaps some - odd memory configuration or some such. - */ - - /* - This is a good place to go and initialize your card. The details are so - device specific, we're not even going to pretend to provide you with sample - code. If this fails, we'll have to bail out, cleaning up the resources - we've already allocated. - */ - /* call the device specific init code */ - if (si->mem_size != Get_Card_Mem_Size()){ - result = B_ERROR; - } - - mach64InitAperture(); - mach64ResetEngine(); - WaitIdleEmpty(); - - /* Disable all interrupts */ - outw(CRTC_INT_CNTL, 0); - - WaitIdleEmpty(); - - /* bail out if it failed */ - if (result != B_OK) goto error1; - - /* - Now would be a good time to figure out what video modes your card supports. - We'll place the list of modes in another shared area so all of the copies - of the driver can see them. The primary copy of the accelerant (ie the one - initialized with this routine) will own the "one true copy" of the list. - Everybody else get's a read-only clone. - */ - - result = create_mode_list(); - if (result != B_OK) goto error2; - - /* - Initialize the frame buffer and cursor pointers. Most newer video cards - have integrated the DAC into the graphics engine, and so the cursor shape - is stored in the frame buffer RAM. Also, newer cards tend not to have as - many restrictions about the placement of the start of the frame buffer in - frame buffer RAM. If you're supporting an older card with frame buffer - positioning restrictions, or one without an integrated DAC, you'll have to - change this accordingly. - */ - - /* - Put the cursor at the start of the frame buffer. The typical 64x64 4 color - (black, white, transparent, inverse) takes up 1024 bytes of RAM. - */ - si->cursor.data = (uint8 *)si->framebuffer; - - /* Initialize cursor as transparent */ - memset(si->cursor.data, 0xaa, 1024); - - /* Initialize the rest of the cursor information while we're here */ - si->cursor.width = 0; - si->cursor.height = 0; - si->cursor.hot_x = 0; - si->cursor.hot_y = 0; - si->cursor.x = 0; - si->cursor.y = 0; - - /* Tell the hardware all the cursor info */ - - outw(CUR_OFFSET, 0x00000000); /* Where it is in memory */ - outw(CUR_HORZ_VERT_POSN, 0x00000000); /* Position in screen */ - outw(CUR_HORZ_VERT_OFF, 0x00000000); /* Hot x,y */ - - /* - Put the frame buffer immediately following the cursor data. We store this - info in a frame_buffer_config structure to make it convienient to return - to the app_server later. - */ - si->fbc.frame_buffer = (void *)(((char *)si->framebuffer) + 1024); - si->fbc.frame_buffer_dma = (void *)(((char *)si->framebuffer_pci) + 1024); - - /* init the shared semaphore */ - INIT_BEN(si->engine.lock); - /* initialize the engine synchronization variables */ - - /* count of issued parameters or commands */ - si->engine.last_idle = si->engine.count = 0; - - /* bail out if something failed */ - if (result != B_OK) goto error3; - - /* set the cursor colors. You may or may not have to do this, depending - on the device. */ - set_cursor_colors(); - - /* ensure cursor state */ - SHOW_CURSOR(false); - /* a winner! */ - result = B_OK; - goto error0; - -error3: - /* free up the benaphore */ - DELETE_BEN(si->engine.lock); - -error2: - /* - Clean up any resources allocated in your device specific initialization - code. - */ - -error1: - /* - Initialization failed after init_common() succeeded, so we need to clean - up before quiting. - */ - uninit_common(); - -error0: - return result; -} - -/* -Return the number of bytes required to hold the information required -to clone the device. -*/ -ssize_t ACCELERANT_CLONE_INFO_SIZE(void) { - /* - Since we're passing the name of the device as the only required - info, return the size of the name buffer - */ - return MAX_ATIMACH64_DEVICE_NAME_LENGTH; -} - - -/* -Return the info required to clone the device. void *data points to -a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length. -*/ -void GET_ACCELERANT_CLONE_INFO(void *data) { - atimach64_device_name dn; - status_t result; - - /* call the kernel driver to get the device name */ - dn.magic = ATIMACH64_PRIVATE_DATA_MAGIC; - /* store the returned info directly into the passed buffer */ - dn.name = (char *)data; - result = ioctl(fd, ATIMACH64_DEVICE_NAME, &dn, sizeof(dn)); -} - -/* -Initialize a copy of the accelerant as a clone. void *data points to -a copy of the data returned by GET_ACCELERANT_CLONE_INFO(). -*/ -status_t CLONE_ACCELERANT(void *data) { - status_t result; - char path[MAXPATHLEN]; - - /* the data is the device name */ - strcpy(path, "/dev/"); - strcat(path, (const char *)data); - /* open the device, the permissions aren't important */ - fd = open(path, B_READ_WRITE); - if (fd < 0) { - result = errno; - goto error0; - } - - /* note that we're a clone accelerant */ - accelerantIsClone = 1; - - /* call the shared initialization code */ - result = init_common(fd); - - /* bail out if the common initialization failed */ - if (result != B_OK) goto error1; - - /* get shared area for display modes */ - result = atimach64_mode_list_area = clone_area( - "ATIMACH64 cloned display_modes", - (void **)&atimach64_mode_list, - B_ANY_ADDRESS, - B_READ_AREA, - si->mode_area - ); - if (result < B_OK) goto error2; - - /* all done */ - result = B_OK; - goto error0; - -error2: - /* free up the areas we cloned */ - uninit_common(); -error1: - /* close the device we opened */ - close(fd); -error0: - return result; -} - -void UNINIT_ACCELERANT(void) { - /* free our mode list area */ - delete_area(atimach64_mode_list_area); - /* paranoia */ - atimach64_mode_list = 0; - /* release our cloned data */ - uninit_common(); - /* close the file handle ONLY if we're the clone */ - if (accelerantIsClone) close(fd); -} diff --git a/src/add-ons/accelerants/atimach64/Jamfile b/src/add-ons/accelerants/atimach64/Jamfile deleted file mode 100644 index e073a933a8..0000000000 --- a/src/add-ons/accelerants/atimach64/Jamfile +++ /dev/null @@ -1,21 +0,0 @@ -SubDir HAIKU_TOP src add-ons accelerants atimach64 ; - -UsePrivateHeaders graphics ; -UsePrivateHeaders [ FDirName graphics atimach64 ] ; - -Addon atimach64.accelerant : - Acceleration.c - Cursor.c - EngineManagment.c - GetAccelerantHook.c - GlobalData.c - GetModeInfo.c - InitAccelerant.c - Mach64.c - Mach64fifo.c - ProposeDisplayMode.c - SetDisplayMode.c -; - -Depends atimach64.accelerant : atimach64.driver ; - diff --git a/src/add-ons/accelerants/atimach64/Mach64.c b/src/add-ons/accelerants/atimach64/Mach64.c deleted file mode 100644 index 9013aabcc1..0000000000 --- a/src/add-ons/accelerants/atimach64/Mach64.c +++ /dev/null @@ -1,447 +0,0 @@ -/* All this code has been reversed engineered from Xfree86 Project :-) - - Copyright 1999 by - - Rene MacKinney - - 7.May.99 - -*/ - -//------------------------------------------------------------------------ -/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64.c,v 3.62.2.15 19 -98/10/18 20:42:04 hohndel Exp $ */ -/* - * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. - * Copyright 1993,1994,1995,1996,1997 by Kevin E. Martin, Chapel Hill, North Car -olina. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Roell not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Roell makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. - * - * THOMAS ROELL, KEVIN E. MARTIN, AND RICKARD E. FAITH DISCLAIM ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHORS - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY - * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Thomas Roell, roell@informatik.tu-muenchen.de - * - * Rewritten for the 8514/A by Kevin E. Martin (martin@cs.unc.edu) - * Modified for the Mach-8 by Rickard E. Faith (faith@cs.unc.edu) - * Rewritten for the Mach32 by Kevin E. Martin (martin@cs.unc.edu) - * Rewritten for the Mach64 by Kevin E. Martin (martin@cs.unc.edu) - * Support for the Mach64 CT added by David Dawes (dawes@XFree86.org) - * - */ -/* $XConsortium: mach64.c /main/34 1996/10/28 04:46:47 kaleb $ */ - - -//--------------------------------------------------------------------------- - -#include - -#include "GlobalData.h" -#include "generic.h" -#include "Mach64fifo.h" -#include "Mach64.h" - - -/* - * mach64FIFOdepth -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepth(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int fifo_depth; - - if (si->device_id == MACH64_VT_ID) { - if (si->revision == 0x48) { /* VTA4 */ - fifo_depth = mach64FIFOdepthVTA4(cdepth, clock, width); - } else { /* VTA3 */ - fifo_depth = mach64FIFOdepthVTA3(cdepth, clock, width); - } - } else if (si->device_id == MACH64_GT_ID) { - fifo_depth = mach64FIFOdepthGT(cdepth, clock, width); - } else if (si->device_id == MACH64_CT_ID && si->revision == 0x0a) { - /* CT-D has a larger FIFO and thus requires special code */ - fifo_depth = mach64FIFOdepthCTD(cdepth, clock, width); - } else if (si->device_id == MACH64_CT_ID || - si->device_id == MACH64_ET_ID) { - fifo_depth = mach64FIFOdepthCT(cdepth, clock, width); - } else { - fifo_depth = mach64FIFOdepthDefault(cdepth, clock, width); - } - - return(fifo_depth); -} - -/* - * mach64ProgramClkMach64CT -- - * - */ -void mach64ProgramClkMach64CT(clkCntl, MHz100) - int clkCntl; - int MHz100; -{ - char old_crtc_ext_disp; -#ifdef DEBUG - extern void mach64PrintCTPLL(); -#endif - int M, N, P, R; - float Q; - int postDiv; - int mhz100 = MHz100; - unsigned char tmp1, tmp2; - int ext_div = 0; - float current_dot_clock; - - old_crtc_ext_disp = inb(CRTC_GEN_CNTL+3); - outb(CRTC_GEN_CNTL+3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24)); - - M = si->RefDivider; - R = si->RefFreq; - - if (clkCntl > 3) clkCntl = 3; - - if (mhz100 < si->MinFreq) mhz100 = si->MinFreq; - if (mhz100 > si->MaxFreq) mhz100 = si->MaxFreq; - - Q = (mhz100 * M)/(2.0 * R); - - if (false) { /* mach64HasDSP) { */ - if (Q > 255) { - /* printf("mach64ProgramClkMach64CT: Warning: Q > 255\n");*/ - Q = 255; - P = 0; - postDiv = 1; - } else if (Q > 127.5) { - P = 0; - postDiv = 1; - } else if (Q > 85) { - P = 1; - postDiv = 2; - } else if (Q > 63.75) { - P = 0; - postDiv = 3; - ext_div = 1; - } else if (Q > 42.5) { - P = 2; - postDiv = 4; - } else if (Q > 31.875) { - P = 2; - postDiv = 6; - ext_div = 1; - } else if (Q > 21.25) { - P = 3; - postDiv = 8; - } else if (Q >= 10.6666666667) { - P = 3; - postDiv = 12; - ext_div = 1; - } else { - /* printf("mach64ProgramClkMach64CT: Warning: Q < 10.66666667\n");*/ - P = 3; - postDiv = 12; - ext_div = 1; - } - } else { - if (Q > 255) { - /* printf("mach64ProgramClkMach64CT: Warning: Q > 255\n");*/ - Q = 255; - P = 0; - } - else if (Q > 127.5) - P = 0; - else if (Q > 63.75) - P = 1; - else if (Q > 31.875) - P = 2; - else if (Q >= 16) - P = 3; - else { - /* printf("mach64ProgramClkMach64CT: Warning: Q < 16\n");*/ - P = 3; - } - postDiv = 1 << P; - } - N = (int)(Q * postDiv + 0.5); - - current_dot_clock = (2.0 * R * N)/(M * postDiv); - -#ifdef DEBUG_HARNESS - printf("Q = %f N = %d P = %d, postDiv = %d R = %d M = %d\n", Q, N, P, postDiv, R, M); - printf("New freq: %.2f\n", (double)((2 * R * N)/(M * postDiv)) / 100.0); -#endif - - outb(CLOCK_CNTL + 1, PLL_VCLK_CNTL << 2); -#ifdef DEBUG_HARNESS - printf("CLOCK_CNTL + 1 = 0x%08x\n",PLL_VCLK_CNTL << 2); -#endif - tmp1 = inb(CLOCK_CNTL + 2); - outb(CLOCK_CNTL + 1, (PLL_VCLK_CNTL << 2) | PLL_WR_EN); - outb(CLOCK_CNTL + 2, tmp1 | 0x04); - outb(CLOCK_CNTL + 1, VCLK_POST_DIV << 2); - tmp2 = inb(CLOCK_CNTL + 2); - outb(CLOCK_CNTL + 1, ((VCLK0_FB_DIV + clkCntl) << 2) | PLL_WR_EN); - outb(CLOCK_CNTL + 2, N); - outb(CLOCK_CNTL + 1, (VCLK_POST_DIV << 2) | PLL_WR_EN); - outb(CLOCK_CNTL + 2, - (tmp2 & ~(0x03 << (2 * clkCntl))) | (P << (2 * clkCntl))); - outb(CLOCK_CNTL + 1, (PLL_VCLK_CNTL << 2) | PLL_WR_EN); - outb(CLOCK_CNTL + 2, tmp1 & ~0x04); - - if (false) { /* mach64HasDSP) { */ - outb(CLOCK_CNTL + 1, PLL_XCLK_CNTL << 2); - tmp1 = inb(CLOCK_CNTL + 2); - outb(CLOCK_CNTL + 1, (PLL_XCLK_CNTL << 2) | PLL_WR_EN); - if (ext_div) - outb(CLOCK_CNTL + 2, tmp1 | (1 << (clkCntl + 4))); - else - outb(CLOCK_CNTL + 2, tmp1 & ~(1 << (clkCntl + 4))); - } - - snooze(5000); - - (void)inb(DAC_REGS); /* Clear DAC Counter */ - outb(CRTC_GEN_CNTL+3, old_crtc_ext_disp); - - return; -} - -/* - * CalcCRTCRegs -- - * Calculate appropiate values for CRTC Registers - */ -void -CalcCRTCRegs(crtcRegs, mode) - mach64CRTCRegPtr crtcRegs; - display_mode *mode; -{ - int h_pol = (mode->timing.flags & B_POSITIVE_HSYNC) ? 1 : 0; - int v_pol = (mode->timing.flags & B_POSITIVE_VSYNC) ? 1 : 0; - - /* Register CRTC_H_TOTAL_DISP - bits 23-16 Horizontal total visible in character clocks (8 pixel units) - bits 7-0 Horizontal display end in character clocks - */ - crtcRegs->h_total_disp = (((mode->timing.h_display >> 3) - 1) << 16) | - ((mode->timing.h_total >> 3) - 1); - - /* Register CRTC_H_SYNC_STRT_WID - bits 21 Horizontal sync polarity - bits 20-16 Horizontal sync width in character clocks - bits 10-8 Horizontal sync start delay in pixels - bits 7-0 Horizontal sync start in character clocks - */ - crtcRegs->h_sync_strt_wid = h_pol << 21 | - (((mode->timing.h_sync_end - mode->timing.h_sync_start) >> 3) << 16) | - /* ((mode->timing.h_sync_start % 8) << 8) |*/ - ((mode->timing.h_sync_start >> 3) - 1); - - /* Register CRTC_V_TOTAL_DISP - bits 23-16 Vertical total visible in lines - bits 7-0 Vertical display end in lines - */ - crtcRegs->v_total_disp = ((mode->timing.v_display - 1) << 16) | - (mode->timing.v_total - 1); - - /* Register CRTC_V_SYNC_STRT_WID - bits 21 Vertical sync polarity - bits 20-16 Vertical sync width in lines - bits 10-0 Vertical sync start in lines - */ - crtcRegs->v_sync_strt_wid = v_pol << 21 | - ((mode->timing.v_sync_end - mode->timing.v_sync_start) << 16) | - (mode->timing.v_sync_start - 1); - - switch (mode->space & 0x0fff) { - case B_CMAP8: - crtcRegs->color_depth = CRTC_PIX_WIDTH_8BPP; - break; - case B_RGB15: - crtcRegs->color_depth = CRTC_PIX_WIDTH_15BPP; - break; - case B_RGB16: - crtcRegs->color_depth = CRTC_PIX_WIDTH_16BPP; - break; - case B_RGB32: - crtcRegs->color_depth = CRTC_PIX_WIDTH_32BPP; - break; - default: - } - - crtcRegs->crtc_gen_cntl = 0; - if (mode->timing.flags & B_TIMING_INTERLACED) - crtcRegs->crtc_gen_cntl |= CRTC_INTERLACE_EN; - - - crtcRegs->clock_cntl = 0x03; /* Hack */ - crtcRegs->dot_clock = mode->timing.pixel_clock / 10; - - crtcRegs->fifo_v1 = mach64FIFOdepth(crtcRegs->color_depth, - crtcRegs->dot_clock, mode->timing.h_display); - - - - -} - -/* - * SetCRTCRegs - * Write values to the CRTC Registers */ -void -SetCRTCRegs(crtcRegs, mode) - mach64CRTCRegPtr crtcRegs; - display_mode *mode; -{ - int crtcGenCntl; - uint32 offset; - - WaitIdleEmpty(); - crtcGenCntl = inw(CRTC_GEN_CNTL); - outw(CRTC_GEN_CNTL, crtcGenCntl & ~(CRTC_EXT_EN | CRTC_LOCK_REGS)); - - /* Program the clock chip */ - mach64ProgramClkMach64CT(0x03, crtcRegs->dot_clock); - - - /* Horizontal CRTC registers */ - outw(CRTC_H_TOTAL_DISP, crtcRegs->h_total_disp); - outw(CRTC_H_SYNC_STRT_WID, crtcRegs->h_sync_strt_wid); - - /* Vertical CRTC registers */ - outw(CRTC_V_TOTAL_DISP, crtcRegs->v_total_disp); - outw(CRTC_V_SYNC_STRT_WID, crtcRegs->v_sync_strt_wid); - - /* Clock select register */ - outw(CLOCK_CNTL, crtcRegs->clock_cntl | CLOCK_STROBE); - - /* Zero overscan register to insure proper color */ - /* outw(OVR_CLR, 0); - outw(OVR_WID_LEFT_RIGHT, 0); - outw(OVR_WID_TOP_BOTTOM, 0); - */ - /* Set the offset and width of the display - We could just use the offset value we already know (1024) but this - will deal with any changes - */ - offset = (si->fbc.frame_buffer - si->framebuffer) >> 3; - - outw(CRTC_OFF_PITCH, ((mode->virtual_width >> 3) << 22) | offset); - outw(DST_OFF_PITCH, ((mode->virtual_width >> 3) << 22) | offset); - outw(SRC_OFF_PITCH, ((mode->virtual_width >> 3) << 22) | offset); - - - - /* Display control register -- this one turns on the display */ - - outw(CRTC_GEN_CNTL, - (crtcGenCntl & 0xff0000ff & - ~(CRTC_PIX_BY_2_EN | CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN | - CRTC_HSYNC_DIS | CRTC_VSYNC_DIS)) | - (crtcRegs->crtc_gen_cntl & ~CRTC_PIX_BY_2_EN) | - crtcRegs->color_depth | - (((crtcRegs->fifo_v1 & 0x0f) << 16) | - CRTC_EXT_DISP_EN | CRTC_EXT_EN)); - - /* printf(" crtcGenCntl 0x%08x\n", (crtcGenCntl & 0xff0000ff & - ~(CRTC_PIX_BY_2_EN | CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN | - CRTC_HSYNC_DIS | CRTC_VSYNC_DIS)) | - (crtcRegs->crtc_gen_cntl & ~CRTC_PIX_BY_2_EN) | - crtcRegs->color_depth | - (((crtcRegs->fifo_v1 & 0x0f) << 16) | - CRTC_EXT_DISP_EN | CRTC_EXT_EN));*/ - - - /* Set the DAC for the currect mode */ - /* mach64SetRamdac(crtcRegs->color_depth, TRUE, crtcRegs->dot_clock); - */ - WaitIdleEmpty(); -} - -/* - * mach64InitAperture -- - * Initialize the aperture for the Mach64. - */ -void mach64InitAperture() -{ - ulong apaddr = (ulong) si->framebuffer_pci; - - outw(CONFIG_CNTL, ((apaddr/(4*1024*1024)) << 4) | 2); - -} - -/* - * mach64ResetEngine -- - * Resets the GUI engine and clears any FIFO errors. - */ -void mach64ResetEngine() -{ - int temp; - - /* Ensure engine is not locked up by clearing any FIFO errors */ - outw(BUS_CNTL, inw(BUS_CNTL) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK); - - /* Reset engine */ - temp = inw(GEN_TEST_CNTL); - outw(GEN_TEST_CNTL, temp & ~GUI_ENGINE_ENABLE); - - outw(GEN_TEST_CNTL, temp | GUI_ENGINE_ENABLE); - - WaitIdleEmpty(); -} - - - -void -InitRAMDAC(uint32 colorDepth, uint32 flags) -{ - int count; - uint8 val; - - WaitIdleEmpty(); - - /* Initialize Acceleration Mode */ - - outb(CRTC_GEN_CNTL+3, ((CRTC_EXT_DISP_EN | CRTC_EXT_EN) >> 24)); - - switch(colorDepth){ - case 8: - val = inb(DAC_CNTL+1); - if (flags & B_8_BIT_DAC) - outb(DAC_CNTL + 1, val | 0x01); - else - outb(DAC_CNTL + 1, val & ~0x01); - break; - case 15: - case 16: - case 24: - case 32: - val = inb(DAC_CNTL + 1); - outb(DAC_CNTL + 1, val | 0x01); - outb(DAC_CNTL + 2, 0xff); - outb(DAC_REGS, 0x00); - for(count = 0; count < 256; count ++) { - outb(DAC_REGS+1, count); - outb(DAC_REGS+1, count); - outb(DAC_REGS+1, count); - } - - break; - } - -} diff --git a/src/add-ons/accelerants/atimach64/Mach64.h b/src/add-ons/accelerants/atimach64/Mach64.h deleted file mode 100644 index dc551550b9..0000000000 --- a/src/add-ons/accelerants/atimach64/Mach64.h +++ /dev/null @@ -1,5 +0,0 @@ -extern void mach64InitAperture(); -extern void mach64ResetEngine(); -extern void CalcCRTCRegs(mach64CRTCRegPtr, display_mode *); -extern void SetCRTCRegs(mach64CRTCRegPtr, display_mode *); -void InitRAMDAC(uint32, uint32); diff --git a/src/add-ons/accelerants/atimach64/Mach64fifo.c b/src/add-ons/accelerants/atimach64/Mach64fifo.c deleted file mode 100644 index 60bec9af83..0000000000 --- a/src/add-ons/accelerants/atimach64/Mach64fifo.c +++ /dev/null @@ -1,1738 +0,0 @@ -/* - * Copyright 1996 by Kevin E. Martin, Chapel Hill, North Carolina. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of Kevin - * E. Martin not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Kevin E. Martin makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64fifo.c,v 3.1 1996/12/28 08:14:40 dawes Exp $ */ - -#include "GlobalData.h" -#include "generic.h" - -#define MAX_CDEPTH 6 -#define MAX_DOTCLOCKS 14 - -typedef struct { - short dotclock; - unsigned char fifo_val; -} mach64FIFOTable; - - -static unsigned char defaultFIFOVals[] = { - 0x02, 0x0c, 0x02, 0x06, 0x02, 0x0e, /* 8 bpp */ - 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, /* 16 bpp */ - 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, /* 24 bpp */ - 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e /* 32 bpp */ -}; - -static unsigned char CT_FIFOVals[] = { - /* 640x480 */ - 0x04, 0x0c, 0x04, 0x08, 0x09, 0x0f, /* 8 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x08, 0x0f, /* 16 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x08, 0x0f, /* 24 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x08, 0x0f, /* 32 bpp */ - /* 800x600 */ - 0x04, 0x0c, 0x04, 0x08, 0x08, 0x0f, /* 8 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x08, 0x0f, /* 16 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 24 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 32 bpp */ - /* 1024x768 */ - 0x04, 0x0c, 0x04, 0x08, 0x08, 0x0f, /* 8 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 16 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 24 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 32 bpp */ - /*1280x1024 */ - 0x04, 0x0c, 0x04, 0x08, 0x0e, 0x0f, /* 8 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 16 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f, /* 24 bpp */ - 0x04, 0x0e, 0x04, 0x0e, 0x0e, 0x0f /* 32 bpp */ -}; - -static mach64FIFOTable VTA3_SDRAM_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 3600, 0x04}, { 4400, 0x06}, { 6800, 0x06}, { 9000, 0x08}, - {10500, 0x0a}, {24000, 0x0c} }, /* 8bpp */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 15bpp */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 16bpp */ - { { 2200, 0x08}, { 2600, 0x08}, { 3300, 0x0a}, { 3600, 0x0c}, - { 4000, 0x0e}, {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x08} } /* 32bpp */ -}; - -static mach64FIFOTable VTA3_SDRAM_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 4000, 0x04}, { 5700, 0x06}, { 9400, 0x08}, {11200,0x0c}, - {24000, 0x0e} }, /* 8bpp */ - { { 2600, 0x06}, { 4200, 0x08}, { 4600, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 15bpp */ - { { 2600, 0x06}, { 4200, 0x08}, { 4600, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 16bpp */ - { { 2600, 0x0a}, { 3800, 0x0c}, { 4000, 0x0c}, { 4500, 0x28}, - {24000, 0x2c} }, /* 24bpp */ - { { 2200, 0x0a}, { 3000, 0x0c}, { 3400, 0x0e}, {24000, 0x0e} } /* 32bpp */ -}; - -static mach64FIFOTable VTA3_SDRAM_1M_6300_5[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, - { { 3800, 0x04}, { 4400, 0x06}, { 6600, 0x06}, { 9000, 0x08}, - {24000, 0x0a} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, { 6900, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, { 6900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 2600, 0x0a}, { 3400, 0x0c}, { 4200, 0x0e}, - { 4600, 0x0e}, {24000, 0x0e} }, - { {24000, 0x06} } - }; - -static mach64FIFOTable VTA3_SDRAM_2M_6300_5[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, - { { 3000, 0x04}, { 4000, 0x06}, { 6000, 0x08}, { 9400, 0x0a}, - {10000, 0x0c}, {11200, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3500, 0x08}, { 4400, 0x0a}, { 6400, 0x0e}, - { 6800, 0x0e}, { 8200, 0x0e}, {10100, 0x0e}, {11100, 0x0e}, - {13100, 0x0e}, {13600, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3500, 0x08}, { 4400, 0x0a}, { 6400, 0x0e}, - { 6800, 0x0e}, { 8200, 0x0e}, {10100, 0x0e}, {11100, 0x0e}, - {13100, 0x0e}, {13600, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 4200, 0x0c}, { 4500, 0x28}, { 5200, 0x2c}, - { 5700, 0x2c}, { 6600, 0x2c}, { 6800, 0x2c}, { 7600, 0x2c}, - { 8200, 0x2c}, {10100, 0x2c}, {11100, 0x2c}, {12200, 0x2c}, - {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0c}, { 3400, 0x0e}, { 4100, 0x2e}, - { 4600, 0x2e}, { 5200, 0x2e}, { 5700, 0x2e}, { 6600, 0x2e}, - { 7000, 0x2e}, { 7600, 0x2e}, { 7900, 0x2e}, { 8200, 0x2e}, - {24000, 0x2e} } -}; - -static mach64FIFOTable VTA3_SDRAM_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 3600, 0x04}, { 4400, 0x06}, { 7500, 0x06}, { 8200, 0x08}, - {24000,0x0a}}, /* 8bpp */ - { { 2600, 0x06}, { 3200, 0x06}, { 3600, 0x08}, { 4000, 0x0a}, - { 5800, 0x0c}, { 8000, 0x0e}, {24000, 0x0e} }, /* 15bpp */ - { { 2600, 0x06}, { 3200, 0x06}, { 3600, 0x08}, { 4000, 0x0a}, - { 5800, 0x0c}, { 8000, 0x0e}, {24000, 0x0e} }, /* 16bpp */ - { { 2000, 0x08}, { 2600, 0x08}, { 3200, 0x0a}, { 3700, 0x0c}, - { 4200, 0x0c}, {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x06} } /* 32bpp */ -}; - -static mach64FIFOTable VTA3_SDRAM_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4 bpp */ - { { 4000, 0x04}, { 5800, 0x06}, { 8200, 0x08}, {10000, 0x0a}, - {11200, 0x0c}, {24000, 0x0e}}, /* 8bpp */ - { { 2600, 0x06}, { 4000, 0x08}, { 5100, 0x0a}, { 5800, 0x0c}, - {24000, 0x0e} }, /* 15bpp */ - { { 2600, 0x06}, { 4000, 0x08}, { 5100, 0x0a}, { 5800, 0x0c}, - {24000, 0x0e} }, /* 16bpp */ - { { 2600, 0x0a}, { 4000, 0x0c}, { 4500, 0x28}, {24000, 0x2c} }, /* 24bpp */ - { { 2600, 0x0a}, { 3600, 0x0e}, {24000, 0x2e} } /* 32bpp */ -}; - -static mach64FIFOTable VTA3_SDRAM_1M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x08}, - {24000, 0x08} }, - { { 3800, 0x04}, { 4400, 0x06}, { 7800, 0x06}, { 9000, 0x08}, - {24000, 0x0a}}, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, - { { 2000, 0x06}, { 2600, 0x06}, { 3400, 0x0a}, { 4100, 0x0c}, - {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA3_SDRAM_2M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x04}, { 9400, 0x06}, {11200, 0x08}, {24000, 0x08} }, - { { 4400, 0x04}, { 6600, 0x06}, { 9400, 0x08}, {10000, 0x0a}, - {11200, 0x0c}, {14000, 0x0c}, {24000, 0x0c}}, - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3000, 0x08}, { 3300, 0x0a}, { 4200, 0x0c}, - { 4600, 0x0c}, {24000, 0x2c} }, - { { 3000, 0x0a}, { 3400, 0x0c}, { 3800, 0x0e}, { 5200, 0x0e}, } -}; - -static mach64FIFOTable VTA3_EDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 4800, 0x06}, { 5400, 0x06}, - { 6800, 0x0a}, { 7700, 0x0a}, { 9000, 0x0a}, {11000, 0x0c}, - {24000,0x0e}}, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, {4400, 0x0a}, - { 4800, 0x0e}, {5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, {4400, 0x0a}, - { 4800, 0x0e}, {5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, {3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA3_EDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11100, 0x0c}, {13000, 0x0c}, {14000, 0x0c}, - {24000, 0x0e}}, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4100, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0e}, { 5700, 0x2a}, { 6800, 0x2a}, - {24000, 0x2a} }, - { { 3000, 0x0a}, { 3500, 0x0e}, {4200, 0x0e}, { 4600, 0x2a}, - { 5200, 0x2a}, {24000, 0x2a} } -}; - -static mach64FIFOTable VTA3_EDO_1M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 5400, 0x06}, { 7700, 0x0a}, - { 9000, 0x0a}, {10500, 0x0c}, {24000, 0x0e}}, - { { 2000, 0x06}, { 3000, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 4800, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 4800, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA3_EDO_2M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11300, 0x0c}, {14000, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4200, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0c}, {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0a}, { 3500, 0x0c}, { 4200, 0x0e}, - {24000, 0x2a} } -}; - -static mach64FIFOTable VTA3_EDO_1M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4200, 0x04}, { 6400, 0x06}, { 9000, 0x0a}, {24000, 0x0c} }, - { { 3800, 0x08}, { 6400, 0x0a}, { 7000, 0x0c}, { 9000, 0x0c}, - {24000, 0x0c}}, - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, - { { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA3_EDO_2M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x02}, { 7000, 0x04}, {10200, 0x06}, {24000, 0x0a} }, - { { 5200, 0x06}, { 6400, 0x08}, { 7000, 0x0a}, { 7900, 0x0c}, - { 8200, 0x0c}, {10800, 0x0c}, {13000, 0x0c}, {24000, 0x0c} }, - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0a}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0c}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 3400, 0x0a}, { 3600, 0x0a}, { 4400, 0x0c}, - { 5200, 0x0c} }, - { { 3400, 0x0c}, { 5200, 0x0c} } -}; - -static mach64FIFOTable VTA3_PSEUDO_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 5400, 0x06}, { 7700, 0x0a}, - { 9000, 0x0a}, {12000, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 4400, 0x0a}, { 4800, 0x0e}, - { 5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 4400, 0x0a}, { 4800, 0x0e}, - { 5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA3_PSEUDO_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11300, 0x0c}, {12700, 0x0c}, {14000, 0x0c}, - {24000, 0x0e} }, /* 8bpp */ - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x0a}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 15bpp */ - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x0a}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 16bpp */ - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4200, 0x0a}, - { 4500, 0x0c}, { 5200, 0x28}, {24000, 0x2a} }, /* 24bpp */ - { { 3000, 0x0a}, { 3500, 0x0e}, { 4200, 0x0e}, {24000, 0x2a} } /* 32bpp */ -}; - -static mach64FIFOTable VTA3_PSEUDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 4800, 0x06}, { 5400, 0x06}, - { 6800, 0x0a}, { 7700, 0x0a}, { 9000, 0x0a}, {11100, 0x0c}, - {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA3_PSEUDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11100, 0x0c}, {13000, 0x0c}, {14000, 0x0c}, - {24000, 0x0e} }, - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4100, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0e}, { 5700, 0x2a}, { 6800, 0x2a}, - {24000, 0x2a} }, - { { 3000, 0x0a}, { 3500, 0x0e}, { 4200, 0x0e}, { 4600, 0x2a}, - { 5200, 0x2a}, {24000, 0x2a} } -}; - -static mach64FIFOTable VTA3_DRAM_1M_5200[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4000, 0x02}, { 5200, 0x04}, { 9000, 0x06}, {24000, 0x0a} }, - { { 2300, 0x02}, { 3800, 0x04}, { 5200, 0x06}, { 7800, 0x0a}, - { 8500, 0x0c}, {24000, 0x0e} }, - { { 1500, 0x04}, { 3000, 0x06}, { 3500, 0x08}, { 3800, 0x0a}, - { 4000, 0x0c}, { 4500, 0x0e}, {24000, 0x2e} }, - { { 1500, 0x04}, { 3000, 0x06}, { 3500, 0x08}, { 3800, 0x0a}, - { 4000, 0x0c}, { 4500, 0x0e}, {24000, 0x2e} }, - { { 1500, 0x06}, { 2200, 0x0a}, { 3000, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA3_DRAM_2M_5200[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x02}, { 8200, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 3000, 0x02}, { 4600, 0x04}, { 6000, 0x06}, { 7600, 0x08}, - { 9000, 0x0a}, {10200, 0x0c}, {12200, 0x0e}, {24000, 0x0e} }, - { { 1500, 0x02}, { 2300, 0x04}, { 3000, 0x06}, { 3800, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 7400, 0x28}, {24000, 0x0e} }, - { { 1500, 0x02}, { 2300, 0x04}, { 3000, 0x06}, { 3800, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 7400, 0x28}, {24000, 0x0e} }, - { { 1500, 0x06}, { 2300, 0x08}, { 3000, 0x0a}, { 3300, 0x0c}, - { 3800, 0x0c}, { 4300, 0x0c}, { 4600, 0x0e}, {24000, 0x2c} }, - { { 1500, 0x06}, { 2300, 0x0a}, { 3400, 0x0c}, {24000, 0x2c} } -}; - -static mach64FIFOTable VTA3_DRAM_1M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x04}, { 7900, 0x06}, {24000, 0x0a} }, - { { 3800, 0x04}, { 5400, 0x06}, { 5800, 0x08}, { 7800, 0x0a}, - { 8500, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3400, 0x08}, { 3800, 0x0a}, - { 4400, 0x0c}, { 5000, 0x0e}, {24000, 0x2c} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3400, 0x08}, { 3800, 0x0a}, - { 4400, 0x0c}, { 5000, 0x0e}, {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA3_DRAM_2M_5600[MAX_CDEPTH][MAX_DOTCLOCKS]= -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 6600, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11200, 0x0c}, {14000, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5200, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5200, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 3500, 0x0c}, { 3800, 0x0c}, { 4200, 0x0e}, - {24000, 0x2c} } -}; - -static mach64FIFOTable VTA4_SDRAM_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 3600, 0x04}, { 4400, 0x06}, { 5500, 0x06}, { 6800, 0x06}, - { 8100, 0x08}, { 9000, 0x08}, {10500, 0x0a}, {11500, 0x0c}, - {12600, 0x0c}, {24000, 0x0c} }, /* 8bpp */ - { { 2200, 0x06}, { 2600, 0x06}, { 3000, 0x06}, { 3400, 0x06}, - { 3700, 0x08}, { 3800, 0x08}, { 4400, 0x0a}, { 4900, 0x0c}, - { 5100, 0x0c}, { 5800, 0x0c}, { 6800, 0x0e}, {24000, 0x0e} }, /* 15bpp*/ - { { 2200, 0x06}, { 2600, 0x06}, { 3000, 0x06}, { 3400, 0x06}, - { 3700, 0x08}, { 3800, 0x08}, { 4400, 0x0a}, { 4900, 0x0c}, - { 5100, 0x0c}, { 5800, 0x0c}, { 6800, 0x0e}, {24000, 0x0e} }, /* 16bpp*/ - { { 2200, 0x08}, { 2600, 0x08}, { 3300, 0x0a}, { 3600, 0x0c}, - { 4000, 0x0e}, { 4500, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x08} } /* 32bpp */ -}; - -static mach64FIFOTable VTA4_SDRAM_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 3700, 0x04}, { 4000, 0x04}, { 5700, 0x06}, { 7900, 0x08}, - { 8100, 0x08}, { 9400, 0x08}, {11200, 0x0c}, {13200, 0x0e}, - {13600, 0x0e}, {24000, 0x0e} }, /* 8bpp */ - { { 2200, 0x06}, { 2600, 0x06}, { 3700, 0x08}, { 4200, 0x08}, - { 4600, 0x0a}, { 5000, 0x0c}, { 5700, 0x0c}, { 6400, 0x0c}, - { 6800, 0x0e}, { 7900, 0x0e}, { 8100, 0x0e}, {10000, 0x0e}, - {11000, 0x0e}, {24000, 0x0e} }, /* 15bpp */ - { { 2200, 0x06}, { 2600, 0x06}, { 3700, 0x08}, { 4200, 0x08}, - { 4600, 0x0a}, { 5000, 0x0c}, { 5700, 0x0c}, { 6400, 0x0c}, - { 6800, 0x0e}, { 7900, 0x0e}, { 8100, 0x0e}, {10000, 0x0e}, - {11000, 0x0e}, {24000, 0x0e} }, /* 16bpp */ - { { 2200, 0x0a}, { 2600, 0x0a}, { 3800, 0x0c}, { 4000, 0x0c}, - { 4500, 0x28}, { 5000, 0x2c}, { 5100, 0x2c}, { 5700, 0x2c}, - { 7500, 0x2c}, {24000, 0x2c} }, /* 24bpp */ - { { 2200, 0x0a}, { 2600, 0x0c}, { 3000, 0x0c}, { 3300, 0x0e}, - { 3400, 0x0e}, { 3800, 0x0e}, { 4000, 0x0e}, { 5000, 0x0e}, - { 5700, 0x0e}, { 6800, 0x0e}, {24000, 0x0e} } /* 32bpp */ -}; - -static mach64FIFOTable VTA4_SDRAM_1M_6300_5[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, - { { 3800, 0x04}, { 4400, 0x06}, { 6600, 0x06}, { 9000, 0x08}, - {24000, 0x0a} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, { 6900, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, { 6900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 2600, 0x0a}, { 3400, 0x0c}, { 4200, 0x0e}, - { 4600, 0x0e}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA4_SDRAM_2M_6300_5[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, - { { 3000, 0x04}, { 4000, 0x06}, { 6000, 0x08}, { 9400, 0x0a}, - {10000, 0x0c}, {11200, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3500, 0x08}, { 4400, 0x0a}, { 6400, 0x0e}, - { 6800, 0x0e}, { 8200, 0x0e}, {10100, 0x0e}, {11100, 0x0e}, - {13100, 0x0e}, {13600, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3500, 0x08}, { 4400, 0x0a}, { 6400, 0x0e}, - { 6800, 0x0e}, { 8200, 0x0e}, {10100, 0x0e}, {11100, 0x0e}, - {13100, 0x0e}, {13600, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 4200, 0x0c}, { 4500, 0x28}, { 5200, 0x2c}, - { 5700, 0x2c}, { 6600, 0x2c}, { 6800, 0x2c}, { 7600, 0x2c}, - { 8200, 0x2c}, {10100, 0x2c}, {11100, 0x2c}, {12200, 0x2c}, - {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0c}, { 3400, 0x0e}, { 4100, 0x2e}, - { 4600, 0x2e}, { 5200, 0x2e}, { 5700, 0x2e}, { 6600, 0x2e}, - { 7000, 0x2e}, { 7600, 0x2e}, { 7900, 0x2e}, { 8200, 0x2e}, - {24000, 0x2e} } -}; - -static mach64FIFOTable VTA4_SDRAM_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 3600, 0x04}, { 4400, 0x06}, { 5800, 0x06}, { 7500, 0x06}, - { 8200, 0x08}, {11000, 0x0a}, {24000,0x0a}}, /* 8bpp */ - { { 2600, 0x06}, { 3200, 0x06}, { 3600, 0x08}, { 4000, 0x0a}, - { 4500, 0x0c}, { 5800, 0x0c}, { 8000, 0x0e}, {24000, 0x0e} }, /* 15bpp */ - { { 2600, 0x06}, { 3200, 0x06}, { 3600, 0x08}, { 4000, 0x0a}, - { 4500, 0x0c}, { 5800, 0x0c}, { 8000, 0x0e}, {24000, 0x0e} }, /* 16bpp */ - { { 2000, 0x08}, { 2600, 0x08}, { 3200, 0x0a}, { 3700, 0x0c}, - { 4200, 0x0c}, { 4600, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x06} } /* 32bpp */ -}; - -static mach64FIFOTable VTA4_SDRAM_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 4000, 0x04}, { 5800, 0x06}, { 8200, 0x08}, {10000, 0x0a}, - {11200, 0x0c}, {12200, 0x0e}, {13500, 0x0e}, {24000, 0x0e} }, /* 8bpp */ - { { 2600, 0x06}, { 4000, 0x08}, { 5100, 0x0a}, { 5800, 0x0c}, - { 6800, 0x0e}, { 8100, 0x0e}, {10000, 0x0e}, { 1100, 0x0e}, - {12200, 0x0e}, {12600, 0x0e}, {13500, 0x0e}, {24000, 0x0e} }, /* 15bpp */ - { { 2600, 0x06}, { 4000, 0x08}, { 5100, 0x0a}, { 5800, 0x0c}, - { 6800, 0x0e}, { 8100, 0x0e}, {10000, 0x0e}, {1100, 0x0e}, - {12200, 0x0e}, {12600, 0x0e}, {13500, 0x0e}, {24000, 0x0e} }, /* 16bpp */ - { { 2600, 0x0a}, { 4000, 0x0c}, { 4500, 0x28}, { 5200, 0x2c}, - { 5700, 0x2c}, { 6600, 0x2c}, { 6800, 0x2c}, { 7600, 0x2c}, - { 8200, 0x2c}, {10100, 0x2c}, {11100, 0x2c}, {12600, 0x2c}, - {24000, 0x2c} }, /* 24bpp */ - { { 2600, 0x0a}, { 3600, 0x0e}, { 4000, 0x0e}, { 4500, 0x2e}, - { 5200, 0x2e}, { 5700, 0x2e}, { 6600, 0x2e}, { 6800, 0x2e}, - { 7600, 0x2e}, { 8200, 0x2e}, {24000, 0x2e} } /* 32bpp */ -}; - -static mach64FIFOTable VTA4_SDRAM_1M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x08}, - {24000, 0x08} }, - { { 3800, 0x04}, { 4400, 0x06}, { 7800, 0x06}, { 9000, 0x08}, - {24000, 0x0a}}, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, - { { 2000, 0x06}, { 2600, 0x06}, { 3400, 0x0a}, { 4100, 0x0c}, - {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA4_SDRAM_2M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x04}, { 9400, 0x06}, {11200, 0x08}, {24000, 0x08} }, - { { 4400, 0x04}, { 6600, 0x06}, { 9400, 0x08}, {10000, 0x0a}, - {11200, 0x0c}, {14000, 0x0c}, {24000, 0x0c}}, - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3000, 0x08}, { 3300, 0x0a}, { 4200, 0x0c}, - { 4600, 0x0c}, {24000, 0x2c} }, - { { 3000, 0x0a}, { 3400, 0x0c}, { 3800, 0x0e}, { 5200, 0x0e} } -}; - -static mach64FIFOTable VTA4_EDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 4800, 0x06}, { 5400, 0x06}, - { 6800, 0x0a}, { 7700, 0x0a}, { 9000, 0x0a}, {11000, 0x0c}, - {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA4_EDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11100, 0x0c}, {13000, 0x0c}, {14000, 0x0c}, - {24000,0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4100, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0e}, { 5700, 0x2a}, { 6800, 0x2a}, - {24000, 0x2a} }, - { { 3000, 0x0a}, { 3500, 0x0e}, { 4200, 0x0e}, { 4600, 0x2a}, - { 5200, 0x2a}, {24000, 0x2a} } -}; - -static mach64FIFOTable VTA4_EDO_1M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 5400, 0x06}, { 7700, 0x0a}, - { 9000, 0x0a}, {10500, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 4800, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 4800, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA4_EDO_2M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11300, 0x0c}, {14000, 0x0c}, {24000, 0x0e}}, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4200, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0c}, {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0a}, { 3500, 0x0c}, { 4200, 0x0e}, - {24000, 0x2a} } -}; - -static mach64FIFOTable VTA4_EDO_1M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4200, 0x04}, { 6400, 0x06}, { 9000, 0x0a}, {24000, 0x0c} }, - { { 3800, 0x08}, { 6400, 0x0a}, { 7000, 0x0c}, { 9000, 0x0c}, - {24000, 0x0c} }, - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, - { { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA4_EDO_2M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x02}, { 7000, 0x04}, {10200, 0x06}, {24000, 0x0a} }, - { { 5200, 0x06}, { 6400, 0x08}, { 7000, 0x0a}, { 7900, 0x0c}, - { 8200, 0x0c}, {10800, 0x0c}, {13000, 0x0c}, {24000, 0x0c} }, - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0a}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0c}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 3400, 0x0a}, { 3600, 0x0a}, { 4400, 0x0c}, - { 5200, 0x0c} }, - { { 3400, 0x0c}, { 5200, 0x0c} } -}; - -static mach64FIFOTable VTA4_PSEUDO_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 4000, 0x06}, { 5400, 0x06}, - { 7700, 0x0a}, { 8000, 0x0a}, { 9000, 0x0a}, {10500, 0x0c}, - {12000, 0x0c}, {12400, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3700, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5200, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3700, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5200, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } }; - -static mach64FIFOTable VTA4_PSEUDO_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 2000, 0x04}, { 3800, 0x04}, { 4600, 0x04}, { 5600, 0x06}, - { 7000, 0x06}, { 9400, 0x08}, {10000, 0x0a}, {11300, 0x0c}, - {12700, 0x0c}, {14000, 0x0c}, {24000, 0x0e} }, /* 8bpp */ - { { 2200, 0x06}, { 3400, 0x06}, { 3700, 0x08}, { 4200, 0x0a}, - { 4500, 0x0a}, { 5500, 0x0a}, { 6600, 0x0c}, { 7000, 0x0c}, - { 7600, 0x0e}, { 7900, 0x0e}, { 9000, 0x0e}, {10500, 0x0e}, - {11500, 0x0e}, {24000, 0x0e} }, /* 15bpp */ - { { 2200, 0x06}, { 3400, 0x06}, { 3700, 0x08}, { 4200, 0x0a}, - { 4500, 0x0a}, { 5500, 0x0a}, { 6600, 0x0c}, { 7000, 0x0c}, - { 7600, 0x0e}, { 7900, 0x0e}, { 9000, 0x0e}, {10500, 0x0e}, - {11500, 0x0e}, {24000, 0x0e} }, /* 16bpp */ - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4200, 0x0a}, - { 4500, 0x0c}, { 5200, 0x28}, { 6000, 0x2a}, { 6600, 0x2a}, - { 7000, 0x2a}, { 7900, 0x2a}, {24000, 0x2a} }, /* 24bpp */ - { { 2000, 0x0a}, { 3000, 0x0a}, { 3500, 0x0e}, { 3700, 0x0e}, - { 4200, 0x0e}, { 4500, 0x2a}, { 5100, 0x2a}, { 5600, 0x2a}, - {24000, 0x2a} } /* 32bpp */ -}; - -static mach64FIFOTable VTA4_PSEUDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, - { { 3000, 0x04}, { 3800, 0x04}, { 4800, 0x06}, { 5400, 0x06}, - { 6800, 0x0a}, { 7700, 0x0a}, { 9000, 0x0a}, {11100, 0x0c}, - {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3300, 0x0a}, { 4400, 0x0a}, - { 4800, 0x0e}, { 5500, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x0a}, { 3000, 0x0a}, { 3400, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA4_PSEUDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11100, 0x0c}, {13000, 0x0c}, {14000, 0x0c}, - {24000, 0x0e} }, - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2200, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5100, 0x0a}, - { 5500, 0x0c}, { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, - { 7900, 0x0e}, {11100, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4100, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0e}, { 5700, 0x2a}, { 6800, 0x2a}, - {24000, 0x2a} }, - { { 3000, 0x0a}, { 3500, 0x0e}, { 4200, 0x0e}, { 4600, 0x2a}, - { 5200, 0x2a}, {24000, 0x2a} } -}; - -static mach64FIFOTable VTA4_DRAM_1M_5200[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4000, 0x02}, { 5200, 0x04}, { 9000, 0x06}, {24000, 0x0a} }, - { { 2300, 0x02}, { 3800, 0x04}, { 5200, 0x06}, { 7800, 0x0a}, - { 8500, 0x0c}, {24000, 0x0e} }, - { { 1500, 0x04}, { 3000, 0x06}, { 3500, 0x08}, { 3800, 0x0a}, - { 4000, 0x0c}, { 4500, 0x0e}, {24000, 0x2e} }, - { { 1500, 0x04}, { 3000, 0x06}, { 3500, 0x08}, { 3800, 0x0a}, - { 4000, 0x0c}, { 4500, 0x0e}, {24000, 0x2e} }, - { { 1500, 0x06}, { 2200, 0x0a}, { 3000, 0x0c}, {24000, 0x0e} }, - { {24000, 0x0c} } -}; - -static mach64FIFOTable VTA4_DRAM_2M_5200[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x02}, { 8200, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 3000, 0x02}, { 4600, 0x04}, { 6000, 0x06}, { 7600, 0x08}, - { 9000, 0x0a}, {10200, 0x0c}, {12200, 0x0e}, {24000, 0x0e} }, - { { 1500, 0x02}, { 2300, 0x04}, { 3000, 0x06}, { 3800, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 7400, 0x28}, {24000, 0x0e} }, - { { 1500, 0x02}, { 2300, 0x04}, { 3000, 0x06}, { 3800, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 7400, 0x28}, {24000, 0x0e} }, - { { 1500, 0x06}, { 2300, 0x08}, { 3000, 0x0a}, { 3300, 0x0c}, - { 3800, 0x0c}, { 4300, 0x0c}, { 4600, 0x0e}, {24000, 0x2c} }, - { { 1500, 0x06}, { 2300, 0x0a}, { 3400, 0x0c}, {24000, 0x2c} } -}; - -static mach64FIFOTable VTA4_DRAM_1M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x04}, { 7900, 0x06}, {24000, 0x0a} }, - { { 3800, 0x04}, { 5400, 0x06}, { 5800, 0x08}, { 7800, 0x0a}, - { 8500, 0x0c}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3400, 0x08}, - { 4400, 0x0c}, { 5000, 0x0e}, {24000, 0x2c} }, - { { 2000, 0x06}, { 3000, 0x06}, { 3400, 0x08}, - { 4400, 0x0c}, { 5000, 0x0e}, {24000, 0x2c} }, - { { 2000, 0x0a}, { 3000, 0x0a}, {24000, 0x0e} }, - { {24000, 0x06} } -}; - -static mach64FIFOTable VTA4_DRAM_2M_5600[MAX_CDEPTH][MAX_DOTCLOCKS]= -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, - { { 3400, 0x04}, { 4600, 0x04}, { 6600, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11200, 0x0c}, {14000, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5200, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5200, 0x0a}, - { 5800, 0x0c}, { 7000, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, - { { 3000, 0x0a}, { 3500, 0x0c}, { 3800, 0x0c}, { 4200, 0x0e}, - {24000, 0x2c} } -}; - -/* This is the CT-D fifo table */ -/* The datum were taken from the ct$9d-*.drm files */ -/*-------------------------------------------------------------------*/ - -/* The following two tables are extracted from CT9D-46.DRM */ -static mach64FIFOTable CTD_DRAM_2M_4600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3900, 0x04}, { 4700, 0x05}, { 5500, 0x06}, { 6300, 0x07}, - { 7100, 0x08}, { 7900, 0x09}, { 8700, 0x0a}, { 9500, 0x0b}, - {10300, 0x0c}, {11100, 0x0d}, {11900, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 4000, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 7600, 0x07}, - { 8000, 0x08}, { 8200, 0x09}, {10100, 0x0b}, {11100, 0x0d}, - {12700, 0x0f}, {24000, 0x10} }, /* 8bpp */ - { { 3300, 0x06}, { 4100, 0x08}, { 4600, 0x09}, { 5200, 0x0b}, - { 6600, 0x0f}, { 7900, 0x10}, { 8200, 0x13}, {24000, 0x1f} }, /* 15bpp */ - { { 3300, 0x06}, { 4100, 0x08}, { 4600, 0x09}, { 5200, 0x0b}, - { 6600, 0x0f}, { 7900, 0x10}, { 8200, 0x13}, {24000, 0x1f} }, /* 16bpp */ - { { 2700, 0x09}, { 3300, 0x0b}, { 4300, 0x0e}, { 4600, 0x10}, - { 5200, 0x12}, { 5700, 0x15}, {24000, 0x1f} }, /* 24bpp */ - { { 2600, 0x0b}, { 3300, 0x0f}, { 4100, 0x13}, { 4600, 0x15}, - {24000, 0x1f} } /* 32bpp */ -}; - -static mach64FIFOTable CTD_DRAM_1M_4600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3100, 0x04}, { 3800, 0x05}, { 4400, 0x06}, { 5100, 0x07}, - { 5700, 0x08}, { 6300, 0x09}, { 7000, 0x0a}, { 7600, 0x0b}, - { 8300, 0x0c}, { 8900, 0x0d}, { 9500, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 4100, 0x04}, { 4600, 0x05}, { 5200, 0x06}, { 5700, 0x07}, - { 7600, 0x09}, { 7900, 0x0a}, { 8200, 0x0b}, {24000, 0x1f} }, /* 8bpp*/ - { { 2800, 0x08}, { 3300, 0x09}, { 4100, 0x0b}, { 4600, 0x0c}, - {24000, 0x1f} }, /* 15bpp */ - { { 2800, 0x08}, { 3300, 0x09}, { 4100, 0x0b}, { 4600, 0x0c}, - {24000, 0x1f} }, /* 15bpp */ - { { 2500, 0x0d}, { 2700, 0x0e}, { 3300, 0x1c}, {24000, 0x1f} }, /* 24bpp */ - { {24000, 0x1f} } /* 32bpp */ -}; - - -/* The following four tables are extracted from CT9D-51.DRM */ -/* The tables CTD_.._4900 are created to cater for the DRAM Memory */ -/* Clock that is less than 49MHz. */ -/* Also some alternation is needed (in the function) to cater for the */ -/* condition of 1M, DRAM Memory Clock between 50MHz and 49MHz with 15 */ -/* and 16bpp */ -static mach64FIFOTable CTD_DRAM_2M_5100[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {12400, 0x0d}, {13400, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {12400, 0x0d}, {13400, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 8bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5300, 0x0a}, { 5500, 0x0b}, { 6300, 0x0c}, - { 6600, 0x0d}, { 7400, 0x0e}, { 7900, 0x0f}, { 9000, 0x11}, - {24000, 0x1f} }, /* 15bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5300, 0x0a}, { 5500, 0x0b}, { 6300, 0x0c}, - { 6600, 0x0d}, { 7400, 0x0e}, { 7900, 0x0f}, { 9000, 0x11}, - {24000, 0x1f} }, /* 16bpp */ - { { 2500, 0x09}, { 2900, 0x0a}, { 3300, 0x0b}, { 3600, 0x0c}, - { 4000, 0x0d}, { 4400, 0x0e}, { 4700, 0x10}, { 5100, 0x11}, - { 6500, 0x15}, { 7000, 0x16}, {24000, 0x1f} }, /* 24bpp */ - { { 2500, 0x0b}, { 2800, 0x0c}, { 3000, 0x0d}, { 3200, 0x0e}, - { 4000, 0x12}, { 4600, 0x13}, { 5200, 0x16}, {24000, 0x1f} } /* 32bpp*/ -}; - -static mach64FIFOTable CTD_DRAM_1M_5100[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {11000, 0x1d}, {24000, 0x1f} }, /* 8bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5100, 0x0d}, { 5500, 0x0e}, - {14000, 0x0f}, {24000, 0x1f} }, /* 15bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5100, 0x0d}, { 5500, 0x0e}, - {14000, 0x0f}, {24000, 0x1f} }, /* 16bpp */ - { { 2700, 0x0a}, { 3000, 0x0b}, { 3500, 0x0d}, { 3800, 0x0e}, - { 8000, 0x0f}, {24000, 0x1f} }, /* 24bpp */ - { {24000, 0x0f} } /* 32bpp */ -}; - -static mach64FIFOTable CTD_DRAM_2M_4900[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {12400, 0x0d}, {13400, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {14000, 0x0f}, {24000, 0x1f} }, /* 8bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5200, 0x0b}, { 5500, 0x0c}, { 6600, 0x0d}, - { 7900, 0x0f}, { 9000, 0x12}, {24000, 0x1f} }, /* 15bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5200, 0x0b}, { 5500, 0x0c}, { 6600, 0x0d}, - { 7900, 0x0f}, { 9000, 0x12}, {24000, 0x1f} }, /* 16bpp */ - { { 2500, 0x09}, { 2900, 0x0a}, { 3300, 0x0b}, { 3600, 0x0c}, - { 4000, 0x0d}, { 4400, 0x0e}, { 4700, 0x10}, { 5100, 0x11}, - { 6500, 0x15}, { 7000, 0x16}, {24000, 0x1f} }, /* 24bpp */ - { { 2500, 0x0b}, { 2800, 0x0c}, { 3000, 0x0d}, { 3200, 0x0e}, - { 4000, 0x12}, { 4600, 0x15}, {24000, 0x1f} } /* 32bpp */ -}; - -static mach64FIFOTable CTD_DRAM_1M_4900[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 4bpp */ - { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10100, 0x13}, {24000, 0x1f} }, /* 8bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5000, 0x12}, {24000, 0x1f} }, /* 15bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5000, 0x12}, {24000, 0x1f} }, /* 16bpp */ - { { 2700, 0x0a}, { 3000, 0x0b}, { 3500, 0x0e}, {24000, 0x1f} }, /* 24bpp */ - { {24000, 0x0f} } /* 32bpp */ -}; - -/* Fifo Table extracted from the file CT9D-54.DRM */ -static mach64FIFOTable CTD_DRAM_2M_5400[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {12400, 0x0d}, {13400, 0x0e}, {14000, 0x0e}, - {24000, 0x1f} }, /* 4bpp */ - { { 3800, 0x04}, { 4700, 0x05}, { 5700, 0x06}, { 6700, 0x07}, - { 7600, 0x08}, { 8600, 0x09}, { 9500, 0x0a}, {10500, 0x0b}, - {11500, 0x0c}, {12400, 0x0d}, {13400, 0x0e}, {14000, 0x0f}, - {24000, 0x1f} }, /* 8bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5300, 0x0a}, { 5800, 0x0b}, { 6300, 0x0c}, - { 6900, 0x0d}, { 7400, 0x0e}, {14000, 0x0f}, {24000, 0x1f} }, /* 15bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 4700, 0x09}, { 5300, 0x0a}, { 5800, 0x0b}, { 6300, 0x0c}, - { 6900, 0x0d}, { 7400, 0x0e}, {14000, 0x0f}, {24000, 0x1f} }, /* 16bpp */ - { { 2500, 0x08}, { 2900, 0x09}, { 3300, 0x0a}, { 3600, 0x0b}, - { 4000, 0x0c}, { 4400, 0x0d}, { 4700, 0x0e}, {14000, 0x1f}, - {24000, 0x1f} }, /* 24bpp */ - { { 2500, 0x0b}, { 2800, 0x0c}, { 3000, 0x0d}, { 3200, 0x0e}, - {14000, 0x0f}, {24000, 0x1f} } /* 32bpp */ -}; - -static mach64FIFOTable CTD_DRAM_1M_5400[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {24000, 0x1f} }, /* 4bpp */ - { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {24000, 0x1f} }, /* 8bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5100, 0x0d}, { 5500, 0x0e}, - {24000, 0x1f} }, /* 15bpp */ - { { 2700, 0x07}, { 3100, 0x08}, { 3500, 0x09}, { 3900, 0x0a}, - { 4300, 0x0b}, { 4700, 0x0c}, { 5100, 0x0d}, { 5500, 0x0e}, - {24000, 0x1f} }, /* 16bpp */ - { { 2700, 0x0a}, { 3000, 0x0b}, { 3300, 0x0c}, { 3500, 0x0d}, - { 3800, 0x0e}, {24000, 0x0f} }, /* 24bpp */ - { {24000, 0x0f} } /* 32bpp */ -}; - -/* Fifo Table extracted from the file CT9D-56.DRM */ -static mach64FIFOTable CTD_DRAM_2M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4700, 0x04}, { 5700, 0x05}, { 6700, 0x06}, { 7600, 0x07}, - { 8600, 0x08}, { 9500, 0x09}, {10500, 0x0a}, {11500, 0x0b}, - {12400, 0x0c}, {13400, 0x0d}, {14000, 0x0e}, {24000, 0x1f} }, /* 4bpp */ - { { 4700, 0x04}, { 5700, 0x05}, { 6700, 0x06}, { 7600, 0x07}, - { 8600, 0x08}, { 9500, 0x09}, {10500, 0x0a}, {11500, 0x0b}, - {12400, 0x0c}, {13400, 0x0d}, {14000, 0x0e}, {24000, 0x1f} }, /* 8bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 5300, 0x0a}, { 5800, 0x0b}, { 6300, 0x0c}, { 6900, 0x0d}, - { 7400, 0x0e}, { 9000, 0x0f}, {24000, 0x1f} }, /* 15bpp */ - { { 2600, 0x05}, { 3100, 0x06}, { 3700, 0x07}, { 4200, 0x08}, - { 5300, 0x0a}, { 5800, 0x0b}, { 6300, 0x0c}, { 6900, 0x0d}, - { 7400, 0x0e}, { 9000, 0x0f}, {24000, 0x1f} }, /* 16bpp */ - { { 2500, 0x07}, { 2900, 0x08}, { 3300, 0x09}, { 3600, 0x0a}, - { 4000, 0x0b}, { 4400, 0x0c}, { 4700, 0x0d}, { 5100, 0x0e}, - { 6500, 0x13}, { 7000, 0x14}, {24000, 0x1f} }, /* 24bpp */ - { { 3800, 0x0e}, { 4200, 0x0f}, { 5200, 0x14}, {24000, 0x1f} } /* 32bpp */ -}; - -static mach64FIFOTable CTD_DRAM_1M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {24000, 0x1f} }, /* 4bpp */ - { { 3500, 0x04}, { 4300, 0x05}, { 5000, 0x06}, { 5700, 0x07}, - { 6400, 0x08}, { 7100, 0x09}, { 7900, 0x0a}, { 8600, 0x0b}, - { 9300, 0x0c}, {10000, 0x0d}, {10700, 0x0e}, {24000, 0x0f} }, /* 8bpp */ - { { 2700, 0x06}, { 3100, 0x07}, { 3500, 0x08}, { 3900, 0x09}, - { 4300, 0x0a}, { 4700, 0x0b}, { 5100, 0x0c}, { 5500, 0x0d}, - { 5900, 0x0e}, {24000, 0x1f} }, /* 15bpp */ - { { 2700, 0x06}, { 3100, 0x07}, { 3500, 0x08}, { 3900, 0x09}, - { 4300, 0x0a}, { 4700, 0x0b}, { 5100, 0x0c}, { 5500, 0x0d}, - { 5900, 0x0e}, {24000, 0x1f} }, /* 16bpp */ - { { 2700, 0x09}, { 3000, 0x0a}, { 3300, 0x0b}, { 3500, 0x0c}, - { 3800, 0x0d}, { 4100, 0x0e}, {24000, 0x1f} }, /* 24bpp */ - { { 2500, 0x0b}, { 2700, 0x0c}, { 2900, 0x0d}, { 3100, 0x0e}, - {24000, 0x1f} } /* 32bpp */ -}; - -/* This is the GT-A2 fifo table */ -/* The datum were taken from the gt$9a-*.* files */ -/*-------------------------------------------------------------------*/ -/* The FIFO TABLE FOR SDRAM */ -/*-------------------------------------------------------------------*/ -/* The fifo table for GT SDRAM of 60MHz */ -/* data was extracted from gt$9a-60.sdr */ -/* table for 2M Ram */ -static mach64FIFOTable GTA2_SDRAM_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4 bpp */ - { { 4000, 0x04}, { 6000, 0x06}, { 9400, 0x08}, {11200, 0x0c}, - {24000, 0x0e} }, /* 8 bpp */ - { { 3000, 0x06}, { 4200, 0x08}, { 4600, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 565 */ - { { 3000, 0x06}, { 4200, 0x08}, { 4600, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 565 */ - { { 3000, 0x0a}, { 3800, 0x0c}, { 4200, 0x0c}, { 4500, 0x28}, - {24000, 0x2c} }, /* 24bpp */ - { { 2000, 0x0a}, { 3000, 0x0c}, { 3400, 0x0e}, {24000, 0x0e} } /* 32bpp */ -}; - -/* table for 1M Ram */ -static mach64FIFOTable GTA2_SDRAM_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x08}, - {24000, 0x08} }, /* 4 bpp */ - { { 3800, 0x04}, { 4400, 0x06}, { 6800, 0x06}, { 9000, 0x08}, - {10500, 0x0a}, {24000, 0x0c} }, /* 8 bpp */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 565 */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 565 */ - { { 2000, 0x08}, { 2600, 0x08}, { 3300, 0x0a}, { 3700, 0x0c}, - { 4100, 0x0e}, {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x06} } /* 32bpp */ -}; - -/* The fifo table for GT SDRAM of 63MHz */ -/* data was extracted from gt$9a-63.sdr */ -/* table for 2M Ram */ -static mach64FIFOTable GTA2_SDRAM_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4400, 0x04}, { 9400, 0x06}, {24000, 0x08} }, /* 4 bpp */ - { { 3800, 0x04}, { 6000, 0x06}, { 7600, 0x08}, { 9800, 0x0a}, - {11200, 0x0c}, {24000, 0x0e} }, /* 8 bpp */ - { { 3000, 0x06}, { 3800, 0x08}, { 5400, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 565 */ - { { 3000, 0x06}, { 3800, 0x08}, { 5400, 0x0a}, { 6400, 0x0c}, - {24000, 0x0e} }, /* 565 */ - { { 3000, 0x0a}, { 3800, 0x0c}, { 4200, 0x0c}, { 4500, 0x2a}, - {24000, 0x2c} }, /* 24bpp */ - { { 2200, 0x0a}, { 3000, 0x0c}, { 3400, 0x0e}, {24000, 0x2e} } /* 32bpp */ -}; - -/* table for 1M Ram */ -static mach64FIFOTable GTA2_SDRAM_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x08}, - {24000, 0x08} }, /* 4 bpp */ - { { 3800, 0x04}, { 4400, 0x06}, { 6600, 0x06}, { 9000, 0x08}, - {24000, 0x0a} }, /* 8 bpp */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 555 */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0e} }, /* 565 */ - { { 2600, 0x0a}, { 3400, 0x0c}, { 4200, 0x0c}, {24000, 0x0e} }, /*24bpp*/ - { {24000, 0x08} } /* 32bpp */ -}; - -/* The fifo table for GT SDRAM of 67MHz */ -/* data was extracted from gt$9a-67.sdr */ -/* table for 2M Ram */ -static mach64FIFOTable GTA2_SDRAM_2M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x04}, { 9400, 0x06}, {11200, 0x08}, {24000, 0x08} }, /* 4bpp */ - { { 4400, 0x04}, { 6600, 0x06}, { 9400, 0x08}, {10000, 0x0a}, - {11200, 0x0c}, {14000, 0x0c}, {24000, 0x0c} }, /* 8 bpp */ - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, /* 555 */ - { { 3400, 0x06}, { 4200, 0x08}, { 5400, 0x0a}, { 6600, 0x0c}, - { 8000, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 2000, 0x08}, { 3000, 0x08}, { 3300, 0x0a}, { 4200, 0x0c}, - { 4600, 0x0c}, {24000, 0x2c} }, /* 24bpp */ - { { 3000, 0x0a}, { 3400, 0x0c}, { 3800, 0x0e}, { 5200, 0x0e} } /* 32bpp */ -}; - -/* table for 1M Ram */ -static mach64FIFOTable GTA2_SDRAM_1M_6700[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x08}, - {24000, 0x08} }, /* 4 bpp */ - { { 3800, 0x04}, { 4400, 0x06}, { 7800, 0x06}, { 9000, 0x08}, - {24000, 0x0a} }, /* 8 bpp */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, /* 555 */ - { { 3000, 0x06}, { 3400, 0x06}, { 3800, 0x08}, { 4400, 0x0a}, - { 5800, 0x0c}, {24000, 0x0c} }, /* 565 */ - { { 2000, 0x06}, { 2600, 0x06}, { 3400, 0x0a}, { 4100, 0x0c}, - {24000, 0x0e} }, /* 24bpp */ - { {24000, 0x06} } /* 32bpp */ -}; - -/*------------------------------------------------------------------*/ -/* The FIFO TABLE FOR DRAM */ -/*------------------------------------------------------------------*/ -/* The fifo table for GT DRAM of 56MHz */ -/* data was extracted from gt$9a-56.dr */ -/* table for 2M Ram */ -static mach64FIFOTable GTA2_DRAM_2M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 7600, 0x04}, {10100, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 4600, 0x04}, { 5500, 0x06}, { 5800, 0x06}, { 7600, 0x08}, - { 8200, 0x0a}, {10100, 0x0c}, {11100, 0x0e}, {12300, 0x0e}, - {24000, 0x0e} }, /* 8 bpp */ - { { 2000, 0x04}, { 2200, 0x04}, { 2600, 0x06}, { 3700, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 5700, 0x0e}, { 6600, 0x0e}, - { 8000, 0x0e}, { 24000, 0x0e} }, /* 555 */ - { { 2000, 0x04}, { 2200, 0x04}, { 2600, 0x06}, { 3700, 0x08}, - { 4600, 0x0a}, { 5200, 0x0c}, { 5700, 0x0e}, { 6600, 0x0e}, - { 8000, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 2600, 0x0a}, { 3200, 0x0c}, { 3600, 0x0c}, { 4100, 0x0c}, - { 4600, 0x0c}, {24000, 0x2c} }, /* 24bpp */ - { { 1500, 0x06}, { 2200, 0x0a}, { 2600, 0x0c}, { 3300, 0x0c}, - { 3700, 0x0c}, {24000, 0x0e} } /* 32bpp */ -}; - -/* table for 1M Ram */ -static mach64FIFOTable GTA2_DRAM_1M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7900, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 3300, 0x04}, { 4600, 0x06}, { 5500, 0x08}, { 6800, 0x0a}, - { 7900, 0x0c}, { 8100, 0x0e}, {24000, 0x0e} }, /* 8 bpp */ - { { 2600, 0x08}, { 3300, 0x0a}, { 3700, 0x0c}, { 4600, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 2600, 0x08}, { 3300, 0x0a}, { 3700, 0x0c}, { 4600, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2000, 0x0a}, { 2600, 0x0c}, {24000, 0x0e} }, /* 24bpp */ - { { 1500, 0x08}, {24000, 0x0c} } /* 32bpp */ -}; - -/*-----------------------------------------------------* - * The FIFO TABLE FOR EDO RAM * - *-----------------------------------------------------* - * The fifo table for GT EDO RAM of 63MHz * - * data was extracted from gt$9a-63.edo * - * table for 2M Ram */ -static mach64FIFOTable GTA2_EDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 7600, 0x04}, {10200, 0x06}, {24000, 0x0a} }, /* 4bpp*/ - { { 4100, 0x04}, { 5200, 0x06}, { 5600, 0x08}, { 7600, 0x08}, - { 9400, 0x0a}, {10000, 0x0c}, {11300, 0x0e}, {13000, 0x0e}, - {24000, 0x0e} }, /* 8 bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2700, 0x0a}, { 3300, 0x0c}, { 3900, 0x0c}, { 4600, 0x0c}, - { 5200, 0x0e}, {24000, 0x0e} }, /*24bpp */ - { { 2200, 0x0a}, { 2700, 0x0c}, { 3300, 0x0c}, { 3700, 0x0e}, - {24000, 0x0e} } /* 32bpp */ -}; - -/*table for 1M Ram*/ -static mach64FIFOTable GTA2_EDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3300, 0x04}, { 3800, 0x06}, - { 4800, 0x08}, { 6800, 0x0a}, { 9000, 0x0c}, {24000, 0x0e} }, /* 8bpp */ - { { 2600, 0x08}, { 3300, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, - { 5200, 0x0c}, {24000, 0x0c} }, /* 555 */ - { { 2600, 0x08}, { 3300, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, - { 5200, 0x0c}, {24000, 0x0c} }, /* 565 */ - { { 2400, 0x0a}, { 3000, 0x0c}, {24000, 0x0c} }, /* 24bpp */ - { { 1500, 0x08}, {24000, 0x0c} } /* 32bpp */ -}; - -/* The fifo table for GT DRAM of 67MHz */ -/* data was extracted from gt$9a-67.edo */ -/* table for 2M Ram */ -static mach64FIFOTable GTA2_EDO_2M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, /* 4bpp */ - { { 4600, 0x04}, { 5600, 0x06}, { 7000, 0x06}, { 9400, 0x08}, - {10000, 0x0a}, {11300, 0x0c}, {14000, 0x0c}, {24000, 0x0e} }, /* 8 bpp*/ - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, /* 555 */ - { { 2000, 0x06}, { 3400, 0x06}, { 4200, 0x08}, { 5500, 0x0a}, - { 6600, 0x0c}, { 7000, 0x0c}, { 7600, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 2000, 0x08}, { 3400, 0x0a}, { 3800, 0x0a}, { 4200, 0x0a}, - { 4500, 0x0c}, { 5200, 0x0c}, {24000, 0x2c} }, /*24bpp*/ - { { 2000, 0x0a}, { 3000, 0x0a}, { 3500, 0x0c}, { 4200, 0x0e}, - {24000, 0x2a} } /* 32bpp */ -}; - -/*table for 1M Ram*/ -static mach64FIFOTable GTA2_EDO_1M_6700_6[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { {3800, 0x02}, {5200, 0x04}, {7600, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { {3000, 0x04}, {3800, 0x04}, {5400, 0x06}, {7700, 0x0a}, - {9000, 0x0a}, {10500, 0x0c}, {24000, 0x0e} }, /* 8 bpp */ - { {2000, 0x06}, {3000, 0x06}, {3800, 0x08}, {4400, 0x0a}, - {4800, 0x0c}, {24000, 0x0e} }, /* 555 */ - { {2000, 0x06}, {3000, 0x06}, {3800, 0x08}, {4400, 0x0a}, - {4800, 0x0c}, {24000, 0x0e} }, /* 565 */ - { {2000, 0x0a}, {3000, 0x0a}, {3400, 0x0c}, {24000, 0x0e} }, /*24bpp*/ - { {24000, 0x06} } /* 32bpp */ -}; - - -/* The fifo table for GT EDO RAM of 67MHz * - * data was extracted from gt$9a-67.ed7 * - * table for 2M Ram */ -static mach64FIFOTable GTA2_EDO_2M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x02}, { 7000, 0x04}, {10200, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 5200, 0x06}, { 6400, 0x08}, { 7000, 0x0a}, { 7900, 0x0c}, - { 8200, 0x0c}, {10800, 0x0c}, {13000, 0x0c}, {24000, 0x0c} }, /* 8bpp */ - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0a}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, /* 555 */ - { { 3000, 0x06}, { 3800, 0x08}, { 4200, 0x0a}, { 5200, 0x0a}, - { 6600, 0x0c}, { 7600, 0x0c}, { 8200, 0x0c}, {24000, 0x0e} }, /* 565 */ - { { 3000, 0x0a}, { 3400, 0x0a}, { 3600, 0x0a}, { 4400, 0x0c}, - { 5200, 0x0c} }, /* 24bpp */ - { { 3400, 0x0c}, { 5200, 0x0c} } /* 32bpp */ -}; - -/*table for 1M Ram */ -static mach64FIFOTable GTA2_EDO_1M_6700_7[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4200, 0x04}, { 6400, 0x06}, { 9000, 0x0a}, {24000, 0x0c} }, /* 4bpp */ - { { 3800, 0x08}, { 6400, 0x0a}, { 7000, 0x0c}, { 9000, 0x0c}, - {24000, 0x0c} }, /* 8 bpp */ - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, /* 555 */ - { { 3800, 0x0a}, { 4800, 0x0c}, { 5600, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 3400, 0x0c}, {24000, 0x0e} }, /*24bpp */ - { {24000, 0x06} } /* 32bpp */ -}; - -/*-----------------------------------------------------* - * The FIFO TABLE FOR PSEUDO EDO RAM * - *-----------------------------------------------------* - * The fifo table for GT PSEUDO EDO RAM of 56MHz * - * data was extracted from gt$9a-56.pdo */ - -/*table for 2M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_2M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 7600, 0x04}, {10200, 0x06}, {24000, 0x0a} }, /* 4bpp*/ - { { 4100, 0x04}, { 5200, 0x06}, { 5600, 0x08}, { 7300, 0x08}, - { 9400, 0x0a}, {10000, 0x0c}, {11300, 0x0e}, {12600, 0x0e}, - {24000, 0x0e} }, /* 8 bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2700, 0x0a}, { 3300, 0x0c}, { 3900, 0x0c}, { 4600, 0x0c}, - {24000, 0x0e} }, /*24bpp*/ - { { 2200, 0x0a}, { 2700, 0x0c}, { 3300, 0x0c}, { 3700, 0x0e}, - {24000, 0x0e} } /* 32bpp */ -}; - -/*Table for 1M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_1M_5600[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3300, 0x04}, { 3800, 0x06}, - { 4800, 0x08}, { 6800, 0x0a}, {24000, 0x0e} }, /* 8 bpp */ - { { 2600, 0x08}, { 3300, 0x0a}, { 3900, 0x0c}, { 4400, 0x0e}, - { 4800, 0x0c}, {24000, 0x0c} }, /* 555 */ - { { 2600, 0x08}, { 3300, 0x0a}, { 3900, 0x0c}, { 4400, 0x0e}, - { 4800, 0x0c}, {24000, 0x0c} }, /* 565 */ - { { 2000, 0x0a}, { 3000, 0x0c}, {24000, 0x0e} }, /*24bpp*/ - { { 1500, 0x08}, {24000, 0x0e} } /* 32bpp */ -}; - - -/* The fifo table for GT PSEUDO EDO RAM of 58MHz * - * data was extracted from gt$9a-58.pdo */ - -/*table for 2M Ram */ -static mach64FIFOTable GTA2_PSEUDO_2M_5800[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 7600, 0x04}, {10200, 0x06}, {24000, 0x0a} }, /* 4bpp*/ - { { 4100, 0x04}, { 5200, 0x06}, { 5600, 0x08}, { 7500, 0x08}, - { 9400, 0x0a}, {10000, 0x0c}, {11300, 0x0e}, {12600, 0x0e}, - {24000, 0x0e} }, /* 8 bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3700, 0x08}, { 4600, 0x0a}, - { 5200, 0x0c}, { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2700, 0x0a}, { 3300, 0x0c}, { 3900, 0x0c}, { 4600, 0x0c}, - {24000, 0x0e} }, /*24bpp*/ - { { 2200, 0x0a}, { 2700, 0x0c}, { 3300, 0x0c}, { 3700, 0x0e}, - {24000, 0x0e} } /* 32bpp */ -}; - -/*table for 1M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_1M_5800[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 2400, 0x06}, { 2600, 0x0a}, { 3300, 0x04}, { 3800, 0x06}, - { 4800, 0x08}, { 6800, 0x0a}, { 9000, 0x0c}, {24000, 0x0e} }, /* 8 bpp */ - { { 2600, 0x08}, { 3300, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, - { 5200, 0x0c}, {24000, 0x0c} }, /* 555 */ - { { 2600, 0x08}, { 3300, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, - { 5200, 0x0c}, {24000, 0x0c} }, /* 565 */ - { { 2400, 0x0a}, { 3000, 0x0c}, {24000, 0x0c} }, /*24bpp */ - { { 1500, 0x08}, {24000, 0x0c} } /* 32bpp */ -}; - -/* The fifo table for GT PSEUDO EDO RAM of 60MHz * - * data was extracted from gt$9a-60.pdo */ - -/*table for 2M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_2M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 9400, 0x04}, {11200, 0x06}, {24000, 0x08} }, /* 4bpp*/ - { { 3000, 0x04}, { 3300, 0x06}, { 4600, 0x04}, { 5600, 0x06}, - { 5800, 0x06}, { 7900, 0x08}, { 8200, 0x0a}, {11300, 0x0c}, - {13000, 0x0c}, {14000, 0x0c}, {24000, 0x0e} }, /* 8 bpp */ - { { 2400, 0x06}, { 2600, 0x08}, { 4100, 0x08}, { 4600, 0x0a}, - { 5500, 0x0c}, { 5700, 0x0e}, { 6600, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 2400, 0x06}, { 2600, 0x08}, { 4100, 0x08}, { 4600, 0x0a}, - { 5500, 0x0c}, { 5700, 0x0e}, { 6600, 0x0e}, { 7900, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2000, 0x08}, { 2600, 0x0a}, { 3300, 0x0c}, { 4000, 0x0c}, - { 4500, 0x26}, { 5200, 0x28}, {24000, 0x2a} }, /*24bpp*/ - { { 2000, 0x0a}, { 2200, 0x0c}, { 2600, 0x0c}, { 3300, 0x0e}, - { 4200, 0x0e}, {24000, 0x2a} } /* 32bpp */ -}; - -/*table for 1M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_1M_6000[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x02}, { 5200, 0x04}, { 7600, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 2400, 0x04}, { 3000, 0x06}, { 3300, 0x06}, { 4600, 0x0a}, - { 5200, 0x08}, { 6800, 0x0a}, { 8200, 0x0c}, {10100, 0x0e}, - {24000, 0x0e} }, /* 8 bpp */ - { { 1500, 0x0a}, { 2000, 0x08}, { 2400, 0x0a}, { 2600, 0x08}, - { 3700, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, { 5200, 0x0e}, - {24000, 0x0e} }, /* 555 */ - { { 1500, 0x0a}, { 2000, 0x08}, { 2400, 0x0a}, { 2600, 0x08}, - { 3700, 0x0a}, { 4100, 0x0c}, { 4600, 0x0e}, { 5200, 0x0e}, - {24000, 0x0e} }, /* 565 */ - { { 2000, 0x0a}, { 2200, 0x0c}, { 2600, 0x0c}, { 3300, 0x0c}, - {24000, 0x0e} }, /*24bpp*/ - { { 2000, 0x0c}, {24000, 0x0c} } /* 32bpp */ -}; - -/* The fifo table for GT PSEUDO EDO RAM of 60MHz * - * data was extracted from gt$9a-63.pdo */ - -/*table for 2M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_2M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 4600, 0x02}, { 7600, 0x04}, {10200, 0x06}, {24000, 0x0a} }, /* 4bpp */ - { { 4600, 0x04}, { 5600, 0x06}, { 7600, 0x08}, { 9400, 0x0a}, - {10000, 0x0c}, {11300, 0x0e}, {13000, 0x0e}, {24000, 0x0e} }, /* 8 bpp*/ - { { 2400, 0x06}, { 3700, 0x08}, { 4600, 0x0a}, { 5200, 0x0c}, - { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, /* 555 */ - { { 2400, 0x06}, { 3700, 0x08}, { 4600, 0x0a}, { 5200, 0x0c}, - { 5800, 0x0e}, { 6900, 0x0e}, { 7900, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 2700, 0x0a}, { 3300, 0x0c}, { 3900, 0x0c}, { 4600, 0x0c}, - { 5200, 0x0e}, {24000, 0x0e} }, /*24bpp */ - { { 2200, 0x0a}, { 2700, 0x0c}, { 3300, 0x0c}, { 3700, 0x0e}, - {24000, 0x0e} } /* 32bpp */ -}; - -/*table for 1M Ram*/ -static mach64FIFOTable GTA2_PSEUDO_1M_6300[MAX_CDEPTH][MAX_DOTCLOCKS] = -{ { { 3800, 0x04}, { 5200, 0x04}, { 7600, 0x06}, { 8000, 0x0a}, - {24000, 0x0a} }, /* 4bpp*/ - { { 3800, 0x06}, { 4800, 0x08}, { 5800, 0x0a}, { 6800, 0x0a}, - { 9000, 0x0c}, {24000, 0x0e} }, /* 8 bpp */ - { { 3000, 0x08}, { 3400, 0x0a}, { 3800, 0x0e}, { 4400, 0x0e}, - { 5800, 0x0e}, {24000, 0x0e} }, /* 555 */ - { { 3000, 0x08}, { 3400, 0x0a}, { 3800, 0x0e}, { 4400, 0x0e}, - { 5800, 0x0e}, {24000, 0x0e} }, /* 565 */ - { { 2400, 0x0a}, { 3000, 0x0c}, { 3400, 0x0c}, {24000, 0x0c} }, /*24bpp*/ - { { 3400, 0x0c}, {24000, 0x0e} } /* 32bpp */ -}; - - -/* - * mach64FIFOdepthDefault -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthDefault(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int fifo_depth; - int index; - - fifo_depth = clock/100; - - switch (cdepth) { - case CRTC_PIX_WIDTH_15BPP: - case CRTC_PIX_WIDTH_16BPP: - fifo_depth <<= 1; - index = 1*6; - break; - case CRTC_PIX_WIDTH_24BPP: - fifo_depth = (fifo_depth << 1) + fifo_depth; - index = 2*6; - break; - case CRTC_PIX_WIDTH_32BPP: - fifo_depth <<= 2; - index = 3*6; - break; - default: - index = 0*6; - break; - } - - if (si->Mem_Size <= MEM_SIZE_1M) { - if (si->Mem_Size == MEM_SIZE_1M) index += 2; - fifo_depth /= 6; - } else { - index += 4; - fifo_depth /= 12; - } - - if (fifo_depth < defaultFIFOVals[index]) - fifo_depth = defaultFIFOVals[index]; - if (fifo_depth > defaultFIFOVals[index+1]) - fifo_depth = defaultFIFOVals[index+1]; - - return(fifo_depth); -} - - -/* - * mach64FIFOdepthVTA3 -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthVTA3(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int i, cdepth_index = (cdepth >> 8) - 1; - mach64FIFOTable *pFIFOTable; - - switch (si->Mem_Type) { - case SDRAM: - if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_SDRAM_1M_6000[cdepth_index][0]; - else - pFIFOTable = &VTA3_SDRAM_2M_6000[cdepth_index][0]; - } else if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_SDRAM_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA3_SDRAM_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_SDRAM_1M_6700[cdepth_index][0]; - else - pFIFOTable = &VTA3_SDRAM_2M_6700[cdepth_index][0]; - } - break; - case EDO_DRAM: - if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_EDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA3_EDO_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->MemCycle <= 6) { /* 6 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_EDO_1M_6700_6[cdepth_index][0]; - else - pFIFOTable = &VTA3_EDO_2M_6700_6[cdepth_index][0]; - } else { /* 7 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_EDO_1M_6700_7[cdepth_index][0]; - else - pFIFOTable = &VTA3_EDO_2M_6700_7[cdepth_index][0]; - } - } - break; - case PSEUDO_EDO: - if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_PSEUDO_1M_6000[cdepth_index][0]; - else - pFIFOTable = &VTA3_PSEUDO_2M_6000[cdepth_index][0]; - } else { /* 63MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_PSEUDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA3_PSEUDO_2M_6300[cdepth_index][0]; - } - break; - default: /* DRAM */ - if (si->DRAMMemClk >= 5200 && si->DRAMMemClk < 5600) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_DRAM_1M_5200[cdepth_index][0]; - else - pFIFOTable = &VTA3_DRAM_2M_5200[cdepth_index][0]; - } else { /* 63MHz and up */ - if (si->DRAMMemClk < 5650) { - switch (cdepth) { - case CRTC_PIX_WIDTH_15BPP: - case CRTC_PIX_WIDTH_16BPP: - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (VTA3_DRAM_2M_5600[cdepth_index][i].dotclock == 7000) - VTA3_DRAM_2M_5600[cdepth_index][i].dotclock = 7600; - break; - case CRTC_PIX_WIDTH_24BPP: - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (VTA3_DRAM_1M_5600[cdepth_index][i].dotclock == 3000) - VTA3_DRAM_1M_5600[cdepth_index][i].fifo_val = 0x0c; - break; - default: /* Table is fine as is */ - break; - } - } - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA3_DRAM_1M_5600[cdepth_index][0]; - else - pFIFOTable = &VTA3_DRAM_2M_5600[cdepth_index][0]; - } - break; - } - - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (clock <= (pFIFOTable+i)->dotclock) - return (pFIFOTable+i)->fifo_val; - - return 0; -} - - -/* - * mach64FIFOdepthVTA4 -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthVTA4(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int i, cdepth_index = (cdepth >> 8) - 1; - mach64FIFOTable *pFIFOTable; - - switch (si->Mem_Type) { - case SDRAM: - if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_SDRAM_1M_6000[cdepth_index][0]; - else - pFIFOTable = &VTA4_SDRAM_2M_6000[cdepth_index][0]; - } else if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_SDRAM_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA4_SDRAM_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_SDRAM_1M_6700[cdepth_index][0]; - else - pFIFOTable = &VTA4_SDRAM_2M_6700[cdepth_index][0]; - } - break; - case EDO_DRAM: - if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_EDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA4_EDO_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->MemCycle <= 6) { /* 6 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_EDO_1M_6700_6[cdepth_index][0]; - else - pFIFOTable = &VTA4_EDO_2M_6700_6[cdepth_index][0]; - } else { /* 7 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_EDO_1M_6700_7[cdepth_index][0]; - else - pFIFOTable = &VTA4_EDO_2M_6700_7[cdepth_index][0]; - } - } - break; - case PSEUDO_EDO: - if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_PSEUDO_1M_6000[cdepth_index][0]; - else - pFIFOTable = &VTA4_PSEUDO_2M_6000[cdepth_index][0]; - } else { /* 63MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_PSEUDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = &VTA4_PSEUDO_2M_6300[cdepth_index][0]; - } - break; - default: /* DRAM */ - if (si->DRAMMemClk >= 5200 && si->DRAMMemClk < 5600) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_DRAM_1M_5200[cdepth_index][0]; - else - pFIFOTable = &VTA4_DRAM_2M_5200[cdepth_index][0]; - } else { /* 63MHz and up */ - if (si->DRAMMemClk < 5650) { - switch (cdepth) { - case CRTC_PIX_WIDTH_15BPP: - case CRTC_PIX_WIDTH_16BPP: - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (VTA4_DRAM_2M_5600[cdepth_index][i].dotclock == 7000) - VTA4_DRAM_2M_5600[cdepth_index][i].dotclock = 7600; - break; - case CRTC_PIX_WIDTH_24BPP: - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (VTA4_DRAM_1M_5600[cdepth_index][i].dotclock == 3000) - VTA4_DRAM_1M_5600[cdepth_index][i].fifo_val = 0x0c; - break; - default: /* Table is fine as is */ - break; - } - } - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &VTA4_DRAM_1M_5600[cdepth_index][0]; - else - pFIFOTable = &VTA4_DRAM_2M_5600[cdepth_index][0]; - } - break; - } - - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (clock <= (pFIFOTable+i)->dotclock) - return (pFIFOTable+i)->fifo_val; - - return 0; -} - - -/* - * mach64FIFOdepthGT -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthGT(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int i, cdepth_index = (cdepth >> 8) - 1; - mach64FIFOTable *pFIFOTable; - - switch (si->Mem_Type) { - case SDRAM: - if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_SDRAM_1M_6000[cdepth_index][0]; - else - pFIFOTable = >A2_SDRAM_2M_6000[cdepth_index][0]; - } else if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_SDRAM_1M_6300[cdepth_index][0]; - else - pFIFOTable = >A2_SDRAM_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_SDRAM_1M_6700[cdepth_index][0]; - else - pFIFOTable = >A2_SDRAM_2M_6700[cdepth_index][0]; - } - break; - case EDO_DRAM: - if (si->DRAMMemClk >= 6300 && si->DRAMMemClk < 6700) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_EDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = >A2_EDO_2M_6300[cdepth_index][0]; - } else { /* 67MHz and up */ - if (si->MemCycle <= 6) { /* 6 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_EDO_1M_6700_6[cdepth_index][0]; - else - pFIFOTable = >A2_EDO_2M_6700_6[cdepth_index][0]; - } else { /* 7 cycles */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_EDO_1M_6700_7[cdepth_index][0]; - else - pFIFOTable = >A2_EDO_2M_6700_7[cdepth_index][0]; - } - } - break; - case PSEUDO_EDO: - if (si->DRAMMemClk >= 5600 && si->DRAMMemClk < 5800) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_PSEUDO_1M_5600[cdepth_index][0]; - else - pFIFOTable = >A2_PSEUDO_2M_5600[cdepth_index][0]; - } else if (si->DRAMMemClk >= 5800 && si->DRAMMemClk < 6000) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_PSEUDO_1M_5800[cdepth_index][0]; - else - pFIFOTable = >A2_PSEUDO_2M_5800[cdepth_index][0]; - } else if (si->DRAMMemClk >= 6000 && si->DRAMMemClk < 6300) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_PSEUDO_1M_6000[cdepth_index][0]; - else - pFIFOTable = >A2_PSEUDO_2M_6000[cdepth_index][0]; - } else { /* 63MHz and up */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_PSEUDO_1M_6300[cdepth_index][0]; - else - pFIFOTable = >A2_PSEUDO_2M_6300[cdepth_index][0]; - } - break; - default: /* DRAM */ - /* Default to 56MHz */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = >A2_DRAM_1M_5600[cdepth_index][0]; - else - pFIFOTable = >A2_DRAM_2M_5600[cdepth_index][0]; - break; - } - - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (clock <= (pFIFOTable+i)->dotclock) - return (pFIFOTable+i)->fifo_val; - - return 0; -} - - -/* - * mach64FIFOdepthCT -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthCT(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int fifo_depth; - int index; - - fifo_depth = clock/100; - - switch (cdepth) { - case CRTC_PIX_WIDTH_15BPP: - case CRTC_PIX_WIDTH_16BPP: - fifo_depth <<= 1; - index = 1*6; - break; - case CRTC_PIX_WIDTH_24BPP: - fifo_depth = (fifo_depth << 1) + fifo_depth; - index = 2*6; - break; - case CRTC_PIX_WIDTH_32BPP: - fifo_depth <<= 2; - index = 3*6; - break; - default: - index = 0*6; - break; - } - - if (si->Mem_Size <= MEM_SIZE_1M) { - if (si->Mem_Size == MEM_SIZE_1M) index += 2; - fifo_depth /= 6; - } else { - index += 4; - fifo_depth /= 10; - } - - if (width <= 640) - index += 0; - else if (width <= 800) - index += 1*6*4; - else if (width <= 1024) - index += 2*6*4; - else - index += 3*6*4; - - if (fifo_depth < CT_FIFOVals[index]) - fifo_depth = CT_FIFOVals[index]; - if (fifo_depth > CT_FIFOVals[index+1]) - fifo_depth = CT_FIFOVals[index+1]; - - return(fifo_depth); -} - - -/* - * mach64FIFOdepthCTD -- - * Calculates the correct FIFO depth for the Mach64 depending on the - * color depth and clock selected. - */ -int mach64FIFOdepthCTD(cdepth, clock, width) - int cdepth; - int clock; - int width; -{ - int i, cdepth_index = (cdepth >> 8) - 1; - mach64FIFOTable *pFIFOTable; - - if (si->DRAMMemClk >= 5600) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &CTD_DRAM_1M_5600[cdepth_index][0]; - else - pFIFOTable = &CTD_DRAM_2M_5600[cdepth_index][0]; - } else if (si->DRAMMemClk >= 5400) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &CTD_DRAM_1M_5400[cdepth_index][0]; - else - pFIFOTable = &CTD_DRAM_2M_5400[cdepth_index][0]; - } else if (si->DRAMMemClk > 4900) { - if (si->DRAMMemClk <= 5000 && si->Mem_Size <= MEM_SIZE_1M && - (cdepth == CRTC_PIX_WIDTH_15BPP || - cdepth == CRTC_PIX_WIDTH_16BPP)) { - for (i = 0; i < MAX_DOTCLOCKS; i++) { - if (CTD_DRAM_1M_5100[cdepth_index][i].dotclock == 5100) - CTD_DRAM_1M_5100[cdepth_index][i].dotclock = 5000; - if (CTD_DRAM_1M_5100[cdepth_index][i].dotclock == 5500 || - CTD_DRAM_1M_5100[cdepth_index][i].dotclock == 14000) { - CTD_DRAM_1M_5100[cdepth_index][i].dotclock = 5200; - CTD_DRAM_1M_5100[cdepth_index][i].fifo_val = 0x10; - } - } - } - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &CTD_DRAM_1M_5100[cdepth_index][0]; - else - pFIFOTable = &CTD_DRAM_2M_5100[cdepth_index][0]; - } else if (si->DRAMMemClk >= 4800) { - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &CTD_DRAM_1M_4900[cdepth_index][0]; - else - pFIFOTable = &CTD_DRAM_2M_4900[cdepth_index][0]; - } else { /* <= 48MHz */ - if (si->Mem_Size <= MEM_SIZE_1M) - pFIFOTable = &CTD_DRAM_1M_4600[cdepth_index][0]; - else - pFIFOTable = &CTD_DRAM_2M_4600[cdepth_index][0]; - } - - for (i = 0; i < MAX_DOTCLOCKS; i++) - if (clock <= (pFIFOTable+i)->dotclock) - return (pFIFOTable+i)->fifo_val; - - return 0; -} diff --git a/src/add-ons/accelerants/atimach64/Mach64fifo.h b/src/add-ons/accelerants/atimach64/Mach64fifo.h deleted file mode 100644 index 707572cac3..0000000000 --- a/src/add-ons/accelerants/atimach64/Mach64fifo.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $XConsortium: mach64fifo.h /main/1 1996/10/27 18:06:29 kaleb $ */ -/* - * Copyright 1996 by Kevin E. Martin, Chapel Hill, North Carolina. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of Kevin - * E. Martin not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Kevin E. Martin makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/mach64/mach64fifo.h,v 3.1 1996/12/27 06:55:52 dawes Exp $ */ - -extern int mach64FIFOdepthDefault( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); - -extern int mach64FIFOdepthVTA3( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); - -extern int mach64FIFOdepthVTA4( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); - -extern int mach64FIFOdepthGT( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); - -extern int mach64FIFOdepthCT( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); - -extern int mach64FIFOdepthCTD( -#if NeedFunctionPrototypes - int cdepth, - int clock, - int width -#endif -); diff --git a/src/add-ons/accelerants/atimach64/ProposeDisplayMode.c b/src/add-ons/accelerants/atimach64/ProposeDisplayMode.c deleted file mode 100644 index 6ce76541e2..0000000000 --- a/src/add-ons/accelerants/atimach64/ProposeDisplayMode.c +++ /dev/null @@ -1,399 +0,0 @@ -#include - -#include "GlobalData.h" -#include "generic.h" - - -#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC) -#define MODE_FLAGS (B_SCROLL | B_8_BIT_DAC | B_HARDWARE_CURSOR | B_PARALLEL_ACCESS) -#define MODE_COUNT (sizeof (mode_list) / sizeof (display_mode)) - -static const display_mode mode_list[] = { -{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */ -{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */ -{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */ -{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */ -{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */ -{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */ -{ { 38100, 800, 832, 960, 1088, 600, 602, 606, 620, 0}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* SVGA_800X600X56HzNI */ -{ { 40000, 800, 840, 968, 1056, 600, 601, 605, 628, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */ -{ { 49500, 800, 816, 896, 1056, 600, 601, 604, 625, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(800X600X8.Z1) */ -{ { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(800X600X8.Z1) */ -{ { 56250, 800, 832, 896, 1048, 600, 601, 604, 631, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(800X600X8.Z1) */ -{ { 65000, 1024, 1048, 1184, 1344, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1024X768X8.Z1) */ -{ { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(1024X768X8.Z1) */ -{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */ -{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */ -{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */ -{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */ -{ { 121500, 1152, 1216, 1344, 1568, 864, 865, 868, 911, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1152X864X8.Z1) */ -{ { 108000, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X1024X8.Z1) */ -{ { 135000, 1280, 1296, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1280X1024X8.Z1) */ -{ { 157500, 1280, 1344, 1504, 1728, 1024, 1025, 1028, 1072, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X1024X8.Z1) */ -{ { 162000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1600X1200X8.Z1) */ -{ { 175500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@65Hz_(1600X1200X8.Z1) */ -{ { 189000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1600X1200X8.Z1) */ -{ { 202500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1600X1200X8.Z1) */ -{ { 216000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@80Hz_(1600X1200X8.Z1) */ -{ { 229500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(1600X1200X8.Z1) */ -}; - - -/* create a mask of one "bits" bits wide */ -#define MASKFROMWIDTH(bits) ((1 << bits) - 1) - -/* - Validate a target display mode is both - a) a valid display mode for this device and - b) falls between the contraints imposed by "low" and "high" - - If the mode is not (or cannot) be made valid for this device, return B_ERROR. - If a valid mode can be constructed, but it does not fall within the limits, - return B_BAD_VALUE. - If the mode is both valid AND falls within the limits, return B_OK. -*/ -status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const display_mode *high) { - - const uint16 h_display_bits = MASKFROMWIDTH(8); - const uint16 h_sync_bits = MASKFROMWIDTH(5); - const uint16 h_total_bits = MASKFROMWIDTH(9); - const uint16 v_display_bits = MASKFROMWIDTH(11); - const uint16 v_sync_bits = MASKFROMWIDTH(5); - const uint16 v_total_bits = MASKFROMWIDTH(11); - - int i, color_depth; - - int mach64CDepths [] = { -1, 4, 8, 15, 16, 24, 32, -1 }; - - status_t - result = B_ERROR; - uint32 - row_bytes, - limit_clock; - double - target_refresh = ((double)target->timing.pixel_clock * 1000.0) / ((double)target->timing.h_total * (double)target->timing.v_total); - bool - want_same_width = target->timing.h_display == target->virtual_width, - want_same_height = target->timing.v_display == target->virtual_height; - - /* - NOTE: - Different devices provide different levels of control over the various CRTC values. - This code should be used as a *GUIDELINE ONLY*. The device you're controling may - have very different constraints, and the code below may be insufficient to insure - that a particular display_mode is valid for your device. You would do well to - spend quite a bit of time ensuring that you understand the limitations of your - device, as setting these values incorrectly can create a display_mode that could - turn your monitor into a useless slag of molten components, burn up your card, - lock up the PCI bus, cause partialy or multiply repeating display images, or - otherwise look just plain wierd. Honest. - */ - /* - NOTE: - This code doesn't explicitly support interlaced video modes. - */ - - /* validate horizontal timings */ - { - /* for most devices, horizontal parameters must be multiples of 8 */ - uint16 h_display = target->timing.h_display >> 3; - uint16 h_sync_start = target->timing.h_sync_start >> 3; - uint16 h_sync_end = target->timing.h_sync_end >> 3; - uint16 h_total = target->timing.h_total >> 3; - - /* ensure reasonable minium display and sequential order of parms */ - - if (h_display < (320 >> 3)) h_display = 320 >> 3; - if (h_display > (2048 >> 3)) h_display = 2048 >> 3; - if (h_sync_start < (h_display + 2)) h_sync_start = h_display + 2; - if (h_sync_end < (h_sync_start + 3)) h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/ - - if (h_total < (h_sync_end + 1)) h_total = h_sync_end + 1; - /* adjust for register limitations: */ - /* h_total is 9 bits */ - - if (h_total > h_total_bits) h_total = h_total_bits; - /* h_display is 8 bits - handled above */ - /* h_sync_start is 9 bits */ - /* h_sync_width is 5 bits */ - if ((h_sync_end - h_sync_start) > h_sync_bits) h_sync_end = h_sync_start + h_sync_bits; - - /* shift back to the full width values */ - - target->timing.h_display = h_display << 3; - target->timing.h_sync_start = h_sync_start << 3; - target->timing.h_sync_end = h_sync_end << 3; - target->timing.h_total = h_total << 3; - } - - /* did we fall out of one of the limits? */ - - if ( - (target->timing.h_display < low->timing.h_display) || - (target->timing.h_display > high->timing.h_display) || - (target->timing.h_sync_start < low->timing.h_sync_start) || - (target->timing.h_sync_start > high->timing.h_sync_start) || - (target->timing.h_sync_end < low->timing.h_sync_end) || - (target->timing.h_sync_end > high->timing.h_sync_end) || - (target->timing.h_total < low->timing.h_total) || - (target->timing.h_total > high->timing.h_total) - ) result = B_BAD_VALUE; - - - /* validate vertical timings */ - - { - uint16 v_display = target->timing.v_display; - uint16 v_sync_start = target->timing.v_sync_start; - uint16 v_sync_end = target->timing.v_sync_end; - uint16 v_total = target->timing.v_total; - - /* ensure reasonable minium display and sequential order of parms */ - /* v_display is 11 bits */ - /* v_total is 11 bits */ - /* v_sync_start is 11 bits */ - /* v_sync_width is 5 bits */ - - if (v_display < 200) v_display = 200; - if (v_display > (v_display_bits - 5)) v_display = (v_display_bits - 5); /* leave room for the sync pulse */ - if (v_sync_start < (v_display + 1)) v_sync_start = v_display + 1; - if (v_sync_end < v_sync_start) v_sync_end = v_sync_start + 3; - if (v_total < (v_sync_end + 1)) v_total = v_sync_end + 1; - /* adjust for register limitations */ - - if ((v_sync_end - v_sync_start) > v_sync_bits) v_sync_end = v_sync_start + v_sync_bits; - target->timing.v_display = v_display; - target->timing.v_sync_start = v_sync_start; - target->timing.v_sync_end = v_sync_end; - target->timing.v_total = v_total; - } - - /* did we fall out of one of the limits? */ - - if ( - (target->timing.v_display < low->timing.v_display) || - (target->timing.v_display > high->timing.v_display) || - (target->timing.v_sync_start < low->timing.v_sync_start) || - (target->timing.v_sync_start > high->timing.h_sync_start) || - (target->timing.v_sync_end < low->timing.v_sync_end) || - (target->timing.v_sync_end > high->timing.v_sync_end) || - (target->timing.v_total < low->timing.v_total) || - (target->timing.v_total > high->timing.v_total) - ) result = B_BAD_VALUE; - - /* adjust pixel clock for DAC limits and target refresh rate */ - /* - We're re-calcuating the pixel_clock here because we might have - changed the h/v totals above. If we didn't change anything - the calculation is wasted, but it's no big deal. - */ - target->timing.pixel_clock = target_refresh * ((double)target->timing.h_total) * ((double)target->timing.v_total) / 1000.0 + .5; - - /* - Select the maximum pixel clock based on the color space. Your - device may have other constraints. In this sample driver, we - calculated the maximum pixel clock for this device in the - initialization code. - This is also a convienient place to determine the number of bytes - per pixel for a later display pitch calculation. - */ - switch (target->space & 0x0fff) { - case B_CMAP8: - limit_clock = si->pix_clk_max8; - row_bytes = 1; - color_depth = 8; - break; - case B_RGB15: - case B_RGB16: - limit_clock = si->pix_clk_max16; - row_bytes = 2; - color_depth = 16; - break; - case B_RGB32: - limit_clock = si->pix_clk_max32; - row_bytes = 4; - color_depth = 32; - break; - default: - /* no amount of adjusting will fix not being able to support the pixel format */ - return B_ERROR; - } - /* make sure we don't generate more pixel bandwidth than the device can handle */ - - if (target->timing.pixel_clock > limit_clock) target->timing.pixel_clock = limit_clock; - /* we probably ought to check against too low of a pixel rate, but I'm lazy */ - - /* note if we fell outside the limits */ - if ( - (target->timing.pixel_clock < low->timing.pixel_clock) || - (target->timing.pixel_clock > high->timing.pixel_clock) - ) return B_ERROR; - - /* validate display vs. virtual */ - - if ((target->timing.h_display > target->virtual_width) || want_same_width) - target->virtual_width = target->timing.h_display; - if ((target->timing.v_display > target->virtual_height) || want_same_height) - target->virtual_height = target->timing.v_display; - if (target->virtual_width > 2048) - target->virtual_width = 2048; - - /* adjust virtual width for engine limitations */ - - target->virtual_width = (target->virtual_width + 7) & ~7; - if ( - (target->virtual_width < low->virtual_width) || - (target->virtual_width > high->virtual_width) - ) result = B_BAD_VALUE; - - /* calculate rowbytes after we've nailed the virtual width */ - - row_bytes *= target->virtual_width; - - /* memory requirement for frame buffer */ - - if ((row_bytes * target->virtual_height) > si->mem_size) - target->virtual_height = si->mem_size / row_bytes; - - if (target->virtual_height > 2048) - target->virtual_height = 2048; - - - if (target->virtual_height < target->timing.v_display){ - /* not enough frame buffer memory for the mode */ - return B_ERROR;} - else if ( - (target->virtual_height < low->virtual_height) || - (target->virtual_height > high->virtual_height) - ) result = B_BAD_VALUE; - - /* - Bit Flag Encoding - - The way the bit flags works is as follows: - - low high meaning - --- ---- ------- - 0 0 Feature must NOT be enabled - 0 1 Feature MAY be enabled, prefered enabled - 1 0 Feature MAY be enabled, prefered disabled - 1 1 Feature MUST be enabled - - */ - /* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */ - - /* Look to see if there if the mode is doable */ - if (result != B_BAD_VALUE) - for(i = 0; si->Freq_Table[i].h_disp != 0; i++) { - - if ((si->Freq_Table[i].h_disp << 3 >= target->timing.h_display) && - (si->Freq_Table[i].dacmask >= si->DAC_SubType) && - (si->Freq_Table[i].max_dot_clock >= (target->timing.pixel_clock / 1000.0)) && - (mach64CDepths[si->Freq_Table[i].color_depth & 0x07] >= color_depth)){ - result = B_OK; - break; - } - } - - return result; - -} - -/* - Return the number of modes this device will return from GET_MODE_LIST(). -*/ -uint32 ACCELERANT_MODE_COUNT(void) { - /* return the number of 'built-in' display modes */ - return si->mode_count; -} - -/* - Copy the list of guaranteed supported video modes to the location - provided. -*/ -status_t GET_MODE_LIST(display_mode *dm) { - /* copy them to the buffer pointed at by *dm */ - memcpy(dm, atimach64_mode_list, si->mode_count * sizeof(display_mode)); - return B_OK; -} - - -status_t get_first_mode(display_mode *dm) { - /* copy first valid mode to the buffer pointed at by *dm */ - memcpy(dm, atimach64_mode_list, sizeof(display_mode)); - return B_OK; -} - - - -/* - Create a list of display_modes to pass back to the caller. -*/ -status_t create_mode_list(void) { - size_t max_size; - uint32 - i, j, - pix_clk_range; - const display_mode - *src; - display_mode - *dst, - low, - high; - - /* - We prefer frame buffers to have the same endianness as the host CPU, but it's - not required. You can even return both, although there isn't a way for the - current Screen preferences panel to allow the user to choose which one to use. - */ -#if defined(__INTEL__) - color_space spaces[4] = {B_CMAP8, B_RGB15_LITTLE, B_RGB16_LITTLE, B_RGB32_LITTLE}; -#else - color_space spaces[4] = {B_CMAP8, B_RGB15_BIG, B_RGB16_BIG, B_RGB32_BIG}; -#endif - - /* printf(" Mode count %ld \n", MODE_COUNT);*/ - - - - - /* figure out how big the list could be, and adjust up to nearest multiple of B_PAGE_SIZE */ - max_size = (((MODE_COUNT * 4) * sizeof(display_mode)) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1); - /* create an area to hold the info */ - si->mode_area = atimach64_mode_list_area = - create_area("ATIMACH64 accelerant mode info", (void **)&atimach64_mode_list, B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); - if (atimach64_mode_list_area < B_OK) return atimach64_mode_list_area; - - /* walk through our predefined list and see which modes fit this device */ - src = mode_list; - dst = atimach64_mode_list; - si->mode_count = 0; - for (i = 0; i < MODE_COUNT; i++) { - /* set ranges for acceptable values */ - low = high = *src; - /* range is 6.25% of default clock: arbitrarily picked */ - - pix_clk_range = low.timing.pixel_clock >> 5; - low.timing.pixel_clock -= pix_clk_range; - high.timing.pixel_clock += pix_clk_range; - /* some cards need wider virtual widths for certain modes */ - high.virtual_width = 2048; - /* do it once for each depth we want to support */ - for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) { - /* set target values */ - *dst = *src; - /* poke the specific space */ - dst->space = low.space = high.space = spaces[j]; - /* ask for a compatible mode */ - if (PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) { - /* count it, and move on to next mode */ - dst++; - si->mode_count++; - } - } - /* advance to next mode */ - src++; - } - - return B_OK; -} diff --git a/src/add-ons/accelerants/atimach64/SetDisplayMode.c b/src/add-ons/accelerants/atimach64/SetDisplayMode.c deleted file mode 100644 index e4b7647fc4..0000000000 --- a/src/add-ons/accelerants/atimach64/SetDisplayMode.c +++ /dev/null @@ -1,285 +0,0 @@ -#include - -#include "GlobalData.h" -#include "generic.h" -#include "Mach64.h" -#include - - -/* - Enable/Disable interrupts. Just a wrapper around the - ioctl() to the kernel driver. -*/ -static void interrupt_enable(bool flag) { - status_t result; - atimach64_set_bool_state sbs; - - /* set the magic number so the driver knows we're for real */ - sbs.magic = ATIMACH64_PRIVATE_DATA_MAGIC; - sbs.do_it = flag; - /* contact driver and get a pointer to the registers and shared data */ - result = ioctl(fd, ATIMACH64_RUN_INTERRUPTS, &sbs, sizeof(sbs)); -} - -/* - Calculates the number of bits for a given color_space. - Usefull for mode setup routines, etc. -*/ -uint32 calcBitsPerPixel(uint32 cs) { - uint32 bpp = 0; - - switch (cs) { - case B_RGB32_BIG: - case B_RGBA32_BIG: - case B_RGB32_LITTLE: - case B_RGBA32_LITTLE: - bpp = 32; break; - case B_RGB24_BIG: - case B_RGB24_LITTLE: - bpp = 24; break; - case B_RGB16_BIG: - case B_RGB16_LITTLE: - bpp = 16; break; - case B_RGB15_BIG: - case B_RGBA15_BIG: - case B_RGB15_LITTLE: - case B_RGBA15_LITTLE: - bpp = 15; break; - case B_CMAP8: - bpp = 8; break; - } - return bpp; -} - -/* - The code to actually configure the display. Unfortunately, there's not much - that can be provided in the way of sample code. If you're lucky, you're writing - a driver for a device that has all (or at least most) of the bits for a particular - configuration value in the same register, rather than spread out over the standard - VGA registers + a zillion expansion bits. In any case, I've found that the way - to simplify this routine is to do all of the error checking in PROPOSE_DISPLAY_MODE(), - and just assume that the values I get here are acceptable. -*/ -static void do_set_display_mode(display_mode *dm) { - - mach64CRTCRegRec Regs; - - - CalcCRTCRegs(&Regs, dm); - - /* disable interrupts using the kernel driver */ - interrupt_enable(false); - - SetCRTCRegs(&Regs, dm); - - /* Initialize RAMDAC */ - InitRAMDAC(calcBitsPerPixel(dm->space), dm->flags); - - /* enable interrupts using the kernel driver */ - interrupt_enable(true); - -} - -/* - The exported mode setting routine. First validate the mode, then call our - private routine to hammer the registers. -*/ -status_t SET_DISPLAY_MODE(display_mode *mode_to_set) { - display_mode bounds, target; - - /* ask for the specific mode */ - target = bounds = *mode_to_set; - if (PROPOSE_DISPLAY_MODE(&target, &bounds, &bounds) == B_ERROR) - return B_ERROR; - - do_set_display_mode(&target); - - /* update shared info */ - target.h_display_start = 0; - target.v_display_start = 0; - si->dm = target; - - /* calculate bytes per row ans set it */ - si->fbc.bytes_per_row = ((calcBitsPerPixel(target.space) + 1) / 8) - *target.virtual_width; - - return B_OK; -} - -/* - Set which pixel of the virtual frame buffer will show up in the - top left corner of the display device. Used for page-flipping - games and virtual desktops. -*/ -status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start) { - int byte_offset; - /* - Many devices have limitations on the granularity of the horizontal offset. - Make any checks for this here. A future revision of the driver API will - add a hook to return the granularity for a given display mode. - */ - /* most cards can handle multiples of 8 */ - if (h_display_start & 0x07) - return B_ERROR; - /* do not run past end of display */ - if ((si->dm.timing.h_display + h_display_start) > si->dm.virtual_width) - return B_ERROR; - if ((si->dm.timing.v_display + v_display_start) > si->dm.virtual_height) - return B_ERROR; - - /* everybody remember where we parked... */ - si->dm.h_display_start = h_display_start; - si->dm.v_display_start = v_display_start; - - /* Calculate offset remebering to include the cursor area */ - byte_offset = (si->fbc.frame_buffer - si->framebuffer) >> 3; - byte_offset += ((h_display_start + v_display_start*si->dm.virtual_width) * - (calcBitsPerPixel(si->dm.space) / 8)) >> 3; - - /* actually set the registers */ - if (~(si->dm.flags & B_HARDWARE_CURSOR)) - SHOW_CURSOR(false); - - outw(CRTC_OFF_PITCH, (inw(CRTC_OFF_PITCH) & 0xfff00000) | byte_offset); - - return B_OK; -} - -/* - Set the indexed color palette. -*/ -void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags) { - - /* - Some cards use the indexed color regisers in the DAC for gamma correction. - If this is true with your device (and it probably is), you need to protect - against setting these registers when not in an indexed mode. - */ - if (si->dm.space != B_CMAP8) return; - - /* - There isn't any need to keep a copy of the data being stored, as the app_server - will set the colors each time it switches to an 8bpp mode, or takes ownership - of an 8bpp mode after a GameKit app has used it. - */ - - /* - You're on your own from here. Chances are your code will look something like - what follows: - */ - /* - Due to the nature of the SAMPLE card, we need to do bytewise writes - to the dac regs. Stupid, but there you go. So, we do it like we're - supposed to. - */ - - WaitQueue(1); - - outb(DAC_REGS, first); - - while (count--) { - outb(DAC_REGS+1, *color_data++); - outb(DAC_REGS+1, *color_data++); - outb(DAC_REGS+1, *color_data++); - } -} - - -/* masks for DPMS control bits */ -enum { - H_SYNC_OFF = 0x01, - V_SYNC_OFF = 0x02, - DISPLAY_OFF = 0x04, - BITSMASK = H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF -}; - -/* - Put the display into one of the Display Power Management modes. -*/ -status_t SET_DPMS_MODE(uint32 dpms_flags) { - uint32 LTemp; - - /* - The register containing the horizontal and vertical sync control bits - usually contains other control bits, so do a read-modify-write. - */ - /* read bits */ - LTemp = inw(CRTC_GEN_CNTL); - /* mask them */ - LTemp &= ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); /* clear all disable bits (including display disable) */ - - /* now pick one of the DPMS configurations */ - switch(dpms_flags) { - case B_DPMS_ON: /* H: on, V: on */ - /* do nothing, bits already clear */ - /* usually, but it may be different for your device */ - break; - case B_DPMS_STAND_BY: /* H: off, V: on, display off */ - LTemp |= CRTC_HSYNC_DIS; - break; - case B_DPMS_SUSPEND: /* H: on, V: off, display off */ - LTemp |= CRTC_VSYNC_DIS; - break; - case B_DPMS_OFF: /* H: off, V: off, display off */ - LTemp |= CRTC_HSYNC_DIS | CRTC_VSYNC_DIS; - break; - default: - return B_ERROR; - } - /* write the bits */ - outw(CRTC_GEN_CNTL, LTemp); - - snooze(10000); - - /* - NOTE: if you're driving a device with a backlight (like a digital LCD), - you may want to turn off the backlight here when in a DPMS power saving mode. - */ - if (dpms_flags == B_DPMS_ON) - /* turn on the back light */ - ; - else - /* turn off the back light */ - ; - - return B_OK; -} - -/* - Report device DPMS capabilities. Most newer cards can do it all. - I've only seen one older card that can do a subset (ON and OFF). - Very early cards may not be able to do this at all. -*/ -uint32 DPMS_CAPABILITIES(void) { - return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF; -} - - -/* - Return the current DPMS mode. -*/ -uint32 DPMS_MODE(void) { - uint32 LTemp; - uint32 mode = B_DPMS_ON; - - /* read the control bits from the device */ - /* read the bits */ - LTemp = inw(CRTC_GEN_CNTL); - - /* what mode is set? */ - switch (LTemp & (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS)) { - case 0: /* H: on, V: on */ - mode = B_DPMS_ON; - break; - case CRTC_HSYNC_DIS: /* H: off, V: on */ - mode = B_DPMS_STAND_BY; - break; - case CRTC_VSYNC_DIS: /* H: on, V: off */ - mode = B_DPMS_SUSPEND; - break; - case (CRTC_HSYNC_DIS | CRTC_VSYNC_DIS): /* H: off, V: off */ - mode = B_DPMS_OFF; - break; - } - return mode; -} diff --git a/src/add-ons/accelerants/atimach64/generic.h b/src/add-ons/accelerants/atimach64/generic.h deleted file mode 100644 index 10d41e010e..0000000000 --- a/src/add-ons/accelerants/atimach64/generic.h +++ /dev/null @@ -1,46 +0,0 @@ -#if !defined(GENERIC_H) -#define GENERIC_H - -#include - -status_t INIT_ACCELERANT(int fd); -ssize_t ACCELERANT_CLONE_INFO_SIZE(void); -void GET_ACCELERANT_CLONE_INFO(void *data); -status_t CLONE_ACCELERANT(void *data); -void UNINIT_ACCELERANT(void); -status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi); -sem_id ACCELERANT_RETRACE_SEMAPHORE(void); - -uint32 ACCELERANT_MODE_COUNT(void); -status_t GET_MODE_LIST(display_mode *dm); -status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const display_mode *high); -status_t SET_DISPLAY_MODE(display_mode *mode_to_set); -status_t GET_DISPLAY_MODE(display_mode *current_mode); -status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *a_frame_buffer); -status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high); -status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start); -status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc); -void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags); - -uint32 DPMS_CAPABILITIES(void); -uint32 DPMS_MODE(void); -status_t SET_DPMS_MODE(uint32 dpms_flags); - -status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask); -void MOVE_CURSOR(uint16 x, uint16 y); -void SHOW_CURSOR(bool is_visible); - -uint32 ACCELERANT_ENGINE_COUNT(void); -status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et); -status_t RELEASE_ENGINE(engine_token *et, sync_token *st); -void WAIT_ENGINE_IDLE(void); -status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st); -status_t SYNC_TO_TOKEN(sync_token *st); - -void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count); -void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count); -void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count); - -void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count); - -#endif diff --git a/src/add-ons/kernel/drivers/graphics/Jamfile b/src/add-ons/kernel/drivers/graphics/Jamfile index ad4502cc4c..b9d4ddcb29 100644 --- a/src/add-ons/kernel/drivers/graphics/Jamfile +++ b/src/add-ons/kernel/drivers/graphics/Jamfile @@ -1,5 +1,6 @@ SubDir HAIKU_TOP src add-ons kernel drivers graphics ; +SubInclude HAIKU_TOP src add-ons kernel drivers graphics ati ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics common ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics et6x00 ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics intel_extreme ; @@ -14,5 +15,3 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics skeleton ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics vesa ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics via ; SubInclude HAIKU_TOP src add-ons kernel drivers graphics vmware ; - -SubIncludeGPL HAIKU_TOP src add-ons kernel drivers graphics atimach64 ; diff --git a/src/add-ons/kernel/drivers/graphics/ati/Jamfile b/src/add-ons/kernel/drivers/graphics/ati/Jamfile new file mode 100644 index 0000000000..12e24d1107 --- /dev/null +++ b/src/add-ons/kernel/drivers/graphics/ati/Jamfile @@ -0,0 +1,9 @@ +SubDir HAIKU_TOP src add-ons kernel drivers graphics ati ; + +UsePrivateHeaders [ FDirName graphics ati ] ; +UsePrivateHeaders [ FDirName graphics common ] ; +UsePrivateHeaders graphics kernel ; + +KernelAddon ati : + driver.cpp +; diff --git a/src/add-ons/kernel/drivers/graphics/ati/driver.cpp b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp new file mode 100644 index 0000000000..2a09c4709b --- /dev/null +++ b/src/add-ons/kernel/drivers/graphics/ati/driver.cpp @@ -0,0 +1,1151 @@ +/* + Copyright 2007-2009 Haiku, Inc. All rights reserved. + Distributed under the terms of the MIT license. + + Authors: + Gerald Zajac 2007-2009 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DriverInterface.h" + + +#undef TRACE + +//#define ENABLE_DEBUG_TRACE +#ifdef ENABLE_DEBUG_TRACE +# define TRACE(x...) dprintf("ati: " x) +#else +# define TRACE(x...) ; +#endif + + +#define ATI_ACCELERANT_NAME "ati.accelerant" + +#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1)) + +#define VESA_MODES_BOOT_INFO "vesa_modes/v1" + +#define SKD_HANDLER_INSTALLED 0x80000000 +#define MAX_DEVICES 4 +#define DEVICE_FORMAT "%04X_%04X_%02X%02X%02X" + +#define M64_BIOS_SIZE 0x10000 // 64KB +#define R128_BIOS_SIZE 0x10000 // 64KB + +int32 api_version = B_CUR_DRIVER_API_VERSION; // revision of driver API we support + +#define VENDOR_ID 0x1002 // ATI vendor ID + +// Mach64 register definitions. +#define M64_CLOCK_INTERNAL 4 +#define M64_CONFIG_CHIP_ID 0x0CE0 // offset in register area +#define M64_CFG_CHIP_TYPE 0x0000FFFF + + +struct ChipInfo { + uint16 chipID; // PCI device id of the chip + ChipType chipType; // assigned chip type identifier + char* chipName; // user recognizable name for chip (must be < 32 chars) +}; + + +// Names for chip types. + +static char sRage128_GL[] = "RAGE 128 GL"; +static char sRage128_VR[] = "RAGE 128 VR"; +static char sRage128_Pro_GL[] = "RAGE 128 PRO GL"; +static char sRage128_Pro_VR[] = "RAGE 128 PRO VR"; +static char sRage128_Pro_Ultra[] = "RAGE 128 PRO Ultra"; + +// This table maps a PCI device ID to a chip type identifier and the chip name. +// The table is split into two groups of chips, the Mach64 and Rage128 chips, +// with each group ordered by the chip ID. + +static const ChipInfo chipTable[] = { + { 0x4742, MACH64_264GTPRO, "3D RAGE PRO, AGP" }, // GB + { 0x4744, MACH64_264GTPRO, "3D RAGE PRO, AGP" }, // GD + { 0x4749, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GI + { 0x474C, MACH64_264XL, "3D RAGE XC, PCI" }, // GL + { 0x474D, MACH64_264XL, "3D RAGE XL, AGP" }, // GM + { 0x474E, MACH64_264XL, "3D RAGE XC, AGP" }, // GN + { 0x474F, MACH64_264XL, "3D RAGE XL, PCI" }, // GO + { 0x4750, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GP + { 0x4751, MACH64_264GTPRO, "3D RAGE PRO, PCI" }, // GQ + { 0x4752, MACH64_264XL, "3D RAGE XL, PCI" }, // GR + { 0x4753, MACH64_264XL, "3D RAGE XC, PCI" }, // GS + { 0x4754, MACH64_264GT, "3D RAGE II" }, // GT + { 0x4755, MACH64_264GTDVD, "3D RAGE II+" }, // GU + { 0x4756, MACH64_264GT2C, "3D RAGE IIC, PCI" }, // GV + { 0x4757, MACH64_264GT2C, "3D RAGE IIC, AGP" }, // GW + { 0x4759, MACH64_264GT2C, "3D RAGE IIC, PCI" }, // GY + { 0x475A, MACH64_264GT2C, "3D RAGE IIC, AGP" }, // GZ + { 0x4C42, MACH64_264LTPRO, "3D RAGE LT PRO, AGP" }, // LB + { 0x4C44, MACH64_264LTPRO, "3D RAGE LT PRO, AGP" }, // LD + { 0x4C47, MACH64_264LT, "3D RAGE LT" }, // LG + { 0x4C49, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LI + { 0x4C4D, MACH64_MOBILITY, "3D RAGE Mobility, AGP" }, // LM + { 0x4C4E, MACH64_MOBILITY, "3D RAGE Mobility, AGP" }, // LN + { 0x4C50, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LP + { 0x4C51, MACH64_264LTPRO, "3D RAGE LT PRO, PCI" }, // LQ + { 0x4C52, MACH64_MOBILITY, "3D RAGE Mobility, PCI" }, // LR + { 0x4C53, MACH64_MOBILITY, "3D RAGE Mobility, PCI" }, // LS + { 0x5654, MACH64_264VT, "264VT2" }, // VT + { 0x5655, MACH64_264VT3, "264VT3" }, // VU + { 0x5656, MACH64_264VT4, "264VT4" }, // VV + + { 0x4C45, RAGE128_MOBILITY, "RAGE 128 Mobility 3" }, // LE + { 0x4C46, RAGE128_MOBILITY, "RAGE 128 Mobility 3" }, // LF + { 0x4D46, RAGE128_MOBILITY, "RAGE 128 Mobility 4" }, // MF + { 0x4D4C, RAGE128_MOBILITY, "RAGE 128 Mobility 4" }, // ML + { 0x5041, RAGE128_PRO_GL, sRage128_Pro_GL }, // PA + { 0x5042, RAGE128_PRO_GL, sRage128_Pro_GL }, // PB + { 0x5043, RAGE128_PRO_GL, sRage128_Pro_GL }, // PC + { 0x5044, RAGE128_PRO_GL, sRage128_Pro_GL }, // PD + { 0x5045, RAGE128_PRO_GL, sRage128_Pro_GL }, // PE + { 0x5046, RAGE128_PRO_GL, sRage128_Pro_GL }, // PF + { 0x5047, RAGE128_PRO_VR, sRage128_Pro_VR }, // PG + { 0x5048, RAGE128_PRO_VR, sRage128_Pro_VR }, // PH + { 0x5049, RAGE128_PRO_VR, sRage128_Pro_VR }, // PI + { 0x504A, RAGE128_PRO_VR, sRage128_Pro_VR }, // PJ + { 0x504B, RAGE128_PRO_VR, sRage128_Pro_VR }, // PK + { 0x504C, RAGE128_PRO_VR, sRage128_Pro_VR }, // PL + { 0x504D, RAGE128_PRO_VR, sRage128_Pro_VR }, // PM + { 0x504E, RAGE128_PRO_VR, sRage128_Pro_VR }, // PN + { 0x504F, RAGE128_PRO_VR, sRage128_Pro_VR }, // PO + { 0x5050, RAGE128_PRO_VR, sRage128_Pro_VR }, // PP + { 0x5051, RAGE128_PRO_VR, sRage128_Pro_VR }, // PQ + { 0x5052, RAGE128_PRO_VR, sRage128_Pro_VR }, // PR + { 0x5053, RAGE128_PRO_VR, sRage128_Pro_VR }, // PS + { 0x5054, RAGE128_PRO_VR, sRage128_Pro_VR }, // PT + { 0x5055, RAGE128_PRO_VR, sRage128_Pro_VR }, // PU + { 0x5056, RAGE128_PRO_VR, sRage128_Pro_VR }, // PV + { 0x5057, RAGE128_PRO_VR, sRage128_Pro_VR }, // PW + { 0x5058, RAGE128_PRO_VR, sRage128_Pro_VR }, // PX + { 0x5245, RAGE128_GL, sRage128_GL }, // RE + { 0x5246, RAGE128_GL, sRage128_GL }, // RF + { 0x5247, RAGE128_GL, sRage128_GL }, // RG + { 0x524B, RAGE128_VR, sRage128_VR }, // RK + { 0x524C, RAGE128_VR, sRage128_VR }, // RL + { 0x5345, RAGE128_VR, sRage128_VR }, // SE + { 0x5346, RAGE128_VR, sRage128_VR }, // SF + { 0x5347, RAGE128_VR, sRage128_VR }, // SG + { 0x5348, RAGE128_VR, sRage128_VR }, // SH + { 0x534B, RAGE128_GL, sRage128_GL }, // SK + { 0x534C, RAGE128_GL, sRage128_GL }, // SL + { 0x534D, RAGE128_GL, sRage128_GL }, // SM + { 0x534E, RAGE128_GL, sRage128_GL }, // SN + { 0x5446, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TF + { 0x544C, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TL + { 0x5452, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TR + { 0x5453, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TS + { 0x5454, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TT + { 0x5455, RAGE128_PRO_ULTRA, sRage128_Pro_Ultra }, // TU + { 0, ATI_NONE, NULL } +}; + + +struct DeviceInfo { + uint32 openCount; // count of how many times device has been opened + int32 flags; + area_id sharedArea; // area shared between driver and all accelerants + SharedInfo* sharedInfo; // pointer to shared info area memory + vuint8* regs; // pointer to memory mapped registers + const ChipInfo* pChipInfo; // info about the selected chip + pci_info pciInfo; // copy of pci info for this device + char name[B_OS_NAME_LENGTH]; // name of device +}; + + +static Benaphore gLock; +static DeviceInfo gDeviceInfo[MAX_DEVICES]; +static char* gDeviceNames[MAX_DEVICES + 1]; +static pci_module_info* gPCI; + + +// Prototypes for device hook functions. + +static status_t device_open(const char* name, uint32 flags, void** cookie); +static status_t device_close(void* dev); +static status_t device_free(void* dev); +static status_t device_read(void* dev, off_t pos, void* buf, size_t* len); +static status_t device_write(void* dev, off_t pos, const void* buf, size_t* len); +static status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len); + +static device_hooks gDeviceHooks = +{ + device_open, + device_close, + device_free, + device_ioctl, + device_read, + device_write, + NULL, + NULL, + NULL, + NULL +}; + + + +static inline uint32 +GetPCI(pci_info& info, uint8 offset, uint8 size) +{ + return gPCI->read_pci_config(info.bus, info.device, info.function, offset, size); +} + + +static inline void +SetPCI(pci_info& info, uint8 offset, uint8 size, uint32 value) +{ + gPCI->write_pci_config(info.bus, info.device, info.function, offset, size, value); +} + + +// Functions for dealing with Vertical Blanking Interrupts. Currently, I do +// not know the commands to handle these operations; thus, these functions +// currently do nothing. + +static bool +InterruptIsVBI() +{ + // return true only if a vertical blanking interrupt has occured + return false; +} + + +static void +ClearVBI() +{ +} + +static void +EnableVBI() +{ +} + +static void +DisableVBI() +{ +} + + + +static status_t +GetEdidFromBIOS(edid1_raw& edidRaw) +{ + // Get the EDID info from the video BIOS, and return B_OK if successful. + +#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4) +#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf) + + vm86_state vmState; + + status_t status = vm86_prepare(&vmState, 0x2000); + if (status != B_OK) { + TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n", status); + return status; + } + + vmState.regs.eax = 0x4f15; + vmState.regs.ebx = 0; // 0 = report DDC service + vmState.regs.ecx = 0; + vmState.regs.es = 0; + vmState.regs.edi = 0; + + status = vm86_do_int(&vmState, 0x10); + if (status == B_OK) { + // AH contains the error code, and AL determines wether or not the + // function is supported. + if (vmState.regs.eax != 0x4f) + status = B_NOT_SUPPORTED; + + // Test if DDC is supported by the monitor. + if ((vmState.regs.ebx & 3) == 0) + status = B_NOT_SUPPORTED; + } + + if (status == B_OK) { + // According to the author of the vm86 functions, the address of any + // object to receive data must be >= 0x1000 and within the ram size + // specified in the second argument of the vm86_prepare() call above. + // Thus, the address of the struct to receive the EDID info is set to + // 0x1000. + + edid1_raw* edid = (edid1_raw*)0x1000; + + vmState.regs.eax = 0x4f15; + vmState.regs.ebx = 1; // 1 = read EDID + vmState.regs.ecx = 0; + vmState.regs.edx = 0; + vmState.regs.es = ADDRESS_SEGMENT(edid); + vmState.regs.edi = ADDRESS_OFFSET(edid); + + status = vm86_do_int(&vmState, 0x10); + if (status == B_OK) { + if (vmState.regs.eax != 0x4f) { + status = B_NOT_SUPPORTED; + } else { + // Copy the EDID info to the caller's location, and compute the + // checksum of the EDID info while copying. + + uint8 sum = 0; + uint8 allOr = 0; + uint8* dest = (uint8*)&edidRaw; + uint8* src = (uint8*)edid; + + for (uint32 j = 0; j < sizeof(edidRaw); j++) { + sum += *src; + allOr |= *src; + *dest++ = *src++; + } + + if (allOr == 0) { + TRACE("GetEdidFromBIOS(); EDID info contains only zeros\n"); + status = B_ERROR; + } else if (sum != 0) { + TRACE("GetEdidFromBIOS(); Checksum error in EDID info\n"); + status = B_ERROR; + } + } + } + } + + vm86_cleanup(&vmState); + + return status; +} + + +static status_t +SetVesaDisplayMode(uint16 mode) +{ + // Set the VESA display mode, and return B_OK if successful. + +#define SET_MODE_MASK 0x01ff +#define SET_MODE_LINEAR_BUFFER (1 << 14) + + vm86_state vmState; + + status_t status = vm86_prepare(&vmState, 0x2000); + if (status != B_OK) { + TRACE("SetVesaDisplayMode(); vm86_prepare() failed, status: 0x%lx\n", status); + return status; + } + + vmState.regs.eax = 0x4f02; + vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER; + + status = vm86_do_int(&vmState, 0x10); + if (status != B_OK) { + TRACE("SetVesaDisplayMode(0x%x): vm86_do_int failed\n", mode); + } + + if (status == B_OK && (vmState.regs.eax & 0xffff) != 0x4f) { + TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04lx\n", mode, + vmState.regs.eax & 0xffff); + status = B_ERROR; + } + + vm86_cleanup(&vmState); + + return status; +} + + + +// Macros for accessing BIOS info. + +#define BIOS8(v) (romAddr[v]) +#define BIOS16(v) (romAddr[v] | \ + (romAddr[(v) + 1] << 8)) +#define BIOS32(v) (romAddr[v] | \ + (romAddr[(v) + 1] << 8) | \ + (romAddr[(v) + 2] << 16) | \ + (romAddr[(v) + 3] << 24)) + + +static status_t +Mach64_GetBiosParameters(DeviceInfo& di, uint8& clockType) +{ + // Get some clock parameters from the video BIOS, and if Mobility chip, + // also get the LCD panel width & height. + + // In case mapping the ROM area fails or other error occurs, set default + // values for the parameters which will be obtained from the BIOS ROM. + + clockType = M64_CLOCK_INTERNAL; + + SharedInfo& si = *(di.sharedInfo); + M64_Params& params = si.m64Params; + params.clockNumberToProgram = 3; + + si.panelX = 0; + si.panelY = 0; + + // Map the ROM area. The Mach64 chips do not assign a ROM address in the + // PCI info; thus, access the ROM via the ISA legacy memory map. + + uint8* romAddr; + area_id romArea = map_physical_memory("ATI Mach64 ROM", + (void*)0x000c0000, + M64_BIOS_SIZE, + B_ANY_KERNEL_ADDRESS, + B_READ_AREA, + (void**)&(romAddr)); + + if (romArea < 0) { + TRACE("Mach64_GetBiosParameters(), ROM mapping error: %ld\n", romArea); + return romArea; // ROM mapping failed; return error code + } + + // Check if we have the BIOS signature (might fail on laptops..). + + if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { + TRACE("Mach64_GetBiosParameters(), ROM does not contain BIOS signature\n"); + delete_area(romArea); + return B_ERROR; + } + + // Get clock info from BIOS. + + uint32 romTable = BIOS16(0x48); + uint32 clockTable = BIOS16(romTable + 16); + clockType = BIOS8(clockTable); + params.clockNumberToProgram = BIOS8(clockTable + 6); + params.maxPixelClock = BIOS16(clockTable + 4) * 10; + params.refFreq = BIOS16(clockTable + 8); + params.refDivider = BIOS16(clockTable + 10); + + // If Mobility chip, get the LCD panel width & height. + + if (si.chipType == MACH64_MOBILITY) { + uint32 lcdTable = BIOS16(0x78); + if (BIOS32(lcdTable) == 0x544d5224) { // is LCD table signature correct? + uint32 lcdPanelInfo = BIOS16(lcdTable + 10); + si.panelX = BIOS16(lcdPanelInfo + 25); + si.panelY = BIOS16(lcdPanelInfo + 27); + TRACE("Mobility LCD Panel size: %dx%d\n", si.panelX, si.panelY); + } else { + TRACE("Mobility LCD table signature 0x%x in BIOS is incorrect\n", + BIOS32(lcdTable)); + } + } + + delete_area(romArea); + + return B_OK; +} + + + +static status_t +Rage128_GetBiosParameters(DeviceInfo& di) +{ + // Get the PLL parameters from the video BIOS, and if Mobility chips, also + // get the LCD panel width & height and a few other related parameters. + + // In case mapping the ROM area fails or other error occurs, set default + // values for the parameters which will be obtained from the BIOS ROM. + // The default PLL parameters values probably will not work for all chips. + // For example, reference freq can be 29.50MHz, 28.63MHz, or 14.32MHz. + + SharedInfo& si = *(di.sharedInfo); + R128_PLLParams& pll = si.r128PLLParams; + pll.reference_freq = 2950; + pll.reference_div = 65; + pll.min_pll_freq = 12500; + pll.max_pll_freq = 25000; + pll.xclk = 10300; + + si.panelX = 0; + si.panelY = 0; + si.panelPowerDelay = 1; + + // Map the ROM area. The Rage128 chips do not assign a ROM address in the + // PCI info; thus, access the ROM via the ISA legacy memory map. + + uint8* romAddr; + area_id romArea = map_physical_memory("ATI Rage128 ROM", + (void*)0x000c0000, + R128_BIOS_SIZE, + B_ANY_KERNEL_ADDRESS, + B_READ_AREA, + (void**)&(romAddr)); + + if (romArea < 0) { + TRACE("Rage128_GetBiosParameters(), ROM mapping error: %ld\n", romArea); + return romArea; // ROM mapping failed; return error code + } + + // Check if we got the BIOS signature (might fail on laptops..). + + if (BIOS8(0) != 0x55 || BIOS8(1) != 0xaa) { + TRACE("Rage128_GetBiosParameters(), ROM does not contain BIOS signature\n"); + delete_area(romArea); + return B_ERROR; + } + + // Get the PLL values from the mapped ROM area. + + uint16 biosHeader = BIOS16(0x48); + uint16 pllInfoBlock = BIOS16(biosHeader + 0x30); + + pll.reference_freq = BIOS16(pllInfoBlock + 0x0e); + pll.reference_div = BIOS16(pllInfoBlock + 0x10); + pll.min_pll_freq = BIOS32(pllInfoBlock + 0x12); + pll.max_pll_freq = BIOS32(pllInfoBlock + 0x16); + pll.xclk = BIOS16(pllInfoBlock + 0x08); + + TRACE("PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n", pll.reference_freq, + pll.reference_div, pll.min_pll_freq, pll.max_pll_freq, pll.xclk); + + // If Mobility chip, get the LCD panel width & height and a few other + // related parameters. + + if (si.chipType == RAGE128_MOBILITY) { + // There should be direct access to the start of the FP info table, but + // until we find out where that offset is stored, we must search for + // the ATI signature string: "M3 ". + + int i; + for (i = 4; i < R128_BIOS_SIZE - 8; i++) { + if (BIOS8(i) == 'M' && + BIOS8(i + 1) == '3' && + BIOS8(i + 2) == ' ' && + BIOS8(i + 3) == ' ' && + BIOS8(i + 4) == ' ' && + BIOS8(i + 5) == ' ' && + BIOS8(i + 6) == ' ' && + BIOS8(i + 7) == ' ') { + int fpHeader = i - 2; + + // Assume that only one panel is attached and supported. + + for (i = fpHeader + 20; i < fpHeader + 84; i += 2) { + if (BIOS16(i) != 0) { + int fpStart = BIOS16(i); + si.panelX = BIOS16(fpStart + 25); + si.panelY = BIOS16(fpStart + 27); + si.panelPowerDelay = BIOS8(fpStart + 56); + TRACE("LCD Panel size: %dx%d Panel type: 0x%x power delay: %d\n", + si.panelX, si.panelY, BIOS16(fpStart + 29), si.panelPowerDelay); + break; + } + } + + break; + } + } + } + + delete_area(romArea); + + return B_OK; +} + + +static status_t +MapDevice(DeviceInfo& di) +{ + SharedInfo& si = *(di.sharedInfo); + pci_info& pciInfo = di.pciInfo; + + // Enable memory mapped IO and bus master. + + SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) + | PCI_command_io | PCI_command_memory | PCI_command_master); + + // Map the video memory. + + uint32 videoRamAddr = pciInfo.u.h0.base_registers[0]; + uint32 videoRamSize = pciInfo.u.h0.base_register_sizes[0]; + si.videoMemPCI = (void *)videoRamAddr; + char frameBufferAreaName[] = "ATI frame buffer"; + + si.videoMemArea = map_physical_memory( + frameBufferAreaName, + (void*)videoRamAddr, + videoRamSize, + B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, + B_READ_AREA + B_WRITE_AREA, + &(si.videoMemAddr)); + + if (si.videoMemArea < 0) { + // Try to map this time without write combining. + si.videoMemArea = map_physical_memory( + frameBufferAreaName, + (void*)videoRamAddr, + videoRamSize, + B_ANY_KERNEL_BLOCK_ADDRESS, + B_READ_AREA + B_WRITE_AREA, + &(si.videoMemAddr)); + } + + if (si.videoMemArea < 0) + return si.videoMemArea; + + // Map the MMIO register area. + + uint32 regsBase = pciInfo.u.h0.base_registers[2]; + uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[2]; + + // If the register area address or size is not in the PCI info, it should + // be at the end of the video memory. Check if it is there. + + if (MACH64_FAMILY(si.chipType) && (regsBase == 0 || regAreaSize == 0)) { + uint32 regsOffset = 0x7ff000; // offset to regs area in video memory + uint32 regs = uint32(si.videoMemAddr) + regsOffset; + uint32 chipInfo = *((vuint32*)(regs + M64_CONFIG_CHIP_ID)); + + if (si.deviceID != (chipInfo & M64_CFG_CHIP_TYPE)) { + // Register area not found; delete any other areas that were + // created. + delete_area(si.videoMemArea); + si.videoMemArea = -1; + TRACE("Mach64 register area not found\n"); + return B_ERROR; + } + + // Adjust params for creating register area below. + + regsBase = videoRamAddr + regsOffset; + regAreaSize = 0x1000; + TRACE("Register address is at end of frame buffer memory at 0x%lx\n", regsBase); + } + + si.regsArea = map_physical_memory("ATI mmio registers", + (void*)regsBase, + regAreaSize, + B_ANY_KERNEL_ADDRESS, + 0, // neither read nor write, to hide it from user space apps + (void**)(&(di.regs))); + + // If there was an error, delete other areas. + if (si.regsArea < 0) { + delete_area(si.videoMemArea); + si.videoMemArea = -1; + } + + return si.regsArea; +} + + +static void +UnmapDevice(DeviceInfo& di) +{ + SharedInfo& si = *(di.sharedInfo); + + if (si.regsArea >= 0) + delete_area(si.regsArea); + if (si.videoMemArea >= 0) + delete_area(si.videoMemArea); + + si.regsArea = si.videoMemArea = -1; + si.videoMemAddr = NULL; + di.regs = NULL; +} + + +static int32 +InterruptHandler(void* data) +{ + int32 handled = B_UNHANDLED_INTERRUPT; + DeviceInfo& di = *((DeviceInfo*)data); + int32* flags = &(di.flags); + + // Is someone already handling an interrupt for this device? + if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED) + return B_UNHANDLED_INTERRUPT; + + if (InterruptIsVBI()) { // was interrupt a VBI? + ClearVBI(); // clear interrupt + + handled = B_HANDLED_INTERRUPT; + + // Release vertical blanking semaphore. + sem_id& sem = di.sharedInfo->vertBlankSem; + + if (sem >= 0) { + int32 blocked; + if ((get_sem_count(sem, &blocked) == B_OK) && (blocked < 0)) { + release_sem_etc(sem, -blocked, B_DO_NOT_RESCHEDULE); + handled = B_INVOKE_SCHEDULER; + } + } + } + + atomic_and(flags, ~SKD_HANDLER_INSTALLED); // note we're not in handler anymore + + return handled; +} + + +static void +InitInterruptHandler(DeviceInfo& di) +{ + SharedInfo& si = *(di.sharedInfo); + + DisableVBI(); // disable & clear any pending interrupts + si.bInterruptAssigned = false; // indicate interrupt not assigned yet + + // Create a semaphore for vertical blank management. + si.vertBlankSem = create_sem(0, di.name); + if (si.vertBlankSem < 0) + return; + + // Change the owner of the semaphores to the calling team (usually the + // app_server). This is required because apps can't aquire kernel + // semaphores. + + thread_id threadID = find_thread(NULL); + thread_info threadInfo; + status_t status = get_thread_info(threadID, &threadInfo); + if (status == B_OK) + status = set_sem_owner(si.vertBlankSem, threadInfo.team); + + // If there is a valid interrupt assigned, set up interrupts. + + if (status == B_OK && di.pciInfo.u.h0.interrupt_pin != 0x00 + && di.pciInfo.u.h0.interrupt_line != 0xff) { + // We have a interrupt line to use. + + status = install_io_interrupt_handler(di.pciInfo.u.h0.interrupt_line, + InterruptHandler, (void*)(&di), 0); + + if (status == B_OK) + si.bInterruptAssigned = true; // we can use interrupt related functions + } + + if (status != B_OK) { + // Interrupt does not exist; thus delete semaphore as it won't be used. + delete_sem(si.vertBlankSem); + si.vertBlankSem = -1; + } +} + + +static status_t +InitDevice(DeviceInfo& di) +{ + // Perform initialization and mapping of the device, and return B_OK if + // sucessful; else, return error code. + + // Get the table of VESA modes that the chip supports. Note that we will + // need this table only for chips that are currently connected to a laptop + // display or a monitor connected via a DVI interface. + + size_t vesaModeTableSize = 0; + VesaMode* vesaModes = (VesaMode*)get_boot_item(VESA_MODES_BOOT_INFO, + &vesaModeTableSize); + + size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; + + // Create the area for shared info with NO user-space read or write + // permissions, to prevent accidental damage. + + di.sharedArea = create_area("ATI shared info", + (void**) &(di.sharedInfo), + B_ANY_KERNEL_ADDRESS, + ROUND_TO_PAGE_SIZE(sharedSize + vesaModeTableSize), + B_FULL_LOCK, 0); + if (di.sharedArea < 0) + return di.sharedArea; // return error code + + SharedInfo& si = *(di.sharedInfo); + + memset(&si, 0, sharedSize); + + if (vesaModes != NULL) { + si.vesaModeTableOffset = sharedSize; + si.vesaModeCount = vesaModeTableSize / sizeof(VesaMode); + + memcpy((uint8*)&si + si.vesaModeTableOffset, vesaModes, vesaModeTableSize); + } + + pci_info& pciInfo = di.pciInfo; + + si.vendorID = pciInfo.vendor_id; + si.deviceID = pciInfo.device_id; + si.revision = pciInfo.revision; + si.chipType = di.pChipInfo->chipType; + strcpy(si.chipName, di.pChipInfo->chipName); + + TRACE("Chip revision: 0x%x\n", si.revision); + + // 264GT has two chip versions. If version is non-zero, chip is 264GTB. + + if (si.chipType == MACH64_264GT && si.revision & 0x7) + si.chipType = MACH64_264GTB; + + // 264VT has two chip versions. If version is non-zero, chip is 264VTB. + + if (si.chipType == MACH64_264VT && si.revision & 0x7) + si.chipType = MACH64_264VTB; + + status_t status = MapDevice(di); + + // If device mapped without any error, get the bios parameters from the + // chip's BIOS ROM. + + if (status >= 0) { + if (MACH64_FAMILY(si.chipType)) { + uint8 clockType; + Mach64_GetBiosParameters(di, clockType); + + // All chips supported by this driver should have an internal clock. + // If the clock is not an internal clock, the video chip is not + // supported. + + if (clockType != M64_CLOCK_INTERNAL) { + TRACE("Video chip clock type %d not supported\n", clockType); + status = B_UNSUPPORTED; + } + } + else if (RAGE128_FAMILY(si.chipType)) + Rage128_GetBiosParameters(di); + } + + if (status < 0) { + delete_area(di.sharedArea); + di.sharedArea = -1; + di.sharedInfo = NULL; + return status; // return error code + } + + InitInterruptHandler(di); + + TRACE("Interrupt assigned: %s\n", si.bInterruptAssigned ? "yes" : "no"); + return B_OK; +} + + +static const ChipInfo* +GetNextSupportedDevice(uint32& pciIndex, pci_info& pciInfo) +{ + // Search the PCI devices for a device that is supported by this driver. + // The search starts at the device specified by argument pciIndex, and + // continues until a supported device is found or there are no more devices + // to examine. Argument pciIndex is incremented after each device is + // examined. + + // If a supported device is found, return a pointer to the struct containing + // the chip info; else return NULL. + + while (gPCI->get_nth_pci_info(pciIndex, &pciInfo) == B_OK) { + + if (pciInfo.vendor_id == VENDOR_ID) { + + // Search the table of supported devices to find a chip/device that + // matches device ID of the current PCI device. + + const ChipInfo* pDevice = chipTable; + + while (pDevice->chipID != 0) { // end of table? + if (pDevice->chipID == pciInfo.device_id) { + // Matching device/chip found. If chip is 264VT, reject it + // if its version is zero since the mode can not be set on + // that chip. + + if (pDevice->chipType == MACH64_264VT + && (pciInfo.revision & 0x7) == 0) + break; + + return pDevice; // matching device/chip found + } + + pDevice++; + } + } + + pciIndex++; + } + + return NULL; // no supported device found +} + + + +// #pragma mark - Kernel Interface + + +status_t +init_hardware(void) +{ + // Return B_OK if a device supported by this driver is found; otherwise, + // return B_ERROR so the driver will be unloaded. + + if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) + return B_ERROR; // unable to access PCI bus + + // Check pci devices for a device supported by this driver. + + uint32 pciIndex = 0; + pci_info pciInfo; + const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, pciInfo); + + TRACE("init_hardware() - %s\n", pDevice == NULL ? "no supported devices" : "device supported"); + + put_module(B_PCI_MODULE_NAME); // put away the module manager + + return (pDevice == NULL ? B_ERROR : B_OK); +} + + +status_t init_driver(void) +{ + // Get handle for the pci bus. + + if (get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI) != B_OK) + return B_ERROR; + + status_t status = gLock.Init("ATI driver lock"); + if (status < B_OK) + return status; + + // Get info about all the devices supported by this driver. + + uint32 pciIndex = 0; + uint32 count = 0; + + while (count < MAX_DEVICES) { + DeviceInfo& di = gDeviceInfo[count]; + + const ChipInfo* pDevice = GetNextSupportedDevice(pciIndex, di.pciInfo); + if (pDevice == NULL) + break; // all supported devices have been obtained + + // Compose device name. + sprintf(di.name, "graphics/" DEVICE_FORMAT, + di.pciInfo.vendor_id, di.pciInfo.device_id, + di.pciInfo.bus, di.pciInfo.device, di.pciInfo.function); + TRACE("init_driver() match found; name: %s\n", di.name); + + gDeviceNames[count] = di.name; + di.openCount = 0; // mark driver as available for R/W open + di.sharedArea = -1; // indicate shared area not yet created + di.sharedInfo = NULL; + di.pChipInfo = pDevice; + count++; + pciIndex++; + } + + gDeviceNames[count] = NULL; // terminate list with null pointer + + TRACE("init_driver() %ld supported devices\n", count); + + return B_OK; +} + + +void +uninit_driver(void) +{ + // Free the driver data. + + gLock.Delete(); + put_module(B_PCI_MODULE_NAME); // put the pci module away +} + + +const char** +publish_devices(void) +{ + return (const char**)gDeviceNames; // return list of supported devices +} + + +device_hooks* +find_device(const char* name) +{ + int i = 0; + while (gDeviceNames[i] != NULL) { + if (strcmp(name, gDeviceNames[i]) == 0) + return &gDeviceHooks; + i++; + } + + return NULL; +} + + + +// #pragma mark - Device Hooks + + +static status_t +device_open(const char* name, uint32 /*flags*/, void** cookie) +{ + status_t status = B_OK; + + TRACE("device_open() - name: %s\n", name); + + // Find the device name in the list of devices. + + int32 i = 0; + while (gDeviceNames[i] != NULL && (strcmp(name, gDeviceNames[i]) != 0)) + i++; + + if (gDeviceNames[i] == NULL) + return B_BAD_VALUE; // device name not found in list of devices + + DeviceInfo& di = gDeviceInfo[i]; + + gLock.Acquire(); // make sure no one else has write access to common data + + if (di.openCount == 0) + status = InitDevice(di); + + gLock.Release(); + + if (status == B_OK) { + di.openCount++; // mark device open + *cookie = &di; // send cookie to opener + } + + TRACE("device_open() returning 0x%lx, open count: %ld\n", status, di.openCount); + return status; +} + + +static status_t +device_read(void* dev, off_t pos, void* buf, size_t* len) +{ + // Following 3 lines of code are here to eliminate "unused parameter" warnings. + (void)dev; + (void)pos; + (void)buf; + + *len = 0; + return B_NOT_ALLOWED; +} + + +static status_t +device_write(void* dev, off_t pos, const void* buf, size_t* len) +{ + // Following 3 lines of code are here to eliminate "unused parameter" warnings. + (void)dev; + (void)pos; + (void)buf; + + *len = 0; + return B_NOT_ALLOWED; +} + + +static status_t +device_close(void* dev) +{ + (void)dev; // avoid compiler warning for unused arg + + return B_NO_ERROR; +} + + +static status_t +device_free(void* dev) +{ + DeviceInfo& di = *((DeviceInfo*)dev); + SharedInfo& si = *(di.sharedInfo); + pci_info& pciInfo = di.pciInfo; + + TRACE("enter device_free()\n"); + + gLock.Acquire(); // lock driver + + // If opened multiple times, merely decrement the open count and exit. + + if (di.openCount <= 1) { + DisableVBI(); // disable & clear any pending interrupts + + if (si.bInterruptAssigned) { + remove_io_interrupt_handler(pciInfo.u.h0.interrupt_line, InterruptHandler, &di); + } + + // Delete the semaphores, ignoring any errors because the owning team may have died. + if (si.vertBlankSem >= 0) + delete_sem(si.vertBlankSem); + si.vertBlankSem = -1; + + UnmapDevice(di); // free regs and frame buffer areas + + delete_area(di.sharedArea); + di.sharedArea = -1; + di.sharedInfo = NULL; + } + + if (di.openCount > 0) + di.openCount--; // mark device available + + gLock.Release(); // unlock driver + + TRACE("exit device_free() openCount: %ld\n", di.openCount); + return B_OK; +} + + +static status_t +device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength) +{ + DeviceInfo& di = *((DeviceInfo*)dev); + +// TRACE("device_ioctl(); ioctl: %lu, buffer: 0x%08lx, bufLen: %lu\n", msg, (uint32)buffer, bufferLength); + + switch (msg) { + case B_GET_ACCELERANT_SIGNATURE: + strcpy((char*)buffer, ATI_ACCELERANT_NAME); + return B_OK; + + case ATI_DEVICE_NAME: + strncpy((char*)buffer, di.name, B_OS_NAME_LENGTH); + ((char*)buffer)[B_OS_NAME_LENGTH -1] = '\0'; + return B_OK; + + case ATI_GET_SHARED_DATA: + if (bufferLength != sizeof(area_id)) + return B_BAD_DATA; + + *((area_id*)buffer) = di.sharedArea; + return B_OK; + + case ATI_GET_EDID: + { + if (bufferLength != sizeof(edid1_raw)) + return B_BAD_DATA; + + edid1_raw rawEdid; + status_t status = GetEdidFromBIOS(rawEdid); + if (status == B_OK) + user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid)); + return status; + } + + case ATI_SET_VESA_DISPLAY_MODE: + if (bufferLength != sizeof(uint16)) + return B_BAD_DATA; + + return SetVesaDisplayMode(*((uint16*)buffer)); + + case ATI_RUN_INTERRUPTS: + if (bufferLength != sizeof(bool)) + return B_BAD_DATA; + + if (*((bool*)buffer)) + EnableVBI(); + else + DisableVBI(); + + return B_OK; + } + + return B_DEV_INVALID_IOCTL; +} diff --git a/src/add-ons/kernel/drivers/graphics/atimach64/COPYING b/src/add-ons/kernel/drivers/graphics/atimach64/COPYING deleted file mode 100644 index a43ea2126f..0000000000 --- a/src/add-ons/kernel/drivers/graphics/atimach64/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/src/add-ons/kernel/drivers/graphics/atimach64/Jamfile b/src/add-ons/kernel/drivers/graphics/atimach64/Jamfile deleted file mode 100644 index 8c0266acca..0000000000 --- a/src/add-ons/kernel/drivers/graphics/atimach64/Jamfile +++ /dev/null @@ -1,11 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel drivers graphics atimach64 ; -SubDirCcFlags -DSEMAPHORE=1 ; - -UsePrivateHeaders graphics ; -UsePrivateHeaders [ FDirName graphics atimach64 ] ; - -KernelAddon atimach64.driver : - driver.c - m64info.c -; - diff --git a/src/add-ons/kernel/drivers/graphics/atimach64/driver.c b/src/add-ons/kernel/drivers/graphics/atimach64/driver.c deleted file mode 100644 index 7178632ad5..0000000000 --- a/src/add-ons/kernel/drivers/graphics/atimach64/driver.c +++ /dev/null @@ -1,976 +0,0 @@ -/* - - Driver for ATIMach64VT - - Lots of rewriting to be able to work with other ATIMACH64 cards - - Rene MacKinney - - 6.May.1999 - - - Based on GraphicDriverKit for R4 alpha release - - Huge thanks to Trey for all the help - - -*/ - -/* standard kernel driver stuff */ -#include -#include -#include -#include - -/* this is for the standardized portion of the driver API */ -/* currently only one operation is defined: B_GET_ACCELERANT_SIGNATURE */ -#include - -/* this is for sprintf() */ -#include - -/* this is for string compares */ -#include - -/* The private interface between the accelerant and the kernel driver. */ -#include "DriverInterface.h" - -/* ATI Mach64 Definitions */ -#include "regmach64.h" -#include "ATIMach64.h" - -#if DEBUG > 0 -#define ddprintf(a) dprintf a -#else -#define ddprintf(a) -#endif - -#define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) -#define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) - -/* Given the fact that the VT is a motherboard integrated - card we only support one */ - -#define MAX_DEVICES 1 - -/* The vertical retrace semaphore is not implemented instead of erasing - all the code about it we simply don't compile it. Waiting for the - implementation */ - -#define SEMAPHORE 0 - - -/* Tell the kernel what revision of the driver API we support */ -int32 api_version = 2; - -/* these structures are private to the kernel driver */ -typedef struct device_info device_info; - -#if defined(POST_R4_0) -typedef struct { - timer te; /* timer entry for add_timer() */ - device_info *di; /* pointer to the owning device */ - bigtime_t when_target; /* when we're supposed to wake up */ -} timer_info; -#endif - -struct device_info { - uint32 is_open; /* a count of how many times the devices has been opened */ - area_id shared_area; /* the area shared between the driver and all of the accelerants */ - shared_info *si; /* a pointer to the shared area, for convenience */ - vuint32 *regs; /* kernel's pointer to memory mapped registers */ - int32 can_interrupt; /* when we're faking interrupts, let's us know if we should generate one */ -#if defined(POST_R4_0) - timer_info ti_a; /* a pool of two timer managment buffers */ - timer_info ti_b; - timer_info *current_timer; /* the timer buffer that's currently in use */ -#else - thread_id tid; -#endif -#if DEBUG > 0 - uint32 interrupt_count; /* if we're debugging, a count of how many times the interrupt handler has - been called for this device */ -#endif - pci_info pcii; /* a convenience copy of the pci info for this device */ - char name[B_OS_NAME_LENGTH]; /* where we keep the name of the device for publishing and comparing */ -}; - -typedef struct { -#if DEBUG > 0 - uint32 total_interrupts; /* total number of interrupts seen by our handler */ -#endif - uint32 count; /* number of devices actually found */ - benaphore kernel; /* for serializing opens/closes */ - char *device_names[MAX_DEVICES+1]; /* device name pointer storage */ - device_info di[MAX_DEVICES]; /* device specific stuff */ -} DeviceData; - -/* prototypes for our private functions */ -static status_t open_hook (const char* name, uint32 flags, void** cookie); -static status_t close_hook (void* dev); -static status_t free_hook (void* dev); -static status_t read_hook (void* dev, off_t pos, void* buf, size_t* len); -static status_t write_hook (void* dev, off_t pos, const void* buf, size_t* len); -static status_t control_hook (void* dev, uint32 msg, void *buf, size_t len); -static status_t map_device(device_info *di); -static void unmap_device(device_info *di); -static void probe_devices(void); -static int32 atimach64_interrupt(void *data); - -#if DEBUG > 0 -static int dump(int argc, char **argv); -#endif - -static DeviceData *pd; -static pci_module_info *pci_bus; -static device_hooks graphics_device_hooks = { - open_hook, - close_hook, - free_hook, - control_hook, - read_hook, - write_hook, - NULL, - NULL, - NULL, - NULL -}; - -static uint16 ati_device_list[] = { - PCI_MACH64_VT_ID, /* Mach64 VT device */ - 0 -}; - -static struct { - uint16 vendor; - uint16 *devices; -} SupportedDevices[] = { - {PCI_ATI_VENDOR_ID, ati_device_list}, - {0x0000, NULL} -}; - -/* - init_hardware() - Returns B_OK if one is - found, otherwise returns B_ERROR so the driver will be unloaded. -*/ -status_t -init_hardware(void) { - long pci_index = 0; - pci_info pcii; - bool found_one = FALSE; - - - /* choke if we can't find the PCI bus */ - if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) - return B_ERROR; - - /* while there are more pci devices */ - while ((*pci_bus->get_nth_pci_info)(pci_index, &pcii) == B_NO_ERROR) { - int vendor = 0; - - ddprintf(("SKD init_hardware(): checking pci index %ld, device 0x%04x/0x%04x\n", pci_index, pcii.vendor_id, pcii.device_id)); - /* if we match a supported vendor */ - while (SupportedDevices[vendor].vendor) { - if (SupportedDevices[vendor].vendor == pcii.vendor_id) { - uint16 *devices = SupportedDevices[vendor].devices; - /* while there are more supported devices */ - while (*devices) { - /* if we match a supported device */ - if (*devices == pcii.device_id ) { - - ddprintf(("SKD: we support this device\n")); - found_one = TRUE; - goto done; - } - /* next supported device */ - devices++; - } - } - vendor++; - } - /* next pci_info struct, please */ - pci_index++; - } - ddprintf(("SKD: init_hardware - no supported devices\n")); - - done: - /* put away the module manager */ - put_module(B_PCI_MODULE_NAME); - return (found_one ? B_OK : B_ERROR); -} - -status_t -init_driver(void) { - - /* get a handle for the pci bus */ - if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) - return B_ERROR; - - /* driver private data */ - pd = (DeviceData *)calloc(1, sizeof(DeviceData)); - if (!pd) { - put_module(B_PCI_MODULE_NAME); - return B_ERROR; - } - /* initialize the benaphore */ - INIT_BEN(pd->kernel); - /* find all of our supported devices */ - probe_devices(); -#if DEBUG > 0 - add_debugger_command("dump", dump, "dump ATIMach64 kernel driver persistant data"); -#endif - return B_OK; -} - -const char ** -publish_devices(void) { - /* return the list of supported devices */ - return (const char **)pd->device_names; -} - -device_hooks * -find_device(const char *name) { - int index = 0; - while (pd->device_names[index]) { - if (strcmp(name, pd->device_names[index]) == 0) - return &graphics_device_hooks; - index++; - } - return NULL; - -} - -void -uninit_driver(void) { - -#if DEBUG > 0 - remove_debugger_command("dump", dump); -#endif - - /* free the driver data */ - DELETE_BEN(pd->kernel); - free(pd); - pd = NULL; - - /* put the pci module away */ - put_module(B_PCI_MODULE_NAME); -} - -static status_t map_device(device_info *di) { - /* default: frame buffer in [0], control regs in [1] */ - /* int regs = 1; */ - int fb = 0; - char buffer[B_OS_NAME_LENGTH]; - shared_info *si = di->si; - uint32 tmpUlong; - pci_info *pcii = &(di->pcii); - uint32 rom_base; - - - /* enable memory mapped IO, disable VGA I/O */ - tmpUlong = get_pci(PCI_command, 4); - tmpUlong |= PCI_command_memory; - tmpUlong &= ~((uint32) PCI_command_io); - set_pci(PCI_command, 4, tmpUlong); - - /* enable ROM decoding */ - /* tmpUlong = get_pci(PCI_rom_base, 4); - tmpUlong |= PCI_rom_enable; - set_pci(PCI_rom_base, 4, tmpUlong); */ - - /* map the rom */ - /* If rom_base points to 0x00 try using standard ROM location for Mach64 */ - rom_base = (di->pcii.u.h0.rom_base == 0) ? 0x000c0000 : di->pcii.u.h0.rom_base; - sprintf(buffer, "%04X_%04X_%02X%02X%02X rom", - di->pcii.vendor_id, di->pcii.device_id, - di->pcii.bus, di->pcii.device, di->pcii.function); - si->rom_area = map_physical_memory( - buffer, - (void *)rom_base, - di->pcii.u.h0.rom_size, - B_ANY_KERNEL_ADDRESS, - B_READ_AREA, - (void **)&(si->rom)); - - /* return the error if there was some problem */ - if (si->rom_area < 0) { - delete_area(si->regs_area); - si->regs_area = -1; - return si->rom_area; - } - - sprintf(buffer, "%04X_%04X_%02X%02X%02X framebuffer", - di->pcii.vendor_id, di->pcii.device_id, - di->pcii.bus, di->pcii.device, di->pcii.function); - si->fb_area = map_physical_memory( - buffer, - (void *) di->pcii.u.h0.base_registers[fb], - di->pcii.u.h0.base_register_sizes[fb], -#if defined(__INTEL__) -#if defined(POST_R4_0) - B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, -#else - B_ANY_KERNEL_ADDRESS | B_MTR_WC, -#endif -#else - B_ANY_KERNEL_BLOCK_ADDRESS, -#endif - B_READ_AREA + B_WRITE_AREA, - &(si->framebuffer)); - -#if defined(__INTEL__) - if (si->fb_area < 0) { - /* try to map this time without write combining */ - /* - After R4.0 (Intel), map_physical_memory() will try B_ANY_KERNEL_ADDRESS if - a call with B_ANY_KERNEL_BLOCK_ADDRESS would fail. It always worked this way - under PPC. - */ - si->fb_area = map_physical_memory( - buffer, - (void *) di->pcii.u.h0.base_registers[fb], - di->pcii.u.h0.base_register_sizes[fb], -#if defined(POST_R4_0) - B_ANY_KERNEL_BLOCK_ADDRESS, -#else - B_ANY_KERNEL_ADDRESS, -#endif - B_READ_AREA + B_WRITE_AREA, - &(si->framebuffer)); - } -#endif - - /* if there was an error, delete our other areas */ - if (si->fb_area < 0) { - delete_area(si->regs_area); - si->regs_area = -1; - delete_area(si->rom_area); - si->rom_area = -1; - } - /* remember the DMA address of the frame buffer for BDirectWindow purposes */ - si->framebuffer_pci = (void *) di->pcii.u.h0.base_registers_pci[fb]; - - return si->fb_area; -} - -static void -unmap_device(device_info *di) { - shared_info *si = di->si; - uint32 tmpUlong; - pci_info *pcii = &(di->pcii); - - ddprintf(("unmap_device(%08lx) begins...\n", (uint32)di)); - ddprintf((" regs_area: %ld\n fb_area: %ld\n", si->regs_area, si->fb_area)); - /* disable memory mapped IO */ - tmpUlong = get_pci(PCI_command, 4); - tmpUlong &= 0xfffffffc; - set_pci(PCI_command, 4, tmpUlong); - /* disable ROM decoding */ - tmpUlong = get_pci(PCI_rom_base, 4); - tmpUlong &= 0xfffffffe; - set_pci(PCI_rom_base, 4, tmpUlong); - /* delete the areas */ - if (si->rom_area >= 0) delete_area(si->rom_area); - /* if (si->regs_area >= 0) delete_area(si->regs_area);*/ - if (si->fb_area >= 0) delete_area(si->fb_area); - si->rom_area = si->regs_area = si->fb_area = -1; - si->framebuffer = NULL; - di->regs = NULL; - si->rom = NULL; - ddprintf(("unmap_device() ends.\n")); -} - -static void -probe_devices(void) { - uint32 pci_index = 0; - uint32 count = 0; - device_info *di = pd->di; - - /* while there are more pci devices */ - while ((count < MAX_DEVICES) && ((*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) == B_NO_ERROR)) { - int vendor = 0; - - /* if we match a supported vendor */ - while (SupportedDevices[vendor].vendor) { - if (SupportedDevices[vendor].vendor == di->pcii.vendor_id) { - uint16 *devices = SupportedDevices[vendor].devices; - /* while there are more supported devices */ - while (*devices) { - /* if we match a supported device */ - if (*devices == di->pcii.device_id ) { - /* publish the device name */ - sprintf(di->name, "graphics/%04X_%04X_%02X%02X%02X", - di->pcii.vendor_id, di->pcii.device_id, - di->pcii.bus, di->pcii.device, di->pcii.function); - ddprintf(("SKD: making /dev/%s\n", di->name)); - /* remember the name */ - pd->device_names[count] = di->name; - /* mark the driver as available for R/W open */ - di->is_open = 0; - /* mark areas as not yet created */ - di->shared_area = -1; - /* mark pointer to shared data as invalid */ - di->si = NULL; - /* inc pointer to device info */ - di++; - /* inc count */ - count++; - /* break out of these while loops */ - goto next_device; - } - /* next supported device */ - devices++; - } - } - vendor++; - } - next_device: - /* next pci_info struct, please */ - pci_index++; - } - /* propagate count */ - pd->count = count; - /* terminate list of device names with a null pointer */ - pd->device_names[pd->count] = NULL; - ddprintf(("SKD probe_devices: %ld supported devices\n", pd->count)); -} - -static uint32 -thread_interrupt_work(int32 *flags, vuint32 *regs, shared_info *si) { - uint32 handled = B_HANDLED_INTERRUPT; - /* release the vblank semaphore */ - if (si->vblank >= 0) { - int32 blocked; - if ((get_sem_count(si->vblank, &blocked) == B_OK) && (blocked < 0)) { - release_sem_etc(si->vblank, -blocked, B_DO_NOT_RESCHEDULE); - handled = B_INVOKE_SCHEDULER; - } - } - return handled; -} - -static int32 -atimach64_interrupt(void *data) -{ - int32 handled = B_UNHANDLED_INTERRUPT; - device_info *di = (device_info *)data; - shared_info *si = di->si; - int32 *flags = &(si->flags); - vuint32 *regs; - -#if DEBUG > 0 - pd->total_interrupts++; -#endif - - /* is someone already handling an interrupt for this device? */ - if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED) { -#if DEBUG > 0 - kprintf("SKD: Already in handler!\n"); -#endif - goto exit0; - } - /* get regs */ - regs = di->regs; - - /* read the interrrupt status register */ - - /* did this card cause an interrupt */ - if (0 /* replace this expression */) { - /* do our stuff */ - handled = thread_interrupt_work(flags, regs, si); -#if DEBUG > 0 - /* increment the counter for this device */ - di->interrupt_count++; -#endif - /* clear the interrupt status */ - } - - /* note that we're not in the handler any more */ - atomic_and(flags, ~SKD_HANDLER_INSTALLED); - - exit0: - return handled; -} - -#if SEMAPHORE -#if defined(POST_R4_0) -static int32 timer_interrupt_func(timer *te, uint32 pc) { - bigtime_t now = system_time(); - /* get the pointer to the device we're handling this time */ - device_info *di = ((timer_info *)te)->di; - shared_info *si = di->si; - int32 *flags = &(si->flags); - vuint32 *regs = di->regs; - uint32 vbl_status = 0 /* read vertical blank status */; - int32 result = B_HANDLED_INTERRUPT; - - /* are we suppoesed to handle interrupts still? */ - if (atomic_and(flags, -1) & SKD_HANDLER_INSTALLED) { - /* reschedule with same period by default */ - bigtime_t when = si->refresh_period; - timer *to; - - /* if interrupts are "enabled", do our thing */ - if (di->can_interrupt) { - /* insert code to sync to interrupts here */ - if (!vbl_status) { - when -= si->blank_period - 4; - } - /* do the things we do when we notice a vertical retrace */ - result = thread_interrupt_work(flags, regs, si); - - } - - /* pick the "other" timer */ - to = (timer *)&(di->ti_a); - if (to == te) to = (timer *)&(di->ti_b); - /* our guess as to when we should be back */ - ((timer_info *)to)->when_target = now + when; - /* reschedule the interrupt */ - add_timer(to, timer_interrupt_func, ((timer_info *)to)->when_target, B_ONE_SHOT_ABSOLUTE_TIMER); - /* remember the currently active timer */ - di->current_timer = (timer_info *)to; - } - - return result; -} -#else -static int32 -fake_interrupt_thread_func(void *_di) -{ - device_info *di; /* = (device_info *)_di; */ - shared_info *si; /* = di->si; */ - int32 *flags; /* = &(si->flags); */ - vuint32 *regs; /* = di->regs; */ - - bigtime_t last_sync; - bigtime_t this_sync; - bigtime_t diff_sync; - - uint32 counter = 1; - - ddprintf((" Device info points to %08x\n",(device_info *)_di)); - di = (device_info *)_di; - ddprintf((" Shared info points to %08x\n",di->si)); - si = di->si; - ddprintf((" Flags points to %08x\n",&(si->flags))); - flags = &(si->flags); - ddprintf((" Regs points to %08x\n",di->regs)); - regs = di->regs; - - /* a lie, but we have to start somewhen */ - - last_sync = system_time() - 8333; - - ddprintf(("fake_interrupt_thread_func begins\ndi: 0x%08lx\nsi: 0x%08lx\nflags: 0x%08lx\n", (uint32)di, (uint32)si, (uint32)flags)); - - /* loop until notified */ - - while(atomic_and(flags, -1) & SKD_HANDLER_INSTALLED) { - /* see if "interrupts" are enabled */ - - if((volatile int32)(di->can_interrupt)) { - /* poll the retrace flag until set */ - - /* YOUR CODE HERE */ - - /* get the system_time */ - this_sync = system_time(); - - /* do our stuff */ - thread_interrupt_work(flags, regs, si); - } else { - /* get the system_time */ - this_sync = system_time(); - } - - /* find out how long it took */ - diff_sync = this_sync - last_sync; - - /* back off a little so we're sure to catch the retrace */ - diff_sync -= diff_sync / 10; - - /* - impose some limits so we can recover from refresh rate changes - Supported refresh rates are 48 Hz - 120 Hz, so these limits should - be slightly wider. - */ - if(diff_sync < 8000) { - diff_sync = 8000; /* not less than 1/125th of sec */ - } - - if(diff_sync > 16666) { - diff_sync = 20000; /* not more than 1/40th of sec */ - } - - if((counter++ & 0x01ff) == 0) { - diff_sync >>= 2; /* periodically quarter the wait to resync */ - } - - /* update for next go-around */ - last_sync = this_sync; - - /* snooze until our next retrace */ - - snooze_until(this_sync + diff_sync, B_SYSTEM_TIMEBASE); - } - - ddprintf(("fake_interrupt_thread_func ends with flags = 0x%08lx\n", *flags)); - - /* gotta return something */ - - return B_OK; -} -#endif -#endif - -#if DEBUG > 0 -static int dump(int argc, char **argv) { - int i; - - kprintf("ATIMach64 Kernel Driver Persistant Data\n\nThere are %ld card(s)\n", pd->count); - kprintf("Driver wide benahpore: %ld/%ld\n", pd->kernel.ben, pd->kernel.sem); - - kprintf("Total seen interrupts: %ld\n", pd->total_interrupts); - for (i = 0; i < pd->count; i++) { - device_info *di = &(pd->di[i]); - uint16 device_id = di->pcii.device_id; - shared_info *si = di->si; - kprintf(" device_id: 0x%04x\n", device_id); - kprintf(" interrupt count: %ld\n", di->interrupt_count); - if (si) { - kprintf(" cursor: %d,%d\n", si->cursor.x, si->cursor.y); - kprintf(" flags:"); - if (si->flags & SKD_MOVE_CURSOR) kprintf(" SKD_MOVE_CURSOR"); - if (si->flags & SKD_PROGRAM_CLUT) kprintf(" SKD_PROGRAM_CLUT"); - if (si->flags & SKD_SET_START_ADDR) kprintf(" SKD_SET_START_ADDR"); - kprintf(" vblank semaphore id: %ld\n", si->vblank); - } - } - - - return 1; /* the magic number for success */ -} -#endif - -static status_t open_hook (const char* name, uint32 flags, void** cookie) { - int32 index = 0; - device_info *di; - shared_info *si; -#if SEMAPHORE - thread_id thid; - thread_info thinfo; -#endif - status_t result = B_OK; - vuint32 *regs; - char shared_name[B_OS_NAME_LENGTH]; - - ddprintf(("SKD open_hook(%s, %ld, 0x%08lx)\n", name, flags, (uint32)cookie)); - - /* find the device name in the list of devices */ - /* we're never passed a name we didn't publish */ - while (pd->device_names[index] && (strcmp(name, pd->device_names[index]) != 0)) index++; - - /* for convienience */ - di = &(pd->di[index]); - - /* make sure no one else has write access to the common data */ - AQUIRE_BEN(pd->kernel); - - /* if it's already open for writing */ - if (di->is_open) { - /* mark it open another time */ - goto mark_as_open; - } - /* create the shared area */ - sprintf(shared_name, "%04X_%04X_%02X%02X%02X shared", - di->pcii.vendor_id, di->pcii.device_id, - di->pcii.bus, di->pcii.device, di->pcii.function); - /* create this area with NO user-space read or write permissions, to prevent accidental dammage */ - di->shared_area = create_area(shared_name, (void **)&(di->si), B_ANY_KERNEL_ADDRESS, ((sizeof(shared_info) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1)), B_FULL_LOCK, 0); - if (di->shared_area < 0) { - /* return the error */ - result = di->shared_area; - goto done; - } - - /* save a few dereferences */ - si = di->si; - - /* save the vendor and device IDs */ - si->vendor_id = di->pcii.vendor_id; - si->device_id = di->pcii.device_id; - si->revision = di->pcii.revision; - - - /* map the device */ - result = map_device(di); - - if (result < 0) goto free_shared; - - /* Find registers in memory */ - /* This is the place for 2MB and 8MB boards */ - si->regs = (void *)((unsigned int)si->framebuffer + 0x7ffc00); - if ((unsigned int)si->device_id != (inw(CONFIG_CHIP_ID) & CFG_CHIP_TYPE)) { - /* Try place for 4MB */ - si->regs = (void *)((unsigned int)si->framebuffer + 0x3ffc00); - if (si->device_id != (inw(CONFIG_CHIP_ID) & CFG_CHIP_TYPE)) { - ddprintf(("Registers not found ! \n")); - goto free_shared; - } - } - - /* obtain all information related to the Mach64 */ - - result = GetATIInfo(si); - if (result < 0) goto free_shared; - - - /* create a semaphore for vertical blank management */ -#if SEMAPHORE - si->vblank = create_sem(0, di->name); - if (si->vblank < 0) { - result = si->vblank; - goto unmap; - } -#else - /* No semafore for the moment */ - si->vblank = B_ERROR; -#endif - - /* change the owner of the semaphores to the opener's team */ - /* this is required because apps can't aquire kernel semaphores */ -#if SEMAPHORE - thid = find_thread(NULL); - get_thread_info(thid, &thinfo); - set_sem_owner(si->vblank, thinfo.team); -#endif - - /* assign local regs pointer for ATIMACH64xx() macros */ - regs = di->regs; - - /* disable and clear any pending interrupts */ - -#if SEMAPHORE - /* if we're faking interrupts */ - if ((di->pcii.u.h0.interrupt_pin == 0x00) || (di->pcii.u.h0.interrupt_line == 0xff)){ - /* fake some kind of interrupt with a timer */ - di->can_interrupt = FALSE; - si->flags = SKD_HANDLER_INSTALLED; - si->refresh_period = 16666; /* fake 60Hz to start */ - si->blank_period = si->refresh_period / 20; -#if defined(POST_R4_0) - di->ti_a.di = di; /* refer to ourself */ - di->ti_b.di = di; - di->current_timer = &(di->ti_a); - /* program the first timer interrupt, and it will handle the rest */ - result = add_timer((timer *)(di->current_timer), timer_interrupt_func, si->refresh_period, B_ONE_SHOT_RELATIVE_TIMER); - /* bail if we can't add the timer */ - if (result != B_OK) goto delete_the_sem; -#else */ - /* fake some kind of interrupt with a thread */ - result = di->tid = spawn_kernel_thread(fake_interrupt_thread_func, "SKD fake interrupt", B_REAL_TIME_DISPLAY_PRIORITY, di); - /* bail if we can't spawn the thread */ - if(result < 0) goto delete_the_sem; - /* start up the thread */ - resume_thread(di->tid); - -#endif - } else { - /* otherwise install our interrupt handler */ - result = install_io_interrupt_handler(di->pcii.u.h0.interrupt_line, atimach64_interrupt, (void *)di, 0); - /* bail if we couldn't install the handler */ - if (result != B_OK) goto delete_the_sem; - } -#endif - - mark_as_open: - /* mark the device open */ - di->is_open++; - - /* send the cookie to the opener */ - *cookie = di; - - goto done; - - /* delete_the_sem: */ - delete_sem(si->vblank); - - /* unmap: */ - unmap_device(di); - - free_shared: - /* clean up our shared area */ - delete_area(di->shared_area); - di->shared_area = -1; - di->si = NULL; - - done: - /* end of critical section */ - RELEASE_BEN(pd->kernel); - - /* all done, return the status */ - ddprintf(("open_hook returning 0x%08lx\n", result)); - - return result; -} - -/* ---------- - read_hook - does nothing, gracefully - ----- */ -static status_t -read_hook (void* dev, off_t pos, void* buf, size_t* len) -{ - *len = 0; - return B_NOT_ALLOWED; -} - - -/* ---------- - write_hook - does nothing, gracefully - ----- */ -static status_t -write_hook (void* dev, off_t pos, const void* buf, size_t* len) -{ - *len = 0; - return B_NOT_ALLOWED; -} - -/* ---------- - close_hook - does nothing, gracefully - ----- */ -static status_t -close_hook (void* dev) -{ - ddprintf(("SKD close_hook(%08lx)\n", (uint32)dev)); - /* we don't do anything on close: there might be dup'd fd */ - return B_NO_ERROR; -} - -/* ----------- - free_hook - close down the device - ----------- */ -static status_t -free_hook (void* dev) { - device_info *di = (device_info *)dev; - shared_info *si = di->si; - - ddprintf(("SKD free_hook() begins...\n")); - /* lock the driver */ - AQUIRE_BEN(pd->kernel); - - /* if opened multiple times, decrement the open count and exit */ - if (di->is_open > 1) - goto unlock_and_exit; - -#if SEMAPHORE - /* disable and clear any pending interrupts */ - - - /* if we were faking the interrupts */ - if ((di->pcii.u.h0.interrupt_pin == 0x00) || (di->pcii.u.h0.interrupt_line == 0xff)){ - /* stop our interrupt faking thread */ - si->flags = 0; - di->can_interrupt = FALSE; -#if defined(POST_R4_0) - /* cancel the timer */ - /* we don't know which one is current, so cancel them both and ignore any error */ - cancel_timer((timer *)&(di->ti_a)); - cancel_timer((timer *)&(di->ti_b)); -#else - /* we don't do anything here, as the R4 kernel reaps its own threads */ - /* After R4.0 we can do it ourselves, but we'd rather use timers */ -#endif - /* otherwise */ - } else { - /* remove interrupt handler */ - remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, atimach64_interrupt, di); - } - - /* delete the semaphores, ignoring any errors ('cause the owning team may have died on us) */ - delete_sem(si->vblank); -#endif - si->vblank = -1; - - - /* free regs and framebuffer areas */ - unmap_device(di); - - /* clean up our shared area */ - delete_area(di->shared_area); - di->shared_area = -1; - di->si = NULL; - - unlock_and_exit: - /* mark the device available */ - di->is_open--; - /* unlock the driver */ - RELEASE_BEN(pd->kernel); - ddprintf(("SKD free_hook() ends.\n")); - /* all done */ - return B_OK; -} - -/* ----------- - control_hook - where the real work is done - ----------- */ -static status_t -control_hook (void* dev, uint32 msg, void *buf, size_t len) { - device_info *di = (device_info *)dev; - status_t result = B_DEV_INVALID_IOCTL; - - /* ddprintf(("ioctl: %d, buf: 0x%08x, len: %d\n", msg, buf, len));*/ - switch (msg) { - /* the only PUBLIC ioctl */ - case B_GET_ACCELERANT_SIGNATURE: { - char *sig = (char *)buf; - strcpy(sig, "atimach64vt.accelerant"); - result = B_OK; - } break; - - /* PRIVATE ioctl from here on */ - case ATIMACH64_GET_PRIVATE_DATA: { - atimach64_get_private_data *gpd = (atimach64_get_private_data *)buf; - if (gpd->magic == ATIMACH64_PRIVATE_DATA_MAGIC) { - gpd->shared_info_area = di->shared_area; - result = B_OK; - } - } break; - case ATIMACH64_GET_PCI: { - atimach64_get_set_pci *gsp = (atimach64_get_set_pci *)buf; - if (gsp->magic == ATIMACH64_PRIVATE_DATA_MAGIC) { - pci_info *pcii = &(di->pcii); - gsp->value = get_pci(gsp->offset, gsp->size); - result = B_OK; - } - } break; - case ATIMACH64_SET_PCI: { - atimach64_get_set_pci *gsp = (atimach64_get_set_pci *)buf; - if (gsp->magic == ATIMACH64_PRIVATE_DATA_MAGIC) { - pci_info *pcii = &(di->pcii); - set_pci(gsp->offset, gsp->size, gsp->value); - result = B_OK; - } - } break; - case ATIMACH64_RUN_INTERRUPTS: { - atimach64_set_bool_state *ri = (atimach64_set_bool_state *)buf; - if (ri->magic == ATIMACH64_PRIVATE_DATA_MAGIC) { - /* are we faking interrupts? */ - if ((di->pcii.u.h0.interrupt_pin == 0x00) || (di->pcii.u.h0.interrupt_line == 0xff)){ - di->can_interrupt = ri->do_it; - } else { - vuint32 *regs = di->regs; - if (ri->do_it) { - /* resume interrupts */ - *regs = *regs; /* CHANGE ME */ - } else { - /* disable interrupts */ - *regs = *regs; /* CHANGE ME */ - } - } - result = B_OK; - } - } break; - } - return result; -} diff --git a/src/add-ons/kernel/drivers/graphics/atimach64/m64info.c b/src/add-ons/kernel/drivers/graphics/atimach64/m64info.c deleted file mode 100644 index a7becf4e3c..0000000000 --- a/src/add-ons/kernel/drivers/graphics/atimach64/m64info.c +++ /dev/null @@ -1,256 +0,0 @@ -/* All this code belongs to Linux Xfree86 Project with lots of modifications */ -/* - Rene MacKinney - - 7.May.99 -*/ - -#include -#include "DriverInterface.h" -#include "regmach64.h" -#include "string.h" - -#if DEBUG > 0 -#define ddprintf(a) dprintf a -#else -#define ddprintf(a) -#endif - -status_t -GetATIInfo(si) - shared_info *si; -{ - char signature[] = " 761295520"; - char *bios_data = rommem(0x00); - char bios_signature[10]; - unsigned short *sbios_data = (unsigned short *)bios_data; - int tmp,i,j; - int ROM_Table_Offset; - int Freq_Table_Ptr; - int CDepth_Table_Ptr; - int CTable_Size; - - - if (si->rom == NULL) - return B_ERROR; - - memcpy(bios_signature, rommem(0x30), 10); - - if (strncmp( signature, bios_signature, 10 )) { - ddprintf(("Mach64 probe failed on BIOS signature\n")); - return B_ERROR; - } - - si->board_identifier[0] = bios_data[ 0x40 ]; - si->board_identifier[1] = bios_data[ 0x41 ]; - si->equipment_flags[0] = bios_data[ 0x42 ]; - si->equipment_flags[1] = bios_data[ 0x44 ]; - si->asic_identifier = bios_data[ 0x43 ]; - si->bios_major = bios_data[ 0x4c ]; - si->bios_minor = bios_data[ 0x4d ]; - strncpy( si->bios_date, bios_data + 0x50, 20 ); - - si->VGA_Wonder_Present = bios_data[ 0x44 ] & 0x40; - - si->Mach64_Present = 1; /* Test for Mach64 product */ - - tmp = inw(SCRATCH_REG0); - - - outw(SCRATCH_REG0, 0x55555555); - if (inw(SCRATCH_REG0) != 0x55555555) { - si->Mach64_Present = 0; - ddprintf(("Mach64 probe failed on read 1 of SCRATCH_REG0 %x\n", - SCRATCH_REG0)); - } else { - outw(SCRATCH_REG0, 0xaaaaaaaa); - if (inw(SCRATCH_REG0) != 0xaaaaaaaa) { - si->Mach64_Present = 0; - ddprintf(("Mach64 probe failed on read 2 of SCRATCH_REG0 %x\n", - SCRATCH_REG0)); - } - } - - outw(SCRATCH_REG0, tmp); - - if (!si->Mach64_Present) - return B_ERROR; - - tmp = inw(CONFIG_CHIP_ID); - if (si->device_id != (tmp & CFG_CHIP_TYPE)) { - ddprintf(("%x %x: Mach64 chipset mismatch", - si->device_id, tmp & CFG_CHIP_TYPE)); - return(B_ERROR); - } - - ddprintf(("CONFIG_CHIP_ID reports: %x rev %d\n", - si->device_id, si->revision)); - - tmp = inw(CONFIG_STAT0); - if (si->device_id == MACH64_GX_ID || si->device_id == MACH64_CX_ID) { - si->Bus_Type = tmp & CFG_BUS_TYPE; - si->Mem_Type = (tmp & CFG_MEM_TYPE) >> 3; - si->DAC_Type = (tmp & CFG_INIT_DAC_TYPE) >> 9; - si->DAC_SubType = (inb(SCRATCH_REG1+1) & 0xf0) | si->DAC_Type; - } else { - si->Mem_Type = tmp & CFG_MEM_TYPE_xT; - si->DAC_Type = DAC_INTERNAL; - si->DAC_SubType = DAC_INTERNAL; - - ddprintf(("CONFIG_STAT0 reports mem type %d\n", si->Mem_Type)); - ddprintf(("CONFIG_STAT0 is 0x%08x\n", tmp)); - } - - /* The copy of the registers starts at 0x7ffc00 or 0x3ffc00 depending on the - memory on the card */ - - tmp = inw(MEM_CNTL); - if (si->device_id == MACH64_GX_ID || - si->device_id == MACH64_CX_ID || - si->device_id == MACH64_CT_ID || - si->device_id == MACH64_ET_ID || - ((si->device_id == MACH64_VT_ID || si->device_id == MACH64_GT_ID) && - !(si->revision & 0x07))) { - switch (tmp & MEM_SIZE_ALIAS) { - case MEM_SIZE_512K: - si->mem_size = 512 * 1024; - break; - case MEM_SIZE_1M: - si->mem_size = 1024 * 1024; - break; - case MEM_SIZE_2M: - si->mem_size = 2*1024 * 1024; - break; - case MEM_SIZE_4M: - si->mem_size = 4*1024 * 1024; - break; - case MEM_SIZE_6M: - si->mem_size = 6*1024 * 1024; - break; - case MEM_SIZE_8M: - si->mem_size = 8*1024 * 1024; - break; - } - si->Mem_Size = tmp & MEM_SIZE_ALIAS; - } else { - switch (tmp & MEM_SIZE_ALIAS_GTB) { - case MEM_SIZE_512K: - si->mem_size = 512 * 1024; - break; - case MEM_SIZE_1M: - si->mem_size = 1024 * 1024; - break; - case MEM_SIZE_2M_GTB: - si->mem_size = 2*1024 * 1024; - break; - case MEM_SIZE_4M_GTB: - si->mem_size = 4*1024 * 1024; - break; - case MEM_SIZE_6M_GTB: - si->mem_size = 6*1024 * 1024; - break; - case MEM_SIZE_8M_GTB: - si->mem_size = 8*1024 * 1024; - break; - case MEM_SIZE_16M_GTB: - si->mem_size = 16*1024 * 1024; - break; - } - si->Mem_Size = tmp & MEM_SIZE_ALIAS_GTB; - } - - ddprintf(("Card Reports 0x%08x Memory\n", si->mem_size)); - - ROM_Table_Offset = sbios_data[0x48 >> 1]; - Freq_Table_Ptr = sbios_data[(ROM_Table_Offset >> 1) + 8]; - si->Clock_Type = bios_data[Freq_Table_Ptr]; - - si->MinFreq = sbios_data[(Freq_Table_Ptr >> 1) + 1]; - si->MaxFreq = sbios_data[(Freq_Table_Ptr >> 1) + 2]; - si->RefFreq = sbios_data[(Freq_Table_Ptr >> 1) + 4]; - si->RefDivider = sbios_data[(Freq_Table_Ptr >> 1) + 5]; - si->NAdj = sbios_data[(Freq_Table_Ptr >> 1) + 6]; - si->DRAMMemClk = sbios_data[(Freq_Table_Ptr >> 1) + 8]; - si->VRAMMemClk = sbios_data[(Freq_Table_Ptr >> 1) + 9]; - si->MemClk = bios_data[Freq_Table_Ptr + 22]; - si->CXClk = bios_data[Freq_Table_Ptr + 6]; - - CDepth_Table_Ptr = sbios_data[(Freq_Table_Ptr >> 1) - 3]; - Freq_Table_Ptr = sbios_data[(Freq_Table_Ptr >> 1) - 1]; - - for (i = 0; i < MACH64_NUM_CLOCKS; i++) - si->Clocks[i] = sbios_data[(Freq_Table_Ptr >> 1) + i]; - - si->MemCycle = bios_data[ROM_Table_Offset + 0]; - - CTable_Size = bios_data[CDepth_Table_Ptr - 1]; - for (i = 0, j = 0; - bios_data[CDepth_Table_Ptr + i] != 0; - i += CTable_Size, j++) { - si->Freq_Table[j].h_disp = bios_data[CDepth_Table_Ptr + i]; - si->Freq_Table[j].dacmask = bios_data[CDepth_Table_Ptr + i + 1]; - si->Freq_Table[j].ram_req = bios_data[CDepth_Table_Ptr + i + 2]; - si->Freq_Table[j].max_dot_clock = bios_data[CDepth_Table_Ptr + i + 3]; - si->Freq_Table[j].color_depth = bios_data[CDepth_Table_Ptr + i + 4]; - switch(si->Freq_Table[j].color_depth) { - case 2: /* 8 Bit */ - si->pix_clk_max8 = max(si->pix_clk_max8, si->Freq_Table[j].max_dot_clock); - break; - case 4: /* 16 Bit */ - si->pix_clk_max16 = max(si->pix_clk_max16, si->Freq_Table[j].max_dot_clock); - break; - case 6: /* 8 Bit */ - si->pix_clk_max32 = max(si->pix_clk_max32, si->Freq_Table2[j].max_dot_clock); - break; - } - } - si->Freq_Table[j].h_disp = 0; - - if (bios_data[CDepth_Table_Ptr + i + 1] != 0) { - CDepth_Table_Ptr += i + 2; - CTable_Size = bios_data[CDepth_Table_Ptr - 1]; - for (i = 0, j = 0; - bios_data[CDepth_Table_Ptr + i] != 0; - i += CTable_Size, j++) { - si->Freq_Table2[j].h_disp = bios_data[CDepth_Table_Ptr + i]; - si->Freq_Table2[j].dacmask = bios_data[CDepth_Table_Ptr + i + -1]; - si->Freq_Table2[j].ram_req = bios_data[CDepth_Table_Ptr + i + -2]; - si->Freq_Table2[j].max_dot_clock = bios_data[CDepth_Table_Ptr + i + -3]; - si->Freq_Table2[j].color_depth = bios_data[CDepth_Table_Ptr + i + -4]; - switch(si->Freq_Table[j].color_depth) { - case 2: /* 8 Bit */ - si->pix_clk_max8 = max(si->pix_clk_max8, si->Freq_Table2[j].max_dot_clock); - break; - case 4: /* 16 Bit */ - si->pix_clk_max16 = max(si->pix_clk_max16, si->Freq_Table2[j].max_dot_clock); - break; - case 6: /* 8 Bit */ - si->pix_clk_max32 = max(si->pix_clk_max32, si->Freq_Table2[j].max_dot_clock); - break; - } - } - si->Freq_Table2[j].h_disp = 0; - } else - si->Freq_Table2[0].h_disp = 0; - - /* Hardwired 120000 for 8bpp and 80000 for the rest */ - - ddprintf(("Clocks %ld %ld %ld\n",si->pix_clk_max32, - si->pix_clk_max16, si->pix_clk_max8)); - - - si->pix_clk_max32 = 80000; - si->pix_clk_max16 = 80000; - si->pix_clk_max8 = 120000; - - - ddprintf(("Clocks %ld %ld %ld\n",si->pix_clk_max32, - si->pix_clk_max16, si->pix_clk_max8)); - - - return B_OK; -}