mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Fix atyfb
@ 2003-01-10  2:48 Paul Mackerras
  2003-01-10 20:00 ` James Simmons
  0 siblings, 1 reply; 2+ messages in thread
From: Paul Mackerras @ 2003-01-10  2:48 UTC (permalink / raw)
  To: James Simmons; +Cc: linux-kernel

Here is a patch which fixes a couple of problems in atyfb.

1. It was modifying the par structure in the check_var routine and not
   reading info->var in the set_par routine.

2. It was relying on info->var.accel_flags and consequently we were
   getting a situation where it was trying to use the drawing engine
   without having initialized it.  This caused my G3 powerbook to hang
   on boot when the console text got to the bottom of the screen and
   it tried to scroll.  I have added an accel_flags field to the par
   structure so that the driver can control when it starts and stops
   using acceleration.  I also added code to the accelerated drawing
   routines so that they will fall back to the cfb routines if
   acceleration is disabled.

3. It was accessing the pseudo_palette as 16-bit quantities in 15/16
   bpp mode rather than as u32.

The driver generally is badly formatted, particularly in the
atyfb_init routine, which is very long and should be split up.  James,
would you accept a patch to split up atyfb_init and fix the
formatting?

Paul.

diff -urN linux-2.5/drivers/video/aty/atyfb.h pmac-2.5/drivers/video/aty/atyfb.h
--- linux-2.5/drivers/video/aty/atyfb.h	2002-11-24 06:49:51.000000000 +1100
+++ pmac-2.5/drivers/video/aty/atyfb.h	2003-01-01 22:15:45.000000000 +1100
@@ -79,6 +79,7 @@
 	u8 ram_type;
 	u8 mem_refresh_rate;
 	u8 blitter_may_be_busy;
+	u32 accel_flags;
 #ifdef __sparc__
 	struct pci_mmap_map *mmap_map;
 	u8 mmaped;
diff -urN linux-2.5/drivers/video/aty/atyfb_base.c pmac-2.5/drivers/video/aty/atyfb_base.c
--- linux-2.5/drivers/video/aty/atyfb_base.c	2002-12-22 09:07:14.000000000 +1100
+++ pmac-2.5/drivers/video/aty/atyfb_base.c	2003-01-10 13:41:01.000000000 +1100
@@ -173,9 +173,6 @@
 			   struct crtc *crtc);
 static int aty_crtc_to_var(const struct crtc *crtc,
 			   struct fb_var_screeninfo *var);
-static int atyfb_encode_var(struct fb_var_screeninfo *var,
-			    const struct atyfb_par *par,
-			    const struct fb_info *info);
 static void set_off_pitch(struct atyfb_par *par,
 			  const struct fb_info *info);
 #ifdef CONFIG_PPC
@@ -772,11 +769,17 @@
 static int atyfb_set_par(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	int accelmode;
+	struct fb_var_screeninfo *var = &info->var;
 	u8 tmp;
 	u32 i;
+	int err;
 
-	accelmode = info->var.accel_flags;	/* hack */
+	if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
+	    (err = par->pll_ops->var_to_pll(info, var->pixclock,
+					var->bits_per_pixel, &par->pll)))
+		return err;
+
+	par->accel_flags = var->accel_flags;	/* hack */
 
 	if (par->blitter_may_be_busy)
 		wait_for_idle(par);
@@ -786,13 +789,14 @@
 	/* better call aty_StrobeClock ?? */
 	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, CLOCK_STROBE, par);
 
-	par->dac_ops->set_dac(info, &par->pll, info->var.bits_per_pixel, accelmode);
+	par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel,
+			      par->accel_flags);
 	par->pll_ops->set_pll(info, &par->pll);
 
 	if (!M64_HAS(INTEGRATED)) {
 		/* Don't forget MEM_CNTL */
 		i = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
-		switch (info->var.bits_per_pixel) {
+		switch (var->bits_per_pixel) {
 		case 8:
 			i |= 0x02000000;
 			break;
@@ -808,7 +812,7 @@
 		i = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
 		if (!M64_HAS(MAGIC_POSTDIV))
 			i |= par->mem_refresh_rate << 20;
-		switch (info->var.bits_per_pixel) {
+		switch (var->bits_per_pixel) {
 		case 8:
 		case 24:
 			i |= 0x00000000;
@@ -841,20 +845,20 @@
 	}
 	aty_st_8(DAC_MASK, 0xff, par);
 
-	info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel/8;
-	info->fix.visual = info->var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+	info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
+	info->fix.visual = var->bits_per_pixel <= 8 ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
 	/* Initialize the graphics engine */
-	if (info->var.accel_flags & FB_ACCELF_TEXT)
+	if (par->accel_flags & FB_ACCELF_TEXT)
 		aty_init_engine(par, info);
 
 #ifdef CONFIG_BOOTX_TEXT
 	btext_update_display(info->fix.smem_start,
-			     (((par->crtc.h_tot_disp >> 16) & 0xff) +
-			      1) * 8,
+			     (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
 			     ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
-			     info->var.bits_per_pixel,
-			     par->crtc.vxres * info->var.bits_per_pixel / 8);
+			     var->bits_per_pixel,
+			     par->crtc.vxres * var->bits_per_pixel / 8);
 #endif				/* CONFIG_BOOTX_TEXT */
 	return 0;
 }
@@ -863,41 +867,24 @@
 			   struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct crtc crtc;
+	union aty_pll pll;
 	int err;
 
-	if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
-	    (err =
-	     par->pll_ops->var_to_pll(info, var->pixclock, var->bits_per_pixel,
-				       &par->pll)))
+	if ((err = aty_var_to_crtc(info, var, &crtc)) ||
+	    (err = par->pll_ops->var_to_pll(info, var->pixclock,
+					var->bits_per_pixel, &pll)))
 		return err;
 
-#if 0				/* fbmon is not done. uncomment for 2.5.x -brad */
+#if 0	/* fbmon is not done. uncomment for 2.5.x -brad */
 	if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
 		return -EINVAL;
 #endif
-	atyfb_encode_var(var, par, info);
-	return 0;
-}
-
-static int atyfb_encode_var(struct fb_var_screeninfo *var,
-			    const struct atyfb_par *par,
-			    const struct fb_info *info)
-{
-	int err;
-
-	memset(var, 0, sizeof(struct fb_var_screeninfo));
-
-	if ((err = aty_crtc_to_var(&par->crtc, var)))
-		return err;
-	var->pixclock = par->pll_ops->pll_to_var(info, &par->pll);
-
-	var->height = -1;
-	var->width = -1;
+	aty_crtc_to_var(&crtc, var);
+	var->pixclock = par->pll_ops->pll_to_var(info, &pll);
 	return 0;
 }
 
-
-
 static void set_off_pitch(struct atyfb_par *par,
 			  const struct fb_info *info)
 {
@@ -1410,7 +1397,7 @@
 	for (info = first_display; info != NULL; info = par->next) {
 		int nb;
 
-		par = (struct atyfb_par *) info->fb.par;
+		par = (struct atyfb_par *) info->par;
 		nb = info->var.yres * info->fix.line_length;
 
 		switch (when) {
@@ -1429,7 +1416,7 @@
 			if (par->blitter_may_be_busy)
 				wait_for_idle(par);
 			/* Stop accel engine (stop bus mastering) */
-			if (info->accel_flags & FB_ACCELF_TEXT)
+			if (par->accel_flags & FB_ACCELF_TEXT)
 				aty_reset_engine(par);
 
 			/* Backup fb content */
@@ -2306,9 +2293,7 @@
 
 #ifdef CONFIG_PMAC_PBOOK
 			if (first_display == NULL)
-				pmu_register_sleep_notifier
-				    (&aty_sleep_notifier);
-			/* FIXME info->next = first_display; */
+				pmu_register_sleep_notifier(&aty_sleep_notifier);
 			default_par->next = first_display;
 #endif
 		}
@@ -2346,7 +2331,7 @@
 		info->fix.smem_start = info->screen_base;	/* Fake! */
 		default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
 							  0x10000) + 0xFC00ul;
-		info->fix.mmio_start = par->ati_regbase; /* Fake! */
+		info->fix.mmio_start = default_par->ati_regbase; /* Fake! */
 
 		aty_st_le32(CLOCK_CNTL, 0x12345678, default_par);
 		clock_r = aty_ld_le32(CLOCK_CNTL, default_par);
@@ -2544,6 +2529,7 @@
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	int i, scale;
+	u32 *pal = info->pseudo_palette;
 
 	if (regno > 255)
 		return 1;
@@ -2570,17 +2556,14 @@
 	if (regno < 16)
 		switch (info->var.bits_per_pixel) {
 		case 16:
-			((u16 *) (info->pseudo_palette))[regno] =
-			    (regno << 10) | (regno << 5) | regno;
+			pal[regno] = (regno << 10) | (regno << 5) | regno;
 			break;
 		case 24:
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (regno << 16) | (regno << 8) | regno;
+			pal[regno] = (regno << 16) | (regno << 8) | regno;
 			break;
 		case 32:
 			i = (regno << 8) | regno;
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (i << 16) | i;
+			pal[regno] = (i << 16) | i;
 			break;
 		}
 	return 0;
diff -urN linux-2.5/drivers/video/aty/mach64_accel.c pmac-2.5/drivers/video/aty/mach64_accel.c
--- linux-2.5/drivers/video/aty/mach64_accel.c	2002-08-08 07:29:36.000000000 +1000
+++ pmac-2.5/drivers/video/aty/mach64_accel.c	2003-01-01 22:36:44.000000000 +1100
@@ -179,6 +179,12 @@
 
 	if (!area->width || !area->height)
 		return;
+	if (!par->accel_flags) {
+		if (par->blitter_may_be_busy)
+			wait_for_idle(par);
+		cfb_copyarea(info, area);
+		return;
+	}
 
 	pitch_value = info->var.xres_virtual;
 	if (info->var.bits_per_pixel == 24) {
@@ -216,6 +222,12 @@
 
 	if (!rect->width || !rect->height)
 		return;
+	if (!par->accel_flags) {
+		if (par->blitter_may_be_busy)
+			wait_for_idle(par);
+		cfb_fillrect(info, rect);
+		return;
+	}
 
 	rect->color |= (rect->color << 8);
 	rect->color |= (rect->color << 16);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix atyfb
  2003-01-10  2:48 [PATCH] Fix atyfb Paul Mackerras
@ 2003-01-10 20:00 ` James Simmons
  0 siblings, 0 replies; 2+ messages in thread
From: James Simmons @ 2003-01-10 20:00 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linux-kernel



Applied.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-01-10 19:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-10  2:48 [PATCH] Fix atyfb Paul Mackerras
2003-01-10 20:00 ` James Simmons

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®