[W701] Grafikkartenproblematik (nur originale Lenovo-Karten mit FRU funktionieren)

el-sahef

Active member
Themenstarter
Registriert
4 Aug. 2008
Beiträge
1.669
Hallo,

ich habe XStoneX ja versprochen, mich mal mit der Problematik beim W701 zu beschäftigen, dass nur Lenovo-Karten funktionieren, falls ich das W701 von ihm wieder hinbekomme.

Hier meine bisherigen Gedanken dazu. Die Hauptinformationsquellen sind dieser Blogpost sowie die MXM 3.0 Software Specification und die MXM 3.0 Electromechanical Specification und der Mainboard-Schaltplan.

Demnach wird das vBIOS von der Karte garnicht benutzt, sondern immer nur die im System-BIOS eingebetteten Video-BIOSe anhand der Vendor & Device ID von der Karte. Mit anderen Karten funktioniert das dann natürlich schon mal nicht. Der Autor des Artikels hatte es offenbar geschafft, das System-BIOS so zu ändern, dass das vBIOS von der Karte genommen wird und konnte damit dann booten, hat dabei jedoch keine Bildausgabe gehabt (da es ihm das EDID im Display überschrieben hat). Da hat er dann aufgegeben. Ich vermute, dass es mehrere Probleme gibt und der Autor des Artikels in Wahrheit schon sehr weit war:


  • Das System-BIOS benutzt nicht das vBIOS von der Karte, sondern nur die eingebetteten: Das hat er ja offenbar durch Editieren des System-BIOS lösen können. Ich weiß nicht, ob ich das auch hinbekomme, weil das dürfte ziemlich schwierig sein und einiges an Assembler-Bastelei erfordern. In den Kommentaren hatte schon mal einer nach dem BIOS gefragt, aber er hat die Dateien wohl nicht mehr. Eine andere Möglichkeit wäre eventuell, das vBIOS von der neu zu verbauenden Karte anstelle eines der vier im System-BIOS integrierten vBIOSe einzubetten. Das traue ich mir zu (habe sowas schon mal beim T61 gemacht), zumal ich bei einem Brick auch problemlos wieder ein funktionierendes BIOS per externem Flasher aufspielen kann.
  • Das vBIOS der Lenovo-Karten hat vermutlich spezielle Anpassungen, die man für das Zusammenspiel mit dem RGB-LED-Display braucht. Ich habe mir den I²C-Bus auf der Platine vom defekten WUXGA-RGB-LED-Display angeschaut sowie das Displaykabel und den Mainboardschaltplan und es ist so, dass durch das Displaykabel der I²C-Bus zur Ansteuerung des LED-Backlight-Controllers mit dem I²C-Bus für das EDID verbunden wird. Wenn an diesen Controller nun Befehle geschickt werden und das vBIOS ist nicht für diese Konfiguration ausgelegt, dann wäre es vielleicht denkbar, dass dabei das EDID überschrieben wird anstatt der Backlight Controller adressiert. Der Backlight-Controller hat außerdem auch noch einen Bus auf der Platine, der direkt mit dem EDID-EEPROM verbunden ist. Außerdem steuert der Backlight-Controller auch den Write-Protect-Pin des EDID-Displays an. Es ist demnach vorgesehen, dass der Backlight-Controller das EDID überschreiben kann. Ich vermute, dass diese Funktion im Zusammenhang mit dem integrierten Displaykalibriergerät (das ich ja nicht habe) verwendet wird.
  • Eine andere Ursache für das Überschreiben des EDID wäre möglicherweise noch, dass in der MXM-Structure, die dem vBIOS übergeben wird, drin steht, dass die Displayhelligkeit über I²C und nicht über ein PWM-Signal verstellt wird. --> vertan, es steht doch PWM drin
    Laut Blogpost gibt das BIOS je nach verbautem Paneltyp auch unterschiedliche MXM-Structures raus*. In dieser MXM-Structure stehen vereinfacht gesagt alle Displayanschlüsse vom Mainboard drin und wie die konfiguriert sind, so dass die Grafikkarte weiß, wie sie die einzelnen Anschlüsse ansteuern muss (und noch ein paar andere Dinge). Details kann man in der MXM Software Specification nachlesen. Ich habe die MXM-Structure, die das BIOS übergibt, via Linux über die DSDT auslesen könnten und die mal aufgedröselt. Übrigens hat der Autor von dem Blogartikel gesagt, dass diese MXM-Structure vom BIOS angeblich nur übergeben wird, wenn eine Nvidia-Karte eingebaut ist und er hat aber mit AMD-Karten getestet...
Ich gehe davon aus, dass bei dem folgendes passiert ist:


  1. Er hat es geschafft, dass das System-BIOS das vBIOS von der Grafikkarte nimmt und konnte so mit anderen Grafikkarten booten. Da hat er eigentlich schon fast alles gehabt bis auf die Hardwareseite, aber das wusste er nicht und hat aufgegeben weil
  2. das EDID von seinem RGB-LED-WUXGA während seiner Testerei überschrieben wurde und das deswegen sowieso nichts mehr angezeigt hat, außerdem konnten die anderen Karten ohne MXM-Structure sowieso kein Bild ausgeben, weil die ja keine Infos über die auf dem Mainboard verlöteten Displayanschlüsse hatten.

Ich werde daher wahrscheinlich nun wie folgt vorgehen:


  • Grafikkarte besorgen (so günstig wie möglich, ich will für eine Sache mit so schlechten Erfolgschancen nicht Unmengen an Euros verschleudern) --> erledigt, nVidia GeForce G210
  • Zunächst mit der originalen Grafikkarte versuchen, ein anders Display ohne RGB-LED-Backlight zu betreiben, um dies schon mal als Fehlerquelle auszuschließen. Da es das W701 laut Wiki auch mit WXGA+ TFT 1440x900 mit normalem (non-RGB) LED-Backlight gab sollte dies eigentlich kein Problem sein. Auf diesem Display kann man dann auch problemlos den EDID-Chip schreibschützen per WriteProtect-Pin, um da schon mal auf der sicheren Seite zu sein. --> erledigt
  • Um Probleme mit der MXM-Structure auszuschließen, will ich eine andere Möglichkeit nutzen, die MXM-Structure an die Grafikkarte zu übergeben als über das System-BIOS. Diese wird in den oben verlinkten Dokumenten zu MXM genannt: Man kann an den I²C-Bus für das EDID des angeschlossenen LVDS-Displays zusätzlich noch ein EEPROM mit der MXM-Structure als Inhalt anschließen und dann nimmt sich die Karte angeblich die MXM-Structure daraus anstatt vom System-BIOS (wenn BIOS und EEPROM eine MXM-Structure breitstellen hat das EEPROM höhere Priorität als das BIOS --> sehr wichtig !). Zum Test will ich daher so ein EEPROM mit der MXM-Structure, die das Lenovo-BIOS übergibt, an den I²C-Bus anschließen und schauen ob die Originalkarte sich die Infos dann tatsächlich aus dem EEPROM holt. Damit ich das kontrollieren kann nehme ich an der MXM-Structure eine Änderung vor, bei der ich den DisplayPort raus editiere. Sollte mit angelötetem EEPROM der DisplayPort im Nvidia-Controlpanel nicht mehr auftauchen, hat es geklappt. Wobei es natürlich denkbar wäre, dass es mit der Originalkarte nicht funktioniert, weil in dem vBIOS von den Lenovo-Karten diese Funktion deaktiviert wurde. --> erledigt, funktioniert
  • Danach käme das Problem mit dem System-BIOS, welches das vBIOS nicht von der Karte nimmt. Hier sehe ich für mich das größte Problem, weil ich im Gegensatz zu dem Autor von dem Blog-Post keine Ahnung von BIOS-Hacking auf Assembler-Ebene habe. Sollte es nicht möglich sein, das System-BIOS mit der anderen Karte zum Booten zu bringen, indem man eines der integrierten vBIOSe gegen das von der neuen Karte tauscht, dann wird es das für mich wahrscheinlich gewesen sein, da derjenige aus dem Blog ja offenbar das BIOS, was er geschrieben hat (das mit anderen Karten funktionierte) laut einem Post in den Kommentaren zum Blogpost dummerweise nicht mehr hat (das ist wirklich wahnsinnig ärgerlich, weil dies meine Erfolgschancen wahrscheinlich signifikant erhöht hätte :( ).
  • Sollte das Problem mit dem System-BIOS gelöst worden sein und die andere Grafikkarte in dem Gerät booten, kann man sich an das Debugging bezüglich der Bildausgabe und bezüglich des RGB-LED-Displays machen. Im Idealfall funktioniert die Bildausgabe mit einem normalen Display bereits, da die Karte die MXM-Structure ja aus dem EEPROM bekommt und es daher egal sein sollte, was das BIOS in dieser Hinsicht macht oder auch nicht macht.

*Ich könnte zum Vergleich dringend einen DSDT-Dump von einem W701 gebrauchen, bei dem das WXGA+ TFT mit 1440x900 Pixeln und normalem LED-Backlight verbaut ist. Falls jemand so ein Gerät hat, bitte hier im Thread melden!

MXM-Structure mit dem RGB-LED-WUXGA:
Code:
                    Name (_S3D, 0x03)  // _S3D: S3 Device State
                    Name (MXM3, Buffer (0x63)
                    {
                        /* 0000 */  0x4D, 0x58, 0x4D, 0x5F, 0x03, 0x00, 0x5B, 0x00,  /* MXM_..[. */
                        /* 0008 */  0x30, 0x11, 0xB8, 0xF7, 0xF9, 0x3E, 0x00, 0x00,  /* 0....>.. */
                        /* 0010 */  0x20, 0x39, 0x92, 0x2F, 0x02, 0x3E, 0x00, 0x00,  /*  9./.>.. */
                        /* 0018 */  0x00, 0x00, 0x0A, 0xF0, 0xF9, 0x3E, 0x00, 0x00,  /* .....>.. */
                        /* 0020 */  0x20, 0x39, 0xD2, 0x25, 0x08, 0xBE, 0x00, 0x00,  /*  9.%.... */
                        /* 0028 */  0x60, 0x6B, 0xE2, 0xFF, 0xF9, 0x3E, 0x00, 0x00,  /* `k...>.. */
                        /* 0030 */  0x60, 0x6C, 0xEC, 0xFF, 0xF9, 0x3E, 0x00, 0x00,  /* `l...>.. */
                        /* 0038 */  0x01, 0x4C, 0x04, 0x00, 0x02, 0x1A, 0x04, 0x00,  /* .L...... */
                        /* 0040 */  0x03, 0x01, 0x90, 0x01, 0x13, 0x00, 0x4C, 0x04,  /* ......L. */
                        /* 0048 */  0x93, 0x00, 0x90, 0x01, 0xF4, 0x0F, 0x30, 0x00,  /* ......0. */
                        /* 0050 */  0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x06, 0x10,  /* ........ */
                        /* 0058 */  0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0xE8, 0x03,  /* ........ */
                        /* 0060 */  0x00, 0x00, 0x28                                 /* ..( */
                    })




// MXM header //

0x4D = M
0x58 = X
0x4D = M
0x5F = _
0x03 = Version 3
0x00 = Revision 0
0x5B = 0101 1011
0x00 = 0000 0000   --> 0000 0000 0101 1011 = 91 Bytes Länge (inkl. Checksum aber ohne Header)


// Output Device LVDS //

0x30 = 0011 --> LVDS  |  0000 --> Device descriptor
0x11 = 0001 --> LVDS con. | 0001 --> LVDS_DDC
0xB8 = 1 --> no audio | 011 1 --> dual link LVDS | 00 --> internal con. | 0 --> LVDS con. 
0xF7 = 1111 --> GPIO for output select unused | 0 --> 24 bit LVDS | 1 --> no CEC | 1 --> spread spectrum enabled | 1 --> no audio
0xF9 = 1111 1 --> GPIO for DDC select unused | 0 --> use GPIO to select output as per bits | 0 --> GPIO low when selected | 1 --> GPIO for output select unused
0x3E = 0 --> no acpi hotplug notification | 0 --> polarity for GPIO dev detection low | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// Output Device DVI-D (channel B)//

0x20 = 0010 --> TMDS / HDMI (DVI) | 0000 --> Device descriptor
0x39 = 0011 --> DVI-D con. | 1001 --> Aux DDC-Port for DP_A / Legacy
0x92 = 1 --> no audio | 001 0 --> dual link TMDS (DP_A + DP_B)| 01 --> chassis con. | 0 --> DVI-D con.
0x2F = 0010 --> GPIO for output select = GPIO 2 | 1 --> 18 bit link | 1 --> no CEC  | 1 --> spread spectrum enabled | 1 --> no audio
0x02 = 0000 0 --> GPIO 0 for DDC select | 0 use GPIO to select output as per bits | 1 --> GPIO high when selected | 0 --> GPIO for output select = GPIO 2
0x3E = 0 --> no acpi hotplug notification | 0 --> polarity for GPIO dev detection low | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// Output Device VGA //

0x00 = 0000 --> analog CRT (VGA) | 0000 --> Device descriptor
0x00 = 0000 --> VGA con. | 0000 --> VGA DDC-Port
0x0A = 0 --> SPDIF audio (unused) | 000 1 --> single link TMDS (unused)| 01 --> chassis con. | 0 --> VGA con.
0xF0 = 1111 --> GPIO for output select unused | 0 --> 24 bit LVDS (unused) | 0 --> CEC (unused)  | 0 --> spread spectrum disabled (unused) | 0 --> SPDIF audio (unused)
0xF9 = 1111 1 --> GPIO for DDC select unused | 0 --> use GPIO to select output as per bits | 0 --> GPIO low when selected | 1 --> GPIO for output select unused
0x3E = 0 --> no acpi hotplug notification | 0 --> polarity for GPIO dev detection low | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// Output Device DVI-D (channel A) // 

0x20 = 0010 --> TMDS / HDMI (DVI) | 0000 --> Device descriptor
0x39 = 0011 --> DVI-D con. | 1001 --> Aux DDC-Port for DP_A / Legacy
0xD2 = 1 --> no audio | 101 0 --> DisplayPort DP_A | 01 --> chassis con. | 0 --> DVI-D con.
0x25 = 0010 --> GPIO for output select = GPIO 2 | 0 --> 18 bit link | 1 --> no CEC  | 0 --> spread spectrum disabled | 1 --> no audio
0x08 = 0000 1 --> GPIO 1 for DDC select | 0 use GPIO to select output as per bits | 0 --> GPIO low when selected | 0 --> GPIO for output select = GPIO 2
0xBE = 1 --> acpi hotplug notification | 0 --> polarity for GPIO dev detection -->  high | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG (unused) | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// Output Device DisplayPort Notebook // 

0x60 = 0110 --> DisplayPort | 0000 --> Device descriptor
0x6B = 0110 --> DisplayPort external con. | 1011 --> Aux DDC-Port for DP_C
0xE2 = 1 --> no audio | 110 0 --> DisplayPort DP_C | 01 --> chassis con. | 0 --> DisplayPort external con.
0xFF = 1111 --> GPIO for output select unused | 1 --> 18 bit link | 1 --> no CEC  | 1 --> spread spectrum enabled | 1 --> no audio
0xF9 = 1111 1 --> GPIO for DDC select unused | 0 --> use GPIO to select output as per bits | 0 --> GPIO low when selected | 1 --> GPIO for output select unused
0x3E = 0 --> no acpi hotplug notification | 0 --> polarity for GPIO dev detection low | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG (unused) | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// Output Device DisplayPort Dock //

0x60 = 0110 --> DisplayPort | 0000 --> Device descriptor
0x6C = 0110 --> DisplayPort external con. | 1100 --> Aux DDC-Port for DP_D
0xEC = 1 --> no audio | 110 1 --> DisplayPort DP_D | 10 --> docking con. | 0 --> DisplayPort external con.
0xFF = 1111 --> GPIO for output select unused | 1 --> 18 bit link | 1 --> no CEC  | 1 --> spread spectrum enabled | 1 --> no audio
0xF9 = 1111 1 --> GPIO for DDC select unused | 0 --> use GPIO to select output as per bits | 0 --> GPIO low when selected | 1 --> GPIO for output select unused
0x3E = 0 --> no acpi hotplug notification | 0 --> polarity for GPIO dev detection low | 11 111 --> GPIO for dev detection unused | 0 --> use GPIO to select DDC as per bits
0x00 = 000 --> LVDS signal type = SPWG (unused) | 0 0000 --> reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)


