All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 02/13] drm/i915: Convert intel_tv connector properties to atomic, v5.
Date: Wed, 12 Apr 2017 09:43:00 +0200	[thread overview]
Message-ID: <888308be-97e0-df1e-fed1-e41fb7b23ce3@linux.intel.com> (raw)
In-Reply-To: <20170412073824.lxkouiagrgsyytxq@phenom.ffwll.local>

Op 12-04-17 om 09:38 schreef Daniel Vetter:
> On Fri, Apr 07, 2017 at 08:07:51AM +0200, Maarten Lankhorst wrote:
>> As a proof of concept, first try to convert intel_tv, which is a rarely
>> used connector. It has 5 properties, tv format and 4 margins.
>>
>> I'm less certain about the state behavior itself, should we pass a size
>> parameter to intel_connector_alloc instead, so duplicate_state
>> can be done globally if it can be blindly copied?
>>
>> Can we also have a atomic_check function for connectors, so the
>> crtc_state->connectors_changed can be set there? It would be cleaner
>> and more atomic-like.
>>
>> To match the legacy behavior, format can be changed by probing just like
>> in legacy mode.
>>
>> Changes since v1:
>> - Add intel_encoder->swap_state to allow updating connector state.
>> - Add intel_tv->format for detect_mode and mode_valid, updated on atomic commit.
>> Changes since v2:
>> - Fix typo in tv_choose_preferred modes function name.
>> - Assignment of tv properties is done in core, so intel_tv only needs
>>   a atomic_check function. Thanks Ville!
>> Changes since v3:
>> - connection_mutex is now held in mode_valid() and get_modes(),
>>   this removes the need for caching parts of the connector_state.
>> Changes since v4:
>> - Use the new atomic connector check function.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_tv.c | 175 +++++++++++++++-------------------------
>>  1 file changed, 63 insertions(+), 112 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
>> index 3af857a75fab..784df024e230 100644
>> --- a/drivers/gpu/drm/i915/intel_tv.c
>> +++ b/drivers/gpu/drm/i915/intel_tv.c
>> @@ -48,8 +48,6 @@ struct intel_tv {
>>  	struct intel_encoder base;
>>  
>>  	int type;
>> -	const char *tv_format;
>> -	int margin[4];
>>  };
>>  
>>  struct video_levels {
>> @@ -840,32 +838,18 @@ intel_disable_tv(struct intel_encoder *encoder,
>>  	I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
>>  }
>>  
>> -static const struct tv_mode *
>> -intel_tv_mode_lookup(const char *tv_format)
>> +static const struct tv_mode *intel_tv_mode_find(struct drm_connector_state *conn_state)
>>  {
>> -	int i;
>> -
>> -	for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
>> -		const struct tv_mode *tv_mode = &tv_modes[i];
>> +	int format = conn_state->tv.mode;
>>  
>> -		if (!strcmp(tv_format, tv_mode->name))
>> -			return tv_mode;
>> -	}
>> -	return NULL;
>> -}
>> -
>> -static const struct tv_mode *
>> -intel_tv_mode_find(struct intel_tv *intel_tv)
>> -{
>> -	return intel_tv_mode_lookup(intel_tv->tv_format);
>> +	return &tv_modes[format];
>>  }
>>  
>>  static enum drm_mode_status
>>  intel_tv_mode_valid(struct drm_connector *connector,
>>  		    struct drm_display_mode *mode)
>>  {
>> -	struct intel_tv *intel_tv = intel_attached_tv(connector);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> +	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
>>  	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
>>  
>>  	if (mode->clock > max_dotclk)
>> @@ -892,8 +876,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
>>  			struct intel_crtc_state *pipe_config,
>>  			struct drm_connector_state *conn_state)
>>  {
>> -	struct intel_tv *intel_tv = enc_to_tv(encoder);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> +	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
>>  
>>  	if (!tv_mode)
>>  		return false;
>> @@ -999,7 +982,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder,
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
>>  	struct intel_tv *intel_tv = enc_to_tv(encoder);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> +	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
>>  	u32 tv_ctl;
>>  	u32 scctl1, scctl2, scctl3;
>>  	int i, j;
>> @@ -1102,12 +1085,12 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder,
>>  	else
>>  		ysize = 2*tv_mode->nbr_end + 1;
>>  
>> -	xpos += intel_tv->margin[TV_MARGIN_LEFT];
>> -	ypos += intel_tv->margin[TV_MARGIN_TOP];
>> -	xsize -= (intel_tv->margin[TV_MARGIN_LEFT] +
>> -		  intel_tv->margin[TV_MARGIN_RIGHT]);
>> -	ysize -= (intel_tv->margin[TV_MARGIN_TOP] +
>> -		  intel_tv->margin[TV_MARGIN_BOTTOM]);
>> +	xpos += conn_state->tv.margins.left;
>> +	ypos += conn_state->tv.margins.top;
>> +	xsize -= (conn_state->tv.margins.left +
>> +		  conn_state->tv.margins.right);
>> +	ysize -= (conn_state->tv.margins.top +
>> +		  conn_state->tv.margins.bottom);
>>  	I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
>>  	I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
>>  
>> @@ -1255,7 +1238,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
>>  static void intel_tv_find_better_format(struct drm_connector *connector)
>>  {
>>  	struct intel_tv *intel_tv = intel_attached_tv(connector);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> +	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
>>  	int i;
>>  
>>  	if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) ==
>> @@ -1271,9 +1254,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
>>  			break;
>>  	}
>>  
>> -	intel_tv->tv_format = tv_mode->name;
>> -	drm_object_property_set_value(&connector->base,
>> -		connector->dev->mode_config.tv_mode_property, i);
>> +	connector->state->tv.mode = i;
>>  }
>>  
>>  /**
>> @@ -1314,16 +1295,15 @@ intel_tv_detect(struct drm_connector *connector,
>>  				connector_status_connected;
>>  		} else
>>  			status = connector_status_unknown;
>> -	} else
>> -		return connector->status;
>>  
>> -	if (status != connector_status_connected)
>> -		return status;
>> -
>> -	intel_tv->type = type;
>> -	intel_tv_find_better_format(connector);
>> +		if (status == connector_status_connected) {
>> +			intel_tv->type = type;
>> +			intel_tv_find_better_format(connector);
>> +		}
>>  
>> -	return connector_status_connected;
>> +		return status;
>> +	} else
>> +		return connector->status;
>>  }
>>  
>>  static const struct input_res {
>> @@ -1343,12 +1323,9 @@ static const struct input_res {
>>   * Chose preferred mode  according to line number of TV format
>>   */
>>  static void
>> -intel_tv_chose_preferred_modes(struct drm_connector *connector,
>> +intel_tv_choose_preferred_modes(const struct tv_mode *tv_mode,
>>  			       struct drm_display_mode *mode_ptr)
>>  {
>> -	struct intel_tv *intel_tv = intel_attached_tv(connector);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> -
>>  	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
>>  		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
>>  	else if (tv_mode->nbr_end > 480) {
>> @@ -1371,8 +1348,7 @@ static int
>>  intel_tv_get_modes(struct drm_connector *connector)
>>  {
>>  	struct drm_display_mode *mode_ptr;
>> -	struct intel_tv *intel_tv = intel_attached_tv(connector);
>> -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>> +	const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
>>  	int j, count = 0;
>>  	u64 tmp;
>>  
>> @@ -1415,7 +1391,7 @@ intel_tv_get_modes(struct drm_connector *connector)
>>  		mode_ptr->clock = (int) tmp;
>>  
>>  		mode_ptr->type = DRM_MODE_TYPE_DRIVER;
>> -		intel_tv_chose_preferred_modes(connector, mode_ptr);
>> +		intel_tv_choose_preferred_modes(tv_mode, mode_ptr);
>>  		drm_mode_probed_add(connector, mode_ptr);
>>  		count++;
>>  	}
>> @@ -1430,74 +1406,47 @@ intel_tv_destroy(struct drm_connector *connector)
>>  	kfree(connector);
>>  }
>>  
>> -
>> -static int
>> -intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
>> -		      uint64_t val)
>> -{
>> -	struct drm_device *dev = connector->dev;
>> -	struct intel_tv *intel_tv = intel_attached_tv(connector);
>> -	struct drm_crtc *crtc = intel_tv->base.base.crtc;
>> -	int ret = 0;
>> -	bool changed = false;
>> -
>> -	ret = drm_object_property_set_value(&connector->base, property, val);
>> -	if (ret < 0)
>> -		goto out;
>> -
>> -	if (property == dev->mode_config.tv_left_margin_property &&
>> -		intel_tv->margin[TV_MARGIN_LEFT] != val) {
>> -		intel_tv->margin[TV_MARGIN_LEFT] = val;
>> -		changed = true;
>> -	} else if (property == dev->mode_config.tv_right_margin_property &&
>> -		intel_tv->margin[TV_MARGIN_RIGHT] != val) {
>> -		intel_tv->margin[TV_MARGIN_RIGHT] = val;
>> -		changed = true;
>> -	} else if (property == dev->mode_config.tv_top_margin_property &&
>> -		intel_tv->margin[TV_MARGIN_TOP] != val) {
>> -		intel_tv->margin[TV_MARGIN_TOP] = val;
>> -		changed = true;
>> -	} else if (property == dev->mode_config.tv_bottom_margin_property &&
>> -		intel_tv->margin[TV_MARGIN_BOTTOM] != val) {
>> -		intel_tv->margin[TV_MARGIN_BOTTOM] = val;
>> -		changed = true;
>> -	} else if (property == dev->mode_config.tv_mode_property) {
>> -		if (val >= ARRAY_SIZE(tv_modes)) {
>> -			ret = -EINVAL;
>> -			goto out;
>> -		}
>> -		if (!strcmp(intel_tv->tv_format, tv_modes[val].name))
>> -			goto out;
>> -
>> -		intel_tv->tv_format = tv_modes[val].name;
>> -		changed = true;
>> -	} else {
>> -		ret = -EINVAL;
>> -		goto out;
>> -	}
>> -
>> -	if (changed && crtc)
>> -		intel_crtc_restore_mode(crtc);
>> -out:
>> -	return ret;
>> -}
>> -
>>  static const struct drm_connector_funcs intel_tv_connector_funcs = {
>>  	.dpms = drm_atomic_helper_connector_dpms,
>>  	.late_register = intel_connector_register,
>>  	.early_unregister = intel_connector_unregister,
>>  	.destroy = intel_tv_destroy,
>> -	.set_property = intel_tv_set_property,
>> -	.atomic_get_property = intel_connector_atomic_get_property,
>> +	.set_property = drm_atomic_helper_connector_set_property,
>>  	.fill_modes = drm_helper_probe_single_connector_modes,
>>  	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
>>  	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
>>  };
>>  
>> +static int intel_tv_atomic_check(struct drm_connector *connector,
>> +				 struct drm_connector_state *new_state)
>> +{
>> +	struct drm_crtc_state *new_crtc_state;
>> +	struct drm_connector_state *old_state;
>> +
>> +	if (!new_state->crtc)
>> +		return 0;
>> +
>> +	old_state = drm_atomic_get_old_connector_state(new_state->state, connector);
>> +	new_crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc);
>> +
>> +	if (old_state->tv.mode != new_state->tv.mode ||
>> +	    old_state->tv.margins.left != new_state->tv.margins.left ||
>> +	    old_state->tv.margins.right != new_state->tv.margins.right ||
>> +	    old_state->tv.margins.top != new_state->tv.margins.top ||
>> +	    old_state->tv.margins.bottom != new_state->tv.margins.bottom) {
>> +		/* Force a modeset. */
>> +
>> +		new_crtc_state->connectors_changed = true;
>> +	}
> I wonder whether we should have a default atomic_check for TV, which does
> exactly the above? Otoh, 2nd driver to use them can do this :-)
>
>> +
>> +	return 0;
>> +}
>> +
>>  static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
>>  	.detect_ctx = intel_tv_detect,
>>  	.mode_valid = intel_tv_mode_valid,
>>  	.get_modes = intel_tv_get_modes,
>> +	.atomic_check = intel_tv_atomic_check,
>>  };
>>  
>>  static const struct drm_encoder_funcs intel_tv_enc_funcs = {
>> @@ -1515,6 +1464,7 @@ intel_tv_init(struct drm_i915_private *dev_priv)
>>  	u32 tv_dac_on, tv_dac_off, save_tv_dac;
>>  	const char *tv_format_names[ARRAY_SIZE(tv_modes)];
>>  	int i, initial_mode = 0;
>> +	struct drm_connector_state *state;
>>  
>>  	if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
>>  		return;
>> @@ -1560,6 +1510,7 @@ intel_tv_init(struct drm_i915_private *dev_priv)
>>  
>>  	intel_encoder = &intel_tv->base;
>>  	connector = &intel_connector->base;
>> +	state = connector->state;
>>  
>>  	/* The documentation, for the older chipsets at least, recommend
>>  	 * using a polling method rather than hotplug detection for TVs.
>> @@ -1597,12 +1548,12 @@ intel_tv_init(struct drm_i915_private *dev_priv)
>>  	intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
>>  
>>  	/* BIOS margin values */
>> -	intel_tv->margin[TV_MARGIN_LEFT] = 54;
>> -	intel_tv->margin[TV_MARGIN_TOP] = 36;
>> -	intel_tv->margin[TV_MARGIN_RIGHT] = 46;
>> -	intel_tv->margin[TV_MARGIN_BOTTOM] = 37;
>> +	state->tv.margins.left = 54;
>> +	state->tv.margins.top = 36;
>> +	state->tv.margins.right = 46;
>> +	state->tv.margins.bottom = 37;
>>  
>> -	intel_tv->tv_format = tv_modes[initial_mode].name;
>> +	state->tv.mode = initial_mode;
>>  
>>  	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
>>  	connector->interlace_allowed = false;
>> @@ -1616,17 +1567,17 @@ intel_tv_init(struct drm_i915_private *dev_priv)
>>  				      tv_format_names);
>>  
>>  	drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
>> -				   initial_mode);
>> +				   state->tv.mode);
>>  	drm_object_attach_property(&connector->base,
>>  				   dev->mode_config.tv_left_margin_property,
>> -				   intel_tv->margin[TV_MARGIN_LEFT]);
>> +				   state->tv.margins.left);
>>  	drm_object_attach_property(&connector->base,
>>  				   dev->mode_config.tv_top_margin_property,
>> -				   intel_tv->margin[TV_MARGIN_TOP]);
>> +				   state->tv.margins.top);
>>  	drm_object_attach_property(&connector->base,
>>  				   dev->mode_config.tv_right_margin_property,
>> -				   intel_tv->margin[TV_MARGIN_RIGHT]);
>> +				   state->tv.margins.right);
>>  	drm_object_attach_property(&connector->base,
>>  				   dev->mode_config.tv_bottom_margin_property,
>> -				   intel_tv->margin[TV_MARGIN_BOTTOM]);
>> +				   state->tv.margins.bottom);
> Another opportunity for a helper to attach the tw mode properties with
> correct defaults and all that. Hm, on that ... should we have an
> attach_prop function which doesn't require the initial value, since with
> atomic that's not needed?
Yeah perhaps, although we could just initialize to 0 here just fine with the atomic getproperty.

