WWW.LUSHNIKOV.NET

linux

Разгоняем матрицу ноутбука с графикой от Intel под Linux.

С разгоном монитора никаких проблем нет. А вот с матрицей, подключенной к Intel HD, всё не так просто. Упрямый xorg берет параметры дисплея у модуля i915 (который читает их из EDID матрицы) и отказывается принимать любые другие значения. Значит, будем делать свой EDID и подсовывать его ядру вместо того EDID, который прописан в матрице.

Рекомендации даны на примере Debian 10.

1. Клонируем к себе генератор EDID-файлов и переходим в его каталог:

$ git clone https://github.com/akatrevorjay/edid-generator
$ cd edid-generator

2. Генерируем пачку Modeline с разными частотами обновления экрана. Edid-generator генерирует некорректные файлы (с длиной чуть больше 128 байт), если Modeline содержит несколько пробелов подряд. Поэтому убираем двойные пробелы. Заодно убираем лишние “.00” из названий режимов. У меня разрешение 1920×1080 и пробовать я буду частоты от 60 до 85. Поэтому строка такая:

$ for i in {60..85}; do cvt 1920 1080 $i | grep Modeline | sed -e 's/\.00"/"/' -e 's/  / /g' >> Modelines.txt; done

У меня получился такой файл:

Modeline "1920x1080_60" 173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
Modeline "1920x1080_61" 176.00 1920 2048 2248 2576 1080 1083 1088 1121 -hsync +vsync
Modeline "1920x1080_62" 179.00 1920 2048 2248 2576 1080 1083 1088 1122 -hsync +vsync
Modeline "1920x1080_63" 182.00 1920 2048 2248 2576 1080 1083 1088 1122 -hsync +vsync
Modeline "1920x1080_64" 185.00 1920 2048 2248 2576 1080 1083 1088 1123 -hsync +vsync
Modeline "1920x1080_65" 188.00 1920 2048 2248 2576 1080 1083 1088 1124 -hsync +vsync
Modeline "1920x1080_66" 192.00 1920 2056 2256 2592 1080 1083 1088 1124 -hsync +vsync
Modeline "1920x1080_67" 195.25 1920 2056 2256 2592 1080 1083 1088 1125 -hsync +vsync
Modeline "1920x1080_68" 198.25 1920 2056 2256 2592 1080 1083 1088 1126 -hsync +vsync
Modeline "1920x1080_69" 201.25 1920 2056 2256 2592 1080 1083 1088 1126 -hsync +vsync
Modeline "1920x1080_70" 204.25 1920 2056 2256 2592 1080 1083 1088 1127 -hsync +vsync
Modeline "1920x1080_71" 207.25 1920 2056 2256 2592 1080 1083 1088 1128 -hsync +vsync
Modeline "1920x1080_72" 210.25 1920 2056 2256 2592 1080 1083 1088 1128 -hsync +vsync
Modeline "1920x1080_73" 213.25 1920 2056 2256 2592 1080 1083 1088 1129 -hsync +vsync
Modeline "1920x1080_74" 217.75 1920 2064 2264 2608 1080 1083 1088 1129 -hsync +vsync
Modeline "1920x1080_75" 220.75 1920 2064 2264 2608 1080 1083 1088 1130 -hsync +vsync
Modeline "1920x1080_76" 224.00 1920 2064 2264 2608 1080 1083 1088 1131 -hsync +vsync
Modeline "1920x1080_77" 227.00 1920 2064 2264 2608 1080 1083 1088 1131 -hsync +vsync
Modeline "1920x1080_78" 230.00 1920 2064 2264 2608 1080 1083 1088 1132 -hsync +vsync
Modeline "1920x1080_79" 233.25 1920 2064 2264 2608 1080 1083 1088 1133 -hsync +vsync
Modeline "1920x1080_80" 236.25 1920 2064 2264 2608 1080 1083 1088 1133 -hsync +vsync
Modeline "1920x1080_81" 239.25 1920 2064 2264 2608 1080 1083 1088 1134 -hsync +vsync
Modeline "1920x1080_82" 242.50 1920 2064 2264 2608 1080 1083 1088 1135 -hsync +vsync
Modeline "1920x1080_83" 245.50 1920 2064 2264 2608 1080 1083 1088 1135 -hsync +vsync
Modeline "1920x1080_84" 250.25 1920 2064 2272 2624 1080 1083 1088 1136 -hsync +vsync
Modeline "1920x1080_85" 253.25 1920 2064 2272 2624 1080 1083 1088 1137 -hsync +vsync

