On Mon, 14 Feb 2005 17:09:39 +0000 James Tappin <[EMAIL PROTECTED]> wrote:
JT> I've been trying to get the external monitor output of my G3 iBook JT> (ca. 2002) working. JT> JT> Does anyone know which (if any) of the various kernel patches that JT> are floating around the place are appropriate to my system and if so JT> whether the symptoms I've described resemble those they are supposed JT> to fix? And if not whether there is anything that does fix the JT> problem -- or what settings I might try tweaking? OK I think I've done it. Basically I took Owen Stampflee's 2.4.21 patch (http://stampflee.com/kernel/index.shtml) and hand-applied it to the 2.6.8 sources (some variable names and structures have changed so it can't be applied directly). The attached file contains the resultant patch. This is NOT an original patch nor do I really understand what it does, it is merely a translation of the 2.4 patch to 2.6, and it appears to work. Since it provides useful functionality absent in the current kernels it is probably desirable that some such patch be added to the Debian patchset if not to the mainstream kernel -- provided someone who knows a lot more about how the code works than I do can check it over. James -- +------------------------+-------------------------------+---------+ | James Tappin | School of Physics & Astronomy | O__ | | [EMAIL PROTECTED] | University of Birmingham | -- \/` | | Ph: 0121-414-6462. Fax: 0121-414-3722 | | +--------------------------------------------------------+---------+
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