public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Erik Andersen <andersen@codepoet.org>
To: Marcelo Tosatti <marcelo@conectiva.com.br>
Cc: lkml <linux-kernel@vger.kernel.org>,
	Ani Joshi <ajoshi@shell.unixbox.com>
Subject: [PATCH] radeonfb update vs 2.4.20-pre1
Date: Sun, 11 Aug 2002 15:22:44 -0600	[thread overview]
Message-ID: <20020811212244.GB27048@codepoet.org> (raw)
In-Reply-To: <Pine.LNX.4.44.0208051938380.6811-100000@freak.distro.conectiva>

Here is an update to the radeonfb.  This is based on a patch 
from Peter Horton that was posted to the lkml back in April
    http://www.uwsg.indiana.edu/hypermail/linux/kernel/0204.1/0364.html

I have been carrying this patch along in my own tree since April
and I find it a huge improvement.  Using this patch, I find that
the radeonfb is quite fast, and colors are correct.

I have updated the patch to fit into 2.4.20-pre1, fixed a few
obvious little things, and reworked the mtrr handling so it
matches the behavior of the other framebuffers.  Any chance 
we could get this into 2.4.20?

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--


--- drivers/video/radeonfb.c.orig	Sun Aug 11 03:43:12 2002
+++ drivers/video/radeonfb.c	Sun Aug 11 03:43:18 2002
@@ -22,6 +22,13 @@
  *
  *	Special thanks to ATI DevRel team for their hardware donations.
  *
+ * 	2002-04-02	Added MTRR support. Fixed 8bpp acceleration. Added
+ * 			acceleration for 16/32bpp. Applied fix from XFree86
+ * 			for hard crash on accelerator reset. Fixed up the
+ * 			colour stuff. Peter Horton <pdh@colonel-panic.org>
+ * 	2002-04-10	Make ypan work. More colour fixes, all modes >8bpp
+ * 			now DIRECTCOLOR. Match up CRTC and accelerator
+ * 			pitch.
  */
 
 
@@ -73,18 +80,24 @@
 #include <video/fbcon.h> 
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
 
 #include "radeon.h"
 
 
-#define DEBUG	0
+#define FIX_DEPTH_15		1
+
+#define DEBUG			0
+
+#define _RTRACE(f,a...)		do{printk("radeonfb: " f "\n", ##a);}while(0)
 
 #if DEBUG
-#define RTRACE		printk
+#define RTRACE(f,a...)		_RTRACE(f,##a)
 #else
-#define RTRACE		if(0) printk
+#define RTRACE(f,a...)
 #endif
 
 
@@ -299,17 +312,16 @@
 
 	struct ram_info ram;
 
+#if 0
         u32 hack_crtc_ext_cntl;
         u32 hack_crtc_v_sync_strt_wid;
+#endif
 
 #if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
         union {
 #if defined(FBCON_HAS_CFB16)
                 u_int16_t cfb16[16];
 #endif
-#if defined(FBCON_HAS_CFB24)
-                u_int32_t cfb24[16];
-#endif  
 #if defined(FBCON_HAS_CFB32)
                 u_int32_t cfb32[16];
 #endif  
@@ -474,11 +486,10 @@
 }
 
 
-static inline int var_to_depth(const struct fb_var_screeninfo *var)
+static __inline__ int var_to_depth(const struct fb_var_screeninfo *var)
 {
-	if (var->bits_per_pixel != 16)
-		return var->bits_per_pixel;
-	return (var->green.length == 6) ? 16 : 15;
+	return (var->bits_per_pixel == 16 && var->green.length == 5)? 
+	    15 : var->bits_per_pixel;
 }
 
 
@@ -531,6 +542,7 @@
 #define radeon_engine_reset()		_radeon_engine_reset(rinfo)
 
 
+#if 0
 static __inline__ u8 radeon_get_post_div_bitval(int post_div)
 {
         switch (post_div) {
@@ -552,6 +564,7 @@
                         return 0x02;
         }
 }
+#endif
 
 
 
@@ -594,14 +607,25 @@
         
 static char fontname[40] __initdata;
 static char *mode_option __initdata;
-static char noaccel __initdata = 0;
+static char noaccel /*__initdata*/ = 0;
+static char fb16fix = 0;
 static int panel_yres __initdata = 0;
 static char force_dfp __initdata = 0;
 static struct radeonfb_info *board_list = NULL;
+#ifdef CONFIG_MTRR
+static int enable_mtrr = 1;
+static int mtrr_handle;
+#endif
 
 #ifdef FBCON_HAS_CFB8
 static struct display_switch fbcon_radeon8;
 #endif
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_radeon16;
+#endif
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_radeon32;
+#endif
 
 
 /*
@@ -731,6 +755,12 @@
 			force_dfp = 1;
 		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
 			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+		} else if (!strncmp(this_opt, "fb16fix", 7)) {
+			fb16fix = 1;
+#ifdef CONFIG_MTRR
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			enable_mtrr = 0;
+#endif
                 } else
 			mode_option = this_opt;
         }
@@ -755,7 +785,7 @@
 	u32 tmp;
 	int i, j;
 
-	RTRACE("radeonfb_pci_register BEGIN\n");
+	RTRACE("radeonfb_pci_register BEGIN");
 
 	rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
 	if (!rinfo) {
@@ -915,7 +945,7 @@
 	rinfo->bios_seg = radeon_find_rom(rinfo);
 	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
 
-	RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+	RTRACE("probed %s %dk videoram", (rinfo->ram_type), (rinfo->video_ram/1024));
 
 #if !defined(__powerpc__)
 	radeon_get_moninfo(rinfo);
@@ -998,6 +1028,15 @@
 		return -ENODEV;
 	}
 
+#ifdef CONFIG_MTRR
+	if (enable_mtrr) {
+	    mtrr_handle = mtrr_add(rinfo->fb_base_phys, rinfo->video_ram, MTRR_TYPE_WRCOMB, 1);
+	    printk("radeonfb: MTRR enabled\n");
+	}
+#endif
+
+	/* XXX look at this re pitch :pdh */
+
 	if (!noaccel) {
 		/* initialize the engine */
 		radeon_engine_init (rinfo);
@@ -1029,7 +1068,7 @@
 			GET_MON_NAME(rinfo->crtDisp_type));
 	}
 
-	RTRACE("radeonfb_pci_register END\n");
+	RTRACE("radeonfb_pci_register END");
 
 	return 0;
 }
@@ -1046,6 +1085,12 @@
 	/* restore original state */
         radeon_write_mode (rinfo, &rinfo->init_state);
  
+#ifdef CONFIG_MTRR
+	if (enable_mtrr) {
+	    mtrr_del(mtrr_handle, rinfo->fb_base_phys, rinfo->video_ram);
+	    printk("radeonfb: MTRR disabled\n");
+	}
+#endif
         unregister_framebuffer ((struct fb_info *) rinfo);
                 
         iounmap ((void*)rinfo->mmio_base);
@@ -1157,7 +1202,7 @@
         	rinfo->pll.ppll_min = pll.PCLK_min_freq;
         	rinfo->pll.ppll_max = pll.PCLK_max_freq;
 
-		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
+		_RTRACE("ref_clk=%d, ref_div=%d, xclk=%d from BIOS",
 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 	} else {
 #ifdef CONFIG_ALL_PPC
@@ -1177,7 +1222,7 @@
 			rinfo->pll.ppll_min = 12000;
 			rinfo->pll.ppll_max = 35000;
 
-			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
+			_RTRACE("ref_clk=%d, ref_div=%d, xclk=%d from OF",
 				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 
 			return;
@@ -1212,7 +1257,7 @@
 				break;
 		}
 
-		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
+		_RTRACE("ref_clk=%d, ref_div=%d, xclk=%d defaults",
 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 	}
 }
@@ -1271,7 +1316,7 @@
 {
 #ifdef CONFIG_ALL_PPC
 	if (!radeon_get_EDID_OF(rinfo))
-		RTRACE("radeonfb: could not retrieve EDID from OF\n");
+		RTRACE("radeonfb: could not retrieve EDID from OF");
 #else
 	/* XXX use other methods later */
 #endif
@@ -1503,6 +1548,8 @@
 		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
 					FP_V_SYNC_WID_SHIFT);
 
+		/* XXX some more stuff needs to go here :pdh */
+
 		return 1;
 	}
 
@@ -1542,13 +1589,10 @@
 	radeon_fifo_wait (1);
 	OUTREG(DSTCACHE_MODE, 0);
 
-	/* XXX */
-	rinfo->pitch = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6;
-
 	radeon_fifo_wait (1);
 	temp = INREG(DEFAULT_PITCH_OFFSET);
 	OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | 
-				      (rinfo->pitch << 0x16)));
+				      (rinfo->pitch << 16)));
 
 	radeon_fifo_wait (1);
 	OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
@@ -1703,30 +1747,22 @@
         switch (disp->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
                 case 8:
-                        disp->dispsw = &fbcon_cfb8;
+                        disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
                         disp->line_length = disp->var.xres_virtual;
                         break;
 #endif
 #ifdef FBCON_HAS_CFB16
                 case 16:
-                        disp->dispsw = &fbcon_cfb16;
+                        disp->dispsw = accel ? &fbcon_radeon16 : &fbcon_cfb16;
                         disp->dispsw_data = &rinfo->con_cmap.cfb16;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
                         disp->line_length = disp->var.xres_virtual * 2;
                         break;
 #endif  
-#ifdef FBCON_HAS_CFB32       
-                case 24:
-                        disp->dispsw = &fbcon_cfb24;
-                        disp->dispsw_data = &rinfo->con_cmap.cfb24;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        disp->line_length = disp->var.xres_virtual * 4;
-                        break;
-#endif
 #ifdef FBCON_HAS_CFB32
                 case 32:
-                        disp->dispsw = &fbcon_cfb32;
+                        disp->dispsw = accel ? &fbcon_radeon32 : &fbcon_cfb32;
                         disp->dispsw_data = &rinfo->con_cmap.cfb32;
                         disp->visual = FB_VISUAL_DIRECTCOLOR;
                         disp->line_length = disp->var.xres_virtual * 4;
@@ -1736,8 +1772,6 @@
                         printk ("radeonfb: setting fbcon_dummy renderer\n");
                         disp->dispsw = &fbcon_dummy;
         }
-                
-        return;
 }
                         
 
@@ -1759,6 +1793,7 @@
 
 
 
+#if 0
 static int radeonfb_do_maximize(struct radeonfb_info *rinfo,
                                 struct fb_var_screeninfo *var,
                                 struct fb_var_screeninfo *v,
@@ -1819,9 +1854,18 @@
                                 
         return 0;
 }
+#endif
                         
 
 
+static void set_palette_entry(struct radeonfb_info *rinfo, unsigned idx, unsigned red, unsigned grn, unsigned blu)
+{
+	OUTREG(PALETTE_INDEX, idx);
+	OUTREG(PALETTE_DATA, (red << 16) | (grn << 8) | blu);
+
+	udelay(1);	/* is this necessary ? */
+}
+
 /*
  * fb ops
  */
@@ -1844,7 +1888,7 @@
         fix->type_aux = disp->type_aux;
         fix->visual = disp->visual;
 
-        fix->xpanstep = 8;
+        fix->xpanstep = 0;
         fix->ypanstep = 1;
         fix->ywrapstep = 0;
         
@@ -1880,7 +1924,7 @@
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
         struct display *disp;
         struct fb_var_screeninfo v;
-        int nom, den, accel;
+        int accel, bytpp, pitch;
         unsigned chgvar = 0;
 
         disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
