[RFC 3/4] drm/mipi-dbi: Support command mode panel drivers
Noralf Trønnes
noralf at tronnes.org
Mon Jul 29 19:55:25 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 | 110 +++++++++++++++++++++++++++++++++
include/drm/drm_mipi_dbi.h | 8 +++
2 files changed, 118 insertions(+)
diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 1961f713aaab..ef6b843eaf31 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -10,6 +10,7 @@
#include <linux/dma-buf.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
@@ -17,11 +18,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 +600,113 @@ 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,
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(drm_mipi_dbi_fops);
+
+static struct drm_driver drm_mipi_dbi_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+ .fops = &drm_mipi_dbi_fops,
+ .release = mipi_dbi_release,
+ DRM_GEM_CMA_VMAP_DRIVER_OPS,
+ .debugfs_init = mipi_dbi_debugfs_init,
+ .name = "drm_mipi_dbi",
+ .desc = "DRM MIPI DBI",
+ .date = "20190729",
+ .major = 1,
+ .minor = 0,
+};
+
+/**
+ * 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,
+ const struct drm_display_mode *mode)
+{
+ struct device *dev = panel->dev;
+ struct drm_device *drm;
+ u32 rotation = 0;
+ int ret;
+
+ dbidev->panel = panel;
+
+ drm = &dbidev->drm;
+ ret = devm_drm_dev_init(dev, drm, &drm_mipi_dbi_driver);
+ if (ret) {
+ kfree(dbidev);
+ return ret;
+ }
+
+ drm_mode_config_init(drm);
+
+ device_property_read_u32(dev, "rotation", &rotation);
+
+ 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..e5047208ffb8 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,8 @@ 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);
+int drm_mipi_dbi_panel_register(struct drm_panel *panel, struct mipi_dbi_dev *dbidev,
+ const struct drm_display_mode *mode);
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