edid.c 16 KB

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