2019-03-16 22:26:15

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 0/8] fbdev: sm712fb: fix a series of lockups, crashes and gliches.

Hi all,

This patchset contains a series of important fixes to various problems,
including lockups, crashes, screen gliches, and missing video modes.
These patches are crucial to the correct operation to the hardware,
especially Lynx3DM+ (SM720). I have tested and verified them on x86.

Please review and queue them for linux-stable.

Thanks,

Yifeng Li (8):
fbdev: sm712fb: fix white screen of death on reboot, don't set
CR3B-CR3F.
fbdev: sm712fb: fix brightness control on reboot, don't set SR30.
fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75.
fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA.
fbdev: sm712fb: fix crashes during framebuffer writes by correctly
mapping VRAM.
fbdev: sm712fb: fix crashes and garbled display during DPMS
modesetting.
fbdev: sm712fb: fix support for 1024x768-16 mode.
fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled
display.

drivers/video/fbdev/sm712.h | 12 +-
drivers/video/fbdev/sm712fb.c | 244 +++++++++++++++++++++++++++-------
2 files changed, 200 insertions(+), 56 deletions(-)

--
2.20.1



2019-03-16 22:26:17

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 1/8] fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F.

On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with
sm712fb framebuffer driver would cause a white screen of death on
the next POST, presumably the proper timings for the LCD panel was
not reprogrammed properly by the BIOS.

Experiments showed a few CRTC Scratch Registers, including CRT3D,
CRT3E and CRT3F may be used internally by BIOS as some flags. CRT3B is
a hardware testing register, we shouldn't mess with it. CRT3C has
blanking signal and line compare control, which is not needed for this
driver.

Stop writing to CR3B-CR3F (a.k.a CRT3B-CRT3F) registers. Even if these
registers don't have side-effect on other systems, writing to them is
also highly questionable.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 502d0de2feec..d05379affa32 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1171,8 +1171,12 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]);

/* init CRTC register CR30 - CR4D */
- for (i = 0; i < SIZE_CR30_CR4D; i++)
+ for (i = 0; i < SIZE_CR30_CR4D; i++) {
+ if ((i + 0x30) >= 0x3B && (i + 0x30) <= 0x3F)
+ /* side-effect, don't write to CR3B-CR3F */
+ continue;
smtc_crtcw(i + 0x30, vgamode[j].init_cr30_cr4d[i]);
+ }

/* init CRTC register CR90 - CRA7 */
for (i = 0; i < SIZE_CR90_CRA7; i++)
--
2.20.1


2019-03-16 22:26:27

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 2/8] fbdev: sm712fb: fix brightness control on reboot, don't set SR30.

On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with
sm712fb framebuffer driver would cause the role of brightness up/down
button to swap.

Experiments showed the FPR30 register caused this behavior. Moreover,
even if this register don't have side-effect on other systems, over-
writing it is also highly questionable, since it was originally
configurated by the motherboard manufacturer by hardwiring pull-down
resistors to indicate the type of LCD panel. We should not mess with
it.

Stop writing to the SR30 (a.k.a FPR30) register.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index d05379affa32..a19655babf67 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1145,8 +1145,8 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)

/* init SEQ register SR30 - SR75 */
for (i = 0; i < SIZE_SR30_SR75; i++)
- if ((i + 0x30) != 0x62 && (i + 0x30) != 0x6a &&
- (i + 0x30) != 0x6b)
+ if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 &&
+ (i + 0x30) != 0x6a && (i + 0x30) != 0x6b)
smtc_seqw(i + 0x30,
vgamode[j].init_sr30_sr75[i]);

--
2.20.1


2019-03-16 22:26:35

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 3/8] fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75.

On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), the amount of Video
RAM is not detected correctly by the xf86-video-siliconmotion driver.
This is because sm712fb overwrites the GPR71 Scratch Pad Register, which
is set by BIOS on x86 and used to indicate amount of VRAM.

Other Scratch Pad Registers, including GPR70/74/75, don't have the same
side-effect, but overwriting to them is still questionable, as they are
not related to modesetting.

Stop writing to SR70/71/74/75 (a.k.a GPR70/71/74/75).

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index a19655babf67..1a3d232c2916 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1146,7 +1146,9 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
/* init SEQ register SR30 - SR75 */
for (i = 0; i < SIZE_SR30_SR75; i++)
if ((i + 0x30) != 0x30 && (i + 0x30) != 0x62 &&
- (i + 0x30) != 0x6a && (i + 0x30) != 0x6b)
+ (i + 0x30) != 0x6a && (i + 0x30) != 0x6b &&
+ (i + 0x30) != 0x70 && (i + 0x30) != 0x71 &&
+ (i + 0x30) != 0x74 && (i + 0x30) != 0x75)
smtc_seqw(i + 0x30,
vgamode[j].init_sr30_sr75[i]);

--
2.20.1


2019-03-16 22:26:45

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 4/8] fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA.

When the machine is booted in VGA mode, loading sm712fb would cause
a glitch of random pixels shown on the screen. To prevent it from
happening, we first clear the entire framebuffer, and we also need
to stop calling smtcfb_setmode() during initialization, the fbdev
layer will call it for us later when it's ready.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 1a3d232c2916..e8149f0f47d5 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1493,7 +1493,11 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
if (err)
goto failed;

- smtcfb_setmode(sfb);
+ /*
+ * The screen would be temporarily garbled when sm712fb takes over
+ * vesafb or VGA text mode. Zero the framebuffer.
+ */
+ memset_io(sfb->lfb, 0, sfb->fb->fix.smem_len);

err = register_framebuffer(info);
if (err < 0)
--
2.20.1


2019-03-16 22:26:53

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 5/8] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM.

On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), running fbtest or X
will crash the machine instantly, because the VRAM/framebuffer is not
mapped correctly.

On SM712, the framebuffer starts at the beginning of address space, but
SM720's framebuffer starts at the 1 MiB offset from the beginning. However,
sm712fb fails to take this into account, as a result, writing to the
framebuffer will destroy all the registers and kill the system immediately.
Another problem is the driver assumes 8 MiB of VRAM for SM720, but some
SM720 system, such as this IBM Thinkpad, only has 4 MiB of VRAM.

Fix this problem by removing the hardcoded VRAM size, adding a function to
query the amount of VRAM from register MCR76 on SM720, and adding proper
framebuffer offset.

Please note that the memory map may have additional problems on Big-Endian
system, which is not available for testing by myself. But I highly suspect
that the original code is also broken on Big-Endian machines for SM720, so
at least we are not making the problem worse. More, the driver also assumed
SM710/SM712 has 4 MiB of VRAM, but it has a 2 MiB version as well, and used
in earlier laptops, such as IBM Thinkpad 240X, the driver would probably
crash on them. I've never seen one of those machines and cannot fix it, but
I have documented these problems in the comments.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712.h | 5 ----
drivers/video/fbdev/sm712fb.c | 48 ++++++++++++++++++++++++++++++++---
2 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/video/fbdev/sm712.h b/drivers/video/fbdev/sm712.h
index aad1cc4be34a..2cba1e73ed24 100644
--- a/drivers/video/fbdev/sm712.h
+++ b/drivers/video/fbdev/sm712.h
@@ -19,11 +19,6 @@
#define SCREEN_Y_RES 600
#define SCREEN_BPP 16

-/*Assume SM712 graphics chip has 4MB VRAM */
-#define SM712_VIDEOMEMORYSIZE 0x00400000
-/*Assume SM722 graphics chip has 8MB VRAM */
-#define SM722_VIDEOMEMORYSIZE 0x00800000
-
#define dac_reg (0x3c8)
#define dac_val (0x3c9)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index e8149f0f47d5..52234c57be02 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1329,6 +1329,11 @@ static int smtc_map_smem(struct smtcfb_info *sfb,
{
sfb->fb->fix.smem_start = pci_resource_start(pdev, 0);

+ if (sfb->chip_id == 0x720)
+ /* on SM720, the framebuffer starts at the 1 MB offset */
+ sfb->fb->fix.smem_start += 0x00200000;
+
+ /* XXX: is it safe for SM720 on Big-Endian? */
if (sfb->fb->var.bits_per_pixel == 32)
sfb->fb->fix.smem_start += big_addr;

@@ -1366,12 +1371,45 @@ static inline void sm7xx_init_hw(void)
outb_p(0x11, 0x3c5);
}

