Patch by Euan Kirkhope:

* option for PIO engine instead of DMA (for dodgy X700s)
* misc RAM config changes inline with x.org codebase


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20273 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-03-01 09:28:25 +00:00
parent 300bef5821
commit a85694c375
17 changed files with 716 additions and 235 deletions

View File

@ -20,7 +20,8 @@
#include "ddc.h"
// magic code for ioctls
#define RADEON_PRIVATE_DATA_MAGIC 'TKRA'
// changed from TKRA to TKR1 for RADEON_WAITFORFIFO ioctl
#define RADEON_PRIVATE_DATA_MAGIC 'TKR1'
#define MAX_RADEON_DEVICE_NAME_LENGTH MAXPATHLEN
@ -35,6 +36,7 @@ enum {
RADEON_FREE_MEM,
RADEON_WAITFORIDLE,
RADEON_WAITFORFIFO,
RADEON_RESETENGINE,
RADEON_VIPREAD,
RADEON_VIPWRITE,
@ -396,6 +398,7 @@ typedef struct {
typedef struct {
// filled out by kernel
CP_info cp; // info concerning command processor
bool acc_dma; // prevent use of dma engine
// set by accelerant
struct {
@ -499,6 +502,12 @@ typedef struct {
bool keep_lock; // keep lock after engine is idle
} radeon_wait_for_idle;
// wait for idle
typedef struct {
uint32 magic;
int entries; // keep lock after engine is idle
} radeon_wait_for_fifo;
// read VIP register
typedef struct {
uint32 magic;

View File

@ -8,4 +8,4 @@
*/
// current version
#define RADEON_DRIVER_VERSION "Version: 5.1.2.1"
#define RADEON_DRIVER_VERSION "Version: 5.1.3.1"

View File

@ -13,6 +13,7 @@
#include "generic.h"
#include "3d_regs.h"
#include "2d_regs.h"
#include "radeon_regs.h"
#include "mmio.h"
#include "CP.h"
@ -21,7 +22,7 @@
// et - ignored
// list - list of rectangles
// count - number of rectangles
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
@ -55,13 +56,63 @@ void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
++ai->si->engine.count;
}
#define SRC_DSTCOLOR 0x00030000
#define DP_SRC_RECT 0x00000200
void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count)
{
int xdir;
int ydir;
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo ( ai , 1 );
// Setup for Screen to screen blit
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT
| RADEON_GMC_BRUSH_NONE
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_SRC_PITCH_OFFSET_CNTL));
for( ; count > 0; --count, ++list ) {
// make sure there is space in the FIFO for 4 register writes
Radeon_WaitForFifo ( ai , 4 );
xdir = ((list->src_left < list->dest_left) && (list->src_top == list->dest_top)) ? -1 : 1;
ydir = (list->src_top < list->dest_top) ? -1 : 1;
if (xdir < 0) list->src_left += list->width , list->dest_left += list->width ;
if (ydir < 0) list->src_top += list->height , list->dest_top += list->height ;
OUTREG(ai->regs, RADEON_DP_CNTL, ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0)
| (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
// Tell the engine where the source data resides.
OUTREG( ai->regs, RADEON_SRC_Y_X, (list->src_top << 16 ) | list->src_left);
OUTREG( ai->regs, RADEON_DST_Y_X, (list->dest_top << 16 ) | list->dest_left);
// this is the blt initiator.
OUTREG( ai->regs, RADEON_DST_HEIGHT_WIDTH, ((list->height + 1) << 16 ) | (list->width + 1));
}
++ai->si->engine.count;
et = et;
}
// fill rectangles on screen
// et - ignored
// colorIndex - fill colour
// list - list of rectangles
// count - number of rectangles
void FILL_RECTANGLE(engine_token *et, uint32 colorIndex,
void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
@ -98,11 +149,47 @@ void FILL_RECTANGLE(engine_token *et, uint32 colorIndex,
}
// fill rectangles on screen
// et - ignored
// colorIndex - fill colour
// list - list of rectangles
// count - number of rectangles
#define BRUSH_SOLIDCOLOR 0x00000d00
void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW( 4, "colorIndex", colorIndex);
Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P));
// Set brush colour
OUTREG(ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list )
{
Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
}
++ai->si->engine.count;
et = et;
}
// invert rectangle on screen
// et - ignored
// list - list of rectangles
// count - number of rectangles
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
@ -151,12 +238,41 @@ void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
++ai->si->engine.count;
}
void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_NONE
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_Dn
| RADEON_DP_SRC_SOURCE_MEMORY));
OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list )
{
Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
}
++ai->si->engine.count;
et = et;
}
// fill horizontal spans on screen
// et - ignored
// colorIndex - fill colour
// list - list of spans
// count - number of spans
void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
virtual_card *vc = ai->vc;
@ -196,72 +312,181 @@ void FILL_SPAN(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
}
// fill horizontal spans on screen
// et - ignored
// colorIndex - fill colour
// list - list of spans
// count - number of spans
void FILL_SPAN_PIO(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
virtual_card *vc = ai->vc;
//int offset = 0;
uint16 y, x, width;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, 0
| RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P);
if ( ai->si->asic >= rt_rv200 ) {
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT);
}
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
for( ; count > 0; --count ) {
Radeon_WaitForFifo( ai , 2);
y = *list++;
x = *list++;
width = *list++ - x + 1;
OUTREG( ai->regs, RADEON_DST_LINE_START, (y << 16) | x);
OUTREG( ai->regs, RADEON_DST_LINE_END, ((y) << 16) | (x + width));
}
++ai->si->engine.count;
et = et;
}
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
{
if ( ai->si->acc_dma )
SCREEN_TO_SCREEN_BLIT_DMA(et,list,count);
else
SCREEN_TO_SCREEN_BLIT_PIO(et,list,count);
}
void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
{
if ( ai->si->acc_dma )
FILL_RECTANGLE_DMA(et, color, list, count);
else
FILL_RECTANGLE_PIO(et, color, list, count);
}
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
{
if ( ai->si->acc_dma )
INVERT_RECTANGLE_DMA(et, list, count);
else
INVERT_RECTANGLE_PIO(et, list, count);
}
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count)
{
if ( ai->si->acc_dma )
FILL_SPAN_DMA(et, color, list, count);
else
FILL_SPAN_PIO(et, color, list, count);
}
// prepare 2D acceleration
void Radeon_Init2D( accelerator_info *ai )
{
SHOW_FLOW0( 3, "" );
START_IB();
// forget about 3D
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
SUBMIT_IB();
if ( ai->si->acc_dma ) {
START_IB();
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
SUBMIT_IB();
}
else {
OUTREG( ai->regs, RADEON_RB3D_CNTL, 0 );
}
}
// fill state buffer that sets 2D registers up for accelerated operations
void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
{
virtual_card *vc = ai->vc;
uint32 pitch_offset;
uint32 *buffer, *buffer_start;
uint32 *buffer = NULL, *buffer_start = NULL;
SHOW_FLOW0( 4, "" );
// make sure buffer is not used
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
// set offset of frame buffer and pitch
pitch_offset =
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
((vc->pitch >> 6) << 22);
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
// no siccors
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
// setup general flags - perhaps this is not needed as all
// 2D commands contain this register
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS );
if ( ai->si->acc_dma ) {
// make sure buffer is not used
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
// most of this init is probably not nessacary
// as we neither draw lines nor use brushes
WRITE_IB_REG( RADEON_DST_LINE_START, 0);
WRITE_IB_REG( RADEON_DST_LINE_END, 0);
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
// no sissors
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
// general fluff
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS );
// most of this init is probably not necessary
// as we neither draw lines nor use brushes
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
// this is required
vc->state_buffer_size = buffer - buffer_start;
vc->state_buffer_size = buffer - buffer_start;
} else {
Radeon_WaitForFifo( ai, 10 );
OUTREG( ai->regs, RADEON_DEFAULT_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_DST_PITCH_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_SRC_PITCH_OFFSET, pitch_offset );
// no sissors
OUTREG( ai->regs, RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
| RADEON_DEFAULT_SC_BOTTOM_MAX));
// general fluff
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS );
// most of this init is probably not necessary
// as we neither draw lines nor use brushes
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
OUTREG( ai->regs, RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
OUTREG( ai->regs, RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
OUTREG( ai->regs, RADEON_DP_SRC_BKGD_CLR, 0x00000000);
OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff);
}
ai->si->active_vc = vc->id;
}

View File

@ -65,21 +65,30 @@ static void writeSyncToken( accelerator_info *ai )
if( ai->si->engine.count == ai->si->engine.written )
return;
START_IB();
// flush pending data
WRITE_IB_REG( RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL );
if( ai->si->acc_dma ) {
START_IB();
// make sure commands are finished
WRITE_IB_REG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN |
RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN );
// flush pending data
WRITE_IB_REG( RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL );
// write scratch register
WRITE_IB_REG( RADEON_SCRATCH_REG0, ai->si->engine.count );
ai->si->engine.written = ai->si->engine.count;
SUBMIT_IB();
// make sure commands are finished
WRITE_IB_REG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN |
RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN );
// write scratch register
WRITE_IB_REG( RADEON_SCRATCH_REG0, ai->si->engine.count );
ai->si->engine.written = ai->si->engine.count;
SUBMIT_IB();
} else {
Radeon_WaitForFifo( ai, 2 );
OUTREG( ai->regs, RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL);
OUTREG( ai->regs, RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN |
RADEON_WAIT_3D_IDLECLEAN |
RADEON_WAIT_HOST_IDLECLEAN);
ai->si->engine.written = ai->si->engine.count;
}
}
// public function: acquire engine for future use
@ -178,6 +187,13 @@ status_t SYNC_TO_TOKEN( sync_token *st )
SHOW_FLOW0( 4, "" );
if ( !ai->si->acc_dma )
{
Radeon_WaitForFifo( ai, 64 );
Radeon_WaitForIdle( ai, false );
return B_OK;
}
start_time = system_time();
while( 1 ) {

View File

@ -111,7 +111,8 @@ err:
static void uninit_common( void )
{
if( !ai->accelerant_is_clone ) {
Radeon_FreeVirtualCardStateBuffer( ai );
if ( ai->si->acc_dma )
Radeon_FreeVirtualCardStateBuffer( ai );
// the last accelerant should must wait for the card to become quite,
// else some nasty command could lunger in some FIFO
@ -200,7 +201,8 @@ status_t INIT_ACCELERANT( int the_fd )
// mark engine as having no state
//si->cp.active_state_buffer = -1;
Radeon_AllocateVirtualCardStateBuffer( ai );
if ( ai->si->acc_dma )
Radeon_AllocateVirtualCardStateBuffer( ai );
// everything else is initialized upon set_display_mode
return B_OK;

View File

@ -23,6 +23,27 @@ status_t Radeon_WaitForIdle( accelerator_info *ai, bool keep_lock )
return ioctl( ai->fd, RADEON_WAITFORIDLE, &wfi, sizeof( wfi ));
}
// wait until "entries" FIFO entries are empty
// lock must be hold
status_t Radeon_WaitForFifo( accelerator_info *ai, int entries )
{
while( 1 ) {
bigtime_t start_time = system_time();
do {
int slots = INREG( ai->regs, RADEON_RBBM_STATUS ) & RADEON_RBBM_FIFOCNT_MASK;
if ( slots >= entries )
return B_OK;
snooze( 1 );
} while( system_time() - start_time < 1000000 );
Radeon_ResetEngine( ai );
}
return B_ERROR;
}
void Radeon_ResetEngine( accelerator_info *ai )
{

View File

@ -49,6 +49,18 @@ void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count);
void FILL_RECTANGLE_DMA(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count);
void FILL_SPAN_DMA(engine_token *et, uint32 color, uint16 *list, uint32 count);
void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count);
void FILL_RECTANGLE_PIO(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count);
void FILL_SPAN_PIO(engine_token *et, uint32 color, uint16 *list, uint32 count);
uint32 OVERLAY_COUNT(const display_mode *dm);
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm);
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space);

