[Fwd: Kernel Patch for PPC Laptops (Corrects bad video mirroring)]

Daniel T. Chen crimsun at fungus.sh.nu
Tue Jul 18 00:52:41 BST 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



- -------- Original Message --------
Subject: Kernel Patch for PPC Laptops (Corrects bad video mirroring)
Date: Mon, 17 Jul 2006 13:57:15 +0100
From: James Tappin <sjt at star.sr.bham.ac.uk>
Reply-To: Ubuntu Help and User Discussions <ubuntu-users at lists.ubuntu.com>
To: ubuntu-users at lists.ubuntu.com

Hi Everyone,
	The attached patch is needed on iBooks (and probably PowerBooks) with
ATI graphics adaptors to prevent output to an external monitor or
projector from being corrupted. It's been adapted from a version I found
for 2.4 series kernels.

The patch should apply cleanly to the current Ubuntu kernel sources.

- --
+------------------------+-------------------------------+---------+
| James Tappin           | School of Physics & Astronomy |  O__    |
| sjt at star.sr.bham.ac.uk | University of Birmingham      | --  \/` |
| Ph: 0121-414-6462. Fax: 0121-414-3722                  |         |
+--------------------------------------------------------+---------+


- --
Daniel T. Chen            crimsun at ubuntu.com
GPG key:   www.sh.nu/~crimsun/pubkey.gpg.asc
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEvCLJe9GwFciKvaMRApV4AJoDMdEpaIfqHH8uFqMoiUWkQzkCKACeN55H
d9y+0bVYvlYemyBsfLXNE1s=
=yG9i
-----END PGP SIGNATURE-----
-------------- next part --------------
diff -ur linux-source-2.6.15-orig/drivers/video/aty/aty128fb.c linux-source-2.6.15/drivers/video/aty/aty128fb.c
--- linux-source-2.6.15-orig/drivers/video/aty/aty128fb.c	2006-03-02 21:18:38.000000000 +0000
+++ linux-source-2.6.15/drivers/video/aty/aty128fb.c	2006-07-10 11:28:23.000000000 +0100
@@ -395,6 +395,14 @@
 	struct aty128_crtc crtc;
 	struct aty128_pll pll;
 	struct aty128_ddafifo fifo_reg;
+
+#ifdef CONFIG_PPC_PMAC
+    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 __iomem *regbase;              /* remapped mmio       */
@@ -998,6 +1006,26 @@
 	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~(0x00030000));
 }
 
+#ifdef CONFIG_PPC_PMAC
+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,
@@ -1249,10 +1277,14 @@
 static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
 {
 	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(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 | DAC_CLK_SEL));
+
 	} else
-		aty_st_le32(CRTC_EXT_CNTL, aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
+		aty_st_le32(CRTC_EXT_CNTL,
+			    aty_ld_le32(CRTC_EXT_CNTL) & ~CRT_CRTC_ON);
 }
 
 static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
@@ -1319,7 +1351,49 @@
 	aty_st_pll(PPLL_CNTL, aty_ld_pll(PPLL_CNTL) & ~PPLL_RESET);
 }
 
+#ifdef CONFIG_PPC_PMAC
+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)
 {
@@ -1378,6 +1452,20 @@
 }
 
 
+#ifdef CONFIG_PPC_PMAC
+static void
+aty128_set_fifo2(const struct aty128_ddafifo *dsp,
+			const struct aty128fb_par *par)
+{
+    /* FIXME - Hardcoded */
+  /*    aty_st_le32(DDA2_CONFIG, dsp->dda_config);
+	aty_st_le32(DDA2_ON_OFF, dsp->dda_on_off);*/
+  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,
@@ -1469,6 +1557,14 @@
 	aty128_set_crtc(&par->crtc, par);
 	aty128_set_pll(&par->pll, par);
 	aty128_set_fifo(&par->fifo_reg, par);
+#ifdef CONFIG_PPC_PMAC
+    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;
 
@@ -1511,9 +1607,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;
@@ -1523,12 +1619,30 @@
 
 	if ((err = aty128_ddafifo(&fifo_reg, &pll, crtc.depth, par)))
 		return err;
+#ifdef CONFIG_PPC_PMAC
+
+    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_PPC_PMAC
+
+        par->crtc2 = crtc2;
+        par->pll2 = pll2;
+        par->fifo_reg2 = fifo_reg2;
 
+#endif
 	return 0;
 }
 
@@ -1608,7 +1722,7 @@
 			  struct aty128fb_par *par)
 {
 	if (par->chip_gen == rage_M3) {
-#if 0
+#if CONFIG_PPC_PMAC
 		/* Note: For now, on M3, we set palette on both heads, which may
 		 * be useless. Can someone with a M3 check this ?
 		 * 
@@ -1616,11 +1730,13 @@
 		 * do mirroring
 		 */
 
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
+		aty_st_le32(DAC_CNTL,
+			    aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
 		aty_st_8(PALETTE_INDEX, regno);
 		aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue);
 #endif
-		aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
+		aty_st_le32(DAC_CNTL, 
+			    aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
 	}
 
 	aty_st_8(PALETTE_INDEX, regno);
diff -ur linux-source-2.6.15-orig/include/video/aty128.h linux-source-2.6.15/include/video/aty128.h
--- linux-source-2.6.15-orig/include/video/aty128.h	2006-03-02 21:18:42.000000000 +0000
+++ linux-source-2.6.15/include/video/aty128.h	2006-07-10 11:28:23.000000000 +0100
@@ -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

-------------- next part --------------
-- 
ubuntu-users mailing list
ubuntu-users at lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-users



More information about the kernel-team mailing list