In fact probably even before this patch, since I believe it's broken with i915 being a atomic driver..

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2017-04-12  7:43 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-07  6:07 [PATCH 00/13] drm/i915: Convert connector properties to atomic Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 01/13] drm/i915: Remove unused members from intel_tv.c Maarten Lankhorst
2017-04-12  7:33   ` Daniel Vetter
2017-04-07  6:07 ` [PATCH 02/13] drm/i915: Convert intel_tv connector properties to atomic, v5 Maarten Lankhorst
2017-04-12  7:38   ` Daniel Vetter
2017-04-12  7:43     ` Maarten Lankhorst [this message]
2017-04-07  6:07 ` [PATCH 03/13] drm/i915: Convert intel_dp_mst connector properties to atomic Maarten Lankhorst
2017-04-12  7:40   ` Daniel Vetter
2017-04-07  6:07 ` [PATCH 04/13] drm/i915: Convert intel_crt " Maarten Lankhorst
2017-04-12  7:45   ` Daniel Vetter
2017-04-07  6:07 ` [PATCH 05/13] drm/i915: Convert intel DVO connector " Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 06/13] drm/i915: Add plumbing for digital connector state Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 07/13] drm/i915: Convert DSI connector properties to atomic Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 08/13] drm/i915: Convert LVDS " Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 09/13] drm/i915: Make intel_dp->has_audio reflect hw state only Maarten Lankhorst
2017-04-07  6:07 ` [PATCH 10/13] drm/i915: Convert intel_dp properties to atomic Maarten Lankhorst
2017-04-07  6:08 ` [PATCH 11/13] drm/i915: Convert intel_hdmi connector " Maarten Lankhorst
2017-04-07  6:08 ` [PATCH 12/13] drm/i915: Handle force_audio correctly in intel_sdvo Maarten Lankhorst
2017-04-07  6:08 ` [PATCH 13/13] drm/i915: Convert intel_sdvo connector properties to atomic Maarten Lankhorst
2017-04-07  6:27 ` ✗ Fi.CI.BAT: warning for drm/i915: Convert " Patchwork

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=888308be-97e0-df1e-fed1-e41fb7b23ce3@linux.intel.com \
    --to=maarten.lankhorst@linux.intel.com \
    --cc=daniel@ffwll.ch \
    --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.