linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 00/15] Armada DRM updates
@ 2014-07-05 10:37 Russell King - ARM Linux
  2014-07-05 10:37 ` [PATCH RFC 01/15] component: fix missed cleanup in case of devres failure Russell King
                   ` (14 more replies)
  0 siblings, 15 replies; 23+ messages in thread
From: Russell King - ARM Linux @ 2014-07-05 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series updates the Armada DRM driver to be more DT friendly
by converting it to the component helper.  This is an incomplete
conversion as we also need to convert the TDA998x as well, hence it
currently retains the existing method of initialisation using the slave
encoder mechanism.  The old mechanism will be removed once the
conversion is complete.

This series includes the component updates (patches 1-3 which have been
recently merged into Greg's driver tree, patch 9 which is scheduled to
be merged) and the recently posted DRM OF helper for encoders (patch 8).
Hence patches 1-3 and 9 are only included for reference purposes.
Please direct comments for patch 8 to the previously posted RFC for
that single patch.

The general idea here is to permit each CRTC device to exist as a
separate device node in DT (as it should be) with all the appropriate
properties such as base address, interrupt and pixel clocks.

The encoders (which may be off-SoC) will be specified separately in DT,
and the connectivity specified via the DT's graph bindings.

The diffstat below is for the entire series, which includes the
component helpre updates and the DRM OF helper.

 .../bindings/drm/armada/marvell,dove-lcd.txt       |  30 +++
 arch/arm/boot/dts/dove.dtsi                        |  14 ++
 drivers/base/component.c                           | 192 +++++++++++++----
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/armada/armada_510.c                |  23 +-
 drivers/gpu/drm/armada/armada_crtc.c               | 188 +++++++++++++++--
 drivers/gpu/drm/armada/armada_crtc.h               |   9 +-
 drivers/gpu/drm/armada/armada_drm.h                |  13 +-
 drivers/gpu/drm/armada/armada_drv.c                | 233 ++++++++++++++-------
 drivers/gpu/drm/drm_of.c                           |  65 ++++++
 include/drm/drm_crtc.h                             |   2 +
 include/drm/drm_of.h                               |  18 ++
 include/linux/component.h                          |   7 +
 13 files changed, 642 insertions(+), 153 deletions(-)

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

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

* [PATCH RFC 01/15] component: fix missed cleanup in case of devres failure
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
@ 2014-07-05 10:37 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 02/15] component: ignore multiple additions of the same component Russell King
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

In try_to_bring_up_master(), we tear down the master's component list
for each error case, except for devres group failure.  Fix this
oversight by making the code less prone to such mistakes.

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 62 ++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index c4778995cd72..d0ebd4431736 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -113,44 +113,44 @@ static void master_remove_components(struct master *master)
 static int try_to_bring_up_master(struct master *master,
 	struct component *component)
 {
-	int ret = 0;
+	int ret;
 
-	if (!master->bound) {
-		/*
-		 * Search the list of components, looking for components that
-		 * belong to this master, and attach them to the master.
-		 */
-		if (master->ops->add_components(master->dev, master)) {
-			/* Failed to find all components */
-			master_remove_components(master);
-			ret = 0;
-			goto out;
-		}
+	if (master->bound)
+		return 0;
 
-		if (component && component->master != master) {
-			master_remove_components(master);
-			ret = 0;
-			goto out;
-		}
+	/*
+	 * Search the list of components, looking for components that
+	 * belong to this master, and attach them to the master.
+	 */
+	if (master->ops->add_components(master->dev, master)) {
+		/* Failed to find all components */
+		ret = 0;
+		goto out;
+	}
 
-		if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
-			ret = -ENOMEM;
-			goto out;
-		}
+	if (component && component->master != master) {
+		ret = 0;
+		goto out;
+	}
 
-		/* Found all components */
-		ret = master->ops->bind(master->dev);
-		if (ret < 0) {
-			devres_release_group(master->dev, NULL);
-			dev_info(master->dev, "master bind failed: %d\n", ret);
-			master_remove_components(master);
-			goto out;
-		}
+	if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
-		master->bound = true;
-		ret = 1;
+	/* Found all components */
+	ret = master->ops->bind(master->dev);
+	if (ret < 0) {
+		devres_release_group(master->dev, NULL);
+		dev_info(master->dev, "master bind failed: %d\n", ret);
+		goto out;
 	}
+
+	master->bound = true;
+	return 1;
+
 out:
+	master_remove_components(master);
 
 	return ret;
 }
-- 
1.8.3.1

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

* [PATCH RFC 02/15] component: ignore multiple additions of the same component
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
  2014-07-05 10:37 ` [PATCH RFC 01/15] component: fix missed cleanup in case of devres failure Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 03/15] component: add support for component match array Russell King
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Permit masters to call component_master_add_child() and match the same
child multiple times.  This may happen if there's multiple connections
to a single component device from other devices.  In such scenarios,
we should not return a failure, but instead ignore the attempt.

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index d0ebd4431736..55813e91bf0d 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -69,6 +69,11 @@ static void component_detach_master(struct master *master, struct component *c)
 	c->master = NULL;
 }
 
+/*
+ * Add a component to a master, finding the component via the compare
+ * function and compare data.  This is safe to call for duplicate matches
+ * and will not result in the same component being added multiple times.
+ */
 int component_master_add_child(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data)
 {
@@ -76,11 +81,12 @@ int component_master_add_child(struct master *master,
 	int ret = -ENXIO;
 
 	list_for_each_entry(c, &component_list, node) {
-		if (c->master)
+		if (c->master && c->master != master)
 			continue;
 
 		if (compare(c->dev, compare_data)) {
-			component_attach_master(master, c);
+			if (!c->master)
+				component_attach_master(master, c);
 			ret = 0;
 			break;
 		}
-- 
1.8.3.1

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

* [PATCH RFC 03/15] component: add support for component match array
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
  2014-07-05 10:37 ` [PATCH RFC 01/15] component: fix missed cleanup in case of devres failure Russell King
  2014-07-05 10:38 ` [PATCH RFC 02/15] component: ignore multiple additions of the same component Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 04/15] drm/armada: move IRQ handling into CRTC Russell King
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for generating a set of component matches at master probe
time, and submitting them to the component layer.  This allows the
component layer to perform the matches internally without needing to
call into the master driver, and allows for further restructuring of
the component helper.

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c  | 120 ++++++++++++++++++++++++++++++++++++++++++++--
 include/linux/component.h |   7 +++
 2 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 55813e91bf0d..b4236daed4fa 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -18,6 +18,15 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
+struct component_match {
+	size_t alloc;
+	size_t num;
+	struct {
+		void *data;
+		int (*fn)(struct device *, void *);
+	} compare[0];
+};
+
 struct master {
 	struct list_head node;
 	struct list_head components;
@@ -25,6 +34,7 @@ struct master {
 
 	const struct component_master_ops *ops;
 	struct device *dev;
+	struct component_match *match;
 };
 
 struct component {
@@ -96,6 +106,34 @@ int component_master_add_child(struct master *master,
 }
 EXPORT_SYMBOL_GPL(component_master_add_child);
 
+static int find_components(struct master *master)
+{
+	struct component_match *match = master->match;
+	size_t i;
+	int ret = 0;
+
+	if (!match) {
+		/*
+		 * Search the list of components, looking for components that
+		 * belong to this master, and attach them to the master.
+		 */
+		return master->ops->add_components(master->dev, master);
+	}
+
+	/*
+	 * Scan the array of match functions and attach
+	 * any components which are found to this master.
+	 */
+	for (i = 0; i < match->num; i++) {
+		ret = component_master_add_child(master,
+						 match->compare[i].fn,
+						 match->compare[i].data);
+		if (ret)
+			break;
+	}
+	return ret;
+}
+
 /* Detach all attached components from this master */
 static void master_remove_components(struct master *master)
 {
@@ -128,7 +166,7 @@ static int try_to_bring_up_master(struct master *master,
 	 * Search the list of components, looking for components that
 	 * belong to this master, and attach them to the master.
 	 */
-	if (master->ops->add_components(master->dev, master)) {
+	if (find_components(master)) {
 		/* Failed to find all components */
 		ret = 0;
 		goto out;
@@ -186,18 +224,87 @@ static void take_down_master(struct master *master)
 	master_remove_components(master);
 }
 
-int component_master_add(struct device *dev,
-	const struct component_master_ops *ops)
+static size_t component_match_size(size_t num)
+{
+	return offsetof(struct component_match, compare[num]);
+}
+
+static struct component_match *component_match_realloc(struct device *dev,
+	struct component_match *match, size_t num)
+{
+	struct component_match *new;
+
+	if (match && match->alloc == num)
+		return match;
+
+	new = devm_kmalloc(dev, component_match_size(num), GFP_KERNEL);
+	if (!new)
+		return ERR_PTR(-ENOMEM);
+
+	if (match) {
+		memcpy(new, match, component_match_size(min(match->num, num)));
+		devm_kfree(dev, match);
+	} else {
+		new->num = 0;
+	}
+
+	new->alloc = num;
+
+	return new;
+}
+
+/*
+ * Add a component to be matched.
+ *
+ * The match array is first created or extended if necessary.
+ */
+void component_match_add(struct device *dev, struct component_match **matchptr,
+	int (*compare)(struct device *, void *), void *compare_data)
+{
+	struct component_match *match = *matchptr;
+
+	if (IS_ERR(match))
+		return;
+
+	if (!match || match->num == match->alloc) {
+		size_t new_size = match ? match->alloc + 16 : 15;
+
+		match = component_match_realloc(dev, match, new_size);
+
+		*matchptr = match;
+
+		if (IS_ERR(match))
+			return;
+	}
+
+	match->compare[match->num].fn = compare;
+	match->compare[match->num].data = compare_data;
+	match->num++;
+}
+EXPORT_SYMBOL(component_match_add);
+
+int component_master_add_with_match(struct device *dev,
+	const struct component_master_ops *ops,
+	struct component_match *match)
 {
 	struct master *master;
 	int ret;
 
+	if (ops->add_components && match)
+		return -EINVAL;
+
+	/* Reallocate the match array for its true size */
+	match = component_match_realloc(dev, match, match->num);
+	if (IS_ERR(match))
+		return PTR_ERR(match);
+
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
 		return -ENOMEM;
 
 	master->dev = dev;
 	master->ops = ops;
+	master->match = match;
 	INIT_LIST_HEAD(&master->components);
 
 	/* Add to the list of available masters. */
@@ -215,6 +322,13 @@ int component_master_add(struct device *dev,
 
 	return ret < 0 ? ret : 0;
 }
+EXPORT_SYMBOL_GPL(component_master_add_with_match);
+
+int component_master_add(struct device *dev,
+	const struct component_master_ops *ops)
+{
+	return component_master_add_with_match(dev, ops, NULL);
+}
 EXPORT_SYMBOL_GPL(component_master_add);
 
 void component_master_del(struct device *dev,
diff --git a/include/linux/component.h b/include/linux/component.h
index 68870182ca1e..c00dcc302611 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -29,4 +29,11 @@ void component_master_del(struct device *,
 int component_master_add_child(struct master *master,
 	int (*compare)(struct device *, void *), void *compare_data);
 
+struct component_match;
+
+int component_master_add_with_match(struct device *,
+	const struct component_master_ops *, struct component_match *);
+void component_match_add(struct device *, struct component_match **,
+	int (*compare)(struct device *, void *), void *compare_data);
+
 #endif
-- 
1.8.3.1

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

* [PATCH RFC 04/15] drm/armada: move IRQ handling into CRTC
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 03/15] component: add support for component match array Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 05/15] drm/armada: use number of CRTCs registered Russell King
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c | 36 +++++++++++++++++--
 drivers/gpu/drm/armada/armada_crtc.h |  4 +--
 drivers/gpu/drm/armada/armada_drv.c  | 68 +++++-------------------------------
 3 files changed, 45 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 81c34f949dfc..9341a94cc906 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -349,7 +349,7 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 	return true;
 }
 
-void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
+static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
 	struct armada_vbl_event *e, *n;
 	void __iomem *base = dcrtc->base;
@@ -410,6 +410,27 @@ void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	}
 }
 
+static irqreturn_t armada_drm_irq(int irq, void *arg)
+{
+	struct armada_crtc *dcrtc = arg;
+	u32 v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
+
+	/*
+	 * This is rediculous - rather than writing bits to clear, we
+	 * have to set the actual status register value.  This is racy.
+	 */
+	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
+
+	/* Mask out those interrupts we haven't enabled */
+	v = stat & dcrtc->irq_ena;
+
+	if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
+		armada_drm_crtc_irq(dcrtc, stat);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
 /* These are locked by dev->vbl_lock */
 void armada_drm_crtc_disable_irq(struct armada_crtc *dcrtc, u32 mask)
 {
@@ -888,6 +909,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
 	if (!IS_ERR(dcrtc->clk))
 		clk_disable_unprepare(dcrtc->clk);
 
+	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
+
 	kfree(dcrtc);
 }
 
@@ -1028,7 +1051,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 }
 
 int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
-	struct resource *res)
+	struct resource *res, int irq)
 {
 	struct armada_private *priv = dev->dev_private;
 	struct armada_crtc *dcrtc;
@@ -1074,6 +1097,15 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
 		       CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
 	writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
 	writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN);
+	writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
+	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
+
+	ret = devm_request_irq(dev, irq, armada_drm_irq, 0, "armada_drm_crtc",
+			       dcrtc);
+	if (ret < 0) {
+		kfree(dcrtc);
+		return ret;
+	}
 
 	if (priv->variant->crtc_init) {
 		ret = priv->variant->crtc_init(dcrtc);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 9c10a07e7492..0e952b271212 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -72,10 +72,10 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *);
+int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *,
+	int);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
-void armada_drm_crtc_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_enable_irq(struct armada_crtc *, u32);
 void armada_drm_crtc_update_regs(struct armada_crtc *, struct armada_regs *);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 8ab3cd1a8cdb..58884d807e6c 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -155,10 +155,16 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 
 	/* Create all LCD controllers */
 	for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
+		int irq;
+
 		if (!res[n])
 			break;
 
-		ret = armada_drm_crtc_create(dev, n, res[n]);
+		irq = platform_get_irq(dev->platformdev, n);
+		if (irq < 0)
+			goto err_kms;
+
+		ret = armada_drm_crtc_create(dev, n, res[n], irq);
 		if (ret)
 			goto err_kms;
 	}
@@ -173,22 +179,16 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	if (ret)
 		goto err_kms;
 
-	ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
-	if (ret)
-		goto err_kms;
-
 	dev->vblank_disable_allowed = 1;
 
 	ret = armada_fbdev_init(dev);
 	if (ret)
-		goto err_irq;
+		goto err_kms;
 
 	drm_kms_helper_poll_init(dev);
 
 	return 0;
 
- err_irq:
-	drm_irq_uninstall(dev);
  err_kms:
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
@@ -203,7 +203,6 @@ static int armada_drm_unload(struct drm_device *dev)
 
 	drm_kms_helper_poll_fini(dev);
 	armada_fbdev_fini(dev);
-	drm_irq_uninstall(dev);
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
 	flush_work(&priv->fb_unref_work);
@@ -259,52 +258,6 @@ static void armada_drm_disable_vblank(struct drm_device *dev, int crtc)
 	armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
 }
 
-static irqreturn_t armada_drm_irq_handler(int irq, void *arg)
-{
-	struct drm_device *dev = arg;
-	struct armada_private *priv = dev->dev_private;
-	struct armada_crtc *dcrtc = priv->dcrtc[0];
-	uint32_t v, stat = readl_relaxed(dcrtc->base + LCD_SPU_IRQ_ISR);
-	irqreturn_t handled = IRQ_NONE;
-
-	/*
-	 * This is rediculous - rather than writing bits to clear, we
-	 * have to set the actual status register value.  This is racy.
-	 */
-	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
-
-	/* Mask out those interrupts we haven't enabled */
-	v = stat & dcrtc->irq_ena;
-
-	if (v & (VSYNC_IRQ|GRA_FRAME_IRQ|DUMB_FRAMEDONE)) {
-		armada_drm_crtc_irq(dcrtc, stat);
-		handled = IRQ_HANDLED;
-	}
-
-	return handled;
-}
-
-static int armada_drm_irq_postinstall(struct drm_device *dev)
-{
-	struct armada_private *priv = dev->dev_private;
-	struct armada_crtc *dcrtc = priv->dcrtc[0];
-
-	spin_lock_irq(&dev->vbl_lock);
-	writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
-	writel(0, dcrtc->base + LCD_SPU_IRQ_ISR);
-	spin_unlock_irq(&dev->vbl_lock);
-
-	return 0;
-}
-
-static void armada_drm_irq_uninstall(struct drm_device *dev)
-{
-	struct armada_private *priv = dev->dev_private;
-	struct armada_crtc *dcrtc = priv->dcrtc[0];
-
-	writel(0, dcrtc->base + LCD_SPU_IRQ_ENA);
-}
-
 static struct drm_ioctl_desc armada_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,
 		DRM_UNLOCKED),
@@ -340,9 +293,6 @@ static struct drm_driver armada_drm_driver = {
 	.get_vblank_counter	= drm_vblank_count,
 	.enable_vblank		= armada_drm_enable_vblank,
 	.disable_vblank		= armada_drm_disable_vblank,
-	.irq_handler		= armada_drm_irq_handler,
-	.irq_postinstall	= armada_drm_irq_postinstall,
-	.irq_uninstall		= armada_drm_irq_uninstall,
 #ifdef CONFIG_DEBUG_FS
 	.debugfs_init		= armada_drm_debugfs_init,
 	.debugfs_cleanup	= armada_drm_debugfs_cleanup,
@@ -362,7 +312,7 @@ static struct drm_driver armada_drm_driver = {
 	.desc			= "Armada SoC DRM",
 	.date			= "20120730",
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET |
-				  DRIVER_HAVE_IRQ | DRIVER_PRIME,
+				  DRIVER_PRIME,
 	.ioctls			= armada_ioctls,
 	.fops			= &armada_drm_fops,
 };
-- 
1.8.3.1

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

* [PATCH RFC 05/15] drm/armada: use number of CRTCs registered
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (3 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 04/15] drm/armada: move IRQ handling into CRTC Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init Russell King
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Use the number of CRTCs registered to size the vblank arrays rather than
our own count.  Number CRTCs using this as well.  This permits us to
register CRTCs as components in the near future rather than as part of a
single device.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c | 6 +++---
 drivers/gpu/drm/armada/armada_crtc.h | 3 +--
 drivers/gpu/drm/armada/armada_drv.c  | 4 ++--
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 9341a94cc906..4336dfd3585d 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1050,8 +1050,8 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 	return 0;
 }
 
-int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
-	struct resource *res, int irq)
+int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
+	int irq)
 {
 	struct armada_private *priv = dev->dev_private;
 	struct armada_crtc *dcrtc;
@@ -1075,7 +1075,7 @@ int armada_drm_crtc_create(struct drm_device *dev, unsigned num,
 	}
 
 	dcrtc->base = base;
-	dcrtc->num = num;
+	dcrtc->num = dev->mode_config.num_crtc;
 	dcrtc->clk = ERR_PTR(-EINVAL);
 	dcrtc->csc_yuv_mode = CSC_AUTO;
 	dcrtc->csc_rgb_mode = CSC_AUTO;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 0e952b271212..531a9b0bdcfb 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -72,8 +72,7 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-int armada_drm_crtc_create(struct drm_device *, unsigned, struct resource *,
-	int);
+int armada_drm_crtc_create(struct drm_device *, struct resource *, int);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 58884d807e6c..add8b101fa9e 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -164,7 +164,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 		if (irq < 0)
 			goto err_kms;
 
-		ret = armada_drm_crtc_create(dev, n, res[n], irq);
+		ret = armada_drm_crtc_create(dev, res[n], irq);
 		if (ret)
 			goto err_kms;
 	}
@@ -175,7 +175,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 		goto err_kms;
 #endif
 
-	ret = drm_vblank_init(dev, n);
+	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret)
 		goto err_kms;
 
-- 
1.8.3.1

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (4 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 05/15] drm/armada: use number of CRTCs registered Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 11:58   ` Sebastian Hesselbarth
  2014-07-05 10:38 ` [PATCH RFC 07/15] drm/armada: make variant a CRTC thing Russell King
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Move the variant initialisation entirely to the CRTC init function -
the variant support is really about the CRTC properties than the whole
system, and we want to treat each CRTC individually when we support DT.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_510.c  | 19 ++++++++-----------
 drivers/gpu/drm/armada/armada_crtc.c |  2 +-
 drivers/gpu/drm/armada/armada_crtc.h |  1 +
 drivers/gpu/drm/armada/armada_drm.h  |  6 ++----
 drivers/gpu/drm/armada/armada_drv.c  |  4 ----
 5 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index 59948eff6095..a9dabcaef92e 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -15,20 +15,19 @@
 #include "armada_drm.h"
 #include "armada_hw.h"
 
-static int armada510_init(struct armada_private *priv, struct device *dev)
+static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
 {
-	priv->extclk[0] = devm_clk_get(dev, "ext_ref_clk_1");
+	struct clk *clk;
 
-	if (IS_ERR(priv->extclk[0]) && PTR_ERR(priv->extclk[0]) == -ENOENT)
-		priv->extclk[0] = ERR_PTR(-EPROBE_DEFER);
+	clk = devm_clk_get(dev, "ext_ref_clk_1");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER : PTR_ERR(clk);
 
-	return PTR_RET(priv->extclk[0]);
-}
+	dcrtc->extclk[0] = clk;
 
-static int armada510_crtc_init(struct armada_crtc *dcrtc)
-{
 	/* Lower the watermark so to eliminate jitter at higher bandwidths */
 	armada_updatel(0x20, (1 << 11) | 0xff, dcrtc->base + LCD_CFG_RDREG4F);
+
 	return 0;
 }
 
@@ -45,8 +44,7 @@ static int armada510_crtc_init(struct armada_crtc *dcrtc)
 static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
 	const struct drm_display_mode *mode, uint32_t *sclk)
 {
-	struct armada_private *priv = dcrtc->crtc.dev->dev_private;
-	struct clk *clk = priv->extclk[0];
+	struct clk *clk = dcrtc->extclk[0];
 	int ret;
 
 	if (dcrtc->num == 1)
@@ -81,7 +79,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
 const struct armada_variant armada510_ops = {
 	.has_spu_adv_reg = true,
 	.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
-	.init = armada510_init,
 	.crtc_init = armada510_crtc_init,
 	.crtc_compute_clock = armada510_crtc_compute_clock,
 };
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 4336dfd3585d..3adddabc3626 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1108,7 +1108,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 	}
 
 	if (priv->variant->crtc_init) {
-		ret = priv->variant->crtc_init(dcrtc);
+		ret = priv->variant->crtc_init(dcrtc, dev->dev);
 		if (ret) {
 			kfree(dcrtc);
 			return ret;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 531a9b0bdcfb..3f0e70bb2e9c 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -38,6 +38,7 @@ struct armada_crtc {
 	unsigned		num;
 	void __iomem		*base;
 	struct clk		*clk;
+	struct clk		*extclk[2];
 	struct {
 		uint32_t	spu_v_h_total;
 		uint32_t	spu_v_porch;
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index a72cae03b99b..a5452ae883d1 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -59,10 +59,9 @@ void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *,
 struct armada_private;
 
 struct armada_variant {
-	bool	has_spu_adv_reg;
+	bool has_spu_adv_reg;
 	uint32_t spu_adv_reg;
-	int (*init)(struct armada_private *, struct device *);
-	int (*crtc_init)(struct armada_crtc *);
+	int (*crtc_init)(struct armada_crtc *, struct device *);
 	int (*crtc_compute_clock)(struct armada_crtc *,
 				  const struct drm_display_mode *,
 				  uint32_t *);
@@ -78,7 +77,6 @@ struct armada_private {
 	struct drm_fb_helper	*fbdev;
 	struct armada_crtc	*dcrtc[2];
 	struct drm_mm		linear;
-	struct clk		*extclk[2];
 	struct drm_property	*csc_yuv_prop;
 	struct drm_property	*csc_rgb_prop;
 	struct drm_property	*colorkey_prop;
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index add8b101fa9e..4939a86a2afc 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -130,10 +130,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 
 	priv->variant = (struct armada_variant *)id->driver_data;
 
-	ret = priv->variant->init(priv, dev->dev);
-	if (ret)
-		return ret;
-
 	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
 	INIT_KFIFO(priv->fb_unref);
 
-- 
1.8.3.1

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

* [PATCH RFC 07/15] drm/armada: make variant a CRTC thing
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (5 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 08/15] drm: add of_graph endpoint helper to find possible CRTCs Russell King
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Move the variant pointer into the armada_crtc structure, and update for
the resulting changes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_510.c  |  4 ++--
 drivers/gpu/drm/armada/armada_crtc.c | 27 ++++++++++++---------------
 drivers/gpu/drm/armada/armada_crtc.h |  5 ++++-
 drivers/gpu/drm/armada/armada_drm.h  |  9 ++++-----
 drivers/gpu/drm/armada/armada_drv.c  |  5 +++--
 5 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index a9dabcaef92e..1bcf1a8c1915 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -79,6 +79,6 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
 const struct armada_variant armada510_ops = {
 	.has_spu_adv_reg = true,
 	.spu_adv_reg = ADV_HWC32ENABLE | ADV_HWC32ARGB | ADV_HWC32BLEND,
-	.crtc_init = armada510_crtc_init,
-	.crtc_compute_clock = armada510_crtc_compute_clock,
+	.init = armada510_crtc_init,
+	.compute_clock = armada510_crtc_compute_clock,
 };
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 3adddabc3626..afa497489000 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -332,17 +332,16 @@ static void armada_drm_crtc_commit(struct drm_crtc *crtc)
 static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 	const struct drm_display_mode *mode, struct drm_display_mode *adj)
 {
-	struct armada_private *priv = crtc->dev->dev_private;
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	int ret;
 
 	/* We can't do interlaced modes if we don't have the SPU_ADV_REG */
-	if (!priv->variant->has_spu_adv_reg &&
+	if (!dcrtc->variant->has_spu_adv_reg &&
 	    adj->flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
 	/* Check whether the display mode is possible */
-	ret = priv->variant->crtc_compute_clock(dcrtc, adj, NULL);
+	ret = dcrtc->variant->compute_clock(dcrtc, adj, NULL);
 	if (ret)
 		return false;
 
@@ -491,7 +490,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	struct drm_display_mode *mode, struct drm_display_mode *adj,
 	int x, int y, struct drm_framebuffer *old_fb)
 {
-	struct armada_private *priv = crtc->dev->dev_private;
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct armada_regs regs[17];
 	uint32_t lm, rm, tm, bm, val, sclk;
@@ -536,7 +534,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	}
 
 	/* Now compute the divider for real */
-	priv->variant->crtc_compute_clock(dcrtc, adj, &sclk);
+	dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
 
 	/* Ensure graphic fifo is enabled */
 	armada_reg_queue_mod(regs, i, 0, CFG_PDWN64x66, LCD_SPU_SRAM_PARA1);
@@ -558,7 +556,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	dcrtc->v[1].spu_v_porch = tm << 16 | bm;
 	val = adj->crtc_hsync_start;
 	dcrtc->v[1].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
-		priv->variant->spu_adv_reg;
+		dcrtc->variant->spu_adv_reg;
 
 	if (interlaced) {
 		/* Odd interlaced frame */
@@ -567,7 +565,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 		dcrtc->v[0].spu_v_porch = dcrtc->v[1].spu_v_porch + 1;
 		val = adj->crtc_hsync_start - adj->crtc_htotal / 2;
 		dcrtc->v[0].spu_adv_reg = val << 20 | val | ADV_VSYNCOFFEN |
-			priv->variant->spu_adv_reg;
+			dcrtc->variant->spu_adv_reg;
 	} else {
 		dcrtc->v[0] = dcrtc->v[1];
 	}
@@ -582,7 +580,7 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 	armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
 			   LCD_SPUT_V_H_TOTAL);
 
-	if (priv->variant->has_spu_adv_reg) {
+	if (dcrtc->variant->has_spu_adv_reg) {
 		armada_reg_queue_mod(regs, i, dcrtc->v[0].spu_adv_reg,
 				     ADV_VSYNC_L_OFF | ADV_VSYNC_H_OFF |
 				     ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
@@ -826,12 +824,11 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_private *priv = crtc->dev->dev_private;
 	struct armada_gem_object *obj = NULL;
 	int ret;
 
 	/* If no cursor support, replicate drm's return value */
-	if (!priv->variant->has_spu_adv_reg)
+	if (!dcrtc->variant->has_spu_adv_reg)
 		return -ENXIO;
 
 	if (handle && w > 0 && h > 0) {
@@ -879,11 +876,10 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 {
 	struct drm_device *dev = crtc->dev;
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
-	struct armada_private *priv = crtc->dev->dev_private;
 	int ret;
 
 	/* If no cursor support, replicate drm's return value */
-	if (!priv->variant->has_spu_adv_reg)
+	if (!dcrtc->variant->has_spu_adv_reg)
 		return -EFAULT;
 
 	mutex_lock(&dev->struct_mutex);
@@ -1051,7 +1047,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 }
 
 int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
-	int irq)
+	int irq, const struct armada_variant *variant)
 {
 	struct armada_private *priv = dev->dev_private;
 	struct armada_crtc *dcrtc;
@@ -1074,6 +1070,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 		return -ENOMEM;
 	}
 
+	dcrtc->variant = variant;
 	dcrtc->base = base;
 	dcrtc->num = dev->mode_config.num_crtc;
 	dcrtc->clk = ERR_PTR(-EINVAL);
@@ -1107,8 +1104,8 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 		return ret;
 	}
 
-	if (priv->variant->crtc_init) {
-		ret = priv->variant->crtc_init(dcrtc, dev->dev);
+	if (dcrtc->variant->init) {
+		ret = dcrtc->variant->init(dcrtc, dev->dev);
 		if (ret) {
 			kfree(dcrtc);
 			return ret;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 3f0e70bb2e9c..73efcfcdf814 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -32,9 +32,11 @@ struct armada_regs {
 	armada_reg_queue_mod(_r, _i, 0, 0, ~0)
 
 struct armada_frame_work;
+struct armada_variant;
 
 struct armada_crtc {
 	struct drm_crtc		crtc;
+	const struct armada_variant *variant;
 	unsigned		num;
 	void __iomem		*base;
 	struct clk		*clk;
@@ -73,7 +75,8 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-int armada_drm_crtc_create(struct drm_device *, struct resource *, int);
+int armada_drm_crtc_create(struct drm_device *, struct resource *, int,
+	const struct armada_variant *);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index a5452ae883d1..ea63c6c7c66f 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -61,17 +61,16 @@ struct armada_private;
 struct armada_variant {
 	bool has_spu_adv_reg;
 	uint32_t spu_adv_reg;
-	int (*crtc_init)(struct armada_crtc *, struct device *);
-	int (*crtc_compute_clock)(struct armada_crtc *,
-				  const struct drm_display_mode *,
-				  uint32_t *);
+	int (*init)(struct armada_crtc *, struct device *);
+	int (*compute_clock)(struct armada_crtc *,
+			     const struct drm_display_mode *,
+			     uint32_t *);
 };
 
 /* Variant ops */
 extern const struct armada_variant armada510_ops;
 
 struct armada_private {
-	const struct armada_variant *variant;
 	struct work_struct	fb_unref_work;
 	DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
 	struct drm_fb_helper	*fbdev;
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 4939a86a2afc..3995be3c686b 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -85,6 +85,7 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
 static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 {
 	const struct platform_device_id *id;
+	const struct armada_variant *variant;
 	struct armada_private *priv;
 	struct resource *res[ARRAY_SIZE(priv->dcrtc)];
 	struct resource *mem = NULL;
@@ -128,7 +129,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	if (!id)
 		return -ENXIO;
 
-	priv->variant = (struct armada_variant *)id->driver_data;
+	variant = (const struct armada_variant *)id->driver_data;
 
 	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
 	INIT_KFIFO(priv->fb_unref);
@@ -160,7 +161,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 		if (irq < 0)
 			goto err_kms;
 
-		ret = armada_drm_crtc_create(dev, res[n], irq);
+		ret = armada_drm_crtc_create(dev, res[n], irq, variant);
 		if (ret)
 			goto err_kms;
 	}
-- 
1.8.3.1

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

* [PATCH RFC 08/15] drm: add of_graph endpoint helper to find possible CRTCs
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (6 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 07/15] drm/armada: make variant a CRTC thing Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 09/15] component: fix bug with legacy API Russell King
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Add a helper to allow encoders to find their possible CRTCs from the
OF graph without having to re-implement this functionality.  We add a
device_node to drm_crtc which corresponds with the port node in the
DT description of the CRTC device.

We can then scan the DRM device list for CRTCs to find their index,
matching the appropriate CRTC using the port device_node, thus building
up the possible CRTC mask.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/Makefile |  1 +
 drivers/gpu/drm/drm_of.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_crtc.h   |  2 ++
 include/drm/drm_of.h     | 18 ++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_of.c
 create mode 100644 include/drm/drm_of.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index dd2ba4269740..533d011eab3e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -20,6 +20,7 @@ drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
 drm-$(CONFIG_PCI) += ati_pcigart.o
 drm-$(CONFIG_DRM_PANEL) += drm_panel.o
+drm-$(CONFIG_OF) += drm_of.o
 
 drm-usb-y   := drm_usb.o
 
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
new file mode 100644
index 000000000000..46d967881689
--- /dev/null
+++ b/drivers/gpu/drm/drm_of.c
@@ -0,0 +1,65 @@
+#include <linux/export.h>
+#include <linux/list.h>
+#include <linux/of_graph.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_of.h>
+
+/**
+ * drm_crtc_port_mask - find the mask of a registered CRTC by port OF node
+ * @dev: DRM device
+ * @port: port OF node
+ *
+ * Given a port OF node, return the possible mask of the corresponding
+ * CRTC within a device's list of CRTCs.  Returns zero if not found.
+ */
+static uint32_t drm_crtc_port_mask(struct drm_device *dev,
+				   struct device_node *port)
+{
+	unsigned int index = 0;
+	struct drm_crtc *tmp;
+
+	list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
+		if (tmp->port == port)
+			return 1 << index;
+
+		index++;
+	}
+
+	return 0;
+}
+
+/**
+ * drm_of_find_possible_crtcs - find the possible CRTCs for an encoder port
+ * @dev: DRM device
+ * @port: encoder port to scan for endpoints
+ *
+ * Scan all endpoints attached to a port, locate their attached CRTCs,
+ * and generate the DRM mask of CRTCs which may be attached to this
+ * encoder.
+ */
+uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
+				    struct device_node *port)
+{
+	struct device_node *remote_port, *ep = NULL;
+	uint32_t possible_crtcs = 0;
+
+	do {
+		ep = of_graph_get_next_endpoint(port, ep);
+		if (!ep)
+			break;
+
+		remote_port = of_graph_get_remote_port(ep);
+		if (!remote_port) {
+			of_node_put(ep);
+			return 0;
+		}
+
+		possible_crtcs |= drm_crtc_port_mask(dev, remote_port);
+
+		of_node_put(remote_port);
+	} while (1);
+
+	return possible_crtcs;
+}
+EXPORT_SYMBOL(drm_of_find_possible_crtcs);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 251b75e6bf7a..6a94909f1ca9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -41,6 +41,7 @@ struct drm_framebuffer;
 struct drm_object_properties;
 struct drm_file;
 struct drm_clip_rect;
+struct device_node;
 
 #define DRM_MODE_OBJECT_CRTC 0xcccccccc
 #define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
@@ -314,6 +315,7 @@ struct drm_crtc_funcs {
  */
 struct drm_crtc {
 	struct drm_device *dev;
+	struct device_node *port;
 	struct list_head head;
 
 	/**
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
new file mode 100644
index 000000000000..2441f7112074
--- /dev/null
+++ b/include/drm/drm_of.h
@@ -0,0 +1,18 @@
+#ifndef __DRM_OF_H__
+#define __DRM_OF_H__
+
+struct drm_device;
+struct device_node;
+
+#ifdef CONFIG_OF
+extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
+					   struct device_node *port);
+#else
+static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
+						  struct device_node *port)
+{
+	return 0;
+}
+#endif
+
+#endif /* __DRM_OF_H__ */
-- 
1.8.3.1

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

* [PATCH RFC 09/15] component: fix bug with legacy API
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (7 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 08/15] drm: add of_graph endpoint helper to find possible CRTCs Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 10/15] drm/armada: convert to componentized support Russell King
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Sachin Kamat reports that "component: add support for component match
array" broke Exynos DRM due to a NULL pointer deref.  Fix this.

Reported-by: Sachin Kamat <sachin.kamat@samsung.com>
Tested-by: Sachin Kamat <sachin.kamat@samsung.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/base/component.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index b4236daed4fa..f748430bb654 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -293,10 +293,12 @@ int component_master_add_with_match(struct device *dev,
 	if (ops->add_components && match)
 		return -EINVAL;
 
-	/* Reallocate the match array for its true size */
-	match = component_match_realloc(dev, match, match->num);
-	if (IS_ERR(match))
-		return PTR_ERR(match);
+	if (match) {
+		/* Reallocate the match array for its true size */
+		match = component_match_realloc(dev, match, match->num);
+		if (IS_ERR(match))
+			return PTR_ERR(match);
+	}
 
 	master = kzalloc(sizeof(*master), GFP_KERNEL);
 	if (!master)
-- 
1.8.3.1

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

* [PATCH RFC 10/15] drm/armada: convert to componentized support
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (8 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 09/15] component: fix bug with legacy API Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 11/15] drm/armada: update Armada 510 (Dove) to use "ext_ref_clk1" as the clock Russell King
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the Armada DRM driver to use the component helpers, which will
permit us to clean up the driver and move towards an implementation
which is compatible with a DT description of the hardware.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_drv.c | 155 ++++++++++++++++++++++++++++++++++--
 1 file changed, 148 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 3995be3c686b..2b6fc6cf62f2 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -6,7 +6,9 @@
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/module.h>
+#include <linux/of_graph.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include "armada_crtc.h"
@@ -52,6 +54,11 @@ static const struct armada_drm_slave_config tda19988_config = {
 };
 #endif
 
+static bool is_componentized(struct device *dev)
+{
+	return dev->of_node || dev->platform_data;
+}
+
 static void armada_drm_unref_work(struct work_struct *work)
 {
 	struct armada_private *priv =
@@ -166,26 +173,35 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 			goto err_kms;
 	}
 
+	if (is_componentized(dev->dev)) {
+		ret = component_bind_all(dev->dev, dev);
+		if (ret)
+			goto err_kms;
+	} else {
 #ifdef CONFIG_DRM_ARMADA_TDA1998X
-	ret = armada_drm_connector_slave_create(dev, &tda19988_config);
-	if (ret)
-		goto err_kms;
+		ret = armada_drm_connector_slave_create(dev, &tda19988_config);
+		if (ret)
+			goto err_kms;
 #endif
+	}
 
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret)
-		goto err_kms;
+		goto err_comp;
 
 	dev->vblank_disable_allowed = 1;
 
 	ret = armada_fbdev_init(dev);
 	if (ret)
-		goto err_kms;
+		goto err_comp;
 
 	drm_kms_helper_poll_init(dev);
 
 	return 0;
 
+ err_comp:
+	if (is_componentized(dev->dev))
+		component_unbind_all(dev->dev, dev);
  err_kms:
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
@@ -200,6 +216,10 @@ static int armada_drm_unload(struct drm_device *dev)
 
 	drm_kms_helper_poll_fini(dev);
 	armada_fbdev_fini(dev);
+
+	if (is_componentized(dev->dev))
+		component_unbind_all(dev->dev, dev);
+
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
 	flush_work(&priv->fb_unref_work);
@@ -314,14 +334,135 @@ static struct drm_driver armada_drm_driver = {
 	.fops			= &armada_drm_fops,
 };
 
+static int armada_drm_bind(struct device *dev)
+{
+	return drm_platform_init(&armada_drm_driver, to_platform_device(dev));
+}
+
+static void armada_drm_unbind(struct device *dev)
+{
+	drm_put_dev(dev_get_drvdata(dev));
+}
+
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static int compare_dev_name(struct device *dev, void *data)
+{
+	const char *name = data;
+	return !strcmp(dev_name(dev), name);
+}
+
+static void armada_add_endpoints(struct device *dev,
+	struct component_match **match, struct device_node *port)
+{
+	struct device_node *ep, *remote;
+
+	for_each_child_of_node(port, ep) {
+		remote = of_graph_get_remote_port_parent(ep);
+		if (!remote || !of_device_is_available(remote)) {
+			of_node_put(remote);
+			continue;
+		} else if (!of_device_is_available(remote->parent)) {
+			dev_warn(dev, "parent device of %s is not available\n",
+				 remote->full_name);
+			of_node_put(remote);
+			continue;
+		}
+
+		component_match_add(dev, match, compare_of, remote);
+		of_node_put(remote);
+	}
+}
+
+static int armada_drm_find_components(struct device *dev,
+	struct component_match **match)
+{
+	struct device_node *port;
+	int i;
+
+	if (dev->of_node) {
+		struct device_node *np = dev->of_node;
+
+		for (i = 0; ; i++) {
+			port = of_parse_phandle(np, "ports", i);
+			if (!port)
+				break;
+
+			component_match_add(dev, match, compare_of, port);
+			of_node_put(port);
+		}
+
+		if (i == 0) {
+			dev_err(dev, "missing 'ports' property\n");
+			return -ENODEV;
+		}
+
+		for (i = 0; ; i++) {
+			port = of_parse_phandle(np, "ports", i);
+			if (!port)
+				break;
+
+			armada_add_endpoints(dev, match, port);
+			of_node_put(port);
+		}
+	} else if (dev->platform_data) {
+		char **devices = dev->platform_data;
+		struct device *d;
+
+		for (i = 0; devices[i]; i++)
+			component_match_add(dev, match, compare_dev_name,
+					    devices[i]);
+
+		if (i == 0) {
+			dev_err(dev, "missing 'ports' property\n");
+			return -ENODEV;
+		}
+
+		for (i = 0; devices[i]; i++) {
+			d = bus_find_device_by_name(&platform_bus_type, NULL,
+					devices[i]);
+			if (d && d->of_node) {
+				for_each_child_of_node(d->of_node, port)
+					armada_add_endpoints(dev, match, port);
+			}
+			put_device(d);
+		}
+	}
+
+	return 0;
+}
+
+static const struct component_master_ops armada_master_ops = {
+	.bind = armada_drm_bind,
+	.unbind = armada_drm_unbind,
+};
+
 static int armada_drm_probe(struct platform_device *pdev)
 {
-	return drm_platform_init(&armada_drm_driver, pdev);
+	if (is_componentized(&pdev->dev)) {
+		struct component_match *match = NULL;
+		int ret;
+
+		ret = armada_drm_find_components(&pdev->dev, &match);
+		if (ret < 0)
+			return ret;
+
+		return component_master_add_with_match(&pdev->dev,
+				&armada_master_ops, match);
+	} else {
+		return drm_platform_init(&armada_drm_driver, pdev);
+	}
 }
 
 static int armada_drm_remove(struct platform_device *pdev)
 {
-	drm_put_dev(platform_get_drvdata(pdev));
+	if (is_componentized(&pdev->dev))
+		component_master_del(&pdev->dev, &armada_master_ops);
+	else
+		drm_put_dev(platform_get_drvdata(pdev));
 	return 0;
 }
 
-- 
1.8.3.1

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

* [PATCH RFC 11/15] drm/armada: update Armada 510 (Dove) to use "ext_ref_clk1" as the clock
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (9 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 10/15] drm/armada: convert to componentized support Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 12/15] dt-bindings: add Marvell Dove LCD controller documentation Russell King
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the underscore between "clk" and "1" so that we match the name
of the clock given in the documentation.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_510.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c
index 1bcf1a8c1915..ad3d2ebf95c9 100644
--- a/drivers/gpu/drm/armada/armada_510.c
+++ b/drivers/gpu/drm/armada/armada_510.c
@@ -19,7 +19,7 @@ static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)
 {
 	struct clk *clk;
 
-	clk = devm_clk_get(dev, "ext_ref_clk_1");
+	clk = devm_clk_get(dev, "ext_ref_clk1");
 	if (IS_ERR(clk))
 		return PTR_ERR(clk) == -ENOENT ? -EPROBE_DEFER : PTR_ERR(clk);
 
-- 
1.8.3.1

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

* [PATCH RFC 12/15] dt-bindings: add Marvell Dove LCD controller documentation
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (10 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 11/15] drm/armada: update Armada 510 (Dove) to use "ext_ref_clk1" as the clock Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:38 ` [PATCH RFC 13/15] drm/armada: permit CRTCs to be registered as separate devices Russell King
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Add the Marvell Dove LCD controller DT binding documentation.  The
clock names used here are intentionally taken from the specification
for the Dove SoC.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 .../bindings/drm/armada/marvell,dove-lcd.txt       | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/armada/marvell,dove-lcd.txt