// Cooling Capability //

0x01 = 0000 --> maximum cooling capability for entire module | 0001 --> cooling capability structure
0x4C = 0100 1100                              |||  0x44C = 1100 
0x04 = 0000 = reserved (must be zero) | 0100  |||  1100 * 0,1 W = 110 W cooling capability
0x00 = 0000 0000 = reserved (must be zero)


// thermal structure //

0x02 = 0000 --> info = maximum temperature to maintain | 0010 = thermal structure
0x1A = 0001 1010                                ||| 0x41A = 1050
0x04 = 0000 0 = reserved (must be zero) | 100   ||| 1050 * 0,1 °C = 105 °C
0x00 = 0000 0000 = reserved (must be zero)


// input power structure //

0x03 = 0000 --> power limit on battery | 0011 --> input power structure
0x01 = 0000 00 = reserved (must be zero) | 0 --> system provides ACPI/SW notification to select power state | 1 --> PWR_LEVEL# pin asserted during this power state
0x90 = 1001 0000                                ||| 0x190 = 400
0x01 = 0000 = reserved (must be zero) | 0001    ||| 400*0,1 W = 40 W input power

// input power structure //

0x13 = 0001 --> power limit on AC power | 0011 --> input power structure
0x00 = 0000 00 = reserved (must be zero) | 0 --> system provides ACPI/SW notification to select power state | 0 --> PWR_LEVEL# pin not asserted during this power state
0x4C = 0100 1100                              |||  0x44C = 1100 
0x04 = 0000 = reserved (must be zero) | 0100  |||  1100 * 0,1 W = 110 W input power

// input power structure //

0x93 = 1001 --> power limit P1 | 0011 --> input power structure
0x00 = 0000 00 = reserved (must be zero) | 0 --> system provides ACPI/SW notification to select power state | 0 --> PWR_LEVEL# pin not asserted during this power state
0x90 = 1001 0000                                ||| 0x190 = 400
0x01 = 0000 = reserved (must be zero) | 0001    ||| 400*0,1 W = 40 W input power


// GPIO device structure //

0xF4 = 1111 --> direct GPIO | 0100 --> MXM GPIO device structure
0x0F = 0000 = reserved (must be zero) | 1111 --> direct GPIO
0x30 = 0011 --> 3 GPIO pin entries | 0000 = reserved (must be zero)
0x00 = 0000 000 = reserved (must be zero) | 0 --> 3 GPIO pin entries

// GPIO pin entry 1 //

0x00 = 000 = reserved (must be zero) | 0 0000 --> GPIO 0
0x01 = 0000 0001 --> function: output device DDC/Aux bus MUX

// GPIO pin entry 2 //
0x01 = 000 = reserved (must be zero) | 0 0001 --> GPIO 1
0x01 = 0000 0001 --> function: output device DDC/Aux bus MUX

// GPIO pin entry 3 //
0x02 = 000 = reserved (must be zero) | 0 0010 --> GPIO 2
0x02 = 0000 0010 --> function: output device display signal MUX


