aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/pl111
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-05-02 09:47:19 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-05-02 13:13:42 -0400
commit57450671776b37d7c81cd52a89982c14bca46cfc (patch)
treed819743252c2f0f036184f37570e7ded4616baa4 /drivers/gpu/drm/pl111
parentca454bd42dc24374150febf83a443e8c1d9cf28a (diff)
drm/pl111: Enable device-specific assigned memory
The Versatile Express has 8 MB of dedicated video RAM (VRAM) on the motherboard, which is what we should be using for the PL111 if available. On this platform, the memory backplane is constructed so that only this memory will work properly with the CLCD on the motherboard, using any other memory area just gives random snow on the display. The CA9 Versatile Express also has a PL111 instance on its core tile that can address all memory, and this does not have the restriction. The memory is assigned to the device using the memory-region device tree property and a "shared-dma-pool" reserved memory pool like this: reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; vram: vram@48000000 { compatible = "shared-dma-pool"; reg = <0x48000000 0x00800000>; no-map; }; }; clcd@1f000 { compatible = "arm,pl111", "arm,primecell"; (...) memory-region = <&vram>; }ยท; Cc: Liviu Dudau <liviu.dudau@arm.com> Cc: Mali DP Maintainers <malidp@foss.arm.com> Reviewed-by: Eric Anholt <eric@anholt.net> Tested-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20180502134719.8388-2-linus.walleij@linaro.org
Diffstat (limited to 'drivers/gpu/drm/pl111')
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h1
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c34
2 files changed, 33 insertions, 2 deletions
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
index 8639b2d4ddf7..ce4501d0ab48 100644
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -79,6 +79,7 @@ struct pl111_drm_dev_private {
79 const struct pl111_variant_data *variant; 79 const struct pl111_variant_data *variant;
80 void (*variant_display_enable) (struct drm_device *drm, u32 format); 80 void (*variant_display_enable) (struct drm_device *drm, u32 format);
81 void (*variant_display_disable) (struct drm_device *drm); 81 void (*variant_display_disable) (struct drm_device *drm);
82 bool use_device_memory;
82}; 83};
83 84
84int pl111_display_init(struct drm_device *dev); 85int pl111_display_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
index 4621259d5387..454ff0804642 100644
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -60,6 +60,7 @@
60#include <linux/slab.h> 60#include <linux/slab.h>
61#include <linux/of.h> 61#include <linux/of.h>
62#include <linux/of_graph.h> 62#include <linux/of_graph.h>
63#include <linux/of_reserved_mem.h>
63 64
64#include <drm/drmP.h> 65#include <drm/drmP.h>
65#include <drm/drm_atomic_helper.h> 66#include <drm/drm_atomic_helper.h>
@@ -207,6 +208,24 @@ finish:
207 return ret; 208 return ret;
208} 209}
209 210
211static struct drm_gem_object *
212pl111_gem_import_sg_table(struct drm_device *dev,
213 struct dma_buf_attachment *attach,
214 struct sg_table *sgt)
215{
216 struct pl111_drm_dev_private *priv = dev->dev_private;
217
218 /*
219 * When using device-specific reserved memory we can't import
220 * DMA buffers: those are passed by reference in any global
221 * memory and we can only handle a specific range of memory.
222 */
223 if (priv->use_device_memory)
224 return ERR_PTR(-EINVAL);
225
226 return drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
227}
228
210DEFINE_DRM_GEM_CMA_FOPS(drm_fops); 229DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
211 230
212static struct drm_driver pl111_drm_driver = { 231static struct drm_driver pl111_drm_driver = {
@@ -227,7 +246,7 @@ static struct drm_driver pl111_drm_driver = {
227 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 246 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
228 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 247 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
229 .gem_prime_import = drm_gem_prime_import, 248 .gem_prime_import = drm_gem_prime_import,
230 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 249 .gem_prime_import_sg_table = pl111_gem_import_sg_table,
231 .gem_prime_export = drm_gem_prime_export, 250 .gem_prime_export = drm_gem_prime_export,
232 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 251 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
233 252
@@ -257,6 +276,12 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
257 drm->dev_private = priv; 276 drm->dev_private = priv;
258 priv->variant = variant; 277 priv->variant = variant;
259 278
279 ret = of_reserved_mem_device_init(dev);
280 if (!ret) {
281 dev_info(dev, "using device-specific reserved memory\n");
282 priv->use_device_memory = true;
283 }
284
260 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth", 285 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth",
261 &priv->memory_bw)) { 286 &priv->memory_bw)) {
262 dev_info(dev, "no max memory bandwidth specified, assume unlimited\n"); 287 dev_info(dev, "no max memory bandwidth specified, assume unlimited\n");
@@ -275,7 +300,8 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
275 priv->regs = devm_ioremap_resource(dev, &amba_dev->res); 300 priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
276 if (IS_ERR(priv->regs)) { 301 if (IS_ERR(priv->regs)) {
277 dev_err(dev, "%s failed mmio\n", __func__); 302 dev_err(dev, "%s failed mmio\n", __func__);
278 return PTR_ERR(priv->regs); 303 ret = PTR_ERR(priv->regs);
304 goto dev_unref;
279 } 305 }
280 306
281 /* This may override some variant settings */ 307 /* This may override some variant settings */
@@ -305,11 +331,14 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
305 331
306dev_unref: 332dev_unref:
307 drm_dev_unref(drm); 333 drm_dev_unref(drm);
334 of_reserved_mem_device_release(dev);
335
308 return ret; 336 return ret;
309} 337}
310 338
311static int pl111_amba_remove(struct amba_device *amba_dev) 339static int pl111_amba_remove(struct amba_device *amba_dev)
312{ 340{
341 struct device *dev = &amba_dev->dev;
313 struct drm_device *drm = amba_get_drvdata(amba_dev); 342 struct drm_device *drm = amba_get_drvdata(amba_dev);
314 struct pl111_drm_dev_private *priv = drm->dev_private; 343 struct pl111_drm_dev_private *priv = drm->dev_private;
315 344
@@ -319,6 +348,7 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
319 drm_panel_bridge_remove(priv->bridge); 348 drm_panel_bridge_remove(priv->bridge);
320 drm_mode_config_cleanup(drm); 349 drm_mode_config_cleanup(drm);
321 drm_dev_unref(drm); 350 drm_dev_unref(drm);
351 of_reserved_mem_device_release(dev);
322 352
323 return 0; 353 return 0;
324} 354}