[PATCH 0/6] sisfb: XGI Z9 POST

STALE5645d

10 messages, 2 authors, 2011-02-16 · open the first message on its own page

[PATCH 0/6] sisfb: XGI Z9 POST

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:11:23

Here's some patches to get POST working with XGI Z9. I have tested them
with the following card:

	http://www.roboard.com/Files/RB-100/MiniPCI-VGA-Z9s_UM_v1r1A.pdf

I'm using the card on an ARM board where the bootloader knows nothing
about VGA or VGA BIOS, so having POST support in the kernel driver
is mandatory. With these patches the memory size is correct detected,
R/W test passes and it's possible to use e.g. framebuffer console.

Aaro Koskinen (6):
  sisfb: POST should fail if R/W test fails
  sisfb: move XGI POST RAM type detection into a subroutine
  sisfb: add subroutine for detecting XGI Z9
  sisfb: add RAM type detection for XGI Z9
  sisfb: move XGI POST DDR2 bootup code into subroutines
  sisfb: add support for XGI Z9 DDR2 POST

 drivers/video/sis/sis.h      |    1 +
 drivers/video/sis/sis_main.c |  315 ++++++++++++++++++++++++++++++------------
 drivers/video/sis/vgatypes.h |    1 +
 3 files changed, 228 insertions(+), 89 deletions(-)

[PATCH 6/6] sisfb: add support for XGI Z9 DDR2 POST

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:11:35

Add support for ZGI Z9 DDR2 POST. The init sequence is from XGI's
xgifb driver.

Tested with ARM board using a PCI card with XGI Z9s and 32 MB DDR2
memory. After a cold reset the POST succeeds.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |   77 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 9c52d7b..7525984 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4983,6 +4983,48 @@ sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
 }
 
 static void __devinit
+sisfb_post_xgi_ddr2_mrs_xg21(struct sis_video_info *ivideo)
+{
+	sisfb_post_xgi_setclocks(ivideo, 1);
+
+	SiS_SetReg(SISCR, 0x97, 0x11);
+	sisfb_post_xgi_delay(ivideo, 0x46);
+
+	SiS_SetReg(SISSR, 0x18, 0x00);	/* EMRS2 */
+	SiS_SetReg(SISSR, 0x19, 0x80);
+	SiS_SetReg(SISSR, 0x16, 0x05);
+	SiS_SetReg(SISSR, 0x16, 0x85);
+
+	SiS_SetReg(SISSR, 0x18, 0x00);	/* EMRS3 */
+	SiS_SetReg(SISSR, 0x19, 0xc0);
+	SiS_SetReg(SISSR, 0x16, 0x05);
+	SiS_SetReg(SISSR, 0x16, 0x85);
+
+	SiS_SetReg(SISSR, 0x18, 0x00);	/* EMRS1 */
+	SiS_SetReg(SISSR, 0x19, 0x40);
+	SiS_SetReg(SISSR, 0x16, 0x05);
+	SiS_SetReg(SISSR, 0x16, 0x85);
+
+	SiS_SetReg(SISSR, 0x18, 0x42);	/* MRS1 */
+	SiS_SetReg(SISSR, 0x19, 0x02);
+	SiS_SetReg(SISSR, 0x16, 0x05);
+	SiS_SetReg(SISSR, 0x16, 0x85);
+	sisfb_post_xgi_delay(ivideo, 1);
+
+	SiS_SetReg(SISSR, 0x1b, 0x04);
+	sisfb_post_xgi_delay(ivideo, 1);
+
+	SiS_SetReg(SISSR, 0x1b, 0x00);
+	sisfb_post_xgi_delay(ivideo, 1);
+
+	SiS_SetReg(SISSR, 0x18, 0x42);	/* MRS1 */
+	SiS_SetReg(SISSR, 0x19, 0x00);
+	SiS_SetReg(SISSR, 0x16, 0x05);
+	SiS_SetReg(SISSR, 0x16, 0x85);
+	sisfb_post_xgi_delay(ivideo, 1);
+}
+
+static void __devinit
 sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
 {
 	unsigned char *bios = ivideo->bios_abase;
@@ -5000,6 +5042,7 @@ sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
 	u8 v2;
 	u8 v3;
 
+	SiS_SetReg(SISCR, 0xb0, 0x80); /* DDR2 dual frequency mode */
 	SiS_SetReg(SISCR, 0x82, 0x77);
 	SiS_SetReg(SISCR, 0x86, 0x00);
 	reg = SiS_GetReg(SISCR, 0x86);
@@ -5021,7 +5064,10 @@ sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
 	SiS_SetReg(SISCR, 0x82, v3);
 	SiS_SetReg(SISCR, 0x98, 0x01);
 	SiS_SetReg(SISCR, 0x9a, 0x02);
-	sisfb_post_xgi_ddr2_default(ivideo, regb);
+	if (sisfb_xgi_is21(ivideo))
+		sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
+	else
+		sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
 }
 
 static u8 __devinit