@@ -1903,110 +1947,97 @@
         switch (v.bits_per_pixel) {
 		case 0 ... 8:
 			v.bits_per_pixel = 8;
-			break;
-		case 9 ... 16:
-			v.bits_per_pixel = 16;
-			break;
-		case 17 ... 24:
-			v.bits_per_pixel = 24;
-			break;
-		case 25 ... 32:
-			v.bits_per_pixel = 32;
-			break;
-		default:
-			return -EINVAL;
-	}
-
-	switch (var_to_depth(&v)) {
-#ifdef FBCON_HAS_CFB8
-                case 8:
-                        nom = den = 1;
-                        disp->line_length = v.xres_virtual;
-                        disp->visual = FB_VISUAL_PSEUDOCOLOR; 
                         v.red.offset = v.green.offset = v.blue.offset = 0;
                         v.red.length = v.green.length = v.blue.length = 8;
                         v.transp.offset = v.transp.length = 0;
-                        break;
-#endif
-                        
-#ifdef FBCON_HAS_CFB16
-		case 15:
-			nom = 2;
-			den = 1;
-			disp->line_length = v.xres_virtual * 2;
-			disp->visual = FB_VISUAL_DIRECTCOLOR;
-			v.red.offset = 10;
-			v.green.offset = 5;
-			v.red.offset = 0;
-			v.red.length = v.green.length = v.blue.length = 5;
-			v.transp.offset = v.transp.length = 0;
 			break;
-                case 16:
-                        nom = 2;
-                        den = 1;
-                        disp->line_length = v.xres_virtual * 2;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        v.red.offset = 11;
+		case 9 ... 16:
+#if FIX_DEPTH_15
+			if(v.bits_per_pixel < 16)
+				v.green.length = 5;
+#endif
+			if(v.green.length != 5 && v.green.length != 6)
+				v.green.length = 5;
+			v.bits_per_pixel = 16;
+                        v.red.offset = v.green.length + 5;
                         v.green.offset = 5;
                         v.blue.offset = 0;
                         v.red.length = 5;
-                        v.green.length = 6;
                         v.blue.length = 5;
                         v.transp.offset = v.transp.length = 0;
-                        break;  
-#endif
-                        
-#ifdef FBCON_HAS_CFB24
-                case 24:
-                        nom = 4;
-                        den = 1;
-                        disp->line_length = v.xres_virtual * 3;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
+			break;
+		case 17 ... 32:
+			v.bits_per_pixel = 32;
                         v.red.offset = 16;
                         v.green.offset = 8;
                         v.blue.offset = 0;
                         v.red.length = v.blue.length = v.green.length = 8;
+                        /* v.transp.offset = 24; v.transp.length = 8; */
                         v.transp.offset = v.transp.length = 0;
-                        break;
-#endif
-#ifdef FBCON_HAS_CFB32
-                case 32:
-                        nom = 4;
-                        den = 1;
-                        disp->line_length = v.xres_virtual * 4;
-                        disp->visual = FB_VISUAL_DIRECTCOLOR;
-                        v.red.offset = 16;
-                        v.green.offset = 8;
-                        v.blue.offset = 0;
-                        v.red.length = v.blue.length = v.green.length = 8;
-                        v.transp.offset = 24;
-                        v.transp.length = 8;
-                        break;
-#endif
-                default:
-                        printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
-                                var->xres, var->yres, var->bits_per_pixel);
-                        return -EINVAL;
-        }
+			break;
+		default:
+			return -EINVAL;
+	}
+
+        v.red.msb_right = v.green.msb_right = v.blue.msb_right = v.transp.msb_right = 0;
+
+	bytpp = v.bits_per_pixel >> 3;
+
+	if(v.xres > v.xres_virtual)
+		v.xres_virtual = v.xres;
+	if(v.yres > v.yres_virtual)
+		v.yres_virtual = v.yres;
+
+	/* XXX this is probably wrong for 24bpp, if we ever get it working :pdh */
+
+	pitch = (v.xres_virtual * bytpp + 63) & ~63;
+
+	if(pitch >= 8192)
+		return -EINVAL;
+
+	v.xres_virtual = pitch / bytpp;
+
+	if(v.xres_virtual < v.xres)
+		v.xres = v.xres_virtual;
+	
+	v.yres_virtual = rinfo->video_ram / pitch;
+
+	/* XXX there is some limit here, I chose 8192 :pdh */
 
+	if(v.yres_virtual >= 8192)
+		v.yres_virtual = 8191;
+
+	if(v.yres_virtual < v.yres)
+		v.yres = v.yres_virtual;
+
+#if 0
         if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
                 return -EINVAL;  
+#endif
                 
+	if(v.xoffset)
+		return -EINVAL;
+
         if (v.xoffset < 0)
                 v.xoffset = 0;
         if (v.yoffset < 0)
                 v.yoffset = 0;
          
         if (v.xoffset > v.xres_virtual - v.xres)
-                v.xoffset = v.xres_virtual - v.xres - 1;
+		return -EINVAL;
                         
         if (v.yoffset > v.yres_virtual - v.yres)
-                v.yoffset = v.yres_virtual - v.yres - 1;
-         
-        v.red.msb_right = v.green.msb_right = v.blue.msb_right =
-                          v.transp.offset = v.transp.length =
-                          v.transp.msb_right = 0;
+		return -EINVAL;
                         
+	/* XXX this shouldn't be here :pdh */
+
+	disp->visual = (v.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR);
+	disp->line_length = v.xres_virtual * bytpp;
+	disp->ypanstep = 1;
+	disp->ywrapstep = 0;
+	disp->var.yres_virtual = v.yres_virtual;
+
+
         switch (v.activate & FB_ACTIVATE_MASK) {
                 case FB_ACTIVATE_TEST:
                         return 0;
@@ -2018,15 +2049,13 @@
         }
         
         memcpy (&disp->var, &v, sizeof (v));
-        
+
         if (chgvar) {     
-                radeon_set_dispsw(rinfo, disp);
 
-                if (noaccel)
-                        disp->scrollmode = SCROLL_YREDRAW;
-                else
-                        disp->scrollmode = 0;
-                
+		disp->scrollmode = accel ? 0 : SCROLL_YREDRAW;
+
+		radeon_set_dispsw(rinfo, disp);
+
                 if (info && info->changevar)
                         info->changevar(con);
         }
@@ -2093,6 +2122,8 @@
                                  struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+
+#if 0
         u32 offset, xoffset, yoffset;
                 
         xoffset = (var->xoffset + 7) & ~7;
@@ -2105,7 +2136,18 @@
         offset = ((yoffset * var->xres + xoffset) * var->bits_per_pixel) >> 6;
          
         OUTREG(CRTC_OFFSET, offset);
+#endif
+
+	/* XXX no X pan for the moment :pdh */
+
+	if(var->xoffset)
+		return -EINVAL;
         
+	if(var->yoffset + var->yres > var->yres_virtual)
+		return -EINVAL;
+
+	OUTREG(CRTC_OFFSET, var->yoffset * rinfo->pitch);
+
         return 0;
 }
 
@@ -2144,12 +2186,14 @@
                 do_install_cmap(con, info);
         }       
 
+#if 0
         /* XXX absurd hack for X to restore console */
         {   
 		OUTREGP(CRTC_EXT_CNTL, rinfo->hack_crtc_ext_cntl,
 			CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
                 OUTREG(CRTC_V_SYNC_STRT_WID, rinfo->hack_crtc_v_sync_strt_wid);
         }
+#endif
 
         return 0;
 }
@@ -2214,18 +2258,7 @@
 
 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
 {
-        int rc = 256;            /* reasonable default */
-        
-        switch (var_to_depth(var)) {
-                case 15:
-                        rc = 32;
-                        break;
-		case 16:
-			rc = 64;
-			break;
-        }
-                
-        return rc;
+	return var->bits_per_pixel == 8 ? 256 : 16;
 }
 
 
@@ -2239,10 +2272,9 @@
 	if (regno > 255)
 		return 1;
      
- 	*red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red; 
-    	*green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
-    	*blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
-    	*transp = 0;
+ 	*red	= (unsigned) rinfo->palette[regno].red << 8;
+    	*green	= (unsigned) rinfo->palette[regno].green << 8;
+    	*blue	= (unsigned) rinfo->palette[regno].blue << 8;
 
 	return 0;
 }                            
@@ -2250,79 +2282,95 @@
 
 
 static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
-                             unsigned blue, unsigned transp, struct fb_info *info)
+                             unsigned blue, unsigned alpha, struct fb_info *info)
 {
         struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
-	u32 pindex;
 
-	if (regno > 255)
+	if(regno > 255)
 		return 1;
 
-	red >>= 8;
-	green >>= 8;
-	blue >>= 8;
-	rinfo->palette[regno].red = red;
-	rinfo->palette[regno].green = green;
-	rinfo->palette[regno].blue = blue;
+	red	>>= 8;
+	green	>>= 8;
+	blue	>>= 8;
+	alpha	>>= 8;
+
+	rinfo->palette[regno].red	= red;
+	rinfo->palette[regno].green	= green;
+	rinfo->palette[regno].blue	= blue;
+
+	/* ugly hack so that the software cursor works */
+
+	if(regno == 0) {
+		switch(rinfo->depth) {
+
+			case 16:
+				radeon_setcolreg(63, ~0, ~0, ~0, 0, info);
+				/* */
 
-        /* default */
-        pindex = regno;
-        
-	if (rinfo->bpp == 16) {
-		pindex = regno * 8;
+			case 15:
+				radeon_setcolreg(31, ~0, ~0, ~0, 0, info);
+				break;
 
-		if (rinfo->depth == 16 && regno > 63)
-			return 1;
-		if (rinfo->depth == 15 && regno > 31)
-			return 1;
+			case 32:
+				radeon_setcolreg(255, ~0, ~0, ~0, 0, info);
+				break;
+		}
+	}
 
-		/* For 565, the green component is mixed one order below */
-		if (rinfo->depth == 16) {
-	                OUTREG(PALETTE_INDEX, pindex>>1);
-       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
-                        	(green << 8) | (rinfo->palette[regno>>1].blue));
-                	green = rinfo->palette[regno<<1].green;
-        	}
-	}
-
-	if (rinfo->depth != 16 || regno < 32) {
-		OUTREG(PALETTE_INDEX, pindex);
-		OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+	switch(rinfo->depth) {
+
+		case 15:
+			if(regno > 31)
+				return 1;
+			if(regno < 16)
+				rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
+			regno <<= 3;
+			break;
+
+		case 16:
+
+			if(fb16fix) {
+
+				/* this is just another format of 15 bit mode, the LSB of the   *
+				 * green pixel data is ignored. this is required for "fbtv" and *
+				 * other apps to work correctly at 16bpp, but it means you land *
+				 * up with a sick looking boot logo. the real fix is to run at  *
+				 * 15bpp when you want to use those apps                   :pdh */
+
+				if(regno > 31)
+					return 1;
+				if(regno < 16)
+					rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 6) | regno;
+				regno <<= 3;
+				set_palette_entry(rinfo, regno | 4, red, green, blue);
+
+			} else {
+
+				if(regno > 63)
+					return 1;
+				if(regno < 16)
+					rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) | regno;
+				set_palette_entry(rinfo, regno << 2, rinfo->palette[regno >> 1].red,
+					green, rinfo->palette[regno >> 1].blue);
+				if(regno > 31)
+					return 0;
+				regno <<= 1;
+				green = rinfo->palette[regno].green;
+				regno <<= 2;
+			}
+			break;
+
+		case 32:
+			if(regno < 16)
+				rinfo->con_cmap.cfb32[regno] = (regno << 16) | (regno << 8) | regno;
+			break;
 	}
 
- 	if (regno < 16) {
-        	switch (rinfo->depth) {
-#ifdef FBCON_HAS_CFB16
-		        case 15:
-        			rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
-				                       	 	  regno;   
-			        break;
-		        case 16:
-        			rinfo->con_cmap.cfb16[regno] = (regno << 11) | (regno << 5) |
-				                       	 	  regno;   
-			        break;
-#endif
-#ifdef FBCON_HAS_CFB24
-                        case 24:
-                                rinfo->con_cmap.cfb24[regno] = (regno << 16) | (regno << 8) | regno;
-                                break;
-#endif
-#ifdef FBCON_HAS_CFB32
-	        	case 32: {
-            			u32 i;    
-   
-  		       		i = (regno << 8) | regno;
-            			rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
-		        	break;
-        		}
-#endif
-		}
-        }
+	set_palette_entry(rinfo, regno, red, green, blue);
+
 	return 0;
 }
 
-
-
 static void radeon_save_state (struct radeonfb_info *rinfo,
                                struct radeon_regs *save)
 {
@@ -2373,8 +2421,10 @@
 	int primary_mon = PRIMARY_MONITOR(rinfo);
 	int depth = var_to_depth(mode);
 
+	bytpp = mode->bits_per_pixel >> 3;
 	rinfo->xres = mode->xres;
 	rinfo->yres = mode->yres;
+	rinfo->pitch = mode->xres_virtual * bytpp;
 	rinfo->pixclock = mode->pixclock;
 
 	hSyncStart = mode->xres + mode->right_margin;
@@ -2404,9 +2454,9 @@
 	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
 	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
 
-	RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
+	RTRACE("hStart = %d, hEnd = %d, hTotal = %d",
 		hSyncStart, hSyncEnd, hTotal);
-	RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
+	RTRACE("vStart = %d, vEnd = %d, vTotal = %d",
 		vSyncStart, vSyncEnd, vTotal);
 
 	hsync_wid = (hSyncEnd - hSyncStart) / 8;
@@ -2427,7 +2477,6 @@
 	cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
 
 	format = radeon_get_dstbpp(depth);
-	bytpp = mode->bits_per_pixel >> 3;
 
 	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
 		hsync_fudge = hsync_fudge_fp[format-1];
@@ -2463,7 +2512,7 @@
 	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
 					 (vsync_wid << 16) | (v_sync_pol  << 23));
 
