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@xxxxxxxxxxx> --- 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"); + + 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: + 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"); + + 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) +{ + 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel