[PATCH 4/4] drm/panel/ili9341: Support DPI panels

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


Add support for panels that use the DPI interface.
ILI9341 has onboard RAM so the assumption made here is that all such
panels support pixel upload over DBI.

The presence/absense of the Device Tree 'port' node decides which
interface is used for pixel transfer.

Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
---
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 56 ++++++++++++++++----
 1 file changed, 45 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
index f6082fa2a389..7cbfd739c7fd 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_graph.h>
 #include <linux/pm.h>
 #include <linux/property.h>
 #include <linux/regulator/consumer.h>
@@ -53,11 +54,13 @@
 struct ili9341_config {
 	const struct drm_panel_funcs *funcs;
 	const struct drm_display_mode *mode;
+	bool no_dpi;
 };
 
 struct ili9341 {
 	struct mipi_dbi_dev dbidev; /* This must be the first entry */
 	struct drm_panel panel;
+	bool use_dpi;
 	struct regulator *regulator;
 	struct backlight_device *backlight;
 	const struct ili9341_config *conf;
@@ -174,6 +177,7 @@ static const struct drm_display_mode yx240qv29_mode = {
 static const struct ili9341_config yx240qv29_data = {
 	.funcs = &yx240qv29_funcs,
 	.mode = &yx240qv29_mode,
+	.no_dpi = true,
 };
 
 static int mi0283qt_prepare(struct drm_panel *panel)
@@ -291,6 +295,7 @@ static const struct drm_display_mode mi0283qt_mode = {
 static const struct ili9341_config mi0283qt_data = {
 	.funcs = &mi0283qt_drm_funcs,
 	.mode = &mi0283qt_mode,
+	.no_dpi = true,
 };
 
 /* Legacy, DRM driver name is ABI */
@@ -303,6 +308,7 @@ static int ili9341_probe(struct spi_device *spi)
 	const struct spi_device_id *spi_id;
 	struct device *dev = &spi->dev;
 	struct drm_driver *driver;
+	struct device_node *port;
 	struct mipi_dbi *dbi;
 	struct gpio_desc *dc;
 	struct ili9341 *ili;
@@ -357,21 +363,44 @@ static int ili9341_probe(struct spi_device *spi)
 	ili->panel.dev = dev;
 	ili->panel.funcs = ili->conf->funcs;
 
-	if (ili->conf == &mi0283qt_data)
-		driver = &mi0283qt_drm_driver;
-	else
-		driver = &ili9341_drm_driver;
 
-	return drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, driver,
-					   ili->conf->mode, rotation);
+	port = of_get_child_by_name(dev->of_node, "port");
+	if (port) {
+		of_node_put(port);
+		ili->use_dpi = true;
+	}
+
+	if (ili->conf->no_dpi)
+		ili->use_dpi = false;
+
+	if (ili->use_dpi) {
+		ret = drm_panel_add(&ili->panel);
+	} else {
+		if (ili->conf == &mi0283qt_data)
+			driver = &mi0283qt_drm_driver;
+		else
+			driver = &ili9341_drm_driver;
+
+		ret = drm_mipi_dbi_panel_register(&ili->panel, &ili->dbidev, driver,
+						  ili->conf->mode, rotation);
+	}
+
+	return ret;
 }
 
 static int ili9341_remove(struct spi_device *spi)
 {
 	struct ili9341 *ili = spi_get_drvdata(spi);
 
-	drm_dev_unplug(&ili->dbidev.drm);
-	drm_atomic_helper_shutdown(&ili->dbidev.drm);
+	if (ili->use_dpi) {
+		drm_panel_remove(&ili->panel);
+		drm_panel_disable(&ili->panel);
+		drm_panel_unprepare(&ili->panel);
+		kfree(ili);
+	} else {
+		drm_dev_unplug(&ili->dbidev.drm);
+		drm_atomic_helper_shutdown(&ili->dbidev.drm);
+	}
 
 	return 0;
 }
@@ -380,21 +409,26 @@ static void ili9341_shutdown(struct spi_device *spi)
 {
 	struct ili9341 *ili = spi_get_drvdata(spi);
 
-	drm_atomic_helper_shutdown(&ili->dbidev.drm);
+	if (!ili->use_dpi)
+		drm_atomic_helper_shutdown(&ili->dbidev.drm);
 }
 
 static int __maybe_unused ili9341_pm_suspend(struct device *dev)
 {
 	struct ili9341 *ili = dev_get_drvdata(dev);
 
-	return drm_mode_config_helper_suspend(&ili->dbidev.drm);
+	if (!ili->use_dpi)
+		return drm_mode_config_helper_suspend(&ili->dbidev.drm);
+
+	return 0;
 }
 
 static int __maybe_unused ili9341_pm_resume(struct device *dev)
 {
 	struct ili9341 *ili = dev_get_drvdata(dev);
 
-	drm_mode_config_helper_resume(&ili->dbidev.drm);
+	if (!ili->use_dpi)
+		drm_mode_config_helper_resume(&ili->dbidev.drm);
 
 	return 0;
 }
-- 
2.20.1



More information about the dri-devel mailing list