diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-03-01 15:37:31 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-03-01 15:37:31 +0000 |
commit | 9db0855e8501365334e859370800c240d25322a2 (patch) | |
tree | bd4a8f0576258a43bf446035c26f9e5c1b1d2c40 /hw/display/sii9022.c | |
parent | 8cb340c613ee3e626b070e0429c589f8a60ac657 (diff) | |
parent | c22e580c2ad1cccef582e1490e732f254d4ac064 (diff) | |
download | qemu-9db0855e8501365334e859370800c240d25322a2.zip qemu-9db0855e8501365334e859370800c240d25322a2.tar.gz qemu-9db0855e8501365334e859370800c240d25322a2.tar.bz2 |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180301' into staging
target-arm queue:
* update MAINTAINERS for Alistair's new email address
* add Arm v8.2 FP16 arithmetic extension for linux-user
* implement display connector emulation for vexpress board
* xilinx_spips: Enable only two slaves when reading/writing with stripe
* xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands
* hw: register: Run post_write hook on reset
# gpg: Signature made Thu 01 Mar 2018 11:22:46 GMT
# gpg: using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg: aka "Peter Maydell <pmaydell@gmail.com>"
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20180301: (42 commits)
MAINTAINERS: Update my email address
linux-user: Report AArch64 FP16 support via hwcap bits
target/arm: Enable ARM_V8_FP16 feature bit for the AArch64 "any" CPU
arm/translate-a64: add all single op FP16 to handle_fp_1src_half
arm/translate-a64: implement simd_scalar_three_reg_same_fp16
arm/translate-a64: add all FP16 ops in simd_scalar_pairwise
arm/translate-a64: add FP16 FMOV to simd_mod_imm
arm/translate-a64: add FP16 FRSQRTE to simd_two_reg_misc_fp16
arm/helper.c: re-factor rsqrte and add rsqrte_f16
arm/translate-a64: add FP16 FSQRT to simd_two_reg_misc_fp16
arm/translate-a64: add FP16 FRCPX to simd_two_reg_misc_fp16
arm/translate-a64: add FP16 FRECPE
arm/helper.c: re-factor recpe and add recepe_f16
arm/translate-a64: add FP16 FNEG/FABS to simd_two_reg_misc_fp16
arm/translate-a64: add FP16 SCVTF/UCVFT to simd_two_reg_misc_fp16
arm/translate-a64: add FP16 FCMxx (zero) to simd_two_reg_misc_fp16
arm/translate-a64: add FCVTxx to simd_two_reg_misc_fp16
arm/translate-a64: add FP16 FPRINTx to simd_two_reg_misc_fp16
arm/translate-a64: initial decode for simd_two_reg_misc_fp16
arm/translate-a64: add FP16 x2 ops for simd_indexed
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/display/sii9022.c')
-rw-r--r-- | hw/display/sii9022.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c new file mode 100644 index 0000000..eaf11a6 --- /dev/null +++ b/hw/display/sii9022.c @@ -0,0 +1,191 @@ +/* + * 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 work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "hw/i2c/i2c.h" +#include "hw/i2c/i2c-ddc.h" +#include "trace.h" + +#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; + } + + trace_sii9022_read_reg(s->ptr, res); + 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; + trace_sii9022_switch_mode("DDC"); + } + } else { + s->ddc_req = false; + s->ddc = false; + trace_sii9022_switch_mode("normal"); + } + break; + default: + break; + } + + trace_sii9022_write_reg(s->ptr, data); + s->ptr++; + + return 0; +} + +static void sii9022_reset(DeviceState *dev) +{ + sii9022_state *s = SII9022(dev); + + s->ptr = 0; + s->addr_byte = false; + s->ddc_req = false; + s->ddc_skip_finish = false; + s->ddc = false; +} + +static void sii9022_realize(DeviceState *dev, Error **errp) +{ + I2CBus *bus; + + bus = I2C_BUS(qdev_get_parent_bus(dev)); + i2c_create_slave(bus, TYPE_I2CDDC, 0x50); +} + +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->realize = sii9022_realize; + 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) |