View File

@ -973,17 +973,27 @@ static void Radeon_ReplaceOverlayBuffer(
shared_info *si = ai->si;
uint32 offset;
START_IB();
offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;
WRITE_IB_REG( RADEON_OV0_VID_BUF0_BASE_ADRS, offset);
si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;
WRITE_IB_REG( RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );
SUBMIT_IB();
if ( ai->si->acc_dma )
{
START_IB();
offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;
WRITE_IB_REG( RADEON_OV0_VID_BUF0_BASE_ADRS, offset);
si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;
WRITE_IB_REG( RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );
SUBMIT_IB();
} else {
Radeon_WaitForFifo( ai, 2 );
offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;
OUTREG( ai->regs, RADEON_OV0_VID_BUF0_BASE_ADRS, offset);
si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;
OUTREG( ai->regs, RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );
}
ai->si->active_overlay.on = ai->si->pending_overlay.on;
#endif
}

View File

@ -13,33 +13,41 @@
#include "GlobalData.h"
#include "dac_regs.h"
#include "mmio.h"
#include "CP.h"
#include "generic.h"
// Radeon's DACs share same public registers, this function
// selects the DAC you'll talk to
#define selectPalette( crtc_idx ) \
WRITE_IB_REG( RADEON_DAC_CNTL2, \
(crtc_idx == 0 ? 0 : RADEON_DAC2_PALETTE_ACC_CTL) | \
(ai->si->dac_cntl2 & ~RADEON_DAC2_PALETTE_ACC_CTL) );
// set standard colour palette (needed for non-palette modes)
void Radeon_InitPalette(
accelerator_info *ai, int crtc_idx )
{
int i;
START_IB();
selectPalette( crtc_idx );
WRITE_IB_REG( RADEON_PALETTE_INDEX, 0 );
for( i = 0; i < 256; ++i )
WRITE_IB_REG( RADEON_PALETTE_DATA, (i << 16) | (i << 8) | i );
if ( ai->si->acc_dma ) {
START_IB();
SUBMIT_IB();
WRITE_IB_REG( RADEON_DAC_CNTL2,
(crtc_idx == 0 ? 0 : RADEON_DAC2_PALETTE_ACC_CTL) |
(ai->si->dac_cntl2 & ~RADEON_DAC2_PALETTE_ACC_CTL) );
WRITE_IB_REG( RADEON_PALETTE_INDEX, 0 );
for( i = 0; i < 256; ++i )
WRITE_IB_REG( RADEON_PALETTE_DATA, (i << 16) | (i << 8) | i );
SUBMIT_IB();
} else {
Radeon_WaitForFifo ( ai , 1 );
OUTREG( ai->regs, RADEON_DAC_CNTL2,
(crtc_idx == 0 ? 0 : RADEON_DAC2_PALETTE_ACC_CTL) |
(ai->si->dac_cntl2 & ~RADEON_DAC2_PALETTE_ACC_CTL) );
OUTREG( ai->regs, RADEON_PALETTE_INDEX, 0 );
for( i = 0; i < 256; ++i ) {
Radeon_WaitForFifo ( ai , 1 ); // TODO FIXME good god this is gonna be slow...
OUTREG( ai->regs, RADEON_PALETTE_DATA, (i << 16) | (i << 8) | i );
}
}
}
static void setPalette(
@ -75,17 +83,35 @@ static void setPalette(
{
uint i;
START_IB();
selectPalette( crtc_idx );
WRITE_IB_REG( RADEON_PALETTE_INDEX, first );
for( i = 0; i < count; ++i, color_data += 3 )
WRITE_IB_REG( RADEON_PALETTE_DATA,
((uint32)color_data[0] << 16) |
((uint32)color_data[1] << 8) |
color_data[2] );
SUBMIT_IB();
if ( ai->si->acc_dma ) {
START_IB();
WRITE_IB_REG( RADEON_DAC_CNTL2,
(crtc_idx == 0 ? 0 : RADEON_DAC2_PALETTE_ACC_CTL) |
(ai->si->dac_cntl2 & ~RADEON_DAC2_PALETTE_ACC_CTL) );
WRITE_IB_REG( RADEON_PALETTE_INDEX, first );
for( i = 0; i < count; ++i, color_data += 3 )
WRITE_IB_REG( RADEON_PALETTE_DATA,
((uint32)color_data[0] << 16) |
((uint32)color_data[1] << 8) |
color_data[2] );
SUBMIT_IB();
} else {
Radeon_WaitForFifo ( ai , 1 );
OUTREG( ai->regs, RADEON_DAC_CNTL2,
(crtc_idx == 0 ? 0 : RADEON_DAC2_PALETTE_ACC_CTL) |
(ai->si->dac_cntl2 & ~RADEON_DAC2_PALETTE_ACC_CTL) );
OUTREG( ai->regs, RADEON_PALETTE_INDEX, first );
for( i = 0; i < count; ++i, color_data += 3 ) {
Radeon_WaitForFifo ( ai , 1 ); // TODO FIXME good god this is gonna be slow...
OUTREG( ai->regs, RADEON_PALETTE_DATA,
((uint32)color_data[0] << 16) |
((uint32)color_data[1] << 8) |
color_data[2] );
}
}
}

View File

@ -115,6 +115,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype );
// driver_wrapper.c
status_t Radeon_WaitForIdle( accelerator_info *ai, bool keep_lock );
status_t Radeon_WaitForFifo( accelerator_info *ai, int entries );
void Radeon_ResetEngine( accelerator_info *ai );
status_t Radeon_VIPRead( accelerator_info *ai, uint channel, uint address, uint32 *data );

View File

@ -227,71 +227,54 @@ void Radeon_ResetEngine( device_info *di )
host_path_cntl = INREG( regs, RADEON_HOST_PATH_CNTL );
rbbm_soft_reset = INREG( regs, RADEON_RBBM_SOFT_RESET );
switch( di->asic ) {
case rt_r300:
OUTREG( regs, RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_AIC ));
INREG( regs, RADEON_RBBM_SOFT_RESET);
OUTREG( regs, RADEON_RBBM_SOFT_RESET, 0);
// this bit has no description
OUTREGP( regs, RADEON_RB2D_DSTCACHE_MODE, (1 << 17), ~0 );
break;
default:
OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset |
OUTREG( regs, RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_RB |
RADEON_SOFT_RESET_AIC );
INREG( regs, RADEON_RBBM_SOFT_RESET );
OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset &
~( RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_RB |
RADEON_SOFT_RESET_AIC ) );
INREG( regs, RADEON_RBBM_SOFT_RESET );
}
RADEON_SOFT_RESET_RB ) );
INREG( regs, RADEON_RBBM_SOFT_RESET);
OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset &
~( RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
RADEON_SOFT_RESET_PP |
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_RB ) );
INREG( regs, RADEON_RBBM_SOFT_RESET);
OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET );
INREG( regs, RADEON_HOST_PATH_CNTL );
OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl );
// restore regs
OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
//R300_PLLFix( regs, di->asic );
Radeon_OUTPLL( regs, di->asic, RADEON_MCLK_CNTL, mclk_cntl );
OUTREG( regs, RADEON_CLOCK_CNTL_INDEX, clock_cntl_index );
//RADEONPllErrataAfterIndex( regs, di->asic ); // drm doesn't do this here!
OUTREG( regs, RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
if ( di->acc_dma )
{
// reset ring buffer
cur_read_ptr = INREG( regs, RADEON_CP_RB_RPTR );
OUTREG( regs, RADEON_CP_RB_WPTR, cur_read_ptr );
//if( si->cp.ring.head ) {
// during init, there are no feedback data
if( si->cp.feedback.mem_handle != 0 ) {
*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) =
cur_read_ptr;
// *si->cp.ring.head = cur_read_ptr;
si->cp.ring.tail = cur_read_ptr;
}
// reset ring buffer
cur_read_ptr = INREG( regs, RADEON_CP_RB_RPTR );
OUTREG( regs, RADEON_CP_RB_WPTR, cur_read_ptr );
//if( si->cp.ring.head ) {
// during init, there are no feedback data
if( si->cp.feedback.mem_handle != 0 ) {
*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) =
cur_read_ptr;
// *si->cp.ring.head = cur_read_ptr;
si->cp.ring.tail = cur_read_ptr;
// mark all buffers as being finished
Radeon_DiscardAllIndirectBuffers( di );
}
++si->engine.count;
// mark all buffers as being finished
Radeon_DiscardAllIndirectBuffers( di );
return;
}
@ -522,7 +505,7 @@ status_t Radeon_InitCP( device_info *di )
set_sem_owner( di->si->cp.lock.sem, thinfo.team );
// init raw CP
loadMicroEngineRAMData( di );
if ( di->acc_dma ) loadMicroEngineRAMData( di );
// do soft-reset
Radeon_ResetEngine( di );
@ -536,26 +519,30 @@ status_t Radeon_InitCP( device_info *di )
// reset CP to make disabling active
Radeon_ResetEngine( di );
res = initRingBuffer( di, CP_RING_SIZE );
if( res < 0 )
goto err4;
res = initCPFeedback( di );
if( res < 0 )
goto err3;
if ( di->acc_dma )
{
res = initRingBuffer( di, CP_RING_SIZE );
if( res < 0 )
goto err4;
res = initIndirectBuffers( di );
if( res < 0 )
goto err2;
res = initCPFeedback( di );
if( res < 0 )
goto err3;
res = initIndirectBuffers( di );
if( res < 0 )
goto err2;
// tell CP to use BM
Radeon_WaitForIdle( di, false, false );
// tell CP to use BM
Radeon_WaitForIdle( di, false, false );
// enable direct and indirect CP bus mastering
OUTREG( di->regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM );
// allow bus mastering in general
OUTREGP( di->regs, RADEON_BUS_CNTL, 0, ~RADEON_BUS_MASTER_DIS );
// enable direct and indirect CP bus mastering
OUTREG( di->regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM );
// allow bus mastering in general
OUTREGP( di->regs, RADEON_BUS_CNTL, 0, ~RADEON_BUS_MASTER_DIS );
}
// don't allow mixing of 2D/3D/scratch/wait_until commands
// (in fact, this doesn't seem to make any difference as we do a
@ -596,11 +583,14 @@ void Radeon_UninitCP( device_info *di )
OUTREG( regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
// read-back for flushing
INREG( regs, RADEON_CP_CSQ_CNTL );
uninitRingBuffer( di );
uninitCPFeedback( di );
uninitIndirectBuffers( di );
if ( di->acc_dma )
{
uninitRingBuffer( di );
uninitCPFeedback( di );
uninitIndirectBuffers( di );
}
DELETE_BEN( di->si->cp.lock );
}

