From nobody Thu Nov 6 06:17:07 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1539348057039413.4123190211442; Fri, 12 Oct 2018 05:40:57 -0700 (PDT) Received: from localhost ([::1]:40239 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAwkM-0007vF-63 for importer@patchew.org; Fri, 12 Oct 2018 08:40:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49038) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gAwif-0006uR-BJ for qemu-devel@nongnu.org; Fri, 12 Oct 2018 08:39:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gAwiY-0007bc-Iu for qemu-devel@nongnu.org; Fri, 12 Oct 2018 08:39:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45484) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gAwiY-0007Zu-5Z for qemu-devel@nongnu.org; Fri, 12 Oct 2018 08:38:58 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EE220D1749; Fri, 12 Oct 2018 12:38:56 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-238.ams2.redhat.com [10.36.116.238]) by smtp.corp.redhat.com (Postfix) with ESMTP id ACF602AA8C; Fri, 12 Oct 2018 12:38:52 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 08AF499AFD; Fri, 12 Oct 2018 14:38:52 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 12 Oct 2018 14:38:50 +0200 Message-Id: <20181012123851.30856-5-kraxel@redhat.com> In-Reply-To: <20181012123851.30856-1-kraxel@redhat.com> References: <20181012123851.30856-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 12 Oct 2018 12:38:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 4/5] i2c: switch ddc to use the new edid generator X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Linus Walleij , Gerd Hoffmann , "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This also makes the default display resolution configurable, via xres and yres properties. The default is 1024x768. The old code had a hard-coded resolution of 1600x1200. Cc: Linus Walleij Cc: BALATON Zoltan Signed-off-by: Gerd Hoffmann Message-id: 20181005110837.28209-1-kraxel@redhat.com --- include/hw/i2c/i2c-ddc.h | 4 +- hw/i2c/i2c-ddc.c | 200 ++-----------------------------------------= ---- 2 files changed, 11 insertions(+), 193 deletions(-) diff --git a/include/hw/i2c/i2c-ddc.h b/include/hw/i2c/i2c-ddc.h index d9b5f33f58..c29443c5af 100644 --- a/include/hw/i2c/i2c-ddc.h +++ b/include/hw/i2c/i2c-ddc.h @@ -19,14 +19,16 @@ #ifndef I2C_DDC_H #define I2C_DDC_H =20 +#include "hw/display/edid.h" + /* A simple I2C slave which just returns the contents of its EDID blob. */ - struct I2CDDCState { /*< private >*/ I2CSlave i2c; /*< public >*/ bool firstbyte; uint8_t reg; + qemu_edid_info edid_info; uint8_t edid_blob[128]; }; =20 diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c index bec0c91e2d..be34fe072c 100644 --- a/hw/i2c/i2c-ddc.c +++ b/hw/i2c/i2c-ddc.c @@ -32,197 +32,6 @@ } = \ } while (0) =20 -/* Structure defining a monitor's characteristics in a - * readable format: this should be passed to build_edid_blob() - * to convert it into the 128 byte binary EDID blob. - * Not all bits of the EDID are customisable here. - */ -struct EDIDData { - char manuf_id[3]; /* three upper case letters */ - uint16_t product_id; - uint32_t serial_no; - uint8_t manuf_week; - int manuf_year; - uint8_t h_cm; - uint8_t v_cm; - uint8_t gamma; - char monitor_name[14]; - char serial_no_string[14]; - /* Range limits */ - uint8_t vmin; /* Hz */ - uint8_t vmax; /* Hz */ - uint8_t hmin; /* kHz */ - uint8_t hmax; /* kHz */ - uint8_t pixclock; /* MHz / 10 */ - uint8_t timing_data[18]; -}; - -typedef struct EDIDData EDIDData; - -/* EDID data for a simple LCD monitor */ -static const EDIDData lcd_edid =3D { - /* The manuf_id ought really to be an assigned EISA ID */ - .manuf_id =3D "QMU", - .product_id =3D 0, - .serial_no =3D 1, - .manuf_week =3D 1, - .manuf_year =3D 2011, - .h_cm =3D 40, - .v_cm =3D 30, - .gamma =3D 0x78, - .monitor_name =3D "QEMU monitor", - .serial_no_string =3D "1", - .vmin =3D 40, - .vmax =3D 120, - .hmin =3D 30, - .hmax =3D 100, - .pixclock =3D 18, - .timing_data =3D { - /* Borrowed from a 21" LCD */ - 0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, - 0xc0, 0x13, 0x00, 0x98, 0x32, 0x11, 0x00, 0x00, 0x1e - } -}; - -static uint8_t manuf_char_to_int(char c) -{ - return (c - 'A') & 0x1f; -} - -static void write_ascii_descriptor_block(uint8_t *descblob, uint8_t blockt= ype, - const char *string) -{ - /* Write an EDID Descriptor Block of the "ascii string" type */ - int i; - descblob[0] =3D descblob[1] =3D descblob[2] =3D descblob[4] =3D 0; - descblob[3] =3D blocktype; - /* The rest is 13 bytes of ASCII; if less then the rest must - * be filled with newline then spaces - */ - for (i =3D 5; i < 19; i++) { - descblob[i] =3D string[i - 5]; - if (!descblob[i]) { - break; - } - } - if (i < 19) { - descblob[i++] =3D '\n'; - } - for ( ; i < 19; i++) { - descblob[i] =3D ' '; - } -} - -static void write_range_limits_descriptor(const EDIDData *edid, - uint8_t *descblob) -{ - int i; - descblob[0] =3D descblob[1] =3D descblob[2] =3D descblob[4] =3D 0; - descblob[3] =3D 0xfd; - descblob[5] =3D edid->vmin; - descblob[6] =3D edid->vmax; - descblob[7] =3D edid->hmin; - descblob[8] =3D edid->hmax; - descblob[9] =3D edid->pixclock; - descblob[10] =3D 0; - descblob[11] =3D 0xa; - for (i =3D 12; i < 19; i++) { - descblob[i] =3D 0x20; - } -} - -static void build_edid_blob(const EDIDData *edid, uint8_t *blob) -{ - /* Write an EDID 1.3 format blob (128 bytes) based - * on the EDIDData structure. - */ - int i; - uint8_t cksum; - - /* 00-07 : header */ - blob[0] =3D blob[7] =3D 0; - for (i =3D 1 ; i < 7; i++) { - blob[i] =3D 0xff; - } - /* 08-09 : manufacturer ID */ - blob[8] =3D (manuf_char_to_int(edid->manuf_id[0]) << 2) - | (manuf_char_to_int(edid->manuf_id[1]) >> 3); - blob[9] =3D (manuf_char_to_int(edid->manuf_id[1]) << 5) - | manuf_char_to_int(edid->manuf_id[2]); - /* 10-11 : product ID code */ - blob[10] =3D edid->product_id; - blob[11] =3D edid->product_id >> 8; - blob[12] =3D edid->serial_no; - blob[13] =3D edid->serial_no >> 8; - blob[14] =3D edid->serial_no >> 16; - blob[15] =3D edid->serial_no >> 24; - /* 16 : week of manufacture */ - blob[16] =3D edid->manuf_week; - /* 17 : year of manufacture - 1990 */ - blob[17] =3D edid->manuf_year - 1990; - /* 18, 19 : EDID version and revision */ - blob[18] =3D 1; - blob[19] =3D 3; - /* 20 - 24 : basic display parameters */ - /* We are always a digital display */ - blob[20] =3D 0x80; - /* 21, 22 : max h/v size in cm */ - blob[21] =3D edid->h_cm; - blob[22] =3D edid->v_cm; - /* 23 : gamma (divide by 100 then add 1 for actual value) */ - blob[23] =3D edid->gamma; - /* 24 feature support: no power management, RGB, preferred timing mode, - * standard colour space - */ - blob[24] =3D 0x0e; - /* 25 - 34 : chromaticity coordinates. These are the - * standard sRGB chromaticity values - */ - blob[25] =3D 0xee; - blob[26] =3D 0x91; - blob[27] =3D 0xa3; - blob[28] =3D 0x54; - blob[29] =3D 0x4c; - blob[30] =3D 0x99; - blob[31] =3D 0x26; - blob[32] =3D 0x0f; - blob[33] =3D 0x50; - blob[34] =3D 0x54; - /* 35, 36 : Established timings: claim to support everything */ - blob[35] =3D blob[36] =3D 0xff; - /* 37 : manufacturer's reserved timing: none */ - blob[37] =3D 0; - /* 38 - 53 : standard timing identification - * don't claim anything beyond what the 'established timings' - * already provide. Unused slots must be (0x1, 0x1) - */ - for (i =3D 38; i < 54; i++) { - blob[i] =3D 0x1; - } - /* 54 - 71 : descriptor block 1 : must be preferred timing data */ - memcpy(blob + 54, edid->timing_data, 18); - /* 72 - 89, 90 - 107, 108 - 125 : descriptor block 2, 3, 4 - * Order not important, but we must have a monitor name and a - * range limits descriptor. - */ - write_range_limits_descriptor(edid, blob + 72); - write_ascii_descriptor_block(blob + 90, 0xfc, edid->monitor_name); - write_ascii_descriptor_block(blob + 108, 0xff, edid->serial_no_string); - - /* 126 : extension flag */ - blob[126] =3D 0; - - cksum =3D 0; - for (i =3D 0; i < 127; i++) { - cksum +=3D blob[i]; - } - /* 127 : checksum */ - blob[127] =3D -cksum; - if (DEBUG_I2CDDC) { - qemu_hexdump((char *)blob, stdout, "", 128); - } -} - static void i2c_ddc_reset(DeviceState *ds) { I2CDDCState *s =3D I2CDDC(ds); @@ -270,7 +79,8 @@ static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data) static void i2c_ddc_init(Object *obj) { I2CDDCState *s =3D I2CDDC(obj); - build_edid_blob(&lcd_edid, s->edid_blob); + + qemu_edid_generate(s->edid_blob, sizeof(s->edid_blob), &s->edid_info); } =20 static const VMStateDescription vmstate_i2c_ddc =3D { @@ -283,6 +93,11 @@ static const VMStateDescription vmstate_i2c_ddc =3D { } }; =20 +static Property i2c_ddc_properties[] =3D { + DEFINE_EDID_PROPERTIES(I2CDDCState, edid_info), + DEFINE_PROP_END_OF_LIST(), +}; + static void i2c_ddc_class_init(ObjectClass *oc, void *data) { DeviceClass *dc =3D DEVICE_CLASS(oc); @@ -290,6 +105,7 @@ static void i2c_ddc_class_init(ObjectClass *oc, void *d= ata) =20 dc->reset =3D i2c_ddc_reset; dc->vmsd =3D &vmstate_i2c_ddc; + dc->props =3D i2c_ddc_properties; isc->event =3D i2c_ddc_event; isc->recv =3D i2c_ddc_rx; isc->send =3D i2c_ddc_tx; --=20 2.9.3