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:
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
Part of Radeon accelerant
|
||||
|
||||
|
||||
Public functions to provide 2D hardware acceleration
|
||||
*/
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
// et - ignored
|
||||
// list - list 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;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
|
||||
(void)et;
|
||||
|
||||
while( count > 0 ) {
|
||||
@@ -35,15 +35,15 @@ void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
*buffer++ = RADEON_GMC_BRUSH_NONE
|
||||
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||
| RADEON_GMC_SRC_DATATYPE_COLOR
|
||||
| RADEON_ROP3_S
|
||||
| RADEON_DP_SRC_SOURCE_MEMORY;
|
||||
|
||||
|
||||
for( ; sub_count > 0; --sub_count, ++list ) {
|
||||
*buffer++ = (list->src_left << 16) | list->src_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();
|
||||
}
|
||||
|
||||
|
||||
++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 ydir;
|
||||
virtual_card *vc = ai->vc;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
|
||||
Radeon_WaitForFifo ( ai , 1 );
|
||||
|
||||
// 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_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)
|
||||
|
||||
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;
|
||||
(void)et;
|
||||
|
||||
}
|
||||
|
||||
@@ -112,21 +112,21 @@ void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count
|
||||
// colorIndex - fill colour
|
||||
// list - list of rectangles
|
||||
// count - number of rectangles
|
||||
void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
|
||||
fill_rect_params *list, uint32 count)
|
||||
void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
|
||||
fill_rect_params *list, uint32 count)
|
||||
{
|
||||
virtual_card *vc = ai->vc;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
|
||||
(void)et;
|
||||
|
||||
while( count > 0 ) {
|
||||
uint32 sub_count;
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
*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 ) {
|
||||
*buffer++ = (list->left << 16) | list->top;
|
||||
*buffer++ =
|
||||
((list->right - list->left + 1) << 16) |
|
||||
*buffer++ =
|
||||
((list->right - list->left + 1) << 16) |
|
||||
(list->bottom - list->top + 1);
|
||||
}
|
||||
|
||||
|
||||
SUBMIT_IB_VC();
|
||||
}
|
||||
|
||||
@@ -156,31 +156,31 @@ void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
|
||||
// count - number of rectangles
|
||||
#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;
|
||||
|
||||
|
||||
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
|
||||
// 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 )
|
||||
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;
|
||||
(void)et;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,23 +189,23 @@ void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *l
|
||||
// et - ignored
|
||||
// list - list 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;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
|
||||
(void)et;
|
||||
|
||||
while( count > 0 ) {
|
||||
uint32 sub_count;
|
||||
|
||||
|
||||
START_IB();
|
||||
|
||||
|
||||
// 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 );
|
||||
|
||||
|
||||
*buffer++ = RADEON_GMC_BRUSH_NONE
|
||||
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||
| 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 ) {
|
||||
*buffer++ = (list->left << 16) | list->top;
|
||||
*buffer++ =
|
||||
((list->right - list->left + 1) << 16) |
|
||||
*buffer++ =
|
||||
((list->right - list->left + 1) << 16) |
|
||||
(list->bottom - list->top + 1);
|
||||
}
|
||||
|
||||
|
||||
// we have to reset ROP, else we get garbage during next
|
||||
// CPU access; it looks like some cache coherency/forwarding
|
||||
// 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;
|
||||
|
||||
|
||||
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
|
||||
@@ -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));
|
||||
|
||||
for( ; count > 0; --count, ++list )
|
||||
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;
|
||||
|
||||
(void)et;
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
// list - list 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;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
|
||||
(void)et;
|
||||
|
||||
while( count > 0 ) {
|
||||
uint32 sub_count;
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
*buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
|
||||
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||
| RADEON_GMC_SRC_DATATYPE_COLOR
|
||||
| RADEON_ROP3_P;
|
||||
*buffer++ = colorIndex;
|
||||
|
||||
|
||||
for( ; sub_count > 0; --sub_count ) {
|
||||
uint16 y, x, width;
|
||||
|
||||
|
||||
y = *list++;
|
||||
x = *list++;
|
||||
width = *list++ - x + 1;
|
||||
|
||||
|
||||
*buffer++ = (x << 16) | y;
|
||||
*buffer++ = (width << 16) | 1;
|
||||
}
|
||||
|
||||
|
||||
SUBMIT_IB_VC();
|
||||
}
|
||||
|
||||
@@ -317,45 +317,45 @@ void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 cou
|
||||
// colorIndex - fill colour
|
||||
// list - list 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;
|
||||
//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);
|
||||
|
||||
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)et;
|
||||
}
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ void Radeon_Init2D( accelerator_info *ai )
|
||||
{
|
||||
SHOW_FLOW0( 3, "" );
|
||||
|
||||
// forget about 3D
|
||||
// forget about 3D
|
||||
if ( ai->si->acc_dma ) {
|
||||
START_IB();
|
||||
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
|
||||
@@ -415,38 +415,38 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
|
||||
virtual_card *vc = ai->vc;
|
||||
uint32 pitch_offset;
|
||||
uint32 *buffer = NULL, *buffer_start = NULL;
|
||||
|
||||
|
||||
SHOW_FLOW0( 4, "" );
|
||||
|
||||
// set offset of frame buffer and pitch
|
||||
pitch_offset =
|
||||
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
|
||||
pitch_offset =
|
||||
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
|
||||
((vc->pitch >> 6) << 22);
|
||||
|
||||
|
||||
if ( ai->si->acc_dma ) {
|
||||
// make sure buffer is not used
|
||||
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
|
||||
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
|
||||
|
||||
|
||||
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
|
||||
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
|
||||
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
|
||||
// no sissors
|
||||
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
|
||||
// no sissors
|
||||
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
|
||||
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
|
||||
|
||||
// general fluff
|
||||
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
|
||||
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
|
||||
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
|
||||
| RADEON_GMC_CLR_CMP_CNTL_DIS
|
||||
|
||||
| RADEON_GMC_BRUSH_SOLID_COLOR
|
||||
|
||||
| RADEON_GMC_BRUSH_SOLID_COLOR
|
||||
| RADEON_GMC_SRC_DATATYPE_COLOR
|
||||
|
||||
|
||||
| RADEON_ROP3_P
|
||||
| RADEON_DP_SRC_SOURCE_MEMORY
|
||||
| RADEON_GMC_WR_MSK_DIS );
|
||||
|
||||
|
||||
// most of this init is probably not necessary
|
||||
// as we neither draw lines nor use brushes
|
||||
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
|
||||
@@ -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_BKGD_CLR, 0x00000000);
|
||||
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
|
||||
|
||||
|
||||
// this is required
|
||||
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_DST_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
|
||||
| RADEON_DEFAULT_SC_BOTTOM_MAX));
|
||||
// general fluff
|
||||
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL,
|
||||
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_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);
|
||||
@@ -487,7 +487,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
|
||||
OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff);
|
||||
|
||||
}
|
||||
|
||||
|
||||
ai->si->active_vc = vc->id;
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
|
||||
void Radeon_AllocateVirtualCardStateBuffer( accelerator_info *ai )
|
||||
{
|
||||
virtual_card *vc = ai->vc;
|
||||
|
||||
|
||||
vc->state_buffer_idx = Radeon_AllocIndirectBuffer( ai, false );
|
||||
// mark as being unused
|
||||
vc->state_buffer_size = -1;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
Copyright (c) 2002-2004, Thomas Kurschel
|
||||
|
||||
|
||||
|
||||
Part of Radeon accelerant
|
||||
|
||||
|
||||
Takes care of PLL
|
||||
*/
|
||||
|
||||
@@ -17,29 +17,29 @@
|
||||
#include "set_mode.h"
|
||||
|
||||
|
||||
static void Radeon_PLLWaitForReadUpdateComplete(
|
||||
static void Radeon_PLLWaitForReadUpdateComplete(
|
||||
accelerator_info *ai, int crtc_idx )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
// we should wait forever, but
|
||||
// 1. this is unsafe
|
||||
// 2. some r300 loop forever (reported by XFree86)
|
||||
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 )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void Radeon_PLLWriteUpdate(
|
||||
static void Radeon_PLLWriteUpdate(
|
||||
accelerator_info *ai, int 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,
|
||||
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
|
||||
// fixed_post_div - if != 0, fixed divider to be used
|
||||
// dividers - filled with proper dividers
|
||||
void Radeon_CalcPLLDividers(
|
||||
void Radeon_CalcPLLDividers(
|
||||
const pll_info *pll, uint32 freq, uint fixed_post_div, pll_dividers *dividers )
|
||||
{
|
||||
// the PLL gets the reference
|
||||
@@ -63,24 +63,24 @@ void Radeon_CalcPLLDividers(
|
||||
// pll_out = vco / 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
|
||||
|
||||
|
||||
// synonyms are:
|
||||
// ref_div = M
|
||||
// feedback_div = N
|
||||
// post_div = P
|
||||
|
||||
int
|
||||
|
||||
int
|
||||
min_post_div_idx, max_post_div_idx,
|
||||
post_div_idx, extra_post_div_idx,
|
||||
best_post_div_idx, best_extra_post_div_idx;
|
||||
|
||||
|
||||
uint32
|
||||
best_ref_div, best_feedback_div, best_freq;
|
||||
int32
|
||||
best_error, best_vco_dev;
|
||||
|
||||
|
||||
best_error = 999999999;
|
||||
|
||||
|
||||
// make compiler happy
|
||||
best_post_div_idx = 0;
|
||||
best_extra_post_div_idx = 0;
|
||||
@@ -91,42 +91,42 @@ void Radeon_CalcPLLDividers(
|
||||
|
||||
if( fixed_post_div == 0 ) {
|
||||
min_post_div_idx = 0;
|
||||
for(
|
||||
max_post_div_idx = 0;
|
||||
pll->post_divs[max_post_div_idx].divider != 0;
|
||||
for(
|
||||
max_post_div_idx = 0;
|
||||
pll->post_divs[max_post_div_idx].divider != 0;
|
||||
++max_post_div_idx )
|
||||
;
|
||||
--max_post_div_idx;
|
||||
} else {
|
||||
for(
|
||||
min_post_div_idx = 0;
|
||||
pll->post_divs[min_post_div_idx].divider != fixed_post_div;
|
||||
for(
|
||||
min_post_div_idx = 0;
|
||||
pll->post_divs[min_post_div_idx].divider != fixed_post_div;
|
||||
++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 );
|
||||
}
|
||||
|
||||
|
||||
// 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( post_div_idx = min_post_div_idx; post_div_idx <= max_post_div_idx; ++post_div_idx ) {
|
||||
uint32 ref_div;
|
||||
uint32 post_div =
|
||||
pll->post_divs[post_div_idx].divider
|
||||
uint32 post_div =
|
||||
pll->post_divs[post_div_idx].divider
|
||||
* pll->extra_post_divs[extra_post_div_idx].divider;
|
||||
|
||||
|
||||
// post devider determines VCO frequency, so determine and verify it;
|
||||
// freq is in Hz, everything else is in 10 kHz units
|
||||
// we use 10 kHz units as long as possible to avoid uint32 overflows
|
||||
uint32 vco = (freq / 10000) * post_div;
|
||||
|
||||
|
||||
//SHOW_FLOW( 2, "post_div=%d, vco=%d", post_div, vco );
|
||||
|
||||
|
||||
if( vco < pll->vco_min || vco > pll->vco_max )
|
||||
continue;
|
||||
|
||||
|
||||
//SHOW_FLOW0( 2, "jau" );
|
||||
|
||||
// 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 ) {
|
||||
uint32 feedback_div, cur_freq;
|
||||
int32 error, vco_dev;
|
||||
|
||||
|
||||
// this implies the frequency of the lock unit
|
||||
uint32 pll_in = pll->ref_freq / ref_div;
|
||||
|
||||
|
||||
if( pll_in < pll->pll_in_min || pll_in > pll->pll_in_max )
|
||||
continue;
|
||||
|
||||
// well, only one variable is left
|
||||
|
||||
// well, only one variable is left
|
||||
// timing is almost certainly valid, time to use Hz units
|
||||
feedback_div = RoundDiv64(
|
||||
(int64)freq * ref_div * post_div,
|
||||
feedback_div = RoundDiv64(
|
||||
(int64)freq * ref_div * post_div,
|
||||
pll->ref_freq * 10000 * pll->extra_feedback_div);
|
||||
|
||||
|
||||
if( feedback_div < pll->min_feedback_div ||
|
||||
feedback_div > pll->max_feedback_div )
|
||||
continue;
|
||||
|
||||
|
||||
// let's see what we've got
|
||||
cur_freq = RoundDiv64(
|
||||
(int64)pll->ref_freq * 10000 * feedback_div * pll->extra_feedback_div,
|
||||
cur_freq = RoundDiv64(
|
||||
(int64)pll->ref_freq * 10000 * feedback_div * pll->extra_feedback_div,
|
||||
ref_div * post_div );
|
||||
|
||||
// absolute error in terms of output clock
|
||||
error = abs( cur_freq - freq );
|
||||
|
||||
// absolute error in terms of output clock
|
||||
error = abs( (int32)cur_freq - (int32)freq );
|
||||
// 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 an optimal VCO frequency, choose new settings if
|
||||
// - error is reduced significantly (100 Hz or more), or
|
||||
// - 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) ||
|
||||
(pll->best_vco != 0 &&
|
||||
(pll->best_vco != 0 &&
|
||||
(error < best_error - 100 ||
|
||||
(abs( error - best_error ) < 100 && vco_dev < best_vco_dev ))))
|
||||
{
|
||||
@@ -193,57 +193,57 @@ void Radeon_CalcPLLDividers(
|
||||
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",
|
||||
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 );*/
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// limited frequency granularity, you don't really get a CRT timing
|
||||
// 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
|
||||
// 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
|
||||
// drift is under a given threshold;
|
||||
// drift is under a given threshold;
|
||||
// we follow two aims:
|
||||
// - primary, keep frame rate in sync
|
||||
// - secondary, only tweak as much as unavoidable
|
||||
void Radeon_MatchCRTPLL(
|
||||
const pll_info *pll,
|
||||
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,
|
||||
uint32 max_frame_rate_drift, uint32 fixed_post_div,
|
||||
void Radeon_MatchCRTPLL(
|
||||
const pll_info *pll,
|
||||
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,
|
||||
uint32 max_frame_rate_drift, uint32 fixed_post_div,
|
||||
pll_dividers *dividers,
|
||||
display_mode *tweaked_mode )
|
||||
{
|
||||
uint32 v_tweak;
|
||||
int32 v_tweak_dir;
|
||||
uint32 pix_per_tv_frame;
|
||||
|
||||
|
||||
SHOW_FLOW( 2, "fixed post divider: %d", fixed_post_div );
|
||||
|
||||
|
||||
// number of TV pixels per frame
|
||||
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
|
||||
// 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_dir = -1; v_tweak_dir <= 1; v_tweak_dir += 2 ) {
|
||||
uint32 h_tweak;
|
||||
int32 h_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_dir = -1; h_tweak_dir <= 1; h_tweak_dir += 2 ) {
|
||||
uint32 pix_per_crt_frame, frame_rate_drift;
|
||||
uint32 crt_freq;
|
||||
uint32 abs_crt_error;
|
||||
|
||||
|
||||
uint32 h_total = mode->timing.h_total + h_tweak * h_tweak_dir;
|
||||
|
||||
|
||||
// number of CRT pixels per frame
|
||||
pix_per_crt_frame = v_total * h_total;
|
||||
|
||||
|
||||
// frame rate must be:
|
||||
// frame_rate = freq / pix_per_tv_half_frame
|
||||
// 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
|
||||
// formula is reordered as usual to improve accuracy
|
||||
crt_freq = (uint64)freq * pix_per_crt_frame * 2 / pix_per_tv_frame;
|
||||
|
||||
|
||||
Radeon_CalcPLLDividers( pll, crt_freq, fixed_post_div, dividers );
|
||||
|
||||
|
||||
// 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 );
|
||||
|
||||
|
||||
// convert it to relative CRT clock error:
|
||||
// rel_error = abs_crt_error / crt_freq
|
||||
// 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
|
||||
// = abs_crt_error / crt_freq * pix_per_tv_frame
|
||||
frame_rate_drift = (uint64)abs_crt_error * pix_per_tv_frame / freq;
|
||||
|
||||
|
||||
// if drift is within threshold, we take this setting and stop
|
||||
// searching (later iteration will increasingly tweak screen size,
|
||||
// and we don't really want that)
|
||||
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 );
|
||||
|
||||
|
||||
tweaked_mode->timing.pixel_clock = crt_freq;
|
||||
tweaked_mode->timing.v_total = v_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
|
||||
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 )
|
||||
{
|
||||
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->extra_post_divs = extra_post_divs;
|
||||
pll->ref_freq = general_pll->ref_freq;
|
||||
|
||||
|
||||
// in sample code, these limits are set in a strange way;
|
||||
// as a first shot, I use the BIOS provided limits
|
||||
/*pll->vco_min = general_pll->min_pll_freq;
|
||||
pll->vco_max = general_pll->max_pll_freq;*/
|
||||
|
||||
|
||||
// in sample code, they use a variable post divider during calculation, but
|
||||
// use a fixed post divider for programming - the variable post divider is
|
||||
// multiplied to the feedback divider;
|
||||
// because of the fixed post divider (3), the VCO always runs far out of
|
||||
// multiplied to the feedback divider;
|
||||
// because of the fixed post divider (3), the VCO always runs far out of
|
||||
// its stable frequency range, so we have hack the limits
|
||||
pll->vco_min = 4000;
|
||||
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
|
||||
// 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 )
|
||||
{
|
||||
pll_info pll;
|
||||
|
||||
pll_info pll;
|
||||
|
||||
pll.post_divs = post_divs;
|
||||
pll.extra_post_divs = extra_post_divs;
|
||||
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
|
||||
// (old: freq is in 10kHz)
|
||||
void Radeon_CalcPLLRegisters(
|
||||
void Radeon_CalcPLLRegisters(
|
||||
const display_mode *mode, const pll_dividers *dividers, pll_regs *values )
|
||||
{
|
||||
values->dot_clock_freq = dividers->freq;
|
||||
values->feedback_div = dividers->feedback;
|
||||
values->post_div = dividers->post;
|
||||
values->pll_output_freq = dividers->freq * dividers->post;
|
||||
|
||||
|
||||
values->ppll_ref_div = dividers->ref;
|
||||
values->ppll_div_3 = (dividers->feedback | (dividers->post_code << 16));
|
||||
// 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
|
||||
void Radeon_ProgramPLL(
|
||||
void Radeon_ProgramPLL(
|
||||
accelerator_info *ai, int crtc_idx, pll_regs *values )
|
||||
{
|
||||
vuint8 *regs = ai->regs;
|
||||
radeon_type asic = ai->si->asic;
|
||||
|
||||
|
||||
SHOW_FLOW0( 2, "" );
|
||||
|
||||
|
||||
// use some other PLL for pixel clock source to not fiddling with PLL
|
||||
// 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_OUTPLLP( regs, asic,
|
||||
@@ -472,48 +472,48 @@ void Radeon_ProgramPLL(
|
||||
~(RADEON_PPLL_RESET
|
||||
| RADEON_PPLL_ATOMIC_UPDATE_EN
|
||||
| RADEON_PPLL_VGA_ATOMIC_UPDATE_EN) );
|
||||
|
||||
|
||||
// select divider 3 (well, only required for first PLL)
|
||||
OUTREGP( regs, RADEON_CLOCK_CNTL_INDEX,
|
||||
RADEON_PLL_DIV_SEL_DIV3,
|
||||
~RADEON_PLL_DIV_SEL_MASK );
|
||||
|
||||
|
||||
RADEONPllErrataAfterIndex(regs, asic);
|
||||
|
||||
if( ai->si->new_pll && crtc_idx == 0 ) {
|
||||
// starting with r300, the reference divider of the first PLL was
|
||||
// moved to another bit position; at the old location, you only
|
||||
// starting with r300, the reference divider of the first PLL was
|
||||
// moved to another bit position; at the old location, you only
|
||||
// find the "BIOS suggested divider"; no clue why they did that
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
RADEON_PPLL_REF_DIV,
|
||||
values->ppll_ref_div << RADEON_PPLL_REF_DIV_ACC_SHIFT,
|
||||
RADEON_PPLL_REF_DIV,
|
||||
values->ppll_ref_div << RADEON_PPLL_REF_DIV_ACC_SHIFT,
|
||||
~RADEON_PPLL_REF_DIV_ACC_MASK );
|
||||
} else {
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV,
|
||||
values->ppll_ref_div,
|
||||
crtc_idx == 0 ? RADEON_PPLL_REF_DIV : RADEON_P2PLL_REF_DIV,
|
||||
values->ppll_ref_div,
|
||||
~RADEON_PPLL_REF_DIV_MASK );
|
||||
}
|
||||
|
||||
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
|
||||
values->ppll_div_3,
|
||||
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
|
||||
values->ppll_div_3,
|
||||
~RADEON_PPLL_FB3_DIV_MASK );
|
||||
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
|
||||
values->ppll_div_3,
|
||||
crtc_idx == 0 ? RADEON_PPLL_DIV_3 : RADEON_P2PLL_DIV_0,
|
||||
values->ppll_div_3,
|
||||
~RADEON_PPLL_POST3_DIV_MASK );
|
||||
|
||||
Radeon_PLLWriteUpdate( ai, crtc_idx );
|
||||
Radeon_PLLWaitForReadUpdateComplete( ai, crtc_idx );
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
crtc_idx == 0 ? RADEON_PPLL_CNTL : RADEON_P2PLL_CNTL, 0,
|
||||
Radeon_OUTPLLP( regs, asic,
|
||||
crtc_idx == 0 ? RADEON_PPLL_CNTL : RADEON_P2PLL_CNTL, 0,
|
||||
~(RADEON_PPLL_RESET
|
||||
| RADEON_PPLL_SLEEP
|
||||
| RADEON_PPLL_ATOMIC_UPDATE_EN
|
||||
@@ -524,6 +524,6 @@ void Radeon_ProgramPLL(
|
||||
|
||||
// use PLL for pixel clock again
|
||||
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 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user