Monitor Dell 1707FP sin EDID por DisplayPort→DVI (pop-os)
pop-os (HP T640) corre tres monitores en el GPU integrado AMD Vega/Picasso (amdgpu): DP-1 (LG FHD, nativo), DP-2 (HP L1710, 1280×1024) y DP-3, un Dell 1707FP conectado por un adaptador DisplayPort→DVI. DP-3 quedaba atascado en 640×480 sin ofrecer ninguna resolución mayor en xrandr/cosmic-randr, aunque el cable estaba detectado (connected).
Causa
dmesg mostraba el error exacto en amdgpu:
[drm:dm_helpers_read_local_edid [amdgpu]] *ERROR* EDID err: 2, on connector: DP-3
amdgpu 0000:04:00.0: [drm] *ERROR* No EDID read.
/sys/class/drm/card1-DP-3/edid estaba en 0 bytes — el GPU nunca logra leer el EDID del monitor por el canal DDC/AUX a través del adaptador, aunque el hotplug (detección de cable) sí funciona. Sin EDID, el kernel usa una lista de modos de emergencia limitada a 640×480 y algunos modos aún menores, en vez de la lista completa de modos DMT que sí aparece en DP-1/DP-2.
Esto es el síntoma característico de un adaptador DP→DVI pasivo en un puerto DisplayPort que no es dual-mode (DP++), o de un adaptador/cable con el par DDC mal cableado: la señal de video (TMDS) puede pasar bien, pero el canal de datos que transporta el EDID no. No es un problema de configuración de resolución — es que el sistema nunca llega a saber qué resoluciones soporta el panel.
Fix: EDID sintético inyectado por firmware del kernel
Como la resolución nativa del panel ya se conocía (1280×1024, confirmado también porque DP-2 — un monitor físicamente igual, mismo tamaño 340×270mm — ya la reporta), la solución fue construir un EDID válido a mano con esa resolución y forzar al kernel a usarlo en vez de intentar leerlo del monitor.
1. Generar el EDID
scripts/edid/make-edid.py de este repo construye un EDID 1.3 (128 bytes, checksum correcto) a partir de fabricante, modelo, tamaño físico y un único detailed timing. Para el 1707FP se usó el timing DMT estándar de 1280×1024@60Hz:
python3 scripts/edid/make-edid.py \
--manufacturer DEL --model "DELL 1707FP" \
--width-mm 340 --height-mm 270 \
--hactive 1280 --vactive 1024 \
--pixel-clock-khz 108000 \
--hfp 48 --hsync 112 --hbp 248 \
--vfp 1 --vsync 3 --vbp 38 \
--out dell1707fp.bin
Validado con edid-decode dell1707fp.bin (paquete edid-decode de apt) antes de usarlo — debe listar el modo sin errores ni warnings.
2. Probar en caliente antes de tocar el arranque
amdgpu expone en debugfs un mecanismo de override por conector que no requiere reiniciar, útil para confirmar que el EDID sintético produce imagen real antes de persistir nada:
DBG=/sys/kernel/debug/dri/0000:04:00.0/DP-3
sudo bash -c "cat dell1707fp.bin > $DBG/edid_override"
sudo bash -c "echo on > $DBG/force" # fuerza 'connected', se salta la detección real
sudo bash -c "echo 0 > $DBG/trigger_hotplug" # simula desconexión...
sudo bash -c "echo 1 > $DBG/trigger_hotplug" # ...y reconexión, para que el compositor re-lea modos
El ciclo desconectar/reconectar es necesario — escribir el override solo no dispara un re-probe; cosmic-comp (y en general cualquier compositor Wayland) solo relee el conector en una transición real de estado. cosmic-randr list confirma el resultado: el conector pasa de reportar Physical Size: 0 x 0mm y un único modo 640×480 a Make: Dell Inc. / Model: DELL 1707FP, Physical Size: 340 x 270mm, con 1280×1024@60Hz como modo actual y preferido.
3. Persistir entre reinicios
El override de debugfs no sobrevive un reinicio. pop-os usa systemd-boot gestionado por kernelstub (Pop!_OS no usa GRUB), así que el parámetro de kernel se agrega así, no editando /etc/default/grub:
sudo cp dell1707fp.bin /lib/firmware/edid/dell1707fp.bin
sudo kernelstub --add-options "drm.edid_firmware=DP-3:edid/dell1707fp.bin"
kernelstub reescribe la entrada de systemd-boot en la ESP con la nueva cmdline. Falta un paso más: amdgpu.ko se carga desde el initramfs (KMS temprano, antes de montar el disco real), así que /lib/firmware/edid/dell1707fp.bin en disco no le sirve — tiene que estar empaquetado dentro del propio initramfs. Se agregó un hook (/etc/initramfs-tools/hooks/edid-dell1707fp, local a este host, no versionado en este repo) que copia el archivo con copy_file firmware ..., y luego:
sudo update-initramfs -u
Esto regenera el initrd con el EDID incluido y dispara automáticamente el hook zz-kernelstub que vuelve a copiar kernel+initrd a la ESP.
Reversión
sudo kernelstub -d "drm.edid_firmware=DP-3:edid/dell1707fp.bin"
No hay riesgo real al arranque: drm.edid_firmware solo afecta cómo se interpreta ese conector puntual, nunca impide que el kernel arranque.
Alcance del fix
Esto resuelve la identificación/negociación de modos, no la causa física — el canal DDC del adaptador sigue roto. Si el adaptador o el puerto DP cambian (otro puerto, otro cable), el mismo síntoma puede repetirse en otro conector (DP-x distinto) y hay que rehacer el override apuntando al conector nuevo. La solución de raíz sería reemplazar el adaptador pasivo por uno activo, o confirmar que el puerto es dual-mode (DP++) antes de usar uno pasivo.
Scripts reutilizables (scripts/edid/ de este repo)
make-edid.py es genérico — no está hardcodeado al 1707FP. Sirve para cualquier monitor futuro (en cualquier host) cuyo EDID real no se pueda leer pero cuya resolución nativa sí se conozca (por specs del fabricante o por comparación con otro monitor idéntico ya funcionando).
Véase también
- Escritorio personal — Pop!_OS / COSMIC — resto de la configuración de pop-os y minibook