All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects
@ 2018-02-16 11:25 Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations Jyri Sarha
                   ` (8 more replies)
  0 siblings, 9 replies; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

This series is an RFC or a proof of concept, to demostrate what is
needed to get DSS6 driver workin on top of Laurent Pinchart's
"omapdrm: Allocate objects dynamically" -series:

https://patchwork.freedesktop.org/series/38152/

This series also contains my earlier "drm/omap: Make omapdss API more
generic + related patches" -series:

https://patchwork.freedesktop.org/series/35884/

... however, I squeezed get_ off from olv_name and mgr_name
dispc_ops. It is quite obvious from the prototype what these ops are
for after all.

These patches, plus some other patches need to get DSS6 workin on
k2g-evm can be found here:

git@github.com:jsarha/linux.git omapdrm-next-dss6

Jyri Sarha (7):
  drm/omap: Update omapdss API to allow alternative DSS implementations
  drm/omap: Fail probe if irq registration fails
  drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  drm/omap: Make omapdss API more generic
  drm/omap: move common stuff from dss.h to omapdss.h
  drm/omap: dss: Move platform_device_register from core.c to dss.c
    probe
  drm/omap: dss: platform_register_drivers() to dss.c and remove core.c

Tomi Valkeinen (2):
  drm/omap: add TI DSS6 driver
  drm/omap: boot-init: add k2g-dss

 drivers/gpu/drm/omapdrm/dss/Kconfig             |    8 +
 drivers/gpu/drm/omapdrm/dss/Makefile            |    5 +-
 drivers/gpu/drm/omapdrm/dss/base.c              |   11 +-
 drivers/gpu/drm/omapdrm/dss/core.c              |   88 --
 drivers/gpu/drm/omapdrm/dss/dispc.c             |  128 +-
 drivers/gpu/drm/omapdrm/dss/dispc.h             |   33 +
 drivers/gpu/drm/omapdrm/dss/dispc6.c            | 1438 +++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/dispc6.h            |  109 ++
 drivers/gpu/drm/omapdrm/dss/dpi6.c              |  283 +++++
 drivers/gpu/drm/omapdrm/dss/dss.c               |   58 +-
 drivers/gpu/drm/omapdrm/dss/dss.h               |   43 +-
 drivers/gpu/drm/omapdrm/dss/dss6.c              |  346 ++++++
 drivers/gpu/drm/omapdrm/dss/dss6.h              |   54 +
 drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c |    1 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h           |  135 ++-
 drivers/gpu/drm/omapdrm/omap_crtc.c             |   30 +-
 drivers/gpu/drm/omapdrm/omap_crtc.h             |    2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c              |    4 +-
 drivers/gpu/drm/omapdrm/omap_drv.h              |    5 +-
 drivers/gpu/drm/omapdrm/omap_irq.c              |  107 +-
 drivers/gpu/drm/omapdrm/omap_irq.h              |    2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c            |   18 +-
 drivers/gpu/drm/omapdrm/omap_plane.h            |    1 +
 23 files changed, 2607 insertions(+), 302 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/dss/core.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dispc6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dispc6.h
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dpi6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dss6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dss6.h

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-19 12:01   ` Tomi Valkeinen
  2018-02-16 11:25 ` [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails Jyri Sarha
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

After this patch OMAP_DSS_BASE module is not including any OMAP2_DSS
headers, only the API omapdss.h. "sturct dss_data", the piece of the
data structure needed for base.c is defined in omapdss.h and added as
a member to struct dss_device, and later to struct dss6_device.

The patch is still a bit hackish. The struct dispc_device declaration
is currently shared between alternative dss implementations, with
different internal definitions. It should be relatively simple to use
a similar struct dispc_data as struct dss_data is for dss_device, move
some common parts - maybe the dispc_ops itself - there and find the
private data with container_of macro. Also the contents of struct
dss_data in side dss_device is currently redundant. These should be
easy enough to fix, if we decide to take this route.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/base.c    | 11 +++++------
 drivers/gpu/drm/omapdrm/dss/dispc.c   |  4 ++++
 drivers/gpu/drm/omapdrm/dss/dss.c     |  2 +-
 drivers/gpu/drm/omapdrm/dss/dss.h     |  2 ++
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 13 +++++++++----
 drivers/gpu/drm/omapdrm/omap_drv.h    |  2 +-
 6 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index 99e8cb8..42442f3 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -19,10 +19,9 @@
 #include <linux/of_graph.h>
 #include <linux/list.h>
 
-#include "dss.h"
 #include "omapdss.h"
 
-static struct dss_device *dss_device;
+static struct dss_data *dss_device;
 
 static struct list_head omapdss_comp_list;
 
@@ -32,25 +31,25 @@ struct omapdss_comp_node {
 	bool dss_core_component;
 };
 
-struct dss_device *omapdss_get_dss(void)
+struct dss_data *omapdss_get_dss(void)
 {
 	return dss_device;
 }
 EXPORT_SYMBOL(omapdss_get_dss);
 
-void omapdss_set_dss(struct dss_device *dss)
+void omapdss_set_dss(struct dss_data *dss)
 {
 	dss_device = dss;
 }
 EXPORT_SYMBOL(omapdss_set_dss);
 
-struct dispc_device *dispc_get_dispc(struct dss_device *dss)
+struct dispc_device *dispc_get_dispc(struct dss_data *dss)
 {
 	return dss->dispc;
 }
 EXPORT_SYMBOL(dispc_get_dispc);
 
-const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
+const struct dispc_ops *dispc_get_ops(struct dss_data *dss)
 {
 	return dss->dispc_ops;
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index ce470b5..338490d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -4791,6 +4791,10 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
 	dispc->debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
 						 dispc);
 
+	// XXX get rid of the above redundant data members
+	dss->data.dispc = dss->dispc;
+	dss->data.dispc_ops = dss->dispc_ops;
+
 	return 0;
 
 err_runtime_get:
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 4a08bd1..5752328 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1326,7 +1326,7 @@ static int dss_bind(struct device *dev)
 	pm_set_vt_switch(0);
 
 	omapdss_gather_components(dev);
-	omapdss_set_dss(dss);
+	omapdss_set_dss(&dss->data);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 6f6fd3d..434262a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -273,6 +273,8 @@ struct dss_device {
 	struct dss_pll	*video1_pll;
 	struct dss_pll	*video2_pll;
 
+	struct dss_data data;
+	// XXX these are redundant, use data instead
 	struct dispc_device *dispc;
 	const struct dispc_ops *dispc_ops;
 };
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index a4f71e0..1299dd6 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -589,8 +589,13 @@ struct omap_dss_driver {
 		const struct hdmi_avi_infoframe *avi);
 };
 
-struct dss_device *omapdss_get_dss(void);
-void omapdss_set_dss(struct dss_device *dss);
+struct dss_data {
+	const struct dispc_ops *dispc_ops;
+	struct dispc_device *dispc;
+};
+
+struct dss_data *omapdss_get_dss(void);
+void omapdss_set_dss(struct dss_data *dss);
 static inline bool omapdss_is_initialized(void)
 {
 	return !!omapdss_get_dss();
@@ -749,8 +754,8 @@ struct dispc_ops {
 					  enum omap_plane_id plane);
 };
 
-struct dispc_device *dispc_get_dispc(struct dss_device *dss);
-const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
+struct dispc_device *dispc_get_dispc(struct dss_data *dss);
+const struct dispc_ops *dispc_get_ops(struct dss_data *dss);
 
 bool omapdss_component_is_display(struct device_node *node);
 bool omapdss_component_is_output(struct device_node *node);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 6eaee4d..3b7ec7e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -50,7 +50,7 @@ struct omap_drm_private {
 	struct device *dev;
 	u32 omaprev;
 
-	struct dss_device *dss;
+	struct dss_data *dss;
 	struct dispc_device *dispc;
 	const struct dispc_ops *dispc_ops;
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-27 14:27   ` Laurent Pinchart
  2018-02-16 11:25 ` [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops Jyri Sarha
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

Call to omap_drm_irq_install() may fail with an error code. In such a
case the driver probe should fail.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 65a567d..979bede 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -321,7 +321,9 @@ static int omap_modeset_init(struct drm_device *dev)
 
 	drm_mode_config_reset(dev);
 
-	omap_drm_irq_install(dev);
+	ret = omap_drm_irq_install(dev);
+	if (ret)
+		return ret;
 
 	return 0;
 }
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-27 14:35   ` Laurent Pinchart
  2018-02-16 11:25 ` [PATCH RFC 4/9] drm/omap: Make omapdss API more generic Jyri Sarha
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

Add ovl_name() and mgr_name() to dispc_ops and get rid of adhoc names
here and there in the omapdrm code. This moves the names of hardware
entities to omapdss side where they have to be when new omapdss
backend drivers are introduced.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dispc.c   | 23 +++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  5 +++++
 drivers/gpu/drm/omapdrm/omap_crtc.c   | 11 ++---------
 drivers/gpu/drm/omapdrm/omap_irq.c    | 19 +++++++------------
 drivers/gpu/drm/omapdrm/omap_plane.c  | 13 +++----------
 5 files changed, 40 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 338490d..6f83b3e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -694,6 +694,26 @@ void dispc_runtime_put(struct dispc_device *dispc)
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
+static const char *dispc_ovl_name(struct dispc_device *dispc,
+				  enum omap_plane_id plane)
+{
+	static const char * const ovl_names[] = {
+		[OMAP_DSS_GFX]		= "GFX",
+		[OMAP_DSS_VIDEO1]	= "VID1",
+		[OMAP_DSS_VIDEO2]	= "VID2",
+		[OMAP_DSS_VIDEO3]	= "VID3",
+		[OMAP_DSS_WB]		= "WB",
+	};
+
+	return ovl_names[plane];
+}
+
+static const char *dispc_mgr_name(struct dispc_device *dispc,
+				  enum omap_channel channel)
+{
+	return mgr_desc[channel].name;
+}
+
 static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc,
 				   enum omap_channel channel)
 {
@@ -4662,6 +4682,9 @@ static const struct dispc_ops dispc_ops = {
 	.get_num_ovls = dispc_get_num_ovls,
 	.get_num_mgrs = dispc_get_num_mgrs,
 
+	.ovl_name = dispc_ovl_name,
+	.mgr_name = dispc_mgr_name,
+
 	.get_memory_bandwidth_limit = dispc_get_memory_bandwidth_limit,
 
 	.mgr_enable = dispc_mgr_enable,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 1299dd6..b84cfd8 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -711,6 +711,11 @@ struct dispc_ops {
 	int (*get_num_ovls)(struct dispc_device *dispc);
 	int (*get_num_mgrs)(struct dispc_device *dispc);
 
+	const char *(*ovl_name)(struct dispc_device *dispc,
+				enum omap_plane_id plane);
+	const char *(*mgr_name)(struct dispc_device *dispc,
+				enum omap_channel channel);
+
 	u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc);
 
 	void (*mgr_enable)(struct dispc_device *dispc,
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 6c4d40b..00ec959 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -672,13 +672,6 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
  * Init and Cleanup
  */
 
-static const char *channel_names[] = {
-	[OMAP_DSS_CHANNEL_LCD] = "lcd",
-	[OMAP_DSS_CHANNEL_DIGIT] = "tv",
-	[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
-	[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
-};
-
 void omap_crtc_pre_init(struct omap_drm_private *priv)
 {
 	memset(omap_crtcs, 0, sizeof(omap_crtcs));
@@ -706,7 +699,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	channel = out->dispc_channel;
 	omap_dss_put_device(out);
 
-	DBG("%s", channel_names[channel]);
+	DBG("%s", priv->dispc_ops->mgr_name(priv->dispc, channel));
 
 	/* Multiple displays on same channel is not allowed */
 	if (WARN_ON(omap_crtcs[channel] != NULL))
@@ -721,7 +714,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	init_waitqueue_head(&omap_crtc->pending_wait);
 
 	omap_crtc->channel = channel;
-	omap_crtc->name = channel_names[channel];
+	omap_crtc->name = priv->dispc_ops->mgr_name(priv->dispc, channel);
 
 	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
 					&omap_crtc_funcs, NULL);
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index c8511504..5cc88b6 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -146,15 +146,10 @@ static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
 {
 	static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
 				      DEFAULT_RATELIMIT_BURST);
-	static const struct {
-		const char *name;
-		u32 mask;
-	} sources[] = {
-		{ "gfx", DISPC_IRQ_GFX_FIFO_UNDERFLOW },
-		{ "vid1", DISPC_IRQ_VID1_FIFO_UNDERFLOW },
-		{ "vid2", DISPC_IRQ_VID2_FIFO_UNDERFLOW },
-		{ "vid3", DISPC_IRQ_VID3_FIFO_UNDERFLOW },
-	};
+	static const u32 irqbits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW,
+				       DISPC_IRQ_VID1_FIFO_UNDERFLOW,
+				       DISPC_IRQ_VID2_FIFO_UNDERFLOW,
+				       DISPC_IRQ_VID3_FIFO_UNDERFLOW };
 
 	const u32 mask = DISPC_IRQ_GFX_FIFO_UNDERFLOW
 		       | DISPC_IRQ_VID1_FIFO_UNDERFLOW
@@ -174,9 +169,9 @@ static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
 
 	DRM_ERROR("FIFO underflow on ");
 
-	for (i = 0; i < ARRAY_SIZE(sources); ++i) {
-		if (sources[i].mask & irqstatus)
-			pr_cont("%s ", sources[i].name);
+	for (i = 0; i < ARRAY_SIZE(irqbits); ++i) {
+		if (irqbits[i] & irqstatus)
+			pr_cont("%s ", priv->dispc_ops->ovl_name(priv->dispc, i));
 	}
 
 	pr_cont("(0x%08x)\n", irqstatus);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2899435..61b0753 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -239,13 +239,6 @@ static const struct drm_plane_funcs omap_plane_funcs = {
 	.atomic_get_property = omap_plane_atomic_get_property,
 };
 
-static const char *plane_id_to_name[] = {
-	[OMAP_DSS_GFX] = "gfx",
-	[OMAP_DSS_VIDEO1] = "vid1",
-	[OMAP_DSS_VIDEO2] = "vid2",
-	[OMAP_DSS_VIDEO3] = "vid3",
-};
-
 static const enum omap_plane_id plane_idx_to_id[] = {
 	OMAP_DSS_GFX,
 	OMAP_DSS_VIDEO1,
@@ -272,7 +265,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 
 	id = plane_idx_to_id[idx];
 
-	DBG("%s: type=%d", plane_id_to_name[id], type);
+	DBG("%s: type=%d", priv->dispc_ops->ovl_name(priv->dispc, id), type);
 
 	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
 	if (!omap_plane)
@@ -282,7 +275,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 	for (nformats = 0; formats[nformats]; ++nformats)
 		;
 	omap_plane->id = id;
-	omap_plane->name = plane_id_to_name[id];
+	omap_plane->name = priv->dispc_ops->ovl_name(priv->dispc, id);
 
 	plane = &omap_plane->base;
 
@@ -301,7 +294,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 
 error:
 	dev_err(dev->dev, "%s(): could not create plane: %s\n",
-		__func__, plane_id_to_name[id]);
+		__func__, priv->dispc_ops->ovl_name(priv->dispc, id));
 
 	kfree(omap_plane);
 	return NULL;
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 4/9] drm/omap: Make omapdss API more generic
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (2 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-19 12:41   ` Tomi Valkeinen
  2018-02-16 11:25 ` [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h Jyri Sarha
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

The new omapdss API is HW independent and cleans up some of the DSS5
specific hacks from the omapdrm side and gets rid off the DSS5 IRQ
register bits and replace them with HW independent generic u64 based
macros. The new macros make it more straight forward to implement the
IRQ code for the future DSS versions that do not share the same
register structure as DSS2 to DSS5 has.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dispc.c   | 115 +++++++++++++++++++++++++---------
 drivers/gpu/drm/omapdrm/dss/dispc.h   |  33 ++++++++++
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  80 +++++++++++------------
 drivers/gpu/drm/omapdrm/omap_crtc.c   |  19 +++---
 drivers/gpu/drm/omapdrm/omap_crtc.h   |   2 +-
 drivers/gpu/drm/omapdrm/omap_drv.h    |   3 +-
 drivers/gpu/drm/omapdrm/omap_irq.c    | 102 ++++++++++++------------------
 drivers/gpu/drm/omapdrm/omap_irq.h    |   2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c  |   7 +++
 drivers/gpu/drm/omapdrm/omap_plane.h  |   1 +
 10 files changed, 219 insertions(+), 145 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 6f83b3e..3df0a88 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -714,30 +714,11 @@ static const char *dispc_mgr_name(struct dispc_device *dispc,
 	return mgr_desc[channel].name;
 }
 
-static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc,
-				   enum omap_channel channel)
+static bool dispc_mgr_has_framedone(struct dispc_device *dispc,
+				    enum omap_channel channel)
 {
-	return mgr_desc[channel].vsync_irq;
-}
-
-static u32 dispc_mgr_get_framedone_irq(struct dispc_device *dispc,
-				       enum omap_channel channel)
-{
-	if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc->feat->no_framedone_tv)
-		return 0;
-
-	return mgr_desc[channel].framedone_irq;
-}
-
-static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc,
-				       enum omap_channel channel)
-{
-	return mgr_desc[channel].sync_lost_irq;
-}
-
-u32 dispc_wb_get_framedone_irq(struct dispc_device *dispc)
-{
-	return DISPC_IRQ_FRAMEDONEWB;
+	return channel != OMAP_DSS_CHANNEL_DIGIT ||
+		dispc->feat->no_framedone_tv;
 }
 
 static void dispc_mgr_enable(struct dispc_device *dispc,
@@ -3752,6 +3733,77 @@ static void dispc_write_irqenable(struct dispc_device *dispc, u32 mask)
 	dispc_read_reg(dispc, DISPC_IRQENABLE);
 }
 
+struct dispc_irq_bit {
+	u32 hw;
+	u64 api;
+};
+
+static const struct dispc_irq_bit dispc_irq_bits[] = {
+	{ DISPC_IRQ_OCP_ERR, DSS_IRQ_DEVICE_OCP_ERR },
+
+	{ DISPC_IRQ_FRAMEDONE, DSS_IRQ_MGR_FRAME_DONE(0) },
+	{ DISPC_IRQ_VSYNC, DSS_IRQ_MGR_VSYNC_EVEN(0) },
+	{ DISPC_IRQ_SYNC_LOST, DSS_IRQ_MGR_SYNC_LOST(0) },
+
+	{ DISPC_IRQ_EVSYNC_EVEN, DSS_IRQ_MGR_VSYNC_EVEN(1) },
+	{ DISPC_IRQ_EVSYNC_ODD, DSS_IRQ_MGR_VSYNC_ODD(1) },
+	{ DISPC_IRQ_SYNC_LOST_DIGIT, DSS_IRQ_MGR_SYNC_LOST(1) },
+	{ DISPC_IRQ_FRAMEDONETV, DSS_IRQ_MGR_FRAME_DONE(1) },
+
+	{ DISPC_IRQ_SYNC_LOST2, DSS_IRQ_MGR_SYNC_LOST(2) },
+	{ DISPC_IRQ_VSYNC2, DSS_IRQ_MGR_VSYNC_EVEN(2) },
+	{ DISPC_IRQ_FRAMEDONE2, DSS_IRQ_MGR_FRAME_DONE(2) },
+
+	{ DISPC_IRQ_SYNC_LOST3, DSS_IRQ_MGR_SYNC_LOST(3) },
+	{ DISPC_IRQ_VSYNC3, DSS_IRQ_MGR_VSYNC_EVEN(3) },
+	{ DISPC_IRQ_FRAMEDONE3, DSS_IRQ_MGR_FRAME_DONE(3) },
+
+	{ DISPC_IRQ_GFX_FIFO_UNDERFLOW, DSS_IRQ_OVL_FIFO_UNDERFLOW(0) },
+	{ DISPC_IRQ_VID1_FIFO_UNDERFLOW, DSS_IRQ_OVL_FIFO_UNDERFLOW(1) },
+	{ DISPC_IRQ_VID2_FIFO_UNDERFLOW, DSS_IRQ_OVL_FIFO_UNDERFLOW(2) },
+	{ DISPC_IRQ_VID3_FIFO_UNDERFLOW, DSS_IRQ_OVL_FIFO_UNDERFLOW(3) },
+};
+
+static u64 dispc_hw_to_api_irq(u32 hw)
+{
+	u64 api = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dispc_irq_bits); i++)
+		if (hw & dispc_irq_bits[i].hw)
+			api |= dispc_irq_bits[i].api;
+
+	return api;
+}
+
+static u32 dispc_api_to_hw_irq(u64 api)
+{
+	u32 hw = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dispc_irq_bits); i++)
+		if (api & dispc_irq_bits[i].api)
+			hw |= dispc_irq_bits[i].hw;
+
+	return hw;
+}
+
+static u64 dispc_api_read_and_clear_irqstatus(struct dispc_device *dispc)
+{
+	u32 hw_status = dispc_read_irqstatus(dispc);
+
+	dispc_clear_irqstatus(dispc, hw_status);
+
+	return dispc_hw_to_api_irq(hw_status);
+}
+
+static void dispc_api_write_irqenable(struct dispc_device *dispc, u64 enable)
+{
+	u32 hw_enable = dispc_api_to_hw_irq(enable);
+
+	dispc_write_irqenable(dispc, hw_enable);
+}
+
 void dispc_enable_sidle(struct dispc_device *dispc)
 {
 	/* SIDLEMODE: smart idle */
@@ -4473,6 +4525,10 @@ static int dispc_request_irq(struct dispc_device *dispc, irq_handler_t handler,
 	if (dispc->user_handler != NULL)
 		return -EBUSY;
 
+	dispc_runtime_get(dispc);
+	dispc_clear_irqstatus(dispc, 0xffffffff);
+	dispc_runtime_put(dispc);
+
 	dispc->user_handler = handler;
 	dispc->user_data = dev_id;
 
@@ -4610,8 +4666,7 @@ static void dispc_errata_i734_wa_fini(struct dispc_device *dispc)
 
 static void dispc_errata_i734_wa(struct dispc_device *dispc)
 {
-	u32 framedone_irq = dispc_mgr_get_framedone_irq(dispc,
-							OMAP_DSS_CHANNEL_LCD);
+	u32 framedone_irq = DISPC_IRQ_FRAMEDONE;
 	struct omap_overlay_info ovli;
 	struct dss_lcd_mgr_config lcd_conf;
 	u32 gatestate;
@@ -4669,9 +4724,8 @@ static void dispc_errata_i734_wa(struct dispc_device *dispc)
 }
 
 static const struct dispc_ops dispc_ops = {
-	.read_irqstatus = dispc_read_irqstatus,
-	.clear_irqstatus = dispc_clear_irqstatus,
-	.write_irqenable = dispc_write_irqenable,
+	.read_and_clear_irqstatus = dispc_api_read_and_clear_irqstatus,
+	.write_irqenable = dispc_api_write_irqenable,
 
 	.request_irq = dispc_request_irq,
 	.free_irq = dispc_free_irq,
@@ -4685,13 +4739,12 @@ static const struct dispc_ops dispc_ops = {
 	.ovl_name = dispc_ovl_name,
 	.mgr_name = dispc_mgr_name,
 
+	.mgr_has_framedone = dispc_mgr_has_framedone,
+
 	.get_memory_bandwidth_limit = dispc_get_memory_bandwidth_limit,
 
 	.mgr_enable = dispc_mgr_enable,
 	.mgr_is_enabled = dispc_mgr_is_enabled,
-	.mgr_get_vsync_irq = dispc_mgr_get_vsync_irq,
-	.mgr_get_framedone_irq = dispc_mgr_get_framedone_irq,
-	.mgr_get_sync_lost_irq = dispc_mgr_get_sync_lost_irq,
 	.mgr_go_busy = dispc_mgr_go_busy,
 	.mgr_go = dispc_mgr_go,
 	.mgr_set_lcd_config = dispc_mgr_set_lcd_config,
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.h b/drivers/gpu/drm/omapdrm/dss/dispc.h
index e901dd1..e71266e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.h
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.h
@@ -18,6 +18,39 @@
 #ifndef __OMAP2_DISPC_REG_H
 #define __OMAP2_DISPC_REG_H
 
+/* DISPC IRQ bits */
+#define DISPC_IRQ_FRAMEDONE		(1 << 0)
+#define DISPC_IRQ_VSYNC			(1 << 1)
+#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
+#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
+#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
+#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
+#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
+#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
+#define DISPC_IRQ_OCP_ERR		(1 << 9)
+#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
+#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
+#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
+#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
+#define DISPC_IRQ_SYNC_LOST		(1 << 14)
+#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
+#define DISPC_IRQ_WAKEUP		(1 << 16)
+#define DISPC_IRQ_SYNC_LOST2		(1 << 17)
+#define DISPC_IRQ_VSYNC2		(1 << 18)
+#define DISPC_IRQ_VID3_END_WIN		(1 << 19)
+#define DISPC_IRQ_VID3_FIFO_UNDERFLOW	(1 << 20)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT2	(1 << 21)
+#define DISPC_IRQ_FRAMEDONE2		(1 << 22)
+#define DISPC_IRQ_FRAMEDONEWB		(1 << 23)
+#define DISPC_IRQ_FRAMEDONETV		(1 << 24)
+#define DISPC_IRQ_WBBUFFEROVERFLOW	(1 << 25)
+#define DISPC_IRQ_WBUNCOMPLETEERROR	(1 << 26)
+#define DISPC_IRQ_SYNC_LOST3		(1 << 27)
+#define DISPC_IRQ_VSYNC3		(1 << 28)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
+#define DISPC_IRQ_FRAMEDONE3		(1 << 30)
+
 /* DISPC common registers */
 #define DISPC_REVISION			0x0000
 #define DISPC_SYSCONFIG			0x0010
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index b84cfd8..493237e 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -27,37 +27,41 @@
 #include <uapi/drm/drm_mode.h>
 #include <drm/drm_crtc.h>
 
-#define DISPC_IRQ_FRAMEDONE		(1 << 0)
-#define DISPC_IRQ_VSYNC			(1 << 1)
-#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
-#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
-#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
-#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
-#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
-#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
-#define DISPC_IRQ_OCP_ERR		(1 << 9)
-#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
-#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
-#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
-#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
-#define DISPC_IRQ_SYNC_LOST		(1 << 14)
-#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
-#define DISPC_IRQ_WAKEUP		(1 << 16)
-#define DISPC_IRQ_SYNC_LOST2		(1 << 17)
-#define DISPC_IRQ_VSYNC2		(1 << 18)
-#define DISPC_IRQ_VID3_END_WIN		(1 << 19)
-#define DISPC_IRQ_VID3_FIFO_UNDERFLOW	(1 << 20)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT2	(1 << 21)
-#define DISPC_IRQ_FRAMEDONE2		(1 << 22)
-#define DISPC_IRQ_FRAMEDONEWB		(1 << 23)
-#define DISPC_IRQ_FRAMEDONETV		(1 << 24)
-#define DISPC_IRQ_WBBUFFEROVERFLOW	(1 << 25)
-#define DISPC_IRQ_WBUNCOMPLETEERROR	(1 << 26)
-#define DISPC_IRQ_SYNC_LOST3		(1 << 27)
-#define DISPC_IRQ_VSYNC3		(1 << 28)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
-#define DISPC_IRQ_FRAMEDONE3		(1 << 30)
+#define DSS_MAX_CHANNELS 8
+#define DSS_MAX_OVLS 8
+
+/*
+ * Based on the above 2 defines the bellow defines describe following
+ * u64 IRQ bits:
+ *
+ * bit group |dev |mrg0|mrg1|mrg2|mrg3|mrg4|mrg5|mrg6|mrg7| ovl0-7  |<unused> |
+ * bit use   |D   |FEOL|FEOL|FEOL|FEOL|FEOL|FEOL|FEOL|FEOL|UUUU|UUUU| | | | | |
+ * bit number|0-3 |4-7 |8-11|            12-35            |  36-43  |  44-63  |
+ *
+ * device bits: D = OCP error
+ * mgr bits:    F = frame done, E = vsync even, O = vsync odd, L = sync lost
+ * ovl bits:    U = fifo underflow
+ */
+#define DSS_IRQ_DEVICE_OCP_ERR		BIT_ULL(0)
+
+#define DSS_IRQ_MGR_BIT_N(ch, bit)	(4 + 4 * ch + bit)
+#define DSS_IRQ_OVL_BIT_N(ovl, bit) \
+	(DSS_IRQ_MGR_BIT_N(DSS_MAX_CHANNELS, 0) + 1 * ovl + bit)
+
+#define DSS_IRQ_MGR_BIT(ch, bit)	BIT_ULL(DSS_IRQ_MGR_BIT_N(ch, bit))
+#define DSS_IRQ_OVL_BIT(ovl, bit)	BIT_ULL(DSS_IRQ_OVL_BIT_N(ovl, bit))
+
+#define DSS_IRQ_MGR_MASK(ch) \
+	GENMASK_ULL(DSS_IRQ_MGR_BIT_N(ch, 3), DSS_IRQ_MGR_BIT_N(ch, 0))
+#define DSS_IRQ_OVL_MASK(ovl) \
+	GENMASK_ULL(DSS_IRQ_OVL_BIT_N(ovl, 0), DSS_IRQ_OVL_BIT_N(ovl, 0))
+
+#define DSS_IRQ_MGR_FRAME_DONE(ch)	DSS_IRQ_MGR_BIT(ch, 0)
+#define DSS_IRQ_MGR_VSYNC_EVEN(ch)	DSS_IRQ_MGR_BIT(ch, 1)
+#define DSS_IRQ_MGR_VSYNC_ODD(ch)	DSS_IRQ_MGR_BIT(ch, 2)
+#define DSS_IRQ_MGR_SYNC_LOST(ch)	DSS_IRQ_MGR_BIT(ch, 3)
+
+#define DSS_IRQ_OVL_FIFO_UNDERFLOW(ovl)	DSS_IRQ_OVL_BIT(ovl, 0)
 
 struct dss_device;
 struct omap_drm_private;
@@ -697,9 +701,8 @@ void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
 /* dispc ops */
 
 struct dispc_ops {
-	u32 (*read_irqstatus)(struct dispc_device *dispc);
-	void (*clear_irqstatus)(struct dispc_device *dispc, u32 mask);
-	void (*write_irqenable)(struct dispc_device *dispc, u32 mask);
+	u64 (*read_and_clear_irqstatus)(struct dispc_device *dispc);
+	void (*write_irqenable)(struct dispc_device *dispc, u64 enable);
 
 	int (*request_irq)(struct dispc_device *dispc, irq_handler_t handler,
 			   void *dev_id);
@@ -716,18 +719,15 @@ struct dispc_ops {
 	const char *(*mgr_name)(struct dispc_device *dispc,
 				enum omap_channel channel);
 
+	bool (*mgr_has_framedone)(struct dispc_device *dispc,
+				  enum omap_channel channel);
+
 	u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc);
 
 	void (*mgr_enable)(struct dispc_device *dispc,
 			   enum omap_channel channel, bool enable);
 	bool (*mgr_is_enabled)(struct dispc_device *dispc,
 			       enum omap_channel channel);
-	u32 (*mgr_get_vsync_irq)(struct dispc_device *dispc,
-				 enum omap_channel channel);
-	u32 (*mgr_get_framedone_irq)(struct dispc_device *dispc,
-				     enum omap_channel channel);
-	u32 (*mgr_get_sync_lost_irq)(struct dispc_device *dispc,
-				     enum omap_channel channel);
 	bool (*mgr_go_busy)(struct dispc_device *dispc,
 			    enum omap_channel channel);
 	void (*mgr_go)(struct dispc_device *dispc, enum omap_channel channel);
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 00ec959..85fc2b8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -153,7 +153,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	enum omap_channel channel = omap_crtc->channel;
 	struct omap_irq_wait *wait;
-	u32 framedone_irq, vsync_irq;
+	u64 vsync_irq;
 	int ret;
 
 	if (WARN_ON(omap_crtc->enabled == enable))
@@ -173,10 +173,8 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 		omap_crtc->ignore_digit_sync_lost = true;
 	}
 
-	framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc,
-							       channel);
-	vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel);
-
+	vsync_irq = (DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+		     DSS_IRQ_MGR_VSYNC_ODD(channel));
 	if (enable) {
 		wait = omap_irq_wait_init(dev, vsync_irq, 1);
 	} else {
@@ -189,8 +187,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 		 * even and odd frames.
 		 */
 
-		if (framedone_irq)
-			wait = omap_irq_wait_init(dev, framedone_irq, 1);
+		if (priv->dispc_ops->mgr_has_framedone(priv->dispc, channel))
+			wait = omap_irq_wait_init(dev,
+					DSS_IRQ_MGR_FRAME_DONE(channel), 1);
 		else
 			wait = omap_irq_wait_init(dev, vsync_irq, 2);
 	}
@@ -281,17 +280,17 @@ static const struct dss_mgr_ops mgr_ops = {
  * Setup, Flush and Page Flip
  */
 
-void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus)
+void omap_crtc_error_irq(struct drm_crtc *crtc, u64 irqstatus)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 
 	if (omap_crtc->ignore_digit_sync_lost) {
-		irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+		irqstatus &= ~DSS_IRQ_MGR_SYNC_LOST(omap_crtc->channel);
 		if (!irqstatus)
 			return;
 	}
 
-	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+	DRM_ERROR_RATELIMITED("%s: errors: %016llx\n", omap_crtc->name, irqstatus);
 }
 
 void omap_crtc_vblank_irq(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h
index eaab2d7..3c441ea 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.h
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.h
@@ -37,7 +37,7 @@ void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct drm_plane *plane, struct omap_dss_device *dssdev);
 int omap_crtc_wait_pending(struct drm_crtc *crtc);
-void omap_crtc_error_irq(struct drm_crtc *crtc, u32 irqstatus);
+void omap_crtc_error_irq(struct drm_crtc *crtc, u64 irqstatus);
 void omap_crtc_vblank_irq(struct drm_crtc *crtc);
 
 #endif /* __OMAPDRM_CRTC_H__ */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 3b7ec7e..08c8c11 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -85,7 +85,8 @@ struct omap_drm_private {
 	/* irq handling: */
 	spinlock_t wait_lock;		/* protects the wait_list */
 	struct list_head wait_list;	/* list of omap_irq_wait */
-	u32 irq_mask;			/* enabled irqs in addition to wait_list */
+	u64 irq_mask;			/* enabled irqs in addition to wait_list */
+	u64 irq_uf_mask;		/* underflow irq bits for all planes */
 
 	/* memory bandwidth limit if it is needed on the platform */
 	unsigned int max_bandwidth;
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index 5cc88b6..9231962 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -20,7 +20,7 @@
 struct omap_irq_wait {
 	struct list_head node;
 	wait_queue_head_t wq;
-	u32 irqmask;
+	u64 irqmask;
 	int count;
 };
 
@@ -29,15 +29,15 @@ static void omap_irq_update(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_irq_wait *wait;
-	u32 irqmask = priv->irq_mask;
+	u64 irqmask;
 
 	assert_spin_locked(&priv->wait_lock);
 
+	irqmask = priv->irq_mask;
+
 	list_for_each_entry(wait, &priv->wait_list, node)
 		irqmask |= wait->irqmask;
 
-	DBG("irqmask=%08x", irqmask);
-
 	priv->dispc_ops->write_irqenable(priv->dispc, irqmask);
 }
 
@@ -48,14 +48,17 @@ static void omap_irq_wait_handler(struct omap_irq_wait *wait)
 }
 
 struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
-		u32 irqmask, int count)
+		u64 waitmask, int count)
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL);
 	unsigned long flags;
 
+	if (!wait)
+		return NULL;
+
 	init_waitqueue_head(&wait->wq);
-	wait->irqmask = irqmask;
+	wait->irqmask = waitmask;
 	wait->count = count;
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
@@ -108,8 +111,8 @@ int omap_irq_enable_vblank(struct drm_crtc *crtc)
 	DBG("dev=%p, crtc=%u", dev, channel);
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
-	priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
-							     channel);
+	priv->irq_mask |= DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+		DSS_IRQ_MGR_VSYNC_ODD(channel);
 	omap_irq_update(dev);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
@@ -135,33 +138,25 @@ void omap_irq_disable_vblank(struct drm_crtc *crtc)
 	DBG("dev=%p, crtc=%u", dev, channel);
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
-	priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
-							      channel);
+	priv->irq_mask &= ~(DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+			    DSS_IRQ_MGR_VSYNC_ODD(channel));
 	omap_irq_update(dev);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 }
 
 static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
-				    u32 irqstatus)
+				    u64 irqstatus)
 {
 	static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
 				      DEFAULT_RATELIMIT_BURST);
-	static const u32 irqbits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID1_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID2_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID3_FIFO_UNDERFLOW };
-
-	const u32 mask = DISPC_IRQ_GFX_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID1_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID2_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID3_FIFO_UNDERFLOW;
 	unsigned int i;
+	u64 masked;
 
 	spin_lock(&priv->wait_lock);
-	irqstatus &= priv->irq_mask & mask;
+	masked = irqstatus & priv->irq_uf_mask & priv->irq_mask;
 	spin_unlock(&priv->wait_lock);
 
-	if (!irqstatus)
+	if (!masked)
 		return;
 
 	if (!__ratelimit(&_rs))
@@ -169,21 +164,20 @@ static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
 
 	DRM_ERROR("FIFO underflow on ");
 
-	for (i = 0; i < ARRAY_SIZE(irqbits); ++i) {
-		if (irqbits[i] & irqstatus)
-			pr_cont("%s ", priv->dispc_ops->ovl_name(priv->dispc, i));
+	for (i = 0; i < DSS_MAX_OVLS; ++i) {
+		if (masked & DSS_IRQ_OVL_FIFO_UNDERFLOW(i))
+			pr_cont("%u:%s ", i,
+				priv->dispc_ops->ovl_name(priv->dispc, i));
 	}
 
-	pr_cont("(0x%08x)\n", irqstatus);
+	pr_cont("(%016llx)\n", irqstatus);
 }
 
 static void omap_irq_ocp_error_handler(struct drm_device *dev,
-	u32 irqstatus)
+				       u64 irqstatus)
 {
-	if (!(irqstatus & DISPC_IRQ_OCP_ERR))
-		return;
-
-	dev_err_ratelimited(dev->dev, "OCP error\n");
+	if (irqstatus & DSS_IRQ_DEVICE_OCP_ERR)
+		dev_err_ratelimited(dev->dev, "OCP error\n");
 }
 
 static irqreturn_t omap_irq_handler(int irq, void *arg)
@@ -193,24 +187,23 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 	struct omap_irq_wait *wait, *n;
 	unsigned long flags;
 	unsigned int id;
-	u32 irqstatus;
+	u64 irqstatus;
 
-	irqstatus = priv->dispc_ops->read_irqstatus(priv->dispc);
-	priv->dispc_ops->clear_irqstatus(priv->dispc, irqstatus);
-	priv->dispc_ops->read_irqstatus(priv->dispc);	/* flush posted write */
+	irqstatus = priv->dispc_ops->read_and_clear_irqstatus(priv->dispc);
 
-	VERB("irqs: %08x", irqstatus);
+	VERB("irqs: 0x%016llx\n", irqstatus);
 
 	for (id = 0; id < priv->num_crtcs; id++) {
 		struct drm_crtc *crtc = priv->crtcs[id];
 		enum omap_channel channel = omap_crtc_channel(crtc);
 
-		if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel)) {
+		if (irqstatus & (DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+				 DSS_IRQ_MGR_VSYNC_ODD(channel))) {
 			drm_handle_vblank(dev, id);
 			omap_crtc_vblank_irq(crtc);
 		}
 
-		if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel))
+		if (irqstatus & DSS_IRQ_MGR_SYNC_LOST(channel))
 			omap_crtc_error_irq(crtc, irqstatus);
 	}
 
@@ -219,7 +212,7 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
 	list_for_each_entry_safe(wait, n, &priv->wait_list, node) {
-		if (wait->irqmask & irqstatus)
+		if (irqstatus & wait->irqmask)
 			omap_irq_wait_handler(wait);
 	}
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
@@ -227,13 +220,6 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static const u32 omap_underflow_irqs[] = {
-	[OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW,
-};
-
 /*
  * We need a special version, instead of just using drm_irq_install(),
  * because we need to register the irq via omapdss.  Once omapdss and
@@ -244,29 +230,23 @@ static const u32 omap_underflow_irqs[] = {
 int omap_drm_irq_install(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
-	unsigned int max_planes;
 	unsigned int i;
 	int ret;
 
 	spin_lock_init(&priv->wait_lock);
 	INIT_LIST_HEAD(&priv->wait_list);
 
-	priv->irq_mask = DISPC_IRQ_OCP_ERR;
-
-	max_planes = min(ARRAY_SIZE(priv->planes),
-			 ARRAY_SIZE(omap_underflow_irqs));
-	for (i = 0; i < max_planes; ++i) {
-		if (priv->planes[i])
-			priv->irq_mask |= omap_underflow_irqs[i];
-	}
+	priv->irq_mask = DSS_IRQ_DEVICE_OCP_ERR;
 
-	for (i = 0; i < num_mgrs; ++i)
-		priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, i);
+	priv->irq_uf_mask = 0;
+	for (i = 0; i < priv->num_planes; ++i)
+		priv->irq_uf_mask |= DSS_IRQ_OVL_FIFO_UNDERFLOW(
+			omap_plane_get_id(priv->planes[i]));
+	priv->irq_mask |= priv->irq_uf_mask;
 
-	priv->dispc_ops->runtime_get(priv->dispc);
-	priv->dispc_ops->clear_irqstatus(priv->dispc, 0xffffffff);
-	priv->dispc_ops->runtime_put(priv->dispc);
+	for (i = 0; i < priv->num_crtcs; ++i)
+		priv->irq_mask |= DSS_IRQ_MGR_SYNC_LOST(
+			omap_crtc_channel(priv->crtcs[i]));
 
 	ret = priv->dispc_ops->request_irq(priv->dispc, omap_irq_handler, dev);
 	if (ret < 0)
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.h b/drivers/gpu/drm/omapdrm/omap_irq.h
index 9d54414..8a7971d 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.h
+++ b/drivers/gpu/drm/omapdrm/omap_irq.h
@@ -32,7 +32,7 @@ void omap_drm_irq_uninstall(struct drm_device *dev);
 int omap_drm_irq_install(struct drm_device *dev);
 
 struct omap_irq_wait *omap_irq_wait_init(struct drm_device *dev,
-		u32 irqmask, int count);
+		u64 irqmask, int count);
 int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
 		unsigned long timeout);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 61b0753..be803a2 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -239,6 +239,13 @@ static const struct drm_plane_funcs omap_plane_funcs = {
 	.atomic_get_property = omap_plane_atomic_get_property,
 };
 
+enum omap_plane_id omap_plane_get_id(struct drm_plane *plane)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+
+	return omap_plane->id;
+}
+
 static const enum omap_plane_id plane_idx_to_id[] = {
 	OMAP_DSS_GFX,
 	OMAP_DSS_VIDEO1,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.h b/drivers/gpu/drm/omapdrm/omap_plane.h
index dc5e82a..dbab345 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.h
+++ b/drivers/gpu/drm/omapdrm/omap_plane.h
@@ -33,5 +33,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 		u32 possible_crtcs);
 void omap_plane_install_properties(struct drm_plane *plane,
 		struct drm_mode_object *obj);
+enum omap_plane_id omap_plane_get_id(struct drm_plane *plane);
 
 #endif /* __OMAPDRM_PLANE_H__ */
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (3 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 4/9] drm/omap: Make omapdss API more generic Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-19 12:06   ` Tomi Valkeinen
  2018-02-27 14:42   ` Laurent Pinchart
  2018-02-16 11:25 ` [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe Jyri Sarha
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

The new DSS6 driver needs some structs and defines which are currently
in dss.h, which is for the old DSS driver.

Move the required structs and defines from dss.h to omapdss.h.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/dss.h     | 41 ++---------------------------------
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 37 +++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 434262a..fa206ca 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -70,14 +70,6 @@ struct seq_file;
 	pr_warn("omapdss: " format, ##__VA_ARGS__)
 #endif
 
-/* OMAP TRM gives bitfields as start:end, where start is the higher bit
-   number. For example 7:0 */
-#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
-#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
-#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
-#define FLD_MOD(orig, val, start, end) \
-	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
-
 enum dss_model {
 	DSS_MODEL_OMAP2,
 	DSS_MODEL_OMAP3,
@@ -86,12 +78,6 @@ enum dss_model {
 	DSS_MODEL_DRA7,
 };
 
-enum dss_io_pad_mode {
-	DSS_IO_PAD_MODE_RESET,
-	DSS_IO_PAD_MODE_RFBI,
-	DSS_IO_PAD_MODE_BYPASS,
-};
-
 enum dss_hdmi_venc_clk_source_select {
 	DSS_VENC_TV_CLK = 0,
 	DSS_HDMI_M_PCLK = 1,
@@ -215,34 +201,11 @@ struct dss_reg_field {
 	u8 start, end;
 };
 
-struct dispc_clock_info {
-	/* rates that we get with dividers below */
-	unsigned long lck;
-	unsigned long pck;
-
-	/* dividers */
-	u16 lck_div;
-	u16 pck_div;
-};
-
-struct dss_lcd_mgr_config {
-	enum dss_io_pad_mode io_pad_mode;
-
-	bool stallmode;
-	bool fifohandcheck;
-
-	struct dispc_clock_info clock_info;
-
-	int video_port_width;
-
-	int lcden_sig_polarity;
-};
-
-#define DSS_SZ_REGS			SZ_512
+#define DSS_SZ_REGS                    SZ_512
 
 struct dss_device {
 	struct platform_device *pdev;
-	void __iomem    *base;
+	void __iomem	*base;
 	struct regmap	*syscon_pll_ctrl;
 	u32		syscon_pll_ctrl_offset;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 493237e..9d789c2 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -647,6 +647,43 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
 struct omap_dss_device *
 omapdss_of_find_source_for_first_ep(struct device_node *node);
 
+/* OMAP TRM gives bitfields as start:end, where start is the higher bit
+   number. For example 7:0 */
+#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
+#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
+#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
+#define FLD_MOD(orig, val, start, end) \
+	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
+
+enum dss_io_pad_mode {
+	DSS_IO_PAD_MODE_RESET,
+	DSS_IO_PAD_MODE_RFBI,
+	DSS_IO_PAD_MODE_BYPASS,
+};
+
+struct dispc_clock_info {
+	/* rates that we get with dividers below */
+	unsigned long lck;
+	unsigned long pck;
+
+	/* dividers */
+	u16 lck_div;
+	u16 pck_div;
+};
+
+struct dss_lcd_mgr_config {
+	enum dss_io_pad_mode io_pad_mode;
+
+	bool stallmode;
+	bool fifohandcheck;
+
+	struct dispc_clock_info clock_info;
+
+	int video_port_width;
+
+	int lcden_sig_polarity;
+};
+
 struct device_node *dss_of_port_get_parent_device(struct device_node *port);
 u32 dss_of_port_get_port_number(struct device_node *port);
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (4 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-27 14:46   ` Laurent Pinchart
  2018-02-16 11:25 ` [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c Jyri Sarha
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

Register the omapdrm device when we know that dss device probe going
to succeed. This avoids DSS6 and DSS2 omapdrm device registration from
colliding with each other.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/core.c | 26 ++------------------------
 drivers/gpu/drm/omapdrm/dss/dss.c  | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
index acef7ec..6c9f667 100644
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ b/drivers/gpu/drm/omapdrm/dss/core.c
@@ -45,36 +45,14 @@ static struct platform_driver * const omap_dss_drivers[] = {
 #endif
 };
 
-static struct platform_device *omap_drm_device;
-
 static int __init omap_dss_init(void)
 {
-	int r;
-
-	r = platform_register_drivers(omap_dss_drivers,
-				      ARRAY_SIZE(omap_dss_drivers));
-	if (r)
-		goto err_reg;
-
-	omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
-	if (IS_ERR(omap_drm_device)) {
-		r = PTR_ERR(omap_drm_device);
-		goto err_reg;
-	}
-
-	return 0;
-
-err_reg:
-	platform_unregister_drivers(omap_dss_drivers,
-				    ARRAY_SIZE(omap_dss_drivers));
-
-	return r;
+	return platform_register_drivers(omap_dss_drivers,
+					 ARRAY_SIZE(omap_dss_drivers));
 }
 
 static void __exit omap_dss_exit(void)
 {
-	platform_device_unregister(omap_drm_device);
-
 	platform_unregister_drivers(omap_dss_drivers,
 				    ARRAY_SIZE(omap_dss_drivers));
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 5752328..dda3237 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1314,6 +1314,17 @@ static const struct soc_device_attribute dss_soc_devices[] = {
 	{ /* sentinel */ }
 };
 
+static struct platform_device *omap_drm_device;
+
+static int initialize_omapdrm_device(void)
+{
+	omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
+	if (IS_ERR(omap_drm_device))
+		return PTR_ERR(omap_drm_device);
+
+	return 0;
+}
+
 static int dss_bind(struct device *dev)
 {
 	struct dss_device *dss = dev_get_drvdata(dev);
@@ -1323,6 +1334,12 @@ static int dss_bind(struct device *dev)
 	if (r)
 		return r;
 
+	r = initialize_omapdrm_device();
+	if (r) {
+		component_unbind_all(dev, NULL);
+		return r;
+	}
+
 	pm_set_vt_switch(0);
 
 	omapdss_gather_components(dev);
@@ -1335,6 +1352,8 @@ static void dss_unbind(struct device *dev)
 {
 	omapdss_set_dss(NULL);
 
+	platform_device_unregister(omap_drm_device);
+
 	component_unbind_all(dev, NULL);
 }
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (5 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-27 14:48   ` Laurent Pinchart
  2018-02-16 11:25 ` [PATCH RFC 8/9] drm/omap: add TI DSS6 driver Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss Jyri Sarha
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

The core.c just for registering the drivers is kind of useless. Let's
get rid of it and register the dss drivers in dss.c.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/Makefile |  2 +-
 drivers/gpu/drm/omapdrm/dss/core.c   | 66 ------------------------------------
 drivers/gpu/drm/omapdrm/dss/dss.c    | 37 ++++++++++++++++++++
 3 files changed, 38 insertions(+), 67 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/dss/core.c

diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index 904101c..5950c3f 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -6,7 +6,7 @@ omapdss-base-y := base.o display.o dss-of.o output.o
 
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 # Core DSS files
-omapdss-y := core.o dss.o dispc.o dispc_coefs.o \
+omapdss-y := dss.o dispc.o dispc_coefs.o \
 	pll.o video-pll.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
deleted file mode 100644
index 6c9f667..0000000
--- a/drivers/gpu/drm/omapdrm/dss/core.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * Some code and ideas taken from drivers/video/omap/ driver
- * by Imre Deak.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define DSS_SUBSYS_NAME "CORE"
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include "omapdss.h"
-#include "dss.h"
-
-/* INIT */
-static struct platform_driver * const omap_dss_drivers[] = {
-	&omap_dsshw_driver,
-	&omap_dispchw_driver,
-#ifdef CONFIG_OMAP2_DSS_DSI
-	&omap_dsihw_driver,
-#endif
-#ifdef CONFIG_OMAP2_DSS_VENC
-	&omap_venchw_driver,
-#endif
-#ifdef CONFIG_OMAP4_DSS_HDMI
-	&omapdss_hdmi4hw_driver,
-#endif
-#ifdef CONFIG_OMAP5_DSS_HDMI
-	&omapdss_hdmi5hw_driver,
-#endif
-};
-
-static int __init omap_dss_init(void)
-{
-	return platform_register_drivers(omap_dss_drivers,
-					 ARRAY_SIZE(omap_dss_drivers));
-}
-
-static void __exit omap_dss_exit(void)
-{
-	platform_unregister_drivers(omap_dss_drivers,
-				    ARRAY_SIZE(omap_dss_drivers));
-}
-
-module_init(omap_dss_init);
-module_exit(omap_dss_exit);
-
-MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
-MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
-MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index dda3237..162fa3a 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1619,3 +1619,40 @@ struct platform_driver omap_dsshw_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+
+/* INIT */
+static struct platform_driver * const omap_dss_drivers[] = {
+	&omap_dsshw_driver,
+	&omap_dispchw_driver,
+#ifdef CONFIG_OMAP2_DSS_DSI
+	&omap_dsihw_driver,
+#endif
+#ifdef CONFIG_OMAP2_DSS_VENC
+	&omap_venchw_driver,
+#endif
+#ifdef CONFIG_OMAP4_DSS_HDMI
+	&omapdss_hdmi4hw_driver,
+#endif
+#ifdef CONFIG_OMAP5_DSS_HDMI
+	&omapdss_hdmi5hw_driver,
+#endif
+};
+
+static int __init omap_dss_init(void)
+{
+	return platform_register_drivers(omap_dss_drivers,
+					 ARRAY_SIZE(omap_dss_drivers));
+}
+
+static void __exit omap_dss_exit(void)
+{
+	platform_unregister_drivers(omap_dss_drivers,
+				    ARRAY_SIZE(omap_dss_drivers));
+}
+
+module_init(omap_dss_init);
+module_exit(omap_dss_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
+MODULE_LICENSE("GPL v2");
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 8/9] drm/omap: add TI DSS6 driver
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (6 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-16 11:25 ` [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss Jyri Sarha
  8 siblings, 0 replies; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart; +Cc: Jyri Sarha

From: Tomi Valkeinen <tomi.valkeinen@ti.com>

Add support for DSS6 IP on TI K2G SoC.

DSS6 is an evolution of the OMAP DSS (DSS2). OMAP DSS has been quite
similar from OMAP2 to OMAP5 (including DRA7 and AM5 which have basically
the same IP as OMAP5), but in DSS6 lots of things have been
restructured.

DSS6 can still be considered as being the same family as DSS2, as the
features offered are mostly the same, and the model how things happen
and work are the same. What's changed are the registers and how the
functionalities in the IP are divided.

Thus there was not much point in trying to share the low level parts of
the driver, and instead a new driver was written from scratch.

This patch adds a new DSS driver for DSS6. The DSS2's panel and encoder
drivers and also omapdrm driver can be used with DSS6.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/Kconfig  |    8 +
 drivers/gpu/drm/omapdrm/dss/Makefile |    3 +
 drivers/gpu/drm/omapdrm/dss/dispc6.c | 1438 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/dispc6.h |  109 +++
 drivers/gpu/drm/omapdrm/dss/dpi6.c   |  283 +++++++
 drivers/gpu/drm/omapdrm/dss/dss6.c   |  346 ++++++++
 drivers/gpu/drm/omapdrm/dss/dss6.h   |   54 ++
 7 files changed, 2241 insertions(+)
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dispc6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dispc6.h
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dpi6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dss6.c
 create mode 100644 drivers/gpu/drm/omapdrm/dss/dss6.h

diff --git a/drivers/gpu/drm/omapdrm/dss/Kconfig b/drivers/gpu/drm/omapdrm/dss/Kconfig
index f24ebf7..82faea6 100644
--- a/drivers/gpu/drm/omapdrm/dss/Kconfig
+++ b/drivers/gpu/drm/omapdrm/dss/Kconfig
@@ -132,3 +132,11 @@ config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
 	  disable the sleep if it doesn't cause problems on your platform.
 
 endif
+
+config TI_DSS6
+	tristate "TI DSS6 support"
+	select OMAP_DSS_BASE
+	select VIDEOMODE_HELPERS
+	select OMAP2_DSS_INIT
+	help
+	  Enable support for Texas Instruments DSS6 IP.
diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile b/drivers/gpu/drm/omapdrm/dss/Makefile
index 5950c3f..c669b2f 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -18,3 +18,6 @@ omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI_CEC) += hdmi4_cec.o
 omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o
 ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG
+
+obj-$(CONFIG_TI_DSS6) += omapdss6.o
+omapdss6-y := dss6.o dispc6.o dpi6.o
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc6.c b/drivers/gpu/drm/omapdrm/dss/dispc6.c
new file mode 100644
index 0000000..fbe4de5
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dispc6.c
@@ -0,0 +1,1438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <drm/drm_fourcc.h>
+
+#include "omapdss.h"
+#include "dss6.h"
+#include "dispc6.h"
+
+#define REG_GET(dispc, idx, start, end)	\
+	FLD_GET(dispc6_read(dispc, idx), start, end)
+
+#define REG_FLD_MOD(dispc, idx, val, start, end) \
+	dispc6_write(dispc, idx, FLD_MOD(dispc6_read(dispc, idx), val, start, end))
+
+#define VID_REG_GET(dispc, plane, idx, start, end) \
+	FLD_GET(dispc6_vid_read(dispc, plane, idx), start, end)
+
+#define VID_REG_FLD_MOD(dispc, plane, idx, val, start, end) \
+	dispc6_vid_write(dispc, plane, idx, FLD_MOD(dispc6_vid_read(dispc, plane, idx), val, start, end))
+
+
+#define VP_REG_GET(dispc, vp, idx, start, end) \
+	FLD_GET(dispc6_vp_read(dispc, vp, idx), start, end)
+
+#define VP_REG_FLD_MOD(dispc, vp, idx, val, start, end)	\
+	dispc6_vp_write(dispc, vp, idx, FLD_MOD(dispc6_vp_read(dispc, vp, idx), val, start, end))
+
+struct dispc_features {
+	/* XXX should these come from the .dts? Min pclk is not feature of DSS IP */
+	unsigned long min_pclk;
+	unsigned long max_pclk;
+};
+
+/* Note: 9MHz is a special allowed case, and is handled separately in the code */
+static const struct dispc_features k2g_dispc_feats = {
+	.min_pclk = 43750000,
+	.max_pclk = 150000000,
+};
+
+static const struct of_device_id dispc6_of_match[];
+
+struct dispc_device {
+	struct platform_device *pdev;
+
+	struct dss6_device *dss6;
+
+	void __iomem *base_common;
+	void __iomem *base_vid1;
+	void __iomem *base_ovr1;
+	void __iomem *base_vp1;
+
+	int irq;
+	irq_handler_t user_handler;
+	void *user_data;
+
+	const struct dispc_features *feat;
+
+	struct clk *fclk;
+	struct clk *vp_clk;
+
+	bool is_enabled;
+
+	bool ctx_valid;
+	u32 ctx_vid1[0x400];
+
+	u32 gamma_table[256];
+};
+
+static void dispc6_write(struct dispc_device *dispc, u16 reg, u32 val)
+{
+	iowrite32(val, dispc->base_common + reg);
+}
+
+static u32 dispc6_read(struct dispc_device *dispc, u16 reg)
+{
+	return ioread32(dispc->base_common + reg);
+}
+
+static void dispc6_vid_write(struct dispc_device *dispc,
+			     enum omap_plane_id plane, u16 reg, u32 val)
+{
+	void __iomem *base = dispc->base_vid1;
+
+	iowrite32(val, base + reg);
+}
+
+static u32 dispc6_vid_read(struct dispc_device *dispc,
+			   enum omap_plane_id plane, u16 reg)
+{
+	void __iomem *base = dispc->base_vid1;
+
+	return ioread32(base + reg);
+}
+
+static void dispc6_ovr_write(struct dispc_device *dispc,
+			     enum omap_channel channel, u16 reg, u32 val)
+{
+	void __iomem *base = dispc->base_ovr1;
+
+	iowrite32(val, base + reg);
+}
+#if 0	/* not used at the moment */
+static u32 dispc6_ovr_read(struct dispc_device *dispc,
+			   enum omap_channel channel, u16 reg)
+{
+	void __iomem *base = dispc->base_ovr1;
+
+	return ioread32(base + reg);
+}
+#endif
+static void dispc6_vp_write(struct dispc_device *dispc,
+			    enum omap_channel channel, u16 reg, u32 val)
+{
+	void __iomem *base = dispc->base_vp1;
+
+	iowrite32(val, base + reg);
+}
+
+static u32 dispc6_vp_read(struct dispc_device *dispc,
+			  enum omap_channel channel, u16 reg)
+{
+	void __iomem *base = dispc->base_vp1;
+
+	return ioread32(base + reg);
+}
+
+int dispc6_runtime_get(struct dispc_device *dispc)
+{
+	int r;
+
+	dev_dbg(&dispc->pdev->dev, "dispc_runtime_get\n");
+
+	r = pm_runtime_get_sync(&dispc->pdev->dev);
+	WARN_ON(r < 0);
+	return r < 0 ? r : 0;
+}
+
+void dispc6_runtime_put(struct dispc_device *dispc)
+{
+	int r;
+
+	dev_dbg(&dispc->pdev->dev, "dispc_runtime_put\n");
+
+	r = pm_runtime_put_sync(&dispc->pdev->dev);
+	WARN_ON(r < 0);
+}
+
+static void dispc6_save_context(struct dispc_device *dispc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dispc->ctx_vid1); ++i)
+		dispc->ctx_vid1[i] = dispc6_vid_read(dispc, 0, i);
+
+	dispc->ctx_valid = true;
+}
+
+static void dispc6_restore_context(struct dispc_device *dispc)
+{
+	int i;
+
+	if (!dispc->ctx_valid)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(dispc->ctx_vid1); ++i)
+		dispc6_vid_write(dispc, 0, i, dispc->ctx_vid1[i]);
+}
+
+static irqreturn_t dispc6_irq_handler(int irq, void *arg)
+{
+	struct dispc_device *dispc = arg;
+	u32 stat;
+
+	if (!dispc->is_enabled)
+		return IRQ_NONE;
+
+	stat = dispc6_read(dispc, DISPC_IRQSTATUS);
+
+	if (stat == 0)
+		return IRQ_NONE;
+
+	dispc6_write(dispc, DISPC_IRQSTATUS, stat);
+
+	return dispc->user_handler(irq, dispc->user_data);
+}
+
+static int dispc6_request_irq(struct dispc_device *dispc,
+			      irq_handler_t handler, void *dev_id)
+{
+	int r;
+
+	if (dispc->user_handler != NULL)
+		return -EBUSY;
+
+	dispc->user_handler = handler;
+	dispc->user_data = dev_id;
+
+	/* ensure the dispc6_irq_handler sees the values above */
+	smp_wmb();
+
+	r = devm_request_irq(&dispc->pdev->dev, dispc->irq, dispc6_irq_handler,
+			     IRQF_SHARED, "DISPC", dispc);
+	if (r) {
+		dispc->user_handler = NULL;
+		dispc->user_data = NULL;
+	}
+
+	return r;
+}
+
+static void dispc6_free_irq(struct dispc_device *dispc, void *dev_id)
+{
+	dispc6_write(dispc, DISPC_IRQENABLE_CLR, 0xffffffff);
+
+	devm_free_irq(&dispc->pdev->dev, dispc->irq, &dispc);
+
+	dispc->user_handler = NULL;
+	dispc->user_data = NULL;
+}
+
+u64 dispc6_vp_irq_from_raw(u32 stat)
+{
+	uint channel = 0;
+	u64 vp_stat = 0;
+
+	if (stat & BIT(0))
+		vp_stat |= DSS_IRQ_MGR_FRAME_DONE(channel);
+	if (stat & BIT(1))
+		vp_stat |= DSS_IRQ_MGR_VSYNC_EVEN(channel);
+	if (stat & BIT(2))
+		vp_stat |= DSS_IRQ_MGR_VSYNC_ODD(channel);
+	if (stat & BIT(4))
+		vp_stat |= DSS_IRQ_MGR_SYNC_LOST(channel);
+
+	return vp_stat;
+}
+
+static u32 dispc6_vp_irq_to_raw(u64 vpstat)
+{
+	uint channel = 0;
+	u32 stat = 0;
+
+	if (vpstat & DSS_IRQ_MGR_FRAME_DONE(channel))
+		stat |= BIT(0);
+	if (vpstat & DSS_IRQ_MGR_VSYNC_EVEN(channel))
+		stat |= BIT(1);
+	if (vpstat & DSS_IRQ_MGR_VSYNC_ODD(channel))
+		stat |= BIT(2);
+	if (vpstat & DSS_IRQ_MGR_SYNC_LOST(channel))
+		stat |= BIT(4);
+
+	return stat;
+}
+
+static u64 dispc6_vid_irq_from_raw(u32 stat)
+{
+	uint plane = 0;
+	u64 vid_stat = 0;
+
+	if (stat & BIT(0))
+		vid_stat |= DSS_IRQ_OVL_FIFO_UNDERFLOW(plane);
+
+	return vid_stat;
+}
+
+static u32 dispc6_vid_irq_to_raw(u64 vidstat)
+{
+	uint plane = 0;
+	u32 stat = 0;
+
+	if (vidstat & DSS_IRQ_OVL_FIFO_UNDERFLOW(plane))
+		stat |= BIT(0);
+
+	return stat;
+}
+
+
+static u64 dispc6_vp_read_irqstatus(struct dispc_device *dispc,
+				    enum omap_channel channel)
+{
+	u32 stat = dispc6_vp_read(dispc, channel, DISPC_VP_IRQSTATUS);
+
+	return dispc6_vp_irq_from_raw(stat);
+}
+
+static void dispc6_vp_write_irqstatus(struct dispc_device *dispc,
+				      enum omap_channel channel,
+				      u64 vpstat)
+{
+	u32 stat = dispc6_vp_irq_to_raw(vpstat);
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_IRQSTATUS, stat);
+}
+
+static u64 dispc6_vid_read_irqstatus(struct dispc_device *dispc,
+				     enum omap_plane_id plane)
+{
+	u32 stat = dispc6_vid_read(dispc, plane, DISPC_VID_IRQSTATUS);
+
+	return dispc6_vid_irq_from_raw(stat);
+}
+
+static void dispc6_vid_write_irqstatus(struct dispc_device *dispc,
+				       enum omap_plane_id plane,
+				       u64 vidstat)
+{
+	u32 stat = dispc6_vid_irq_to_raw(vidstat);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_IRQSTATUS, stat);
+}
+
+
+static u64 dispc6_vp_read_irqenable(struct dispc_device *dispc,
+				    enum omap_channel channel)
+{
+	u32 stat = dispc6_vp_read(dispc, channel, DISPC_VP_IRQENABLE);
+
+	return dispc6_vp_irq_from_raw(stat);
+}
+
+static void dispc6_vp_write_irqenable(struct dispc_device *dispc,
+				      enum omap_channel channel,
+				      u64 vpstat)
+{
+	u32 stat = dispc6_vp_irq_to_raw(vpstat);
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_IRQENABLE, stat);
+}
+
+static u64 dispc6_vid_read_irqenable(struct dispc_device *dispc,
+				     enum omap_plane_id plane)
+{
+	u32 stat = dispc6_vid_read(dispc, plane, DISPC_VID_IRQENABLE);
+
+	return dispc6_vid_irq_from_raw(stat);
+}
+
+static void dispc6_vid_write_irqenable(struct dispc_device *dispc,
+				       enum omap_plane_id plane,
+				       u64 vidstat)
+{
+	u32 stat = dispc6_vid_irq_to_raw(vidstat);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_IRQENABLE, stat);
+}
+
+
+static void dispc6_clear_irqstatus(struct dispc_device *dispc, u64 mask)
+{
+	dispc6_vp_write_irqstatus(dispc, 0, mask);
+	dispc6_vid_write_irqstatus(dispc, 0, mask);
+}
+
+static u64 dispc6_read_and_clear_irqstatus(struct dispc_device *dispc)
+{
+	u64 stat = 0;
+
+	stat |= dispc6_vp_read_irqstatus(dispc, 0);
+	stat |= dispc6_vid_read_irqstatus(dispc, 0);
+
+	dispc6_clear_irqstatus(dispc, stat);
+
+	return stat;
+}
+
+static u64 dispc6_read_irqenable(struct dispc_device *dispc)
+{
+	u64 stat = 0;
+
+	stat |= dispc6_vp_read_irqenable(dispc, 0);
+	stat |= dispc6_vid_read_irqenable(dispc, 0);
+
+	return stat;
+}
+
+static void dispc6_write_irqenable(struct dispc_device *dispc, u64 mask)
+{
+	u64 old_mask = dispc6_read_irqenable(dispc);
+
+	/* clear the irqstatus for newly enabled irqs */
+	dispc6_clear_irqstatus(dispc, (mask ^ old_mask) & mask);
+
+	dispc6_vp_write_irqenable(dispc, 0, mask);
+	dispc6_vid_write_irqenable(dispc, 0, mask);
+
+	dispc6_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7));
+
+	/* flush posted write */
+	dispc6_read_irqenable(dispc);
+}
+
+
+static bool dispc6_mgr_go_busy(struct dispc_device *dispc,
+			       enum omap_channel channel)
+{
+	return VP_REG_GET(dispc, channel, DISPC_VP_CONTROL, 5, 5);
+}
+
+static void dispc6_mgr_go(struct dispc_device *dispc,
+			  enum omap_channel channel)
+{
+	VP_REG_FLD_MOD(dispc, channel, DISPC_VP_CONTROL, 1, 5, 5);
+}
+
+static void dispc6_mgr_enable(struct dispc_device *dispc,
+			      enum omap_channel channel, bool enable)
+{
+	VP_REG_FLD_MOD(dispc, channel, DISPC_VP_CONTROL, !!enable, 0, 0);
+}
+
+static bool dispc6_mgr_is_enabled(struct dispc_device *dispc,
+				  enum omap_channel channel)
+{
+	return VP_REG_GET(dispc, channel, DISPC_VP_CONTROL, 0, 0);
+}
+
+static u16 c8_to_c12(u8 c8)
+{
+	u16 c12;
+
+	c12 = c8 << 4;
+
+	/* Replication logic: Copy c8 4 MSB to 4 LSB for full scale c12 */
+	c12 = c8 >> 4;
+
+	return c12;
+}
+
+static u64 argb8888_to_argb12121212(u32 argb8888)
+{
+	u8 a, r, g, b;
+	u64 v;
+
+	a = (argb8888 >> 24) & 0xff;
+	r = (argb8888 >> 16) & 0xff;
+	g = (argb8888 >> 8) & 0xff;
+	b = (argb8888 >> 0) & 0xff;
+
+	v = ((u64)c8_to_c12(a) << 36) | ((u64)c8_to_c12(r) << 24) |
+	    ((u64)c8_to_c12(g) << 12) | (u64)c8_to_c12(b);
+
+	return v;
+}
+
+static void dispc6_mgr_setup(struct dispc_device *dispc,
+			     enum omap_channel channel,
+			     const struct omap_overlay_manager_info *info)
+{
+	u64 v;
+
+	v = argb8888_to_argb12121212(info->default_color);
+
+	dispc6_ovr_write(dispc, 0, DISPC_OVR_DEFAULT_COLOR, v & 0xffffffff);
+	dispc6_ovr_write(dispc, 0, DISPC_OVR_DEFAULT_COLOR2, (v >> 32) & 0xffff);
+}
+
+static void dispc6_set_num_datalines(struct dispc_device *dispc,
+				     enum omap_channel channel, int num_lines)
+{
+	int v;
+
+	switch (num_lines) {
+	case 12:
+		v = 0; break;
+	case 16:
+		v = 1; break;
+	case 18:
+		v = 2; break;
+	case 24:
+		v = 3; break;
+	case 30:
+		v = 4; break;
+	case 36:
+		v = 5; break;
+	default:
+		__WARN();
+		v = 3;
+		break;
+	}
+
+	VP_REG_FLD_MOD(dispc, channel, DISPC_VP_CONTROL, v, 10, 8);
+}
+
+static void dispc6_mgr_set_lcd_config(struct dispc_device *dispc,
+				      enum omap_channel channel,
+				      const struct dss_lcd_mgr_config *config)
+{
+	dispc6_set_num_datalines(dispc, channel, config->video_port_width);
+}
+
+static bool dispc6_lcd_timings_ok(int hsw, int hfp, int hbp,
+				  int vsw, int vfp, int vbp)
+{
+	if (hsw < 1 || hsw > 256 ||
+	    hfp < 1 || hfp > 4096 ||
+	    hbp < 1 || hbp > 4096 ||
+	    vsw < 1 || vsw > 256 ||
+	    vfp < 0 || vfp > 4095 ||
+	    vbp < 0 || vbp > 4095)
+		return false;
+	return true;
+}
+
+bool dispc6_mgr_timings_ok(struct dispc_device *dispc,
+			   enum omap_channel channel,
+			   const struct videomode *vm)
+{
+	if (vm->pixelclock < dispc->feat->min_pclk && vm->pixelclock != 9000000)
+		return false;
+
+	if (vm->pixelclock > dispc->feat->max_pclk)
+		return false;
+
+	if (vm->hactive > 4096)
+		return false;
+
+	if (vm->vactive > 4096)
+		return false;
+
+	/* TODO: add interlace support */
+	if (vm->flags & DISPLAY_FLAGS_INTERLACED)
+		return false;
+
+	if (!dispc6_lcd_timings_ok(vm->hsync_len, vm->hfront_porch, vm->hback_porch,
+				   vm->vsync_len, vm->vfront_porch, vm->vback_porch))
+		return false;
+
+	return true;
+}
+
+static void dispc6_mgr_set_timings(struct dispc_device *dispc,
+				   enum omap_channel channel,
+				   const struct videomode *vm)
+{
+	bool align, onoff, rf, ieo, ipc, ihs, ivs;
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_TIMING_H,
+			FLD_VAL(vm->hsync_len - 1, 7, 0) |
+			FLD_VAL(vm->hfront_porch - 1, 19, 8) |
+			FLD_VAL(vm->hback_porch - 1, 31, 20));
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_TIMING_V,
+			FLD_VAL(vm->vsync_len - 1, 7, 0) |
+			FLD_VAL(vm->vfront_porch, 19, 8) |
+			FLD_VAL(vm->vback_porch, 31, 20));
+
+	if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
+		ivs = false;
+	else
+		ivs = true;
+
+	if (vm->flags & DISPLAY_FLAGS_HSYNC_HIGH)
+		ihs = false;
+	else
+		ihs = true;
+
+	if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
+		ieo = false;
+	else
+		ieo = true;
+
+	if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+		ipc = false;
+	else
+		ipc = true;
+
+	/* always use the 'rf' setting */
+	onoff = true;
+
+	if (vm->flags & DISPLAY_FLAGS_SYNC_POSEDGE)
+		rf = true;
+	else
+		rf = false;
+
+	/* always use aligned syncs */
+	align = true;
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_POL_FREQ,
+			FLD_VAL(align, 18, 18) |
+			FLD_VAL(onoff, 17, 17) |
+			FLD_VAL(rf, 16, 16) |
+			FLD_VAL(ieo, 15, 15) |
+			FLD_VAL(ipc, 14, 14) |
+			FLD_VAL(ihs, 13, 13) |
+			FLD_VAL(ivs, 12, 12));
+
+	dispc6_vp_write(dispc, channel, DISPC_VP_SIZE_SCREEN,
+			FLD_VAL(vm->hactive - 1, 11, 0) |
+			FLD_VAL(vm->vactive - 1, 27, 16));
+}
+
+int dispc6_vp_enable_clk(struct dispc_device *dispc, enum omap_channel channel)
+{
+	return clk_prepare_enable(dispc->vp_clk);
+}
+void dispc6_vp_disable_clk(struct dispc_device *dispc,
+			   enum omap_channel channel)
+{
+	clk_disable_unprepare(dispc->vp_clk);
+}
+
+int dispc6_vp_set_clk_rate(struct dispc_device *dispc,
+			   enum omap_channel channel, unsigned long rate)
+{
+	int r;
+	unsigned long new_rate;
+
+	r = clk_set_rate(dispc->vp_clk, rate);
+	if (r) {
+		dev_err(&dispc->pdev->dev, "Failed to set vp clk rate to %lu\n",
+			rate);
+		return r;
+	}
+
+	new_rate = clk_get_rate(dispc->vp_clk);
+
+	if (rate != new_rate)
+		dev_warn(&dispc->pdev->dev,
+			 "Failed to get exact pix clock %lu != %lu\n",
+			 rate, new_rate);
+
+	dev_dbg(&dispc->pdev->dev, "New VP rate %lu Hz (requested %lu Hz)\n",
+		clk_get_rate(dispc->vp_clk), rate);
+
+	return 0;
+}
+
+/* CSC */
+
+struct color_conv_coef {
+	int ry, rcb, rcr;
+	int gy, gcb, gcr;
+	int by, bcb, bcr;
+	int roffset, goffset, boffset;
+	bool full_range;
+};
+
+static void dispc6_vid_write_color_conv_coefs(struct dispc_device *dispc,
+					      enum omap_plane_id plane,
+					      const struct color_conv_coef *ct)
+{
+#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(0), CVAL(ct->rcr, ct->ry));
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(1), CVAL(ct->gy,  ct->rcb));
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(2), CVAL(ct->gcb, ct->gcr));
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(3), CVAL(ct->bcr, ct->by));
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(4), CVAL(0, ct->bcb));
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(5),
+			 FLD_VAL(ct->roffset, 15, 3) | FLD_VAL(ct->goffset, 31, 19));
+	dispc6_vid_write(dispc, plane, DISPC_VID_CONV_COEF(6),
+			 FLD_VAL(ct->boffset, 15, 3));
+
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, ct->full_range, 11, 11);
+
+#undef CVAL
+}
+
+static void dispc6_vid_csc_setup(struct dispc_device *dispc)
+{
+	/* YUV -> RGB, ITU-R BT.601, full range */
+	const struct color_conv_coef coefs_yuv2rgb_bt601_full = {
+		256,   0,  358,
+		256, -88, -182,
+		256, 452,    0,
+		0, -2048, -2048,
+		true,
+	};
+
+	dispc6_vid_write_color_conv_coefs(dispc, 0, &coefs_yuv2rgb_bt601_full);
+}
+
+static void dispc6_vid_csc_enable(struct dispc_device *dispc,
+				  enum omap_plane_id plane, bool enable)
+{
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, !!enable, 9, 9);
+}
+
+/* SCALER */
+
+static u32 dispc6_calc_fir_inc(u32 in, u32 out)
+{
+	return (u32)div_u64(0x200000ull * in, out);
+}
+
+struct dispc6_vid_fir_coefs {
+	s16 c2[16];
+	s16 c1[16];
+	u16 c0[9];
+};
+
+static const struct dispc6_vid_fir_coefs dispc6_fir_coefs_null = {
+	.c2 = {	0 },
+	.c1 = { 0 },
+	.c0 = { 512, 512, 512, 512, 512, 512, 512, 512, 256,  },
+};
+
+/* M=8, Upscale x >= 1 */
+static const struct dispc6_vid_fir_coefs dispc6_fir_coefs_m8 = {
+	.c2 = {	0, -4, -8, -16, -24, -32, -40, -48, 0, 2, 4, 6, 8, 6, 4, 2,  },
+	.c1 = { 0, 28, 56, 94, 132, 176, 220, 266, -56, -60, -64, -62, -60, -50, -40, -20,  },
+	.c0 = { 512, 506, 500, 478, 456, 424, 392, 352, 312,  },
+};
+
+/* 5-tap, M=22, Downscale Ratio 2.5 < x < 3 */
+static const struct dispc6_vid_fir_coefs dispc6_fir_coefs_m22_5tap = {
+	.c2 = { 16, 20, 24, 30, 36, 42, 48, 56, 0, 0, 0, 2, 4, 8, 12, 14,  },
+	.c1 = { 132, 140, 148, 156, 164, 172, 180, 186, 64, 72, 80, 88, 96, 104, 112, 122,  },
+	.c0 = { 216, 216, 216, 214, 212, 208, 204, 198, 192,  },
+};
+
+/* 3-tap, M=22, Downscale Ratio 2.5 < x < 3 */
+static const struct dispc6_vid_fir_coefs dispc6_fir_coefs_m22_3tap = {
+	.c1 = { 100, 118, 136, 156, 176, 196, 216, 236, 0, 10, 20, 30, 40, 54, 68, 84,  },
+	.c0 = { 312, 310, 308, 302, 296, 286, 276, 266, 256,  },
+};
+
+enum dispc6_vid_fir_coef_set {
+	DISPC6_VID_FIR_COEF_HORIZ,
+	DISPC6_VID_FIR_COEF_HORIZ_UV,
+	DISPC6_VID_FIR_COEF_VERT,
+	DISPC6_VID_FIR_COEF_VERT_UV,
+};
+
+static void dispc6_vid_write_fir_coefs(struct dispc_device *dispc,
+				       enum omap_plane_id plane,
+				       enum dispc6_vid_fir_coef_set coef_set,
+				       const struct dispc6_vid_fir_coefs *coefs)
+{
+	static const u16 c0_regs[] = {
+		[DISPC6_VID_FIR_COEF_HORIZ] = DISPC_VID_FIR_COEFS_H0,
+		[DISPC6_VID_FIR_COEF_HORIZ_UV] = DISPC_VID_FIR_COEFS_H0_C,
+		[DISPC6_VID_FIR_COEF_VERT] = DISPC_VID_FIR_COEFS_V0,
+		[DISPC6_VID_FIR_COEF_VERT_UV] = DISPC_VID_FIR_COEFS_V0_C,
+	};
+
+	static const u16 c12_regs[] = {
+		[DISPC6_VID_FIR_COEF_HORIZ] = DISPC_VID_FIR_COEFS_H12,
+		[DISPC6_VID_FIR_COEF_HORIZ_UV] = DISPC_VID_FIR_COEFS_H12_C,
+		[DISPC6_VID_FIR_COEF_VERT] = DISPC_VID_FIR_COEFS_V12,
+		[DISPC6_VID_FIR_COEF_VERT_UV] = DISPC_VID_FIR_COEFS_V12_C,
+	};
+
+	const u16 c0_base = c0_regs[coef_set];
+	const u16 c12_base = c12_regs[coef_set];
+	int phase;
+
+	for (phase = 0; phase <= 8; ++phase) {
+		u16 reg = c0_base + phase * 4;
+		u16 c0 = coefs->c0[phase];
+
+		dispc6_vid_write(dispc, plane, reg, c0);
+	}
+
+	for (phase = 0; phase <= 15; ++phase) {
+		u16 reg = c12_base + phase * 4;
+		s16 c1, c2;
+		u32 c12;
+
+		c1 = coefs->c1[phase];
+		c2 = coefs->c2[phase];
+		c12 = FLD_VAL(c1, 19, 10) | FLD_VAL(c2, 29, 20);
+
+		dispc6_vid_write(dispc, plane, reg, c12);
+	}
+}
+
+static void dispc6_vid_write_scale_coefs(struct dispc_device *dispc,
+					 enum omap_plane_id plane)
+{
+	dispc6_vid_write_fir_coefs(dispc, plane, DISPC6_VID_FIR_COEF_HORIZ, &dispc6_fir_coefs_null);
+	dispc6_vid_write_fir_coefs(dispc, plane, DISPC6_VID_FIR_COEF_HORIZ_UV, &dispc6_fir_coefs_null);
+	dispc6_vid_write_fir_coefs(dispc, plane, DISPC6_VID_FIR_COEF_VERT, &dispc6_fir_coefs_null);
+	dispc6_vid_write_fir_coefs(dispc, plane, DISPC6_VID_FIR_COEF_VERT_UV, &dispc6_fir_coefs_null);
+}
+
+static void dispc6_vid_set_scaling(struct dispc_device *dispc,
+				   enum omap_plane_id plane,
+				   u32 orig_width, u32 orig_height,
+				   u32 out_width, u32 out_height,
+				   u32 fourcc)
+{
+	u32 in_w, in_h, in_w_uv, in_h_uv;
+	u32 fir_hinc, fir_vinc, fir_hinc_uv, fir_vinc_uv;
+	bool scale_x, scale_y;
+	bool five_taps = false;		/* XXX always 3-tap for now */
+
+	in_w = in_w_uv = orig_width;
+	in_h = in_h_uv = orig_height;
+
+	switch (fourcc) {
+	case DRM_FORMAT_NV12:
+		/* UV is subsampled by 2 horizontally and vertically */
+		in_h_uv >>= 1;
+		in_w_uv >>= 1;
+		break;
+
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_UYVY:
+		/* UV is subsampled by 2 horizontally */
+		in_w_uv >>= 1;
+		break;
+
+	default:
+		break;
+	}
+
+	scale_x = in_w != out_width || in_w_uv != out_width;
+	scale_y = in_h != out_height || in_h_uv != out_height;
+
+	/* HORIZONTAL RESIZE ENABLE */
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, scale_x, 7, 7);
+
+	/* VERTICAL RESIZE ENABLE */
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, scale_y, 8, 8);
+
+	/* Skip the rest if no scaling is used */
+	if (!scale_x && !scale_y)
+		return;
+
+	/* VERTICAL 5-TAPS  */
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, five_taps, 21, 21);
+
+	/* FIR INC */
+
+	fir_hinc = dispc6_calc_fir_inc(in_w, out_width);
+	fir_vinc = dispc6_calc_fir_inc(in_h, out_height);
+	fir_hinc_uv = dispc6_calc_fir_inc(in_w_uv, out_width);
+	fir_vinc_uv = dispc6_calc_fir_inc(in_h_uv, out_height);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_FIRH, fir_hinc);
+	dispc6_vid_write(dispc, plane, DISPC_VID_FIRV, fir_vinc);
+	dispc6_vid_write(dispc, plane, DISPC_VID_FIRH2, fir_hinc_uv);
+	dispc6_vid_write(dispc, plane, DISPC_VID_FIRV2, fir_vinc_uv);
+
+	dispc6_vid_write_scale_coefs(dispc, plane);
+}
+
+/* OTHER */
+
+static const enum omap_color_mode dispc6_supported_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_NV12,
+	0
+};
+
+static const struct {
+	u32 fourcc;
+	u8 dss_code;
+	u8 bytespp;
+} dispc6_color_formats[] = {
+	{ DRM_FORMAT_XRGB8888, 0x27, 4, },
+	{ DRM_FORMAT_ARGB8888, 0x7, 4, },
+
+	{ DRM_FORMAT_RGBX8888, 0x29, 4, },
+	{ DRM_FORMAT_RGBA8888, 0x9, 4, },
+
+	{ DRM_FORMAT_YUYV, 0x3e, 2, },
+	{ DRM_FORMAT_UYVY, 0x3f, 2, },
+
+	{ DRM_FORMAT_NV12, 0x3d, 2, },
+};
+
+static bool dispc6_fourcc_is_yuv(u32 fourcc)
+{
+	switch (fourcc) {
+	case DRM_FORMAT_YUYV:
+	case DRM_FORMAT_UYVY:
+	case DRM_FORMAT_NV12:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void dispc6_ovl_set_pixel_format(struct dispc_device *dispc,
+					enum omap_plane_id plane, u32 fourcc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dispc6_color_formats); ++i) {
+		if (dispc6_color_formats[i].fourcc == fourcc) {
+			VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES,
+					dispc6_color_formats[i].dss_code,
+					6, 1);
+			return;
+		}
+	}
+
+	__WARN();
+}
+
+static int dispc6_fourcc_to_bytespp(u32 fourcc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dispc6_color_formats); ++i) {
+		if (dispc6_color_formats[i].fourcc == fourcc)
+			return dispc6_color_formats[i].bytespp;
+	}
+
+	__WARN();
+	return 4;
+}
+
+static s32 pixinc(int pixels, u8 ps)
+{
+	if (pixels == 1)
+		return 1;
+	else if (pixels > 1)
+		return 1 + (pixels - 1) * ps;
+	else if (pixels < 0)
+		return 1 - (-pixels + 1) * ps;
+
+	__WARN();
+	return 0;
+}
+
+static int dispc6_ovl_setup(struct dispc_device *dispc,
+			    enum omap_plane_id plane,
+			    const struct omap_overlay_info *oi,
+			    const struct videomode *vm, bool mem_to_mem,
+			    enum omap_channel channel)
+{
+	u32 fourcc = oi->fourcc;
+	int bytespp = dispc6_fourcc_to_bytespp(fourcc);
+
+	dispc6_ovl_set_pixel_format(dispc, plane, fourcc);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_BA_0, oi->paddr);
+	dispc6_vid_write(dispc, plane, DISPC_VID_BA_1, oi->paddr);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_BA_UV_0, oi->p_uv_addr);
+	dispc6_vid_write(dispc, plane, DISPC_VID_BA_UV_1, oi->p_uv_addr);
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_PICTURE_SIZE,
+			 (oi->width - 1) | ((oi->height - 1) << 16));
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_PIXEL_INC, pixinc(1, bytespp));
+	dispc6_vid_write(dispc, plane, DISPC_VID_ROW_INC,
+			 pixinc(1 + oi->screen_width - oi->width, bytespp));
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_POSITION,
+			 oi->pos_x | (oi->pos_y << 16));
+
+	dispc6_vid_write(dispc, plane, DISPC_VID_SIZE,
+			 (oi->out_width - 1) | ((oi->out_height - 1) << 16));
+
+	dispc6_vid_set_scaling(dispc, plane,
+			       oi->width, oi->height, oi->out_width, oi->out_height,
+			       fourcc);
+
+	/* enable YUV->RGB color conversion */
+	if (dispc6_fourcc_is_yuv(fourcc))
+		dispc6_vid_csc_enable(dispc, plane, true);
+	else
+		dispc6_vid_csc_enable(dispc, plane, false);
+
+	/* channel */
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, 0, 16, 14);
+
+	return 0;
+}
+
+static int dispc6_ovl_enable(struct dispc_device *dispc,
+			     enum omap_plane_id plane, bool enable)
+{
+	VID_REG_FLD_MOD(dispc, plane, DISPC_VID_ATTRIBUTES, !!enable, 0, 0);
+	return 0;
+}
+
+static u32 dispc6_vid_get_fifo_size(struct dispc_device *dispc,
+				    enum omap_plane_id plane)
+{
+	const u32 unit_size = 16;	/* 128-bits */
+
+	return VID_REG_GET(dispc, plane, DISPC_VID_BUF_SIZE_STATUS, 15, 0) * unit_size;
+}
+
+static void dispc6_vid_set_mflag_threshold(struct dispc_device *dispc,
+					   enum omap_plane_id plane,
+					   u32 low, u32 high)
+{
+	dispc6_vid_write(dispc, plane, DISPC_VID_MFLAG_THRESHOLD,
+			 FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0));
+}
+
+static void dispc6_mflag_setup(struct dispc_device *dispc)
+{
+	enum omap_plane_id plane = 0;
+	const u32 unit_size = 16;	/* 128-bits */
+	u32 size = dispc6_vid_get_fifo_size(dispc, plane);
+	u32 low, high;
+
+	/* MFLAG_CTRL */
+	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 1, 1, 0);
+	/* MFLAG_START */
+	REG_FLD_MOD(dispc, DISPC_GLOBAL_MFLAG_ATTRIBUTE, 0, 2, 2);
+
+	/*
+	 * Simulation team suggests below thesholds:
+	 * HT = fifosize * 5 / 8;
+	 * LT = fifosize * 4 / 8;
+	 */
+
+	low = size * 4 / 8 / unit_size;
+	high = size * 5 / 8 / unit_size;
+
+	dispc6_vid_set_mflag_threshold(dispc, plane, low, high);
+}
+
+static void dispc6_vp_setup(struct dispc_device *dispc)
+{
+	/* Enable the gamma Shadow bit-field */
+	VP_REG_FLD_MOD(dispc, 0, DISPC_VP_CONFIG, 1, 2, 2);
+}
+
+static void dispc6_initial_config(struct dispc_device *dispc)
+{
+	dispc6_vid_csc_setup(dispc);
+	dispc6_mflag_setup(dispc);
+	dispc6_vp_setup(dispc);
+}
+
+static int dispc6_init_features(struct dispc_device *dispc)
+{
+	struct platform_device *pdev = dispc->pdev;
+	const struct of_device_id *match;
+
+	match = of_match_node(dispc6_of_match, pdev->dev.of_node);
+	if (!match) {
+		dev_err(&pdev->dev, "Unsupported DISPC version\n");
+		return -ENODEV;
+	}
+
+	dispc->feat = match->data;
+
+	return 0;
+}
+
+static enum omap_dss_output_id
+dispc6_mgr_get_supported_outputs(struct dispc_device *dispc,
+				 enum omap_channel channel)
+{
+	return OMAP_DSS_OUTPUT_DPI;
+}
+
+static const u32 *dispc6_ovl_get_color_modes(struct dispc_device *dispc,
+					     enum omap_plane_id plane)
+{
+	return dispc6_supported_formats;
+}
+
+static int dispc6_get_num_ovls(struct dispc_device *dispc)
+{
+	return 1;
+}
+
+static int dispc6_get_num_mgrs(struct dispc_device *dispc)
+{
+	return 1;
+}
+
+static u32 dispc6_mgr_gamma_size(struct dispc_device *dispc,
+				 enum omap_channel channel)
+{
+	return ARRAY_SIZE(dispc->gamma_table);
+}
+
+static void dispc6_mgr_write_gamma_table(struct dispc_device *dispc,
+					 enum omap_channel channel)
+{
+	u32 *table = dispc->gamma_table;
+	uint hwlen = ARRAY_SIZE(dispc->gamma_table);
+	unsigned int i;
+
+	dev_dbg(&dispc->pdev->dev, "%s: channel %d\n", __func__, channel);
+
+	for (i = 0; i < hwlen; ++i) {
+		u32 v = table[i];
+
+		v |= i << 24;
+
+		dispc6_vp_write(dispc, channel, DISPC_VP_GAMMA_TABLE, v);
+	}
+}
+
+static void dispc6_restore_gamma_tables(struct dispc_device *dispc)
+{
+	dev_dbg(&dispc->pdev->dev, "%s()\n", __func__);
+
+	dispc6_mgr_write_gamma_table(dispc, 0);
+}
+
+static const struct drm_color_lut dispc6_mgr_gamma_default_lut[] = {
+	{ .red = 0, .green = 0, .blue = 0, },
+	{ .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, },
+};
+
+static void dispc6_mgr_set_gamma(struct dispc_device *dispc,
+			 enum omap_channel channel,
+			 const struct drm_color_lut *lut,
+			 unsigned int length)
+{
+	u32 *table = dispc->gamma_table;
+	uint hwlen = ARRAY_SIZE(dispc->gamma_table);
+	static const uint hwbits = 8;
+	uint i;
+
+	dev_dbg(&dispc->pdev->dev, "%s: channel %d, lut len %u, hw len %u\n",
+		__func__, channel, length, hwlen);
+
+	if (lut == NULL || length < 2) {
+		lut = dispc6_mgr_gamma_default_lut;
+		length = ARRAY_SIZE(dispc6_mgr_gamma_default_lut);
+	}
+
+	for (i = 0; i < length - 1; ++i) {
+		uint first = i * (hwlen - 1) / (length - 1);
+		uint last = (i + 1) * (hwlen - 1) / (length - 1);
+		uint w = last - first;
+		u16 r, g, b;
+		uint j;
+
+		if (w == 0)
+			continue;
+
+		for (j = 0; j <= w; j++) {
+			r = (lut[i].red * (w - j) + lut[i+1].red * j) / w;
+			g = (lut[i].green * (w - j) + lut[i+1].green * j) / w;
+			b = (lut[i].blue * (w - j) + lut[i+1].blue * j) / w;
+
+			r >>= 16 - hwbits;
+			g >>= 16 - hwbits;
+			b >>= 16 - hwbits;
+
+			table[first + j] = (r << (hwbits * 2)) |
+				(g << hwbits) | b;
+		}
+	}
+
+	if (dispc->is_enabled)
+		dispc6_mgr_write_gamma_table(dispc, channel);
+}
+
+static int dispc6_init_gamma_tables(struct dispc_device *dispc)
+{
+	dispc6_mgr_set_gamma(dispc, 0, NULL, 0);
+
+	return 0;
+}
+
+static u32 dispc6_get_memory_bandwidth_limit(struct dispc_device *dispc)
+{
+	u32 limit = 0;
+
+	/* Optional maximum memory bandwidth */
+	of_property_read_u32(dispc->pdev->dev.of_node, "max-memory-bandwidth",
+			     &limit);
+
+	return limit;
+}
+
+static const char *dispc6_ovl_name(struct dispc_device *dispc,
+				   enum omap_plane_id plane)
+{
+	return "vid1";
+}
+
+static const char *dispc6_mgr_name(struct dispc_device *dispc,
+				   enum omap_channel channel)
+{
+	return "vp1";
+}
+
+static bool dispc6_mgr_has_framedone(struct dispc_device *dispc,
+				     enum omap_channel channel)
+{
+	return true;
+}
+
+static const struct dispc_ops dispc6_ops = {
+	.read_and_clear_irqstatus = dispc6_read_and_clear_irqstatus,
+	.write_irqenable = dispc6_write_irqenable,
+
+	.request_irq = dispc6_request_irq,
+	.free_irq = dispc6_free_irq,
+
+	.runtime_get = dispc6_runtime_get,
+	.runtime_put = dispc6_runtime_put,
+
+	.get_num_ovls = dispc6_get_num_ovls,
+	.get_num_mgrs = dispc6_get_num_mgrs,
+
+	.ovl_name = dispc6_ovl_name,
+	.mgr_name = dispc6_mgr_name,
+
+	.mgr_has_framedone = dispc6_mgr_has_framedone,
+
+	.get_memory_bandwidth_limit = dispc6_get_memory_bandwidth_limit,
+
+	.mgr_enable = dispc6_mgr_enable,
+	.mgr_is_enabled = dispc6_mgr_is_enabled,
+	.mgr_go_busy = dispc6_mgr_go_busy,
+	.mgr_go = dispc6_mgr_go,
+	.mgr_set_lcd_config = dispc6_mgr_set_lcd_config,
+	.mgr_set_timings = dispc6_mgr_set_timings,
+	.mgr_setup = dispc6_mgr_setup,
+	.mgr_get_supported_outputs = dispc6_mgr_get_supported_outputs,
+	.mgr_gamma_size = dispc6_mgr_gamma_size,
+	.mgr_set_gamma = dispc6_mgr_set_gamma,
+
+	.ovl_enable = dispc6_ovl_enable,
+	.ovl_setup = dispc6_ovl_setup,
+	.ovl_get_color_modes = dispc6_ovl_get_color_modes,
+};
+
+static int dispc6_iomap_resource(struct platform_device *pdev, const char *name,
+				 void __iomem **base)
+{
+	struct resource *res;
+	void __iomem *b;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot get mem resource '%s'\n", name);
+		return -EINVAL;
+	}
+
+	b = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(b)) {
+		dev_err(&pdev->dev, "cannot ioremap resource '%s'\n", name);
+		return PTR_ERR(b);
+	}
+
+	*base = b;
+
+	return 0;
+}
+
+static int dispc6_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dss6_device *dss6 = dss6_get_device(master);
+	struct dispc_device *dispc;
+	int r = 0;
+
+	dispc = kzalloc(sizeof(*dispc), GFP_KERNEL);
+	if (!dispc)
+		return -ENOMEM;
+
+	dispc->pdev = pdev;
+	platform_set_drvdata(pdev, dispc);
+	dispc->dss6 = dss6;
+
+	r = dispc6_init_features(dispc);
+	if (r)
+		goto err_free;
+
+	r = dispc6_iomap_resource(pdev, "common", &dispc->base_common);
+	if (r)
+		goto err_free;
+
+	r = dispc6_iomap_resource(pdev, "vid1", &dispc->base_vid1);
+	if (r)
+		goto err_free;
+
+	r = dispc6_iomap_resource(pdev, "ovr1", &dispc->base_ovr1);
+	if (r)
+		goto err_free;
+
+	r = dispc6_iomap_resource(pdev, "vp1", &dispc->base_vp1);
+	if (r)
+		goto err_free;
+
+	dispc->irq = platform_get_irq(dispc->pdev, 0);
+	if (dispc->irq < 0) {
+		dev_err(dev, "platform_get_irq failed\n");
+		r = -ENODEV;
+		goto err_free;
+	}
+
+	dispc->fclk = devm_clk_get(dev, "fck");
+	if (IS_ERR(dispc->fclk)) {
+		dev_err(dev, "Failed to get fclk\n");
+		r = PTR_ERR(dispc->fclk);
+		goto err_free;
+	}
+
+	dispc->vp_clk = devm_clk_get(dev, "vp");
+	if (IS_ERR(dispc->vp_clk)) {
+		dev_err(dev, "Failed to get vp clk\n");
+		r = PTR_ERR(dispc->vp_clk);
+		goto err_free;
+	}
+
+	r = dispc6_init_gamma_tables(dispc);
+	if (r)
+		goto err_free;
+
+	pm_runtime_enable(&pdev->dev);
+
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 200);
+	pm_runtime_use_autosuspend(&pdev->dev);
+
+	dss6->data.dispc_ops = &dispc6_ops;
+	dss6->data.dispc = dispc;
+
+	return 0;
+err_free:
+	kfree(dispc);
+	return r;
+}
+
+static void dispc6_unbind(struct device *dev, struct device *master,
+			  void *data)
+{
+	struct dispc_device *dispc = dev_get_drvdata(dev);
+	struct dss6_device *dss6 = dispc->dss6;
+
+	dss6->data.dispc_ops = NULL;
+	dss6->data.dispc = NULL;
+
+	pm_runtime_disable(dev);
+
+	kfree(dispc);
+}
+
+static const struct component_ops dispc6_component_ops = {
+	.bind	= dispc6_bind,
+	.unbind	= dispc6_unbind,
+};
+
+static int dispc6_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &dispc6_component_ops);
+}
+
+static int dispc6_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dispc6_component_ops);
+	return 0;
+}
+
+static int dispc6_runtime_suspend(struct device *dev)
+{
+	struct dispc_device *dispc = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "suspend\n");
+
+	dispc->is_enabled = false;
+	/* ensure the dispc6_irq_handler sees the is_enabled value */
+	smp_wmb();
+	/* wait for current handler to finish before turning the DISPC off */
+	synchronize_irq(dispc->irq);
+
+	dispc6_save_context(dispc);
+
+	clk_disable_unprepare(dispc->fclk);
+
+	return 0;
+}
+
+static int dispc6_runtime_resume(struct device *dev)
+{
+	struct dispc_device *dispc = dev_get_drvdata(dev);
+
+	dev_dbg(dev, "resume\n");
+
+	clk_prepare_enable(dispc->fclk);
+
+	if (REG_GET(dispc, DISPC_SYSSTATUS, 0, 0) == 0)
+		dev_warn(dev, "DISPC FUNC RESET not done!\n");
+	if (REG_GET(dispc, DISPC_SYSSTATUS, 1, 1) == 0)
+		dev_warn(dev, "DISPC VP RESET not done!\n");
+
+	dispc6_initial_config(dispc);
+
+	dispc6_restore_context(dispc);
+
+	dispc6_restore_gamma_tables(dispc);
+
+	dispc->is_enabled = true;
+	/* ensure the dispc6_irq_handler sees the is_enabled value */
+	smp_wmb();
+
+	return 0;
+}
+
+static const struct dev_pm_ops dispc_pm_ops = {
+	.runtime_suspend = dispc6_runtime_suspend,
+	.runtime_resume = dispc6_runtime_resume,
+};
+
+static const struct of_device_id dispc6_of_match[] = {
+	{ .compatible = "ti,k2g-dispc", .data = &k2g_dispc_feats, },
+	{},
+};
+
+static struct platform_driver dispc6_driver = {
+	.probe		= dispc6_probe,
+	.remove         = dispc6_remove,
+	.driver         = {
+		.name   = "omap_dispc6",
+		.pm	= &dispc_pm_ops,
+		.of_match_table = dispc6_of_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+int __init dispc6_init_platform_driver(void)
+{
+	return platform_driver_register(&dispc6_driver);
+}
+
+void dispc6_uninit_platform_driver(void)
+{
+	platform_driver_unregister(&dispc6_driver);
+}
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc6.h b/drivers/gpu/drm/omapdrm/dss/dispc6.h
new file mode 100644
index 0000000..824fda4
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dispc6.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#ifndef __OMAP2_DISPC6_REG_H
+#define __OMAP2_DISPC6_REG_H
+
+/* COMMON */
+
+#define DISPC_REVISION			0x000
+#define DISPC_SYSCONFIG			0x004
+#define DISPC_SYSSTATUS			0x008
+
+#define DISPC_IRQ_EOI			0x020
+#define DISPC_IRQSTATUS_RAW		0x024
+#define DISPC_IRQSTATUS			0x028
+#define DISPC_IRQENABLE_SET		0x02c
+#define DISPC_IRQENABLE_CLR		0x030
+#define DISPC_IRQWAKEEN			0x034
+
+#define DISPC_GLOBAL_MFLAG_ATTRIBUTE	0x040
+#define DISPC_GLOBAL_BUFFER		0x044
+#define DISPC_BA0_FLIPIMMEDIATE_EN	0x048
+
+#define DISPC_DBG_CONTROL		0x04c
+#define DISPC_DBG_STATUS		0x050
+
+#define DISPC_CLKGATING_DISABLE		0x054
+
+/* VID */
+
+#define DISPC_VID_ACCUH_0		0x0
+#define DISPC_VID_ACCUH_1		0x4
+#define DISPC_VID_ACCUH2_0		0x8
+#define DISPC_VID_ACCUH2_1		0xc
+
+#define DISPC_VID_ACCUV_0		0x10
+#define DISPC_VID_ACCUV_1		0x14
+#define DISPC_VID_ACCUV2_0		0x18
+#define DISPC_VID_ACCUV2_1		0x1c
+
+#define DISPC_VID_ATTRIBUTES		0x20
+#define DISPC_VID_ATTRIBUTES2		0x24
+
+#define DISPC_VID_BA_0			0x28
+#define DISPC_VID_BA_1			0x2c
+#define DISPC_VID_BA_UV_0		0x30
+#define DISPC_VID_BA_UV_1		0x34
+#define DISPC_VID_BUF_SIZE_STATUS	0x38
+#define DISPC_VID_BUF_THRESHOLD		0x3c
+
+#define DISPC_VID_CONV_COEF(n)		(0x40 + (n) * 4)
+
+#define DISPC_VID_FIRH			0x5c
+#define DISPC_VID_FIRH2			0x60
+#define DISPC_VID_FIRV			0x64
+#define DISPC_VID_FIRV2			0x68
+
+#define DISPC_VID_FIR_COEFS_H0		0x6c
+#define DISPC_VID_FIR_COEF_H0(phase)	(0x6c + (phase) * 4)
+#define DISPC_VID_FIR_COEFS_H0_C	0x90
+#define DISPC_VID_FIR_COEF_H0_C(phase)	(0x90 + (phase) * 4)
+
+#define DISPC_VID_FIR_COEFS_H12		0xb4
+#define DISPC_VID_FIR_COEF_H12(phase)	(0xb4 + (phase) * 4)
+#define DISPC_VID_FIR_COEFS_H12_C	0xf4
+#define DISPC_VID_FIR_COEF_H12_C(phase)	(0xf4 + (phase) * 4)
+
+#define DISPC_VID_FIR_COEFS_V0		0x134
+#define DISPC_VID_FIR_COEF_V0(phase)	(0x134 + (phase) * 4)
+#define DISPC_VID_FIR_COEFS_V0_C	0x158
+#define DISPC_VID_FIR_COEF_V0_C(phase)	(0x158 + (phase) * 4)
+
+#define DISPC_VID_FIR_COEFS_V12		0x17c
+#define DISPC_VID_FIR_COEF_V12(phase)	(0x17c + (phase) * 4)
+#define DISPC_VID_FIR_COEFS_V12_C	0x1bc
+#define DISPC_VID_FIR_COEF_V12_C(phase)	(0x1bc + (phase) * 4)
+
+#define DISPC_VID_IRQENABLE		0x200
+#define DISPC_VID_IRQSTATUS		0x204
+
+#define DISPC_VID_MFLAG_THRESHOLD	0x208
+#define DISPC_VID_PICTURE_SIZE		0x20c
+#define DISPC_VID_PIXEL_INC		0x210
+#define DISPC_VID_POSITION		0x214
+#define DISPC_VID_PRELOAD		0x218
+#define DISPC_VID_ROW_INC		0x21c
+#define DISPC_VID_SIZE			0x220
+
+/* OVR */
+
+#define DISPC_OVR_DEFAULT_COLOR		0x08
+#define DISPC_OVR_DEFAULT_COLOR2	0x0c
+
+/* VP */
+
+#define DISPC_VP_CONFIG			0x00
+#define DISPC_VP_CONTROL		0x04
+#define DISPC_VP_GAMMA_TABLE		0x20
+#define DISPC_VP_IRQENABLE		0x3c
+#define DISPC_VP_IRQSTATUS		0x40
+#define DISPC_VP_POL_FREQ		0x4c
+#define DISPC_VP_SIZE_SCREEN		0x50
+#define DISPC_VP_TIMING_H		0x54
+#define DISPC_VP_TIMING_V		0x58
+
+#endif
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi6.c b/drivers/gpu/drm/omapdrm/dss/dpi6.c
new file mode 100644
index 0000000..458c8f3
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dpi6.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "omapdss.h"
+#include "dss6.h"
+
+struct dpi_data {
+	struct platform_device *pdev;
+
+	struct mutex lock;
+
+	struct videomode vm;
+	int data_lines;
+
+	struct omap_dss_device output;
+
+	bool port_initialized;
+
+	struct dss6_device *dss6;
+};
+
+static struct dpi_data *dpi6_get_data_from_dssdev(struct omap_dss_device *out)
+{
+	return container_of(out, struct dpi_data, output);
+}
+
+static void dpi6_config_lcd_manager(struct dpi_data *dpi)
+{
+	struct dss_lcd_mgr_config mgr_config = {
+		.io_pad_mode = DSS_IO_PAD_MODE_BYPASS,
+		.stallmode = false,
+		.fifohandcheck = false,
+		.video_port_width = dpi->data_lines,
+		.lcden_sig_polarity = 0,
+	};
+
+	dss_mgr_set_lcd_config(&dpi->output, &mgr_config);
+}
+
+static int dpi6_connect(struct omap_dss_device *out,
+			struct omap_dss_device *dst)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+	int r;
+
+	r = dss_mgr_connect(&dpi->output, out);
+	if (r)
+		return r;
+
+	r = omapdss_output_set_device(out, dst);
+	if (r) {
+		dev_err(&dpi->pdev->dev,
+			"failed to connect output to new device: %s\n",
+			dst->name);
+		dss_mgr_disconnect(&dpi->output, out);
+		return r;
+	}
+
+	return 0;
+}
+
+static void dpi6_disconnect(struct omap_dss_device *out,
+			    struct omap_dss_device *dst)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+
+	WARN_ON(dst != out->dst);
+
+	if (dst != out->dst)
+		return;
+
+	omapdss_output_unset_device(out);
+
+	dss_mgr_disconnect(&dpi->output, out);
+}
+
+static int dpi6_display_enable(struct omap_dss_device *out)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+	enum omap_channel channel = out->dispc_channel;
+	int r;
+
+	mutex_lock(&dpi->lock);
+
+	if (!out->dispc_channel_connected) {
+		dev_err(&dpi->pdev->dev, "failed to enable display: no output channel set\n");
+		r = -ENODEV;
+		goto err_no_out_mgr;
+	}
+
+	r = dispc6_runtime_get(dpi->dss6->data.dispc);
+	if (r)
+		goto err_get_dispc;
+
+	r = dispc6_vp_set_clk_rate(dpi->dss6->data.dispc, channel,
+				   dpi->vm.pixelclock);
+	if (r)
+		goto err_set_clk;
+
+	r = dispc6_vp_enable_clk(dpi->dss6->data.dispc, channel);
+	if (r)
+		goto err_enable_clk;
+
+	dpi6_config_lcd_manager(dpi);
+
+	r = dss_mgr_enable(&dpi->output);
+	if (r)
+		goto err_mgr_enable;
+
+	dss6_ungate_dpi_clk(&dpi->pdev->dev, out->port_num);
+
+	mutex_unlock(&dpi->lock);
+
+	return 0;
+
+err_mgr_enable:
+	dispc6_vp_disable_clk(dpi->dss6->data.dispc, channel);
+err_enable_clk:
+err_set_clk:
+	dispc6_runtime_put(dpi->dss6->data.dispc);
+err_get_dispc:
+err_no_out_mgr:
+	mutex_unlock(&dpi->lock);
+	return r;
+}
+
+static void dpi6_display_disable(struct omap_dss_device *out)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+	enum omap_channel channel = out->dispc_channel;
+
+	mutex_lock(&dpi->lock);
+
+	dss6_gate_dpi_clk(&dpi->pdev->dev, out->port_num);
+
+	dss_mgr_disable(&dpi->output);
+
+	dispc6_vp_disable_clk(dpi->dss6->data.dispc, channel);
+
+	dispc6_runtime_put(dpi->dss6->data.dispc);
+
+	mutex_unlock(&dpi->lock);
+}
+
+static int dpi6_check_timings(struct omap_dss_device *out,
+			      struct videomode *vm)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+	enum omap_channel channel = out->dispc_channel;
+
+	if (!dispc6_mgr_timings_ok(dpi->dss6->data.dispc, channel, vm))
+		return -EINVAL;
+
+	return 0;
+}
+
+static void dpi6_set_timings(struct omap_dss_device *out,
+			     struct videomode *vm)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+
+	mutex_lock(&dpi->lock);
+
+	dpi->vm = *vm;
+
+	mutex_unlock(&dpi->lock);
+}
+
+static void dpi6_get_timings(struct omap_dss_device *out,
+			     struct videomode *vm)
+{
+	struct dpi_data *dpi = dpi6_get_data_from_dssdev(out);
+
+	mutex_lock(&dpi->lock);
+
+	*vm = dpi->vm;
+
+	mutex_unlock(&dpi->lock);
+}
+
+
+static const struct omapdss_dpi_ops dpi6_ops = {
+	.connect = dpi6_connect,
+	.disconnect = dpi6_disconnect,
+
+	.enable = dpi6_display_enable,
+	.disable = dpi6_display_disable,
+
+	.check_timings = dpi6_check_timings,
+	.set_timings = dpi6_set_timings,
+	.get_timings = dpi6_get_timings,
+};
+
+static void dpi6_setup_output_port(struct platform_device *pdev,
+				   struct device_node *port)
+{
+	struct dpi_data *dpi = port->data;
+	struct omap_dss_device *out = &dpi->output;
+	int r;
+	u32 port_num;
+
+	r = of_property_read_u32(port, "reg", &port_num);
+	if (r)
+		port_num = 0;
+
+	switch (port_num) {
+	case 0:
+	default:
+		out->name = "dpi.0";
+		break;
+	}
+
+	out->dev = &pdev->dev;
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->output_type = OMAP_DISPLAY_TYPE_DPI;
+	out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+	out->port_num = port_num;
+	out->ops.dpi = &dpi6_ops;
+	out->owner = THIS_MODULE;
+
+	omapdss_register_output(out);
+}
+
+int dpi6_init_port(struct platform_device *pdev, struct device_node *port)
+{
+	struct dss6_device *dss6 = dss6_get_device(&pdev->dev);
+	struct dpi_data *dpi;
+	struct device_node *ep;
+	u32 datalines;
+	int r;
+
+	dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
+	if (!dpi)
+		return -ENOMEM;
+
+	ep = of_get_next_child(port, NULL);
+	if (!ep)
+		return 0;
+
+	r = of_property_read_u32(ep, "data-lines", &datalines);
+	if (r) {
+		dev_err(&dpi->pdev->dev, "failed to parse datalines\n");
+		goto err_datalines;
+	}
+
+	dpi->data_lines = datalines;
+
+	of_node_put(ep);
+
+	dpi->pdev = pdev;
+	port->data = dpi;
+
+	mutex_init(&dpi->lock);
+
+	dpi6_setup_output_port(pdev, port);
+
+	dpi->dss6 = dss6;
+	dpi->port_initialized = true;
+
+	return 0;
+
+err_datalines:
+	of_node_put(ep);
+
+	return r;
+}
+
+void dpi6_uninit_port(struct device_node *port)
+{
+	struct dpi_data *dpi = port->data;
+
+	if (!dpi->port_initialized)
+		return;
+
+	omapdss_unregister_output(&dpi->output);
+}
diff --git a/drivers/gpu/drm/omapdrm/dss/dss6.c b/drivers/gpu/drm/omapdrm/dss/dss6.c
new file mode 100644
index 0000000..180fa69
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dss6.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/dma-mapping.h>
+
+#include "omapdss.h"
+#include "dss6.h"
+
+#define DSS_REVISION	0x00
+#define DSS_SYSCONFIG	0x10
+#define DSS_SYSSTATUS	0x14
+#define DSS_RFBI_CTRL	0x18
+#define DSS_DPI_CTRL	0x1c
+#define DSS_DEBUG_CFG	0x40
+
+#define REG_GET(data, idx, start, end) \
+	FLD_GET(dss6_read(data, idx), start, end)
+
+#define REG_FLD_MOD(data, idx, val, start, end) \
+	dss6_write(data, idx, FLD_MOD(dss6_read(data, idx), val, start, end))
+
+struct dss_features {
+	int num_ports;
+};
+
+static const struct dss_features k2g_dss_feats = {
+	.num_ports = 1,
+};
+
+static const struct of_device_id dss6_of_match[];
+
+/* omapdrm device */
+
+static struct platform_device *omap_drm_device;
+
+static int initialize_omapdrm_device(void)
+{
+	omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
+	if (IS_ERR(omap_drm_device))
+		return PTR_ERR(omap_drm_device);
+
+	return 0;
+}
+
+/* omapdrm device end */
+
+static inline void dss6_write(struct dss6_device *dss6, u16 reg, u32 val)
+{
+	iowrite32(val, dss6->base + reg);
+}
+
+static inline u32 dss6_read(struct dss6_device *dss6, u16 reg)
+{
+	return ioread32(dss6->base + reg);
+}
+
+void dss6_ungate_dpi_clk(struct device *dev, int port)
+{
+	struct dss6_device *dss6 = dss6_get_device(dev);
+
+	REG_FLD_MOD(dss6, DSS_DPI_CTRL, 1, 1, 0);
+}
+
+void dss6_gate_dpi_clk(struct device *dev, int port)
+{
+	struct dss6_device *dss6 = dss6_get_device(dev);
+
+	REG_FLD_MOD(dss6, DSS_DPI_CTRL, 0, 1, 0);
+}
+
+static int dss6_init_features(struct platform_device *pdev)
+{
+	struct dss6_device *dss6 = dss6_get_device(&pdev->dev);
+	const struct of_device_id *match;
+
+	match = of_match_node(dss6_of_match, pdev->dev.of_node);
+	if (!match) {
+		dev_err(&pdev->dev, "Unsupported DSS version\n");
+		return -ENODEV;
+	}
+
+	dss6->feat = match->data;
+
+	return 0;
+}
+
+static int dss6_init_ports(struct platform_device *pdev)
+{
+	struct dss6_device *dss6 = dss6_get_device(&pdev->dev);
+	struct device_node *parent = pdev->dev.of_node;
+	struct device_node *port;
+	int i, ret;
+
+	for (i = 0; i < dss6->feat->num_ports; i++) {
+		port = of_graph_get_port_by_id(parent, i);
+		if (!port)
+			continue;
+
+		ret = dpi6_init_port(pdev, port);
+		of_node_put(port);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static void dss6_uninit_ports(struct platform_device *pdev)
+{
+	struct dss6_device *dss6 = dss6_get_device(&pdev->dev);
+	struct device_node *parent = pdev->dev.of_node;
+	struct device_node *port;
+	int i;
+
+	for (i = 0; i < dss6->feat->num_ports; i++) {
+		port = of_graph_get_port_by_id(parent, i);
+		if (!port)
+			continue;
+
+		dpi6_uninit_port(port);
+		of_node_put(port);
+	}
+}
+
+static int dss6_bind(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dss6_device *dss6;
+	struct resource *dss_mem;
+	int r;
+
+	dss6 = devm_kzalloc(dev, sizeof(*dss6), GFP_KERNEL);
+	if (!dss6)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, dss6);
+	dss6->pdev = pdev;
+
+	r = dss6_init_features(dss6->pdev);
+	if (r)
+		goto err_features;
+
+	dss_mem = platform_get_resource(dss6->pdev, IORESOURCE_MEM, 0);
+	if (!dss_mem) {
+		dev_err(dev, "Failed to get IORESOURCE_MEM\n");
+		r = -EINVAL;
+		goto err_resource;
+	}
+
+	dss6->base = devm_ioremap(&pdev->dev, dss_mem->start,
+					resource_size(dss_mem));
+	if (!dss6->base) {
+		dev_err(dev, "Failed to ioremap\n");
+		r = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	r = dss6_init_ports(pdev);
+	if (r)
+		goto err_init_ports;
+
+	dss6->fclk = devm_clk_get(dev, "fck");
+	if (IS_ERR(dss6->fclk)) {
+		dev_err(dev, "Failed to get fclk\n");
+		r = PTR_ERR(dss6->fclk);
+		goto err_clk_get;
+	}
+
+	dev_dbg(&pdev->dev, "DSS fclk %lu Hz\n", clk_get_rate(dss6->fclk));
+
+	pm_runtime_enable(&pdev->dev);
+
+	r = component_bind_all(&pdev->dev, NULL);
+	if (r)
+		goto err_component;
+
+	r = initialize_omapdrm_device();
+	if (r)
+		goto err_omapdrm_device;
+
+	omapdss_gather_components(dev);
+	omapdss_set_dss(&dss6->data);
+
+	return 0;
+
+err_omapdrm_device:
+	component_unbind_all(&pdev->dev, NULL);
+err_component:
+	pm_runtime_disable(&pdev->dev);
+err_clk_get:
+err_init_ports:
+err_ioremap:
+err_resource:
+err_features:
+	kfree(dss6);
+	return r;
+}
+
+static void dss6_unbind(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	omapdss_set_dss(NULL);
+
+	platform_device_unregister(omap_drm_device);
+
+	component_unbind_all(&pdev->dev, NULL);
+
+	dss6_uninit_ports(pdev);
+
+	pm_runtime_disable(&pdev->dev);
+}
+
+static const struct component_master_ops dss6_component_ops = {
+	.bind = dss6_bind,
+	.unbind = dss6_unbind,
+};
+
+static int dss6_component_compare(struct device *dev, void *data)
+{
+	struct device *child = data;
+	return dev == child;
+}
+
+static int dss6_add_child_component(struct device *dev, void *data)
+{
+	struct component_match **match = data;
+
+	component_match_add(dev->parent, match, dss6_component_compare, dev);
+
+	return 0;
+}
+
+static int dss6_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+	int r;
+
+	/* add all the child devices as components */
+	device_for_each_child(&pdev->dev, &match, dss6_add_child_component);
+
+	if (!match) {
+		dev_err(&pdev->dev, "No submodules found\n");
+		return -EINVAL;
+	}
+
+	r = component_master_add_with_match(&pdev->dev, &dss6_component_ops, match);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static int dss6_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &dss6_component_ops);
+	return 0;
+}
+
+static int dss6_runtime_suspend(struct device *dev)
+{
+	struct dss6_device *dss6 = dss6_get_device(dev);
+
+	clk_disable_unprepare(dss6->fclk);
+
+	return 0;
+}
+
+static int dss6_runtime_resume(struct device *dev)
+{
+	struct dss6_device *dss6 = dss6_get_device(dev);
+
+
+	clk_prepare_enable(dss6->fclk);
+
+	if (REG_GET(dss6, DSS_SYSSTATUS, 0, 0) == 0)
+		dev_warn(dev, "DSS FUNC RESET not done!\n");
+
+	return 0;
+}
+
+static const struct dev_pm_ops dss6_pm_ops = {
+	.runtime_suspend = dss6_runtime_suspend,
+	.runtime_resume = dss6_runtime_resume,
+};
+
+static const struct of_device_id dss6_of_match[] = {
+	{ .compatible = "ti,k2g-dss", .data = &k2g_dss_feats, },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, dss6_of_match);
+
+static struct platform_driver dss6_driver = {
+	.probe		= dss6_probe,
+	.remove		= dss6_remove,
+	.driver         = {
+		.name   = "omap_dss6",
+		.pm	= &dss6_pm_ops,
+		.of_match_table = dss6_of_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init omap_dss_init(void)
+{
+	int r;
+
+	r = platform_driver_register(&dss6_driver);
+	if (r)
+		return r;
+
+	r = dispc6_init_platform_driver();
+	if (r) {
+		platform_driver_unregister(&dss6_driver);
+		return r;
+	}
+
+	return 0;
+}
+
+static void __exit omap_dss_exit(void)
+{
+	dispc6_uninit_platform_driver();
+	platform_driver_unregister(&dss6_driver);
+}
+
+module_init(omap_dss_init);
+module_exit(omap_dss_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
+MODULE_DESCRIPTION("OMAP6 Display Subsystem");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/omapdrm/dss/dss6.h b/drivers/gpu/drm/omapdrm/dss/dss6.h
new file mode 100644
index 0000000..b581d71
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/dss/dss6.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ */
+
+#ifndef __TI_DSS6_H
+#define __TI_DSS6_H
+
+#include "omapdss.h"
+
+struct dss6_device {
+	struct platform_device *pdev;
+	void __iomem *base;
+
+	struct clk *fclk;
+
+	const struct dss_features *feat;
+
+	struct dss_data data;
+};
+
+static inline struct dss6_device *dss6_get_device(struct device *dev)
+{
+	return dev_get_drvdata(dev);
+}
+
+/* DSS6 */
+void dss6_ungate_dpi_clk(struct device *dev, int port);
+void dss6_gate_dpi_clk(struct device *dev, int port);
+
+/* DISPC6 */
+int __init dispc6_init_platform_driver(void);
+void dispc6_uninit_platform_driver(void);
+
+int dispc6_runtime_get(struct dispc_device *dispc);
+void dispc6_runtime_put(struct dispc_device *dispc);
+
+bool dispc6_mgr_timings_ok(struct dispc_device *dispc,
+			   enum omap_channel channel,
+			   const struct videomode *vm);
+
+int dispc6_vp_set_clk_rate(struct dispc_device *dispc,
+			   enum omap_channel channel, unsigned long rate);
+int dispc6_vp_enable_clk(struct dispc_device *dispc,
+			 enum omap_channel channel);
+void dispc6_vp_disable_clk(struct dispc_device *dispc,
+			   enum omap_channel channel);
+
+/* DPI6 */
+int dpi6_init_port(struct platform_device *pdev, struct device_node *port);
+void dpi6_uninit_port(struct device_node *port);
+
+#endif /* __TI_DSS6_H */
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss
  2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
                   ` (7 preceding siblings ...)
  2018-02-16 11:25 ` [PATCH RFC 8/9] drm/omap: add TI DSS6 driver Jyri Sarha
@ 2018-02-16 11:25 ` Jyri Sarha
  2018-02-27 14:15   ` Laurent Pinchart
  8 siblings, 1 reply; 26+ messages in thread
From: Jyri Sarha @ 2018-02-16 11:25 UTC (permalink / raw)
  To: dri-devel, tomi.valkeinen, laurent.pinchart

From: Tomi Valkeinen <tomi.valkeinen@ti.com>

Add "ti,k2g-dss" to the list of DSS devices which need the mangling of
the panels' & encoders' compatible strings.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
index 3bfb95d..698388e 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
@@ -181,6 +181,7 @@ static const struct of_device_id omapdss_of_match[] __initconst = {
 	{ .compatible = "ti,omap4-dss", },
 	{ .compatible = "ti,omap5-dss", },
 	{ .compatible = "ti,dra7-dss", },
+	{ .compatible = "ti,k2g-dss", },
 	{},
 };
 
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations
  2018-02-16 11:25 ` [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations Jyri Sarha
@ 2018-02-19 12:01   ` Tomi Valkeinen
  2018-02-27 14:27     ` Laurent Pinchart
  0 siblings, 1 reply; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-19 12:01 UTC (permalink / raw)
  To: Jyri Sarha, dri-devel, laurent.pinchart

Hi Jyri, Laurent,

On 16/02/18 13:25, Jyri Sarha wrote:
> After this patch OMAP_DSS_BASE module is not including any OMAP2_DSS
> headers, only the API omapdss.h. "sturct dss_data", the piece of the
> data structure needed for base.c is defined in omapdss.h and added as
> a member to struct dss_device, and later to struct dss6_device.
> 
> The patch is still a bit hackish. The struct dispc_device declaration
> is currently shared between alternative dss implementations, with
> different internal definitions. It should be relatively simple to use
> a similar struct dispc_data as struct dss_data is for dss_device, move
> some common parts - maybe the dispc_ops itself - there and find the
> private data with container_of macro. Also the contents of struct
> dss_data in side dss_device is currently redundant. These should be
> easy enough to fix, if we decide to take this route.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/base.c    | 11 +++++------
>  drivers/gpu/drm/omapdrm/dss/dispc.c   |  4 ++++
>  drivers/gpu/drm/omapdrm/dss/dss.c     |  2 +-
>  drivers/gpu/drm/omapdrm/dss/dss.h     |  2 ++
>  drivers/gpu/drm/omapdrm/dss/omapdss.h | 13 +++++++++----
>  drivers/gpu/drm/omapdrm/omap_drv.h    |  2 +-
>  6 files changed, 22 insertions(+), 12 deletions(-)

I think something in this direction would be good. I'd really like to keep it possible to run dss6 on top of omapdrm.

But I think this can be done slightly simpler like this:


diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index 99e8cb8dc65b..08913e006e93 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -19,10 +19,11 @@
 #include <linux/of_graph.h>
 #include <linux/list.h>
 
-#include "dss.h"
 #include "omapdss.h"
 
 static struct dss_device *dss_device;
+static struct dispc_device *s_dispc_device;
+static const struct dispc_ops *s_dispc_ops;
 
 static struct list_head omapdss_comp_list;
 
@@ -46,16 +47,23 @@ EXPORT_SYMBOL(omapdss_set_dss);
 
 struct dispc_device *dispc_get_dispc(struct dss_device *dss)
 {
-	return dss->dispc;
+	return s_dispc_device;
 }
 EXPORT_SYMBOL(dispc_get_dispc);
 
 const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
 {
-	return dss->dispc_ops;
+	return s_dispc_ops;
 }
 EXPORT_SYMBOL(dispc_get_ops);
 
+void omapdss_set_dispc(struct dispc_device *dispc, const struct dispc_ops* dispc_ops)
+{
+	s_dispc_device = dispc;
+	s_dispc_ops = dispc_ops;
+}
+EXPORT_SYMBOL(omapdss_set_dispc);
+
 static bool omapdss_list_contains(const struct device_node *node)
 {
 	struct omapdss_comp_node *comp;
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index ce470b51e326..b72f981d660e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -4786,7 +4786,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
 	dispc_runtime_put(dispc);
 
 	dss->dispc = dispc;
-	dss->dispc_ops = &dispc_ops;
+	omapdss_set_dispc(dispc, &dispc_ops);
 
 	dispc->debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
 						 dispc);
@@ -4807,8 +4807,8 @@ static void dispc_unbind(struct device *dev, struct device *master, void *data)
 
 	dss_debugfs_remove_file(dispc->debugfs);
 
+	omapdss_set_dispc(NULL, NULL);
 	dss->dispc = NULL;
-	dss->dispc_ops = NULL;
 
 	pm_runtime_disable(dev);
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 6f6fd3d1b159..3d23232ec1f7 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -274,7 +274,6 @@ struct dss_device {
 	struct dss_pll	*video2_pll;
 
 	struct dispc_device *dispc;
-	const struct dispc_ops *dispc_ops;
 };
 
 /* core */
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index a4f71e082c1c..b724dae22d7a 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -751,6 +751,7 @@ struct dispc_ops {
 
 struct dispc_device *dispc_get_dispc(struct dss_device *dss);
 const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
+void omapdss_set_dispc(struct dispc_device *dispc, const struct dispc_ops* dispc_ops);
 
 bool omapdss_component_is_display(struct device_node *node);
 bool omapdss_component_is_output(struct device_node *node);


Yes, it adds two new globals. But I don't think those are a big issue. Note that I left the dss->dispc there, for dss internal use.

Laurent, what do you think? If this is fine, can you squash to your series? Or I can even have this on top as well. I think otherwise it's good for merging.

Can you also have a quick look at patches 2, 3, 4, 5, 6 and 7. While their aim is to get dss6 working, I think they're ok cleanups and shouldn't cause issues with the main dss rework.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h
  2018-02-16 11:25 ` [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h Jyri Sarha
@ 2018-02-19 12:06   ` Tomi Valkeinen
  2018-02-27 14:42   ` Laurent Pinchart
  1 sibling, 0 replies; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-19 12:06 UTC (permalink / raw)
  To: Jyri Sarha, dri-devel, laurent.pinchart

Hi Jyri,

On 16/02/18 13:25, Jyri Sarha wrote:
> The new DSS6 driver needs some structs and defines which are currently
> in dss.h, which is for the old DSS driver.
> 
> Move the required structs and defines from dss.h to omapdss.h.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dss.h     | 41 ++---------------------------------
>  drivers/gpu/drm/omapdrm/dss/omapdss.h | 37 +++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
> index 434262a..fa206ca 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.h
> @@ -70,14 +70,6 @@ struct seq_file;
>  	pr_warn("omapdss: " format, ##__VA_ARGS__)
>  #endif
>  
> -/* OMAP TRM gives bitfields as start:end, where start is the higher bit
> -   number. For example 7:0 */
> -#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
> -#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
> -#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
> -#define FLD_MOD(orig, val, start, end) \
> -	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
> -
>  enum dss_model {
>  	DSS_MODEL_OMAP2,
>  	DSS_MODEL_OMAP3,
> @@ -86,12 +78,6 @@ enum dss_model {
>  	DSS_MODEL_DRA7,
>  };
>  
> -enum dss_io_pad_mode {
> -	DSS_IO_PAD_MODE_RESET,
> -	DSS_IO_PAD_MODE_RFBI,
> -	DSS_IO_PAD_MODE_BYPASS,
> -};
> -
>  enum dss_hdmi_venc_clk_source_select {
>  	DSS_VENC_TV_CLK = 0,
>  	DSS_HDMI_M_PCLK = 1,
> @@ -215,34 +201,11 @@ struct dss_reg_field {
>  	u8 start, end;
>  };
>  
> -struct dispc_clock_info {
> -	/* rates that we get with dividers below */
> -	unsigned long lck;
> -	unsigned long pck;
> -
> -	/* dividers */
> -	u16 lck_div;
> -	u16 pck_div;
> -};
> -
> -struct dss_lcd_mgr_config {
> -	enum dss_io_pad_mode io_pad_mode;
> -
> -	bool stallmode;
> -	bool fifohandcheck;
> -
> -	struct dispc_clock_info clock_info;
> -
> -	int video_port_width;
> -
> -	int lcden_sig_polarity;
> -};
> -
> -#define DSS_SZ_REGS			SZ_512
> +#define DSS_SZ_REGS                    SZ_512
>  
>  struct dss_device {
>  	struct platform_device *pdev;
> -	void __iomem    *base;
> +	void __iomem	*base;

Extra changes here, and in the above SZ_REGS.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 4/9] drm/omap: Make omapdss API more generic
  2018-02-16 11:25 ` [PATCH RFC 4/9] drm/omap: Make omapdss API more generic Jyri Sarha
@ 2018-02-19 12:41   ` Tomi Valkeinen
  0 siblings, 0 replies; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-19 12:41 UTC (permalink / raw)
  To: Jyri Sarha, dri-devel, laurent.pinchart

Hi Jyri,

On 16/02/18 13:25, Jyri Sarha wrote:
> The new omapdss API is HW independent and cleans up some of the DSS5
> specific hacks from the omapdrm side and gets rid off the DSS5 IRQ
> register bits and replace them with HW independent generic u64 based
> macros. The new macros make it more straight forward to implement the
> IRQ code for the future DSS versions that do not share the same
> register structure as DSS2 to DSS5 has.

This removes DISPC_IRQ_FRAMEDONEWB.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss
  2018-02-16 11:25 ` [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss Jyri Sarha
@ 2018-02-27 14:15   ` Laurent Pinchart
  2018-02-27 14:15     ` Laurent Pinchart
  0 siblings, 1 reply; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:15 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Tomi,

Thank you for the patch.

On Friday, 16 February 2018 13:25:10 EET Jyri Sarha wrote:
> From: Tomi Valkeinen <tomi.valkeinen@ti.com>
> 
> Add "ti,k2g-dss" to the list of DSS devices which need the mangling of
> the panels' & encoders' compatible strings.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Based on the DT bindings from Documentation/devicetree/bindings/display/ti/
ti,k2g-dss.txt in git@github.com:jsarha/linux.git omapdrm-next-dss6,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c index 3bfb95d..698388e
> 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> @@ -181,6 +181,7 @@ static const struct of_device_id omapdss_of_match[]
> __initconst = { { .compatible = "ti,omap4-dss", },
>  	{ .compatible = "ti,omap5-dss", },
>  	{ .compatible = "ti,dra7-dss", },
> +	{ .compatible = "ti,k2g-dss", },
>  	{},
>  };

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss
  2018-02-27 14:15   ` Laurent Pinchart
@ 2018-02-27 14:15     ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:15 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

On Tuesday, 27 February 2018 16:15:11 EET Laurent Pinchart wrote:
> Hi Tomi,

This should obviously have read Jyri :-)

> Thank you for the patch.
> 
> On Friday, 16 February 2018 13:25:10 EET Jyri Sarha wrote:
> > From: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > 
> > Add "ti,k2g-dss" to the list of DSS devices which need the mangling of
> > the panels' & encoders' compatible strings.
> > 
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> 
> Based on the DT bindings from Documentation/devicetree/bindings/display/ti/
> ti,k2g-dss.txt in git@github.com:jsarha/linux.git omapdrm-next-dss6,
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> > ---
> > 
> >  drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> > b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c index 3bfb95d..698388e
> > 100644
> > --- a/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> > +++ b/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c
> > @@ -181,6 +181,7 @@ static const struct of_device_id omapdss_of_match[]
> > __initconst = {
> >  	{ .compatible = "ti,omap4-dss", },
> >  	{ .compatible = "ti,omap5-dss", },
> >  	{ .compatible = "ti,dra7-dss", },
> > +	{ .compatible = "ti,k2g-dss", },
> >  	{},
> >  };

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations
  2018-02-19 12:01   ` Tomi Valkeinen
@ 2018-02-27 14:27     ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:27 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: dri-devel, Jyri Sarha

Hi Tomi,

On Monday, 19 February 2018 14:01:05 EET Tomi Valkeinen wrote:
> On 16/02/18 13:25, Jyri Sarha wrote:
> > After this patch OMAP_DSS_BASE module is not including any OMAP2_DSS
> > headers, only the API omapdss.h. "sturct dss_data", the piece of the
> > data structure needed for base.c is defined in omapdss.h and added as
> > a member to struct dss_device, and later to struct dss6_device.
> > 
> > The patch is still a bit hackish. The struct dispc_device declaration
> > is currently shared between alternative dss implementations, with
> > different internal definitions. It should be relatively simple to use
> > a similar struct dispc_data as struct dss_data is for dss_device, move
> > some common parts - maybe the dispc_ops itself - there and find the
> > private data with container_of macro. Also the contents of struct
> > dss_data in side dss_device is currently redundant. These should be
> > easy enough to fix, if we decide to take this route.
> > 
> > Signed-off-by: Jyri Sarha <jsarha@ti.com>
> > ---
> > 
> >  drivers/gpu/drm/omapdrm/dss/base.c    | 11 +++++------
> >  drivers/gpu/drm/omapdrm/dss/dispc.c   |  4 ++++
> >  drivers/gpu/drm/omapdrm/dss/dss.c     |  2 +-
> >  drivers/gpu/drm/omapdrm/dss/dss.h     |  2 ++
> >  drivers/gpu/drm/omapdrm/dss/omapdss.h | 13 +++++++++----
> >  drivers/gpu/drm/omapdrm/omap_drv.h    |  2 +-
> >  6 files changed, 22 insertions(+), 12 deletions(-)
> 
> I think something in this direction would be good. I'd really like to keep
> it possible to run dss6 on top of omapdrm.
> 
> But I think this can be done slightly simpler like this:
> 
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/base.c
> b/drivers/gpu/drm/omapdrm/dss/base.c index 99e8cb8dc65b..08913e006e93
> 100644
> --- a/drivers/gpu/drm/omapdrm/dss/base.c
> +++ b/drivers/gpu/drm/omapdrm/dss/base.c
> @@ -19,10 +19,11 @@
>  #include <linux/of_graph.h>
>  #include <linux/list.h>
> 
> -#include "dss.h"
>  #include "omapdss.h"
> 
>  static struct dss_device *dss_device;
> +static struct dispc_device *s_dispc_device;
> +static const struct dispc_ops *s_dispc_ops;
> 
>  static struct list_head omapdss_comp_list;
> 
> @@ -46,16 +47,23 @@ EXPORT_SYMBOL(omapdss_set_dss);
> 
>  struct dispc_device *dispc_get_dispc(struct dss_device *dss)
>  {
> -	return dss->dispc;
> +	return s_dispc_device;
>  }
>  EXPORT_SYMBOL(dispc_get_dispc);
> 
>  const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
>  {
> -	return dss->dispc_ops;
> +	return s_dispc_ops;
>  }
>  EXPORT_SYMBOL(dispc_get_ops);
> 
> +void omapdss_set_dispc(struct dispc_device *dispc, const struct dispc_ops*
> dispc_ops)
> +{
> +	s_dispc_device = dispc;
> +	s_dispc_ops = dispc_ops;
> +}
> +EXPORT_SYMBOL(omapdss_set_dispc);
> +
>  static bool omapdss_list_contains(const struct device_node *node)
>  {
>  	struct omapdss_comp_node *comp;
> diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c
> b/drivers/gpu/drm/omapdrm/dss/dispc.c index ce470b51e326..b72f981d660e
> 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dispc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
> @@ -4786,7 +4786,7 @@ static int dispc_bind(struct device *dev, struct
> device *master, void *data) dispc_runtime_put(dispc);
> 
>  	dss->dispc = dispc;
> -	dss->dispc_ops = &dispc_ops;
> +	omapdss_set_dispc(dispc, &dispc_ops);
> 
>  	dispc->debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
>  						 dispc);
> @@ -4807,8 +4807,8 @@ static void dispc_unbind(struct device *dev, struct
> device *master, void *data)
> 
>  	dss_debugfs_remove_file(dispc->debugfs);
> 
> +	omapdss_set_dispc(NULL, NULL);
>  	dss->dispc = NULL;
> -	dss->dispc_ops = NULL;
> 
>  	pm_runtime_disable(dev);
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h
> b/drivers/gpu/drm/omapdrm/dss/dss.h index 6f6fd3d1b159..3d23232ec1f7 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.h
> @@ -274,7 +274,6 @@ struct dss_device {
>  	struct dss_pll	*video2_pll;
> 
>  	struct dispc_device *dispc;
> -	const struct dispc_ops *dispc_ops;
>  };
> 
>  /* core */
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> b/drivers/gpu/drm/omapdrm/dss/omapdss.h index a4f71e082c1c..b724dae22d7a
> 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -751,6 +751,7 @@ struct dispc_ops {
> 
>  struct dispc_device *dispc_get_dispc(struct dss_device *dss);
>  const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
> +void omapdss_set_dispc(struct dispc_device *dispc, const struct dispc_ops*
> dispc_ops);
> 
>  bool omapdss_component_is_display(struct device_node *node);
>  bool omapdss_component_is_output(struct device_node *node);
> 
> 
> Yes, it adds two new globals. But I don't think those are a big issue. Note
> that I left the dss->dispc there, for dss internal use.
> 
> Laurent, what do you think? If this is fine, can you squash to your series?
> Or I can even have this on top as well. I think otherwise it's good for
> merging.

To be honest I like Jyri's approach better, with a small caveat: we really 
need to standardize how we name our data structures. It will be painful (as in 
generating conflicts) but should make the code much clearer. dss_data vs. 
dss_device vs. omap_dss_device is just too confusing. If you agree to a rename 
of data structure I'll make a proposal.

Additionally, one thing I like about this patch is that the dss_data structure 
(to be renamed...) can store data shared between the DSS2-5 and DSS6 
implementations, which would make it easier to share code where applicable. 
Being completely honest again I haven't reviewed the DSS6 implementation yet, 
so there might be no opportunity for code sharing.

> Can you also have a quick look at patches 2, 3, 4, 5, 6 and 7. While their
> aim is to get dss6 working, I think they're ok cleanups and shouldn't cause
> issues with the main dss rework.

Sure, I'll review them now.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails
  2018-02-16 11:25 ` [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails Jyri Sarha
@ 2018-02-27 14:27   ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:27 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Jyri,

Thank you for the patch.

On Friday, 16 February 2018 13:25:03 EET Jyri Sarha wrote:
> Call to omap_drm_irq_install() may fail with an error code. In such a
> case the driver probe should fail.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c
> b/drivers/gpu/drm/omapdrm/omap_drv.c index 65a567d..979bede 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -321,7 +321,9 @@ static int omap_modeset_init(struct drm_device *dev)
> 
>  	drm_mode_config_reset(dev);
> 
> -	omap_drm_irq_install(dev);
> +	ret = omap_drm_irq_install(dev);
> +	if (ret)
> +		return ret;
> 
>  	return 0;

Or maybe just

	return omap_drm_irq_install(dev);

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>  }

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-16 11:25 ` [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops Jyri Sarha
@ 2018-02-27 14:35   ` Laurent Pinchart
  2018-02-28 11:37     ` Tomi Valkeinen
  0 siblings, 1 reply; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:35 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Jyri,

Thank you for the patch.

On Friday, 16 February 2018 13:25:04 EET Jyri Sarha wrote:
> Add ovl_name() and mgr_name() to dispc_ops and get rid of adhoc names
> here and there in the omapdrm code. This moves the names of hardware
> entities to omapdss side where they have to be when new omapdss
> backend drivers are introduced.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dispc.c   | 23 +++++++++++++++++++++++
>  drivers/gpu/drm/omapdrm/dss/omapdss.h |  5 +++++
>  drivers/gpu/drm/omapdrm/omap_crtc.c   | 11 ++---------
>  drivers/gpu/drm/omapdrm/omap_irq.c    | 19 +++++++------------
>  drivers/gpu/drm/omapdrm/omap_plane.c  | 13 +++----------
>  5 files changed, 40 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c
> b/drivers/gpu/drm/omapdrm/dss/dispc.c index 338490d..6f83b3e 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dispc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
> @@ -694,6 +694,26 @@ void dispc_runtime_put(struct dispc_device *dispc)
>  	WARN_ON(r < 0 && r != -ENOSYS);
>  }
> 
> +static const char *dispc_ovl_name(struct dispc_device *dispc,
> +				  enum omap_plane_id plane)
> +{
> +	static const char * const ovl_names[] = {
> +		[OMAP_DSS_GFX]		= "GFX",
> +		[OMAP_DSS_VIDEO1]	= "VID1",
> +		[OMAP_DSS_VIDEO2]	= "VID2",
> +		[OMAP_DSS_VIDEO3]	= "VID3",
> +		[OMAP_DSS_WB]		= "WB",
> +	};
> +
> +	return ovl_names[plane];
> +}
> +
> +static const char *dispc_mgr_name(struct dispc_device *dispc,
> +				  enum omap_channel channel)
> +{
> +	return mgr_desc[channel].name;
> +}
> +
>  static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc,
>  				   enum omap_channel channel)
>  {
> @@ -4662,6 +4682,9 @@ static const struct dispc_ops dispc_ops = {
>  	.get_num_ovls = dispc_get_num_ovls,
>  	.get_num_mgrs = dispc_get_num_mgrs,
> 
> +	.ovl_name = dispc_ovl_name,
> +	.mgr_name = dispc_mgr_name,
> +
>  	.get_memory_bandwidth_limit = dispc_get_memory_bandwidth_limit,
> 
>  	.mgr_enable = dispc_mgr_enable,
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 1299dd6..b84cfd8 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -711,6 +711,11 @@ struct dispc_ops {
>  	int (*get_num_ovls)(struct dispc_device *dispc);
>  	int (*get_num_mgrs)(struct dispc_device *dispc);
> 
> +	const char *(*ovl_name)(struct dispc_device *dispc,
> +				enum omap_plane_id plane);
> +	const char *(*mgr_name)(struct dispc_device *dispc,
> +				enum omap_channel channel);
> +
>  	u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc);
> 
>  	void (*mgr_enable)(struct dispc_device *dispc,
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c
> b/drivers/gpu/drm/omapdrm/omap_crtc.c index 6c4d40b..00ec959 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -672,13 +672,6 @@ static const struct drm_crtc_helper_funcs
> omap_crtc_helper_funcs = { * Init and Cleanup
>   */
> 
> -static const char *channel_names[] = {
> -	[OMAP_DSS_CHANNEL_LCD] = "lcd",
> -	[OMAP_DSS_CHANNEL_DIGIT] = "tv",
> -	[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
> -	[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
> -};
> -
>  void omap_crtc_pre_init(struct omap_drm_private *priv)
>  {
>  	memset(omap_crtcs, 0, sizeof(omap_crtcs));
> @@ -706,7 +699,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
>  	channel = out->dispc_channel;
>  	omap_dss_put_device(out);
> 
> -	DBG("%s", channel_names[channel]);
> +	DBG("%s", priv->dispc_ops->mgr_name(priv->dispc, channel));
> 
>  	/* Multiple displays on same channel is not allowed */
>  	if (WARN_ON(omap_crtcs[channel] != NULL))
> @@ -721,7 +714,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
>  	init_waitqueue_head(&omap_crtc->pending_wait);
> 
>  	omap_crtc->channel = channel;
> -	omap_crtc->name = channel_names[channel];
> +	omap_crtc->name = priv->dispc_ops->mgr_name(priv->dispc, channel);

Possibly a small improvement here, you could cache the name in a local 
variable instead of calling the mgr_name operation twice.

> 
>  	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
>  					&omap_crtc_funcs, NULL);
> diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c
> b/drivers/gpu/drm/omapdrm/omap_irq.c index c8511504..5cc88b6 100644
> --- a/drivers/gpu/drm/omapdrm/omap_irq.c
> +++ b/drivers/gpu/drm/omapdrm/omap_irq.c
> @@ -146,15 +146,10 @@ static void omap_irq_fifo_underflow(struct
> omap_drm_private *priv, {
>  	static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
>  				      DEFAULT_RATELIMIT_BURST);
> -	static const struct {
> -		const char *name;
> -		u32 mask;
> -	} sources[] = {
> -		{ "gfx", DISPC_IRQ_GFX_FIFO_UNDERFLOW },
> -		{ "vid1", DISPC_IRQ_VID1_FIFO_UNDERFLOW },
> -		{ "vid2", DISPC_IRQ_VID2_FIFO_UNDERFLOW },
> -		{ "vid3", DISPC_IRQ_VID3_FIFO_UNDERFLOW },
> -	};
> +	static const u32 irqbits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW,
> +				       DISPC_IRQ_VID1_FIFO_UNDERFLOW,
> +				       DISPC_IRQ_VID2_FIFO_UNDERFLOW,
> +				       DISPC_IRQ_VID3_FIFO_UNDERFLOW };

The indentation looks weird, I'd write it

	static const u32 irqbits[] = {
		DISPC_IRQ_GFX_FIFO_UNDERFLOW,
		DISPC_IRQ_VID1_FIFO_UNDERFLOW,
		DISPC_IRQ_VID2_FIFO_UNDERFLOW,
		DISPC_IRQ_VID3_FIFO_UNDERFLOW,
	};

>  	const u32 mask = DISPC_IRQ_GFX_FIFO_UNDERFLOW
>  		       | DISPC_IRQ_VID1_FIFO_UNDERFLOW
> 
> @@ -174,9 +169,9 @@ static void omap_irq_fifo_underflow(struct
> omap_drm_private *priv,
> 
>  	DRM_ERROR("FIFO underflow on ");
> 
> -	for (i = 0; i < ARRAY_SIZE(sources); ++i) {
> -		if (sources[i].mask & irqstatus)
> -			pr_cont("%s ", sources[i].name);
> +	for (i = 0; i < ARRAY_SIZE(irqbits); ++i) {
> +		if (irqbits[i] & irqstatus)
> +			pr_cont("%s ", priv->dispc_ops->ovl_name(priv->dispc, i));

I wonder if it's worth it here, in the sense that you're splitting the name 
and mask, which are both DISPC-specific, in two. Would it make sense to move 
the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ 
handling to the DSS side, as they're not DRM/KMS-related ?

>  	}
> 
>  	pr_cont("(0x%08x)\n", irqstatus);
> diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c
> b/drivers/gpu/drm/omapdrm/omap_plane.c index 2899435..61b0753 100644
> --- a/drivers/gpu/drm/omapdrm/omap_plane.c
> +++ b/drivers/gpu/drm/omapdrm/omap_plane.c
> @@ -239,13 +239,6 @@ static const struct drm_plane_funcs omap_plane_funcs =
> { .atomic_get_property = omap_plane_atomic_get_property,
>  };
> 
> -static const char *plane_id_to_name[] = {
> -	[OMAP_DSS_GFX] = "gfx",
> -	[OMAP_DSS_VIDEO1] = "vid1",
> -	[OMAP_DSS_VIDEO2] = "vid2",
> -	[OMAP_DSS_VIDEO3] = "vid3",
> -};
> -
>  static const enum omap_plane_id plane_idx_to_id[] = {
>  	OMAP_DSS_GFX,
>  	OMAP_DSS_VIDEO1,
> @@ -272,7 +265,7 @@ struct drm_plane *omap_plane_init(struct drm_device
> *dev,
> 
>  	id = plane_idx_to_id[idx];
> 
> -	DBG("%s: type=%d", plane_id_to_name[id], type);
> +	DBG("%s: type=%d", priv->dispc_ops->ovl_name(priv->dispc, id), type);
> 
>  	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
>  	if (!omap_plane)
> @@ -282,7 +275,7 @@ struct drm_plane *omap_plane_init(struct drm_device
> *dev, for (nformats = 0; formats[nformats]; ++nformats)
>  		;
>  	omap_plane->id = id;
> -	omap_plane->name = plane_id_to_name[id];
> +	omap_plane->name = priv->dispc_ops->ovl_name(priv->dispc, id);

Same here, we could cache the name.

> 
>  	plane = &omap_plane->base;
> 
> @@ -301,7 +294,7 @@ struct drm_plane *omap_plane_init(struct drm_device
> *dev,
> 
>  error:
>  	dev_err(dev->dev, "%s(): could not create plane: %s\n",
> -		__func__, plane_id_to_name[id]);
> +		__func__, priv->dispc_ops->ovl_name(priv->dispc, id));

You could use omap_plane->name here.

> 
>  	kfree(omap_plane);
>  	return NULL;

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h
  2018-02-16 11:25 ` [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h Jyri Sarha
  2018-02-19 12:06   ` Tomi Valkeinen
@ 2018-02-27 14:42   ` Laurent Pinchart
  1 sibling, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:42 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Jyri,

Thank you for the patch.

On Friday, 16 February 2018 13:25:06 EET Jyri Sarha wrote:
> The new DSS6 driver needs some structs and defines which are currently
> in dss.h, which is for the old DSS driver.
> 
> Move the required structs and defines from dss.h to omapdss.h.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/dss.h     | 41 ++-----------------------------
>  drivers/gpu/drm/omapdrm/dss/omapdss.h | 37 +++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h
> b/drivers/gpu/drm/omapdrm/dss/dss.h index 434262a..fa206ca 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.h
> @@ -70,14 +70,6 @@ struct seq_file;
>  	pr_warn("omapdss: " format, ##__VA_ARGS__)
>  #endif
> 
> -/* OMAP TRM gives bitfields as start:end, where start is the higher bit
> -   number. For example 7:0 */
> -#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << 
(end))
> -#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
> -#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
> -#define FLD_MOD(orig, val, start, end) \
> -	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
> -
>  enum dss_model {
>  	DSS_MODEL_OMAP2,
>  	DSS_MODEL_OMAP3,
> @@ -86,12 +78,6 @@ enum dss_model {
>  	DSS_MODEL_DRA7,
>  };
> 
> -enum dss_io_pad_mode {
> -	DSS_IO_PAD_MODE_RESET,
> -	DSS_IO_PAD_MODE_RFBI,
> -	DSS_IO_PAD_MODE_BYPASS,
> -};
> -
>  enum dss_hdmi_venc_clk_source_select {
>  	DSS_VENC_TV_CLK = 0,
>  	DSS_HDMI_M_PCLK = 1,
> @@ -215,34 +201,11 @@ struct dss_reg_field {
>  	u8 start, end;
>  };
> 
> -struct dispc_clock_info {
> -	/* rates that we get with dividers below */
> -	unsigned long lck;
> -	unsigned long pck;
> -
> -	/* dividers */
> -	u16 lck_div;
> -	u16 pck_div;
> -};
> -
> -struct dss_lcd_mgr_config {
> -	enum dss_io_pad_mode io_pad_mode;
> -
> -	bool stallmode;
> -	bool fifohandcheck;
> -
> -	struct dispc_clock_info clock_info;
> -
> -	int video_port_width;
> -
> -	int lcden_sig_polarity;
> -};
> -
> -#define DSS_SZ_REGS			SZ_512
> +#define DSS_SZ_REGS                    SZ_512
> 
>  struct dss_device {
>  	struct platform_device *pdev;
> -	void __iomem    *base;
> +	void __iomem	*base;
>  	struct regmap	*syscon_pll_ctrl;
>  	u32		syscon_pll_ctrl_offset;
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 493237e..9d789c2 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -647,6 +647,43 @@ static inline bool omapdss_device_is_enabled(struct
> omap_dss_device *dssdev) struct omap_dss_device *
>  omapdss_of_find_source_for_first_ep(struct device_node *node);
> 
> +/* OMAP TRM gives bitfields as start:end, where start is the higher bit
> +   number. For example 7:0 */
> +#define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << 
(end))

While at it would it make sense to use GENMASK to implement this ?

> +#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
> +#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
> +#define FLD_MOD(orig, val, start, end) \
> +	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
> +
> +enum dss_io_pad_mode {
> +	DSS_IO_PAD_MODE_RESET,
> +	DSS_IO_PAD_MODE_RFBI,
> +	DSS_IO_PAD_MODE_BYPASS,
> +};
> +
> +struct dispc_clock_info {
> +	/* rates that we get with dividers below */
> +	unsigned long lck;
> +	unsigned long pck;
> +
> +	/* dividers */
> +	u16 lck_div;
> +	u16 pck_div;
> +};

I think we should start documenting the common structures and enums with 
kerneldoc. omapdss.h and dss.h are a bit of a mess, let's try to make them 
readable :-)

> +struct dss_lcd_mgr_config {
> +	enum dss_io_pad_mode io_pad_mode;
> +
> +	bool stallmode;
> +	bool fifohandcheck;
> +
> +	struct dispc_clock_info clock_info;
> +
> +	int video_port_width;
> +
> +	int lcden_sig_polarity;
> +};
> +
>  struct device_node *dss_of_port_get_parent_device(struct device_node
> *port);
>  u32 dss_of_port_get_port_number(struct device_node *port);

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe
  2018-02-16 11:25 ` [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe Jyri Sarha
@ 2018-02-27 14:46   ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:46 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Jyri,

Thank you for the patch.

On Friday, 16 February 2018 13:25:07 EET Jyri Sarha wrote:
> Register the omapdrm device when we know that dss device probe going
> to succeed. This avoids DSS6 and DSS2 omapdrm device registration from
> colliding with each other.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/core.c | 26 ++------------------------
>  drivers/gpu/drm/omapdrm/dss/dss.c  | 19 +++++++++++++++++++
>  2 files changed, 21 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/core.c
> b/drivers/gpu/drm/omapdrm/dss/core.c index acef7ec..6c9f667 100644
> --- a/drivers/gpu/drm/omapdrm/dss/core.c
> +++ b/drivers/gpu/drm/omapdrm/dss/core.c
> @@ -45,36 +45,14 @@ static struct platform_driver * const omap_dss_drivers[]
> = { #endif
>  };
> 
> -static struct platform_device *omap_drm_device;
> -
>  static int __init omap_dss_init(void)
>  {
> -	int r;
> -
> -	r = platform_register_drivers(omap_dss_drivers,
> -				      ARRAY_SIZE(omap_dss_drivers));
> -	if (r)
> -		goto err_reg;
> -
> -	omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
> -	if (IS_ERR(omap_drm_device)) {
> -		r = PTR_ERR(omap_drm_device);
> -		goto err_reg;
> -	}
> -
> -	return 0;
> -
> -err_reg:
> -	platform_unregister_drivers(omap_dss_drivers,
> -				    ARRAY_SIZE(omap_dss_drivers));
> -
> -	return r;
> +	return platform_register_drivers(omap_dss_drivers,
> +					 ARRAY_SIZE(omap_dss_drivers));
>  }
> 
>  static void __exit omap_dss_exit(void)
>  {
> -	platform_device_unregister(omap_drm_device);
> -
>  	platform_unregister_drivers(omap_dss_drivers,
>  				    ARRAY_SIZE(omap_dss_drivers));
>  }
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c
> b/drivers/gpu/drm/omapdrm/dss/dss.c index 5752328..dda3237 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.c
> @@ -1314,6 +1314,17 @@ static const struct soc_device_attribute
> dss_soc_devices[] = { { /* sentinel */ }
>  };
> 
> +static struct platform_device *omap_drm_device;

Let's store this in the dss_device structure instead of adding a new global 
variable. I've spent enough time chasing the globals, I don't want any new one 
:-)

> +static int initialize_omapdrm_device(void)
> +{
> +	omap_drm_device = platform_device_register_simple("omapdrm", 0, NULL, 0);
> +	if (IS_ERR(omap_drm_device))
> +		return PTR_ERR(omap_drm_device);
> +
> +	return 0;
> +}
> +
>  static int dss_bind(struct device *dev)
>  {
>  	struct dss_device *dss = dev_get_drvdata(dev);
> @@ -1323,6 +1334,12 @@ static int dss_bind(struct device *dev)
>  	if (r)
>  		return r;
> 
> +	r = initialize_omapdrm_device();
> +	if (r) {
> +		component_unbind_all(dev, NULL);
> +		return r;
> +	}
> +

Should this be called after omapdss_gather_components() and omapdss_set_dss() 
to make sure the omapdrm probe won't be deferred by the DSS not being 
initialized ?

>  	pm_set_vt_switch(0);
> 
>  	omapdss_gather_components(dev);
> @@ -1335,6 +1352,8 @@ static void dss_unbind(struct device *dev)
>  {
>  	omapdss_set_dss(NULL);
> 
> +	platform_device_unregister(omap_drm_device);
> +

Same here, should this be called before omapdss_set_dss() for symmetry ?

>  	component_unbind_all(dev, NULL);
>  }

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c
  2018-02-16 11:25 ` [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c Jyri Sarha
@ 2018-02-27 14:48   ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-27 14:48 UTC (permalink / raw)
  To: Jyri Sarha; +Cc: tomi.valkeinen, dri-devel

Hi Jyri,

Thank you for the patch.

On Friday, 16 February 2018 13:25:08 EET Jyri Sarha wrote:
> The core.c just for registering the drivers is kind of useless. Let's
> get rid of it and register the dss drivers in dss.c.
> 
> Signed-off-by: Jyri Sarha <jsarha@ti.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/dss/Makefile |  2 +-
>  drivers/gpu/drm/omapdrm/dss/core.c   | 66 ---------------------------------
>  drivers/gpu/drm/omapdrm/dss/dss.c    | 37 ++++++++++++++++++++
>  3 files changed, 38 insertions(+), 67 deletions(-)
>  delete mode 100644 drivers/gpu/drm/omapdrm/dss/core.c
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile
> b/drivers/gpu/drm/omapdrm/dss/Makefile index 904101c..5950c3f 100644
> --- a/drivers/gpu/drm/omapdrm/dss/Makefile
> +++ b/drivers/gpu/drm/omapdrm/dss/Makefile
> @@ -6,7 +6,7 @@ omapdss-base-y := base.o display.o dss-of.o output.o
> 
>  obj-$(CONFIG_OMAP2_DSS) += omapdss.o
>  # Core DSS files
> -omapdss-y := core.o dss.o dispc.o dispc_coefs.o \
> +omapdss-y := dss.o dispc.o dispc_coefs.o \
>  	pll.o video-pll.o
>  omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
>  omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
> diff --git a/drivers/gpu/drm/omapdrm/dss/core.c
> b/drivers/gpu/drm/omapdrm/dss/core.c deleted file mode 100644
> index 6c9f667..0000000
> --- a/drivers/gpu/drm/omapdrm/dss/core.c
> +++ /dev/null
> @@ -1,66 +0,0 @@
> -/*
> - * Copyright (C) 2009 Nokia Corporation
> - * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
> - *
> - * Some code and ideas taken from drivers/video/omap/ driver
> - * by Imre Deak.
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License version 2 as published
> by
> - * the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> WITHOUT
> - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> for
> - * more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> with
> - * this program.  If not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#define DSS_SUBSYS_NAME "CORE"
> -
> -#include <linux/kernel.h>
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -
> -#include "omapdss.h"
> -#include "dss.h"
> -
> -/* INIT */
> -static struct platform_driver * const omap_dss_drivers[] = {
> -	&omap_dsshw_driver,
> -	&omap_dispchw_driver,
> -#ifdef CONFIG_OMAP2_DSS_DSI
> -	&omap_dsihw_driver,
> -#endif
> -#ifdef CONFIG_OMAP2_DSS_VENC
> -	&omap_venchw_driver,
> -#endif
> -#ifdef CONFIG_OMAP4_DSS_HDMI
> -	&omapdss_hdmi4hw_driver,
> -#endif
> -#ifdef CONFIG_OMAP5_DSS_HDMI
> -	&omapdss_hdmi5hw_driver,
> -#endif
> -};
> -
> -static int __init omap_dss_init(void)
> -{
> -	return platform_register_drivers(omap_dss_drivers,
> -					 ARRAY_SIZE(omap_dss_drivers));
> -}
> -
> -static void __exit omap_dss_exit(void)
> -{
> -	platform_unregister_drivers(omap_dss_drivers,
> -				    ARRAY_SIZE(omap_dss_drivers));
> -}
> -
> -module_init(omap_dss_init);
> -module_exit(omap_dss_exit);
> -
> -MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
> -MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
> -MODULE_LICENSE("GPL v2");
> -
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c
> b/drivers/gpu/drm/omapdrm/dss/dss.c index dda3237..162fa3a 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.c
> @@ -1619,3 +1619,40 @@ struct platform_driver omap_dsshw_driver = {
>  		.suppress_bind_attrs = true,
>  	},
>  };
> +
> +/* INIT */
> +static struct platform_driver * const omap_dss_drivers[] = {
> +	&omap_dsshw_driver,
> +	&omap_dispchw_driver,
> +#ifdef CONFIG_OMAP2_DSS_DSI
> +	&omap_dsihw_driver,
> +#endif
> +#ifdef CONFIG_OMAP2_DSS_VENC
> +	&omap_venchw_driver,
> +#endif
> +#ifdef CONFIG_OMAP4_DSS_HDMI
> +	&omapdss_hdmi4hw_driver,
> +#endif
> +#ifdef CONFIG_OMAP5_DSS_HDMI
> +	&omapdss_hdmi5hw_driver,
> +#endif
> +};
> +
> +static int __init omap_dss_init(void)
> +{
> +	return platform_register_drivers(omap_dss_drivers,
> +					 ARRAY_SIZE(omap_dss_drivers));
> +}
> +
> +static void __exit omap_dss_exit(void)
> +{
> +	platform_unregister_drivers(omap_dss_drivers,
> +				    ARRAY_SIZE(omap_dss_drivers));
> +}
> +
> +module_init(omap_dss_init);
> +module_exit(omap_dss_exit);
> +
> +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
> +MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
> +MODULE_LICENSE("GPL v2");

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-27 14:35   ` Laurent Pinchart
@ 2018-02-28 11:37     ` Tomi Valkeinen
  2018-02-28 13:23       ` Laurent Pinchart
  0 siblings, 1 reply; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-28 11:37 UTC (permalink / raw)
  To: Laurent Pinchart, Jyri Sarha; +Cc: dri-devel

On 27/02/18 16:35, Laurent Pinchart wrote:

> the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ 
> handling to the DSS side, as they're not DRM/KMS-related ?

I think we should react to both errors somehow (I'm not sure how,
disable output probably), and that has to be done on the KMS level. We
don't do that now, but moving this to DSS side would make error handling
more difficult to do in the future.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-28 11:37     ` Tomi Valkeinen
@ 2018-02-28 13:23       ` Laurent Pinchart
  2018-02-28 14:05         ` Tomi Valkeinen
  0 siblings, 1 reply; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-28 13:23 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: dri-devel, Jyri Sarha

Hi Tomi,

On Wednesday, 28 February 2018 13:37:48 EET Tomi Valkeinen wrote:
> On 27/02/18 16:35, Laurent Pinchart wrote:
> > the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ
> > handling to the DSS side, as they're not DRM/KMS-related ?
> 
> I think we should react to both errors somehow (I'm not sure how,
> disable output probably), and that has to be done on the KMS level. We
> don't do that now, but moving this to DSS side would make error handling
> more difficult to do in the future.

Ideally I'd demultiplex interrupts on the DSS side and report events to the 
KMS side (page flip completion, underflows, ...).

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-28 13:23       ` Laurent Pinchart
@ 2018-02-28 14:05         ` Tomi Valkeinen
  2018-02-28 14:24           ` Laurent Pinchart
  0 siblings, 1 reply; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-28 14:05 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, Jyri Sarha

On 28/02/18 15:23, Laurent Pinchart wrote:
> Hi Tomi,
> 
> On Wednesday, 28 February 2018 13:37:48 EET Tomi Valkeinen wrote:
>> On 27/02/18 16:35, Laurent Pinchart wrote:
>>> the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ
>>> handling to the DSS side, as they're not DRM/KMS-related ?
>>
>> I think we should react to both errors somehow (I'm not sure how,
>> disable output probably), and that has to be done on the KMS level. We
>> don't do that now, but moving this to DSS side would make error handling
>> more difficult to do in the future.
> 
> Ideally I'd demultiplex interrupts on the DSS side and report events to the 
> KMS side (page flip completion, underflows, ...).

That's more or less what Jyri's "drm/omap: Make omapdss API more
generic" does, isn't it? Or what is the difference with interrupt and
event in your mind? Function calls vs status bits?

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-28 14:05         ` Tomi Valkeinen
@ 2018-02-28 14:24           ` Laurent Pinchart
  2018-02-28 14:31             ` Tomi Valkeinen
  0 siblings, 1 reply; 26+ messages in thread
From: Laurent Pinchart @ 2018-02-28 14:24 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: dri-devel, Jyri Sarha

Hi Tomi,

On Wednesday, 28 February 2018 16:05:34 EET Tomi Valkeinen wrote:
> On 28/02/18 15:23, Laurent Pinchart wrote:
> > On Wednesday, 28 February 2018 13:37:48 EET Tomi Valkeinen wrote:
> >> On 27/02/18 16:35, Laurent Pinchart wrote:
> >>> the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ
> >>> handling to the DSS side, as they're not DRM/KMS-related ?
> >> 
> >> I think we should react to both errors somehow (I'm not sure how,
> >> disable output probably), and that has to be done on the KMS level. We
> >> don't do that now, but moving this to DSS side would make error handling
> >> more difficult to do in the future.
> > 
> > Ideally I'd demultiplex interrupts on the DSS side and report events to
> > the KMS side (page flip completion, underflows, ...).
> 
> That's more or less what Jyri's "drm/omap: Make omapdss API more
> generic" does, isn't it? Or what is the difference with interrupt and
> event in your mind? Function calls vs status bits?

Yes, that's the difference in my mind. I'd keep the status bits on the DSS 
side. We don't have to implement one callback function for each status bit, we 
could translate them into abstract event bits that are not specific to a 
particular DSS version. What I'd like to avoid is omapdrm calling into omapdss 
to retrieve a name for a bit that is DSS-specific. If we want hardware names 
in debug messages I think they should be printed on the omapdss side, and if 
we want to handle status bits on the omapdrm side they shouldn't require 
hardware names.

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops
  2018-02-28 14:24           ` Laurent Pinchart
@ 2018-02-28 14:31             ` Tomi Valkeinen
  0 siblings, 0 replies; 26+ messages in thread
From: Tomi Valkeinen @ 2018-02-28 14:31 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, Jyri Sarha



On 28/02/18 16:24, Laurent Pinchart wrote:
> Hi Tomi,
> 
> On Wednesday, 28 February 2018 16:05:34 EET Tomi Valkeinen wrote:
>> On 28/02/18 15:23, Laurent Pinchart wrote:
>>> On Wednesday, 28 February 2018 13:37:48 EET Tomi Valkeinen wrote:
>>>> On 27/02/18 16:35, Laurent Pinchart wrote:
>>>>> the whole omap_irq_fifo_underflow() and omap_irq_ocp_error_handler() IRQ
>>>>> handling to the DSS side, as they're not DRM/KMS-related ?
>>>>
>>>> I think we should react to both errors somehow (I'm not sure how,
>>>> disable output probably), and that has to be done on the KMS level. We
>>>> don't do that now, but moving this to DSS side would make error handling
>>>> more difficult to do in the future.
>>>
>>> Ideally I'd demultiplex interrupts on the DSS side and report events to
>>> the KMS side (page flip completion, underflows, ...).
>>
>> That's more or less what Jyri's "drm/omap: Make omapdss API more
>> generic" does, isn't it? Or what is the difference with interrupt and
>> event in your mind? Function calls vs status bits?
> 
> Yes, that's the difference in my mind. I'd keep the status bits on the DSS 
> side. We don't have to implement one callback function for each status bit, we 
> could translate them into abstract event bits that are not specific to a 
> particular DSS version. What I'd like to avoid is omapdrm calling into omapdss 
> to retrieve a name for a bit that is DSS-specific. If we want hardware names 
> in debug messages I think they should be printed on the omapdss side, and if 
> we want to handle status bits on the omapdrm side they shouldn't require 
> hardware names.

Ok, yes, I see your point, and agree.

Here, I think what's done (after the IRQ change patch) is that we get a
an abstracted bit for the underflow. Omapdrm can map that bit to an
omap_plane, and should get the name from omap_plane, instead of asking
it directly from dispc.

 Tomi

-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2018-02-28 14:31 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-16 11:25 [PATCH RFC 0/9] drm/omap: DSS6 with dynamically allocated objects Jyri Sarha
2018-02-16 11:25 ` [PATCH RFC 1/9] drm/omap: Update omapdss API to allow alternative DSS implementations Jyri Sarha
2018-02-19 12:01   ` Tomi Valkeinen
2018-02-27 14:27     ` Laurent Pinchart
2018-02-16 11:25 ` [PATCH RFC 2/9] drm/omap: Fail probe if irq registration fails Jyri Sarha
2018-02-27 14:27   ` Laurent Pinchart
2018-02-16 11:25 ` [PATCH RFC 3/9] drm/omap: Add ovl_name() and mgr_name() to dispc_ops Jyri Sarha
2018-02-27 14:35   ` Laurent Pinchart
2018-02-28 11:37     ` Tomi Valkeinen
2018-02-28 13:23       ` Laurent Pinchart
2018-02-28 14:05         ` Tomi Valkeinen
2018-02-28 14:24           ` Laurent Pinchart
2018-02-28 14:31             ` Tomi Valkeinen
2018-02-16 11:25 ` [PATCH RFC 4/9] drm/omap: Make omapdss API more generic Jyri Sarha
2018-02-19 12:41   ` Tomi Valkeinen
2018-02-16 11:25 ` [PATCH RFC 5/9] drm/omap: move common stuff from dss.h to omapdss.h Jyri Sarha
2018-02-19 12:06   ` Tomi Valkeinen
2018-02-27 14:42   ` Laurent Pinchart
2018-02-16 11:25 ` [PATCH RFC 6/9] drm/omap: dss: Move platform_device_register from core.c to dss.c probe Jyri Sarha
2018-02-27 14:46   ` Laurent Pinchart
2018-02-16 11:25 ` [PATCH RFC 7/9] drm/omap: dss: platform_register_drivers() to dss.c and remove core.c Jyri Sarha
2018-02-27 14:48   ` Laurent Pinchart
2018-02-16 11:25 ` [PATCH RFC 8/9] drm/omap: add TI DSS6 driver Jyri Sarha
2018-02-16 11:25 ` [PATCH RFC 9/9] drm/omap: boot-init: add k2g-dss Jyri Sarha
2018-02-27 14:15   ` Laurent Pinchart
2018-02-27 14:15     ` Laurent Pinchart

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.