Hi,
Since updating my snapshot machine last night, I'm seeing the folloing.
This is with one external monitor attached through the dock
(DisplayPort). The "timed out" lines appear when X starts and halt it
for a few minutes. Once X does come up, the error no longer appears. The
last line ("FIFO underrun") appeared about two minutes later during
regular operation.
OpenBSD 6.5-current (GENERIC.MP) #32: Thu May 16 09:45:13 MDT 2019
...
inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics 5500" rev 0x09
drm0 at inteldrm0
inteldrm0: msi
...
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* CPU pipe B FIFO underrun
Find full dmesg attached. I'm also attaching output from a program I
have lying around that dumps various drm info, especially the
monitor/output topology.*
Regards,
pesco
* It currently errors out on a GETPROPBLOB ioctl somewhere late, which
I would have to investigate, so the output is truncated - but the
important info should be there.
OpenBSD 6.5-current (GENERIC.MP) #32: Thu May 16 09:45:13 MDT 2019
[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 8277159936 (7893MB)
avail mem = 8016203776 (7644MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xacbfd000 (65 entries)
bios0: vendor LENOVO version "N10ET36W (1.15 )" date 06/19/2015
bios0: LENOVO 20CLS2LK00
acpi0 at bios0: rev 2
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP ASF! HPET ECDT APIC MCFG SSDT SSDT SSDT SSDT SSDT SSDT
SSDT SSDT SSDT PCCT SSDT TCPA SSDT UEFI POAT BATB FPDT UEFI DMAR
acpi0: wakeup devices LID_(S4) SLPB(S3) IGBE(S4) EXP2(S4) XHCI(S3) EHC1(S3)
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpihpet0 at acpi0: 14318179 Hz
acpiec0 at acpi0
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz, 2095.48 MHz, 06-3d-04
cpu0:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
cpu1 at mainbus0: apid 1 (application processor)
cpu1: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz, 2095.16 MHz, 06-3d-04
cpu1:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 1, core 0, package 0
cpu2 at mainbus0: apid 2 (application processor)
cpu2: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz, 2095.16 MHz, 06-3d-04
cpu2:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu2: 256KB 64b/line 8-way L2 cache
cpu2: smt 0, core 1, package 0
cpu3 at mainbus0: apid 3 (application processor)
cpu3: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz, 2095.16 MHz, 06-3d-04
cpu3:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,PT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,MELTDOWN
cpu3: 256KB 64b/line 8-way L2 cache
cpu3: smt 1, core 1, package 0
ioapic0 at mainbus0: apid 2 pa 0xfec00000, version 20, 40 pins
acpimcfg0 at acpi0
acpimcfg0: addr 0xf8000000, bus 0-63
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus -1 (PEG_)
acpiprt2 at acpi0: bus 2 (EXP1)
acpiprt3 at acpi0: bus 3 (EXP2)
acpiprt4 at acpi0: bus -1 (EXP3)
acpicpu0 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33),
C1(1000@1 mwait.1), PSS
acpicpu1 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33),
C1(1000@1 mwait.1), PSS
acpicpu2 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33),
C1(1000@1 mwait.1), PSS
acpicpu3 at acpi0: C3(200@233 mwait.1@0x40), C2(200@148 mwait.1@0x33),
C1(1000@1 mwait.1), PSS
acpipwrres0 at acpi0: PUBS, resource for XHCI, EHC1
acpipwrres1 at acpi0: NVP3, resource for PEG_
acpipwrres2 at acpi0: NVP2, resource for PEG_
acpitz0 at acpi0: critical temperature is 128 degC
acpibtn0 at acpi0: LID_
acpibtn1 at acpi0: SLPB
acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
acpicmos0 at acpi0
acpibat0 at acpi0: BAT0 model "45N1111" serial 16669 type LiP oem "SONY"
acpibat1 at acpi0: BAT1 model "45N1777" serial 3056 type LION oem "SANYO"
acpiac0 at acpi0: AC unit online
acpithinkpad0 at acpi0
tpm0 at acpi0: TPM_ addr 0xfed40000/0x5000, device 0x0000104a rev 0x4e
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"PNP0C14" at acpi0 not configured
"INT340F" at acpi0 not configured
acpivideo0 at acpi0: VID_
acpivout at acpivideo0 not configured
acpivideo1 at acpi0: VID_
cpu0: using VERW MDS workaround
cpu0: Enhanced SpeedStep 2095 MHz: speeds: 2201, 2200, 2100, 2000, 1800, 1700,
1600, 1500, 1300, 1200, 1100, 1000, 900, 700, 600, 500 MHz
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel Core 5G Host" rev 0x09
inteldrm0 at pci0 dev 2 function 0 "Intel HD Graphics 5500" rev 0x09
drm0 at inteldrm0
inteldrm0: msi
azalia0 at pci0 dev 3 function 0 "Intel Core 5G HD Audio" rev 0x09: msi
azalia0: No codecs found
xhci0 at pci0 dev 20 function 0 "Intel 9 Series xHCI" rev 0x03: msi, xHCI 1.0
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev 3.00/1.00
addr 1
"Intel 9 Series MEI" rev 0x03 at pci0 dev 22 function 0 not configured
em0 at pci0 dev 25 function 0 "Intel I218-LM" rev 0x03: msi, address
50:7b:9d:11:24:e8
azalia1 at pci0 dev 27 function 0 "Intel 9 Series HD Audio" rev 0x03: msi
azalia1: codecs: Realtek ALC292
audio0 at azalia1
ppb0 at pci0 dev 28 function 0 "Intel 9 Series PCIE" rev 0xe3: msi
pci1 at ppb0 bus 2
rtsx0 at pci1 dev 0 function 0 "Realtek RTS5227 Card Reader" rev 0x01: msi
sdmmc0 at rtsx0: 4-bit, dma
ppb1 at pci0 dev 28 function 1 "Intel 9 Series PCIE" rev 0xe3: msi
pci2 at ppb1 bus 3
iwm0 at pci2 dev 0 function 0 "Intel Dual Band Wireless AC 7265" rev 0x59, msi
pcib0 at pci0 dev 31 function 0 "Intel 9 Series LPC" rev 0x03
ahci0 at pci0 dev 31 function 2 "Intel 9 Series AHCI" rev 0x03: msi, AHCI 1.3
ahci0: port 0: 6.0Gb/s
scsibus1 at ahci0: 32 targets
sd0 at scsibus1 targ 0 lun 0: <ATA, Samsung SSD 850, EMT0> SCSI3 0/direct fixed
naa.5002538d40242fcb
sd0: 476940MB, 512 bytes/sector, 976773168 sectors, thin
ichiic0 at pci0 dev 31 function 3 "Intel 9 Series SMBus" rev 0x03: apic 2 int 18
iic0 at ichiic0
pchtemp0 at pci0 dev 31 function 6 "Intel 9 Series Thermal" rev 0x03
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
wsmouse1 at pms0 mux 0
pms0: Synaptics clickpad, firmware 8.1, 0x1e2b1 0x943300
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
vmm0 at mainbus0: VMX/EPT
uhub1 at uhub0 port 3 configuration 1 interface 0 "LENOVO Lenovo ThinkPad Dock"
rev 2.10/50.40 addr 2
uhidev0 at uhub1 port 2 configuration 1 interface 0 "Kensington Kensington
Slimblade Trackball" rev 1.10/1.05 addr 3
uhidev0: iclass 3/1
ums0 at uhidev0: 2 buttons, Z dir
wsmouse2 at ums0 mux 0
uhidev1 at uhub1 port 3 configuration 1 interface 0 "Holtek USB Keyboard" rev
1.10/1.10 addr 4
uhidev1: iclass 3/1
ukbd0 at uhidev1: 8 variable keys, 6 key codes
wskbd1 at ukbd0 mux 1
uhidev2 at uhub1 port 3 configuration 1 interface 1 "Holtek USB Keyboard" rev
1.10/1.10 addr 4
uhidev2: iclass 3/1, 2 report ids
uhid0 at uhidev2 reportid 1: input=6, output=0, feature=0
uhid1 at uhidev2 reportid 2: input=1, output=0, feature=0
uhub2 at uhub1 port 4 configuration 1 interface 0 "Lenovo Lenovo ThinkPad Dock"
rev 2.00/0.01 addr 5
ugen0 at uhub0 port 5 "Generic EMV Smartcard Reader" rev 2.01/1.20 addr 6
usbd_free_xfer: xfer=0xfffffd824d855960 not free
ugen0: setting configuration index 0 failed
ugen1 at uhub0 port 6 "Validity Sensors VFS5011 Fingerprint Reader" rev
1.10/0.78 addr 7
ugen2 at uhub0 port 7 "Intel Bluetooth" rev 2.01/0.01 addr 8
uhub3 at uhub0 port 14 configuration 1 interface 0 "LENOVO Lenovo ThinkPad
Dock" rev 3.00/50.41 addr 9
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
sd1 at scsibus3 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006> SCSI2 0/direct fixed
sd1: 409599MB, 512 bytes/sector, 838860209 sectors
root on sd1a (1aebccd650f38400.a) swap on sd1b dump on sd1b
inteldrm0: 1920x1080, 32bpp
wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
wskbd1: connecting to wsdisplay0
wsdisplay0: screen 1-5 added (std, vt100 emulation)
iwm0: hw rev 0x210, fw ver 16.242414.0, address 94:65:9c:46:8a:f2
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:39:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:51:pipe ] cleanup_done timed out
[drm] *ERROR* [CRTC:63:pipe ] cleanup_done timed out
[drm] *ERROR* CPU pipe B FIFO underrun
/dev/drm0:
drm v1.6.0, driver i915, Intel Graphics (20180719)
auth id (magic number): 4
bus id string: pci:0000:00:02.0
device 2, function 0 at pci bus 0, domain 0
vendor 8086, device 1616, subvendor 17aa, subdevice 2226
revision 0
capabilities:
DUMB_BUFFER = 1
VBLANK_HIGH_CRTC = 1
DUMB_PREFERRED_DEPTH = 24
DUMB_PREFER_SHADOW = 1
PRIME = IMPORT, EXPORT
TIMESTAMP_MONOTONIC = 1
ASYNC_PAGE_FLIP = 0
CURSOR_WIDTH = 256
CURSOR_HEIGHT = 256
set client capabilities:
vblank no. 414576 reached at time 6922.895168s, waited 0.006048104s
period 16.6ms, freq 60Hz
modesetting: kernel
3 crtcs, 10 connectors, 9 encoders, 0 framebuffers, 9 planes
min width 0, max width 8192
min height 0, max height 8192
crtc 39: framebuffer 98, x-offset 1920
mode 1920x1080 60.04Hz PHSYNC NVSYNC
2106x1095 hsync 1968-2000 vsync 1083-1088, pixel clock 138460kHz
fbuf 3840x1200 32 bpp, pitch 15360, depth 24, driver handle 1
properties:
ACTIVE: 1 (0 - 1) RANGE
MODE_ID: BLOB
OUT_FENCE_PTR: 136 (0 - 18446744073709551615) RANGE
DEGAMMA_LUT: BLOB
DEGAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
CTM: BLOB
GAMMA_LUT: BLOB
GAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
crtc 51: framebuffer 98
mode 1920x1200 59.95Hz PHSYNC NVSYNC
2080x1235 hsync 1968-2000 vsync 1203-1209, pixel clock 154000kHz
fbuf 3840x1200 32 bpp, pitch 15360, depth 24, driver handle 2
properties:
ACTIVE: 1 (0 - 1) RANGE
MODE_ID: BLOB
OUT_FENCE_PTR: 132 (0 - 18446744073709551615) RANGE
DEGAMMA_LUT: BLOB
DEGAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
CTM: BLOB
GAMMA_LUT: BLOB
GAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
crtc 63: framebuffer 0, no mode
properties:
ACTIVE: 0 (0 - 1) RANGE
MODE_ID: BLOB
OUT_FENCE_PTR: 0 (0 - 18446744073709551615) RANGE
DEGAMMA_LUT: BLOB
DEGAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
CTM: BLOB
GAMMA_LUT: BLOB
GAMMA_LUT_SIZE: 0 (0 - 4294967295) IMMUTABLE RANGE
connector 65: eDP, connected, 280mm x 160mm
valid encoders: 64
mode 1920x1080 ("1920x1080") 60.04Hz ("60Hz") PREFERRED DRIVER PHSYNC
NVSYNC
2106x1095 hsync 1968-2000 vsync 1083-1088, pixel clock 138460kHz
properties:
EDID:
"\x00\xff\xff\xff\xff\xff\xff\x000\xe47\x04\x00\x00\x00\x00\x00\x17\x01\x04\x95\x1c\x10x\x02\xbf\x05\x9aYU\x8e&\x1dPT\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x166\x80\xbap8\x0f@0
5\x00\x14\x9c\x10\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x00LG
Display\x0a \x00\x00\x00\xfe\x00LP125WF2-SPB2\x00\xdd" IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 39 (flags=0x80000040, count_values=1) OBJECT
Broadcast RGB: [Automatic], Full, Limited 16:235 ENUM
scaling mode: Full, Center, [Full aspect] ENUM
Backlight: 12 (0 - 15) RANGE
connector 72: DisplayPort, disconnected
valid encoders: 71
properties:
EDID: IMMUTABLE BLOB
DPMS: On, Standby, Suspend, [Off] ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
audio: force-dvi, off, [auto], on ENUM
Broadcast RGB: [Automatic], Full, Limited 16:235 ENUM
Content Protection: [Undesired], Desired, Enabled ENUM
connector 78: HDMIA, disconnected
valid encoders: 71
properties:
EDID: IMMUTABLE BLOB
DPMS: On, Standby, Suspend, [Off] ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
audio: force-dvi, off, [auto], on ENUM
Broadcast RGB: [Automatic], Full, Limited 16:235 ENUM
aspect ratio: [Automatic], 4:3, 16:9 ENUM
content type: [No Data], Graphics, Photo, Cinema, Game ENUM
Content Protection: [Undesired], Desired, Enabled ENUM
connector 83: DisplayPort, disconnected
valid encoders: 82
properties:
EDID: IMMUTABLE BLOB
DPMS: On, Standby, Suspend, [Off] ENUM
link-status: Good, [Bad] ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
audio: force-dvi, off, [auto], on ENUM
Broadcast RGB: [Automatic], Full, Limited 16:235 ENUM
Content Protection: [Undesired], Desired, Enabled ENUM
connector 88: HDMIA, disconnected
valid encoders: 82
properties:
EDID: IMMUTABLE BLOB
DPMS: On, Standby, Suspend, [Off] ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
audio: force-dvi, off, [auto], on ENUM
Broadcast RGB: [Automatic], Full, Limited 16:235 ENUM
aspect ratio: [Automatic], 4:3, 16:9 ENUM
content type: [No Data], Graphics, Photo, Cinema, Game ENUM
Content Protection: [Undesired], Desired, Enabled ENUM
connector 94: DisplayPort, connected, 520mm x 320mm
valid encoders: 84 85 86
mode 1920x1200 ("1920x1200") 59.95Hz ("60Hz") PREFERRED DRIVER PHSYNC
NVSYNC
2080x1235 hsync 1968-2000 vsync 1203-1209, pixel clock 154000kHz
mode 1920x1080 ("1920x1080") 60.00Hz ("60Hz") DRIVER PHSYNC PVSYNC
2200x1125 hsync 2008-2052 vsync 1084-1089, pixel clock 148500kHz
mode 1920x1080 ("1920x1080") 60.00Hz ("60Hz") DRIVER PHSYNC PVSYNC
2200x1125 hsync 2008-2052 vsync 1084-1089, pixel clock 148500kHz
mode 1920x1080 ("1920x1080") 59.94Hz ("60Hz") DRIVER PHSYNC PVSYNC
2200x1125 hsync 2008-2052 vsync 1084-1089, pixel clock 148352kHz
mode 1920x1080 ("1920x1080") 50.00Hz ("50Hz") DRIVER PHSYNC PVSYNC
2640x1125 hsync 2448-2492 vsync 1084-1089, pixel clock 148500kHz
mode 1920x1080 ("1920x1080") 24.00Hz ("24Hz") DRIVER PHSYNC PVSYNC
2750x1125 hsync 2558-2602 vsync 1084-1089, pixel clock 74250kHz
mode 1920x1080 ("1920x1080") 23.98Hz ("24Hz") DRIVER PHSYNC PVSYNC
2750x1125 hsync 2558-2602 vsync 1084-1089, pixel clock 74176kHz
mode 1600x1200 ("1600x1200") 60.00Hz ("60Hz") DRIVER PHSYNC PVSYNC
2160x1250 hsync 1664-1856 vsync 1201-1204, pixel clock 162000kHz
mode 1280x1024 ("1280x1024") 75.02Hz ("75Hz") DRIVER PHSYNC PVSYNC
1688x1066 hsync 1296-1440 vsync 1025-1028, pixel clock 135000kHz
mode 1280x1024 ("1280x1024") 60.02Hz ("60Hz") DRIVER PHSYNC PVSYNC
1688x1066 hsync 1328-1440 vsync 1025-1028, pixel clock 108000kHz
mode 1152x864 ("1152x864") 75.00Hz ("75Hz") DRIVER PHSYNC PVSYNC
1600x900 hsync 1216-1344 vsync 865-868, pixel clock 108000kHz
mode 1280x720 ("1280x720") 60.00Hz ("60Hz") DRIVER PHSYNC PVSYNC
1650x750 hsync 1390-1430 vsync 725-730, pixel clock 74250kHz
mode 1280x720 ("1280x720") 60.00Hz ("60Hz") DRIVER PHSYNC PVSYNC
1650x750 hsync 1390-1430 vsync 725-730, pixel clock 74250kHz
mode 1280x720 ("1280x720") 59.94Hz ("60Hz") DRIVER PHSYNC PVSYNC
1650x750 hsync 1390-1430 vsync 725-730, pixel clock 74176kHz
mode 1280x720 ("1280x720") 50.00Hz ("50Hz") DRIVER PHSYNC PVSYNC
1980x750 hsync 1720-1760 vsync 725-730, pixel clock 74250kHz
mode 1024x768 ("1024x768") 75.03Hz ("75Hz") DRIVER PHSYNC PVSYNC
1312x800 hsync 1040-1136 vsync 769-772, pixel clock 78750kHz
mode 1024x768 ("1024x768") 60.00Hz ("60Hz") DRIVER NHSYNC NVSYNC
1344x806 hsync 1048-1184 vsync 771-777, pixel clock 65000kHz
mode 800x600 ("800x600") 75.00Hz ("75Hz") DRIVER PHSYNC PVSYNC
1056x625 hsync 816-896 vsync 601-604, pixel clock 49500kHz
mode 800x600 ("800x600") 60.32Hz ("60Hz") DRIVER PHSYNC PVSYNC
1056x628 hsync 840-968 vsync 601-605, pixel clock 40000kHz
mode 720x576 ("720x576") 50.00Hz ("50Hz") DRIVER NHSYNC NVSYNC
864x625 hsync 732-796 vsync 581-586, pixel clock 27000kHz
mode 720x576 ("720x576") 50.00Hz ("50Hz") DRIVER NHSYNC NVSYNC
864x625 hsync 732-796 vsync 581-586, pixel clock 27000kHz
mode 720x480 ("720x480") 60.00Hz ("60Hz") DRIVER NHSYNC NVSYNC
858x525 hsync 736-798 vsync 489-495, pixel clock 27027kHz
mode 720x480 ("720x480") 60.00Hz ("60Hz") DRIVER NHSYNC NVSYNC
858x525 hsync 736-798 vsync 489-495, pixel clock 27027kHz
mode 720x480 ("720x480") 59.94Hz ("60Hz") DRIVER NHSYNC NVSYNC
858x525 hsync 736-798 vsync 489-495, pixel clock 27000kHz
mode 720x480 ("720x480") 59.94Hz ("60Hz") DRIVER NHSYNC NVSYNC
858x525 hsync 736-798 vsync 489-495, pixel clock 27000kHz
mode 720x480 ("720x480") 59.94Hz ("60Hz") DRIVER NHSYNC NVSYNC
858x525 hsync 736-798 vsync 489-495, pixel clock 27000kHz
mode 640x480 ("640x480") 75.00Hz ("75Hz") DRIVER NHSYNC NVSYNC
840x500 hsync 656-720 vsync 481-484, pixel clock 31500kHz
mode 640x480 ("640x480") 60.00Hz ("60Hz") DRIVER NHSYNC NVSYNC
800x525 hsync 656-752 vsync 490-492, pixel clock 25200kHz
mode 640x480 ("640x480") 59.94Hz ("60Hz") DRIVER NHSYNC NVSYNC
800x525 hsync 656-752 vsync 490-492, pixel clock 25175kHz
mode 640x480 ("640x480") 59.94Hz ("60Hz") DRIVER NHSYNC NVSYNC
800x525 hsync 656-752 vsync 490-492, pixel clock 25175kHz
mode 720x400 ("720x400") 70.08Hz ("70Hz") DRIVER NHSYNC PVSYNC
900x449 hsync 738-846 vsync 412-414, pixel clock 28320kHz
properties:
EDID:
"\x00\xff\xff\xff\xff\xff\xff\x00\x10\xacF\xf0LKKA-\x19\x01\x04\xb54
x:\x1d\xf5\xaeO5\xb3%\x0dPT\xa5K\x00\x81\x80\xa9@\xd1\x00qO\x01\x01\x01\x01\x01\x01\x01\x01(<\x80\xa0p\xb0#@0
6\x00\x06D!\x00\x00\x1a\x00\x00\x00\xff\x0084K965B6AKKL\x0a\x00\x00\x00\xfc\x00DELL
U2413\x0a \x00\x00\x00\xfd\x008L\x1eQ\x11\x00\x0a
\x01(\x02\x03\x1d\xf1P\x90\x05\x04\x03\x02\x07\x16\x01\x1f\x12\x13\x14
\x15\x11\x06#\x09\x1f\x07\x83\x01\x00\x00\x02:\x80\x18q8-@X,E\x00\x06D!\x00\x00\x1e\x01\x1d\x80\x18q\x1c\x16
X,%\x00\x06D!\x00\x00\x9e\x01\x1d\x00rQ\xd0\x1e
n(U\x00\x06D!\x00\x00\x1e\x8c\x0a\xd0\x8a
\xe0-\x10\x10>\x96\x00\x06D!\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09"
IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 51 (flags=0x80000040, count_values=1) OBJECT
PATH: "mst:83-1-8\x00" IMMUTABLE BLOB
TILE: IMMUTABLE BLOB
connector 96: DisplayPort, disconnected
valid encoders: 84 85 86
properties:
EDID: IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
PATH: "mst:83-1-1\x00" IMMUTABLE BLOB
TILE: IMMUTABLE BLOB
connector 93: DisplayPort, disconnected
valid encoders: 84 85 86
properties:
EDID: IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
PATH: "mst:83-1\x00" IMMUTABLE BLOB
TILE: IMMUTABLE BLOB
connector 120: DisplayPort, disconnected
valid encoders: 84 85 86
properties:
EDID: IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
PATH: "mst:83-2\x00" IMMUTABLE BLOB
TILE: IMMUTABLE BLOB
connector 126: DisplayPort, disconnected
valid encoders: 84 85 86
properties:
EDID: IMMUTABLE BLOB
DPMS: [On], Standby, Suspend, Off ENUM
link-status: [Good], Bad ENUM
non-desktop: 0 (0 - 1) IMMUTABLE RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
PATH: "mst:83-3\x00" IMMUTABLE BLOB
TILE: IMMUTABLE BLOB
encoder 64: TMDS, active on crtc 39
possible crtcs: 39 51 63
possible clones: 64
encoder 71: TMDS, inactive
possible crtcs: 39 51 63
possible clones: 71
encoder 73: DPMST, inactive
possible crtcs: 39 51 63
possible clones: 73
encoder 74: DPMST, inactive
possible crtcs: 39 51 63
possible clones: 74
encoder 75: DPMST, inactive
possible crtcs: 39 51 63
possible clones: 75
encoder 82: TMDS, inactive
possible crtcs: 39 51 63
possible clones: 82
encoder 84: DPMST, inactive
possible crtcs: 39 51 63
possible clones: 84
encoder 85: DPMST, active on crtc 51
possible crtcs: 39 51 63
possible clones: 85
encoder 86: DPMST, inactive
possible crtcs: 39 51 63
possible clones: 86
plane 28: active on crtc 39 using framebuffer 98
possible crtcs: 39
supported formats: C8 RG16 XR24 XB24 XR30 XB30
properties:
type: Overlay, [Primary], Cursor IMMUTABLE ENUM
FB_ID: 0 (flags=0x80000040, count_values=1) OBJECT
IN_FENCE_FD: 98 (flags=0x80000080, count_values=2) SIGNED_RANGE
CRTC_ID: 0 (flags=0x80000040, count_values=1) OBJECT
CRTC_X: 4294967295 (flags=0x80000080, count_values=2) SIGNED_RANGE
CRTC_Y: 4294967295 (flags=0x80000080, count_values=2) SIGNED_RANGE
CRTC_W: 39 (0 - 2147483647) RANGE
CRTC_H: 0 (0 - 2147483647) RANGE
SRC_X: 0 (0 - 4294967295) RANGE
SRC_Y: 0 (0 - 4294967295) RANGE
SRC_W: 0 (0 - 4294967295) RANGE
SRC_H: 0 (0 - 4294967295) RANGE
IN_FORMATS:
// drminfo - interrogate kernel graphics driver
// pesco 2018
#include <fcntl.h>
#include <sys/ioctl.h>
#include <err.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <inttypes.h>
#include <ctype.h>
#include <errno.h>
#include "drm.h"
#include <unistd.h>
// XXX from dev/pci/drm/drm_crtc.h
enum drm_connector_status {
connector_status_connected = 1,
connector_status_disconnected = 2,
connector_status_unknown = 3,
};
#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
#define DRM_MODE_OBJECT_MODE 0xdededede
#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
#define DRM_MODE_OBJECT_ANY 0
// The following ioctls declared in drm.h are Linux-only:
//
// IRQ_BUSID
// GET_MAP
// GET_CLIENT
// GET_STATS
//
// ADD_MAP
// RM_MAP
//
// SET_SAREA_CTX (noop on other systems)
// GET_SAREA_CTX (noop)
//
// SET_MASTER (noop)
// DROP_MASTER (noop)
//
// ADD_CTX
// RM_CTX
// GET_CTX
// SWITCH_CTX (noop)
// NEW_CTX (noop)
// RES_CTX
//
// LOCK
// UNLOCK
//
// ADD_BUFS
// MARK_BUFS (noop)
// INFO_BUFS (noop)
// MAP_BUFS
// FREE_BUFS
// DMA
//
// CONTROL
//
// AGP_ACQUIRE
// AGP_RELEASE
// AGP_ENABLE
// AGP_INFO
// AGP_ALLOC
// AGP_FREE
// AGP_BIND
// AGP_UNBIND
//
// SG_ALLOC
// SG_FREE
// The following ioctls are unimplemented in general (as of OpenBSD 6.4):
//
// BLOCK (noop)
// UNBLOCK (noop)
//
// MOD_CTX (noop)
//
// ADD_DRAW (noop)
// RM_DRAW (noop)
//
// FINISH (noop)
//
// UPDATE_DRAW (noop)
//
// ATTACHMODE (noop)
// DETACHMODE (noop)
//
// ATOMIC (missing from ioctl table)
// CREATEPROPBLOB (missing)
// DESTROYPROPBLOB (missing)
// This leaves as our actual API:
//
// VERSION
// get API and driver version info
// GET_UNIQUE
// get a unique "bus id" string for the device
// GET_MAGIC
// get an id ("magic number") for this client for authentication purposes
// GET_CAP
// query device capabiliities
// SET_CLIENT_CAP
// enable specific driver features for this client
// SET_VERSION
// demand a certain major/minor version
//
// SET_UNIQUE
// deprecated since drm v1.1, always fails with EBUSY
// AUTH_MAGIC
// mark the client with the given magic number as authenticated
//
// GET_PCIINFO (OpenBSD only)
// get detailed PCI bus location and identification of the device
//
// WAIT_VBLANK
// wait for a vertical retrace, with various options
//
// MODESET_CTL
// used by user-space drivers to signal when they perform modesetting
//
// GEM_CLOSE
// GEM_FLINK
// GEM_OPEN
//
// PRIME_HANDLE_TO_FD
// convert handle of a shareable buffer to a file descriptor
// PRIME_FD_TO_HANDLE
// convert a file descriptor back to a buffer handle
//
// MODE_GETRESOURCES
// get number and ids of framebuffers, crtcs, encoders, connectors
// MODE_GETPLANERESOURCES
// get number and ids of image planes
// MODE_GETCRTC
// get configuration of a given CRTC
// MODE_SETCRTC
// modify configuration of a given CRTC
// MODE_GETPLANE
// get configuration of a given plane
// MODE_SETPLANE
// modify configuration of a given plane
// MODE_CURSOR
// set CRTC's cursor configuration
// MODE_CURSOR2
// set CRTC's cursor configuration, including cursor "hotspot"
// MODE_GETGAMMA
// get the gamma table
// MODE_SETGAMMA
// set the gamma table
// MODE_GETENCODER
// get encoder configuration
// MODE_GETCONNECTOR
// get connector configuration
// MODE_ATTACHMODE
// MODE_DETACHMODE
// MODE_GETPROPERTY
// get property metadata (name, value range, etc.)
// MODE_SETPROPERTY
// set property values on connector objects
// MODE_GETPROPBLOB
// get the value of a "blob"-type property
// MODE_GETFB
// get framebuffer configuration
// MODE_ADDFB
// MODE_ADDFB2
// MODE_RMFB
// MODE_PAGE_FLIP
// switch a crtc to a different framebuffer
// MODE_DIRTYFB
// request a framebuffer redraw on hardware that doesn't do so automatically
// MODE_CREATE_DUMB
// MODE_MAP_DUMB
// MODE_DESTROY_DUMB
// MODE_OBJ_GETPROPERTIES
// get properties of various driver objects
// MODE_OBJ_SETPROPERTY
// modify properties of various driver objects
uint32_t *fb_ids, *crtc_ids, *connector_ids, *encoder_ids, *plane_ids;
int nfbs, ncrtcs, nconnectors, nencoders, nplanes;
int devfd;
#define ioc(req,arg) if(ioctl(devfd, DRM_IOCTL_##req, arg) < 0) err(1, #req)
#define PU PRIu32
void *alloc(size_t nmemb, size_t size)
{
void *p = calloc(nmemb, size);
if(!p) err(1, "alloc");
return p;
}
void print_modeinfo(struct drm_mode_modeinfo m);
void print_obj_properties(uint32_t obj_id, uint32_t obj_type);
void print_property(uint32_t prop, uint64_t value);
void print_byte(uint8_t c);
void print_framebuffer(uint32_t fb_id);
void print_fbinfo(struct drm_mode_fb_cmd f);
int main(int argc, char **argv)
{
const char *file = "/dev/drm0";
if(argc>1)
file = argv[1];
if((devfd = open(file, O_RDWR)) < 0)
err(1, "%s", file);
printf("%s:\n", file);
// VERSION
{
char name[100], date[100], desc[100];
struct drm_version v;
v.name_len = sizeof(name)-1;
v.date_len = sizeof(date)-1;
v.desc_len = sizeof(desc)-1;
v.name = name;
v.date = date;
v.desc = desc;
ioc(VERSION, &v);
v.name[v.name_len] = '\0';
v.date[v.date_len] = '\0';
v.desc[v.desc_len] = '\0';
printf(" drm v%d.%d.%d, driver %s, %s (%s)\n",
v.version_major, v.version_minor, v.version_patchlevel,
v.name, v.desc, v.date);
}
// GET_MAGIC
// AUTH_MAGIC
{
struct drm_auth auth;
ioc(GET_MAGIC, &auth);
printf(" auth id (magic number): %u\n", auth.magic);
int r = ioctl(devfd, DRM_IOCTL_AUTH_MAGIC, &auth);
perror(" authenticate self");
}
// GET_UNIQUE
{
char unique[100];
struct drm_unique u;
u.unique_len = sizeof(unique)-1;
u.unique = unique;
ioc(GET_UNIQUE, &u);
printf(" bus id string: %s\n", u.unique);
}
// GET_PCIINFO
{
struct drm_pciinfo pi;
ioc(GET_PCIINFO, &pi);
printf(" device %d, function %d at pci bus %d, domain %d\n",
(int)pi.dev, (int)pi.func, (int)pi.bus, (int)pi.domain);
printf(" vendor %04x, device %04x, subvendor %04x, subdevice %04x\n",
(unsigned)pi.vendor_id, (unsigned)pi.device_id,
(unsigned)pi.subvendor_id, (unsigned)pi.subdevice_id);
printf(" revision %d\n", (int)pi.revision_id);
}
// GET_CAP
{
struct drm_get_cap gc;
#define printcap(cap) do { \
gc.capability = DRM_CAP_##cap; \
ioc(GET_CAP, &gc); \
printf(" %-20s = %lld\n", #cap, (long long)gc.value); \
} while(0)
printf(" capabilities:\n");
printcap(DUMB_BUFFER);
printcap(VBLANK_HIGH_CRTC);
printcap(DUMB_PREFERRED_DEPTH);
printcap(DUMB_PREFER_SHADOW);
gc.capability = DRM_CAP_PRIME;
ioc(GET_CAP, &gc);
printf(" %-20s = %s%s\n", "PRIME",
gc.value & DRM_PRIME_CAP_IMPORT ? "IMPORT, " : "",
gc.value & DRM_PRIME_CAP_EXPORT ? "EXPORT" : "");
printcap(TIMESTAMP_MONOTONIC);
printcap(ASYNC_PAGE_FLIP);
printcap(CURSOR_WIDTH);
printcap(CURSOR_HEIGHT);
#undef printcap
}
// SET_CLIENT_CAP
{
struct drm_set_client_cap c;
#define setcap(cap) do { \
c.capability = DRM_CLIENT_CAP_##cap; \
c.value = 1; \
ioctl(devfd, DRM_IOCTL_SET_CLIENT_CAP, &c); \
perror(" " #cap); \
} while(0)
printf(" set client capabilities:\n");
setcap(STEREO_3D);
setcap(UNIVERSAL_PLANES);
setcap(ATOMIC);
#undef setcap
}
// WAIT_VBLANK
{
union drm_wait_vblank vb;
struct timespec t0,t1;
vb.request.type = _DRM_VBLANK_RELATIVE;
vb.request.sequence = 1;
clock_gettime(CLOCK_MONOTONIC, &t0);
ioc(WAIT_VBLANK, &vb);
clock_gettime(CLOCK_MONOTONIC, &t1);
printf(" vblank no. %u reached at time %ld.%06lds, waited
%lld.%09lds\n",
vb.reply.sequence, vb.reply.tval_sec, vb.reply.tval_usec,
t1.tv_sec-t0.tv_sec, t1.tv_nsec-t0.tv_nsec);
vb.request.type = _DRM_VBLANK_RELATIVE | _DRM_VBLANK_NEXTONMISS;
vb.request.sequence = 1;
ioc(WAIT_VBLANK, &vb);
vb.request.sequence++;
clock_gettime(CLOCK_MONOTONIC, &t0);
ioc(WAIT_VBLANK, &vb);
clock_gettime(CLOCK_MONOTONIC, &t1);
double period = (t1.tv_nsec-t0.tv_nsec)/100000/10.0;
printf(" period %.1fms, freq %.0fHz\n", period, round(1000/period));
}
// MODESET_CTL
{
struct drm_modeset_ctl c = {.crtc=0, .cmd=0};
// with KMS, this ioctl is a no-op for any argument.
// cmd=0 is invalid, so with user-space modesetting, it will fail
int r = ioctl(devfd, DRM_IOCTL_MODESET_CTL, &c);
printf(" modesetting: %s\n", r<0 ? "user space" : "kernel");
}
// === begin KMS stuff ===
// MODE_GETRESOURCES
// MODE_GETPLANERESOURCES
{
struct drm_mode_card_res r = {0};
#define doalloc(what) do { \
n##what##s = r.count_##what##s; \
what##_ids = alloc(n##what##s, sizeof(*what##_ids)); \
r.what##_id_ptr = (uintptr_t)what##_ids; \
} while(0)
ioc(MODE_GETRESOURCES, &r);
doalloc(fb);
doalloc(crtc);
doalloc(encoder);
doalloc(connector);
ioc(MODE_GETRESOURCES, &r);
{
struct drm_mode_get_plane_res r = {0};
ioc(MODE_GETPLANERESOURCES, &r);
doalloc(plane);
ioc(MODE_GETPLANERESOURCES, &r);
}
#undef doalloc
printf(" %"PU" crtcs, %"PU" connectors, %"PU" encoders, "
"%"PU" framebuffers, %"PU" planes\n"
" min width %u, max width %u\n"
" min height %u, max height %u\n",
ncrtcs, nconnectors, nencoders,
nfbs, nplanes,
r.min_width, r.max_width,
r.min_height, r.max_height);
}
// MODE_GETCRTC
// MODE_GETFB
// MODE_OBJ_GETPROPERTIES
{
struct drm_mode_crtc c;
for(int i=0; i<ncrtcs; i++) {
c.crtc_id = crtc_ids[i];
printf(" crtc %"PU": ", c.crtc_id);
ioc(MODE_GETCRTC, &c);
// NB: set_connectors_ptr and count_connectors are for SETCRTC
printf("framebuffer %"PU, c.fb_id);
if(c.x || c.y) printf(",");
if(c.x) printf(" x-offset %"PU, c.x);
if(c.y) printf(" y-offset %"PU, c.y);
if(c.mode_valid) {
printf("\n");
print_modeinfo(c.mode);
} else {
printf(", no mode\n");
}
if(c.fb_id) {
printf(" fbuf ");
print_framebuffer(c.fb_id);
}
print_obj_properties(c.crtc_id, DRM_MODE_OBJECT_CRTC);
}
}
// MODE_GETCONNECTOR
// MODE_GETPROPERTY
// MODE_GETPROPBLOB
{
struct drm_mode_get_connector c;
const char *type, *status;
for(int i=0; i<nconnectors; i++) {
c.encoders_ptr = c.modes_ptr = c.props_ptr = c.prop_values_ptr = 0;
c.count_modes = c.count_props = c.count_encoders = 0;
c.connector_id = connector_ids[i];
ioc(MODE_GETCONNECTOR, &c);
type = status = "*unrecognized*";
switch(c.connector_type) {
#define docase(T) case DRM_MODE_CONNECTOR_##T: type = #T; break;
docase(Unknown)
docase(VGA)
docase(DVII)
docase(DVID)
docase(DVIA)
docase(Composite)
docase(SVIDEO)
docase(LVDS)
docase(Component)
docase(9PinDIN)
docase(DisplayPort)
docase(HDMIA)
docase(HDMIB)
docase(TV)
docase(eDP)
docase(VIRTUAL)
docase(DSI)
#undef docase
}
switch(c.connection) {
case connector_status_connected: status = "connected"; break;
case connector_status_disconnected: status = "disconnected";
break;
case connector_status_unknown: status = "unknown status"; break;
}
printf(" connector %"PU": %s, %s", c.connector_id, type, status);
if(c.mm_width || c.mm_height)
printf(", %"PU"mm x %"PU"mm", c.mm_width, c.mm_height);
printf("\n");
// XXX how to use this?
//printf(" connector type id: %"PU"\n", c.connector_type_id);
if(c.subpixel)
printf(" subpixel layout: %"PU"\n", c.subpixel);
// get encoders, modes, props
c.encoders_ptr = (uintptr_t)alloc(c.count_encoders,
sizeof(uint32_t));
c.modes_ptr = (uintptr_t)alloc(c.count_modes, sizeof(struct
drm_mode_modeinfo));
c.props_ptr = (uintptr_t)alloc(c.count_props, sizeof(uint32_t));
c.prop_values_ptr = (uintptr_t)alloc(c.count_props,
sizeof(uint64_t));
ioc(MODE_GETCONNECTOR, &c);
printf(" valid encoders:");
for(int j=0; j<c.count_encoders; j++)
printf(" %"PU, ((uint32_t *)c.encoders_ptr)[j]);
printf("\n");
for(int j=0; j<c.count_modes; j++)
print_modeinfo(((struct drm_mode_modeinfo *)c.modes_ptr)[j]);
if(c.count_props > 0) {
uint32_t *props = (uint32_t *)c.props_ptr;
uint64_t *values = (uint64_t *)c.prop_values_ptr;
printf(" properties:\n");
for(int j=0; j<c.count_props; j++)
print_property(props[j], values[j]);
}
}
}
// MODE_GETENCODER
{
struct drm_mode_get_encoder e;
const char *type;
for(int i=0; i<nencoders; i++) {
e.encoder_id = encoder_ids[i];
ioc(MODE_GETENCODER, &e);
type = "*unrecognized*";
switch(e.encoder_type) {
#define docase(T) case DRM_MODE_ENCODER_##T: type = #T; break;
docase(NONE)
docase(DAC)
docase(TMDS)
docase(LVDS)
docase(TVDAC)
docase(VIRTUAL)
docase(DSI)
docase(DPMST)
#undef docase
}
printf(" encoder %"PU": %s, ", e.encoder_id, type);
if(e.crtc_id)
printf("active on crtc %"PU"\n", e.crtc_id);
else
printf("inactive\n");
printf(" possible crtcs:");
for(int j=0; j<32; j++)
if(e.possible_crtcs & (1UL<<j))
printf(" %d", crtc_ids[j]);
printf("\n");
printf(" possible clones:");
for(int j=0; j<32; j++)
if(e.possible_clones & (1UL<<j))
printf(" %d", encoder_ids[j]);
printf("\n");
print_obj_properties(e.encoder_id, DRM_MODE_OBJECT_ENCODER);
}
}
// MODE_GETFB
{
for(int i=0; i<nfbs; i++) {
printf(" framebuffer %"PU": ", fb_ids[i]);
print_framebuffer(fb_ids[i]);
}
}
// MODE_GETPLANE
{
struct drm_mode_get_plane p;
for(int i=0; i<nplanes; i++) {
p.plane_id = plane_ids[i];
p.count_format_types = 0;
printf(" plane %"PU": ", p.plane_id);
ioc(MODE_GETPLANE, &p);
if(!p.crtc_id && !p.fb_id)
printf("inactive\n");
else
printf("active on crtc %"PU" using framebuffer %"PU"\n",
p.crtc_id, p.fb_id);
printf(" possible crtcs:");
for(int j=0; j<32; j++)
if(p.possible_crtcs & (1UL<<j)) printf(" %d", crtc_ids[j]);
printf("\n");
printf(" supported formats:");
p.format_type_ptr = (uintptr_t)alloc(p.count_format_types, 4);
ioc(MODE_GETPLANE, &p);
for(int j=0; j<p.count_format_types; j++)
printf(" %.4s", (char *)&((uint32_t *)p.format_type_ptr)[j]);
printf("\n");
if(p.gamma_size > 0)
printf(" gamma size %"PU"\n", p.gamma_size);
print_obj_properties(p.plane_id, DRM_MODE_OBJECT_PLANE);
}
}
// XXX experimentation XXX
printf("\n--------\n");
{
struct drm_mode_fb_cmd fb;
struct drm_mode_create_dumb cd;
struct drm_mode_destroy_dumb dd;
struct drm_mode_set_plane sp;
cd.width = 1920;
cd.height = 1080;
cd.bpp = 32;
cd.flags = 0;
ioc(MODE_CREATE_DUMB, &cd);
printf("created buf: handle %"PU", pitch %"PU", size %"PRIu64"\n",
cd.handle, cd.pitch, cd.size);
fb.width = cd.width;
fb.height = cd.height;
fb.pitch = cd.pitch;
fb.bpp = cd.bpp;
fb.depth = 24;
fb.handle = cd.handle;
ioc(MODE_ADDFB, &fb);
printf("added fb %"PU": ", fb.fb_id);
print_fbinfo(fb);
sp.plane_id = plane_ids[0];
sp.crtc_id = crtc_ids[0];
sp.fb_id = fb.fb_id;
sp.flags = 0;
sp.crtc_x = 100;
sp.crtc_y = 100;
sp.crtc_w = 1920-200;
sp.crtc_h = 1080-200;
sp.src_x = sp.crtc_x;
sp.src_y = sp.crtc_y;
sp.src_w = sp.crtc_w<<16;
sp.src_h = sp.crtc_h<<16;
ioc(MODE_SETPLANE, &sp);
printf("enabled plane %"PU" using fb %"PU"\n", sp.plane_id, sp.fb_id);
sleep(1);
sp.fb_id = 0;
ioc(MODE_SETPLANE, &sp);
printf("disabled plane %"PU"\n", sp.plane_id);
ioc(MODE_RMFB, &fb.fb_id);
printf("removed fb %"PU"\n", fb.fb_id);
dd.handle = cd.handle;
ioc(MODE_DESTROY_DUMB, &dd);
printf("destroyed buf %"PU"\n", dd.handle);
}
return 0;
}
void print_modeinfo(struct drm_mode_modeinfo m)
{
printf(" mode %"PU"x%"PU, m.hdisplay, m.vdisplay);
if(m.name[0])
printf(" (\"%s\")", m.name);
printf(" %.2fHz", (m.clock*1000.0) / (m.htotal*m.vtotal));
if(m.vrefresh)
printf(" (\"%"PU"Hz\") ", m.vrefresh);
// pretty-print type/flags
#define dotype(F) if(m.type & DRM_MODE_TYPE_##F) printf(" %s", #F)
#define doflag(F) if(m.flags & DRM_MODE_FLAG_##F) printf(" %s", #F)
dotype(BUILTIN);
dotype(CLOCK_C);
dotype(CRTC_C);
dotype(PREFERRED);
dotype(DEFAULT);
dotype(USERDEF);
dotype(DRIVER);
doflag(PHSYNC);
doflag(NHSYNC);
doflag(PVSYNC);
doflag(NVSYNC);
doflag(INTERLACE);
doflag(DBLSCAN);
doflag(CSYNC);
doflag(PCSYNC);
doflag(NCSYNC);
doflag(HSKEW);
doflag(BCAST);
doflag(PIXMUX);
doflag(DBLCLK);
doflag(CLKDIV2);
#undef dotype
#undef doflag
printf("\n");
printf(" %"PU"x%"PU" hsync %"PU"-%"PU" vsync %"PU"-%"PU,
m.htotal, m.vtotal,
m.hsync_start, m.hsync_end,
m.vsync_start, m.vsync_end);
if(m.hskew) printf(" hskew %"PU, m.hskew);
if(m.vscan) printf(" vscan %"PU, m.vscan);
printf(", pixel clock %"PU"kHz\n", m.clock);
}
// MODE_GETPROPERTY
// MODE_GETPROPBLOB
//
void print_property(uint32_t prop, uint64_t value)
{
struct drm_mode_get_property p;
struct drm_mode_property_enum *en;
uint64_t *values;
p.prop_id = prop;
p.values_ptr = p.enum_blob_ptr = 0;
p.count_values = p.count_enum_blobs = 0;
ioc(MODE_GETPROPERTY, &p);
printf(" %s:", p.name);
if(p.flags & DRM_MODE_PROP_ENUM) {
en = alloc(p.count_enum_blobs, sizeof(struct drm_mode_property_enum));
p.enum_blob_ptr = (uintptr_t)en;
p.count_values = 0;
ioc(MODE_GETPROPERTY, &p);
for(int i=0; i<p.count_enum_blobs; i++) {
if(i>0)
printf(",");
if(en[i].value == value)
printf(" [%s]", en[i].name);
else
printf(" %s", en[i].name);
}
}
else if(p.flags & DRM_MODE_PROP_BITMASK) {
en = alloc(p.count_enum_blobs, sizeof(struct drm_mode_property_enum));
p.enum_blob_ptr = (uintptr_t)en;
p.count_values = 0;
ioc(MODE_GETPROPERTY, &p);
for(int i=0; i<p.count_enum_blobs; i++) {
if(i>0)
printf(",");
if(value & (1ULL << en[i].value))
printf(" [%s]", en[i].name);
else
printf(" %s", en[i].name);
}
}
else if(p.flags & DRM_MODE_PROP_BLOB) {
struct drm_mode_get_blob b;
if(value) {
b.blob_id = value;
b.length = b.data = 0;
ioc(MODE_GETPROPBLOB, &b);
b.data = (uintptr_t)alloc(b.length, 1);
ioc(MODE_GETPROPBLOB, &b);
printf(" \"");
for(int i=0; i<b.length; i++)
print_byte(((uint8_t *)b.data)[i]);
printf("\"");
}
}
else if((p.flags & DRM_MODE_PROP_RANGE) && p.count_values == 2) {
values = alloc(p.count_values, sizeof(uint64_t));
p.values_ptr = (uintptr_t)values;
p.count_enum_blobs = 0;
ioc(MODE_GETPROPERTY, &p);
printf(" %"PRIu64" (%"PRIu64" - %"PRIu64")",
value, values[0], values[1]);
}
else {
printf(" %"PRIu64" (flags=0x%"PRIx32", count_values=%"PU")",
value, p.flags, p.count_values);
}
#define doflag(F) if(p.flags & DRM_MODE_PROP_##F) printf(" %s", #F)
#define dotype(T) case DRM_MODE_PROP_##T: printf(" %s", #T); break;
printf(" ");
doflag(PENDING);
doflag(IMMUTABLE);
doflag(RANGE);
doflag(ENUM);
doflag(BLOB);
doflag(BITMASK);
switch(p.flags & DRM_MODE_PROP_EXTENDED_TYPE) {
dotype(OBJECT)
dotype(SIGNED_RANGE)
}
#undef doflag
#undef dotype
printf("\n");
}
void print_byte(uint8_t c)
{
if(isprint(c))
printf("%c", c);
else
printf("\\x%.2x", (unsigned)c);
}
// MODE_OBJ_GETPROPERTIES
//
void print_obj_properties(uint32_t obj_id, uint32_t obj_type)
{
struct drm_mode_obj_get_properties p;
uint32_t *props, *values;
int r;
p.props_ptr = p.prop_values_ptr = p.count_props = 0;
p.obj_id = obj_id;
p.obj_type = obj_type;
r = ioctl(devfd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &p);
if(r<0 && errno == EINVAL)
return; // no properties on this object
if(p.count_props > 0) {
props = alloc(p.count_props, sizeof(uint32_t));
values = alloc(p.count_props, sizeof(uint64_t));
p.props_ptr = (uintptr_t)props;
p.prop_values_ptr = (uintptr_t)values;
ioc(MODE_OBJ_GETPROPERTIES, &p);
printf(" properties:\n");
for(int j=0; j<p.count_props; j++)
print_property(props[j], values[j]);
}
}
// MODE_GETFB
//
void print_framebuffer(uint32_t fb_id)
{
struct drm_mode_fb_cmd f;
f.fb_id = fb_id;
ioc(MODE_GETFB, &f);
print_fbinfo(f);
}
void print_fbinfo(struct drm_mode_fb_cmd f)
{
printf("%"PU"x%"PU" %"PU" bpp, pitch %"PU", depth %"PU
", driver handle %"PU"\n",
f.width, f.height, f.bpp, f.pitch, f.depth, f.handle);
}