summaryrefslogtreecommitdiffstats
path: root/drm-nouveau-d620.patch
diff options
context:
space:
mode:
authorJesse Keating <jkeating@redhat.com>2010-07-29 17:18:45 -0700
committerJesse Keating <jkeating@redhat.com>2010-07-29 17:18:45 -0700
commit2f82dda4a9bf41e64e864889bf06564bdf826e25 (patch)
tree118a7b483ae5de4dbf83d20001302f1404866ef0 /drm-nouveau-d620.patch
parent64ba2e5ffde5f2418eb26c700cb0ab62b04e5013 (diff)
downloaddom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.gz
dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.tar.xz
dom0-kernel-2f82dda4a9bf41e64e864889bf06564bdf826e25.zip
initial srpm import
Diffstat (limited to 'drm-nouveau-d620.patch')
-rw-r--r--drm-nouveau-d620.patch121
1 files changed, 121 insertions, 0 deletions
diff --git a/drm-nouveau-d620.patch b/drm-nouveau-d620.patch
new file mode 100644
index 0000000..601e200
--- /dev/null
+++ b/drm-nouveau-d620.patch
@@ -0,0 +1,121 @@
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
+index 6b6c303..a81c738 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
+@@ -3198,7 +3198,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
+ struct nvbios *bios = &dev_priv->vbios;
+ unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
+ uint16_t scriptptr = 0, clktable;
+- uint8_t clktableptr = 0;
+
+ /*
+ * For now we assume version 3.0 table - g80 support will need some
+@@ -3217,26 +3216,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
+ scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
+ break;
+ case LVDS_RESET:
++ clktable = bios->fp.lvdsmanufacturerpointer + 15;
++ if (dcbent->or == 4)
++ clktable += 8;
++
+ if (dcbent->lvdsconf.use_straps_for_mode) {
+ if (bios->fp.dual_link)
+- clktableptr += 2;
+- if (bios->fp.BITbit1)
+- clktableptr++;
++ clktable += 4;
++ if (bios->fp.if_is_24bit)
++ clktable += 2;
+ } else {
+ /* using EDID */
+- uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+- int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
++ int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
+
+ if (bios->fp.dual_link) {
+- clktableptr += 2;
+- fallbackcmpval *= 2;
++ clktable += 4;
++ cmpval_24bit <<= 1;
+ }
+- if (fallbackcmpval & fallback)
+- clktableptr++;
++
++ if (bios->fp.strapless_is_24bit & cmpval_24bit)
++ clktable += 2;
+ }
+
+- /* adding outputset * 8 may not be correct */
+- clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
++ clktable = ROM16(bios->data[clktable]);
+ if (!clktable) {
+ NV_ERROR(dev, "Pixel clock comparison table not found\n");
+ return -ENOENT;
+@@ -3638,37 +3640,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
+ *if_is_24bit = bios->data[lvdsofs] & 16;
+ break;
+ case 0x30:
+- /*
+- * My money would be on there being a 24 bit interface bit in
+- * this table, but I have no example of a laptop bios with a
+- * 24 bit panel to confirm that. Hence we shout loudly if any
+- * bit other than bit 0 is set (I've not even seen bit 1)
+- */
+- if (bios->data[lvdsofs] > 1)
+- NV_ERROR(dev,
+- "You have a very unusual laptop display; please report it\n");
++ case 0x40:
+ /*
+ * No sign of the "power off for reset" or "reset for panel
+ * on" bits, but it's safer to assume we should
+ */
+ bios->fp.power_off_for_reset = true;
+ bios->fp.reset_after_pclk_change = true;
++
+ /*
+ * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
+- * over-written, and BITbit1 isn't used
++ * over-written, and if_is_24bit isn't used
+ */
+ bios->fp.dual_link = bios->data[lvdsofs] & 1;
+- bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
+- bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+- break;
+- case 0x40:
+- bios->fp.dual_link = bios->data[lvdsofs] & 1;
+ bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
+ bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
+ bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
+ break;
+ }
+
++ /* Dell Latitude D620 reports a too-high value for the dual-link
++ * transition freq, causing us to program the panel incorrectly.
++ *
++ * It doesn't appear the VBIOS actually uses its transition freq
++ * (90000kHz), instead it uses the "Number of LVDS channels" field
++ * out of the panel ID structure (http://www.spwg.org/).
++ *
++ * For the moment, a quirk will do :)
++ */
++ if ((dev->pdev->device == 0x01d7) &&
++ (dev->pdev->subsystem_vendor == 0x1028) &&
++ (dev->pdev->subsystem_device == 0x01c2)) {
++ bios->fp.duallink_transition_clk = 80000;
++ }
++
+ /* set dual_link flag for EDID case */
+ if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
+ bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
+index 4f88e69..fd6274a 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
++++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
+@@ -267,7 +267,6 @@ struct nvbios {
+ bool reset_after_pclk_change;
+ bool dual_link;
+ bool link_c_increment;
+- bool BITbit1;
+ bool if_is_24bit;
+ int duallink_transition_clk;
+ uint8_t strapless_is_24bit;