diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2018-06-24 14:03:31 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2020-08-04 17:42:15 +0100 |
commit | 92839b0f00d02b64eb87c1fa80fade781cfbba32 (patch) | |
tree | fbe900e65851729cf1c13ef6964828468eeac737 | |
parent | bcf876870b95592b52519ed4aafcf9d95999bc9c (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.c | 52 |
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")) |