Skip to contentSkip to conversation

atyfb: Get initial mode timings from LCD BIOS

PATCH In review Antonino A. Daplas 2 participants 3 messages Oct 18, 2005 – Oct 19, 2005 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

PATCH 7/17 atyfb: Get initial mode timings from LCD BIOS

Reported by: Jean-Philippe Guérard (Bugzilla Bug 1782)

"I've tried with video=atyfb:debug and video=atyfb:debug,mode:1280x600, \
nomtrr.

In both case, the screen stays black, but seems divided into 4 vertical bands. Some white lines pop up randomly on each vertical band."

The problem is a combination of an incorrect xclk plus lack of timing information. The adapter is attached to an LCD device that can do 1280x600 (which is not a standard resolution). The global mode database does not have an entry for it. Fortunately, the Video BIOS contains the complete timing info for this display, however, atyfb is not making use of it.

Add support to get the timing information from the BIOS, if available.

---
 atyfb_base.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 44 insertions(+), 14 deletions(-)
drivers/video/aty/atyfb_base.c +44 -14
@@ -2156,11 +2156,38 @@ static void __init aty_calc_mem_refresh(
 
 static struct fb_info *fb_list = NULL;
 
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+						struct fb_var_screeninfo *var)
+{
+	int ret = -EINVAL;
+
+	if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+		*var = default_var;
+		var->xres = var->xres_virtual = par->lcd_hdisp;
+		var->right_margin = par->lcd_right_margin;
+		var->left_margin = par->lcd_hblank_len -
+			(par->lcd_right_margin + par->lcd_hsync_dly +
+			 par->lcd_hsync_len);
+		var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
+		var->yres = var->yres_virtual = par->lcd_vdisp;
+		var->lower_margin = par->lcd_lower_margin;
+		var->upper_margin = par->lcd_vblank_len -
+			(par->lcd_lower_margin + par->lcd_vsync_len);
+		var->vsync_len = par->lcd_vsync_len;
+		var->pixclock = par->lcd_pixclock;
+		ret = 0;
+	}
+
+	return ret;
+}
+#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
+
 static int __init aty_init(struct fb_info *info, const char *name)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	const char *ramname = NULL, *xtal;
-	int gtb_memsize;
+	int gtb_memsize, has_var = 0;
 	struct fb_var_screeninfo var;
 	u8 pll_ref_div;
 	u32 i;
@@ -2468,8 +2495,8 @@ static int __init aty_init(struct fb_inf
 		 *         applies to all Mac video cards
 		 */
 		if (mode) {
-			if (!mac_find_mode(&var, info, mode, 8))
-				var = default_var;
+			if (mac_find_mode(&var, info, mode, 8))
+				has_var = 1;
 		} else {
 			if (default_vmode == VMODE_CHOOSE) {
 				if (M64_HAS(G3_PB_1024x768))
@@ -2491,20 +2518,23 @@ static int __init aty_init(struct fb_inf
 				default_vmode = VMODE_640_480_60;
 			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
 				default_cmode = CMODE_8;
-			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-				var = default_var;
+			if (!mac_vmode_to_var(default_vmode, default_cmode,
+					       &var))
+				has_var = 1;
 		}
-	} else
+	}
+
 #endif /* !CONFIG_PPC */
-	if (
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
-	   /* On Sparc, unless the user gave a specific mode
-	    * specification, use the PROM probed values in
-	    * default_var.
-	    */
-	    !mode ||
+
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+	if (!atyfb_get_timings_from_lcd(par, &var))
+		has_var = 1;
 #endif
-	    !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+
+	if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+		has_var = 1;
+
+	if (!has_var)
 		var = default_var;
 
 	if (noaccel)

-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions, and more. http://solutions.newsforge.com/ibmarch.tmpl

#1 lore raw
Quoted 27 lines · Antonino A. Daplas

"I've tried with video=atyfb:debug and video=atyfb:debug,mode:1280x600, \
nomtrr.

In both case, the screen stays black, but seems divided into 4 vertical bands. Some white lines pop up randomly on each vertical band."

The problem is a combination of an incorrect xclk plus lack of timing information. The adapter is attached to an LCD device that can do 1280x600 (which is not a standard resolution). The global mode database does not have an entry for it. Fortunately, the Video BIOS contains the complete timing info for this display, however, atyfb is not making use of it.

Add support to get the timing information from the BIOS, if available.

---

  atyfb_base.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--------------
  1 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c --- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2156,11 +2156,38 @@ static void __init aty_calc_mem_refresh(

Quoted 5 lines
  static struct fb_info *fb_list = NULL;

+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) +static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+ struct fb_var_screeninfo *var)

Are we sure that __i386__ is the right thing to use here? Is it not valid for x86_64, for example? Or other architecctures, come to that.

CONFIG_X86_32?

-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions, and more. http://solutions.newsforge.com/ibmarch.tmpl

#2 lore raw
Quoted 29 lines · Andrew Morton
Quoted 28 lines · Antonino A. Daplas

"I've tried with video=atyfb:debug and video=atyfb:debug,mode:1280x600, \
nomtrr.

In both case, the screen stays black, but seems divided into 4 vertical bands. Some white lines pop up randomly on each vertical band."

The problem is a combination of an incorrect xclk plus lack of timing information. The adapter is attached to an LCD device that can do 1280x600 (which is not a standard resolution). The global mode database does not have an entry for it. Fortunately, the Video BIOS contains the complete timing info for this display, however, atyfb is not making use of it.

Add support to get the timing information from the BIOS, if available.

---

  atyfb_base.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--------------
  1 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c --- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2156,11 +2156,38 @@ static void __init aty_calc_mem_refresh(

  static struct fb_info *fb_list = NULL;
Quoted 9 lines
Quoted 3 lines

+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) +static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+ struct fb_var_screeninfo *var)

Are we sure that __i386__ is the right thing to use here? Is it not valid for x86_64, for example? Or other architecctures, come to that.

CONFIG_X86_32?

This patch depends on aty_init_lcd() which is enclosed in this...

#ifdef __i386__
#ifdef CONFIG_FB_ATY_GENERIC_LCD
static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
...

...so I just follow that.

Tony

-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions, and more. http://solutions.newsforge.com/ibmarch.tmpl