diff --git a/Documentation/devicetree/bindings/drm/armada/marvell,dove-lcd.txt b/Documentation/devicetree/bindings/drm/armada/marvell,dove-lcd.txt
new file mode 100644
index 000000000000..46525ea3e646
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/armada/marvell,dove-lcd.txt
@@ -0,0 +1,30 @@
+Device Tree bindings for Armada DRM CRTC driver
+
+Required properties:
+ - compatible: value should be "marvell,dove-lcd".
+ - reg: base address and size of the LCD controller
+ - interrupts: single interrupt number for the LCD controller
+ - port: video output port with endpoints, as described by graph.txt
+
+Optional properties:
+
+ - clocks: as described by clock-bindings.txt
+ - clock-names: as described by clock-bindings.txt
+	"axiclk" - axi bus clock for pixel clock
+	"plldivider" - pll divider clock for pixel clock
+	"ext_ref_clk0" - external clock 0 for pixel clock
+	"ext_ref_clk1" - external clock 1 for pixel clock
+
+Note: all clocks are optional but at least one must be specified.
+Further clocks may be added in the future according to requirements of
+different SoCs.
+
+Example:
+
+	lcd0: lcd-controller at 820000 {
+		compatible = "marvell,dove-lcd";
+		reg = <0x820000 0x1000>;
+		interrupts = <47>;
+		clocks = <&si5351 0>;
+		clock-names = "ext_ref_clk_1";
+	};
-- 
1.8.3.1

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

