linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/3] drm/mipi-dbi: Type B bus support, drm/tiny: MRB2801
@ 2020-11-30  6:23 mdurnev
  2020-11-30  6:23 ` [PATCH v1 1/3] drm/mipi-dbi: Add support for Type B mdurnev
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: mdurnev @ 2020-11-30  6:23 UTC (permalink / raw)
  To: linux-kernel, dri-devel, noralf; +Cc: mikhail_durnev

From: Mikhail Durnev <mikhail_durnev@mentor.com>

Hi All,

This patch series is aiming at extending the mipi-dbi bus driver
to support Intel 8080 type parallel bus (Type B) over GPIO and
adding a new driver for ILI9341 display panels with 8- or 16-bit
parallel interface.

It was tested with the MRB2801 display module [1] that had
a connector compatible with the ALIENTEK STM32 development board.
The module was connected to Raspberry Pi 3 via GPIO pins.

The parallel bus is implemented partially. It supports only write
operations from the host to the display. Read operations would
require switching GPIO mode between input and output back and
forth. But this implementation is very simple, and GPIO mode can
be set for all used pins to output once at initialization.
The RD pin of the display has to always receive the logic high
signal to make sure the data bus pins from the dislay side are
always in the high impedance state. Otherwise the display module
as well as the GPIO controller of the host can be damaged.
To be on the safe side I recommend using protective resistors
for all GPIO pins conneced to DB pins of the display. Resistors
of 10 kOhms are just fine for RPi 3. The WR and DC pins may not
work well with 10K resistors. Although there is no need to protect
them, you can try using 1K resistors if you want.

Bit banging is used to transmit data over the parallel bus from
host to display. There are two numbers that contol timings. They
should be defined in the device tree via the wr-up-down-delays
property. The first number is related to the write control pulse
duration, and the second number is related to the write cycle
duration. For ILI9341, the write pulse cannot be shorter than 15 ns,
and the write duration cannot be shorter than 66 ns. Delays of
10 and 51 ns respectively allow to meet the specifications on
RPi 3. Faster machines may need values closer to 15 and 66.

[1] http://www.lcdwiki.com/2.8inch_16BIT_Module_ILI9341_SKU:MRB2801

Mikhail Durnev (3):
  drm/mipi-dbi: Add support for Type B
  drm/tiny: Add driver for ili9341 with parallel bus
  dt-bindings: panel: Add bindings for MRB2801

 .../devicetree/bindings/display/ronbo,mrb2801.txt  |  42 +++
 drivers/gpu/drm/drm_mipi_dbi.c                     | 116 ++++++++-
 drivers/gpu/drm/tiny/Kconfig                       |  13 +
 drivers/gpu/drm/tiny/Makefile                      |   1 +
 drivers/gpu/drm/tiny/ili9341_gpio.c                | 290 +++++++++++++++++++++
 include/drm/drm_mipi_dbi.h                         |  30 ++-
 6 files changed, 490 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/ronbo,mrb2801.txt
 create mode 100644 drivers/gpu/drm/tiny/ili9341_gpio.c

-- 
2.7.4


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v1 1/3] drm/mipi-dbi: Add support for Type B
  2020-11-30  6:23 [PATCH v1 0/3] drm/mipi-dbi: Type B bus support, drm/tiny: MRB2801 mdurnev
@ 2020-11-30  6:23 ` mdurnev
  2020-11-30  6:23 ` [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus mdurnev
  2020-11-30  6:23 ` [PATCH v1 3/3] dt-bindings: panel: Add bindings for MRB2801 mdurnev
  2 siblings, 0 replies; 5+ messages in thread
From: mdurnev @ 2020-11-30  6:23 UTC (permalink / raw)
  To: linux-kernel, dri-devel, noralf; +Cc: mikhail_durnev

From: Mikhail Durnev <mikhail_durnev@mentor.com>

Intel 8080 type (Type B) parallel bus over GPIO.

The parallel bus is implemented partially. It supports only write
operations from the host to the display. Read operations would
require switching GPIO mode between input and output back and
forth. But this implementation is very simple, and GPIO mode can
be set for all used pins to output once at initialization.

It is enough to support only write operations to initialize displays
and output video data. The bus driver returns EOPNOTSUPP for all read
operations requested through a display driver.

