diff options
Diffstat (limited to 'drivers/video/aty/mach64_ct.c')
| -rw-r--r-- | drivers/video/aty/mach64_ct.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index 10232cc2dc76..f3b487b8710b 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c | |||
| @@ -398,8 +398,8 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info, | |||
| 398 | union aty_pll *pll) | 398 | union aty_pll *pll) |
| 399 | { | 399 | { |
| 400 | struct atyfb_par *par = (struct atyfb_par *) info->par; | 400 | struct atyfb_par *par = (struct atyfb_par *) info->par; |
| 401 | u8 mpost_div, xpost_div, sclk_post_div_real, sclk_fb_div, spll_cntl2; | 401 | u8 mpost_div, xpost_div, sclk_post_div_real; |
| 402 | u32 q, i, memcntl, trp; | 402 | u32 q, memcntl, trp; |
| 403 | u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off; | 403 | u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off; |
| 404 | #ifdef DEBUG | 404 | #ifdef DEBUG |
| 405 | int pllmclk, pllsclk; | 405 | int pllmclk, pllsclk; |
| @@ -575,14 +575,30 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info, | |||
| 575 | mpost_div += (q < 32*8); | 575 | mpost_div += (q < 32*8); |
| 576 | } | 576 | } |
| 577 | sclk_post_div_real = postdividers[mpost_div]; | 577 | sclk_post_div_real = postdividers[mpost_div]; |
| 578 | sclk_fb_div = q * sclk_post_div_real / 8; | 578 | pll->ct.sclk_fb_div = q * sclk_post_div_real / 8; |
| 579 | spll_cntl2 = mpost_div << 4; | 579 | pll->ct.spll_cntl2 = mpost_div << 4; |
| 580 | #ifdef DEBUG | 580 | #ifdef DEBUG |
| 581 | pllsclk = (1000000 * 2 * sclk_fb_div) / | 581 | pllsclk = (1000000 * 2 * pll->ct.sclk_fb_div) / |
| 582 | (par->ref_clk_per * pll->ct.pll_ref_div); | 582 | (par->ref_clk_per * pll->ct.pll_ref_div); |
| 583 | printk("atyfb(%s): use sclk, pllsclk=%d MHz, sclk=mclk=%d MHz\n", | 583 | printk("atyfb(%s): use sclk, pllsclk=%d MHz, sclk=mclk=%d MHz\n", |
| 584 | __FUNCTION__, pllsclk, pllsclk / sclk_post_div_real); | 584 | __FUNCTION__, pllsclk, pllsclk / sclk_post_div_real); |
| 585 | #endif | 585 | #endif |
| 586 | } | ||
| 587 | |||
| 588 | /* Disable the extra precision pixel clock controls since we do not use them. */ | ||
| 589 | pll->ct.ext_vpll_cntl = aty_ld_pll_ct(EXT_VPLL_CNTL, par); | ||
| 590 | pll->ct.ext_vpll_cntl &= ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC); | ||
| 591 | |||
| 592 | return 0; | ||
| 593 | } | ||
| 594 | |||
| 595 | static void aty_resume_pll_ct(const struct fb_info *info, | ||
| 596 | union aty_pll *pll) | ||
| 597 | { | ||
| 598 | struct atyfb_par *par = info->par; | ||
| 599 | |||
| 600 | if (par->mclk_per != par->xclk_per) { | ||
| 601 | int i; | ||
| 586 | /* | 602 | /* |
| 587 | * This disables the sclk, crashes the computer as reported: | 603 | * This disables the sclk, crashes the computer as reported: |
| 588 | * aty_st_pll_ct(SPLL_CNTL2, 3, info); | 604 | * aty_st_pll_ct(SPLL_CNTL2, 3, info); |
| @@ -590,8 +606,8 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info, | |||
| 590 | * So it seems the sclk must be enabled before it is used; | 606 | * So it seems the sclk must be enabled before it is used; |
| 591 | * so PLL_GEN_CNTL must be programmed *after* the sclk. | 607 | * so PLL_GEN_CNTL must be programmed *after* the sclk. |
| 592 | */ | 608 | */ |
| 593 | aty_st_pll_ct(SCLK_FB_DIV, sclk_fb_div, par); | 609 | aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par); |
| 594 | aty_st_pll_ct(SPLL_CNTL2, spll_cntl2, par); | 610 | aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par); |
| 595 | /* | 611 | /* |
| 596 | * The sclk has been started. However, I believe the first clock | 612 | * The sclk has been started. However, I believe the first clock |
| 597 | * ticks it generates are not very stable. Hope this primitive loop | 613 | * ticks it generates are not very stable. Hope this primitive loop |
| @@ -605,11 +621,7 @@ static int __devinit aty_init_pll_ct(const struct fb_info *info, | |||
| 605 | aty_st_pll_ct(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par); | 621 | aty_st_pll_ct(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par); |
| 606 | aty_st_pll_ct(MCLK_FB_DIV, pll->ct.mclk_fb_div, par); | 622 | aty_st_pll_ct(MCLK_FB_DIV, pll->ct.mclk_fb_div, par); |
| 607 | aty_st_pll_ct(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par); | 623 | aty_st_pll_ct(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par); |
| 608 | /* Disable the extra precision pixel clock controls since we do not use them. */ | 624 | aty_st_pll_ct(EXT_VPLL_CNTL, pll->ct.ext_vpll_cntl, par); |
| 609 | aty_st_pll_ct(EXT_VPLL_CNTL, aty_ld_pll_ct(EXT_VPLL_CNTL, par) & | ||
| 610 | ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC), par); | ||
| 611 | |||
| 612 | return 0; | ||
| 613 | } | 625 | } |
| 614 | 626 | ||
| 615 | static int dummy(void) | 627 | static int dummy(void) |
| @@ -626,5 +638,6 @@ const struct aty_pll_ops aty_pll_ct = { | |||
| 626 | .pll_to_var = aty_pll_to_var_ct, | 638 | .pll_to_var = aty_pll_to_var_ct, |
| 627 | .set_pll = aty_set_pll_ct, | 639 | .set_pll = aty_set_pll_ct, |
| 628 | .get_pll = aty_get_pll_ct, | 640 | .get_pll = aty_get_pll_ct, |
| 629 | .init_pll = aty_init_pll_ct | 641 | .init_pll = aty_init_pll_ct, |
| 642 | .resume_pll = aty_resume_pll_ct, | ||
| 630 | }; | 643 | }; |
