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

Re: video mirroring on G3 (mach64) powerbooks



Geert Uytterhoeven <geert@linux-m68k.org> writes:

> X uses the secondary MMIO and disables the primary MMIO. So you end
> up changing the underlying video memory instead of the MMIO
> registers.

Hah, that explains a lot.  I suspect that when I screw with the video
memory it happens to be where the cursor image is stored, since it
adds a small dot to the right of the cursor.  This explains a lot. :)

> Solution: make atyfb use the secondary MMIO and disable the primary
> MMIO too.  As a side effect, we gain 4 kB of video memory on systems
> with 8 MB.

hmm, I'll take a look to see what that involves.

> P.S. Doesn't this belong more on linux-fbdev-devel and linuxppc-dev
> than on a Debian-specific list?

Absolutely...

I'll post new threads to linuxppc-dev...perhaps I should subscribe to
the fbdev list as well?

oh, and I just noticed that my diffs were accidentally reversed.
sorry about that.  (new versions attached)

ttyl,

-- 
Josh Huber                                   | huber@debian.org |
--- atyfb_base.c.orig	Mon Sep 24 11:46:48 2001
+++ atyfb_base.c	Mon Sep 24 15:03:05 2001
@@ -267,6 +267,11 @@
 #endif
 #endif
 
+#ifdef CONFIG_PMAC_PBOOK
+static int default_crt_on __initdata = 0;
+static int default_lcd_on __initdata = 1;
+#endif
+
 #ifdef CONFIG_ATARI
 static unsigned int mach64_count __initdata = 0;
 static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
@@ -723,6 +728,32 @@
     return 0;
 }
 
+/* bit 0 of LCD_GEN_CTRL is crt on/off */
+static void
+aty_set_crt_enable(struct fb_info_aty *info, int on)
+{
+    if (on) {
+	    aty_st_lcd(LCD_GEN_CTRL,
+		       aty_ld_lcd(LCD_GEN_CTRL, info) | 0x1, info);
+    } else {
+	    aty_st_lcd(LCD_GEN_CTRL,
+		       aty_ld_lcd(LCD_GEN_CTRL, info) & ~0x1, info);
+    }
+}
+
+/* bit 1 of LCD_GEN_CTRL is lcd on/off */
+static void
+aty_set_lcd_enable(struct fb_info_aty *info, int on)
+{
+    if (on) {
+	    aty_st_lcd(LCD_GEN_CTRL,
+		       aty_ld_lcd(LCD_GEN_CTRL, info) | 0x2, info);
+    } else {
+	    aty_st_lcd(LCD_GEN_CTRL,
+		       aty_ld_lcd(LCD_GEN_CTRL, info) & ~0x2, info);
+    }
+}
+
 /* ------------------------------------------------------------------------- */
 
 static void atyfb_set_par(const struct atyfb_par *par,
@@ -802,6 +833,13 @@
     if (par->accel_flags & FB_ACCELF_TEXT)
 	aty_init_engine(par, info);
 
+#ifdef CONFIG_PMAC_PBOOK
+    if (M64_HAS(G3_PB_1_1)) {
+	aty_set_crt_enable(info, info->crt_on);
+	aty_set_lcd_enable(info, info->lcd_on);
+    }
+#endif
+
 #ifdef CONFIG_FB_COMPAT_XPMAC
     if (!console_fb_info || console_fb_info == &info->fb_info) {
 	struct fb_var_screeninfo var;
@@ -1251,10 +1289,14 @@
 #define ATYIO_FEATW		0x41545903	/* ATY\03 */
 #endif
 
+#define FBIO_ATY_GET_MIRROR	_IOR('#', 1, sizeof(__u32*))
+#define FBIO_ATY_SET_MIRROR	_IOW('#', 2, sizeof(__u32*))
+
 static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 		       u_long arg, int con, struct fb_info *info2)
 {
-#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT))
+#if defined(__sparc__) || (defined(DEBUG) && defined(CONFIG_FB_ATY_CT)) \
+    || defined(CONFIG_PMAC_PBOOK)
     struct fb_info_aty *info = (struct fb_info_aty *)info2;
 #endif /* __sparc__ || DEBUG */
 #ifdef __sparc__
@@ -1266,8 +1308,31 @@
     else
         disp = info2->disp;
 #endif
+#if defined(CONFIG_PMAC_PBOOK)
+    u32 value, rc;
+#endif
 
     switch (cmd) {
+#ifdef CONFIG_PMAC_PBOOK
+    case FBIO_ATY_SET_MIRROR:
+    	if (! M64_HAS(G3_PB_1_1))
+    		return -EINVAL;
+    	rc = get_user(value, (__u32*)arg);
+    	if (rc)
+    		return rc;
+    	info->lcd_on = (value & 0x01) != 0;
+    	info->crt_on = (value & 0x02) != 0;
+    	if (!info->crt_on && !info->lcd_on)
+    		info->lcd_on = 1;
+    	aty_set_crt_enable(info, info->crt_on);	
+    	aty_set_lcd_enable(info, info->lcd_on);	
+	break;
+    case FBIO_ATY_GET_MIRROR:
+    	if (! M64_HAS(G3_PB_1_1))
+    		return -EINVAL;
+	value = (info->crt_on << 1) | info->lcd_on;
+    	return put_user(value, (__u32*)arg);
+#endif
 #ifdef __sparc__
     case FBIOGTYPE:
 	fbtyp.fb_type = FBTYPE_PCI_GENERIC;
@@ -2016,6 +2081,11 @@
 	register_backlight_controller(&aty_backlight_controller, info, "ati");
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
+#ifdef CONFIG_PMAC_PBOOK
+    info->lcd_on = default_lcd_on;
+    info->crt_on = default_crt_on;
+#endif
+
 #ifdef MODULE
     var = default_var;
 #else /* !MODULE */
@@ -2547,6 +2617,12 @@
 		curblink = 0;
 	} else if (!strncmp(this_opt, "noaccel", 7)) {
 		noaccel = 1;
+#ifdef CONFIG_PMAC_PBOOK
+        } else if (!strncmp(this_opt, "lcd:", 4)) {
+            default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
+        } else if (!strncmp(this_opt, "crt:", 4)) {
+            default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
+#endif
 	} else if (!strncmp(this_opt, "vram:", 5))
 		default_vram = simple_strtoul(this_opt+5, NULL, 0);
 	else if (!strncmp(this_opt, "pll:", 4))
--- atyfb.h.orig	Mon Sep 24 11:49:50 2001
+++ atyfb.h	Mon Sep 24 11:52:40 2001
@@ -133,6 +133,7 @@
 #ifdef CONFIG_PMAC_PBOOK
     unsigned char *save_framebuffer;
     unsigned long save_pll[64];
+    int crt_on, lcd_on;
 #endif
 };
 

Reply to: