Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1638291 > unrolled thread

[PATCH v2 0/8] Introduce new mode validation callbacks

Started byJose Abreu <Jose.Abreu@synopsys.com>
First post2017-05-09 19:10 +0200
Last post2017-05-09 19:10 +0200
Articles 20 on this page of 34 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/8] Introduce new mode validation callbacks Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
    [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
      Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Ville Syrjälä <ville.syrjala@linux.intel.com> - 2017-05-10 15:50 +0200
        Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-10 16:10 +0200
          Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-10 16:10 +0200
        Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Daniel Vetter <daniel@ffwll.ch> - 2017-05-10 17:20 +0200
          Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-12 11:40 +0200
            Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Archit Taneja <architt@codeaurora.org> - 2017-05-12 13:00 +0200
              Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-12 13:10 +0200
                Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Archit Taneja <architt@codeaurora.org> - 2017-05-15 06:20 +0200
                Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid() Daniel Vetter <daniel@ffwll.ch> - 2017-05-15 08:50 +0200
    [PATCH v2 4/8] drm: Add drm_connector_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
    [PATCH v2 2/8] drm: Add drm_crtc_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
      Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid() Daniel Vetter <daniel@ffwll.ch> - 2017-05-10 10:10 +0200
        Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-10 11:00 +0200
          Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid() Daniel Vetter <daniel@ffwll.ch> - 2017-05-10 17:20 +0200
    [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
      Re: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-12 12:00 +0200
        Re: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-15 03:50 +0200
    [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
      Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector  probe helper Daniel Vetter <daniel@ffwll.ch> - 2017-05-10 10:10 +0200
        Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector  probe helper Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-10 11:10 +0200
      Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-12 11:40 +0200
        Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector  probe helper Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-12 18:10 +0200
          Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-14 13:10 +0200
            Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector  probe helper Daniel Vetter <daniel@ffwll.ch> - 2017-05-15 08:50 +0200
              Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-15 09:10 +0200
                Re: [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector  probe helper Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-16 07:20 +0200
    [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid() callbacks Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200
      Re: [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid()  callbacks Daniel Vetter <daniel@ffwll.ch> - 2017-05-10 10:10 +0200
        Re: [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid()  callbacks Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-10 11:10 +0200
        Re: [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid() callbacks Laurent Pinchart <laurent.pinchart@ideasonboard.com> - 2017-05-12 10:30 +0200
          Re: [PATCH v2 1/8] drm: Add crtc/encoder/bridge->mode_valid()  callbacks Daniel Vetter <daniel@ffwll.ch> - 2017-05-15 08:50 +0200
    [PATCH v2 3/8] drm: Add drm_encoder_mode_valid() Jose Abreu <Jose.Abreu@synopsys.com> - 2017-05-09 19:10 +0200

Page 1 of 2  [1] 2  Next page →


#1638291 — [PATCH v2 0/8] Introduce new mode validation callbacks

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 0/8] Introduce new mode validation callbacks
Message-ID<tFgO5-4HS-5@gated-at.bofh.it>
This series is a follow up from the discussion at [1]. We start by
introducing crtc->mode_valid(), encoder->mode_valid() and
bridge->mode_valid() callbacks which will be used in followup
patches.

We proceed by introducing new helpers to call this new callbacks
at 2/8, 3/8 and 4/8.

Next, at 5/8 we modify the connector probe helper so that only modes
which are supported by a given encoder+crtc combination are probbed.

At 6/8 a helper function is introduced that calls all mode_valid()
from a set of bridges.

At 7/8 we call all the mode_valid() callbacks for a given pipeline,
except the connector->mode_valid one, so that the mode is validated.
This is done before calling mode_fixup().

Finally, at 8/8 we use the new crtc->mode_valid() callback in arcpgu
and remove the atomic_check() callback.

[1] https://patchwork.kernel.org/patch/9702233/

Jose Abreu (8):
  drm: Add crtc/encoder/bridge->mode_valid() callbacks
  drm: Add drm_crtc_mode_valid()
  drm: Add drm_encoder_mode_valid()
  drm: Add drm_connector_mode_valid()
  drm: Use new mode_valid() helpers in connector probe helper
  drm: Introduce drm_bridge_mode_valid()
  drm: Use mode_valid() in atomic modeset
  drm: arc: Use crtc->mode_valid() callback

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>

 drivers/gpu/drm/arc/arcpgu_crtc.c        | 39 ++++++++++-------
 drivers/gpu/drm/drm_atomic_helper.c      | 75 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/drm_bridge.c             | 33 ++++++++++++++
 drivers/gpu/drm/drm_connector.c          | 23 ++++++++++
 drivers/gpu/drm/drm_crtc.c               | 22 ++++++++++
 drivers/gpu/drm/drm_crtc_internal.h      |  7 +++
 drivers/gpu/drm/drm_encoder.c            | 23 ++++++++++
 drivers/gpu/drm/drm_probe_helper.c       | 60 +++++++++++++++++++++++--
 include/drm/drm_bridge.h                 | 22 ++++++++++
 include/drm/drm_modeset_helper_vtables.h | 45 +++++++++++++++++++
 10 files changed, 328 insertions(+), 21 deletions(-)

-- 
1.9.1

[toc] | [next] | [standalone]


#1638292 — [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tFgO5-4HS-7@gated-at.bofh.it>
In reply to#1638291
Introduce a new helper function which calls mode_valid() callback
for all bridges in an encoder chain.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
 include/drm/drm_bridge.h     |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 86a7637..dc8cdfe 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 EXPORT_SYMBOL(drm_bridge_mode_fixup);
 
 /**
+ * drm_bridge_mode_valid - validate the mode against all bridges in the
+ * 			   encoder chain.
+ * @bridge: bridge control structure
+ * @mode: desired mode to be validated
+ *
+ * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the mode the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * MODE_OK on success, drm_mode_status Enum error code on failure
+ */
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+					   const struct drm_display_mode *mode)
+{
+	enum drm_mode_status ret = MODE_OK;
+
+	if (!bridge)
+		return ret;
+
+	if (bridge->funcs->mode_valid)
+		ret = bridge->funcs->mode_valid(bridge, mode);
+
+	if (ret != MODE_OK)
+		return ret;
+
+	return drm_bridge_mode_valid(bridge->next, mode);
+}
+EXPORT_SYMBOL(drm_bridge_mode_valid);
+
+/**
  * drm_bridge_disable - disables all bridges in the encoder chain
  * @bridge: bridge control structure
  *
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 00c6c36..8358eb3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
 bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
 			const struct drm_display_mode *mode,
 			struct drm_display_mode *adjusted_mode);
+enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
+					   const struct drm_display_mode *mode);
 void drm_bridge_disable(struct drm_bridge *bridge);
 void drm_bridge_post_disable(struct drm_bridge *bridge);
 void drm_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1638833 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromVille Syrjälä <ville.syrjala@linux.intel.com>
Date2017-05-10 15:50 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tFAa6-1mz-1@gated-at.bofh.it>
In reply to#1638292
On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
> Introduce a new helper function which calls mode_valid() callback
> for all bridges in an encoder chain.
> 
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> Cc: Carlos Palminha <palminha@synopsys.com>
> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Dave Airlie <airlied@linux.ie>
> Cc: Andrzej Hajda <a.hajda@samsung.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
>  include/drm/drm_bridge.h     |  2 ++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 86a7637..dc8cdfe 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>  
>  /**
> + * drm_bridge_mode_valid - validate the mode against all bridges in the
> + * 			   encoder chain.
> + * @bridge: bridge control structure
> + * @mode: desired mode to be validated
> + *
> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
> + * chain, starting from the first bridge to the last. If at least one bridge
> + * does not accept the mode the function returns the error code.
> + *
> + * Note: the bridge passed should be the one closest to the encoder.
> + *
> + * RETURNS:
> + * MODE_OK on success, drm_mode_status Enum error code on failure
> + */
> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> +					   const struct drm_display_mode *mode)
> +{
> +	enum drm_mode_status ret = MODE_OK;
> +
> +	if (!bridge)
> +		return ret;
> +
> +	if (bridge->funcs->mode_valid)
> +		ret = bridge->funcs->mode_valid(bridge, mode);
> +
> +	if (ret != MODE_OK)
> +		return ret;
> +
> +	return drm_bridge_mode_valid(bridge->next, mode);

Looks like it should be pretty trivial to avoid the recursion.

Am I correct in interpreting this that bridges have some kind of
a hand rolled linked list implementation? Reusing the standard
linked lists would allow you to use list_for_each() etc.

> +}
> +EXPORT_SYMBOL(drm_bridge_mode_valid);
> +
> +/**
>   * drm_bridge_disable - disables all bridges in the encoder chain
>   * @bridge: bridge control structure
>   *
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index 00c6c36..8358eb3 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
>  bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>  			const struct drm_display_mode *mode,
>  			struct drm_display_mode *adjusted_mode);
> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> +					   const struct drm_display_mode *mode);
>  void drm_bridge_disable(struct drm_bridge *bridge);
>  void drm_bridge_post_disable(struct drm_bridge *bridge);
>  void drm_bridge_mode_set(struct drm_bridge *bridge,
> -- 
> 1.9.1
> 

-- 
Ville Syrjälä
Intel OTC

[toc] | [prev] | [next] | [standalone]


#1638861 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-10 16:10 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tFAtr-1IC-1@gated-at.bofh.it>
In reply to#1638833
Hi Ville,


On 10-05-2017 14:41, Ville Syrjälä wrote:
> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>> Introduce a new helper function which calls mode_valid() callback
>> for all bridges in an encoder chain.
>>
>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>> Cc: Carlos Palminha <palminha@synopsys.com>
>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Dave Airlie <airlied@linux.ie>
>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>> Cc: Archit Taneja <architt@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
>>  include/drm/drm_bridge.h     |  2 ++
>>  2 files changed, 35 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>> index 86a7637..dc8cdfe 100644
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>  
>>  /**
>> + * drm_bridge_mode_valid - validate the mode against all bridges in the
>> + * 			   encoder chain.
>> + * @bridge: bridge control structure
>> + * @mode: desired mode to be validated
>> + *
>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
>> + * chain, starting from the first bridge to the last. If at least one bridge
>> + * does not accept the mode the function returns the error code.
>> + *
>> + * Note: the bridge passed should be the one closest to the encoder.
>> + *
>> + * RETURNS:
>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>> + */
>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>> +					   const struct drm_display_mode *mode)
>> +{
>> +	enum drm_mode_status ret = MODE_OK;
>> +
>> +	if (!bridge)
>> +		return ret;
>> +
>> +	if (bridge->funcs->mode_valid)
>> +		ret = bridge->funcs->mode_valid(bridge, mode);
>> +
>> +	if (ret != MODE_OK)
>> +		return ret;
>> +
>> +	return drm_bridge_mode_valid(bridge->next, mode);
> Looks like it should be pretty trivial to avoid the recursion.
>
> Am I correct in interpreting this that bridges have some kind of
> a hand rolled linked list implementation? Reusing the standard
> linked lists would allow you to use list_for_each() etc.

I reused the drm_bridge_mode_fixup but now I see how its done
like that: so that the fixup is propagated in the correct order.
As for mode_valid we just need to check if ret != MODE_OK then I
think we can use the list_for_each_entry(bridge->list).

Best regards,
Jose Miguel Abreu

>
>> +}
>> +EXPORT_SYMBOL(drm_bridge_mode_valid);
>> +
>> +/**
>>   * drm_bridge_disable - disables all bridges in the encoder chain
>>   * @bridge: bridge control structure
>>   *
>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>> index 00c6c36..8358eb3 100644
>> --- a/include/drm/drm_bridge.h
>> +++ b/include/drm/drm_bridge.h
>> @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
>>  bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>  			const struct drm_display_mode *mode,
>>  			struct drm_display_mode *adjusted_mode);
>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>> +					   const struct drm_display_mode *mode);
>>  void drm_bridge_disable(struct drm_bridge *bridge);
>>  void drm_bridge_post_disable(struct drm_bridge *bridge);
>>  void drm_bridge_mode_set(struct drm_bridge *bridge,
>> -- 
>> 1.9.1
>>

[toc] | [prev] | [next] | [standalone]


#1638864 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-10 16:10 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tFAts-1IC-15@gated-at.bofh.it>
In reply to#1638861
Hi Ville,


On 10-05-2017 15:01, Jose Abreu wrote:
> Hi Ville,
>
>
> On 10-05-2017 14:41, Ville Syrjälä wrote:
>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>>> Introduce a new helper function which calls mode_valid() callback
>>> for all bridges in an encoder chain.
>>>
>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>>> Cc: Carlos Palminha <palminha@synopsys.com>
>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>> Cc: Dave Airlie <airlied@linux.ie>
>>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>>> Cc: Archit Taneja <architt@codeaurora.org>
>>> ---
>>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
>>>  include/drm/drm_bridge.h     |  2 ++
>>>  2 files changed, 35 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>>> index 86a7637..dc8cdfe 100644
>>> --- a/drivers/gpu/drm/drm_bridge.c
>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>>  
>>>  /**
>>> + * drm_bridge_mode_valid - validate the mode against all bridges in the
>>> + * 			   encoder chain.
>>> + * @bridge: bridge control structure
>>> + * @mode: desired mode to be validated
>>> + *
>>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
>>> + * chain, starting from the first bridge to the last. If at least one bridge
>>> + * does not accept the mode the function returns the error code.
>>> + *
>>> + * Note: the bridge passed should be the one closest to the encoder.
>>> + *
>>> + * RETURNS:
>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>>> + */
>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>> +					   const struct drm_display_mode *mode)
>>> +{
>>> +	enum drm_mode_status ret = MODE_OK;
>>> +
>>> +	if (!bridge)
>>> +		return ret;
>>> +
>>> +	if (bridge->funcs->mode_valid)
>>> +		ret = bridge->funcs->mode_valid(bridge, mode);
>>> +
>>> +	if (ret != MODE_OK)
>>> +		return ret;
>>> +
>>> +	return drm_bridge_mode_valid(bridge->next, mode);
>> Looks like it should be pretty trivial to avoid the recursion.
>>
>> Am I correct in interpreting this that bridges have some kind of
>> a hand rolled linked list implementation? Reusing the standard
>> linked lists would allow you to use list_for_each() etc.
> I reused the drm_bridge_mode_fixup but now I see how its done
> like that: so that the fixup is propagated in the correct order.
> As for mode_valid we just need to check if ret != MODE_OK then I
> think we can use the list_for_each_entry(bridge->list).

Oops, I got this wrong sorry. I meant there is a list but its for
all the system bridges. This is a "custom" linked list yeah.

Best regards,
Jose Miguel Abreu

>
> Best regards,
> Jose Miguel Abreu
>
>>> +}
>>> +EXPORT_SYMBOL(drm_bridge_mode_valid);
>>> +
>>> +/**
>>>   * drm_bridge_disable - disables all bridges in the encoder chain
>>>   * @bridge: bridge control structure
>>>   *
>>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>>> index 00c6c36..8358eb3 100644
>>> --- a/include/drm/drm_bridge.h
>>> +++ b/include/drm/drm_bridge.h
>>> @@ -233,6 +233,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
>>>  bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
>>>  			const struct drm_display_mode *mode,
>>>  			struct drm_display_mode *adjusted_mode);
>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>> +					   const struct drm_display_mode *mode);
>>>  void drm_bridge_disable(struct drm_bridge *bridge);
>>>  void drm_bridge_post_disable(struct drm_bridge *bridge);
>>>  void drm_bridge_mode_set(struct drm_bridge *bridge,
>>> -- 
>>> 1.9.1
>>>

[toc] | [prev] | [next] | [standalone]


#1638903 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromDaniel Vetter <daniel@ffwll.ch>
Date2017-05-10 17:20 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tFBzc-2lT-17@gated-at.bofh.it>
In reply to#1638833
On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
> > Introduce a new helper function which calls mode_valid() callback
> > for all bridges in an encoder chain.
> > 
> > Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> > Cc: Carlos Palminha <palminha@synopsys.com>
> > Cc: Alexey Brodkin <abrodkin@synopsys.com>
> > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: Dave Airlie <airlied@linux.ie>
> > Cc: Andrzej Hajda <a.hajda@samsung.com>
> > Cc: Archit Taneja <architt@codeaurora.org>
> > ---
> >  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
> >  include/drm/drm_bridge.h     |  2 ++
> >  2 files changed, 35 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > index 86a7637..dc8cdfe 100644
> > --- a/drivers/gpu/drm/drm_bridge.c
> > +++ b/drivers/gpu/drm/drm_bridge.c
> > @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge *bridge,
> >  EXPORT_SYMBOL(drm_bridge_mode_fixup);
> >  
> >  /**
> > + * drm_bridge_mode_valid - validate the mode against all bridges in the
> > + * 			   encoder chain.
> > + * @bridge: bridge control structure
> > + * @mode: desired mode to be validated
> > + *
> > + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
> > + * chain, starting from the first bridge to the last. If at least one bridge
> > + * does not accept the mode the function returns the error code.
> > + *
> > + * Note: the bridge passed should be the one closest to the encoder.
> > + *
> > + * RETURNS:
> > + * MODE_OK on success, drm_mode_status Enum error code on failure
> > + */
> > +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> > +					   const struct drm_display_mode *mode)
> > +{
> > +	enum drm_mode_status ret = MODE_OK;
> > +
> > +	if (!bridge)
> > +		return ret;
> > +
> > +	if (bridge->funcs->mode_valid)
> > +		ret = bridge->funcs->mode_valid(bridge, mode);
> > +
> > +	if (ret != MODE_OK)
> > +		return ret;
> > +
> > +	return drm_bridge_mode_valid(bridge->next, mode);
> 
> Looks like it should be pretty trivial to avoid the recursion.
> 
> Am I correct in interpreting this that bridges have some kind of
> a hand rolled linked list implementation? Reusing the standard
> linked lists would allow you to use list_for_each() etc.

Yeah it's a hand-rolled list, but current hw also has a bridge nesting
depth of 2, so it really doesn't matter. I guess once we have real long
chains of bridges we can fix this (and just using list_head sounds like a
great idea).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1640359 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Date2017-05-12 11:40 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tGfdg-2rg-25@gated-at.bofh.it>
In reply to#1638903
Hi Daniel,

On Wednesday 10 May 2017 17:14:33 Daniel Vetter wrote:
> On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
> > On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
> > > Introduce a new helper function which calls mode_valid() callback
> > > for all bridges in an encoder chain.
> > > 
> > > Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> > > Cc: Carlos Palminha <palminha@synopsys.com>
> > > Cc: Alexey Brodkin <abrodkin@synopsys.com>
> > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > Cc: Dave Airlie <airlied@linux.ie>
> > > Cc: Andrzej Hajda <a.hajda@samsung.com>
> > > Cc: Archit Taneja <architt@codeaurora.org>
> > > ---
> > > 
> > >  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
> > >  include/drm/drm_bridge.h     |  2 ++
> > >  2 files changed, 35 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > > index 86a7637..dc8cdfe 100644
> > > --- a/drivers/gpu/drm/drm_bridge.c
> > > +++ b/drivers/gpu/drm/drm_bridge.c
> > > @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge
> > > *bridge,
> > > 
> > >  EXPORT_SYMBOL(drm_bridge_mode_fixup);
> > >  
> > >  /**
> > > 
> > > + * drm_bridge_mode_valid - validate the mode against all bridges in the
> > > + * 			   encoder chain.
> > > + * @bridge: bridge control structure
> > > + * @mode: desired mode to be validated
> > > + *
> > > + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the
> > > encoder
> > > + * chain, starting from the first bridge to the last. If at least one
> > > bridge + * does not accept the mode the function returns the error
> > > code.
> > > + *
> > > + * Note: the bridge passed should be the one closest to the encoder.
> > > + *
> > > + * RETURNS:
> > > + * MODE_OK on success, drm_mode_status Enum error code on failure
> > > + */
> > > +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> > > +					   const struct drm_display_mode 
*mode)
> > > +{
> > > +	enum drm_mode_status ret = MODE_OK;
> > > +
> > > +	if (!bridge)
> > > +		return ret;
> > > +
> > > +	if (bridge->funcs->mode_valid)
> > > +		ret = bridge->funcs->mode_valid(bridge, mode);
> > > +
> > > +	if (ret != MODE_OK)
> > > +		return ret;
> > > +
> > > +	return drm_bridge_mode_valid(bridge->next, mode);
> > 
> > Looks like it should be pretty trivial to avoid the recursion.
> > 
> > Am I correct in interpreting this that bridges have some kind of
> > a hand rolled linked list implementation? Reusing the standard
> > linked lists would allow you to use list_for_each() etc.
> 
> Yeah it's a hand-rolled list, but current hw also has a bridge nesting
> depth of 2, so it really doesn't matter. I guess once we have real long
> chains of bridges we can fix this (and just using list_head sounds like a
> great idea).

Even if not really needed right now, it's a pretty easy cleanup, if Jose has 
time to handle it in v3 of this series let's not postpone it ;-)

-- 
Regards,

Laurent Pinchart

[toc] | [prev] | [next] | [standalone]


#1640393 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromArchit Taneja <architt@codeaurora.org>
Date2017-05-12 13:00 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tGgsG-3ff-11@gated-at.bofh.it>
In reply to#1640359

On 05/12/2017 03:08 PM, Laurent Pinchart wrote:
> Hi Daniel,
>
> On Wednesday 10 May 2017 17:14:33 Daniel Vetter wrote:
>> On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
>>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>>>> Introduce a new helper function which calls mode_valid() callback
>>>> for all bridges in an encoder chain.
>>>>
>>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>>>> Cc: Carlos Palminha <palminha@synopsys.com>
>>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>> Cc: Dave Airlie <airlied@linux.ie>
>>>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>>>> Cc: Archit Taneja <architt@codeaurora.org>
>>>> ---
>>>>
>>>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
>>>>  include/drm/drm_bridge.h     |  2 ++
>>>>  2 files changed, 35 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>>>> index 86a7637..dc8cdfe 100644
>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge
>>>> *bridge,
>>>>
>>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>>>
>>>>  /**
>>>>
>>>> + * drm_bridge_mode_valid - validate the mode against all bridges in the
>>>> + * 			   encoder chain.
>>>> + * @bridge: bridge control structure
>>>> + * @mode: desired mode to be validated
>>>> + *
>>>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the
>>>> encoder
>>>> + * chain, starting from the first bridge to the last. If at least one
>>>> bridge + * does not accept the mode the function returns the error
>>>> code.
>>>> + *
>>>> + * Note: the bridge passed should be the one closest to the encoder.
>>>> + *
>>>> + * RETURNS:
>>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>>>> + */
>>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>>> +					   const struct drm_display_mode
> *mode)
>>>> +{
>>>> +	enum drm_mode_status ret = MODE_OK;
>>>> +
>>>> +	if (!bridge)
>>>> +		return ret;
>>>> +
>>>> +	if (bridge->funcs->mode_valid)
>>>> +		ret = bridge->funcs->mode_valid(bridge, mode);
>>>> +
>>>> +	if (ret != MODE_OK)
>>>> +		return ret;
>>>> +
>>>> +	return drm_bridge_mode_valid(bridge->next, mode);
>>>
>>> Looks like it should be pretty trivial to avoid the recursion.
>>>
>>> Am I correct in interpreting this that bridges have some kind of
>>> a hand rolled linked list implementation? Reusing the standard
>>> linked lists would allow you to use list_for_each() etc.
>>
>> Yeah it's a hand-rolled list, but current hw also has a bridge nesting
>> depth of 2, so it really doesn't matter. I guess once we have real long
>> chains of bridges we can fix this (and just using list_head sounds like a
>> great idea).
>
> Even if not really needed right now, it's a pretty easy cleanup, if Jose has
> time to handle it in v3 of this series let's not postpone it ;-)

jfyi, some of the bridge functions call the ops from the last bridge in the
chain to first, so we'd need to use list_for_each_entry_prev() (or something
like that) for them.

Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1640394 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Date2017-05-12 13:10 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tGgCl-3yS-1@gated-at.bofh.it>
In reply to#1640393
Hi Archit,

On Friday 12 May 2017 16:20:07 Archit Taneja wrote:
> On 05/12/2017 03:08 PM, Laurent Pinchart wrote:
> > On Wednesday 10 May 2017 17:14:33 Daniel Vetter wrote:
> >> On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
> >>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
> >>>> Introduce a new helper function which calls mode_valid() callback
> >>>> for all bridges in an encoder chain.
> >>>> 
> >>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> >>>> Cc: Carlos Palminha <palminha@synopsys.com>
> >>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> >>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >>>> Cc: Dave Airlie <airlied@linux.ie>
> >>>> Cc: Andrzej Hajda <a.hajda@samsung.com>
> >>>> Cc: Archit Taneja <architt@codeaurora.org>
> >>>> ---
> >>>> 
> >>>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
> >>>>  include/drm/drm_bridge.h     |  2 ++
> >>>>  2 files changed, 35 insertions(+)
> >>>> 
> >>>> diff --git a/drivers/gpu/drm/drm_bridge.c
> >>>> b/drivers/gpu/drm/drm_bridge.c
> >>>> index 86a7637..dc8cdfe 100644
> >>>> --- a/drivers/gpu/drm/drm_bridge.c
> >>>> +++ b/drivers/gpu/drm/drm_bridge.c
> >>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge
> >>>> *bridge,
> >>>> 
> >>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
> >>>>  
> >>>>  /**
> >>>> 
> >>>> + * drm_bridge_mode_valid - validate the mode against all bridges in
> >>>> the
> >>>> + * 			   encoder chain.
> >>>> + * @bridge: bridge control structure
> >>>> + * @mode: desired mode to be validated
> >>>> + *
> >>>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the
> >>>> encoder
> >>>> + * chain, starting from the first bridge to the last. If at least one
> >>>> bridge + * does not accept the mode the function returns the error
> >>>> code.
> >>>> + *
> >>>> + * Note: the bridge passed should be the one closest to the encoder.
> >>>> + *
> >>>> + * RETURNS:
> >>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
> >>>> + */
> >>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> >>>> +					   const struct 
drm_display_mode
> > 
> > *mode)
> > 
> >>>> +{
> >>>> +	enum drm_mode_status ret = MODE_OK;
> >>>> +
> >>>> +	if (!bridge)
> >>>> +		return ret;
> >>>> +
> >>>> +	if (bridge->funcs->mode_valid)
> >>>> +		ret = bridge->funcs->mode_valid(bridge, mode);
> >>>> +
> >>>> +	if (ret != MODE_OK)
> >>>> +		return ret;
> >>>> +
> >>>> +	return drm_bridge_mode_valid(bridge->next, mode);
> >>> 
> >>> Looks like it should be pretty trivial to avoid the recursion.
> >>> 
> >>> Am I correct in interpreting this that bridges have some kind of
> >>> a hand rolled linked list implementation? Reusing the standard
> >>> linked lists would allow you to use list_for_each() etc.
> >> 
> >> Yeah it's a hand-rolled list, but current hw also has a bridge nesting
> >> depth of 2, so it really doesn't matter. I guess once we have real long
> >> chains of bridges we can fix this (and just using list_head sounds like a
> >> great idea).
> > 
> > Even if not really needed right now, it's a pretty easy cleanup, if Jose
> > has time to handle it in v3 of this series let's not postpone it ;-)
> 
> jfyi, some of the bridge functions call the ops from the last bridge in the
> chain to first, so we'd need to use list_for_each_entry_prev() (or something
> like that) for them.

And now that I think about it, for some of the operations (especially 
enable/disable) I believe that the bridge should be able to decide whether to 
call the next/previous bridge first or to configure its hardware first. I can 
image bridges that need the previous bridge in the chain to provide a valid 
clock before they get started, as well as bridges that need to be started with 
the incoming video signal stopped.

-- 
Regards,

Laurent Pinchart

[toc] | [prev] | [next] | [standalone]


#1641268 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromArchit Taneja <architt@codeaurora.org>
Date2017-05-15 06:20 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tHfEe-2Yc-5@gated-at.bofh.it>
In reply to#1640394

On 05/12/2017 04:31 PM, Laurent Pinchart wrote:
> Hi Archit,
>
> On Friday 12 May 2017 16:20:07 Archit Taneja wrote:
>> On 05/12/2017 03:08 PM, Laurent Pinchart wrote:
>>> On Wednesday 10 May 2017 17:14:33 Daniel Vetter wrote:
>>>> On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
>>>>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
>>>>>> Introduce a new helper function which calls mode_valid() callback
>>>>>> for all bridges in an encoder chain.
>>>>>>
>>>>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>>>>>> Cc: Carlos Palminha <palminha@synopsys.com>
>>>>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>>>>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>>>>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>>>> Cc: Dave Airlie <airlied@linux.ie>
>>>>>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>>>>>> Cc: Archit Taneja <architt@codeaurora.org>
>>>>>> ---
>>>>>>
>>>>>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
>>>>>>  include/drm/drm_bridge.h     |  2 ++
>>>>>>  2 files changed, 35 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>>> b/drivers/gpu/drm/drm_bridge.c
>>>>>> index 86a7637..dc8cdfe 100644
>>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge
>>>>>> *bridge,
>>>>>>
>>>>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
>>>>>>
>>>>>>  /**
>>>>>>
>>>>>> + * drm_bridge_mode_valid - validate the mode against all bridges in
>>>>>> the
>>>>>> + * 			   encoder chain.
>>>>>> + * @bridge: bridge control structure
>>>>>> + * @mode: desired mode to be validated
>>>>>> + *
>>>>>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the
>>>>>> encoder
>>>>>> + * chain, starting from the first bridge to the last. If at least one
>>>>>> bridge + * does not accept the mode the function returns the error
>>>>>> code.
>>>>>> + *
>>>>>> + * Note: the bridge passed should be the one closest to the encoder.
>>>>>> + *
>>>>>> + * RETURNS:
>>>>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
>>>>>> + */
>>>>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
>>>>>> +					   const struct
> drm_display_mode
>>>
>>> *mode)
>>>
>>>>>> +{
>>>>>> +	enum drm_mode_status ret = MODE_OK;
>>>>>> +
>>>>>> +	if (!bridge)
>>>>>> +		return ret;
>>>>>> +
>>>>>> +	if (bridge->funcs->mode_valid)
>>>>>> +		ret = bridge->funcs->mode_valid(bridge, mode);
>>>>>> +
>>>>>> +	if (ret != MODE_OK)
>>>>>> +		return ret;
>>>>>> +
>>>>>> +	return drm_bridge_mode_valid(bridge->next, mode);
>>>>>
>>>>> Looks like it should be pretty trivial to avoid the recursion.
>>>>>
>>>>> Am I correct in interpreting this that bridges have some kind of
>>>>> a hand rolled linked list implementation? Reusing the standard
>>>>> linked lists would allow you to use list_for_each() etc.
>>>>
>>>> Yeah it's a hand-rolled list, but current hw also has a bridge nesting
>>>> depth of 2, so it really doesn't matter. I guess once we have real long
>>>> chains of bridges we can fix this (and just using list_head sounds like a
>>>> great idea).
>>>
>>> Even if not really needed right now, it's a pretty easy cleanup, if Jose
>>> has time to handle it in v3 of this series let's not postpone it ;-)
>>
>> jfyi, some of the bridge functions call the ops from the last bridge in the
>> chain to first, so we'd need to use list_for_each_entry_prev() (or something
>> like that) for them.
>
> And now that I think about it, for some of the operations (especially
> enable/disable) I believe that the bridge should be able to decide whether to
> call the next/previous bridge first or to configure its hardware first. I can
> image bridges that need the previous bridge in the chain to provide a valid
> clock before they get started, as well as bridges that need to be started with
> the incoming video signal stopped.

I guess converting into list would be a good start to achieve this. We'd probably
need to extend/redo the drm_bridge_attach() API to tweak the order in the which
the ops are called.

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

[toc] | [prev] | [next] | [standalone]


#1641311 — Re: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()

FromDaniel Vetter <daniel@ffwll.ch>
Date2017-05-15 08:50 +0200
SubjectRe: [PATCH v2 6/8] drm: Introduce drm_bridge_mode_valid()
Message-ID<tHhZo-4vl-7@gated-at.bofh.it>
In reply to#1640394
On Fri, May 12, 2017 at 02:01:49PM +0300, Laurent Pinchart wrote:
> Hi Archit,
> 
> On Friday 12 May 2017 16:20:07 Archit Taneja wrote:
> > On 05/12/2017 03:08 PM, Laurent Pinchart wrote:
> > > On Wednesday 10 May 2017 17:14:33 Daniel Vetter wrote:
> > >> On Wed, May 10, 2017 at 04:41:09PM +0300, Ville Syrjälä wrote:
> > >>> On Tue, May 09, 2017 at 06:00:13PM +0100, Jose Abreu wrote:
> > >>>> Introduce a new helper function which calls mode_valid() callback
> > >>>> for all bridges in an encoder chain.
> > >>>> 
> > >>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> > >>>> Cc: Carlos Palminha <palminha@synopsys.com>
> > >>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> > >>>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > >>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > >>>> Cc: Dave Airlie <airlied@linux.ie>
> > >>>> Cc: Andrzej Hajda <a.hajda@samsung.com>
> > >>>> Cc: Archit Taneja <architt@codeaurora.org>
> > >>>> ---
> > >>>> 
> > >>>>  drivers/gpu/drm/drm_bridge.c | 33 +++++++++++++++++++++++++++++++++
> > >>>>  include/drm/drm_bridge.h     |  2 ++
> > >>>>  2 files changed, 35 insertions(+)
> > >>>> 
> > >>>> diff --git a/drivers/gpu/drm/drm_bridge.c
> > >>>> b/drivers/gpu/drm/drm_bridge.c
> > >>>> index 86a7637..dc8cdfe 100644
> > >>>> --- a/drivers/gpu/drm/drm_bridge.c
> > >>>> +++ b/drivers/gpu/drm/drm_bridge.c
> > >>>> @@ -206,6 +206,39 @@ bool drm_bridge_mode_fixup(struct drm_bridge
> > >>>> *bridge,
> > >>>> 
> > >>>>  EXPORT_SYMBOL(drm_bridge_mode_fixup);
> > >>>>  
> > >>>>  /**
> > >>>> 
> > >>>> + * drm_bridge_mode_valid - validate the mode against all bridges in
> > >>>> the
> > >>>> + * 			   encoder chain.
> > >>>> + * @bridge: bridge control structure
> > >>>> + * @mode: desired mode to be validated
> > >>>> + *
> > >>>> + * Calls &drm_bridge_funcs.mode_valid for all the bridges in the
> > >>>> encoder
> > >>>> + * chain, starting from the first bridge to the last. If at least one
> > >>>> bridge + * does not accept the mode the function returns the error
> > >>>> code.
> > >>>> + *
> > >>>> + * Note: the bridge passed should be the one closest to the encoder.
> > >>>> + *
> > >>>> + * RETURNS:
> > >>>> + * MODE_OK on success, drm_mode_status Enum error code on failure
> > >>>> + */
> > >>>> +enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge,
> > >>>> +					   const struct 
> drm_display_mode
> > > 
> > > *mode)
> > > 
> > >>>> +{
> > >>>> +	enum drm_mode_status ret = MODE_OK;
> > >>>> +
> > >>>> +	if (!bridge)
> > >>>> +		return ret;
> > >>>> +
> > >>>> +	if (bridge->funcs->mode_valid)
> > >>>> +		ret = bridge->funcs->mode_valid(bridge, mode);
> > >>>> +
> > >>>> +	if (ret != MODE_OK)
> > >>>> +		return ret;
> > >>>> +
> > >>>> +	return drm_bridge_mode_valid(bridge->next, mode);
> > >>> 
> > >>> Looks like it should be pretty trivial to avoid the recursion.
> > >>> 
> > >>> Am I correct in interpreting this that bridges have some kind of
> > >>> a hand rolled linked list implementation? Reusing the standard
> > >>> linked lists would allow you to use list_for_each() etc.
> > >> 
> > >> Yeah it's a hand-rolled list, but current hw also has a bridge nesting
> > >> depth of 2, so it really doesn't matter. I guess once we have real long
> > >> chains of bridges we can fix this (and just using list_head sounds like a
> > >> great idea).
> > > 
> > > Even if not really needed right now, it's a pretty easy cleanup, if Jose
> > > has time to handle it in v3 of this series let's not postpone it ;-)
> > 
> > jfyi, some of the bridge functions call the ops from the last bridge in the
> > chain to first, so we'd need to use list_for_each_entry_prev() (or something
> > like that) for them.
> 
> And now that I think about it, for some of the operations (especially 
> enable/disable) I believe that the bridge should be able to decide whether to 
> call the next/previous bridge first or to configure its hardware first. I can 
> image bridges that need the previous bridge in the chain to provide a valid 
> clock before they get started, as well as bridges that need to be started with 
> the incoming video signal stopped.

