[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