dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/20] Armada DRM updates for 4.4
@ 2015-09-29 18:08 Russell King - ARM Linux
  2015-09-29 18:09 ` [PATCH 01/20] drm/armada: remove non-component support Russell King
                   ` (20 more replies)
  0 siblings, 21 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2015-09-29 18:08 UTC (permalink / raw)
  To: dri-devel

Here are my queued changes for the Armada DRM driver, for the upcoming
4.4 merge window.

These changes are about updating the driver to some of the more recent
DRM APIs, and removing the non-component support now that has
stabilised.  This results in all of armada_output and armada_slave
being removed, resulting in 460 lines of code removed from that change
alone.

Other changes include:

* moving more towards supporting DRM planes in a more generic way,
  thereby reducing the duplication between the primary and overlay
  planes.
* locking cleanups, more like locking removal, prefering inherently
  atomic operations (eg, xchg) instead of spinlocking.  This ultimately
  results in simpler and faster code.

I've been running these patches for a while and haven't noticed any ill
effects.

Posted for comment, if nothing is forthcoming, I'll send a pull request
to David in a week or so's time.  These patches are against v4.2, but
rebase to 4.3-rc3 without any fuss.

 drivers/gpu/drm/armada/Kconfig          |   9 --
 drivers/gpu/drm/armada/Makefile         |   3 +-
 drivers/gpu/drm/armada/armada_crtc.c    | 258 +++++++++++++++++++++++---------
 drivers/gpu/drm/armada/armada_crtc.h    |  34 +++--
 drivers/gpu/drm/armada/armada_drm.h     |  16 --
 drivers/gpu/drm/armada/armada_drv.c     | 148 +++---------------
 drivers/gpu/drm/armada/armada_output.c  | 142 ------------------
 drivers/gpu/drm/armada/armada_output.h  |  33 ----
 drivers/gpu/drm/armada/armada_overlay.c | 147 +++++++++---------
 drivers/gpu/drm/armada/armada_slave.c   | 139 -----------------
 drivers/gpu/drm/armada/armada_slave.h   |  26 ----
 11 files changed, 297 insertions(+), 658 deletions(-)
 delete mode 100644 drivers/gpu/drm/armada/armada_output.c
 delete mode 100644 drivers/gpu/drm/armada/armada_output.h
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.h

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* [PATCH 01/20] drm/armada: remove non-component support
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:09 ` [PATCH 02/20] drm/armada: move vbl code into armada_crtc Russell King
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

Now that the transition of TDA998x to the component helpers is complete,
remove the non-componentised support from the Armada DRM driver.  All
outputs are expected to use the component helpers from now on.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/Kconfig         |   9 ---
 drivers/gpu/drm/armada/Makefile        |   3 +-
 drivers/gpu/drm/armada/armada_crtc.c   |   2 +-
 drivers/gpu/drm/armada/armada_crtc.h   |   4 -
 drivers/gpu/drm/armada/armada_drv.c    | 125 ++++-------------------------
 drivers/gpu/drm/armada/armada_output.c | 142 ---------------------------------
 drivers/gpu/drm/armada/armada_output.h |  33 --------
 drivers/gpu/drm/armada/armada_slave.c  | 139 --------------------------------
 drivers/gpu/drm/armada/armada_slave.h  |  26 ------
 9 files changed, 19 insertions(+), 464 deletions(-)
 delete mode 100644 drivers/gpu/drm/armada/armada_output.c
 delete mode 100644 drivers/gpu/drm/armada/armada_output.h
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
 delete mode 100644 drivers/gpu/drm/armada/armada_slave.h

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index 50ae88ad4d76..eb773e9af313 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -14,12 +14,3 @@ config DRM_ARMADA
 	  This driver provides no built-in acceleration; acceleration is
 	  performed by other IP found on the SoC.  This driver provides
 	  kernel mode setting and buffer management to userspace.
-
-config DRM_ARMADA_TDA1998X
-	bool "Support TDA1998X HDMI output"
-	depends on DRM_ARMADA != n
-	depends on I2C && DRM_I2C_NXP_TDA998X = y
-	default y
-	help
-	  Support the TDA1998x HDMI output device found on the Solid-Run
-	  CuBox.
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index d6f43e06150a..ffd673615772 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -1,6 +1,5 @@
 armada-y	:= armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
-		   armada_gem.o armada_output.o armada_overlay.o \
-		   armada_slave.o
+		   armada_gem.o armada_overlay.o
 armada-y	+= armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 01ffe9bffe38..c7374a3ec67a 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1044,7 +1044,7 @@ static int armada_drm_crtc_create_properties(struct drm_device *dev)
 	return 0;
 }
 
-int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
+static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	struct resource *res, int irq, const struct armada_variant *variant,
 	struct device_node *port)
 {
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 98102a5a9af5..a13469f5d72b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,10 +75,6 @@ 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 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 225034b74cda..b373cf9b2f65 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -18,47 +18,6 @@
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-#include <drm/i2c/tda998x.h>
-#include "armada_slave.h"
-
-static struct tda998x_encoder_params params = {
-	/* With 0x24, there is no translation between vp_out and int_vp
-	FB	LCD out	Pins	VIP	Int Vp
-	R:23:16	R:7:0	VPC7:0	7:0	7:0[R]
-	G:15:8	G:15:8	VPB7:0	23:16	23:16[G]
-	B:7:0	B:23:16	VPA7:0	15:8	15:8[B]
-	*/
-	.swap_a = 2,
-	.swap_b = 3,
-	.swap_c = 4,
-	.swap_d = 5,
-	.swap_e = 0,
-	.swap_f = 1,
-	.audio_cfg = BIT(2),
-	.audio_frame[1] = 1,
-	.audio_format = AFMT_SPDIF,
-	.audio_sample_rate = 44100,
-};
-
-static const struct armada_drm_slave_config tda19988_config = {
-	.i2c_adapter_id = 0,
-	.crtcs = 1 << 0, /* Only LCD0 at the moment */
-	.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
-	.interlace_allowed = true,
-	.info = {
-		.type = "tda998x",
-		.addr = 0x70,
-		.platform_data = &params,
-	},
-};
-#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 =
@@ -91,16 +50,11 @@ 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;
-	int ret, n, i;
+	int ret, n;
 
-	memset(res, 0, sizeof(res));
-
-	for (n = i = 0; ; n++) {
+	for (n = 0; ; n++) {
 		struct resource *r = platform_get_resource(dev->platformdev,
 							   IORESOURCE_MEM, n);
 		if (!r)
@@ -109,8 +63,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 		/* Resources above 64K are graphics memory */
 		if (resource_size(r) > SZ_64K)
 			mem = r;
-		else if (i < ARRAY_SIZE(priv->dcrtc))
-			res[i++] = r;
 		else
 			return -EINVAL;
 	}
@@ -131,13 +83,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	platform_set_drvdata(dev->platformdev, dev);
 	dev->dev_private = priv;
 
-	/* Get the implementation specific driver data. */
-	id = platform_get_device_id(dev->platformdev);
-	if (!id)
-		return -ENXIO;
-
-	variant = (const struct armada_variant *)id->driver_data;
-
 	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
 	INIT_KFIFO(priv->fb_unref);
 
@@ -157,34 +102,9 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	dev->mode_config.funcs = &armada_drm_mode_config_funcs;
 	drm_mm_init(&priv->linear, mem->start, resource_size(mem));
 
-	/* Create all LCD controllers */
-	for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
-		int irq;
-
-		if (!res[n])
-			break;
-
-		irq = platform_get_irq(dev->platformdev, n);
-		if (irq < 0)
-			goto err_kms;
-
-		ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
-					     variant, NULL);
-		if (ret)
-			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;
-#endif
-	}
+	ret = component_bind_all(dev->dev, dev);
+	if (ret)
+		goto err_kms;
 
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret)
@@ -202,8 +122,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	return 0;
 
  err_comp:
-	if (is_componentized(dev->dev))
-		component_unbind_all(dev->dev, dev);
+	component_unbind_all(dev->dev, dev);
  err_kms:
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
@@ -219,8 +138,7 @@ 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);
+	component_unbind_all(dev->dev, dev);
 
 	drm_mode_config_cleanup(dev);
 	drm_mm_takedown(&priv->linear);
@@ -435,37 +353,28 @@ static const struct component_master_ops armada_master_ops = {
 
 static int armada_drm_probe(struct platform_device *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);
-	}
+	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);
 }
 
 static int armada_drm_remove(struct platform_device *pdev)
 {
-	if (is_componentized(&pdev->dev))
-		component_master_del(&pdev->dev, &armada_master_ops);
-	else
-		drm_put_dev(platform_get_drvdata(pdev));
+	component_master_del(&pdev->dev, &armada_master_ops);
 	return 0;
 }
 
 static const struct platform_device_id armada_drm_platform_ids[] = {
 	{
 		.name		= "armada-drm",
-		.driver_data	= (unsigned long)&armada510_ops,
 	}, {
 		.name		= "armada-510-drm",
-		.driver_data	= (unsigned long)&armada510_ops,
 	},
 	{ },
 };
diff --git a/drivers/gpu/drm/armada/armada_output.c b/drivers/gpu/drm/armada/armada_output.c
deleted file mode 100644
index 5a9823178291..000000000000
--- a/drivers/gpu/drm/armada/armada_output.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * 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.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_output.h"
-#include "armada_drm.h"
-
-struct armada_connector {
-	struct drm_connector conn;
-	const struct armada_output_type *type;
-};
-
-#define drm_to_armada_conn(c) container_of(c, struct armada_connector, conn)
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn)
-{
-	struct drm_encoder *enc = conn->encoder;
-
-	return enc ? enc : drm_encoder_find(conn->dev, conn->encoder_ids[0]);
-}
-
-static enum drm_connector_status armada_drm_connector_detect(
-	struct drm_connector *conn, bool force)
-{
-	struct armada_connector *dconn = drm_to_armada_conn(conn);
-	enum drm_connector_status status = connector_status_disconnected;
-
-	if (dconn->type->detect) {
-		status = dconn->type->detect(conn, force);
-	} else {
-		struct drm_encoder *enc = armada_drm_connector_encoder(conn);
-
-		if (enc)
-			status = encoder_helper_funcs(enc)->detect(enc, conn);
-	}
-
-	return status;
-}
-
-static void armada_drm_connector_destroy(struct drm_connector *conn)
-{
-	struct armada_connector *dconn = drm_to_armada_conn(conn);
-
-	drm_connector_unregister(conn);
-	drm_connector_cleanup(conn);
-	kfree(dconn);
-}
-
-static int armada_drm_connector_set_property(struct drm_connector *conn,
-	struct drm_property *property, uint64_t value)
-{
-	struct armada_connector *dconn = drm_to_armada_conn(conn);
-
-	if (!dconn->type->set_property)
-		return -EINVAL;
-
-	return dconn->type->set_property(conn, property, value);
-}
-
-static const struct drm_connector_funcs armada_drm_conn_funcs = {
-	.dpms		= drm_helper_connector_dpms,
-	.fill_modes	= drm_helper_probe_single_connector_modes,
-	.detect		= armada_drm_connector_detect,
-	.destroy	= armada_drm_connector_destroy,
-	.set_property	= armada_drm_connector_set_property,
-};
-
-/* Shouldn't this be a generic helper function? */
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
-	struct drm_display_mode *mode)
-{
-	struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
-	int valid = MODE_BAD;
-
-	if (encoder) {
-		struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
-		valid = slave->slave_funcs->mode_valid(encoder, mode);
-	}
-	return valid;
-}
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
-	struct drm_property *property, uint64_t value)
-{
-	struct drm_encoder *encoder = armada_drm_connector_encoder(conn);
-	int rc = -EINVAL;
-
-	if (encoder) {
-		struct drm_encoder_slave *slave = to_encoder_slave(encoder);
-
-		rc = slave->slave_funcs->set_property(encoder, conn, property,
-						      value);
-	}
-	return rc;
-}
-
-int armada_output_create(struct drm_device *dev,
-	const struct armada_output_type *type, const void *data)
-{
-	struct armada_connector *dconn;
-	int ret;
-
-	dconn = kzalloc(sizeof(*dconn), GFP_KERNEL);
-	if (!dconn)
-		return -ENOMEM;
-
-	dconn->type = type;
-
-	ret = drm_connector_init(dev, &dconn->conn, &armada_drm_conn_funcs,
-				 type->connector_type);
-	if (ret) {
-		DRM_ERROR("unable to init connector\n");
-		goto err_destroy_dconn;
-	}
-
-	ret = type->create(&dconn->conn, data);
-	if (ret)
-		goto err_conn;
-
-	ret = drm_connector_register(&dconn->conn);
-	if (ret)
-		goto err_sysfs;
-
-	return 0;
-
- err_sysfs:
-	if (dconn->conn.encoder)
-		dconn->conn.encoder->funcs->destroy(dconn->conn.encoder);
- err_conn:
-	drm_connector_cleanup(&dconn->conn);
- err_destroy_dconn:
-	kfree(dconn);
-	return ret;
-}
diff --git a/drivers/gpu/drm/armada/armada_output.h b/drivers/gpu/drm/armada/armada_output.h
deleted file mode 100644
index f448785753e8..000000000000
--- a/drivers/gpu/drm/armada/armada_output.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * 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.
- */
-#ifndef ARMADA_CONNETOR_H
-#define ARMADA_CONNETOR_H
-
-#define encoder_helper_funcs(encoder) \
-	((const struct drm_encoder_helper_funcs *)encoder->helper_private)
-
-struct armada_output_type {
-	int connector_type;
-	enum drm_connector_status (*detect)(struct drm_connector *, bool);
-	int (*create)(struct drm_connector *, const void *);
-	int (*set_property)(struct drm_connector *, struct drm_property *,
-			    uint64_t);
-};
-
-struct drm_encoder *armada_drm_connector_encoder(struct drm_connector *conn);
-
-int armada_drm_slave_encoder_mode_valid(struct drm_connector *conn,
-	struct drm_display_mode *mode);
-
-int armada_drm_slave_encoder_set_property(struct drm_connector *conn,
-	struct drm_property *property, uint64_t value);
-
-int armada_output_create(struct drm_device *dev,
-	const struct armada_output_type *type, const void *data);
-
-#endif
diff --git a/drivers/gpu/drm/armada/armada_slave.c b/drivers/gpu/drm/armada/armada_slave.c
deleted file mode 100644
index 00d0facb42f3..000000000000
--- a/drivers/gpu/drm/armada/armada_slave.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *  Rewritten from the dovefb driver, and Armada510 manuals.
- *
- * 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.
- */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include "armada_drm.h"
-#include "armada_output.h"
-#include "armada_slave.h"
-
-static int armada_drm_slave_get_modes(struct drm_connector *conn)
-{
-	struct drm_encoder *enc = armada_drm_connector_encoder(conn);
-	int count = 0;
-
-	if (enc) {
-		struct drm_encoder_slave *slave = to_encoder_slave(enc);
-
-		count = slave->slave_funcs->get_modes(enc, conn);
-	}
-
-	return count;
-}
-
-static void armada_drm_slave_destroy(struct drm_encoder *enc)
-{
-	struct drm_encoder_slave *slave = to_encoder_slave(enc);
-	struct i2c_client *client = drm_i2c_encoder_get_client(enc);
-
-	if (slave->slave_funcs)
-		slave->slave_funcs->destroy(enc);
-	if (client)
-		i2c_put_adapter(client->adapter);
-
-	drm_encoder_cleanup(&slave->base);
-	kfree(slave);
-}
-
-static const struct drm_encoder_funcs armada_drm_slave_encoder_funcs = {
-	.destroy	= armada_drm_slave_destroy,
-};
-
-static const struct drm_connector_helper_funcs armada_drm_slave_helper_funcs = {
-	.get_modes	= armada_drm_slave_get_modes,
-	.mode_valid	= armada_drm_slave_encoder_mode_valid,
-	.best_encoder	= armada_drm_connector_encoder,
-};
-
-static const struct drm_encoder_helper_funcs drm_slave_encoder_helpers = {
-	.dpms = drm_i2c_encoder_dpms,
-	.save = drm_i2c_encoder_save,
-	.restore = drm_i2c_encoder_restore,
-	.mode_fixup = drm_i2c_encoder_mode_fixup,
-	.prepare = drm_i2c_encoder_prepare,
-	.commit = drm_i2c_encoder_commit,
-	.mode_set = drm_i2c_encoder_mode_set,
-	.detect = drm_i2c_encoder_detect,
-};
-
-static int
-armada_drm_conn_slave_create(struct drm_connector *conn, const void *data)
-{
-	const struct armada_drm_slave_config *config = data;
-	struct drm_encoder_slave *slave;
-	struct i2c_adapter *adap;
-	int ret;
-
-	conn->interlace_allowed = config->interlace_allowed;
-	conn->doublescan_allowed = config->doublescan_allowed;
-	conn->polled = config->polled;
-
-	drm_connector_helper_add(conn, &armada_drm_slave_helper_funcs);
-
-	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
-	if (!slave)
-		return -ENOMEM;
-
-	slave->base.possible_crtcs = config->crtcs;
-
-	adap = i2c_get_adapter(config->i2c_adapter_id);
-	if (!adap) {
-		kfree(slave);
-		return -EPROBE_DEFER;
-	}
-
-	ret = drm_encoder_init(conn->dev, &slave->base,
-			       &armada_drm_slave_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS);
-	if (ret) {
-		DRM_ERROR("unable to init encoder\n");
-		i2c_put_adapter(adap);
-		kfree(slave);
-		return ret;
-	}
-
-	ret = drm_i2c_encoder_init(conn->dev, slave, adap, &config->info);
-	i2c_put_adapter(adap);
-	if (ret) {
-		DRM_ERROR("unable to init encoder slave\n");
-		armada_drm_slave_destroy(&slave->base);
-		return ret;
-	}
-
-	drm_encoder_helper_add(&slave->base, &drm_slave_encoder_helpers);
-
-	ret = slave->slave_funcs->create_resources(&slave->base, conn);
-	if (ret) {
-		armada_drm_slave_destroy(&slave->base);
-		return ret;
-	}
-
-	ret = drm_mode_connector_attach_encoder(conn, &slave->base);
-	if (ret) {
-		armada_drm_slave_destroy(&slave->base);
-		return ret;
-	}
-
-	conn->encoder = &slave->base;
-
-	return ret;
-}
-
-static const struct armada_output_type armada_drm_conn_slave = {
-	.connector_type	= DRM_MODE_CONNECTOR_HDMIA,
-	.create		= armada_drm_conn_slave_create,
-	.set_property	= armada_drm_slave_encoder_set_property,
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
-	const struct armada_drm_slave_config *config)
-{
-	return armada_output_create(dev, &armada_drm_conn_slave, config);
-}
diff --git a/drivers/gpu/drm/armada/armada_slave.h b/drivers/gpu/drm/armada/armada_slave.h
deleted file mode 100644
index bf2374c96fc1..000000000000
--- a/drivers/gpu/drm/armada/armada_slave.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2012 Russell King
- *
- * 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.
- */
-#ifndef ARMADA_SLAVE_H
-#define ARMADA_SLAVE_H
-
-#include <linux/i2c.h>
-#include <drm/drmP.h>
-
-struct armada_drm_slave_config {
-	int i2c_adapter_id;
-	uint32_t crtcs;
-	uint8_t polled;
-	bool interlace_allowed;
-	bool doublescan_allowed;
-	struct i2c_board_info info;
-};
-
-int armada_drm_connector_slave_create(struct drm_device *dev,
-	const struct armada_drm_slave_config *);
-
-#endif
-- 
2.1.0

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

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

* [PATCH 02/20] drm/armada: move vbl code into armada_crtc
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
  2015-09-29 18:09 ` [PATCH 01/20] drm/armada: remove non-component support Russell King
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:09 ` [PATCH 03/20] drm/armada: use drm_plane_force_disable() to disable the overlay plane Russell King
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

Our vblank event code belongs in armada_crtc.c rather than the core of
the driver.  Move it there.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index c7374a3ec67a..418594b19d1d 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -173,6 +173,44 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
 	return i;
 }
 
+void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
+	struct armada_vbl_event *evt)
+{
+	unsigned long flags;
+	bool not_on_list;
+
+	WARN_ON(drm_vblank_get(dcrtc->crtc.dev, dcrtc->num));
+
+	spin_lock_irqsave(&dcrtc->irq_lock, flags);
+	not_on_list = list_empty(&evt->node);
+	if (not_on_list)
+		list_add_tail(&evt->node, &dcrtc->vbl_list);
+	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+
+	if (!not_on_list)
+		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+}
+
+void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
+	struct armada_vbl_event *evt)
+{
+	if (!list_empty(&evt->node)) {
+		list_del_init(&evt->node);
+		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+	}
+}
+
+static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
+{
+	struct armada_vbl_event *e, *n;
+
+	list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
+		list_del_init(&e->node);
+		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+		e->fn(dcrtc, e->data);
+	}
+}
+
 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
 	struct armada_frame_work *work)
 {
@@ -356,7 +394,6 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
-	struct armada_vbl_event *e, *n;
 	void __iomem *base = dcrtc->base;
 
 	if (stat & DMA_FF_UNDERFLOW)
@@ -368,12 +405,7 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 		drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
 
 	spin_lock(&dcrtc->irq_lock);
-
-	list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
-		list_del_init(&e->node);
-		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-		e->fn(dcrtc, e->data);
-	}
+	armada_drm_vbl_event_run(dcrtc);
 
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index a13469f5d72b..a86243ef4a51 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -75,6 +75,23 @@ struct armada_crtc {
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
+struct armada_vbl_event {
+	struct list_head	node;
+	void			*data;
+	void			(*fn)(struct armada_crtc *, void *);
+};
+
+void armada_drm_vbl_event_add(struct armada_crtc *,
+	struct armada_vbl_event *);
+void armada_drm_vbl_event_remove(struct armada_crtc *,
+	struct armada_vbl_event *);
+#define armada_drm_vbl_event_init(_e, _f, _d) do {	\
+	struct armada_vbl_event *__e = _e;		\
+	INIT_LIST_HEAD(&__e->node);			\
+	__e->data = _d;					\
+	__e->fn = _f;					\
+} while (0)
+
 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 5f6aef0dca59..4df6f2af2b21 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -37,22 +37,6 @@ static inline uint32_t armada_pitch(uint32_t width, uint32_t bpp)
 	return ALIGN(pitch, 128);
 }
 
-struct armada_vbl_event {
-	struct list_head	node;
-	void			*data;
-	void			(*fn)(struct armada_crtc *, void *);
-};
-void armada_drm_vbl_event_add(struct armada_crtc *,
-	struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-	struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do {	\
-	struct armada_vbl_event *__e = _e;		\
-	INIT_LIST_HEAD(&__e->node);			\
-	__e->data = _d;					\
-	__e->fn = _f;					\
-} while (0)
-
 
 struct armada_private;
 
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index b373cf9b2f65..3f1396e673dd 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -148,29 +148,6 @@ static int armada_drm_unload(struct drm_device *dev)
 	return 0;
 }
 
-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-	struct armada_vbl_event *evt)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	if (list_empty(&evt->node)) {
-		list_add_tail(&evt->node, &dcrtc->vbl_list);
-
-		drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
-	}
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-	struct armada_vbl_event *evt)
-{
-	if (!list_empty(&evt->node)) {
-		list_del_init(&evt->node);
-		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-	}
-}
-
 /* These are called under the vbl_lock. */
 static int armada_drm_enable_vblank(struct drm_device *dev, int crtc)
 {
-- 
2.1.0

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

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

* [PATCH 03/20] drm/armada: use drm_plane_force_disable() to disable the overlay plane
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
  2015-09-29 18:09 ` [PATCH 01/20] drm/armada: remove non-component support Russell King
  2015-09-29 18:09 ` [PATCH 02/20] drm/armada: move vbl code into armada_crtc Russell King
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:09 ` [PATCH 04/20] drm/armada: disable CRTC clock during DPMS Russell King
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

