From fc179324b07c303f74cc88fb65d7efebdf4e249a Mon Sep 17 00:00:00 2001 From: X512 Date: Mon, 23 Mar 2020 09:38:57 +0900 Subject: [PATCH] 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 --- src/add-ons/accelerants/radeon/Acceleration.c | 194 ++++++++-------- src/add-ons/accelerants/radeon/pll.c | 210 +++++++++--------- 2 files changed, 202 insertions(+), 202 deletions(-) diff --git a/src/add-ons/accelerants/radeon/Acceleration.c b/src/add-ons/accelerants/radeon/Acceleration.c index 8c118a1999..7c8b642345 100644 --- a/src/add-ons/accelerants/radeon/Acceleration.c +++ b/src/add-ons/accelerants/radeon/Acceleration.c @@ -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; diff --git a/src/add-ons/accelerants/radeon/pll.c b/src/add-ons/accelerants/radeon/pll.c index 1dc57aeaa5..80543d87cc 100644 --- a/src/add-ons/accelerants/radeon/pll.c +++ b/src/add-ons/accelerants/radeon/pll.c @@ -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 ); }