All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: thomas.petazzoni@free-electrons.com, dri-devel@lists.freedesktop.org
Subject: Re: [RFC v2 3/8] drm: Add helper for simple kms drivers
Date: Mon, 2 May 2016 17:55:15 +0200	[thread overview]
Message-ID: <57277863.5020100@tronnes.org> (raw)
In-Reply-To: <20160413110553.GY2510@phenom.ffwll.local>


Den 13.04.2016 13:05, skrev Daniel Vetter:
> On Fri, Apr 08, 2016 at 07:05:05PM +0200, Noralf Trønnes wrote:
>> Provides helper functions for drivers that have a simple display
>> pipeline. Plane, crtc and encoder are collapsed into one entity.
>>
>> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

[...]

>> +static void drm_simple_kms_encoder_disable(struct drm_encoder *encoder)
>> +{
>> +}
>> +
>> +static void drm_simple_kms_encoder_enable(struct drm_encoder *encoder)
>> +{
>> +}
>> +
>> +static int drm_simple_kms_encoder_atomic_check(struct drm_encoder *encoder,
>> +					struct drm_crtc_state *crtc_state,
>> +					struct drm_connector_state *conn_state)
>> +{
>> +	return 0;
>> +}
> Above dummy functions shouldn't be necessary.

I could remove .atomic_check, but not .disable and .enable which gave me
NULL pointer errors. I need .enable or .commit, and .disable or .dpms.

Gist:

void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
                                               struct drm_atomic_state 