+static u_long sm7xx_vram_probe(struct smtcfb_info *sfb)
+{
+ u8 vram;
+
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ /*
+ * Assume SM712 graphics chip has 4MB VRAM.
+ *
+ * FIXME: SM712 can have 2MB VRAM, which is used on earlier
+ * laptops, such as IBM Thinkpad 240X. This driver would
+ * probably crash on those machines. If anyone gets one of
+ * those and is willing to help, run "git blame" and send me
+ * an E-mail.
+ */
+ return 0x00400000;
+ case 0x720:
+ outb_p(0x76, 0x3c4);
+ vram = inb_p(0x3c5) >> 6;
+
+ if (vram == 0x00)
+ return 0x00800000; /* 8 MB */
+ else if (vram == 0x01)
+ return 0x01000000; /* 16 MB */
+ else if (vram == 0x02)
+ return 0x00400000; /* illegal, fallback to 4 MB */
+ else if (vram == 0x03)
+ return 0x00400000; /* 4 MB */
+ }
+ return 0; /* unknown hardware */
+}
+
static int smtcfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct smtcfb_info *sfb;
struct fb_info *info;
- u_long smem_size = 0x00800000; /* default 8MB */
+ u_long smem_size;
int err;
unsigned long mmio_base;

@@ -1428,12 +1466,15 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
mmio_base = pci_resource_start(pdev, 0);
pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);

+ smem_size = sm7xx_vram_probe(sfb);
+ dev_info(&pdev->dev, "%lu MiB of VRAM detected.\n",
+ smem_size / 1048576);
+
switch (sfb->chip_id) {
case 0x710:
case 0x712:
sfb->fb->fix.mmio_start = mmio_base + 0x00400000;
sfb->fb->fix.mmio_len = 0x00400000;
- smem_size = SM712_VIDEOMEMORYSIZE;
sfb->lfb = ioremap(mmio_base, mmio_addr);
if (!sfb->lfb) {
dev_err(&pdev->dev,
@@ -1465,8 +1506,7 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
case 0x720:
sfb->fb->fix.mmio_start = mmio_base;
sfb->fb->fix.mmio_len = 0x00200000;
- smem_size = SM722_VIDEOMEMORYSIZE;
- sfb->dp_regs = ioremap(mmio_base, 0x00a00000);
+ sfb->dp_regs = ioremap(mmio_base, 0x00200000 + smem_size);
sfb->lfb = sfb->dp_regs + 0x00200000;
sfb->mmio = (smtc_regbaseaddress =
sfb->dp_regs + 0x000c0000);
--
2.20.1


2019-03-16 22:27:35

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 8/8] fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display.

Loongson MIPS netbooks use 1024x600 LCD panels, which is the original
target platform of this driver, but nearly all old x86 laptops have
1024x768. Lighting 768 panels using 600's timings would partially
garble the display. Since it's not possible to distinguish them reliably,
we change the default to 768, but keep 600 as-is on MIPS.

Further, earlier laptops, such as IBM Thinkpad 240X, has a 800x600 LCD
panel, this driver would probably garbled those display. As we don't
have one for testing, the original behavior of the driver is kept as-is,
but the problem has been documented is the comments.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712.h | 7 +++--
drivers/video/fbdev/sm712fb.c | 53 ++++++++++++++++++++++++++---------
2 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/video/fbdev/sm712.h b/drivers/video/fbdev/sm712.h
index 2cba1e73ed24..c7ebf03b8d53 100644
--- a/drivers/video/fbdev/sm712.h
+++ b/drivers/video/fbdev/sm712.h
@@ -15,9 +15,10 @@

#define FB_ACCEL_SMI_LYNX 88

-#define SCREEN_X_RES 1024
-#define SCREEN_Y_RES 600
-#define SCREEN_BPP 16
+#define SCREEN_X_RES 1024
+#define SCREEN_Y_RES_PC 768
+#define SCREEN_Y_RES_NETBOOK 600
+#define SCREEN_BPP 16

#define dac_reg (0x3c8)
#define dac_val (0x3c9)
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index c39a2641182a..1e2503b52c6f 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1475,6 +1475,43 @@ static u_long sm7xx_vram_probe(struct smtcfb_info *sfb)
return 0; /* unknown hardware */
}

+static void sm7xx_resolution_probe(struct smtcfb_info *sfb)
+{
+ /* get mode parameter from smtc_scr_info */
+ if (smtc_scr_info.lfb_width != 0) {
+ sfb->fb->var.xres = smtc_scr_info.lfb_width;
+ sfb->fb->var.yres = smtc_scr_info.lfb_height;
+ sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth;
+ goto final;
+ }
+
+ /*
+ * No parameter, default resolution is 1024x768-16.
+ *
+ * FIXME: earlier laptops, such as IBM Thinkpad 240X, has a 800x600
+ * panel, also see the comments about Thinkpad 240X above.
+ */
+ sfb->fb->var.xres = SCREEN_X_RES;
+ sfb->fb->var.yres = SCREEN_Y_RES_PC;
+ sfb->fb->var.bits_per_pixel = SCREEN_BPP;
+
+#ifdef CONFIG_MIPS
+ /*
+ * Loongson MIPS netbooks use 1024x600 LCD panels, which is the original
+ * target platform of this driver, but nearly all old x86 laptops have
+ * 1024x768. Lighting 768 panels using 600's timings would partially
+ * garble the display, so we don't want that. But it's not possible to
+ * distinguish them reliably.
+ *
+ * So we change the default to 768, but keep 600 as-is on MIPS.
+ */
+ sfb->fb->var.yres = SCREEN_Y_RES_NETBOOK;
+#endif
+
+final:
+ big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth);
+}
+
static int smtcfb_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1520,19 +1557,6 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,