@@ -5346,9 +5392,23 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISCR, 0x77, v1);
 	}
 
-	/* RAM type */
-
-	regb = 0;	/* ! */
+	/* RAM type:
+	 *
+	 * 0 = DDR1, 1 = DDR2, 2..7 = reserved?
+	 *
+	 * The code seems to written so that regb should equal ramtype,
+	 * however, so far it has been hardcoded to 0. Enable other values only
+	 * on XGI Z9, as it passes the POST, and add a warning for others.
+	 */
+	ramtype = sisfb_post_xgi_ramtype(ivideo);
+	if (!sisfb_xgi_is21(ivideo) && ramtype) {
+		dev_warn(&pdev->dev,
+			 "RAM type something else than expected: %d\n",
+			 ramtype);
+		regb = 0;
+	} else {
+		regb = ramtype;
+	}
 
 	v1 = 0xff;
 	if(ivideo->haveXGIROM) {
@@ -5500,7 +5560,10 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		}
 	}
 
-	SiS_SetReg(SISSR, 0x17, 0x00);
+	if (regb = 1)
+		SiS_SetReg(SISSR, 0x17, 0x80);		/* DDR2 */
+	else
+		SiS_SetReg(SISSR, 0x17, 0x00);		/* DDR1 */
 	SiS_SetReg(SISSR, 0x1a, 0x87);
 
 	if(ivideo->chip = XGI_20) {
@@ -5508,10 +5571,6 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x1c, 0x00);
 	}
 