Bit banging is used to transmit data over the parallel bus from host
to display. There are two numbers that contol timings: wr_up_delay
and wr_down_delay. They should be provided by the display driver.
The first number is related to the write control pulse duration, and
the second number is related to the write cycle duration that can
be found in the specification of the display.

Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
---
 drivers/gpu/drm/drm_mipi_dbi.c | 116 ++++++++++++++++++++++++++++++++++++++++-
 include/drm/drm_mipi_dbi.h     |  30 ++++++++++-
 2 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c
index 230c4fd..5dedc59 100644
--- a/drivers/gpu/drm/drm_mipi_dbi.c
+++ b/drivers/gpu/drm/drm_mipi_dbi.c
@@ -61,7 +61,7 @@
  *    3. 8-bit with the Data/Command signal as a separate D/CX pin
  *
  * Currently mipi_dbi only supports Type C options 1 and 3 with
- * mipi_dbi_spi_init().
+ * mipi_dbi_spi_init() and Type B with mipi_dbi_gpio_init().
  */
 
 #define MIPI_DBI_DEBUG_COMMAND(cmd, data, len) \
@@ -1158,6 +1158,120 @@ EXPORT_SYMBOL(mipi_dbi_spi_transfer);
 
 #endif /* CONFIG_SPI */
 