sm7xx_init_hw();

- /* get mode parameter from smtc_scr_info */
- if (smtc_scr_info.lfb_width != 0) {
- sfb->fb->var.xres = smtc_scr_info.lfb_width;
- sfb->fb->var.yres = smtc_scr_info.lfb_height;
- sfb->fb->var.bits_per_pixel = smtc_scr_info.lfb_depth;
- } else {
- /* default resolution 1024x600 16bit mode */
- sfb->fb->var.xres = SCREEN_X_RES;
- sfb->fb->var.yres = SCREEN_Y_RES;
- sfb->fb->var.bits_per_pixel = SCREEN_BPP;
- }
-
- big_pixel_depth(sfb->fb->var.bits_per_pixel, smtc_scr_info.lfb_depth);
/* Map address and memory detection */
mmio_base = pci_resource_start(pdev, 0);
pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);
@@ -1594,6 +1618,9 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
goto failed_fb;
}

+ /* probe and decide resolution */
+ sm7xx_resolution_probe(sfb);
+
/* can support 32 bpp */
if (sfb->fb->var.bits_per_pixel == 15)
sfb->fb->var.bits_per_pixel = 16;
--
2.20.1


2019-03-16 22:27:42

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 6/8] fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting.

On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), blanking the display
or starting the X server will crash and freeze the system, or garble the
display.

Experiments showed this problem can mostly be solved by adjusting the
order of register writes. Also, sm712fb failed to consider the difference
of clock frequency when unblanking the display, and programs the clock for
SM712 to SM720.

