[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