summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_gem_framebuffer_helper.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2022-06-15 19:12:17 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2022-06-15 19:12:17 +0200
commit0f95ee9a0c579ebed0309657f6918673927189f2 (patch)
treee10c39634b67eaaae5d6330f1f3538b24251439c /drivers/gpu/drm/drm_gem_framebuffer_helper.c
parentb13baccc3850ca8b8cccbf8ed9912dbaa0fdf7f3 (diff)
parentdfa687bffc8a4a21ed929c7dececf01b8f1f52ee (diff)
Merge tag 'drm-misc-next-2022-06-08' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.20: UAPI Changes: * connector: export bpc limits in debugfs * dma-buf: Print buffer name in debugfs Cross-subsystem Changes: * dma-buf: Improve dma-fence handling; Cleanups * fbdev: Device-unregistering fixes Core Changes: * client: Only use driver-validated modes to avoid blank screen * dp-aux: Make probing more reliable; Small fixes * edit: CEA data-block iterators; Introduce struct drm_edid; Many cleanups * gem: Don't use framebuffer format's non-exising color planes * probe-helper: Use 640x480 as DisplayPort fallback; Refactoring * scheduler: Don't kill jobs in interrupt context Driver Changes: * amdgpu: Use atomic fence helpers in DM; Fix VRAM address calculation; Export CRTC bpc settings via debugfs * bridge: Add TI-DLPC3433; anx7625: Fixes; fy07024di26a30d: Optional GPIO reset; icn6211: Cleanups; ldb: Add reg and reg-name properties to bindings, Kconfig fixes; lt9611: Fix display sensing; lt9611uxc: Fixes; nwl-dsi: Fixes; ps8640: Cleanups; st7735r: Fixes; tc358767: DSI/DPI refactoring and DSI-to-eDP support, Fixes; ti-sn65dsi83: Fixes; * gma500: Cleanup connector I2C handling * hyperv: Unify VRAM allocation of Gen1 and Gen2 * i915: export CRTC bpc settings via debugfs * meson: Support YUV422 output; Refcount fixes * mgag200: Support damage clipping; Support gamma handling; Protect concurrent HW access; Fixes to connector; Store model-specific limits in device-info structure; Cleanups * nouveau: Fixes and Cleanups * panel: Kconfig fixes * panfrost: Valhall support * r128: Fix bit-shift overflow * rockchip: Locking fixes in error path; Minor cleanups * ssd130x: Fix built-in linkage * ttm: Cleanups * udl; Always advertize VGA connector * fbdev/vesa: Support COMPILE_TEST Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/YqBtumw05JZDEZE2@linux-uq9g
Diffstat (limited to 'drivers/gpu/drm/drm_gem_framebuffer_helper.c')
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index f4619803acd0..61339a9cd010 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -53,7 +53,11 @@ MODULE_IMPORT_NS(DMA_BUF);
struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
unsigned int plane)
{
- if (plane >= ARRAY_SIZE(fb->obj))
+ struct drm_device *dev = fb->dev;
+
+ if (drm_WARN_ON_ONCE(dev, plane >= ARRAY_SIZE(fb->obj)))
+ return NULL;
+ else if (drm_WARN_ON_ONCE(dev, !fb->obj[plane]))
return NULL;
return fb->obj[plane];
@@ -92,9 +96,9 @@ drm_gem_fb_init(struct drm_device *dev,
*/
void drm_gem_fb_destroy(struct drm_framebuffer *fb)
{
- size_t i;
+ unsigned int i;
- for (i = 0; i < ARRAY_SIZE(fb->obj); i++)
+ for (i = 0; i < fb->format->num_planes; i++)
drm_gem_object_put(fb->obj[i]);
drm_framebuffer_cleanup(fb);
@@ -329,24 +333,26 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
* The argument returns the addresses of the data stored in each BO. This
* is different from @map if the framebuffer's offsets field is non-zero.
*
+ * Both, @map and @data, must each refer to arrays with at least
+ * fb->format->num_planes elements.
+ *
* See drm_gem_fb_vunmap() for unmapping.
*
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
-int drm_gem_fb_vmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES],
- struct iosys_map data[DRM_FORMAT_MAX_PLANES])
+int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map,
+ struct iosys_map *data)
{
struct drm_gem_object *obj;
unsigned int i;
int ret;
- for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
+ for (i = 0; i < fb->format->num_planes; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
if (!obj) {
- iosys_map_clear(&map[i]);
- continue;
+ ret = -EINVAL;
+ goto err_drm_gem_vunmap;
}
ret = drm_gem_vmap(obj, &map[i]);
if (ret)
@@ -354,7 +360,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb,
}
if (data) {
- for (i = 0; i < DRM_FORMAT_MAX_PLANES; ++i) {
+ for (i = 0; i < fb->format->num_planes; ++i) {
memcpy(&data[i], &map[i], sizeof(data[i]));
if (iosys_map_is_null(&data[i]))
continue;
@@ -385,10 +391,9 @@ EXPORT_SYMBOL(drm_gem_fb_vmap);
*
* See drm_gem_fb_vmap() for more information.
*/
-void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
- struct iosys_map map[static DRM_FORMAT_MAX_PLANES])
+void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map)
{
- unsigned int i = DRM_FORMAT_MAX_PLANES;
+ unsigned int i = fb->format->num_planes;
struct drm_gem_object *obj;
while (i) {
@@ -403,6 +408,28 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb,
}
EXPORT_SYMBOL(drm_gem_fb_vunmap);
+static void __drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir,
+ unsigned int num_planes)
+{
+ struct dma_buf_attachment *import_attach;
+ struct drm_gem_object *obj;
+ int ret;
+
+ while (num_planes) {
+ --num_planes;
+ obj = drm_gem_fb_get_obj(fb, num_planes);
+ if (!obj)
+ continue;
+ import_attach = obj->import_attach;
+ if (!import_attach)
+ continue;
+ ret = dma_buf_end_cpu_access(import_attach->dmabuf, dir);
+ if (ret)
+ drm_err(fb->dev, "dma_buf_end_cpu_access(%u, %d) failed: %d\n",
+ ret, num_planes, dir);
+ }
+}
+
/**
* drm_gem_fb_begin_cpu_access - prepares GEM buffer objects for CPU access
* @fb: the framebuffer
@@ -421,40 +448,27 @@ int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direct
{
struct dma_buf_attachment *import_attach;
struct drm_gem_object *obj;
- size_t i;
- int ret, ret2;
+ unsigned int i;
+ int ret;
- for (i = 0; i < ARRAY_SIZE(fb->obj); ++i) {
+ for (i = 0; i < fb->format->num_planes; ++i) {
obj = drm_gem_fb_get_obj(fb, i);
- if (!obj)
- continue;
+ if (!obj) {
+ ret = -EINVAL;
+ goto err___drm_gem_fb_end_cpu_access;
+ }
import_attach = obj->import_attach;
if (!import_attach)
continue;
ret = dma_buf_begin_cpu_access(import_attach->dmabuf, dir);
if (ret)
- goto err_dma_buf_end_cpu_access;
+ goto err___drm_gem_fb_end_cpu_access;
}
return 0;
-err_dma_buf_end_cpu_access:
- while (i) {
- --i;
- obj = drm_gem_fb_get_obj(fb, i);
- if (!obj)
- continue;
- import_attach = obj->import_attach;
- if (!import_attach)
- continue;
- ret2 = dma_buf_end_cpu_access(import_attach->dmabuf, dir);
- if (ret2) {
- drm_err(fb->dev,
- "dma_buf_end_cpu_access() failed during error handling: %d\n",
- ret2);
- }
- }
-
+err___drm_gem_fb_end_cpu_access:
+ __drm_gem_fb_end_cpu_access(fb, dir, i);
return ret;
}
EXPORT_SYMBOL(drm_gem_fb_begin_cpu_access);
@@ -472,23 +486,7 @@ EXPORT_SYMBOL(drm_gem_fb_begin_cpu_access);
*/
void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir)
{
- size_t i = ARRAY_SIZE(fb->obj);
- struct dma_buf_attachment *import_attach;
- struct drm_gem_object *obj;
- int ret;
-
- while (i) {
- --i;
- obj = drm_gem_fb_get_obj(fb, i);
- if (!obj)
- continue;
- import_attach = obj->import_attach;
- if (!import_attach)
- continue;
- ret = dma_buf_end_cpu_access(import_attach->dmabuf, dir);
- if (ret)
- drm_err(fb->dev, "dma_buf_end_cpu_access() failed: %d\n", ret);
- }
+ __drm_gem_fb_end_cpu_access(fb, dir, fb->format->num_planes);
}
EXPORT_SYMBOL(drm_gem_fb_end_cpu_access);