That's why we have pre_/post_ hooks ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1638296 — [PATCH v2 4/8] drm: Add drm_connector_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 4/8] drm: Add drm_connector_mode_valid()
Message-ID<tFgO6-4HS-17@gated-at.bofh.it>
In reply to#1638291
Add a new helper to call connector->mode_valid callback.

Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>
---

TODO: function prototype should receive a const, but currently
mode_valid declaration is not const. In order to change this
I needed to touch *every* driver who uses this callback.
Postponed to when I have the time.

 drivers/gpu/drm/drm_connector.c     | 23 +++++++++++++++++++++++
 drivers/gpu/drm/drm_crtc_internal.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 9f84761..f2634a2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -24,6 +24,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
+#include <drm/drm_modeset_helper_vtables.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
@@ -1418,3 +1419,25 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
 	return tg;
 }
 EXPORT_SYMBOL(drm_mode_create_tile_group);
+
+/**
+ * drm_connector_mode_valid - call connector->mode_valid callback, if any.
+ * @connector: connector
+ * @mode: mode to be validated
+ *
+ * If no mode_valid callback is available this will return MODE_OK.
+ *
+ * Returns: drm_mode_status Enum
+ */
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+					      struct drm_display_mode *mode)
+{
+	const struct drm_connector_helper_funcs *connector_funcs =
+		connector->helper_private;
+
+	if (!connector_funcs || !connector_funcs->mode_valid)
+		return MODE_OK;
+
+	return connector_funcs->mode_valid(connector, mode);
+}
+EXPORT_SYMBOL(drm_connector_mode_valid);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 6165bc9..018b154 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -146,6 +146,8 @@ int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 				    uint64_t value);
 int drm_connector_create_standard_properties(struct drm_device *dev);
 const char *drm_get_connector_force_name(enum drm_connector_force force);
+enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
+					      struct drm_display_mode *mode);
 
 /* IOCTL */
 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1638300 — [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 2/8] drm: Add drm_crtc_mode_valid()
Message-ID<tFgO6-4HS-29@gated-at.bofh.it>
In reply to#1638291
Add a new helper to call crtc->mode_valid callback.

Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/drm_crtc.c          | 22 ++++++++++++++++++++++
 drivers/gpu/drm/drm_crtc_internal.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5af25ce..07ae705 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,6 +38,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_fourcc.h>
+#include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_modeset_lock.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_auth.h>
@@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
 
 	return ret;
 }
+
+/**
+ * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
+ * @crtc: crtc
+ * @mode: mode to be validated
+ *
+ * If no mode_valid callback is available this will return MODE_OK.
+ *
+ * Returns: drm_mode_status Enum
+ */
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+					 const struct drm_display_mode *mode)
+{
+	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+	if (!crtc_funcs || !crtc_funcs->mode_valid)
+		return MODE_OK;
+
+	return crtc_funcs->mode_valid(crtc, mode);
+}
+EXPORT_SYMBOL(drm_crtc_mode_valid);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index d077c54..3800abd 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -45,6 +45,9 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
 
 struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
 
+enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
+					 const struct drm_display_mode *mode);
+
 /* IOCTLs */
 int drm_mode_getcrtc(struct drm_device *dev,
 		     void *data, struct drm_file *file_priv);
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1638640 — Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

FromDaniel Vetter <daniel@ffwll.ch>
Date2017-05-10 10:10 +0200
SubjectRe: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()
Message-ID<tFuR4-6F7-23@gated-at.bofh.it>
In reply to#1638300
On Tue, May 09, 2017 at 06:00:09PM +0100, Jose Abreu wrote:
> Add a new helper to call crtc->mode_valid callback.
> 
> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> Cc: Carlos Palminha <palminha@synopsys.com>
> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Dave Airlie <airlied@linux.ie>
> Cc: Andrzej Hajda <a.hajda@samsung.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/drm_crtc.c          | 22 ++++++++++++++++++++++
>  drivers/gpu/drm/drm_crtc_internal.h |  3 +++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 5af25ce..07ae705 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -38,6 +38,7 @@
>  #include <drm/drm_crtc.h>
>  #include <drm/drm_edid.h>
>  #include <drm/drm_fourcc.h>
> +#include <drm/drm_modeset_helper_vtables.h>
>  #include <drm/drm_modeset_lock.h>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_auth.h>
> @@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
>  
>  	return ret;
>  }
> +
> +/**
> + * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
> + * @crtc: crtc
> + * @mode: mode to be validated
> + *
> + * If no mode_valid callback is available this will return MODE_OK.
> + *
> + * Returns: drm_mode_status Enum
> + */
> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
> +					 const struct drm_display_mode *mode)
> +{
> +	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;

This is clearly a helper func, but you place it into the core and
EXPORT_SYMBOL it. Imo this should be entirely internal to the helpers,
perhaps just stuff them all into drm_probe_helpers.c? Header file would be
drm_crtc_helper_internal.h.

That also means no need for kernel-doc (only the driver api is formally
documented) and then these 3 patches are so tiny it's better to squash
them into the patch that adds their users.

Thanks, Daniel
> +
> +	if (!crtc_funcs || !crtc_funcs->mode_valid)
> +		return MODE_OK;
> +
> +	return crtc_funcs->mode_valid(crtc, mode);
> +}
> +EXPORT_SYMBOL(drm_crtc_mode_valid);
> diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
> index d077c54..3800abd 100644
> --- a/drivers/gpu/drm/drm_crtc_internal.h
> +++ b/drivers/gpu/drm/drm_crtc_internal.h
> @@ -45,6 +45,9 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
>  
>  struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
>  
> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
> +					 const struct drm_display_mode *mode);
> +
>  /* IOCTLs */
>  int drm_mode_getcrtc(struct drm_device *dev,
>  		     void *data, struct drm_file *file_priv);
> -- 
> 1.9.1
> 
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1638681 — Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-10 11:00 +0200
SubjectRe: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()
Message-ID<tFvDs-6WY-25@gated-at.bofh.it>
In reply to#1638640
Hi Daniel,


On 10-05-2017 08:59, Daniel Vetter wrote:
> On Tue, May 09, 2017 at 06:00:09PM +0100, Jose Abreu wrote:
>> Add a new helper to call crtc->mode_valid callback.
>>
>> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>> Cc: Carlos Palminha <palminha@synopsys.com>
>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Dave Airlie <airlied@linux.ie>
>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>> Cc: Archit Taneja <architt@codeaurora.org>
>> ---
>>  drivers/gpu/drm/drm_crtc.c          | 22 ++++++++++++++++++++++
>>  drivers/gpu/drm/drm_crtc_internal.h |  3 +++
>>  2 files changed, 25 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> index 5af25ce..07ae705 100644
>> --- a/drivers/gpu/drm/drm_crtc.c
>> +++ b/drivers/gpu/drm/drm_crtc.c
>> @@ -38,6 +38,7 @@
>>  #include <drm/drm_crtc.h>
>>  #include <drm/drm_edid.h>
>>  #include <drm/drm_fourcc.h>
>> +#include <drm/drm_modeset_helper_vtables.h>
>>  #include <drm/drm_modeset_lock.h>
>>  #include <drm/drm_atomic.h>
>>  #include <drm/drm_auth.h>
>> @@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
>>  
>>  	return ret;
>>  }
>> +
>> +/**
>> + * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
>> + * @crtc: crtc
>> + * @mode: mode to be validated
>> + *
>> + * If no mode_valid callback is available this will return MODE_OK.
>> + *
>> + * Returns: drm_mode_status Enum
>> + */
>> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
>> +					 const struct drm_display_mode *mode)
>> +{
>> +	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
> This is clearly a helper func, but you place it into the core and
> EXPORT_SYMBOL it. Imo this should be entirely internal to the helpers,
> perhaps just stuff them all into drm_probe_helpers.c? Header file would be
> drm_crtc_helper_internal.h.

Yeah, at first I was not planning to export it but then I saw
that drm_bridge_mode_fixup() is exported (and is in drm_bridge.c)
so it kind of felt right to place this in drm_crtc.c. Anyway, I
will move them to drm_probe_helpers.c, indeed there is no point
in exporting this.

>
> That also means no need for kernel-doc (only the driver api is formally
> documented) and then these 3 patches are so tiny it's better to squash
> them into the patch that adds their users.

Ok, will remove the docs but I think its better to have a single
patch which adds all the helpers so that I can use the
suggested-by tag. Thanks!

Best regards,
Jose Miguel Abreu

>
> Thanks, Daniel
>> +
>> +	if (!crtc_funcs || !crtc_funcs->mode_valid)
>> +		return MODE_OK;
>> +
>> +	return crtc_funcs->mode_valid(crtc, mode);
>> +}
>> +EXPORT_SYMBOL(drm_crtc_mode_valid);
>> diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
>> index d077c54..3800abd 100644
>> --- a/drivers/gpu/drm/drm_crtc_internal.h
>> +++ b/drivers/gpu/drm/drm_crtc_internal.h
>> @@ -45,6 +45,9 @@ int drm_crtc_check_viewport(const struct drm_crtc *crtc,
>>  
>>  struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
>>  
>> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
>> +					 const struct drm_display_mode *mode);
>> +
>>  /* IOCTLs */
>>  int drm_mode_getcrtc(struct drm_device *dev,
>>  		     void *data, struct drm_file *file_priv);
>> -- 
>> 1.9.1
>>
>>

[toc] | [prev] | [next] | [standalone]


#1638901 — Re: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()

FromDaniel Vetter <daniel@ffwll.ch>
Date2017-05-10 17:20 +0200
SubjectRe: [PATCH v2 2/8] drm: Add drm_crtc_mode_valid()
Message-ID<tFBzc-2lT-11@gated-at.bofh.it>
In reply to#1638681
On Wed, May 10, 2017 at 09:57:30AM +0100, Jose Abreu wrote:
> Hi Daniel,
> 
> 
> On 10-05-2017 08:59, Daniel Vetter wrote:
> > On Tue, May 09, 2017 at 06:00:09PM +0100, Jose Abreu wrote:
> >> Add a new helper to call crtc->mode_valid callback.
> >>
> >> Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> >> Cc: Carlos Palminha <palminha@synopsys.com>
> >> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> >> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >> Cc: Dave Airlie <airlied@linux.ie>
> >> Cc: Andrzej Hajda <a.hajda@samsung.com>
> >> Cc: Archit Taneja <architt@codeaurora.org>
> >> ---
> >>  drivers/gpu/drm/drm_crtc.c          | 22 ++++++++++++++++++++++
> >>  drivers/gpu/drm/drm_crtc_internal.h |  3 +++
> >>  2 files changed, 25 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> >> index 5af25ce..07ae705 100644
> >> --- a/drivers/gpu/drm/drm_crtc.c
> >> +++ b/drivers/gpu/drm/drm_crtc.c
> >> @@ -38,6 +38,7 @@
> >>  #include <drm/drm_crtc.h>
> >>  #include <drm/drm_edid.h>
> >>  #include <drm/drm_fourcc.h>
> >> +#include <drm/drm_modeset_helper_vtables.h>
> >>  #include <drm/drm_modeset_lock.h>
> >>  #include <drm/drm_atomic.h>
> >>  #include <drm/drm_auth.h>
> >> @@ -741,3 +742,24 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
> >>  
> >>  	return ret;
> >>  }
> >> +
> >> +/**
> >> + * drm_crtc_mode_valid - call crtc->mode_valid callback, if any.
> >> + * @crtc: crtc
> >> + * @mode: mode to be validated
> >> + *
> >> + * If no mode_valid callback is available this will return MODE_OK.
> >> + *
> >> + * Returns: drm_mode_status Enum
> >> + */
> >> +enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
> >> +					 const struct drm_display_mode *mode)
> >> +{
> >> +	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
> > This is clearly a helper func, but you place it into the core and
> > EXPORT_SYMBOL it. Imo this should be entirely internal to the helpers,
> > perhaps just stuff them all into drm_probe_helpers.c? Header file would be
> > drm_crtc_helper_internal.h.
> 
> Yeah, at first I was not planning to export it but then I saw
> that drm_bridge_mode_fixup() is exported (and is in drm_bridge.c)
> so it kind of felt right to place this in drm_crtc.c. Anyway, I
> will move them to drm_probe_helpers.c, indeed there is no point
> in exporting this.

Bridge is a bit special, since there's the bridge integration through
atomic/legacy helpers, but drivers could also wire up a bridge on their
own (i.e. without using the drm_encoder->bridge pointer). Not sure anyone
is doing that right now, but that was the idea behind having the helpers
all exported.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1638301 — [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback
Message-ID<tFgO6-4HS-33@gated-at.bofh.it>
In reply to#1638291
Now that we have a callback to check if crtc supports a given mode
we can use it in arcpgu so that we restrict the number of probbed
modes to the ones we can actually display.

This is specially useful because arcpgu crtc is responsible to set
a clock value in the commit() stage but unfortunatelly this clock
does not support all the needed ranges.

Also, remove the atomic_check() callback as mode_valid() callback
will be called before.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index ad9a959..01cae0a 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -32,6 +32,18 @@
 	{ "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
 };
 
+static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
+				  const struct drm_display_mode *mode)
+{
+	long rate, clk_rate = mode->clock * 1000;
+
+	rate = clk_round_rate(arcpgu->clk, clk_rate);
+	if (rate != clk_rate)
+		return false;
+
+	return true;
+}
+
 static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
 {
 	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
+enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
+					     const struct drm_display_mode *mode)
+{
+	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
+
+	if (!arc_pgu_is_mode_valid(arcpgu, mode))
+		return MODE_NOCLOCK;
+
+	return MODE_OK;
+}
+
 static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
@@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
 			      ~ARCPGU_CTRL_ENABLE_MASK);
 }
 
-static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
-				     struct drm_crtc_state *state)
-{
-	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-	struct drm_display_mode *mode = &state->adjusted_mode;
-	long rate, clk_rate = mode->clock * 1000;
-
-	rate = clk_round_rate(arcpgu->clk, clk_rate);
-	if (rate != clk_rate)
-		return -EINVAL;
-
-	return 0;
-}
-
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 				      struct drm_crtc_state *state)
 {
@@ -158,6 +167,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
+	.mode_valid	= arc_pgu_crtc_mode_valid,
 	.mode_set	= drm_helper_crtc_mode_set,
 	.mode_set_base	= drm_helper_crtc_mode_set_base,
 	.mode_set_nofb	= arc_pgu_crtc_mode_set_nofb,
@@ -165,7 +175,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 	.disable	= arc_pgu_crtc_disable,
 	.prepare	= arc_pgu_crtc_disable,
 	.commit		= arc_pgu_crtc_enable,
-	.atomic_check	= arc_pgu_crtc_atomic_check,
 	.atomic_begin	= arc_pgu_crtc_atomic_begin,
 };
 
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1640373 — Re: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback

FromLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Date2017-05-12 12:00 +0200
SubjectRe: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback
Message-ID<tGfwC-2A6-15@gated-at.bofh.it>
In reply to#1638301
Hi Jose,

Thank you for the patch.

On Tuesday 09 May 2017 18:00:15 Jose Abreu wrote:
> Now that we have a callback to check if crtc supports a given mode
> we can use it in arcpgu so that we restrict the number of probbed
> modes to the ones we can actually display.
> 
> This is specially useful because arcpgu crtc is responsible to set
> a clock value in the commit() stage but unfortunatelly this clock
> does not support all the needed ranges.
> 
> Also, remove the atomic_check() callback as mode_valid() callback
> will be called before.
> 
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> Cc: Carlos Palminha <palminha@synopsys.com>
> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Dave Airlie <airlied@linux.ie>
> Cc: Andrzej Hajda <a.hajda@samsung.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ++++++++++++++++++++---------------
>  1 file changed, 24 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c
> b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a959..01cae0a 100644
> --- a/drivers/gpu/drm/arc/arcpgu_crtc.c
> +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
> @@ -32,6 +32,18 @@
>  	{ "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
>  };
> 
> +static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
> +				  const struct drm_display_mode *mode)
> +{
> +	long rate, clk_rate = mode->clock * 1000;
> +
> +	rate = clk_round_rate(arcpgu->clk, clk_rate);
> +	if (rate != clk_rate)
> +		return false;

This isn't anything new introduced by this patch, but shouldn't drivers allow 
for some margin in clock frequencies ? Surely if the mode requires a 
60.000.000 Hz frequency and the hardware can only generate 59.999.999 Hz or 
60.000.001 Hz we shouldn't fail. As far as I understand, this is something the 
mode_fixup() operation is supposed to handle, but the arc driver doesn't 
implement it.

> +	return true;
> +}

Can't you inline this in arc_pgu_crtc_mode_valid() as there's a single caller 
?

>  static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>  {
>  	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> @@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>  	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>  };
> 
> +enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
> +					     const struct drm_display_mode 
*mode)
> +{
> +	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> +
> +	if (!arc_pgu_is_mode_valid(arcpgu, mode))
> +		return MODE_NOCLOCK;
> +
> +	return MODE_OK;
> +}
> +
>  static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  {
>  	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> @@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
> ~ARCPGU_CTRL_ENABLE_MASK);
>  }
> 
> -static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
> -				     struct drm_crtc_state *state)
> -{
> -	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
> -	struct drm_display_mode *mode = &state->adjusted_mode;
> -	long rate, clk_rate = mode->clock * 1000;
> -
> -	rate = clk_round_rate(arcpgu->clk, clk_rate);
> -	if (rate != clk_rate)
> -		return -EINVAL;
> -
> -	return 0;
> -}
> -
>  static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
>  				      struct drm_crtc_state *state)
>  {
> @@ -158,6 +167,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc
> *crtc, }
> 
>  static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
> +	.mode_valid	= arc_pgu_crtc_mode_valid,
>  	.mode_set	= drm_helper_crtc_mode_set,
>  	.mode_set_base	= drm_helper_crtc_mode_set_base,
>  	.mode_set_nofb	= arc_pgu_crtc_mode_set_nofb,
> @@ -165,7 +175,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc
> *crtc, .disable	= arc_pgu_crtc_disable,
>  	.prepare	= arc_pgu_crtc_disable,
>  	.commit		= arc_pgu_crtc_enable,
> -	.atomic_check	= arc_pgu_crtc_atomic_check,
>  	.atomic_begin	= arc_pgu_crtc_atomic_begin,
>  };

-- 
Regards,

Laurent Pinchart

[toc] | [prev] | [next] | [standalone]


#1641242 — Re: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-15 03:50 +0200
SubjectRe: [PATCH v2 8/8] drm: arc: Use crtc->mode_valid() callback
Message-ID<tHdj3-1gC-1@gated-at.bofh.it>
In reply to#1640373
Hi Laurent,


Sorry for the late reply.


On 12-05-2017 10:57, Laurent Pinchart wrote:
> Hi Jose,
>
> Thank you for the patch.
>
> On Tuesday 09 May 2017 18:00:15 Jose Abreu wrote:
>> Now that we have a callback to check if crtc supports a given mode
>> we can use it in arcpgu so that we restrict the number of probbed
>> modes to the ones we can actually display.
>>
>> This is specially useful because arcpgu crtc is responsible to set
>> a clock value in the commit() stage but unfortunatelly this clock
>> does not support all the needed ranges.
>>
>> Also, remove the atomic_check() callback as mode_valid() callback
>> will be called before.
>>
>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>> Cc: Carlos Palminha <palminha@synopsys.com>
>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>> Cc: Dave Airlie <airlied@linux.ie>
>> Cc: Andrzej Hajda <a.hajda@samsung.com>
>> Cc: Archit Taneja <architt@codeaurora.org>
>> ---
>>  drivers/gpu/drm/arc/arcpgu_crtc.c | 39 ++++++++++++++++++++---------------
>>  1 file changed, 24 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c
>> b/drivers/gpu/drm/arc/arcpgu_crtc.c index ad9a959..01cae0a 100644
>> --- a/drivers/gpu/drm/arc/arcpgu_crtc.c
>> +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
>> @@ -32,6 +32,18 @@
>>  	{ "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 },
>>  };
>>
>> +static bool arc_pgu_is_mode_valid(struct arcpgu_drm_private *arcpgu,
>> +				  const struct drm_display_mode *mode)
>> +{
>> +	long rate, clk_rate = mode->clock * 1000;
>> +
>> +	rate = clk_round_rate(arcpgu->clk, clk_rate);
>> +	if (rate != clk_rate)
>> +		return false;
> This isn't anything new introduced by this patch, but shouldn't drivers allow 
> for some margin in clock frequencies ? Surely if the mode requires a 
> 60.000.000 Hz frequency and the hardware can only generate 59.999.999 Hz or 
> 60.000.001 Hz we shouldn't fail. As far as I understand, this is something the 
> mode_fixup() operation is supposed to handle, but the arc driver doesn't 
> implement it.

Its funny you mentioned this because I had exactly the same
discussion with Alexey (arcpgu maintainer) last Friday. Perhaps
we could think about a better way for this.

The main problem is that clock driver does not have all the
available clock values, so some modes will not have a compliant
clock value. Right now we are using clk_round_rate() and checking
if the return value matches the one we supplied, but as you
mentioned for 60vs59.94, for example, the mode will still fail to
commit because the clock will not be the same. We reached to the
conclusion that we could in this function have a max deviation
(which would be determined by max allowed tmds variation in HDMI
spec). What do you think?

Initially my idea was that clock driver should support this
variation and just return the same rate if the clock supported it
(i.e. if the deviation was not that much), but, as mentioned by
Alexey, the clock driver is agnostic of TMDS deviation, its just
a clock driver.

>
>> +	return true;
>> +}
> Can't you inline this in arc_pgu_crtc_mode_valid() as there's a single caller 
> ?

Yeah, I will in next version. This was a leftover from previous
version where atomic_check() and mode_valid() did the same
validation.

Thanks!

Best regards,
Jose Miguel Abreu

>>  static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>  {
>>  	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> @@ -64,6 +76,17 @@ static void arc_pgu_set_pxl_fmt(struct drm_crtc *crtc)
>>  	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>>  };
>>
>> +enum drm_mode_status arc_pgu_crtc_mode_valid(struct drm_crtc *crtc,
>> +					     const struct drm_display_mode 
> *mode)
>> +{
>> +	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> +
>> +	if (!arc_pgu_is_mode_valid(arcpgu, mode))
>> +		return MODE_NOCLOCK;
>> +
>> +	return MODE_OK;
>> +}
>> +
>>  static void arc_pgu_crtc_mode_set_nofb(struct drm_crtc *crtc)
>>  {
>>  	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> @@ -129,20 +152,6 @@ static void arc_pgu_crtc_disable(struct drm_crtc *crtc)
>> ~ARCPGU_CTRL_ENABLE_MASK);
>>  }
>>
>> -static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
>> -				     struct drm_crtc_state *state)
>> -{
>> -	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
>> -	struct drm_display_mode *mode = &state->adjusted_mode;
>> -	long rate, clk_rate = mode->clock * 1000;
>> -
>> -	rate = clk_round_rate(arcpgu->clk, clk_rate);
>> -	if (rate != clk_rate)
>> -		return -EINVAL;
>> -
>> -	return 0;
>> -}
>> -
>>  static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
>>  				      struct drm_crtc_state *state)
>>  {
>> @@ -158,6 +167,7 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc
>> *crtc, }
>>
>>  static const struct drm_crtc_helper_funcs arc_pgu_crtc_helper_funcs = {
>> +	.mode_valid	= arc_pgu_crtc_mode_valid,
>>  	.mode_set	= drm_helper_crtc_mode_set,
>>  	.mode_set_base	= drm_helper_crtc_mode_set_base,
>>  	.mode_set_nofb	= arc_pgu_crtc_mode_set_nofb,
>> @@ -165,7 +175,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc
>> *crtc, .disable	= arc_pgu_crtc_disable,
>>  	.prepare	= arc_pgu_crtc_disable,
>>  	.commit		= arc_pgu_crtc_enable,
>> -	.atomic_check	= arc_pgu_crtc_atomic_check,
>>  	.atomic_begin	= arc_pgu_crtc_atomic_begin,
>>  };

[toc] | [prev] | [next] | [standalone]


#1638302 — [PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper

FromJose Abreu <Jose.Abreu@synopsys.com>
Date2017-05-09 19:10 +0200
Subject[PATCH v2 5/8] drm: Use new mode_valid() helpers in connector probe helper
Message-ID<tFgO6-4HS-31@gated-at.bofh.it>
In reply to#1638291
This changes the connector probe helper function to use the new
encoder->mode_valid() and crtc->mode_valid() helper callbacks to
validate the modes.

The new callbacks are optional so the behaviour remains the same
if they are not implemented. If they are, then the code loops
through all the connector's encodersXcrtcs and calls the
callback.

If at least a valid encoderXcrtc combination is found which
accepts the mode then the function returns MODE_OK.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@linux.ie>
Cc: Andrzej Hajda <a.hajda@samsung.com>
Cc: Archit Taneja <architt@codeaurora.org>
---

Changes v1->v2:
	- Use new helpers suggested by Ville
	- Change documentation (Daniel)

 drivers/gpu/drm/drm_probe_helper.c | 60 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 1b0c14a..de47413 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -39,6 +39,8 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_edid.h>
 
+#include "drm_crtc_internal.h"
+
 /**
  * DOC: output probing helper overview
  *
@@ -80,6 +82,54 @@
 	return MODE_OK;
 }
 
+static enum drm_mode_status
+drm_mode_validate_connector(struct drm_connector *connector,
+			    struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	uint32_t *ids = connector->encoder_ids;
+	enum drm_mode_status ret = MODE_OK;
+	unsigned int i;
+
+	/* Step 1: Validate against connector */
+	ret = drm_connector_mode_valid(connector, mode);
+	if (ret != MODE_OK)
+		return ret;
+
+	/* Step 2: Validate against encoders and crtcs */
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+		struct drm_crtc *crtc;
+
+		if (!encoder)
+			continue;
+
+		ret = drm_encoder_mode_valid(encoder, mode);
+		if (ret != MODE_OK) {
+			/* No point in continuing for crtc check as this encoder
+			 * will not accept the mode anyway. If all encoders
+			 * reject the mode then, at exit, ret will not be
+			 * MODE_OK. */
+			continue;
+		}
+
+		drm_for_each_crtc(crtc, dev) {
+			if (!drm_encoder_crtc_ok(encoder, crtc))
+				continue;
+
+			ret = drm_crtc_mode_valid(crtc, mode);
+			if (ret == MODE_OK) {
+				/* If we get to this point there is at least
+				 * one combination of encoder+crtc that works
+				 * for this mode. Lets return now. */
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
 {
 	struct drm_cmdline_mode *cmdline_mode;
@@ -284,7 +334,11 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
  *    - drm_mode_validate_flag() checks the modes against basic connector
  *      capabilities (interlace_allowed,doublescan_allowed,stereo_allowed)
  *    - the optional &drm_connector_helper_funcs.mode_valid helper can perform
- *      driver and/or hardware specific checks
+ *      driver and/or sink specific checks
+ *    - the optional &drm_crtc_helper_funcs.mode_valid and
+ *      &drm_encoder_helper_funcs.mode_valid helpers can perform driver and/or
+ *      source specific checks which are also enforced by the modeset/atomic
+ *      helpers
  *
  * 5. Any mode whose status is not OK is pruned from the connector's modes list,
  *    accompanied by a debug message indicating the reason for the mode's
@@ -428,8 +482,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 		if (mode->status == MODE_OK)
 			mode->status = drm_mode_validate_flag(mode, mode_flags);
 
-		if (mode->status == MODE_OK && connector_funcs->mode_valid)
-			mode->status = connector_funcs->mode_valid(connector,
+		if (mode->status == MODE_OK)
+			mode->status = drm_mode_validate_connector(connector,
 								   mode);
 	}
 
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web