From: zippel@fh-brandenburg.de (Roman Zippel)
Subject: L68K: amifb fix
To: linux-m68k@phil.uni-sb.de
Date: Sun, 28 Sep 1997 18:08:56 +0200 (MET DST)
Sender: owner-linux-m68k@phil.uni-sb.de

Hi,

Below is a patch, so that lowres modes are working again
(did they ever work?!) and the ami fb is now a bit more
informative, when it can't set any mode. It prints now
a debugging message in these cases (in normal configurations
these messages are not visible, check your log files or
try dmesg under linux). If these messages are not informative
enough (really? :-) ), at least I can faster say why certain
modes don't work.

Roman

--- snapshot-200997/drivers/video/amifb.c	Mon Sep 15 17:39:09 1997
+++ linux/drivers/video/amifb.c	Sun Sep 28 16:47:34 1997
@@ -94,6 +94,12 @@
 #  define IS_AGA (1)
 #endif
 
+#ifdef DEBUG
+#  define DPRINTK(fmt, args...)	printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
 /*******************************************************************************
 
 
@@ -2231,36 +2237,53 @@
 	 * Find a matching Pixel Clock
 	 */
 
-	for (clk_shift = TAG_SHRES; clk_shift < TAG_LORES; clk_shift++)
+	for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
 		if (var->pixclock <= pixclock[clk_shift])
 			break;
-	if (clk_shift >= TAG_LORES)
+	if (clk_shift > TAG_LORES) {
+		DPRINTK("pixclock too high\n");
 		return -EINVAL;
+	}
 	par->clk_shift = clk_shift;
 
 	/*
 	 * Check the Geometry Values
 	 */
 
-	if ((par->xres = var->xres) < 64)
+	if ((par->xres = var->xres) < 64) {
+		DPRINTK("xres too small\n");
 		return -EINVAL;
-	if ((par->yres = var->yres) < 64)
+	}
+	if ((par->yres = var->yres) < 64) {
+		DPRINTK("yres too high\n");
 		return -EINVAL;
-	if ((par->vxres = var->xres_virtual) < 64)
+	}
+	if ((par->vxres = var->xres_virtual) < 64) {
+		DPRINTK("vxres too high\n");
 		return -EINVAL;
-	if ((par->vyres = var->yres_virtual) < 64)
+	}
+	if ((par->vyres = var->yres_virtual) < 64) {
+		DPRINTK("vyres too high\n");
 		return -EINVAL;
+	}
 
 	par->bpp = var->bits_per_pixel;
 	if (!var->nonstd) {
-		if (par->bpp <= 0 || par->bpp > maxdepth[clk_shift])
+		if (par->bpp <= 0 || par->bpp > maxdepth[clk_shift]) {
+			DPRINTK("invalid bpp\n");
 			return -EINVAL;
+		}
 	} else if (var->nonstd == FB_NONSTD_HAM) {
-		if (par->bpp != 6)
-			if (par->bpp != 8 || !IS_AGA)
+		if (par->bpp != 6) {
+			if (par->bpp != 8 || !IS_AGA) {
+				DPRINTK("invalid bpp for ham mode\n");
 				return -EINVAL;
-	} else
+			}
+		}
+	} else {
+		DPRINTK("unknown nonstd mode\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
@@ -2276,11 +2299,14 @@
 			line_shift = 1;
 			break;
 		case FB_VMODE_DOUBLE:
-			if (!IS_AGA)
+			if (!IS_AGA) {
+				DPRINTK("double mode only possible with aga\n");
 				return -EINVAL;
+			}
 			line_shift = 2;
 			break;
 		default:
+			DPRINTK("unknown video mode\n");
 			return -EINVAL;
 			break;
 	}
@@ -2305,11 +2331,19 @@
 			par->diwstop_h += mod4(var->hsync_len);
 		else
 			par->diwstop_h = down4(par->diwstop_h);
+
 		par->diwstrt_h = par->diwstop_h - xres_n;
 		par->diwstop_v = par->vtotal-((var->lower_margin-var->vsync_len)<<line_shift);
 		par->diwstrt_v = par->diwstop_v - yres_n;
-		if (par->diwstop_h >= par->htotal+8 || par->diwstop_v > par->vtotal)
+		if (par->diwstop_h >= par->htotal+8) {
+			DPRINTK("invalid diwstop_h\n");
+			return -EINVAL;
+		}
+		if (par->diwstop_v > par->vtotal) {
+			DPRINTK("invaild diwstop_v\n");
 			return -EINVAL;
+		}
+
 		if (!IS_OCS) {
 			/* Initialize sync with some reasonable values for pwrsave */
 			par->hsstrt = 160;
@@ -2324,12 +2358,18 @@
 		}
 		if (par->vtotal > (PAL_VTOTAL+NTSC_VTOTAL)/2) {
 			/* PAL video mode */
-			if (par->htotal != PAL_HTOTAL)
+			if (par->htotal != PAL_HTOTAL) {
+				DPRINTK("htotal invalid for pal\n");
 				return -EINVAL;
-			if (par->diwstrt_h < PAL_DIWSTRT_H)
+			}
+			if (par->diwstrt_h < PAL_DIWSTRT_H) {
+				DPRINTK("diwstrt_h too low for pal\n");
 				return -EINVAL;
-			if (par->diwstrt_v < PAL_DIWSTRT_V)
+			}
+			if (par->diwstrt_v < PAL_DIWSTRT_V) {
+				DPRINTK("diwstrt_v too low for pal\n");
 				return -EINVAL;
+			}
 			hrate = 15625;
 			vrate = 50;
 			if (!IS_OCS) {
@@ -2339,19 +2379,27 @@
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = BMC0_PAL;
 				par->hsstop = 1;
-			} else if (amiga_vblank != 50)
+			} else if (amiga_vblank != 50) {
+				DPRINTK("pal not supported by this chipset\n");
 				return -EINVAL;
+			}
 		} else {
 			/* NTSC video mode
 			 * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
 			 * and NTSC activated, so than better let diwstop_h <= 1812
 			 */
-			if (par->htotal != NTSC_HTOTAL)
+			if (par->htotal != NTSC_HTOTAL) {
+				DPRINTK("htotal invalid for ntsc\n");
 				return -EINVAL;
-			if (par->diwstrt_h < NTSC_DIWSTRT_H)
+			}
+			if (par->diwstrt_h < NTSC_DIWSTRT_H) {
+				DPRINTK("diwstrt_h too low for ntsc\n");
 				return -EINVAL;
-			if (par->diwstrt_v < NTSC_DIWSTRT_V)
+			}
+			if (par->diwstrt_v < NTSC_DIWSTRT_V) {
+				DPRINTK("diwstrt_v too low for ntsc\n");
 				return -EINVAL;
+			}
 			hrate = 15750;
 			vrate = 60;
 			if (!IS_OCS) {
@@ -2361,13 +2409,17 @@
 			           AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
 				par->beamcon0 = 0;
 				par->hsstop = 1;
-			} else if (amiga_vblank != 60)
+			} else if (amiga_vblank != 60) {
+				DPRINTK("ntsc not supported by this chipset\n");
 				return -EINVAL;
+			}
 		}
 		if (IS_OCS) {
 			if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
-			    par->diwstrt_v >=  512 || par->diwstop_v <  256)
+			    par->diwstrt_v >=  512 || par->diwstop_v <  256) {
+				DPRINTK("invalid position for display on ocs\n");
 				return -EINVAL;
+			}
 		}
 	} else if (!IS_OCS) {
 		/* Programmable video mode */
@@ -2390,8 +2442,14 @@
 		par->diwstrt_v = par->diwstop_v - yres_n;
 		par->vbstop = par->diwstrt_v - 2;
 		par->vbstrt = par->diwstop_v - 2;
-		if (par->vtotal > 2048 || par->htotal > 2048)
+		if (par->vtotal > 2048) {
+			DPRINTK("vtotal too high\n");
 			return -EINVAL;
+		}
+		if (par->htotal > 2048) {
+			DPRINTK("htotal too high\n");
+			return -EINVAL;
+		}
 		par->bplcon3 |= BPC3_EXTBLKEN;
 		par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
 		                BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
@@ -2405,8 +2463,10 @@
 		hrate = (amiga_masterclock+par->htotal/2)/par->htotal;
 		vrate = div2(par->vtotal) * par->htotal;
 		vrate = (amiga_masterclock+vrate/2)/vrate;
-	} else
+	} else {
+		DPRINTK("only broadcast modes possible for ocs\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * Checking the DMA timing
@@ -2422,8 +2482,10 @@
 
 	fsize = ((maxfmode+clk_shift <= 1) ? fconst : 64);
 	fstrt = downx(fconst, par->diwstrt_h-4) - fsize;
-	if (fstrt < min_fstrt)
+	if (fstrt < min_fstrt) {
+		DPRINTK("fetch start too low\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * smallest window start value where smooth scrolling is possible
@@ -2441,8 +2503,10 @@
 		par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
 
 	fsize = upx(fconst, xres_n);
-	if (fstrt + fsize > maxfetchstop)
+	if (fstrt + fsize > maxfetchstop) {
+		DPRINTK("fetch stop too high\n");
 		return -EINVAL;
+	}
 
 	if (maxfmode + clk_shift <= 1) {
 		fsize = up64(xres_n + fconst - 1);
@@ -2450,8 +2514,10 @@
 			par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
 
 		fsize = up64(xres_n);
-		if (min_fstrt + fsize - 64 > maxfetchstop)
+		if (min_fstrt + fsize - 64 > maxfetchstop) {
+			DPRINTK("fetch size too high\n");
 			return -EINVAL;
+		}
 
 		fsize -= 64;
 	} else
@@ -2471,13 +2537,17 @@
 	if (amifb_ilbm) {
 		par->next_plane = div8(upx(16<<maxfmode, par->vxres));
 		par->next_line = par->bpp*par->next_plane;
-		if (par->next_line * par->vyres > videomemorysize)
+		if (par->next_line * par->vyres > videomemorysize) {
+			DPRINTK("too less video mem\n");
 			return -EINVAL;
+		}
 	} else {
 		par->next_line = div8(upx(16<<maxfmode, par->vxres));
 		par->next_plane = par->vyres*par->next_line;
-		if (par->next_plane * par->bpp > videomemorysize)
+		if (par->next_plane * par->bpp > videomemorysize) {
+			DPRINTK("too less video mem\n");
 			return -EINVAL;
+		}
 	}
 
 	/*
@@ -2527,8 +2597,10 @@
 	par->crsr.spot_x = par->crsr.spot_y = 0;
 	par->crsr.height = par->crsr.width = 0;
 
-	if (hrate < hfmin || hrate > hfmax || vrate < vfmin || vrate > vfmax)
+	if (hrate < hfmin || hrate > hfmax || vrate < vfmin || vrate > vfmax) {
+		DPRINTK("mode doesn't fit for monitor\n");
 		return -EINVAL;
+	}
 
 	return 0;
 }


