summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2018-06-24 14:03:31 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2023-10-30 13:21:43 +0000
commit87125ba103873bbdeb0e0f08d10ce8e1daf1709a (patch)
treef0850ff76ef76aaee21803d7065ff19fab5821c3
parentffc253263a1375a65fa6c9f62a893e9767fbebfa (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 e8d2fe955909..9200ede96427 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
+#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <drm/drm_aperture.h>
@@ -56,11 +57,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),
@@ -72,11 +102,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"))