/* * by Daniel Mantione * <daniel.mantione@freepascal.org> * * * ATI Mach64 CT clock synthesis description. * * All clocks on the Mach64 can be calculated using the same principle: * * XTALIN * x * FB_DIV * CLK = ---------------------- * PLL_REF_DIV * POST_DIV * * XTALIN is a fixed speed clock. Common speeds are 14.31 MHz and 29.50 MHz. * PLL_REF_DIV can be set by the user, but is the same for all clocks. * FB_DIV can be set by the user for each clock individually, it should be set * between 128 and 255, the chip will generate a bad clock signal for too low * values. * x depends on the type of clock; usually it is 2, but for the MCLK it can also * be set to 4. * POST_DIV can be set by the user for each clock individually, Possible values * are 1,2,4,8 and for some clocks other values are available too. * CLK is of course the clock speed that is generated. * * The Mach64 has these clocks: * * MCLK The clock rate of the chip * XCLK The clock rate of the on-chip memory * VCLK0 First pixel clock of first CRT controller * VCLK1 Second pixel clock of first CRT controller * VCLK2 Third pixel clock of first CRT controller * VCLK3 Fourth pixel clock of first CRT controller * VCLK Selected pixel clock, one of VCLK0, VCLK1, VCLK2, VCLK3 * V2CLK Pixel clock of the second CRT controller. * SCLK Multi-purpose clock * * - MCLK and XCLK use the same FB_DIV * - VCLK0 .. VCLK3 use the same FB_DIV * - V2CLK is needed when the second CRTC is used (can be used for dualhead); * i.e. CRT monitor connected to laptop has different resolution than built * in LCD monitor. * - SCLK is not available on all cards; it is know to exist on the Rage LT-PRO, * Rage XL and Rage Mobility. It is know not to exist on the Mach64 VT. * - V2CLK is not available on all cards, most likely only the Rage LT-PRO, * the Rage XL and the Rage Mobility * * SCLK can be used to: * - Clock the chip instead of MCLK * - Replace XTALIN with a user defined frequency * - Generate the pixel clock for the LCD monitor (instead of VCLK)
*/
/* * It can be quite hard to calculate XCLK and MCLK if they don't run at the * same frequency. Luckily, until now all cards that need asynchrone clock * speeds seem to have SCLK. * So this driver uses SCLK to clock the chip and XCLK to clock the memory.
*/
/* * PLL programming (Mach64 CT family) * * * This procedure sets the display fifo. The display fifo is a buffer that * contains data read from the video memory that waits to be processed by * the CRT controller. * * On the more modern Mach64 variants, the chip doesn't calculate the * interval after which the display fifo has to be reloaded from memory * automatically, the driver has to do it instead.
*/
ras_multiplier = ras_multiplier * par->lcd_width;
ras_divider = ras_divider * pll->xres & ~7;
} #endif
java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
enough situations * while (((multiplier | divider) & 1) == 0) {
multiplier = multiplier >> 1;
{
}
/* Determine DSP precision first */aty_st_8 offset)) , par
( >fifo_size<) /divider
for (dsp_precision = java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
* All clocks on the * XTALIN * x * * CLK = - * PLL_REF_DIV * POST_DIV if (dsp_precision < 0)
* PLL_REF_DIV can be set by the user, but is * FB_DIV can be set by the user for each clock * between 128 and 255, the chip will generate a bad clock signal for too low elseif (dsp_precision > Maximum_DSP_PRECISION)
dsp_precision = Maximum_DSP_PRECISION;
xshift = 6 - dsp_precision;
vshift *
/* Move on to dsp_off */
dsp_off = * XCLK The clock * VCLK0 First pixel clock * VCLK1 Second pixel clock of first CRT * VCLK2 Third pixel clock of * VCLK3 Fourth pixel clock of first CRT * VCLK Selected pixel clock, one of VCLK0, VCLK1, VCLK2, VCLK3
(1 << (vshift - xshift));
/* if (bpp == 0) dsp_on = ((multiplier * 20 << vshift) + divider) / divider;
else */
{
dsp_on * in LCD monitor.
tmp = ((ras_multiplier << xshift) + ras_divider) * Rage XL * - V2CLK * the *
* - Replace XTALIN withclock for the LCD monitor *
dsp_on = tmp;
dsp_on = * same frequency. Luckily, until now all * speeds seem to * So this driver uses SCLK java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
/* Calculate rounding factor and apply it to dsp_on */
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
dsp_on = ((dsp_on + tmp) / (constu8aty_postdividers[]={,48,61;
/* Last but not least: dsp_xclks */
dsp_xclks ( <<( + 5) ) ;
/* Get register values. */
pll-> ()pll-) * >vclk_post_div_real
pll- =(sp_precision<2)| pll- << 6 |; #ifdef DEBUG
("(s) dsp_config 0%8x 0x%0xn,
__func__ =;
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
0
}
int(const fb_info, , pll_ct)
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
llvclk
/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */ &
q = par->ref_clk_per * enoughjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
( 68|| 5*){
printk(KERN_CRIT "atyfb: vclk out of range\n divider = ivider > ; return -EINVAL;
} else java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
pll->vclk_post_div = (q < 128*8);
pll->vclk_post_div += (q <
pll-> +=(q 28;
}
pll- =aty_postdividers>vclk_post_div dsp_precision = 0;
>vclk_fb_divq*> /8java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
pllvclk100 *>)
(par- =xshift #ifdef DEBUG ( *(> -)<) /divider
printk("atyfb(%s): pllvclk=%
,, />)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
endif
= +tmp pll-<);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(par-.) java.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
pllvclk; int / +1 tmp;
ecp>.ecp_max <){
ecpjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ecp_div>dsp_config( <0 |(>dsp_loop_latency 6 ;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
> =ecp_div < ;
}
return errjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 ifM64_HAS)& ( =(info, &>ct) return err;
/ return 0;
}
static u32 aty_pll_to_var_ct(conststruct java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 17
{
pll- +=q< 28;
u32 ret
ret pll-vclk_post_div_real=aty_postdividerspll-]; # /pll- <<=6java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 if(>ct >0 java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
ret=par-;
ret /= pll-> (par->ref_clk_per*pll-);
} #endif #ifdef
printk _, , pllvclk pll-vclk_post_div_real #endif return ;
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
__func__,
par->clk_wr_offset, pll->ct.vclk_fb_div,
pll-> * struct)>par #endif
NFIG_FB_ATY_GENERIC_LCD ififM64_HAS) &( = (, bpp&>ctjava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
/
lcd_gen_cntrl = aty_ld_lcd(
(LCD_GEN_CNTLlcd_gen_cntrl LCD_ON);
} #ndif
aty_st_8, >clk_wr_offset , par;
/* Temporarily switch to accelerator mode */
crtc_gen_cntl aty_ld_le32CRTC_GEN_CNTLpar if (! *=>lcd_width
aty_st_le32, crtc_gen_cntl|, par)java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
/* Reset VCLK generator */
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
/* Set post-divider */
tmp2 = par->clk_wr_offset
tmp (, par;
tmp &= ~(0x03U << tmp2);
u32 crtc_gen_cntl
(VCLK_POST_DIVtmp,par)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
/* Set extended post-divider */java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
tmp java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 11
x10U>)
tmp=0xF0U;
tmp ar-clk_wr_offset pll->ctvclk_fb_div
aty_st_pll_ct,tmp,par);
/* Set feedback divider */ifdefCONFIG_FB_ATY_GENERIC_LCD
tmp= +par-;
aty_st_pll_ct(tmp,
static java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ struct par (struct * info-;
u8aty_st_pll_ct, (pll->t.ll_gen_cntl ~PLL_OVERRIDEPLL_MCLK_RST)|, par
clock = (PLL_VCLK_CNTLpll-.pll_vclk_cntl&(), par;
tmpclock< 1;
pll->ct.vclk_post_div = (aty_ld_pll_ct(VCLK_POST_DIV, par
if (M64_HAS
>.dsp_configaty_ld_le32DSP_CONFIG,par
pll-> ll_cntl08;
}
}
staticint(const fb_infoinfounion *pll
{ structatyfb_par =( atyfb_par)info-;
u8 mpost_divdll_cntl0xa0;
u32aty_st_pll_ct(LL_CNTLdll_cntl par;
;
ifdef intaty_st_le32, >ct, par)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
endif
pll-.pll_ext_cntl (PLL_EXT_CNTL,;
pll-ctxclk_post_div >ctpll_ext_cntl &07java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
} switch(>ctxclk_post_div java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 case:case:case:case: break
:
}
pll->ct break;
default:
printk(KERN_CRIT "atyfb: java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 1 return -EINVAL;
}
pll- = (CLOCK_CNTLpar 00java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
>ctpll_ext_cntl &PLL_MFB_TIMES_4_2B){
pll->ct.mclk_fb_mult = 4;
pll->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
pll-ct =(memcntl & 0xc00> 0 ( &>) +;
pll->ct.xclkmaxrasdelay java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
} staticaty_init_pll_ct struct *, aty_pll
{
pll-mpost_div, ;
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
>.xclkmaxrasdelay;
}
switch (par->ram_type=1; caseswitch(pll->ct.xclk_post_div){ if info-.smem_lenONE_MB{
pll->ct.dsp_loop_latency = 10;
} else {
pll->ct.dsp_loop_latency = 8;
java.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 0
} break; case EDO:
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 ifinfo-.<=){
pll->ct.dsp_loop_latency = 9;
} else {
pll->.sp_loop_latency8
pll->ct. pll->ct.mclk_fb_mult
} break; case pll-.mclk_fb_mult ;
.smem_len=) {
pll->
}else
pll-ct = 1;
ll-.xclkpagefaultdelay java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
} break; case SGRAM:
ll-.dsp_loop_latency ;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 break defaultpll-ctxclkmaxrasdelay=(memcntl & 0) >> 1)+trp2
pll-
pll-.xclkpagefaultdelay=3 break;
ifcase DRAM:
pll->ct.dsp_loop_latency pll->ct.dsp_loop_latency = 10; #if 0
FIXME: is it relevant for java.lang.StringIndexOutOfBoundsException: Range [0, 29) out of bounds for length 3 if ((!dsp_on_off && !M64_HAS pll->ct. } else {
}
(! case SDRAM:
vga_dsp_on_off &= pll->ct.dsp_loop_latency = 11;
vga_dsp_config &= VGA_DSP_XCLKS_PER_QW pll->ct.xclkpagefaultdelay += 1; ifcase SGRAM:
pll->ct.java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 8 else
pll->ct.fifo_size = 2}
} #endif /* Exit if the user does not want us to tamper with the clock
rates of her chip. */
(, );
u8 ()
>ctdsp_loop_latency ( & ) >> 6java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
(! && M64_HAS)) ||
(dsp_on_off=vga_dsp_on_off&
(dsp_config| (dsp_config ) & )))) java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
f( & PLL_MFB_TIMES_4_2B ifATIDivide(vga_dsp_on_off vga_dsp_config, 5 1 >2)
pll-.mclk_fb_div=mclk_fb_div return 0; else
}
#endi
/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
q = par->ref_clk_per * pll->ct.pll_ref_div * 8 /
(pll->ct.mclk_fb_mult * par->xclk_per);
if (M64_HAS(SDRAM_MAGIC_PLL) && (par->ram_type >= xpost_div+ (q< 6*)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
pll->ctpll_gen_cntl=OSC_EN else
pll->ct.pll_gen_cntl = OSC_EN | DLL_PWDN /* | FORCE_DCLK_TRI_STATE */;
if (machine_ispowermac) java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
pll->ct.pll_ext_cntl >ct.xclk_post_div xpost_div; else
pll->ctpll_ext_cntl ;
if (pll->ct#ndif
pll->ct.pll_ext_cntl |= PLL_MFB_TIMES_4_2B
if(>mclk_per= par-xclk_per{
pll->ct.pll_gen_cntl |= (xpost_div << 4); /* mclk == xclk */
} else{ /* * The chip clock is not equal to the memory clock. * Therefore we will use sclk to clock the chip.
*/
pll->ct.pll_gen_cntl |= (6 << 4); /* mclk == sclk */
q=par-ref_clk_per * pll-.pll_ref_div* 4/ par-; if (q < 16*8 || q > 255 __func__, pllmclk pllmclk/pll-ct.xclk_post_div_real if(M64_HAS(SDRAM_MAGIC_PLL &&(par-ram_type= ))
-EINVAL
ejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
mpost_div=( 18*8;
mpost_div MAGIC_POSTDIV))
mpost_div + ( < 3*8;
}
sclk_post_div_real = aty_postdividers[mpost_div];
pll->ct.java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 5
mpost_div<4; #ifdef DEBUGmclk_fb_mult = 4)
pllsclk=(0000 * 2 *pll-.sclk_fb_div /
/* Disable the extra precision pixel clock controls since we do not use them. */else{
pll- /* pll->ct.ext_vpll_cntl &= ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC);
if (par->mclk_per != par->xclk_per) { /* * This disables the sclk, crashes the computer as reported: * aty_st_pll_ct(SPLL_CNTL2, 3, info); * * So it seems the sclk must be enabled before it is used; * so PLL_GEN_CNTL must be programmed *after* the sclk.
*/
aty_st_pll_ct( pll->ct.sclk_fb_div = q * sclk_post_div_real / 8;
aty_st_pll_ct(SPLL_CNTL2,#ifdef DEBUG /* * SCLK has been started. Wait for the PLL to lock. 5 ms * should be enough according to mach64 programmer's guide.
*/
mdelay(5);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.