Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0021  * SOFTWARE.
0022  *
0023  * Authors:
0024  *    Ke Yu
0025  *    Zhiyuan Lv <zhiyuan.lv@intel.com>
0026  *
0027  * Contributors:
0028  *    Terrence Xu <terrence.xu@intel.com>
0029  *    Changbin Du <changbin.du@intel.com>
0030  *    Bing Niu <bing.niu@intel.com>
0031  *    Zhi Wang <zhi.a.wang@intel.com>
0032  *
0033  */
0034 
0035 #include "i915_drv.h"
0036 #include "i915_reg.h"
0037 #include "gvt.h"
0038 
0039 #define GMBUS1_TOTAL_BYTES_SHIFT 16
0040 #define GMBUS1_TOTAL_BYTES_MASK 0x1ff
0041 #define gmbus1_total_byte_count(v) (((v) >> \
0042     GMBUS1_TOTAL_BYTES_SHIFT) & GMBUS1_TOTAL_BYTES_MASK)
0043 #define gmbus1_slave_addr(v) (((v) & 0xff) >> 1)
0044 #define gmbus1_slave_index(v) (((v) >> 8) & 0xff)
0045 #define gmbus1_bus_cycle(v) (((v) >> 25) & 0x7)
0046 
0047 /* GMBUS0 bits definitions */
0048 #define _GMBUS_PIN_SEL_MASK     (0x7)
0049 
0050 static unsigned char edid_get_byte(struct intel_vgpu *vgpu)
0051 {
0052     struct intel_vgpu_i2c_edid *edid = &vgpu->display.i2c_edid;
0053     unsigned char chr = 0;
0054 
0055     if (edid->state == I2C_NOT_SPECIFIED || !edid->slave_selected) {
0056         gvt_vgpu_err("Driver tries to read EDID without proper sequence!\n");
0057         return 0;
0058     }
0059     if (edid->current_edid_read >= EDID_SIZE) {
0060         gvt_vgpu_err("edid_get_byte() exceeds the size of EDID!\n");
0061         return 0;
0062     }
0063 
0064     if (!edid->edid_available) {
0065         gvt_vgpu_err("Reading EDID but EDID is not available!\n");
0066         return 0;
0067     }
0068 
0069     if (intel_vgpu_has_monitor_on_port(vgpu, edid->port)) {
0070         struct intel_vgpu_edid_data *edid_data =
0071             intel_vgpu_port(vgpu, edid->port)->edid;
0072 
0073         chr = edid_data->edid_block[edid->current_edid_read];
0074         edid->current_edid_read++;
0075     } else {
0076         gvt_vgpu_err("No EDID available during the reading?\n");
0077     }
0078     return chr;
0079 }
0080 
0081 static inline int cnp_get_port_from_gmbus0(u32 gmbus0)
0082 {
0083     int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
0084     int port = -EINVAL;
0085 
0086     if (port_select == GMBUS_PIN_1_BXT)
0087         port = PORT_B;
0088     else if (port_select == GMBUS_PIN_2_BXT)
0089         port = PORT_C;
0090     else if (port_select == GMBUS_PIN_3_BXT)
0091         port = PORT_D;
0092     else if (port_select == GMBUS_PIN_4_CNP)
0093         port = PORT_E;
0094     return port;
0095 }
0096 
0097 static inline int bxt_get_port_from_gmbus0(u32 gmbus0)
0098 {
0099     int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
0100     int port = -EINVAL;
0101 
0102     if (port_select == GMBUS_PIN_1_BXT)
0103         port = PORT_B;
0104     else if (port_select == GMBUS_PIN_2_BXT)
0105         port = PORT_C;
0106     else if (port_select == GMBUS_PIN_3_BXT)
0107         port = PORT_D;
0108     return port;
0109 }
0110 
0111 static inline int get_port_from_gmbus0(u32 gmbus0)
0112 {
0113     int port_select = gmbus0 & _GMBUS_PIN_SEL_MASK;
0114     int port = -EINVAL;
0115 
0116     if (port_select == GMBUS_PIN_VGADDC)
0117         port = PORT_E;
0118     else if (port_select == GMBUS_PIN_DPC)
0119         port = PORT_C;
0120     else if (port_select == GMBUS_PIN_DPB)
0121         port = PORT_B;
0122     else if (port_select == GMBUS_PIN_DPD)
0123         port = PORT_D;
0124     return port;
0125 }
0126 
0127 static void reset_gmbus_controller(struct intel_vgpu *vgpu)
0128 {
0129     vgpu_vreg_t(vgpu, PCH_GMBUS2) = GMBUS_HW_RDY;
0130     if (!vgpu->display.i2c_edid.edid_available)
0131         vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_SATOER;
0132     vgpu->display.i2c_edid.gmbus.phase = GMBUS_IDLE_PHASE;
0133 }
0134 
0135 /* GMBUS0 */
0136 static int gmbus0_mmio_write(struct intel_vgpu *vgpu,
0137             unsigned int offset, void *p_data, unsigned int bytes)
0138 {
0139     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0140     int port, pin_select;
0141 
0142     memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
0143 
0144     pin_select = vgpu_vreg(vgpu, offset) & _GMBUS_PIN_SEL_MASK;
0145 
0146     intel_vgpu_init_i2c_edid(vgpu);
0147 
0148     if (pin_select == 0)
0149         return 0;
0150 
0151     if (IS_BROXTON(i915))
0152         port = bxt_get_port_from_gmbus0(pin_select);
0153     else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
0154         port = cnp_get_port_from_gmbus0(pin_select);
0155     else
0156         port = get_port_from_gmbus0(pin_select);
0157     if (drm_WARN_ON(&i915->drm, port < 0))
0158         return 0;
0159 
0160     vgpu->display.i2c_edid.state = I2C_GMBUS;
0161     vgpu->display.i2c_edid.gmbus.phase = GMBUS_IDLE_PHASE;
0162 
0163     vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_ACTIVE;
0164     vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_HW_RDY | GMBUS_HW_WAIT_PHASE;
0165 
0166     if (intel_vgpu_has_monitor_on_port(vgpu, port) &&
0167             !intel_vgpu_port_is_dp(vgpu, port)) {
0168         vgpu->display.i2c_edid.port = port;
0169         vgpu->display.i2c_edid.edid_available = true;
0170         vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_SATOER;
0171     } else
0172         vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_SATOER;
0173     return 0;
0174 }
0175 
0176 static int gmbus1_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
0177         void *p_data, unsigned int bytes)
0178 {
0179     struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
0180     u32 slave_addr;
0181     u32 wvalue = *(u32 *)p_data;
0182 
0183     if (vgpu_vreg(vgpu, offset) & GMBUS_SW_CLR_INT) {
0184         if (!(wvalue & GMBUS_SW_CLR_INT)) {
0185             vgpu_vreg(vgpu, offset) &= ~GMBUS_SW_CLR_INT;
0186             reset_gmbus_controller(vgpu);
0187         }
0188         /*
0189          * TODO: "This bit is cleared to zero when an event
0190          * causes the HW_RDY bit transition to occur "
0191          */
0192     } else {
0193         /*
0194          * per bspec setting this bit can cause:
0195          * 1) INT status bit cleared
0196          * 2) HW_RDY bit asserted
0197          */
0198         if (wvalue & GMBUS_SW_CLR_INT) {
0199             vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_INT;
0200             vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_HW_RDY;
0201         }
0202 
0203         /* For virtualization, we suppose that HW is always ready,
0204          * so GMBUS_SW_RDY should always be cleared
0205          */
0206         if (wvalue & GMBUS_SW_RDY)
0207             wvalue &= ~GMBUS_SW_RDY;
0208 
0209         i2c_edid->gmbus.total_byte_count =
0210             gmbus1_total_byte_count(wvalue);
0211         slave_addr = gmbus1_slave_addr(wvalue);
0212 
0213         /* vgpu gmbus only support EDID */
0214         if (slave_addr == EDID_ADDR) {
0215             i2c_edid->slave_selected = true;
0216         } else if (slave_addr != 0) {
0217             gvt_dbg_dpy(
0218                 "vgpu%d: unsupported gmbus slave addr(0x%x)\n"
0219                 "   gmbus operations will be ignored.\n",
0220                     vgpu->id, slave_addr);
0221         }
0222 
0223         if (wvalue & GMBUS_CYCLE_INDEX)
0224             i2c_edid->current_edid_read =
0225                 gmbus1_slave_index(wvalue);
0226 
0227         i2c_edid->gmbus.cycle_type = gmbus1_bus_cycle(wvalue);
0228         switch (gmbus1_bus_cycle(wvalue)) {
0229         case GMBUS_NOCYCLE:
0230             break;
0231         case GMBUS_STOP:
0232             /* From spec:
0233              * This can only cause a STOP to be generated
0234              * if a GMBUS cycle is generated, the GMBUS is
0235              * currently in a data/wait/idle phase, or it is in a
0236              * WAIT phase
0237              */
0238             if (gmbus1_bus_cycle(vgpu_vreg(vgpu, offset))
0239                 != GMBUS_NOCYCLE) {
0240                 intel_vgpu_init_i2c_edid(vgpu);
0241                 /* After the 'stop' cycle, hw state would become
0242                  * 'stop phase' and then 'idle phase' after a
0243                  * few milliseconds. In emulation, we just set
0244                  * it as 'idle phase' ('stop phase' is not
0245                  * visible in gmbus interface)
0246                  */
0247                 i2c_edid->gmbus.phase = GMBUS_IDLE_PHASE;
0248                 vgpu_vreg_t(vgpu, PCH_GMBUS2) &= ~GMBUS_ACTIVE;
0249             }
0250             break;
0251         case NIDX_NS_W:
0252         case IDX_NS_W:
0253         case NIDX_STOP:
0254         case IDX_STOP:
0255             /* From hw spec the GMBUS phase
0256              * transition like this:
0257              * START (-->INDEX) -->DATA
0258              */
0259             i2c_edid->gmbus.phase = GMBUS_DATA_PHASE;
0260             vgpu_vreg_t(vgpu, PCH_GMBUS2) |= GMBUS_ACTIVE;
0261             break;
0262         default:
0263             gvt_vgpu_err("Unknown/reserved GMBUS cycle detected!\n");
0264             break;
0265         }
0266         /*
0267          * From hw spec the WAIT state will be
0268          * cleared:
0269          * (1) in a new GMBUS cycle
0270          * (2) by generating a stop
0271          */
0272         vgpu_vreg(vgpu, offset) = wvalue;
0273     }
0274     return 0;
0275 }
0276 
0277 static int gmbus3_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
0278     void *p_data, unsigned int bytes)
0279 {
0280     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0281 
0282     drm_WARN_ON(&i915->drm, 1);
0283     return 0;
0284 }
0285 
0286 static int gmbus3_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
0287         void *p_data, unsigned int bytes)
0288 {
0289     int i;
0290     unsigned char byte_data;
0291     struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
0292     int byte_left = i2c_edid->gmbus.total_byte_count -
0293                 i2c_edid->current_edid_read;
0294     int byte_count = byte_left;
0295     u32 reg_data = 0;
0296 
0297     /* Data can only be recevied if previous settings correct */
0298     if (vgpu_vreg_t(vgpu, PCH_GMBUS1) & GMBUS_SLAVE_READ) {
0299         if (byte_left <= 0) {
0300             memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
0301             return 0;
0302         }
0303 
0304         if (byte_count > 4)
0305             byte_count = 4;
0306         for (i = 0; i < byte_count; i++) {
0307             byte_data = edid_get_byte(vgpu);
0308             reg_data |= (byte_data << (i << 3));
0309         }
0310 
0311         memcpy(&vgpu_vreg(vgpu, offset), &reg_data, byte_count);
0312         memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
0313 
0314         if (byte_left <= 4) {
0315             switch (i2c_edid->gmbus.cycle_type) {
0316             case NIDX_STOP:
0317             case IDX_STOP:
0318                 i2c_edid->gmbus.phase = GMBUS_IDLE_PHASE;
0319                 break;
0320             case NIDX_NS_W:
0321             case IDX_NS_W:
0322             default:
0323                 i2c_edid->gmbus.phase = GMBUS_WAIT_PHASE;
0324                 break;
0325             }
0326             intel_vgpu_init_i2c_edid(vgpu);
0327         }
0328         /*
0329          * Read GMBUS3 during send operation,
0330          * return the latest written value
0331          */
0332     } else {
0333         memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
0334         gvt_vgpu_err("warning: gmbus3 read with nothing returned\n");
0335     }
0336     return 0;
0337 }
0338 
0339 static int gmbus2_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
0340         void *p_data, unsigned int bytes)
0341 {
0342     u32 value = vgpu_vreg(vgpu, offset);
0343 
0344     if (!(vgpu_vreg(vgpu, offset) & GMBUS_INUSE))
0345         vgpu_vreg(vgpu, offset) |= GMBUS_INUSE;
0346     memcpy(p_data, (void *)&value, bytes);
0347     return 0;
0348 }
0349 
0350 static int gmbus2_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
0351         void *p_data, unsigned int bytes)
0352 {
0353     u32 wvalue = *(u32 *)p_data;
0354 
0355     if (wvalue & GMBUS_INUSE)
0356         vgpu_vreg(vgpu, offset) &= ~GMBUS_INUSE;
0357     /* All other bits are read-only */
0358     return 0;
0359 }
0360 
0361 /**
0362  * intel_gvt_i2c_handle_gmbus_read - emulate gmbus register mmio read
0363  * @vgpu: a vGPU
0364  * @offset: reg offset
0365  * @p_data: data return buffer
0366  * @bytes: access data length
0367  *
0368  * This function is used to emulate gmbus register mmio read
0369  *
0370  * Returns:
0371  * Zero on success, negative error code if failed.
0372  *
0373  */
0374 int intel_gvt_i2c_handle_gmbus_read(struct intel_vgpu *vgpu,
0375     unsigned int offset, void *p_data, unsigned int bytes)
0376 {
0377     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0378 
0379     if (drm_WARN_ON(&i915->drm, bytes > 8 && (offset & (bytes - 1))))
0380         return -EINVAL;
0381 
0382     if (offset == i915_mmio_reg_offset(PCH_GMBUS2))
0383         return gmbus2_mmio_read(vgpu, offset, p_data, bytes);
0384     else if (offset == i915_mmio_reg_offset(PCH_GMBUS3))
0385         return gmbus3_mmio_read(vgpu, offset, p_data, bytes);
0386 
0387     memcpy(p_data, &vgpu_vreg(vgpu, offset), bytes);
0388     return 0;
0389 }
0390 
0391 /**
0392  * intel_gvt_i2c_handle_gmbus_write - emulate gmbus register mmio write
0393  * @vgpu: a vGPU
0394  * @offset: reg offset
0395  * @p_data: data return buffer
0396  * @bytes: access data length
0397  *
0398  * This function is used to emulate gmbus register mmio write
0399  *
0400  * Returns:
0401  * Zero on success, negative error code if failed.
0402  *
0403  */
0404 int intel_gvt_i2c_handle_gmbus_write(struct intel_vgpu *vgpu,
0405         unsigned int offset, void *p_data, unsigned int bytes)
0406 {
0407     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0408 
0409     if (drm_WARN_ON(&i915->drm, bytes > 8 && (offset & (bytes - 1))))
0410         return -EINVAL;
0411 
0412     if (offset == i915_mmio_reg_offset(PCH_GMBUS0))
0413         return gmbus0_mmio_write(vgpu, offset, p_data, bytes);
0414     else if (offset == i915_mmio_reg_offset(PCH_GMBUS1))
0415         return gmbus1_mmio_write(vgpu, offset, p_data, bytes);
0416     else if (offset == i915_mmio_reg_offset(PCH_GMBUS2))
0417         return gmbus2_mmio_write(vgpu, offset, p_data, bytes);
0418     else if (offset == i915_mmio_reg_offset(PCH_GMBUS3))
0419         return gmbus3_mmio_write(vgpu, offset, p_data, bytes);
0420 
0421     memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
0422     return 0;
0423 }
0424 
0425 enum {
0426     AUX_CH_CTL = 0,
0427     AUX_CH_DATA1,
0428     AUX_CH_DATA2,
0429     AUX_CH_DATA3,
0430     AUX_CH_DATA4,
0431     AUX_CH_DATA5
0432 };
0433 
0434 static inline int get_aux_ch_reg(unsigned int offset)
0435 {
0436     int reg;
0437 
0438     switch (offset & 0xff) {
0439     case 0x10:
0440         reg = AUX_CH_CTL;
0441         break;
0442     case 0x14:
0443         reg = AUX_CH_DATA1;
0444         break;
0445     case 0x18:
0446         reg = AUX_CH_DATA2;
0447         break;
0448     case 0x1c:
0449         reg = AUX_CH_DATA3;
0450         break;
0451     case 0x20:
0452         reg = AUX_CH_DATA4;
0453         break;
0454     case 0x24:
0455         reg = AUX_CH_DATA5;
0456         break;
0457     default:
0458         reg = -1;
0459         break;
0460     }
0461     return reg;
0462 }
0463 
0464 #define AUX_CTL_MSG_LENGTH(reg) \
0465     ((reg & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> \
0466         DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT)
0467 
0468 /**
0469  * intel_gvt_i2c_handle_aux_ch_write - emulate AUX channel register write
0470  * @vgpu: a vGPU
0471  * @port_idx: port index
0472  * @offset: reg offset
0473  * @p_data: write ptr
0474  *
0475  * This function is used to emulate AUX channel register write
0476  *
0477  */
0478 void intel_gvt_i2c_handle_aux_ch_write(struct intel_vgpu *vgpu,
0479                 int port_idx,
0480                 unsigned int offset,
0481                 void *p_data)
0482 {
0483     struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
0484     struct intel_vgpu_i2c_edid *i2c_edid = &vgpu->display.i2c_edid;
0485     int msg_length, ret_msg_size;
0486     int msg, addr, ctrl, op;
0487     u32 value = *(u32 *)p_data;
0488     int aux_data_for_write = 0;
0489     int reg = get_aux_ch_reg(offset);
0490 
0491     if (reg != AUX_CH_CTL) {
0492         vgpu_vreg(vgpu, offset) = value;
0493         return;
0494     }
0495 
0496     msg_length = AUX_CTL_MSG_LENGTH(value);
0497     // check the msg in DATA register.
0498     msg = vgpu_vreg(vgpu, offset + 4);
0499     addr = (msg >> 8) & 0xffff;
0500     ctrl = (msg >> 24) & 0xff;
0501     op = ctrl >> 4;
0502     if (!(value & DP_AUX_CH_CTL_SEND_BUSY)) {
0503         /* The ctl write to clear some states */
0504         return;
0505     }
0506 
0507     /* Always set the wanted value for vms. */
0508     ret_msg_size = (((op & 0x1) == GVT_AUX_I2C_READ) ? 2 : 1);
0509     vgpu_vreg(vgpu, offset) =
0510         DP_AUX_CH_CTL_DONE |
0511         ((ret_msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) &
0512         DP_AUX_CH_CTL_MESSAGE_SIZE_MASK);
0513 
0514     if (msg_length == 3) {
0515         if (!(op & GVT_AUX_I2C_MOT)) {
0516             /* stop */
0517             intel_vgpu_init_i2c_edid(vgpu);
0518         } else {
0519             /* start or restart */
0520             i2c_edid->aux_ch.i2c_over_aux_ch = true;
0521             i2c_edid->aux_ch.aux_ch_mot = true;
0522             if (addr == 0) {
0523                 /* reset the address */
0524                 intel_vgpu_init_i2c_edid(vgpu);
0525             } else if (addr == EDID_ADDR) {
0526                 i2c_edid->state = I2C_AUX_CH;
0527                 i2c_edid->port = port_idx;
0528                 i2c_edid->slave_selected = true;
0529                 if (intel_vgpu_has_monitor_on_port(vgpu,
0530                     port_idx) &&
0531                     intel_vgpu_port_is_dp(vgpu, port_idx))
0532                     i2c_edid->edid_available = true;
0533             }
0534         }
0535     } else if ((op & 0x1) == GVT_AUX_I2C_WRITE) {
0536         /* TODO
0537          * We only support EDID reading from I2C_over_AUX. And
0538          * we do not expect the index mode to be used. Right now
0539          * the WRITE operation is ignored. It is good enough to
0540          * support the gfx driver to do EDID access.
0541          */
0542     } else {
0543         if (drm_WARN_ON(&i915->drm, (op & 0x1) != GVT_AUX_I2C_READ))
0544             return;
0545         if (drm_WARN_ON(&i915->drm, msg_length != 4))
0546             return;
0547         if (i2c_edid->edid_available && i2c_edid->slave_selected) {
0548             unsigned char val = edid_get_byte(vgpu);
0549 
0550             aux_data_for_write = (val << 16);
0551         } else
0552             aux_data_for_write = (0xff << 16);
0553     }
0554     /* write the return value in AUX_CH_DATA reg which includes:
0555      * ACK of I2C_WRITE
0556      * returned byte if it is READ
0557      */
0558     aux_data_for_write |= GVT_AUX_I2C_REPLY_ACK << 24;
0559     vgpu_vreg(vgpu, offset + 4) = aux_data_for_write;
0560 }
0561 
0562 /**
0563  * intel_vgpu_init_i2c_edid - initialize vGPU i2c edid emulation
0564  * @vgpu: a vGPU
0565  *
0566  * This function is used to initialize vGPU i2c edid emulation stuffs
0567  *
0568  */
0569 void intel_vgpu_init_i2c_edid(struct intel_vgpu *vgpu)
0570 {
0571     struct intel_vgpu_i2c_edid *edid = &vgpu->display.i2c_edid;
0572 
0573     edid->state = I2C_NOT_SPECIFIED;
0574 
0575     edid->port = -1;
0576     edid->slave_selected = false;
0577     edid->edid_available = false;
0578     edid->current_edid_read = 0;
0579 
0580     memset(&edid->gmbus, 0, sizeof(struct intel_vgpu_i2c_gmbus));
0581 
0582     edid->aux_ch.i2c_over_aux_ch = false;
0583     edid->aux_ch.aux_ch_mot = false;
0584 }