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

Noralf Trønnes noralf at tronnes.org
Thu Aug 1 13:52:46 UTC 2019


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");
+
+	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



More information about the dri-devel mailing list