Skip to contentSkip to conversation

nvidiafb: PPC & mode setting fixes

PATCH In review Benjamin Herrenschmidt 2 participants 4 messages Oct 2, 2005 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvidiafb: PPC & mode setting fixes

Hi !

This patch fixes a couple of things in nvidiafb:

- The code for retreiving the mode from Open Firmware was broken. It
would crash at boot and was copied from the old rivafb code that didn't work very well (I'll update rivafb too one of these days).

- The mode setting code produced weird results on the 5200 card in the
iMac G5 here. X "nv" code works fine though. After comparing them, I found out that we aren't really manipulating some VGA bits the same way and X code seemed better, so I slightly changed the mode setting to do the same and that fixed the problem. (The display was strangely shifted with garbage in the margin but not on all lines, and not in bpp 32)

drivers/video/Kconfig +1 -1
Index: linux-work/drivers/video/Kconfig
===================================================================
@@ -662,7 +662,7 @@
 
 config FB_NVIDIA_I2C
        bool "Enable DDC Support"
-       depends on FB_NVIDIA && !PPC_OF
+       depends on FB_NVIDIA
        help
 	  This enables I2C support for nVidia Chipsets.  This is used
 	  only for getting EDID information from the attached display
drivers/video/fbmon.c +2 -1
Index: linux-work/drivers/video/fbmon.c
===================================================================
@@ -574,8 +574,9 @@
 
 	*dbsize = num;
 	m = kmalloc(num * sizeof(struct fb_videomode), GFP_KERNEL);
-	if (!m)
+	if (!m) {
 		return mode;
+	}
 	memmove(m, mode, num * sizeof(struct fb_videomode));
 	kfree(mode);
 	return m;
drivers/video/nvidia/nv_of.c +44 -18

78 lines not on this page · raw message

drivers/video/nvidia/nv_proto.h +11 -1
Index: linux-work/drivers/video/nvidia/nv_proto.h
===================================================================
@@ -31,7 +31,7 @@
 void NVLockUnlock(struct nvidia_par *par, int);
 
 /* in nvidia-i2c.c */
-#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
+#ifdef CONFIG_FB_NVIDIA_I2C
 void nvidia_create_i2c_busses(struct nvidia_par *par);
 void nvidia_delete_i2c_busses(struct nvidia_par *par);
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -45,6 +45,16 @@
 } while(0)
 #endif
 
+#ifdef CONFIG_FB_OF
+int nvidia_probe_of_connector(struct fb_info *info, int conn,
+			      u8 ** out_edid);
+#else
+#define nvidia_probe_of_connector(p, c, edid)  \
+do {                                           \
+	*(edid) = NULL;                        \
+} while(0)
+#endif
+
 /* in nv_accel.c */
 extern void NVResetGraphics(struct fb_info *info);
 extern void nvidiafb_copyarea(struct fb_info *info,
drivers/video/nvidia/nv_setup.c +11 -5
Index: linux-work/drivers/video/nvidia/nv_setup.c
===================================================================
@@ -190,9 +190,9 @@
 	present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
 
 	if (present)
-		printk("nvidiafb: CRTC%i found\n", output);
+		printk("nvidiafb: CRTC%i analog found\n", output);
 	else
-		printk("nvidiafb: CRTC%i not found\n", output);
+		printk("nvidiafb: CRTC%i analog not found\n", output);
 
 	NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
 		0x0000EFFF);
@@ -305,6 +305,9 @@
 	int FlatPanel = -1;	/* really means the CRTC is slaved */
 	int Television = 0;
 
+	memset(&monitorA, 0, sizeof(struct fb_monspecs));
+	memset(&monitorB, 0, sizeof(struct fb_monspecs));
+
 	par->PRAMIN = par->REGS + (0x00710000 / 4);
 	par->PCRTC0 = par->REGS + (0x00600000 / 4);
 	par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@
 	nvidia_create_i2c_busses(par);
 	if (!par->twoHeads) {
 		par->CRTCnumber = 0;
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
@@ -488,14 +492,16 @@
 		oldhead = NV_RD32(par->PCRTC0, 0x00000860);
 		NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
 
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
 			fb_edid_to_monspecs(edidA, monA);
 		}
 
-		nvidia_probe_i2c_connector(info, 2, &edidB);
+		if (nvidia_probe_i2c_connector(info, 2, &edidB))
+			nvidia_probe_of_connector(info, 2, &edidB);
 		if (edidB && !fb_parse_edid(edidB, &var)) {
 			printk("nvidiafb: EDID found from BUS2\n");
 			monB = &monitorB;
drivers/video/nvidia/nvidia.c +71 -13

140 lines not on this page · raw message

#1 lore raw

Re: [PATCH] nvidiafb: PPC & mode setting fixes (#2)

(This version removes a useless bit that slipped in the previous one)

This patch fixes a couple of things in nvidiafb:

- The code for retreiving the mode from Open Firmware was broken. It
would crash at boot and was copied from the old rivafb code that didn't work very well (I'll update rivafb too one of these days).

- The mode setting code produced weird results on the 5200 card in the
iMac G5 here. X "nv" code works fine though. After comparing them, I found out that we aren't really manipulating some VGA bits the same way and X code seemed better, so I slightly changed the mode setting to do the same and that fixed the problem. (The display was strangely shifted with garbage in the margin but not on all lines, and not in bpp 32)

drivers/video/Kconfig +1 -1
Index: linux-work/drivers/video/Kconfig
===================================================================
@@ -662,7 +662,7 @@
 
 config FB_NVIDIA_I2C
        bool "Enable DDC Support"
-       depends on FB_NVIDIA && !PPC_OF
+       depends on FB_NVIDIA
        help
 	  This enables I2C support for nVidia Chipsets.  This is used
 	  only for getting EDID information from the attached display
drivers/video/nvidia/nv_of.c +44 -18

78 lines not on this page · raw message

drivers/video/nvidia/nv_proto.h +11 -1
Index: linux-work/drivers/video/nvidia/nv_proto.h
===================================================================
@@ -31,7 +31,7 @@
 void NVLockUnlock(struct nvidia_par *par, int);
 
 /* in nvidia-i2c.c */
-#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
+#ifdef CONFIG_FB_NVIDIA_I2C
 void nvidia_create_i2c_busses(struct nvidia_par *par);
 void nvidia_delete_i2c_busses(struct nvidia_par *par);
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -45,6 +45,16 @@
 } while(0)
 #endif
 