-	ramtype = sisfb_post_xgi_ramtype(ivideo);
-
-	regb = 0;	/* ! */
-
 	switch(ramtype) {
 	case 0:
 		sisfb_post_xgi_setclocks(ivideo, regb);
-- 
1.5.6.5

[PATCH 3/6] sisfb: add subroutine for detecting XGI Z9

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:11:45

Z7 and Z9 have the same PCI ID, so additional checking is needed to
detect Z9. The method was "documented" in XGI's xgifb driver.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis.h      |    1 +
 drivers/video/sis/sis_main.c |   18 ++++++++++++++++++
 drivers/video/sis/vgatypes.h |    1 +
 3 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index eac7a01..1987f1b 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -495,6 +495,7 @@ struct sis_video_info {
 	unsigned int	refresh_rate;
 
 	unsigned int	chip;
+	unsigned int	chip_real_id;
 	u8		revision_id;
 	int		sisvga_enabled;		/* PCI device was enabled */
 
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 364559b..f0c48e8 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4563,6 +4563,11 @@ sisfb_post_sis315330(struct pci_dev *pdev)
 }
 #endif
 
+static inline int sisfb_xgi_is21(struct sis_video_info *ivideo)
+{
+	return ivideo->chip_real_id = XGI_21;
+}
+
 static void __devinit
 sisfb_post_xgi_delay(struct sis_video_info *ivideo, int delay)
 {
@@ -5802,6 +5807,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 #endif
 
 	ivideo->chip = chipinfo->chip;
+	ivideo->chip_real_id = chipinfo->chip;
 	ivideo->sisvga_engine = chipinfo->vgaengine;
 	ivideo->hwcursor_size = chipinfo->hwcursor_size;
 	ivideo->CRT2_write_enable = chipinfo->CRT2_write_enable;
@@ -6035,6 +6041,18 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		sisfb_detect_custom_timing(ivideo);
 	}
 
+#ifdef CONFIG_FB_SIS_315
+	if (ivideo->chip = XGI_20) {
+		/* Check if our Z7 chip is actually Z9 */
+		SiS_SetRegOR(SISCR, 0x4a, 0x40);	/* GPIOG EN */
+		reg = SiS_GetReg(SISCR, 0x48);
+		if (reg & 0x02) {			/* GPIOG */
+			ivideo->chip_real_id = XGI_21;
+			dev_info(&pdev->dev, "Z9 detected\n");
+		}
+	}
+#endif
+
 	/* POST card in case this has not been done by the BIOS */
 	if( (!ivideo->sisvga_enabled)
 #if !defined(__i386__) && !defined(__x86_64__)
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 12c0dfa..e3f9976 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -87,6 +87,7 @@ typedef enum _SIS_CHIP_TYPE {
     SIS_341,
     SIS_342,
     XGI_20  = 75,
+    XGI_21,
     XGI_40,
     MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
-- 
1.5.6.5

[PATCH 5/6] sisfb: move XGI POST DDR2 bootup code into subroutines

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:11:55

Move DDR2 register setting code into separate subroutines. No changes
in functionality.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |  139 +++++++++++++++++++++++++-----------------
 1 files changed, 84 insertions(+), 55 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index de03567..9c52d7b 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4941,6 +4941,89 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
 	sisfb_post_xgi_delay(ivideo, 0x43);
 }
 
+static void __devinit
+sisfb_post_xgi_ddr2_mrs_default(struct sis_video_info *ivideo, u8 regb)
+{
+	unsigned char *bios = ivideo->bios_abase;
+	u8 v1;
+
+	SiS_SetReg(SISSR, 0x28, 0x64);
+	SiS_SetReg(SISSR, 0x29, 0x63);
+	sisfb_post_xgi_delay(ivideo, 15);
+	SiS_SetReg(SISSR, 0x18, 0x00);
+	SiS_SetReg(SISSR, 0x19, 0x20);
+	SiS_SetReg(SISSR, 0x16, 0x00);
+	SiS_SetReg(SISSR, 0x16, 0x80);
+	SiS_SetReg(SISSR, 0x18, 0xc5);
+	SiS_SetReg(SISSR, 0x19, 0x23);
+	SiS_SetReg(SISSR, 0x16, 0x00);
+	SiS_SetReg(SISSR, 0x16, 0x80);
+	sisfb_post_xgi_delay(ivideo, 1);
+	SiS_SetReg(SISCR, 0x97, 0x11);
+	sisfb_post_xgi_setclocks(ivideo, regb);
+	sisfb_post_xgi_delay(ivideo, 0x46);
+	SiS_SetReg(SISSR, 0x18, 0xc5);
+	SiS_SetReg(SISSR, 0x19, 0x23);
+	SiS_SetReg(SISSR, 0x16, 0x00);
+	SiS_SetReg(SISSR, 0x16, 0x80);
+	sisfb_post_xgi_delay(ivideo, 1);
+	SiS_SetReg(SISSR, 0x1b, 0x04);
+	sisfb_post_xgi_delay(ivideo, 1);
+	SiS_SetReg(SISSR, 0x1b, 0x00);
+	sisfb_post_xgi_delay(ivideo, 1);
+	v1 = 0x31;
+	if (ivideo->haveXGIROM) {
+		v1 = bios[0xf0];
+	}
+	SiS_SetReg(SISSR, 0x18, v1);
+	SiS_SetReg(SISSR, 0x19, 0x06);
+	SiS_SetReg(SISSR, 0x16, 0x04);
+	SiS_SetReg(SISSR, 0x16, 0x84);
+	sisfb_post_xgi_delay(ivideo, 1);
+}
+
+static void __devinit
+sisfb_post_xgi_ddr2(struct sis_video_info *ivideo, u8 regb)
+{
+	unsigned char *bios = ivideo->bios_abase;
+	static const u8 cs158[8] = {
+		0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	static const u8 cs160[8] = {
+		0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	static const u8 cs168[8] = {
+		0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	u8 reg;
+	u8 v1;
+	u8 v2;
+	u8 v3;
+
+	SiS_SetReg(SISCR, 0x82, 0x77);
+	SiS_SetReg(SISCR, 0x86, 0x00);
+	reg = SiS_GetReg(SISCR, 0x86);
+	SiS_SetReg(SISCR, 0x86, 0x88);
+	reg = SiS_GetReg(SISCR, 0x86);
+	v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
+	if (ivideo->haveXGIROM) {
+		v1 = bios[regb + 0x168];
+		v2 = bios[regb + 0x160];
+		v3 = bios[regb + 0x158];
+	}
+	SiS_SetReg(SISCR, 0x86, v1);
+	SiS_SetReg(SISCR, 0x82, 0x77);
+	SiS_SetReg(SISCR, 0x85, 0x00);
+	reg = SiS_GetReg(SISCR, 0x85);
+	SiS_SetReg(SISCR, 0x85, 0x88);
+	reg = SiS_GetReg(SISCR, 0x85);
+	SiS_SetReg(SISCR, 0x85, v2);
+	SiS_SetReg(SISCR, 0x82, v3);
+	SiS_SetReg(SISCR, 0x98, 0x01);
+	SiS_SetReg(SISCR, 0x9a, 0x02);
+	sisfb_post_xgi_ddr2_default(ivideo, regb);
+}
+
 static u8 __devinit
 sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
 {
@@ -5514,61 +5597,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x1b, 0x00);
 		break;
 	case 1:
-		SiS_SetReg(SISCR, 0x82, 0x77);
-		SiS_SetReg(SISCR, 0x86, 0x00);
-		reg = SiS_GetReg(SISCR, 0x86);
-		SiS_SetReg(SISCR, 0x86, 0x88);
-		reg = SiS_GetReg(SISCR, 0x86);
-		v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
-		if(ivideo->haveXGIROM) {
-			v1 = bios[regb + 0x168];
-			v2 = bios[regb + 0x160];
-			v3 = bios[regb + 0x158];
-		}
-		SiS_SetReg(SISCR, 0x86, v1);
-		SiS_SetReg(SISCR, 0x82, 0x77);
-		SiS_SetReg(SISCR, 0x85, 0x00);
-		reg = SiS_GetReg(SISCR, 0x85);
-		SiS_SetReg(SISCR, 0x85, 0x88);
-		reg = SiS_GetReg(SISCR, 0x85);
-		SiS_SetReg(SISCR, 0x85, v2);
-		SiS_SetReg(SISCR, 0x82, v3);
-		SiS_SetReg(SISCR, 0x98, 0x01);
-		SiS_SetReg(SISCR, 0x9a, 0x02);
-
-		SiS_SetReg(SISSR, 0x28, 0x64);
-		SiS_SetReg(SISSR, 0x29, 0x63);
-		sisfb_post_xgi_delay(ivideo, 15);
-		SiS_SetReg(SISSR, 0x18, 0x00);
-		SiS_SetReg(SISSR, 0x19, 0x20);
-		SiS_SetReg(SISSR, 0x16, 0x00);
-		SiS_SetReg(SISSR, 0x16, 0x80);
-		SiS_SetReg(SISSR, 0x18, 0xc5);
-		SiS_SetReg(SISSR, 0x19, 0x23);
-		SiS_SetReg(SISSR, 0x16, 0x00);
-		SiS_SetReg(SISSR, 0x16, 0x80);
-		sisfb_post_xgi_delay(ivideo, 1);
-		SiS_SetReg(SISCR, 0x97, 0x11);
-		sisfb_post_xgi_setclocks(ivideo, regb);
-		sisfb_post_xgi_delay(ivideo, 0x46);
-		SiS_SetReg(SISSR, 0x18, 0xc5);
-		SiS_SetReg(SISSR, 0x19, 0x23);
-		SiS_SetReg(SISSR, 0x16, 0x00);
-		SiS_SetReg(SISSR, 0x16, 0x80);
-		sisfb_post_xgi_delay(ivideo, 1);
-		SiS_SetReg(SISSR, 0x1b, 0x04);
-		sisfb_post_xgi_delay(ivideo, 1);
-		SiS_SetReg(SISSR, 0x1b, 0x00);
-		sisfb_post_xgi_delay(ivideo, 1);
-		v1 = 0x31;
-		if(ivideo->haveXGIROM) {
-			v1 = bios[0xf0];
-		}
-		SiS_SetReg(SISSR, 0x18, v1);
-		SiS_SetReg(SISSR, 0x19, 0x06);
-		SiS_SetReg(SISSR, 0x16, 0x04);
-		SiS_SetReg(SISSR, 0x16, 0x84);
-		sisfb_post_xgi_delay(ivideo, 1);
+		sisfb_post_xgi_ddr2(ivideo, regb);
 		break;
 	default:
 		sisfb_post_xgi_setclocks(ivideo, regb);
-- 
1.5.6.5

[PATCH 1/6] sisfb: POST should fail if R/W test fails

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:18:13

Currently there is no indication if R/W test fails during POST. This can
happen e.g. when user plugs in a card with unsupported type of memory.
Since the driver will be unusable, it's better to fail the whole POST
if the memory cannot be configured properly.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |   22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a..2c5de66 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info *ivideo, int starta,
 	return 1;
 }
 
-static void __devinit
+static int __devinit
 sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
 {
 	unsigned int buswidth, ranksize, channelab, mapsize;
-	int i, j, k, l;
+	int i, j, k, l, status;
 	u8 reg, sr14;
 	static const u8 dramsr13[12 * 5] = {
 		0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
 		SiS_SetReg(SISSR, 0x13, 0x35);
 		SiS_SetReg(SISSR, 0x14, 0x41);
 		/* TODO */
-		return;
+		return -ENOMEM;
 	}
 
 	/* Non-interleaving */
@@ -4835,6 +4835,7 @@ bail_out:
 
 	j = (ivideo->chip = XGI_20) ? 5 : 9;
 	k = (ivideo->chip = XGI_20) ? 12 : 4;
+	status = -EIO;
 
 	for(i = 0; i < k; i++) {
 
@@ -4868,11 +4869,15 @@ bail_out:
 		SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
 		sisfb_post_xgi_delay(ivideo, 1);
 
-		if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize))
+		if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
+			status = 0;
 			break;
+		}
 	}
 
 	iounmap(ivideo->video_vbase);
+
+	return status;
 }
 
 static void __devinit
@@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);
 
 	} else {
+		int err;
 
 		/* Set default mode, don't clear screen */
 		ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)
 
 		/* Disable read-cache */
 		SiS_SetRegAND(SISSR, 0x21, 0xdf);
