{"id":789,"date":"2018-09-15T11:00:38","date_gmt":"2018-09-15T09:00:38","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=789"},"modified":"2018-09-15T11:41:20","modified_gmt":"2018-09-15T09:41:20","slug":"overriding-misreported-screen-dimensions-with-kms-backed-drivers","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2018\/09\/15\/overriding-misreported-screen-dimensions-with-kms-backed-drivers\/","title":{"rendered":"Overriding misreported screen dimensions with KMS-backed drivers"},"content":{"rendered":"<p>With Qt5 gaining support for high-DPI displays, and\u00a0applications starting to\u00a0exercise that support, it&#8217;s easy for applications to\u00a0suddenly become unusable with some screens.  For\u00a0example, my old Samsung TV reported itself as\u00a07\u2033 screen.  While this used not to\u00a0really matter with websites forcing you to\u00a0force the\u00a0resolution of\u00a096\u00a0DPI, the\u00a0high-DPI applications started scaling themselves to\u00a0occupy most of\u00a0my screen, with elements becoming really huge (and\u00a0ugly, apparently due to\u00a0some poor scaling).<\/p>\n<p>It turns out that it is really hard to find a\u00a0solution for this.  Most of\u00a0the\u00a0guides and\u00a0tips are focused either on\u00a0proprietary drivers or\u00a0on\u00a0getting custom resolutions.  The\u00a0<kbd>DisplaySize<\/kbd> specification in\u00a0<kbd>xorg.conf<\/kbd> apparently did not change anything either.  Finally, I was able to\u00a0resolve the\u00a0issue by\u00a0overriding the\u00a0EDID data for my screen.  This guide explains how I did it.<\/p>\n<p><!--more--><\/p>\n<h2>Step\u00a01: dump EDID data<\/h2>\n<p>Firstly, you need to\u00a0get the\u00a0EDID data from your monitor.  Supposedly <a rel='external' href='http:\/\/www.polypux.org\/projects\/read-edid\/'>read-edid<\/a> tool could be used for this purpose but\u00a0it did not\u00a0work for\u00a0me.  With only a\u00a0little bit more effort, you can get it e.g. from\u00a0xrandr:<\/p>\n<pre>$ <kbd>xrandr --verbose<\/kbd>\r\n[...]\r\nHDMI-0 connected primary 1920x1080+0+0 (0x57) normal (normal left inverted right x axis y axis) 708mm x 398mm\r\n[...]\r\n  EDID:\r\n    00ffffffffffff004c2dfb0400000000\r\n    2f120103804728780aee91a3544c9926\r\n    0f5054bdef80714f8100814081809500\r\n    950fb300a940023a801871382d40582c\r\n    4500c48e2100001e662150b051001b30\r\n    40703600c48e2100001e000000fd0018\r\n    4b1a5117000a2020202020200000000a\r\n    0053414d53554e470a20202020200143\r\n    020323f14b901f041305140312202122\r\n    2309070783010000e2000f67030c0010\r\n    00b82d011d007251d01e206e285500c4\r\n    8e2100001e011d00bc52d01e20b82855\r\n    40c48e2100001e011d8018711c162058\r\n    2c2500c48e2100009e011d80d0721c16\r\n    20102c2580c48e2100009e0000000000\r\n    00000000000000000000000000000029\r\n[...]<\/pre>\n<p>If you have multiple displays connected, make sure to\u00a0use the\u00a0EDID for the\u00a0one you&#8217;re overriding.  Copy the\u00a0hexdump and\u00a0convert it to a\u00a0binary blob.  You can do this by\u00a0passing it through <kbd>xxd -p -r<\/kbd> (installed by\u00a0vim).<\/p>\n<h2>Step\u00a02: fix screen dimensions<\/h2>\n<p>Once you have the\u00a0EDID blob ready, you need to\u00a0update the\u00a0screen dimensions inside it.  Initially, I did it using hex editor which involved finding all the\u00a0occurrences, updating them (and\u00a0manually encoding into the\u00a0weird split-integers) and\u00a0correcting the\u00a0checksums.  Then, I&#8217;ve written <a rel='external' href='https:\/\/github.com\/mgorny\/edid-fixdim'>edid-fixdim<\/a> so you wouldn&#8217;t have to\u00a0repeat that experience.<\/p>\n<p>First, use <kbd>--get<\/kbd> option to\u00a0verify that your EDID is\u00a0supported correctly:<\/p>\n<pre>$ <kbd>edid-fixdim -g edid.bin<\/kbd>\r\nEDID structure: 71 cm x 40 cm\r\nDetailed timing desc: 708 mm x 398 mm\r\nDetailed timing desc: 708 mm x 398 mm\r\nCEA EDID found\r\nDetailed timing desc: 708 mm x 398 mm\r\nDetailed timing desc: 708 mm x 398 mm\r\nDetailed timing desc: 708 mm x 398 mm\r\nDetailed timing desc: 708 mm x 398 mm<\/pre>\n<p>So your EDID consists of\u00a0basic EDID structure, followed by\u00a0one extension block.  The\u00a0screen dimensions are stored in\u00a07\u00a0different blocks you&#8217;d have to\u00a0update, and\u00a0referenced in\u00a0two checksums.  The\u00a0tool will take care of updating it all for you, so just pass the\u00a0correct dimensions to <kbd>--set<\/kbd>:<\/p>\n<pre>$ <kbd>edid-fixdim -s 1600x900 edid.bin<\/kbd>\r\nEDID structure updated to 160 cm x 90 cm\r\nDetailed timing desc updated to 1600 mm x 900 mm\r\nDetailed timing desc updated to 1600 mm x 900 mm\r\nCEA EDID found\r\nDetailed timing desc updated to 1600 mm x 900 mm\r\nDetailed timing desc updated to 1600 mm x 900 mm\r\nDetailed timing desc updated to 1600 mm x 900 mm\r\nDetailed timing desc updated to 1600 mm x 900 mm<\/pre>\n<p>Afterwards, you can use <kbd>--get<\/kbd> again to\u00a0verify that the\u00a0changes were made correctly.<\/p>\n<h2>Step\u00a03: overriding EDID data<\/h2>\n<p>Now it&#8217;s just the\u00a0matter of\u00a0putting the\u00a0override in\u00a0motion.  First, make sure to\u00a0enable <kbd>CONFIG_DRM_LOAD_EDID_FIRMWARE<\/kbd> in\u00a0your kernel:<\/p>\n<pre>Device Drivers  ---&gt;\r\n  Graphics support  ---&gt;\r\n    Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  ---&gt;\r\n      [*] Allow to specify an EDID data set instead of probing for it<\/pre>\n<p>Then, determine the\u00a0correct connector name.  You can find it in\u00a0<kbd>dmesg<\/kbd> output:<\/p>\n<pre>$ <kbd>dmesg | grep -C 1 Connector<\/kbd>\r\n[   15.192088] [drm] ib test on ring 5 succeeded\r\n[   15.193461] [drm] Radeon Display Connectors\r\n[   15.193524] [drm] Connector 0:\r\n[   15.193580] [drm]   <strong>HDMI-A-1<\/strong>\r\n--\r\n[   15.193800] [drm]     DFP1: INTERNAL_UNIPHY1\r\n[   15.193857] [drm] Connector 1:\r\n[   15.193911] [drm]   <strong>DVI-I-1<\/strong>\r\n--\r\n[   15.194210] [drm]     CRT1: INTERNAL_KLDSCP_DAC1\r\n[   15.194267] [drm] Connector 2:\r\n[   15.194322] [drm]   <strong>VGA-1<\/strong><\/pre>\n<p>Copy the\u00a0new EDID blob into location of\u00a0your choice inside <kbd>\/lib\/firmware<\/kbd>:<\/p>\n<pre>$ <kbd>mkdir \/lib\/firmware\/edid<\/kbd>\r\n$ <kbd>cp edid.bin \/lib\/firmware\/edid\/samsung.bin<\/kbd><\/pre>\n<p>Finally, add the\u00a0override to your kernel command-line:<\/p>\n<pre><kbd>drm.edid_firmware=HDMI-A-1:edid\/samsung.bin<\/kbd><\/pre>\n<p>If\u00a0everything went fine, <kbd>xrandr<\/kbd> should report correct screen dimensions after next reboot, and\u00a0<kbd>dmesg<\/kbd> should report that EDID override has been loaded:<\/p>\n<p><pre>$ <kbd>dmesg | grep EDID<kbd>\r\n[   15.549063] [drm] Got external EDID base block and 1 extension from \"edid\/samsung.bin\" for connector \"HDMI-A-1\"<\/pre>\n<p>If it didn't, check <kbd>dmesg<\/kbd> for error messages.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With Qt5 gaining support for high-DPI displays, and\u00a0applications starting to\u00a0exercise that support, it&#8217;s easy for applications to\u00a0suddenly become unusable with some screens. For\u00a0example, my old Samsung TV reported itself as\u00a07\u2033 screen. While this used not to\u00a0really matter with websites forcing you to\u00a0force the\u00a0resolution of\u00a096\u00a0DPI, the\u00a0high-DPI applications started scaling themselves to\u00a0occupy most of\u00a0my screen, with elements &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2018\/09\/15\/overriding-misreported-screen-dimensions-with-kms-backed-drivers\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Overriding misreported screen dimensions with KMS-backed drivers&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[3],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/789"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=789"}],"version-history":[{"count":14,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/789\/revisions"}],"predecessor-version":[{"id":803,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/789\/revisions\/803"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}