Commit 4023f301 authored by Xiaolin Zhang's avatar Xiaolin Zhang Committed by Zhenyu Wang

drm/i915/gvt: opregion virtualization for win guest

this is an enhanced opregion emulation for win guest support
by initializing more data members including opregion header
size, version and child device propertity for display port.
for simplicity, redefined child_device_config structure.
Signed-off-by: default avatarXiaolin Zhang <xiaolin.zhang@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent a2ae95af
...@@ -63,6 +63,60 @@ struct bdb_data_header { ...@@ -63,6 +63,60 @@ struct bdb_data_header {
u16 size; /* data size */ u16 size; /* data size */
} __packed; } __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 { struct vbt {
/* header->bdb_offset point to bdb_header offset */ /* header->bdb_offset point to bdb_header offset */
struct vbt_header header; struct vbt_header header;
...@@ -73,10 +127,11 @@ struct vbt { ...@@ -73,10 +127,11 @@ struct vbt {
struct bdb_data_header general_definitions_header; struct bdb_data_header general_definitions_header;
struct bdb_general_definitions general_definitions; struct bdb_general_definitions general_definitions;
struct child_device_config child0;
struct child_device_config child1; struct efp_child_device_config child0;
struct child_device_config child2; struct efp_child_device_config child1;
struct child_device_config child3; struct efp_child_device_config child2;
struct efp_child_device_config child3;
struct bdb_data_header driver_features_header; struct bdb_data_header driver_features_header;
struct bdb_driver_features driver_features; struct bdb_driver_features driver_features;
...@@ -100,7 +155,7 @@ static void virt_vbt_generation(struct vbt *v) ...@@ -100,7 +155,7 @@ static void virt_vbt_generation(struct vbt *v)
v->header.bdb_offset = offsetof(struct vbt, bdb_header); v->header.bdb_offset = offsetof(struct vbt, bdb_header);
strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK"); 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.header_size = sizeof(v->bdb_header);
v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_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) ...@@ -125,24 +180,32 @@ static void virt_vbt_generation(struct vbt *v)
v->child0.device_type = DEVICE_TYPE_DP; v->child0.device_type = DEVICE_TYPE_DP;
v->child0.dvo_port = DVO_PORT_DPA; v->child0.dvo_port = DVO_PORT_DPA;
v->child0.aux_channel = DP_AUX_A; v->child0.aux_channel = DP_AUX_A;
v->child0.dp_compat = true;
v->child0.integrated_encoder = true;
/* portB */ /* portB */
v->child1.handle = DEVICE_TYPE_EFP2; v->child1.handle = DEVICE_TYPE_EFP2;
v->child1.device_type = DEVICE_TYPE_DP; v->child1.device_type = DEVICE_TYPE_DP;
v->child1.dvo_port = DVO_PORT_DPB; v->child1.dvo_port = DVO_PORT_DPB;
v->child1.aux_channel = DP_AUX_B; v->child1.aux_channel = DP_AUX_B;
v->child1.dp_compat = true;
v->child1.integrated_encoder = true;
/* portC */ /* portC */
v->child2.handle = DEVICE_TYPE_EFP3; v->child2.handle = DEVICE_TYPE_EFP3;
v->child2.device_type = DEVICE_TYPE_DP; v->child2.device_type = DEVICE_TYPE_DP;
v->child2.dvo_port = DVO_PORT_DPC; v->child2.dvo_port = DVO_PORT_DPC;
v->child2.aux_channel = DP_AUX_C; v->child2.aux_channel = DP_AUX_C;
v->child2.dp_compat = true;
v->child2.integrated_encoder = true;
/* portD */ /* portD */
v->child3.handle = DEVICE_TYPE_EFP4; v->child3.handle = DEVICE_TYPE_EFP4;
v->child3.device_type = DEVICE_TYPE_DP; v->child3.device_type = DEVICE_TYPE_DP;
v->child3.dvo_port = DVO_PORT_DPD; v->child3.dvo_port = DVO_PORT_DPD;
v->child3.aux_channel = DP_AUX_D; v->child3.aux_channel = DP_AUX_D;
v->child3.dp_compat = true;
v->child3.integrated_encoder = true;
/* driver features */ /* driver features */
v->driver_features_header.id = BDB_DRIVER_FEATURES; v->driver_features_header.id = BDB_DRIVER_FEATURES;
...@@ -278,22 +341,23 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt) ...@@ -278,22 +341,23 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt)
} }
/* emulated opregion with VBT mailbox only */ /* 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, memcpy(header->signature, OPREGION_SIGNATURE,
sizeof(OPREGION_SIGNATURE)); sizeof(OPREGION_SIGNATURE));
header->size = 0x8;
header->opregion_ver = 0x02000000;
header->mboxes = MBOX_VBT; header->mboxes = MBOX_VBT;
/* for unknown reason, the value in LID field is incorrect /* for unknown reason, the value in LID field is incorrect
* which block the windows guest, so workaround it by force * which block the windows guest, so workaround it by force
* setting it to "OPEN" * setting it to "OPEN"
*/ */
buf = (u8 *)gvt->opregion.opregion_va;
buf[INTEL_GVT_OPREGION_CLID] = 0x3; buf[INTEL_GVT_OPREGION_CLID] = 0x3;
/* emulated vbt from virt vbt generation */ /* emulated vbt from virt vbt generation */
virt_vbt_generation(&v); virt_vbt_generation(&v);
memcpy(gvt->opregion.opregion_va + INTEL_GVT_OPREGION_VBT_OFFSET, memcpy(buf + INTEL_GVT_OPREGION_VBT_OFFSET, &v, sizeof(struct vbt));
&v, sizeof(struct vbt));
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment