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:
@@ -20,7 +20,8 @@
|
|||||||
#include "ddc.h"
|
#include "ddc.h"
|
||||||
|
|
||||||
// magic code for ioctls
|
// 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
|
#define MAX_RADEON_DEVICE_NAME_LENGTH MAXPATHLEN
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ enum {
|
|||||||
RADEON_FREE_MEM,
|
RADEON_FREE_MEM,
|
||||||
|
|
||||||
RADEON_WAITFORIDLE,
|
RADEON_WAITFORIDLE,
|
||||||
|
RADEON_WAITFORFIFO,
|
||||||
RADEON_RESETENGINE,
|
RADEON_RESETENGINE,
|
||||||
RADEON_VIPREAD,
|
RADEON_VIPREAD,
|
||||||
RADEON_VIPWRITE,
|
RADEON_VIPWRITE,
|
||||||
@@ -396,6 +398,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
// filled out by kernel
|
// filled out by kernel
|
||||||
CP_info cp; // info concerning command processor
|
CP_info cp; // info concerning command processor
|
||||||
|
bool acc_dma; // prevent use of dma engine
|
||||||
|
|
||||||
// set by accelerant
|
// set by accelerant
|
||||||
struct {
|
struct {
|
||||||
@@ -499,6 +502,12 @@ typedef struct {
|
|||||||
bool keep_lock; // keep lock after engine is idle
|
bool keep_lock; // keep lock after engine is idle
|
||||||
} radeon_wait_for_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
|
// read VIP register
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32 magic;
|
uint32 magic;
|
||||||
|
|||||||
@@ -8,4 +8,4 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// current version
|
// 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 "generic.h"
|
||||||
#include "3d_regs.h"
|
#include "3d_regs.h"
|
||||||
#include "2d_regs.h"
|
#include "2d_regs.h"
|
||||||
|
#include "radeon_regs.h"
|
||||||
#include "mmio.h"
|
#include "mmio.h"
|
||||||
#include "CP.h"
|
#include "CP.h"
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@
|
|||||||
// et - ignored
|
// et - ignored
|
||||||
// list - list of rectangles
|
// list - list of rectangles
|
||||||
// count - number 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;
|
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;
|
++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
|
// fill rectangles on screen
|
||||||
// et - ignored
|
// et - ignored
|
||||||
// colorIndex - fill colour
|
// colorIndex - fill colour
|
||||||
// list - list of rectangles
|
// list - list of rectangles
|
||||||
// count - number 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)
|
fill_rect_params *list, uint32 count)
|
||||||
{
|
{
|
||||||
virtual_card *vc = ai->vc;
|
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
|
// invert rectangle on screen
|
||||||
// et - ignored
|
// et - ignored
|
||||||
// list - list of rectangles
|
// list - list of rectangles
|
||||||
// count - number 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;
|
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;
|
++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
|
// fill horizontal spans on screen
|
||||||
// et - ignored
|
// et - ignored
|
||||||
// colorIndex - fill colour
|
// colorIndex - fill colour
|
||||||
// list - list of spans
|
// list - list of spans
|
||||||
// count - number 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;
|
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
|
// prepare 2D acceleration
|
||||||
void Radeon_Init2D( accelerator_info *ai )
|
void Radeon_Init2D( accelerator_info *ai )
|
||||||
{
|
{
|
||||||
SHOW_FLOW0( 3, "" );
|
SHOW_FLOW0( 3, "" );
|
||||||
|
|
||||||
START_IB();
|
|
||||||
|
|
||||||
// forget about 3D
|
// forget about 3D
|
||||||
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
|
if ( ai->si->acc_dma ) {
|
||||||
|
START_IB();
|
||||||
SUBMIT_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
|
// fill state buffer that sets 2D registers up for accelerated operations
|
||||||
void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
|
void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
|
||||||
{
|
{
|
||||||
virtual_card *vc = ai->vc;
|
virtual_card *vc = ai->vc;
|
||||||
uint32 pitch_offset;
|
uint32 pitch_offset;
|
||||||
uint32 *buffer, *buffer_start;
|
uint32 *buffer = NULL, *buffer_start = NULL;
|
||||||
|
|
||||||
SHOW_FLOW0( 4, "" );
|
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
|
// set offset of frame buffer and pitch
|
||||||
pitch_offset =
|
pitch_offset =
|
||||||
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
|
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
|
||||||
((vc->pitch >> 6) << 22);
|
((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
|
if ( ai->si->acc_dma ) {
|
||||||
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
|
// make sure buffer is not used
|
||||||
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
|
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
|
||||||
|
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
|
||||||
|
|
||||||
// setup general flags - perhaps this is not needed as all
|
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
|
||||||
// 2D commands contain this register
|
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
|
||||||
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
|
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
|
||||||
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
// no sissors
|
||||||
| RADEON_GMC_CLR_CMP_CNTL_DIS
|
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
|
||||||
|
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
|
||||||
|
|
||||||
| RADEON_GMC_BRUSH_SOLID_COLOR
|
// general fluff
|
||||||
| RADEON_GMC_SRC_DATATYPE_COLOR
|
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
|
||||||
|
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||||
|
| RADEON_GMC_CLR_CMP_CNTL_DIS
|
||||||
|
|
||||||
| RADEON_ROP3_P
|
| RADEON_GMC_BRUSH_SOLID_COLOR
|
||||||
| RADEON_DP_SRC_SOURCE_MEMORY
|
| RADEON_GMC_SRC_DATATYPE_COLOR
|
||||||
| RADEON_GMC_WR_MSK_DIS );
|
|
||||||
|
|
||||||
|
| RADEON_ROP3_P
|
||||||
|
| RADEON_DP_SRC_SOURCE_MEMORY
|
||||||
|
| RADEON_GMC_WR_MSK_DIS );
|
||||||
|
|
||||||
// most of this init is probably not nessacary
|
// most of this init is probably not necessary
|
||||||
// as we neither draw lines nor use brushes
|
// as we neither draw lines nor use brushes
|
||||||
WRITE_IB_REG( RADEON_DST_LINE_START, 0);
|
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
|
||||||
WRITE_IB_REG( RADEON_DST_LINE_END, 0);
|
WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
|
||||||
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
|
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
|
||||||
WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
|
WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
|
||||||
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
|
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 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;
|
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 )
|
if( ai->si->engine.count == ai->si->engine.written )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
START_IB();
|
if( ai->si->acc_dma ) {
|
||||||
|
START_IB();
|
||||||
|
|
||||||
// flush pending data
|
// flush pending data
|
||||||
WRITE_IB_REG( RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL );
|
WRITE_IB_REG( RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL );
|
||||||
|
|
||||||
// make sure commands are finished
|
// make sure commands are finished
|
||||||
WRITE_IB_REG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN |
|
WRITE_IB_REG( RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN |
|
||||||
RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN );
|
RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN );
|
||||||
|
|
||||||
// write scratch register
|
// write scratch register
|
||||||
WRITE_IB_REG( RADEON_SCRATCH_REG0, ai->si->engine.count );
|
WRITE_IB_REG( RADEON_SCRATCH_REG0, ai->si->engine.count );
|
||||||
|
|
||||||
ai->si->engine.written = ai->si->engine.count;
|
ai->si->engine.written = ai->si->engine.count;
|
||||||
|
|
||||||
SUBMIT_IB();
|
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
|
// public function: acquire engine for future use
|
||||||
@@ -178,6 +187,13 @@ status_t SYNC_TO_TOKEN( sync_token *st )
|
|||||||
|
|
||||||
SHOW_FLOW0( 4, "" );
|
SHOW_FLOW0( 4, "" );
|
||||||
|
|
||||||
|
if ( !ai->si->acc_dma )
|
||||||
|
{
|
||||||
|
Radeon_WaitForFifo( ai, 64 );
|
||||||
|
Radeon_WaitForIdle( ai, false );
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
start_time = system_time();
|
start_time = system_time();
|
||||||
|
|
||||||
while( 1 ) {
|
while( 1 ) {
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ err:
|
|||||||
static void uninit_common( void )
|
static void uninit_common( void )
|
||||||
{
|
{
|
||||||
if( !ai->accelerant_is_clone ) {
|
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,
|
// the last accelerant should must wait for the card to become quite,
|
||||||
// else some nasty command could lunger in some FIFO
|
// 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
|
// mark engine as having no state
|
||||||
//si->cp.active_state_buffer = -1;
|
//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
|
// everything else is initialized upon set_display_mode
|
||||||
return B_OK;
|
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 ));
|
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 )
|
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 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);
|
uint32 OVERLAY_COUNT(const display_mode *dm);
|
||||||
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm);
|
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm);
|
||||||
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space);
|
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space);
|
||||||
|
|||||||
@@ -973,17 +973,27 @@ static void Radeon_ReplaceOverlayBuffer(
|
|||||||
shared_info *si = ai->si;
|
shared_info *si = ai->si;
|
||||||
uint32 offset;
|
uint32 offset;
|
||||||
|
|
||||||
START_IB();
|
if ( ai->si->acc_dma )
|
||||||
|
{
|
||||||
|
START_IB();
|
||||||
|
|
||||||
offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;
|
offset = si->pending_overlay.on->mem_offset + si->active_overlay.rel_offset;
|
||||||
|
|
||||||
WRITE_IB_REG( RADEON_OV0_VID_BUF0_BASE_ADRS, offset);
|
WRITE_IB_REG( RADEON_OV0_VID_BUF0_BASE_ADRS, offset);
|
||||||
|
|
||||||
si->overlay_mgr.auto_flip_reg ^= RADEON_OV0_SOFT_EOF_TOGGLE;
|
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 );
|
WRITE_IB_REG( RADEON_OV0_AUTO_FLIP_CNTRL, si->overlay_mgr.auto_flip_reg );
|
||||||
|
|
||||||
SUBMIT_IB();
|
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;
|
ai->si->active_overlay.on = ai->si->pending_overlay.on;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,33 +13,41 @@
|
|||||||
|
|
||||||
#include "GlobalData.h"
|
#include "GlobalData.h"
|
||||||
#include "dac_regs.h"
|
#include "dac_regs.h"
|
||||||
|
#include "mmio.h"
|
||||||
#include "CP.h"
|
#include "CP.h"
|
||||||
#include "generic.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)
|
// set standard colour palette (needed for non-palette modes)
|
||||||
void Radeon_InitPalette(
|
void Radeon_InitPalette(
|
||||||
accelerator_info *ai, int crtc_idx )
|
accelerator_info *ai, int crtc_idx )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
START_IB();
|
if ( ai->si->acc_dma ) {
|
||||||
|
START_IB();
|
||||||
|
|
||||||
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) );
|
||||||
|
|
||||||
WRITE_IB_REG( RADEON_PALETTE_INDEX, 0 );
|
WRITE_IB_REG( RADEON_PALETTE_INDEX, 0 );
|
||||||
|
|
||||||
for( i = 0; i < 256; ++i )
|
for( i = 0; i < 256; ++i )
|
||||||
WRITE_IB_REG( RADEON_PALETTE_DATA, (i << 16) | (i << 8) | i );
|
WRITE_IB_REG( RADEON_PALETTE_DATA, (i << 16) | (i << 8) | i );
|
||||||
|
|
||||||
SUBMIT_IB();
|
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(
|
static void setPalette(
|
||||||
@@ -75,17 +83,35 @@ static void setPalette(
|
|||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
START_IB();
|
if ( ai->si->acc_dma ) {
|
||||||
|
START_IB();
|
||||||
|
|
||||||
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) );
|
||||||
|
|
||||||
WRITE_IB_REG( RADEON_PALETTE_INDEX, first );
|
WRITE_IB_REG( RADEON_PALETTE_INDEX, first );
|
||||||
|
|
||||||
for( i = 0; i < count; ++i, color_data += 3 )
|
for( i = 0; i < count; ++i, color_data += 3 )
|
||||||
WRITE_IB_REG( RADEON_PALETTE_DATA,
|
WRITE_IB_REG( RADEON_PALETTE_DATA,
|
||||||
((uint32)color_data[0] << 16) |
|
((uint32)color_data[0] << 16) |
|
||||||
((uint32)color_data[1] << 8) |
|
((uint32)color_data[1] << 8) |
|
||||||
color_data[2] );
|
color_data[2] );
|
||||||
|
|
||||||
SUBMIT_IB();
|
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
|
// driver_wrapper.c
|
||||||
status_t Radeon_WaitForIdle( accelerator_info *ai, bool keep_lock );
|
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 );
|
void Radeon_ResetEngine( accelerator_info *ai );
|
||||||
|
|
||||||
status_t Radeon_VIPRead( accelerator_info *ai, uint channel, uint address, uint32 *data );
|
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 );
|
host_path_cntl = INREG( regs, RADEON_HOST_PATH_CNTL );
|
||||||
rbbm_soft_reset = INREG( regs, RADEON_RBBM_SOFT_RESET );
|
rbbm_soft_reset = INREG( regs, RADEON_RBBM_SOFT_RESET );
|
||||||
|
|
||||||
switch( di->asic ) {
|
OUTREG( regs, RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
|
||||||
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 |
|
|
||||||
RADEON_SOFT_RESET_CP |
|
RADEON_SOFT_RESET_CP |
|
||||||
RADEON_SOFT_RESET_HI |
|
RADEON_SOFT_RESET_HI |
|
||||||
RADEON_SOFT_RESET_SE |
|
RADEON_SOFT_RESET_SE |
|
||||||
RADEON_SOFT_RESET_RE |
|
RADEON_SOFT_RESET_RE |
|
||||||
RADEON_SOFT_RESET_PP |
|
RADEON_SOFT_RESET_PP |
|
||||||
RADEON_SOFT_RESET_E2 |
|
RADEON_SOFT_RESET_E2 |
|
||||||
RADEON_SOFT_RESET_RB |
|
RADEON_SOFT_RESET_RB ) );
|
||||||
RADEON_SOFT_RESET_AIC );
|
INREG( regs, RADEON_RBBM_SOFT_RESET);
|
||||||
INREG( regs, RADEON_RBBM_SOFT_RESET );
|
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_CP |
|
RADEON_SOFT_RESET_HI |
|
||||||
RADEON_SOFT_RESET_HI |
|
RADEON_SOFT_RESET_SE |
|
||||||
RADEON_SOFT_RESET_SE |
|
RADEON_SOFT_RESET_RE |
|
||||||
RADEON_SOFT_RESET_RE |
|
RADEON_SOFT_RESET_PP |
|
||||||
RADEON_SOFT_RESET_PP |
|
RADEON_SOFT_RESET_E2 |
|
||||||
RADEON_SOFT_RESET_E2 |
|
RADEON_SOFT_RESET_RB ) );
|
||||||
RADEON_SOFT_RESET_RB |
|
INREG( regs, RADEON_RBBM_SOFT_RESET);
|
||||||
RADEON_SOFT_RESET_AIC ) );
|
|
||||||
INREG( regs, RADEON_RBBM_SOFT_RESET );
|
|
||||||
}
|
|
||||||
|
|
||||||
OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET );
|
OUTREG( regs, RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET );
|
||||||
INREG( regs, RADEON_HOST_PATH_CNTL );
|
INREG( regs, RADEON_HOST_PATH_CNTL );
|
||||||
OUTREG( regs, RADEON_HOST_PATH_CNTL, 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 );
|
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);
|
||||||
|
|
||||||
// reset ring buffer
|
if ( di->acc_dma )
|
||||||
cur_read_ptr = INREG( regs, RADEON_CP_RB_RPTR );
|
{
|
||||||
OUTREG( regs, RADEON_CP_RB_WPTR, 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 ) {
|
//if( si->cp.ring.head ) {
|
||||||
// during init, there are no feedback data
|
// during init, there are no feedback data
|
||||||
if( si->cp.feedback.mem_handle != 0 ) {
|
if( si->cp.feedback.mem_handle != 0 ) {
|
||||||
*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) =
|
*(uint32 *)MEM2CPU( si->cp.feedback.mem_type, si->cp.feedback.head_mem_offset) =
|
||||||
cur_read_ptr;
|
cur_read_ptr;
|
||||||
// *si->cp.ring.head = cur_read_ptr;
|
// *si->cp.ring.head = cur_read_ptr;
|
||||||
si->cp.ring.tail = cur_read_ptr;
|
si->cp.ring.tail = cur_read_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark all buffers as being finished
|
||||||
|
Radeon_DiscardAllIndirectBuffers( di );
|
||||||
}
|
}
|
||||||
|
|
||||||
++si->engine.count;
|
++si->engine.count;
|
||||||
|
|
||||||
// mark all buffers as being finished
|
|
||||||
Radeon_DiscardAllIndirectBuffers( di );
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +505,7 @@ status_t Radeon_InitCP( device_info *di )
|
|||||||
set_sem_owner( di->si->cp.lock.sem, thinfo.team );
|
set_sem_owner( di->si->cp.lock.sem, thinfo.team );
|
||||||
|
|
||||||
// init raw CP
|
// init raw CP
|
||||||
loadMicroEngineRAMData( di );
|
if ( di->acc_dma ) loadMicroEngineRAMData( di );
|
||||||
|
|
||||||
// do soft-reset
|
// do soft-reset
|
||||||
Radeon_ResetEngine( di );
|
Radeon_ResetEngine( di );
|
||||||
@@ -536,26 +519,30 @@ status_t Radeon_InitCP( device_info *di )
|
|||||||
// reset CP to make disabling active
|
// reset CP to make disabling active
|
||||||
Radeon_ResetEngine( di );
|
Radeon_ResetEngine( di );
|
||||||
|
|
||||||
res = initRingBuffer( di, CP_RING_SIZE );
|
if ( di->acc_dma )
|
||||||
if( res < 0 )
|
{
|
||||||
goto err4;
|
res = initRingBuffer( di, CP_RING_SIZE );
|
||||||
|
if( res < 0 )
|
||||||
|
goto err4;
|
||||||
|
|
||||||
res = initCPFeedback( di );
|
res = initCPFeedback( di );
|
||||||
if( res < 0 )
|
if( res < 0 )
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
res = initIndirectBuffers( di );
|
res = initIndirectBuffers( di );
|
||||||
if( res < 0 )
|
if( res < 0 )
|
||||||
goto err2;
|
goto err2;
|
||||||
|
|
||||||
// tell CP to use BM
|
// tell CP to use BM
|
||||||
Radeon_WaitForIdle( di, false, false );
|
Radeon_WaitForIdle( di, false, false );
|
||||||
|
|
||||||
// enable direct and indirect CP bus mastering
|
// enable direct and indirect CP bus mastering
|
||||||
OUTREG( di->regs, RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM );
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
// 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
|
// (in fact, this doesn't seem to make any difference as we do a
|
||||||
@@ -597,9 +584,12 @@ void Radeon_UninitCP( device_info *di )
|
|||||||
// read-back for flushing
|
// read-back for flushing
|
||||||
INREG( regs, RADEON_CP_CSQ_CNTL );
|
INREG( regs, RADEON_CP_CSQ_CNTL );
|
||||||
|
|
||||||
uninitRingBuffer( di );
|
if ( di->acc_dma )
|
||||||
uninitCPFeedback( di );
|
{
|
||||||
uninitIndirectBuffers( di );
|
uninitRingBuffer( di );
|
||||||
|
uninitCPFeedback( di );
|
||||||
|
uninitIndirectBuffers( di );
|
||||||
|
}
|
||||||
|
|
||||||
DELETE_BEN( di->si->cp.lock );
|
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 );
|
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
|
// detect amount of graphics memory
|
||||||
static void Radeon_DetectRAM( device_info *di )
|
static void Radeon_DetectRAM( device_info *di )
|
||||||
{
|
{
|
||||||
vuint8 *regs = di->regs;
|
vuint8 *regs = di->regs;
|
||||||
|
uint32 accessible, bar_size, tmp = 0;
|
||||||
|
|
||||||
if( !di->is_igp )
|
if( di->is_igp ) {
|
||||||
di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK;
|
|
||||||
else {
|
|
||||||
uint32 tom;
|
uint32 tom;
|
||||||
|
|
||||||
tom = INREG( regs, RADEON_NB_TOM );
|
tom = INREG( regs, RADEON_NB_TOM );
|
||||||
di->local_mem_size = ((tom >> 16) + 1 - (tom & 0xffff)) << 16;
|
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
|
// 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;
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOW_INFO( 1, "%ld MB %s found", di->local_mem_size / 1024 / 1024,
|
|
||||||
di->ram_type );
|
// 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 on %d wide bus",
|
||||||
|
di->local_mem_size / 1024 / 1024, di->ram_type, di->ram.width);
|
||||||
|
|
||||||
/* if( di->local_mem_size > 64 * 1024 * 1024 ) {
|
/* if( di->local_mem_size > 64 * 1024 * 1024 ) {
|
||||||
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 )
|
if( Radeon_MapBIOS( &di->pcii, &di->rom ) != B_OK )
|
||||||
// give up checking this device - no BIOS, no fun
|
// give up checking this device - no BIOS, no fun
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -273,6 +273,16 @@ static status_t control_hook( void *dev, uint32 msg, void *buf, size_t len )
|
|||||||
result = B_OK;
|
result = B_OK;
|
||||||
} break;
|
} 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: {
|
case RADEON_RESETENGINE: {
|
||||||
radeon_no_arg *na = (radeon_no_arg *)buf;
|
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_atombios = di->is_atombios;
|
||||||
si->is_mobility = di->is_mobility;
|
si->is_mobility = di->is_mobility;
|
||||||
si->panel_pwr_delay = di->si->panel_pwr_delay;
|
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,
|
// detecting theatre channel in kernel would lead to code duplication,
|
||||||
@@ -359,14 +360,21 @@ status_t Radeon_FirstOpen( device_info *di )
|
|||||||
if( di->asic == rt_rs100 || di->asic == rt_rs200 || di->asic == rt_rs300)
|
if( di->asic == rt_rs100 || di->asic == rt_rs200 || di->asic == rt_rs300)
|
||||||
Radeon_Fix_AGP();
|
Radeon_Fix_AGP();
|
||||||
|
|
||||||
// time to init Command Processor
|
if ( di->acc_dma )
|
||||||
result = Radeon_InitCP( di );
|
{
|
||||||
if( result != B_OK )
|
// time to init Command Processor
|
||||||
goto err;
|
result = Radeon_InitCP( di );
|
||||||
|
if( result != B_OK )
|
||||||
|
goto err;
|
||||||
|
|
||||||
result = Radeon_InitDMA( di );
|
result = Radeon_InitDMA( di );
|
||||||
if( result != B_OK )
|
if( result != B_OK )
|
||||||
goto err0;
|
goto err0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHOW_INFO0( 0, "DMA is diabled using PIO mode");
|
||||||
|
}
|
||||||
|
|
||||||
// mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset );
|
// mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset );
|
||||||
/* dma_offset = 15 * 1024 * 1024;
|
/* dma_offset = 15 * 1024 * 1024;
|
||||||
@@ -402,7 +410,8 @@ err8:
|
|||||||
// during tests)
|
// during tests)
|
||||||
void Radeon_LastClose( device_info *di )
|
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,
|
// M6 fix - unfortunately, the device is never closed by app_server,
|
||||||
// not even before reboot
|
// not even before reboot
|
||||||
|
|||||||
@@ -39,10 +39,21 @@ static uint32 getTopOfRam()
|
|||||||
static void Radeon_SetupMCAddresses_Direct( device_info *di )
|
static void Radeon_SetupMCAddresses_Direct( device_info *di )
|
||||||
{
|
{
|
||||||
shared_info *si = di->si;
|
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;
|
// set address range of video memory;
|
||||||
// use the same addresses the CPU sees
|
// 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;
|
si->memory[mt_local].virtual_size = di->local_mem_size;
|
||||||
|
|
||||||
// PCI GART has no corresponding CPU address space, so we must find an unused
|
// PCI GART has no corresponding CPU address space, so we must find an unused
|
||||||
@@ -149,6 +160,10 @@ void Radeon_InitMemController( device_info *di )
|
|||||||
|
|
||||||
//si->nonlocal_mem = di->DMABuffer.ptr;
|
//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
|
// set PCI GART page-table base address
|
||||||
OUTREG( regs, RADEON_AIC_PT_BASE, di->pci_gart.GATT.phys );
|
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 );
|
si->memory[mt_PCI].virtual_size/*di->pci_gart.buffer.size*/ - 1 );
|
||||||
|
|
||||||
// set AGP address range
|
// 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 >> 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
|
// set address range of video memory
|
||||||
// (lower word = begin >> 16
|
// (lower word = begin >> 16
|
||||||
@@ -176,18 +194,10 @@ void Radeon_InitMemController( device_info *di )
|
|||||||
OUTREG( regs, RADEON_CRTC2_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 );
|
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
|
// fix some bus controller setting
|
||||||
// I reckon this takes care of discarding data unnecessarily read
|
// I reckon this takes care of discarding data unnecessarily read
|
||||||
// during a burst; let's hope this will fix the nasty CP crashing problem
|
// 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" );
|
// SHOW_FLOW0( 3, "done" );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ typedef struct {
|
|||||||
int Tr2w;
|
int Tr2w;
|
||||||
int loop_latency;
|
int loop_latency;
|
||||||
int Rloop;
|
int Rloop;
|
||||||
|
int width;
|
||||||
} ram_info;
|
} ram_info;
|
||||||
|
|
||||||
// ROM information
|
// ROM information
|
||||||
@@ -109,7 +110,8 @@ typedef struct device_info {
|
|||||||
bool has_vip;
|
bool has_vip;
|
||||||
bool is_igp;
|
bool is_igp;
|
||||||
bool has_no_i2c;
|
bool has_no_i2c;
|
||||||
//display_type_e disp_type[2];
|
bool acc_dma;
|
||||||
|
|
||||||
fp_info fp_info;
|
fp_info fp_info;
|
||||||
|
|
||||||
general_pll_info pll;
|
general_pll_info pll;
|
||||||
|
|||||||
Reference in New Issue
Block a user