All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915/bios: iterate over child devices to initialize ddi_port_info
Date: Mon, 25 Mar 2019 15:30:54 +0200	[thread overview]
Message-ID: <87zhpjqdwx.fsf@intel.com> (raw)
In-Reply-To: <20190322121008.4456-1-jani.nikula@intel.com>

On Fri, 22 Mar 2019, Jani Nikula <jani.nikula@intel.com> wrote:
> Iterate over child devices instead of ports in parse_ddi_ports() to
> initialize dri_port_info. We'll eventually need to decide some stuff
> based on the child device order, which may be different from the port
> order.
>
> As a bonus, this allows better abstractions for e.g. dvo port mapping.
>
> There's a subtle change in the DDC pin and AUX channel sanitization as
> we change the order. Otherwise, this should not change behaviour.
>
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Pushed to dinq, thanks for the review.

BR,
Jani.

> ---
>  drivers/gpu/drm/i915/i915_drv.h   |   1 +
>  drivers/gpu/drm/i915/intel_bios.c | 104 +++++++++++++++++-------------
>  2 files changed, 59 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index fefcb39aefc4..d82d63dfa5a1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -954,6 +954,7 @@ struct ddi_vbt_port_info {
>  #define HDMI_LEVEL_SHIFT_UNKNOWN	0xff
>  	u8 hdmi_level_shift;
>  
> +	u8 present:1;
>  	u8 supports_dvi:1;
>  	u8 supports_hdmi:1;
>  	u8 supports_dp:1;
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 64f20175a6dc..1dc8d03ff127 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -1247,10 +1247,11 @@ static void sanitize_ddc_pin(struct drm_i915_private *dev_priv,
>  	if (!info->alternate_ddc_pin)
>  		return;
>  
> -	for_each_port_masked(p, (1 << port) - 1) {
> +	for (p = PORT_A; p < I915_MAX_PORTS; p++) {
>  		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
>  
> -		if (info->alternate_ddc_pin != i->alternate_ddc_pin)
> +		if (p == port || !i->present ||
> +		    info->alternate_ddc_pin != i->alternate_ddc_pin)
>  			continue;
>  
>  		DRM_DEBUG_KMS("port %c trying to use the same DDC pin (0x%x) as port %c, "
> @@ -1264,8 +1265,8 @@ static void sanitize_ddc_pin(struct drm_i915_private *dev_priv,
>  		 * port. Otherwise they share the same ddc bin and
>  		 * system couldn't communicate with them separately.
>  		 *
> -		 * Due to parsing the ports in alphabetical order,
> -		 * a higher port will always clobber a lower one.
> +		 * Due to parsing the ports in child device order,
> +		 * a later device will always clobber an earlier one.
>  		 */
>  		i->supports_dvi = false;
>  		i->supports_hdmi = false;
> @@ -1283,10 +1284,11 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv,
>  	if (!info->alternate_aux_channel)
>  		return;
>  
> -	for_each_port_masked(p, (1 << port) - 1) {
> +	for (p = PORT_A; p < I915_MAX_PORTS; p++) {
>  		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
>  
> -		if (info->alternate_aux_channel != i->alternate_aux_channel)
> +		if (p == port || !i->present ||
> +		    info->alternate_aux_channel != i->alternate_aux_channel)
>  			continue;
>  
>  		DRM_DEBUG_KMS("port %c trying to use the same AUX CH (0x%x) as port %c, "
> @@ -1300,8 +1302,8 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv,
>  		 * port. Otherwise they share the same aux channel
>  		 * and system couldn't communicate with them separately.
>  		 *
> -		 * Due to parsing the ports in alphabetical order,
> -		 * a higher port will always clobber a lower one.
> +		 * Due to parsing the ports in child device order,
> +		 * a later device will always clobber an earlier one.
>  		 */
>  		i->supports_dp = false;
>  		i->alternate_aux_channel = 0;
> @@ -1349,49 +1351,58 @@ static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
>  	return 0;
>  }
>  
> -static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
> -			   u8 bdb_version)
> +static enum port dvo_port_to_port(u8 dvo_port)
>  {
> -	struct child_device_config *it, *child = NULL;
> -	struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port];
> -	int i, j;
> -	bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
> -	/* Each DDI port can have more than one value on the "DVO Port" field,
> +	/*
> +	 * Each DDI port can have more than one value on the "DVO Port" field,
>  	 * so look for all the possible values for each port.
>  	 */
> -	int dvo_ports[][3] = {
> -		{DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
> -		{DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
> -		{DVO_PORT_HDMIC, DVO_PORT_DPC, -1},
> -		{DVO_PORT_HDMID, DVO_PORT_DPD, -1},
> -		{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
> -		{DVO_PORT_HDMIF, DVO_PORT_DPF, -1},
> +	static const int dvo_ports[][3] = {
> +		[PORT_A] = { DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
> +		[PORT_B] = { DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
> +		[PORT_C] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1},
> +		[PORT_D] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1},
> +		[PORT_E] = { DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
> +		[PORT_F] = { DVO_PORT_HDMIF, DVO_PORT_DPF, -1},
>  	};
> +	enum port port;
> +	int i;
>  
> -	/*
> -	 * Find the first child device to reference the port, report if more
> -	 * than one found.
> -	 */
> -	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
> -		it = dev_priv->vbt.child_dev + i;
> -
> -		for (j = 0; j < 3; j++) {
> -			if (dvo_ports[port][j] == -1)
> +	for (port = PORT_A; port < ARRAY_SIZE(dvo_ports); port++) {
> +		for (i = 0; i < ARRAY_SIZE(dvo_ports[port]); i++) {
> +			if (dvo_ports[port][i] == -1)
>  				break;
>  
> -			if (it->dvo_port == dvo_ports[port][j]) {
> -				if (child) {
> -					DRM_DEBUG_KMS("More than one child device for port %c in VBT, using the first.\n",
> -						      port_name(port));
> -				} else {
> -					child = it;
> -				}
> -			}
> +			if (dvo_port == dvo_ports[port][i])
> +				return port;
>  		}
>  	}
> -	if (!child)
> +
> +	return PORT_NONE;
> +}
> +
> +static void parse_ddi_port(struct drm_i915_private *dev_priv,
> +			   const struct child_device_config *child,
> +			   u8 bdb_version)
> +{
> +	struct ddi_vbt_port_info *info;
> +	bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
> +	enum port port;
> +
> +	port = dvo_port_to_port(child->dvo_port);
> +	if (port == PORT_NONE)
>  		return;
>  
> +	info = &dev_priv->vbt.ddi_port_info[port];
> +
> +	if (info->present) {
> +		DRM_DEBUG_KMS("More than one child device for port %c in VBT, using the first.\n",
> +			      port_name(port));
> +		return;
> +	}
> +
> +	info->present = true;
> +
>  	is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
>  	is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
>  	is_crt = child->device_type & DEVICE_TYPE_ANALOG_OUTPUT;
> @@ -1523,19 +1534,20 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
>  
>  static void parse_ddi_ports(struct drm_i915_private *dev_priv, u8 bdb_version)
>  {
> -	enum port port;
> +	const struct child_device_config *child;
> +	int i;
>  
>  	if (!HAS_DDI(dev_priv) && !IS_CHERRYVIEW(dev_priv))
>  		return;
>  
> -	if (!dev_priv->vbt.child_dev_num)
> -		return;
> -
>  	if (bdb_version < 155)
>  		return;
>  
> -	for (port = PORT_A; port < I915_MAX_PORTS; port++)
> -		parse_ddi_port(dev_priv, port, bdb_version);
> +	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
> +		child = dev_priv->vbt.child_dev + i;
> +
> +		parse_ddi_port(dev_priv, child, bdb_version);
> +	}
>  }
>  
>  static void

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

      parent reply	other threads:[~2019-03-25 13:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-22 12:10 [PATCH] drm/i915/bios: iterate over child devices to initialize ddi_port_info Jani Nikula
2019-03-22 12:52 ` ✗ Fi.CI.SPARSE: warning for " Patchwork
2019-03-22 13:14 ` ✓ Fi.CI.BAT: success " Patchwork
2019-03-23  9:32 ` ✗ Fi.CI.SPARSE: warning for drm/i915/bios: iterate over child devices to initialize ddi_port_info (rev2) Patchwork
2019-03-23  9:47 ` ✓ Fi.CI.IGT: success for drm/i915/bios: iterate over child devices to initialize ddi_port_info Patchwork
2019-03-23  9:51 ` ✓ Fi.CI.BAT: success for drm/i915/bios: iterate over child devices to initialize ddi_port_info (rev2) Patchwork
2019-03-24  6:30 ` ✓ Fi.CI.IGT: " Patchwork
2019-03-25 13:30 ` Jani Nikula [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zhpjqdwx.fsf@intel.com \
    --to=jani.nikula@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.