From patchwork Sat Feb 17 14:00:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 874749 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="SC4BoolG"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zkBbY1ZqLz9ryT for ; Sun, 18 Feb 2018 01:04:57 +1100 (AEDT) Received: from localhost ([::1]:53205 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1en36l-0006Zq-8n for incoming@patchwork.ozlabs.org; Sat, 17 Feb 2018 09:04:55 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46338) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1en35w-0006Xe-UH for qemu-devel@nongnu.org; Sat, 17 Feb 2018 09:04:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1en35v-000483-MQ for qemu-devel@nongnu.org; Sat, 17 Feb 2018 09:04:04 -0500 Received: from mail-lf0-x244.google.com ([2a00:1450:4010:c07::244]:37330) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1en35v-00047Z-Bq for qemu-devel@nongnu.org; Sat, 17 Feb 2018 09:04:03 -0500 Received: by mail-lf0-x244.google.com with SMTP id f137so7592095lfe.4 for ; Sat, 17 Feb 2018 06:04:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KWsTBDfBdhi/iC7vjg9grd1Np8GxFeYjxGwjjAolK6I=; b=SC4BoolGW0kUQqXv3N56R6MRundntLhypznH4xoXA7IW3MA2j7/2h/AF+pkURR1LWE 4eWsY5uMwWnoJ+8apDjoxMDhnYPwcCI3N436VP+r9ugZ7fI/9wQyxmHUr+vJCmHx/0W7 0MGTLykHfURkR9uKTh5hLFuWntG4q7beVzLz4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KWsTBDfBdhi/iC7vjg9grd1Np8GxFeYjxGwjjAolK6I=; b=o3x6EJRxzpFvGNFJ1+ziV/HYX1T5P6U9wX5z9Ed6Iv6mmfPRKIkLA4RS1IUt4jnZg7 V6EzXVhXyoLtc+cn+lg3pofEL4CpBtRvJJ5XWX3barrEZEHDqHsdF7rhmuSQkDN1V+j9 w53KZKTB0WgVmUufb1fkJkYGKOa3Dg0aNCzdotA5Jm6ry3jn59DrlVG1csIWW4DNfEaZ bjUp6JTKzuNirYJk4fEg+Kj/OIhOfxWt9Jai7z6TkuC/LA5lfORJdmuQoYILcyJsC4kr iJ3ic+3q7SHMuKgTt6KWODQQRTxTUhEHCTiXrpiT80/+zB2t74Zcd4t7BUiyIOT6K/VL 7tUg== X-Gm-Message-State: APf1xPB9WIrRkYLBVkSdDJt2vIh1VLa55hAJoojejg/L16omoKz9ZyUf gjYOyIOGKkq627zzE5uc2uT8qzQR3iY= X-Google-Smtp-Source: AH8x225AP/6yQ7yI7XcrPJQ63nn7fSwqxoVpwvJCucpxuadoDz7utZ9tIzbl5aSbU3ol+voisYZZqw== X-Received: by 10.46.41.157 with SMTP id p29mr5956160ljp.137.1518876241656; Sat, 17 Feb 2018 06:04:01 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id w204sm122054lff.29.2018.02.17.06.04.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 17 Feb 2018 06:04:00 -0800 (PST) From: Linus Walleij To: qemu-devel@nongnu.org Date: Sat, 17 Feb 2018 15:00:50 +0100 Message-Id: <20180217140051.22731-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180217140051.22731-1-linus.walleij@linaro.org> References: <20180217140051.22731-1-linus.walleij@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4010:c07::244 Subject: [Qemu-devel] [PATCH 2/3] hw/sii9022: Add support for Silicon Image SII9022 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 , qemu-arm@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This adds support for emulating the Silicon Image SII9022 DVI/HDMI bridge. It's not very clever right now, it just acknowledges the switch into DDC I2C mode and back. Combining this with the existing DDC I2C emulation gives the right behavior on the Versatile Express emulation passing through the QEMU EDID to the emulated platform. Signed-off-by: Linus Walleij --- hw/display/Makefile.objs | 1 + hw/display/sii9022.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 hw/display/sii9022.c diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs index d3a4cb396eb9..3c7c75b94da5 100644 --- a/hw/display/Makefile.objs +++ b/hw/display/Makefile.objs @@ -3,6 +3,7 @@ common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o common-obj-$(CONFIG_G364FB) += g364fb.o common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o common-obj-$(CONFIG_PL110) += pl110.o +common-obj-$(CONFIG_SII9022) += sii9022.o common-obj-$(CONFIG_SSD0303) += ssd0303.o common-obj-$(CONFIG_SSD0323) += ssd0323.o common-obj-$(CONFIG_XEN) += xenfb.o diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c new file mode 100644 index 000000000000..d6f3cdc04293 --- /dev/null +++ b/hw/display/sii9022.c @@ -0,0 +1,185 @@ +/* + * Silicon Image SiI9022 + * + * This is a pretty hollow emulation: all we do is acknowledge that we + * exist (chip ID) and confirm that we get switched over into DDC mode + * so the emulated host can proceed to read out EDID data. All subsequent + * set-up of connectors etc will be acknowledged and ignored. + * + * Copyright (c) 2018 Linus Walleij + * + * This code is licensed under the GNU GPL v2. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "hw/i2c/i2c.h" + +#define DEBUG_SII9022 0 + +#define DPRINTF(fmt, ...) \ + do { \ + if (DEBUG_SII9022) { \ + printf("sii9022: " fmt, ## __VA_ARGS__); \ + } \ + } while (0) + +#define SII9022_SYS_CTRL_DATA 0x1a +#define SII9022_SYS_CTRL_PWR_DWN 0x10 +#define SII9022_SYS_CTRL_AV_MUTE 0x08 +#define SII9022_SYS_CTRL_DDC_BUS_REQ 0x04 +#define SII9022_SYS_CTRL_DDC_BUS_GRTD 0x02 +#define SII9022_SYS_CTRL_OUTPUT_MODE 0x01 +#define SII9022_SYS_CTRL_OUTPUT_HDMI 1 +#define SII9022_SYS_CTRL_OUTPUT_DVI 0 +#define SII9022_REG_CHIPID 0x1b +#define SII9022_INT_ENABLE 0x3c +#define SII9022_INT_STATUS 0x3d +#define SII9022_INT_STATUS_HOTPLUG 0x01; +#define SII9022_INT_STATUS_PLUGGED 0x04; + +#define TYPE_SII9022 "sii9022" +#define SII9022(obj) OBJECT_CHECK(sii9022_state, (obj), TYPE_SII9022) + +typedef struct sii9022_state { + I2CSlave parent_obj; + uint8_t ptr; + bool addr_byte; + bool ddc_req; + bool ddc_skip_finish; + bool ddc; +} sii9022_state; + +static const VMStateDescription vmstate_sii9022 = { + .name = "sii9022", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_I2C_SLAVE(parent_obj, sii9022_state), + VMSTATE_UINT8(ptr, sii9022_state), + VMSTATE_BOOL(addr_byte, sii9022_state), + VMSTATE_BOOL(ddc_req, sii9022_state), + VMSTATE_BOOL(ddc_skip_finish, sii9022_state), + VMSTATE_BOOL(ddc, sii9022_state), + VMSTATE_END_OF_LIST() + } +}; + +static int sii9022_event(I2CSlave *i2c, enum i2c_event event) +{ + sii9022_state *s = SII9022(i2c); + + switch (event) { + case I2C_START_SEND: + s->addr_byte = true; + break; + case I2C_START_RECV: + break; + case I2C_FINISH: + break; + case I2C_NACK: + break; + } + + return 0; +} + +static int sii9022_rx(I2CSlave *i2c) +{ + sii9022_state *s = SII9022(i2c); + uint8_t res = 0x00; + + switch (s->ptr) { + case SII9022_SYS_CTRL_DATA: + if (s->ddc_req) { + /* Acknowledge DDC bus request */ + res = SII9022_SYS_CTRL_DDC_BUS_GRTD | SII9022_SYS_CTRL_DDC_BUS_REQ; + } + break; + case SII9022_REG_CHIPID: + res = 0xb0; + break; + case SII9022_INT_STATUS: + /* Something is cold-plugged in, no interrupts */ + res = SII9022_INT_STATUS_PLUGGED; + break; + default: + break; + } + DPRINTF("%02x read from %02x\n", res, s->ptr); + s->ptr++; + + return res; +} + +static int sii9022_tx(I2CSlave *i2c, uint8_t data) +{ + sii9022_state *s = SII9022(i2c); + + if (s->addr_byte) { + s->ptr = data; + s->addr_byte = false; + return 0; + } + + switch (s->ptr) { + case SII9022_SYS_CTRL_DATA: + if (data & SII9022_SYS_CTRL_DDC_BUS_REQ) { + s->ddc_req = true; + if (data & SII9022_SYS_CTRL_DDC_BUS_GRTD) { + s->ddc = true; + /* Skip this finish since we just switched to DDC */ + s->ddc_skip_finish = true; + DPRINTF("switched to DDC mode\n"); + } + } else { + s->ddc_req = false; + s->ddc = false; + } + break; + default: + break; + } + + DPRINTF("%02x written to %02x\n", data, s->ptr); + s->ptr++; + + return 0; +} + +static void sii9022_reset(DeviceState *dev) +{ + sii9022_state *s = SII9022(dev); + + s->ptr = 0; + s->addr_byte = false; +} + +static void sii9022_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); + + k->event = sii9022_event; + k->recv = sii9022_rx; + k->send = sii9022_tx; + dc->reset = sii9022_reset; + dc->vmsd = &vmstate_sii9022; +} + +static const TypeInfo sii9022_info = { + .name = TYPE_SII9022, + .parent = TYPE_I2C_SLAVE, + .instance_size = sizeof(sii9022_state), + .class_init = sii9022_class_init, +}; + +static void sii9022_register_types(void) +{ + type_register_static(&sii9022_info); +} + +type_init(sii9022_register_types)