-		sisfb_post_xgi_ramsize(ivideo);
+		err = sisfb_post_xgi_ramsize(ivideo);
 		/* Enable read-cache */
 		SiS_SetRegOR(SISSR, 0x21, 0x20);
 
+		if (err) {
+			dev_err(&pdev->dev,
+				"%s: RAM size detection failed: %d\n",
+				__func__, err);
+			return 0;
+		}
 	}
 
 #if 0
-- 
1.5.6.5

RE: [PATCH 1/6] sisfb: POST should fail if R/W test fails

From: Janorkar, Mayuresh <hidden>
Date: 2011-02-14 06:08:41

quoted hunk
-----Original Message-----
From: linux-fbdev-owner@vger.kernel.org [mailto:linux-fbdev-
owner@vger.kernel.org] On Behalf Of Aaro Koskinen
Sent: Monday, February 14, 2011 3:41 AM
To: linux-fbdev@vger.kernel.org; linux-kernel@vger.kernel.org
Cc: Thomas Winischhofer
Subject: [PATCH 1/6] sisfb: POST should fail if R/W test fails

Currently there is no indication if R/W test fails during POST. This can
happen e.g. when user plugs in a card with unsupported type of memory.
Since the driver will be unusable, it's better to fail the whole POST
if the memory cannot be configured properly.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |   22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a..2c5de66 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info
*ivideo, int starta,
 	return 1;
 }

-static void __devinit
+static int __devinit
 sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
 {
 	unsigned int buswidth, ranksize, channelab, mapsize;
-	int i, j, k, l;
+	int i, j, k, l, status;
 	u8 reg, sr14;
 	static const u8 dramsr13[12 * 5] = {
 		0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info
*ivideo)
 		SiS_SetReg(SISSR, 0x13, 0x35);
 		SiS_SetReg(SISSR, 0x14, 0x41);
 		/* TODO */
-		return;
+		return -ENOMEM;
 	}

 	/* Non-interleaving */
@@ -4835,6 +4835,7 @@ bail_out:

 	j = (ivideo->chip = XGI_20) ? 5 : 9;
 	k = (ivideo->chip = XGI_20) ? 12 : 4;
+	status = -EIO;
How about assigning this value during variable declaration?
quoted hunk
 	for(i = 0; i < k; i++) {
@@ -4868,11 +4869,15 @@ bail_out:
 		SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
 		sisfb_post_xgi_delay(ivideo, 1);

-		if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
2 + 20), mapsize))
+		if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
2 + 20), mapsize)) {
+			status = 0;
 			break;
+		}
 	}

 	iounmap(ivideo->video_vbase);
+
+	return status;
 }

 static void __devinit
@@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);

 	} else {
+		int err;

 		/* Set default mode, don't clear screen */
 		ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)

 		/* Disable read-cache */
 		SiS_SetRegAND(SISSR, 0x21, 0xdf);