+#ifdef CONFIG_FB_OF
+int nvidia_probe_of_connector(struct fb_info *info, int conn,
+			      u8 ** out_edid);
+#else
+#define nvidia_probe_of_connector(p, c, edid)  \
+do {                                           \
+	*(edid) = NULL;                        \
+} while(0)
+#endif
+
 /* in nv_accel.c */
 extern void NVResetGraphics(struct fb_info *info);
 extern void nvidiafb_copyarea(struct fb_info *info,
drivers/video/nvidia/nv_setup.c +11 -5
Index: linux-work/drivers/video/nvidia/nv_setup.c
===================================================================
@@ -190,9 +190,9 @@
 	present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
 
 	if (present)
-		printk("nvidiafb: CRTC%i found\n", output);
+		printk("nvidiafb: CRTC%i analog found\n", output);
 	else
-		printk("nvidiafb: CRTC%i not found\n", output);
+		printk("nvidiafb: CRTC%i analog not found\n", output);
 
 	NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
 		0x0000EFFF);
@@ -305,6 +305,9 @@
 	int FlatPanel = -1;	/* really means the CRTC is slaved */
 	int Television = 0;
 
+	memset(&monitorA, 0, sizeof(struct fb_monspecs));
+	memset(&monitorB, 0, sizeof(struct fb_monspecs));
+
 	par->PRAMIN = par->REGS + (0x00710000 / 4);
 	par->PCRTC0 = par->REGS + (0x00600000 / 4);
 	par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@
 	nvidia_create_i2c_busses(par);
 	if (!par->twoHeads) {
 		par->CRTCnumber = 0;
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
@@ -488,14 +492,16 @@
 		oldhead = NV_RD32(par->PCRTC0, 0x00000860);
 		NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
 
-		nvidia_probe_i2c_connector(info, 1, &edidA);
+		if (nvidia_probe_i2c_connector(info, 1, &edidA))
+			nvidia_probe_of_connector(info, 1, &edidA);
 		if (edidA && !fb_parse_edid(edidA, &var)) {
 			printk("nvidiafb: EDID found from BUS1\n");
 			monA = &monitorA;
 			fb_edid_to_monspecs(edidA, monA);
 		}
 
-		nvidia_probe_i2c_connector(info, 2, &edidB);
+		if (nvidia_probe_i2c_connector(info, 2, &edidB))
+			nvidia_probe_of_connector(info, 2, &edidB);
 		if (edidB && !fb_parse_edid(edidB, &var)) {
 			printk("nvidiafb: EDID found from BUS2\n");
 			monB = &monitorB;
drivers/video/nvidia/nvidia.c +71 -13

140 lines not on this page · raw message

Acked-by Antonino Daplas
#2 lore raw

Re: [PATCH] nvidiafb: PPC & mode setting fixes (#2)

Quoted 7 lines · Benjamin Herrenschmidt

(This version removes a useless bit that slipped in the previous one)

This patch fixes a couple of things in nvidiafb:

- The code for retreiving the mode from Open Firmware was broken. It
would crash at boot and was copied from the old rivafb code that didn't work very well (I'll update rivafb too one of these days).

What do you think of making EDID retrieval from the OF generic? Or is it too much hassle?

Quoted 9 lines

- The mode setting code produced weird results on the 5200 card in the
iMac G5 here. X "nv" code works fine though. After comparing them, I found out that we aren't really manipulating some VGA bits the same way and X code seemed better, so I slightly changed the mode setting to do the same and that fixed the problem. (The display was strangely shifted with garbage in the margin but not on all lines, and not in bpp 32)

Thanks for the fix :-)

#3 lore raw

Re: [PATCH] nvidiafb: PPC & mode setting fixes (#2)

Quoted 11 lines · Antonino A. Daplas
Quoted 7 lines · Benjamin Herrenschmidt

(This version removes a useless bit that slipped in the previous one)

This patch fixes a couple of things in nvidiafb:

- The code for retreiving the mode from Open Firmware was broken. It
would crash at boot and was copied from the old rivafb code that didn't work very well (I'll update rivafb too one of these days).

What do you think of making EDID retrieval from the OF generic? Or is it too much hassle?

Well, at this point, it only really concerns nvidia and ati's and their respective firmwares seem to expose some properties a bit differently... The radeon code would probably work for nvidia though as I'm not trying to get the connector type for nvidiafb yet, but if I ever try, it seems the stuff is a bit different.

I'd say let's keep them separate for now, I may put them in a common place some day ..

Ben.

Quoted 3 lines

Thanks for the fix :-)

Ok, if you confirm it doesn't seem to do any regression on other hardware (I don't have any other nvidia hw to test with), I'd like it upstream asap (probably too late for 2.6.14 though).

Ben.