+/*
+ * This function implements data transfer only from host to display.
+ */
+static void mipi_dbi_gpio_transfer(struct mipi_dbi *dbi, u16 data)
+{
+	unsigned long ldata = data;
+
+	/*
+	 * Set W/R to low to start transfer.
+	 * Set DB bits with provided data when W/R is low.
+	 */
+	gpiod_set_value_cansleep(dbi->wr, 0);
+	gpiod_set_array_value_cansleep(dbi->db->ndescs, dbi->db->desc,
+				       dbi->db->info, &ldata);
+
+	/*
+	 * The bus usually needs additional delay.
+	 */
+	ndelay(dbi->wr_up_delay);
+
+	/*
+	 * Set W/R to high to indicate that DB lines are set.
+	 */
+	gpiod_set_value_cansleep(dbi->wr, 1);
+
+	/*
+	 * The connected display needs some time to read the data.
+	 */
+	ndelay(dbi->wr_down_delay);
+}
+
+static int mipi_dbi_gpio_command(struct mipi_dbi *dbi, u8 *cmd,
+				u8 *par, size_t num)
+{
+	int i;
+
+	/*
+	 * Read commands are not currently supported.
+	 */
+	if (mipi_dbi_command_is_read(dbi, *cmd))
+		return -EOPNOTSUPP;
+
+	MIPI_DBI_DEBUG_COMMAND(*cmd, par, num);
+
+	gpiod_set_value_cansleep(dbi->dc, 0);
+	mipi_dbi_gpio_transfer(dbi, (u16)*cmd);
+	gpiod_set_value_cansleep(dbi->dc, 1);
+
+	if (dbi->db->ndescs == 16 &&
+	    (*cmd == MIPI_DCS_WRITE_MEMORY_START ||
+	     *cmd == MIPI_DCS_WRITE_MEMORY_CONTINUE)) {
+		/*
+		 * Only a couple of commands supports 16-bit transfer.
+		 */
+		for (i = 0; i < num; i += 2) {
+			u16 data = *(u16 *)&par[i];
+
+			if (dbi->swap_bytes)
+				data = (data >> 8) | (data << 8);
+
+			mipi_dbi_gpio_transfer(dbi, data);
+		}
+	} else {
+		for (i = 0; i < num; i++) {
+			/*
+			 * Other commands ignore most significant bits.
+			 */
+			mipi_dbi_gpio_transfer(dbi, (u16)par[i]);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * mipi_dbi_gpio_init - Initialize MIPI DBI Type B interface implemented via GPIO
+ * @dbi: MIPI DBI structure to initialize
+ * @dc: D/C gpio
+ * @wr: W/R gpio
+ * @db: DB gpios
+ * @wr_up_delay: Delay after setting DB and before changing W/R from low to high
+ * @wr_down_delay: Delay after changing W/R from low to high
+ *
+ * This function sets &mipi_dbi->command, enables &mipi_dbi->read_commands for the
+ * usual read commands. It should be followed by a call to mipi_dbi_dev_init() or
+ * a driver-specific init.
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int mipi_dbi_gpio_init(struct mipi_dbi *dbi, struct gpio_desc *dc,
+		      struct gpio_desc *wr, struct gpio_descs *db,
+		      unsigned long wr_up_delay, unsigned long wr_down_delay)
+{
+	dbi->spi = NULL; /* Type B uses GPIO lines rather than SPI */
+
+	dbi->read_commands = mipi_dbi_dcs_read_commands;
+	dbi->command = mipi_dbi_gpio_command;
+
+	dbi->dc = dc;
+	dbi->wr = wr;
+	dbi->db = db;
+	dbi->wr_up_delay = wr_up_delay;
+	dbi->wr_down_delay = wr_down_delay;
+
+	if (mipi_dbi_machine_little_endian())
+		dbi->swap_bytes = true;
+
+	mutex_init(&dbi->cmdlock);
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dbi_gpio_init);
+
 #ifdef CONFIG_DEBUG_FS
 
 static ssize_t mipi_dbi_debugfs_command_write(struct file *file,
diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h
index c2827ce..c4be5ca 100644
--- a/include/drm/drm_mipi_dbi.h
+++ b/include/drm/drm_mipi_dbi.h
@@ -55,7 +55,7 @@ struct mipi_dbi {
 	struct spi_device *spi;
 
 	/**
-	 * @dc: Optional D/C gpio.
+	 * @dc: D/C gpio, optional for Type C and mandatory for Type B.
 	 */
 	struct gpio_desc *dc;
 
@@ -68,6 +68,31 @@ struct mipi_dbi {
 	 * @tx_buf9_len: Size of tx_buf9.
 	 */
 	size_t tx_buf9_len;
+
+	/* Type B specific */
+
+	/**
+	 * @wr: W/R gpio.
+	 */
+	struct gpio_desc *wr;
+
+	/**
+	 * @db: Data Bus gpios (usually 8 or 16).
+	 */
+	struct gpio_descs *db;
+
+	/**
+	 * @wr_up_delay: Delay after setting all db lines and before changing
+	 * wr from low to high.
+	 */
+	unsigned long wr_up_delay;
+
+	/**
+	 * @wr_down_delay: Delay after changing wr from low to high and
+	 * before wr can be changed again from hight to low to start a new
+	 * write operation.
+	 */
+	unsigned long wr_down_delay;
 };
 
 /**
@@ -139,6 +164,9 @@ static inline struct mipi_dbi_dev *drm_to_mipi_dbi_dev(struct drm_device *drm)
 
 int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi,
 		      struct gpio_desc *dc);
+int mipi_dbi_gpio_init(struct mipi_dbi *dbi, struct gpio_desc *dc,
+		      struct gpio_desc *wr, struct gpio_descs *db,
+		      unsigned long wr_up_delay, unsigned long wr_down_delay);
 int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev,
 				   const struct drm_simple_display_pipe_funcs *funcs,
 				   const uint32_t *formats, unsigned int format_count,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus
  2020-11-30  6:23 [PATCH v1 0/3] drm/mipi-dbi: Type B bus support, drm/tiny: MRB2801 mdurnev
  2020-11-30  6:23 ` [PATCH v1 1/3] drm/mipi-dbi: Add support for Type B mdurnev
@ 2020-11-30  6:23 ` mdurnev
  2020-11-30  8:54   ` kernel test robot
  2020-11-30  6:23 ` [PATCH v1 3/3] dt-bindings: panel: Add bindings for MRB2801 mdurnev
  2 siblings, 1 reply; 5+ messages in thread
From: mdurnev @ 2020-11-30  6:23 UTC (permalink / raw)
  To: linux-kernel, dri-devel, noralf; +Cc: mikhail_durnev

From: Mikhail Durnev <mikhail_durnev@mentor.com>

MRB2801 display module [1] is an example of ILI9341 display that connects to
Intel 8080 parallel bus. Its connector is compatible with the ALIENTEK STM32
development board.

It can be used with the drm/mipi-dbi bus driver if the bus is emulated with
GPIO.

[1] http://www.lcdwiki.com/2.8inch_16BIT_Module_ILI9341_SKU:MRB2801

Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
---
 drivers/gpu/drm/tiny/Kconfig        |  13 ++
 drivers/gpu/drm/tiny/Makefile       |   1 +
 drivers/gpu/drm/tiny/ili9341_gpio.c | 290 ++++++++++++++++++++++++++++++++++++
 3 files changed, 304 insertions(+)
 create mode 100644 drivers/gpu/drm/tiny/ili9341_gpio.c

diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig
index 2b6414f..e48e268 100644
--- a/drivers/gpu/drm/tiny/Kconfig
+++ b/drivers/gpu/drm/tiny/Kconfig
@@ -66,6 +66,19 @@ config TINYDRM_ILI9341
 
 	  If M is selected the module will be called ili9341.
 
+config TINYDRM_ILI9341_GPIO
+	tristate "DRM support for ILI9341 display panels with parallel bus interface over GPIO"
+	depends on DRM
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_MIPI_DBI
+	select BACKLIGHT_CLASS_DEVICE
+	help
+	  DRM driver for the following Ilitek ILI9341 panels:
+	  * MRB2801 2.8" 240x320 TFT
+
+	  If M is selected the module will be called ili9341_gpio.
+
 config TINYDRM_ILI9486
 	tristate "DRM support for ILI9486 display panels"
 	depends on DRM && SPI
diff --git a/drivers/gpu/drm/tiny/Makefile b/drivers/gpu/drm/tiny/Makefile
index 6ae4e9e5..1ad2c0d 100644
--- a/drivers/gpu/drm/tiny/Makefile
+++ b/drivers/gpu/drm/tiny/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_GM12U320)		+= gm12u320.o
 obj-$(CONFIG_TINYDRM_HX8357D)		+= hx8357d.o
 obj-$(CONFIG_TINYDRM_ILI9225)		+= ili9225.o
 obj-$(CONFIG_TINYDRM_ILI9341)		+= ili9341.o
+obj-$(CONFIG_TINYDRM_ILI9341_GPIO)	+= ili9341_gpio.o
 obj-$(CONFIG_TINYDRM_ILI9486)		+= ili9486.o
 obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
 obj-$(CONFIG_TINYDRM_REPAPER)		+= repaper.o
diff --git a/drivers/gpu/drm/tiny/ili9341_gpio.c b/drivers/gpu/drm/tiny/ili9341_gpio.c
new file mode 100644
index 0000000..de8a63b8
--- /dev/null
+++ b/drivers/gpu/drm/tiny/ili9341_gpio.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DRM driver for Ilitek ILI9341 panels with parallel bus interface
+ *
+ * Copyright 2020 Mikhail Durnev <mikhail_durnev@mentor.com>
+ *
+ * Based on ili9341.c:
+ * Copyright 2018 David Lechner <david@lechnology.com>
+ *
+ * Based on mi0283qt.c:
+ * Copyright 2016 Noralf Trønnes
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_mipi_dbi.h>
+#include <drm/drm_modeset_helper.h>
+#include <video/mipi_display.h>
+
+#define ILI9341_FRMCTR1		0xb1
+#define ILI9341_DISCTRL		0xb6
+#define ILI9341_ETMOD		0xb7
+
+#define ILI9341_PWCTRL1		0xc0
+#define ILI9341_PWCTRL2		0xc1
+#define ILI9341_VMCTRL1		0xc5
+#define ILI9341_VMCTRL2		0xc7
+#define ILI9341_PWCTRLA		0xcb
+#define ILI9341_PWCTRLB		0xcf
+
+#define ILI9341_PGAMCTRL	0xe0
+#define ILI9341_NGAMCTRL	0xe1
+#define ILI9341_DTCTRLA		0xe8
+#define ILI9341_DTCTRLB		0xea
+#define ILI9341_PWRSEQ		0xed
+
+#define ILI9341_EN3GAM		0xf2
+#define ILI9341_PUMPCTRL	0xf7
+
+#define ILI9341_MADCTL_BGR	BIT(3)
+#define ILI9341_MADCTL_MV	BIT(5)
+#define ILI9341_MADCTL_MX	BIT(6)
+#define ILI9341_MADCTL_MY	BIT(7)
+
+static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
+			     struct drm_crtc_state *crtc_state,
+			     struct drm_plane_state *plane_state)
+{
+	struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev);
+	struct mipi_dbi *dbi = &dbidev->dbi;
+	u8 addr_mode;
+	int ret, idx;
+
+	if (!drm_dev_enter(pipe->crtc.dev, &idx))
+		return;
+
+	DRM_DEBUG_KMS("\n");
+
+	ret = mipi_dbi_poweron_conditional_reset(dbidev);
+	if (ret < 0)
+		goto out_exit;
+	if (ret == 1)
+		goto out_enable;
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
+
+	mipi_dbi_command(dbi, ILI9341_PWCTRLB, 0x00, 0xc1, 0x30);
+	mipi_dbi_command(dbi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
+	mipi_dbi_command(dbi, ILI9341_DTCTRLA, 0x85, 0x00, 0x78);
+	mipi_dbi_command(dbi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
+	mipi_dbi_command(dbi, ILI9341_PUMPCTRL, 0x20);
+	mipi_dbi_command(dbi, ILI9341_DTCTRLB, 0x00, 0x00);
+
+	/* Power Control */
+	mipi_dbi_command(dbi, ILI9341_PWCTRL1, 0x23);
+	mipi_dbi_command(dbi, ILI9341_PWCTRL2, 0x10);
+	/* VCOM */
+	mipi_dbi_command(dbi, ILI9341_VMCTRL1, 0x3e, 0x28);
+	mipi_dbi_command(dbi, ILI9341_VMCTRL2, 0x86);
+
+	/* Memory Access Control */
+	mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
+
+	/* Frame Rate */
+	mipi_dbi_command(dbi, ILI9341_FRMCTR1, 0x00, 0x1b);
+
+	/* Gamma */
+	mipi_dbi_command(dbi, ILI9341_EN3GAM, 0x00);
+	mipi_dbi_command(dbi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
+	mipi_dbi_command(dbi, ILI9341_PGAMCTRL,
+			 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
+			 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
+	mipi_dbi_command(dbi, ILI9341_NGAMCTRL,
+			 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
+			 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
+
+	/* DDRAM */
+	mipi_dbi_command(dbi, ILI9341_ETMOD, 0x07);
+
+	/* Display */
+	mipi_dbi_command(dbi, ILI9341_DISCTRL, 0x08, 0x82, 0x27, 0x00);
+	mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE);
+	msleep(100);
+
+	mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON);
+	msleep(100);
+
+out_enable:
+	switch (dbidev->rotation) {
+	default:
+		addr_mode = ILI9341_MADCTL_MX;
+		break;
+	case 90:
+		addr_mode = ILI9341_MADCTL_MV;
+		break;
+	case 180:
+		addr_mode = ILI9341_MADCTL_MY;
+		break;
+	case 270:
+		addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
+			    ILI9341_MADCTL_MX;
+		break;
+	}
+	addr_mode |= ILI9341_MADCTL_BGR;
+	mipi_dbi_command(dbi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
+	mipi_dbi_enable_flush(dbidev, crtc_state, plane_state);
+out_exit:
+	drm_dev_exit(idx);
+}
+
+static const struct drm_simple_display_pipe_funcs ili9341gpio_pipe_funcs = {
+	.enable = yx240qv29_enable,
+	.disable = mipi_dbi_pipe_disable,
+	.update = mipi_dbi_pipe_update,
+	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
+};
+
+static const struct drm_display_mode yx240qv29_mode = {
+	DRM_SIMPLE_MODE(240, 320, 37, 49),
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(ili9341gpio_fops);
+
+static struct drm_driver ili9341gpio_driver = {
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+	.fops			= &ili9341gpio_fops,
+	.release		= mipi_dbi_release,
+	DRM_GEM_CMA_VMAP_DRIVER_OPS,
+	.debugfs_init		= mipi_dbi_debugfs_init,
+	.name			= "ili9341gpio",
+	.desc			= "Ilitek ILI9341",
+	.date			= "20201114",
+	.major			= 1,
+	.minor			= 0,
+};
+
+static const struct of_device_id ili9341gpio_of_match[] = {
+	{ .compatible = "ronbo,mrb2801" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ili9341gpio_of_match);
+
+static int ili9341gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mipi_dbi_dev *dbidev;
+	struct drm_device *drm;
+	struct mipi_dbi *dbi;
+	struct gpio_desc *dc;
+	struct gpio_desc *wr;
+	struct gpio_descs *db;
+	u32 rotation = 0;
+	u32 wr_delays[2] = {15, 60};
+	int ret;
+
+	dbidev = kzalloc(sizeof(*dbidev), GFP_KERNEL);
+	if (!dbidev)
+		return -ENOMEM;
+
+	dbi = &dbidev->dbi;
+	drm = &dbidev->drm;
+	ret = devm_drm_dev_init(dev, drm, &ili9341gpio_driver);
+	if (ret) {
+		kfree(dbidev);
+		return ret;
+	}
+
+	drm_mode_config_init(drm);
+
+	dbi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(dbi->reset)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
+		return PTR_ERR(dbi->reset);
+	}
+
+	dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_HIGH);
+	if (IS_ERR(dc)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
+		return PTR_ERR(dc);
+	}
+
+	wr = devm_gpiod_get(dev, "wr", GPIOD_OUT_HIGH);
+	if (IS_ERR(wr)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'wr'\n");
+		return PTR_ERR(wr);
+	}
+
+	db = devm_gpiod_get_array(dev, "db", GPIOD_OUT_LOW);
+	if (IS_ERR(db)) {
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'db'\n");
+		return PTR_ERR(db);
+	}
+	if (db->ndescs != 16 && db->ndescs != 8) {
+		/*
+		 * The data bus can be either 8 or 16 bits wide.
+		 * ILI9341 can work with 6, 8, 9, 16, and 18-bit parallel interfaces,
+		 * but the MRB2801 board supports only 8 or 16-bit interfaces.
+		 */
+		DRM_DEV_ERROR(dev, "Wrong number of bits in gpio 'db': %u\n", db->ndescs);
+		return PTR_ERR(db);
+	}
+
+	dbidev->backlight = devm_of_find_backlight(dev);
+	if (IS_ERR(dbidev->backlight))
+		return PTR_ERR(dbidev->backlight);
+
+	device_property_read_u32(dev, "rotation", &rotation);
+
+	device_property_read_u32_array(dev, "wr-up-down-delays", wr_delays, 2);
+
+	ret = mipi_dbi_gpio_init(dbi, dc, wr, db, wr_delays[0], wr_delays[1]);
+	if (ret)
+		return ret;
+
+	ret = mipi_dbi_dev_init(dbidev, &ili9341gpio_pipe_funcs, &yx240qv29_mode, rotation);
+	if (ret)
+		return ret;
+
+	drm_mode_config_reset(drm);
+
+	ret = drm_dev_register(drm, 0);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, drm);
+
+	drm_fbdev_generic_setup(drm, 0);
+
+	return 0;
+}
+
+static int ili9341gpio_remove(struct platform_device *pdev)
+{
+	struct drm_device *drm = platform_get_drvdata(pdev);
+
+	drm_dev_unplug(drm);
+	drm_atomic_helper_shutdown(drm);
+
+	return 0;
+}
+
+static void ili9341gpio_shutdown(struct platform_device *pdev)
+{
+	drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
+}
+
+static struct platform_driver ili9341gpio_platform_driver = {
+	.driver = {
+		.name = "ili9341gpio",
+		.of_match_table = ili9341gpio_of_match,
+	},
+	.probe = ili9341gpio_probe,
+	.remove = ili9341gpio_remove,
+	.shutdown = ili9341gpio_shutdown,
+};
+module_platform_driver(ili9341gpio_platform_driver);
+
+MODULE_DESCRIPTION("Ilitek ILI9341 8/16-bit DRM driver");
+MODULE_AUTHOR("Mikhail Durnev <mikhail_durnev@mentor.com>");
+MODULE_LICENSE("GPL");
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v1 3/3] dt-bindings: panel: Add bindings for MRB2801
  2020-11-30  6:23 [PATCH v1 0/3] drm/mipi-dbi: Type B bus support, drm/tiny: MRB2801 mdurnev
  2020-11-30  6:23 ` [PATCH v1 1/3] drm/mipi-dbi: Add support for Type B mdurnev
  2020-11-30  6:23 ` [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus mdurnev
@ 2020-11-30  6:23 ` mdurnev
  2 siblings, 0 replies; 5+ messages in thread
From: mdurnev @ 2020-11-30  6:23 UTC (permalink / raw)
  To: linux-kernel, dri-devel, noralf; +Cc: mikhail_durnev

From: Mikhail Durnev <mikhail_durnev@mentor.com>

Add binding for Ronbo MRB2801 display module.

This binding is for display panels using an Ilitek ILI9341 controller in
parallel mode.

Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
---
 .../devicetree/bindings/display/ronbo,mrb2801.txt  | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/ronbo,mrb2801.txt

diff --git a/Documentation/devicetree/bindings/display/ronbo,mrb2801.txt b/Documentation/devicetree/bindings/display/ronbo,mrb2801.txt
new file mode 100644
index 0000000..db1a861e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/ronbo,mrb2801.txt
@@ -0,0 +1,42 @@
+MRB2801 display panel
+
+This binding is for display panels using an Ilitek ILI9341 controller in
+parallel mode.
+
+Required properties:
+- compatible:		"ronbo,mrb2801"
+- dc-gpios:		D/C pin
+- wr-gpios:		W/R pin
+- db-gpios:		8 or 16 DB pins
+- reset-gpios:		Reset pin
+- wr-up-down-delays:	Delays in ns for changing W/R from down to up and from up to down
+
+Optional properties:
+- backlight:	phandle of the backlight device attached to the panel
+- rotation:	panel rotation in degrees counter clockwise (0,90,180,270)
+
+Example:
+	mrb2801{
+		compatible = "ronbo,mrb2801";
+		db-gpios = <&gpio 17 0>, /* DB0 */
+			   <&gpio 18 0>, /* DB1 */
+			   <&gpio 27 0>, /* DB2 */
+			   <&gpio 22 0>, /* DB3 */
+			   <&gpio 23 0>, /* DB4 */
+			   <&gpio 24 0>, /* DB5 */
+			   <&gpio 25 0>, /* DB6 */
+			   <&gpio  4 0>, /* DB7 */
+			   <&gpio 14 0>, /* DB8 */
+			   <&gpio 15 0>, /* DB9 */
+			   <&gpio  5 0>, /* DB10 */
+			   <&gpio  6 0>, /* DB11 */
+			   <&gpio 13 0>, /* DB12 */
+			   <&gpio 19 0>, /* DB13 */
+			   <&gpio 26 0>, /* DB14 */
+			   <&gpio 12 0>; /* DB15 */
+		dc-gpios = <&gpio 16 0>; /* D/C */
+		wr-gpios = <&gpio 20 0>; /* W/R */
+		wr-up-down-delays = <10 51>;
+		reset-gpios = <&gpio 21 0>; /* RST */
+		backlight = <&backlight>;
+	};
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus
  2020-11-30  6:23 ` [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus mdurnev
@ 2020-11-30  8:54   ` kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2020-11-30  8:54 UTC (permalink / raw)
  To: mdurnev, linux-kernel, dri-devel, noralf; +Cc: kbuild-all, mikhail_durnev

[-- Attachment #1: Type: text/plain, Size: 5387 bytes --]

Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linux/master]
[also build test ERROR on drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next drm-tip/drm-tip linus/master v5.10-rc6 next-20201127]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/mdurnev-gmail-com/drm-mipi-dbi-Type-B-bus-support-drm-tiny-MRB2801/20201130-142812
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 09162bc32c880a791c6c0668ce0745cf7958f576
config: arm64-randconfig-r024-20201130 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/5883e05578f8008b00a270e8f4ebe9cb7e06a6b6
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review mdurnev-gmail-com/drm-mipi-dbi-Type-B-bus-support-drm-tiny-MRB2801/20201130-142812
        git checkout 5883e05578f8008b00a270e8f4ebe9cb7e06a6b6
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/drm_mipi_dbi.c: In function 'mipi_dbi_gpio_init':
>> drivers/gpu/drm/drm_mipi_dbi.c:1266:6: error: implicit declaration of function 'mipi_dbi_machine_little_endian' [-Werror=implicit-function-declaration]
    1266 |  if (mipi_dbi_machine_little_endian())
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/mipi_dbi_machine_little_endian +1266 drivers/gpu/drm/drm_mipi_dbi.c

12265315ac41a3e Mikhail Durnev 2020-11-30  1234  
12265315ac41a3e Mikhail Durnev 2020-11-30  1235  /**
12265315ac41a3e Mikhail Durnev 2020-11-30  1236   * mipi_dbi_gpio_init - Initialize MIPI DBI Type B interface implemented via GPIO
12265315ac41a3e Mikhail Durnev 2020-11-30  1237   * @dbi: MIPI DBI structure to initialize
12265315ac41a3e Mikhail Durnev 2020-11-30  1238   * @dc: D/C gpio
12265315ac41a3e Mikhail Durnev 2020-11-30  1239   * @wr: W/R gpio
12265315ac41a3e Mikhail Durnev 2020-11-30  1240   * @db: DB gpios
12265315ac41a3e Mikhail Durnev 2020-11-30  1241   * @wr_up_delay: Delay after setting DB and before changing W/R from low to high
12265315ac41a3e Mikhail Durnev 2020-11-30  1242   * @wr_down_delay: Delay after changing W/R from low to high
12265315ac41a3e Mikhail Durnev 2020-11-30  1243   *
12265315ac41a3e Mikhail Durnev 2020-11-30  1244   * This function sets &mipi_dbi->command, enables &mipi_dbi->read_commands for the
12265315ac41a3e Mikhail Durnev 2020-11-30  1245   * usual read commands. It should be followed by a call to mipi_dbi_dev_init() or
12265315ac41a3e Mikhail Durnev 2020-11-30  1246   * a driver-specific init.
12265315ac41a3e Mikhail Durnev 2020-11-30  1247   *
12265315ac41a3e Mikhail Durnev 2020-11-30  1248   * Returns:
12265315ac41a3e Mikhail Durnev 2020-11-30  1249   * Zero on success, negative error code on failure.
12265315ac41a3e Mikhail Durnev 2020-11-30  1250   */
12265315ac41a3e Mikhail Durnev 2020-11-30  1251  int mipi_dbi_gpio_init(struct mipi_dbi *dbi, struct gpio_desc *dc,
12265315ac41a3e Mikhail Durnev 2020-11-30  1252  		      struct gpio_desc *wr, struct gpio_descs *db,
12265315ac41a3e Mikhail Durnev 2020-11-30  1253  		      unsigned long wr_up_delay, unsigned long wr_down_delay)
12265315ac41a3e Mikhail Durnev 2020-11-30  1254  {
12265315ac41a3e Mikhail Durnev 2020-11-30  1255  	dbi->spi = NULL; /* Type B uses GPIO lines rather than SPI */
12265315ac41a3e Mikhail Durnev 2020-11-30  1256  
12265315ac41a3e Mikhail Durnev 2020-11-30  1257  	dbi->read_commands = mipi_dbi_dcs_read_commands;
12265315ac41a3e Mikhail Durnev 2020-11-30  1258  	dbi->command = mipi_dbi_gpio_command;
12265315ac41a3e Mikhail Durnev 2020-11-30  1259  
12265315ac41a3e Mikhail Durnev 2020-11-30  1260  	dbi->dc = dc;
12265315ac41a3e Mikhail Durnev 2020-11-30  1261  	dbi->wr = wr;
12265315ac41a3e Mikhail Durnev 2020-11-30  1262  	dbi->db = db;
12265315ac41a3e Mikhail Durnev 2020-11-30  1263  	dbi->wr_up_delay = wr_up_delay;
12265315ac41a3e Mikhail Durnev 2020-11-30  1264  	dbi->wr_down_delay = wr_down_delay;
12265315ac41a3e Mikhail Durnev 2020-11-30  1265  
12265315ac41a3e Mikhail Durnev 2020-11-30 @1266  	if (mipi_dbi_machine_little_endian())
12265315ac41a3e Mikhail Durnev 2020-11-30  1267  		dbi->swap_bytes = true;
12265315ac41a3e Mikhail Durnev 2020-11-30  1268  
12265315ac41a3e Mikhail Durnev 2020-11-30  1269  	mutex_init(&dbi->cmdlock);
12265315ac41a3e Mikhail Durnev 2020-11-30  1270  
12265315ac41a3e Mikhail Durnev 2020-11-30  1271  	return 0;
12265315ac41a3e Mikhail Durnev 2020-11-30  1272  }
12265315ac41a3e Mikhail Durnev 2020-11-30  1273  EXPORT_SYMBOL(mipi_dbi_gpio_init);
12265315ac41a3e Mikhail Durnev 2020-11-30  1274  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 37164 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-30  8:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-30  6:23 [PATCH v1 0/3] drm/mipi-dbi: Type B bus support, drm/tiny: MRB2801 mdurnev
2020-11-30  6:23 ` [PATCH v1 1/3] drm/mipi-dbi: Add support for Type B mdurnev
2020-11-30  6:23 ` [PATCH v1 2/3] drm/tiny: Add driver for ili9341 with parallel bus mdurnev
2020-11-30  8:54   ` kernel test robot
2020-11-30  6:23 ` [PATCH v1 3/3] dt-bindings: panel: Add bindings for MRB2801 mdurnev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).