-		sisfb_post_xgi_ramsize(ivideo);
+		err = sisfb_post_xgi_ramsize(ivideo);
 		/* Enable read-cache */
 		SiS_SetRegOR(SISSR, 0x21, 0x20);

+		if (err) {
+			dev_err(&pdev->dev,
+				"%s: RAM size detection failed: %d\n",
+				__func__, err);
+			return 0;

Are you sure you wish to return 0 when there is an error?
+		}
 	}

 #if 0
--
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH 1/6] sisfb: POST should fail if R/W test fails

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-14 19:01:56

Hi,

On Mon, 14 Feb 2011, Janorkar, Mayuresh wrote:
quoted
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2fb8c5a..2c5de66 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4627,11 +4627,11 @@ sisfb_post_xgi_rwtest(struct sis_video_info
*ivideo, int starta,
 	return 1;
 }

-static void __devinit
+static int __devinit
 sisfb_post_xgi_ramsize(struct sis_video_info *ivideo)
 {
 	unsigned int buswidth, ranksize, channelab, mapsize;
-	int i, j, k, l;
+	int i, j, k, l, status;
 	u8 reg, sr14;
 	static const u8 dramsr13[12 * 5] = {
 		0x02, 0x0e, 0x0b, 0x80, 0x5d,
@@ -4673,7 +4673,7 @@ sisfb_post_xgi_ramsize(struct sis_video_info
*ivideo)
 		SiS_SetReg(SISSR, 0x13, 0x35);
 		SiS_SetReg(SISSR, 0x14, 0x41);
 		/* TODO */
-		return;
+		return -ENOMEM;
 	}

 	/* Non-interleaving */
@@ -4835,6 +4835,7 @@ bail_out:

 	j = (ivideo->chip = XGI_20) ? 5 : 9;
 	k = (ivideo->chip = XGI_20) ? 12 : 4;
+	status = -EIO;
How about assigning this value during variable declaration?
Yes, that can be done.
quoted
 	for(i = 0; i < k; i++) {
@@ -4868,11 +4869,15 @@ bail_out:
 		SiS_SetRegANDOR(SISSR, 0x14, 0x0f, (reg & 0xf0));
 		sisfb_post_xgi_delay(ivideo, 1);

-		if(sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
2 + 20), mapsize))
+		if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab -
2 + 20), mapsize)) {
+			status = 0;
 			break;
+		}
 	}

 	iounmap(ivideo->video_vbase);
+
+	return status;
 }

 static void __devinit