Fix them by adjusting the order of register writes, and adding an
additional check for SM720 for programming the clock frequency.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 64 +++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 26 deletions(-)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 52234c57be02..a40d0ae7cb66 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -827,67 +827,79 @@ static inline unsigned int chan_to_field(unsigned int chan,

static int smtc_blank(int blank_mode, struct fb_info *info)
{
+ struct smtcfb_info *sfb = info->par;
+
/* clear DPMS setting */
switch (blank_mode) {
case FB_BLANK_UNBLANK:
/* Screen On: HSync: On, VSync : On */
+
+ switch (sfb->chip_id) {
+ case 0x710:
+ case 0x712:
+ smtc_seqw(0x6a, 0x16);
+ smtc_seqw(0x6b, 0x02);
+ case 0x720:
+ smtc_seqw(0x6a, 0x0d);
+ smtc_seqw(0x6b, 0x02);
+ break;
+ }
+
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
- smtc_seqw(0x6a, 0x16);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
break;
case FB_BLANK_NORMAL:
/* Screen Off: HSync: On, VSync : On Soft blank */
+ smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+ smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
smtc_seqw(0x6a, 0x16);
smtc_seqw(0x6b, 0x02);
- smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
- smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
- smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
break;
case FB_BLANK_VSYNC_SUSPEND:
/* Screen On: HSync: On, VSync : Off */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
case FB_BLANK_HSYNC_SUSPEND:
/* Screen On: HSync: Off, VSync : On */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
case FB_BLANK_POWERDOWN:
/* Screen On: HSync: Off, VSync : Off */
+ smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+ smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+ smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
- smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
- smtc_seqw(0x6a, 0x0c);
- smtc_seqw(0x6b, 0x02);
smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+ smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
- smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
- smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
- smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+ smtc_seqw(0x6a, 0x0c);
+ smtc_seqw(0x6b, 0x02);
break;
default:
return -EINVAL;
--
2.20.1


2019-03-16 22:28:42

by Yifeng Li

[permalink] [raw]
Subject: [PATCH 7/8] fbdev: sm712fb: fix support for 1024x768-16 mode.

In order to support the 1024x600 panel on Yeeloong Loongson MIPS
laptop, the original 1024x768-16 table was modified to 1024x600-16,
without leaving the original. It causes problem on x86 laptop as
the 1024x768-16 support was still claimed but not working.

Fix it by introducing the 1024x768-16 mode.

Signed-off-by: Yifeng Li <[email protected]>
Cc: [email protected] # v4.4+
---
drivers/video/fbdev/sm712fb.c | 59 +++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)

diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index a40d0ae7cb66..c39a2641182a 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -530,6 +530,65 @@ static const struct modeinit vgamode[] = {
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
},
},
+ { /* 1024 x 768 16Bpp 60Hz */
+ 1024, 768, 16, 60,
+ /* Init_MISC */
+ 0xEB,
+ { /* Init_SR0_SR4 */
+ 0x03, 0x01, 0x0F, 0x03, 0x0E,
+ },
+ { /* Init_SR10_SR24 */
+ 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+ 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC4, 0x30, 0x02, 0x01, 0x01,
+ },
+ { /* Init_SR30_SR75 */
+ 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+ 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+ 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+ 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+ 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+ 0x0F, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+ 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+ 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+ 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+ },
+ { /* Init_SR80_SR93 */
+ 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+ 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+ 0x00, 0x00, 0x00, 0x00,
+ },
+ { /* Init_SRA0_SRAF */
+ 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+ 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+ },
+ { /* Init_GR00_GR08 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ },
+ { /* Init_AR00_AR14 */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00,
+ },
+ { /* Init_CR00_CR18 */
+ 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+ 0xFF,
+ },
+ { /* Init_CR30_CR4D */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+ 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+ 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+ },
+ { /* Init_CR90_CRA7 */
+ 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+ 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+ },
+ },
{ /* mode#5: 1024 x 768 24Bpp 60Hz */
1024, 768, 24, 60,
/* Init_MISC */
--
2.20.1


2019-03-24 21:40:15

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 5/8] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM.

Hi Teddy,

On Sun, Mar 17, 2019 at 06:25:01AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), running fbtest or X
> will crash the machine instantly, because the VRAM/framebuffer is not
> mapped correctly.
>
> On SM712, the framebuffer starts at the beginning of address space, but
> SM720's framebuffer starts at the 1 MiB offset from the beginning. However,
> sm712fb fails to take this into account, as a result, writing to the
> framebuffer will destroy all the registers and kill the system immediately.
> Another problem is the driver assumes 8 MiB of VRAM for SM720, but some
> SM720 system, such as this IBM Thinkpad, only has 4 MiB of VRAM.
>
> Fix this problem by removing the hardcoded VRAM size, adding a function to
> query the amount of VRAM from register MCR76 on SM720, and adding proper
> framebuffer offset.
>
> Please note that the memory map may have additional problems on Big-Endian
> system, which is not available for testing by myself. But I highly suspect
> that the original code is also broken on Big-Endian machines for SM720, so
> at least we are not making the problem worse. More, the driver also assumed
> SM710/SM712 has 4 MiB of VRAM, but it has a 2 MiB version as well, and used
> in earlier laptops, such as IBM Thinkpad 240X, the driver would probably
> crash on them. I've never seen one of those machines and cannot fix it, but
> I have documented these problems in the comments.

