[PATCH v1] drm/i915/gvt: opregion virtualization for win guest
Xiaolin Zhang
xiaolin.zhang at intel.com
Fri Oct 13 18:13:22 UTC 2017
this is an enhanced opregion emulation for win guest
by filling more struct data members. for simplicity,
redefined child_device_config structure.
Signed-off-by: Xiaolin Zhang <xiaolin.zhang at intel.com>
---
drivers/gpu/drm/i915/gvt/opregion.c | 85 ++++++++++++++++++++++++++++++++-----
1 file changed, 74 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index db8abac..ba8636d 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -63,6 +63,60 @@ struct bdb_data_header {
u16 size; /* data size */
} __packed;
+struct efp_child_device_config {
+ u16 handle;
+ u16 device_type;
+ u16 device_class;
+ u8 i2c_speed;
+ u8 dp_onboard_redriver; /* 158 */
+ u8 dp_ondock_redriver; /* 158 */
+ u8 hdmi_level_shifter_value:4; /* 169 */
+ u8 hdmi_max_data_rate:4; /* 204 */
+ u16 dtd_buf_ptr; /* 161 */
+ u8 edidless_efp:1; /* 161 */
+ u8 compression_enable:1; /* 198 */
+ u8 compression_method:1; /* 198 */
+ u8 ganged_edp:1; /* 202 */
+ u8 skip0:4;
+ u8 compression_structure_index:4; /* 198 */
+ u8 skip1:4;
+ u8 slave_port; /* 202 */
+ u8 skip2;
+ u8 dvo_port;
+ u8 i2c_pin; /* for add-in card */
+ u8 slave_addr; /* for add-in card */
+ u8 ddc_pin;
+ u16 edid_ptr;
+ u8 dvo_config;
+ u8 efp_docked_port:1; /* 158 */
+ u8 lane_reversal:1; /* 184 */
+ u8 onboard_lspcon:1; /* 192 */
+ u8 iboost_enable:1; /* 196 */
+ u8 hpd_invert:1; /* BXT 196 */
+ u8 slip3:3;
+ u8 hdmi_compat:1;
+ u8 dp_compat:1;
+ u8 tmds_compat:1;
+ u8 skip4:5;
+ u8 aux_channel;
+ u8 dongle_detect;
+ u8 pipe_cap:2;
+ u8 sdvo_stall:1; /* 158 */
+ u8 hpd_status:2;
+ u8 integrated_encoder:1;
+ u8 skip5:2;
+ u8 dvo_wiring;
+ u8 mipi_bridge_type; /* 171 */
+ u16 device_class_ext;
+ u8 dvo_function;
+ u8 dp_usb_type_c:1; /* 195 */
+ u8 skip6:7;
+ u8 dp_usb_type_c_2x_gpio_index; /* 195 */
+ u16 dp_usb_type_c_2x_gpio_pin; /* 195 */
+ u8 iboost_dp:4; /* 196 */
+ u8 iboost_hdmi:4; /* 196 */
+} __packed;
+
struct vbt {
/* header->bdb_offset point to bdb_header offset */
struct vbt_header header;
@@ -73,10 +127,11 @@ struct vbt {
struct bdb_data_header general_definitions_header;
struct bdb_general_definitions general_definitions;
- struct child_device_config child0;
- struct child_device_config child1;
- struct child_device_config child2;
- struct child_device_config child3;
+
+ struct efp_child_device_config child0;
+ struct efp_child_device_config child1;
+ struct efp_child_device_config child2;
+ struct efp_child_device_config child3;
struct bdb_data_header driver_features_header;
struct bdb_driver_features driver_features;
@@ -100,7 +155,7 @@ static void virt_vbt_generation(struct vbt *v)
v->header.bdb_offset = offsetof(struct vbt, bdb_header);
strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK");
- v->bdb_header.version = 198; /* child_dev_size = 38 */
+ v->bdb_header.version = 186; /* child_dev_size = 38 */
v->bdb_header.header_size = sizeof(v->bdb_header);
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header)
@@ -125,24 +180,32 @@ static void virt_vbt_generation(struct vbt *v)
v->child0.device_type = DEVICE_TYPE_DP;
v->child0.dvo_port = DVO_PORT_DPA;
v->child0.aux_channel = DP_AUX_A;
+ v->child0.dp_compat = true;
+ v->child0.integrated_encoder = true;
/* portB */
v->child1.handle = DEVICE_TYPE_EFP2;
v->child1.device_type = DEVICE_TYPE_DP;
v->child1.dvo_port = DVO_PORT_DPB;
v->child1.aux_channel = DP_AUX_B;
+ v->child1.dp_compat = true;
+ v->child1.integrated_encoder = true;
/* portC */
v->child2.handle = DEVICE_TYPE_EFP3;
v->child2.device_type = DEVICE_TYPE_DP;
v->child2.dvo_port = DVO_PORT_DPC;
v->child2.aux_channel = DP_AUX_C;
+ v->child2.dp_compat = true;
+ v->child2.integrated_encoder = true;
/* portD */
v->child3.handle = DEVICE_TYPE_EFP4;
v->child3.device_type = DEVICE_TYPE_DP;
v->child3.dvo_port = DVO_PORT_DPD;
v->child3.aux_channel = DP_AUX_D;
+ v->child3.dp_compat = true;
+ v->child3.integrated_encoder = true;
/* driver features */
v->driver_features_header.id = BDB_DRIVER_FEATURES;
@@ -207,9 +270,8 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
map_vgpu_opregion(vgpu, false);
free_pages((unsigned long)vgpu_opregion(vgpu)->va,
get_order(INTEL_GVT_OPREGION_SIZE));
-
- vgpu_opregion(vgpu)->va = NULL;
}
+ vgpu_opregion(vgpu)->va = NULL;
}
/**
@@ -278,22 +340,23 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt)
}
/* emulated opregion with VBT mailbox only */
- header = (struct opregion_header *)gvt->opregion.opregion_va;
+ buf = (u8 *)gvt->opregion.opregion_va;
+ header = (struct opregion_header *)buf;
memcpy(header->signature, OPREGION_SIGNATURE,
sizeof(OPREGION_SIGNATURE));
+ header->size = 0x8;
+ header->opregion_ver = 0x02000000;
header->mboxes = MBOX_VBT;
/* for unknown reason, the value in LID field is incorrect
* which block the windows guest, so workaround it by force
* setting it to "OPEN"
*/
- buf = (u8 *)gvt->opregion.opregion_va;
buf[INTEL_GVT_OPREGION_CLID] = 0x3;
/* emulated vbt from virt vbt generation */
virt_vbt_generation(&v);
- memcpy(gvt->opregion.opregion_va + INTEL_GVT_OPREGION_VBT_OFFSET,
- &v, sizeof(struct vbt));
+ memcpy(buf + INTEL_GVT_OPREGION_VBT_OFFSET, &v, sizeof(struct vbt));
return 0;
}
--
1.9.1
More information about the intel-gvt-dev
mailing list