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:
parent
300bef5821
commit
a85694c375
@ -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;
|
||||
|
@ -8,4 +8,4 @@
|
||||
*/
|
||||
|
||||
// current version
|
||||
#define RADEON_DRIVER_VERSION "Version: 5.1.2.1"
|
||||
#define RADEON_DRIVER_VERSION "Version: 5.1.3.1"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 ) {
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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" );
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user