From: Thierry Reding <thierry.reding@gmail.com>
To: David Airlie <airlied@redhat.com>,
Daniel Vetter <daniel@ffwll.ch>,
Thomas Zimmermann <tzimmermann@suse.de>
Cc: Jon Hunter <jonathanh@nvidia.com>,
Robin Murphy <robin.murphy@arm.com>,
dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org,
devicetree@vger.kernel.org
Subject: [PATCH v4 5/8] drm/simpledrm: Add support for system memory framebuffers
Date: Fri, 20 Jan 2023 18:31:00 +0100 [thread overview]
Message-ID: <20230120173103.4002342-6-thierry.reding@gmail.com> (raw)
In-Reply-To: <20230120173103.4002342-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Simple framebuffers can be set up in system memory, which cannot be
requested and/or I/O remapped using the I/O resource helpers. Add a
separate code path that obtains system memory framebuffers from the
reserved memory region referenced in the memory-region property.
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
Changes in v4:
- rebase onto latest format helper changes
- turn drm_info() into drm_dbg()
- add Reviewed-by from Thomas
Changes in v3:
- simplify memory code and move back to simpledrm_device_create()
- extract screen_base iosys_map fix into separate patch
Changes in v2:
- make screen base a struct iosys_map to avoid sparse warnings
drivers/gpu/drm/tiny/simpledrm.c | 99 ++++++++++++++++++++++++--------
1 file changed, 75 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index c1ed6dd426ec..2acc0eb32489 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -3,6 +3,7 @@
#include <linux/clk.h>
#include <linux/of_clk.h>
#include <linux/minmax.h>
+#include <linux/of_address.h>
#include <linux/platform_data/simplefb.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
@@ -184,6 +185,31 @@ simplefb_get_format_of(struct drm_device *dev, struct device_node *of_node)
return simplefb_get_validated_format(dev, format);
}
+static struct resource *
+simplefb_get_memory_of(struct drm_device *dev, struct device_node *of_node)
+{
+ struct device_node *np;
+ struct resource *res;
+ int err;
+
+ np = of_parse_phandle(of_node, "memory-region", 0);
+ if (!np)
+ return NULL;
+
+ res = devm_kzalloc(dev->dev, sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return ERR_PTR(-ENOMEM);
+
+ err = of_address_to_resource(np, 0, res);
+ if (err)
+ return ERR_PTR(err);
+
+ if (of_get_property(of_node, "reg", NULL))
+ drm_warn(dev, "preferring \"memory-region\" over \"reg\" property\n");
+
+ return res;
+}
+
/*
* Simple Framebuffer device
*/
@@ -604,8 +630,7 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
struct drm_device *dev;
int width, height, stride;
const struct drm_format_info *format;
- struct resource *res, *mem;
- void __iomem *screen_base;
+ struct resource *res, *mem = NULL;
struct drm_plane *primary_plane;
struct drm_crtc *crtc;
struct drm_encoder *encoder;
@@ -657,6 +682,9 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
format = simplefb_get_format_of(dev, of_node);
if (IS_ERR(format))
return ERR_CAST(format);
+ mem = simplefb_get_memory_of(dev, of_node);
+ if (IS_ERR(mem))
+ return ERR_CAST(mem);
} else {
drm_err(dev, "no simplefb configuration found\n");
return ERR_PTR(-ENODEV);
@@ -679,32 +707,55 @@ static struct simpledrm_device *simpledrm_device_create(struct drm_driver *drv,
* Memory management
*/
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return ERR_PTR(-EINVAL);
+ if (mem) {
+ void *screen_base;
- ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
- if (ret) {
- drm_err(dev, "could not acquire memory range %pr: error %d\n", res, ret);
- return ERR_PTR(ret);
- }
+ ret = devm_aperture_acquire_from_firmware(dev, mem->start, resource_size(mem));
+ if (ret) {
+ drm_err(dev, "could not acquire memory range %pr: %d\n", mem, ret);
+ return ERR_PTR(ret);
+ }
- mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res), drv->name);
- if (!mem) {
- /*
- * We cannot make this fatal. Sometimes this comes from magic
- * spaces our resource handlers simply don't know about. Use
- * the I/O-memory resource as-is and try to map that instead.
- */
- drm_warn(dev, "could not acquire memory region %pr\n", res);
- mem = res;
- }
+ drm_dbg(dev, "using system memory framebuffer at %pr\n", mem);
- screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem));
- if (!screen_base)
- return ERR_PTR(-ENOMEM);
+ screen_base = devm_memremap(dev->dev, mem->start, resource_size(mem), MEMREMAP_WC);
+ if (!screen_base)
+ return ERR_PTR(-ENOMEM);
+
+ iosys_map_set_vaddr(&sdev->screen_base, screen_base);
+ } else {
+ void __iomem *screen_base;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return ERR_PTR(-EINVAL);
- iosys_map_set_vaddr_iomem(&sdev->screen_base, screen_base);
+ ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
+ if (ret) {
+ drm_err(dev, "could not acquire memory range %pr: %d\n", &res, ret);
+ return ERR_PTR(ret);
+ }
+
+ drm_dbg(dev, "using I/O memory framebuffer at %pr\n", res);
+
+ mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+ drv->name);
+ if (!mem) {
+ /*
+ * We cannot make this fatal. Sometimes this comes from magic
+ * spaces our resource handlers simply don't know about. Use
+ * the I/O-memory resource as-is and try to map that instead.
+ */
+ drm_warn(dev, "could not acquire memory region %pr\n", res);
+ mem = res;
+ }
+
+ screen_base = devm_ioremap_wc(&pdev->dev, mem->start, resource_size(mem));
+ if (!screen_base)
+ return ERR_PTR(-ENOMEM);
+
+ iosys_map_set_vaddr_iomem(&sdev->screen_base, screen_base);
+ }
/*
* Modesetting
--
2.39.0
next prev parent reply other threads:[~2023-01-20 17:31 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-20 17:30 [PATCH v4 0/8] drm/simpledrm: Support system memory framebuffers Thierry Reding
2023-01-20 17:30 ` [PATCH v4 1/8] dt-bindings: display: simple-framebuffer: " Thierry Reding
2023-01-20 17:30 ` [PATCH v4 2/8] dt-bindings: display: simple-framebuffer: Document 32-bit BGR format Thierry Reding
2023-01-20 17:30 ` [PATCH v4 3/8] dt-bindings: reserved-memory: Support framebuffer reserved memory Thierry Reding
2023-01-20 17:30 ` [PATCH v4 4/8] drm/simpledrm: Use struct iosys_map consistently Thierry Reding
2023-01-20 17:31 ` Thierry Reding [this message]
2023-01-20 17:31 ` [PATCH v4 6/8] drm/format-helper: Support the AB24/XB24 formats Thierry Reding
2023-01-20 17:31 ` [PATCH v4 7/8] drm/simpledrm: Support the XB24/AB24 format Thierry Reding
2023-01-23 9:16 ` Thomas Zimmermann
2023-01-23 15:19 ` Thierry Reding
2023-01-20 17:31 ` [PATCH v4 8/8] arm64: tegra: Add simple framebuffer on Jetson Xavier NX Thierry Reding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230120173103.4002342-6-thierry.reding@gmail.com \
--to=thierry.reding@gmail.com \
--cc=airlied@redhat.com \
--cc=daniel@ffwll.ch \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=jonathanh@nvidia.com \
--cc=linux-tegra@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox