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


Groups > linux.kernel > #1623630 > unrolled thread

Re: [PATCH 1/6] drm: Add writeback connector type

Started byBoris Brezillon <boris.brezillon@free-electrons.com>
First post2017-04-14 12:10 +0200
Last post2017-04-19 15:00 +0200
Articles 6 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH 1/6] drm: Add writeback connector type Boris Brezillon <boris.brezillon@free-electrons.com> - 2017-04-14 12:10 +0200
    Re: [PATCH 1/6] drm: Add writeback connector type Brian Starkey <brian.starkey@arm.com> - 2017-04-18 19:40 +0200
      Re: [PATCH 1/6] drm: Add writeback connector type Boris Brezillon <boris.brezillon@free-electrons.com> - 2017-04-18 22:00 +0200
        Re: [PATCH 1/6] drm: Add writeback connector type Brian Starkey <brian.starkey@arm.com> - 2017-04-19 12:00 +0200
          Re: [PATCH 1/6] drm: Add writeback connector type Boris Brezillon <boris.brezillon@free-electrons.com> - 2017-04-19 13:40 +0200
            Re: [PATCH 1/6] drm: Add writeback connector type Brian Starkey <brian.starkey@arm.com> - 2017-04-19 15:00 +0200

#1623630 — Re: [PATCH 1/6] drm: Add writeback connector type

FromBoris Brezillon <boris.brezillon@free-electrons.com>
Date2017-04-14 12:10 +0200
SubjectRe: [PATCH 1/6] drm: Add writeback connector type
Message-ID<tw6kW-8fJ-21@gated-at.bofh.it>
On Fri, 25 Nov 2016 16:48:59 +0000
Brian Starkey <brian.starkey@arm.com> wrote:


>  
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index b5c6a8e..6bbd93f 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -86,6 +86,7 @@ struct drm_conn_prop_enum_list {
>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },

Is there a reason we have a Writeback connector, but keep using a
Virtual encoder to connect it to the CRTC? Wouldn't it make more sense
to also add a Writeback encoder?

>  };
>  
>  void drm_connector_ida_init(void)
> @@ -235,7 +236,8 @@ int drm_connector_init(struct drm_device *dev,
>  	list_add_tail(&connector->head, &config->connector_list);
>  	config->num_connector++;
>  
> -	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
> +	if ((connector_type != DRM_MODE_CONNECTOR_VIRTUAL) &&
> +	    (connector_type != DRM_MODE_CONNECTOR_WRITEBACK))

Nitpick: you don't need the extra parenthesis:

	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL &&
	    connector_type != DRM_MODE_CONNECTOR_WRITEBACK)

>  		drm_object_attach_property(&connector->base,
>  					      config->edid_property,
>  					      0);



> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 34f9741..dc4910d6 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -214,6 +214,19 @@ struct drm_connector_state {
>  	struct drm_encoder *best_encoder;
>  
>  	struct drm_atomic_state *state;
> +
> +	/**
> +	 * @writeback_job: Writeback job for writeback connectors
> +	 *
> +	 * Holds the framebuffer for a writeback connector. As the writeback
> +	 * completion may be asynchronous to the normal commit cycle, the
> +	 * writeback job lifetime is managed separately from the normal atomic
> +	 * state by this object.
> +	 *
> +	 * See also: drm_writeback_queue_job() and
> +	 * drm_writeback_signal_completion()
> +	 */
> +	struct drm_writeback_job *writeback_job;

Maybe I'm wrong, but is feels weird to have the writeback_job field
directly embedded in drm_connector_state, while drm_writeback_connector
inherits from drm_connector.

IMO, either you decide to directly put the drm_writeback_connector's
job_xxx fields in drm_connector and keep the drm_connector_state as is,
or you create a drm_writeback_connector_state which inherits from
drm_connector_state and embeds the writeback_job field.

Anyway, wait for Daniel's feedback before doing this change.

>  };
>  
>  /**
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index bf9991b2..3d3d07f 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -634,6 +634,20 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *suggested_y_property;
>  
> +	/**
> +	 * @writeback_fb_id_property: Property for writeback connectors, storing
> +	 * the ID of the output framebuffer.
> +	 * See also: drm_writeback_connector_init()
> +	 */
> +	struct drm_property *writeback_fb_id_property;
> +	/**
> +	 * @writeback_pixel_formats_property: Property for writeback connectors,
> +	 * storing an array of the supported pixel formats for the writeback
> +	 * engine (read-only).
> +	 * See also: drm_writeback_connector_init()
> +	 */
> +	struct drm_property *writeback_pixel_formats_property;
> +
>  	/* dumb ioctl parameters */
>  	uint32_t preferred_depth, prefer_shadow;
>  
> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
> new file mode 100644
> index 0000000..6b2ac45
> --- /dev/null
> +++ b/include/drm/drm_writeback.h
> @@ -0,0 +1,78 @@
> +/*
> + * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
> + * Author: Brian Starkey <brian.starkey@arm.com>
> + *
> + * This program is free software and is provided to you under the terms of the
> + * GNU General Public License version 2 as published by the Free Software
> + * Foundation, and any use by you of this program is subject to the terms
> + * of such GNU licence.
> + */
> +
> +#ifndef __DRM_WRITEBACK_H__
> +#define __DRM_WRITEBACK_H__
> +#include <drm/drm_connector.h>
> +#include <linux/workqueue.h>
> +
> +struct drm_writeback_connector {
> +	struct drm_connector base;

AFAIU, a writeback connector will always require an 'dummy' encoder to
make the DRM framework happy (AFAIK, a connector is always connected to
a CRTC through an encoder).

Wouldn't it make more sense to have a drm_encoder object embedded in
drm_writeback_connector so that people don't have to declare an extra
structure containing both the drm_writeback_connector connector and a
drm_encoder? Is there a good reason to keep them separate?

> +
> +	/**
> +	 * @pixel_formats_blob_ptr:
> +	 *
> +	 * DRM blob property data for the pixel formats list on writeback
> +	 * connectors
> +	 * See also drm_writeback_connector_init()
> +	 */
> +	struct drm_property_blob *pixel_formats_blob_ptr;
> +
> +	/** @job_lock: Protects job_queue */
> +	spinlock_t job_lock;
> +	/**
> +	 * @job_queue:
> +	 *
> +	 * Holds a list of a connector's writeback jobs; the last item is the
> +	 * most recent. The first item may be either waiting for the hardware
> +	 * to begin writing, or currently being written.
> +	 *
> +	 * See also: drm_writeback_queue_job() and
> +	 * drm_writeback_signal_completion()
> +	 */
> +	struct list_head job_queue;
> +};

[toc] | [next] | [standalone]


#1625489

FromBrian Starkey <brian.starkey@arm.com>
Date2017-04-18 19:40 +0200
Message-ID<txFgB-un-1@gated-at.bofh.it>
In reply to#1623630
Hi Boris,

On Fri, Apr 14, 2017 at 12:08:23PM +0200, Boris Brezillon wrote:
>On Fri, 25 Nov 2016 16:48:59 +0000
>Brian Starkey <brian.starkey@arm.com> wrote:
>
>
>>
>> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>> index b5c6a8e..6bbd93f 100644
>> --- a/drivers/gpu/drm/drm_connector.c
>> +++ b/drivers/gpu/drm/drm_connector.c
>> @@ -86,6 +86,7 @@ struct drm_conn_prop_enum_list {
>>  	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
>>  	{ DRM_MODE_CONNECTOR_DSI, "DSI" },
>>  	{ DRM_MODE_CONNECTOR_DPI, "DPI" },
>> +	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
>
>Is there a reason we have a Writeback connector, but keep using a
>Virtual encoder to connect it to the CRTC? Wouldn't it make more sense
>to also add a Writeback encoder?
>

Only that a writeback connector is functionally and conceptually quite
different from the existing connector types, whereas the "encoder"
(which realistically only exists because the framework forces it to)
acts pretty much like any other.

>>  };
>>
>>  void drm_connector_ida_init(void)
>> @@ -235,7 +236,8 @@ int drm_connector_init(struct drm_device *dev,
>>  	list_add_tail(&connector->head, &config->connector_list);
>>  	config->num_connector++;
>>
>> -	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL)
>> +	if ((connector_type != DRM_MODE_CONNECTOR_VIRTUAL) &&
>> +	    (connector_type != DRM_MODE_CONNECTOR_WRITEBACK))
>
>Nitpick: you don't need the extra parenthesis:
>
>	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL &&
>	    connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
>

Yeah fair enough, I can drop them.

>>  		drm_object_attach_property(&connector->base,
>>  					      config->edid_property,
>>  					      0);
>
>
>
>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>> index 34f9741..dc4910d6 100644
>> --- a/include/drm/drm_connector.h
>> +++ b/include/drm/drm_connector.h
>> @@ -214,6 +214,19 @@ struct drm_connector_state {
>>  	struct drm_encoder *best_encoder;
>>
>>  	struct drm_atomic_state *state;
>> +
>> +	/**
>> +	 * @writeback_job: Writeback job for writeback connectors
>> +	 *
>> +	 * Holds the framebuffer for a writeback connector. As the writeback
>> +	 * completion may be asynchronous to the normal commit cycle, the
>> +	 * writeback job lifetime is managed separately from the normal atomic
>> +	 * state by this object.
>> +	 *
>> +	 * See also: drm_writeback_queue_job() and
>> +	 * drm_writeback_signal_completion()
>> +	 */
>> +	struct drm_writeback_job *writeback_job;
>
>Maybe I'm wrong, but is feels weird to have the writeback_job field
>directly embedded in drm_connector_state, while drm_writeback_connector
>inherits from drm_connector.
>
>IMO, either you decide to directly put the drm_writeback_connector's
>job_xxx fields in drm_connector and keep the drm_connector_state as is,
>or you create a drm_writeback_connector_state which inherits from
>drm_connector_state and embeds the writeback_job field.

I did spend a decent amount of time looking at tracking the writeback
state along with the normal connector state. I couldn't come up with
anything I liked.

As the comment mentions, one of the problems is that you have to make
sure the relevant parts of the connector_state stay around until the
writeback is finished. That means you've got to block before
"swap_state()" until the previous writeback is done, and that
effectively limits your frame rate to refresh/2.

The Mali-DP HW doesn't have that limitation - we can queue up a new
commit while the current writeback is ongoing. For that reason I
didn't want to impose such a limitation in the framework.

In v1 I allowed that by making the Mali-DP driver hold its own
references to the relevant bits of the state for as long as it needed
them. In v3 I moved most of that code back to the core (in part
because Gustavo didn't like me signalling the DRM-"owned" fence from
my driver code directly). I think the new approach of "queue_job()"
and "signal_job()" reduces the amount of tricky code in drivers, and
is generally more clear (also familiar, when compared to vsync
events).

I'm certain there's other ways to do it (refcount atomic states?), but
it seemed like a biggish overhaul to achieve what would basically be
the same thing.

I was expecting each driver supporting writeback to have its own
different requirements around writeback lifetime/duration. For example
I think VC4 specifically came up, in that its writeback could take
several frames, whereas on Mali-DP we either finish within the frame
or we fail.

Letting the driver manage its writeback_job lifetime seemed like a
reasonable way to handle all that, with the documentation stating the
only behaviour which is guaranteed to work on all drivers:

   *     Userspace should wait for this fence to signal before making another
   *     commit affecting any of the same CRTCs, Planes or Connectors.
   *     **Failure to do so will result in undefined behaviour.**
   *     For this reason it is strongly recommended that all userspace
   *     applications making use of writeback connectors *always* retrieve an
   *     out-fence for the commit and use it appropriately.



... so all of that is why the _job fields don't live in a *_state
structure directly, and instead have to live in the separately-managed
structure pointed to by ->writeback_job.

Now, I did look at creating drm_writeback_connector_state, but as it
would only be holding the job pointer (see above) it didn't seem worth
scattering around the

    if (conn_state->connector->connector_type ==
        DRM_MODE_CONNECTOR_WRITEBACK)

checks everywhere before up-casting - {clear,reset,duplicate}_state(),
prepare_signalling(), complete_signalling(), etc. It just touched a
lot of code for the sake of an extra pointer field in each connector
state.

I can easily revisit that part if you like.

>
>Anyway, wait for Daniel's feedback before doing this change.
>

Am I expecting some more feedback from Daniel?

>>  };
>>
>>  /**
>> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> index bf9991b2..3d3d07f 100644
>> --- a/include/drm/drm_mode_config.h
>> +++ b/include/drm/drm_mode_config.h
>> @@ -634,6 +634,20 @@ struct drm_mode_config {
>>  	 */
>>  	struct drm_property *suggested_y_property;
>>
>> +	/**
>> +	 * @writeback_fb_id_property: Property for writeback connectors, storing
>> +	 * the ID of the output framebuffer.
>> +	 * See also: drm_writeback_connector_init()
>> +	 */
>> +	struct drm_property *writeback_fb_id_property;
>> +	/**
>> +	 * @writeback_pixel_formats_property: Property for writeback connectors,
>> +	 * storing an array of the supported pixel formats for the writeback
>> +	 * engine (read-only).
>> +	 * See also: drm_writeback_connector_init()
>> +	 */
>> +	struct drm_property *writeback_pixel_formats_property;
>> +
>>  	/* dumb ioctl parameters */
>>  	uint32_t preferred_depth, prefer_shadow;
>>
>> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
>> new file mode 100644
>> index 0000000..6b2ac45
>> --- /dev/null
>> +++ b/include/drm/drm_writeback.h
>> @@ -0,0 +1,78 @@
>> +/*
>> + * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
>> + * Author: Brian Starkey <brian.starkey@arm.com>
>> + *
>> + * This program is free software and is provided to you under the terms of the
>> + * GNU General Public License version 2 as published by the Free Software
>> + * Foundation, and any use by you of this program is subject to the terms
>> + * of such GNU licence.
>> + */
>> +
>> +#ifndef __DRM_WRITEBACK_H__
>> +#define __DRM_WRITEBACK_H__
>> +#include <drm/drm_connector.h>
>> +#include <linux/workqueue.h>
>> +
>> +struct drm_writeback_connector {
>> +	struct drm_connector base;
>
>AFAIU, a writeback connector will always require an 'dummy' encoder to
>make the DRM framework happy (AFAIK, a connector is always connected to
>a CRTC through an encoder).
>
>Wouldn't it make more sense to have a drm_encoder object embedded in
>drm_writeback_connector so that people don't have to declare an extra
>structure containing both the drm_writeback_connector connector and a
>drm_encoder? Is there a good reason to keep them separate?
>

Yeah that's not a bad idea. The encoder funcs could be passed in to
drm_writeback_connector_init() (in which case adding a writeback
encoder type would also make sense).

Thanks for the review,

-Brian

>> +
>> +	/**
>> +	 * @pixel_formats_blob_ptr:
>> +	 *
>> +	 * DRM blob property data for the pixel formats list on writeback
>> +	 * connectors
>> +	 * See also drm_writeback_connector_init()
>> +	 */
>> +	struct drm_property_blob *pixel_formats_blob_ptr;
>> +
>> +	/** @job_lock: Protects job_queue */
>> +	spinlock_t job_lock;
>> +	/**
>> +	 * @job_queue:
>> +	 *
>> +	 * Holds a list of a connector's writeback jobs; the last item is the
>> +	 * most recent. The first item may be either waiting for the hardware
>> +	 * to begin writing, or currently being written.
>> +	 *
>> +	 * See also: drm_writeback_queue_job() and
>> +	 * drm_writeback_signal_completion()
>> +	 */
>> +	struct list_head job_queue;
>> +};

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


#1625607

FromBoris Brezillon <boris.brezillon@free-electrons.com>
Date2017-04-18 22:00 +0200
Message-ID<txHs7-1Kl-43@gated-at.bofh.it>
In reply to#1625489
Hi Brian,

On Tue, 18 Apr 2017 18:34:43 +0100
Brian Starkey <brian.starkey@arm.com> wrote:

> >> @@ -214,6 +214,19 @@ struct drm_connector_state {
> >>  	struct drm_encoder *best_encoder;
> >>
> >>  	struct drm_atomic_state *state;
> >> +
> >> +	/**
> >> +	 * @writeback_job: Writeback job for writeback connectors
> >> +	 *
> >> +	 * Holds the framebuffer for a writeback connector. As the writeback
> >> +	 * completion may be asynchronous to the normal commit cycle, the
> >> +	 * writeback job lifetime is managed separately from the normal atomic
> >> +	 * state by this object.
> >> +	 *
> >> +	 * See also: drm_writeback_queue_job() and
> >> +	 * drm_writeback_signal_completion()
> >> +	 */
> >> +	struct drm_writeback_job *writeback_job;  
> >
> >Maybe I'm wrong, but is feels weird to have the writeback_job field
> >directly embedded in drm_connector_state, while drm_writeback_connector
> >inherits from drm_connector.
> >
> >IMO, either you decide to directly put the drm_writeback_connector's
> >job_xxx fields in drm_connector and keep the drm_connector_state as is,
> >or you create a drm_writeback_connector_state which inherits from
> >drm_connector_state and embeds the writeback_job field.  
> 
> I did spend a decent amount of time looking at tracking the writeback
> state along with the normal connector state. I couldn't come up with
> anything I liked.
> 
> As the comment mentions, one of the problems is that you have to make
> sure the relevant parts of the connector_state stay around until the
> writeback is finished. That means you've got to block before
> "swap_state()" until the previous writeback is done, and that
> effectively limits your frame rate to refresh/2.
> 
> The Mali-DP HW doesn't have that limitation - we can queue up a new
> commit while the current writeback is ongoing. For that reason I
> didn't want to impose such a limitation in the framework.
> 
> In v1 I allowed that by making the Mali-DP driver hold its own
> references to the relevant bits of the state for as long as it needed
> them. In v3 I moved most of that code back to the core (in part
> because Gustavo didn't like me signalling the DRM-"owned" fence from
> my driver code directly). I think the new approach of "queue_job()"
> and "signal_job()" reduces the amount of tricky code in drivers, and
> is generally more clear (also familiar, when compared to vsync
> events).
> 
> I'm certain there's other ways to do it (refcount atomic states?), but
> it seemed like a biggish overhaul to achieve what would basically be
> the same thing.
> 
> I was expecting each driver supporting writeback to have its own
> different requirements around writeback lifetime/duration. For example
> I think VC4 specifically came up, in that its writeback could take
> several frames, whereas on Mali-DP we either finish within the frame
> or we fail.
> 
> Letting the driver manage its writeback_job lifetime seemed like a
> reasonable way to handle all that, with the documentation stating the
> only behaviour which is guaranteed to work on all drivers:
> 
>    *     Userspace should wait for this fence to signal before making another
>    *     commit affecting any of the same CRTCs, Planes or Connectors.
>    *     **Failure to do so will result in undefined behaviour.**
>    *     For this reason it is strongly recommended that all userspace
>    *     applications making use of writeback connectors *always* retrieve an
>    *     out-fence for the commit and use it appropriately.
> 
> 
> 
> ... so all of that is why the _job fields don't live in a *_state
> structure directly, and instead have to live in the separately-managed
> structure pointed to by ->writeback_job.
> 
> Now, I did look at creating drm_writeback_connector_state, but as it
> would only be holding the job pointer (see above) it didn't seem worth
> scattering around the
> 
>     if (conn_state->connector->connector_type ==
>         DRM_MODE_CONNECTOR_WRITEBACK)
> 
> checks everywhere before up-casting - {clear,reset,duplicate}_state(),
> prepare_signalling(), complete_signalling(), etc. It just touched a
> lot of code for the sake of an extra pointer field in each connector
> state.
> 
> I can easily revisit that part if you like.

I think there's a misunderstanding. I was just suggesting to be
consistent in the inheritance vs 'one object to handle everything'
approach.

I'm perfectly fine with embedding the writeback_job pointer directly in
drm_connector_state, but then it would IMO make more sense to do the
same for the drm_connector object (embed drm_writeback_connector fields
into drm_connector instead of making drm_writeback_connector inherit
from drm_connector).

Anyway, that's just a detail.

> 
> >
> >Anyway, wait for Daniel's feedback before doing this change.
> >  
> 
> Am I expecting some more feedback from Daniel?

No, I was just saying that before doing the changes I was suggesting,
you should wait for Daniel's opinion, because I might be wrong.

> 
> >>  };
> >>
> >>  /**
> >> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> >> index bf9991b2..3d3d07f 100644
> >> --- a/include/drm/drm_mode_config.h
> >> +++ b/include/drm/drm_mode_config.h
> >> @@ -634,6 +634,20 @@ struct drm_mode_config {
> >>  	 */
> >>  	struct drm_property *suggested_y_property;
> >>
> >> +	/**
> >> +	 * @writeback_fb_id_property: Property for writeback connectors, storing
> >> +	 * the ID of the output framebuffer.
> >> +	 * See also: drm_writeback_connector_init()
> >> +	 */
> >> +	struct drm_property *writeback_fb_id_property;
> >> +	/**
> >> +	 * @writeback_pixel_formats_property: Property for writeback connectors,
> >> +	 * storing an array of the supported pixel formats for the writeback
> >> +	 * engine (read-only).
> >> +	 * See also: drm_writeback_connector_init()
> >> +	 */
> >> +	struct drm_property *writeback_pixel_formats_property;
> >> +
> >>  	/* dumb ioctl parameters */
> >>  	uint32_t preferred_depth, prefer_shadow;
> >>
> >> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
> >> new file mode 100644
> >> index 0000000..6b2ac45
> >> --- /dev/null
> >> +++ b/include/drm/drm_writeback.h
> >> @@ -0,0 +1,78 @@
> >> +/*
> >> + * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
> >> + * Author: Brian Starkey <brian.starkey@arm.com>
> >> + *
> >> + * This program is free software and is provided to you under the terms of the
> >> + * GNU General Public License version 2 as published by the Free Software
> >> + * Foundation, and any use by you of this program is subject to the terms
> >> + * of such GNU licence.
> >> + */
> >> +
> >> +#ifndef __DRM_WRITEBACK_H__
> >> +#define __DRM_WRITEBACK_H__
> >> +#include <drm/drm_connector.h>
> >> +#include <linux/workqueue.h>
> >> +
> >> +struct drm_writeback_connector {
> >> +	struct drm_connector base;  
> >
> >AFAIU, a writeback connector will always require an 'dummy' encoder to
> >make the DRM framework happy (AFAIK, a connector is always connected to
> >a CRTC through an encoder).
> >
> >Wouldn't it make more sense to have a drm_encoder object embedded in
> >drm_writeback_connector so that people don't have to declare an extra
> >structure containing both the drm_writeback_connector connector and a
> >drm_encoder? Is there a good reason to keep them separate?
> >  
> 
> Yeah that's not a bad idea. The encoder funcs could be passed in to
> drm_writeback_connector_init() (in which case adding a writeback
> encoder type would also make sense).

Well, the more I look at it the more I find it weird to represent this
writeback feature as a connector. To me, it seems to be closer to a
plane object (DRM_PLANE_TYPE_WRITEBACK?) than a real connector.
Actually, the Atmel HLCDC IP use the same register interface to expose
the overlay planes and writeback features.
Of course, representing it as a plane requires patching the core to
allow enabling a CRTC that has no active connectors connected to it if
at least one writeback plane is enabled and connected to the CRTC, but
it should be doable.
By doing that, we would also get rid of these fake connector/encoder
objects as well as the fake modes we are returning in
connector->get_modes().

As far as I can tell, the VC4 and Atmel HLCDC IP should fit pretty well
in this model, not sure about the mali-dp though.

Brian, did you consider this approach, and if you did, can you detail
why you decided to expose this feature as a connector?

Daniel (or anyone else), please step in if you think this is a stupid
idea :-).

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


#1625978

FromBrian Starkey <brian.starkey@arm.com>
Date2017-04-19 12:00 +0200
Message-ID<txUz0-1Rj-3@gated-at.bofh.it>
In reply to#1625607
On Tue, Apr 18, 2017 at 09:57:17PM +0200, Boris Brezillon wrote:
>Hi Brian,
>
>On Tue, 18 Apr 2017 18:34:43 +0100
>Brian Starkey <brian.starkey@arm.com> wrote:
>
>> >> @@ -214,6 +214,19 @@ struct drm_connector_state {
>> >>  	struct drm_encoder *best_encoder;
>> >>
>> >>  	struct drm_atomic_state *state;
>> >> +
>> >> +	/**
>> >> +	 * @writeback_job: Writeback job for writeback connectors
>> >> +	 *
>> >> +	 * Holds the framebuffer for a writeback connector. As the writeback
>> >> +	 * completion may be asynchronous to the normal commit cycle, the
>> >> +	 * writeback job lifetime is managed separately from the normal atomic
>> >> +	 * state by this object.
>> >> +	 *
>> >> +	 * See also: drm_writeback_queue_job() and
>> >> +	 * drm_writeback_signal_completion()
>> >> +	 */
>> >> +	struct drm_writeback_job *writeback_job;
>> >
>> >Maybe I'm wrong, but is feels weird to have the writeback_job field
>> >directly embedded in drm_connector_state, while drm_writeback_connector
>> >inherits from drm_connector.
>> >
>> >IMO, either you decide to directly put the drm_writeback_connector's
>> >job_xxx fields in drm_connector and keep the drm_connector_state as is,
>> >or you create a drm_writeback_connector_state which inherits from
>> >drm_connector_state and embeds the writeback_job field.
>>
>> I did spend a decent amount of time looking at tracking the writeback
>> state along with the normal connector state. I couldn't come up with
>> anything I liked.
>>
>> As the comment mentions, one of the problems is that you have to make
>> sure the relevant parts of the connector_state stay around until the
>> writeback is finished. That means you've got to block before
>> "swap_state()" until the previous writeback is done, and that
>> effectively limits your frame rate to refresh/2.
>>
>> The Mali-DP HW doesn't have that limitation - we can queue up a new
>> commit while the current writeback is ongoing. For that reason I
>> didn't want to impose such a limitation in the framework.
>>
>> In v1 I allowed that by making the Mali-DP driver hold its own
>> references to the relevant bits of the state for as long as it needed
>> them. In v3 I moved most of that code back to the core (in part
>> because Gustavo didn't like me signalling the DRM-"owned" fence from
>> my driver code directly). I think the new approach of "queue_job()"
>> and "signal_job()" reduces the amount of tricky code in drivers, and
>> is generally more clear (also familiar, when compared to vsync
>> events).
>>
>> I'm certain there's other ways to do it (refcount atomic states?), but
>> it seemed like a biggish overhaul to achieve what would basically be
>> the same thing.
>>
>> I was expecting each driver supporting writeback to have its own
>> different requirements around writeback lifetime/duration. For example
>> I think VC4 specifically came up, in that its writeback could take
>> several frames, whereas on Mali-DP we either finish within the frame
>> or we fail.
>>
>> Letting the driver manage its writeback_job lifetime seemed like a
>> reasonable way to handle all that, with the documentation stating the
>> only behaviour which is guaranteed to work on all drivers:
>>
>>    *     Userspace should wait for this fence to signal before making another
>>    *     commit affecting any of the same CRTCs, Planes or Connectors.
>>    *     **Failure to do so will result in undefined behaviour.**
>>    *     For this reason it is strongly recommended that all userspace
>>    *     applications making use of writeback connectors *always* retrieve an
>>    *     out-fence for the commit and use it appropriately.
>>
>>
>>
>> ... so all of that is why the _job fields don't live in a *_state
>> structure directly, and instead have to live in the separately-managed
>> structure pointed to by ->writeback_job.
>>
>> Now, I did look at creating drm_writeback_connector_state, but as it
>> would only be holding the job pointer (see above) it didn't seem worth
>> scattering around the
>>
>>     if (conn_state->connector->connector_type ==
>>         DRM_MODE_CONNECTOR_WRITEBACK)
>>
>> checks everywhere before up-casting - {clear,reset,duplicate}_state(),
>> prepare_signalling(), complete_signalling(), etc. It just touched a
>> lot of code for the sake of an extra pointer field in each connector
>> state.
>>
>> I can easily revisit that part if you like.
>
>I think there's a misunderstanding. I was just suggesting to be
>consistent in the inheritance vs 'one object to handle everything'
>approach.

doh.. right yeah I misread. Sorry for the tangent. :-)

>
>I'm perfectly fine with embedding the writeback_job pointer directly in
>drm_connector_state, but then it would IMO make more sense to do the
>same for the drm_connector object (embed drm_writeback_connector fields
>into drm_connector instead of making drm_writeback_connector inherit
>from drm_connector).
>

I agree that it's inconsistent. I guess I did it out of pragmatism -
there's quite a lot of new fields in drm_writeback_connector, and the
code needed to support it was comparatively small. On the other hand
there's only one additional field in drm_connector_state and the code
required to subclass it looked comparatively large.

>Anyway, that's just a detail.
>
>>
>> >
>> >Anyway, wait for Daniel's feedback before doing this change.
>> >
>>
>> Am I expecting some more feedback from Daniel?
>
>No, I was just saying that before doing the changes I was suggesting,
>you should wait for Daniel's opinion, because I might be wrong.
>
>>
>> >>  };
>> >>
>> >>  /**
>> >> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> >> index bf9991b2..3d3d07f 100644
>> >> --- a/include/drm/drm_mode_config.h
>> >> +++ b/include/drm/drm_mode_config.h
>> >> @@ -634,6 +634,20 @@ struct drm_mode_config {
>> >>  	 */
>> >>  	struct drm_property *suggested_y_property;
>> >>
>> >> +	/**
>> >> +	 * @writeback_fb_id_property: Property for writeback connectors, storing
>> >> +	 * the ID of the output framebuffer.
>> >> +	 * See also: drm_writeback_connector_init()
>> >> +	 */
>> >> +	struct drm_property *writeback_fb_id_property;
>> >> +	/**
>> >> +	 * @writeback_pixel_formats_property: Property for writeback connectors,
>> >> +	 * storing an array of the supported pixel formats for the writeback
>> >> +	 * engine (read-only).
>> >> +	 * See also: drm_writeback_connector_init()
>> >> +	 */
>> >> +	struct drm_property *writeback_pixel_formats_property;
>> >> +
>> >>  	/* dumb ioctl parameters */
>> >>  	uint32_t preferred_depth, prefer_shadow;
>> >>
>> >> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
>> >> new file mode 100644
>> >> index 0000000..6b2ac45
>> >> --- /dev/null
>> >> +++ b/include/drm/drm_writeback.h
>> >> @@ -0,0 +1,78 @@
>> >> +/*
>> >> + * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
>> >> + * Author: Brian Starkey <brian.starkey@arm.com>
>> >> + *
>> >> + * This program is free software and is provided to you under the terms of the
>> >> + * GNU General Public License version 2 as published by the Free Software
>> >> + * Foundation, and any use by you of this program is subject to the terms
>> >> + * of such GNU licence.
>> >> + */
>> >> +
>> >> +#ifndef __DRM_WRITEBACK_H__
>> >> +#define __DRM_WRITEBACK_H__
>> >> +#include <drm/drm_connector.h>
>> >> +#include <linux/workqueue.h>
>> >> +
>> >> +struct drm_writeback_connector {
>> >> +	struct drm_connector base;
>> >
>> >AFAIU, a writeback connector will always require an 'dummy' encoder to
>> >make the DRM framework happy (AFAIK, a connector is always connected to
>> >a CRTC through an encoder).
>> >
>> >Wouldn't it make more sense to have a drm_encoder object embedded in
>> >drm_writeback_connector so that people don't have to declare an extra
>> >structure containing both the drm_writeback_connector connector and a
>> >drm_encoder? Is there a good reason to keep them separate?
>> >
>>
>> Yeah that's not a bad idea. The encoder funcs could be passed in to
>> drm_writeback_connector_init() (in which case adding a writeback
>> encoder type would also make sense).
>
>Well, the more I look at it the more I find it weird to represent this
>writeback feature as a connector. To me, it seems to be closer to a
>plane object (DRM_PLANE_TYPE_WRITEBACK?) than a real connector.
>Actually, the Atmel HLCDC IP use the same register interface to expose
>the overlay planes and writeback features.
>Of course, representing it as a plane requires patching the core to
>allow enabling a CRTC that has no active connectors connected to it if
>at least one writeback plane is enabled and connected to the CRTC, but
>it should be doable.

Could you expand a bit on how you think planes fit better? It is
something we've previously talked about internally, but so far I'm not
convinced :-)

>By doing that, we would also get rid of these fake connector/encoder
>objects as well as the fake modes we are returning in
>connector->get_modes().

What makes the connector/encoder fake? They represent a real piece of
hardware just the same as a drm_plane would.

I don't mind dropping the mode list and letting userspace just make
up whatever timing it wants - it'd need to do the same if writeback
was a plane - but in some respects giving it a list of modes the same
way we normally do seems nicer for userspace.

>
>As far as I can tell, the VC4 and Atmel HLCDC IP should fit pretty well
>in this model, not sure about the mali-dp though.
>
>Brian, did you consider this approach, and if you did, can you detail
>why you decided to expose this feature as a connector?
>
>Daniel (or anyone else), please step in if you think this is a stupid
>idea :-).

Ville originally suggested using a connector, which Eric followed up
by saying that's what he was thinking of for VC4 writeback too[1].
That was my initial reason for focussing on a connector-based
approach.

I prefer connector over plane conceptually because it keeps with the
established data flow: planes are sources, connectors are sinks.

In some respects the plane _object_ looks like it would fit - it has a
pixel format list and an FB_ID. But everything else would be acting
the exact opposite to a normal plane, and I think there's a bunch of
baked-in assumptions in the kernel and userspace around CRTCs always
having at least one connector.

On the other hand, a writeback connector gains a few extra properties
over a normal connector, but most stuff stays the same. The pipeline
setup looks the same as normal to userspace, you don't need a CRTC to
be active with no connectors, output cloning is the same etc.

Thanks,
-Brian

[1] https://lists.freedesktop.org/archives/dri-devel/2016-July/113329.html

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


#1626037

FromBoris Brezillon <boris.brezillon@free-electrons.com>
Date2017-04-19 13:40 +0200
Message-ID<txW7M-2U9-29@gated-at.bofh.it>
In reply to#1625978
On Wed, 19 Apr 2017 10:51:23 +0100
Brian Starkey <brian.starkey@arm.com> wrote:

> On Tue, Apr 18, 2017 at 09:57:17PM +0200, Boris Brezillon wrote:
> >Hi Brian,
> >
> >On Tue, 18 Apr 2017 18:34:43 +0100
> >Brian Starkey <brian.starkey@arm.com> wrote:
> >  
> >> >> @@ -214,6 +214,19 @@ struct drm_connector_state {
> >> >>  	struct drm_encoder *best_encoder;
> >> >>
> >> >>  	struct drm_atomic_state *state;
> >> >> +
> >> >> +	/**
> >> >> +	 * @writeback_job: Writeback job for writeback connectors
> >> >> +	 *
> >> >> +	 * Holds the framebuffer for a writeback connector. As the writeback
> >> >> +	 * completion may be asynchronous to the normal commit cycle, the
> >> >> +	 * writeback job lifetime is managed separately from the normal atomic
> >> >> +	 * state by this object.
> >> >> +	 *
> >> >> +	 * See also: drm_writeback_queue_job() and
> >> >> +	 * drm_writeback_signal_completion()
> >> >> +	 */
> >> >> +	struct drm_writeback_job *writeback_job;  
> >> >
> >> >Maybe I'm wrong, but is feels weird to have the writeback_job field
> >> >directly embedded in drm_connector_state, while drm_writeback_connector
> >> >inherits from drm_connector.
> >> >
> >> >IMO, either you decide to directly put the drm_writeback_connector's
> >> >job_xxx fields in drm_connector and keep the drm_connector_state as is,
> >> >or you create a drm_writeback_connector_state which inherits from
> >> >drm_connector_state and embeds the writeback_job field.  
> >>
> >> I did spend a decent amount of time looking at tracking the writeback
> >> state along with the normal connector state. I couldn't come up with
> >> anything I liked.
> >>
> >> As the comment mentions, one of the problems is that you have to make
> >> sure the relevant parts of the connector_state stay around until the
> >> writeback is finished. That means you've got to block before
> >> "swap_state()" until the previous writeback is done, and that
> >> effectively limits your frame rate to refresh/2.
> >>
> >> The Mali-DP HW doesn't have that limitation - we can queue up a new
> >> commit while the current writeback is ongoing. For that reason I
> >> didn't want to impose such a limitation in the framework.
> >>
> >> In v1 I allowed that by making the Mali-DP driver hold its own
> >> references to the relevant bits of the state for as long as it needed
> >> them. In v3 I moved most of that code back to the core (in part
> >> because Gustavo didn't like me signalling the DRM-"owned" fence from
> >> my driver code directly). I think the new approach of "queue_job()"
> >> and "signal_job()" reduces the amount of tricky code in drivers, and
> >> is generally more clear (also familiar, when compared to vsync
> >> events).
> >>
> >> I'm certain there's other ways to do it (refcount atomic states?), but
> >> it seemed like a biggish overhaul to achieve what would basically be
> >> the same thing.
> >>
> >> I was expecting each driver supporting writeback to have its own
> >> different requirements around writeback lifetime/duration. For example
> >> I think VC4 specifically came up, in that its writeback could take
> >> several frames, whereas on Mali-DP we either finish within the frame
> >> or we fail.
> >>
> >> Letting the driver manage its writeback_job lifetime seemed like a
> >> reasonable way to handle all that, with the documentation stating the
> >> only behaviour which is guaranteed to work on all drivers:
> >>
> >>    *     Userspace should wait for this fence to signal before making another
> >>    *     commit affecting any of the same CRTCs, Planes or Connectors.
> >>    *     **Failure to do so will result in undefined behaviour.**
> >>    *     For this reason it is strongly recommended that all userspace
> >>    *     applications making use of writeback connectors *always* retrieve an
> >>    *     out-fence for the commit and use it appropriately.
> >>
> >>
> >>
> >> ... so all of that is why the _job fields don't live in a *_state
> >> structure directly, and instead have to live in the separately-managed
> >> structure pointed to by ->writeback_job.
> >>
> >> Now, I did look at creating drm_writeback_connector_state, but as it
> >> would only be holding the job pointer (see above) it didn't seem worth
> >> scattering around the
> >>
> >>     if (conn_state->connector->connector_type ==
> >>         DRM_MODE_CONNECTOR_WRITEBACK)
> >>
> >> checks everywhere before up-casting - {clear,reset,duplicate}_state(),
> >> prepare_signalling(), complete_signalling(), etc. It just touched a
> >> lot of code for the sake of an extra pointer field in each connector
> >> state.
> >>
> >> I can easily revisit that part if you like.  
> >
> >I think there's a misunderstanding. I was just suggesting to be
> >consistent in the inheritance vs 'one object to handle everything'
> >approach.  
> 
> doh.. right yeah I misread. Sorry for the tangent. :-)
> 
> >
> >I'm perfectly fine with embedding the writeback_job pointer directly in
> >drm_connector_state, but then it would IMO make more sense to do the
> >same for the drm_connector object (embed drm_writeback_connector fields
> >into drm_connector instead of making drm_writeback_connector inherit
> >from drm_connector).
> >  
> 
> I agree that it's inconsistent. I guess I did it out of pragmatism -
> there's quite a lot of new fields in drm_writeback_connector, and the
> code needed to support it was comparatively small. On the other hand
> there's only one additional field in drm_connector_state and the code
> required to subclass it looked comparatively large.
> 
> >Anyway, that's just a detail.
> >  
> >>  
> >> >
> >> >Anyway, wait for Daniel's feedback before doing this change.
> >> >  
> >>
> >> Am I expecting some more feedback from Daniel?  
> >
> >No, I was just saying that before doing the changes I was suggesting,
> >you should wait for Daniel's opinion, because I might be wrong.
> >  
> >>  
> >> >>  };
> >> >>
> >> >>  /**
> >> >> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> >> >> index bf9991b2..3d3d07f 100644
> >> >> --- a/include/drm/drm_mode_config.h
> >> >> +++ b/include/drm/drm_mode_config.h
> >> >> @@ -634,6 +634,20 @@ struct drm_mode_config {
> >> >>  	 */
> >> >>  	struct drm_property *suggested_y_property;
> >> >>
> >> >> +	/**
> >> >> +	 * @writeback_fb_id_property: Property for writeback connectors, storing
> >> >> +	 * the ID of the output framebuffer.
> >> >> +	 * See also: drm_writeback_connector_init()
> >> >> +	 */
> >> >> +	struct drm_property *writeback_fb_id_property;
> >> >> +	/**
> >> >> +	 * @writeback_pixel_formats_property: Property for writeback connectors,
> >> >> +	 * storing an array of the supported pixel formats for the writeback
> >> >> +	 * engine (read-only).
> >> >> +	 * See also: drm_writeback_connector_init()
> >> >> +	 */
> >> >> +	struct drm_property *writeback_pixel_formats_property;
> >> >> +
> >> >>  	/* dumb ioctl parameters */
> >> >>  	uint32_t preferred_depth, prefer_shadow;
> >> >>
> >> >> diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
> >> >> new file mode 100644
> >> >> index 0000000..6b2ac45
> >> >> --- /dev/null
> >> >> +++ b/include/drm/drm_writeback.h
> >> >> @@ -0,0 +1,78 @@
> >> >> +/*
> >> >> + * (C) COPYRIGHT 2016 ARM Limited. All rights reserved.
> >> >> + * Author: Brian Starkey <brian.starkey@arm.com>
> >> >> + *
> >> >> + * This program is free software and is provided to you under the terms of the
> >> >> + * GNU General Public License version 2 as published by the Free Software
> >> >> + * Foundation, and any use by you of this program is subject to the terms
> >> >> + * of such GNU licence.
> >> >> + */
> >> >> +
> >> >> +#ifndef __DRM_WRITEBACK_H__
> >> >> +#define __DRM_WRITEBACK_H__
> >> >> +#include <drm/drm_connector.h>
> >> >> +#include <linux/workqueue.h>
> >> >> +
> >> >> +struct drm_writeback_connector {
> >> >> +	struct drm_connector base;  
> >> >
> >> >AFAIU, a writeback connector will always require an 'dummy' encoder to
> >> >make the DRM framework happy (AFAIK, a connector is always connected to
> >> >a CRTC through an encoder).
> >> >
> >> >Wouldn't it make more sense to have a drm_encoder object embedded in
> >> >drm_writeback_connector so that people don't have to declare an extra
> >> >structure containing both the drm_writeback_connector connector and a
> >> >drm_encoder? Is there a good reason to keep them separate?
> >> >  
> >>
> >> Yeah that's not a bad idea. The encoder funcs could be passed in to
> >> drm_writeback_connector_init() (in which case adding a writeback
> >> encoder type would also make sense).  
> >
> >Well, the more I look at it the more I find it weird to represent this
> >writeback feature as a connector. To me, it seems to be closer to a
> >plane object (DRM_PLANE_TYPE_WRITEBACK?) than a real connector.
> >Actually, the Atmel HLCDC IP use the same register interface to expose
> >the overlay planes and writeback features.
> >Of course, representing it as a plane requires patching the core to
> >allow enabling a CRTC that has no active connectors connected to it if
> >at least one writeback plane is enabled and connected to the CRTC, but
> >it should be doable.  
> 
> Could you expand a bit on how you think planes fit better?

Just had the impression that the writeback feature was conceptually
closer to a plane object (which is attached buffers and expose ways to
specify which portion of the buffer should be used, provides way to
atomically switch 2 buffers, ...).

> It is
> something we've previously talked about internally, but so far I'm not
> convinced :-)

Okay, as I said, I don't know all the history, hence my questions ;-).

> 
> >By doing that, we would also get rid of these fake connector/encoder
> >objects as well as the fake modes we are returning in
> >connector->get_modes().  
> 
> What makes the connector/encoder fake? They represent a real piece of
> hardware just the same as a drm_plane would.

Well, that's probably subject to interpretation, but I don't consider
these writeback encoders/connectors as real encoders/connectors. They
are definitely real HW blocks, but not what we usually consider as an
encoder/connector.

> 
> I don't mind dropping the mode list and letting userspace just make
> up whatever timing it wants - it'd need to do the same if writeback
> was a plane - but in some respects giving it a list of modes the same
> way we normally do seems nicer for userspace.
> 
> >
> >As far as I can tell, the VC4 and Atmel HLCDC IP should fit pretty well
> >in this model, not sure about the mali-dp though.
> >
> >Brian, did you consider this approach, and if you did, can you detail
> >why you decided to expose this feature as a connector?
> >
> >Daniel (or anyone else), please step in if you think this is a stupid
> >idea :-).  
> 
> Ville originally suggested using a connector, which Eric followed up
> by saying that's what he was thinking of for VC4 writeback too[1].

Thanks for the pointer.

> That was my initial reason for focussing on a connector-based
> approach.
> 
> I prefer connector over plane conceptually because it keeps with the
> established data flow: planes are sources, connectors are sinks.

Okay, it's a valid point.

> 
> In some respects the plane _object_ looks like it would fit - it has a
> pixel format list and an FB_ID. But everything else would be acting
> the exact opposite to a normal plane, and I think there's a bunch of
> baked-in assumptions in the kernel and userspace around CRTCs always
> having at least one connector.

Yep, but writeback connectors are already different enough to not be
considered as regular connectors, so userspace programs will have to
handle them differently anyway (pass a framebuffer and pixel format to
it before adding them to the display pipeline).

Anyway, I see this approach has already been suggested in [1], and you
all agreed that the writeback feature should be exposed as a connector,
so I'll just stop here :-).

Thanks for taking the time to explain the rationale behind this
decision.

> 
> On the other hand, a writeback connector gains a few extra properties
> over a normal connector, but most stuff stays the same. The pipeline
> setup looks the same as normal to userspace, you don't need a CRTC to
> be active with no connectors, output cloning is the same etc.
> 
> Thanks,
> -Brian
> 
> [1] https://lists.freedesktop.org/archives/dri-devel/2016-July/113329.html
> 

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


#1626080

FromBrian Starkey <brian.starkey@arm.com>
Date2017-04-19 15:00 +0200
Message-ID<txXnc-3yQ-45@gated-at.bofh.it>
In reply to#1626037
On Wed, Apr 19, 2017 at 01:34:34PM +0200, Boris Brezillon wrote:
>On Wed, 19 Apr 2017 10:51:23 +0100
>Brian Starkey <brian.starkey@arm.com> wrote:

[snip]

>> Could you expand a bit on how you think planes fit better?
>
>Just had the impression that the writeback feature was conceptually
>closer to a plane object (which is attached buffers and expose ways to
>specify which portion of the buffer should be used, provides way to
>atomically switch 2 buffers, ...).

Yeah sort-of, except that SRC_X/Y/W/H doesn't mean the same for an
"output" plane as an "input" plane (and CRTC_X/Y/W/H similarly,
probably other properties too).

In atomic land, the swapping of buffers is really just the swapping of
object IDs via properties - I don't think planes actually have
anything special in terms of buffer handling, except for all the
legacy state handling cruft.

>
>> It is
>> something we've previously talked about internally, but so far I'm not
>> convinced :-)
>
>Okay, as I said, I don't know all the history, hence my questions ;-).
>

I think that history was here in our office rather than on the list
anyway.

>>
>> >By doing that, we would also get rid of these fake connector/encoder
>> >objects as well as the fake modes we are returning in
>> >connector->get_modes().
>>
>> What makes the connector/encoder fake? They represent a real piece of
>> hardware just the same as a drm_plane would.
>
>Well, that's probably subject to interpretation, but I don't consider
>these writeback encoders/connectors as real encoders/connectors. They
>are definitely real HW blocks, but not what we usually consider as an
>encoder/connector.
>

This is true

>>
>> I don't mind dropping the mode list and letting userspace just make
>> up whatever timing it wants - it'd need to do the same if writeback
>> was a plane - but in some respects giving it a list of modes the same
>> way we normally do seems nicer for userspace.
>>
>> >
>> >As far as I can tell, the VC4 and Atmel HLCDC IP should fit pretty well
>> >in this model, not sure about the mali-dp though.
>> >
>> >Brian, did you consider this approach, and if you did, can you detail
>> >why you decided to expose this feature as a connector?
>> >
>> >Daniel (or anyone else), please step in if you think this is a stupid
>> >idea :-).
>>
>> Ville originally suggested using a connector, which Eric followed up
>> by saying that's what he was thinking of for VC4 writeback too[1].
>
>Thanks for the pointer.
>
>> That was my initial reason for focussing on a connector-based
>> approach.
>>
>> I prefer connector over plane conceptually because it keeps with the
>> established data flow: planes are sources, connectors are sinks.
>
>Okay, it's a valid point.
>
>>
>> In some respects the plane _object_ looks like it would fit - it has a
>> pixel format list and an FB_ID. But everything else would be acting
>> the exact opposite to a normal plane, and I think there's a bunch of
>> baked-in assumptions in the kernel and userspace around CRTCs always
>> having at least one connector.
>
>Yep, but writeback connectors are already different enough to not be
>considered as regular connectors, so userspace programs will have to
>handle them differently anyway (pass a framebuffer and pixel format to
>it before adding them to the display pipeline).
>
>Anyway, I see this approach has already been suggested in [1], and you
>all agreed that the writeback feature should be exposed as a connector,
>so I'll just stop here :-).
>
>Thanks for taking the time to explain the rationale behind this
>decision.
>

No problem, now is the right time to be discussing the decision before
we merge something wrong.

Are you happy enough with the connector approach then? Any concerns
with going ahead with it?

Cheers,
-Brian

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web