cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

edid.c (15979B)


      1/*
      2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice (including the next
     12 * paragraph) shall be included in all copies or substantial portions of the
     13 * Software.
     14 *
     15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21 * SOFTWARE.
     22 *
     23 * Authors:
     24 *    Ke Yu
     25 *    Zhiyuan Lv <zhiyuan.lv@intel.com>
     26 *
     27 * Contributors:
     28 *    Terrence Xu <terrence.xu@intel.com>
     29 *    Changbin Du <changbin.du@intel.com>
     30 *    Bing Niu <bing.niu@intel.com>
     31 *    Zhi Wang <zhi.a.wang@intel.com>
     32 *
     33 */
     34
     35#include "i915_drv.h"
     36#include "i915_reg.h"
     37#include "gvt.h"
     38
     39#define GMBUS1_TOTAL_BYTES_SHIFT 16
     40#define GMBUS1_TOTAL_BYTES_MASK 0x1ff
     41#define gmbus1_total_byte_count(v) (((v) >> \
     42	GMBUS1_TOTAL_BYTES_SHIFT) & GMBUS1_TOTAL_BYTES_MASK)
     43#define gmbus1_slave_addr(v) (((v) & 0xff) >> 1)
     44#define gmbus1_slave_index(v) (((v) >> 8) & 0xff)
     45#define gmbus1_bus_cycle(v) (((v) >> 25) & 0x7)
     46
     47/* GMBUS0 bits definitions */
     48#define _GMBUS_PIN_SEL_MASK     (0x7)
     49
     50static unsigned char edid_get_byte(struct intel_vgpu *vgpu)
     51{
     52	struct intel_vgpu_i2c_edid *edid = &vgpu->display.i2c_edid;
     53	unsigned char chr = 0;
     54
     55	if (edid->state == I2C_NOT_SPECIFIED || !edid->slave_selected) {
     56		gvt_vgpu_err("Driver tries to read EDID without proper sequence!\n");
     57		return 0;
     58	}
     59	if (edid->current_edid_read >= EDID_SIZE) {
     60		gvt_vgpu_err("edid_get_byte() exceeds the size of EDID!\n");
     61		return 0;
     62	}
     63
     64	if (!edid->edid_available) {
     65		gvt_vgpu_err("Reading EDID but EDID is not available!\n");
     66		return 0;
     67	}
     68
     69	if (intel_vgpu_has_monitor_on_port(vgpu, edid->port)) {
     70		struct intel_vgpu_edid_data *edid_data =
     71			intel_vgpu_port(vgpu, edid->port)->edid;
     72
     73		chr = edid_data->edid_block[edid->current_edid_read];
     74		edid->current_edid_read++;
     75	} else {
     76		gvt_vgpu_err("No EDID available during the reading?\n");
     77	}
     78	return chr;
     79}
     80
     81static inline int cnp_get_port_from_gmbus0(u32 gmbus0)
     82{
     83	int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
     84	int port = -EINVAL;
     85
     86	if (port_select == GMBUS_PIN_1_BXT)
     87		port = PORT_B;
     88	else if (port_select == GMBUS_PIN_2_BXT)
     89		port = PORT_C;
     90	else if (port_select == GMBUS_PIN_3_BXT)
     91		port = PORT_D;
     92	else if (port_select == GMBUS_PIN_4_CNP)
     93		port = PORT_E;
     94	return port;
     95}
     96
     97static inline int bxt_get_port_from_gmbus0(u32 gmbus0)
     98{
     99	int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
    100	int port = -EINVAL;
    101
    102	if (port_select == GMBUS_PIN_1_BXT)
    103		port = PORT_B;
    104	else if (port_select == GMBUS_PIN_2_BXT)
    105		port = PORT_C;
    106	else if (port_select == GMBUS_PIN_3_BXT)
    107		port = PORT_D;
    108	return port;
    109}
    110
    111static inline int get_port_from_gmbus0(u32 gmbus0)
    112{
    113	int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
    114	int port = -EINVAL;
    115
    116	if (port_select == GMBUS_PIN_VGADDC)
    117		port = PORT_E;
    118	else if (port_select == GMBUS_PIN_DPC)
    119		port = PORT_C;
    120	else if (port_select == GMBUS_PIN_DPB)
    121		port = PORT_B;
    122	else if (port_select == GMBUS_PIN_DPD)
    123		port = PORT_D;
    124	return port;
    125}
    126
    127static void reset_gmbus_controller(struct intel_vgpu *vgpu)
    128{
    129	vgpu_vreg_t(vgpu, PCH_GMBUS2) = GMBUS_HW_RDY;
    130	if (!vgpu->display.i2c_edid.edid_available)
    131		vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_SATOER;
    132	vgpu->display.i2c_edid.gmbus.phase = GMBUS_IDLE_PHASE;
    133}
    134
    135/* GMBUS0 */
    136static int gmbus0_mmio_write(struct intel_vgpu *vgpu,
    137			unsigned int offset, void *p_data, unsigned int bytes)
    138{
    139	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
    140	int port, pin_select;
    141
    142	memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
    143
    144	pin_select = vgpu_vreg(vgpu, offset) & _GMBUS_PIN_SEL_MASK;
    145
    146	intel_vgpu_init_i2c_edid(vgpu);
    147
    148	if (pin_select == 0)
    149		return 0;
    150
    151	if (IS_BROXTON(i915))
    152		port = bxt_get_port_from_gmbus0(pin_select);
    153	else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
    154		port = cnp_get_port_from_gmbus0(pin_select);
    155	else
    156		port = get_port_from_gmbus0(pin_select);
    157	if (drm_WARN_ON(&i915->drm, port < 0))
    158		return 0;
    159
    160	vgpu->display.i2c_edid.state = I2C_GMBUS;
    161	vgpu->display.i2c_edid.gmbus.phase = GMBUS_IDLE_PHASE;
    162
    163	vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_ACTIVE;
    164	vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_HW_RDY | GMBUS_HW_WAIT_PHASE;
    165
    166	if (intel_vgpu_has_monitor_on_port(vgpu, port) &&
    167			!intel_vgpu_port_is_dp(vgpu, port)) {
    168		vgpu->display.i2c_edid.port = port;
    169		vgpu->display.i2c_edid.edid_available = true;
    170		vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_SATOER;
    171	} else
    172		vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_SATOER;
    173	return 0;
    174}
    175
    176static int gmbus1_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
    177		void *p_data, unsigned int bytes)
    178{
    179	struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
    180	u32 slave_addr;
    181	u32 wvalue = *(u32 *)p_data;
    182
    183	if (vgpu_vreg(vgpu, offset) & GMBUS_SW_CLR_INT) {
    184		if (!(wvalue & GMBUS_SW_CLR_INT)) {
    185			vgpu_vreg(vgpu, offset) &= ~GMBUS_SW_CLR_INT;
    186			reset_gmbus_controller(vgpu);
    187		}
    188		/*
    189		 * TODO: "This bit is cleared to zero when an event
    190		 * causes the HW_RDY bit transition to occur "
    191		 */
    192	} else {
    193		/*
    194		 * per bspec setting this bit can cause:
    195		 * 1) INT status bit cleared
    196		 * 2) HW_RDY bit asserted
    197		 */
    198		if (wvalue & GMBUS_SW_CLR_INT) {
    199			vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_INT;
    200			vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_HW_RDY;
    201		}
    202
    203		/* For virtualization, we suppose that HW is always ready,
    204		 * so GMBUS_SW_RDY should always be cleared
    205		 */
    206		if (wvalue & GMBUS_SW_RDY)
    207			wvalue &= ~GMBUS_SW_RDY;
    208
    209		i2c_edid->gmbus.total_byte_count =
    210			gmbus1_total_byte_count(wvalue);
    211		slave_addr = gmbus1_slave_addr(wvalue);
    212
    213		/* vgpu gmbus only support EDID */
    214		if (slave_addr == EDID_ADDR) {
    215			i2c_edid->slave_selected = true;
    216		} else if (slave_addr != 0) {
    217			gvt_dbg_dpy(
    218				"vgpu%d: unsupported gmbus slave addr(0x%x)\n"
    219				"	gmbus operations will be ignored.\n",
    220					vgpu->id, slave_addr);
    221		}
    222
    223		if (wvalue & GMBUS_CYCLE_INDEX)
    224			i2c_edid->current_edid_read =
    225				gmbus1_slave_index(wvalue);
    226
    227		i2c_edid->gmbus.cycle_type = gmbus1_bus_cycle(wvalue);
    228		switch (gmbus1_bus_cycle(wvalue)) {
    229		case GMBUS_NOCYCLE:
    230			break;
    231		case GMBUS_STOP:
    232			/* From spec:
    233			 * This can only cause a STOP to be generated
    234			 * if a GMBUS cycle is generated, the GMBUS is
    235			 * currently in a data/wait/idle phase, or it is in a
    236			 * WAIT phase
    237			 */
    238			if (gmbus1_bus_cycle(vgpu_vreg(vgpu, offset))
    239				!= GMBUS_NOCYCLE) {
    240				intel_vgpu_init_i2c_edid(vgpu);
    241				/* After the 'stop' cycle, hw state would become
    242				 * 'stop phase' and then 'idle phase' after a
    243				 * few milliseconds. In emulation, we just set
    244				 * it as 'idle phase' ('stop phase' is not
    245				 * visible in gmbus interface)
    246				 */
    247				i2c_edid->gmbus.phase = GMBUS_IDLE_PHASE;
    248				vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_ACTIVE;
    249			}
    250			break;
    251		case NIDX_NS_W:
    252		case IDX_NS_W:
    253		case NIDX_STOP:
    254		case IDX_STOP:
    255			/* From hw spec the GMBUS phase
    256			 * transition like this:
    257			 * START (-->INDEX) -->DATA
    258			 */
    259			i2c_edid->gmbus.phase = GMBUS_DATA_PHASE;
    260			vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_ACTIVE;
    261			break;
    262		default:
    263			gvt_vgpu_err("Unknown/reserved GMBUS cycle detected!\n");
    264			break;
    265		}
    266		/*
    267		 * From hw spec the WAIT state will be
    268		 * cleared:
    269		 * (1) in a new GMBUS cycle
    270		 * (2) by generating a stop
    271		 */
    272		vgpu_vreg(vgpu, offset) = wvalue;
    273	}
    274	return 0;
    275}
    276
    277static int gmbus3_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
    278	void *p_data, unsigned int bytes)
    279{
    280	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
    281
    282	drm_WARN_ON(&i915->drm, 1);
    283	return 0;
    284}
    285
    286static int gmbus3_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
    287		void *p_data, unsigned int bytes)
    288{
    289	int i;
    290	unsigned char byte_data;
    291	struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
    292	int byte_left = i2c_edid->gmbus.total_byte_count -
    293				i2c_edid->current_edid_read;
    294	int byte_count = byte_left;
    295	u32 reg_data = 0;
    296
    297	/* Data can only be recevied if previous settings correct */
    298	if (vgpu_vreg_t(vgpu, PCH_GMBUS1) & GMBUS_SLAVE_READ) {
    299		if (byte_left <= 0) {
    300			memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
    301			return 0;
    302		}
    303
    304		if (byte_count > 4)
    305			byte_count = 4;
    306		for (i = 0; i < byte_count; i++) {
    307			byte_data = edid_get_byte(vgpu);
    308			reg_data |= (byte_data << (i << 3));
    309		}
    310
    311		memcpy(&vgpu_vreg(vgpu, offset), &reg_data, byte_count);
    312		memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
    313
    314		if (byte_left <= 4) {
    315			switch (i2c_edid->gmbus.cycle_type) {
    316			case NIDX_STOP:
    317			case IDX_STOP:
    318				i2c_edid->gmbus.phase = GMBUS_IDLE_PHASE;
    319				break;
    320			case NIDX_NS_W:
    321			case IDX_NS_W:
    322			default:
    323				i2c_edid->gmbus.phase = GMBUS_WAIT_PHASE;
    324				break;
    325			}
    326			intel_vgpu_init_i2c_edid(vgpu);
    327		}
    328		/*
    329		 * Read GMBUS3 during send operation,
    330		 * return the latest written value
    331		 */
    332	} else {
    333		memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
    334		gvt_vgpu_err("warning: gmbus3 read with nothing returned\n");
    335	}
    336	return 0;
    337}
    338
    339static int gmbus2_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
    340		void *p_data, unsigned int bytes)
    341{
    342	u32 value = vgpu_vreg(vgpu, offset);
    343
    344	if (!(vgpu_vreg(vgpu, offset) & GMBUS_INUSE))
    345		vgpu_vreg(vgpu, offset) |= GMBUS_INUSE;
    346	memcpy(p_data, (void *)&value, bytes);
    347	return 0;
    348}
    349
    350static int gmbus2_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
    351		void *p_data, unsigned int bytes)
    352{
    353	u32 wvalue = *(u32 *)p_data;
    354
    355	if (wvalue & GMBUS_INUSE)
    356		vgpu_vreg(vgpu, offset) &= ~GMBUS_INUSE;
    357	/* All other bits are read-only */
    358	return 0;
    359}
    360
    361/**
    362 * intel_gvt_i2c_handle_gmbus_read - emulate gmbus register mmio read
    363 * @vgpu: a vGPU
    364 * @offset: reg offset
    365 * @p_data: data return buffer
    366 * @bytes: access data length
    367 *
    368 * This function is used to emulate gmbus register mmio read
    369 *
    370 * Returns:
    371 * Zero on success, negative error code if failed.
    372 *
    373 */
    374int intel_gvt_i2c_handle_gmbus_read(struct intel_vgpu *vgpu,
    375	unsigned int offset, void *p_data, unsigned int bytes)
    376{
    377	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
    378
    379	if (drm_WARN_ON(&i915->drm, bytes > 8 && (offset & (bytes - 1))))
    380		return -EINVAL;
    381
    382	if (offset == i915_mmio_reg_offset(PCH_GMBUS2))
    383		return gmbus2_mmio_read(vgpu, offset, p_data, bytes);
    384	else if (offset == i915_mmio_reg_offset(PCH_GMBUS3))
    385		return gmbus3_mmio_read(vgpu, offset, p_data, bytes);
    386
    387	memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
    388	return 0;
    389}
    390
    391/**
    392 * intel_gvt_i2c_handle_gmbus_write - emulate gmbus register mmio write
    393 * @vgpu: a vGPU
    394 * @offset: reg offset
    395 * @p_data: data return buffer
    396 * @bytes: access data length
    397 *
    398 * This function is used to emulate gmbus register mmio write
    399 *
    400 * Returns:
    401 * Zero on success, negative error code if failed.
    402 *
    403 */
    404int intel_gvt_i2c_handle_gmbus_write(struct intel_vgpu *vgpu,
    405		unsigned int offset, void *p_data, unsigned int bytes)
    406{
    407	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
    408
    409	if (drm_WARN_ON(&i915->drm, bytes > 8 && (offset & (bytes - 1))))
    410		return -EINVAL;
    411
    412	if (offset == i915_mmio_reg_offset(PCH_GMBUS0))
    413		return gmbus0_mmio_write(vgpu, offset, p_data, bytes);
    414	else if (offset == i915_mmio_reg_offset(PCH_GMBUS1))
    415		return gmbus1_mmio_write(vgpu, offset, p_data, bytes);
    416	else if (offset == i915_mmio_reg_offset(PCH_GMBUS2))
    417		return gmbus2_mmio_write(vgpu, offset, p_data, bytes);
    418	else if (offset == i915_mmio_reg_offset(PCH_GMBUS3))
    419		return gmbus3_mmio_write(vgpu, offset, p_data, bytes);
    420
    421	memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
    422	return 0;
    423}
    424
    425enum {
    426	AUX_CH_CTL = 0,
    427	AUX_CH_DATA1,
    428	AUX_CH_DATA2,
    429	AUX_CH_DATA3,
    430	AUX_CH_DATA4,
    431	AUX_CH_DATA5
    432};
    433
    434static inline int get_aux_ch_reg(unsigned int offset)
    435{
    436	int reg;
    437
    438	switch (offset & 0xff) {
    439	case 0x10:
    440		reg = AUX_CH_CTL;
    441		break;
    442	case 0x14:
    443		reg = AUX_CH_DATA1;
    444		break;
    445	case 0x18:
    446		reg = AUX_CH_DATA2;
    447		break;
    448	case 0x1c:
    449		reg = AUX_CH_DATA3;
    450		break;
    451	case 0x20:
    452		reg = AUX_CH_DATA4;
    453		break;
    454	case 0x24:
    455		reg = AUX_CH_DATA5;
    456		break;
    457	default:
    458		reg = -1;
    459		break;
    460	}
    461	return reg;
    462}
    463
    464#define AUX_CTL_MSG_LENGTH(reg) \
    465	((reg & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> \
    466		DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT)
    467
    468/**
    469 * intel_gvt_i2c_handle_aux_ch_write - emulate AUX channel register write
    470 * @vgpu: a vGPU
    471 * @port_idx: port index
    472 * @offset: reg offset
    473 * @p_data: write ptr
    474 *
    475 * This function is used to emulate AUX channel register write
    476 *
    477 */
    478void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
    479				int port_idx,
    480				unsigned int offset,
    481				void *p_data)
    482{
    483	struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
    484	struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
    485	int msg_length, ret_msg_size;
    486	int msg, addr, ctrl, op;
    487	u32 value = *(u32 *)p_data;
    488	int aux_data_for_write = 0;
    489	int reg = get_aux_ch_reg(offset);
    490
    491	if (reg != AUX_CH_CTL) {
    492		vgpu_vreg(vgpu, offset) = value;
    493		return;
    494	}
    495
    496	msg_length = AUX_CTL_MSG_LENGTH(value);
    497	// check the msg in DATA register.
    498	msg = vgpu_vreg(vgpu, offset + 4);
    499	addr = (msg >> 8) & 0xffff;
    500	ctrl = (msg >> 24) & 0xff;
    501	op = ctrl >> 4;
    502	if (!(value & DP_AUX_CH_CTL_SEND_BUSY)) {
    503		/* The ctl write to clear some states */
    504		return;
    505	}
    506
    507	/* Always set the wanted value for vms. */
    508	ret_msg_size = (((op & 0x1) == GVT_AUX_I2C_READ) ? 2 : 1);
    509	vgpu_vreg(vgpu, offset) =
    510		DP_AUX_CH_CTL_DONE |
    511		((ret_msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) &
    512		DP_AUX_CH_CTL_MESSAGE_SIZE_MASK);
    513
    514	if (msg_length == 3) {
    515		if (!(op & GVT_AUX_I2C_MOT)) {
    516			/* stop */
    517			intel_vgpu_init_i2c_edid(vgpu);
    518		} else {
    519			/* start or restart */
    520			i2c_edid->aux_ch.i2c_over_aux_ch = true;
    521			i2c_edid->aux_ch.aux_ch_mot = true;
    522			if (addr == 0) {
    523				/* reset the address */
    524				intel_vgpu_init_i2c_edid(vgpu);
    525			} else if (addr == EDID_ADDR) {
    526				i2c_edid->state = I2C_AUX_CH;
    527				i2c_edid->port = port_idx;
    528				i2c_edid->slave_selected = true;
    529				if (intel_vgpu_has_monitor_on_port(vgpu,
    530					port_idx) &&
    531					intel_vgpu_port_is_dp(vgpu, port_idx))
    532					i2c_edid->edid_available = true;
    533			}
    534		}
    535	} else if ((op & 0x1) == GVT_AUX_I2C_WRITE) {
    536		/* TODO
    537		 * We only support EDID reading from I2C_over_AUX. And
    538		 * we do not expect the index mode to be used. Right now
    539		 * the WRITE operation is ignored. It is good enough to
    540		 * support the gfx driver to do EDID access.
    541		 */
    542	} else {
    543		if (drm_WARN_ON(&i915->drm, (op & 0x1) != GVT_AUX_I2C_READ))
    544			return;
    545		if (drm_WARN_ON(&i915->drm, msg_length != 4))
    546			return;
    547		if (i2c_edid->edid_available && i2c_edid->slave_selected) {
    548			unsigned char val = edid_get_byte(vgpu);
    549
    550			aux_data_for_write = (val << 16);
    551		} else
    552			aux_data_for_write = (0xff << 16);
    553	}
    554	/* write the return value in AUX_CH_DATA reg which includes:
    555	 * ACK of I2C_WRITE
    556	 * returned byte if it is READ
    557	 */
    558	aux_data_for_write |= GVT_AUX_I2C_REPLY_ACK << 24;
    559	vgpu_vreg(vgpu, offset + 4) = aux_data_for_write;
    560}
    561
    562/**
    563 * intel_vgpu_init_i2c_edid - initialize vGPU i2c edid emulation
    564 * @vgpu: a vGPU
    565 *
    566 * This function is used to initialize vGPU i2c edid emulation stuffs
    567 *
    568 */
    569void intel_vgpu_init_i2c_edid(struct intel_vgpu *vgpu)
    570{
    571	struct intel_vgpu_i2c_edid *edid = &vgpu->display.i2c_edid;
    572
    573	edid->state = I2C_NOT_SPECIFIED;
    574
    575	edid->port = -1;
    576	edid->slave_selected = false;
    577	edid->edid_available = false;
    578	edid->current_edid_read = 0;
    579
    580	memset(&edid->gmbus, 0, sizeof(struct intel_vgpu_i2c_gmbus));
    581
    582	edid->aux_ch.i2c_over_aux_ch = false;
    583	edid->aux_ch.aux_ch_mot = false;
    584}