summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs2010-05-25 05:47:16 +0200
committerBen Skeggs2010-05-28 08:06:28 +0200
commitd13102c6b4836289138431e3fbfc08e90c925ffd (patch)
tree5208465fcf72117479373789909a06de6a06b3e5
parentdrm/nouveau: Add getparam for current PTIMER time. (diff)
downloadkernel-qcow2-linux-d13102c6b4836289138431e3fbfc08e90c925ffd.tar.gz
kernel-qcow2-linux-d13102c6b4836289138431e3fbfc08e90c925ffd.tar.xz
kernel-qcow2-linux-d13102c6b4836289138431e3fbfc08e90c925ffd.zip
drm/nouveau: fix POST detection for certain chipsets
We totally fail at detecting un-POSTed chipsets prior to G80. This commit changes the pre-G80 POST detection to read the programmed horizontal total from CRTC 0, and assume the card isn't POSTed if it's 0. NVIDIA use some other heuristics more similar to what we do on G80, but I wasted quite a long time trying to figure out the exact specifics of what they do so we can try this for a bit instead. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index e7e69ccce5c9..61d932261356 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -6205,6 +6205,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev)
nouveau_i2c_fini(dev, entry);
}
+static bool
+nouveau_bios_posted(struct drm_device *dev)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ bool was_locked;
+ unsigned htotal;
+
+ if (dev_priv->chipset >= NV_50) {
+ if (NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
+ NVReadVgaCrtc(dev, 0, 0x1a) == 0)
+ return false;
+ return true;
+ }
+
+ was_locked = NVLockVgaCrtcs(dev, false);
+ htotal = NVReadVgaCrtc(dev, 0, 0x06);
+ htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
+ htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
+ htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
+ htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
+ NVLockVgaCrtcs(dev, was_locked);
+ return (htotal != 0);
+}
+
int
nouveau_bios_init(struct drm_device *dev)
{
@@ -6239,9 +6263,7 @@ nouveau_bios_init(struct drm_device *dev)
bios->execute = false;
/* ... unless card isn't POSTed already */
- if (dev_priv->card_type >= NV_10 &&
- NVReadVgaCrtc(dev, 0, 0x00) == 0 &&
- NVReadVgaCrtc(dev, 0, 0x1a) == 0) {
+ if (!nouveau_bios_posted(dev)) {
NV_INFO(dev, "Adaptor not initialised\n");
if (dev_priv->card_type < NV_50) {
NV_ERROR(dev, "Unable to POST this chipset\n");