radeon: fix computing difference

Also fix clang warning self-assign.

Pointed by clang.

Change-Id: I0e104420414fecece87015a0af9a4535ccfc8263
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2401
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
X512
2020-03-23 01:30:23 +00:00
committed by waddlesplash
parent 39be4f89f5
commit fc179324b0
2 changed files with 202 additions and 202 deletions
+97 -97
View File
@@ -3,7 +3,7 @@
Part of Radeon accelerant Part of Radeon accelerant
Public functions to provide 2D hardware acceleration Public functions to provide 2D hardware acceleration
*/ */
@@ -22,12 +22,12 @@
// 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_DMA(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;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
(void)et; (void)et;
while( count > 0 ) { while( count > 0 ) {
@@ -35,15 +35,15 @@ void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count
START_IB(); START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_BITBLT_MULTI, count, WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_BITBLT_MULTI, count,
INDIRECT_BUFFER_SIZE, 3, 2 ); INDIRECT_BUFFER_SIZE, 3, 2 );
*buffer++ = RADEON_GMC_BRUSH_NONE *buffer++ = RADEON_GMC_BRUSH_NONE
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_S | RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY; | RADEON_DP_SRC_SOURCE_MEMORY;
for( ; sub_count > 0; --sub_count, ++list ) { for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->src_left << 16) | list->src_top; *buffer++ = (list->src_left << 16) | list->src_top;
*buffer++ = (list->dest_left << 16) | list->dest_top; *buffer++ = (list->dest_left << 16) | list->dest_top;
@@ -52,7 +52,7 @@ void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count
SUBMIT_IB_VC(); SUBMIT_IB_VC();
} }
++ai->si->engine.count; ++ai->si->engine.count;
} }
@@ -64,9 +64,9 @@ void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count
int xdir; int xdir;
int ydir; int ydir;
virtual_card *vc = ai->vc; virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo ( ai , 1 ); Radeon_WaitForFifo ( ai , 1 );
// Setup for Screen to screen blit // Setup for Screen to screen blit
@@ -76,33 +76,33 @@ void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count
| RADEON_ROP3_S | RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY | RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_SRC_PITCH_OFFSET_CNTL)); | RADEON_GMC_SRC_PITCH_OFFSET_CNTL));
for( ; count > 0; --count, ++list ) { for( ; count > 0; --count, ++list ) {
// make sure there is space in the FIFO for 4 register writes // make sure there is space in the FIFO for 4 register writes
Radeon_WaitForFifo ( ai , 4 ); Radeon_WaitForFifo ( ai , 4 );
xdir = ((list->src_left < list->dest_left) && (list->src_top == list->dest_top)) ? -1 : 1; xdir = ((list->src_left < list->dest_left) && (list->src_top == list->dest_top)) ? -1 : 1;
ydir = (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 (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 ; 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) OUTREG(ai->regs, RADEON_DP_CNTL, ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0)
| (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0))); | (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
// Tell the engine where the source data resides. // 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_SRC_Y_X, (list->src_top << 16 ) | list->src_left);
OUTREG( ai->regs, RADEON_DST_Y_X, (list->dest_top << 16 ) | list->dest_left); OUTREG( ai->regs, RADEON_DST_Y_X, (list->dest_top << 16 ) | list->dest_left);
// this is the blt initiator. // this is the blt initiator.
OUTREG( ai->regs, RADEON_DST_HEIGHT_WIDTH, ((list->height + 1) << 16 ) | (list->width + 1)); OUTREG( ai->regs, RADEON_DST_HEIGHT_WIDTH, ((list->height + 1) << 16 ) | (list->width + 1));
} }
++ai->si->engine.count; ++ai->si->engine.count;
et = et; (void)et;
} }
@@ -112,21 +112,21 @@ void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count
// 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_DMA(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;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
(void)et; (void)et;
while( count > 0 ) { while( count > 0 ) {
uint32 sub_count; uint32 sub_count;
START_IB(); START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count, WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE, 2, 3 ); INDIRECT_BUFFER_SIZE, 2, 3 );
*buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR *buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
@@ -137,11 +137,11 @@ void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
for( ; sub_count > 0; --sub_count, ++list ) { for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->left << 16) | list->top; *buffer++ = (list->left << 16) | list->top;
*buffer++ = *buffer++ =
((list->right - list->left + 1) << 16) | ((list->right - list->left + 1) << 16) |
(list->bottom - list->top + 1); (list->bottom - list->top + 1);
} }
SUBMIT_IB_VC(); SUBMIT_IB_VC();
} }
@@ -156,31 +156,31 @@ void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
// count - number of rectangles // count - number of rectangles
#define BRUSH_SOLIDCOLOR 0x00000d00 #define BRUSH_SOLIDCOLOR 0x00000d00
void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count) void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
{ {
virtual_card *vc = ai->vc; virtual_card *vc = ai->vc;
SHOW_FLOW( 4, "colorIndex", colorIndex); SHOW_FLOW( 4, "colorIndex", colorIndex);
Radeon_WaitForFifo(ai, 3); Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P)); | RADEON_ROP3_P));
// Set brush colour // Set brush colour
OUTREG(ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex); 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)); OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list ) for( ; count > 0; --count, ++list )
{ {
Radeon_WaitForFifo(ai, 2); Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left); 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)); OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
} }
++ai->si->engine.count; ++ai->si->engine.count;
et = et; (void)et;
} }
@@ -189,23 +189,23 @@ void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *l
// et - ignored // et - ignored
// list - list of rectangles // list - list of rectangles
// count - number of rectangles // count - number of rectangles
void INVERT_RECTANGLE_DMA(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;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
(void)et; (void)et;
while( count > 0 ) { while( count > 0 ) {
uint32 sub_count; uint32 sub_count;
START_IB(); START_IB();
// take core to leave space for ROP reset! // take core to leave space for ROP reset!
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count, WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE - 2, 2, 2 ); INDIRECT_BUFFER_SIZE - 2, 2, 2 );
*buffer++ = RADEON_GMC_BRUSH_NONE *buffer++ = RADEON_GMC_BRUSH_NONE
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
@@ -213,11 +213,11 @@ void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count
for( ; sub_count > 0; --sub_count, ++list ) { for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->left << 16) | list->top; *buffer++ = (list->left << 16) | list->top;
*buffer++ = *buffer++ =
((list->right - list->left + 1) << 16) | ((list->right - list->left + 1) << 16) |
(list->bottom - list->top + 1); (list->bottom - list->top + 1);
} }
// we have to reset ROP, else we get garbage during next // we have to reset ROP, else we get garbage during next
// CPU access; it looks like some cache coherency/forwarding // CPU access; it looks like some cache coherency/forwarding
// problem as it goes away later on; things like flushing the // problem as it goes away later on; things like flushing the
@@ -239,12 +239,12 @@ void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count
} }
void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count) void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count)
{ {
virtual_card *vc = ai->vc; virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo(ai, 3); Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_NONE | RADEON_GMC_BRUSH_NONE
@@ -254,17 +254,17 @@ void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count
OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM)); OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list ) for( ; count > 0; --count, ++list )
{ {
Radeon_WaitForFifo(ai, 2); Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left); 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)); OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
} }
++ai->si->engine.count; ++ai->si->engine.count;
et = et; (void)et;
} }
// fill horizontal spans on screen // fill horizontal spans on screen
@@ -272,39 +272,39 @@ void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count
// 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_DMA(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;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
(void)et; (void)et;
while( count > 0 ) { while( count > 0 ) {
uint32 sub_count; uint32 sub_count;
START_IB(); START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count, WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE , 2, 3 ); INDIRECT_BUFFER_SIZE , 2, 3 );
*buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR *buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P; | RADEON_ROP3_P;
*buffer++ = colorIndex; *buffer++ = colorIndex;
for( ; sub_count > 0; --sub_count ) { for( ; sub_count > 0; --sub_count ) {
uint16 y, x, width; uint16 y, x, width;
y = *list++; y = *list++;
x = *list++; x = *list++;
width = *list++ - x + 1; width = *list++ - x + 1;
*buffer++ = (x << 16) | y; *buffer++ = (x << 16) | y;
*buffer++ = (width << 16) | 1; *buffer++ = (width << 16) | 1;
} }
SUBMIT_IB_VC(); SUBMIT_IB_VC();
} }
@@ -317,45 +317,45 @@ void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 cou
// 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_PIO(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count) void FILL_SPAN_PIO(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{ {
virtual_card *vc = ai->vc; virtual_card *vc = ai->vc;
//int offset = 0; //int offset = 0;
uint16 y, x, width; uint16 y, x, width;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo( ai , 1); Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, 0 OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, 0
| RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P); | RADEON_ROP3_P);
if ( ai->si->asic >= rt_rv200 ) { if ( ai->si->asic >= rt_rv200 ) {
Radeon_WaitForFifo( ai , 1); Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT); OUTREG( ai->regs, RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT);
} }
Radeon_WaitForFifo( ai , 1); Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex); OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
for( ; count > 0; --count ) { for( ; count > 0; --count ) {
Radeon_WaitForFifo( ai , 2); Radeon_WaitForFifo( ai , 2);
y = *list++; y = *list++;
x = *list++; x = *list++;
width = *list++ - x + 1; width = *list++ - x + 1;
OUTREG( ai->regs, RADEON_DST_LINE_START, (y << 16) | x); OUTREG( ai->regs, RADEON_DST_LINE_START, (y << 16) | x);
OUTREG( ai->regs, RADEON_DST_LINE_END, ((y) << 16) | (x + width)); OUTREG( ai->regs, RADEON_DST_LINE_END, ((y) << 16) | (x + width));
} }
++ai->si->engine.count; ++ai->si->engine.count;
et = et; (void)et;
} }
@@ -398,7 +398,7 @@ void Radeon_Init2D( accelerator_info *ai )
{ {
SHOW_FLOW0( 3, "" ); SHOW_FLOW0( 3, "" );
// forget about 3D // forget about 3D
if ( ai->si->acc_dma ) { if ( ai->si->acc_dma ) {
START_IB(); START_IB();
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 ); WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
@@ -415,38 +415,38 @@ 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 = NULL, *buffer_start = NULL; uint32 *buffer = NULL, *buffer_start = NULL;
SHOW_FLOW0( 4, "" ); SHOW_FLOW0( 4, "" );
// 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);
if ( ai->si->acc_dma ) { if ( ai->si->acc_dma ) {
// make sure buffer is not used // make sure buffer is not used
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx ); Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx ); buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset ); WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset ); WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset ); WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
// no sissors // no sissors
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT, WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX)); (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
// general fluff // general fluff
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL, WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT) (datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P | RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY | RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS ); | RADEON_GMC_WR_MSK_DIS );
// most of this init is probably not necessary // 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_DP_BRUSH_FRGD_CLR, 0xffffffff); WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
@@ -454,7 +454,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff); WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000); WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff); WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
// this is required // this is required
vc->state_buffer_size = buffer - buffer_start; vc->state_buffer_size = buffer - buffer_start;
@@ -463,21 +463,21 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
OUTREG( ai->regs, RADEON_DEFAULT_OFFSET, pitch_offset ); OUTREG( ai->regs, RADEON_DEFAULT_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_DST_PITCH_OFFSET, pitch_offset ); OUTREG( ai->regs, RADEON_DST_PITCH_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_SRC_PITCH_OFFSET, pitch_offset ); OUTREG( ai->regs, RADEON_SRC_PITCH_OFFSET, pitch_offset );
// no sissors // no sissors
OUTREG( ai->regs, RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX OUTREG( ai->regs, RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
| RADEON_DEFAULT_SC_BOTTOM_MAX)); | RADEON_DEFAULT_SC_BOTTOM_MAX));
// general fluff // general fluff
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT) (datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR | RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P | RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY | RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS ); | RADEON_GMC_WR_MSK_DIS );
// most of this init is probably not necessary // most of this init is probably not necessary
// as we neither draw lines nor use brushes // as we neither draw lines nor use brushes
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
@@ -487,7 +487,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff); OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff);
} }
ai->si->active_vc = vc->id; ai->si->active_vc = vc->id;
} }
@@ -496,7 +496,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
void Radeon_AllocateVirtualCardStateBuffer( accelerator_info *ai ) void Radeon_AllocateVirtualCardStateBuffer( accelerator_info *ai )
{ {
virtual_card *vc = ai->vc; virtual_card *vc = ai->vc;
vc->state_buffer_idx = Radeon_AllocIndirectBuffer( ai, false ); vc->state_buffer_idx = Radeon_AllocIndirectBuffer( ai, false );
// mark as being unused // mark as being unused
vc->state_buffer_size = -1; vc->state_buffer_size = -1;
+105 -105
View File
@@ -1,9 +1,9 @@
/* /*
Copyright (c) 2002-2004, Thomas Kurschel Copyright (c) 2002-2004, Thomas Kurschel
Part of Radeon accelerant Part of Radeon accelerant
Takes care of PLL Takes care of PLL
*/ */
@@ -17,29 +17,29 @@
#include "set_mode.h" #include "set_mode.h"
static void Radeon_PLLWaitForReadUpdateComplete( static void Radeon_PLLWaitForReadUpdateComplete(
accelerator_info *ai, int crtc_idx ) accelerator_info *ai, int crtc_idx )
{ {
int i; int i;
// we should wait forever, but // we should wait forever, but
// 1. this is unsafe // 1. this is unsafe
// 2. some r300 loop forever (reported by XFree86) // 2. some r300 loop forever (reported by XFree86)
for( i = 0; i < 10000; ++i ) { for( i = 0; i < 10000; ++i ) {
if( (Radeon_INPLL( ai->regs, ai->si->asic, crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV ) if( (Radeon_INPLL( ai->regs, ai->si->asic, crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV )
& RADEON_PPLL_ATOMIC_UPDATE_R) == 0 ) & RADEON_PPLL_ATOMIC_UPDATE_R) == 0 )
return; return;
} }
} }
static void Radeon_PLLWriteUpdate( static void Radeon_PLLWriteUpdate(
accelerator_info *ai, int crtc_idx ) accelerator_info *ai, int crtc_idx )
{ {
Radeon_PLLWaitForReadUpdateComplete( ai, crtc_idx ); Radeon_PLLWaitForReadUpdateComplete( ai, crtc_idx );
Radeon_OUTPLLP( ai->regs, ai->si->asic, Radeon_OUTPLLP( ai->regs, ai->si->asic,
crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV, crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV,
RADEON_PPLL_ATOMIC_UPDATE_W, RADEON_PPLL_ATOMIC_UPDATE_W,
~RADEON_PPLL_ATOMIC_UPDATE_W ); ~RADEON_PPLL_ATOMIC_UPDATE_W );
} }
@@ -48,7 +48,7 @@ static void Radeon_PLLWriteUpdate(
// freq - whished frequency in Hz // freq - whished frequency in Hz
// fixed_post_div - if != 0, fixed divider to be used // fixed_post_div - if != 0, fixed divider to be used
// dividers - filled with proper dividers // dividers - filled with proper dividers
void Radeon_CalcPLLDividers( void Radeon_CalcPLLDividers(
const pll_info *pll, uint32 freq, uint fixed_post_div, pll_dividers *dividers ) const pll_info *pll, uint32 freq, uint fixed_post_div, pll_dividers *dividers )
{ {
// the PLL gets the reference // the PLL gets the reference
@@ -63,24 +63,24 @@ void Radeon_CalcPLLDividers(
// pll_out = vco / post_div / extra_post_div // pll_out = vco / post_div / extra_post_div
// = ref_freq * feedback_div * extra_feedback_div / (ref_div * post_div * extra_post_div) // = ref_freq * feedback_div * extra_feedback_div / (ref_div * post_div * extra_post_div)
// where extra_post_div _may_ be choosable between 1 and 2 // where extra_post_div _may_ be choosable between 1 and 2
// synonyms are: // synonyms are:
// ref_div = M // ref_div = M
// feedback_div = N // feedback_div = N
// post_div = P // post_div = P
int int
min_post_div_idx, max_post_div_idx, min_post_div_idx, max_post_div_idx,
post_div_idx, extra_post_div_idx, post_div_idx, extra_post_div_idx,
best_post_div_idx, best_extra_post_div_idx; best_post_div_idx, best_extra_post_div_idx;
uint32 uint32
best_ref_div, best_feedback_div, best_freq; best_ref_div, best_feedback_div, best_freq;
int32 int32
best_error, best_vco_dev; best_error, best_vco_dev;
best_error = 999999999; best_error = 999999999;
// make compiler happy // make compiler happy
best_post_div_idx = 0; best_post_div_idx = 0;
best_extra_post_div_idx = 0; best_extra_post_div_idx = 0;
@@ -91,42 +91,42 @@ void Radeon_CalcPLLDividers(
if( fixed_post_div == 0 ) { if( fixed_post_div == 0 ) {
min_post_div_idx = 0; min_post_div_idx = 0;
for( for(
max_post_div_idx = 0; max_post_div_idx = 0;
pll->post_divs[max_post_div_idx].divider != 0; pll->post_divs[max_post_div_idx].divider != 0;
++max_post_div_idx ) ++max_post_div_idx )
; ;
--max_post_div_idx; --max_post_div_idx;
} else { } else {
for( for(
min_post_div_idx = 0; min_post_div_idx = 0;
pll->post_divs[min_post_div_idx].divider != fixed_post_div; pll->post_divs[min_post_div_idx].divider != fixed_post_div;
++min_post_div_idx ) ++min_post_div_idx )
; ;
max_post_div_idx = min_post_div_idx; max_post_div_idx = min_post_div_idx;
//SHOW_FLOW( 2, "idx of fixed post divider: %d", min_post_div_idx ); //SHOW_FLOW( 2, "idx of fixed post divider: %d", min_post_div_idx );
} }
// post dividers are quite restrictive, so they provide little search space only // post dividers are quite restrictive, so they provide little search space only
for( extra_post_div_idx = 0; pll->extra_post_divs[extra_post_div_idx].divider != 0; ++extra_post_div_idx ) { for( extra_post_div_idx = 0; pll->extra_post_divs[extra_post_div_idx].divider != 0; ++extra_post_div_idx ) {
for( post_div_idx = min_post_div_idx; post_div_idx <= max_post_div_idx; ++post_div_idx ) { for( post_div_idx = min_post_div_idx; post_div_idx <= max_post_div_idx; ++post_div_idx ) {
uint32 ref_div; uint32 ref_div;
uint32 post_div = uint32 post_div =
pll->post_divs[post_div_idx].divider pll->post_divs[post_div_idx].divider
* pll->extra_post_divs[extra_post_div_idx].divider; * pll->extra_post_divs[extra_post_div_idx].divider;
// post devider determines VCO frequency, so determine and verify it; // post devider determines VCO frequency, so determine and verify it;
// freq is in Hz, everything else is in 10 kHz units // freq is in Hz, everything else is in 10 kHz units
// we use 10 kHz units as long as possible to avoid uint32 overflows // we use 10 kHz units as long as possible to avoid uint32 overflows
uint32 vco = (freq / 10000) * post_div; uint32 vco = (freq / 10000) * post_div;
//SHOW_FLOW( 2, "post_div=%d, vco=%d", post_div, vco ); //SHOW_FLOW( 2, "post_div=%d, vco=%d", post_div, vco );
if( vco < pll->vco_min || vco > pll->vco_max ) if( vco < pll->vco_min || vco > pll->vco_max )
continue; continue;
//SHOW_FLOW0( 2, "jau" ); //SHOW_FLOW0( 2, "jau" );
// we can either iterate through feedback or reference dividers; // we can either iterate through feedback or reference dividers;
@@ -134,40 +134,40 @@ void Radeon_CalcPLLDividers(
for( ref_div = pll->min_ref_div; ref_div <= pll->max_ref_div; ++ref_div ) { for( ref_div = pll->min_ref_div; ref_div <= pll->max_ref_div; ++ref_div ) {
uint32 feedback_div, cur_freq; uint32 feedback_div, cur_freq;
int32 error, vco_dev; int32 error, vco_dev;
// this implies the frequency of the lock unit // this implies the frequency of the lock unit
uint32 pll_in = pll->ref_freq / ref_div; uint32 pll_in = pll->ref_freq / ref_div;
if( pll_in < pll->pll_in_min || pll_in > pll->pll_in_max ) if( pll_in < pll->pll_in_min || pll_in > pll->pll_in_max )
continue; continue;
// well, only one variable is left // well, only one variable is left
// timing is almost certainly valid, time to use Hz units // timing is almost certainly valid, time to use Hz units
feedback_div = RoundDiv64( feedback_div = RoundDiv64(
(int64)freq * ref_div * post_div, (int64)freq * ref_div * post_div,
pll->ref_freq * 10000 * pll->extra_feedback_div); pll->ref_freq * 10000 * pll->extra_feedback_div);
if( feedback_div < pll->min_feedback_div || if( feedback_div < pll->min_feedback_div ||
feedback_div > pll->max_feedback_div ) feedback_div > pll->max_feedback_div )
continue; continue;
// let's see what we've got // let's see what we've got
cur_freq = RoundDiv64( cur_freq = RoundDiv64(
(int64)pll->ref_freq * 10000 * feedback_div * pll->extra_feedback_div, (int64)pll->ref_freq * 10000 * feedback_div * pll->extra_feedback_div,
ref_div * post_div ); ref_div * post_div );
// absolute error in terms of output clock // absolute error in terms of output clock
error = abs( cur_freq - freq ); error = abs( (int32)cur_freq - (int32)freq );
// deviation from perfect VCO clock // deviation from perfect VCO clock
vco_dev = abs( vco - pll->best_vco ); vco_dev = abs( (int32)vco - (int32)(pll->best_vco) );
// if there is no optimal VCO frequency, choose setting with less error; // if there is no optimal VCO frequency, choose setting with less error;
// if there is an optimal VCO frequency, choose new settings if // if there is an optimal VCO frequency, choose new settings if
// - error is reduced significantly (100 Hz or more), or // - error is reduced significantly (100 Hz or more), or
// - output frequency is almost the same (less then 100 Hz difference) but // - output frequency is almost the same (less then 100 Hz difference) but
// VCO frequency is closer to best frequency // VCO frequency is closer to best frequency
if( (pll->best_vco == 0 && error < best_error) || if( (pll->best_vco == 0 && error < best_error) ||
(pll->best_vco != 0 && (pll->best_vco != 0 &&
(error < best_error - 100 || (error < best_error - 100 ||
(abs( error - best_error ) < 100 && vco_dev < best_vco_dev )))) (abs( error - best_error ) < 100 && vco_dev < best_vco_dev ))))
{ {
@@ -193,57 +193,57 @@ void Radeon_CalcPLLDividers(
dividers->freq = best_freq; dividers->freq = best_freq;
/*SHOW_FLOW( 2, "post_code=%d, post=%d, extra_post_code=%d, extra_post=%d, ref=%d, feedback=%d, freq=%d", /*SHOW_FLOW( 2, "post_code=%d, post=%d, extra_post_code=%d, extra_post=%d, ref=%d, feedback=%d, freq=%d",
dividers->post_code, dividers->post, dividers->extra_post_code, dividers->post_code, dividers->post, dividers->extra_post_code,
dividers->extra_post, dividers->ref, dividers->feedback, dividers->freq );*/ dividers->extra_post, dividers->ref, dividers->feedback, dividers->freq );*/
} }
// with a TV timing given, find a corresponding CRT timing. // with a TV timing given, find a corresponding CRT timing.
// both timing must meet at the end of a frame, but as the PLL has a // both timing must meet at the end of a frame, but as the PLL has a
// limited frequency granularity, you don't really get a CRT timing // limited frequency granularity, you don't really get a CRT timing
// with precisely the same frame rate; the solution is to tweak the CRT // with precisely the same frame rate; the solution is to tweak the CRT
// image a bit by making it wider/taller/smaller until the frame rate // image a bit by making it wider/taller/smaller until the frame rate
// drift is under a given threshold; // drift is under a given threshold;
// we follow two aims: // we follow two aims:
// - primary, keep frame rate in sync // - primary, keep frame rate in sync
// - secondary, only tweak as much as unavoidable // - secondary, only tweak as much as unavoidable
void Radeon_MatchCRTPLL( void Radeon_MatchCRTPLL(
const pll_info *pll, const pll_info *pll,
uint32 tv_v_total, uint32 tv_h_total, uint32 tv_frame_size_adjust, uint32 freq, uint32 tv_v_total, uint32 tv_h_total, uint32 tv_frame_size_adjust, uint32 freq,
const display_mode *mode, uint32 max_v_tweak, uint32 max_h_tweak, const display_mode *mode, uint32 max_v_tweak, uint32 max_h_tweak,
uint32 max_frame_rate_drift, uint32 fixed_post_div, uint32 max_frame_rate_drift, uint32 fixed_post_div,
pll_dividers *dividers, pll_dividers *dividers,
display_mode *tweaked_mode ) display_mode *tweaked_mode )
{ {
uint32 v_tweak; uint32 v_tweak;
int32 v_tweak_dir; int32 v_tweak_dir;
uint32 pix_per_tv_frame; uint32 pix_per_tv_frame;
SHOW_FLOW( 2, "fixed post divider: %d", fixed_post_div ); SHOW_FLOW( 2, "fixed post divider: %d", fixed_post_div );
// number of TV pixels per frame // number of TV pixels per frame
pix_per_tv_frame = tv_v_total * tv_h_total + tv_frame_size_adjust; pix_per_tv_frame = tv_v_total * tv_h_total + tv_frame_size_adjust;
// starting with original data we tweak total horizontal and vertical size // starting with original data we tweak total horizontal and vertical size
// more and more until we find a proper CRT clock frequency // more and more until we find a proper CRT clock frequency
for( v_tweak = 0; v_tweak <= max_v_tweak; ++v_tweak ) { for( v_tweak = 0; v_tweak <= max_v_tweak; ++v_tweak ) {
for( v_tweak_dir = -1; v_tweak_dir <= 1; v_tweak_dir += 2 ) { for( v_tweak_dir = -1; v_tweak_dir <= 1; v_tweak_dir += 2 ) {
uint32 h_tweak; uint32 h_tweak;
int32 h_tweak_dir; int32 h_tweak_dir;
uint32 v_total = mode->timing.v_total + v_tweak * v_tweak_dir; uint32 v_total = mode->timing.v_total + v_tweak * v_tweak_dir;
for( h_tweak = 0; h_tweak <= max_h_tweak; ++h_tweak ) { for( h_tweak = 0; h_tweak <= max_h_tweak; ++h_tweak ) {
for( h_tweak_dir = -1; h_tweak_dir <= 1; h_tweak_dir += 2 ) { for( h_tweak_dir = -1; h_tweak_dir <= 1; h_tweak_dir += 2 ) {
uint32 pix_per_crt_frame, frame_rate_drift; uint32 pix_per_crt_frame, frame_rate_drift;
uint32 crt_freq; uint32 crt_freq;
uint32 abs_crt_error; uint32 abs_crt_error;
uint32 h_total = mode->timing.h_total + h_tweak * h_tweak_dir; uint32 h_total = mode->timing.h_total + h_tweak * h_tweak_dir;
// number of CRT pixels per frame // number of CRT pixels per frame
pix_per_crt_frame = v_total * h_total; pix_per_crt_frame = v_total * h_total;
// frame rate must be: // frame rate must be:
// frame_rate = freq / pix_per_tv_half_frame // frame_rate = freq / pix_per_tv_half_frame
// because of interlace, we must use half frames // because of interlace, we must use half frames
@@ -253,14 +253,14 @@ void Radeon_MatchCRTPLL(
// = freq / (pix_per_tv_frame / 2) * pix_per_crt_frame // = freq / (pix_per_tv_frame / 2) * pix_per_crt_frame
// formula is reordered as usual to improve accuracy // formula is reordered as usual to improve accuracy
crt_freq = (uint64)freq * pix_per_crt_frame * 2 / pix_per_tv_frame; crt_freq = (uint64)freq * pix_per_crt_frame * 2 / pix_per_tv_frame;
Radeon_CalcPLLDividers( pll, crt_freq, fixed_post_div, dividers ); Radeon_CalcPLLDividers( pll, crt_freq, fixed_post_div, dividers );
// get absolute CRT clock error per second // get absolute CRT clock error per second
abs_crt_error = abs( dividers->freq - crt_freq ); abs_crt_error = abs( (int32)(dividers->freq) - (int32)crt_freq );
//SHOW_INFO( 2, "whished=%d, is=%d", crt_freq, dividers->freq ); //SHOW_INFO( 2, "whished=%d, is=%d", crt_freq, dividers->freq );
// convert it to relative CRT clock error: // convert it to relative CRT clock error:
// rel_error = abs_crt_error / crt_freq // rel_error = abs_crt_error / crt_freq
// now to absolute TV clock error per second: // now to absolute TV clock error per second:
@@ -274,14 +274,14 @@ void Radeon_MatchCRTPLL(
// frame_rate_drift = abs_crt_error / crt_freq * pix_per_tv_frame * frame_rate / frame_rate // frame_rate_drift = abs_crt_error / crt_freq * pix_per_tv_frame * frame_rate / frame_rate
// = abs_crt_error / crt_freq * pix_per_tv_frame // = abs_crt_error / crt_freq * pix_per_tv_frame
frame_rate_drift = (uint64)abs_crt_error * pix_per_tv_frame / freq; frame_rate_drift = (uint64)abs_crt_error * pix_per_tv_frame / freq;
// if drift is within threshold, we take this setting and stop // if drift is within threshold, we take this setting and stop
// searching (later iteration will increasingly tweak screen size, // searching (later iteration will increasingly tweak screen size,
// and we don't really want that) // and we don't really want that)
if( frame_rate_drift <= max_frame_rate_drift ) { if( frame_rate_drift <= max_frame_rate_drift ) {
SHOW_INFO( 2, "frame_rate_drift=%d, crt_freq=%d, v_total=%d, h_total=%d", SHOW_INFO( 2, "frame_rate_drift=%d, crt_freq=%d, v_total=%d, h_total=%d",
frame_rate_drift, crt_freq, v_total, h_total ); frame_rate_drift, crt_freq, v_total, h_total );
tweaked_mode->timing.pixel_clock = crt_freq; tweaked_mode->timing.pixel_clock = crt_freq;
tweaked_mode->timing.v_total = v_total; tweaked_mode->timing.v_total = v_total;
tweaked_mode->timing.h_total = h_total; tweaked_mode->timing.h_total = h_total;
@@ -345,7 +345,7 @@ static pll_divider_map tv_post_divs[] = {
// get PLL parameters of TV PLL // get PLL parameters of TV PLL
void Radeon_GetTVPLLConfiguration( const general_pll_info *general_pll, pll_info *pll, void Radeon_GetTVPLLConfiguration( const general_pll_info *general_pll, pll_info *pll,
bool internal_encoder ) bool internal_encoder )
{ {
pll->post_divs = tv_post_divs; pll->post_divs = tv_post_divs;
@@ -376,16 +376,16 @@ void Radeon_GetTVCRTPLLConfiguration( const general_pll_info *general_pll, pll_i
pll->post_divs = post_divs; pll->post_divs = post_divs;
pll->extra_post_divs = extra_post_divs; pll->extra_post_divs = extra_post_divs;
pll->ref_freq = general_pll->ref_freq; pll->ref_freq = general_pll->ref_freq;
// in sample code, these limits are set in a strange way; // in sample code, these limits are set in a strange way;
// as a first shot, I use the BIOS provided limits // as a first shot, I use the BIOS provided limits
/*pll->vco_min = general_pll->min_pll_freq; /*pll->vco_min = general_pll->min_pll_freq;
pll->vco_max = general_pll->max_pll_freq;*/ pll->vco_max = general_pll->max_pll_freq;*/
// in sample code, they use a variable post divider during calculation, but // in sample code, they use a variable post divider during calculation, but
// use a fixed post divider for programming - the variable post divider is // use a fixed post divider for programming - the variable post divider is
// multiplied to the feedback divider; // multiplied to the feedback divider;
// because of the fixed post divider (3), the VCO always runs far out of // because of the fixed post divider (3), the VCO always runs far out of
// its stable frequency range, so we have hack the limits // its stable frequency range, so we have hack the limits
pll->vco_min = 4000; pll->vco_min = 4000;
pll->vco_max = general_pll->max_pll_freq; pll->vco_max = general_pll->max_pll_freq;
@@ -404,11 +404,11 @@ void Radeon_GetTVCRTPLLConfiguration( const general_pll_info *general_pll, pll_i
// calc PLL dividers for CRT // calc PLL dividers for CRT
// mode->timing.pixel_clock must be in Hz because required accuracy in TV-Out mode // mode->timing.pixel_clock must be in Hz because required accuracy in TV-Out mode
void Radeon_CalcCRTPLLDividers( void Radeon_CalcCRTPLLDividers(
const general_pll_info *general_pll, const display_mode *mode, pll_dividers *dividers ) const general_pll_info *general_pll, const display_mode *mode, pll_dividers *dividers )
{ {
pll_info pll; pll_info pll;
pll.post_divs = post_divs; pll.post_divs = post_divs;
pll.extra_post_divs = extra_post_divs; pll.extra_post_divs = extra_post_divs;
pll.ref_freq = general_pll->ref_freq; pll.ref_freq = general_pll->ref_freq;
@@ -429,17 +429,17 @@ void Radeon_CalcCRTPLLDividers(
} }
// calculate PLL registers // calculate PLL registers
// mode->timing.pixel_clock must be in Hz because required accuracy in TV-Out mode // mode->timing.pixel_clock must be in Hz because required accuracy in TV-Out mode
// (old: freq is in 10kHz) // (old: freq is in 10kHz)
void Radeon_CalcPLLRegisters( void Radeon_CalcPLLRegisters(
const display_mode *mode, const pll_dividers *dividers, pll_regs *values ) const display_mode *mode, const pll_dividers *dividers, pll_regs *values )
{ {
values->dot_clock_freq = dividers->freq; values->dot_clock_freq = dividers->freq;
values->feedback_div = dividers->feedback; values->feedback_div = dividers->feedback;
values->post_div = dividers->post; values->post_div = dividers->post;
values->pll_output_freq = dividers->freq * dividers->post; values->pll_output_freq = dividers->freq * dividers->post;
values->ppll_ref_div = dividers->ref; values->ppll_ref_div = dividers->ref;
values->ppll_div_3 = (dividers->feedback | (dividers->post_code << 16)); values->ppll_div_3 = (dividers->feedback | (dividers->post_code << 16));
// this is mad: the PLL controls the horizontal length in sub-byte precision! // this is mad: the PLL controls the horizontal length in sub-byte precision!
@@ -451,17 +451,17 @@ void Radeon_CalcPLLRegisters(
} }
// write values into PLL registers // write values into PLL registers
void Radeon_ProgramPLL( void Radeon_ProgramPLL(
accelerator_info *ai, int crtc_idx, pll_regs *values ) accelerator_info *ai, int crtc_idx, pll_regs *values )
{ {
vuint8 *regs = ai->regs; vuint8 *regs = ai->regs;
radeon_type asic = ai->si->asic; radeon_type asic = ai->si->asic;
SHOW_FLOW0( 2, "" ); SHOW_FLOW0( 2, "" );
// use some other PLL for pixel clock source to not fiddling with PLL // use some other PLL for pixel clock source to not fiddling with PLL
// while somebody is using it // while somebody is using it
Radeon_OUTPLLP( regs, asic, crtc_idx == 0 ? RADEON_VCLK_ECP_CNTL : RADEON_PIXCLKS_CNTL, Radeon_OUTPLLP( regs, asic, crtc_idx == 0 ? RADEON_VCLK_ECP_CNTL : RADEON_PIXCLKS_CNTL,
RADEON_VCLK_SRC_CPU_CLK, ~RADEON_VCLK_SRC_SEL_MASK ); RADEON_VCLK_SRC_CPU_CLK, ~RADEON_VCLK_SRC_SEL_MASK );
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
@@ -472,48 +472,48 @@ void Radeon_ProgramPLL(
~(RADEON_PPLL_RESET ~(RADEON_PPLL_RESET
| RADEON_PPLL_ATOMIC_UPDATE_EN | RADEON_PPLL_ATOMIC_UPDATE_EN
| RADEON_PPLL_VGA_ATOMIC_UPDATE_EN) ); | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN) );
// select divider 3 (well, only required for first PLL) // select divider 3 (well, only required for first PLL)
OUTREGP( regs, RADEON_CLOCK_CNTL_INDEX, OUTREGP( regs, RADEON_CLOCK_CNTL_INDEX,
RADEON_PLL_DIV_SEL_DIV3, RADEON_PLL_DIV_SEL_DIV3,
~RADEON_PLL_DIV_SEL_MASK ); ~RADEON_PLL_DIV_SEL_MASK );
RADEONPllErrataAfterIndex(regs, asic); RADEONPllErrataAfterIndex(regs, asic);
if( ai->si->new_pll && crtc_idx == 0 ) { if( ai->si->new_pll && crtc_idx == 0 ) {
// starting with r300, the reference divider of the first PLL was // starting with r300, the reference divider of the first PLL was
// moved to another bit position; at the old location, you only // moved to another bit position; at the old location, you only
// find the "BIOS suggested divider"; no clue why they did that // find the "BIOS suggested divider"; no clue why they did that
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
RADEON_PPLL_REF_DIV, RADEON_PPLL_REF_DIV,
values->ppll_ref_div << RADEON_PPLL_REF_DIV_ACC_SHIFT, values->ppll_ref_div << RADEON_PPLL_REF_DIV_ACC_SHIFT,
~RADEON_PPLL_REF_DIV_ACC_MASK ); ~RADEON_PPLL_REF_DIV_ACC_MASK );
} else { } else {
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV, crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV,
values->ppll_ref_div, values->ppll_ref_div,
~RADEON_PPLL_REF_DIV_MASK ); ~RADEON_PPLL_REF_DIV_MASK );
} }
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0, crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
values->ppll_div_3, values->ppll_div_3,
~RADEON_PPLL_FB3_DIV_MASK ); ~RADEON_PPLL_FB3_DIV_MASK );
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0, crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
values->ppll_div_3, values->ppll_div_3,
~RADEON_PPLL_POST3_DIV_MASK ); ~RADEON_PPLL_POST3_DIV_MASK );
Radeon_PLLWriteUpdate( ai, crtc_idx ); Radeon_PLLWriteUpdate( ai, crtc_idx );
Radeon_PLLWaitForReadUpdateComplete( ai, crtc_idx ); Radeon_PLLWaitForReadUpdateComplete( ai, crtc_idx );
Radeon_OUTPLL( regs, asic, Radeon_OUTPLL( regs, asic,
crtc_idx == 0 ? RADEON_HTOTAL_CNTL : RADEON_HTOTAL2_CNTL, crtc_idx == 0 ? RADEON_HTOTAL_CNTL : RADEON_HTOTAL2_CNTL,
values->htotal_cntl ); values->htotal_cntl );
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
crtc_idx == 0 ? RADEON_PPLL_CNTL : RADEON_P2PLL_CNTL, 0, crtc_idx == 0 ? RADEON_PPLL_CNTL : RADEON_P2PLL_CNTL, 0,
~(RADEON_PPLL_RESET ~(RADEON_PPLL_RESET
| RADEON_PPLL_SLEEP | RADEON_PPLL_SLEEP
| RADEON_PPLL_ATOMIC_UPDATE_EN | RADEON_PPLL_ATOMIC_UPDATE_EN
@@ -524,6 +524,6 @@ void Radeon_ProgramPLL(
// use PLL for pixel clock again // use PLL for pixel clock again
Radeon_OUTPLLP( regs, asic, Radeon_OUTPLLP( regs, asic,
crtc_idx == 0 ? RADEON_VCLK_ECP_CNTL : RADEON_PIXCLKS_CNTL, crtc_idx == 0 ? RADEON_VCLK_ECP_CNTL : RADEON_PIXCLKS_CNTL,
RADEON_VCLK_SRC_PPLL_CLK, ~RADEON_VCLK_SRC_SEL_MASK ); RADEON_VCLK_SRC_PPLL_CLK, ~RADEON_VCLK_SRC_SEL_MASK );
} }