All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jagan Teki <jagan@amarulasolutions.com>
To: Andrzej Hajda <a.hajda@samsung.com>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Chen-Yu Tsai <wens@csie.org>,
	Maxime Ripard <maxime.ripard@bootlin.com>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>
Cc: Michael Trimarchi <michael@amarulasolutions.com>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-sunxi@googlegroups.com, linux-amarula@amarulasolutions.com,
	Jagan Teki <jagan@amarulasolutions.com>
Subject: [PATCH 5/6] drm/bridge: Add Chipone ICN6211 MIPI-DSI/RGB convertor bridge
Date: Fri, 15 Mar 2019 18:38:24 +0530	[thread overview]
Message-ID: <20190315130825.9005-6-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20190315130825.9005-1-jagan@amarulasolutions.com>

ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
It has a flexible configuration of MIPI DSI signal input
and produce RGB565, RGB666, RGB888 output format.

Add bridge driver for it.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 MAINTAINERS                              |   6 +
 drivers/gpu/drm/bridge/Kconfig           |  10 +
 drivers/gpu/drm/bridge/Makefile          |   1 +
 drivers/gpu/drm/bridge/chipone-icn6211.c | 275 +++++++++++++++++++++++
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/chipone-icn6211.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4de80222cffb..e529addd30f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4897,6 +4897,12 @@ T:	git git://anongit.freedesktop.org/drm/drm-misc
 S:	Maintained
 F:	drivers/gpu/drm/bochs/
 
+DRM DRIVER FOR CHIPONE ICN6211 MIPI-DSI to RGB CONVERTOR BRIDGE
+M:	Jagan Teki <jagan@amarulasolutions.com>
+S:	Maintained
+F:	drivers/gpu/drm/bridge/chipone-icn6211.c
+F:	Documentation/devicetree/bindings/display/bridge/chipone,icn6211.txt
+
 DRM DRIVER FOR FARADAY TVE200 TV ENCODER
 M:	Linus Walleij <linus.walleij@linaro.org>
 T:	git git://anongit.freedesktop.org/drm/drm-misc
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 8840f396a7b6..cd314572e4ed 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -36,6 +36,16 @@ config DRM_CDNS_DSI
 	  Support Cadence DPI to DSI bridge. This is an internal
 	  bridge and is meant to be directly embedded in a SoC.
 
+config DRM_CHIPONE_ICN6211
+	tristate "Chipone ICN6211 MIPI-DSI/RGB converter bridge"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	help
+	  ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
+	  It has a flexible configuration of MIPI DSI signal input
+	  and produce RGB565, RGB666, RGB888 output format.
+
 config DRM_DUMB_VGA_DAC
 	tristate "Dumb VGA DAC Bridge support"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 4934fcf5a6f8..541fdccad10b 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
+obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
 obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c
new file mode 100644
index 000000000000..cd2f3505f845
--- /dev/null
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+
+#define ICN6211_INIT_CMD_LEN		2
+
+struct chipone {
+	struct device *dev;
+	struct drm_bridge bridge;
+	struct drm_connector connector;
+	struct drm_panel *panel;
+
+	struct gpio_desc *reset;
+};
+
+static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct chipone, bridge);
+}
+
+static inline
+struct chipone *connector_to_chipone(struct drm_connector *connector)
+{
+	return container_of(connector, struct chipone, connector);
+}
+
+struct icn6211_init_cmd {
+	u8 data[ICN6211_INIT_CMD_LEN];
+};
+
+static const struct icn6211_init_cmd icn6211_init_cmds[] = {
+	{ .data = { 0x7A, 0xC1 } },
+	{ .data = { 0x20, 0x20 } },
+	{ .data = { 0x21, 0xE0 } },
+	{ .data = { 0x22, 0x13 } },
+	{ .data = { 0x23, 0x28 } },
+	{ .data = { 0x24, 0x30 } },
+	{ .data = { 0x25, 0x28 } },
+	{ .data = { 0x26, 0x00 } },
+	{ .data = { 0x27, 0x0D } },
+	{ .data = { 0x28, 0x03 } },
+	{ .data = { 0x29, 0x1D } },
+	{ .data = { 0x34, 0x80 } },
+	{ .data = { 0x36, 0x28 } },
+	{ .data = { 0xB5, 0xA0 } },
+	{ .data = { 0x5C, 0xFF } },
+	{ .data = { 0x2A, 0x01 } },
+	{ .data = { 0x56, 0x92 } },
+	{ .data = { 0x6B, 0x71 } },
+	{ .data = { 0x69, 0x2B } },
+	{ .data = { 0x10, 0x40 } },
+	{ .data = { 0x11, 0x98 } },
+	{ .data = { 0xB6, 0x20 } },
+	{ .data = { 0x51, 0x20 } },
+	{ .data = { 0x09, 0x10 } },
+};
+
+static int chipone_get_modes(struct drm_connector *connector)
+{
+	struct chipone *icn = connector_to_chipone(connector);
+
+	return drm_panel_get_modes(icn->panel);
+}
+
+static const
+struct drm_connector_helper_funcs chipone_connector_helper_funcs = {
+	.get_modes = chipone_get_modes,
+};
+
+static const struct drm_connector_funcs chipone_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void chipone_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_disable(bridge_to_chipone(bridge)->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error disabling panel (%d)\n", ret);
+}
+
+static void chipone_post_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret;
+
+	ret = drm_panel_unprepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error unpreparing panel (%d)\n", ret);
+
+	msleep(50);
+
+	gpiod_set_value(icn->reset, 0);
+}
+
+static void chipone_pre_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(icn->dev);
+	unsigned int i;
+	int ret;
+
+	gpiod_set_value(icn->reset, 0);
+	msleep(20);
+
+	gpiod_set_value(icn->reset, 1);
+	msleep(50);
+
+	for (i = 0; i < ARRAY_SIZE(icn6211_init_cmds); i++) {
+		const struct icn6211_init_cmd *cmd = &icn6211_init_cmds[i];
+
+		ret = mipi_dsi_generic_write(dsi, cmd->data,
+					     ICN6211_INIT_CMD_LEN);
+		if (ret < 0) {
+			DRM_DEV_ERROR(icn->dev,
+				      "failed to write cmd %d: %d\n", i, ret);
+			return;
+		}
+	}
+
+	ret = drm_panel_prepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error preparing panel (%d)\n", ret);
+}
+
+static void chipone_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_enable(icn->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error enabling panel (%d)\n", ret);
+}
+
+static int chipone_attach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+	int ret;
+
+	icn->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	ret = drm_connector_init(drm, &icn->connector,
+				 &chipone_connector_funcs,
+				 DRM_MODE_CONNECTOR_Unknown);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(&icn->connector,
+				 &chipone_connector_helper_funcs);
+	drm_connector_attach_encoder(&icn->connector, bridge->encoder);
+	drm_panel_attach(icn->panel, &icn->connector);
+	icn->connector.funcs->reset(&icn->connector);
+	drm_fb_helper_add_one_connector(drm->fb_helper, &icn->connector);
+	drm_connector_register(&icn->connector);
+
+	return 0;
+}
+
+static void chipone_detach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+
+	drm_connector_unregister(&icn->connector);
+	drm_fb_helper_remove_one_connector(drm->fb_helper, &icn->connector);
+	drm_panel_detach(icn->panel);
+	icn->panel = NULL;
+	drm_connector_put(&icn->connector);
+}
+
+static const struct drm_bridge_funcs chipone_bridge_funcs = {
+	.disable = chipone_disable,
+	.post_disable = chipone_post_disable,
+	.enable = chipone_enable,
+	.pre_enable = chipone_pre_enable,
+	.attach = chipone_attach,
+	.detach = chipone_detach,
+};
+
+static int chipone_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct chipone *icn;
+	int ret;
+
+	icn = devm_kzalloc(dev, sizeof(struct chipone), GFP_KERNEL);
+	if (!icn)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, icn);
+
+	icn->dev = dev;
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+
+	icn->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(icn->reset)) {
+		DRM_DEV_ERROR(dev, "no reset GPIO pin provided\n");
+		return PTR_ERR(icn->reset);
+	}
+
+	ret = drm_of_find_panel_or_bridge(icn->dev->of_node, 1, 0,
+					  &icn->panel, NULL);
+	if (ret && ret != -EPROBE_DEFER) {
+		DRM_DEV_ERROR(dev, "failed to find panel (ret = %d)\n", ret);
+		return ret;
+	}
+
+	icn->bridge.funcs = &chipone_bridge_funcs;
+	icn->bridge.of_node = dev->of_node;
+
+	drm_bridge_add(&icn->bridge);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		drm_bridge_remove(&icn->bridge);
+		DRM_DEV_ERROR(dev, "failed to attach dsi (ret = %d)\n", ret);
+	}
+
+	return ret;
+}
+
+static int chipone_remove(struct mipi_dsi_device *dsi)
+{
+	struct chipone *icn = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_bridge_remove(&icn->bridge);
+
+	return 0;
+}
+
+static const struct of_device_id chipone_of_match[] = {
+	{ .compatible = "bananapi,icn6211" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, chipone_of_match);
+
+static struct mipi_dsi_driver chipone_driver = {
+	.probe = chipone_probe,
+	.remove = chipone_remove,
+	.driver = {
+		.name = "chipone-icn6211",
+		.owner = THIS_MODULE,
+		.of_match_table = chipone_of_match,
+	},
+};
+module_mipi_dsi_driver(chipone_driver);
+
+MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
+MODULE_DESCRIPTION("Chipone ICN6211 MIPI-DSI to RGB Convertor Bridge");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0.321.gffc6fa0e3


WARNING: multiple messages have this Message-ID (diff)
From: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
To: Andrzej Hajda <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>,
	Laurent Pinchart
	<Laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>,
	Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
	Maxime Ripard
	<maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org>,
	David Airlie <airlied-cv59FeDIM0c@public.gmane.org>,
	Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org>,
	Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
Cc: Michael Trimarchi
	<michael-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
	linux-amarula-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org,
	Jagan Teki
	<jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Subject: [PATCH 5/6] drm/bridge: Add Chipone ICN6211 MIPI-DSI/RGB convertor bridge
Date: Fri, 15 Mar 2019 18:38:24 +0530	[thread overview]
Message-ID: <20190315130825.9005-6-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20190315130825.9005-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>

ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
It has a flexible configuration of MIPI DSI signal input
and produce RGB565, RGB666, RGB888 output format.

Add bridge driver for it.

Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
 MAINTAINERS                              |   6 +
 drivers/gpu/drm/bridge/Kconfig           |  10 +
 drivers/gpu/drm/bridge/Makefile          |   1 +
 drivers/gpu/drm/bridge/chipone-icn6211.c | 275 +++++++++++++++++++++++
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/chipone-icn6211.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4de80222cffb..e529addd30f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4897,6 +4897,12 @@ T:	git git://anongit.freedesktop.org/drm/drm-misc
 S:	Maintained
 F:	drivers/gpu/drm/bochs/
 
+DRM DRIVER FOR CHIPONE ICN6211 MIPI-DSI to RGB CONVERTOR BRIDGE
+M:	Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
+S:	Maintained
+F:	drivers/gpu/drm/bridge/chipone-icn6211.c
+F:	Documentation/devicetree/bindings/display/bridge/chipone,icn6211.txt
+
 DRM DRIVER FOR FARADAY TVE200 TV ENCODER
 M:	Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
 T:	git git://anongit.freedesktop.org/drm/drm-misc
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 8840f396a7b6..cd314572e4ed 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -36,6 +36,16 @@ config DRM_CDNS_DSI
 	  Support Cadence DPI to DSI bridge. This is an internal
 	  bridge and is meant to be directly embedded in a SoC.
 
+config DRM_CHIPONE_ICN6211
+	tristate "Chipone ICN6211 MIPI-DSI/RGB converter bridge"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	help
+	  ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
+	  It has a flexible configuration of MIPI DSI signal input
+	  and produce RGB565, RGB666, RGB888 output format.
+
 config DRM_DUMB_VGA_DAC
 	tristate "Dumb VGA DAC Bridge support"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 4934fcf5a6f8..541fdccad10b 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
+obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
 obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c
new file mode 100644
index 000000000000..cd2f3505f845
--- /dev/null
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions
+ * Author: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+
+#define ICN6211_INIT_CMD_LEN		2
+
+struct chipone {
+	struct device *dev;
+	struct drm_bridge bridge;
+	struct drm_connector connector;
+	struct drm_panel *panel;
+
+	struct gpio_desc *reset;
+};
+
+static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct chipone, bridge);
+}
+
+static inline
+struct chipone *connector_to_chipone(struct drm_connector *connector)
+{
+	return container_of(connector, struct chipone, connector);
+}
+
+struct icn6211_init_cmd {
+	u8 data[ICN6211_INIT_CMD_LEN];
+};
+
+static const struct icn6211_init_cmd icn6211_init_cmds[] = {
+	{ .data = { 0x7A, 0xC1 } },
+	{ .data = { 0x20, 0x20 } },
+	{ .data = { 0x21, 0xE0 } },
+	{ .data = { 0x22, 0x13 } },
+	{ .data = { 0x23, 0x28 } },
+	{ .data = { 0x24, 0x30 } },
+	{ .data = { 0x25, 0x28 } },
+	{ .data = { 0x26, 0x00 } },
+	{ .data = { 0x27, 0x0D } },
+	{ .data = { 0x28, 0x03 } },
+	{ .data = { 0x29, 0x1D } },
+	{ .data = { 0x34, 0x80 } },
+	{ .data = { 0x36, 0x28 } },
+	{ .data = { 0xB5, 0xA0 } },
+	{ .data = { 0x5C, 0xFF } },
+	{ .data = { 0x2A, 0x01 } },
+	{ .data = { 0x56, 0x92 } },
+	{ .data = { 0x6B, 0x71 } },
+	{ .data = { 0x69, 0x2B } },
+	{ .data = { 0x10, 0x40 } },
+	{ .data = { 0x11, 0x98 } },
+	{ .data = { 0xB6, 0x20 } },
+	{ .data = { 0x51, 0x20 } },
+	{ .data = { 0x09, 0x10 } },
+};
+
+static int chipone_get_modes(struct drm_connector *connector)
+{
+	struct chipone *icn = connector_to_chipone(connector);
+
+	return drm_panel_get_modes(icn->panel);
+}
+
+static const
+struct drm_connector_helper_funcs chipone_connector_helper_funcs = {
+	.get_modes = chipone_get_modes,
+};
+
+static const struct drm_connector_funcs chipone_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void chipone_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_disable(bridge_to_chipone(bridge)->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error disabling panel (%d)\n", ret);
+}
+
+static void chipone_post_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret;
+
+	ret = drm_panel_unprepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error unpreparing panel (%d)\n", ret);
+
+	msleep(50);
+
+	gpiod_set_value(icn->reset, 0);
+}
+
+static void chipone_pre_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(icn->dev);
+	unsigned int i;
+	int ret;
+
+	gpiod_set_value(icn->reset, 0);
+	msleep(20);
+
+	gpiod_set_value(icn->reset, 1);
+	msleep(50);
+
+	for (i = 0; i < ARRAY_SIZE(icn6211_init_cmds); i++) {
+		const struct icn6211_init_cmd *cmd = &icn6211_init_cmds[i];
+
+		ret = mipi_dsi_generic_write(dsi, cmd->data,
+					     ICN6211_INIT_CMD_LEN);
+		if (ret < 0) {
+			DRM_DEV_ERROR(icn->dev,
+				      "failed to write cmd %d: %d\n", i, ret);
+			return;
+		}
+	}
+
+	ret = drm_panel_prepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error preparing panel (%d)\n", ret);
+}
+
+static void chipone_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_enable(icn->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error enabling panel (%d)\n", ret);
+}
+
+static int chipone_attach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+	int ret;
+
+	icn->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	ret = drm_connector_init(drm, &icn->connector,
+				 &chipone_connector_funcs,
+				 DRM_MODE_CONNECTOR_Unknown);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(&icn->connector,
+				 &chipone_connector_helper_funcs);
+	drm_connector_attach_encoder(&icn->connector, bridge->encoder);
+	drm_panel_attach(icn->panel, &icn->connector);
+	icn->connector.funcs->reset(&icn->connector);
+	drm_fb_helper_add_one_connector(drm->fb_helper, &icn->connector);
+	drm_connector_register(&icn->connector);
+
+	return 0;
+}
+
+static void chipone_detach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+
+	drm_connector_unregister(&icn->connector);
+	drm_fb_helper_remove_one_connector(drm->fb_helper, &icn->connector);
+	drm_panel_detach(icn->panel);
+	icn->panel = NULL;
+	drm_connector_put(&icn->connector);
+}
+
+static const struct drm_bridge_funcs chipone_bridge_funcs = {
+	.disable = chipone_disable,
+	.post_disable = chipone_post_disable,
+	.enable = chipone_enable,
+	.pre_enable = chipone_pre_enable,
+	.attach = chipone_attach,
+	.detach = chipone_detach,
+};
+
+static int chipone_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct chipone *icn;
+	int ret;
+
+	icn = devm_kzalloc(dev, sizeof(struct chipone), GFP_KERNEL);
+	if (!icn)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, icn);
+
+	icn->dev = dev;
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+
+	icn->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(icn->reset)) {
+		DRM_DEV_ERROR(dev, "no reset GPIO pin provided\n");
+		return PTR_ERR(icn->reset);
+	}
+
+	ret = drm_of_find_panel_or_bridge(icn->dev->of_node, 1, 0,
+					  &icn->panel, NULL);
+	if (ret && ret != -EPROBE_DEFER) {
+		DRM_DEV_ERROR(dev, "failed to find panel (ret = %d)\n", ret);
+		return ret;
+	}
+
+	icn->bridge.funcs = &chipone_bridge_funcs;
+	icn->bridge.of_node = dev->of_node;
+
+	drm_bridge_add(&icn->bridge);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		drm_bridge_remove(&icn->bridge);
+		DRM_DEV_ERROR(dev, "failed to attach dsi (ret = %d)\n", ret);
+	}
+
+	return ret;
+}
+
+static int chipone_remove(struct mipi_dsi_device *dsi)
+{
+	struct chipone *icn = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_bridge_remove(&icn->bridge);
+
+	return 0;
+}
+
+static const struct of_device_id chipone_of_match[] = {
+	{ .compatible = "bananapi,icn6211" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, chipone_of_match);
+
+static struct mipi_dsi_driver chipone_driver = {
+	.probe = chipone_probe,
+	.remove = chipone_remove,
+	.driver = {
+		.name = "chipone-icn6211",
+		.owner = THIS_MODULE,
+		.of_match_table = chipone_of_match,
+	},
+};
+module_mipi_dsi_driver(chipone_driver);
+
+MODULE_AUTHOR("Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>");
+MODULE_DESCRIPTION("Chipone ICN6211 MIPI-DSI to RGB Convertor Bridge");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0.321.gffc6fa0e3

WARNING: multiple messages have this Message-ID (diff)
From: Jagan Teki <jagan@amarulasolutions.com>
To: Andrzej Hajda <a.hajda@samsung.com>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Chen-Yu Tsai <wens@csie.org>,
	Maxime Ripard <maxime.ripard@bootlin.com>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org, linux-sunxi@googlegroups.com,
	Jagan Teki <jagan@amarulasolutions.com>,
	Michael Trimarchi <michael@amarulasolutions.com>,
	linux-amarula@amarulasolutions.com,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 5/6] drm/bridge: Add Chipone ICN6211 MIPI-DSI/RGB convertor bridge
