воскресенье, 13 января 2013 г.

Nouveau + Xrandr: Монитор и телевизор

В прошлом я уже описывал два способа одновременного использования монитора и телевизора на одной видеокарте: Xinerama: монитор и телевизор и TwinView: монитор и телевизор.

На этот раз мне, по некоторым причинам, понадобилось поставить свободный драйвер Nouveau. Сам по себе он ставится довольно просто, а вот с настройкой одновременного использования монитора и телевизора пришлось попотеть.

Установка nouveau

Итак, сначала опишу процедуру замены проприетарного драйвера nvidia на свободный nouveau. Для этого я воспользовался статьёй Переход на драйвер nouveau с проприетарных драйверов nvidia.

У меня установлен Wheezy, поэтому я сразу установил драйвер (в ответ на что система сообщила, что у меня уже установлено всё необходимое):
# apt-get install libdrm-nouveau1a xserver-xorg-video-nouveau
Остановил LightDM из первой консоли:
# /etc/init.d/lightdm stop
Выгрузил модули nvidia и drm и загрузил модуль nouveau:
# rmmod nvidia
# rmmod drm
# modprobe nouveau
Удостоверился, что система не ругнулась в ответ на загрузку модуля nouveau:
# dmesg | tail
Сделал резервную копию файла конфигурации X-сервера:
# cp /etc/X11/xorg.conf /etc/X11/xorg.conf-nvidia-twinview
В исходном файле закомментировал секции Monitor и Screen, соответствующие телевизору, в секции ServerLayout оставил только один Screen, в секции Driver закомментировал использование TwinView.
Затем удалил пакет nvidia-glx:
# apt-get remove nvidia-glx
И поставил замену для него:
# apt-get install libgl1-mesa-dri libgl1-mesa-glx
Затем попробовал запустить LightDM и убедился, что монитор работает:
# /etc/init.d/lightdm start
Затем, удалил остатки проприетарного драйвера nvidia:
# apt-get remove nvidia-\*
Добавил модуль проприетарного драйвера в чёрный список, закомментировав строчку с nouveau и прописав строчку с nvidia в файле /etc/modprobe.d/nvidia-kernel-common.conf:
#blacklist nouveau
blacklist nvidia
И добавил модуль nouveau в автозагрузку:
# echo nouveau >> /etc/modules
Теперь настала пора самого сложного - настроить телевизор.

Настройка монитора и телевизора

В результате всех мытарств получился такой /etc/X11/xorg.conf:
Section "ServerFlags"
    Option "AutoAddDevices" "False"
    Option "AllowEmptyInput" "False"
    Option "DontZap" "False"
EndSection

Section "ServerLayout"
    Identifier     "X.org Configured"
    Screen      0  "Screen0" 0 0
    InputDevice    "Mouse0" "CorePointer"
    InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
    ModulePath   "/usr/lib/xorg/modules"
    FontPath     "/usr/share/fonts/X11/misc"
    FontPath     "/usr/share/fonts/X11/Type1"
    FontPath     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType"
EndSection

Section "Module"
    Load  "dri"
    Load  "GLcore"
    Load  "glx"
    Load  "dbe"
    Load  "record"
    Load  "extmod"
    Load  "xtrap"
    Load  "Xrandr"
EndSection

Section "InputDevice"
    Identifier  "Keyboard0"
    Driver      "kbd"
    Option      "XkbRules" "xorg"
    Option      "XkbModel" "pc104"
    Option      "XkbLayout" "us,ru"
    Option      "XkbOptions" "grp:alt_shift_toggle"
    Option      "XkbVariant" ",winkeys"
    Option      "AutoRepeat" "250 30"
EndSection

