Thursday, April 26, 2012

A Solution for External Monitors on a Thinkpad W520 running Linux

Disclaimer: These are not detailed instructions. If you are new at using linux, you will almost certainly have to look up a few things outside this blog to be able to follow these instructions.

External display without restarting X !


If you use linux on your Thinkpad W520, you have undoubtedly been frustrated by the graphics situation. With a default install, it's impossible to enjoy both the battery life of the integrated intel graphics card and to have external monitors. The situation is documented in this earlier blog post, along with a partial solution to the problem. The biggest drawback to the solution presented in that post is that you must log out of your X-session to disconnect or connect an external display. Fortunately, with some hacking from Liskni_si , we now have a better option:

A dynamic external display in nVidia Optimus Mode without having to restart the X-Server!
 
Notes:
- As far as I know this should also work on some T420/520 models to get the display port output and/or tri-head display.
- You may use this with bumblebee installed, however, you MUST follow ALL the steps that Lekensteyn lays out here except instead of $ export DISPLAY=:8 , run $ screenclone -d :8
- There are some perhaps easier-to-follow instructions to do this with bumblebee and 3D support on the intel card here:  http://sagark.org/optimal-ubuntu-graphics-setup-for-thinkpads/


So, here is how the system works:


1. Use bbswitch to turn the nVidia card on and off when you need it.
2.  All of the rendering is done on the intel card. This requires an extra virtual screen inside the intel card which can be dynamically activated and configured via xrandr.
3. The content of the intel card's virtual screen is copied to the nvidia card via Liskni_si's screenclone for displaying on the external display.


Here's some basic instructions to get it to work:

1. Download bbswitch via your package manager (for ubuntu it is in the bumblebee ppa). Source and instructions on how to use it are here: https://github.com/Bumblebee-Project/bbswitch (you don't NEED to install all of bumblebee)

$ sudo apt-add-repository ppa:bumblebee/stable
$ sudo apt-get update
$ sudo apt-get install bbswitch-dkms

Learn how to use it. You may also have to manually insert the bbswitch module for it to work

$ sudo modprobe bbswitch

2. Patch your intel driver to give it an extra virtual display.

First download the source for the intel driver

$ apt-get build-dep xserver-xorg-video-intel
$ apt-get source xserver-xorg-video-intel

Then, download and apply the patch to create the extra virtual screen

$ cd <wherever you put the source>/xserver-xorg-...
$ wget https://raw.github.com/liskin/patches/master/hacks/xserver-xorg-video-intel-2.18.0_virtual_crtc.patch
$ patch -p1 < xserver-xorg-video-intel-2.18.0_virtual_crtc.patch

[EDIT - there is a newer update of the patch here: https://github.com/liskin/patches/blob/master/hacks/xserver-xorg-video-intel-2.20.14_virtual_crtc.patch. This new patch may be required for newer systems such as ubuntu 12.10. It also contains support for 2 virtual screens, although support for two external screens in screenclone may not be available yet]

Finally, build and install the new intel driver

$ dpkg-buildpackage -b
$ cd ..
$ sudo dpkg --install xserver-xorg-video-intel_2.17.0-1ubuntu4_amd64.deb

Now you probably have to restart X, but after you do, if you run xrandr, you should see an entry called "VIRTUAL", that's what we need.

3. Download and build the screenclone source

$ git clone git://github.com/liskin/hybrid-screenclone.git
$ cd hybrid-screenclone
$ make


Usage

To attach an external monitor, first start the x server on the nvidia device with the xorg.conf (xorg.conf.nvidia) included with the hybrid-screenclone source (the nvidia card must be on of course - you can check this with bbswitch).


$ /usr/bin/X -ac -audit 0 -config xorg.conf.nvidia -sharevts -modulepath /usr/lib/nvidia/current,/usr/lib/xorg/modules -nolisten tcp -noreset :1

(If you have bumblebee installed, skip the step above because bumblebee controls the nvidia X server. Instead just run $ optirun true to get the X server going)

Then turn on the virtual screen in the intel chip

$ xrandr --output LVDS1 --auto --output VIRTUAL --mode 1920x1080 --left-of LVDS1

And finally, send the intel output to the nvidia card (you'll need to put the screenclone binary in your path)

$ screenclone

(If you have bumblee installed use $ screenclone -d :8 instead)

If you don't see the right screen on your external monitor, try running screenclone with the argument -x n where n is 0, 1, or 2. 

Make some scripts out of this (you can see the scripts I have made for my use here), and enjoy your new-found freedom!

And maybe one day, Liskni_si will even extend his code so that we W520 users can have triple head without needing to restart X every time ; )

[If you are looking for a way to enable 3D acceleration on the Intel card, have a look at Christoph Gritschenberger's comment below]