Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1699344 > unrolled thread

[PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display

Started byDavid Lechner <david@lechnology.com>
First post2017-07-29 21:20 +0200
Last post2017-07-30 20:30 +0200
Articles 20 on this page of 28 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
    [PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
      Re: [PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-07-30 20:30 +0200
    [PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
      Re: [PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-07-30 20:30 +0200
    [PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
      Re: [PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel David Lechner <david@lechnology.com> - 2017-07-29 21:40 +0200
    [PATCH 6/6] ARM: dts: da850-lego-ev3: Add node for LCD display David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
    [PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers David Lechner <david@lechnology.com> - 2017-07-29 21:20 +0200
      Re: [PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-07-30 20:20 +0200
    Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-07-29 21:50 +0200
      Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-07-30 19:20 +0200
        Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-01 19:00 +0200
          Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-08-01 20:10 +0200
            Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-02 00:30 +0200
              Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-08-02 10:10 +0200
                Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-02 18:10 +0200
                  Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Daniel Vetter <daniel@ffwll.ch> - 2017-08-03 12:10 +0200
              Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-08-03 16:10 +0200
                Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-03 17:20 +0200
                  Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-08-03 19:10 +0200
                    Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-08-03 19:20 +0200
                      Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-08-03 22:20 +0200
                        Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-04 03:10 +0200
                          Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display David Lechner <david@lechnology.com> - 2017-08-04 03:20 +0200
    Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Noralf Trønnes <noralf@tronnes.org> - 2017-07-30 19:20 +0200
    Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-07-30 20:30 +0200
      Re: [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-07-30 20:30 +0200

Page 1 of 2  [1] 2  Next page →


#1699344 — [PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 0/6] Support for LEGO MINDSTORMS EV3 LCD display
Message-ID<u8Frj-6FJ-3@gated-at.bofh.it>
The goal of this series is to get the built-in LCD of the LEGO MINDSTORMS EV3
working. But, most of the content here is building up the infrastructure to do
that.

The controller used in the EV3 uses MIPI commands, but it uses a different
memory layout. The current tinydrm stuff is hard-coded for RGB565, so most
of the patches are adding support for other memory layouts.

I've also made the one existing tinydrm driver generic so that it can work for
any MIPI display rather than copying a bunch of boiler-plate code for each
panel and/or controller.

Once all of this is done, it is really easy to add a new panel. :-)

David Lechner (6):
  drm/tinydrm: Add parameter for MIPI DCS pixel format
  drm/tinydrm: add helpers for ST7586 controllers
  drm/tinydrm: rename mi028qt module to mipi-panel
  drm/tinydrm: mipi-panel: refactor to use driver id
  drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD
  ARM: dts: da850-lego-ev3: Add node for LCD display

 .../devicetree/bindings/display/mipi-panel.txt     |  27 ++
 .../bindings/display/multi-inno,mi0283qt.txt       |  27 --
 MAINTAINERS                                        |   6 +-
 arch/arm/boot/dts/da850-lego-ev3.dts               |  24 ++
 drivers/gpu/drm/tinydrm/Kconfig                    |  13 +-
 drivers/gpu/drm/tinydrm/Makefile                   |   2 +-
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c     | 148 ++++++++
 drivers/gpu/drm/tinydrm/mi0283qt.c                 | 282 ---------------
 drivers/gpu/drm/tinydrm/mipi-dbi.c                 | 117 ++++--
 drivers/gpu/drm/tinydrm/mipi-panel.c               | 395 +++++++++++++++++++++
 include/drm/tinydrm/mipi-dbi.h                     |   9 +-
 include/drm/tinydrm/st7586.h                       |  34 ++
 include/drm/tinydrm/tinydrm-helpers.h              |   6 +
 include/video/mipi_display.h                       |  16 +-
 14 files changed, 759 insertions(+), 347 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mipi-panel.txt
 delete mode 100644 Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
 delete mode 100644 drivers/gpu/drm/tinydrm/mi0283qt.c
 create mode 100644 drivers/gpu/drm/tinydrm/mipi-panel.c
 create mode 100644 include/drm/tinydrm/st7586.h

-- 
2.7.4

[toc] | [next] | [standalone]


#1699345 — [PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id
Message-ID<u8Frj-6FJ-5@gated-at.bofh.it>
In reply to#1699344
This refactors the mipi-panel module to use the driver id for panel-specific
data. This is in preparation for adding additional panels.

Signed-off-by: David Lechner <david@lechnology.com>
---
 drivers/gpu/drm/tinydrm/mipi-panel.c | 40 ++++++++++++++++++++++++++++--------
 include/drm/tinydrm/mipi-dbi.h       |  2 ++
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/tinydrm/mipi-panel.c b/drivers/gpu/drm/tinydrm/mipi-panel.c
index 64344f0..8aa1d8e 100644
--- a/drivers/gpu/drm/tinydrm/mipi-panel.c
+++ b/drivers/gpu/drm/tinydrm/mipi-panel.c
@@ -21,7 +21,18 @@
 #include <linux/spi/spi.h>
 #include <video/mipi_display.h>
 
-static int mipi_panel_init(struct mipi_dbi *mipi)
+enum mipi_panel_type {
+	MIPI_PANEL_TYPE_UNKNOWN,
+	MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT,
+};
+
+struct mipi_panel_info {
+	int (*init)(struct mipi_dbi *mipi);
+	const struct drm_display_mode mode;
+	enum mipi_dcs_pixel_format pixel_fmt;
+};
+
+static int mipi_panel_init_ili9341(struct mipi_dbi *mipi)
 {
 	struct tinydrm_device *tdev = &mipi->tinydrm;
 	struct device *dev = tdev->drm->dev;
@@ -129,8 +140,12 @@ static const struct drm_simple_display_pipe_funcs mipi_panel_pipe_funcs = {
 	.prepare_fb = tinydrm_display_pipe_prepare_fb,
 };
 
-static const struct drm_display_mode mipi_panel_mode = {
-	TINYDRM_MODE(320, 240, 58, 43),
+static const struct mipi_panel_info mipi_panel_infos[] = {
+	[MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT] = {
+		.init		= mipi_panel_init_ili9341,
+		.mode		= { TINYDRM_MODE(320, 240, 58, 43) },
+		.pixel_fmt	= MIPI_DCS_PIXEL_FMT_16BIT,
+	},
 };
 
 DEFINE_DRM_GEM_CMA_FOPS(mipi_panel_fops);
@@ -156,13 +171,15 @@ static const struct of_device_id mipi_panel_of_match[] = {
 MODULE_DEVICE_TABLE(of, mipi_panel_of_match);
 
 static const struct spi_device_id mipi_panel_id[] = {
-	{ "mi0283qt", 0 },
+	{ "mi0283qt", MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT },
 	{ },
 };
 MODULE_DEVICE_TABLE(spi, mipi_panel_id);
 
 static int mipi_panel_probe(struct spi_device *spi)
 {
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	enum mipi_panel_type type = id->driver_data;
 	struct device *dev = &spi->dev;
 	struct tinydrm_device *tdev;
 	struct mipi_dbi *mipi;
@@ -170,10 +187,17 @@ static int mipi_panel_probe(struct spi_device *spi)
 	u32 rotation = 0;
 	int ret;
 
+	if (type == MIPI_PANEL_TYPE_UNKNOWN) {
+		dev_err(dev, "Unknown panel type\n");
+		return -EINVAL;
+	}
+
 	mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
 	if (!mipi)
 		return -ENOMEM;
 
+	mipi->init = mipi_panel_infos[type].init;
+
 	mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(mipi->reset)) {
 		dev_err(dev, "Failed to get gpio 'reset'\n");
@@ -197,12 +221,12 @@ static int mipi_panel_probe(struct spi_device *spi)
 	device_property_read_u32(dev, "rotation", &rotation);
 
 	ret = mipi_dbi_spi_init(spi, mipi, dc, &mipi_panel_pipe_funcs,
-				&mipi_panel_driver, &mipi_panel_mode,
-				MIPI_DCS_PIXEL_FMT_16BIT, rotation);
+				&mipi_panel_driver, &mipi_panel_infos[type].mode,
+				mipi_panel_infos[type].pixel_fmt, rotation);
 	if (ret)
 		return ret;
 
-	ret = mipi_panel_init(mipi);
+	ret = mipi->init(mipi);
 	if (ret)
 		return ret;
 
@@ -255,7 +279,7 @@ static int __maybe_unused mipi_panel_pm_resume(struct device *dev)
 	struct mipi_dbi *mipi = dev_get_drvdata(dev);
 	int ret;
 
-	ret = mipi_panel_init(mipi);
+	ret = mipi->init(mipi);
 	if (ret)
 		return ret;
 
diff --git a/include/drm/tinydrm/mipi-dbi.h b/include/drm/tinydrm/mipi-dbi.h
index dda100c..f7ae5ae 100644
--- a/include/drm/tinydrm/mipi-dbi.h
+++ b/include/drm/tinydrm/mipi-dbi.h
@@ -25,6 +25,7 @@ struct regulator;
  * @spi: SPI device
  * @enabled: Pipeline is enabled
  * @cmdlock: Command lock
+ * @init: Panel specific callback executing initialization command sequence.
  * @command: Bus specific callback executing commands.
  * @read_commands: Array of read commands terminated by a zero entry.
  *                 Reading is disabled if this is NULL.
@@ -44,6 +45,7 @@ struct mipi_dbi {
 	struct spi_device *spi;
 	bool enabled;
 	struct mutex cmdlock;
+	int (*init)(struct mipi_dbi *mipi);
 	int (*command)(struct mipi_dbi *mipi, u8 cmd, u8 *param, size_t num);
 	const u8 *read_commands;
 	struct gpio_desc *dc;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699598 — Re: [PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-07-30 20:30 +0200
SubjectRe: [PATCH 4/6] drm/tinydrm: mipi-panel: refactor to use driver id
Message-ID<u918u-3Rn-11@gated-at.bofh.it>
In reply to#1699345
On Sat, Jul 29, 2017 at 10:17 PM, David Lechner <david@lechnology.com> wrote:
> This refactors the mipi-panel module to use the driver id for panel-specific
> data. This is in preparation for adding additional panels.
>

Wouldn't be better to split glue driver from what looks like more
generic in the first place? Then you will not need to spread some
stuff
over generic files.

Are we going to disrupt genericy of the framework already with second driver?!

-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1699346 — [PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD
Message-ID<u8Frk-6FJ-15@gated-at.bofh.it>
In reply to#1699344
LEGO MINDSTORMS EV3 has an LCD with a ST7586 controller. This adds a new
module for the ST7586 controller with parameters for the EV3 LCD dispay.

Signed-off-by: David Lechner <david@lechnology.com>
---
 .../devicetree/bindings/display/mipi-panel.txt     |  2 +-
 drivers/gpu/drm/tinydrm/Kconfig                    |  1 +
 drivers/gpu/drm/tinydrm/mipi-panel.c               | 87 ++++++++++++++++++++++
 include/drm/tinydrm/st7586.h                       | 34 +++++++++
 4 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 include/drm/tinydrm/st7586.h

diff --git a/Documentation/devicetree/bindings/display/mipi-panel.txt b/Documentation/devicetree/bindings/display/mipi-panel.txt
index 01d6ea9..ba8c8ab 100644
--- a/Documentation/devicetree/bindings/display/mipi-panel.txt
+++ b/Documentation/devicetree/bindings/display/mipi-panel.txt
@@ -1,7 +1,7 @@
 MIPI DBI compatible display panel
 
 Required properties:
-- compatible:	"multi-inno,mi0283qt".
+- compatible:	one of "lego,ev3-lcd", "multi-inno,mi0283qt".
 
 The node for this driver must be a child node of a SPI controller, hence
 all mandatory properties described in ../spi/spi-bus.txt must be specified.
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 394519b..6e90bb5 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -20,6 +20,7 @@ config TINYDRM_MIPI_PANEL
 	  DRM driver for the MIPI DBI compatible display panels.
 	  
 	  Supported panels include:
+	  * LEGO MINDSTORMS EV3
 	  * Multi-Inno MI0283QT
 
 	  If M is selected the module will be called mipi-panel.
diff --git a/drivers/gpu/drm/tinydrm/mipi-panel.c b/drivers/gpu/drm/tinydrm/mipi-panel.c
index 8aa1d8e..e3d5678 100644
--- a/drivers/gpu/drm/tinydrm/mipi-panel.c
+++ b/drivers/gpu/drm/tinydrm/mipi-panel.c
@@ -12,6 +12,7 @@
 
 #include <drm/tinydrm/ili9341.h>
 #include <drm/tinydrm/mipi-dbi.h>
+#include <drm/tinydrm/st7586.h>
 #include <drm/tinydrm/tinydrm-helpers.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
@@ -23,6 +24,7 @@
 
 enum mipi_panel_type {
 	MIPI_PANEL_TYPE_UNKNOWN,
+	MIPI_PANEL_TYPE_LEGO_EV3_LCD,
 	MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT,
 };
 
@@ -125,6 +127,84 @@ static int mipi_panel_init_ili9341(struct mipi_dbi *mipi)
 	return 0;
 }
 
+static int mipi_panel_init_st7586(struct mipi_dbi *mipi)
+{
+	struct tinydrm_device *tdev = &mipi->tinydrm;
+	struct device *dev = tdev->drm->dev;
+	u8 addr_mode;
+	int ret;
+
+	DRM_DEBUG_KMS("\n");
+
+	ret = regulator_enable(mipi->regulator);
+	if (ret) {
+		dev_err(dev, "Failed to enable regulator %d\n", ret);
+		return ret;
+	}
+
+	/* Avoid flicker by skipping setup if the bootloader has done it */
+	if (mipi_dbi_display_is_on(mipi))
+		return 0;
+
+	mipi_dbi_hw_reset(mipi);
+	ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
+	if (ret) {
+		dev_err(dev, "Error sending command %d\n", ret);
+		regulator_disable(mipi->regulator);
+		return ret;
+	}
+
+	mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
+
+	msleep(10);
+
+	mipi_dbi_command(mipi, ST7586_OTP_READ);
+
+	msleep(20);
+
+	mipi_dbi_command(mipi, ST7586_OTP_CTRL_OUT);
+	mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+
+	msleep(50);
+
+	mipi_dbi_command(mipi, ST7586_SET_VOP_OFFSET, 0x00);
+	mipi_dbi_command(mipi, ST7586_SET_VOP, 0xe3, 0x00);
+	mipi_dbi_command(mipi, ST7586_SET_BIAS_SYSTEM, 0x02);
+	mipi_dbi_command(mipi, ST7586_SET_BOOST_LEVEL, 0x04);
+	mipi_dbi_command(mipi, ST7586_ENABLE_ANALOG, 0x1d);
+	mipi_dbi_command(mipi, ST7586_SET_NLINE_INV, 0x00);
+	mipi_dbi_command(mipi, ST7586_DISP_MODE_GRAY);
+	mipi_dbi_command(mipi, ST7586_ENABLE_DDRAM, 0x02);
+
+	switch (mipi->rotation) {
+	default:
+		addr_mode = 0x00;
+		break;
+	case 90:
+		addr_mode = ST7586_DISP_CTRL_MY;
+		break;
+	case 180:
+		addr_mode = ST7586_DISP_CTRL_MX | ST7586_DISP_CTRL_MY;
+		break;
+	case 270:
+		addr_mode = ST7586_DISP_CTRL_MX;
+		break;
+	}
+	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+
+	mipi_dbi_command(mipi, ST7586_SET_DISP_DUTY, 0x7f);
+	mipi_dbi_command(mipi, ST7586_SET_PART_DISP, 0xa0);
+	mipi_dbi_command(mipi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, 0x00, 0x00, 0x77);
+	mipi_dbi_command(mipi, MIPI_DCS_EXIT_INVERT_MODE);
+
+	msleep(100);
+
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
+
+	return 0;
+}
+
 static void mipi_panel_fini(void *data)
 {
 	struct mipi_dbi *mipi = data;
@@ -141,6 +221,11 @@ static const struct drm_simple_display_pipe_funcs mipi_panel_pipe_funcs = {
 };
 
 static const struct mipi_panel_info mipi_panel_infos[] = {
+	[MIPI_PANEL_TYPE_LEGO_EV3_LCD] = {
+		.init		= mipi_panel_init_st7586,
+		.mode		= { TINYDRM_MODE(178, 128, 37, 27) },
+		.pixel_fmt	= MIPI_DCS_PIXEL_FMT_ST7586_332,
+	},
 	[MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT] = {
 		.init		= mipi_panel_init_ili9341,
 		.mode		= { TINYDRM_MODE(320, 240, 58, 43) },
@@ -165,12 +250,14 @@ static struct drm_driver mipi_panel_driver = {
 };
 
 static const struct of_device_id mipi_panel_of_match[] = {
+	{ .compatible = "lego,ev3-lcd" },
 	{ .compatible = "multi-inno,mi0283qt" },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mipi_panel_of_match);
 
 static const struct spi_device_id mipi_panel_id[] = {
+	{ "ev3-lcd", MIPI_PANEL_TYPE_LEGO_EV3_LCD },
 	{ "mi0283qt", MIPI_PANEL_TYPE_MULTI_INNO_MI0283QT },
 	{ },
 };
diff --git a/include/drm/tinydrm/st7586.h b/include/drm/tinydrm/st7586.h
new file mode 100644
index 0000000..18fb56b
--- /dev/null
+++ b/include/drm/tinydrm/st7586.h
@@ -0,0 +1,34 @@
+/*
+ * ST7586 LCD controller
+ *
+ * Copyright (C) 2017 David Lechner <david@lechnology.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_ST7856_H
+#define __LINUX_ST7856_H
+
+#define ST7586_DISP_MODE_GRAY	0x38
+#define ST7586_DISP_MODE_MONO	0x39
+#define ST7586_ENABLE_DDRAM	0x3a
+#define ST7586_SET_DISP_DUTY	0xb0
+#define ST7586_SET_PART_DISP	0xb4
+#define ST7586_SET_NLINE_INV	0xb5
+#define ST7586_SET_VOP		0xc0
+#define ST7586_SET_BIAS_SYSTEM	0xc3
+#define ST7586_SET_BOOST_LEVEL	0xc4
+#define ST7586_SET_VOP_OFFSET	0xc7
+#define ST7586_ENABLE_ANALOG	0xd0
+#define ST7586_AUTO_READ_CTRL	0xd7
+#define ST7586_OTP_RW_CTRL	0xe0
+#define ST7586_OTP_CTRL_OUT	0xe1
+#define ST7586_OTP_READ		0xe3
+
+#define ST7586_DISP_CTRL_MX	BIT(6)
+#define ST7586_DISP_CTRL_MY	BIT(7)
+
+#endif /* __LINUX_ST7856_H */
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699597 — Re: [PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-07-30 20:30 +0200
SubjectRe: [PATCH 5/6] drm/tinydrm: add support for LEGO MINDSTORMS EV3 LCD
Message-ID<u918u-3Rn-7@gated-at.bofh.it>
In reply to#1699346
On Sat, Jul 29, 2017 at 10:17 PM, David Lechner <david@lechnology.com> wrote:
> LEGO MINDSTORMS EV3 has an LCD with a ST7586 controller. This adds a new
> module for the ST7586 controller with parameters for the EV3 LCD dispay.

>  .../devicetree/bindings/display/mipi-panel.txt     |  2 +-
>  drivers/gpu/drm/tinydrm/mipi-panel.c               | 87 ++++++++++++++++++++++\]

C'mon, changes here have nothing to do with the framework itself!

Header, OTOH, has been looking fine.

-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1699347 — [PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel
Message-ID<u8Frk-6FJ-13@gated-at.bofh.it>
In reply to#1699344
This renames the mi028qt module to mipi-panel so that it can be used for
other types of panels as well. There is no reason to copy a bunch of
boiler-plate code for each panel or controller.

Signed-off-by: David Lechner <david@lechnology.com>
---
 .../devicetree/bindings/display/mipi-panel.txt     |  27 ++
 .../bindings/display/multi-inno,mi0283qt.txt       |  27 --
 MAINTAINERS                                        |   6 +-
 drivers/gpu/drm/tinydrm/Kconfig                    |  12 +-
 drivers/gpu/drm/tinydrm/Makefile                   |   2 +-
 drivers/gpu/drm/tinydrm/mi0283qt.c                 | 283 --------------------
 drivers/gpu/drm/tinydrm/mipi-panel.c               | 284 +++++++++++++++++++++
 7 files changed, 323 insertions(+), 318 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mipi-panel.txt
 delete mode 100644 Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
 delete mode 100644 drivers/gpu/drm/tinydrm/mi0283qt.c
 create mode 100644 drivers/gpu/drm/tinydrm/mipi-panel.c

diff --git a/Documentation/devicetree/bindings/display/mipi-panel.txt b/Documentation/devicetree/bindings/display/mipi-panel.txt
new file mode 100644
index 0000000..01d6ea9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mipi-panel.txt
@@ -0,0 +1,27 @@
+MIPI DBI compatible display panel
+
+Required properties:
+- compatible:	"multi-inno,mi0283qt".
+
+The node for this driver must be a child node of a SPI controller, hence
+all mandatory properties described in ../spi/spi-bus.txt must be specified.
+
+Optional properties:
+- dc-gpios:	D/C pin. The presence/absence of this GPIO determines
+		the panel interface mode (IM[3:0] pins):
+		- present: IM=x110 4-wire 8-bit data serial interface
+		- absent:  IM=x101 3-wire 9-bit data serial interface
+- reset-gpios:	Reset pin
+- power-supply:	A regulator node for the supply voltage.
+- backlight:	phandle of the backlight device attached to the panel
+- rotation:	panel rotation in degrees counter clockwise (0,90,180,270)
+
+Example:
+	display@0{
+		compatible = "multi-inno,mi0283qt";
+		reg = <0>;
+		spi-max-frequency = <32000000>;
+		rotation = <90>;
+		dc-gpios = <&gpio 25 0>;
+		backlight = <&backlight>;
+	};
diff --git a/Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt b/Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
deleted file mode 100644
index eed48c3..0000000
--- a/Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Multi-Inno MI0283QT display panel
-
-Required properties:
-- compatible:	"multi-inno,mi0283qt".
-
-The node for this driver must be a child node of a SPI controller, hence
-all mandatory properties described in ../spi/spi-bus.txt must be specified.
-
-Optional properties:
-- dc-gpios:	D/C pin. The presence/absence of this GPIO determines
-		the panel interface mode (IM[3:0] pins):
-		- present: IM=x110 4-wire 8-bit data serial interface
-		- absent:  IM=x101 3-wire 9-bit data serial interface
-- reset-gpios:	Reset pin
-- power-supply:	A regulator node for the supply voltage.
-- backlight:	phandle of the backlight device attached to the panel
-- rotation:	panel rotation in degrees counter clockwise (0,90,180,270)
-
-Example:
-	mi0283qt@0{
-		compatible = "multi-inno,mi0283qt";
-		reg = <0>;
-		spi-max-frequency = <32000000>;
-		rotation = <90>;
-		dc-gpios = <&gpio 25 0>;
-		backlight = <&backlight>;
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index f66488d..812ffd0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4315,11 +4315,11 @@ M:	Dave Airlie <airlied@redhat.com>
 S:	Odd Fixes
 F:	drivers/gpu/drm/mgag200/
 
-DRM DRIVER FOR MI0283QT
+DRM DRIVER FOR MIPI DBI compatible panels
 M:	Noralf Trønnes <noralf@tronnes.org>
 S:	Maintained
-F:	drivers/gpu/drm/tinydrm/mi0283qt.c
-F:	Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
+F:	drivers/gpu/drm/tinydrm/mipi-panel.c
+F:	Documentation/devicetree/bindings/display/mipi-panel.txt
 
 DRM DRIVER FOR MSM ADRENO GPU
 M:	Rob Clark <robdclark@gmail.com>
diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
index 3504c53..394519b 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -12,10 +12,14 @@ menuconfig DRM_TINYDRM
 config TINYDRM_MIPI_DBI
 	tristate
 
-config TINYDRM_MI0283QT
-	tristate "DRM support for MI0283QT"
+config TINYDRM_MIPI_PANEL
+	tristate "DRM support for MIPI DBI compatible display panels"
 	depends on DRM_TINYDRM && SPI
 	select TINYDRM_MIPI_DBI
 	help
-	  DRM driver for the Multi-Inno MI0283QT display panel
-	  If M is selected the module will be called mi0283qt.
+	  DRM driver for the MIPI DBI compatible display panels.
+
+	  Supported panels include:
+	  * Multi-Inno MI0283QT
+
+	  If M is selected the module will be called mipi-panel.
diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile
index 7a3604c..7eae65e 100644
--- a/drivers/gpu/drm/tinydrm/Makefile
+++ b/drivers/gpu/drm/tinydrm/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_DRM_TINYDRM)		+= core/
 obj-$(CONFIG_TINYDRM_MIPI_DBI)		+= mipi-dbi.o
 
 # Displays
-obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
+obj-$(CONFIG_TINYDRM_MIPI_PANEL)	+= mipi-panel.o
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
deleted file mode 100644
index 2680dab..0000000
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * DRM driver for Multi-Inno MI0283QT panels
- *
- * Copyright 2016 Noralf Trønnes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <drm/tinydrm/ili9341.h>
-#include <drm/tinydrm/mipi-dbi.h>
-#include <drm/tinydrm/tinydrm-helpers.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
-#include <linux/module.h>
-#include <linux/property.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <video/mipi_display.h>
-
-static int mi0283qt_init(struct mipi_dbi *mipi)
-{
-	struct tinydrm_device *tdev = &mipi->tinydrm;
-	struct device *dev = tdev->drm->dev;
-	u8 addr_mode;
-	int ret;
-
-	DRM_DEBUG_KMS("\n");
-
-	ret = regulator_enable(mipi->regulator);
-	if (ret) {
-		dev_err(dev, "Failed to enable regulator %d\n", ret);
-		return ret;
-	}
-
-	/* Avoid flicker by skipping setup if the bootloader has done it */
-	if (mipi_dbi_display_is_on(mipi))
-		return 0;
-
-	mipi_dbi_hw_reset(mipi);
-	ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
-	if (ret) {
-		dev_err(dev, "Error sending command %d\n", ret);
-		regulator_disable(mipi->regulator);
-		return ret;
-	}
-
-	msleep(20);
-
-	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
-
-	mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0x83, 0x30);
-	mipi_dbi_command(mipi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
-	mipi_dbi_command(mipi, ILI9341_DTCTRLA, 0x85, 0x01, 0x79);
-	mipi_dbi_command(mipi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
-	mipi_dbi_command(mipi, ILI9341_PUMPCTRL, 0x20);
-	mipi_dbi_command(mipi, ILI9341_DTCTRLB, 0x00, 0x00);
-
-	/* Power Control */
-	mipi_dbi_command(mipi, ILI9341_PWCTRL1, 0x26);
-	mipi_dbi_command(mipi, ILI9341_PWCTRL2, 0x11);
-	/* VCOM */
-	mipi_dbi_command(mipi, ILI9341_VMCTRL1, 0x35, 0x3e);
-	mipi_dbi_command(mipi, ILI9341_VMCTRL2, 0xbe);
-
-	/* Memory Access Control */
-	mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55);
-
-	switch (mipi->rotation) {
-	default:
-		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
-			    ILI9341_MADCTL_MX;
-		break;
-	case 90:
-		addr_mode = ILI9341_MADCTL_MY;
-		break;
-	case 180:
-		addr_mode = ILI9341_MADCTL_MV;
-		break;
-	case 270:
-		addr_mode = ILI9341_MADCTL_MX;
-		break;
-	}
-	addr_mode |= ILI9341_MADCTL_BGR;
-	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
-
-	/* Frame Rate */
-	mipi_dbi_command(mipi, ILI9341_FRMCTR1, 0x00, 0x1b);
-
-	/* Gamma */
-	mipi_dbi_command(mipi, ILI9341_EN3GAM, 0x08);
-	mipi_dbi_command(mipi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
-	mipi_dbi_command(mipi, ILI9341_PGAMCTRL,
-		       0x1f, 0x1a, 0x18, 0x0a, 0x0f, 0x06, 0x45, 0x87,
-		       0x32, 0x0a, 0x07, 0x02, 0x07, 0x05, 0x00);
-	mipi_dbi_command(mipi, ILI9341_NGAMCTRL,
-		       0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3a, 0x78,
-		       0x4d, 0x05, 0x18, 0x0d, 0x38, 0x3a, 0x1f);
-
-	/* DDRAM */
-	mipi_dbi_command(mipi, ILI9341_ETMOD, 0x07);
-
-	/* Display */
-	mipi_dbi_command(mipi, ILI9341_DISCTRL, 0x0a, 0x82, 0x27, 0x00);
-	mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
-	msleep(100);
-
-	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
-	msleep(100);
-
-	return 0;
-}
-
-static void mi0283qt_fini(void *data)
-{
-	struct mipi_dbi *mipi = data;
-
-	DRM_DEBUG_KMS("\n");
-	regulator_disable(mipi->regulator);
-}
-
-static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = {
-	.enable = mipi_dbi_pipe_enable,
-	.disable = mipi_dbi_pipe_disable,
-	.update = tinydrm_display_pipe_update,
-	.prepare_fb = tinydrm_display_pipe_prepare_fb,
-};
-
-static const struct drm_display_mode mi0283qt_mode = {
-	TINYDRM_MODE(320, 240, 58, 43),
-};
-
-DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
-
-static struct drm_driver mi0283qt_driver = {
-	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
-				  DRIVER_ATOMIC,
-	.fops			= &mi0283qt_fops,
-	TINYDRM_GEM_DRIVER_OPS,
-	.lastclose		= tinydrm_lastclose,
-	.debugfs_init		= mipi_dbi_debugfs_init,
-	.name			= "mi0283qt",
-	.desc			= "Multi-Inno MI0283QT",
-	.date			= "20160614",
-	.major			= 1,
-	.minor			= 0,
-};
-
-static const struct of_device_id mi0283qt_of_match[] = {
-	{ .compatible = "multi-inno,mi0283qt" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, mi0283qt_of_match);
-
-static const struct spi_device_id mi0283qt_id[] = {
-	{ "mi0283qt", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(spi, mi0283qt_id);
-
-static int mi0283qt_probe(struct spi_device *spi)
-{
-	struct device *dev = &spi->dev;
-	struct tinydrm_device *tdev;
-	struct mipi_dbi *mipi;
-	struct gpio_desc *dc;
-	u32 rotation = 0;
-	int ret;
-
-	mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
-	if (!mipi)
-		return -ENOMEM;
-
-	mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-	if (IS_ERR(mipi->reset)) {
-		dev_err(dev, "Failed to get gpio 'reset'\n");
-		return PTR_ERR(mipi->reset);
-	}
-
-	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
-	if (IS_ERR(dc)) {
-		dev_err(dev, "Failed to get gpio 'dc'\n");
-		return PTR_ERR(dc);
-	}
-
-	mipi->regulator = devm_regulator_get(dev, "power");
-	if (IS_ERR(mipi->regulator))
-		return PTR_ERR(mipi->regulator);
-
-	mipi->backlight = tinydrm_of_find_backlight(dev);
-	if (IS_ERR(mipi->backlight))
-		return PTR_ERR(mipi->backlight);
-
-	device_property_read_u32(dev, "rotation", &rotation);
-
-	ret = mipi_dbi_spi_init(spi, mipi, dc, &mi0283qt_pipe_funcs,
-				&mi0283qt_driver, &mi0283qt_mode,
-				MIPI_DCS_PIXEL_FMT_16BIT, rotation);
-	if (ret)
-		return ret;
-
-	ret = mi0283qt_init(mipi);
-	if (ret)
-		return ret;
-
-	/* use devres to fini after drm unregister (drv->remove is before) */
-	ret = devm_add_action(dev, mi0283qt_fini, mipi);
-	if (ret) {
-		mi0283qt_fini(mipi);
-		return ret;
-	}
-
-	tdev = &mipi->tinydrm;
-
-	ret = devm_tinydrm_register(tdev);
-	if (ret)
-		return ret;
-
-	spi_set_drvdata(spi, mipi);
-
-	DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
-			 tdev->drm->driver->name, dev_name(dev),
-			 spi->max_speed_hz / 1000000,
-			 tdev->drm->primary->index);
-
-	return 0;
-}
-
-static void mi0283qt_shutdown(struct spi_device *spi)
-{
-	struct mipi_dbi *mipi = spi_get_drvdata(spi);
-
-	tinydrm_shutdown(&mipi->tinydrm);
-}
-
-static int __maybe_unused mi0283qt_pm_suspend(struct device *dev)
-{
-	struct mipi_dbi *mipi = dev_get_drvdata(dev);
-	int ret;
-
-	ret = tinydrm_suspend(&mipi->tinydrm);
-	if (ret)
-		return ret;
-
-	mi0283qt_fini(mipi);
-
-	return 0;
-}
-
-static int __maybe_unused mi0283qt_pm_resume(struct device *dev)
-{
-	struct mipi_dbi *mipi = dev_get_drvdata(dev);
-	int ret;
-
-	ret = mi0283qt_init(mipi);
-	if (ret)
-		return ret;
-
-	return tinydrm_resume(&mipi->tinydrm);
-}
-
-static const struct dev_pm_ops mi0283qt_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mi0283qt_pm_suspend, mi0283qt_pm_resume)
-};
-
-static struct spi_driver mi0283qt_spi_driver = {
-	.driver = {
-		.name = "mi0283qt",
-		.owner = THIS_MODULE,
-		.of_match_table = mi0283qt_of_match,
-		.pm = &mi0283qt_pm_ops,
-	},
-	.id_table = mi0283qt_id,
-	.probe = mi0283qt_probe,
-	.shutdown = mi0283qt_shutdown,
-};
-module_spi_driver(mi0283qt_spi_driver);
-
-MODULE_DESCRIPTION("Multi-Inno MI0283QT DRM driver");
-MODULE_AUTHOR("Noralf Trønnes");
-MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tinydrm/mipi-panel.c b/drivers/gpu/drm/tinydrm/mipi-panel.c
new file mode 100644
index 0000000..64344f0
--- /dev/null
+++ b/drivers/gpu/drm/tinydrm/mipi-panel.c
@@ -0,0 +1,284 @@
+/*
+ * DRM driver for MIPI DBI compatible panels
+ *
+ * Copyright 2016 Noralf Trønnes
+ * Copyright 2017 David Lechner <david@lechnology.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <drm/tinydrm/ili9341.h>
+#include <drm/tinydrm/mipi-dbi.h>
+#include <drm/tinydrm/tinydrm-helpers.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <video/mipi_display.h>
+
+static int mipi_panel_init(struct mipi_dbi *mipi)
+{
+	struct tinydrm_device *tdev = &mipi->tinydrm;
+	struct device *dev = tdev->drm->dev;
+	u8 addr_mode;
+	int ret;
+
+	DRM_DEBUG_KMS("\n");
+
+	ret = regulator_enable(mipi->regulator);
+	if (ret) {
+		dev_err(dev, "Failed to enable regulator %d\n", ret);
+		return ret;
+	}
+
+	/* Avoid flicker by skipping setup if the bootloader has done it */
+	if (mipi_dbi_display_is_on(mipi))
+		return 0;
+
+	mipi_dbi_hw_reset(mipi);
+	ret = mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
+	if (ret) {
+		dev_err(dev, "Error sending command %d\n", ret);
+		regulator_disable(mipi->regulator);
+		return ret;
+	}
+
+	msleep(20);
+
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
+
+	mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0x83, 0x30);
+	mipi_dbi_command(mipi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
+	mipi_dbi_command(mipi, ILI9341_DTCTRLA, 0x85, 0x01, 0x79);
+	mipi_dbi_command(mipi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
+	mipi_dbi_command(mipi, ILI9341_PUMPCTRL, 0x20);
+	mipi_dbi_command(mipi, ILI9341_DTCTRLB, 0x00, 0x00);
+
+	/* Power Control */
+	mipi_dbi_command(mipi, ILI9341_PWCTRL1, 0x26);
+	mipi_dbi_command(mipi, ILI9341_PWCTRL2, 0x11);
+	/* VCOM */
+	mipi_dbi_command(mipi, ILI9341_VMCTRL1, 0x35, 0x3e);
+	mipi_dbi_command(mipi, ILI9341_VMCTRL2, 0xbe);
+
+	/* Memory Access Control */
+	mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55);
+
+	switch (mipi->rotation) {
+	default:
+		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
+			    ILI9341_MADCTL_MX;
+		break;
+	case 90:
+		addr_mode = ILI9341_MADCTL_MY;
+		break;
+	case 180:
+		addr_mode = ILI9341_MADCTL_MV;
+		break;
+	case 270:
+		addr_mode = ILI9341_MADCTL_MX;
+		break;
+	}
+	addr_mode |= ILI9341_MADCTL_BGR;
+	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+
+	/* Frame Rate */
+	mipi_dbi_command(mipi, ILI9341_FRMCTR1, 0x00, 0x1b);
+
+	/* Gamma */
+	mipi_dbi_command(mipi, ILI9341_EN3GAM, 0x08);
+	mipi_dbi_command(mipi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
+	mipi_dbi_command(mipi, ILI9341_PGAMCTRL,
+		       0x1f, 0x1a, 0x18, 0x0a, 0x0f, 0x06, 0x45, 0x87,
+		       0x32, 0x0a, 0x07, 0x02, 0x07, 0x05, 0x00);
+	mipi_dbi_command(mipi, ILI9341_NGAMCTRL,
+		       0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3a, 0x78,
+		       0x4d, 0x05, 0x18, 0x0d, 0x38, 0x3a, 0x1f);
+
+	/* DDRAM */
+	mipi_dbi_command(mipi, ILI9341_ETMOD, 0x07);
+
+	/* Display */
+	mipi_dbi_command(mipi, ILI9341_DISCTRL, 0x0a, 0x82, 0x27, 0x00);
+	mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(100);
+
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
+	msleep(100);
+
+	return 0;
+}
+
+static void mipi_panel_fini(void *data)
+{
+	struct mipi_dbi *mipi = data;
+
+	DRM_DEBUG_KMS("\n");
+	regulator_disable(mipi->regulator);
+}
+
+static const struct drm_simple_display_pipe_funcs mipi_panel_pipe_funcs = {
+	.enable = mipi_dbi_pipe_enable,
+	.disable = mipi_dbi_pipe_disable,
+	.update = tinydrm_display_pipe_update,
+	.prepare_fb = tinydrm_display_pipe_prepare_fb,
+};
+
+static const struct drm_display_mode mipi_panel_mode = {
+	TINYDRM_MODE(320, 240, 58, 43),
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(mipi_panel_fops);
+
+static struct drm_driver mipi_panel_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
+				  DRIVER_ATOMIC,
+	.fops			= &mipi_panel_fops,
+	TINYDRM_GEM_DRIVER_OPS,
+	.lastclose		= tinydrm_lastclose,
+	.debugfs_init		= mipi_dbi_debugfs_init,
+	.name			= "mipi-panel",
+	.desc			= "MIPI DBI compatible panel",
+	.date			= "20160614",
+	.major			= 1,
+	.minor			= 0,
+};
+
+static const struct of_device_id mipi_panel_of_match[] = {
+	{ .compatible = "multi-inno,mi0283qt" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mipi_panel_of_match);
+
+static const struct spi_device_id mipi_panel_id[] = {
+	{ "mi0283qt", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, mipi_panel_id);
+
+static int mipi_panel_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct tinydrm_device *tdev;
+	struct mipi_dbi *mipi;
+	struct gpio_desc *dc;
+	u32 rotation = 0;
+	int ret;
+
+	mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
+	if (!mipi)
+		return -ENOMEM;
+
+	mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(mipi->reset)) {
+		dev_err(dev, "Failed to get gpio 'reset'\n");
+		return PTR_ERR(mipi->reset);
+	}
+
+	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
+	if (IS_ERR(dc)) {
+		dev_err(dev, "Failed to get gpio 'dc'\n");
+		return PTR_ERR(dc);
+	}
+
+	mipi->regulator = devm_regulator_get(dev, "power");
+	if (IS_ERR(mipi->regulator))
+		return PTR_ERR(mipi->regulator);
+
+	mipi->backlight = tinydrm_of_find_backlight(dev);
+	if (IS_ERR(mipi->backlight))
+		return PTR_ERR(mipi->backlight);
+
+	device_property_read_u32(dev, "rotation", &rotation);
+
+	ret = mipi_dbi_spi_init(spi, mipi, dc, &mipi_panel_pipe_funcs,
+				&mipi_panel_driver, &mipi_panel_mode,
+				MIPI_DCS_PIXEL_FMT_16BIT, rotation);
+	if (ret)
+		return ret;
+
+	ret = mipi_panel_init(mipi);
+	if (ret)
+		return ret;
+
+	/* use devres to fini after drm unregister (drv->remove is before) */
+	ret = devm_add_action(dev, mipi_panel_fini, mipi);
+	if (ret) {
+		mipi_panel_fini(mipi);
+		return ret;
+	}
+
+	tdev = &mipi->tinydrm;
+
+	ret = devm_tinydrm_register(tdev);
+	if (ret)
+		return ret;
+
+	spi_set_drvdata(spi, mipi);
+
+	DRM_DEBUG_DRIVER("Initialized %s:%s @%uMHz on minor %d\n",
+			 tdev->drm->driver->name, dev_name(dev),
+			 spi->max_speed_hz / 1000000,
+			 tdev->drm->primary->index);
+
+	return 0;
+}
+
+static void mipi_panel_shutdown(struct spi_device *spi)
+{
+	struct mipi_dbi *mipi = spi_get_drvdata(spi);
+
+	tinydrm_shutdown(&mipi->tinydrm);
+}
+
+static int __maybe_unused mipi_panel_pm_suspend(struct device *dev)
+{
+	struct mipi_dbi *mipi = dev_get_drvdata(dev);
+	int ret;
+
+	ret = tinydrm_suspend(&mipi->tinydrm);
+	if (ret)
+		return ret;
+
+	mipi_panel_fini(mipi);
+
+	return 0;
+}
+
+static int __maybe_unused mipi_panel_pm_resume(struct device *dev)
+{
+	struct mipi_dbi *mipi = dev_get_drvdata(dev);
+	int ret;
+
+	ret = mipi_panel_init(mipi);
+	if (ret)
+		return ret;
+
+	return tinydrm_resume(&mipi->tinydrm);
+}
+
+static const struct dev_pm_ops mipi_panel_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mipi_panel_pm_suspend, mipi_panel_pm_resume)
+};
+
+static struct spi_driver mipi_panel_spi_driver = {
+	.driver = {
+		.name = "mipi-panel",
+		.owner = THIS_MODULE,
+		.of_match_table = mipi_panel_of_match,
+		.pm = &mipi_panel_pm_ops,
+	},
+	.id_table = mipi_panel_id,
+	.probe = mipi_panel_probe,
+	.shutdown = mipi_panel_shutdown,
+};
+module_spi_driver(mipi_panel_spi_driver);
+
+MODULE_DESCRIPTION("MIPI DBI panel DRM driver");
+MODULE_AUTHOR("Noralf Trønnes");
+MODULE_LICENSE("GPL");
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699352 — Re: [PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:40 +0200
SubjectRe: [PATCH 3/6] drm/tinydrm: rename mi028qt module to mipi-panel
Message-ID<u8FKF-6NY-9@gated-at.bofh.it>
In reply to#1699347
On 07/29/2017 02:17 PM, David Lechner wrote:
> This renames the mi028qt module to mipi-panel so that it can be used for
> other types of panels as well. There is no reason to copy a bunch of
> boiler-plate code for each panel or controller.
> 
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
>   .../devicetree/bindings/display/mipi-panel.txt     |  27 ++
>   .../bindings/display/multi-inno,mi0283qt.txt       |  27 --
>   MAINTAINERS                                        |   6 +-
>   drivers/gpu/drm/tinydrm/Kconfig                    |  12 +-
>   drivers/gpu/drm/tinydrm/Makefile                   |   2 +-
>   drivers/gpu/drm/tinydrm/mi0283qt.c                 | 283 --------------------
>   drivers/gpu/drm/tinydrm/mipi-panel.c               | 284 +++++++++++++++++++++
>   7 files changed, 323 insertions(+), 318 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/display/mipi-panel.txt
>   delete mode 100644 Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
>   delete mode 100644 drivers/gpu/drm/tinydrm/mi0283qt.c
>   create mode 100644 drivers/gpu/drm/tinydrm/mipi-panel.c
> 

Apparently, I missed an option on git format-patch. This diff should be 
easier to look at...

---

diff --git 
a/Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt 
b/Documentation/devicetree/bindings/display/mipi-panel.txt
similarity index 94%
rename from 
Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
rename to Documentation/devicetree/bindings/display/mipi-panel.txt
index eed48c3..01d6ea9 100644
--- a/Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
+++ b/Documentation/devicetree/bindings/display/mipi-panel.txt
@@ -1,4 +1,4 @@
-Multi-Inno MI0283QT display panel
+MIPI DBI compatible display panel

  Required properties:
  - compatible:  "multi-inno,mi0283qt".
@@ -17,7 +17,7 @@ Optional properties:
  - rotation:    panel rotation in degrees counter clockwise (0,90,180,270)

  Example:
-       mi0283qt@0{
+       display@0{
                 compatible = "multi-inno,mi0283qt";
                 reg = <0>;
                 spi-max-frequency = <32000000>;
diff --git a/MAINTAINERS b/MAINTAINERS
index f66488d..812ffd0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4315,11 +4315,11 @@ M:      Dave Airlie <airlied@redhat.com>
  S:     Odd Fixes
  F:     drivers/gpu/drm/mgag200/

-DRM DRIVER FOR MI0283QT
+DRM DRIVER FOR MIPI DBI compatible panels
  M:     Noralf Trønnes <noralf@tronnes.org>
  S:     Maintained
-F:     drivers/gpu/drm/tinydrm/mi0283qt.c
-F:     Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
+F:     drivers/gpu/drm/tinydrm/mipi-panel.c
+F:     Documentation/devicetree/bindings/display/mipi-panel.txt

  DRM DRIVER FOR MSM ADRENO GPU
  M:     Rob Clark <robdclark@gmail.com>
diff --git a/drivers/gpu/drm/tinydrm/Kconfig 
b/drivers/gpu/drm/tinydrm/Kconfig
index 3504c53..0a0db7a 100644
--- a/drivers/gpu/drm/tinydrm/Kconfig
+++ b/drivers/gpu/drm/tinydrm/Kconfig
@@ -12,10 +12,14 @@ menuconfig DRM_TINYDRM
  config TINYDRM_MIPI_DBI
         tristate

-config TINYDRM_MI0283QT
-       tristate "DRM support for MI0283QT"
+config TINYDRM_MIPI_PANEL
+       tristate "DRM support for MIPI DBI compatible display panels"
         depends on DRM_TINYDRM && SPI
         select TINYDRM_MIPI_DBI
         help
-         DRM driver for the Multi-Inno MI0283QT display panel
-         If M is selected the module will be called mi0283qt.
+         DRM driver for the MIPI DBI compatible display panels.
+
+         Supported panels include:
+         * Multi-Inno MI0283QT
+
+         If M is selected the module will be called mipi-panel.
diff --git a/drivers/gpu/drm/tinydrm/Makefile 
b/drivers/gpu/drm/tinydrm/Makefile
index 7a3604c..7eae65e 100644
--- a/drivers/gpu/drm/tinydrm/Makefile
+++ b/drivers/gpu/drm/tinydrm/Makefile
@@ -4,4 +4,4 @@ obj-$(CONFIG_DRM_TINYDRM)               += core/
  obj-$(CONFIG_TINYDRM_MIPI_DBI)         += mipi-dbi.o

  # Displays
-obj-$(CONFIG_TINYDRM_MI0283QT)         += mi0283qt.o
+obj-$(CONFIG_TINYDRM_MIPI_PANEL)       += mipi-panel.o
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c 
b/drivers/gpu/drm/tinydrm/mipi-panel.c
similarity index 76%
rename from drivers/gpu/drm/tinydrm/mi0283qt.c
rename to drivers/gpu/drm/tinydrm/mipi-panel.c
index 2680dab..64344f0 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mipi-panel.c
@@ -1,7 +1,8 @@
  /*
- * DRM driver for Multi-Inno MI0283QT panels
+ * DRM driver for MIPI DBI compatible panels
   *
   * Copyright 2016 Noralf Trønnes
+ * Copyright 2017 David Lechner <david@lechnology.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@ -20,7 +21,7 @@
  #include <linux/spi/spi.h>
  #include <video/mipi_display.h>

-static int mi0283qt_init(struct mipi_dbi *mipi)
+static int mipi_panel_init(struct mipi_dbi *mipi)
  {
         struct tinydrm_device *tdev = &mipi->tinydrm;
         struct device *dev = tdev->drm->dev;
@@ -113,7 +114,7 @@ static int mi0283qt_init(struct mipi_dbi *mipi)
         return 0;
  }

-static void mi0283qt_fini(void *data)
+static void mipi_panel_fini(void *data)
  {
         struct mipi_dbi *mipi = data;

@@ -121,46 +122,46 @@ static void mi0283qt_fini(void *data)
         regulator_disable(mipi->regulator);
  }

-static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = {
+static const struct drm_simple_display_pipe_funcs mipi_panel_pipe_funcs = {
         .enable = mipi_dbi_pipe_enable,
         .disable = mipi_dbi_pipe_disable,
         .update = tinydrm_display_pipe_update,
         .prepare_fb = tinydrm_display_pipe_prepare_fb,
  };

-static const struct drm_display_mode mi0283qt_mode = {
+static const struct drm_display_mode mipi_panel_mode = {
         TINYDRM_MODE(320, 240, 58, 43),
  };

-DEFINE_DRM_GEM_CMA_FOPS(mi0283qt_fops);
+DEFINE_DRM_GEM_CMA_FOPS(mipi_panel_fops);

-static struct drm_driver mi0283qt_driver = {
+static struct drm_driver mipi_panel_driver = {
         .driver_features        = DRIVER_GEM | DRIVER_MODESET | 
DRIVER_PRIME |
                                   DRIVER_ATOMIC,
-       .fops                   = &mi0283qt_fops,
+       .fops                   = &mipi_panel_fops,
         TINYDRM_GEM_DRIVER_OPS,
         .lastclose              = tinydrm_lastclose,
         .debugfs_init           = mipi_dbi_debugfs_init,
-       .name                   = "mi0283qt",
-       .desc                   = "Multi-Inno MI0283QT",
+       .name                   = "mipi-panel",
+       .desc                   = "MIPI DBI compatible panel",
         .date                   = "20160614",
         .major                  = 1,
         .minor                  = 0,
  };

-static const struct of_device_id mi0283qt_of_match[] = {
+static const struct of_device_id mipi_panel_of_match[] = {
         { .compatible = "multi-inno,mi0283qt" },
         {},
  };
-MODULE_DEVICE_TABLE(of, mi0283qt_of_match);
+MODULE_DEVICE_TABLE(of, mipi_panel_of_match);

-static const struct spi_device_id mi0283qt_id[] = {
+static const struct spi_device_id mipi_panel_id[] = {
         { "mi0283qt", 0 },
         { },
  };
-MODULE_DEVICE_TABLE(spi, mi0283qt_id);
+MODULE_DEVICE_TABLE(spi, mipi_panel_id);

-static int mi0283qt_probe(struct spi_device *spi)
+static int mipi_panel_probe(struct spi_device *spi)
  {
         struct device *dev = &spi->dev;
         struct tinydrm_device *tdev;
@@ -195,20 +196,20 @@ static int mi0283qt_probe(struct spi_device *spi)

         device_property_read_u32(dev, "rotation", &rotation);

-       ret = mipi_dbi_spi_init(spi, mipi, dc, &mi0283qt_pipe_funcs,
-                               &mi0283qt_driver, &mi0283qt_mode,
+       ret = mipi_dbi_spi_init(spi, mipi, dc, &mipi_panel_pipe_funcs,
+                               &mipi_panel_driver, &mipi_panel_mode,
                                 MIPI_DCS_PIXEL_FMT_16BIT, rotation);
         if (ret)
                 return ret;

-       ret = mi0283qt_init(mipi);
+       ret = mipi_panel_init(mipi);
         if (ret)
                 return ret;

         /* use devres to fini after drm unregister (drv->remove is 
before) */
-       ret = devm_add_action(dev, mi0283qt_fini, mipi);
+       ret = devm_add_action(dev, mipi_panel_fini, mipi);
         if (ret) {
-               mi0283qt_fini(mipi);
+               mipi_panel_fini(mipi);
                 return ret;
         }

@@ -228,14 +229,14 @@ static int mi0283qt_probe(struct spi_device *spi)
         return 0;
  }

-static void mi0283qt_shutdown(struct spi_device *spi)
+static void mipi_panel_shutdown(struct spi_device *spi)
  {
         struct mipi_dbi *mipi = spi_get_drvdata(spi);

         tinydrm_shutdown(&mipi->tinydrm);
  }

-static int __maybe_unused mi0283qt_pm_suspend(struct device *dev)
+static int __maybe_unused mipi_panel_pm_suspend(struct device *dev)
  {
         struct mipi_dbi *mipi = dev_get_drvdata(dev);
         int ret;
@@ -244,40 +245,40 @@ static int __maybe_unused 
mi0283qt_pm_suspend(struct device *dev)
         if (ret)
                 return ret;

-       mi0283qt_fini(mipi);
+       mipi_panel_fini(mipi);

         return 0;
  }

-static int __maybe_unused mi0283qt_pm_resume(struct device *dev)
+static int __maybe_unused mipi_panel_pm_resume(struct device *dev)
  {
         struct mipi_dbi *mipi = dev_get_drvdata(dev);
         int ret;

-       ret = mi0283qt_init(mipi);
+       ret = mipi_panel_init(mipi);
         if (ret)
                 return ret;

         return tinydrm_resume(&mipi->tinydrm);
  }

-static const struct dev_pm_ops mi0283qt_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(mi0283qt_pm_suspend, mi0283qt_pm_resume)
+static const struct dev_pm_ops mipi_panel_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(mipi_panel_pm_suspend, mipi_panel_pm_resume)
  };

-static struct spi_driver mi0283qt_spi_driver = {
+static struct spi_driver mipi_panel_spi_driver = {
         .driver = {
-               .name = "mi0283qt",
+               .name = "mipi-panel",
                 .owner = THIS_MODULE,
-               .of_match_table = mi0283qt_of_match,
-               .pm = &mi0283qt_pm_ops,
+               .of_match_table = mipi_panel_of_match,
+               .pm = &mipi_panel_pm_ops,
         },
-       .id_table = mi0283qt_id,
-       .probe = mi0283qt_probe,
-       .shutdown = mi0283qt_shutdown,
+       .id_table = mipi_panel_id,
+       .probe = mipi_panel_probe,
+       .shutdown = mipi_panel_shutdown,
  };
-module_spi_driver(mi0283qt_spi_driver);
+module_spi_driver(mipi_panel_spi_driver);

-MODULE_DESCRIPTION("Multi-Inno MI0283QT DRM driver");
+MODULE_DESCRIPTION("MIPI DBI panel DRM driver");
  MODULE_AUTHOR("Noralf Trønnes");
  MODULE_LICENSE("GPL");
--
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699348 — [PATCH 6/6] ARM: dts: da850-lego-ev3: Add node for LCD display

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 6/6] ARM: dts: da850-lego-ev3: Add node for LCD display
Message-ID<u8Frk-6FJ-17@gated-at.bofh.it>
In reply to#1699344
This adds a new node for the LEGO MINDSTORMS EV3 LCD display.

Signed-off-by: David Lechner <david@lechnology.com>
---
 arch/arm/boot/dts/da850-lego-ev3.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts
index 45983c0..249b317 100644
--- a/arch/arm/boot/dts/da850-lego-ev3.dts
+++ b/arch/arm/boot/dts/da850-lego-ev3.dts
@@ -249,6 +249,15 @@
 			0x4c 0x00000080 0x000000f0
 		>;
 	};
+
+	ev3_lcd_pins: pinmux_lcd {
+		pinctrl-single,bits = <
+			/* SIMO, GP2[11], GP2[12], CLK */
+			0x14 0x00188100 0x00ffff00
+			/* GP5[0] */
+			0x30 0x80000000 0xf0000000
+		>;
+	};
 };
 
 &pinconf {
@@ -357,6 +366,21 @@
 	};
 };
 
+&spi1 {
+	status = "okay";
+	pinctrl-0 = <&ev3_lcd_pins>;
+	pinctrl-names = "default";
+	cs-gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+
+	display@0{
+		compatible = "lego,ev3-lcd";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		dc-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>;
+	};
+};
+
 &ehrpwm0 {
 	status = "okay";
 };
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699349 — [PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:20 +0200
Subject[PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers
Message-ID<u8Frk-6FJ-21@gated-at.bofh.it>
In reply to#1699344
This adds helper functions and support for ST7586 controllers. These
controllers have an unusual memory layout where 3 pixels are packed into
1 byte.

+-------+-----------------+
| bit   | 7 6 5 4 3 2 1 0 |
+-------+-----------------+
| pixel | 0 0 0 1 1 1 2 2 |
+-------+-----------------+

So, there are a nuber of places in the tinydrm pipline where this format
needs to be taken into consideration.

Signed-off-by: David Lechner <david@lechnology.com>
---
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c | 148 +++++++++++++++++++++++++
 drivers/gpu/drm/tinydrm/mipi-dbi.c             |  96 ++++++++++++----
 include/drm/tinydrm/tinydrm-helpers.h          |   6 +
 include/video/mipi_display.h                   |   2 +
 4 files changed, 232 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index d4cda33..4a36441 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -181,6 +181,154 @@ void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
 EXPORT_SYMBOL(tinydrm_xrgb8888_to_rgb565);
 
 /**
+ * tinydrm_rgb565_to_st7586 - Convert RGB565 to ST7586 clip buffer
+ * @dst: ST7586 destination buffer
+ * @vaddr: RGB565 source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ * @swap: Swap bytes
+ *
+ * The ST7586 controller has a non-standard pixel layout. It is 2-bit grayscale
+ * (or 1-bit monochrome) packed into 3 pixels per byte.
+ *
+ * Note: the @clip x values are modified! They are aligned to the 3 pixel
+ * boundtry and divied by 3 to get the starting and ending byte (+ 1) in the
+ * @dst buffer.
+ */
+void tinydrm_rgb565_to_st7586(u8 *dst, void *vaddr,
+				struct drm_framebuffer *fb,
+				struct drm_clip_rect *clip)
+{
+	size_t len;
+	unsigned int x, y;
+	u16 *src, *buf;
+	u8 val;
+
+	/* 3 pixels per byte, so align to dst byte */
+	clip->x1 -= clip->x1 % 3;
+	clip->x2 = (clip->x2 + 2) / 3 * 3;
+	len = (clip->x2 - clip->x1) * sizeof(u16);
+
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return;
+
+	for (y = clip->y1; y < clip->y2; y++) {
+		src = vaddr + (y * fb->pitches[0]);
+		src += clip->x1;
+		memcpy(buf, src, len);
+		src = buf;
+		for (x = clip->x1; x < clip->x2; x += 3) {
+			/*
+			 * TODO: There is probably a better algorithm to get
+			 * a better downsampling.
+			 * If red or green is > 50%, set the high bit, which is
+			 * bright gray. If blue is greater than 50%, set the
+			 * low bit, which is dark gray.
+			 */
+			val =   ((*src & 0x8000) >>  8) |
+				((*src & 0x0400) >>  3) |
+				((*src & 0x0010) <<  2);
+			if (val & 0xC0)
+				val |= 0x20;
+			src++;
+			val |=  ((*src & 0x8000) >> 11) |
+				((*src & 0x0400) >>  6) |
+				((*src & 0x0010) >>  1);
+			if (val & 0x18)
+				val |= 0x04;
+			src++;
+			val |=  ((*src & 0x8000) >> 14) |
+				((*src & 0x0400) >>  9) |
+				((*src & 0x0010) >>  4);
+			src++;
+			*dst++ = ~val;
+		}
+	}
+
+	/* now adjust the clip so it applies to dst */
+	clip->x1 /= 3;
+	clip->x2 /= 3;
+
+	kfree(buf);
+}
+EXPORT_SYMBOL(tinydrm_rgb565_to_st7586);
+
+/**
+ * tinydrm_xrgb8888_to_st7586 - Convert XRGB8888 to ST7586 clip buffer
+ * @dst: ST7586 destination buffer
+ * @vaddr: XRGB8888 source buffer
+ * @fb: DRM framebuffer
+ * @clip: Clip rectangle area to copy
+ * @swap: Swap bytes
+ *
+ * The ST7586 controller has a non-standard pixel layout. It is 2-bit grayscale
+ * (or 1-bit monochrome) packed into 3 pixels per byte.
+ *
+ * Note: the @clip x values are modified! They are aligned to the 3 pixel
+ * boundtry and divied by 3 to get the starting and ending byte (+ 1) in the
+ * @dst buffer.
+ */
+void tinydrm_xrgb8888_to_st7586(u8 *dst, void *vaddr,
+				struct drm_framebuffer *fb,
+				struct drm_clip_rect *clip)
+{
+	size_t len;
+	unsigned int x, y;
+	u32 *src, *buf;
+	u8 val;
+
+	/* 3 pixels per byte, so align to dst byte */
+	clip->x1 -= clip->x1 % 3;
+	clip->x2 = (clip->x2 + 2) / 3 * 3;
+	len = (clip->x2 - clip->x1) * sizeof(u32);
+
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return;
+
+	for (y = clip->y1; y < clip->y2; y++) {
+		src = vaddr + (y * fb->pitches[0]);
+		src += clip->x1;
+		memcpy(buf, src, len);
+		src = buf;
+		for (x = clip->x1; x < clip->x2; x += 3) {
+			/*
+			 * TODO: There is probably a better algorithm to get
+			 * a better downsampling.
+			 * If red or green is > 50%, set the high bit, which is
+			 * bright gray. If blue is greater than 50%, set the
+			 * low bit, which is dark gray.
+			 */
+			val =   ((*src & 0x00800000) >> 16) |
+				((*src & 0x00008000) >>  8) |
+				((*src & 0x00000080) >>  1);
+			if (val & 0xC0)
+				val |= 0x20;
+			src++;
+			val |=  ((*src & 0x00800000) >> 19) |
+				((*src & 0x00008000) >> 11) |
+				((*src & 0x00000080) >>  4);
+			if (val & 0x18)
+				val |= 0x04;
+			src++;
+			val |=  ((*src & 0x00800000) >> 22) |
+				((*src & 0x00008000) >> 14) |
+				((*src & 0x00000080) >>  7);
+			src++;
+			*dst++ = ~val;
+		}
+	}
+
+	/* now adjust the clip so it applies to dst */
+	clip->x1 /= 3;
+	clip->x2 /= 3;
+
+	kfree(buf);
+}
+EXPORT_SYMBOL(tinydrm_xrgb8888_to_st7586);
+
+/**
  * tinydrm_of_find_backlight - Find backlight device in device-tree
  * @dev: Device
  *
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index 7d49366..c8fb622 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -154,7 +154,8 @@ int mipi_dbi_command_buf(struct mipi_dbi *mipi, u8 cmd, u8 *data, size_t len)
 EXPORT_SYMBOL(mipi_dbi_command_buf);
 
 static int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
-				struct drm_clip_rect *clip, bool swap)
+				struct drm_clip_rect *clip,
+				enum mipi_dcs_pixel_format pixel_fmt, bool swap)
 {
 	struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
 	struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
@@ -169,21 +170,45 @@ static int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb,
 			return ret;
 	}
 
-	switch (fb->format->format) {
-	case DRM_FORMAT_RGB565:
-		if (swap)
-			tinydrm_swab16(dst, src, fb, clip);
-		else
-			tinydrm_memcpy(dst, src, fb, clip);
+	switch (pixel_fmt) {
+	case MIPI_DCS_PIXEL_FMT_16BIT:
+		switch (fb->format->format) {
+		case DRM_FORMAT_RGB565:
+			if (swap)
+				tinydrm_swab16(dst, src, fb, clip);
+			else
+				tinydrm_memcpy(dst, src, fb, clip);
+			break;
+		case DRM_FORMAT_XRGB8888:
+			tinydrm_xrgb8888_to_rgb565(dst, src, fb, clip, swap);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
 		break;
-	case DRM_FORMAT_XRGB8888:
-		tinydrm_xrgb8888_to_rgb565(dst, src, fb, clip, swap);
+	case MIPI_DCS_PIXEL_FMT_ST7586_332:
+		switch (fb->format->format) {
+		case DRM_FORMAT_RGB565:
+			tinydrm_rgb565_to_st7586(dst, src, fb, clip);
+			break;
+		case DRM_FORMAT_XRGB8888:
+			tinydrm_xrgb8888_to_st7586(dst, src, fb, clip);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
 		break;
 	default:
+		ret = -EINVAL;
+		break;
+	}
+	if (ret) {
 		dev_err_once(fb->dev->dev, "Format is not supported: %s\n",
-			     drm_get_format_name(fb->format->format,
-						 &format_name));
-		return -EINVAL;
+			drm_get_format_name(fb->format->format,
+						&format_name));
+		return ret;
 	}
 
 	if (import_attach)
@@ -204,8 +229,9 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
 	bool swap = mipi->swap_bytes;
 	struct drm_clip_rect clip;
 	int ret = 0;
-	bool full;
+	bool full, pixel_fmt_match;
 	void *tr;
+	size_t len;
 
 	mutex_lock(&tdev->dirty_lock);
 
@@ -218,20 +244,24 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
 
 	full = tinydrm_merge_clips(&clip, clips, num_clips, flags,
 				   fb->width, fb->height);
+	pixel_fmt_match = !swap && fb->format->format == DRM_FORMAT_RGB565 &&
+				mipi->pixel_fmt == MIPI_DCS_PIXEL_FMT_16BIT;
 
 	DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id,
 		  clip.x1, clip.x2, clip.y1, clip.y2);
 
-	if (!mipi->dc || !full || swap ||
-	    fb->format->format == DRM_FORMAT_XRGB8888) {
+	if (!mipi->dc || !full || !pixel_fmt_match) {
 		tr = mipi->tx_buf;
-		ret = mipi_dbi_buf_copy(mipi->tx_buf, fb, &clip, swap);
+		ret = mipi_dbi_buf_copy(mipi->tx_buf, fb, &clip,
+					mipi->pixel_fmt, swap);
 		if (ret)
 			goto out_unlock;
 	} else {
 		tr = cma_obj->vaddr;
 	}
 
+	/* NB: mipi_dbi_buf_copy() may modify clip! */
+
 	mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
 			 (clip.x1 >> 8) & 0xFF, clip.x1 & 0xFF,
 			 (clip.x2 >> 8) & 0xFF, (clip.x2 - 1) & 0xFF);
@@ -239,8 +269,16 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
 			 (clip.y1 >> 8) & 0xFF, clip.y1 & 0xFF,
 			 (clip.y2 >> 8) & 0xFF, (clip.y2 - 1) & 0xFF);
 
-	ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, tr,
-				(clip.x2 - clip.x1) * (clip.y2 - clip.y1) * 2);
+	len = (clip.x2 - clip.x1) * (clip.y2 - clip.y1);
+	switch (mipi->pixel_fmt) {
+	case MIPI_DCS_PIXEL_FMT_16BIT:
+		len *= sizeof(u16);
+		break;
+	default:
+		break;
+	}
+
+	ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, tr, len);
 
 out_unlock:
 	mutex_unlock(&tdev->dirty_lock);
@@ -288,7 +326,20 @@ static void mipi_dbi_blank(struct mipi_dbi *mipi)
 	struct drm_device *drm = mipi->tinydrm.drm;
 	u16 height = drm->mode_config.min_height;
 	u16 width = drm->mode_config.min_width;
-	size_t len = width * height * 2;
+	size_t len;
+
+	switch (mipi->pixel_fmt) {
+	case MIPI_DCS_PIXEL_FMT_16BIT:
+		len = width * height * sizeof(u16);
+		break;
+	case MIPI_DCS_PIXEL_FMT_ST7586_332:
+		width = (width + 2) / 3;
+		len = width * height;
+		break;
+	default:
+		/* unsupported pixel format */
+		return;
+	}
 
 	memset(mipi->tx_buf, 0, len);
 
@@ -367,6 +418,10 @@ int mipi_dbi_init(struct device *dev, struct mipi_dbi *mipi,
 	case MIPI_DCS_PIXEL_FMT_16BIT:
 		bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
 		break;
+	case MIPI_DCS_PIXEL_FMT_ST7586_332:
+		/* 3 pixels per byte */
+		bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay;
+		break;
 	default:
 		DRM_ERROR("Pixel format is not supported\n");
 		return -EINVAL;
@@ -776,7 +831,8 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 cmd,
 	if (ret || !num)
 		return ret;
 
-	if (cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
+	if (cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes &&
+	    mipi->pixel_fmt != MIPI_DCS_PIXEL_FMT_ST7586_332)
 		bpw = 16;
 
 	gpiod_set_value_cansleep(mipi->dc, 1);
diff --git a/include/drm/tinydrm/tinydrm-helpers.h b/include/drm/tinydrm/tinydrm-helpers.h
index 9b9b6cf..94792fb 100644
--- a/include/drm/tinydrm/tinydrm-helpers.h
+++ b/include/drm/tinydrm/tinydrm-helpers.h
@@ -43,6 +43,12 @@ void tinydrm_swab16(u16 *dst, void *vaddr, struct drm_framebuffer *fb,
 void tinydrm_xrgb8888_to_rgb565(u16 *dst, void *vaddr,
 				struct drm_framebuffer *fb,
 				struct drm_clip_rect *clip, bool swap);
+void tinydrm_rgb565_to_st7586(u8 *dst, void *vaddr,
+				struct drm_framebuffer *fb,
+				struct drm_clip_rect *clip);
+void tinydrm_xrgb8888_to_st7586(u8 *dst, void *vaddr,
+				struct drm_framebuffer *fb,
+				struct drm_clip_rect *clip);
 
 struct backlight_device *tinydrm_of_find_backlight(struct device *dev);
 int tinydrm_enable_backlight(struct backlight_device *backlight);
diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h
index 84b70cd..1c134c4 100644
--- a/include/video/mipi_display.h
+++ b/include/video/mipi_display.h
@@ -135,6 +135,8 @@ enum mipi_dcs_pixel_format {
 	MIPI_DCS_PIXEL_FMT_12BIT	= 3,
 	MIPI_DCS_PIXEL_FMT_8BIT		= 2,
 	MIPI_DCS_PIXEL_FMT_3BIT		= 1,
+	/* non-standard format packing 1 or 2bpp in 3:3:2 bits */
+	MIPI_DCS_PIXEL_FMT_ST7586_332	= -1,
 };
 
 #endif
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1699595 — Re: [PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-07-30 20:20 +0200
SubjectRe: [PATCH 2/6] drm/tinydrm: add helpers for ST7586 controllers
Message-ID<u90YO-3NX-3@gated-at.bofh.it>
In reply to#1699349
On Sat, Jul 29, 2017 at 10:17 PM, David Lechner <david@lechnology.com> wrote:
> This adds helper functions and support for ST7586 controllers. These
> controllers have an unusual memory layout where 3 pixels are packed into
> 1 byte.
>
> +-------+-----------------+
> | bit   | 7 6 5 4 3 2 1 0 |
> +-------+-----------------+
> | pixel | 0 0 0 1 1 1 2 2 |
> +-------+-----------------+
>
> So, there are a nuber of places in the tinydrm pipline where this format

number

> needs to be taken into consideration.

> + * tinydrm_rgb565_to_st7586 - Convert RGB565 to ST7586 clip buffer

How this can be generic tinydrm helper?
Why driver can't handle it by its own and avoid spreading stuff into
generic header?

> +void tinydrm_rgb565_to_st7586(u8 *dst, void *vaddr,

> + * tinydrm_xrgb8888_to_st7586 - Convert XRGB8888 to ST7586 clip buffer

> +void tinydrm_xrgb8888_to_st7586(u8 *dst, void *vaddr,

Ditto.

> -       switch (fb->format->format) {
> -       case DRM_FORMAT_RGB565:
> -               if (swap)
> -                       tinydrm_swab16(dst, src, fb, clip);
> -               else
> -                       tinydrm_memcpy(dst, src, fb, clip);
> +       switch (pixel_fmt) {
> +       case MIPI_DCS_PIXEL_FMT_16BIT:
> +               switch (fb->format->format) {
> +               case DRM_FORMAT_RGB565:
> +                       if (swap)
> +                               tinydrm_swab16(dst, src, fb, clip);
> +                       else
> +                               tinydrm_memcpy(dst, src, fb, clip);
> +                       break;

Can't you use some other approach? Callbacks? Plugins?

> +       switch (mipi->pixel_fmt) {
> +       case MIPI_DCS_PIXEL_FMT_16BIT:
> +               len = width * height * sizeof(u16);
> +               break;
> +       case MIPI_DCS_PIXEL_FMT_ST7586_332:
> +               width = (width + 2) / 3;
> +               len = width * height;
> +               break;

Ditto.

> +       case MIPI_DCS_PIXEL_FMT_ST7586_332:
> +               /* 3 pixels per byte */
> +               bufsize = (mode->vdisplay + 2) / 3 * mode->hdisplay;
> +               break;

Ditto.

> -       if (cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes)
> +       if (cmd == MIPI_DCS_WRITE_MEMORY_START && !mipi->swap_bytes &&
> +           mipi->pixel_fmt != MIPI_DCS_PIXEL_FMT_ST7586_332)

Ditto.

If we allow this we end up to have 100500 LOCs in tinydrm-helpers.c
which will have nothing to do with the framework itself.



-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1699354

FromDavid Lechner <david@lechnology.com>
Date2017-07-29 21:50 +0200
Message-ID<u8FUl-6S9-9@gated-at.bofh.it>
In reply to#1699344
On 07/29/2017 02:17 PM, David Lechner wrote:
> The goal of this series is to get the built-in LCD of the LEGO MINDSTORMS EV3
> working. But, most of the content here is building up the infrastructure to do
> that.
> 

Some general comments/questions:

I have noticed that DRM doesn't really have support for monochrome 
displays. I'm guessing that is because no one really uses them anymore?

The LEGO EV3 display is just an LCD (not the backlit kind). It has two 
modes of operation. It can to 2bbp grayscale or it can do 1bpp 
monochrome. The grayscale isn't the best (looks splotchy in places), so 
it would be nice to be able to choose between these two modes. How would 
I implement something like that?

Also, how can I indicate to userspace that this display really is 
monochrome/grayscale since the reported color depth 16bpp?

[toc] | [prev] | [next] | [standalone]


#1699583

FromNoralf Trønnes <noralf@tronnes.org>
Date2017-07-30 19:20 +0200
Message-ID<u902J-3bi-7@gated-at.bofh.it>
In reply to#1699354
Den 29.07.2017 21.40, skrev David Lechner:
> On 07/29/2017 02:17 PM, David Lechner wrote:
>> The goal of this series is to get the built-in LCD of the LEGO 
>> MINDSTORMS EV3
>> working. But, most of the content here is building up the 
>> infrastructure to do
>> that.
>>
>
> Some general comments/questions:
>
> I have noticed that DRM doesn't really have support for monochrome 
> displays. I'm guessing that is because no one really uses them anymore?
>

The repaper driver was the first monochrome drm driver and I chose to
present it to userspace as XRGB8888 and convert it to monochrome.
The reason for this is that everything, libraries, apps, plymouth (boot
splash, no rgb565) supports it. I didn't see any point in adding a new
monochrome drm format that didn't have, or probably wouldn't get
userspace support (by libraries at least). The application of course
needs to know this to get a good result.

tinydrm_xrgb8888_to_gray8() does the conversion:
https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781

> The LEGO EV3 display is just an LCD (not the backlit kind). It has two 
> modes of operation. It can to 2bbp grayscale or it can do 1bpp 
> monochrome. The grayscale isn't the best (looks splotchy in places), 
> so it would be nice to be able to choose between these two modes. How 
> would I implement something like that?
>

Do you expect anyone to use grayscale if it doesn't look good?
Maybe better to add it later if there's a demand for it.

> Also, how can I indicate to userspace that this display really is 
> monochrome/grayscale since the reported color depth 16bpp?
>

There isn't unless we add formats for it.
Since this display is in a Lego piece, doesn't it have custom userspace
that already know it's monochrome?

Noralf.

[toc] | [prev] | [next] | [standalone]


#1701241

FromDavid Lechner <david@lechnology.com>
Date2017-08-01 19:00 +0200
Message-ID<u9IGt-6pq-7@gated-at.bofh.it>
In reply to#1699583
On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
> 
> Den 29.07.2017 21.40, skrev David Lechner:
>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>> The goal of this series is to get the built-in LCD of the LEGO 
>>> MINDSTORMS EV3
>>> working. But, most of the content here is building up the 
>>> infrastructure to do
>>> that.
>>>
>>
>> Some general comments/questions:
>>
>> I have noticed that DRM doesn't really have support for monochrome 
>> displays. I'm guessing that is because no one really uses them anymore?
>>
> 
> The repaper driver was the first monochrome drm driver and I chose to
> present it to userspace as XRGB8888 and convert it to monochrome.
> The reason for this is that everything, libraries, apps, plymouth (boot
> splash, no rgb565) supports it. I didn't see any point in adding a new
> monochrome drm format that didn't have, or probably wouldn't get
> userspace support (by libraries at least). The application of course
> needs to know this to get a good result.
> 
> tinydrm_xrgb8888_to_gray8() does the conversion:
> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
> 
> 
>> The LEGO EV3 display is just an LCD (not the backlit kind). It has two 
>> modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>> monochrome. The grayscale isn't the best (looks splotchy in places), 
>> so it would be nice to be able to choose between these two modes. How 
>> would I implement something like that?
>>
> 
> Do you expect anyone to use grayscale if it doesn't look good?
> Maybe better to add it later if there's a demand for it.

I don't expect many people to use it at all. The people that do will be 
hackers like me that want to see what it is capable of, so I think I 
will keep it grayscale by default.

> 
>> Also, how can I indicate to userspace that this display really is 
>> monochrome/grayscale since the reported color depth 16bpp?
>>
> 
> There isn't unless we add formats for it.
> Since this display is in a Lego piece, doesn't it have custom userspace
> that already know it's monochrome?

The official LEGO software is like this, yes. But I am working on a 
project that supports other LEGO compatible devices that have color 
screens, so the same software needs to be able to detect at runtime 
which type of screen it is using. Currently I have a plain fbdev driver 
that provides FB_VISUAL_MONO10 for the EV3 display and so the software 
knows when it has a monochrome screen and when it doesn't. But since 
plain fbdev drivers can't be accepted into mainline, I need to find a 
different way to detect what type of screen this is so that my graphics 
library can treat it differently.

[toc] | [prev] | [next] | [standalone]


#1701302

FromNoralf Trønnes <noralf@tronnes.org>
Date2017-08-01 20:10 +0200
Message-ID<u9JMe-7ne-17@gated-at.bofh.it>
In reply to#1701241
(cc: Daniel Vetter)


Den 01.08.2017 18.51, skrev David Lechner:
> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>
>> Den 29.07.2017 21.40, skrev David Lechner:
>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>> MINDSTORMS EV3
>>>> working. But, most of the content here is building up the 
>>>> infrastructure to do
>>>> that.
>>>>
>>>
>>> Some general comments/questions:
>>>
>>> I have noticed that DRM doesn't really have support for monochrome 
>>> displays. I'm guessing that is because no one really uses them anymore?
>>>
>>
>> The repaper driver was the first monochrome drm driver and I chose to
>> present it to userspace as XRGB8888 and convert it to monochrome.
>> The reason for this is that everything, libraries, apps, plymouth (boot
>> splash, no rgb565) supports it. I didn't see any point in adding a new
>> monochrome drm format that didn't have, or probably wouldn't get
>> userspace support (by libraries at least). The application of course
>> needs to know this to get a good result.
>>
>> tinydrm_xrgb8888_to_gray8() does the conversion:
>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>
>>
>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>> monochrome. The grayscale isn't the best (looks splotchy in places), 
>>> so it would be nice to be able to choose between these two modes. 
>>> How would I implement something like that?
>>>
>>
>> Do you expect anyone to use grayscale if it doesn't look good?
>> Maybe better to add it later if there's a demand for it.
>
> I don't expect many people to use it at all. The people that do will 
> be hackers like me that want to see what it is capable of, so I think 
> I will keep it grayscale by default.
>

It looks like the best way to satisfy your needs is to add specific formats.

Video for Linux have these:

include/uapi/linux/videodev2.h

/* Grey formats */
#define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /*  8 
Greyscale     */
#define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*  4 
Greyscale     */
#define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /*  6 
Greyscale     */
#define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
Greyscale     */
#define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
Greyscale     */
#define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
Greyscale     */
#define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16  
Greyscale BE  */


Maybe we can add formats like these:

include/uapi/drm/drm_fourcc.h

#define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
Monochrome */
or
#define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
Monochrome */

#define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
Greyscale */

Daniel, what do you think?

>>
>>> Also, how can I indicate to userspace that this display really is 
>>> monochrome/grayscale since the reported color depth 16bpp?
>>>
>>
>> There isn't unless we add formats for it.
>> Since this display is in a Lego piece, doesn't it have custom userspace
>> that already know it's monochrome?
>
> The official LEGO software is like this, yes. But I am working on a 
> project that supports other LEGO compatible devices that have color 
> screens, so the same software needs to be able to detect at runtime 
> which type of screen it is using. Currently I have a plain fbdev 
> driver that provides FB_VISUAL_MONO10 for the EV3 display and so the 
> software knows when it has a monochrome screen and when it doesn't. 
> But since plain fbdev drivers can't be accepted into mainline, I need 
> to find a different way to detect what type of screen this is so that 
> my graphics library can treat it differently.
>
>

You can tell userspace about the preferred bitdepth:
drm->mode_config.preferred_depth


Noralf.

[toc] | [prev] | [next] | [standalone]


#1701547

FromDavid Lechner <david@lechnology.com>
Date2017-08-02 00:30 +0200
Message-ID<u9NPQ-1sk-13@gated-at.bofh.it>
In reply to#1701302
On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
> (cc: Daniel Vetter)
> 
> 
> Den 01.08.2017 18.51, skrev David Lechner:
>> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>>
>>> Den 29.07.2017 21.40, skrev David Lechner:
>>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>>> MINDSTORMS EV3
>>>>> working. But, most of the content here is building up the 
>>>>> infrastructure to do
>>>>> that.
>>>>>
>>>>
>>>> Some general comments/questions:
>>>>
>>>> I have noticed that DRM doesn't really have support for monochrome 
>>>> displays. I'm guessing that is because no one really uses them anymore?
>>>>
>>>
>>> The repaper driver was the first monochrome drm driver and I chose to
>>> present it to userspace as XRGB8888 and convert it to monochrome.
>>> The reason for this is that everything, libraries, apps, plymouth (boot
>>> splash, no rgb565) supports it. I didn't see any point in adding a new
>>> monochrome drm format that didn't have, or probably wouldn't get
>>> userspace support (by libraries at least). The application of course
>>> needs to know this to get a good result.
>>>
>>> tinydrm_xrgb8888_to_gray8() does the conversion:
>>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>>
>>>
>>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>>> monochrome. The grayscale isn't the best (looks splotchy in places), 
>>>> so it would be nice to be able to choose between these two modes. 
>>>> How would I implement something like that?
>>>>
>>>
>>> Do you expect anyone to use grayscale if it doesn't look good?
>>> Maybe better to add it later if there's a demand for it.
>>
>> I don't expect many people to use it at all. The people that do will 
>> be hackers like me that want to see what it is capable of, so I think 
>> I will keep it grayscale by default.
>>
> 
> It looks like the best way to satisfy your needs is to add specific 
> formats.
> 
> Video for Linux have these:
> 
> include/uapi/linux/videodev2.h
> 
> /* Grey formats */
> #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /*  8 
> Greyscale     */
> #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*  4 
> Greyscale     */
> #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /*  6 
> Greyscale     */
> #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
> Greyscale     */
> #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
> Greyscale     */
> #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
> Greyscale     */
> #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 
> Greyscale BE  */
> 
> 
> Maybe we can add formats like these:
> 
> include/uapi/drm/drm_fourcc.h
> 
> #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
> Monochrome */
> or
> #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
> Monochrome */
> 
> #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
> Greyscale */
> 
> Daniel, what do you think?

2 of the first 3 tinydrm drivers are monochrome (and I would like to 
write a driver for the Seeed/Grove I2C OLED displays which are also 
monochrome), so I think the 1bpp modes would definitely be useful. I 
think there is enough userspace code still around that knows about 
FB_VISUAL_MONO01 and FB_VISUAL_MONO10 that could use these.

I don't think a Y02 mode would be useful though. There is pretty much 
nothing out there (that I could find) that uses such a mode.

A Y08 mode for 8bpp grayscale would be useful though. This is another 
more commonly used format.

> 
>>>
>>>> Also, how can I indicate to userspace that this display really is 
>>>> monochrome/grayscale since the reported color depth 16bpp?
>>>>
>>>
>>> There isn't unless we add formats for it.
>>> Since this display is in a Lego piece, doesn't it have custom userspace
>>> that already know it's monochrome?
>>
>> The official LEGO software is like this, yes. But I am working on a 
>> project that supports other LEGO compatible devices that have color 
>> screens, so the same software needs to be able to detect at runtime 
>> which type of screen it is using. Currently I have a plain fbdev 
>> driver that provides FB_VISUAL_MONO10 for the EV3 display and so the 
>> software knows when it has a monochrome screen and when it doesn't. 
>> But since plain fbdev drivers can't be accepted into mainline, I need 
>> to find a different way to detect what type of screen this is so that 
>> my graphics library can treat it differently.
>>
>>
> 
> You can tell userspace about the preferred bitdepth:
> drm->mode_config.preferred_depth
> 
> 
> Noralf.
> 

[toc] | [prev] | [next] | [standalone]


#1701823

FromNoralf Trønnes <noralf@tronnes.org>
Date2017-08-02 10:10 +0200
Message-ID<u9WT7-7j8-5@gated-at.bofh.it>
In reply to#1701547
Den 02.08.2017 00.26, skrev David Lechner:
> On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
>> (cc: Daniel Vetter)
>>
>>
>> Den 01.08.2017 18.51, skrev David Lechner:
>>> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>>>
>>>> Den 29.07.2017 21.40, skrev David Lechner:
>>>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>>>> MINDSTORMS EV3
>>>>>> working. But, most of the content here is building up the 
>>>>>> infrastructure to do
>>>>>> that.
>>>>>>
>>>>>
>>>>> Some general comments/questions:
>>>>>
>>>>> I have noticed that DRM doesn't really have support for monochrome 
>>>>> displays. I'm guessing that is because no one really uses them 
>>>>> anymore?
>>>>>
>>>>
>>>> The repaper driver was the first monochrome drm driver and I chose to
>>>> present it to userspace as XRGB8888 and convert it to monochrome.
>>>> The reason for this is that everything, libraries, apps, plymouth 
>>>> (boot
>>>> splash, no rgb565) supports it. I didn't see any point in adding a new
>>>> monochrome drm format that didn't have, or probably wouldn't get
>>>> userspace support (by libraries at least). The application of course
>>>> needs to know this to get a good result.
>>>>
>>>> tinydrm_xrgb8888_to_gray8() does the conversion:
>>>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>>>
>>>>
>>>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>>>> monochrome. The grayscale isn't the best (looks splotchy in 
>>>>> places), so it would be nice to be able to choose between these 
>>>>> two modes. How would I implement something like that?
>>>>>
>>>>
>>>> Do you expect anyone to use grayscale if it doesn't look good?
>>>> Maybe better to add it later if there's a demand for it.
>>>
>>> I don't expect many people to use it at all. The people that do will 
>>> be hackers like me that want to see what it is capable of, so I 
>>> think I will keep it grayscale by default.
>>>
>>
>> It looks like the best way to satisfy your needs is to add specific 
>> formats.
>>
>> Video for Linux have these:
>>
>> include/uapi/linux/videodev2.h
>>
>> /* Grey formats */
>> #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /* 4 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /* 6 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 
>> Greyscale BE  */
>>
>>
>> Maybe we can add formats like these:
>>
>> include/uapi/drm/drm_fourcc.h
>>
>> #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
>> Monochrome */
>> or
>> #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
>> Monochrome */
>>
>> #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
>> Greyscale */
>>
>> Daniel, what do you think?
>
> 2 of the first 3 tinydrm drivers are monochrome (and I would like to 
> write a driver for the Seeed/Grove I2C OLED displays which are also 
> monochrome), so I think the 1bpp modes would definitely be useful. I 
> think there is enough userspace code still around that knows about 
> FB_VISUAL_MONO01 and FB_VISUAL_MONO10 that could use these.
>

Can you elaborate, would you use the display trough monochrome fbdev
or through drm?

> I don't think a Y02 mode would be useful though. There is pretty much 
> nothing out there (that I could find) that uses such a mode.
>
> A Y08 mode for 8bpp grayscale would be useful though. This is another 
> more commonly used format.
>

Another source of fourcc's is FFmpeg which has these:

     { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', '0', '0') },
     { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', ' ', ' ') },
     { AV_PIX_FMT_GRAY8,   MKTAG('G', 'R', 'E', 'Y') },

     { AV_PIX_FMT_MONOWHITE,MKTAG('B', '1', 'W', '0') },
     { AV_PIX_FMT_MONOBLACK,MKTAG('B', '0', 'W', '1') },

AV_PIX_FMT_GRAY8
Y , 8bpp.
AV_PIX_FMT_MONOWHITE
Y , 1bpp, 0 is white, 1 is black,
     in each byte pixels are ordered from the msb to the lsb.
AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white,
     in each byte pixels are ordered from the msb to the lsb.


__drm_format_info() provides details about formats:
     { .format = DRM_FORMAT_MONO,    .depth = 1,  .num_planes = 1, .cpp 
= { 0, 0, 0 }, .hsub = 1, .vsub = 1 },
     { .format = DRM_FORMAT_GREY,    .depth = 8,  .num_planes = 1, .cpp 
= { 1, 0, 0 }, .hsub = 1, .vsub = 1 },

framebuffer_check() and drm_fb_cma_create_with_funcs() use cpp for
validation and they don't expect it to be zero.


Noralf.

>>
>>>>
>>>>> Also, how can I indicate to userspace that this display really is 
>>>>> monochrome/grayscale since the reported color depth 16bpp?
>>>>>
>>>>
>>>> There isn't unless we add formats for it.
>>>> Since this display is in a Lego piece, doesn't it have custom 
>>>> userspace
>>>> that already know it's monochrome?
>>>
>>> The official LEGO software is like this, yes. But I am working on a 
>>> project that supports other LEGO compatible devices that have color 
>>> screens, so the same software needs to be able to detect at runtime 
>>> which type of screen it is using. Currently I have a plain fbdev 
>>> driver that provides FB_VISUAL_MONO10 for the EV3 display and so the 
>>> software knows when it has a monochrome screen and when it doesn't. 
>>> But since plain fbdev drivers can't be accepted into mainline, I 
>>> need to find a different way to detect what type of screen this is 
>>> so that my graphics library can treat it differently.
>>>
>>>
>>
>> You can tell userspace about the preferred bitdepth:
>> drm->mode_config.preferred_depth
>>
>>
>> Noralf.
>>
>

[toc] | [prev] | [next] | [standalone]


#1702229

FromDavid Lechner <david@lechnology.com>
Date2017-08-02 18:10 +0200
Message-ID<ua4nG-3Eo-55@gated-at.bofh.it>
In reply to#1701823
On 08/02/2017 03:05 AM, Noralf Trønnes wrote:
> 
> Den 02.08.2017 00.26, skrev David Lechner:
>> On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
>>> (cc: Daniel Vetter)
>>>
>>>
>>> Den 01.08.2017 18.51, skrev David Lechner:
>>>> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>>>>
>>>>> Den 29.07.2017 21.40, skrev David Lechner:
>>>>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>>>>> MINDSTORMS EV3
>>>>>>> working. But, most of the content here is building up the 
>>>>>>> infrastructure to do
>>>>>>> that.
>>>>>>>
>>>>>>
>>>>>> Some general comments/questions:
>>>>>>
>>>>>> I have noticed that DRM doesn't really have support for monochrome 
>>>>>> displays. I'm guessing that is because no one really uses them 
>>>>>> anymore?
>>>>>>
>>>>>
>>>>> The repaper driver was the first monochrome drm driver and I chose to
>>>>> present it to userspace as XRGB8888 and convert it to monochrome.
>>>>> The reason for this is that everything, libraries, apps, plymouth 
>>>>> (boot
>>>>> splash, no rgb565) supports it. I didn't see any point in adding a new
>>>>> monochrome drm format that didn't have, or probably wouldn't get
>>>>> userspace support (by libraries at least). The application of course
>>>>> needs to know this to get a good result.
>>>>>
>>>>> tinydrm_xrgb8888_to_gray8() does the conversion:
>>>>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>>>>
>>>>>
>>>>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>>>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>>>>> monochrome. The grayscale isn't the best (looks splotchy in 
>>>>>> places), so it would be nice to be able to choose between these 
>>>>>> two modes. How would I implement something like that?
>>>>>>
>>>>>
>>>>> Do you expect anyone to use grayscale if it doesn't look good?
>>>>> Maybe better to add it later if there's a demand for it.
>>>>
>>>> I don't expect many people to use it at all. The people that do will 
>>>> be hackers like me that want to see what it is capable of, so I 
>>>> think I will keep it grayscale by default.
>>>>
>>>
>>> It looks like the best way to satisfy your needs is to add specific 
>>> formats.
>>>
>>> Video for Linux have these:
>>>
>>> include/uapi/linux/videodev2.h
>>>
>>> /* Grey formats */
>>> #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /* 4 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /* 6 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 
>>> Greyscale BE  */
>>>
>>>
>>> Maybe we can add formats like these:
>>>
>>> include/uapi/drm/drm_fourcc.h
>>>
>>> #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
>>> Monochrome */
>>> or
>>> #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
>>> Monochrome */
>>>
>>> #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
>>> Greyscale */
>>>
>>> Daniel, what do you think?
>>
>> 2 of the first 3 tinydrm drivers are monochrome (and I would like to 
>> write a driver for the Seeed/Grove I2C OLED displays which are also 
>> monochrome), so I think the 1bpp modes would definitely be useful. I 
>> think there is enough userspace code still around that knows about 
>> FB_VISUAL_MONO01 and FB_VISUAL_MONO10 that could use these.
>>
> 
> Can you elaborate, would you use the display trough monochrome fbdev
> or through drm?

I have a small collection of programs and libraries that work using 
monochrome fbdev. I would like to just keep using them without having to 
convert everything to drm.


>> I don't think a Y02 mode would be useful though. There is pretty much 
>> nothing out there (that I could find) that uses such a mode.
>>
>> A Y08 mode for 8bpp grayscale would be useful though. This is another 
>> more commonly used format.
>>
> 
> Another source of fourcc's is FFmpeg which has these:
> 
>      { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', '0', '0') },
>      { AV_PIX_FMT_GRAY8,    MKTAG('Y', '8', ' ', ' ') },
>      { AV_PIX_FMT_GRAY8,   MKTAG('G', 'R', 'E', 'Y') },
> 
>      { AV_PIX_FMT_MONOWHITE,MKTAG('B', '1', 'W', '0') },
>      { AV_PIX_FMT_MONOBLACK,MKTAG('B', '0', 'W', '1') },
> 
> AV_PIX_FMT_GRAY8
> Y , 8bpp.
> AV_PIX_FMT_MONOWHITE
> Y , 1bpp, 0 is white, 1 is black,
>      in each byte pixels are ordered from the msb to the lsb.
> AV_PIX_FMT_MONOBLACK
> Y , 1bpp, 0 is black, 1 is white,
>      in each byte pixels are ordered from the msb to the lsb.
> 
> 
> __drm_format_info() provides details about formats:
>      { .format = DRM_FORMAT_MONO,    .depth = 1,  .num_planes = 1, .cpp 
> = { 0, 0, 0 }, .hsub = 1, .vsub = 1 },
>      { .format = DRM_FORMAT_GREY,    .depth = 8,  .num_planes = 1, .cpp 
> = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
> 
> framebuffer_check() and drm_fb_cma_create_with_funcs() use cpp for
> validation and they don't expect it to be zero.
> 
> 
> Noralf.
> 
>>>
>>>>>
>>>>>> Also, how can I indicate to userspace that this display really is 
>>>>>> monochrome/grayscale since the reported color depth 16bpp?
>>>>>>
>>>>>
>>>>> There isn't unless we add formats for it.
>>>>> Since this display is in a Lego piece, doesn't it have custom 
>>>>> userspace
>>>>> that already know it's monochrome?
>>>>
>>>> The official LEGO software is like this, yes. But I am working on a 
>>>> project that supports other LEGO compatible devices that have color 
>>>> screens, so the same software needs to be able to detect at runtime 
>>>> which type of screen it is using. Currently I have a plain fbdev 
>>>> driver that provides FB_VISUAL_MONO10 for the EV3 display and so the 
>>>> software knows when it has a monochrome screen and when it doesn't. 
>>>> But since plain fbdev drivers can't be accepted into mainline, I 
>>>> need to find a different way to detect what type of screen this is 
>>>> so that my graphics library can treat it differently.
>>>>
>>>>
>>>
>>> You can tell userspace about the preferred bitdepth:
>>> drm->mode_config.preferred_depth
>>>
>>>
>>> Noralf.
>>>
>>
> 

[toc] | [prev] | [next] | [standalone]


#1702879

FromDaniel Vetter <daniel@ffwll.ch>
Date2017-08-03 12:10 +0200
Message-ID<ualeP-6Uy-23@gated-at.bofh.it>
In reply to#1702229
On Wed, Aug 02, 2017 at 11:05:58AM -0500, David Lechner wrote:
> On 08/02/2017 03:05 AM, Noralf Trønnes wrote:
> > 
> > Den 02.08.2017 00.26, skrev David Lechner:
> > > On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
> > > > (cc: Daniel Vetter)
> > > > 
> > > > 
> > > > Den 01.08.2017 18.51, skrev David Lechner:
> > > > > On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
> > > > > > 
> > > > > > Den 29.07.2017 21.40, skrev David Lechner:
> > > > > > > On 07/29/2017 02:17 PM, David Lechner wrote:
> > > > > > > > The goal of this series is to get the built-in
> > > > > > > > LCD of the LEGO MINDSTORMS EV3
> > > > > > > > working. But, most of the content here is
> > > > > > > > building up the infrastructure to do
> > > > > > > > that.
> > > > > > > > 
> > > > > > > 
> > > > > > > Some general comments/questions:
> > > > > > > 
> > > > > > > I have noticed that DRM doesn't really have support
> > > > > > > for monochrome displays. I'm guessing that is
> > > > > > > because no one really uses them anymore?
> > > > > > > 
> > > > > > 
> > > > > > The repaper driver was the first monochrome drm driver and I chose to
> > > > > > present it to userspace as XRGB8888 and convert it to monochrome.
> > > > > > The reason for this is that everything, libraries, apps,
> > > > > > plymouth (boot
> > > > > > splash, no rgb565) supports it. I didn't see any point in adding a new
> > > > > > monochrome drm format that didn't have, or probably wouldn't get
> > > > > > userspace support (by libraries at least). The application of course
> > > > > > needs to know this to get a good result.
> > > > > > 
> > > > > > tinydrm_xrgb8888_to_gray8() does the conversion:
> > > > > > https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781
> > > > > > 
> > > > > > 
> > > > > > > The LEGO EV3 display is just an LCD (not the backlit
> > > > > > > kind). It has two modes of operation. It can to 2bbp
> > > > > > > grayscale or it can do 1bpp monochrome. The
> > > > > > > grayscale isn't the best (looks splotchy in places),
> > > > > > > so it would be nice to be able to choose between
> > > > > > > these two modes. How would I implement something
> > > > > > > like that?
> > > > > > > 
> > > > > > 
> > > > > > Do you expect anyone to use grayscale if it doesn't look good?
> > > > > > Maybe better to add it later if there's a demand for it.
> > > > > 
> > > > > I don't expect many people to use it at all. The people that
> > > > > do will be hackers like me that want to see what it is
> > > > > capable of, so I think I will keep it grayscale by default.
> > > > > 
> > > > 
> > > > It looks like the best way to satisfy your needs is to add
> > > > specific formats.
> > > > 
> > > > Video for Linux have these:
> > > > 
> > > > include/uapi/linux/videodev2.h
> > > > 
> > > > /* Grey formats */
> > > > #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /*
> > > > 8 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*
> > > > 4 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /*
> > > > 6 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /*
> > > > 10 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /*
> > > > 12 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /*
> > > > 16 Greyscale     */
> > > > #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ')
> > > > /* 16 Greyscale BE  */
> > > > 
> > > > 
> > > > Maybe we can add formats like these:
> > > > 
> > > > include/uapi/drm/drm_fourcc.h
> > > > 
> > > > #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ')
> > > > /* [0] Monochrome */
> > > > or
> > > > #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /*
> > > > [0] Monochrome */
> > > > 
> > > > #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /*
> > > > [1:0] Greyscale */
> > > > 
> > > > Daniel, what do you think?
> > > 
> > > 2 of the first 3 tinydrm drivers are monochrome (and I would like to
> > > write a driver for the Seeed/Grove I2C OLED displays which are also
> > > monochrome), so I think the 1bpp modes would definitely be useful. I
> > > think there is enough userspace code still around that knows about
> > > FB_VISUAL_MONO01 and FB_VISUAL_MONO10 that could use these.
> > > 
> > 
> > Can you elaborate, would you use the display trough monochrome fbdev
> > or through drm?
> 
> I have a small collection of programs and libraries that work using
> monochrome fbdev. I would like to just keep using them without having to
> convert everything to drm.

That probably means we'd need to extend fbdev emulation helpers in drm to
support Monochrome modes better. Shouldn't be that much work really.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

[toc] | [prev] | [next] | [standalone]


#1703151

FromNoralf Trønnes <noralf@tronnes.org>
Date2017-08-03 16:10 +0200
Message-ID<uaoZ4-12B-9@gated-at.bofh.it>
In reply to#1701547
Den 02.08.2017 00.26, skrev David Lechner:
> On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
>> (cc: Daniel Vetter)
>>
>>
>> Den 01.08.2017 18.51, skrev David Lechner:
>>> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>>>
>>>> Den 29.07.2017 21.40, skrev David Lechner:
>>>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>>>> MINDSTORMS EV3
>>>>>> working. But, most of the content here is building up the 
>>>>>> infrastructure to do
>>>>>> that.
>>>>>>
>>>>>
>>>>> Some general comments/questions:
>>>>>
>>>>> I have noticed that DRM doesn't really have support for monochrome 
>>>>> displays. I'm guessing that is because no one really uses them 
>>>>> anymore?
>>>>>
>>>>
>>>> The repaper driver was the first monochrome drm driver and I chose to
>>>> present it to userspace as XRGB8888 and convert it to monochrome.
>>>> The reason for this is that everything, libraries, apps, plymouth 
>>>> (boot
>>>> splash, no rgb565) supports it. I didn't see any point in adding a new
>>>> monochrome drm format that didn't have, or probably wouldn't get
>>>> userspace support (by libraries at least). The application of course
>>>> needs to know this to get a good result.
>>>>
>>>> tinydrm_xrgb8888_to_gray8() does the conversion:
>>>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>>>
>>>>
>>>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>>>> monochrome. The grayscale isn't the best (looks splotchy in 
>>>>> places), so it would be nice to be able to choose between these 
>>>>> two modes. How would I implement something like that?
>>>>>
>>>>
>>>> Do you expect anyone to use grayscale if it doesn't look good?
>>>> Maybe better to add it later if there's a demand for it.
>>>
>>> I don't expect many people to use it at all. The people that do will 
>>> be hackers like me that want to see what it is capable of, so I 
>>> think I will keep it grayscale by default.
>>>
>>
>> It looks like the best way to satisfy your needs is to add specific 
>> formats.
>>
>> Video for Linux have these:
>>
>> include/uapi/linux/videodev2.h
>>
>> /* Grey formats */
>> #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /* 4 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /* 6 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
>> Greyscale     */
>> #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 
>> Greyscale BE  */
>>
>>
>> Maybe we can add formats like these:
>>
>> include/uapi/drm/drm_fourcc.h
>>
>> #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
>> Monochrome */
>> or
>> #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
>> Monochrome */
>>
>> #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
>> Greyscale */
>>
>> Daniel, what do you think?
>
> 2 of the first 3 tinydrm drivers are monochrome (and I would like to 
> write a driver for the Seeed/Grove I2C OLED displays which are also 
> monochrome), so I think the 1bpp modes would definitely be useful.

David, I'm curious about those displays what controller/interface they use.
I have been hoping that it would be possible to use regmap as an
abstraction for many of these controllers and their registers.

For MIPI DCS it wasn't possible because it's command oriented with
arguments. Since zero arguments is possible, a register with no value
is nonsense, even though the regmap implementation happily let me do it.
There's also the problem that regmap doesn't support registers with
different widths. Which is a problem if all registers are 8-bit wide,
except the GRAM register being 16-bit on RGB565 formats.

regmap is especially helpful with controllers that also have
gpios/keypad/touch/pwm, since the mfd (multi function device) subsystem
has good support for sharing regmaps between drivers. Multi function
devices are split into several drivers.

Noralf.

[toc] | [prev] | [next] | [standalone]


#1703187

FromDavid Lechner <david@lechnology.com>
Date2017-08-03 17:20 +0200
Message-ID<uaq4N-1Mc-3@gated-at.bofh.it>
In reply to#1703151
On 08/03/2017 09:07 AM, Noralf Trønnes wrote:
> 
> Den 02.08.2017 00.26, skrev David Lechner:
>> On 08/01/2017 01:08 PM, Noralf Trønnes wrote:
>>> (cc: Daniel Vetter)
>>>
>>>
>>> Den 01.08.2017 18.51, skrev David Lechner:
>>>> On 07/30/2017 12:14 PM, Noralf Trønnes wrote:
>>>>>
>>>>> Den 29.07.2017 21.40, skrev David Lechner:
>>>>>> On 07/29/2017 02:17 PM, David Lechner wrote:
>>>>>>> The goal of this series is to get the built-in LCD of the LEGO 
>>>>>>> MINDSTORMS EV3
>>>>>>> working. But, most of the content here is building up the 
>>>>>>> infrastructure to do
>>>>>>> that.
>>>>>>>
>>>>>>
>>>>>> Some general comments/questions:
>>>>>>
>>>>>> I have noticed that DRM doesn't really have support for monochrome 
>>>>>> displays. I'm guessing that is because no one really uses them 
>>>>>> anymore?
>>>>>>
>>>>>
>>>>> The repaper driver was the first monochrome drm driver and I chose to
>>>>> present it to userspace as XRGB8888 and convert it to monochrome.
>>>>> The reason for this is that everything, libraries, apps, plymouth 
>>>>> (boot
>>>>> splash, no rgb565) supports it. I didn't see any point in adding a new
>>>>> monochrome drm format that didn't have, or probably wouldn't get
>>>>> userspace support (by libraries at least). The application of course
>>>>> needs to know this to get a good result.
>>>>>
>>>>> tinydrm_xrgb8888_to_gray8() does the conversion:
>>>>> https://cgit.freedesktop.org/drm/drm-misc/commit/drivers/gpu/drm/tinydrm?id=379ea9a1a59a5a32c8db6f164e80a3fd00cb3781 
>>>>>
>>>>>
>>>>>> The LEGO EV3 display is just an LCD (not the backlit kind). It has 
>>>>>> two modes of operation. It can to 2bbp grayscale or it can do 1bpp 
>>>>>> monochrome. The grayscale isn't the best (looks splotchy in 
>>>>>> places), so it would be nice to be able to choose between these 
>>>>>> two modes. How would I implement something like that?
>>>>>>
>>>>>
>>>>> Do you expect anyone to use grayscale if it doesn't look good?
>>>>> Maybe better to add it later if there's a demand for it.
>>>>
>>>> I don't expect many people to use it at all. The people that do will 
>>>> be hackers like me that want to see what it is capable of, so I 
>>>> think I will keep it grayscale by default.
>>>>
>>>
>>> It looks like the best way to satisfy your needs is to add specific 
>>> formats.
>>>
>>> Video for Linux have these:
>>>
>>> include/uapi/linux/videodev2.h
>>>
>>> /* Grey formats */
>>> #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /* 4 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /* 6 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16 
>>> Greyscale     */
>>> #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16 
>>> Greyscale BE  */
>>>
>>>
>>> Maybe we can add formats like these:
>>>
>>> include/uapi/drm/drm_fourcc.h
>>>
>>> #define DRM_FORMAT_MONO        fourcc_code('Y', '0', '1', ' ') /* [0] 
>>> Monochrome */
>>> or
>>> #define DRM_FORMAT_Y1        fourcc_code('Y', '0', '1', ' ') /* [0] 
>>> Monochrome */
>>>
>>> #define DRM_FORMAT_Y2        fourcc_code('Y', '0', '2', ' ') /* [1:0] 
>>> Greyscale */
>>>
>>> Daniel, what do you think?
>>
>> 2 of the first 3 tinydrm drivers are monochrome (and I would like to 
>> write a driver for the Seeed/Grove I2C OLED displays which are also 
>> monochrome), so I think the 1bpp modes would definitely be useful.
> 
> David, I'm curious about those displays what controller/interface they use.
> I have been hoping that it would be possible to use regmap as an
> abstraction for many of these controllers and their registers.

The particular display I have is this one: 
http://wiki.seeed.cc/Grove-OLED_Display_1.12inch/

It looks like it uses a command/data scheme like the MIPI displays, but 
doesn't use any of the standard values for the commands. The controller 
can do parallel, SPI and I2C, but the display I have is wired for I2C.

> 
> For MIPI DCS it wasn't possible because it's command oriented with
> arguments. Since zero arguments is possible, a register with no value
> is nonsense, even though the regmap implementation happily let me do it.
> There's also the problem that regmap doesn't support registers with
> different widths. Which is a problem if all registers are 8-bit wide,
> except the GRAM register being 16-bit on RGB565 formats.
> 
> regmap is especially helpful with controllers that also have
> gpios/keypad/touch/pwm, since the mfd (multi function device) subsystem
> has good support for sharing regmaps between drivers. Multi function
> devices are split into several drivers.
> 
> Noralf.
> 

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web