Section "InputDevice"
    Identifier  "Mouse0"
    Driver      "mouse"
    Option      "Protocol" "auto"
    Option      "Device" "/dev/input/mice"
    Option      "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
    DisplaySize  338 270 # mm
    Identifier   "VGA-1"
    VendorName   "LG"
    ModelName    "Flatron L1730S"
    HorizSync    30.0 - 80.2
    VertRefresh  56.0 - 75.0
    Option       "DPMS"
    # 1280x1024 @ 75.00 Hz (GTF) hsync: 80.17 kHz; pclk: 138.54 MHz
    Modeline "1280x1024_75.00"  138.54  1280 1368 1504 1728  1024 1025 1028 1069  -HSync +Vsync
    # 1024x768 @ 75.00 Hz (GTF) hsync: 60.15 kHz; pclk: 81.80 MHz
    Modeline "1024x768_75.00"  81.80  1024 1080 1192 1360  768 769 772 802  -HSync +Vsync
    # 800x600 @ 75.00 Hz (GTF) hsync: 47.02 kHz; pclk: 48.91 MHz
    Modeline "800x600_75.00"  48.91  800 840 920 1040  600 601 604 627  -HSync +Vsync
    # 640x480 @ 75.00 Hz (GTF) hsync: 37.65 kHz; pclk: 30.72 MHz
    Modeline "640x480_75.00"  30.72  640 664 728 816  480 481 484 502  -HSync +Vsync
    Option       "PreferredMode" "1280x1024_75.00"
EndSection

Section "Monitor"
    DisplaySize    450 350 # mm
    Identifier     "TV-1"
    VendorName     "LG"
    ModelName      "Flatron RT-21FA32X"
    HorizSync      15.625 - 29.7
    VertRefresh    50.0 - 50.0
    Option         "DPMS"
    # 720x576 @ 50.00 Hz (GTF) hsync: 29.65 kHz; pclk: 26.57 MHz
    Modeline "720x576_50.00"  26.57 720 736 808 896  576 577 580 593  -HSync +Vsync
    Option         "PreferredMode" "720x576_50.00"
    Option         "RightOf" "VGA-1"
EndSection

Section "Device"
    Identifier  "Card0"
    Driver      "nouveau"
    VendorName  "nVidia Corporation"
    BoardName   "NV43 [GeForce 6600]"
    BusID       "PCI:5:0:0"

    Option      "Monitor-VGA-1" "VGA-1"
    Option      "Monitor-TV-1" "TV-1"
EndSection

Section "Screen"
    Identifier "Screen0"
    Device     "Card0"
    Monitor    "VGA-1"
    DefaultDepth    24
    SubSection "Display"
        Depth     24
    EndSubSection
EndSection
На что следует обратить внимание?

Во-первых, на опции в секции Device, которые устанавливают соответствие между портами видеокарты и секциями мониторов в файле конфигурации. Порты, по крайней мере на моей видеокарте, имеют названия "VGA-1", "DVI-I-1" и "TV-1" (их названия можно узнать с помощью команды xrandr), поэтому в опциях они будут называться "Monitor-VGA-1", "Monitor-DVI-I-1" и "Monitor-TV-1". Названия же секций мониторов могут быть произвольными - я решил назвать их так же, как и порты.

Во-вторых, в секции, описывающей один из мониторов, нужно добавить опцию, указывающую его расположение относительно первого. В моём случае эта опция выглядит так:
Option         "RightOf" "VGA-1"
В-третьих, в секции Screen, описывающей единственный экран, не должно быть посторонних опций вроде ViewPort, Modes и Virtual. Если они указаны, Xrandr может проявить самостоятельность в выборе настроек видеорежимов, если ему что-то не понравится.

В-четвёртых, предпочитаемый видеорежим монитора можно выбрать с помощью опции PreferredMode. Единственный его недостаток заключается в том, что нельзя ещё дополнительно указать частоту кадровой развёртки. У меня Xrandr упорно выбирал наименьшую из возможных. Для того, чтобы заставить его использовать нужную частоту развёртки, пришлось описать каждый режим вручную в опциях Modeline. Список доступных режимов можно узнать с помощью команды xrandr. Строчки Modeline можно посчитать с помощью команды gtf.

В-пятых, опция Modeline может быть молча проигнорирована, если Xrandr решит, что такой режим не поддерживается монитором. Для того, чтобы убедить Xrandr всё-же установить запрошенный видеорежим, нужно ещё вручную задать допустимые пределы вертикальной и горизонтальной частот синхронизации. Их значения можно получить с помощью команды ddcprobe и перед внесением в файл конфигурации отредактировать так, чтобы они соответствовали Modeline'у.

Например, с помощью gtf я рассчитал Modeline для телевизора:
# 720x576 @ 50.00 Hz (GTF) hsync: 29.65 kHz; pclk: 26.57 MHz
Modeline "720x576_50.00"  26.57 720 736 808 896  576 577 580 593  -HSync +Vsync
Чтобы им можно было воспользоваться, нужно чтобы верхнее значение горизонтальной частоты синхронизации равнялось, а лучше - было чуть больше, чем указанное в Modeline (hsync: 29.65 kHz). Исходя из этого, я задрал верхнюю планку в настройке HorizSync:
HorizSync      15.625 - 29.7
Наконец, после прописывания этих настроек, Xrandr установил нужные мне видеорежимы. Нетребовательные люди могут остановиться на устраивающих их настройках, потому что Xrandr довольно хорошо (но не идеально) выбирает режимы сам.

Ещё один подводный камень возник с XFCE. У него есть собственное меню для настройки видеорежимов - "Дисплей" в "Диспетчере настроек". Чтобы настройки XFCE не сбивали то, что прописано в настройках X-сервера, нужно удалить из домашнего каталога файл ~/.config/xfce4/xfconf/xfce4-perchannel-xml/display.xml и больше не заходить в это меню, потому что при запуске этот файл создаётся снова.

И, наконец, завершающий штрих.

Настройка видеорежима в консоли

Драйвер nouveau располагает двумя мониторами с разными разрешениями. В режиме отображения консоли он показывает на обоих мониторах одно и то же изображение. Чтобы изображение целиком отображалось на обоих мониторах, он формирует картинку, размеры которой позволяют отобразить её целиком на мониторе с меньшим разрешением (на телевизоре). Соответственно, на мониторе с большим разрешением используется только прямоугольная область в верхнем левом углу, совпадающая по пиксельным размерам с разрешением второго монитора (телевизора).

Выглядит это не очень приятно, поэтому я настроил на обоих мониторах одинаковое разрешение, которое они оба могут отобразить: 640x480. При этом разрешении текст умещается в экран телевизора, и занимает 100% площади экрана как на мониторе, так и на телевизоре.

Добавим модуль в загрузочный образ системы. Для этого в файле /etc/initramfs-tools/modules добавим строчку с текстом "nouveau" и обновим загрузочный образ:
# update-initramfs -u -k all
Теперь добавим настройки видеорежимов к параметрам ядер Linux, загружаемых с помощью GRUB 2. Для этого откроем файл /etc/defaults/grub и добавим в опцию GRUB_CMDLINE_LINUX необходимые настройки. У меня в этой опции было пусто, поэтому она приняла следующий вид:
GRUB_CMDLINE_LINUX="video=VGA-1:640x480 video=TV-1:640x480"
Теперь сгенерируем новую конфигурацию GRUB 2:
# update-grub
И перезагрузим компьютер. Оба экрана будут использовать в режиме текстовой консоли разрешения 640x480, а в графическом режиме - настройки X-сервера.

Ссылки:
1. Переход на драйвер nouveau с проприетарных драйверов nvidia
2. Enabling Randr12 support in nouveau
3. Kernel Mode-setting
4. http://cgit.freedesktop.org/nouveau/linux-2.6/tree/Documentation/fb/modedb.txt
5. Проблема со шрифтами в консоли...
6. Оптимизация initramfs в Debian
7. Отключение режима обнаружения TV драйвером NOUVEAU
8. Gentoo: переходим на Grub2
9. Не работает OpenGL в Debian(Nouveau)

Комментариев нет: