From nobody Sat May 18 19:12:34 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1615639563; cv=none; d=zohomail.com; s=zohoarc; b=jiqemsmGX61pT020nR489PyiISBTKByCANjRh/I6tzGtDsNfv7IHkINjKGHV6A3glBhXzQmnlCDMHSNJO0o8NEcjOwJbpqhm4h5npzxtFz7s7evbsbgOpIkd4Vd3AWAp5p/RWthlsfbpMB6Ij4yQO0NxowH2/uBDK+CT5mtiiWs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615639563; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=MrcByp2mhwjKCvU8y7GwYu+3pxDV7xhqR+EKxHjaOxA=; b=niZe9hNK3R86XSopLpikKfGYFACrQ6jB5NhWpSAtjA4X/77U7G36olOsntuZxa28bvekHPsEjhM0sO26Uyb63CCy70Vj4zFbT+SlzpuQ+7YstvAj3RudYOiH06ltxd9XO7DYWxjvM7Fu+cXeIDuGBg6Z+UWnwQYnMmC+pRiuCY4= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1615639563051359.7395095096771; Sat, 13 Mar 2021 04:46:03 -0800 (PST) Received: from localhost ([::1]:38892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lL3eb-0004Sj-FJ for importer@patchew.org; Sat, 13 Mar 2021 07:46:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40028) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lL1lz-00039u-T6 for qemu-devel@nongnu.org; Sat, 13 Mar 2021 05:45:32 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:52603) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lL1lw-0007tY-Gr for qemu-devel@nongnu.org; Sat, 13 Mar 2021 05:45:31 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 7B9385C0094; Sat, 13 Mar 2021 05:45:26 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Sat, 13 Mar 2021 05:45:26 -0500 Received: from pin.lan (unknown [109.252.107.9]) by mail.messagingengine.com (Postfix) with ESMTPA id 2C1C9108005C; Sat, 13 Mar 2021 05:45:25 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=knazarov.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=fm2; bh=MrcByp2mhwjKCvU8y7GwYu+3px DV7xhqR+EKxHjaOxA=; b=bNc3wsRc94UEVL2Ih8gXTZQoAwTRiSB6zc5zhwCSQQ Zva7YSp4MfK0WHOeQrO+wdh8Tq3AI6WyNpGcODFUM10eb/ETtm7YwqudbgY6Ar/x 4swzlj8h3X7y9Jk+o7qEp/1ZT39lWAGKz6UB24ZBkhVe87AZqNK+8NGZiP3uYRak ezmgxIeyR5OqzKFp5CuzCy+qSmOX6DIoTyW97ZFCUv0jxWDHcA98X2Tttm41Bk0u FzMA73gApimN8Ikfa0cX0/ABGl7zL1X2/F7NCj1SM/XWCMJZOyUeSd1DnRgcTVma uIpO4+KLzybA1Hv8Zz0F6Sg6O9bmrXmYuROjDyWFozEQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=MrcByp2mhwjKCvU8y 7GwYu+3pxDV7xhqR+EKxHjaOxA=; b=qwpDESWdopMzENB2pxkKbJKYywYqsPa7i HB/8crhM04yWUfn04tUgTpv8xynkZwU+P6j+9X779MWShGTna+X4LHnX1Al2gWlP /TtbVgxsQ/HoblaD6PAof02c1bvWuWjDifZNDTyW+o8q/FHkWDFRTv8XJVrXZr+n fER625Q89jxWZBlpM86ybGGznm4G2ylMghwE8WCkYML1h+aF7BL1ZABI9q3F6vCn olkvW2pWX24KuyaaZalC7KlTsxKNIP1RZXCJeLVRA7l4Zhquq70IgzzDAXnbByKp gti0DQm/aeFirIC5Etv2ukT9y8oxRKasBp3neIG65u0jYxp91rzSA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledruddvgedgudekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffoggfgsedtkeertdertddtnecuhfhrohhmpefmohhnshhtrghn thhinhcupfgriigrrhhovhcuoehmrghilheskhhnrgiirghrohhvrdgtohhmqeenucggtf frrghtthgvrhhnpefgkeetvdfhffelfeevffdttddtleeljeelkeetfeekheduveeuffdv ffefjeduheenucfkphepuddtledrvdehvddruddtjedrleenucevlhhushhtvghrufhiii gvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghilheskhhnrgiirghrohhvrdgt ohhm X-ME-Proxy: From: Konstantin Nazarov To: qemu-devel@nongnu.org Subject: [PATCH] edid: add support for DisplayID extension (5k resolution) Date: Sat, 13 Mar 2021 13:44:32 +0300 Message-Id: <20210313104432.3591-1-mail@knazarov.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=66.111.4.27; envelope-from=mail@knazarov.com; helo=out3-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 13 Mar 2021 07:44:33 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Konstantin Nazarov , Gerd Hoffmann , Akihiko Odaki Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The Detailed Timing Descriptor has only 12 bits to store the resolution. This limits the guest to 4095 pixels. This patch adds support for the DisplayID extension, that has 2 full bytes for that purpose, thus allowing 5k resolutions and above. Based-on: <20210303152948.59943-2-akihiko.odaki@gmail.com> Signed-off-by: Konstantin Nazarov --- hw/display/edid-generate.c | 158 +++++++++++++++++++++++++++++-------- hw/display/vga-pci.c | 2 +- qemu-edid.c | 2 +- 3 files changed, 126 insertions(+), 36 deletions(-) diff --git a/hw/display/edid-generate.c b/hw/display/edid-generate.c index b0ce583d436..c34c879fba3 100644 --- a/hw/display/edid-generate.c +++ b/hw/display/edid-generate.c @@ -44,6 +44,35 @@ static const struct edid_mode { { .xres =3D 640, .yres =3D 480, .byte =3D 35, .bit =3D 5 }, }; =20 +struct timings { + uint32_t xfront; + uint32_t xsync; + uint32_t xblank; + + uint32_t yfront; + uint32_t ysync; + uint32_t yblank; + + uint64_t clock; +}; + +static void generate_timings(struct timings *timings, uint32_t refresh_rat= e, + uint32_t xres, uint32_t yres) +{ + /* pull some realistic looking timings out of thin air */ + timings->xfront =3D xres * 25 / 100; + timings->xsync =3D xres * 3 / 100; + timings->xblank =3D xres * 35 / 100; + + timings->yfront =3D yres * 5 / 1000; + timings->ysync =3D yres * 5 / 1000; + timings->yblank =3D yres * 35 / 1000; + + timings->clock =3D ((uint64_t)refresh_rate * + (xres + timings->xblank) * + (yres + timings->yblank)) / 10000000; +} + static void edid_ext_dta(uint8_t *dta) { dta[0] =3D 0x02; @@ -129,17 +158,17 @@ static void edid_fill_modes(uint8_t *edid, uint8_t *x= tra3, uint8_t *dta, } } =20 -static void edid_checksum(uint8_t *edid) +static void edid_checksum(uint8_t *edid, size_t len) { uint32_t sum =3D 0; int i; =20 - for (i =3D 0; i < 127; i++) { + for (i =3D 0; i < len; i++) { sum +=3D edid[i]; } sum &=3D 0xff; if (sum) { - edid[127] =3D 0x100 - sum; + edid[len] =3D 0x100 - sum; } } =20 @@ -180,8 +209,8 @@ static void edid_desc_ranges(uint8_t *desc) desc[7] =3D 30; desc[8] =3D 160; =20 - /* max dot clock (1200 MHz) */ - desc[9] =3D 1200 / 10; + /* max dot clock (2550 MHz) */ + desc[9] =3D 2550 / 10; =20 /* no extended timing information */ desc[10] =3D 0x01; @@ -207,38 +236,29 @@ static void edid_desc_timing(uint8_t *desc, uint32_t = refresh_rate, uint32_t xres, uint32_t yres, uint32_t xmm, uint32_t ymm) { - /* pull some realistic looking timings out of thin air */ - uint32_t xfront =3D xres * 25 / 100; - uint32_t xsync =3D xres * 3 / 100; - uint32_t xblank =3D xres * 35 / 100; - - uint32_t yfront =3D yres * 5 / 1000; - uint32_t ysync =3D yres * 5 / 1000; - uint32_t yblank =3D yres * 35 / 1000; - - uint64_t clock =3D (uint64_t)refresh_rate * (xres + xblank) * (yres += yblank); - - stl_le_p(desc, clock / 10000000); + struct timings timings; + generate_timings(&timings, refresh_rate, xres, yres); + stl_le_p(desc, timings.clock); =20 desc[2] =3D xres & 0xff; - desc[3] =3D xblank & 0xff; + desc[3] =3D timings.xblank & 0xff; desc[4] =3D (((xres & 0xf00) >> 4) | - ((xblank & 0xf00) >> 8)); + ((timings.xblank & 0xf00) >> 8)); =20 desc[5] =3D yres & 0xff; - desc[6] =3D yblank & 0xff; + desc[6] =3D timings.yblank & 0xff; desc[7] =3D (((yres & 0xf00) >> 4) | - ((yblank & 0xf00) >> 8)); + ((timings.yblank & 0xf00) >> 8)); =20 - desc[8] =3D xfront & 0xff; - desc[9] =3D xsync & 0xff; + desc[8] =3D timings.xfront & 0xff; + desc[9] =3D timings.xsync & 0xff; =20 - desc[10] =3D (((yfront & 0x00f) << 4) | - ((ysync & 0x00f) << 0)); - desc[11] =3D (((xfront & 0x300) >> 2) | - ((xsync & 0x300) >> 4) | - ((yfront & 0x030) >> 2) | - ((ysync & 0x030) >> 4)); + desc[10] =3D (((timings.yfront & 0x00f) << 4) | + ((timings.ysync & 0x00f) << 0)); + desc[11] =3D (((timings.xfront & 0x300) >> 2) | + ((timings.xsync & 0x300) >> 4) | + ((timings.yfront & 0x030) >> 2) | + ((timings.ysync & 0x030) >> 4)); =20 desc[12] =3D xmm & 0xff; desc[13] =3D ymm & 0xff; @@ -296,15 +316,62 @@ uint32_t qemu_edid_dpi_to_mm(uint32_t dpi, uint32_t r= es) return res * 254 / 10 / dpi; } =20 +static void dummy_displayid(uint8_t *did) +{ + did[0] =3D 0x70; /* display id extension */ + did[1] =3D 0x13; /* version 1.3 */ + did[2] =3D 4; /* length */ + did[3] =3D 0x03; /* product type (0x03 =3D=3D standalone display devic= e) */ + edid_checksum(did + 1, did[2] + 4); +} + +static void qemu_displayid_generate(uint8_t *did, uint32_t refresh_rate, + uint32_t xres, uint32_t yres, + uint32_t xmm, uint32_t ymm) +{ + struct timings timings; + generate_timings(&timings, refresh_rate, xres, yres); + + did[0] =3D 0x70; /* display id extension */ + did[1] =3D 0x13; /* version 1.3 */ + did[2] =3D 23; /* length */ + did[3] =3D 0x03; /* product type (0x03 =3D=3D standalone display devic= e) */ + + did[5] =3D 0x03; /* Detailed Timings Data Block */ + did[6] =3D 0x00; /* revision */ + did[7] =3D 0x14; /* block length */ + + did[8] =3D timings.clock & 0xff; + did[9] =3D (timings.clock & 0xff00) >> 8; + did[10] =3D (timings.clock & 0xff0000) >> 16; + + did[11] =3D 0x88; /* leave aspect ratio undefined */ + + stw_le_p(did + 12, 0xffff & (xres - 1)); + stw_le_p(did + 14, 0xffff & (timings.xblank - 1)); + stw_le_p(did + 16, 0xffff & (timings.xfront - 1)); + stw_le_p(did + 18, 0xffff & (timings.xsync - 1)); + + stw_le_p(did + 20, 0xffff & (yres - 1)); + stw_le_p(did + 22, 0xffff & (timings.yblank - 1)); + stw_le_p(did + 24, 0xffff & (timings.yfront - 1)); + stw_le_p(did + 26, 0xffff & (timings.ysync - 1)); + + edid_checksum(did + 1, did[2] + 4); +} + void qemu_edid_generate(uint8_t *edid, size_t size, qemu_edid_info *info) { uint32_t desc =3D 54; uint8_t *xtra3 =3D NULL; uint8_t *dta =3D NULL; + uint8_t *did =3D NULL; uint32_t width_mm, height_mm; uint32_t refresh_rate =3D info->refresh_rate ? info->refresh_rate : 75= 000; uint32_t dpi =3D 100; /* if no width_mm/height_mm */ + uint32_t large_screen =3D 0; + =20 /* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D set defaults =3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ =20 @@ -320,6 +387,9 @@ void qemu_edid_generate(uint8_t *edid, size_t size, if (!info->prefy) { info->prefy =3D 768; } + if (info->prefx >=3D 4096 || info->prefy >=3D 4096) { + large_screen =3D 1; + } if (info->width_mm && info->height_mm) { width_mm =3D info->width_mm; height_mm =3D info->height_mm; @@ -401,9 +471,12 @@ void qemu_edid_generate(uint8_t *edid, size_t size, =20 /* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D descriptor blocks =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ =20 - edid_desc_timing(edid + desc, refresh_rate, info->prefx, info->prefy, - width_mm, height_mm); - desc +=3D 18; + /* The DTD section has only 12 bits to store the resolution */ + if (!large_screen) { + edid_desc_timing(edid + desc, refresh_rate, info->prefx, info->pre= fy, + width_mm, height_mm); + desc +=3D 18; + } =20 edid_desc_ranges(edid + desc); desc +=3D 18; @@ -429,13 +502,30 @@ void qemu_edid_generate(uint8_t *edid, size_t size, desc +=3D 18; } =20 + /* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D display id extensions= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ + + if (size >=3D 384) { + did =3D edid + 256; + dummy_displayid(did); + edid[126]++; + + if (large_screen) { + qemu_displayid_generate(did, refresh_rate, info->prefx, info->= prefy, + width_mm, height_mm); + } + } + /* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D finish up =3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ =20 edid_fill_modes(edid, xtra3, dta, info->maxx, info->maxy); - edid_checksum(edid); + edid_checksum(edid, 127); if (dta) { - edid_checksum(dta); + edid_checksum(dta, 127); } + if (did) { + edid_checksum(did, 127); + } + } =20 size_t qemu_edid_size(uint8_t *edid) diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 48d29630ab7..62fb5c38c1f 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -49,7 +49,7 @@ struct PCIVGAState { qemu_edid_info edid_info; MemoryRegion mmio; MemoryRegion mrs[4]; - uint8_t edid[256]; + uint8_t edid[384]; }; =20 #define TYPE_PCI_VGA "pci-vga" diff --git a/qemu-edid.c b/qemu-edid.c index 1cd6a951723..028f2d181a1 100644 --- a/qemu-edid.c +++ b/qemu-edid.c @@ -41,7 +41,7 @@ static void usage(FILE *out) int main(int argc, char *argv[]) { FILE *outfile =3D NULL; - uint8_t blob[256]; + uint8_t blob[384]; uint32_t dpi =3D 100; int rc; =20 --=20 2.24.3 (Apple Git-128)