-	newmode.crtc_pitch = (mode->xres >> 3);
+	newmode.crtc_pitch = mode->xres_virtual >> 3;
 	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
 
 #if defined(__BIG_ENDIAN)
@@ -2479,12 +2528,9 @@
 	}
 #endif
 
-	rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
-			& ~(0x3f)) / 64;
-
-	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
+	RTRACE("h_total_disp = 0x%x  hsync_strt_wid = 0x%x",
 		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
-	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
+	RTRACE("v_total_disp = 0x%x  vsync_strt_wid = 0x%x",
 		newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
 
 	newmode.xres = mode->xres;
@@ -2493,8 +2539,10 @@
 	rinfo->bpp = mode->bits_per_pixel;
 	rinfo->depth = depth;
 
+#if 0
 	rinfo->hack_crtc_ext_cntl = newmode.crtc_ext_cntl;
 	rinfo->hack_crtc_v_sync_strt_wid = newmode.crtc_v_sync_strt_wid;
+#endif
 
 	if (freq > rinfo->pll.ppll_max)
 		freq = rinfo->pll.ppll_max;
@@ -2532,9 +2580,9 @@
 		newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
 	}
 
-	RTRACE("post div = 0x%x\n", rinfo->post_div);
-	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
-	RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
+	RTRACE("post div = 0x%x", rinfo->post_div);
+	RTRACE("fb_div = 0x%x", rinfo->fb_div);
+	RTRACE("ppll_div_3 = 0x%x", newmode.ppll_div_3);
 
 	/* DDA */
 	vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
@@ -2554,8 +2602,8 @@
 	       xclk_per_trans) << (11 - useable_precision);
 	roff = xclk_per_trans_precise * (32 - 4);
 
-	RTRACE("ron = %d, roff = %d\n", ron, roff);
-	RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
+	RTRACE("ron = %d, roff = %d", ron, roff);
+	RTRACE("vclk_freq = %d, per = %d", vclk_freq, xclk_per_trans_precise);
 
 	if ((ron + rinfo->ram.rloop) >= roff) {
 		printk("radeonfb: error ron out of range\n");
@@ -2621,6 +2669,11 @@
 		newmode.tmds_crc = rinfo->init_state.tmds_crc;
 		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
 
+		/* XXX                                                  :pdh *
+		 * this doesn't work with some DFPs. a different driver that *
+		 * does work loads the FP CRTC registers from initial saved  *
+		 * values and doesn't tweak with tmds_transmitter_cntl ????? */
+
 		if (primary_mon == MT_LCD) {
 			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
 			newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
@@ -2657,15 +2710,13 @@
 	int primary_mon = PRIMARY_MONITOR(rinfo);
 
 	/* blank screen */
-	OUTREGP(CRTC_EXT_CNTL, CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS,
-		~(CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS));
+	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+		~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
 
 	for (i=0; i<9; i++)
 		OUTREG(common_regs[i].reg, common_regs[i].val);
 
 	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
-	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
-		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
 	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
 	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
 	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
@@ -2743,7 +2794,7 @@
 	}
 
 	/* unblank screen */
-	OUTREG8(CRTC_EXT_CNTL + 1, 0);
+	OUTREG(CRTC_EXT_CNTL, mode->crtc_ext_cntl);
 
 	return;
 }
@@ -2966,6 +3017,8 @@
 	width *= fontwidth(p);
 	height *= fontheight(p);
 
+	dp_cntl = 0;
+
 	if (srcy < dsty) {
 		srcy += height - 1;
 		dsty += height - 1;
@@ -2992,22 +3045,8 @@
 }
 
 
-
-static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
-			       int srcy, int srcx, int height, int width)
+static void fbcon_radeon_clear(struct radeonfb_info *rinfo, int srcy, int srcx, int height, int width, u32 clr)
 {
-	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
-	u32 clr;
-
-	clr = attr_bgcol_ec(p, conp);
-	clr |= (clr << 8);
-	clr |= (clr << 16);
-
-	srcx *= fontwidth(p);
-	srcy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-
 	radeon_fifo_wait(6);
 	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
 				    GMC_BRUSH_SOLID_COLOR |
@@ -3021,12 +3060,24 @@
 }
 
 
-
 #ifdef FBCON_HAS_CFB8
+static void fbcon_radeon8_clear(struct vc_data *conp, struct display *p,
+		int srcy, int srcx, int height, int width)
+{
+	u32 clr;
+  
+	clr = attr_bgcol_ec(p, conp);
+	clr |= clr << 8;
+
+	fbcon_radeon_clear((struct radeonfb_info *) p->fb_info, srcy * fontheight(p), srcx * fontwidth(p),
+			height * fontheight(p), width * fontwidth(p), clr | (clr << 16));
+}
+
+
 static struct display_switch fbcon_radeon8 = {
 	setup:			fbcon_cfb8_setup,
 	bmove:			fbcon_radeon_bmove,
-	clear:			fbcon_radeon_clear,
+	clear:			fbcon_radeon8_clear,
 	putc:			fbcon_cfb8_putc,
 	putcs:			fbcon_cfb8_putcs,
 	revc:			fbcon_cfb8_revc,
@@ -3034,3 +3085,48 @@
 	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
+
+#ifdef FBCON_HAS_CFB16
+static void fbcon_radeon16_clear(struct vc_data *conp, struct display *p,
+		int srcy, int srcx, int height, int width)
+{
+	u32 clr;
+
+	clr = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
+
+	fbcon_radeon_clear((struct radeonfb_info *) p->fb_info, srcy * fontheight(p), srcx * fontwidth(p),
+			height * fontheight(p), width * fontwidth(p), clr | (clr << 16));
+}
+
+static struct display_switch fbcon_radeon16 = {
+	setup:			fbcon_cfb16_setup,
+	bmove:			fbcon_radeon_bmove,
+	clear:			fbcon_radeon16_clear,
+	putc:			fbcon_cfb16_putc,
+	putcs:			fbcon_cfb16_putcs,
+	revc:			fbcon_cfb16_revc,
+	clear_margins:		fbcon_cfb16_clear_margins,
+	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void fbcon_radeon32_clear(struct vc_data *conp, struct display *p,
+		int srcy, int srcx, int height, int width)
+{
+	fbcon_radeon_clear((struct radeonfb_info *) p->fb_info, srcy * fontheight(p), srcx * fontwidth(p),
+		height * fontheight(p), width * fontwidth(p), ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)]);
+}
+
+static struct display_switch fbcon_radeon32 = {
+	setup:			fbcon_cfb32_setup,
+	bmove:			fbcon_radeon_bmove,
+	clear:			fbcon_radeon32_clear,
+	putc:			fbcon_cfb32_putc,
+	putcs:			fbcon_cfb32_putcs,
+	revc:			fbcon_cfb32_revc,
+	clear_margins:		fbcon_cfb32_clear_margins,
+  	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+

  parent reply	other threads:[~2002-08-11 21:19 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-08-05 22:40 Linux 2.4.20-pre1 Marcelo Tosatti
2002-08-06  0:20 ` Ben Greear
2002-08-06 11:32   ` Marcelo Tosatti
2002-08-06 12:26     ` David S. Miller
2002-08-06 16:45     ` Ben Greear
2002-08-06 17:12     ` NAPI (was Re: Linux 2.4.20-pre1) Jeff Garzik
2002-08-07 14:09       ` Marcus Sundberg
2002-08-06 14:58 ` Linux 2.4.20-pre1 Jason Lunz
2002-08-06 15:03   ` CaT
2002-08-06 21:05 ` Adrian Bunk
2002-08-07 11:09   ` David S. Miller
2002-08-07  0:21 ` J.A. Magallon
2002-08-07  1:08 ` J.A. Magallon
2002-08-07  1:56 ` Bryan Whitehead
2002-08-07  3:35   ` Tim Hockin
2002-08-11  8:57 ` Erik Andersen
2002-08-11  9:16   ` Christoph Hellwig
2002-08-11  9:40     ` Erik Andersen
2002-08-11  9:46     ` Erik Andersen
2002-08-11 19:46   ` Alan Cox
2002-08-11 18:49     ` Erik Andersen
2002-08-12 19:29     ` Paul P Komkoff Jr
2002-08-11 10:56 ` Erik Andersen
2002-08-11 21:22 ` Erik Andersen [this message]
2002-08-12 10:18   ` [PATCH] radeonfb update vs 2.4.20-pre1 Ani Joshi
2002-08-12 10:26     ` Erik Andersen
2002-08-17 19:51 ` Linux 2.4.20-pre1 Adrian Bunk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020811212244.GB27048@codepoet.org \
    --to=andersen@codepoet.org \
    --cc=ajoshi@shell.unixbox.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox