[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: m3mirror and distortion (Problem solved -- patch attached)



On Mon, 14 Feb 2005 17:09:39 +0000
James Tappin <sjt@star.sr.bham.ac.uk> 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__    |
| sjt@star.sr.bham.ac.uk | 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

Reply to: