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 dera...@amd64.openbsd.org:/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); }