Use drm_plane_force_disable() to disable the overlay plane on a mode_set
rather than coding this ourselves.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 418594b19d1d..bbf5ff785cd2 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -348,17 +348,11 @@ static void armada_drm_crtc_prepare(struct drm_crtc *crtc)
 	/*
 	 * If we have an overlay plane associated with this CRTC, disable
 	 * it before the modeset to avoid its coordinates being outside
-	 * the new mode parameters.  DRM doesn't provide help with this.
+	 * the new mode parameters.
 	 */
 	plane = dcrtc->plane;
-	if (plane) {
-		struct drm_framebuffer *fb = plane->fb;
-
-		plane->funcs->disable_plane(plane);
-		plane->fb = NULL;
-		plane->crtc = NULL;
-		drm_framebuffer_unreference(fb);
-	}
+	if (plane)
+		drm_plane_force_disable(plane);
 }
 
 /* The mode_config.mutex will be held for this call */
-- 
2.1.0

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

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

* [PATCH 04/20] drm/armada: disable CRTC clock during DPMS
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (2 preceding siblings ...)
  2015-09-29 18:09 ` [PATCH 03/20] drm/armada: use drm_plane_force_disable() to disable the overlay plane Russell King
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:09 ` [PATCH 05/20] drm/armada: redo locking and atomics for armada_drm_crtc_complete_frame_work() Russell King
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

