summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-06-24 14:03:31 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2020-08-04 17:42:15 +0100
commit92839b0f00d02b64eb87c1fa80fade781cfbba32 (patch)
treefbe900e65851729cf1c13ef6964828468eeac737
parentbcf876870b95592b52519ed4aafcf9d95999bc9c (diff)
drm/armada: add reserved memory support
Existing Armada DRM makes use of reserved memory for allocating contiguous screen buffers, which currently prevents its use with DT systems. Add support for this for DT systems. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/gpu/drm/armada/armada_drv.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 5fc25c3f445c..12e641eb8548 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -7,6 +7,7 @@
#include <linux/component.h>
#include <linux/module.h>
#include <linux/of_graph.h>
+#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <drm/drm_atomic_helper.h>
@@ -61,11 +62,40 @@ static const struct drm_mode_config_funcs armada_drm_mode_config_funcs = {
.atomic_commit = drm_atomic_helper_commit,
};
-static int armada_drm_bind(struct device *dev)
+static struct reserved_mem *armada_drm_get_rmem(struct device *dev,
+ const char *compatible)
+{
+ struct device_node *np;
+ struct reserved_mem *rmem;
+
+ np = of_find_compatible_node(NULL, NULL, compatible);
+ if (!np)
+ return NULL;
+
+ rmem = of_reserved_mem_lookup(np);
+ of_node_put(np);
+
+ return rmem;
+}
+
+static struct resource *armada_drm_get_mem(struct device *dev)
{
- struct armada_private *priv;
struct resource *mem = NULL;
- int ret, n;
+ struct reserved_mem *rmem;
+ int n;
+
+ rmem = armada_drm_get_rmem(dev, "marvell,armada-framebuffer");
+ if (rmem) {
+ mem = devm_kzalloc(dev, sizeof(*mem), GFP_KERNEL);
+ if (!mem)
+ return ERR_PTR(-ENOMEM);
+
+ mem->start = rmem->base;
+ mem->end = rmem->base + rmem->size - 1;
+ mem->flags = IORESOURCE_MEM;
+
+ return mem;
+ }
for (n = 0; ; n++) {
struct resource *r = platform_get_resource(to_platform_device(dev),
@@ -77,11 +107,21 @@ static int armada_drm_bind(struct device *dev)
if (resource_size(r) > SZ_64K)
mem = r;
else
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
- if (!mem)
- return -ENXIO;
+ return mem ? : ERR_PTR(-ENXIO);
+}
+
+static int armada_drm_bind(struct device *dev)
+{
+ struct armada_private *priv;
+ struct resource *mem;
+ int ret;
+
+ mem = armada_drm_get_mem(dev);
+ if (IS_ERR(mem))
+ return PTR_ERR(mem);
if (!devm_request_mem_region(dev, mem->start, resource_size(mem),
"armada-drm"))