Date: Fri, 15 Mar 2019 18:38:24 +0530	[thread overview]
Message-ID: <20190315130825.9005-6-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20190315130825.9005-1-jagan@amarulasolutions.com>

ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
It has a flexible configuration of MIPI DSI signal input
and produce RGB565, RGB666, RGB888 output format.

Add bridge driver for it.

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 MAINTAINERS                              |   6 +
 drivers/gpu/drm/bridge/Kconfig           |  10 +
 drivers/gpu/drm/bridge/Makefile          |   1 +
 drivers/gpu/drm/bridge/chipone-icn6211.c | 275 +++++++++++++++++++++++
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/chipone-icn6211.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4de80222cffb..e529addd30f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4897,6 +4897,12 @@ T:	git git://anongit.freedesktop.org/drm/drm-misc
 S:	Maintained
 F:	drivers/gpu/drm/bochs/
 
+DRM DRIVER FOR CHIPONE ICN6211 MIPI-DSI to RGB CONVERTOR BRIDGE
+M:	Jagan Teki <jagan@amarulasolutions.com>
+S:	Maintained
+F:	drivers/gpu/drm/bridge/chipone-icn6211.c
+F:	Documentation/devicetree/bindings/display/bridge/chipone,icn6211.txt
+
 DRM DRIVER FOR FARADAY TVE200 TV ENCODER
 M:	Linus Walleij <linus.walleij@linaro.org>
 T:	git git://anongit.freedesktop.org/drm/drm-misc
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 8840f396a7b6..cd314572e4ed 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -36,6 +36,16 @@ config DRM_CDNS_DSI
 	  Support Cadence DPI to DSI bridge. This is an internal
 	  bridge and is meant to be directly embedded in a SoC.
 