When the CRTC is in low power mode, it isn't running, and so there's
no point keeping the CRTC clock enabled.  Disable the CRTC clock during
DPMS.

We need to re-enable it in the mode_set callback to ensure that the
variant's compute_clock() continues to see its clock in the expected
state (enabled).

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index bbf5ff785cd2..8c43ecc19c15 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -325,7 +325,11 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
 
 	if (dcrtc->dpms != dpms) {
 		dcrtc->dpms = dpms;
+		if (!IS_ERR(dcrtc->clk) && !dpms_blanked(dpms))
+			WARN_ON(clk_prepare_enable(dcrtc->clk));
 		armada_drm_crtc_update(dcrtc);
+		if (!IS_ERR(dcrtc->clk) && dpms_blanked(dpms))
+			clk_disable_unprepare(dcrtc->clk);
 		if (dpms_blanked(dpms))
 			armada_drm_vblank_off(dcrtc);
 		else
@@ -563,6 +567,13 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 		writel_relaxed(val, dcrtc->base + LCD_SPU_DUMB_CTRL);
 	}
 
+	/*
+	 * If we are blanked, we would have disabled the clock.  Re-enable
+	 * it so that compute_clock() does the right thing.
+	 */
+	if (!IS_ERR(dcrtc->clk) && dpms_blanked(dcrtc->dpms))
+		WARN_ON(clk_prepare_enable(dcrtc->clk));
+
 	/* Now compute the divider for real */
 	dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
 
-- 
2.1.0

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

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

* [PATCH 05/20] drm/armada: redo locking and atomics for armada_drm_crtc_complete_frame_work()
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (3 preceding siblings ...)
  2015-09-29 18:09 ` [PATCH 04/20] drm/armada: disable CRTC clock during DPMS Russell King
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:09 ` [PATCH 06/20] drm/armada: rename overlay identifiers Russell King
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

We can do better with armada_drm_crtc_complete_frame_work() - we can
avoid taking the event lock unless a call to drm_send_vblank_event()
is required, and using cmpxchg() and xchg(), we can eliminate the
locking around dcrtc->frame_work entirely.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 8c43ecc19c15..5d627646601e 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -215,7 +215,6 @@ static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
 	struct armada_frame_work *work)
 {
 	struct drm_device *dev = dcrtc->crtc.dev;
-	unsigned long flags;
 	int ret;
 
 	ret = drm_vblank_get(dev, dcrtc->num);
@@ -224,30 +223,29 @@ static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
 		return ret;
 	}
 
-	spin_lock_irqsave(&dev->event_lock, flags);
-	if (!dcrtc->frame_work)
-		dcrtc->frame_work = work;
-	else
-		ret = -EBUSY;
-	spin_unlock_irqrestore(&dev->event_lock, flags);
-
-	if (ret)
+	if (cmpxchg(&dcrtc->frame_work, NULL, work)) {
 		drm_vblank_put(dev, dcrtc->num);
+		ret = -EBUSY;
+	}
 
 	return ret;
 }
 
-static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc)
+static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
+	struct armada_frame_work *work)
 {
 	struct drm_device *dev = dcrtc->crtc.dev;
-	struct armada_frame_work *work = dcrtc->frame_work;
-
-	dcrtc->frame_work = NULL;
+	unsigned long flags;
 
+	spin_lock_irqsave(&dcrtc->irq_lock, flags);
 	armada_drm_crtc_update_regs(dcrtc, work->regs);
+	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 
-	if (work->event)
+	if (work->event) {
+		spin_lock_irqsave(&dev->event_lock, flags);
 		drm_send_vblank_event(dev, dcrtc->num, work->event);
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+	}
 
 	drm_vblank_put(dev, dcrtc->num);
 
@@ -293,7 +291,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 
 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-	struct drm_device *dev = dcrtc->crtc.dev;
+	struct armada_frame_work *work;
 
 	/*
 	 * Tell the DRM core that vblank IRQs aren't going to happen for
@@ -302,10 +300,9 @@ static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 	drm_crtc_vblank_off(&dcrtc->crtc);
 
 	/* Handle any pending flip event. */
-	spin_lock_irq(&dev->event_lock);
-	if (dcrtc->frame_work)
-		armada_drm_crtc_complete_frame_work(dcrtc);
-	spin_unlock_irq(&dev->event_lock);
+	work = xchg(&dcrtc->frame_work, NULL);
+	if (work)
+		armada_drm_crtc_complete_frame_work(dcrtc, work);
 }
 
 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@ -434,12 +431,10 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	spin_unlock(&dcrtc->irq_lock);
 
 	if (stat & GRA_FRAME_IRQ) {
-		struct drm_device *dev = dcrtc->crtc.dev;
+		struct armada_frame_work *work = xchg(&dcrtc->frame_work, NULL);
 
-		spin_lock(&dev->event_lock);
-		if (dcrtc->frame_work)
-			armada_drm_crtc_complete_frame_work(dcrtc);
-		spin_unlock(&dev->event_lock);
+		if (work)
+			armada_drm_crtc_complete_frame_work(dcrtc, work);
 
 		wake_up(&dcrtc->frame_wait);
 	}
@@ -957,8 +952,6 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct armada_frame_work *work;
-	struct drm_device *dev = crtc->dev;
-	unsigned long flags;
 	unsigned i;
 	int ret;
 
@@ -1004,10 +997,10 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	 * interrupt, so complete it now.
 	 */
 	if (dpms_blanked(dcrtc->dpms)) {
-		spin_lock_irqsave(&dev->event_lock, flags);
-		if (dcrtc->frame_work)
-			armada_drm_crtc_complete_frame_work(dcrtc);
-		spin_unlock_irqrestore(&dev->event_lock, flags);
+		struct armada_frame_work *work = xchg(&dcrtc->frame_work, NULL);
+
+		if (work)
+			armada_drm_crtc_complete_frame_work(dcrtc, work);
 	}
 
 	return 0;
-- 
2.1.0

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

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

* [PATCH 06/20] drm/armada: rename overlay identifiers
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (4 preceding siblings ...)
  2015-09-29 18:09 ` [PATCH 05/20] drm/armada: redo locking and atomics for armada_drm_crtc_complete_frame_work() Russell King
@ 2015-09-29 18:09 ` Russell King
  2015-09-29 18:10 ` [PATCH 07/20] drm/armada: factor out retirement of old fb Russell King
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:09 UTC (permalink / raw)
  To: dri-devel

Include an _ovl infix into the overlay identifiers to separate them from
the primary plane.

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

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e939faba7fcc..9393a15183e2 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -16,7 +16,7 @@
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-struct armada_plane_properties {
+struct armada_ovl_plane_properties {
 	uint32_t colorkey_yr;
 	uint32_t colorkey_ug;
 	uint32_t colorkey_vb;
@@ -29,7 +29,7 @@ struct armada_plane_properties {
 	uint32_t colorkey_mode;
 };
 
-struct armada_plane {
+struct armada_ovl_plane {
 	struct drm_plane base;
 	spinlock_t lock;
 	struct drm_framebuffer *old_fb;
@@ -42,13 +42,13 @@ struct armada_plane {
 		struct armada_regs regs[13];
 		wait_queue_head_t wait;
 	} vbl;
-	struct armada_plane_properties prop;
+	struct armada_ovl_plane_properties prop;
 };
-#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+#define drm_to_armada_ovl_plane(p) container_of(p, struct armada_ovl_plane, base)
 
 
 static void
-armada_ovl_update_attr(struct armada_plane_properties *prop,
+armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
 	struct armada_crtc *dcrtc)
 {
 	writel_relaxed(prop->colorkey_yr, dcrtc->base + LCD_SPU_COLORKEY_Y);
@@ -72,9 +72,9 @@ armada_ovl_update_attr(struct armada_plane_properties *prop,
 }
 
 /* === Plane support === */
-static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data)
+static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
 {
-	struct armada_plane *dplane = data;
+	struct armada_ovl_plane *dplane = data;
 	struct drm_framebuffer *fb;
 
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
@@ -91,12 +91,12 @@ static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data)
 }
 
 static int
-armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
+armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	struct drm_framebuffer *fb,
 	int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
 	uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 	struct drm_rect src = {
 		.x1 = src_x,
@@ -267,9 +267,9 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	return 0;
 }
 
-static int armada_plane_disable(struct drm_plane *plane)
+static int armada_ovl_plane_disable(struct drm_plane *plane)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
 	struct drm_framebuffer *fb;
 	struct armada_crtc *dcrtc;
 
@@ -302,20 +302,20 @@ static int armada_plane_disable(struct drm_plane *plane)
 	return 0;
 }
 
-static void armada_plane_destroy(struct drm_plane *plane)
+static void armada_ovl_plane_destroy(struct drm_plane *plane)
 {
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
 
 	drm_plane_cleanup(plane);
 
 	kfree(dplane);
 }
 
-static int armada_plane_set_property(struct drm_plane *plane,
+static int armada_ovl_plane_set_property(struct drm_plane *plane,
 	struct drm_property *property, uint64_t val)
 {
 	struct armada_private *priv = plane->dev->dev_private;
-	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_ovl_plane *dplane = drm_to_armada_ovl_plane(plane);
 	bool update_attr = false;
 
 	if (property == priv->colorkey_prop) {
@@ -379,14 +379,14 @@ static int armada_plane_set_property(struct drm_plane *plane,
 	return 0;
 }
 
-static const struct drm_plane_funcs armada_plane_funcs = {
-	.update_plane	= armada_plane_update,
-	.disable_plane	= armada_plane_disable,
-	.destroy	= armada_plane_destroy,
-	.set_property	= armada_plane_set_property,
+static const struct drm_plane_funcs armada_ovl_plane_funcs = {
+	.update_plane	= armada_ovl_plane_update,
+	.disable_plane	= armada_ovl_plane_disable,
+	.destroy	= armada_ovl_plane_destroy,
+	.set_property	= armada_ovl_plane_set_property,
 };
 
-static const uint32_t armada_formats[] = {
+static const uint32_t armada_ovl_formats[] = {
 	DRM_FORMAT_UYVY,
 	DRM_FORMAT_YUYV,
 	DRM_FORMAT_YUV420,
@@ -456,7 +456,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 {
 	struct armada_private *priv = dev->dev_private;
 	struct drm_mode_object *mobj;
-	struct armada_plane *dplane;
+	struct armada_ovl_plane *dplane;
 	int ret;
 
 	ret = armada_overlay_create_properties(dev);
@@ -469,11 +469,16 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 
 	spin_lock_init(&dplane->lock);
 	init_waitqueue_head(&dplane->vbl.wait);
-	armada_drm_vbl_event_init(&dplane->vbl.update, armada_plane_vbl,
+	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
 				  dplane);
 
-	drm_plane_init(dev, &dplane->base, crtcs, &armada_plane_funcs,
-		       armada_formats, ARRAY_SIZE(armada_formats), false);
+	drm_plane_init(dev, &dplane->base, crtcs, &armada_ovl_plane_funcs,
+		       armada_ovl_formats, ARRAY_SIZE(armada_ovl_formats),
+		       false);
+	if (ret) {
+		kfree(dplane);
+		return ret;
+	}
 
 	dplane->prop.colorkey_yr = 0xfefefe00;
 	dplane->prop.colorkey_ug = 0x01010100;
-- 
2.1.0

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

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

* [PATCH 07/20] drm/armada: factor out retirement of old fb
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (5 preceding siblings ...)
  2015-09-29 18:09 ` [PATCH 06/20] drm/armada: rename overlay identifiers Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb Russell King
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

We have two identical places in the overlay code which retire the drm
framebuffer.  Factor these out into a common function.

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

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 9393a15183e2..093c2d4f2b79 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -71,21 +71,27 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
 	spin_unlock_irq(&dcrtc->irq_lock);
 }
 
+static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
+	struct drm_framebuffer *fb)
+{
+	struct drm_framebuffer *old_fb;
+
+	spin_lock(&dplane->lock);
+	old_fb = dplane->old_fb;
+	dplane->old_fb = fb;
+	spin_unlock(&dplane->lock);
+
+	if (old_fb)
+		armada_drm_queue_unref_work(dplane->base.dev, old_fb);
+}
+
 /* === Plane support === */
 static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
 {
 	struct armada_ovl_plane *dplane = data;
-	struct drm_framebuffer *fb;
 
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
-
-	spin_lock(&dplane->lock);
-	fb = dplane->old_fb;
-	dplane->old_fb = NULL;
-	spin_unlock(&dplane->lock);
-
-	if (fb)
-		armada_drm_queue_unref_work(dcrtc->crtc.dev, fb);
+	armada_ovl_retire_fb(dplane, NULL);
 
 	wake_up(&dplane->vbl.wait);
 }
@@ -175,17 +181,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 		 */
 		drm_framebuffer_reference(fb);
 
-		if (plane->fb) {
-			struct drm_framebuffer *older_fb;
-
-			spin_lock_irq(&dplane->lock);
-			older_fb = dplane->old_fb;
-			dplane->old_fb = plane->fb;
-			spin_unlock_irq(&dplane->lock);
-			if (older_fb)
-				armada_drm_queue_unref_work(dcrtc->crtc.dev,
-							    older_fb);
-		}
+		if (plane->fb)
+			armada_ovl_retire_fb(dplane, plane->fb);
 
 		src_y = src.y1 >> 16;
 		src_x = src.x1 >> 16;
-- 
2.1.0

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

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

* [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (6 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 07/20] drm/armada: factor out retirement of old fb Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-30 10:49   ` Emil Velikov
  2015-09-29 18:10 ` [PATCH 09/20] drm/armada: update armada overlay to use drm_universal_plane_init() Russell King
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Rather than using a spinlock, use xchg() to atomically update
dplane->old_fb.  This allows us to eliminate dplane->lock.

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

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 093c2d4f2b79..8738b590abc2 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -31,7 +31,6 @@ struct armada_ovl_plane_properties {
 
 struct armada_ovl_plane {
 	struct drm_plane base;
-	spinlock_t lock;
 	struct drm_framebuffer *old_fb;
 	uint32_t src_hw;
 	uint32_t dst_hw;
@@ -76,13 +75,10 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
 {
 	struct drm_framebuffer *old_fb;
 
-	spin_lock(&dplane->lock);
-	old_fb = dplane->old_fb;
-	dplane->old_fb = fb;
-	spin_unlock(&dplane->lock);
+	old_fb = xchg(&dplane->old_fb, fb);
 
 	if (old_fb)
-		armada_drm_queue_unref_work(dplane->base.dev, old_fb);
+		armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
 }
 
 /* === Plane support === */
@@ -289,10 +285,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 	if (plane->fb)
 		drm_framebuffer_unreference(plane->fb);
 
-	spin_lock_irq(&dplane->lock);
-	fb = dplane->old_fb;
-	dplane->old_fb = NULL;
-	spin_unlock_irq(&dplane->lock);
+	fb = xchg(&dplane->old_fb, NULL);
 	if (fb)
 		drm_framebuffer_unreference(fb);
 
@@ -464,7 +457,6 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	if (!dplane)
 		return -ENOMEM;
 
-	spin_lock_init(&dplane->lock);
 	init_waitqueue_head(&dplane->vbl.wait);
 	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
 				  dplane);
-- 
2.1.0

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

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

* [PATCH 09/20] drm/armada: update armada overlay to use drm_universal_plane_init()
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (7 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 10/20] drm/armada: introduce generic armada_plane struct Russell King
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Use the new drm_universal_plane_init() rather than the legacy
drm_plane_init().

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

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 8738b590abc2..4609ae8de042 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -461,9 +461,11 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
 				  dplane);
 
-	drm_plane_init(dev, &dplane->base, crtcs, &armada_ovl_plane_funcs,
-		       armada_ovl_formats, ARRAY_SIZE(armada_ovl_formats),
-		       false);
+	ret = drm_universal_plane_init(dev, &dplane->base, crtcs,
+				       &armada_ovl_plane_funcs,
+				       armada_ovl_formats,
+				       ARRAY_SIZE(armada_ovl_formats),
+				       DRM_PLANE_TYPE_OVERLAY);
 	if (ret) {
 		kfree(dplane);
 		return ret;
-- 
2.1.0

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

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

* [PATCH 10/20] drm/armada: introduce generic armada_plane struct
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (8 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 09/20] drm/armada: update armada overlay to use drm_universal_plane_init() Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 11/20] drm/armada: add primary plane creation Russell King
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Introduce a generic armada_plane struct which will eventually be used
for both the primary and overlay planes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.h    |  5 +++++
 drivers/gpu/drm/armada/armada_overlay.c | 17 +++++++++--------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index a86243ef4a51..549b5f538266 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -34,6 +34,11 @@ struct armada_regs {
 struct armada_frame_work;
 struct armada_variant;
 
+struct armada_plane {
+	struct drm_plane	base;
+};
+#define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
+
 struct armada_crtc {
 	struct drm_crtc		crtc;
 	const struct armada_variant *variant;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 4609ae8de042..e5a5b73a08cb 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -30,7 +30,7 @@ struct armada_ovl_plane_properties {
 };
 
 struct armada_ovl_plane {
-	struct drm_plane base;
+	struct armada_plane base;
 	struct drm_framebuffer *old_fb;
 	uint32_t src_hw;
 	uint32_t dst_hw;
@@ -43,7 +43,8 @@ struct armada_ovl_plane {
 	} vbl;
 	struct armada_ovl_plane_properties prop;
 };
-#define drm_to_armada_ovl_plane(p) container_of(p, struct armada_ovl_plane, base)
+#define drm_to_armada_ovl_plane(p) \
+	container_of(p, struct armada_ovl_plane, base.base)
 
 
 static void
@@ -266,10 +267,10 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 	struct drm_framebuffer *fb;
 	struct armada_crtc *dcrtc;
 
-	if (!dplane->base.crtc)
+	if (!dplane->base.base.crtc)
 		return 0;
 
-	dcrtc = drm_to_armada_crtc(dplane->base.crtc);
+	dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
 	dcrtc->plane = NULL;
 
 	spin_lock_irq(&dcrtc->irq_lock);
@@ -362,9 +363,9 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane,
 		update_attr = true;
 	}
 
-	if (update_attr && dplane->base.crtc)
+	if (update_attr && dplane->base.base.crtc)
 		armada_ovl_update_attr(&dplane->prop,
-				       drm_to_armada_crtc(dplane->base.crtc));
+				       drm_to_armada_crtc(dplane->base.base.crtc));
 
 	return 0;
 }
@@ -461,7 +462,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
 				  dplane);
 
-	ret = drm_universal_plane_init(dev, &dplane->base, crtcs,
+	ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
 				       &armada_ovl_plane_funcs,
 				       armada_ovl_formats,
 				       ARRAY_SIZE(armada_ovl_formats),
@@ -479,7 +480,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	dplane->prop.contrast = 0x4000;
 	dplane->prop.saturation = 0x4000;
 
-	mobj = &dplane->base.base;
+	mobj = &dplane->base.base.base;
 	drm_object_attach_property(mobj, priv->colorkey_prop,
 				   0x0101fe);
 	drm_object_attach_property(mobj, priv->colorkey_min_prop,
-- 
2.1.0

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

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

* [PATCH 11/20] drm/armada: add primary plane creation
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (9 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 10/20] drm/armada: introduce generic armada_plane struct Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 12/20] drm/armada: allocate primary plane ourselves Russell King
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Use drm_primary_helper_create_plane() to create our primary plane, and
register the CRTC with drm_crtc_init_with_planes().  This enables the
primary plane to be initialised with the supported format information.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 5d627646601e..b96b77b61337 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -33,6 +33,23 @@ enum csc_mode {
 	CSC_RGB_STUDIO = 2,
 };
 
+static const uint32_t armada_primary_formats[] = {
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_VYUY,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+};
+
 /*
  * A note about interlacing.  Let's consider HDMI 1920x1080i.
  * The timing parameters we have from X are:
@@ -1080,6 +1097,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 {
 	struct armada_private *priv = drm->dev_private;
 	struct armada_crtc *dcrtc;
+	struct drm_plane *primary;
 	void __iomem *base;
 	int ret;
 
@@ -1148,7 +1166,17 @@ static 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);
+
+	primary = drm_primary_helper_create_plane(drm, armada_primary_formats,
+					ARRAY_SIZE(armada_primary_formats));
+	if (!primary)
+		return -ENOMEM;
+
+	ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, primary, NULL,
+					&armada_crtc_funcs);
+	if (ret)
+		goto err_crtc_init;
+
 	drm_crtc_helper_add(&dcrtc->crtc, &armada_crtc_helper_funcs);
 
 	drm_object_attach_property(&dcrtc->crtc.base, priv->csc_yuv_prop,
@@ -1157,6 +1185,10 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 				   dcrtc->csc_rgb_mode);
 
 	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
+
+err_crtc_init:
+	primary->funcs->destroy(primary);
+	return ret;
 }
 
 static int
-- 
2.1.0

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

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

* [PATCH 12/20] drm/armada: allocate primary plane ourselves
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (10 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 11/20] drm/armada: add primary plane creation Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 13/20] drm/armada: provide a common helper to disable a plane Russell King
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Allocate our own primary plane as an armada_plane.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index b96b77b61337..f146fcf6b274 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -1059,6 +1059,12 @@ static struct drm_crtc_funcs armada_crtc_funcs = {
 	.set_property	= armada_drm_crtc_set_property,
 };
 
+static const struct drm_plane_funcs armada_primary_plane_funcs = {
+	.update_plane	= drm_primary_helper_update,
+	.disable_plane	= drm_primary_helper_disable,
+	.destroy	= drm_primary_helper_destroy,
+};
+
 static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
 	{ CSC_AUTO,        "Auto" },
 	{ CSC_YUV_CCIR601, "CCIR601" },
@@ -1097,7 +1103,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 {
 	struct armada_private *priv = drm->dev_private;
 	struct armada_crtc *dcrtc;
-	struct drm_plane *primary;
+	struct armada_plane *primary;
 	void __iomem *base;
 	int ret;
 
@@ -1167,12 +1173,21 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 
 	dcrtc->crtc.port = port;
 
-	primary = drm_primary_helper_create_plane(drm, armada_primary_formats,
-					ARRAY_SIZE(armada_primary_formats));
+	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
 	if (!primary)
 		return -ENOMEM;
 
-	ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, primary, NULL,
+	ret = drm_universal_plane_init(drm, &primary->base, 0,
+				       &armada_primary_plane_funcs,
+				       armada_primary_formats,
+				       ARRAY_SIZE(armada_primary_formats),
+				       DRM_PLANE_TYPE_PRIMARY);
+	if (ret) {
+		kfree(primary);
+		return ret;
+	}
+
+	ret = drm_crtc_init_with_planes(drm, &dcrtc->crtc, &primary->base, NULL,
 					&armada_crtc_funcs);
 	if (ret)
 		goto err_crtc_init;
@@ -1187,7 +1202,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	return armada_overlay_plane_create(drm, 1 << dcrtc->num);
 
 err_crtc_init:
-	primary->funcs->destroy(primary);
+	primary->base.funcs->destroy(&primary->base);
 	return ret;
 }
 
-- 
2.1.0

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

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

* [PATCH 13/20] drm/armada: provide a common helper to disable a plane
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (11 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 12/20] drm/armada: allocate primary plane ourselves Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 14/20] drm/armada: move write to dma_ctrl0 to armada_drm_crtc_plane_disable() Russell King
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Provide a common helper to disable either the overlay or the primary
plane.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index f146fcf6b274..007fc5d3eb54 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -700,18 +700,39 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	return 0;
 }
 
+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+	struct drm_plane *plane)
+{
+	u32 sram_para1;
+
+	/*
+	 * Drop our reference on any framebuffer attached to this plane.
+	 * We don't need to NULL this out as drm_plane_force_disable(),
+	 * and __setplane_internal() will do so for an overlay plane, and
+	 * __drm_helper_disable_unused_functions() will do so for the
+	 * primary plane.
+	 */
+	if (plane->fb)
+		drm_framebuffer_unreference(plane->fb);
+
+	/* Power down the Y/U/V FIFOs */
+	sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
+
+	/* Power down most RAMs and FIFOs if this is the primary plane */
+	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+		sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
+			      CFG_PDWN32x32 | CFG_PDWN64x66;
+
+	armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1);
+}
+
 /* The mode_config.mutex will be held for this call */
 static void armada_drm_crtc_disable(struct drm_crtc *crtc)
 {
 	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
 
 	armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
-	armada_drm_crtc_finish_fb(dcrtc, crtc->primary->fb, true);
-
-	/* Power down most RAMs and FIFOs */
-	writel_relaxed(CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
-		       CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
-		       CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
+	armada_drm_crtc_plane_disable(dcrtc, crtc->primary);
 }
 
 static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 549b5f538266..500ce0f43f64 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -103,6 +103,9 @@ 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 *);
 
+void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
+	struct drm_plane *plane);
+
 extern struct platform_driver armada_lcd_platform_driver;
 
 #endif
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e5a5b73a08cb..1032f9b3d5f1 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -279,12 +279,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 	dplane->ctrl0 = 0;
 	spin_unlock_irq(&dcrtc->irq_lock);
 
-	/* Power down the Y/U/V FIFOs */
-	armada_updatel(CFG_PDWN16x66 | CFG_PDWN32x66, 0,
-		       dcrtc->base + LCD_SPU_SRAM_PARA1);
-
-	if (plane->fb)
-		drm_framebuffer_unreference(plane->fb);
+	armada_drm_crtc_plane_disable(dcrtc, plane);
 
 	fb = xchg(&dplane->old_fb, NULL);
 	if (fb)
-- 
2.1.0

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

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

* [PATCH 14/20] drm/armada: move write to dma_ctrl0 to armada_drm_crtc_plane_disable()
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (12 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 13/20] drm/armada: provide a common helper to disable a plane Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 15/20] drm/armada: move the update of dplane->ctrl0 out of spinlock Russell King
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Move the write to clear the DMA enable bit, and augment it with clearing
the graphics enable bit for the primary plane.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c    | 12 ++++++++++--
 drivers/gpu/drm/armada/armada_overlay.c |  1 -
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 007fc5d3eb54..89decc5bdcd4 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -703,7 +703,7 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
 	struct drm_plane *plane)
 {
-	u32 sram_para1;
+	u32 sram_para1, dma_ctrl0_mask;
 
 	/*
 	 * Drop our reference on any framebuffer attached to this plane.
@@ -719,9 +719,17 @@ void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc,
 	sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66;
 
 	/* Power down most RAMs and FIFOs if this is the primary plane */
-	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+	if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
 		sram_para1 |= CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 |
 			      CFG_PDWN32x32 | CFG_PDWN64x66;
+		dma_ctrl0_mask = CFG_GRA_ENA;
+	} else {
+		dma_ctrl0_mask = CFG_DMA_ENA;
+	}
+
+	spin_lock_irq(&dcrtc->irq_lock);
+	armada_updatel(0, dma_ctrl0_mask, dcrtc->base + LCD_SPU_DMA_CTRL0);
+	spin_unlock_irq(&dcrtc->irq_lock);
 
 	armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1);
 }
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 1032f9b3d5f1..9686d79335a0 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -275,7 +275,6 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 
 	spin_lock_irq(&dcrtc->irq_lock);
 	armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
-	armada_updatel(0, CFG_DMA_ENA, dcrtc->base + LCD_SPU_DMA_CTRL0);
 	dplane->ctrl0 = 0;
 	spin_unlock_irq(&dcrtc->irq_lock);
 
-- 
2.1.0

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

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

* [PATCH 15/20] drm/armada: move the update of dplane->ctrl0 out of spinlock
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (13 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 14/20] drm/armada: move write to dma_ctrl0 to armada_drm_crtc_plane_disable() Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 16/20] drm/armada: move the locking for armada_drm_vbl_event_remove() Russell King
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

It is not necessary to write dplane->ctrl0 under the CRTC spinlock, as
this is only accessed under process context where the DRM locks will
protect us instead.

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

diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 9686d79335a0..e7e020d4372a 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -275,9 +275,10 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 
 	spin_lock_irq(&dcrtc->irq_lock);
 	armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
-	dplane->ctrl0 = 0;
 	spin_unlock_irq(&dcrtc->irq_lock);
 
+	dplane->ctrl0 = 0;
+
 	armada_drm_crtc_plane_disable(dcrtc, plane);
 
 	fb = xchg(&dplane->old_fb, NULL);
-- 
2.1.0

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

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

* [PATCH 16/20] drm/armada: move the locking for armada_drm_vbl_event_remove()
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (14 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 15/20] drm/armada: move the update of dplane->ctrl0 out of spinlock Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:10 ` [PATCH 17/20] drm/armada: move frame wait into armada_frame Russell King
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Move the locking for armada_drm_vbl_event_remove() into itself, which
makes this function symmetrical with armada_drm_vbl_event_add().

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 89decc5bdcd4..e3e6f81593c0 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -211,10 +211,12 @@ void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
 void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
 	struct armada_vbl_event *evt)
 {
+	spin_lock_irq(&dcrtc->irq_lock);
 	if (!list_empty(&evt->node)) {
 		list_del_init(&evt->node);
 		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
 	}
+	spin_unlock_irq(&dcrtc->irq_lock);
 }
 
 static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index e7e020d4372a..6ec42eb85981 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -273,9 +273,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 	dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
 	dcrtc->plane = NULL;
 
-	spin_lock_irq(&dcrtc->irq_lock);
 	armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
-	spin_unlock_irq(&dcrtc->irq_lock);
 
 	dplane->ctrl0 = 0;
 
-- 
2.1.0

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

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

* [PATCH 17/20] drm/armada: move frame wait into armada_frame
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (15 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 16/20] drm/armada: move the locking for armada_drm_vbl_event_remove() Russell King
@ 2015-09-29 18:10 ` Russell King
  2015-09-29 18:11 ` [PATCH 18/20] drm/armada: move CRTC flip work to primary plane work Russell King
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:10 UTC (permalink / raw)
  To: dri-devel

Both the CRTC and overlay frames have their own wait queues.  It would
make more sense if these were part of the plane - the primary plane for
the CRTC and overlay plane for the overlay.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index e3e6f81593c0..46d932bc7678 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -455,7 +455,7 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 		if (work)
 			armada_drm_crtc_complete_frame_work(dcrtc, work);
 
-		wake_up(&dcrtc->frame_wait);
+		wake_up(&drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait);
 	}
 }
 
@@ -571,7 +571,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 		adj->crtc_vtotal, tm, bm);
 
 	/* Wait for pending flips to complete */
-	wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+	wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
+		   !dcrtc->frame_work);
 
 	drm_crtc_vblank_off(crtc);
 
@@ -688,7 +689,8 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	armada_reg_queue_end(regs, i);
 
 	/* Wait for pending flips to complete */
-	wait_event(dcrtc->frame_wait, !dcrtc->frame_work);
+	wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
+		   !dcrtc->frame_work);
 
 	/* Take a reference to the new fb as we're using it */
 	drm_framebuffer_reference(crtc->primary->fb);
@@ -1096,6 +1098,13 @@ static const struct drm_plane_funcs armada_primary_plane_funcs = {
 	.destroy	= drm_primary_helper_destroy,
 };
 
+int armada_drm_plane_init(struct armada_plane *plane)
+{
+	init_waitqueue_head(&plane->frame_wait);
+
+	return 0;
+}
+
 static struct drm_prop_enum_list armada_drm_csc_yuv_enum_list[] = {
 	{ CSC_AUTO,        "Auto" },
 	{ CSC_YUV_CCIR601, "CCIR601" },
@@ -1166,7 +1175,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	spin_lock_init(&dcrtc->irq_lock);
 	dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
 	INIT_LIST_HEAD(&dcrtc->vbl_list);
-	init_waitqueue_head(&dcrtc->frame_wait);
 
 	/* Initialize some registers which we don't otherwise set */
 	writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
@@ -1208,6 +1216,12 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	if (!primary)
 		return -ENOMEM;
 
+	ret = armada_drm_plane_init(primary);
+	if (ret) {
+		kfree(primary);
+		return ret;
+	}
+
 	ret = drm_universal_plane_init(drm, &primary->base, 0,
 				       &armada_primary_plane_funcs,
 				       armada_primary_formats,
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 500ce0f43f64..3ec5101e13f7 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -36,9 +36,12 @@ struct armada_variant;
 
 struct armada_plane {
 	struct drm_plane	base;
+	wait_queue_head_t	frame_wait;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
 
+int armada_drm_plane_init(struct armada_plane *plane);
+
 struct armada_crtc {
 	struct drm_crtc		crtc;
 	const struct armada_variant *variant;
@@ -71,7 +74,6 @@ struct armada_crtc {
 	uint32_t		dumb_ctrl;
 	uint32_t		spu_iopad_ctrl;
 
-	wait_queue_head_t	frame_wait;
 	struct armada_frame_work *frame_work;
 
 	spinlock_t		irq_lock;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 6ec42eb85981..9a5bab765085 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -39,7 +39,6 @@ struct armada_ovl_plane {
 	struct {
 		struct armada_vbl_event update;
 		struct armada_regs regs[13];
-		wait_queue_head_t wait;
 	} vbl;
 	struct armada_ovl_plane_properties prop;
 };
@@ -90,7 +89,7 @@ static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
 	armada_ovl_retire_fb(dplane, NULL);
 
-	wake_up(&dplane->vbl.wait);
+	wake_up(&dplane->base.frame_wait);
 }
 
 static int
@@ -163,7 +162,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 			       dcrtc->base + LCD_SPU_SRAM_PARA1);
 	}
 
-	wait_event_timeout(dplane->vbl.wait,
+	wait_event_timeout(dplane->base.frame_wait,
 			   list_empty(&dplane->vbl.update.node),
 			   HZ/25);
 
@@ -451,7 +450,12 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 	if (!dplane)
 		return -ENOMEM;
 
-	init_waitqueue_head(&dplane->vbl.wait);
+	ret = armada_drm_plane_init(&dplane->base);
+	if (ret) {
+		kfree(dplane);
+		return ret;
+	}
+
 	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
 				  dplane);
 
-- 
2.1.0

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

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

* [PATCH 18/20] drm/armada: move CRTC flip work to primary plane work
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (16 preceding siblings ...)
  2015-09-29 18:10 ` [PATCH 17/20] drm/armada: move frame wait into armada_frame Russell King
@ 2015-09-29 18:11 ` Russell King
  2015-09-29 18:11 ` [PATCH 19/20] drm/armada: convert overlay plane vbl worker to a armada plane worker Russell King
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:11 UTC (permalink / raw)
  To: dri-devel

Add a plane work implementation, and move the CRTC framebuffer flip
work to it for the primary plane.  The idea is to have a common
plane work implementation for both the primary and overlay planes.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c | 102 ++++++++++++++++++++---------------
 drivers/gpu/drm/armada/armada_crtc.h |  15 ++++--
 2 files changed, 70 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 46d932bc7678..0c1a1524f5d5 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -20,6 +20,7 @@
 #include "armada_hw.h"
 
 struct armada_frame_work {
+	struct armada_plane_work work;
 	struct drm_pending_vblank_event *event;
 	struct armada_regs regs[4];
 	struct drm_framebuffer *old_fb;
@@ -190,6 +191,41 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
 	return i;
 }
 
+static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
+	struct armada_plane *plane)
+{
+	struct armada_plane_work *work = xchg(&plane->work, NULL);
+
+	/* Handle any pending frame work. */
+	if (work) {
+		work->fn(dcrtc, plane, work);
+		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+	}
+}
+
+int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
+	struct armada_plane *plane, struct armada_plane_work *work)
+{
+	int ret;
+
+	ret = drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
+	if (ret) {
+		DRM_ERROR("failed to acquire vblank counter\n");
+		return ret;
+	}
+
+	ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0;
+	if (ret)
+		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
+
+	return ret;
+}
+
+int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout)
+{
+	return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
+}
+
 void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
 	struct armada_vbl_event *evt)
 {
@@ -233,44 +269,31 @@ static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
 	struct armada_frame_work *work)
 {
-	struct drm_device *dev = dcrtc->crtc.dev;
-	int ret;
+	struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
 
-	ret = drm_vblank_get(dev, dcrtc->num);
-	if (ret) {
-		DRM_ERROR("failed to acquire vblank counter\n");
-		return ret;
-	}
-
-	if (cmpxchg(&dcrtc->frame_work, NULL, work)) {
-		drm_vblank_put(dev, dcrtc->num);
-		ret = -EBUSY;
-	}
-
-	return ret;
+	return armada_drm_plane_work_queue(dcrtc, plane, &work->work);
 }
 
 static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
-	struct armada_frame_work *work)
+	struct armada_plane *plane, struct armada_plane_work *work)
 {
+	struct armada_frame_work *fwork = container_of(work, struct armada_frame_work, work);
 	struct drm_device *dev = dcrtc->crtc.dev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	armada_drm_crtc_update_regs(dcrtc, work->regs);
+	armada_drm_crtc_update_regs(dcrtc, fwork->regs);
 	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
 
-	if (work->event) {
+	if (fwork->event) {
 		spin_lock_irqsave(&dev->event_lock, flags);
-		drm_send_vblank_event(dev, dcrtc->num, work->event);
+		drm_send_vblank_event(dev, dcrtc->num, fwork->event);
 		spin_unlock_irqrestore(&dev->event_lock, flags);
 	}
 
-	drm_vblank_put(dev, dcrtc->num);
-
 	/* Finally, queue the process-half of the cleanup. */
-	__armada_drm_queue_unref_work(dcrtc->crtc.dev, work->old_fb);
-	kfree(work);
+	__armada_drm_queue_unref_work(dcrtc->crtc.dev, fwork->old_fb);
+	kfree(fwork);
 }
 
 static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
@@ -290,6 +313,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 	work = kmalloc(sizeof(*work), GFP_KERNEL);
 	if (work) {
 		int i = 0;
+		work->work.fn = armada_drm_crtc_complete_frame_work;
 		work->event = NULL;
 		work->old_fb = fb;
 		armada_reg_queue_end(work->regs, i);
@@ -310,18 +334,14 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 
 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-	struct armada_frame_work *work;
+	struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
 
 	/*
 	 * Tell the DRM core that vblank IRQs aren't going to happen for
 	 * a while.  This cleans up any pending vblank events for us.
 	 */
 	drm_crtc_vblank_off(&dcrtc->crtc);
-
-	/* Handle any pending flip event. */
-	work = xchg(&dcrtc->frame_work, NULL);
-	if (work)
-		armada_drm_crtc_complete_frame_work(dcrtc, work);
+	armada_drm_plane_work_run(dcrtc, plane);
 }
 
 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@ -450,12 +470,9 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	spin_unlock(&dcrtc->irq_lock);
 
 	if (stat & GRA_FRAME_IRQ) {
-		struct armada_frame_work *work = xchg(&dcrtc->frame_work, NULL);
-
-		if (work)
-			armada_drm_crtc_complete_frame_work(dcrtc, work);
-
-		wake_up(&drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait);
+		struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
+		armada_drm_plane_work_run(dcrtc, plane);
+		wake_up(&plane->frame_wait);
 	}
 }
 