*old_state)
{
         for_each_connector_in_state(old_state, connector, 
old_conn_state, i) {
                 const struct drm_encoder_helper_funcs *funcs;

                 funcs = encoder->helper_private;

                 if (funcs->enable)
                         funcs->enable(encoder);
                 else
                         funcs->commit(encoder);

static void
disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
{
         for_each_connector_in_state(old_state, connector, 
old_conn_state, i) {
                 const struct drm_encoder_helper_funcs *funcs;

                 funcs = encoder->helper_private;

                 if (connector->state->crtc && funcs->prepare)
                         funcs->prepare(encoder);
                 else if (funcs->disable)
                         funcs->disable(encoder);
                 else
                         funcs->dpms(encoder, DRM_MODE_DPMS_OFF);

>
>> +
>> +static const struct drm_encoder_helper_funcs drm_simple_kms_encoder_helper_funcs = {
>> +	.disable = drm_simple_kms_encoder_disable,
>> +	.enable = drm_simple_kms_encoder_enable,
>> +	.atomic_check = drm_simple_kms_encoder_atomic_check,
>> +};
>> +
>> +static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = {
>> +	.destroy = drm_encoder_cleanup,
>> +};
>> +
>> +static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
>> +{
>> +	struct drm_simple_display_pipe *pipe;
>> +
>> +	pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
>> +	if (!pipe->funcs || !pipe->funcs->enable)
>> +		return;
>> +
>> +	pipe->funcs->enable(pipe, crtc->state);
>> +}
>> +
>> +static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
>> +{
>> +	struct drm_simple_display_pipe *pipe;
>> +
>> +	pipe = container_of(crtc, struct drm_simple_display_pipe, crtc);
>> +	if (!pipe->funcs || !pipe->funcs->disable)
>> +		return;
>> +
>> +	pipe->funcs->disable(pipe);
>> +}
>> +
>> +static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
>> +	.disable = drm_simple_kms_crtc_disable,
>> +	.enable = drm_simple_kms_crtc_enable,
>> +};
>> +
>> +static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
>> +	.reset = drm_atomic_helper_crtc_reset,
>> +	.destroy = drm_crtc_cleanup,
>> +	.set_config = drm_atomic_helper_set_config,
>> +	.page_flip = drm_atomic_helper_page_flip,
>> +	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
>> +	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
>> +};
>> +
>> +static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane,
>> +					struct drm_plane_state *old_state)
>> +{
>> +	struct drm_simple_display_pipe *pipe;
>> +
>> +	pipe = container_of(plane, struct drm_simple_display_pipe, plane);
>> +	if (!pipe->funcs || !pipe->funcs->plane_update)
>> +		return;
>> +
>> +	pipe->funcs->plane_update(pipe, old_state);
>> +}
>> +
>> +static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = {
>> +	.atomic_update = drm_simple_kms_plane_atomic_update,
>> +};
>> +
>> +static const struct drm_plane_funcs drm_simple_kms_plane_funcs = {
>> +	.update_plane		= drm_atomic_helper_update_plane,
>> +	.disable_plane		= drm_atomic_helper_disable_plane,
>> +	.destroy		= drm_plane_cleanup,
>> +	.reset			= drm_atomic_helper_plane_reset,
>> +	.atomic_duplicate_state	= drm_atomic_helper_plane_duplicate_state,
>> +	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
>> +};
>> +
>> +/**
>> + * drm_simple_display_pipe_init - Initialize a simple display pipe
>> + * @dev: DRM device
>> + * @pipe: simple display pipe object to initialize
>> + * @funcs: callbacks for the display pipe
>> + * @formats: array of supported formats (%DRM_FORMAT_*)
>> + * @format_count: number of elements in @formats
>> + * @connector: connector to attach and register
>> + *
>> + * Sets up a display pipe which consist of a really simple plane-crtc-encoder
>> + * pipe coupled with the provided connector.
>> + *
>> + * Returns:
>> + * Zero on success, error code on failure.
>> + */
>> +int drm_simple_display_pipe_init(struct drm_device *dev,
>> +				 struct drm_simple_display_pipe *pipe,
>> +				 struct drm_simple_display_pipe_funcs *funcs,
>> +				 const uint32_t *formats, unsigned int format_count,
>> +				 struct drm_connector *connector)
>> +{
>> +	struct drm_encoder *encoder = &pipe->encoder;
>> +	struct drm_plane *plane = &pipe->plane;
>> +	struct drm_crtc *crtc = &pipe->crtc;
>> +	int ret;
>> +
>> +	pipe->funcs = funcs;
>> +
>> +	drm_plane_helper_add(plane, &drm_simple_kms_plane_helper_funcs);
>> +	ret = drm_universal_plane_init(dev, plane, 0, &drm_simple_kms_plane_funcs,
>> +				       formats, format_count,
>> +				       DRM_PLANE_TYPE_PRIMARY, NULL);
>> +	if (ret)
>> +		return ret;
>> +
>> +	drm_crtc_helper_add(crtc, &drm_simple_kms_crtc_helper_funcs);
>> +	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
>> +					&drm_simple_kms_crtc_funcs, NULL);
>> +	if (ret)
>> +		return ret;
>> +
>> +	encoder->possible_crtcs = 1 << drm_crtc_index(crtc);
>> +	drm_encoder_helper_add(encoder, &drm_simple_kms_encoder_helper_funcs);
>> +	ret = drm_encoder_init(dev, encoder, &drm_simple_kms_encoder_funcs,
>> +			       DRM_MODE_ENCODER_NONE, NULL);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = drm_mode_connector_attach_encoder(connector, encoder);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return drm_connector_register(connector);
>> +}
>> +EXPORT_SYMBOL(drm_simple_display_pipe_init);
>> +
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h
>> new file mode 100644
>> index 0000000..0f7461b
>> --- /dev/null
>> +++ b/include/drm/drm_simple_kms_helper.h
>> @@ -0,0 +1,44 @@
>> +/*
>> + * Copyright (C) 2016 Noralf Trønnes
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + */
>> +
>> +#ifndef __LINUX_DRM_SIMPLE_KMS_HELPER_H
>> +#define __LINUX_DRM_SIMPLE_KMS_HELPER_H
>> +
>> +struct drm_simple_display_pipe;
>> +
>> +struct drm_simple_display_pipe_funcs {
>> +	void (*enable)(struct drm_simple_display_pipe *pipe,
>> +		       struct drm_crtc_state *crtc_state);
>> +	void (*disable)(struct drm_simple_display_pipe *pipe);
>> +	void (*plane_update)(struct drm_simple_display_pipe *pipe,
>> +			     struct drm_plane_state *plane_state);
> On 2nd thought maybe we want an atomic_check in here too, with same
> parameters *pipe, *crtc_state and *plane_state (so that it's useful for
> both plane-only updates and modeset changes).

I could do this for the plane:

struct drm_simple_display_pipe_funcs {
      void (*plane_check)(struct drm_simple_display_pipe *pipe,
                          struct drm_plane_state *plane_state);
}

static void drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
                                         struct drm_plane_state *state)
{
         struct drm_simple_display_pipe *pipe;

         pipe = container_of(plane, struct drm_simple_display_pipe, plane);
         if (!pipe->funcs || !pipe->funcs->plane_check)
                 return;

         pipe->funcs->plane_check(pipe, state);
}

static const struct drm_plane_helper_funcs 
drm_simple_kms_plane_helper_funcs = {
         .atomic_check = drm_simple_kms_plane_atomic_check,
};

But how should I do crtc_state ?

Noralf.

>> +};
>> +
>> +struct drm_simple_display_pipe {
>> +	struct drm_crtc crtc;
>> +	struct drm_plane plane;
>> +	struct drm_encoder encoder;
>> +	struct drm_connector *connector;
>> +
>> +	struct drm_simple_display_pipe_funcs *funcs;
>> +};
>> +
>> +int drm_simple_display_pipe_init(struct drm_device *dev,
>> +				 struct drm_simple_display_pipe *pipe,
>> +				 struct drm_simple_display_pipe_funcs *funcs,
>> +				 const uint32_t *formats, unsigned int format_count,
>> +				 struct drm_connector *connector);
>> +struct drm_connector *
>> +drm_simple_kms_panel_connector_create(struct drm_device *dev,
>> +				      struct drm_panel *panel,
>> +				      int connector_type);
>> +
>> +
>> +
>> +#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
>> -- 
>> 2.2.2
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2016-05-02 15:55 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-08 17:05 [RFC v2 0/8] drm: Add support for tiny LCD displays Noralf Trønnes
2016-04-08 17:05 ` [RFC v2 1/8] drm/fb-helper: Add fb_deferred_io support Noralf Trønnes
2016-04-13 10:57   ` Daniel Vetter
2016-04-13 11:09   ` Daniel Vetter
2016-04-18 15:15     ` Noralf Trønnes
2016-04-20 11:12       ` Daniel Vetter
2016-04-20 15:22         ` Noralf Trønnes
2016-04-20 22:29       ` Dave Airlie
2016-04-21  6:53         ` Daniel Vetter
2016-04-08 17:05 ` [RFC v2 2/8] drm/fb-cma-helper: " Noralf Trønnes
2016-04-13 11:19   ` Daniel Vetter
2016-04-08 17:05 ` [RFC v2 3/8] drm: Add helper for simple kms drivers Noralf Trønnes
2016-04-13 11:05   ` Daniel Vetter
2016-05-02 15:55     ` Noralf Trønnes [this message]
2016-05-02 20:20       ` Daniel Vetter
2016-04-08 17:05 ` [RFC v2 4/8] drm: Add DRM support for tiny LCD displays Noralf Trønnes
2016-04-08 17:05 ` [RFC v2 5/8] drm/tinydrm: Add lcd register abstraction Noralf Trønnes
2016-04-08 17:05 ` [RFC v2 6/8] drm/tinydrm/lcdreg: Add SPI support Noralf Trønnes
2016-04-08 17:05 ` [RFC v2 7/8] drm/tinydrm: Add mipi-dbi support Noralf Trønnes
2016-04-08 17:05 ` [RFC v2 8/8] drm/tinydrm: Add support for several Adafruit TFT displays Noralf Trønnes
2016-04-13 11:11 ` [RFC v2 0/8] drm: Add support for tiny LCD displays Daniel Vetter

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=57277863.5020100@tronnes.org \
    --to=noralf@tronnes.org \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=thomas.petazzoni@free-electrons.com \
    /path/to/YOUR_REPLY

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

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