[PATCH 1/4] drm/mipi-dbi: Support command mode panel drivers

Sam Ravnborg sam at ravnborg.org
Sun Aug 11 14:16:59 UTC 2019


Hi Noralf.

I really like how this allows us to have a single file for all
the uses of a driver IC.
And this patch-set is much easier to grasp than the first RFC.

General things:

- The current design have a tight connection between the display
  controller and the panel. Will this hurt in the long run?
  In other words, should we try to add a panel_bridge in-between?
  For now I think this would just make something simple more
  complicated.
  So this note was to say - no I think we should not use panel_bridge.

- drm_panel has proper support for modes.
  This is today duplicated in mipi_dbi.
  Could we make it so that when a panel is used then the panel
  has the mode info - as we then use the panel more in the way we do
  in other cases?
  As it is now the mode is specified in mipi_dbi_dev_init()
  The drm_connector would then, if a panel is used, ask the panel for
  the mode.
  I did not really think to the end of this, but it seems wrong that
  we introduce drm_panel and then keep modes in mipi_dbi.

- For backlight support please move this to drm_panel.
  I have patches that makes it simple to use backlight with drm_panel,
  and this will then benefit from it.
  The drm_panel backlight supports requires that a backlight
  phandle is specified in the DT node of the panel.

Some more specific comments in the following.

	Sam

On Thu, Aug 01, 2019 at 03:52:46PM +0200, Noralf Trønnes wrote:
> This adds a function that registers a DRM driver for use with MIPI DBI
> panels in command mode. That is, framebuffer upload over DBI.
> 
> Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
> ---
>  drivers/gpu/drm/drm_mipi_dbi.c | 92 ++++++++++++++++++++++++++++++++++
>  include/drm/drm_mipi_dbi.h     | 34 +++++++++++++
>  2 files changed, 126 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
> index 1961f713aaab..797a20e3a017 100644
> --- a/drivers/gpu/drm/drm_mipi_dbi.c
> +++ b/drivers/gpu/drm/drm_mipi_dbi.c
> @@ -17,11 +17,13 @@
>  #include <drm/drm_damage_helper.h>
>  #include <drm/drm_drv.h>
>  #include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_fb_helper.h>
>  #include <drm/drm_format_helper.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_mipi_dbi.h>
>  #include <drm/drm_modes.h>
> +#include <drm/drm_panel.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_rect.h>
>  #include <drm/drm_vblank.h>
> @@ -597,6 +599,96 @@ void mipi_dbi_release(struct drm_device *drm)
>  }
>  EXPORT_SYMBOL(mipi_dbi_release);
>  
> +static void drm_mipi_dbi_panel_pipe_enable(struct drm_simple_display_pipe *pipe,
> +					   struct drm_crtc_state *crtc_state,
> +					   struct drm_plane_state *plane_state)
> +{
> +	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
> +	struct drm_panel *panel = dbidev->panel;
> +	int ret, idx;
> +
> +	if (!drm_dev_enter(pipe->crtc.dev, &idx))
> +		return;
> +
> +	DRM_DEBUG_KMS("\n");
Still usefull?

> +
> +	ret = drm_panel_prepare(panel);
> +	if (ret)
> +		goto out_exit;
> +
> +	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
> +
> +	drm_panel_enable(panel);
> +out_exit:
nit - blank line above label?

> +	drm_dev_exit(idx);
> +}
> +
> +static void drm_mipi_dbi_panel_pipe_disable(struct drm_simple_display_pipe *pipe)
> +{
> +	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
> +	struct drm_panel *panel = dbidev->panel;
> +
> +	if (!dbidev->enabled)
> +		return;
> +
> +	DRM_DEBUG_KMS("\n");
Still usefull?
> +
> +	dbidev->enabled = false;
> +	drm_panel_disable(panel);
> +	drm_panel_unprepare(panel);
> +}
> +
> +static const struct drm_simple_display_pipe_funcs drm_mipi_dbi_pipe_funcs = {
> +	.enable = drm_mipi_dbi_panel_pipe_enable,
> +	.disable = drm_mipi_dbi_panel_pipe_disable,
> +	.update = mipi_dbi_pipe_update,
> +	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
> +};
> +
> +/**
> + * drm_mipi_dbi_panel_register - Register a MIPI DBI DRM driver
> + * @panel: DRM Panel
> + * @dbidev: MIPI DBI device structure to initialize
> + * @mode: Display mode
> + *
> + * This function registeres a DRM driver with @panel attached.
> + *
> + * Returns:
> + * Zero on success, negative error code on failure.
> + */
> +int drm_mipi_dbi_panel_register(struct drm_panel *panel, struct mipi_dbi_dev *dbidev,
> +				struct drm_driver *driver, const struct drm_display_mode *mode,
> +				u32 rotation)
Can we make this use enum drm_panel_orientation - so we can use
of_drm_get_panel_orientation() in the callers?
of_drm_get_panel_orientation() is not merged yet, but we could do so if
this patch-set needs it.