@@ -571,8 +588,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
 		adj->crtc_vtotal, tm, bm);
 
 	/* Wait for pending flips to complete */
-	wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
-		   !dcrtc->frame_work);
+	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+				   MAX_SCHEDULE_TIMEOUT);
 
 	drm_crtc_vblank_off(crtc);
 
@@ -689,8 +706,8 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	armada_reg_queue_end(regs, i);
 
 	/* Wait for pending flips to complete */
-	wait_event(drm_to_armada_plane(dcrtc->crtc.primary)->frame_wait,
-		   !dcrtc->frame_work);
+	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary),
+				   MAX_SCHEDULE_TIMEOUT);
 
 	/* Take a reference to the new fb as we're using it */
 	drm_framebuffer_reference(crtc->primary->fb);
@@ -1013,6 +1030,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	if (!work)
 		return -ENOMEM;
 
+	work->work.fn = armada_drm_crtc_complete_frame_work;
 	work->event = event;
 	work->old_fb = dcrtc->crtc.primary->fb;
 
@@ -1046,12 +1064,8 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	 * Finally, if the display is blanked, we won't receive an
 	 * interrupt, so complete it now.
 	 */
-	if (dpms_blanked(dcrtc->dpms)) {
-		struct armada_frame_work *work = xchg(&dcrtc->frame_work, NULL);
-
-		if (work)
-			armada_drm_crtc_complete_frame_work(dcrtc, work);
-	}
+	if (dpms_blanked(dcrtc->dpms))
+		armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary));
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index 3ec5101e13f7..aaad5ab78673 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -31,16 +31,27 @@ struct armada_regs {
 #define armada_reg_queue_end(_r, _i)		\
 	armada_reg_queue_mod(_r, _i, 0, 0, ~0)
 
-struct armada_frame_work;
+struct armada_crtc;
+struct armada_plane;
 struct armada_variant;
 
+struct armada_plane_work {
+	void			(*fn)(struct armada_crtc *,
+				      struct armada_plane *,
+				      struct armada_plane_work *);
+};
+
 struct armada_plane {
 	struct drm_plane	base;
 	wait_queue_head_t	frame_wait;
+	struct armada_plane_work *work;
 };
 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base)
 
 int armada_drm_plane_init(struct armada_plane *plane);
+int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
+	struct armada_plane *plane, struct armada_plane_work *work);
+int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
 
 struct armada_crtc {
 	struct drm_crtc		crtc;
@@ -74,8 +85,6 @@ struct armada_crtc {
 	uint32_t		dumb_ctrl;
 	uint32_t		spu_iopad_ctrl;
 
-	struct armada_frame_work *frame_work;
-
 	spinlock_t		irq_lock;
 	uint32_t		irq_ena;
 	struct list_head	vbl_list;
-- 
2.1.0

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

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

* [PATCH 19/20] drm/armada: convert overlay plane vbl worker to a armada plane worker
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (17 preceding siblings ...)
  2015-09-29 18:11 ` [PATCH 18/20] drm/armada: move CRTC flip work to primary plane work Russell King
@ 2015-09-29 18:11 ` Russell King
  2015-09-29 18:11 ` [PATCH 20/20] drm/armada: move frame wait wakeup into plane work Russell King
  2015-10-09 13:24 ` [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:11 UTC (permalink / raw)
  To: dri-devel

Convert the overlay plane to use the generic armada plane worker
infrastructure which is shared with the primary plane.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/gpu/drm/armada/armada_crtc.c    | 48 +++++++++------------------------
 drivers/gpu/drm/armada/armada_crtc.h    | 20 ++------------
 drivers/gpu/drm/armada/armada_overlay.c | 27 +++++++++----------
 3 files changed, 26 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 0c1a1524f5d5..418dbfad4271 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -226,44 +226,15 @@ int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout)
 	return wait_event_timeout(plane->frame_wait, !plane->work, timeout);
 }
 
-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-	struct armada_vbl_event *evt)
+struct armada_plane_work *armada_drm_plane_work_cancel(
+	struct armada_crtc *dcrtc, struct armada_plane *plane)
 {
-	unsigned long flags;
-	bool not_on_list;
-
-	WARN_ON(drm_vblank_get(dcrtc->crtc.dev, dcrtc->num));
-
-	spin_lock_irqsave(&dcrtc->irq_lock, flags);
-	not_on_list = list_empty(&evt->node);
-	if (not_on_list)
-		list_add_tail(&evt->node, &dcrtc->vbl_list);
-	spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
+	struct armada_plane_work *work = xchg(&plane->work, NULL);
 
-	if (!not_on_list)
+	if (work)
 		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-}
 
-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-	struct armada_vbl_event *evt)
-{
-	spin_lock_irq(&dcrtc->irq_lock);
-	if (!list_empty(&evt->node)) {
-		list_del_init(&evt->node);
-		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-	}
-	spin_unlock_irq(&dcrtc->irq_lock);
-}
-
-static void armada_drm_vbl_event_run(struct armada_crtc *dcrtc)
-{
-	struct armada_vbl_event *e, *n;
-
-	list_for_each_entry_safe(e, n, &dcrtc->vbl_list, node) {
-		list_del_init(&e->node);
-		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-		e->fn(dcrtc, e->data);
-	}
+	return work;
 }
 
 static int armada_drm_crtc_queue_frame_work(struct armada_crtc *dcrtc,
@@ -429,6 +400,7 @@ static bool armada_drm_crtc_mode_fixup(struct drm_crtc *crtc,
 static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 {
 	void __iomem *base = dcrtc->base;
+	struct drm_plane *ovl_plane;
 
 	if (stat & DMA_FF_UNDERFLOW)
 		DRM_ERROR("video underflow on crtc %u\n", dcrtc->num);
@@ -439,7 +411,12 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 		drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
 
 	spin_lock(&dcrtc->irq_lock);
-	armada_drm_vbl_event_run(dcrtc);
+	ovl_plane = dcrtc->plane;
+	if (ovl_plane) {
+		struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
+		armada_drm_plane_work_run(dcrtc, plane);
+		wake_up(&plane->frame_wait);
+	}
 
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
@@ -1188,7 +1165,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
 	dcrtc->spu_iopad_ctrl = CFG_VSCALE_LN_EN | CFG_IOPAD_DUMB24;
 	spin_lock_init(&dcrtc->irq_lock);
 	dcrtc->irq_ena = CLEAN_SPU_IRQ_ISR;
-	INIT_LIST_HEAD(&dcrtc->vbl_list);
 
 	/* Initialize some registers which we don't otherwise set */
 	writel_relaxed(0x00000001, dcrtc->base + LCD_CFG_SCLK_DIV);
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h
index aaad5ab78673..04fdd22d483b 100644
--- a/drivers/gpu/drm/armada/armada_crtc.h
+++ b/drivers/gpu/drm/armada/armada_crtc.h
@@ -52,6 +52,8 @@ int armada_drm_plane_init(struct armada_plane *plane);
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
 	struct armada_plane *plane, struct armada_plane_work *work);
 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout);
+struct armada_plane_work *armada_drm_plane_work_cancel(
+	struct armada_crtc *dcrtc, struct armada_plane *plane);
 
 struct armada_crtc {
 	struct drm_crtc		crtc;
@@ -87,27 +89,9 @@ struct armada_crtc {
 
 	spinlock_t		irq_lock;
 	uint32_t		irq_ena;
-	struct list_head	vbl_list;
 };
 #define drm_to_armada_crtc(c) container_of(c, struct armada_crtc, crtc)
 
-struct armada_vbl_event {
-	struct list_head	node;
-	void			*data;
-	void			(*fn)(struct armada_crtc *, void *);
-};
-
-void armada_drm_vbl_event_add(struct armada_crtc *,
-	struct armada_vbl_event *);
-void armada_drm_vbl_event_remove(struct armada_crtc *,
-	struct armada_vbl_event *);
-#define armada_drm_vbl_event_init(_e, _f, _d) do {	\
-	struct armada_vbl_event *__e = _e;		\
-	INIT_LIST_HEAD(&__e->node);			\
-	__e->data = _d;					\
-	__e->fn = _f;					\
-} while (0)
-
 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_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 9a5bab765085..5c22b380f8f3 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -37,7 +37,7 @@ struct armada_ovl_plane {
 	uint32_t dst_yx;
 	uint32_t ctrl0;
 	struct {
-		struct armada_vbl_event update;
+		struct armada_plane_work work;
 		struct armada_regs regs[13];
 	} vbl;
 	struct armada_ovl_plane_properties prop;
@@ -82,14 +82,13 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
 }
 
 /* === Plane support === */
-static void armada_ovl_plane_vbl(struct armada_crtc *dcrtc, void *data)
+static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
+	struct armada_plane *plane, struct armada_plane_work *work)
 {
-	struct armada_ovl_plane *dplane = data;
+	struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base);
 
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
 	armada_ovl_retire_fb(dplane, NULL);
-
-	wake_up(&dplane->base.frame_wait);
 }
 
 static int
@@ -162,9 +161,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 			       dcrtc->base + LCD_SPU_SRAM_PARA1);
 	}
 
-	wait_event_timeout(dplane->base.frame_wait,
-			   list_empty(&dplane->vbl.update.node),
-			   HZ/25);
+	if (armada_drm_plane_work_wait(&dplane->base, HZ / 25) == 0)
+		armada_drm_plane_work_cancel(dcrtc, &dplane->base);
 
 	if (plane->fb != fb) {
 		struct armada_gem_object *obj = drm_fb_obj(fb);
@@ -255,7 +253,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	}
 	if (idx) {
 		armada_reg_queue_end(dplane->vbl.regs, idx);
-		armada_drm_vbl_event_add(dcrtc, &dplane->vbl.update);
+		armada_drm_plane_work_queue(dcrtc, &dplane->base,
+					    &dplane->vbl.work);
 	}
 	return 0;
 }
@@ -270,14 +269,13 @@ static int armada_ovl_plane_disable(struct drm_plane *plane)
 		return 0;
 
 	dcrtc = drm_to_armada_crtc(dplane->base.base.crtc);
-	dcrtc->plane = NULL;
 
-	armada_drm_vbl_event_remove(dcrtc, &dplane->vbl.update);
+	armada_drm_plane_work_cancel(dcrtc, &dplane->base);
+	armada_drm_crtc_plane_disable(dcrtc, plane);
 
+	dcrtc->plane = NULL;
 	dplane->ctrl0 = 0;
 
-	armada_drm_crtc_plane_disable(dcrtc, plane);
-
 	fb = xchg(&dplane->old_fb, NULL);
 	if (fb)
 		drm_framebuffer_unreference(fb);
@@ -456,8 +454,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
 		return ret;
 	}
 
-	armada_drm_vbl_event_init(&dplane->vbl.update, armada_ovl_plane_vbl,
-				  dplane);
+	dplane->vbl.work.fn = armada_ovl_plane_work;
 
 	ret = drm_universal_plane_init(dev, &dplane->base.base, crtcs,
 				       &armada_ovl_plane_funcs,
-- 
2.1.0

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

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

* [PATCH 20/20] drm/armada: move frame wait wakeup into plane work
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (18 preceding siblings ...)
  2015-09-29 18:11 ` [PATCH 19/20] drm/armada: convert overlay plane vbl worker to a armada plane worker Russell King
@ 2015-09-29 18:11 ` Russell King
  2015-10-09 13:24 ` [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King @ 2015-09-29 18:11 UTC (permalink / raw)
  To: dri-devel

Move the wakeup for the frame wait into the armada plane work, to
ensure that it is woken up every time we run a work.

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

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 418dbfad4271..cebcab560626 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -201,6 +201,8 @@ static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
 		work->fn(dcrtc, plane, work);
 		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
 	}
+
+	wake_up(&plane->frame_wait);
 }
 
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
@@ -415,7 +417,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	if (ovl_plane) {
 		struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
 		armada_drm_plane_work_run(dcrtc, plane);
-		wake_up(&plane->frame_wait);
 	}
 
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
@@ -449,7 +450,6 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 	if (stat & GRA_FRAME_IRQ) {
 		struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
 		armada_drm_plane_work_run(dcrtc, plane);
-		wake_up(&plane->frame_wait);
 	}
 }
 
-- 
2.1.0

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

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

* Re: [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb
  2015-09-29 18:10 ` [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb Russell King
@ 2015-09-30 10:49   ` Emil Velikov
  2015-10-01 13:34     ` Russell King - ARM Linux
  0 siblings, 1 reply; 24+ messages in thread
From: Emil Velikov @ 2015-09-30 10:49 UTC (permalink / raw)
  To: Russell King; +Cc: ML dri-devel

Hi Russell,

On 29 September 2015 at 19:10, Russell King <rmk+kernel@arm.linux.org.uk> wrote:
> Rather than using a spinlock, use xchg() to atomically update
> dplane->old_fb.  This allows us to eliminate dplane->lock.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
[...]
> @@ -76,13 +75,10 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
>  {
>         struct drm_framebuffer *old_fb;
>
> -       spin_lock(&dplane->lock);
> -       old_fb = dplane->old_fb;
> -       dplane->old_fb = fb;
> -       spin_unlock(&dplane->lock);
> +       old_fb = xchg(&dplane->old_fb, fb);
>
>         if (old_fb)
> -               armada_drm_queue_unref_work(dplane->base.dev, old_fb);
> +               armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
Shouldn't this be part of another patch ?

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

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

* Re: [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb
  2015-09-30 10:49   ` Emil Velikov
@ 2015-10-01 13:34     ` Russell King - ARM Linux
  0 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2015-10-01 13:34 UTC (permalink / raw)
  To: Emil Velikov; +Cc: ML dri-devel

On Wed, Sep 30, 2015 at 11:49:44AM +0100, Emil Velikov wrote:
> Hi Russell,
> 
> On 29 September 2015 at 19:10, Russell King <rmk+kernel@arm.linux.org.uk> wrote:
> > Rather than using a spinlock, use xchg() to atomically update
> > dplane->old_fb.  This allows us to eliminate dplane->lock.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> [...]
> > @@ -76,13 +75,10 @@ static void armada_ovl_retire_fb(struct armada_ovl_plane *dplane,
> >  {
> >         struct drm_framebuffer *old_fb;
> >
> > -       spin_lock(&dplane->lock);
> > -       old_fb = dplane->old_fb;
> > -       dplane->old_fb = fb;
> > -       spin_unlock(&dplane->lock);
> > +       old_fb = xchg(&dplane->old_fb, fb);
> >
> >         if (old_fb)
> > -               armada_drm_queue_unref_work(dplane->base.dev, old_fb);
> > +               armada_drm_queue_unref_work(dplane->base.base.dev, old_fb);
> Shouldn't this be part of another patch ?

Yes, you're right, it should be in:

drm/armada: introduce generic armada_plane struct

Now moved there, thanks.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH 00/20] Armada DRM updates for 4.4
  2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
                   ` (19 preceding siblings ...)
  2015-09-29 18:11 ` [PATCH 20/20] drm/armada: move frame wait wakeup into plane work Russell King
@ 2015-10-09 13:24 ` Russell King - ARM Linux
  20 siblings, 0 replies; 24+ messages in thread
From: Russell King - ARM Linux @ 2015-10-09 13:24 UTC (permalink / raw)
  To: dri-devel

On Tue, Sep 29, 2015 at 07:08:43PM +0100, Russell King - ARM Linux wrote:
> Here are my queued changes for the Armada DRM driver, for the upcoming
> 4.4 merge window.

If there are no further comments (there was only one minor comment which
has been fixed), I'll send a pull request for this to David later today.

> 
> These changes are about updating the driver to some of the more recent
> DRM APIs, and removing the non-component support now that has
> stabilised.  This results in all of armada_output and armada_slave
> being removed, resulting in 460 lines of code removed from that change
> alone.
> 
> Other changes include:
> 
> * moving more towards supporting DRM planes in a more generic way,
>   thereby reducing the duplication between the primary and overlay
>   planes.
> * locking cleanups, more like locking removal, prefering inherently
>   atomic operations (eg, xchg) instead of spinlocking.  This ultimately
>   results in simpler and faster code.
> 
> I've been running these patches for a while and haven't noticed any ill
> effects.
> 
> Posted for comment, if nothing is forthcoming, I'll send a pull request
> to David in a week or so's time.  These patches are against v4.2, but
> rebase to 4.3-rc3 without any fuss.
> 
>  drivers/gpu/drm/armada/Kconfig          |   9 --
>  drivers/gpu/drm/armada/Makefile         |   3 +-
>  drivers/gpu/drm/armada/armada_crtc.c    | 258 +++++++++++++++++++++++---------
>  drivers/gpu/drm/armada/armada_crtc.h    |  34 +++--
>  drivers/gpu/drm/armada/armada_drm.h     |  16 --
>  drivers/gpu/drm/armada/armada_drv.c     | 148 +++---------------
>  drivers/gpu/drm/armada/armada_output.c  | 142 ------------------
>  drivers/gpu/drm/armada/armada_output.h  |  33 ----
>  drivers/gpu/drm/armada/armada_overlay.c | 147 +++++++++---------
>  drivers/gpu/drm/armada/armada_slave.c   | 139 -----------------
>  drivers/gpu/drm/armada/armada_slave.h   |  26 ----
>  11 files changed, 297 insertions(+), 658 deletions(-)
>  delete mode 100644 drivers/gpu/drm/armada/armada_output.c
>  delete mode 100644 drivers/gpu/drm/armada/armada_output.h
>  delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
>  delete mode 100644 drivers/gpu/drm/armada/armada_slave.h
> 
> -- 
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2015-10-09 13:24 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-29 18:08 [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux
2015-09-29 18:09 ` [PATCH 01/20] drm/armada: remove non-component support Russell King
2015-09-29 18:09 ` [PATCH 02/20] drm/armada: move vbl code into armada_crtc Russell King
2015-09-29 18:09 ` [PATCH 03/20] drm/armada: use drm_plane_force_disable() to disable the overlay plane Russell King
2015-09-29 18:09 ` [PATCH 04/20] drm/armada: disable CRTC clock during DPMS Russell King
2015-09-29 18:09 ` [PATCH 05/20] drm/armada: redo locking and atomics for armada_drm_crtc_complete_frame_work() Russell King
2015-09-29 18:09 ` [PATCH 06/20] drm/armada: rename overlay identifiers Russell King
2015-09-29 18:10 ` [PATCH 07/20] drm/armada: factor out retirement of old fb Russell King
2015-09-29 18:10 ` [PATCH 08/20] drm/armada: use xchg() to atomically update dplane->old_fb Russell King
2015-09-30 10:49   ` Emil Velikov
2015-10-01 13:34     ` Russell King - ARM Linux
2015-09-29 18:10 ` [PATCH 09/20] drm/armada: update armada overlay to use drm_universal_plane_init() Russell King
2015-09-29 18:10 ` [PATCH 10/20] drm/armada: introduce generic armada_plane struct Russell King
2015-09-29 18:10 ` [PATCH 11/20] drm/armada: add primary plane creation Russell King
2015-09-29 18:10 ` [PATCH 12/20] drm/armada: allocate primary plane ourselves Russell King
2015-09-29 18:10 ` [PATCH 13/20] drm/armada: provide a common helper to disable a plane Russell King
2015-09-29 18:10 ` [PATCH 14/20] drm/armada: move write to dma_ctrl0 to armada_drm_crtc_plane_disable() Russell King
2015-09-29 18:10 ` [PATCH 15/20] drm/armada: move the update of dplane->ctrl0 out of spinlock Russell King
2015-09-29 18:10 ` [PATCH 16/20] drm/armada: move the locking for armada_drm_vbl_event_remove() Russell King
2015-09-29 18:10 ` [PATCH 17/20] drm/armada: move frame wait into armada_frame Russell King
2015-09-29 18:11 ` [PATCH 18/20] drm/armada: move CRTC flip work to primary plane work Russell King
2015-09-29 18:11 ` [PATCH 19/20] drm/armada: convert overlay plane vbl worker to a armada plane worker Russell King
2015-09-29 18:11 ` [PATCH 20/20] drm/armada: move frame wait wakeup into plane work Russell King
2015-10-09 13:24 ` [PATCH 00/20] Armada DRM updates for 4.4 Russell King - ARM Linux

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).