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(-)
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 <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
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 <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
Move DDR2 register setting code into separate subroutines. No changes
in functionality.
Signed-off-by: Aaro Koskinen <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
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 <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
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 <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
Detect the XGI Z9 RAM type as "documented" by the XGI's xgifb driver.
Signed-off-by: Aaro Koskinen <[email protected]>
Cc: Thomas Winischhofer <[email protected]>
---
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
> -----Original Message-----
> From: [email protected] [mailto:linux-fbdev-
> [email protected]] On Behalf Of Aaro Koskinen
> Sent: Monday, February 14, 2011 3:41 AM
> To: [email protected]; [email protected]
> 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 <[email protected]>
> Cc: Thomas Winischhofer <[email protected]>
> ---
> 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?
>
> 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 [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi,
On Mon, 14 Feb 2011, Janorkar, Mayuresh wrote:
>> 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.
>>
>> 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.
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.