From: Yifeng Li <tomli@tomli.me>
To: Sudip Mukherjee <sudipm.mukherjee@gmail.com>,
Teddy Wang <teddy.wang@siliconmotion.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, Yifeng Li <tomli@tomli.me>,
stable@vger.kernel.org
Subject: [PATCH 5/8] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM.
Date: Sun, 17 Mar 2019 06:25:01 +0800 [thread overview]
Message-ID: <20190316222504.27170-6-tomli@tomli.me> (raw)
In-Reply-To: <20190316222504.27170-1-tomli@tomli.me>
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 <tomli@tomli.me>
Cc: stable@vger.kernel.org # 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
next prev parent reply other threads:[~2019-03-16 22:25 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-16 22:24 [PATCH 0/8] fbdev: sm712fb: fix a series of lockups, crashes and gliches Yifeng Li
2019-03-16 22:24 ` [PATCH 1/8] fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F Yifeng Li
2019-03-31 12:18 ` Sudip Mukherjee
2019-03-16 22:24 ` [PATCH 2/8] fbdev: sm712fb: fix brightness control on reboot, don't set SR30 Yifeng Li
2019-03-31 12:19 ` Sudip Mukherjee
2019-03-16 22:24 ` [PATCH 3/8] fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75 Yifeng Li
2019-03-31 12:19 ` Sudip Mukherjee
2019-03-16 22:25 ` [PATCH 4/8] fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA Yifeng Li
2019-03-31 12:19 ` Sudip Mukherjee
2019-03-16 22:25 ` Yifeng Li [this message]
2019-03-24 21:39 ` [PATCH 5/8] fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping VRAM Sudip Mukherjee
2019-03-31 12:20 ` Sudip Mukherjee
2019-03-16 22:25 ` [PATCH 6/8] fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting Yifeng Li
2019-03-31 12:20 ` Sudip Mukherjee
2019-03-16 22:25 ` [PATCH 7/8] fbdev: sm712fb: fix support for 1024x768-16 mode Yifeng Li
2019-03-31 12:20 ` Sudip Mukherjee
2019-03-16 22:25 ` [PATCH 8/8] fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display Yifeng Li
2019-03-31 12:21 ` Sudip Mukherjee
2019-03-31 12:18 ` [PATCH 0/8] fbdev: sm712fb: fix a series of lockups, crashes and gliches Sudip Mukherjee
2019-04-01 15:13 ` Bartlomiej Zolnierkiewicz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190316222504.27170-6-tomli@tomli.me \
--to=tomli@tomli.me \
--cc=b.zolnierkie@samsung.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=sudipm.mukherjee@gmail.com \
--cc=teddy.wang@siliconmotion.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®