root/drivers/gpu/drm/i915/gvt/edid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. edid_get_byte
  2. cnp_get_port_from_gmbus0
  3. bxt_get_port_from_gmbus0
  4. get_port_from_gmbus0
  5. reset_gmbus_controller
  6. gmbus0_mmio_write
  7. gmbus1_mmio_write
  8. gmbus3_mmio_write
  9. gmbus3_mmio_read
  10. gmbus2_mmio_read
  11. gmbus2_mmio_write
  12. intel_gvt_i2c_handle_gmbus_read
  13. intel_gvt_i2c_handle_gmbus_write
  14. get_aux_ch_reg
  15. intel_gvt_i2c_handle_aux_ch_write
  16. intel_vgpu_init_i2c_edid

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

/* [<][>][^][v][top][bottom][index][help] */