@@ -5648,6 +5653,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x14, bios[regb + 0xe0 + 8]);

 	} else {
+		int err;

 		/* Set default mode, don't clear screen */
 		ivideo->SiS_Pr.SiS_UseOEM = false;
@@ -5661,10 +5667,16 @@ sisfb_post_xgi(struct pci_dev *pdev)

 		/* Disable read-cache */
 		SiS_SetRegAND(SISSR, 0x21, 0xdf);
-		sisfb_post_xgi_ramsize(ivideo);
+		err = sisfb_post_xgi_ramsize(ivideo);
 		/* Enable read-cache */
 		SiS_SetRegOR(SISSR, 0x21, 0x20);

+		if (err) {
+			dev_err(&pdev->dev,
+				"%s: RAM size detection failed: %d\n",
+				__func__, err);
+			return 0;

Are you sure you wish to return 0 when there is an error?
sisfb_post_xgi() returns zero on failure.

A.

[PATCH 2/6] sisfb: move XGI POST RAM type detection into a subroutine

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:18:20

Move XGI POST RAM type detection into a separate subroutine to make
further code changes easier. No changes in functionality

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |   57 +++++++++++++++++++++++++----------------
 1 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 2c5de66..364559b 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4936,6 +4936,40 @@ sisfb_post_xgi_setclocks(struct sis_video_info *ivideo, u8 regb)
 	sisfb_post_xgi_delay(ivideo, 0x43);
 }
 
+static u8 __devinit
+sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
+{
+	unsigned char *bios = ivideo->bios_abase;
+	u8 ramtype;
+	u8 reg;
+	u8 v1;
+
+	ramtype = 0x00; v1 = 0x10;
+	if (ivideo->haveXGIROM) {
+		ramtype = bios[0x62];
+		v1 = bios[0x1d2];
+	}
+	if (!(ramtype & 0x80)) {
+		if (ivideo->chip = XGI_20) {
+			SiS_SetReg(SISCR, 0x97, v1);
+			reg = SiS_GetReg(SISCR, 0x97);
+			if (reg & 0x10) {
+				ramtype = (reg & 0x01) << 1;
+			}
+		} else {
+			reg = SiS_GetReg(SISSR, 0x39);
+			ramtype = reg & 0x02;
+			if (!(ramtype)) {
+				reg = SiS_GetReg(SISSR, 0x3a);
+				ramtype = (reg >> 1) & 0x01;
+			}
+		}
+	}
+	ramtype &= 0x07;
+
+	return ramtype;
+}
+
 static int __devinit
 sisfb_post_xgi(struct pci_dev *pdev)
 {
@@ -5380,28 +5414,7 @@ sisfb_post_xgi(struct pci_dev *pdev)
 		SiS_SetReg(SISSR, 0x1c, 0x00);
 	}
 
-	ramtype = 0x00; v1 = 0x10;
-	if(ivideo->haveXGIROM) {
-		ramtype = bios[0x62];
-		v1 = bios[0x1d2];
-	}
-	if(!(ramtype & 0x80)) {
-		if(ivideo->chip = XGI_20) {
-			SiS_SetReg(SISCR, 0x97, v1);
-			reg = SiS_GetReg(SISCR, 0x97);
-			if(reg & 0x10) {
-				ramtype = (reg & 0x01) << 1;
-			}
-		} else {
-			reg = SiS_GetReg(SISSR, 0x39);
-			ramtype = reg & 0x02;
-			if(!(ramtype)) {
-				reg = SiS_GetReg(SISSR, 0x3a);
-				ramtype = (reg >> 1) & 0x01;
-			}
-		}
-	}
-	ramtype &= 0x07;
+	ramtype = sisfb_post_xgi_ramtype(ivideo);
 
 	regb = 0;	/* ! */
 
-- 
1.5.6.5

[PATCH 4/6] sisfb: add RAM type detection for XGI Z9

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-13 22:20:12

Detect the XGI Z9 RAM type as "documented" by the XGI's xgifb driver.

Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
---
 drivers/video/sis/sis_main.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index f0c48e8..de03567 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -4955,7 +4955,13 @@ sisfb_post_xgi_ramtype(struct sis_video_info *ivideo)
 		v1 = bios[0x1d2];
 	}
 	if (!(ramtype & 0x80)) {
-		if (ivideo->chip = XGI_20) {
+		if (sisfb_xgi_is21(ivideo)) {
+			SiS_SetRegAND(SISCR, 0xb4, 0xfd); /* GPIO control */
+			SiS_SetRegOR(SISCR, 0x4a, 0x80);  /* GPIOH EN */
+			reg = SiS_GetReg(SISCR, 0x48);
+			SiS_SetRegOR(SISCR, 0xb4, 0x02);
+			ramtype = reg & 0x01;		  /* GPIOH */
+		} else if (ivideo->chip = XGI_20) {
 			SiS_SetReg(SISCR, 0x97, v1);
 			reg = SiS_GetReg(SISCR, 0x97);
 			if (reg & 0x10) {
-- 
1.5.6.5

Re: [PATCH 0/6] sisfb: XGI Z9 POST

From: Aaro Koskinen <aaro.koskinen@iki.fi>
Date: 2011-02-16 17:41:47

Hi,

On Mon, 14 Feb 2011, Aaro Koskinen wrote:
Here's some patches to get POST working with XGI Z9. I have tested them
with the following card:

	http://www.roboard.com/Files/RB-100/MiniPCI-VGA-Z9s_UM_v1r1A.pdf

I'm using the card on an ARM board where the bootloader knows nothing
about VGA or VGA BIOS, so having POST support in the kernel driver
is mandatory. With these patches the memory size is correct detected,
R/W test passes and it's possible to use e.g. framebuffer console.

Aaro Koskinen (6):
 sisfb: POST should fail if R/W test fails
 sisfb: move XGI POST RAM type detection into a subroutine
 sisfb: add subroutine for detecting XGI Z9
 sisfb: add RAM type detection for XGI Z9
 sisfb: move XGI POST DDR2 bootup code into subroutines
 sisfb: add support for XGI Z9 DDR2 POST
Hmm, I think these patches can be ignored, at least for a while.

I realized that xgifb driver is now in staging, and it has much wider
support for XGI chips. So, we should work on getting that driver into
an acceptable form. And after that, it should be even possible to drop
XGI support from sisfb.

A.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help