View File

@ -536,58 +536,142 @@ static void Radeon_GetFPData( device_info *di )
SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock );
}
// Depending on card genertation, chipset bugs, etc... the amount of vram
// accessible to the CPU can vary. This function is our best shot at figuring
// it out. Returns a value in KB.
static uint32 RADEON_GetAccessibleVRAM( device_info *di )
{
vuint8 *regs = di->regs;
pci_info *pcii = &(di->pcii);
uint32 aper_size = INREG( regs, RADEON_CONFIG_APER_SIZE );
// Set HDP_APER_CNTL only on cards that are known not to be broken,
// that is has the 2nd generation multifunction PCI interface
if (di->asic == rt_rv280 ||
di->asic == rt_rv350 ||
di->asic == rt_rv380 ||
di->asic == rt_r420 ) {
OUTREGP( regs, RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL,
~RADEON_HDP_APER_CNTL);
SHOW_INFO0( 0, "Generation 2 PCI interface, using max accessible memory");
return aper_size * 2;
}
// Older cards have all sorts of funny issues to deal with. First
// check if it's a multifunction card by reading the PCI config
// header type... Limit those to one aperture size
if (get_pci(PCI_header_type, 1) & 0x80) {
SHOW_INFO0( 0, "Generation 1 PCI interface in multifunction mode"
", accessible memory limited to one aperture\n");
return aper_size;
}
// Single function older card. We read HDP_APER_CNTL to see how the BIOS
// have set it up. We don't write this as it's broken on some ASICs but
// we expect the BIOS to have done the right thing (might be too optimistic...)
if (INREG( regs, RADEON_HOST_PATH_CNTL ) & RADEON_HDP_APER_CNTL )
return aper_size * 2;
return aper_size;
}
// detect amount of graphics memory
static void Radeon_DetectRAM( device_info *di )
{
vuint8 *regs = di->regs;
if( !di->is_igp )
di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK;
else {
uint32 accessible, bar_size, tmp = 0;
if( di->is_igp ) {
uint32 tom;
tom = INREG( regs, RADEON_NB_TOM );
di->local_mem_size = ((tom >> 16) + 1 - (tom & 0xffff)) << 16;
OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size * 1024);
} else {
di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK;
}
// some production boards of m6 will return 0 if it's 8 MB
if( di->local_mem_size == 0 )
if( di->local_mem_size == 0 ) {
di->local_mem_size = 8 * 1024 *1024;
OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size);
}
switch( INREG( regs, RADEON_MEM_SDRAM_MODE_REG ) & RADEON_MEM_CFG_TYPE_MASK ) {
case RADEON_MEM_CFG_SDR:
// SDR SGRAM (2:1)
strcpy(di->ram_type, "SDR SGRAM");
di->ram.ml = 4;
di->ram.MB = 4;
di->ram.Trcd = 1;
di->ram.Trp = 2;
di->ram.Twr = 1;
di->ram.CL = 2;
di->ram.loop_latency = 16;
di->ram.Rloop = 16;
di->ram.Tr2w = 0;
break;
case RADEON_MEM_CFG_DDR:
// DDR SGRAM
strcpy(di->ram_type, "DDR SGRAM");
di->ram.ml = 4;
di->ram.MB = 4;
di->ram.Trcd = 3;
di->ram.Trp = 3;
di->ram.Twr = 2;
di->ram.CL = 3;
di->ram.Tr2w = 1;
di->ram.loop_latency = 16;
di->ram.Rloop = 16;
break;
// only one bit, so there's no default
// Get usable Vram, after asic bugs, configuration screw ups etc
accessible = RADEON_GetAccessibleVRAM( di );
// Crop it to the size of the PCI BAR
bar_size = di->pcii.u.h0.base_register_sizes[0];
if (bar_size == 0)
bar_size = 0x200000;
if (accessible > bar_size)
accessible = bar_size;
SHOW_INFO( 0, "Detected total video RAM=%ldK, accessible=%ldK (PCI BAR=%ldK)"
, di->local_mem_size/1024, accessible/1024, bar_size/1024);
if (di->local_mem_size > accessible)
di->local_mem_size = accessible;
// detect ram bus width only used by dynamic clocks for now.
tmp = INREG( regs, RADEON_MEM_CNTL );
if (IS_DI_R300_VARIANT) {
tmp &= R300_MEM_NUM_CHANNELS_MASK;
switch (tmp) {
case 0: di->ram.width = 64; break;
case 1: di->ram.width = 128; break;
case 2: di->ram.width = 256; break;
default: di->ram.width = 128; break;
}
} else if ( (di->asic >= rt_rv100) ||
(di->asic >= rt_rs100) ||
(di->asic >= rt_rs200)) {
if (tmp & RV100_HALF_MODE)
di->ram.width = 32;
else
di->ram.width = 64;
} else {
if (tmp & RADEON_MEM_NUM_CHANNELS_MASK)
di->ram.width = 128;
else
di->ram.width = 64;
}
if (di->is_igp || (di->asic >= rt_r300))
{
uint32 mem_type = INREG( regs, RADEON_MEM_SDRAM_MODE_REG ) & RADEON_MEM_CFG_TYPE_MASK;
if ( mem_type == RADEON_MEM_CFG_SDR) {
// SDR SGRAM (2:1)
strcpy(di->ram_type, "SDR SGRAM");
di->ram.ml = 4;
di->ram.MB = 4;
di->ram.Trcd = 1;
di->ram.Trp = 2;
di->ram.Twr = 1;
di->ram.CL = 2;
di->ram.loop_latency = 16;
di->ram.Rloop = 16;
di->ram.Tr2w = 0;
} else { // RADEON_MEM_CFG_DDR
// DDR SGRAM
strcpy(di->ram_type, "DDR SGRAM");
di->ram.ml = 4;
di->ram.MB = 4;
di->ram.Trcd = 3;
di->ram.Trp = 3;
di->ram.Twr = 2;
di->ram.CL = 3;
di->ram.Tr2w = 1;
di->ram.loop_latency = 16;
di->ram.Rloop = 16;
}
}
SHOW_INFO( 1, "%ld MB %s found", di->local_mem_size / 1024 / 1024,
di->ram_type );
SHOW_INFO( 1, "%ld MB %s found on %d wide bus",
di->local_mem_size / 1024 / 1024, di->ram_type, di->ram.width);
/* if( di->local_mem_size > 64 * 1024 * 1024 ) {
di->local_mem_size = 64 * 1024 * 1024;

View File

@ -592,6 +592,60 @@ static bool probeDevice( device_info *di )
}
// disable 2d DMA engine for chips that don't work with our
// dma code (yet). I would have used asic type, but R410s are
// treated same asic as r420s in code, and the AGP x800 works fine.
switch ( device->device_id )
{
// rv370
case DEVICE_ID_RADEON_5b60:
case DEVICE_ID_RADEON_5b62:
case DEVICE_ID_RADEON_5b64:
case DEVICE_ID_RADEON_5b65:
case DEVICE_ID_RADEON_5460:
case DEVICE_ID_RADEON_5464:
// rv380
case DEVICE_ID_RADEON_3e50:
case DEVICE_ID_RADEON_3e54:
case DEVICE_ID_RADEON_3150:
case DEVICE_ID_RADEON_3154:
case DEVICE_ID_RADEON_5462:
// rv410
case DEVICE_ID_RADEON_5e48:
case DEVICE_ID_RADEON_564a:
case DEVICE_ID_RADEON_564b:
case DEVICE_ID_RADEON_564f:
case DEVICE_ID_RADEON_5652:
case DEVICE_ID_RADEON_5653:
case DEVICE_ID_RADEON_5e4b:
case DEVICE_ID_RADEON_5e4a:
case DEVICE_ID_RADEON_5e4d:
case DEVICE_ID_RADEON_5e4c:
case DEVICE_ID_RADEON_5e4f:
// rs400
case DEVICE_ID_RS400_5a41:
case DEVICE_ID_RS400_5a42:
// rs410
case DEVICE_ID_RS410_5a61:
case DEVICE_ID_RS410_5a62:
// rs480
case DEVICE_ID_RS480_5954:
case DEVICE_ID_RS480_5955:
case DEVICE_ID_RS482_5974:
case DEVICE_ID_RS482_5975:
di->acc_dma = false;
break;
default:
di->acc_dma = true;
break;
}
if( Radeon_MapBIOS( &di->pcii, &di->rom ) != B_OK )
// give up checking this device - no BIOS, no fun
return false;

View File

@ -273,6 +273,16 @@ static status_t control_hook( void *dev, uint32 msg, void *buf, size_t len )
result = B_OK;
} break;
case RADEON_WAITFORFIFO: {
radeon_wait_for_fifo *wff = (radeon_wait_for_fifo *)buf;
if( wff->magic != RADEON_PRIVATE_DATA_MAGIC )
break;
Radeon_WaitForFifo( di, wff->entries );
result = B_OK;
} break;
case RADEON_RESETENGINE: {
radeon_no_arg *na = (radeon_no_arg *)buf;

View File

@ -250,6 +250,7 @@ status_t Radeon_FirstOpen( device_info *di )
si->is_atombios = di->is_atombios;
si->is_mobility = di->is_mobility;
si->panel_pwr_delay = di->si->panel_pwr_delay;
si->acc_dma = di->acc_dma;
// detecting theatre channel in kernel would lead to code duplication,
@ -359,15 +360,22 @@ status_t Radeon_FirstOpen( device_info *di )
if( di->asic == rt_rs100 || di->asic == rt_rs200 || di->asic == rt_rs300)
Radeon_Fix_AGP();
// time to init Command Processor
result = Radeon_InitCP( di );
if( result != B_OK )
goto err;
if ( di->acc_dma )
{
// time to init Command Processor
result = Radeon_InitCP( di );
if( result != B_OK )
goto err;
result = Radeon_InitDMA( di );
if( result != B_OK )
goto err0;
}
else
{
SHOW_INFO0( 0, "DMA is diabled using PIO mode");
}
result = Radeon_InitDMA( di );
if( result != B_OK )
goto err0;
// mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset );
/* dma_offset = 15 * 1024 * 1024;
@ -402,7 +410,8 @@ err8:
// during tests)
void Radeon_LastClose( device_info *di )
{
Radeon_UninitCP( di );
if ( di->acc_dma )
Radeon_UninitCP( di );
// M6 fix - unfortunately, the device is never closed by app_server,
// not even before reboot

View File

@ -39,10 +39,21 @@ static uint32 getTopOfRam()
static void Radeon_SetupMCAddresses_Direct( device_info *di )
{
shared_info *si = di->si;
uint32 mc_fb_location;
uint32 aper0 = INREG( di->regs, RADEON_CONFIG_APER_0_BASE );
// bug in asics mean memory must be aligned to memory size...
if ( IS_DI_R300_VARIANT || di->asic == rt_rv280 ) {
aper0 &= ~( di->local_mem_size - 1 );
}
mc_fb_location = ( aper0 >> 16 ) ||
(aper0 + di->local_mem_size - 1 ) & 0xffff0000;
// set address range of video memory;
// use the same addresses the CPU sees
si->memory[mt_local].virtual_addr_start = (uint32)si->framebuffer_pci;
si->memory[mt_local].virtual_addr_start = mc_fb_location;
si->memory[mt_local].virtual_size = di->local_mem_size;
// PCI GART has no corresponding CPU address space, so we must find an unused
@ -148,6 +159,10 @@ void Radeon_InitMemController( device_info *di )
si->memory[mt_AGP].virtual_size, si->memory[mt_AGP].virtual_addr_start );
//si->nonlocal_mem = di->DMABuffer.ptr;
// Turn on PCI GART
OUTREGP( regs, RADEON_AIC_CNTL, RADEON_PCIGART_TRANSLATE_EN,
~RADEON_PCIGART_TRANSLATE_EN );
// set PCI GART page-table base address
OUTREG( regs, RADEON_AIC_PT_BASE, di->pci_gart.GATT.phys );
@ -159,9 +174,12 @@ void Radeon_InitMemController( device_info *di )
si->memory[mt_PCI].virtual_size/*di->pci_gart.buffer.size*/ - 1 );
// set AGP address range
OUTREG( regs, RADEON_MC_AGP_LOCATION,
OUTREG( regs, RADEON_MC_AGP_LOCATION, 0xffffffc0 /* EK magic numbers from X.org
(si->memory[mt_AGP].virtual_addr_start >> 16) |
((si->memory[mt_AGP].virtual_addr_start + si->memory[mt_AGP].virtual_size - 1) & 0xffff0000 ));
((si->memory[mt_AGP].virtual_addr_start + si->memory[mt_AGP].virtual_size - 1) & 0xffff0000 )*/);
// disable AGP
OUTREG( regs, RADEON_AGP_COMMAND, 0 );
// set address range of video memory
// (lower word = begin >> 16
@ -175,19 +193,11 @@ void Radeon_InitMemController( device_info *di )
OUTREG( regs, RADEON_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
OUTREG( regs, RADEON_CRTC2_DISPLAY_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
OUTREG( regs, RADEON_OV0_BASE_ADDRESS, si->memory[mt_local].virtual_addr_start );
// disable AGP
OUTREG( regs, RADEON_AGP_COMMAND, 0 );
// Turn on PCI GART
OUTREGP( regs, RADEON_AIC_CNTL, RADEON_PCIGART_TRANSLATE_EN,
~RADEON_PCIGART_TRANSLATE_EN );
// fix some bus controller setting
// I reckon this takes care of discarding data unnecessarily read
// during a burst; let's hope this will fix the nasty CP crashing problem
OUTREGP( regs, RADEON_BUS_CNTL, RADEON_BUS_RD_DISCARD_EN, ~RADEON_BUS_RD_DISCARD_EN );
// EK this seems unecessary. OUTREGP( regs, RADEON_BUS_CNTL, RADEON_BUS_RD_DISCARD_EN, ~RADEON_BUS_RD_DISCARD_EN );
// SHOW_FLOW0( 3, "done" );
}

View File

@ -67,6 +67,7 @@ typedef struct {
int Tr2w;
int loop_latency;
int Rloop;
int width;
} ram_info;
// ROM information
@ -109,7 +110,8 @@ typedef struct device_info {
bool has_vip;
bool is_igp;
bool has_no_i2c;
//display_type_e disp_type[2];
bool acc_dma;
fp_info fp_info;
general_pll_info pll;