+config DRM_CHIPONE_ICN6211
+	tristate "Chipone ICN6211 MIPI-DSI/RGB converter bridge"
+	depends on DRM && DRM_PANEL
+	depends on OF
+	select DRM_MIPI_DSI
+	help
+	  ICN6211 is MIPI-DSI/RGB converter bridge from chipone.
+	  It has a flexible configuration of MIPI DSI signal input
+	  and produce RGB565, RGB666, RGB888 output format.
+
 config DRM_DUMB_VGA_DAC
 	tristate "Dumb VGA DAC Bridge support"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 4934fcf5a6f8..541fdccad10b 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
+obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
 obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c
new file mode 100644
index 000000000000..cd2f3505f845
--- /dev/null
+++ b/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Amarula Solutions
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+
+#define ICN6211_INIT_CMD_LEN		2
+
+struct chipone {
+	struct device *dev;
+	struct drm_bridge bridge;
+	struct drm_connector connector;
+	struct drm_panel *panel;
+
+	struct gpio_desc *reset;
+};
+
+static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct chipone, bridge);
+}
+
+static inline
+struct chipone *connector_to_chipone(struct drm_connector *connector)
+{
+	return container_of(connector, struct chipone, connector);
+}
+
+struct icn6211_init_cmd {
+	u8 data[ICN6211_INIT_CMD_LEN];
+};
+
+static const struct icn6211_init_cmd icn6211_init_cmds[] = {
+	{ .data = { 0x7A, 0xC1 } },
+	{ .data = { 0x20, 0x20 } },
+	{ .data = { 0x21, 0xE0 } },
+	{ .data = { 0x22, 0x13 } },
+	{ .data = { 0x23, 0x28 } },
+	{ .data = { 0x24, 0x30 } },
+	{ .data = { 0x25, 0x28 } },
+	{ .data = { 0x26, 0x00 } },
+	{ .data = { 0x27, 0x0D } },
+	{ .data = { 0x28, 0x03 } },
+	{ .data = { 0x29, 0x1D } },
+	{ .data = { 0x34, 0x80 } },
+	{ .data = { 0x36, 0x28 } },
+	{ .data = { 0xB5, 0xA0 } },
+	{ .data = { 0x5C, 0xFF } },
+	{ .data = { 0x2A, 0x01 } },
+	{ .data = { 0x56, 0x92 } },
+	{ .data = { 0x6B, 0x71 } },
+	{ .data = { 0x69, 0x2B } },
+	{ .data = { 0x10, 0x40 } },
+	{ .data = { 0x11, 0x98 } },
+	{ .data = { 0xB6, 0x20 } },
+	{ .data = { 0x51, 0x20 } },
+	{ .data = { 0x09, 0x10 } },
+};
+
+static int chipone_get_modes(struct drm_connector *connector)
+{
+	struct chipone *icn = connector_to_chipone(connector);
+
+	return drm_panel_get_modes(icn->panel);
+}
+
+static const
+struct drm_connector_helper_funcs chipone_connector_helper_funcs = {
+	.get_modes = chipone_get_modes,
+};
+
+static const struct drm_connector_funcs chipone_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void chipone_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_disable(bridge_to_chipone(bridge)->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error disabling panel (%d)\n", ret);
+}
+
+static void chipone_post_disable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret;
+
+	ret = drm_panel_unprepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error unpreparing panel (%d)\n", ret);
+
+	msleep(50);
+
+	gpiod_set_value(icn->reset, 0);
+}
+
+static void chipone_pre_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct mipi_dsi_device *dsi = to_mipi_dsi_device(icn->dev);
+	unsigned int i;
+	int ret;
+
+	gpiod_set_value(icn->reset, 0);
+	msleep(20);
+
+	gpiod_set_value(icn->reset, 1);
+	msleep(50);
+
+	for (i = 0; i < ARRAY_SIZE(icn6211_init_cmds); i++) {
+		const struct icn6211_init_cmd *cmd = &icn6211_init_cmds[i];
+
+		ret = mipi_dsi_generic_write(dsi, cmd->data,
+					     ICN6211_INIT_CMD_LEN);
+		if (ret < 0) {
+			DRM_DEV_ERROR(icn->dev,
+				      "failed to write cmd %d: %d\n", i, ret);
+			return;
+		}
+	}
+
+	ret = drm_panel_prepare(icn->panel);
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error preparing panel (%d)\n", ret);
+}
+
+static void chipone_enable(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	int ret = drm_panel_enable(icn->panel);
+
+	if (ret < 0)
+		DRM_DEV_ERROR(icn->dev, "error enabling panel (%d)\n", ret);
+}
+
+static int chipone_attach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+	int ret;
+
+	icn->connector.polled = DRM_CONNECTOR_POLL_HPD;
+	ret = drm_connector_init(drm, &icn->connector,
+				 &chipone_connector_funcs,
+				 DRM_MODE_CONNECTOR_Unknown);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(&icn->connector,
+				 &chipone_connector_helper_funcs);
+	drm_connector_attach_encoder(&icn->connector, bridge->encoder);
+	drm_panel_attach(icn->panel, &icn->connector);
+	icn->connector.funcs->reset(&icn->connector);
+	drm_fb_helper_add_one_connector(drm->fb_helper, &icn->connector);
+	drm_connector_register(&icn->connector);
+
+	return 0;
+}
+
+static void chipone_detach(struct drm_bridge *bridge)
+{
+	struct chipone *icn = bridge_to_chipone(bridge);
+	struct drm_device *drm = bridge->dev;
+
+	drm_connector_unregister(&icn->connector);
+	drm_fb_helper_remove_one_connector(drm->fb_helper, &icn->connector);
+	drm_panel_detach(icn->panel);
+	icn->panel = NULL;
+	drm_connector_put(&icn->connector);
+}
+
+static const struct drm_bridge_funcs chipone_bridge_funcs = {
+	.disable = chipone_disable,
+	.post_disable = chipone_post_disable,
+	.enable = chipone_enable,
+	.pre_enable = chipone_pre_enable,
+	.attach = chipone_attach,
+	.detach = chipone_detach,
+};
+
+static int chipone_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct chipone *icn;
+	int ret;
+
+	icn = devm_kzalloc(dev, sizeof(struct chipone), GFP_KERNEL);
+	if (!icn)
+		return -ENOMEM;
+
+	mipi_dsi_set_drvdata(dsi, icn);
+
+	icn->dev = dev;
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+
+	icn->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(icn->reset)) {
+		DRM_DEV_ERROR(dev, "no reset GPIO pin provided\n");
+		return PTR_ERR(icn->reset);
+	}
+
+	ret = drm_of_find_panel_or_bridge(icn->dev->of_node, 1, 0,
+					  &icn->panel, NULL);
+	if (ret && ret != -EPROBE_DEFER) {
+		DRM_DEV_ERROR(dev, "failed to find panel (ret = %d)\n", ret);
+		return ret;
+	}
+
+	icn->bridge.funcs = &chipone_bridge_funcs;
+	icn->bridge.of_node = dev->of_node;
+
+	drm_bridge_add(&icn->bridge);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		drm_bridge_remove(&icn->bridge);
+		DRM_DEV_ERROR(dev, "failed to attach dsi (ret = %d)\n", ret);
+	}
+
+	return ret;
+}
+
+static int chipone_remove(struct mipi_dsi_device *dsi)
+{
+	struct chipone *icn = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(dsi);
+	drm_bridge_remove(&icn->bridge);
+
+	return 0;
+}
+
+static const struct of_device_id chipone_of_match[] = {
+	{ .compatible = "bananapi,icn6211" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, chipone_of_match);
+
+static struct mipi_dsi_driver chipone_driver = {
+	.probe = chipone_probe,
+	.remove = chipone_remove,
+	.driver = {
+		.name = "chipone-icn6211",
+		.owner = THIS_MODULE,
+		.of_match_table = chipone_of_match,
+	},
+};
+module_mipi_dsi_driver(chipone_driver);
+
+MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");
+MODULE_DESCRIPTION("Chipone ICN6211 MIPI-DSI to RGB Convertor Bridge");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0.321.gffc6fa0e3


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2019-03-15 13:09 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-15 13:08 [PATCH 0/6] drm/bridge: Add ICN6211 MIPI-DSI/RGB bridge Jagan Teki
2019-03-15 13:08 ` Jagan Teki
2019-03-15 13:08 ` Jagan Teki
2019-03-15 13:08 ` [PATCH 1/6] drm/bridge: Export drm_bridge_detach Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:27   ` [linux-sunxi] " Paul Kocialkowski
2019-03-15 13:27     ` Paul Kocialkowski
2019-03-15 13:27     ` Paul Kocialkowski
2019-03-18 16:48     ` [linux-sunxi] " Jagan Teki
2019-03-18 16:48       ` Jagan Teki
2019-03-18 16:57       ` Paul Kocialkowski
2019-03-18 16:57         ` Paul Kocialkowski
2019-03-18 17:07         ` Jagan Teki
2019-03-18 17:07           ` Jagan Teki
2019-03-18 17:07           ` Jagan Teki
2019-03-15 13:08 ` [PATCH 2/6] drm/exynos: dsi: Use drm_bridge_detach Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-19  3:59   ` Inki Dae
2019-03-19  3:59     ` Inki Dae
2019-03-15 13:08 ` [PATCH 3/6] drm/sun4i: dsi: Add bridge support Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:32   ` [linux-sunxi] " Paul Kocialkowski
2019-03-15 13:32     ` Paul Kocialkowski
2019-03-15 13:32     ` Paul Kocialkowski
2019-03-15 13:45     ` [linux-sunxi] " Maxime Ripard
2019-03-15 13:45       ` Maxime Ripard
2019-03-15 13:45       ` Maxime Ripard
2019-03-15 13:48       ` [linux-sunxi] " Paul Kocialkowski
2019-03-15 13:48         ` Paul Kocialkowski
2019-03-15 13:48         ` Paul Kocialkowski
2019-03-15 15:20       ` [linux-sunxi] " Sergey Suloev
2019-05-22 12:01     ` Jagan Teki
2019-05-22 12:01       ` Jagan Teki
2019-03-15 13:08 ` [PATCH 4/6] dt-bindings: display: bridge: Add ICN6211 MIPI-DSI to RGB convertor bridge Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:34   ` Maxime Ripard
2019-03-15 13:34     ` Maxime Ripard
2019-03-15 13:34     ` Maxime Ripard
2019-03-18 16:58     ` Jagan Teki
2019-03-18 16:58       ` Jagan Teki
2019-03-19  2:59       ` [linux-sunxi] " Chen-Yu Tsai
2019-03-19  2:59         ` Chen-Yu Tsai
2019-03-19  7:48         ` Jagan Teki
2019-03-19  7:48           ` Jagan Teki
2019-03-19  7:48           ` Jagan Teki
2019-03-19  8:35       ` Maxime Ripard
2019-03-19  8:35         ` Maxime Ripard
2019-03-15 13:08 ` Jagan Teki [this message]
2019-03-15 13:08   ` [PATCH 5/6] drm/bridge: Add Chipone ICN6211 MIPI-DSI/RGB " Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:33   ` Maxime Ripard
2019-03-15 13:33     ` Maxime Ripard
2019-03-15 13:33     ` Maxime Ripard
2019-03-17 16:30     ` Laurent Pinchart
2019-03-17 16:30       ` Laurent Pinchart
2019-03-17 16:30       ` Laurent Pinchart
2019-03-18 17:59     ` Jagan Teki
2019-03-18 17:59       ` Jagan Teki
2019-03-19  3:05       ` [linux-sunxi] " Chen-Yu Tsai
2019-03-19  3:05         ` Chen-Yu Tsai
2019-03-19  3:05         ` Chen-Yu Tsai
2019-03-15 13:08 ` [PATCH 6/6] arm64: dts: allwinner: bananapi-m64: Enable S070WV20-CT16 DSI panel Jagan Teki
2019-03-15 13:08   ` Jagan Teki
2019-03-15 13:25   ` Maxime Ripard
2019-03-15 13:25     ` Maxime Ripard
2019-03-15 13:25     ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190315130825.9005-6-jagan@amarulasolutions.com \
    --to=jagan@amarulasolutions.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=a.hajda@samsung.com \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-amarula@amarulasolutions.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=mark.rutland@arm.com \
    --cc=maxime.ripard@bootlin.com \
    --cc=michael@amarulasolutions.com \
    --cc=robh+dt@kernel.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.