diff mbox series

[05/12] drm/i915/bios: create fake child devices on missing VBT

Message ID 23911ee2dee946211f180ac92512ccbb87bbfcfe.1613580193.git.jani.nikula@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915/bios: vbt child device rework | expand

Commit Message

Jani Nikula Feb. 17, 2021, 5:03 p.m. UTC
Instead of initialing data directly in ddi_port_info array, create fake
child devices for default outputs when the VBT is missing. This makes
further unification of output handling easier.

This will make intel_bios_is_port_present() return true for the fake
child devices. This may cause subtle changes in a handful of places.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c | 47 ++++++++++++++++++-----
 1 file changed, 37 insertions(+), 10 deletions(-)

Comments

Lucas De Marchi March 9, 2021, 12:51 a.m. UTC | #1
On Wed, Feb 17, 2021 at 07:03:35PM +0200, Jani Nikula wrote:
>Instead of initialing data directly in ddi_port_info array, create fake
>child devices for default outputs when the VBT is missing. This makes
>further unification of output handling easier.
>
>This will make intel_bios_is_port_present() return true for the fake
>child devices. This may cause subtle changes in a handful of places.
>
>Cc: Lucas De Marchi <lucas.demarchi@intel.com>
>Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>---
> drivers/gpu/drm/i915/display/intel_bios.c | 47 ++++++++++++++++++-----
> 1 file changed, 37 insertions(+), 10 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
>index b9d99324d66d..59d315b395c2 100644
>--- a/drivers/gpu/drm/i915/display/intel_bios.c
>+++ b/drivers/gpu/drm/i915/display/intel_bios.c
>@@ -2063,8 +2063,8 @@ init_vbt_missing_defaults(struct drm_i915_private *i915)
> 		return;
>
> 	for_each_port_masked(port, ports) {
>-		struct ddi_vbt_port_info *info =
>-			&i915->vbt.ddi_port_info[port];
>+		struct display_device_data *devdata;
>+		struct child_device_config *child;
> 		enum phy phy = intel_port_to_phy(i915, port);
>
> 		/*
>@@ -2074,11 +2074,38 @@ init_vbt_missing_defaults(struct drm_i915_private *i915)
> 		if (intel_phy_is_tc(i915, phy))
> 			continue;
>
>-		info->supports_dvi = (port != PORT_A && port != PORT_E);
>-		info->supports_hdmi = info->supports_dvi;
>-		info->supports_dp = (port != PORT_E);
>-		info->supports_edp = (port == PORT_A);
>+		/* Create fake child device config */
>+		devdata = kzalloc(sizeof(*devdata), GFP_KERNEL);
>+		if (!devdata)
>+			break;
>+
>+		child = &devdata->child;
>+
>+		if (port == PORT_F)
>+			child->dvo_port = DVO_PORT_HDMIF;
>+		else if (port == PORT_E)
>+			child->dvo_port = DVO_PORT_HDMIE;
>+		else
>+			child->dvo_port = DVO_PORT_HDMIA + port;

initially I was confused here, but after checking I understoo why you're
doing this, since DVO_PORT_HDMIE/DVO_PORT_HDMIF doesn't follow
DVO_PORT_HDMID


Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>

Lucas De Marchi

>+
>+		if (port != PORT_A && port != PORT_E)
>+			child->device_type |= DEVICE_TYPE_TMDS_DVI_SIGNALING;
>+
>+		if (port != PORT_E)
>+			child->device_type |= DEVICE_TYPE_DISPLAYPORT_OUTPUT;
>+
>+		if (port == PORT_A)
>+			child->device_type |= DEVICE_TYPE_INTERNAL_CONNECTOR;
>+
>+		list_add_tail(&devdata->node, &i915->vbt.display_devices);
>+
>+		drm_dbg_kms(&i915->drm,
>+			    "Generating default VBT child device with type 0x04%x on port %c\n",
>+			    child->device_type, port_name(port));
> 	}
>+
>+	/* Bypass some minimum baseline VBT version checks */
>+	i915->vbt.version = 155;
> }
>
> static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
>@@ -2255,10 +2282,6 @@ void intel_bios_init(struct drm_i915_private *i915)
> 	/* Depends on child device list */
> 	parse_compression_parameters(i915, bdb);
>
>-	/* Further processing on pre-parsed data */
>-	parse_sdvo_device_mapping(i915);
>-	parse_ddi_ports(i915);
>-
> out:
> 	if (!vbt) {
> 		drm_info(&i915->drm,
>@@ -2266,6 +2289,10 @@ void intel_bios_init(struct drm_i915_private *i915)
> 		init_vbt_missing_defaults(i915);
> 	}
>
>+	/* Further processing on pre-parsed or generated child device data */
>+	parse_sdvo_device_mapping(i915);
>+	parse_ddi_ports(i915);
>+
> 	kfree(oprom_vbt);
> }
>
>-- 
>2.20.1
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index b9d99324d66d..59d315b395c2 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -2063,8 +2063,8 @@  init_vbt_missing_defaults(struct drm_i915_private *i915)
 		return;
 
 	for_each_port_masked(port, ports) {
-		struct ddi_vbt_port_info *info =
-			&i915->vbt.ddi_port_info[port];
+		struct display_device_data *devdata;
+		struct child_device_config *child;
 		enum phy phy = intel_port_to_phy(i915, port);
 
 		/*
@@ -2074,11 +2074,38 @@  init_vbt_missing_defaults(struct drm_i915_private *i915)
 		if (intel_phy_is_tc(i915, phy))
 			continue;
 
-		info->supports_dvi = (port != PORT_A && port != PORT_E);
-		info->supports_hdmi = info->supports_dvi;
-		info->supports_dp = (port != PORT_E);
-		info->supports_edp = (port == PORT_A);
+		/* Create fake child device config */
+		devdata = kzalloc(sizeof(*devdata), GFP_KERNEL);
+		if (!devdata)
+			break;
+
+		child = &devdata->child;
+
+		if (port == PORT_F)
+			child->dvo_port = DVO_PORT_HDMIF;
+		else if (port == PORT_E)
+			child->dvo_port = DVO_PORT_HDMIE;
+		else
+			child->dvo_port = DVO_PORT_HDMIA + port;
+
+		if (port != PORT_A && port != PORT_E)
+			child->device_type |= DEVICE_TYPE_TMDS_DVI_SIGNALING;
+
+		if (port != PORT_E)
+			child->device_type |= DEVICE_TYPE_DISPLAYPORT_OUTPUT;
+
+		if (port == PORT_A)
+			child->device_type |= DEVICE_TYPE_INTERNAL_CONNECTOR;
+
+		list_add_tail(&devdata->node, &i915->vbt.display_devices);
+
+		drm_dbg_kms(&i915->drm,
+			    "Generating default VBT child device with type 0x04%x on port %c\n",
+			    child->device_type, port_name(port));
 	}
+
+	/* Bypass some minimum baseline VBT version checks */
+	i915->vbt.version = 155;
 }
 
 static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
@@ -2255,10 +2282,6 @@  void intel_bios_init(struct drm_i915_private *i915)
 	/* Depends on child device list */
 	parse_compression_parameters(i915, bdb);
 
-	/* Further processing on pre-parsed data */
-	parse_sdvo_device_mapping(i915);
-	parse_ddi_ports(i915);
-
 out:
 	if (!vbt) {
 		drm_info(&i915->drm,
@@ -2266,6 +2289,10 @@  void intel_bios_init(struct drm_i915_private *i915)
 		init_vbt_missing_defaults(i915);
 	}
 
+	/* Further processing on pre-parsed or generated child device data */
+	parse_sdvo_device_mapping(i915);
+	parse_ddi_ports(i915);
+
 	kfree(oprom_vbt);
 }