Package: kernel-image-2.6.8-powerpc Version: 2.6.8-9 Severity: normal Tags: patch
On an iBook G3, the output to an external VGA monitor has high spatial frequency waves drifting across it. The patch accompanying this report is Owen Stampflee's 2.4 patch ported to 2.6 and fixes the problem. It probably needs at least a once over from someone more familiar with the workings of the kernel before it's released into the wild. N.B. The kernel reported in the system information below is my patched copy built from the Debian kernel sources package. -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (500, 'testing') Architecture: powerpc (ppc) Kernel: Linux 2.6.8vga-fix Locale: LANG=en_GB, LC_CTYPE=en_GB (charmap=ISO-8859-1) Versions of packages kernel-image-2.6.8-powerpc depends on: ii initrd-tools 0.1.77 tools to create initrd image for p ii module-init-tools 3.2-pre1-2 tools for managing Linux kernel mo -- no debconf information
diff -ru kernel-source-2.6.8/drivers/video/aty/aty128fb.c kernel-source-2.6.8-patched/drivers/video/aty/aty128fb.c --- kernel-source-2.6.8/drivers/video/aty/aty128fb.c 2004-08-14 06:36:57.000000000 +0100 +++ kernel-source-2.6.8-patched/drivers/video/aty/aty128fb.c 2005-02-15 16:19:11.000000000 +0000 @@ -395,6 +395,14 @@ struct aty128_crtc crtc; struct aty128_pll pll; struct aty128_ddafifo fifo_reg; + +#ifdef CONFIG_PMAC_PBOOK + struct aty128_crtc crtc2; + struct aty128_pll pll2; + struct aty128_ddafifo fifo_reg2; +#endif + + u32 accel_flags; struct aty128_constants constants; /* PLL and others */ void *regbase; /* remapped mmio */ @@ -1036,6 +1044,26 @@ aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000)); } +#ifdef CONFIG_PMAC_PBOOK +static void +aty128_set_crtc2(const struct aty128_crtc *crtc, + const struct aty128fb_par *par) +{ + + aty_st_le32(CRTC2_GEN_CNTL, crtc->gen_cntl); + + /* FIXME - Hardcoded */ + aty_st_le32(CRTC2_H_TOTAL_DISP, crtc->h_total & ~0xf | 0xa); + aty_st_le32(CRTC2_H_SYNC_STRT_WID, crtc->h_sync_strt_wid & ~0xff | 0x10 ); + + aty_st_le32(CRTC2_V_TOTAL_DISP, crtc->v_total); + aty_st_le32(CRTC2_V_SYNC_STRT_WID, crtc->v_sync_strt_wid); + aty_st_le32(CRTC2_PITCH, crtc->pitch); + aty_st_le32(CRTC2_OFFSET, crtc->offset); + aty_st_le32(CRTC2_OFFSET_CNTL, crtc->offset_cntl); + +} +#endif static int aty128_var_to_crtc(const struct fb_var_screeninfo *var, struct aty128_crtc *crtc, @@ -1289,7 +1317,9 @@ { if (on) { aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) | CRT_CRTC_ON); - aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | DAC_PALETTE2_SNOOP_EN)); + aty_st_le32(DAC_CNTL, (aty_ld_le32(DAC_CNTL) | + DAC_PALETTE2_SNOOP_EN | DAC_CLK_SEL)); + } else aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON); } @@ -1359,7 +1389,49 @@ aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET); } +#ifdef CONFIG_PMAC_PBOOK +static void +aty128_set_pll2(struct aty128_pll *pll, const struct aty128fb_par *par) +{ + u32 div; + + unsigned char post_conv[] = /* register values for post dividers */ + { 2, 0, 1, 4, 2, 2, 6, 2, 3, 2, 2, 2, 7 }; + + /* reset PLL */ + aty_st_pll(P2PLL_CNTL, + aty_ld_pll(P2PLL_CNTL) | PPLL_RESET | PPLL_ATOMIC_UPDATE_EN); + + /* write the reference divider */ + aty_pll_wait_readupdate(par); + aty_st_pll(P2PLL_REF_DIV, par->constants.ref_divider & 0x3ff); + aty_pll_writeupdate(par); + + div = aty_ld_pll(P2PLL_DIV_0); + div &= ~XPLL_FB_DIV_MASK; + div |= pll->feedback_divider; + div |= post_conv[pll->post_divider] << 16; + div |= 0x00040000; /* magic value */ + + /* write feedback and post dividers */ + aty_pll_wait_readupdate(par); + aty_st_pll(P2PLL_DIV_0, div); + aty_pll_writeupdate(par); + + aty_pll_wait_readupdate(par); + aty_st_pll(HTOTAL_CNTL, 0); /* no horiz crtc adjustment */ + aty_pll_writeupdate(par); + + + /* clear the reset, just in case */ + aty_st_pll(P2PLL_CNTL, aty_ld_pll(P2PLL_CNTL) & ~PPLL_RESET); + +} +#endif + + + static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll, const struct aty128fb_par *par) { @@ -1418,6 +1490,17 @@ } +#ifdef CONFIG_PMAC_PBOOK +static void +aty128_set_fifo2(const struct aty128_ddafifo *dsp, + const struct aty128fb_par *par) +{ + /* FIXME - Hardcoded */ + aty_st_le32(DDA2_CONFIG, 0x010502aa); + aty_st_le32(DDA2_ON_OFF, 0x11805a74); +} +#endif + static int aty128_ddafifo(struct aty128_ddafifo *dsp, const struct aty128_pll *pll, u32 depth, @@ -1509,6 +1592,14 @@ aty128_set_crtc(&par->crtc, par); aty128_set_pll(&par->pll, par); aty128_set_fifo(&par->fifo_reg, par); +#ifdef CONFIG_PMAC_PBOOK + if(par->chip_gen == rage_M3) { + aty128_set_crtc2(&par->crtc2, par); + aty128_set_pll2(&par->pll2, par); + aty128_set_fifo2(&par->fifo_reg2, par); + } +#endif + config = aty_ld_le32(CONFIG_CNTL) & ~3; @@ -1553,9 +1644,9 @@ static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par) { int err; - struct aty128_crtc crtc; - struct aty128_pll pll; - struct aty128_ddafifo fifo_reg; + struct aty128_crtc crtc, crtc2; + struct aty128_pll pll, pll2; + struct aty128_ddafifo fifo_reg, fifo_reg2; if ((err = aty128_var_to_crtc(var, &crtc, par))) return err; @@ -1565,12 +1656,30 @@ if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par))) return err; +#ifdef CONFIG_PMAC_PBOOK + + if ((err = aty128_var_to_crtc(var, &crtc2, par))) + return err; + + if ((err = aty128_var_to_pll(var->pixclock, &pll2, par))) + return err; + + if ((err = aty128_ddafifo(&fifo_reg2, &pll2, crtc2.depth, par))) + return err; +#endif + par->crtc = crtc; par->pll = pll; par->fifo_reg = fifo_reg; par->accel_flags = var->accel_flags; +#ifdef CONFIG_PMAC_PBOOK + par->crtc2 = crtc2; + par->pll2 = pll2; + par->fifo_reg2 = fifo_reg2; + +#endif return 0; } @@ -1650,7 +1759,7 @@ struct aty128fb_par *par) { if (par->chip_gen == rage_M3) { -#if 0 +#if CONFIG_PMAC_PBOOK /* Note: For now, on M3, we set palette on both heads, which may * be useless. Can someone with a M3 check this ? * diff -ru kernel-source-2.6.8/include/video/aty128.h kernel-source-2.6.8-patched/include/video/aty128.h --- kernel-source-2.6.8/include/video/aty128.h 2004-08-14 06:36:56.000000000 +0100 +++ kernel-source-2.6.8-patched/include/video/aty128.h 2005-02-15 14:54:05.000000000 +0000 @@ -258,7 +258,7 @@ #define PLL_TEST_CNTL 0x0013 #define P2PLL_CNTL 0x002a #define P2PLL_REF_DIV 0x002b -#define P2PLL_DIV_0 0x002b +#define P2PLL_DIV_0 0x002c #define POWER_MANAGEMENT 0x002f #define PPLL_RESET 0x01