I only have access to SM712 and I am testing this series on it. Can you please
test them on SM710, SM720 and also on big-endian machine, specially the patches
from 5 to 8.

--
Regards
Sudip

2019-03-31 12:21:17

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 0/8] fbdev: sm712fb: fix a series of lockups, crashes and gliches.

On Sun, Mar 17, 2019 at 06:24:56AM +0800, Yifeng Li wrote:
> Hi all,
>
> This patchset contains a series of important fixes to various problems,
> including lockups, crashes, screen gliches, and missing video modes.
> These patches are crucial to the correct operation to the hardware,
> especially Lynx3DM+ (SM720). I have tested and verified them on x86.
>
> Please review and queue them for linux-stable.

Thanks for the changes.
Verified the register changes from the datasheet and also tested the full
series (separate test for individual patches) with SM712 on little endian
for any regression.

--
Regards
Sudip

2019-03-31 12:21:17

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 3/8] fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75.

On Sun, Mar 17, 2019 at 06:24:59AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), the amount of Video
> RAM is not detected correctly by the xf86-video-siliconmotion driver.
> This is because sm712fb overwrites the GPR71 Scratch Pad Register, which
> is set by BIOS on x86 and used to indicate amount of VRAM.
>
> Other Scratch Pad Registers, including GPR70/74/75, don't have the same
> side-effect, but overwriting to them is still questionable, as they are
> not related to modesetting.
>
> Stop writing to SR70/71/74/75 (a.k.a GPR70/71/74/75).
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:21:17

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 4/8] fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA.

On Sun, Mar 17, 2019 at 06:25:00AM +0800, Yifeng Li wrote:
> When the machine is booted in VGA mode, loading sm712fb would cause
> a glitch of random pixels shown on the screen. To prevent it from
> happening, we first clear the entire framebuffer, and we also need
> to stop calling smtcfb_setmode() during initialization, the fbdev
> layer will call it for us later when it's ready.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:21:56

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 5/8] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM.

On Sun, Mar 17, 2019 at 06:25:01AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), running fbtest or X
> will crash the machine instantly, because the VRAM/framebuffer is not
> mapped correctly.
>
> On SM712, the framebuffer starts at the beginning of address space, but
> SM720's framebuffer starts at the 1 MiB offset from the beginning. However,
> sm712fb fails to take this into account, as a result, writing to the
> framebuffer will destroy all the registers and kill the system immediately.
> Another problem is the driver assumes 8 MiB of VRAM for SM720, but some
> SM720 system, such as this IBM Thinkpad, only has 4 MiB of VRAM.
>
> Fix this problem by removing the hardcoded VRAM size, adding a function to
> query the amount of VRAM from register MCR76 on SM720, and adding proper
> framebuffer offset.
>
> Please note that the memory map may have additional problems on Big-Endian
> system, which is not available for testing by myself. But I highly suspect
> that the original code is also broken on Big-Endian machines for SM720, so
> at least we are not making the problem worse. More, the driver also assumed
> SM710/SM712 has 4 MiB of VRAM, but it has a 2 MiB version as well, and used
> in earlier laptops, such as IBM Thinkpad 240X, the driver would probably
> crash on them. I've never seen one of those machines and cannot fix it, but
> I have documented these problems in the comments.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:22:41

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 2/8] fbdev: sm712fb: fix brightness control on reboot, don't set SR30.