3. Скармливаем эти строки генератору:

$ cat Modelines.txt | ./modeline2edid 
$ make

Через некоторое время в каталоге появится куча файлов. Нас интересуют только 1920x1080_*.bin. Копируем их в /lib/firmware/edid:

$ sudo mkdir -p /lib/firmware/edid
$ sudo cp 1920x1080_*.bin /lib/firmware/edid

4. Добавляем в параметры ядра загрузку нашего EDID. Для этого смотрим в xrandr название интерфейса, к которому подключена матрица (у меня это eDP-1), и пишем в /etc/default/grub:

GRUB_CMDLINE_LINUX="drm.edid_firmware=eDP-1:edid/1920x1080_60.bin"

Не забываем перегененировать конфиги бутлоадера:

$ sudo update-grub

5. Ядро будет пытаться загрузить EDID еще до того, как будет смонтирована корневая файловая система. Поэтому надо положить наши EDIDы в initrd. Ну и желательно сделать так, чтобы они туда автоматически попадали при каждом обновлении ядра.

Добавляем хук в initramfs-tools. Для этого создаём файл /etc/initramfs-tools/hooks/edid, делаем его исполняемым (это важно) и пишем в него:

#!/bin/sh
PREREQ=""
prereqs()
{
    echo "$PREREQ"
}

case $1 in
prereqs)
    prereqs
    exit 0
    ;;
esac

. /usr/share/initramfs-tools/hook-functions
# Begin real processing below this line
mkdir -p "${DESTDIR}/lib/firmware/edid"
cp -a /lib/firmware/edid/*.bin "${DESTDIR}/lib/firmware/edid/"

exit 0

Обновляем наш initrd:

$ sudo update-initramfs -u

6. Перезагружаемся и убеждаемся, что всё работает в штатном режиме. Должен загрузиться EDID со стандартной частотой 60Hz. При этом в dmesg не должно быть ошибок, связанных с загрузкой этого EDID. Если ошибки есть, значит на одном из предыдущих этапов что-то пошло не так. Читаем, гуглим, разбираемся.

7. Перезагружаемся еще раз и дожидаемся, когда grub нам предложит выбрать ядро. Нажимаем букву E, навигируем клавиатурными кнопками к той строке, в которой написано “1920x1080_60”, меняем 60 на ту частоту обновления экрана, с которой хотим попытаться загрузиться, и нажимаем Ctrl+X. Если после загрузки видим на экране картинку, то радуемся и либо на этом и успокаиваемся, либо продолжаем искать максимум. Если после загрузки видим на экране вертикальные полосы или другие неприятные спецэффекты, то перезагружаемся (хоть резетом) и уменьшаем частоту.

8. Прописываем в /etc/default/grub имя EDID-файла, содержащего ту частоту, на которой мы решили остановиться. Не забываем запускать update-grub.

Бонус. Как узнать текущую частоту матрицы. Отдельно стоящий монитор обычно умеет рисовать какое-нибудь информационное меню. Встроенная в ноутбук матрица не умеет. Но пара вариантов есть:

  1. запустить glxgears – opengl-бенчмарк, который по-умолчанию запускается с включенной вертикальной синхронизацией, поэтому показываемые им попугаи оказываются равны частоте обновления экрана
  2. почитать /sys/kernel/debug/dri/0/i915_display_info – в отличии от xrandr, этот файл не врёт и показывает действительно тот режим, в котором сейчас работает матрица

Еще бонус. Подробности по багу, из-за которого xorg не может поменять частоту без подмены EDID, можно почитать по этой ссылке.

Tags:

Leave a Reply