edid.c 16 KB

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