* [PATCH RFC 13/15] drm/armada: permit CRTCs to be registered as separate devices
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (11 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 12/15] dt-bindings: add Marvell Dove LCD controller documentation Russell King
@ 2014-07-05 10:38 ` Russell King
  2014-07-05 10:39 ` [PATCH RFC 14/15] drm/armada: register crtc with port Russell King
  2014-07-05 10:39 ` [PATCH RFC 15/15] ARM: dts: dove: add DT LCD controllers Russell King
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c | 114 ++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/armada/armada_crtc.h |   4 +-
 drivers/gpu/drm/armada/armada_drv.c  |   5 +-
 3 files changed, 110 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index afa497489000..7cc30475f8f3 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -7,6 +7,9 @@
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include "armada_crtc.h"
@@ -1046,19 +1049,19 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 	return 0;
 }
 
-int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
-	int irq, const struct armada_variant *variant)
+int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
+	struct resource *res, int irq, const struct armada_variant *variant)
 {
-	struct armada_private *priv = dev->dev_private;
+	struct armada_private *priv = drm->dev_private;
 	struct armada_crtc *dcrtc;
 	void __iomem *base;
 	int ret;
 
-	ret = armada_drm_crtc_create_properties(dev);
+	ret = armada_drm_crtc_create_properties(drm);
 	if (ret)
 		return ret;
 
-	base = devm_request_and_ioremap(dev->dev, res);
+	base = devm_request_and_ioremap(dev, res);
 	if (!base) {
 		DRM_ERROR("failed to ioremap register\n");
 		return -ENOMEM;
@@ -1070,9 +1073,12 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 		return -ENOMEM;
 	}
 
+	if (dev != drm->dev)
+		dev_set_drvdata(dev, dcrtc);
+
 	dcrtc->variant = variant;
 	dcrtc->base = base;
-	dcrtc->num = dev->mode_config.num_crtc;
+	dcrtc->num = drm->mode_config.num_crtc;
 	dcrtc->clk = ERR_PTR(-EINVAL);
 	dcrtc->csc_yuv_mode = CSC_AUTO;
 	dcrtc->csc_rgb_mode = CSC_AUTO;
@@ -1105,7 +1111,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 	}
 
 	if (dcrtc->variant->init) {
-		ret = dcrtc->variant->init(dcrtc, dev->dev);
+		ret = dcrtc->variant->init(dcrtc, dev);
 		if (ret) {
 			kfree(dcrtc);
 			return ret;
@@ -1117,7 +1123,7 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 
 	priv->dcrtc[dcrtc->num] = dcrtc;
 
-	drm_crtc_init(dev, &dcrtc->crtc, &armada_crtc_funcs);
+	drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs);
 	drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
 
 	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
@@ -1125,5 +1131,95 @@ int armada_drm_crtc_create(struct drm_device *dev, struct resource *res,
 	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_rgb_prop,
 				   dcrtc->csc_rgb_mode);
 
-	return armada_overlay_plane_create(dev, 1 << dcrtc->num);
+	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
+}
+
+static int
+armada_lcd_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = data;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int irq = platform_get_irq(pdev, 0);
+	const struct armada_variant *variant;
+
+	if (irq < 0)
+		return irq;
+
+	if (!dev->of_node) {
+		const struct platform_device_id *id;
+
+		id = platform_get_device_id(pdev);
+		if (!id)
+			return -ENXIO;
+
+		variant = (const struct armada_variant *)id->driver_data;
+	} else {
+		const struct of_device_id *match;
+
+		match = of_match_device(dev->driver->of_match_table, dev);
+		if (!match)
+			return -ENXIO;
+
+		variant = match->data;
+	}
+
+	return armada_drm_crtc_create(drm, dev, res, irq, variant);
+}
+
+static void
+armada_lcd_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct armada_crtc *dcrtc = dev_get_drvdata(dev);
+
+	armada_drm_crtc_destroy(&dcrtc->crtc);
+}
+
+static const struct component_ops armada_lcd_ops = {
+	.bind = armada_lcd_bind,
+	.unbind = armada_lcd_unbind,
+};
+
+static int armada_lcd_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &armada_lcd_ops);
+}
+
+static int armada_lcd_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &armada_lcd_ops);
+	return 0;
 }
+
+static struct of_device_id armada_lcd_of_match[] = {
+	{
+		.compatible	= "marvell,dove-lcd",
+		.data		= &armada510_ops,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, armada_lcd_of_match);
+
+static const struct platform_device_id armada_lcd_platform_ids[] = {
+	{
+		.name		= "armada-lcd",
+		.driver_data	= (unsigned long)&armada510_ops,
+	}, {
+		.name		= "armada-510-lcd",
+		.driver_data	= (unsigned long)&armada510_ops,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, armada_lcd_platform_ids);
+
+static struct platform_driver armada_lcd_platform_driver = {
+	.probe	= armada_lcd_probe,
+	.remove	= armada_lcd_remove,
+	.driver = {
+		.name	= "armada-lcd",
+		.owner	=  THIS_MODULE,
+		.of_match_table = armada_lcd_of_match,
+	},
+	.id_table = armada_lcd_platform_ids,
+};
+module_platform_driver(armada_lcd_platform_driver);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 73efcfcdf814..0fc50b39f129 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,8 +75,8 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-int armada_drm_crtc_create(struct drm_device *, struct resource *, int,
-	const struct armada_variant *);
+int armada_drm_crtc_create(struct drm_device *, struct device *,
+	struct resource *, int, const struct armada_variant *);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 2b6fc6cf62f2..ef8aeeee1db7 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -115,7 +115,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 			return -EINVAL;
 	}
 
-	if (!res[0] || !mem)
+	if (!mem)
 		return -ENXIO;
 
 	if (!devm_request_mem_region(dev->dev, mem->start,
@@ -168,7 +168,8 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 		if (irq < 0)
 			goto err_kms;
 
-		ret = armada_drm_crtc_create(dev, res[n], irq, variant);
+		ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
+					     variant);
 		if (ret)
 			goto err_kms;
 	}
-- 
1.8.3.1

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

* [PATCH RFC 14/15] drm/armada: register crtc with port
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (12 preceding siblings ...)
  2014-07-05 10:38 ` [PATCH RFC 13/15] drm/armada: permit CRTCs to be registered as separate devices Russell King
@ 2014-07-05 10:39 ` Russell King
  2014-07-05 10:39 ` [PATCH RFC 15/15] ARM: dts: dove: add DT LCD controllers Russell King
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Register the CRTC with the port node so that the DRM OF helpers can
find the appropriate CRTC.  This is important so that encoders can
identify their corresponding possible CRTCs.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c | 21 +++++++++++++++++++--
 drivers/gpu/drm/armada/armada_crtc.h |  4 +++-
 drivers/gpu/drm/armada/armada_drv.c  |  2 +-
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 7cc30475f8f3..9b06ff0f5442 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -910,6 +910,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
 
 	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
 
+	of_node_put(dcrtc->crtc.port);
+
 	kfree(dcrtc);
 }
 
@@ -1050,7 +1052,8 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 }
 
 int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
-	struct resource *res, int irq, const struct armada_variant *variant)
+	struct resource *res, int irq, const struct armada_variant *variant,
+	struct device_node *port)
 {
 	struct armada_private *priv = drm->dev_private;
 	struct armada_crtc *dcrtc;
@@ -1123,6 +1126,7 @@ int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 
 	priv->dcrtc[dcrtc->num] = dcrtc;
 
+	dcrtc->crtc.port = port;
 	drm_crtc_init(drm, &dcrtc->crtc, &armada_crtc_funcs);
 	drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
 
@@ -1142,6 +1146,7 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data)
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	int irq = platform_get_irq(pdev, 0);
 	const struct armada_variant *variant;
+	struct device_node *port = NULL;
 
 	if (irq < 0)
 		return irq;
@@ -1156,15 +1161,27 @@ armada_lcd_bind(struct device *dev, struct device *master, void *data)
 		variant = (const struct armada_variant *)id->driver_data;
 	} else {
 		const struct of_device_id *match;
+		struct device_node *np, *parent = dev->of_node;
 
 		match = of_match_device(dev->driver->of_match_table, dev);
 		if (!match)
 			return -ENXIO;
 
+		np = of_get_child_by_name(parent, "ports");
+		if (np)
+			parent = np;
+		port = of_get_child_by_name(parent, "port");
+		of_node_put(np);
+		if (!port) {
+			dev_err(dev, "no port node found in %s\n",
+				parent->full_name);
+			return -ENXIO;
+		}
+
 		variant = match->data;
 	}
 
-	return armada_drm_crtc_create(drm, dev, res, irq, variant);
+	return armada_drm_crtc_create(drm, dev, res, irq, variant, port);
 }
 
 static void
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 0fc50b39f129..23135aa94b50 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,8 +75,10 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
+struct device_node;
 int armada_drm_crtc_create(struct drm_device *, struct device *,
-	struct resource *, int, const struct armada_variant *);
+	struct resource *, int, const struct armada_variant *,
+	struct device_node *);
 void armada_drm_crtc_gamma_set(struct drm_crtc *, u16, u16, u16, int);
 void armada_drm_crtc_gamma_get(struct drm_crtc *, u16 *, u16 *, u16 *, int);
 void armada_drm_crtc_disable_irq(struct armada_crtc *, u32);
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index ef8aeeee1db7..082ae845d70f 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -169,7 +169,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 			goto err_kms;
 
 		ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
-					     variant);
+					     variant, NULL);
 		if (ret)
 			goto err_kms;
 	}
-- 
1.8.3.1

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

* [PATCH RFC 15/15] ARM: dts: dove: add DT LCD controllers
  2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
                   ` (13 preceding siblings ...)
  2014-07-05 10:39 ` [PATCH RFC 14/15] drm/armada: register crtc with port Russell King
@ 2014-07-05 10:39 ` Russell King
  14 siblings, 0 replies; 23+ messages in thread
From: Russell King @ 2014-07-05 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Add the DT fragment for the Marvell Dove LCD controllers.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/boot/dts/dove.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 3b891dd20993..a5441d5482a6 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -630,6 +630,20 @@
 				reg = <0xe8400 0x0c>;
 				ngpios = <8>;
 			};
+
+			lcd1: lcd-controller at 810000 {
+				compatible = "marvell,dove-lcd";
+				reg = <0x810000 0x1000>;
+				interrupts = <46>;
+				status = "disabled";
+			};
+
+			lcd0: lcd-controller at 820000 {
+				compatible = "marvell,dove-lcd";
+				reg = <0x820000 0x1000>;
+				interrupts = <47>;
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
1.8.3.1

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-05 10:38 ` [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init Russell King
@ 2014-07-05 11:58   ` Sebastian Hesselbarth
  2014-07-05 12:21     ` Russell King - ARM Linux
  2014-07-11 14:37     ` Russell King - ARM Linux
  0 siblings, 2 replies; 23+ messages in thread
From: Sebastian Hesselbarth @ 2014-07-05 11:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/05/2014 12:38 PM, Russell King wrote:
> Move the variant initialisation entirely to the CRTC init function -
> the variant support is really about the CRTC properties than the whole
> system, and we want to treat each CRTC individually when we support DT.
> 
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
[...]
> diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
> index 531a9b0bdcfb..3f0e70bb2e9c 100644
> --- a/drivers/gpu/drm/armada/armada_crtc.h
> +++ b/drivers/gpu/drm/armada/armada_crtc.h
> @@ -38,6 +38,7 @@ struct armada_crtc {
>  	unsigned		num;
>  	void __iomem		*base;
>  	struct clk		*clk;
> +	struct clk		*extclk[2];

Russell,

I wonder, if we should rename above array srcclk instead of extclk
while moving it anyway. That way we can use it for the other variant
specific clocks, too.

FWIW, I totally agree the it was the right thing to wait for you
to sort out the dependencies. Good work, great patience.

Sebastian

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-05 11:58   ` Sebastian Hesselbarth
@ 2014-07-05 12:21     ` Russell King - ARM Linux
  2014-07-06  9:46       ` Sebastian Hesselbarth
  2014-07-11 14:37     ` Russell King - ARM Linux
  1 sibling, 1 reply; 23+ messages in thread
From: Russell King - ARM Linux @ 2014-07-05 12:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 05, 2014 at 01:58:37PM +0200, Sebastian Hesselbarth wrote:
> On 07/05/2014 12:38 PM, Russell King wrote:
> > Move the variant initialisation entirely to the CRTC init function -
> > the variant support is really about the CRTC properties than the whole
> > system, and we want to treat each CRTC individually when we support DT.
> > 
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> [...]
> > diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
> > index 531a9b0bdcfb..3f0e70bb2e9c 100644
> > --- a/drivers/gpu/drm/armada/armada_crtc.h
> > +++ b/drivers/gpu/drm/armada/armada_crtc.h
> > @@ -38,6 +38,7 @@ struct armada_crtc {
> >  	unsigned		num;
> >  	void __iomem		*base;
> >  	struct clk		*clk;
> > +	struct clk		*extclk[2];
> 
> Russell,
> 
> I wonder, if we should rename above array srcclk instead of extclk
> while moving it anyway. That way we can use it for the other variant
> specific clocks, too.

pixelclk may be a better name for it.  I would like to think about the
clock handling further though - the issues surrounding clock selection
are not limited to just Armada - imx-drm has the exact same problem.

The issue with clocking of CRTCs is that it seems to be common that:

1. you have multiple clocks to choose from, some of which may be more
   suitable than others depending on the type of output.

2. clocks end up being shared between multiple CRTCs, and one CRTC
   can (at the moment) interfere with the clock rate delivered to
   another CRTC.

This happens on imx-drm today, where the two DIs (CRTCs) are in use -
one for HDMI, the other for LVDS.  We end up with HDMI set first to
148.5MHz, and then LVDS sets it's clock to 65MHz, which results in
HDMI receiving a clock at over 500MHz!  At the moment, there are hacks
to solve this by adjusting the muxes in the clock paths to ensure that
they both derive from different PLLs - moving the LVDS onto the USB OTG
PLL rather than the video PLL.  That works fine until USB OTG wants
to change the OTG PLL.

There's also the issue whether the output can cope with fractional
clock-skipping dividers - entirely synchronous display systems can
(such as synchronously clocked LCD panels), but asynchronous display
systems (such as HDMI, TV out, etc) can't.  That said, the other
parameter that needs to be taken account of here is that even with the
fractional divider, the minimum output clock period isn't the average
frequency, but the maximum frequency, which may violate a panel's minimum
clock period specification.

I think there's lots to do on the clocking side, and as it's a fairly
complex problem which is common to multiple implementations, I think
that any solution should not be specific.

However, this topic isn't one which I want to work on until I have
reduced down my patch sets to something more manageable - something
which I'm desperate to do.  (I've been trying to avoid adding any
further patches to any tree for some time now.)  This is why (eg) I'm
not going to fix the kernel oops-able bugs I found in the SGTL5000
codec - someone else can do that.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-05 12:21     ` Russell King - ARM Linux
@ 2014-07-06  9:46       ` Sebastian Hesselbarth
  2014-07-09  9:38         ` Russell King - ARM Linux
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Hesselbarth @ 2014-07-06  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/05/2014 02:21 PM, Russell King - ARM Linux wrote:
> On Sat, Jul 05, 2014 at 01:58:37PM +0200, Sebastian Hesselbarth wrote:
>> On 07/05/2014 12:38 PM, Russell King wrote:
>>> Move the variant initialisation entirely to the CRTC init function -
>>> the variant support is really about the CRTC properties than the whole
>>> system, and we want to treat each CRTC individually when we support DT.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>>> ---
>> [...]
>>> diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
>>> index 531a9b0bdcfb..3f0e70bb2e9c 100644
>>> --- a/drivers/gpu/drm/armada/armada_crtc.h
>>> +++ b/drivers/gpu/drm/armada/armada_crtc.h
>>> @@ -38,6 +38,7 @@ struct armada_crtc {
>>>  	unsigned		num;
>>>  	void __iomem		*base;
>>>  	struct clk		*clk;
>>> +	struct clk		*extclk[2];
>>
>> I wonder, if we should rename above array srcclk instead of extclk
>> while moving it anyway. That way we can use it for the other variant
>> specific clocks, too.
> 
> pixelclk may be a better name for it.  I would like to think about the

The name was derived from the "SCLK_SOURCE_SELECT" bits in Dove FS, but
any other name not limited to external clocks is fine, too.

> clock handling further though - the issues surrounding clock selection
> are not limited to just Armada - imx-drm has the exact same problem.
> 
> The issue with clocking of CRTCs is that it seems to be common that:
> 
> 1. you have multiple clocks to choose from, some of which may be more
>    suitable than others depending on the type of output.

Given the limited capabilities of the internal clock dividers, on Dove
the heuristic seems to be fairly simple: always prefer the external
clock. This is true for all actively supported Dove boards (Cubox and
{d2,d3}plug) as all have an external PLL connected.

I'd even say to make the external clock mandatory. Hitting a standard
pixclk frequency with one of the internal clocks is pure coincidence.

As long as there is no board using anything else than HDMI transmitter
on dumb RGB, we shouldn't try to foresee any suitable heuristic.

> 2. clocks end up being shared between multiple CRTCs, and one CRTC
>    can (at the moment) interfere with the clock rate delivered to
>    another CRTC.
> 
> This happens on imx-drm today, where the two DIs (CRTCs) are in use -
> one for HDMI, the other for LVDS.  We end up with HDMI set first to
> 148.5MHz, and then LVDS sets it's clock to 65MHz, which results in
> HDMI receiving a clock at over 500MHz!  At the moment, there are hacks
> to solve this by adjusting the muxes in the clock paths to ensure that
> they both derive from different PLLs - moving the LVDS onto the USB OTG
> PLL rather than the video PLL.  That works fine until USB OTG wants
> to change the OTG PLL.

Again, luckily on Cubox we have 2 VCOs for the two external clocks
(audio and video) so we won't have to deal with it. For the {d2,d3}plug
I'll have to check the IDT datasheet again.

In particular, for imx maybe it is possible to identify some clock tree
configurations for specific use-cases. I don't think there is any non-
manual way to tell the best clock tree config.

> There's also the issue whether the output can cope with fractional
> clock-skipping dividers - entirely synchronous display systems can
> (such as synchronously clocked LCD panels), but asynchronous display
> systems (such as HDMI, TV out, etc) can't.  That said, the other
> parameter that needs to be taken account of here is that even with the
> fractional divider, the minimum output clock period isn't the average
> frequency, but the maximum frequency, which may violate a panel's minimum
> clock period specification.

Yeah, the fractional divider isn't made for external HDMI transmitters
for sure. I have seen from your branch that there is some Armada 610
stub for OLPC, do they have a dumb panel directly connected?

I also saw that they do have an external PLL, so maybe we should stick
to the external clock inputs as long as no other configurations pops-up
(which may never happen).

Sebastian

> I think there's lots to do on the clocking side, and as it's a fairly
> complex problem which is common to multiple implementations, I think
> that any solution should not be specific.
> 
> However, this topic isn't one which I want to work on until I have
> reduced down my patch sets to something more manageable - something
> which I'm desperate to do.  (I've been trying to avoid adding any
> further patches to any tree for some time now.)  This is why (eg) I'm
> not going to fix the kernel oops-able bugs I found in the SGTL5000
> codec - someone else can do that.

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-06  9:46       ` Sebastian Hesselbarth
@ 2014-07-09  9:38         ` Russell King - ARM Linux
  0 siblings, 0 replies; 23+ messages in thread
From: Russell King - ARM Linux @ 2014-07-09  9:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jul 06, 2014 at 11:46:56AM +0200, Sebastian Hesselbarth wrote:
> On 07/05/2014 02:21 PM, Russell King - ARM Linux wrote:
> > There's also the issue whether the output can cope with fractional
> > clock-skipping dividers - entirely synchronous display systems can
> > (such as synchronously clocked LCD panels), but asynchronous display
> > systems (such as HDMI, TV out, etc) can't.  That said, the other
> > parameter that needs to be taken account of here is that even with the
> > fractional divider, the minimum output clock period isn't the average
> > frequency, but the maximum frequency, which may violate a panel's minimum
> > clock period specification.
> 
> Yeah, the fractional divider isn't made for external HDMI transmitters
> for sure. I have seen from your branch that there is some Armada 610
> stub for OLPC, do they have a dumb panel directly connected?

I believe they do have a dumb panel connected directly.  I've asked
Jon what the status of OLPC is with mainline kernels, and how difficult
it would be to get to the stage where the 610 stuff could be finished
off.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-05 11:58   ` Sebastian Hesselbarth
  2014-07-05 12:21     ` Russell King - ARM Linux
@ 2014-07-11 14:37     ` Russell King - ARM Linux
  2014-07-11 15:18       ` Sebastian Hesselbarth
  1 sibling, 1 reply; 23+ messages in thread
From: Russell King - ARM Linux @ 2014-07-11 14:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jul 05, 2014 at 01:58:37PM +0200, Sebastian Hesselbarth wrote:
> On 07/05/2014 12:38 PM, Russell King wrote:
> > Move the variant initialisation entirely to the CRTC init function -
> > the variant support is really about the CRTC properties than the whole
> > system, and we want to treat each CRTC individually when we support DT.
> > 
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> [...]
> > diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
> > index 531a9b0bdcfb..3f0e70bb2e9c 100644
> > --- a/drivers/gpu/drm/armada/armada_crtc.h
> > +++ b/drivers/gpu/drm/armada/armada_crtc.h
> > @@ -38,6 +38,7 @@ struct armada_crtc {
> >  	unsigned		num;
> >  	void __iomem		*base;
> >  	struct clk		*clk;
> > +	struct clk		*extclk[2];
> 
> Russell,
> 
> I wonder, if we should rename above array srcclk instead of extclk
> while moving it anyway. That way we can use it for the other variant
> specific clocks, too.

As the patches are prepared with this change, I'd prefer to submit them
as-is, and then we can update that as and when the support for things
like the MMP/610 is finished off.  I think they're good to go, so I'll
send them off later today to David.

This leaves the TDA998x componentisation patches which I need to kick
out, and the initial DT changes.  Once those are in place, we should
have almost all ducks lined up for working DRM support - it'll certainly
be advanced enough to describe the LCD controllers and the TDA998x as
three separate DT entities using the of graph helpers.

What's left is the display-subsystem { } entity to describe the makeup
of the subsystem.  That's not included as we currently need to pass
a block of memory, and the DT support for reserving chunks of memory
appeared (last time I looked) to only be botch-merged (only half of it
seems to have been merged making the whole reserved memory thing
totally useless - why people only half-merge features I've no idea.)

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-11 14:37     ` Russell King - ARM Linux
@ 2014-07-11 15:18       ` Sebastian Hesselbarth
  2014-07-11 15:24         ` Russell King - ARM Linux
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Hesselbarth @ 2014-07-11 15:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/11/2014 04:37 PM, Russell King - ARM Linux wrote:
> On Sat, Jul 05, 2014 at 01:58:37PM +0200, Sebastian Hesselbarth wrote:
>> On 07/05/2014 12:38 PM, Russell King wrote:
>>> Move the variant initialisation entirely to the CRTC init function -
>>> the variant support is really about the CRTC properties than the whole
>>> system, and we want to treat each CRTC individually when we support DT.
>>>
>>> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>>> ---
>> [...]
>>> diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
>>> index 531a9b0bdcfb..3f0e70bb2e9c 100644
>>> --- a/drivers/gpu/drm/armada/armada_crtc.h
>>> +++ b/drivers/gpu/drm/armada/armada_crtc.h
>>> @@ -38,6 +38,7 @@ struct armada_crtc {
>>>   	unsigned		num;
>>>   	void __iomem		*base;
>>>   	struct clk		*clk;
>>> +	struct clk		*extclk[2];
>>
>> Russell,
>>
>> I wonder, if we should rename above array srcclk instead of extclk
>> while moving it anyway. That way we can use it for the other variant
>> specific clocks, too.
>
> As the patches are prepared with this change, I'd prefer to submit them
> as-is, and then we can update that as and when the support for things
> like the MMP/610 is finished off.  I think they're good to go, so I'll
> send them off later today to David.

Ok, sounds fine to me.

> This leaves the TDA998x componentisation patches which I need to kick
> out, and the initial DT changes.  Once those are in place, we should
> have almost all ducks lined up for working DRM support - it'll certainly
> be advanced enough to describe the LCD controllers and the TDA998x as
> three separate DT entities using the of graph helpers.

Ok.

> What's left is the display-subsystem { } entity to describe the makeup
> of the subsystem.  That's not included as we currently need to pass
> a block of memory, and the DT support for reserving chunks of memory
> appeared (last time I looked) to only be botch-merged (only half of it
> seems to have been merged making the whole reserved memory thing
> totally useless - why people only half-merge features I've no idea.)

There was a follow-up patch set for this some days ago
http://comments.gmane.org/gmane.linux.ports.arm.kernel/337686

Sebastian

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

* [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init
  2014-07-11 15:18       ` Sebastian Hesselbarth
@ 2014-07-11 15:24         ` Russell King - ARM Linux
  0 siblings, 0 replies; 23+ messages in thread
From: Russell King - ARM Linux @ 2014-07-11 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jul 11, 2014 at 05:18:50PM +0200, Sebastian Hesselbarth wrote:
> On 07/11/2014 04:37 PM, Russell King - ARM Linux wrote:
>> What's left is the display-subsystem { } entity to describe the makeup
>> of the subsystem.  That's not included as we currently need to pass
>> a block of memory, and the DT support for reserving chunks of memory
>> appeared (last time I looked) to only be botch-merged (only half of it
>> seems to have been merged making the whole reserved memory thing
>> totally useless - why people only half-merge features I've no idea.)
>
> There was a follow-up patch set for this some days ago
> http://comments.gmane.org/gmane.linux.ports.arm.kernel/337686

Yes, I did a bit of digging a while back and found the outstanding
stuff, but it wasn't clear what's happening with it.  As it isn't
part of mainline, and I don't want to pick up further patches to
add dependencies, I decided it was better to stick with old proven
ways of a manually declared platform device for the time being.

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.

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

end of thread, other threads:[~2014-07-11 15:24 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-05 10:37 [PATCH RFC 00/15] Armada DRM updates Russell King - ARM Linux
2014-07-05 10:37 ` [PATCH RFC 01/15] component: fix missed cleanup in case of devres failure Russell King
2014-07-05 10:38 ` [PATCH RFC 02/15] component: ignore multiple additions of the same component Russell King
2014-07-05 10:38 ` [PATCH RFC 03/15] component: add support for component match array Russell King
2014-07-05 10:38 ` [PATCH RFC 04/15] drm/armada: move IRQ handling into CRTC Russell King
2014-07-05 10:38 ` [PATCH RFC 05/15] drm/armada: use number of CRTCs registered Russell King
2014-07-05 10:38 ` [PATCH RFC 06/15] drm/armada: move variant initialisation to CRTC init Russell King
2014-07-05 11:58   ` Sebastian Hesselbarth
2014-07-05 12:21     ` Russell King - ARM Linux
2014-07-06  9:46       ` Sebastian Hesselbarth
2014-07-09  9:38         ` Russell King - ARM Linux
2014-07-11 14:37     ` Russell King - ARM Linux
2014-07-11 15:18       ` Sebastian Hesselbarth
2014-07-11 15:24         ` Russell King - ARM Linux
2014-07-05 10:38 ` [PATCH RFC 07/15] drm/armada: make variant a CRTC thing Russell King
2014-07-05 10:38 ` [PATCH RFC 08/15] drm: add of_graph endpoint helper to find possible CRTCs Russell King
2014-07-05 10:38 ` [PATCH RFC 09/15] component: fix bug with legacy API Russell King
2014-07-05 10:38 ` [PATCH RFC 10/15] drm/armada: convert to componentized support Russell King
2014-07-05 10:38 ` [PATCH RFC 11/15] drm/armada: update Armada 510 (Dove) to use "ext_ref_clk1" as the clock Russell King
2014-07-05 10:38 ` [PATCH RFC 12/15] dt-bindings: add Marvell Dove LCD controller documentation Russell King
2014-07-05 10:38 ` [PATCH RFC 13/15] drm/armada: permit CRTCs to be registered as separate devices Russell King
2014-07-05 10:39 ` [PATCH RFC 14/15] drm/armada: register crtc with port Russell King
2014-07-05 10:39 ` [PATCH RFC 15/15] ARM: dts: dove: add DT LCD controllers Russell King

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