I know that this would require mipi_dbi_dev_init() and all users to be
updated. But it is a simpler interface so worth it.

> +{
> +	struct device *dev = panel->dev;
> +	struct drm_device *drm;
> +	int ret;
> +
> +	dbidev->panel = panel;
> +
> +	drm = &dbidev->drm;
> +	ret = devm_drm_dev_init(dev, drm, driver);
> +	if (ret) {
> +		kfree(dbidev);
> +		return ret;
> +	}
> +
> +	drm_mode_config_init(drm);
> +
> +	ret = mipi_dbi_dev_init(dbidev, &drm_mipi_dbi_pipe_funcs, mode, rotation);
> +
> +	drm_mode_config_reset(drm);
> +
> +	ret = drm_dev_register(drm, 0);
> +	if (ret)
> +		return ret;
> +
> +	drm_fbdev_generic_setup(drm, 16);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_mipi_dbi_panel_register);
> +
>  /**
>   * mipi_dbi_hw_reset - Hardware reset of controller
>   * @dbi: MIPI DBI structure
> diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
> index 67c66f5ee591..f41ee0d31871 100644
> --- a/include/drm/drm_mipi_dbi.h
> +++ b/include/drm/drm_mipi_dbi.h
> @@ -12,6 +12,7 @@
>  #include <drm/drm_device.h>
>  #include <drm/drm_simple_kms_helper.h>
>  
> +struct drm_panel;
>  struct drm_rect;
>  struct spi_device;
>  struct gpio_desc;
> @@ -123,6 +124,11 @@ struct mipi_dbi_dev {
>  	 * @dbi: MIPI DBI interface
>  	 */
>  	struct mipi_dbi dbi;
> +
> +	/**
> +	 * @panel: Attached DRM panel. See drm_mipi_dbi_panel_register().
> +	 */
> +	struct drm_panel *panel;
>  };
>  
>  static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm)
> @@ -140,6 +146,34 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
>  int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev,
>  		      const struct drm_simple_display_pipe_funcs *funcs,
>  		      const struct drm_display_mode *mode, unsigned int rotation);
> +
> +/**
> + * DEFINE_DRM_MIPI_DBI_PANEL_DRIVER - Define a DRM driver structure
> + * @_name: Name
> + * @_desc: Description
> + * @_date: Date
> + *
> + * This macro defines a &drm_driver for MIPI DBI panel drivers.
> + */
> +#define DEFINE_DRM_MIPI_DBI_PANEL_DRIVER(_name, _desc, _date) \
> +	DEFINE_DRM_GEM_CMA_FOPS(_name ## _fops); \
> +	static struct drm_driver _name ## _drm_driver = { \
> +		.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, \
> +		.fops			= & _name ## _fops, \
> +		.release		= mipi_dbi_release, \
> +		DRM_GEM_CMA_VMAP_DRIVER_OPS, \
> +		.debugfs_init		= mipi_dbi_debugfs_init, \
> +		.name			= #_name, \
> +		.desc			= _desc, \
> +		.date			= _date, \
> +		.major			= 1, \
> +		.minor			= 0, \
> +	}
> +
> +int drm_mipi_dbi_panel_register(struct drm_panel *panel, struct mipi_dbi_dev *dbidev,
> +				struct drm_driver *driver, const struct drm_display_mode *mode,
> +				u32 rotation);
> +
>  void mipi_dbi_release(struct drm_device *drm);
>  void mipi_dbi_pipe_update(struct drm_simple_display_pipe *pipe,
>  			  struct drm_plane_state *old_state);
> -- 
> 2.20.1


More information about the dri-devel mailing list