xref: /haiku/src/add-ons/accelerants/s3/accel.cpp (revision c1379d357b3737534088b8e62fe68df6db9f2468)
135db13eaSAxel Dörfler /*
235db13eaSAxel Dörfler 	Copyright 2007-2008 Haiku, Inc.  All rights reserved.
335db13eaSAxel Dörfler 	Distributed under the terms of the MIT license.
435db13eaSAxel Dörfler 
535db13eaSAxel Dörfler 	Authors:
635db13eaSAxel Dörfler 	Gerald Zajac 2007-2008
735db13eaSAxel Dörfler */
835db13eaSAxel Dörfler 
935db13eaSAxel Dörfler #include "accel.h"
1035db13eaSAxel Dörfler 
1135db13eaSAxel Dörfler #include <errno.h>
1235db13eaSAxel Dörfler #include <string.h>
1335db13eaSAxel Dörfler #include <unistd.h>
1435db13eaSAxel Dörfler 
1535db13eaSAxel Dörfler 
1635db13eaSAxel Dörfler 
1735db13eaSAxel Dörfler AccelerantInfo gInfo;		// global data used by various source files of accelerant.
1835db13eaSAxel Dörfler 
1935db13eaSAxel Dörfler 
2035db13eaSAxel Dörfler 
2135db13eaSAxel Dörfler static status_t
InitCommon(int fileDesc)2235db13eaSAxel Dörfler InitCommon(int fileDesc)
2335db13eaSAxel Dörfler {
2435db13eaSAxel Dörfler 	// Initialization function used by primary and cloned accelerants.
2535db13eaSAxel Dörfler 
2635db13eaSAxel Dörfler 	gInfo.deviceFileDesc = fileDesc;
2735db13eaSAxel Dörfler 
2835db13eaSAxel Dörfler 	// Get pointer to registers and shared data from driver.
2935db13eaSAxel Dörfler 
3035db13eaSAxel Dörfler 	S3GetPrivateData gpd;
3135db13eaSAxel Dörfler 	gpd.magic = S3_PRIVATE_DATA_MAGIC;
3235db13eaSAxel Dörfler 
3335db13eaSAxel Dörfler 	status_t result = ioctl(gInfo.deviceFileDesc, S3_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
3435db13eaSAxel Dörfler 	if (result != B_OK)
3535db13eaSAxel Dörfler 		return result;
3635db13eaSAxel Dörfler 
3735db13eaSAxel Dörfler 	gInfo.sharedInfoArea = clone_area("S3 shared info", (void**)&(gInfo.sharedInfo),
3835db13eaSAxel Dörfler 		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gpd.sharedInfoArea);
3935db13eaSAxel Dörfler 	if (gInfo.sharedInfoArea < 0)
4035db13eaSAxel Dörfler 		return gInfo.sharedInfoArea;	// sharedInfoArea has error code
4135db13eaSAxel Dörfler 
4235db13eaSAxel Dörfler 	gInfo.regsArea = clone_area("S3 regs area", (void**)&(gInfo.regs),
4335db13eaSAxel Dörfler 		B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, gInfo.sharedInfo->regsArea);
4435db13eaSAxel Dörfler 	if (gInfo.regsArea < 0) {
4535db13eaSAxel Dörfler 		delete_area(gInfo.sharedInfoArea);
4635db13eaSAxel Dörfler 		return gInfo.regsArea;		// regsArea has error code
4735db13eaSAxel Dörfler 	}
4835db13eaSAxel Dörfler 
4935db13eaSAxel Dörfler 	// Set pointers to various device specific functions.
5035db13eaSAxel Dörfler 
5135db13eaSAxel Dörfler 	if (S3_SAVAGE_FAMILY(gInfo.sharedInfo->chipType))
5235db13eaSAxel Dörfler 		Savage_SetFunctionPointers();
5335db13eaSAxel Dörfler 	else if (S3_TRIO64_FAMILY(gInfo.sharedInfo->chipType))
5435db13eaSAxel Dörfler 		Trio64_SetFunctionPointers();
5535db13eaSAxel Dörfler 	else if (S3_VIRGE_FAMILY(gInfo.sharedInfo->chipType))
5635db13eaSAxel Dörfler 		Virge_SetFunctionPointers();
5735db13eaSAxel Dörfler 	else
5835db13eaSAxel Dörfler 		return B_ERROR;		// undefined chip type code
5935db13eaSAxel Dörfler 
6035db13eaSAxel Dörfler 	return B_OK;
6135db13eaSAxel Dörfler }
6235db13eaSAxel Dörfler 
6335db13eaSAxel Dörfler 
6435db13eaSAxel Dörfler static void
UninitCommon(void)6535db13eaSAxel Dörfler UninitCommon(void)
6635db13eaSAxel Dörfler {
6735db13eaSAxel Dörfler 	// This function is used by both primary and cloned accelerants.
6835db13eaSAxel Dörfler 
6935db13eaSAxel Dörfler 	delete_area(gInfo.regsArea);
7035db13eaSAxel Dörfler 	gInfo.regs = 0;
7135db13eaSAxel Dörfler 
7235db13eaSAxel Dörfler 	delete_area(gInfo.sharedInfoArea);
7335db13eaSAxel Dörfler 	gInfo.sharedInfo = 0;
7435db13eaSAxel Dörfler }
7535db13eaSAxel Dörfler 
7635db13eaSAxel Dörfler 
7735db13eaSAxel Dörfler status_t
InitAccelerant(int fileDesc)7835db13eaSAxel Dörfler InitAccelerant(int fileDesc)
7935db13eaSAxel Dörfler {
8035db13eaSAxel Dörfler 	// Initialize the accelerant.	fileDesc is the file handle of the device
8135db13eaSAxel Dörfler 	// (in /dev/graphics) that has been opened by the app_server.
8235db13eaSAxel Dörfler 
8335db13eaSAxel Dörfler 	TRACE("Enter InitAccelerant()\n");
8435db13eaSAxel Dörfler 
8535db13eaSAxel Dörfler 	gInfo.bAccelerantIsClone = false;		// indicate this is primary accelerant
8635db13eaSAxel Dörfler 
8735db13eaSAxel Dörfler 	status_t result = InitCommon(fileDesc);
8835db13eaSAxel Dörfler 	if (result == B_OK) {
8935db13eaSAxel Dörfler 		SharedInfo& si = *gInfo.sharedInfo;
9035db13eaSAxel Dörfler 
9135db13eaSAxel Dörfler 		TRACE("Vendor ID: 0x%X,  Device ID: 0x%X\n", si.vendorID, si.deviceID);
9235db13eaSAxel Dörfler 
9335db13eaSAxel Dörfler 		// Ensure that InitAccelerant is executed just once (copies should be clones)
9435db13eaSAxel Dörfler 
9535db13eaSAxel Dörfler 		if (si.bAccelerantInUse) {
9635db13eaSAxel Dörfler 			result = B_NOT_ALLOWED;
9735db13eaSAxel Dörfler 		} else {
9835db13eaSAxel Dörfler 			result = gInfo.ChipInit();	// perform init related to current chip
9935db13eaSAxel Dörfler 			if (result == B_OK) {
100*c1379d35SAxel Dörfler 				result = si.engineLock.Init("ATI engine lock");
101*c1379d35SAxel Dörfler 				if (result == B_OK) {
102*c1379d35SAxel Dörfler 					if (gInfo.ShowCursor != NULL)
10335db13eaSAxel Dörfler 						gInfo.ShowCursor(false);
10435db13eaSAxel Dörfler 
105*c1379d35SAxel Dörfler 					// ensure that this function won't be executed again
106*c1379d35SAxel Dörfler 					// (copies should be clones)
10735db13eaSAxel Dörfler 					si.bAccelerantInUse = true;
10835db13eaSAxel Dörfler 				}
10935db13eaSAxel Dörfler 			}
110*c1379d35SAxel Dörfler 		}
11135db13eaSAxel Dörfler 
11235db13eaSAxel Dörfler 		if (result != B_OK)
11335db13eaSAxel Dörfler 			UninitCommon();
11435db13eaSAxel Dörfler 	}
11535db13eaSAxel Dörfler 
11635db13eaSAxel Dörfler 	TRACE("Leave InitAccelerant(), result: 0x%X\n", result);
11735db13eaSAxel Dörfler 	return result;
11835db13eaSAxel Dörfler }
11935db13eaSAxel Dörfler 
12035db13eaSAxel Dörfler 
12135db13eaSAxel Dörfler ssize_t
AccelerantCloneInfoSize(void)12235db13eaSAxel Dörfler AccelerantCloneInfoSize(void)
12335db13eaSAxel Dörfler {
12435db13eaSAxel Dörfler 	// Return the number of bytes required to hold the information required
12535db13eaSAxel Dörfler 	// to clone the device.  The information is merely the name of the device;
12635db13eaSAxel Dörfler 	// thus, return the size of the name buffer.
12735db13eaSAxel Dörfler 
12835db13eaSAxel Dörfler 	return B_OS_NAME_LENGTH;
12935db13eaSAxel Dörfler }
13035db13eaSAxel Dörfler 
13135db13eaSAxel Dörfler 
13235db13eaSAxel Dörfler void
GetAccelerantCloneInfo(void * data)13335db13eaSAxel Dörfler GetAccelerantCloneInfo(void* data)
13435db13eaSAxel Dörfler {
13535db13eaSAxel Dörfler 	// Return the info required to clone the device.  Argument data points to
13635db13eaSAxel Dörfler 	// a buffer which is the size returned by AccelerantCloneInfoSize().
13735db13eaSAxel Dörfler 
13835db13eaSAxel Dörfler 	ioctl(gInfo.deviceFileDesc, S3_DEVICE_NAME, data, B_OS_NAME_LENGTH);
13935db13eaSAxel Dörfler }
14035db13eaSAxel Dörfler 
14135db13eaSAxel Dörfler 
14235db13eaSAxel Dörfler status_t
CloneAccelerant(void * data)14335db13eaSAxel Dörfler CloneAccelerant(void* data)
14435db13eaSAxel Dörfler {
14535db13eaSAxel Dörfler 	// Initialize a copy of the accelerant as a clone.  Argument data points to
14635db13eaSAxel Dörfler 	// a copy of the data which was returned by GetAccelerantCloneInfo().
14735db13eaSAxel Dörfler 
14835db13eaSAxel Dörfler 	TRACE("Enter CloneAccelerant()\n");
14935db13eaSAxel Dörfler 
15035db13eaSAxel Dörfler 	char path[MAXPATHLEN] = "/dev/";
15135db13eaSAxel Dörfler 	strcat(path, (const char*)data);
15235db13eaSAxel Dörfler 
15335db13eaSAxel Dörfler 	gInfo.deviceFileDesc = open(path, B_READ_WRITE);	// open the device
15435db13eaSAxel Dörfler 	if (gInfo.deviceFileDesc < 0)
15535db13eaSAxel Dörfler 		return errno;
15635db13eaSAxel Dörfler 
15735db13eaSAxel Dörfler 	gInfo.bAccelerantIsClone = true;
15835db13eaSAxel Dörfler 
15935db13eaSAxel Dörfler 	status_t result = InitCommon(gInfo.deviceFileDesc);
16035db13eaSAxel Dörfler 	if (result != B_OK) {
16135db13eaSAxel Dörfler 		close(gInfo.deviceFileDesc);
16235db13eaSAxel Dörfler 		return result;
16335db13eaSAxel Dörfler 	}
16435db13eaSAxel Dörfler 
16535db13eaSAxel Dörfler 	result = gInfo.modeListArea = clone_area("S3 cloned display_modes",
16635db13eaSAxel Dörfler 		(void**) &gInfo.modeList, B_ANY_ADDRESS, B_READ_AREA,
16735db13eaSAxel Dörfler 		gInfo.sharedInfo->modeArea);
16835db13eaSAxel Dörfler 	if (result < 0) {
16935db13eaSAxel Dörfler 		UninitCommon();
17035db13eaSAxel Dörfler 		close(gInfo.deviceFileDesc);
17135db13eaSAxel Dörfler 		return result;
17235db13eaSAxel Dörfler 	}
17335db13eaSAxel Dörfler 
17435db13eaSAxel Dörfler 	TRACE("Leave CloneAccelerant()\n");
17535db13eaSAxel Dörfler 	return B_OK;
17635db13eaSAxel Dörfler }
17735db13eaSAxel Dörfler 
17835db13eaSAxel Dörfler 
17935db13eaSAxel Dörfler void
UninitAccelerant(void)18035db13eaSAxel Dörfler UninitAccelerant(void)
18135db13eaSAxel Dörfler {
18235db13eaSAxel Dörfler 	delete_area(gInfo.modeListArea);
18335db13eaSAxel Dörfler 	gInfo.modeList = NULL;
18435db13eaSAxel Dörfler 
18535db13eaSAxel Dörfler 	UninitCommon();
18635db13eaSAxel Dörfler 
18735db13eaSAxel Dörfler 	if (gInfo.bAccelerantIsClone)
18835db13eaSAxel Dörfler 		close(gInfo.deviceFileDesc);
18935db13eaSAxel Dörfler }
19035db13eaSAxel Dörfler 
19135db13eaSAxel Dörfler 
19235db13eaSAxel Dörfler sem_id
AccelerantRetraceSemaphore(void)19335db13eaSAxel Dörfler AccelerantRetraceSemaphore(void)
19435db13eaSAxel Dörfler {
19535db13eaSAxel Dörfler 	// Return the semaphore id that will be used to signal that a vertical
19635db13eaSAxel Dörfler 	// retrace occured.
19735db13eaSAxel Dörfler 
19835db13eaSAxel Dörfler 	return B_ERROR;
19935db13eaSAxel Dörfler }
20035db13eaSAxel Dörfler 
20135db13eaSAxel Dörfler 
20235db13eaSAxel Dörfler status_t
GetAccelerantDeviceInfo(accelerant_device_info * adi)20335db13eaSAxel Dörfler GetAccelerantDeviceInfo(accelerant_device_info* adi)
20435db13eaSAxel Dörfler {
20535db13eaSAxel Dörfler 	// Get info about the device.
20635db13eaSAxel Dörfler 
20735db13eaSAxel Dörfler 	SharedInfo& si = *gInfo.sharedInfo;
20835db13eaSAxel Dörfler 
20935db13eaSAxel Dörfler 	adi->version = 1;
21035db13eaSAxel Dörfler 	strcpy(adi->name, "S3 chipset");
21135db13eaSAxel Dörfler 	strcpy(adi->chipset, si.chipName);
21235db13eaSAxel Dörfler 	strcpy(adi->serial_no, "unknown");
21335db13eaSAxel Dörfler 	adi->memory = si.maxFrameBufferSize;
21435db13eaSAxel Dörfler 	adi->dac_speed = 270;
21535db13eaSAxel Dörfler 
21635db13eaSAxel Dörfler 	return B_OK;
21735db13eaSAxel Dörfler }
218