summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma-buf/Makefile2
-rw-r--r--drivers/dma-buf/dma-buf.c4
-rw-r--r--drivers/dma-buf/dma-fence-chain.c4
-rw-r--r--drivers/dma-buf/dma-fence-unwrap.c162
-rw-r--r--drivers/dma-buf/st-dma-fence-unwrap.c157
-rw-r--r--drivers/dma-buf/sync_file.c119
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c51
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h27
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c27
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c38
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.h2
-rw-r--r--drivers/gpu/drm/bridge/Kconfig17
-rw-r--r--drivers/gpu/drm/bridge/Makefile1
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511.h12
-rw-r--r--drivers/gpu/drm/bridge/adv7511/adv7511_cec.c12
-rw-r--r--drivers/gpu/drm/bridge/analogix/anx7625.c1
-rw-r--r--drivers/gpu/drm/bridge/cdns-dsi.c26
-rw-r--r--drivers/gpu/drm/bridge/chipone-icn6211.c42
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611.c24
-rw-r--r--drivers/gpu/drm/bridge/lontium-lt9611uxc.c2
-rw-r--r--drivers/gpu/drm/bridge/nwl-dsi.c6
-rw-r--r--drivers/gpu/drm/bridge/parade-ps8640.c73
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c169
-rw-r--r--drivers/gpu/drm/bridge/ti-dlpc3433.c417
-rw-r--r--drivers/gpu/drm/display/drm_dp_aux_bus.c211
-rw-r--r--drivers/gpu/drm/drm_bridge.c23
-rw-r--r--drivers/gpu/drm/drm_client_modeset.c28
-rw-r--r--drivers/gpu/drm/drm_debugfs.c21
-rw-r--r--drivers/gpu/drm/drm_displayid.c16
-rw-r--r--drivers/gpu/drm/drm_edid.c1272
-rw-r--r--drivers/gpu/drm/drm_encoder.c2
-rw-r--r--drivers/gpu/drm/drm_gem_atomic_helper.c6
-rw-r--r--drivers/gpu/drm/drm_gem_framebuffer_helper.c104
-rw-r--r--drivers/gpu/drm/drm_gem_vram_helper.c54
-rw-r--r--drivers/gpu/drm/drm_mipi_dbi.c7
-rw-r--r--drivers/gpu/drm/drm_modes.c4
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c178
-rw-r--r--drivers/gpu/drm/drm_syncobj.c57
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c47
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c98
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_lvds.c80
-rw-r--r--drivers/gpu/drm/gma500/intel_i2c.c36
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c50
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c36
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_drv.h24
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c86
-rw-r--r--drivers/gpu/drm/hyperv/hyperv_drm_drv.c74
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c28
-rw-r--r--drivers/gpu/drm/meson/meson_encoder_cvbs.c1
-rw-r--r--drivers/gpu/drm/meson/meson_encoder_hdmi.c27
-rw-r--r--drivers/gpu/drm/mgag200/Makefile14
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c386
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.h148
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200.c200
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200eh.c50
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200eh3.c51
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200er.c46
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200ev.c50
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200ew3.c60
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200se.c130
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_g200wb.c50
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_i2c.c59
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mm.c116
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c453
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_pll.c12
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_reg.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c2
-rw-r--r--drivers/gpu/drm/panel/Kconfig2
-rw-r--r--drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c2
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_device.c9
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_drv.c1
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_features.h13
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_gpu.c18
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_issues.h19
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_regs.h1
-rw-r--r--drivers/gpu/drm/r128/r128_drv.h4
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig4
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop2.c5
-rw-r--r--drivers/gpu/drm/scheduler/sched_entity.c6
-rw-r--r--drivers/gpu/drm/solomon/ssd130x-spi.c2
-rw-r--r--drivers/gpu/drm/tiny/st7735r.c1
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c9
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c2
-rw-r--r--drivers/gpu/drm/vkms/vkms_composer.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_bo.c10
-rw-r--r--drivers/video/fbdev/Kconfig2
-rw-r--r--drivers/video/fbdev/core/fbmem.c22
93 files changed, 3756 insertions, 2198 deletions
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 4c9eb53ba3f8..70ec901edf2c 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
- dma-resv.o
+ dma-fence-unwrap.o dma-resv.o
obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o
obj-$(CONFIG_DMABUF_HEAPS) += heaps/
obj-$(CONFIG_SYNC_FILE) += sync_file.o
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 32f55640890c..727f5bb7d106 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1359,7 +1359,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
return ret;
seq_puts(s, "\nDma-buf Objects:\n");
- seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\t%-8s\n",
+ seq_printf(s, "%-8s\t%-8s\t%-8s\t%-8s\texp_name\t%-8s\tname\n",
"size", "flags", "mode", "count", "ino");
list_for_each_entry(buf_obj, &db_list.head, list_node) {
@@ -1376,7 +1376,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
file_count(buf_obj->file),
buf_obj->exp_name,
file_inode(buf_obj->file)->i_ino,
- buf_obj->name ?: "");
+ buf_obj->name ?: "<none>");
spin_unlock(&buf_obj->name_lock);
dma_resv_describe(buf_obj->resv, s);
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
index 06f8ef97c6e8..a0d920576ba6 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -62,8 +62,8 @@ struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
replacement = NULL;
}
- tmp = cmpxchg((struct dma_fence __force **)&chain->prev,
- prev, replacement);
+ tmp = unrcu_pointer(cmpxchg(&chain->prev, RCU_INITIALIZER(prev),
+ RCU_INITIALIZER(replacement)));
if (tmp == prev)
dma_fence_put(tmp);
else
diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c
new file mode 100644
index 000000000000..502a65ea6d44
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-unwrap.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * dma-fence-util: misc functions for dma_fence objects
+ *
+ * Copyright (C) 2022 Advanced Micro Devices, Inc.
+ * Authors:
+ * Christian König <christian.koenig@amd.com>
+ */
+
+#include <linux/dma-fence.h>
+#include <linux/dma-fence-array.h>
+#include <linux/dma-fence-chain.h>
+#include <linux/dma-fence-unwrap.h>
+#include <linux/slab.h>
+
+/* Internal helper to start new array iteration, don't use directly */
+static struct dma_fence *
+__dma_fence_unwrap_array(struct dma_fence_unwrap *cursor)
+{
+ cursor->array = dma_fence_chain_contained(cursor->chain);
+ cursor->index = 0;
+ return dma_fence_array_first(cursor->array);
+}
+
+/**
+ * dma_fence_unwrap_first - return the first fence from fence containers
+ * @head: the entrypoint into the containers
+ * @cursor: current position inside the containers
+ *
+ * Unwraps potential dma_fence_chain/dma_fence_array containers and return the
+ * first fence.
+ */
+struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head,
+ struct dma_fence_unwrap *cursor)
+{
+ cursor->chain = dma_fence_get(head);
+ return __dma_fence_unwrap_array(cursor);
+}
+EXPORT_SYMBOL_GPL(dma_fence_unwrap_first);
+
+/**
+ * dma_fence_unwrap_next - return the next fence from a fence containers
+ * @cursor: current position inside the containers
+ *
+ * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return
+ * the next fence from them.
+ */
+struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor)
+{
+ struct dma_fence *tmp;
+
+ ++cursor->index;
+ tmp = dma_fence_array_next(cursor->array, cursor->index);
+ if (tmp)
+ return tmp;
+
+ cursor->chain = dma_fence_chain_walk(cursor->chain);
+ return __dma_fence_unwrap_array(cursor);
+}
+EXPORT_SYMBOL_GPL(dma_fence_unwrap_next);
+
+/* Implementation for the dma_fence_merge() marco, don't use directly */
+struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
+ struct dma_fence **fences,
+ struct dma_fence_unwrap *iter)
+{
+ struct dma_fence_array *result;
+ struct dma_fence *tmp, **array;
+ unsigned int i;
+ size_t count;
+
+ count = 0;
+ for (i = 0; i < num_fences; ++i) {
+ dma_fence_unwrap_for_each(tmp, &iter[i], fences[i])
+ ++count;
+ }
+
+ if (count == 0)
+ return dma_fence_get_stub();
+
+ array = kmalloc_array(count, sizeof(*array), GFP_KERNEL);
+ if (!array)
+ return NULL;
+
+ /*
+ * This trashes the input fence array and uses it as position for the
+ * following merge loop. This works because the dma_fence_merge()
+ * wrapper macro is creating this temporary array on the stack together
+ * with the iterators.
+ */
+ for (i = 0; i < num_fences; ++i)
+ fences[i] = dma_fence_unwrap_first(fences[i], &iter[i]);
+
+ count = 0;
+ do {
+ unsigned int sel;
+
+restart:
+ tmp = NULL;
+ for (i = 0; i < num_fences; ++i) {
+ struct dma_fence *next;
+
+ while (fences[i] && dma_fence_is_signaled(fences[i]))
+ fences[i] = dma_fence_unwrap_next(&iter[i]);
+
+ next = fences[i];
+ if (!next)
+ continue;
+
+ /*
+ * We can't guarantee that inpute fences are ordered by
+ * context, but it is still quite likely when this
+ * function is used multiple times. So attempt to order
+ * the fences by context as we pass over them and merge
+ * fences with the same context.
+ */
+ if (!tmp || tmp->context > next->context) {
+ tmp = next;
+ sel = i;
+
+ } else if (tmp->context < next->context) {
+ continue;
+
+ } else if (dma_fence_is_later(tmp, next)) {
+ fences[i] = dma_fence_unwrap_next(&iter[i]);
+ goto restart;
+ } else {
+ fences[sel] = dma_fence_unwrap_next(&iter[sel]);
+ goto restart;
+ }
+ }
+
+ if (tmp) {
+ array[count++] = dma_fence_get(tmp);
+ fences[sel] = dma_fence_unwrap_next(&iter[sel]);
+ }
+ } while (tmp);
+
+ if (count == 0) {
+ tmp = dma_fence_get_stub();
+ goto return_tmp;
+ }
+
+ if (count == 1) {
+ tmp = array[0];
+ goto return_tmp;
+ }
+
+ result = dma_fence_array_create(count, array,
+ dma_fence_context_alloc(1),
+ 1, false);
+ if (!result) {
+ tmp = NULL;
+ goto return_tmp;
+ }
+ return &result->base;
+
+return_tmp:
+ kfree(array);
+ return tmp;
+}
+EXPORT_SYMBOL_GPL(__dma_fence_unwrap_merge);
diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c
index 039f016b57be..4105d5ea8dde 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -4,27 +4,19 @@
* Copyright (C) 2022 Advanced Micro Devices, Inc.
*/
+#include <linux/dma-fence.h>
+#include <linux/dma-fence-array.h>
+#include <linux/dma-fence-chain.h>
#include <linux/dma-fence-unwrap.h>
-#if 0
-#include <linux/kernel.h>
-#include <linux/kthread.h>
-#include <linux/mm.h>
-#include <linux/sched/signal.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/random.h>
-#endif
#include "selftest.h"
#define CHAIN_SZ (4 << 10)
-static inline struct mock_fence {
+struct mock_fence {
struct dma_fence base;
spinlock_t lock;
-} *to_mock_fence(struct dma_fence *f) {
- return container_of(f, struct mock_fence, base);
-}
+};
static const char *mock_name(struct dma_fence *f)
{
@@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void)
return NULL;
spin_lock_init(&f->lock);
- dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
+ dma_fence_init(&f->base, &mock_ops, &f->lock,
+ dma_fence_context_alloc(1), 1);
return &f->base;
}
@@ -59,7 +52,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...)
fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
if (!fences)
- return NULL;
+ goto error_put;
va_start(valist, num_fences);
for (i = 0; i < num_fences; ++i)
@@ -70,13 +63,17 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...)
dma_fence_context_alloc(1),
1, false);
if (!array)
- goto cleanup;
+ goto error_free;
return &array->base;
-cleanup:
- for (i = 0; i < num_fences; ++i)
- dma_fence_put(fences[i]);
+error_free:
kfree(fences);
+
+error_put:
+ va_start(valist, num_fences);
+ for (i = 0; i < num_fences; ++i)
+ dma_fence_put(va_arg(valist, typeof(*fences)));
+ va_end(valist);
return NULL;
}
@@ -113,7 +110,6 @@ static int sanitycheck(void *arg)
if (!chain)
return -ENOMEM;
- dma_fence_signal(f);
dma_fence_put(chain);
return err;
}
@@ -154,10 +150,8 @@ static int unwrap_array(void *arg)
err = -EINVAL;
}
- dma_fence_signal(f1);
- dma_fence_signal(f2);
dma_fence_put(array);
- return 0;
+ return err;
}
static int unwrap_chain(void *arg)
@@ -196,10 +190,8 @@ static int unwrap_chain(void *arg)
err = -EINVAL;
}
- dma_fence_signal(f1);
- dma_fence_signal(f2);
dma_fence_put(chain);
- return 0;
+ return err;
}
static int unwrap_chain_array(void *arg)
@@ -242,10 +234,115 @@ static int unwrap_chain_array(void *arg)
err = -EINVAL;
}
- dma_fence_signal(f1);
- dma_fence_signal(f2);
dma_fence_put(chain);
- return 0;
+ return err;
+}
+
+static int unwrap_merge(void *arg)
+{
+ struct dma_fence *fence, *f1, *f2, *f3;
+ struct dma_fence_unwrap iter;
+ int err = 0;
+
+ f1 = mock_fence();
+ if (!f1)
+ return -ENOMEM;
+
+ f2 = mock_fence();
+ if (!f2) {
+ err = -ENOMEM;
+ goto error_put_f1;
+ }
+
+ f3 = dma_fence_unwrap_merge(f1, f2);
+ if (!f3) {
+ err = -ENOMEM;
+ goto error_put_f2;
+ }
+
+ dma_fence_unwrap_for_each(fence, &iter, f3) {
+ if (fence == f1) {
+ dma_fence_put(f1);
+ f1 = NULL;
+ } else if (fence == f2) {
+ dma_fence_put(f2);
+ f2 = NULL;
+ } else {
+ pr_err("Unexpected fence!\n");
+ err = -EINVAL;
+ }
+ }
+
+ if (f1 || f2) {
+ pr_err("Not all fences seen!\n");
+ err = -EINVAL;