// backlight control structure // 

0x06 = 0000 --> associated output device structure = 0 (LVDS) | 0110 --> backlight control structure
0x10 = 0001 --> 1 backlight frequency entry | 00 --> backlight type CCFL (falsch, aber steht so da) | 00 --> Inverter control type = PWM
0x00 = 0000 0000 = reserved (must be zero)
0x00 = 0000 0000 = reserved (must be zero)

// backlight frequency structure // 

0xC8 = 1100 1000     ||| 0x000C8 = 200 (200 Hz PWM frequency)
0x00 = 0000 0000
0x00 = 0000 00 = reserved (must be zero) | 00
0x00 = 0000 0000 = reserved (must be zero)
0xE8 = 1110 1000       ||| 0x3E8 = 1000 
0x03 = 0000 00 | 11    ||| 1000 * 0,1 % = 100 % maximum PWM duty cycle
0x00 = 0000 = reserved (must be zero) | 0000     ||| 0 % minimum PWM duty cycle
0x00 = 0000 0000 = reserved (must be zero)


// checksum //
0x28 ||| Checksum über alles (ohne die Checksum selber natürlich) wie hier:
     ||| http://www.planetimming.com/checksum8.html
 
Zuletzt bearbeitet:
Finde das Thema äußerst spannend und werde dran bleiben, helfen kann ich dir dabei jedoch nicht mehr. Das übersteigt meine Fähigkeiten bei Weitem.

Trotzdem wünsche ich dir in dieser Sache viel Glück!
 
Habe das jetzt mal soweit verkabelt, dass man normale Displays anschließen kann. Mit einem WXGA+-Display aus einem DELL-Notebook geht es einwandfrei. Anschließend ein EEPROM mit der W701-MXM-Structure beschrieben (allerdings editiert, so dass die DisplayPorts nicht mehr drin stehen), auf Adresse A8/A9 eingestellt und mit an den I²C-Bus vom EDID gehängt. Wird aber leider nicht ausgelesen, die DisplayPorts sind immer noch da. Allerdings muss das nichts heißen, weil das System-BIOS ja die integrierten vBIOSe nimmt und nicht das von der Karte. Da wäre es auch nicht verwunderlich, wenn Lenovo die soweit geändert hat, dass die integrierten vBIOSe nicht auf das Vorhandensein vom EEPROM testen würden. Nur lässt sich so dummerweise halt nicht verifizieren, ob das EEPROM korrekt beschrieben ist und von einer anderen Karte, die sich standardkonform verhält, gefunden werden könnte.

Jetzt bräuchte ich das BIOS von dem Author von dem Blog-Post, der es hinbekommen hat, dass das vBIOS von der Grafikkarte benutzt wird. Selber hinbekommen dürfte für mich ziemlich schwierig werden. Alternativ probieren, ob man das vBIOS der GT210M, die ich hier habe, in das Lenovo-BIOS integrieren kann und die PCI-ID-Abfrage auch entsprechend editieren.

EDIT 08:27 Uhr : Ich Depp habe die VCC-Leitung vom MXM-EEPROM an die VCC-Leitung vom Displaypanel anstatt an die vom EDID-EEPROM gehängt. Die wird aber erst aktiviert, nachdem das EDID-EEPROM ausgelesen wurde. Zu dem Zeitpunkt konnte die Grafikkarte das MXM-EEPROM also noch garnicht finden, da dieses keinen Strom bekam. Nachdem ich die VCC-Leitung vom MXM-EEPROM an die VCC-Leitung vom EDID-EEPROM gehängt habe funktioniert es jetzt! Die DisplayPorts sind in der Ausgabe von "xrandr --verbose" weg!

Nun bin ich mir sicher, dass ich es hinbekäme, wenn ich bloß dieses modifizierte BIOS hätte.



 
Zuletzt bearbeitet:
  • ok1.de
  • ok2.de
  • thinkstore24.de
  • Preiswerte-IT - Gebrauchte Lenovo Notebooks kaufen

Werbung

Zurück
Oben