Copyright (c) 2002, Thomas Kurschel
Part of Radeon accelerant
Main init/uninit functions
*/
#include "GlobalData.h"
#include "generic.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include "CP.h"
static status_t init_common( int the_fd, bool accelerant_is_clone )
{
status_t result;
radeon_get_private_data gpd;
SHOW_FLOW0( 3, "" );
ai = malloc( sizeof( *ai ));
if( ai == NULL )
return B_NO_MEMORY;
memset( ai, 0, sizeof( *ai ));
ai->accelerant_is_clone = accelerant_is_clone;
ai->fd = the_fd;
gpd.magic = RADEON_PRIVATE_DATA_MAGIC;
result = ioctl( ai->fd, RADEON_GET_PRIVATE_DATA, &gpd, sizeof(gpd) );
if (result != B_OK) goto err;
ai->virtual_card_area = clone_area( "Radeon virtual card", (void **)&ai->vc, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, gpd.virtual_card_area );
if( ai->virtual_card_area < 0 ) {
result = ai->virtual_card_area;
goto err;
}
ai->shared_info_area = clone_area( "Radeon shared info", (void **)&ai->si, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area );
if( ai->shared_info_area < 0 ) {
result = ai->shared_info_area;
goto err2;
}
ai->regs_area = clone_area( "Radeon regs area", (void **)&ai->regs, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, ai->si->regs_area );
if( ai->regs_area < 0 ) {
result = ai->regs_area;
goto err3;
}
if( ai->si->memory[mt_PCI].area > 0 ) {
ai->mapped_memory[mt_PCI].area = clone_area( "Radeon PCI GART area",
(void **)&ai->mapped_memory[mt_PCI].data, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, ai->si->memory[mt_PCI].area );
if( ai->mapped_memory[mt_PCI].area < 0 ) {
result = ai->mapped_memory[mt_PCI].area;
goto err4;
}
}
if( ai->si->memory[mt_AGP].area > 0 ) {
ai->mapped_memory[mt_AGP].area = clone_area( "Radeon AGP GART area",
(void **)&ai->mapped_memory[mt_AGP].data, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, ai->si->memory[mt_AGP].area );
if( ai->mapped_memory[mt_AGP].area < 0 ) {
result = ai->mapped_memory[mt_AGP].area;
goto err5;
}
}
ai->mapped_memory[mt_nonlocal] = ai->mapped_memory[ai->si->nonlocal_type];
ai->mapped_memory[mt_local].data = ai->si->local_mem;
return B_OK;
err5:
if( ai->mapped_memory[mt_PCI].area > 0 )
delete_area( ai->mapped_memory[mt_PCI].area );
err4:
delete_area( ai->regs_area );
err3:
delete_area( ai->shared_info_area );
err2:
delete_area( ai->virtual_card_area );
err:
free( ai );
return result;
}
static void uninit_common( void )
{
if( !ai->accelerant_is_clone ) {
if ( ai->si->acc_dma )
Radeon_FreeVirtualCardStateBuffer( ai );
Radeon_WaitForIdle( ai, false );
}
if( ai->mapped_memory[mt_AGP].area > 0 )
delete_area( ai->mapped_memory[mt_AGP].area );
if( ai->mapped_memory[mt_PCI].area > 0 )
delete_area( ai->mapped_memory[mt_PCI].area );
delete_area( ai->regs_area );
delete_area( ai->shared_info_area );
delete_area( ai->virtual_card_area );
ai->regs_area = ai->shared_info_area = ai->virtual_card_area = 0;
ai->regs = 0;
ai->si = 0;
ai->vc = 0;
if( ai->accelerant_is_clone )
close( ai->fd );
free( ai );
}
status_t INIT_ACCELERANT( int the_fd )
{
shared_info *si;
virtual_card *vc;
status_t result;
SHOW_FLOW0( 3, "" );
result = init_common( the_fd, 0 );
if (result != B_OK)
goto err;
si = ai->si;
vc = ai->vc;
if( result != B_OK )
goto err2;*/
Radeon_ReadSettings( vc );
Radeon_DetectTVOut( ai );
Radeon_DetectDisplays( ai );
result = Radeon_CreateModeList( si );
if (result != B_OK)
goto err3;
(void)INIT_BEN( si->engine.lock, "Radeon engine" );
si->engine.last_idle = si->engine.count = 0;
si->engine.written = -1;
si->overlay_mgr.token = 0;
si->overlay_mgr.inuse = 0;
si->active_overlay.crtc_idx = -1;
si->pending_overlay.crtc_idx = -1;
vc->overlay_buffers = NULL;
if ( ai->si->acc_dma )
Radeon_AllocateVirtualCardStateBuffer( ai );
return B_OK;
err3:
uninit_common();
err:
return result;
}
ssize_t ACCELERANT_CLONE_INFO_SIZE( void )
{
SHOW_FLOW0( 0, "" );
return MAX_RADEON_DEVICE_NAME_LENGTH;
}
void GET_ACCELERANT_CLONE_INFO( void *data )
{
radeon_device_name dn;
status_t result;
SHOW_FLOW0( 0, "" );
dn.magic = RADEON_PRIVATE_DATA_MAGIC;
dn.name = (char *)data;
result = ioctl( ai->fd, RADEON_DEVICE_NAME, &dn, sizeof(dn) );
}
status_t CLONE_ACCELERANT( void *data )
{
status_t result;
char path[MAXPATHLEN];
int fd;
SHOW_FLOW0( 0, "" );
strcpy(path, "/dev/");
strcat(path, (const char *)data);
fd = open(path, B_READ_WRITE);
if( fd < 0 )
return errno;
result = init_common( fd, 1 );
if( result != B_OK )
goto err1;
result = ai->mode_list_area = clone_area(
"Radeon cloned display_modes", (void **)&ai->mode_list,
B_ANY_ADDRESS, B_READ_AREA, ai->si->mode_list_area );
if (result < B_OK)
goto err2;
return B_OK;
err2:
uninit_common();
err1:
close( fd );
return result;
}
void UNINIT_ACCELERANT( void )
{
SHOW_FLOW0( 0, "" );
delete_area( ai->mode_list_area );
ai->mode_list = 0;
uninit_common();
}
status_t GET_ACCELERANT_DEVICE_INFO( accelerant_device_info *di )
{
SHOW_FLOW0( 0, "" );
di->version = B_ACCELERANT_VERSION;
strcpy( di->name, "Radeon" );
strcpy( di->chipset, "Radeon" );
strcpy( di->serial_no, "None" );
di->memory = ai->si->memory[mt_local].size;
di->dac_speed = ai->si->pll.max_pll_freq;
return B_OK;
}