On Sun, Mar 17, 2019 at 06:24:58AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with
> sm712fb framebuffer driver would cause the role of brightness up/down
> button to swap.
>
> Experiments showed the FPR30 register caused this behavior. Moreover,
> even if this register don't have side-effect on other systems, over-
> writing it is also highly questionable, since it was originally
> configurated by the motherboard manufacturer by hardwiring pull-down
> resistors to indicate the type of LCD panel. We should not mess with
> it.
>
> Stop writing to the SR30 (a.k.a FPR30) register.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:22:54

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 7/8] fbdev: sm712fb: fix support for 1024x768-16 mode.

On Sun, Mar 17, 2019 at 06:25:03AM +0800, Yifeng Li wrote:
> In order to support the 1024x600 panel on Yeeloong Loongson MIPS
> laptop, the original 1024x768-16 table was modified to 1024x600-16,
> without leaving the original. It causes problem on x86 laptop as
> the 1024x768-16 support was still claimed but not working.
>
> Fix it by introducing the 1024x768-16 mode.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:23:04

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 8/8] fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display.

On Sun, Mar 17, 2019 at 06:25:04AM +0800, Yifeng Li wrote:
> Loongson MIPS netbooks use 1024x600 LCD panels, which is the original
> target platform of this driver, but nearly all old x86 laptops have
> 1024x768. Lighting 768 panels using 600's timings would partially
> garble the display. Since it's not possible to distinguish them reliably,
> we change the default to 768, but keep 600 as-is on MIPS.
>
> Further, earlier laptops, such as IBM Thinkpad 240X, has a 800x600 LCD
> panel, this driver would probably garbled those display. As we don't
> have one for testing, the original behavior of the driver is kept as-is,
> but the problem has been documented is the comments.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:23:06

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 1/8] fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F.

On Sun, Mar 17, 2019 at 06:24:57AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), rebooting with
> sm712fb framebuffer driver would cause a white screen of death on
> the next POST, presumably the proper timings for the LCD panel was
> not reprogrammed properly by the BIOS.
>
> Experiments showed a few CRTC Scratch Registers, including CRT3D,
> CRT3E and CRT3F may be used internally by BIOS as some flags. CRT3B is
> a hardware testing register, we shouldn't mess with it. CRT3C has
> blanking signal and line compare control, which is not needed for this
> driver.
>
> Stop writing to CR3B-CR3F (a.k.a CRT3B-CRT3F) registers. Even if these
> registers don't have side-effect on other systems, writing to them is
> also highly questionable.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

2019-03-31 12:23:54

by Sudip Mukherjee

[permalink] [raw]
Subject: Re: [PATCH 6/8] fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting.

On Sun, Mar 17, 2019 at 06:25:02AM +0800, Yifeng Li wrote:
> On a Thinkpad s30 (Pentium III / i440MX, Lynx3DM), blanking the display
> or starting the X server will crash and freeze the system, or garble the
> display.
>
> Experiments showed this problem can mostly be solved by adjusting the
> order of register writes. Also, sm712fb failed to consider the difference
> of clock frequency when unblanking the display, and programs the clock for
> SM712 to SM720.
>
> Fix them by adjusting the order of register writes, and adding an
> additional check for SM720 for programming the clock frequency.
>
> Signed-off-by: Yifeng Li <[email protected]>
> Cc: [email protected] # v4.4+

Tested-by: Sudip Mukherjee <[email protected]>

--
Regards
Sudip

Subject: Re: [PATCH 0/8] fbdev: sm712fb: fix a series of lockups, crashes and gliches.


On 03/31/2019 02:18 PM, Sudip Mukherjee wrote:
> On Sun, Mar 17, 2019 at 06:24:56AM +0800, Yifeng Li wrote:
>> Hi all,
>>
>> This patchset contains a series of important fixes to various problems,
>> including lockups, crashes, screen gliches, and missing video modes.
>> These patches are crucial to the correct operation to the hardware,
>> especially Lynx3DM+ (SM720). I have tested and verified them on x86.
>>
>> Please review and queue them for linux-stable.
>
> Thanks for the changes.
> Verified the register changes from the datasheet and also tested the full
> series (separate test for individual patches) with SM712 on little endian
> for any regression.

Patches #1-8 queued for v5.2, thanks.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics