From nobody Sun May 19 06:50:50 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=1615713298; cv=none; d=zohomail.com; s=zohoarc; b=hOfsMfMi0+LIBS/d5m4fGcypdlShcaGAXPnschkyhZqBkIqg/dFelHdrr+/8LqZbeOPqOU2BXQb1hufftGXZypFYlH1jbgdaaFnk/521A2OETOfOEe4WjRQX8aYsDAeAKfgvp0z1i9uYHeXJYdnXOwgVWS3wIQjknkaTc4i4xz4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615713298; 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=wk2KWSc9IS7RnAS4lzfAlrBD3PAyqKdCwTioUG9cndw=; b=FUUxBtI3xWFYtt6j+NR0NzXai5spBkViJ26cnhUq6u6PlVqCrKDorX756hmfHgmdc9ZoPTJ09GeAv2+O+dcly9BXq/kMamkjtdxCgV7bKDCQakftKABSeeuImneXA4VwtITDYgOKYakK37WDZacYT9IOMVTSpbqruGe/jzzMdm8= 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 1615713298778689.0232772855846; Sun, 14 Mar 2021 01:14:58 -0800 (PST) Received: from localhost ([::1]:42716 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lLMpt-0000hV-OM for importer@patchew.org; Sun, 14 Mar 2021 05:14:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34736) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lLMnt-0007ti-UY for qemu-devel@nongnu.org; Sun, 14 Mar 2021 05:12:53 -0400 Received: from out5-smtp.messagingengine.com ([66.111.4.29]:52509) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lLMnq-0004y4-9T for qemu-devel@nongnu.org; Sun, 14 Mar 2021 05:12:53 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 727405C008F; Sun, 14 Mar 2021 05:12:49 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Sun, 14 Mar 2021 05:12:49 -0400 Received: from pin.lan (unknown [109.252.107.9]) by mail.messagingengine.com (Postfix) with ESMTPA id 4A6031080063; Sun, 14 Mar 2021 05:12:48 -0400 (EDT) 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=wk2KWSc9IS7RnAS4lzfAlrBD3P AyqKdCwTioUG9cndw=; b=cETXFBHql2xFH+f5tq+0aEsMr4h3/I3oGJihtf9Znf Z+6V7cb4oGucNNfKDUlRNeWtrA4kLFmG70gJ+sAorghpiktXVTGqH2N/4qbKPt35 TNTP9Vb761jYsfqIG6B8qj6p64g5AlQSNfECDKGJMt8kNN2JfyEsPzIBP0E1W3mz 9t54ktKRWdNSpxXgshFsKQtzF7hBnfP4hdG6Za+YHfbYo+anwjHQEKAhY5laVr6i 6Ps0LkwuWmXS8uHLLMV3iLVoA+Wtg0e/jTTtTEV0GrZiEn9ahL4zp1XwfZwQvKnN hWaz/n70OMVAwvGcqWDBdhpKu3+MoBbb8x19M4fgdU+w== 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=wk2KWSc9IS7RnAS4l zfAlrBD3PAyqKdCwTioUG9cndw=; b=aNSBDf1kqIQ4zyQCzT+FCceuU40DHdfW/ 55UPBXrQU+c0Jw7X2PlCM+x3rRqX1rdhweJ99c0x+gYzK9BuxMoax4sgeE5fr5Hg QIWnt7fS6DiDmBtJFDo8tRIS0Kbc9yrwFYFJKR0MfKtlWUMW+Z4sswQ3IndJdvvC D+dkagPdaGM/cIp6sna8Krki4XxYrgGtymrAgyotigG1wCB4j2eXp79oqNqTwFki UlzsFfZ5OY9Ie0sFK1tl6+VYSkNVV1Sy3g8IIULq+Q4PoaLZ0TFabPeA+QvRL2pK p026BaajS0z0DQs09u7y55yYS8ZfecNn6r1mN/AfGH1vnJw3iq2tg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledruddvhedgkeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffoggfgsedtkeertdertddtnecuhfhrohhmpefmohhnshhtrghn thhinhcupfgriigrrhhovhcuoehmrghilheskhhnrgiirghrohhvrdgtohhmqeenucggtf frrghtthgvrhhnpefgkeetvdfhffelfeevffdttddtleeljeelkeetfeekheduveeuffdv ffefjeduheenucfkphepuddtledrvdehvddruddtjedrleenucevlhhushhtvghrufhiii gvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghilheskhhnrgiirghrohhvrdgt ohhm X-ME-Proxy: From: Konstantin Nazarov To: qemu-devel@nongnu.org Subject: [PATCH v2] edid: add support for DisplayID extension (5k resolution) Date: Sun, 14 Mar 2021 12:12:36 +0300 Message-Id: <20210314091236.44313-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.29; envelope-from=mail@knazarov.com; helo=out5-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-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 Reviewed-by: Akihiko Odaki --- hw/display/edid-generate.c | 156 +++++++++++++++++++++++++++++-------- hw/display/vga-pci.c | 2 +- qemu-edid.c | 2 +- 3 files changed, 124 insertions(+), 36 deletions(-) diff --git a/hw/display/edid-generate.c b/hw/display/edid-generate.c index b0ce583d436..db1e319e2dc 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 +typedef struct Timings { + uint32_t xfront; + uint32_t xsync; + uint32_t xblank; + + uint32_t yfront; + uint32_t ysync; + uint32_t yblank; + + uint64_t clock; +} Timings; + +static void generate_timings(Timings *timings, uint32_t refresh_rate, + 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); + 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,61 @@ 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) +{ + 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 +386,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 +470,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,12 +501,28 @@ 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 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)